summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-10-09 16:20:26 +0000
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-05-12 21:20:55 +0200
commit023e5ba09ad15faa261f0f424780e5b2150fe9c0 (patch)
tree16559c722dbb0fbcab077f3cf21331ad2b3c1236
parent7f924cec5928fa9cdf2b8fde5146f9fcf031adb6 (diff)
[MOVED FROM BAD 27/57] gst/flv/: Get an approximate duration of the file by looking at the timestamp of the last tag in pull mode. If we get...
Original commit message from CVS: * gst/flv/gstflvdemux.c: (gst_flv_demux_loop): * gst/flv/gstflvparse.c: (gst_flv_parse_tag_timestamp): * gst/flv/gstflvparse.h: Get an approximate duration of the file by looking at the timestamp of the last tag in pull mode. If we get (maybe better) duration from metadata later we'll use that instead.
-rw-r--r--gst/flv/gstflvdemux.c32
-rw-r--r--gst/flv/gstflvparse.c31
-rw-r--r--gst/flv/gstflvparse.h2
3 files changed, 65 insertions, 0 deletions
diff --git a/gst/flv/gstflvdemux.c b/gst/flv/gstflvdemux.c
index dc148507..8cc74f1d 100644
--- a/gst/flv/gstflvdemux.c
+++ b/gst/flv/gstflvdemux.c
@@ -443,6 +443,38 @@ gst_flv_demux_loop (GstPad * pad)
break;
default:
ret = gst_flv_demux_pull_header (pad, demux);
+
+ /* If we parsed the header successfully try to get an
+ * approximate duration by looking at the last tag's timestamp */
+ if (ret == GST_FLOW_OK) {
+ gint64 size;
+ GstFormat fmt = GST_FORMAT_BYTES;
+
+ if (gst_pad_query_peer_duration (pad, &fmt, &size) &&
+ fmt == GST_FORMAT_BYTES && size != -1 && size > FLV_HEADER_SIZE) {
+ GstBuffer *buffer;
+
+ if (gst_flv_demux_pull_range (demux, pad, size - 4, 4,
+ &buffer) == GST_FLOW_OK) {
+ guint32 prev_tag_size =
+ GST_READ_UINT32_BE (GST_BUFFER_DATA (buffer));
+
+ gst_buffer_unref (buffer);
+
+ if (size - 4 - prev_tag_size > FLV_HEADER_SIZE &&
+ prev_tag_size >= 8 &&
+ gst_flv_demux_pull_range (demux, pad,
+ size - prev_tag_size - 4, prev_tag_size,
+ &buffer) == GST_FLOW_OK) {
+ demux->duration =
+ gst_flv_parse_tag_timestamp (demux,
+ GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
+
+ gst_buffer_unref (buffer);
+ }
+ }
+ }
+ }
}
/* pause if something went wrong */
diff --git a/gst/flv/gstflvparse.c b/gst/flv/gstflvparse.c
index fd51cbfe..c5545054 100644
--- a/gst/flv/gstflvparse.c
+++ b/gst/flv/gstflvparse.c
@@ -1006,6 +1006,37 @@ beach:
return ret;
}
+GstClockTime
+gst_flv_parse_tag_timestamp (GstFLVDemux * demux, const guint8 * data,
+ size_t data_size)
+{
+ guint32 pts = 0, pts_ext = 0;
+
+ if (data[0] != 9 && data[0] != 8 && data[0] != 18) {
+ GST_WARNING_OBJECT (demux, "Unsupported tag type %u", data[0]);
+ return GST_CLOCK_TIME_NONE;
+ }
+
+ if (FLV_GET_BEUI24 (data + 1, data_size - 1) != data_size - 11) {
+ GST_WARNING_OBJECT (demux, "Invalid tag");
+ return GST_CLOCK_TIME_NONE;
+ }
+
+ data += 4;
+
+ GST_LOG_OBJECT (demux, "pts bytes %02X %02X %02X %02X", data[0], data[1],
+ data[2], data[3]);
+
+ /* Grab timestamp of tag tag */
+ pts = FLV_GET_BEUI24 (data, data_size);
+ /* read the pts extension to 32 bits integer */
+ pts_ext = GST_READ_UINT8 (data + 3);
+ /* Combine them */
+ pts |= pts_ext << 24;
+
+ return pts * GST_MSECOND;
+}
+
GstFlowReturn
gst_flv_parse_tag_type (GstFLVDemux * demux, const guint8 * data,
size_t data_size)
diff --git a/gst/flv/gstflvparse.h b/gst/flv/gstflvparse.h
index 7b9d498e..0dfeaa97 100644
--- a/gst/flv/gstflvparse.h
+++ b/gst/flv/gstflvparse.h
@@ -38,5 +38,7 @@ GstFlowReturn gst_flv_parse_tag_type (GstFLVDemux * demux, const guint8 * data,
GstFlowReturn gst_flv_parse_header (GstFLVDemux * demux, const guint8 * data,
size_t data_size);
+GstClockTime gst_flv_parse_tag_timestamp (GstFLVDemux *demux, const guint8 *data, size_t data_size);
+
G_END_DECLS
#endif /* __FLV_PARSE_H__ */