* compressed audio or video data, this will only work if you have the
* right decoder elements/plugins installed.
* </refsect2>
- *
- * Last reviewed on 2006-12-29 (0.10.6)
*/
#ifdef HAVE_CONFIG_H
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GObjectClass *gobject_class = (GObjectClass *) klass;
GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl, *subpicsrctempl;
- GstCaps *audcaps, *vidcaps, *subcaps, *subpiccaps;;
+ GstCaps *audcaps, *vidcaps, *subcaps, *subpiccaps;
GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
0, "Demuxer for AVI streams");
"Erik Walthinsen <omega@cse.ogi.edu>, "
"Wim Taymans <wim.taymans@chello.be>, "
"Thijs Vermeir <thijsvermeir@gmail.com>");
+
+ gst_caps_unref(audcaps);
+ gst_caps_unref(vidcaps);
+ gst_caps_unref(subcaps);
+ gst_caps_unref(subpiccaps);
}
static void
gst_element_add_pad (GST_ELEMENT_CAST (avi), avi->sinkpad);
avi->adapter = gst_adapter_new ();
+ avi->flowcombiner = gst_flow_combiner_new ();
gst_avi_demux_reset (avi);
GST_DEBUG ("AVI: finalize");
g_object_unref (avi->adapter);
+ gst_flow_combiner_free (avi->flowcombiner);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
if (stream->exposed) {
gst_pad_set_active (stream->pad, FALSE);
gst_element_remove_pad (GST_ELEMENT_CAST (avi), stream->pad);
+ gst_flow_combiner_remove_pad (avi->flowcombiner, stream->pad);
} else
gst_object_unref (stream->pad);
}
if (stream->is_vbr) {
/* VBR */
pos = avi_stream_convert_frames_to_time_unchecked (stream,
- stream->current_total);
+ stream->current_entry);
GST_DEBUG_OBJECT (avi, "VBR convert frame %u, time %"
GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos));
} else if (stream->strf.auds->av_bps != 0) {
guint64 xlen = avi->avih->us_frame *
avi->avih->tot_frames * GST_USECOND;
- if (stream->is_vbr) {
- pos = gst_util_uint64_scale (xlen, stream->current_entry,
- stream->idx_n);
- GST_DEBUG_OBJECT (avi, "VBR perc convert frame %u, time %"
- GST_TIME_FORMAT, stream->current_entry, GST_TIME_ARGS (pos));
- } else {
- pos = gst_util_uint64_scale (xlen, stream->current_total,
- stream->total_bytes);
- GST_DEBUG_OBJECT (avi,
- "CBR perc convert bytes %u, time %" GST_TIME_FORMAT,
- stream->current_total, GST_TIME_ARGS (pos));
- }
+ pos = gst_util_uint64_scale (xlen, stream->current_total,
+ stream->total_bytes);
+ GST_DEBUG_OBJECT (avi,
+ "CBR perc convert bytes %u, time %" GST_TIME_FORMAT,
+ stream->current_total, GST_TIME_ARGS (pos));
} else {
/* we don't know */
res = FALSE;
}
#endif
-static guint
+static gint
gst_avi_demux_index_entry_offset_search (GstAviIndexEntry * entry,
guint64 * offset)
{
gst_adapter_clear (avi->adapter);
avi->have_eos = FALSE;
for (i = 0; i < avi->num_streams; i++) {
- avi->stream[i].last_flow = GST_FLOW_OK;
avi->stream[i].discont = TRUE;
}
/* fall through to default case so that the event gets passed downstream */
not_avi:
{
GST_ELEMENT_ERROR (element, STREAM, WRONG_TYPE, (NULL),
- ("File is not an AVI file: %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (doctype)));
+ ("File is not an AVI file: 0x%" G_GINT32_MODIFIER "x", doctype));
return FALSE;
}
}
if (force || stream->idx_n != 0) {
GST_LOG_OBJECT (avi, "Adding pad %s", GST_PAD_NAME (stream->pad));
gst_element_add_pad ((GstElement *) avi, stream->pad);
+ gst_flow_combiner_add_pad (avi->flowcombiner, stream->pad);
#if 0
if (avi->element_index)
gst_riff_vprp *vprp = NULL;
GstEvent *event;
gchar *stream_id;
+ GstMapInfo map;
element = GST_ELEMENT_CAST (avi);
break;
case GST_RIFF_TAG_strn:
g_free (stream->name);
- if (sub != NULL) {
- GstMapInfo map;
- gst_buffer_map (sub, &map, GST_MAP_READ);
- stream->name = g_strndup ((gchar *) map.data, map.size);
- gst_buffer_unmap (sub, &map);
- gst_buffer_unref (sub);
- sub = NULL;
+ gst_buffer_map (sub, &map, GST_MAP_READ);
+ stream->name = g_strndup ((gchar *) map.data, map.size);
+ gst_buffer_unmap (sub, &map);
+ gst_buffer_unref (sub);
+ sub = NULL;
- if (avi->globaltags == NULL)
- avi->globaltags = gst_tag_list_new_empty ();
- gst_tag_list_add (avi->globaltags, GST_TAG_MERGE_REPLACE,
- GST_TAG_TITLE, stream->name, NULL);
- } else {
- stream->name = g_strdup ("");
- }
+ if (avi->globaltags == NULL)
+ avi->globaltags = gst_tag_list_new_empty ();
+ gst_tag_list_add (avi->globaltags, GST_TAG_MERGE_REPLACE,
+ GST_TAG_TITLE, stream->name, NULL);
GST_DEBUG_OBJECT (avi, "stream name: %s", stream->name);
break;
case GST_RIFF_IDIT:
stream->current_entry = -1;
stream->current_total = 0;
- stream->last_flow = GST_FLOW_OK;
stream->discont = TRUE;
stream->total_bytes = 0;
gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
guint * size)
{
- GstFlowReturn res = GST_FLOW_OK;
+ GstFlowReturn res;
GstBuffer *buf = NULL;
GstMapInfo map;
if (avi->globaltags) {
gst_tag_list_insert (avi->globaltags, tags,
GST_TAG_MERGE_REPLACE);
+ gst_tag_list_unref (tags);
} else {
avi->globaltags = tags;
}
if (avi->globaltags) {
gst_tag_list_insert (avi->globaltags, tags,
GST_TAG_MERGE_REPLACE);
+ gst_tag_list_unref (tags);
} else {
avi->globaltags = tags;
}
if (avi->globaltags) {
gst_tag_list_insert (avi->globaltags, tags,
GST_TAG_MERGE_REPLACE);
+ gst_tag_list_unref (tags);
} else {
avi->globaltags = tags;
}
if (avi->globaltags) {
gst_tag_list_insert (avi->globaltags, tags,
GST_TAG_MERGE_REPLACE);
+ gst_tag_list_unref (tags);
} else {
avi->globaltags = tags;
}
if (avi->globaltags) {
gst_tag_list_insert (avi->globaltags, tags,
GST_TAG_MERGE_REPLACE);
+ gst_tag_list_unref (tags);
} else {
avi->globaltags = tags;
}
}
pull_range_failed:
{
+ if (res == GST_FLOW_FLUSHING)
+ return res;
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
("pull_range flow reading header: %s", gst_flow_get_name (res)));
- return GST_FLOW_ERROR;
+ return res;
}
}
/* reset the last flow and mark discont, seek is always DISCONT */
for (i = 0; i < avi->num_streams; i++) {
GST_DEBUG_OBJECT (avi, "marking DISCONT");
- avi->stream[i].last_flow = GST_FLOW_OK;
avi->stream[i].discont = TRUE;
}
+ /* likewise for the whole new segment */
+ gst_flow_combiner_reset (avi->flowcombiner);
GST_PAD_STREAM_UNLOCK (avi->sinkpad);
return TRUE;
gst_avi_demux_combine_flows (GstAviDemux * avi, GstAviStream * stream,
GstFlowReturn ret)
{
- guint i;
- gboolean unexpected = FALSE, not_linked = TRUE;
-
- /* store the value */
- stream->last_flow = ret;
+ GST_LOG_OBJECT (avi, "Stream %s:%s flow return: %s",
+ GST_DEBUG_PAD_NAME (stream->pad), gst_flow_get_name (ret));
+ ret = gst_flow_combiner_update_pad_flow (avi->flowcombiner, stream->pad, ret);
+ GST_LOG_OBJECT (avi, "combined to return %s", gst_flow_get_name (ret));
- /* any other error that is not-linked or eos can be returned right away */
- if (G_LIKELY (ret != GST_FLOW_EOS && ret != GST_FLOW_NOT_LINKED))
- goto done;
-
- /* only return NOT_LINKED if all other pads returned NOT_LINKED */
- for (i = 0; i < avi->num_streams; i++) {
- GstAviStream *ostream = &avi->stream[i];
-
- ret = ostream->last_flow;
- /* no unexpected or unlinked, return */
- if (G_LIKELY (ret != GST_FLOW_EOS && ret != GST_FLOW_NOT_LINKED))
- goto done;
-
- /* we check to see if we have at least 1 unexpected or all unlinked */
- unexpected |= (ret == GST_FLOW_EOS);
- not_linked &= (ret == GST_FLOW_NOT_LINKED);
- }
- /* when we get here, we all have unlinked or unexpected */
- if (not_linked)
- ret = GST_FLOW_NOT_LINKED;
- else if (unexpected)
- ret = GST_FLOW_EOS;
-done:
- GST_LOG_OBJECT (avi, "combined %s to return %s",
- gst_flow_get_name (stream->last_flow), gst_flow_get_name (ret));
return ret;
}
&stream->current_timestamp, &stream->current_ts_end,
&stream->current_offset, &stream->current_offset_end);
/* and MARK discont for this stream */
- stream->last_flow = GST_FLOW_OK;
stream->discont = TRUE;
GST_DEBUG_OBJECT (avi, "Moved from %u to %u, ts %" GST_TIME_FORMAT
", ts_end %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
stream = &avi->stream[i];
/* ignore streams that finished */
- if (stream->last_flow == GST_FLOW_EOS)
+ if (stream->pad && GST_PAD_LAST_FLOW_RETURN (stream->pad) == GST_FLOW_EOS)
continue;
position = stream->current_timestamp;
GST_OBJECT_UNLOCK (avi);
/* calculate and perform seek */
- if (!avi_demux_handle_seek_push (avi, avi->sinkpad, event))
+ if (!avi_demux_handle_seek_push (avi, avi->sinkpad, event)) {
+ gst_event_unref (event);
goto seek_failed;
+ }
gst_event_unref (event);
avi->state = GST_AVI_DEMUX_MOVI;