diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | gst/flv/gstflvdemux.c | 32 | ||||
-rw-r--r-- | gst/flv/gstflvparse.c | 31 | ||||
-rw-r--r-- | gst/flv/gstflvparse.h | 2 |
4 files changed, 74 insertions, 0 deletions
@@ -1,5 +1,14 @@ 2008-10-09 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * 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. + +2008-10-09 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * gst/flv/gstflvdemux.c: (gst_flv_demux_pull_range), (gst_flv_demux_pull_tag), (gst_flv_demux_pull_header): Refactor _pull_range() logic with checks into a seperate function 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__ */ |