mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-17 22:06:41 +00:00
gst/avi/gstavidemux.*: Proper aggregation of each stream's GstFlowReturn in order to figure out whether the task shou...
Original commit message from CVS: * gst/avi/gstavidemux.c: (gst_avi_demux_reset), (gst_avi_demux_read_subindexes), (gst_avi_demux_parse_stream), (gst_avi_demux_handle_seek), (gst_avi_demux_aggregated_flow), (gst_avi_demux_process_next_entry), (push_tag_lists), (gst_avi_demux_stream_data), (gst_avi_demux_loop): * gst/avi/gstavidemux.h: Proper aggregation of each stream's GstFlowReturn in order to figure out whether the task should stop or not. Don't send inline events before pushing out a NEW_SEGMENT, more specifically for GST_TAG_EVENT. Change a GST_ERROR to a GST_WARNING for a non-fatal situation in reading sub-indexes.
This commit is contained in:
parent
48197ea826
commit
663856a514
4 changed files with 102 additions and 33 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2006-07-03 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* gst/avi/gstavidemux.c: (gst_avi_demux_reset),
|
||||||
|
(gst_avi_demux_read_subindexes), (gst_avi_demux_parse_stream),
|
||||||
|
(gst_avi_demux_handle_seek), (gst_avi_demux_aggregated_flow),
|
||||||
|
(gst_avi_demux_process_next_entry), (push_tag_lists),
|
||||||
|
(gst_avi_demux_stream_data), (gst_avi_demux_loop):
|
||||||
|
* gst/avi/gstavidemux.h:
|
||||||
|
Proper aggregation of each stream's GstFlowReturn in order to figure out
|
||||||
|
whether the task should stop or not.
|
||||||
|
Don't send inline events before pushing out a NEW_SEGMENT, more
|
||||||
|
specifically for GST_TAG_EVENT.
|
||||||
|
Change a GST_ERROR to a GST_WARNING for a non-fatal situation in reading
|
||||||
|
sub-indexes.
|
||||||
|
|
||||||
2006-06-30 Tim-Philipp Müller <tim at centricular dot net>
|
2006-06-30 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
Patch by: Brian Cameron <brian dot cameron at sun dot com>
|
Patch by: Brian Cameron <brian dot cameron at sun dot com>
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 123195d3bbcc0b6e1cf867d3a180685f8766a0be
|
Subproject commit dd173e2720ac21e4a47c97705d7ff32271a0ee66
|
|
@ -206,6 +206,10 @@ gst_avi_demux_reset (GstAviDemux * avi)
|
||||||
gst_buffer_unref (avi->stream[i].extradata);
|
gst_buffer_unref (avi->stream[i].extradata);
|
||||||
if (avi->stream[i].pad)
|
if (avi->stream[i].pad)
|
||||||
gst_element_remove_pad (GST_ELEMENT (avi), avi->stream[i].pad);
|
gst_element_remove_pad (GST_ELEMENT (avi), avi->stream[i].pad);
|
||||||
|
if (avi->stream[i].taglist) {
|
||||||
|
gst_tag_list_free (avi->stream[i].taglist);
|
||||||
|
avi->stream[i].taglist = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
memset (&avi->stream, 0, sizeof (avi->stream));
|
memset (&avi->stream, 0, sizeof (avi->stream));
|
||||||
|
|
||||||
|
@ -228,6 +232,8 @@ gst_avi_demux_reset (GstAviDemux * avi)
|
||||||
gst_event_unref (avi->seek_event);
|
gst_event_unref (avi->seek_event);
|
||||||
avi->seek_event = NULL;
|
avi->seek_event = NULL;
|
||||||
|
|
||||||
|
avi->got_tags = FALSE;
|
||||||
|
|
||||||
gst_segment_init (&avi->segment, GST_FORMAT_TIME);
|
gst_segment_init (&avi->segment, GST_FORMAT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,7 +974,7 @@ gst_avi_demux_read_subindexes (GstAviDemux * avi,
|
||||||
continue;
|
continue;
|
||||||
else if (tag != GST_MAKE_FOURCC ('i', 'x', '0' + stream->num / 10,
|
else if (tag != GST_MAKE_FOURCC ('i', 'x', '0' + stream->num / 10,
|
||||||
'0' + stream->num % 10)) {
|
'0' + stream->num % 10)) {
|
||||||
GST_ERROR_OBJECT (GST_ELEMENT (avi),
|
GST_WARNING_OBJECT (GST_ELEMENT (avi),
|
||||||
"Not an ix## chunk (%" GST_FOURCC_FORMAT ")",
|
"Not an ix## chunk (%" GST_FOURCC_FORMAT ")",
|
||||||
GST_FOURCC_ARGS (tag));
|
GST_FOURCC_ARGS (tag));
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
@ -1202,11 +1208,13 @@ gst_avi_demux_parse_stream (GstElement * element, GstBuffer * buf)
|
||||||
GST_PAD_NAME (pad), caps);
|
GST_PAD_NAME (pad), caps);
|
||||||
|
|
||||||
if (codec_name) {
|
if (codec_name) {
|
||||||
GstTagList *list = gst_tag_list_new ();
|
if (!stream->taglist)
|
||||||
|
stream->taglist = gst_tag_list_new ();
|
||||||
|
|
||||||
gst_tag_list_add (list, GST_TAG_MERGE_APPEND, tag_name, codec_name, NULL);
|
avi->got_tags = TRUE;
|
||||||
gst_element_found_tags_for_pad (GST_ELEMENT (avi), pad, list);
|
|
||||||
g_free (codec_name);
|
gst_tag_list_add (stream->taglist, GST_TAG_MERGE_APPEND, tag_name,
|
||||||
|
codec_name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -2342,6 +2350,7 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, gboolean update)
|
||||||
GstClockTime start_time;
|
GstClockTime start_time;
|
||||||
gboolean flush, keyframe;
|
gboolean flush, keyframe;
|
||||||
gst_avi_index_entry *entry;
|
gst_avi_index_entry *entry;
|
||||||
|
guint i;
|
||||||
|
|
||||||
/* FIXME: if we seek in an openDML file, we will have multiple
|
/* FIXME: if we seek in an openDML file, we will have multiple
|
||||||
* primary levels. Seeking in between those will cause havoc. */
|
* primary levels. Seeking in between those will cause havoc. */
|
||||||
|
@ -2393,6 +2402,9 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, gboolean update)
|
||||||
if (flush) {
|
if (flush) {
|
||||||
gst_avi_demux_push_event (avi, gst_event_new_flush_stop ());
|
gst_avi_demux_push_event (avi, gst_event_new_flush_stop ());
|
||||||
gst_pad_push_event (avi->sinkpad, gst_event_new_flush_stop ());
|
gst_pad_push_event (avi->sinkpad, gst_event_new_flush_stop ());
|
||||||
|
for (i = 0; i < avi->num_streams; i++) {
|
||||||
|
avi->stream[i].last_flow = GST_FLOW_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
|
||||||
|
@ -2458,26 +2470,40 @@ gst_avi_demux_invert (avi_stream_context * stream, GstBuffer * buf)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
/*
|
||||||
gst_avi_demux_all_source_pads_unlinked (GstAviDemux * avi)
|
Returns the aggregated GstFlowReturn.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_avi_demux_aggregated_flow (GstAviDemux * avi)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
|
gboolean haveok = FALSE;
|
||||||
|
|
||||||
for (i = 0; i < avi->num_streams; ++i) {
|
for (i = 0; i < avi->num_streams; i++) {
|
||||||
if (gst_pad_is_linked (avi->stream[i].pad))
|
GstFlowReturn last = avi->stream[i].last_flow;
|
||||||
return FALSE;
|
|
||||||
/* ignore unlinked state if we haven't tried to push on this pad yet */
|
GST_LOG_OBJECT (avi, "stream %d , flow : %s", i, gst_flow_get_name (last));
|
||||||
if (avi->stream[i].last_flow == GST_FLOW_OK)
|
if (last == GST_FLOW_OK)
|
||||||
return FALSE;
|
haveok = TRUE;
|
||||||
|
else if (last < res) {
|
||||||
|
res = last;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
if (!GST_FLOW_IS_FATAL (res) && res != GST_FLOW_WRONG_STATE && haveok)
|
||||||
|
res = GST_FLOW_OK;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (avi, "Returning aggregated value of %s",
|
||||||
|
gst_flow_get_name (res));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
{
|
{
|
||||||
GstFlowReturn res;
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
gboolean processed = FALSE;
|
gboolean processed = FALSE;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -2485,6 +2511,7 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
if (avi->current_entry >= avi->index_size) {
|
if (avi->current_entry >= avi->index_size) {
|
||||||
GST_LOG_OBJECT (avi, "Handled last index entry, setting EOS (%d > %d)",
|
GST_LOG_OBJECT (avi, "Handled last index entry, setting EOS (%d > %d)",
|
||||||
avi->current_entry, avi->index_size);
|
avi->current_entry, avi->index_size);
|
||||||
|
avi->stream[0].last_flow = GST_FLOW_UNEXPECTED;
|
||||||
goto eos;
|
goto eos;
|
||||||
} else {
|
} else {
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
@ -2497,6 +2524,8 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream = &avi->stream[entry->stream_nr];
|
||||||
|
|
||||||
if ((entry->flags & GST_RIFF_IF_KEYFRAME)
|
if ((entry->flags & GST_RIFF_IF_KEYFRAME)
|
||||||
&& GST_CLOCK_TIME_IS_VALID (entry->ts)
|
&& GST_CLOCK_TIME_IS_VALID (entry->ts)
|
||||||
&& GST_CLOCK_TIME_IS_VALID (avi->segment.stop)
|
&& GST_CLOCK_TIME_IS_VALID (avi->segment.stop)
|
||||||
|
@ -2504,11 +2533,10 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
GST_LOG_OBJECT (avi, "Found keyframe after segment,"
|
GST_LOG_OBJECT (avi, "Found keyframe after segment,"
|
||||||
" setting EOS (%" GST_TIME_FORMAT " > %" GST_TIME_FORMAT ")",
|
" setting EOS (%" GST_TIME_FORMAT " > %" GST_TIME_FORMAT ")",
|
||||||
GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (avi->segment.stop));
|
GST_TIME_ARGS (entry->ts), GST_TIME_ARGS (avi->segment.stop));
|
||||||
goto eos;
|
res = stream->last_flow = GST_FLOW_UNEXPECTED;
|
||||||
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream = &avi->stream[entry->stream_nr];
|
|
||||||
|
|
||||||
if (entry->size == 0 || !stream->pad) {
|
if (entry->size == 0 || !stream->pad) {
|
||||||
GST_DEBUG_OBJECT (avi, "Skipping entry %d (%d, %p)",
|
GST_DEBUG_OBJECT (avi, "Skipping entry %d (%d, %p)",
|
||||||
avi->current_entry - 1, entry->size, stream->pad);
|
avi->current_entry - 1, entry->size, stream->pad);
|
||||||
|
@ -2517,14 +2545,16 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
|
|
||||||
if ((res = gst_pad_pull_range (avi->sinkpad, entry->offset +
|
if ((res = gst_pad_pull_range (avi->sinkpad, entry->offset +
|
||||||
avi->index_offset, entry->size, &buf)) != GST_FLOW_OK) {
|
avi->index_offset, entry->size, &buf)) != GST_FLOW_OK) {
|
||||||
return res;
|
stream->last_flow = res;
|
||||||
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (buf) < entry->size) {
|
if (GST_BUFFER_SIZE (buf) < entry->size) {
|
||||||
GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
|
GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
|
||||||
", only got %d/%d bytes (truncated file?)", entry->offset +
|
", only got %d/%d bytes (truncated file?)", entry->offset +
|
||||||
avi->index_offset, GST_BUFFER_SIZE (buf), entry->size);
|
avi->index_offset, GST_BUFFER_SIZE (buf), entry->size);
|
||||||
goto eos;
|
res = stream->last_flow = GST_FLOW_UNEXPECTED;
|
||||||
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
|
if (stream->strh->fcc_handler == GST_MAKE_FOURCC ('D', 'I', 'B', ' ')) {
|
||||||
|
@ -2545,7 +2575,7 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
if (res != GST_FLOW_OK && res != GST_FLOW_NOT_LINKED) {
|
if (res != GST_FLOW_OK && res != GST_FLOW_NOT_LINKED) {
|
||||||
GST_DEBUG_OBJECT (avi, "Flow on pad %s: %s",
|
GST_DEBUG_OBJECT (avi, "Flow on pad %s: %s",
|
||||||
GST_PAD_NAME (stream->pad), gst_flow_get_name (res));
|
GST_PAD_NAME (stream->pad), gst_flow_get_name (res));
|
||||||
return res;
|
goto beach;
|
||||||
}
|
}
|
||||||
processed = TRUE;
|
processed = TRUE;
|
||||||
|
|
||||||
|
@ -2555,7 +2585,9 @@ gst_avi_demux_process_next_entry (GstAviDemux * avi)
|
||||||
}
|
}
|
||||||
} while (!processed);
|
} while (!processed);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
beach:
|
||||||
|
GST_DEBUG_OBJECT (avi, "returning %s", gst_flow_get_name (res));
|
||||||
|
return res;
|
||||||
|
|
||||||
eos:
|
eos:
|
||||||
{
|
{
|
||||||
|
@ -2563,6 +2595,23 @@ eos:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
push_tag_lists (GstAviDemux * avi)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (!avi->got_tags)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < avi->num_streams; i++)
|
||||||
|
if (avi->stream[i].pad && avi->stream[i].taglist) {
|
||||||
|
gst_element_found_tags_for_pad (GST_ELEMENT (avi), avi->stream[i].pad,
|
||||||
|
avi->stream[i].taglist);
|
||||||
|
avi->stream[i].taglist = NULL;
|
||||||
|
}
|
||||||
|
avi->got_tags = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read data.
|
* Read data.
|
||||||
*/
|
*/
|
||||||
|
@ -2641,7 +2690,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
|
||||||
static void
|
static void
|
||||||
gst_avi_demux_loop (GstPad * pad)
|
gst_avi_demux_loop (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstFlowReturn res;
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
|
GstAviDemux *avi = GST_AVI_DEMUX (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
switch (avi->state) {
|
switch (avi->state) {
|
||||||
|
@ -2656,24 +2705,25 @@ gst_avi_demux_loop (GstPad * pad)
|
||||||
avi->state = GST_AVI_DEMUX_MOVI;
|
avi->state = GST_AVI_DEMUX_MOVI;
|
||||||
break;
|
break;
|
||||||
case GST_AVI_DEMUX_MOVI:
|
case GST_AVI_DEMUX_MOVI:
|
||||||
if (avi->seek_event) {
|
if (G_UNLIKELY (avi->seek_event)) {
|
||||||
gst_avi_demux_push_event (avi, avi->seek_event);
|
gst_avi_demux_push_event (avi, avi->seek_event);
|
||||||
avi->seek_event = NULL;
|
avi->seek_event = NULL;
|
||||||
}
|
}
|
||||||
if ((res = gst_avi_demux_stream_data (avi)) != GST_FLOW_OK) {
|
if (G_UNLIKELY (avi->got_tags))
|
||||||
GST_DEBUG_OBJECT (avi, "stream_data flow: %s", gst_flow_get_name (res));
|
push_tag_lists (avi);
|
||||||
goto pause;
|
res = gst_avi_demux_stream_data (avi);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_avi_demux_all_source_pads_unlinked (avi)) {
|
GST_DEBUG_OBJECT (avi, "res:%s", gst_flow_get_name (res));
|
||||||
GST_DEBUG_OBJECT (avi, "all source pads unlinked, pausing");
|
|
||||||
res = GST_FLOW_NOT_LINKED;
|
/* Get Aggregated flow return */
|
||||||
|
|
||||||
|
if ((res != GST_FLOW_OK)
|
||||||
|
&& ((res = gst_avi_demux_aggregated_flow (avi)) != GST_FLOW_OK))
|
||||||
goto pause;
|
goto pause;
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,8 @@ typedef struct {
|
||||||
GstClockTime idx_duration;
|
GstClockTime idx_duration;
|
||||||
|
|
||||||
guint64 *indexes;
|
guint64 *indexes;
|
||||||
|
|
||||||
|
GstTagList *taglist;
|
||||||
} avi_stream_context;
|
} avi_stream_context;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -127,6 +129,8 @@ typedef struct _GstAviDemux {
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
GstEvent *seek_event;
|
GstEvent *seek_event;
|
||||||
|
|
||||||
|
gboolean got_tags;
|
||||||
|
|
||||||
} GstAviDemux;
|
} GstAviDemux;
|
||||||
|
|
||||||
typedef struct _GstAviDemuxClass {
|
typedef struct _GstAviDemuxClass {
|
||||||
|
|
Loading…
Reference in a new issue