GST_STATIC_CAPS ("video/x-msvideo")
);
-static void gst_avi_demux_base_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_class_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_init (GstAviDemux * avi);
static void gst_avi_demux_finalize (GObject * object);
static void gst_avi_demux_reset (GstAviDemux * avi);
#if 0
static const GstFormat *gst_avi_demux_get_src_formats (GstPad * pad);
#endif
-static const GstQueryType *gst_avi_demux_get_src_query_types (GstPad * pad);
static gboolean gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query);
static gboolean gst_avi_demux_src_convert (GstPad * pad, GstFormat src_format,
gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
static void gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf);
-static GstElementClass *parent_class = NULL;
-
/* GObject methods */
-GType
-gst_avi_demux_get_type (void)
-{
- static GType avi_demux_type = 0;
-
- if (!avi_demux_type) {
- static const GTypeInfo avi_demux_info = {
- sizeof (GstAviDemuxClass),
- (GBaseInitFunc) gst_avi_demux_base_init,
- NULL,
- (GClassInitFunc) gst_avi_demux_class_init,
- NULL,
- NULL,
- sizeof (GstAviDemux),
- 0,
- (GInstanceInitFunc) gst_avi_demux_init,
- };
-
- avi_demux_type =
- g_type_register_static (GST_TYPE_ELEMENT,
- "GstAviDemux", &avi_demux_info, 0);
- }
-
- return avi_demux_type;
-}
+#define gst_avi_demux_parent_class parent_class
+G_DEFINE_TYPE (GstAviDemux, gst_avi_demux, GST_TYPE_ELEMENT);
static void
-gst_avi_demux_base_init (GstAviDemuxClass * klass)
+gst_avi_demux_class_init (GstAviDemuxClass * klass)
{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+ GObjectClass *gobject_class = (GObjectClass *) klass;
GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
GstCaps *audcaps, *vidcaps, *subcaps;
+ GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
+ 0, "Demuxer for AVI streams");
+
+ gobject_class->finalize = gst_avi_demux_finalize;
+
+ gstelement_class->change_state =
+ GST_DEBUG_FUNCPTR (gst_avi_demux_change_state);
+ gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_avi_demux_set_index);
+ gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_avi_demux_get_index);
+
audcaps = gst_riff_create_audio_template_caps ();
- gst_caps_append (audcaps, gst_caps_new_simple ("audio/x-avi-unknown", NULL));
- audiosrctempl = gst_pad_template_new ("audio_%02d",
+ gst_caps_append (audcaps, gst_caps_new_empty_simple ("audio/x-avi-unknown"));
+ audiosrctempl = gst_pad_template_new ("audio_%u",
GST_PAD_SRC, GST_PAD_SOMETIMES, audcaps);
vidcaps = gst_riff_create_video_template_caps ();
gst_caps_append (vidcaps, gst_riff_create_iavs_template_caps ());
- gst_caps_append (vidcaps, gst_caps_new_simple ("video/x-avi-unknown", NULL));
- videosrctempl = gst_pad_template_new ("video_%02d",
+ gst_caps_append (vidcaps, gst_caps_new_empty_simple ("video/x-avi-unknown"));
+ videosrctempl = gst_pad_template_new ("video_%u",
GST_PAD_SRC, GST_PAD_SOMETIMES, vidcaps);
- subcaps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
- subsrctempl = gst_pad_template_new ("subtitle_%02d",
+ subcaps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
+ subsrctempl = gst_pad_template_new ("subtitle_%u",
GST_PAD_SRC, GST_PAD_SOMETIMES, subcaps);
- gst_element_class_add_pad_template (element_class, audiosrctempl);
- gst_element_class_add_pad_template (element_class, videosrctempl);
- gst_element_class_add_pad_template (element_class, subsrctempl);
- gst_element_class_add_pad_template (element_class,
+ gst_element_class_add_pad_template (gstelement_class, audiosrctempl);
+ gst_element_class_add_pad_template (gstelement_class, videosrctempl);
+ gst_element_class_add_pad_template (gstelement_class, subsrctempl);
+ gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sink_templ));
- gst_element_class_set_details_simple (element_class, "Avi demuxer",
+
+ gst_element_class_set_details_simple (gstelement_class, "Avi demuxer",
"Codec/Demuxer",
"Demultiplex an avi file into audio and video",
"Erik Walthinsen <omega@cse.ogi.edu>, "
}
static void
-gst_avi_demux_class_init (GstAviDemuxClass * klass)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
- 0, "Demuxer for AVI streams");
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_avi_demux_finalize;
- gstelement_class->change_state =
- GST_DEBUG_FUNCPTR (gst_avi_demux_change_state);
-
- gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_avi_demux_set_index);
- gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_avi_demux_get_index);
-}
-
-static void
gst_avi_demux_init (GstAviDemux * avi)
{
avi->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
gst_object_unref (avi->element_index);
avi->element_index = NULL;
- if (avi->close_seg_event) {
- gst_event_unref (avi->close_seg_event);
- avi->close_seg_event = NULL;
- }
if (avi->seg_event) {
gst_event_unref (avi->seg_event);
avi->seg_event = NULL;
return res;
}
-static const GstQueryType *
-gst_avi_demux_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType src_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_SEEKING,
- GST_QUERY_CONVERT,
- 0
- };
-
- return src_types;
-}
-
static gboolean
gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
{
if (stream->idx_n >= 0)
gst_query_set_duration (query, fmt, stream->idx_n);
else if (gst_pad_query_convert (pad, GST_FORMAT_TIME,
- duration, &fmt, &dur))
+ duration, fmt, &dur))
gst_query_set_duration (query, fmt, dur);
break;
}
"have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
{
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time, offset = 0;
- gboolean update;
+ gint64 boffset, offset = 0;
GstSegment segment;
/* some debug output */
- gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
- gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
- start, stop, time);
- GST_DEBUG_OBJECT (avi,
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
+ gst_event_copy_segment (event, &segment);
+ GST_DEBUG_OBJECT (avi, "received newsegment %" GST_SEGMENT_FORMAT,
&segment);
/* chain will send initial newsegment after pads have been added */
}
/* we only expect a BYTE segment, e.g. following a seek */
- if (format != GST_FORMAT_BYTES) {
+ if (segment.format != GST_FORMAT_BYTES) {
GST_DEBUG_OBJECT (avi, "unsupported segment format, ignoring");
goto exit;
}
GstAviStream *stream;
/* compensate chunk header, stored index offset points after header */
- start += 8;
+ boffset = segment.start + 8;
/* find which stream we're on */
do {
stream = &avi->stream[i];
entry = gst_util_array_binary_search (stream->index,
stream->idx_n, sizeof (GstAviIndexEntry),
(GCompareDataFunc) gst_avi_demux_index_entry_offset_search,
- GST_SEARCH_MODE_AFTER, &start, NULL);
+ GST_SEARCH_MODE_AFTER, &boffset, NULL);
if (entry == NULL)
continue;
k = i;
}
/* exact match needs no further searching */
- if (stream->index[index].offset == start)
+ if (stream->index[index].offset == segment.start)
break;
} while (++i < avi->num_streams);
- start -= 8;
+ boffset -= 8;
offset -= 8;
stream = &avi->stream[k];
/* get the ts corresponding to start offset bytes for the stream */
gst_avi_demux_get_buffer_info (avi, stream, index,
- (GstClockTime *) & time, NULL, NULL, NULL);
+ (GstClockTime *) & segment.time, NULL, NULL, NULL);
} else if (avi->element_index) {
GstIndexEntry *entry;
/* Let's check if we have an index entry for this position */
entry = gst_index_get_assoc_entry (avi->element_index, avi->index_id,
GST_INDEX_LOOKUP_AFTER, GST_ASSOCIATION_FLAG_NONE,
- GST_FORMAT_BYTES, start);
+ GST_FORMAT_BYTES, segment.start);
/* we can not go where we have not yet been before ... */
if (!entry) {
goto eos;
}
- gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time);
+ gst_index_entry_assoc_map (entry, GST_FORMAT_TIME,
+ (gint64 *) & segment.time);
gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &offset);
} else {
GST_WARNING_OBJECT (avi, "no index data, forcing EOS");
goto eos;
}
- stop = GST_CLOCK_TIME_NONE;
+ segment.format = GST_FORMAT_TIME;
+ segment.start = segment.time;
+ segment.stop = GST_CLOCK_TIME_NONE;
+ segment.position = segment.start;
+
+ /* rescue duration */
+ segment.duration = avi->segment.duration;
/* set up segment and send downstream */
- gst_segment_set_newsegment_full (&avi->segment, update, rate, arate,
- GST_FORMAT_TIME, time, stop, time);
- GST_DEBUG_OBJECT (avi, "Pushing newseg update %d, rate %g, "
- "applied rate %g, format %d, start %" G_GINT64_FORMAT ", "
- "stop %" G_GINT64_FORMAT, update, rate, arate, GST_FORMAT_TIME,
- time, stop);
- gst_avi_demux_push_event (avi,
- gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,
- time, stop, time));
-
- GST_DEBUG_OBJECT (avi, "next chunk expected at %" G_GINT64_FORMAT, start);
+ gst_segment_copy_into (&segment, &avi->segment);
+
+ GST_DEBUG_OBJECT (avi, "Pushing newseg %" GST_SEGMENT_FORMAT, &segment);
+ gst_avi_demux_push_event (avi, gst_event_new_segment (&segment));
+
+ GST_DEBUG_OBJECT (avi, "next chunk expected at %" G_GINT64_FORMAT,
+ boffset);
/* adjust state for streaming thread accordingly */
if (avi->have_index)
gst_avi_demux_seek_streams (avi, offset, FALSE);
/* set up streaming thread */
- g_assert (offset >= start);
- avi->offset = start;
- avi->todrop = offset - start;
+ g_assert (offset >= boffset);
+ avi->offset = boffset;
+ avi->todrop = offset - boffset;
exit:
gst_event_unref (event);
if (gst_adapter_available (avi->adapter) < 8)
return FALSE;
- data = gst_adapter_peek (avi->adapter, 8);
+ data = gst_adapter_map (avi->adapter, 8);
*tag = GST_READ_UINT32_LE (data);
*size = GST_READ_UINT32_LE (data + 4);
+ gst_adapter_unmap (avi->adapter, 0);
return TRUE;
}
GstBuffer * buf, gst_riff_avih ** _avih)
{
gst_riff_avih *avih;
+ gsize size;
if (buf == NULL)
goto no_buffer;
- if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih))
+ size = gst_buffer_get_size (buf);
+ if (size < sizeof (gst_riff_avih))
goto avih_too_small;
- avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ avih = g_malloc (size);
+ gst_buffer_extract (buf, 0, avih, size);
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
avih->us_frame = GUINT32_FROM_LE (avih->us_frame);
{
GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
("Too small avih (%d available, %d needed)",
- GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
+ size, (int) sizeof (gst_riff_avih)));
gst_buffer_unref (buf);
return FALSE;
}
guint16 bpe = 16;
guint32 num, i;
guint64 *indexes;
- guint size;
+ gsize size;
*_indexes = NULL;
- size = buf ? GST_BUFFER_SIZE (buf) : 0;
+ if (buf) {
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ } else {
+ data = NULL;
+ size = 0;
+ }
+
if (size < 24)
goto too_small;
- data = GST_BUFFER_DATA (buf);
-
/* check type of index. The opendml2 specs state that
* there should be 4 dwords per array entry. Type can be
* either frame or field (and we don't care). */
indexes[i] = GST_BUFFER_OFFSET_NONE;
*_indexes = indexes;
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return TRUE;
{
GST_ERROR_OBJECT (avi,
"Not enough data to parse superindex (%d available, 24 needed)", size);
- if (buf)
+ if (buf) {
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
+ }
return FALSE;
}
invalid_params:
{
GST_ERROR_OBJECT (avi, "invalid index parameters (num = %d, bpe = %d)",
num, bpe);
- if (buf)
- gst_buffer_unref (buf);
+ gst_buffer_unmap (buf, data, size);
+ gst_buffer_unref (buf);
return FALSE;
}
}
guint16 bpe;
guint32 num, i;
guint64 baseoff;
- guint size;
+ gsize size;
- if (!buf)
+ if (buf == NULL)
return TRUE;
- size = GST_BUFFER_SIZE (buf);
-
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
/* check size */
if (size < 24)
goto too_small;
- data = GST_BUFFER_DATA (buf);
-
/* We don't support index-data yet */
if (data[3] & 0x80)
goto not_implemented;
if (G_UNLIKELY (!gst_avi_demux_add_index (avi, stream, num, &entry)))
goto out_of_mem;
}
+done:
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return TRUE;
{
GST_ERROR_OBJECT (avi,
"Not enough data to parse subindex (%d available, 24 needed)", size);
- gst_buffer_unref (buf);
- return TRUE; /* continue */
+ goto done; /* continue */
}
not_implemented:
{
GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
("Subindex-is-data is not implemented"));
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return FALSE;
}
empty_index:
{
GST_DEBUG_OBJECT (avi, "the index is empty");
- gst_buffer_unref (buf);
- return TRUE;
+ goto done; /* continue */
}
out_of_mem:
{
("Cannot allocate memory for %u*%u=%u bytes",
(guint) sizeof (GstAviIndexEntry), num,
(guint) sizeof (GstAviIndexEntry) * num));
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return FALSE;
}
{
gst_riff_vprp *vprp;
gint k;
+ gsize size;
g_return_val_if_fail (buf != NULL, FALSE);
g_return_val_if_fail (_vprp != NULL, FALSE);
- if (GST_BUFFER_SIZE (buf) < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
+ size = gst_buffer_get_size (buf);
+
+ if (size < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
goto too_small;
- vprp = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ vprp = g_malloc (size);
+ gst_buffer_extract (buf, 0, vprp, size);
#if (G_BYTE_ORDER == G_BIG_ENDIAN)
vprp->format_token = GUINT32_FROM_LE (vprp->format_token);
/* size checking */
/* calculate fields based on size */
- k = (GST_BUFFER_SIZE (buf) - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) /
- vprp->fields;
+ k = (size - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) / vprp->fields;
if (vprp->fields > k) {
GST_WARNING_OBJECT (element,
"vprp header indicated %d fields, only %d available", vprp->fields, k);
{
GST_ERROR_OBJECT (element,
"Too small vprp (%d available, at least %d needed)",
- GST_BUFFER_SIZE (buf),
- (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
+ size, (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
gst_buffer_unref (buf);
return FALSE;
}
GstAviStream *stream = &avi->stream[i];
if (force || stream->idx_n != 0) {
- GST_LOG_OBJECT (avi, "Added pad %s with caps %" GST_PTR_FORMAT,
- GST_PAD_NAME (stream->pad), GST_PAD_CAPS (stream->pad));
+ GST_LOG_OBJECT (avi, "Adding pad %s" GST_PTR_FORMAT,
+ GST_PAD_NAME (stream->pad));
gst_element_add_pad ((GstElement *) avi, stream->pad);
if (avi->element_index)
static inline void
gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
{
- gint size = GST_BUFFER_SIZE (*buf);
+ gsize size;
+
+ size = gst_buffer_get_size (*buf);
if (G_UNLIKELY (size & 1)) {
GstBuffer *obuf;
+ guint8 *data;
GST_DEBUG_OBJECT (avi, "rounding up dubious list size %d", size);
obuf = gst_buffer_new_and_alloc (size + 1);
- memcpy (GST_BUFFER_DATA (obuf), GST_BUFFER_DATA (*buf), size);
+
+ data = gst_buffer_map (obuf, NULL, NULL, GST_MAP_WRITE);
+ gst_buffer_extract (*buf, 0, data, size);
/* assume 0 padding, at least makes outcome deterministic */
- (GST_BUFFER_DATA (obuf))[size] = 0;
+ data[size] = 0;
+ gst_buffer_unmap (obuf, data, size + 1);
gst_buffer_replace (buf, obuf);
}
}
case GST_RIFF_TAG_strn:
g_free (stream->name);
if (sub != NULL) {
- stream->name =
- g_strndup ((gchar *) GST_BUFFER_DATA (sub),
- (gsize) GST_BUFFER_SIZE (sub));
+ gchar *bdata;
+ gsize bsize;
+
+ bdata = gst_buffer_map (sub, &bsize, NULL, GST_MAP_READ);
+ stream->name = g_strndup (bdata, bsize);
+ gst_buffer_unmap (sub, bdata, bsize);
gst_buffer_unref (sub);
sub = NULL;
} else {
fourcc = (stream->strf.vids->compression) ?
stream->strf.vids->compression : stream->strh->fcc_handler;
- padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
- templ = gst_element_class_get_pad_template (klass, "video_%02d");
+ padname = g_strdup_printf ("video_%u", avi->num_v_streams);
+ templ = gst_element_class_get_pad_template (klass, "video_%u");
caps = gst_riff_create_video_caps (fourcc, stream->strh,
stream->strf.vids, stream->extradata, stream->initdata, &codec_name);
if (!caps) {
caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
- GST_TYPE_FOURCC, fourcc, NULL);
+ G_TYPE_INT, fourcc, NULL);
} else if (got_vprp && vprp) {
guint32 aspect_n, aspect_d;
gint n, d;
break;
}
case GST_RIFF_FCC_auds:{
- padname = g_strdup_printf ("audio_%02d", avi->num_a_streams);
- templ = gst_element_class_get_pad_template (klass, "audio_%02d");
+ padname = g_strdup_printf ("audio_%u", avi->num_a_streams);
+ templ = gst_element_class_get_pad_template (klass, "audio_%u");
caps = gst_riff_create_audio_caps (stream->strf.auds->format,
stream->strh, stream->strf.auds, stream->extradata,
stream->initdata, &codec_name);
case GST_RIFF_FCC_iavs:{
guint32 fourcc = stream->strh->fcc_handler;
- padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
- templ = gst_element_class_get_pad_template (klass, "video_%02d");
+ padname = g_strdup_printf ("video_%u", avi->num_v_streams);
+ templ = gst_element_class_get_pad_template (klass, "video_%u");
caps = gst_riff_create_iavs_caps (fourcc, stream->strh,
stream->strf.iavs, stream->extradata, stream->initdata, &codec_name);
if (!caps) {
caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
- GST_TYPE_FOURCC, fourcc, NULL);
+ G_TYPE_INT, fourcc, NULL);
}
tag_name = GST_TAG_VIDEO_CODEC;
avi->num_v_streams++;
break;
}
case GST_RIFF_FCC_txts:{
- padname = g_strdup_printf ("subtitle_%02d", avi->num_t_streams);
- templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
- caps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
+ padname = g_strdup_printf ("subtitle_%u", avi->num_t_streams);
+ templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
+ caps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
tag_name = NULL;
avi->num_t_streams++;
break;
#endif
gst_pad_set_event_function (pad,
GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_event));
- gst_pad_set_query_type_function (pad,
- GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_query_types));
gst_pad_set_query_function (pad,
GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_query));
#if 0
gst_pad_set_element_private (pad, stream);
avi->num_streams++;
- gst_pad_set_caps (pad, caps);
gst_pad_set_active (pad, TRUE);
+ gst_pad_push_event (pad, gst_event_new_caps (caps));
gst_caps_unref (caps);
/* make tags */
if (codec_name) {
if (!stream->taglist)
- stream->taglist = gst_tag_list_new ();
+ stream->taglist = gst_tag_list_new_empty ();
avi->got_tags = TRUE;
switch (tag) {
case GST_RIFF_TAG_dmlh:{
gst_riff_dmlh dmlh, *_dmlh;
- guint size;
+ gsize size;
+ guint8 *data;
/* sub == NULL is possible and means an empty buffer */
- size = sub ? GST_BUFFER_SIZE (sub) : 0;
+ if (sub == NULL)
+ goto next;
+
+ data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
/* check size */
if (size < sizeof (gst_riff_dmlh)) {
GST_ERROR_OBJECT (avi,
"DMLH entry is too small (%d bytes, %d needed)",
size, (int) sizeof (gst_riff_dmlh));
+ gst_buffer_unmap (sub, data, size);
goto next;
}
- _dmlh = (gst_riff_dmlh *) GST_BUFFER_DATA (sub);
+ _dmlh = (gst_riff_dmlh *) data;
dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes);
+ gst_buffer_unmap (sub, data, size);
GST_INFO_OBJECT (avi, "dmlh tag found: totalframes: %u",
dmlh.totalframes);
gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
{
guint8 *data;
- guint size;
+ gsize size;
guint i, num, n;
gst_riff_index_entry *index;
GstClockTime stamp;
if (!buf)
return FALSE;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
stamp = gst_util_get_timestamp ();
n++;
}
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
/* get stream stats now */
empty_list:
{
GST_DEBUG_OBJECT (avi, "empty index");
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return FALSE;
}
("Cannot allocate memory for %u*%u=%u bytes",
(guint) sizeof (GstAviIndexEntry), num,
(guint) sizeof (GstAviIndexEntry) * num));
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
return FALSE;
}
GstBuffer *buf;
guint32 tag;
guint32 size;
+ gsize bsize;
+ guint8 *bdata;
GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
if (res != GST_FLOW_OK)
goto pull_failed;
- else if (GST_BUFFER_SIZE (buf) < 8)
+
+ bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ if (bsize < 8)
goto too_small;
/* check tag first before blindy trying to read 'size' bytes */
- tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+ tag = GST_READ_UINT32_LE (bdata);
+ size = GST_READ_UINT32_LE (bdata + 4);
if (tag == GST_RIFF_TAG_LIST) {
/* this is the movi tag */
GST_DEBUG_OBJECT (avi, "skip LIST chunk, size %" G_GUINT32_FORMAT,
(8 + GST_ROUND_UP_2 (size)));
offset += 8 + GST_ROUND_UP_2 (size);
+ gst_buffer_unmap (buf, bdata, bsize);
gst_buffer_unref (buf);
+
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
if (res != GST_FLOW_OK)
goto pull_failed;
- else if (GST_BUFFER_SIZE (buf) < 8)
+
+ bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ if (bsize < 8)
goto too_small;
- tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
- size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+
+ tag = GST_READ_UINT32_LE (bdata);
+ size = GST_READ_UINT32_LE (bdata + 4);
}
+ gst_buffer_unmap (buf, bdata, bsize);
+ gst_buffer_unref (buf);
if (tag != GST_RIFF_TAG_idx1)
goto no_index;
if (!size)
goto zero_index;
- gst_buffer_unref (buf);
-
GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
/* read chunk, advance offset */
return;
GST_DEBUG ("will parse index chunk size %u for tag %"
- GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
+ GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
gst_avi_demux_parse_index (avi, buf);
too_small:
{
GST_DEBUG_OBJECT (avi, "Buffer is too small");
+ gst_buffer_unmap (buf, bdata, bsize);
gst_buffer_unref (buf);
return;
}
GST_WARNING_OBJECT (avi,
"No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (tag));
- gst_buffer_unref (buf);
return;
}
zero_index:
{
GST_WARNING_OBJECT (avi, "Empty index data (idx1) after movi chunk");
- gst_buffer_unref (buf);
return;
}
}
offset += 8 + GST_ROUND_UP_2 (size);
GST_DEBUG ("will parse index chunk size %u for tag %"
- GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
+ GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
avi->offset = avi->first_movi_offset;
gst_avi_demux_parse_index (avi, buf);
{
GstFlowReturn res = GST_FLOW_OK;
GstBuffer *buf = NULL;
- guint bufsize;
+ gsize bufsize;
guint8 *bufdata;
res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
if (res != GST_FLOW_OK)
goto pull_failed;
- bufsize = GST_BUFFER_SIZE (buf);
+ bufdata = gst_buffer_map (buf, &bufsize, NULL, GST_MAP_READ);
if (bufsize != 8)
goto wrong_size;
- bufdata = GST_BUFFER_DATA (buf);
-
*tag = GST_READ_UINT32_LE (bufdata);
*size = GST_READ_UINT32_LE (bufdata + 4);
*size, offset + 8, offset + 8 + (gint64) * size);
done:
+ gst_buffer_unmap (buf, bufdata, bufsize);
gst_buffer_unref (buf);
return res;
{
GstFlowReturn res;
GstAviStream *stream;
- GstFormat format;
guint64 pos = 0;
guint64 length;
gint64 tmplength;
GST_DEBUG_OBJECT (avi, "Creating index");
/* get the size of the file */
- format = GST_FORMAT_BYTES;
- if (!gst_pad_query_peer_duration (avi->sinkpad, &format, &tmplength))
+ if (!gst_pad_query_peer_duration (avi->sinkpad, GST_FORMAT_BYTES, &tmplength))
return FALSE;
length = tmplength;
GST_INFO ("Setting total duration to: %" GST_TIME_FORMAT,
GST_TIME_ARGS (total));
- gst_segment_set_duration (&avi->segment, GST_FORMAT_TIME, total);
+ avi->segment.duration = total;
}
/* returns FALSE if there are no pads to deliver event to,
/* try harder to query upstream size if we didn't get it the first time */
if (seekable && stop == -1) {
- GstFormat fmt = GST_FORMAT_BYTES;
-
GST_DEBUG_OBJECT (avi, "doing duration query to fix up unset stop");
- gst_pad_query_peer_duration (avi->sinkpad, &fmt, &stop);
+ gst_pad_query_peer_duration (avi->sinkpad, GST_FORMAT_BYTES, &stop);
}
/* if upstream doesn't know the size, it's likely that it's not seekable in
const guint8 *data;
GstBuffer *buf = NULL, *sub = NULL;
guint offset = 4;
- gint64 stop;
gint i;
GstTagList *tags = NULL;
+ guint8 fourcc[4];
GST_DEBUG ("Reading and parsing avi headers: %d", avi->header_state);
GST_DEBUG ("Reading %d bytes", size);
buf = gst_adapter_take_buffer (avi->adapter, size);
- if (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl)
+ gst_buffer_extract (buf, 0, fourcc, 4);
+
+ if (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl)
goto header_no_hdrl;
/* mind padding */
switch (tag) {
case GST_RIFF_TAG_LIST:
- if (GST_BUFFER_SIZE (sub) < 4)
+ if (gst_buffer_get_size (sub) < 4)
goto next;
- switch (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))) {
+ gst_buffer_extract (sub, 0, fourcc, 4);
+
+ switch (GST_READ_UINT32_LE (fourcc)) {
case GST_RIFF_LIST_strl:
if (!(gst_avi_demux_parse_stream (avi, sub))) {
sub = NULL;
default:
GST_WARNING_OBJECT (avi,
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
- GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA
- (sub))));
+ GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
/* fall-through */
case GST_RIFF_TAG_JUNQ:
case GST_RIFF_TAG_JUNK:
goto next;
+ break;
}
- break;
case GST_RIFF_IDIT:
gst_avi_demux_parse_idit (avi, sub);
goto next;
if (gst_adapter_available (avi->adapter) < 12)
return GST_FLOW_OK;
- data = gst_adapter_peek (avi->adapter, 12);
+ data = gst_adapter_map (avi->adapter, 12);
tag = GST_READ_UINT32_LE (data);
size = GST_READ_UINT32_LE (data + 4);
ltag = GST_READ_UINT32_LE (data + 8);
+ gst_adapter_unmap (avi->adapter, 0);
if (tag == GST_RIFF_TAG_LIST) {
switch (ltag) {
avi->stream[i].current_entry = 0;
/* create initial NEWSEGMENT event */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
- GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
if (avi->seg_event)
gst_event_unref (avi->seg_event);
- avi->seg_event = gst_event_new_new_segment_full
- (FALSE, avi->segment.rate, avi->segment.applied_rate, GST_FORMAT_TIME,
- avi->segment.start, stop, avi->segment.time);
+ avi->seg_event = gst_event_new_segment (&avi->segment);
gst_avi_demux_check_seekability (avi);
dt = gst_date_time_new_local_time (y, m, d, h, min, s);
if (avi->globaltags == NULL)
- avi->globaltags = gst_tag_list_new ();
+ avi->globaltags = gst_tag_list_new_empty ();
gst_tag_list_add (avi->globaltags, GST_TAG_MERGE_REPLACE, GST_TAG_DATE, date,
NULL);
static void
gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
{
- gchar *data = (gchar *) GST_BUFFER_DATA (buf);
- guint size = GST_BUFFER_SIZE (buf);
+ gchar *data, *ptr;
+ gsize size, left;
gchar *safedata = NULL;
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
/*
* According to:
* http://www.eden-foundation.org/products/code/film_date_stamp/index.html
*/
/* skip eventual initial whitespace */
- while (size > 0 && g_ascii_isspace (data[0])) {
- data++;
- size--;
+ ptr = data;
+ left = size;
+
+ while (left > 0 && g_ascii_isspace (ptr[0])) {
+ ptr++;
+ left--;
}
- if (size == 0) {
+ if (left == 0) {
goto non_parsable;
}
/* make a safe copy to add a \0 to the end of the string */
- safedata = g_strndup (data, size);
+ safedata = g_strndup (ptr, left);
/* test if the first char is a alpha or a number */
- if (g_ascii_isdigit (data[0])) {
+ if (g_ascii_isdigit (ptr[0])) {
gst_avi_demux_parse_idit_nums_only (avi, safedata);
g_free (safedata);
return;
- } else if (g_ascii_isalpha (data[0])) {
+ } else if (g_ascii_isalpha (ptr[0])) {
gst_avi_demux_parse_idit_text (avi, safedata);
g_free (safedata);
return;
non_parsable:
GST_WARNING_OBJECT (avi, "IDIT tag has no parsable info");
+ gst_buffer_unmap (buf, data, size);
}
/*
GstBuffer *buf, *sub = NULL;
guint32 tag;
guint offset = 4;
- gint64 stop;
GstElement *element = GST_ELEMENT_CAST (avi);
GstClockTime stamp;
GstTagList *tags = NULL;
+ guint8 fourcc[4];
stamp = gst_util_get_timestamp ();
goto pull_range_failed;
else if (tag != GST_RIFF_TAG_LIST)
goto no_list;
- else if (GST_BUFFER_SIZE (buf) < 4)
+ else if (gst_buffer_get_size (buf) < 4)
goto no_header;
GST_DEBUG_OBJECT (avi, "parsing headers");
/* Find the 'hdrl' LIST tag */
- while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl) {
+ gst_buffer_extract (buf, 0, fourcc, 4);
+ while (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl) {
GST_LOG_OBJECT (avi, "buffer contains %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf))));
+ GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
/* Eat up */
gst_buffer_unref (buf);
goto pull_range_failed;
else if (tag != GST_RIFF_TAG_LIST)
goto no_list;
- else if (GST_BUFFER_SIZE (buf) < 4)
+ else if (gst_buffer_get_size (buf) < 4)
goto no_header;
+ gst_buffer_extract (buf, 0, fourcc, 4);
}
GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
/* now, read the elements from the header until the end */
while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
+ gsize size;
+ guint8 *data;
+
/* sub can be NULL on empty tags */
if (!sub)
continue;
+ data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
+
switch (tag) {
case GST_RIFF_TAG_LIST:
- {
- guint8 *data;
- guint32 fourcc;
-
- if (GST_BUFFER_SIZE (sub) < 4)
+ if (size < 4)
goto next;
- data = GST_BUFFER_DATA (sub);
- fourcc = GST_READ_UINT32_LE (data);
-
- switch (fourcc) {
+ switch (GST_READ_UINT32_LE (data)) {
case GST_RIFF_LIST_strl:
if (!(gst_avi_demux_parse_stream (avi, sub))) {
GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
sub = NULL;
break;
case GST_RIFF_LIST_INFO:
- GST_BUFFER_DATA (sub) = data + 4;
- GST_BUFFER_SIZE (sub) -= 4;
+ gst_buffer_resize (sub, 4, -1);
gst_riff_parse_info (element, sub, &tags);
if (tags) {
if (avi->globaltags) {
default:
GST_WARNING_OBJECT (avi,
"Unknown list %" GST_FOURCC_FORMAT " in AVI header",
- GST_FOURCC_ARGS (fourcc));
- GST_MEMDUMP_OBJECT (avi, "Unknown list", GST_BUFFER_DATA (sub),
- GST_BUFFER_SIZE (sub));
+ GST_FOURCC_ARGS (GST_READ_UINT32_LE (data)));
+ GST_MEMDUMP_OBJECT (avi, "Unknown list", data, size);
/* fall-through */
case GST_RIFF_TAG_JUNQ:
case GST_RIFF_TAG_JUNK:
goto next;
}
break;
- }
case GST_RIFF_IDIT:
gst_avi_demux_parse_idit (avi, sub);
goto next;
GST_WARNING_OBJECT (avi,
"Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
GST_FOURCC_ARGS (tag), offset);
- GST_MEMDUMP_OBJECT (avi, "Unknown tag", GST_BUFFER_DATA (sub),
- GST_BUFFER_SIZE (sub));
+ GST_MEMDUMP_OBJECT (avi, "Unknown tag", data, size);
/* fall-through */
case GST_RIFF_TAG_JUNQ:
case GST_RIFF_TAG_JUNK:
next:
- if (sub)
+ if (sub) {
+ gst_buffer_unmap (sub, data, size);
gst_buffer_unref (sub);
+ }
sub = NULL;
break;
}
/* Now, find the data (i.e. skip all junk between header and data) */
do {
guint size;
+ gsize bsize;
guint8 *data;
guint32 tag, ltag;
if (res != GST_FLOW_OK) {
GST_DEBUG_OBJECT (avi, "pull_range failure while looking for tags");
goto pull_range_failed;
- } else if (GST_BUFFER_SIZE (buf) < 12) {
+ } else if (gst_buffer_get_size (buf) < 12) {
GST_DEBUG_OBJECT (avi, "got %d bytes which is less than 12 bytes",
- GST_BUFFER_SIZE (buf));
+ gst_buffer_get_size (buf));
gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
- data = GST_BUFFER_DATA (buf);
-
+ data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
tag = GST_READ_UINT32_LE (data);
size = GST_READ_UINT32_LE (data + 4);
ltag = GST_READ_UINT32_LE (data + 8);
GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
GST_FOURCC_ARGS (tag), size);
- GST_MEMDUMP ("Tag content", data, GST_BUFFER_SIZE (buf));
+ GST_MEMDUMP ("Tag content", data, bsize);
+ gst_buffer_unmap (buf, data, bsize);
gst_buffer_unref (buf);
switch (tag) {
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
goto pull_range_failed;
}
- GST_DEBUG ("got size %u", GST_BUFFER_SIZE (buf));
+ GST_DEBUG ("got size %u", gst_buffer_get_size (buf));
if (size < 4) {
GST_DEBUG ("skipping INFO LIST prefix");
avi->offset += (4 - GST_ROUND_UP_2 (size));
continue;
}
- sub = gst_buffer_create_sub (buf, 4, GST_BUFFER_SIZE (buf) - 4);
+ sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, 4, -1);
gst_riff_parse_info (element, sub, &tags);
if (tags) {
if (avi->globaltags) {
GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
goto pull_range_failed;
}
- GST_MEMDUMP ("Junk", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ GST_MEMDUMP ("Junk", data, bsize);
+ gst_buffer_unmap (buf, data, bsize);
gst_buffer_unref (buf);
}
avi->offset += 8 + GST_ROUND_UP_2 (size);
gst_avi_demux_expose_streams (avi, FALSE);
- /* create initial NEWSEGMENT event */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
- GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
/* do initial seek to the default segment values */
gst_avi_demux_do_seek (avi, &avi->segment);
- /* prepare initial segment */
+ /* create initial NEWSEGMENT event */
if (avi->seg_event)
gst_event_unref (avi->seg_event);
- avi->seg_event = gst_event_new_new_segment_full
- (FALSE, avi->segment.rate, avi->segment.applied_rate, GST_FORMAT_TIME,
- avi->segment.start, stop, avi->segment.time);
+ avi->seg_event = gst_event_new_segment (&avi->segment);
stamp = gst_util_get_timestamp () - stamp;
GST_DEBUG_OBJECT (avi, "pulling header took %" GST_TIME_FORMAT,
guint i, index;
GstAviStream *stream;
- seek_time = segment->last_stop;
- keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
+ seek_time = segment->position;
+ keyframe = ! !(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
GST_DEBUG_OBJECT (avi, "seek to: %" GST_TIME_FORMAT
" keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe);
GST_TIME_ARGS (seek_time));
}
- /* the seek time is also the last_stop and stream time when going
+ /* the seek time is also the position and stream time when going
* forwards */
- segment->last_stop = seek_time;
+ segment->position = seek_time;
if (segment->rate > 0.0)
segment->time = seek_time;
/* we have to have a format as the segment format. Try to convert
* if not. */
if (format != GST_FORMAT_TIME) {
- GstFormat fmt = GST_FORMAT_TIME;
gboolean res = TRUE;
if (cur_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, cur, &fmt, &cur);
+ res = gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &cur);
if (res && stop_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, stop, &fmt, &stop);
+ res = gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME, &stop);
if (!res)
goto no_format;
- format = fmt;
+ format = GST_FORMAT_TIME;
}
GST_DEBUG_OBJECT (avi,
"seek requested: rate %g cur %" GST_TIME_FORMAT " stop %"
if (event) {
GST_DEBUG_OBJECT (avi, "configuring seek");
- gst_segment_set_seek (&seeksegment, rate, format, flags,
+ gst_segment_do_seek (&seeksegment, rate, format, flags,
cur_type, cur, stop_type, stop, &update);
}
- /* do the seek, seeksegment.last_stop contains the new position, this
+ /* do the seek, seeksegment.position contains the new position, this
* actually never fails. */
gst_avi_demux_do_seek (avi, &seeksegment);
- gst_event_replace (&avi->close_seg_event, NULL);
if (flush) {
- GstEvent *fevent = gst_event_new_flush_stop ();
+ GstEvent *fevent = gst_event_new_flush_stop (TRUE);
GST_DEBUG_OBJECT (avi, "sending flush stop");
gst_avi_demux_push_event (avi, gst_event_ref (fevent));
gst_pad_push_event (avi->sinkpad, fevent);
- } else if (avi->segment_running) {
- /* we are running the current segment and doing a non-flushing seek,
- * close the segment first based on the last_stop. */
- GST_DEBUG_OBJECT (avi, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, avi->segment.start, avi->segment.last_stop);
- avi->close_seg_event = gst_event_new_new_segment_full (TRUE,
- avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
- avi->segment.start, avi->segment.last_stop, avi->segment.time);
}
/* now update the real segment info */
if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT_CAST (avi),
gst_message_new_segment_start (GST_OBJECT_CAST (avi),
- avi->segment.format, avi->segment.last_stop));
+ avi->segment.format, avi->segment.position));
}
- /* prepare for streaming again */
- if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
- stop = avi->segment.duration;
-
/* queue the segment event for the streaming thread. */
if (avi->seg_event)
gst_event_unref (avi->seg_event);
- if (avi->segment.rate > 0.0) {
- /* forwards goes from last_stop to stop */
- avi->seg_event = gst_event_new_new_segment_full (FALSE,
- avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
- avi->segment.last_stop, stop, avi->segment.time);
- } else {
- /* reverse goes from start to last_stop */
- avi->seg_event = gst_event_new_new_segment_full (FALSE,
- avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
- avi->segment.start, avi->segment.last_stop, avi->segment.time);
- }
+ avi->seg_event = gst_event_new_segment (&avi->segment);
if (!avi->streaming) {
- avi->segment_running = TRUE;
gst_pad_start_task (avi->sinkpad, (GstTaskFunction) gst_avi_demux_loop,
avi->sinkpad);
}
&cur_type, &cur, &stop_type, &stop);
if (format != GST_FORMAT_TIME) {
- GstFormat fmt = GST_FORMAT_TIME;
gboolean res = TRUE;
if (cur_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, cur, &fmt, &cur);
+ res = gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &cur);
if (res && stop_type != GST_SEEK_TYPE_NONE)
- res = gst_pad_query_convert (pad, format, stop, &fmt, &stop);
+ res = gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME, &stop);
if (!res) {
GST_DEBUG_OBJECT (avi, "unsupported format given, seek aborted.");
return FALSE;
}
- format = fmt;
+ format = GST_FORMAT_TIME;
}
/* let gst_segment handle any tricky stuff */
GST_DEBUG_OBJECT (avi, "configuring seek");
memcpy (&seeksegment, &avi->segment, sizeof (GstSegment));
- gst_segment_set_seek (&seeksegment, rate, format, flags,
+ gst_segment_do_seek (&seeksegment, rate, format, flags,
cur_type, cur, stop_type, stop, &update);
- keyframe = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
- cur = seeksegment.last_stop;
+ keyframe = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
+ cur = seeksegment.position;
GST_DEBUG_OBJECT (avi,
"Seek requested: ts %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
GstStructure *s;
gint y, w, h;
gint bpp, stride;
- guint8 *tmp = NULL;
+ guint8 *tmp = NULL, *data;
+ gsize size;
+ GstCaps *caps;
if (stream->strh->type != GST_RIFF_FCC_vids)
return buf;
return buf; /* Ignore non DIB buffers */
}
- s = gst_caps_get_structure (GST_PAD_CAPS (stream->pad), 0);
+ caps = gst_pad_get_current_caps (stream->pad);
+ s = gst_caps_get_structure (caps, 0);
+ gst_caps_unref (caps);
+
if (!gst_structure_get_int (s, "bpp", &bpp)) {
GST_WARNING ("Failed to retrieve depth from caps");
return buf;
h = stream->strf.vids->height;
w = stream->strf.vids->width;
- stride = w * (bpp / 8);
+ stride = GST_ROUND_UP_4 (w * (bpp / 8));
buf = gst_buffer_make_writable (buf);
- if (GST_BUFFER_SIZE (buf) < (stride * h)) {
+
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
+ if (size < (stride * h)) {
GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
+ gst_buffer_unmap (buf, data, size);
return buf;
}
tmp = g_malloc (stride);
for (y = 0; y < h / 2; y++) {
- swap_line (GST_BUFFER_DATA (buf) + stride * y,
- GST_BUFFER_DATA (buf) + stride * (h - 1 - y), tmp, stride);
+ swap_line (data + stride * y, data + stride * (h - 1 - y), tmp, stride);
}
g_free (tmp);
+ gst_buffer_unmap (buf, data, size);
+
return buf;
}
goto pull_failed;
/* check for short buffers, this is EOS as well */
- if (GST_BUFFER_SIZE (buf) < size)
+ if (gst_buffer_get_size (buf) < size)
goto short_buffer;
/* invert the picture if needed */
gst_avi_demux_add_assoc (avi, stream, timestamp, offset, keyframe);
- gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
-
/* update current position in the segment */
- gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp);
+ avi->segment.position = timestamp;
GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
", off_end %" G_GUINT64_FORMAT,
- GST_BUFFER_SIZE (buf), GST_TIME_ARGS (timestamp),
+ gst_buffer_get_size (buf), GST_TIME_ARGS (timestamp),
GST_TIME_ARGS (duration), out_offset, out_offset_end);
ret = gst_pad_push (stream->pad, buf);
{
GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
", only got %d/%" G_GUINT64_FORMAT " bytes (truncated file?)", offset,
- GST_BUFFER_SIZE (buf), size);
+ gst_buffer_get_size (buf), size);
gst_buffer_unref (buf);
ret = GST_FLOW_UNEXPECTED;
goto beach;
guint32 size = 0;
gint stream_nr = 0;
GstFlowReturn res = GST_FLOW_OK;
- GstFormat format = GST_FORMAT_TIME;
if (G_UNLIKELY (avi->have_eos)) {
/* Clean adapter, we're done */
if (size) {
buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
/* patch the size */
- GST_BUFFER_SIZE (buf) = size;
+ gst_buffer_resize (buf, 0, size);
} else {
buf = NULL;
}
gst_buffer_unref (buf);
} else {
/* get time of this buffer */
- gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
- if (G_UNLIKELY (format != GST_FORMAT_TIME))
- goto wrong_format;
+ gst_pad_query_position (stream->pad, GST_FORMAT_TIME,
+ (gint64 *) & next_ts);
gst_avi_demux_add_assoc (avi, stream, next_ts, offset, FALSE);
stream->current_total += size;
/* update current position in the segment */
- gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, next_ts);
+ avi->segment.position = next_ts;
if (saw_desired_kf && buf) {
GstClockTime dur_ts = 0;
/* invert the picture if needed */
buf = gst_avi_demux_invert (stream, buf);
- gst_pad_query_position (stream->pad, &format, (gint64 *) & dur_ts);
- if (G_UNLIKELY (format != GST_FORMAT_TIME))
- goto wrong_format;
+ gst_pad_query_position (stream->pad, GST_FORMAT_TIME,
+ (gint64 *) & dur_ts);
GST_BUFFER_TIMESTAMP (buf) = next_ts;
GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
}
- gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
GST_DEBUG_OBJECT (avi,
"Pushing buffer with time=%" GST_TIME_FORMAT ", duration %"
GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
}
}
-done:
return res;
-
- /* ERRORS */
-wrong_format:
- {
- GST_DEBUG_OBJECT (avi, "format %s != GST_FORMAT_TIME",
- gst_format_get_name (format));
- res = GST_FLOW_ERROR;
- goto done;
- }
}
/*
if (pad && tags) {
GST_DEBUG_OBJECT (pad, "Tags: %" GST_PTR_FORMAT, tags);
- gst_element_found_tags_for_pad (GST_ELEMENT_CAST (avi), pad, tags);
+ gst_pad_push_event (pad, gst_event_new_tag (tags));
stream->taglist = NULL;
}
}
if (!(tags = avi->globaltags))
- tags = gst_tag_list_new ();
+ tags = gst_tag_list_new_empty ();
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
GST_TAG_CONTAINER_FORMAT, "AVI", NULL);
GST_DEBUG_OBJECT (avi, "Global tags: %" GST_PTR_FORMAT, tags);
- gst_element_found_tags (GST_ELEMENT_CAST (avi), tags);
+ gst_avi_demux_push_event (avi, gst_event_new_tag (tags));
avi->globaltags = NULL;
avi->got_tags = FALSE;
}
avi->state = GST_AVI_DEMUX_MOVI;
break;
case GST_AVI_DEMUX_MOVI:
- if (G_UNLIKELY (avi->close_seg_event)) {
- gst_avi_demux_push_event (avi, avi->close_seg_event);
- avi->close_seg_event = NULL;
- }
if (G_UNLIKELY (avi->seg_event)) {
gst_avi_demux_push_event (avi, avi->seg_event);
avi->seg_event = NULL;
gboolean push_eos = FALSE;
GST_LOG_OBJECT (avi, "pausing task, reason %s", gst_flow_get_name (res));
- avi->segment_running = FALSE;
gst_pad_pause_task (avi->sinkpad);
-
if (res == GST_FLOW_UNEXPECTED) {
/* handle end-of-stream/segment */
+ /* so align our position with the end of it, if there is one
+ * this ensures a subsequent will arrive at correct base/acc time */
+ if (avi->segment.rate > 0.0 &&
+ GST_CLOCK_TIME_IS_VALID (avi->segment.stop))
+ avi->segment.position = avi->segment.stop;
+ else if (avi->segment.rate < 0.0)
+ avi->segment.position = avi->segment.start;
if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gint64 stop;
avi->stream[i].discont = TRUE;
}
- GST_DEBUG ("Store %d bytes in adapter", GST_BUFFER_SIZE (buf));
+ GST_DEBUG ("Store %d bytes in adapter", gst_buffer_get_size (buf));
gst_adapter_push (avi->adapter, buf);
switch (avi->state) {
}
break;
case GST_AVI_DEMUX_MOVI:
- if (G_UNLIKELY (avi->close_seg_event)) {
- gst_avi_demux_push_event (avi, avi->close_seg_event);
- avi->close_seg_event = NULL;
- }
if (G_UNLIKELY (avi->seg_event)) {
gst_avi_demux_push_event (avi, avi->seg_event);
avi->seg_event = NULL;
static gboolean
gst_avi_demux_sink_activate (GstPad * sinkpad)
{
- if (gst_pad_check_pull_range (sinkpad)) {
- GST_DEBUG ("going to pull mode");
- return gst_pad_activate_pull (sinkpad, TRUE);
- } else {
- GST_DEBUG ("going to push (streaming) mode");
+ GstQuery *query;
+ gboolean pull_mode;
+
+ query = gst_query_new_scheduling ();
+
+ if (!gst_pad_peer_query (sinkpad, query)) {
+ gst_query_unref (query);
+ goto activate_push;
+ }
+
+ gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+ gst_query_unref (query);
+
+ if (!pull_mode)
+ goto activate_push;
+
+ GST_DEBUG_OBJECT (sinkpad, "activating pull");
+ return gst_pad_activate_pull (sinkpad, TRUE);
+
+activate_push:
+ {
+ GST_DEBUG_OBJECT (sinkpad, "activating push");
return gst_pad_activate_push (sinkpad, TRUE);
}
}
GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (sinkpad));
if (active) {
- avi->segment_running = TRUE;
avi->streaming = FALSE;
return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop,
sinkpad);
} else {
- avi->segment_running = FALSE;
return gst_pad_stop_task (sinkpad);
}
}