mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-05 06:58:49 +00:00
gst/avi/gstavidemux.c: Catch UNEXPECTED when downstream has reached end of segment in reverse mode.
Original commit message from CVS: * gst/avi/gstavidemux.c: Catch UNEXPECTED when downstream has reached end of segment in reverse mode.
This commit is contained in:
parent
8057839bdd
commit
61a15f8c5f
3 changed files with 67 additions and 25 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2008-06-05 Thijs Vermeir <thijsvermeir@gmail.com>
|
||||||
|
|
||||||
|
* gst/avi/gstavidemux.c:
|
||||||
|
Catch UNEXPECTED when downstream has reached end of
|
||||||
|
segment in reverse mode.
|
||||||
|
|
||||||
2008-06-04 Thijs Vermeir <thijsvermeir@gmail.com>
|
2008-06-04 Thijs Vermeir <thijsvermeir@gmail.com>
|
||||||
|
|
||||||
* gst/avi/gstavidemux.c:
|
* gst/avi/gstavidemux.c:
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 130fa8f739ff09aedb520c33239f53d06cfe9bd5
|
Subproject commit 68fb019d4044b9878aef4ca223fc13c19ffc7d0c
|
|
@ -140,7 +140,8 @@ gst_avi_demux_base_init (GstAviDemuxClass * klass)
|
||||||
"Demultiplex an avi file into audio and video",
|
"Demultiplex an avi file into audio and video",
|
||||||
"Erik Walthinsen <omega@cse.ogi.edu>\n"
|
"Erik Walthinsen <omega@cse.ogi.edu>\n"
|
||||||
"Wim Taymans <wim.taymans@chello.be>\n"
|
"Wim Taymans <wim.taymans@chello.be>\n"
|
||||||
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
|
"Ronald Bultje <rbultje@ronald.bitfreak.net>\n"
|
||||||
|
"Thijs Vermeir <thijsvermeir@gmail.com>");
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
|
GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
|
||||||
GstCaps *audcaps, *vidcaps, *subcaps;
|
GstCaps *audcaps, *vidcaps, *subcaps;
|
||||||
|
@ -1693,7 +1694,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
|
||||||
stream->total_frames++;
|
stream->total_frames++;
|
||||||
stream->idx_duration = next_ts;
|
stream->idx_duration = next_ts;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (avi,
|
GST_LOG_OBJECT (avi,
|
||||||
"Adding index entry %d (%6u), flags %02x, stream %d, size %u "
|
"Adding index entry %d (%6u), flags %02x, stream %d, size %u "
|
||||||
", offset %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT ", dur %"
|
", offset %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT ", dur %"
|
||||||
GST_TIME_FORMAT,
|
GST_TIME_FORMAT,
|
||||||
|
@ -2403,7 +2404,7 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
||||||
num_per_stream[entry->stream_nr]++;
|
num_per_stream[entry->stream_nr]++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_DEBUG ("Sorted index entry %3d for stream %d of size %6u"
|
GST_LOG_OBJECT (avi, "Sorted index entry %3d for stream %d of size %6u"
|
||||||
" at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
|
" at offset %7" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT
|
||||||
" dur %" GST_TIME_FORMAT,
|
" dur %" GST_TIME_FORMAT,
|
||||||
avi->index_entries[i].index_nr, entry->stream_nr, entry->size,
|
avi->index_entries[i].index_nr, entry->stream_nr, entry->size,
|
||||||
|
@ -3447,6 +3448,38 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare the avi element for a reverse jump to a prev keyframe
|
||||||
|
* this function will return the start entry. if the function returns
|
||||||
|
* NULL there was no prev keyframe.
|
||||||
|
*/
|
||||||
|
static gst_avi_index_entry *
|
||||||
|
gst_avi_demux_step_reverse (GstAviDemux * avi)
|
||||||
|
{
|
||||||
|
gst_avi_index_entry *entry;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
avi->reverse_stop_index = avi->reverse_start_index;
|
||||||
|
entry =
|
||||||
|
gst_avi_demux_index_prev (avi, 0, avi->reverse_stop_index,
|
||||||
|
GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME);
|
||||||
|
if (!entry) {
|
||||||
|
GST_DEBUG_OBJECT (avi, "no valid index entry found index %d",
|
||||||
|
avi->reverse_stop_index);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
avi->current_entry = avi->reverse_start_index = entry->index_nr;
|
||||||
|
GST_DEBUG_OBJECT (avi,
|
||||||
|
"reverse playback jump: start idx (%d) and stop idx (%d)",
|
||||||
|
avi->reverse_start_index, avi->reverse_stop_index);
|
||||||
|
gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, entry->ts);
|
||||||
|
for (i = 0; i < avi->num_streams; i++) {
|
||||||
|
avi->stream[i].last_flow = GST_FLOW_OK;
|
||||||
|
avi->stream[i].discont = TRUE;
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read data from one index entry
|
* Read data from one index entry
|
||||||
*/
|
*/
|
||||||
|
@ -3458,7 +3491,6 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
avi_stream_context *stream;
|
avi_stream_context *stream;
|
||||||
gst_avi_index_entry *entry;
|
gst_avi_index_entry *entry;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
gint i;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* see if we are at the end */
|
/* see if we are at the end */
|
||||||
|
@ -3478,24 +3510,9 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
if (avi->index_entries[avi->reverse_start_index].ts < avi->segment.start)
|
if (avi->index_entries[avi->reverse_start_index].ts < avi->segment.start)
|
||||||
goto eos_reverse_segment;
|
goto eos_reverse_segment;
|
||||||
|
|
||||||
avi->reverse_stop_index = avi->reverse_start_index;
|
if (!(entry = gst_avi_demux_step_reverse (avi)))
|
||||||
entry =
|
|
||||||
gst_avi_demux_index_prev (avi, 0, avi->reverse_stop_index,
|
|
||||||
GST_AVI_INDEX_ENTRY_FLAG_KEYFRAME);
|
|
||||||
if (!entry) {
|
|
||||||
GST_DEBUG_OBJECT (avi, "no valid index entry found index %d",
|
|
||||||
avi->reverse_stop_index);
|
|
||||||
goto eos;
|
goto eos;
|
||||||
}
|
|
||||||
avi->current_entry = avi->reverse_start_index = entry->index_nr;
|
|
||||||
GST_DEBUG_OBJECT (avi,
|
|
||||||
"reverse playback jump: start idx (%d) and stop idx (%d)",
|
|
||||||
avi->reverse_start_index, avi->reverse_stop_index);
|
|
||||||
gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, entry->ts);
|
|
||||||
for (i = 0; i < avi->num_streams; i++) {
|
|
||||||
avi->stream[i].last_flow = GST_FLOW_OK;
|
|
||||||
avi->stream[i].discont = TRUE;
|
|
||||||
}
|
|
||||||
avi->current_entry++;
|
avi->current_entry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3574,15 +3591,34 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
|
|
||||||
res = gst_pad_push (stream->pad, buf);
|
res = gst_pad_push (stream->pad, buf);
|
||||||
|
|
||||||
/* combine flows */
|
|
||||||
res = gst_avi_demux_combine_flows (avi, stream, res);
|
|
||||||
|
|
||||||
/* mark as processed, we increment the frame and byte counters then
|
/* mark as processed, we increment the frame and byte counters then
|
||||||
* leave the while loop and return the GstFlowReturn */
|
* leave the while loop and return the GstFlowReturn */
|
||||||
processed = TRUE;
|
processed = TRUE;
|
||||||
GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", entry->index_nr,
|
GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", entry->index_nr,
|
||||||
gst_flow_get_name (res));
|
gst_flow_get_name (res));
|
||||||
|
|
||||||
|
if (avi->segment.rate < 0
|
||||||
|
&& entry->ts > avi->segment.stop && res == GST_FLOW_UNEXPECTED) {
|
||||||
|
/* In reverse playback we can get a GST_FLOW_UNEXPECTED when
|
||||||
|
* we are at the end of the segment, so we just need to jump
|
||||||
|
* back to the previous section.
|
||||||
|
*/
|
||||||
|
GST_DEBUG_OBJECT (avi, "downstream has reached end of segment");
|
||||||
|
|
||||||
|
if (!(entry = gst_avi_demux_step_reverse (avi)))
|
||||||
|
goto eos;
|
||||||
|
|
||||||
|
res = GST_FLOW_OK;
|
||||||
|
|
||||||
|
stream->current_frame = entry->frames_before;
|
||||||
|
stream->current_byte = entry->bytes_before;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* combine flows */
|
||||||
|
res = gst_avi_demux_combine_flows (avi, stream, res);
|
||||||
|
|
||||||
next:
|
next:
|
||||||
stream->current_frame = entry->frames_before + 1;
|
stream->current_frame = entry->frames_before + 1;
|
||||||
stream->current_byte = entry->bytes_before + entry->size;
|
stream->current_byte = entry->bytes_before + entry->size;
|
||||||
|
|
Loading…
Reference in a new issue