mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
Improved seeking and indexing
Original commit message from CVS: Improved seeking and indexing
This commit is contained in:
parent
a0646013c2
commit
72f3cbcb7b
5 changed files with 229 additions and 83 deletions
|
@ -138,6 +138,7 @@ static void gst_mpeg_demux_send_data (GstMPEGParse *mpeg_parse,
|
|||
GstData *data, GstClockTime time);
|
||||
|
||||
static void gst_mpeg_demux_handle_discont (GstMPEGParse *mpeg_parse);
|
||||
static gboolean gst_mpeg_demux_handle_src_event (GstPad *pad, GstEvent *event);
|
||||
|
||||
static void gst_mpeg_demux_set_index (GstElement *element, GstIndex *index);
|
||||
static GstIndex* gst_mpeg_demux_get_index (GstElement *element);
|
||||
|
@ -421,12 +422,17 @@ gst_mpeg_demux_parse_syshead (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
gst_pad_try_set_caps (*outpad, gst_pad_get_pad_template_caps (*outpad));
|
||||
|
||||
gst_pad_set_formats_function (*outpad, gst_mpeg_parse_get_src_formats);
|
||||
gst_pad_set_convert_function (*outpad, gst_mpeg_parse_convert_src);
|
||||
gst_pad_set_event_mask_function (*outpad, gst_mpeg_parse_get_src_event_masks);
|
||||
gst_pad_set_event_function (*outpad, gst_mpeg_parse_handle_src_event);
|
||||
gst_pad_set_event_function (*outpad, gst_mpeg_demux_handle_src_event);
|
||||
gst_pad_set_query_type_function (*outpad, gst_mpeg_parse_get_src_query_types);
|
||||
gst_pad_set_query_function (*outpad, gst_mpeg_parse_handle_src_query);
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (mpeg_demux), (*outpad));
|
||||
gst_pad_set_element_private (*outpad, *outstream);
|
||||
|
||||
(*outstream)->size_bound = buf_byte_size_bound;
|
||||
mpeg_demux->total_size_bound += buf_byte_size_bound;
|
||||
|
||||
if (mpeg_demux->index) {
|
||||
gst_index_get_writer_id (mpeg_demux->index, GST_OBJECT (*outpad),
|
||||
|
@ -854,12 +860,14 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
gst_pad_try_set_caps (*outpad, gst_pad_get_pad_template_caps (*outpad));
|
||||
|
||||
gst_pad_set_formats_function (*outpad, gst_mpeg_parse_get_src_formats);
|
||||
gst_pad_set_convert_function (*outpad, gst_mpeg_parse_convert_src);
|
||||
gst_pad_set_event_mask_function (*outpad, gst_mpeg_parse_get_src_event_masks);
|
||||
gst_pad_set_event_function (*outpad, gst_mpeg_parse_handle_src_event);
|
||||
gst_pad_set_event_function (*outpad, gst_mpeg_demux_handle_src_event);
|
||||
gst_pad_set_query_type_function (*outpad, gst_mpeg_parse_get_src_query_types);
|
||||
gst_pad_set_query_function (*outpad, gst_mpeg_parse_handle_src_query);
|
||||
|
||||
gst_element_add_pad(GST_ELEMENT(mpeg_demux), *outpad);
|
||||
gst_pad_set_element_private (*outpad, *outstream);
|
||||
|
||||
if (mpeg_demux->index) {
|
||||
gst_index_get_writer_id (mpeg_demux->index, GST_OBJECT (*outpad),
|
||||
|
@ -911,6 +919,78 @@ gst_mpeg_demux_parse_pes (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
index_seek (GstPad *pad, GstEvent *event, gint64 *offset)
|
||||
{
|
||||
GstIndexEntry *entry;
|
||||
GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad));
|
||||
GstMPEGStream *stream = gst_pad_get_element_private (pad);
|
||||
|
||||
entry = gst_index_get_assoc_entry (mpeg_demux->index, stream->index_id,
|
||||
GST_INDEX_LOOKUP_BEFORE, 0,
|
||||
GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event));
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
if (gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, offset)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
normal_seek (GstPad *pad, GstEvent *event, gint64 *offset)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
gint64 adjust;
|
||||
GstFormat format;
|
||||
GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad));
|
||||
|
||||
format = GST_EVENT_SEEK_FORMAT (event);
|
||||
|
||||
res = gst_pad_convert (pad, GST_FORMAT_BYTES, mpeg_demux->total_size_bound,
|
||||
&format, &adjust);
|
||||
|
||||
GST_DEBUG (0, "seek adjusted from %lld bytes to %lld\n", mpeg_demux->total_size_bound, adjust);
|
||||
|
||||
if (res)
|
||||
*offset = MAX (GST_EVENT_SEEK_OFFSET (event) - adjust, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_mpeg_demux_handle_src_event (GstPad *pad, GstEvent *event)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstMPEGDemux *mpeg_demux = GST_MPEG_DEMUX (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:
|
||||
{
|
||||
guint64 desired_offset;
|
||||
|
||||
if (mpeg_demux->index)
|
||||
res = index_seek (pad, event, &desired_offset);
|
||||
if (!res)
|
||||
res = normal_seek (pad, event, &desired_offset);
|
||||
|
||||
if (res) {
|
||||
GstEvent *new_event;
|
||||
|
||||
new_event = gst_event_new_seek (GST_EVENT_SEEK_TYPE (event), desired_offset);
|
||||
gst_event_unref (event);
|
||||
res = gst_mpeg_parse_handle_src_event (pad, new_event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static GstElementStateReturn
|
||||
gst_mpeg_demux_change_state (GstElement *element)
|
||||
{
|
||||
|
|
|
@ -54,24 +54,26 @@ struct _GstMPEGStream {
|
|||
GstPad *pad;
|
||||
guint64 pts;
|
||||
gint index_id;
|
||||
gint size_bound;
|
||||
};
|
||||
|
||||
struct _GstMPEGDemux {
|
||||
GstMPEGParse parent;
|
||||
GstMPEGParse parent;
|
||||
|
||||
/* previous partial chunk and bytes remaining in it */
|
||||
gboolean in_flush;
|
||||
gboolean in_flush;
|
||||
|
||||
/* program stream header values */
|
||||
guint16 header_length;
|
||||
guint32 rate_bound;
|
||||
guint8 audio_bound;
|
||||
gboolean fixed;
|
||||
gboolean constrained;
|
||||
gboolean audio_lock;
|
||||
gboolean video_lock;
|
||||
guint8 video_bound;
|
||||
gboolean packet_rate_restriction;
|
||||
guint16 header_length;
|
||||
guint32 rate_bound;
|
||||
guint8 audio_bound;
|
||||
gboolean fixed;
|
||||
gboolean constrained;
|
||||
gboolean audio_lock;
|
||||
gboolean video_lock;
|
||||
guint8 video_bound;
|
||||
gboolean packet_rate_restriction;
|
||||
gint64 total_size_bound;
|
||||
|
||||
#define NUM_PRIVATE_1_STREAMS 8
|
||||
#define NUM_SUBTITLE_STREAMS 16
|
||||
|
|
|
@ -250,8 +250,6 @@ gst_mpeg_packetize_read (GstMPEGPacketize *packetize)
|
|||
gst_bytestream_get_status (packetize->bs, &remaining, &event);
|
||||
etype = event? GST_EVENT_TYPE (event) : GST_EVENT_EOS;
|
||||
|
||||
g_print ("remaining %d\n", remaining);
|
||||
|
||||
switch (etype) {
|
||||
case GST_EVENT_DISCONTINUOUS:
|
||||
GST_DEBUG (GST_CAT_EVENT, "packetize: discont\n");
|
||||
|
|
|
@ -159,7 +159,6 @@ gst_mpeg_parse_class_init (GstMPEGParseClass *klass)
|
|||
gstelement_class->get_index = gst_mpeg_parse_get_index;
|
||||
gstelement_class->set_index = gst_mpeg_parse_set_index;
|
||||
|
||||
|
||||
klass->parse_packhead = gst_mpeg_parse_parse_packhead;
|
||||
klass->parse_syshead = NULL;
|
||||
klass->parse_packet = NULL;
|
||||
|
@ -174,11 +173,14 @@ gst_mpeg_parse_init (GstMPEGParse *mpeg_parse)
|
|||
mpeg_parse->sinkpad = gst_pad_new_from_template(
|
||||
GST_PAD_TEMPLATE_GET (sink_factory), "sink");
|
||||
gst_element_add_pad(GST_ELEMENT(mpeg_parse),mpeg_parse->sinkpad);
|
||||
gst_pad_set_formats_function (mpeg_parse->sinkpad, gst_mpeg_parse_get_src_formats);
|
||||
gst_pad_set_convert_function (mpeg_parse->sinkpad, gst_mpeg_parse_convert_src);
|
||||
|
||||
mpeg_parse->srcpad = gst_pad_new_from_template(
|
||||
GST_PAD_TEMPLATE_GET (src_factory), "src");
|
||||
gst_element_add_pad(GST_ELEMENT(mpeg_parse),mpeg_parse->srcpad);
|
||||
gst_pad_set_formats_function (mpeg_parse->srcpad, gst_mpeg_parse_get_src_formats);
|
||||
gst_pad_set_convert_function (mpeg_parse->srcpad, gst_mpeg_parse_convert_src);
|
||||
gst_pad_set_event_mask_function (mpeg_parse->srcpad, gst_mpeg_parse_get_src_event_masks);
|
||||
gst_pad_set_event_function (mpeg_parse->srcpad, gst_mpeg_parse_handle_src_event);
|
||||
gst_pad_set_query_type_function (mpeg_parse->srcpad, gst_mpeg_parse_get_src_query_types);
|
||||
|
@ -186,17 +188,8 @@ gst_mpeg_parse_init (GstMPEGParse *mpeg_parse)
|
|||
|
||||
gst_element_set_loop_function (GST_ELEMENT (mpeg_parse), gst_mpeg_parse_loop);
|
||||
|
||||
/* initialize parser state */
|
||||
mpeg_parse->packetize = NULL;
|
||||
mpeg_parse->current_scr = 0;
|
||||
mpeg_parse->bytes_since_scr = 0;
|
||||
mpeg_parse->adjust = 0;
|
||||
mpeg_parse->sync = FALSE;
|
||||
|
||||
/* zero counters (should be done at RUNNING?) */
|
||||
mpeg_parse->mux_rate = 0;
|
||||
mpeg_parse->discont_pending = FALSE;
|
||||
mpeg_parse->scr_pending = TRUE;
|
||||
mpeg_parse->max_discont = DEFAULT_MAX_DISCONT;
|
||||
mpeg_parse->provided_clock = gst_mpeg_clock_new ("MPEGParseClock",
|
||||
gst_mpeg_parse_get_time, mpeg_parse);
|
||||
|
@ -207,9 +200,9 @@ gst_mpeg_parse_init (GstMPEGParse *mpeg_parse)
|
|||
static GstClock*
|
||||
gst_mpeg_parse_get_clock (GstElement *element)
|
||||
{
|
||||
//GstMPEGParse *parse = GST_MPEG_PARSE (element);
|
||||
/* GstMPEGParse *parse = GST_MPEG_PARSE (element); */
|
||||
|
||||
//return parse->provided_clock;
|
||||
/* return parse->provided_clock; */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -329,6 +322,10 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
mpeg_parse->bytes_since_scr = 0;
|
||||
scr_adj = scr + mpeg_parse->adjust;
|
||||
|
||||
if (mpeg_parse->next_scr == -1) {
|
||||
mpeg_parse->next_scr = scr;
|
||||
}
|
||||
|
||||
GST_DEBUG (0, "SCR is %llu (%llu) next: %lld (%lld) diff: %lld (%lld)",
|
||||
scr,
|
||||
MPEGTIME_TO_GSTTIME (scr),
|
||||
|
@ -356,8 +353,7 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
gst_index_add_association (mpeg_parse->index, mpeg_parse->index_id,
|
||||
GST_ACCOCIATION_FLAG_KEY_UNIT,
|
||||
GST_FORMAT_BYTES, GST_BUFFER_OFFSET (buffer),
|
||||
GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (scr),
|
||||
scr_format, scr_orig, 0);
|
||||
GST_FORMAT_TIME, MPEGTIME_TO_GSTTIME (scr), 0);
|
||||
}
|
||||
|
||||
mpeg_parse->current_scr = scr;
|
||||
|
@ -367,10 +363,9 @@ gst_mpeg_parse_parse_packhead (GstMPEGParse *mpeg_parse, GstBuffer *buffer)
|
|||
mpeg_parse->mux_rate = new_rate;
|
||||
|
||||
g_object_notify (G_OBJECT (mpeg_parse), "bitrate");
|
||||
GST_DEBUG (0, "stream is %1.3fMbs", (mpeg_parse->mux_rate * 400) / 1000000.0);
|
||||
}
|
||||
|
||||
GST_DEBUG (0, "stream is %1.3fMbs", (mpeg_parse->mux_rate * 400) / 1000000.0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -433,7 +428,6 @@ gst_mpeg_parse_loop (GstElement *element)
|
|||
GST_DEBUG (GST_CAT_EVENT, "event: %d\n", GST_EVENT_TYPE (data));
|
||||
|
||||
mpeg_parse->discont_pending = TRUE;
|
||||
mpeg_parse->scr_pending = TRUE;
|
||||
mpeg_parse->packetize->resync = TRUE;
|
||||
gst_event_unref (event);
|
||||
return;
|
||||
|
@ -478,6 +472,7 @@ gst_mpeg_parse_loop (GstElement *element)
|
|||
gst_element_clock_wait (GST_ELEMENT (mpeg_parse), mpeg_parse->clock, time, NULL);
|
||||
}
|
||||
|
||||
if (mpeg_parse->current_scr != -1)
|
||||
{
|
||||
guint64 scr, bss, br;
|
||||
|
||||
|
@ -521,6 +516,46 @@ gst_mpeg_parse_get_src_formats (GstPad *pad)
|
|||
return formats;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_mpeg_parse_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||
GstFormat *dest_format, gint64 *dest_value)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad));
|
||||
|
||||
switch (src_format) {
|
||||
case GST_FORMAT_BYTES:
|
||||
switch (*dest_format) {
|
||||
case GST_FORMAT_DEFAULT:
|
||||
*dest_format = GST_FORMAT_TIME;
|
||||
case GST_FORMAT_TIME:
|
||||
if (mpeg_parse->mux_rate == 0)
|
||||
res = FALSE;
|
||||
else
|
||||
*dest_value = src_value * GST_SECOND / (mpeg_parse->mux_rate * 50);
|
||||
break;
|
||||
default:
|
||||
res = FALSE;
|
||||
}
|
||||
break;
|
||||
case GST_FORMAT_TIME:
|
||||
switch (*dest_format) {
|
||||
case GST_FORMAT_DEFAULT:
|
||||
*dest_format = GST_FORMAT_BYTES;
|
||||
case GST_FORMAT_BYTES:
|
||||
*dest_value = mpeg_parse->mux_rate * 50 * src_value / GST_SECOND;
|
||||
break;
|
||||
default:
|
||||
res = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const GstPadQueryType*
|
||||
gst_mpeg_parse_get_src_query_types (GstPad *pad)
|
||||
{
|
||||
|
@ -538,6 +573,8 @@ gst_mpeg_parse_handle_src_query (GstPad *pad, GstPadQueryType type,
|
|||
{
|
||||
gboolean res = TRUE;
|
||||
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad));
|
||||
GstFormat src_format;
|
||||
gint64 src_value;
|
||||
|
||||
switch (type) {
|
||||
case GST_PAD_QUERY_TOTAL:
|
||||
|
@ -546,27 +583,13 @@ gst_mpeg_parse_handle_src_query (GstPad *pad, GstPadQueryType type,
|
|||
case GST_FORMAT_DEFAULT:
|
||||
*format = GST_FORMAT_TIME;
|
||||
/* fallthrough */
|
||||
case GST_FORMAT_TIME:
|
||||
{
|
||||
GstFormat peer_format;
|
||||
gint64 peer_value;
|
||||
|
||||
if (mpeg_parse->mux_rate == 0)
|
||||
return FALSE;
|
||||
|
||||
peer_format = GST_FORMAT_BYTES;
|
||||
if (gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
|
||||
GST_PAD_QUERY_TOTAL, &peer_format, &peer_value))
|
||||
{
|
||||
/* multiply bywith 8 because vbr is in bits/second */
|
||||
*value = peer_value * GST_SECOND / (mpeg_parse->mux_rate * 50);
|
||||
}
|
||||
else
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = FALSE;
|
||||
src_format = GST_FORMAT_BYTES;
|
||||
if (!gst_pad_query (GST_PAD_PEER (mpeg_parse->sinkpad),
|
||||
GST_PAD_QUERY_TOTAL, &src_format, &src_value))
|
||||
{
|
||||
res = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -577,11 +600,9 @@ gst_mpeg_parse_handle_src_query (GstPad *pad, GstPadQueryType type,
|
|||
case GST_FORMAT_DEFAULT:
|
||||
*format = GST_FORMAT_TIME;
|
||||
/* fallthrough */
|
||||
case GST_FORMAT_TIME:
|
||||
*value = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr);
|
||||
break;
|
||||
default:
|
||||
res = FALSE;
|
||||
src_format = GST_FORMAT_TIME;
|
||||
src_value = MPEGTIME_TO_GSTTIME (mpeg_parse->current_scr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -591,6 +612,10 @@ gst_mpeg_parse_handle_src_query (GstPad *pad, GstPadQueryType type,
|
|||
break;
|
||||
}
|
||||
|
||||
/* bring to requested format */
|
||||
if (res)
|
||||
res = gst_pad_convert (pad, src_format, src_value, format, value);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -605,23 +630,57 @@ gst_mpeg_parse_get_src_event_masks (GstPad *pad)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
seek_index (GstMPEGParse *parse, GstEvent *event, guint64 *offset)
|
||||
index_seek (GstPad *pad, GstEvent *event, guint64 *offset, gint64 *scr)
|
||||
{
|
||||
GstIndexEntry *entry;
|
||||
GstMPEGParse *mpeg_parse = GST_MPEG_PARSE (gst_pad_get_parent (pad));
|
||||
|
||||
entry = gst_index_get_assoc_entry (parse->index, parse->index_id,
|
||||
GST_INDEX_LOOKUP_BEFORE,
|
||||
entry = gst_index_get_assoc_entry (mpeg_parse->index, mpeg_parse->index_id,
|
||||
GST_INDEX_LOOKUP_BEFORE, 0,
|
||||
GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event));
|
||||
if (!entry)
|
||||
return FALSE;
|
||||
|
||||
if (gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, offset)) {
|
||||
gint64 time;
|
||||
|
||||
if (gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time)) {
|
||||
*scr = GSTTIME_TO_MPEGTIME (time);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
normal_seek (GstPad *pad, GstEvent *event, guint64 *offset, gint64 *scr)
|
||||
{
|
||||
gboolean res;
|
||||
GstFormat format;
|
||||
gint64 time;
|
||||
|
||||
/* bring offset to bytes */
|
||||
format = GST_FORMAT_BYTES;
|
||||
res = gst_pad_convert (pad,
|
||||
GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event),
|
||||
&format,
|
||||
offset);
|
||||
/* bring offset to time */
|
||||
format = GST_FORMAT_TIME;
|
||||
res &= gst_pad_convert (pad,
|
||||
GST_EVENT_SEEK_FORMAT (event),
|
||||
GST_EVENT_SEEK_OFFSET (event),
|
||||
&format,
|
||||
&time);
|
||||
|
||||
/* convert to scr */
|
||||
*scr = GSTTIME_TO_MPEGTIME (time);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_mpeg_parse_handle_src_event (GstPad *pad, GstEvent *event)
|
||||
{
|
||||
|
@ -632,37 +691,32 @@ gst_mpeg_parse_handle_src_event (GstPad *pad, GstEvent *event)
|
|||
case GST_EVENT_SEEK:
|
||||
{
|
||||
guint64 desired_offset;
|
||||
guint64 expected_scr;
|
||||
|
||||
switch (GST_EVENT_SEEK_FORMAT (event)) {
|
||||
case GST_FORMAT_BYTES:
|
||||
if (mpeg_parse->index) {
|
||||
if (!seek_index (mpeg_parse, event, &desired_offset)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
desired_offset = GST_EVENT_SEEK_OFFSET (event);
|
||||
}
|
||||
break;
|
||||
case GST_FORMAT_TIME:
|
||||
desired_offset = mpeg_parse->mux_rate * 50 * GST_EVENT_SEEK_OFFSET (event) / (GST_SECOND);
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
/* first to to use the index if we have one */
|
||||
if (mpeg_parse->index)
|
||||
res = index_seek (pad, event, &desired_offset, &expected_scr);
|
||||
/* nothing found, try fuzzy seek */
|
||||
if (!res)
|
||||
res = normal_seek (pad, event, &desired_offset, &expected_scr);
|
||||
|
||||
if (!gst_bytestream_seek (mpeg_parse->packetize->bs, desired_offset, GST_SEEK_METHOD_SET)) {
|
||||
goto done;
|
||||
if (!res)
|
||||
break;
|
||||
|
||||
GST_DEBUG (0, "sending seek to %lld", desired_offset);
|
||||
if (gst_bytestream_seek (mpeg_parse->packetize->bs, desired_offset, GST_SEEK_METHOD_SET)) {
|
||||
mpeg_parse->discont_pending = TRUE;
|
||||
mpeg_parse->scr_pending = TRUE;
|
||||
mpeg_parse->next_scr = expected_scr;
|
||||
mpeg_parse->current_scr = -1;
|
||||
mpeg_parse->adjust = 0;
|
||||
res = TRUE;
|
||||
}
|
||||
mpeg_parse->discont_pending = TRUE;
|
||||
mpeg_parse->scr_pending = TRUE;
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
done:
|
||||
gst_event_unref (event);
|
||||
return res;
|
||||
}
|
||||
|
@ -677,6 +731,16 @@ gst_mpeg_parse_change_state (GstElement *element)
|
|||
if (!mpeg_parse->packetize) {
|
||||
mpeg_parse->packetize = gst_mpeg_packetize_new (mpeg_parse->sinkpad, GST_MPEG_PACKETIZE_SYSTEM);
|
||||
}
|
||||
/* initialize parser state */
|
||||
mpeg_parse->current_scr = 0;
|
||||
mpeg_parse->bytes_since_scr = 0;
|
||||
mpeg_parse->adjust = 0;
|
||||
mpeg_parse->next_scr = 0;
|
||||
|
||||
/* zero counters (should be done at RUNNING?) */
|
||||
mpeg_parse->mux_rate = 0;
|
||||
mpeg_parse->discont_pending = FALSE;
|
||||
mpeg_parse->scr_pending = FALSE;
|
||||
break;
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
if (mpeg_parse->packetize) {
|
||||
|
@ -696,7 +760,6 @@ gst_mpeg_parse_get_property (GObject *object, guint prop_id, GValue *value, GPar
|
|||
{
|
||||
GstMPEGParse *mpeg_parse;
|
||||
|
||||
/* it's not null if we got it, but it might not be ours */
|
||||
mpeg_parse = GST_MPEG_PARSE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
|
|
|
@ -44,6 +44,7 @@ extern "C" {
|
|||
#define GST_MPEG_PARSE_IS_MPEG2(parse) (GST_MPEG_PACKETIZE_IS_MPEG2 (GST_MPEG_PARSE (parse)->packetize))
|
||||
|
||||
#define MPEGTIME_TO_GSTTIME(time) (((time) * (GST_MSECOND/10)) / 9LL)
|
||||
#define GSTTIME_TO_MPEGTIME(time) (((time) * 9) / (GST_MSECOND/10))
|
||||
|
||||
typedef struct _GstMPEGParse GstMPEGParse;
|
||||
typedef struct _GstMPEGParseClass GstMPEGParseClass;
|
||||
|
@ -96,6 +97,8 @@ gboolean gst_mpeg_parse_plugin_init (GModule *module, GstPlugin *plugin);
|
|||
const GstFormat*
|
||||
gst_mpeg_parse_get_src_formats (GstPad *pad);
|
||||
|
||||
gboolean gst_mpeg_parse_convert_src (GstPad *pad, GstFormat src_format, gint64 src_value,
|
||||
GstFormat *dest_format, gint64 *dest_value);
|
||||
const GstEventMask*
|
||||
gst_mpeg_parse_get_src_event_masks (GstPad *pad);
|
||||
gboolean gst_mpeg_parse_handle_src_event (GstPad *pad, GstEvent *event);
|
||||
|
|
Loading…
Reference in a new issue