mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-02 21:48:55 +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>
|
||||
|
||||
* 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",
|
||||
"Erik Walthinsen <omega@cse.ogi.edu>\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);
|
||||
GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
|
||||
GstCaps *audcaps, *vidcaps, *subcaps;
|
||||
|
@ -1693,7 +1694,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi,
|
|||
stream->total_frames++;
|
||||
stream->idx_duration = next_ts;
|
||||
|
||||
GST_DEBUG_OBJECT (avi,
|
||||
GST_LOG_OBJECT (avi,
|
||||
"Adding index entry %d (%6u), flags %02x, stream %d, size %u "
|
||||
", offset %" G_GUINT64_FORMAT ", time %" GST_TIME_FORMAT ", dur %"
|
||||
GST_TIME_FORMAT,
|
||||
|
@ -2403,7 +2404,7 @@ gst_avi_demux_massage_index (GstAviDemux * avi,
|
|||
num_per_stream[entry->stream_nr]++;
|
||||
#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
|
||||
" dur %" GST_TIME_FORMAT,
|
||||
avi->index_entries[i].index_nr, entry->stream_nr, entry->size,
|
||||
|
@ -3447,6 +3448,38 @@ done:
|
|||
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
|
||||
*/
|
||||
|
@ -3458,7 +3491,6 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
|||
avi_stream_context *stream;
|
||||
gst_avi_index_entry *entry;
|
||||
GstBuffer *buf;
|
||||
gint i;
|
||||
|
||||
do {
|
||||
/* 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)
|
||||
goto eos_reverse_segment;
|
||||
|
||||
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);
|
||||
if (!(entry = gst_avi_demux_step_reverse (avi)))
|
||||
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++;
|
||||
}
|
||||
|
||||
|
@ -3574,15 +3591,34 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
|||
|
||||
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
|
||||
* leave the while loop and return the GstFlowReturn */
|
||||
processed = TRUE;
|
||||
GST_DEBUG_OBJECT (avi, "Processed buffer %d: %s", entry->index_nr,
|
||||
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:
|
||||
stream->current_frame = entry->frames_before + 1;
|
||||
stream->current_byte = entry->bytes_before + entry->size;
|
||||
|
|
Loading…
Reference in a new issue