* <refsect2>
* <title>Example launch line</title>
* |[
- * gst-launch filesrc location=test.mov ! qtdemux name=demux demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
+ * gst-launch filesrc location=test.mov ! qtdemux name=demux demux.audio_0 ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_0 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
* ]| Play (parse and decode) a .mov file and try to output it to
* an automatically detected soundcard and videosink. If the MOV file contains
* compressed audio or video data, this will only work if you have the
#include <glib/gprintf.h>
#include <gst/tag/tag.h>
+#include <gst/audio/audio.h>
#include "qtatomparser.h"
#include "qtdemux_types.h"
);
static GstStaticPadTemplate gst_qtdemux_videosrc_template =
-GST_STATIC_PAD_TEMPLATE ("video_%02d",
+GST_STATIC_PAD_TEMPLATE ("video_%u",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate gst_qtdemux_audiosrc_template =
-GST_STATIC_PAD_TEMPLATE ("audio_%02d",
+GST_STATIC_PAD_TEMPLATE ("audio_%u",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate gst_qtdemux_subsrc_template =
-GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
+GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
-GST_BOILERPLATE (GstQTDemux, gst_qtdemux, GstQTDemux, GST_TYPE_ELEMENT);
+#define gst_qtdemux_parent_class parent_class
+G_DEFINE_TYPE (GstQTDemux, gst_qtdemux, GST_TYPE_ELEMENT);
static void gst_qtdemux_dispose (GObject * object);
static GstFlowReturn qtdemux_expose_streams (GstQTDemux * qtdemux);
static void
-gst_qtdemux_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_videosrc_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_audiosrc_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&gst_qtdemux_subsrc_template));
- gst_element_class_set_details_simple (element_class, "QuickTime demuxer",
- "Codec/Demuxer",
- "Demultiplex a QuickTime file into audio and video streams",
- "David Schleef <ds@schleef.org>, Wim Taymans <wim@fluendo.com>");
-
- GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin");
-}
-
-static void
gst_qtdemux_class_init (GstQTDemuxClass * klass)
{
GObjectClass *gobject_class;
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
gst_tag_register_musicbrainz_tags ();
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_qtdemux_sink_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_qtdemux_videosrc_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_qtdemux_audiosrc_template));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&gst_qtdemux_subsrc_template));
+ gst_element_class_set_details_simple (gstelement_class, "QuickTime demuxer",
+ "Codec/Demuxer",
+ "Demultiplex a QuickTime file into audio and video streams",
+ "David Schleef <ds@schleef.org>, Wim Taymans <wim@fluendo.com>");
+
+ GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin");
+
}
static void
-gst_qtdemux_init (GstQTDemux * qtdemux, GstQTDemuxClass * klass)
+gst_qtdemux_init (GstQTDemux * qtdemux)
{
qtdemux->sinkpad =
gst_pad_new_from_static_template (&gst_qtdemux_sink_template, "sink");
}
}
+static void
+_gst_buffer_copy_into_mem (GstBuffer * dest, const guint8 * src,
+ gsize offset, gsize size)
+{
+ guint8 *bdata;
+ gsize bsize;
+
+ g_return_if_fail (gst_buffer_is_writable (dest));
+
+ bsize = gst_buffer_get_size (dest);
+ g_return_if_fail (bsize >= offset + size);
+
+ bdata = gst_buffer_map (dest, &bsize, NULL, GST_MAP_WRITE);
+ memcpy (bdata + offset, src, size);
+ gst_buffer_unmap (dest, bdata, bsize);
+}
+
+static GstBuffer *
+_gst_buffer_new_wrapped (gpointer mem, gsize size, GFreeFunc free_func)
+{
+ GstBuffer *buf;
+
+ buf = gst_buffer_new ();
+ gst_buffer_take_memory (buf, -1,
+ gst_memory_new_wrapped (free_func ? 0 : GST_MEMORY_FLAG_READONLY,
+ mem, free_func, size, 0, size));
+
+ return buf;
+}
+
static GstFlowReturn
gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
GstBuffer ** buf)
{
GstFlowReturn flow;
+ guint8 *bdata;
+ gsize bsize;
if (G_UNLIKELY (size == 0)) {
GstFlowReturn ret;
if (ret != GST_FLOW_OK)
return ret;
- size = QT_UINT32 (GST_BUFFER_DATA (tmp));
+ bdata = gst_buffer_map (tmp, &bsize, NULL, GST_MAP_READ);
+ size = QT_UINT32 (bdata);
GST_DEBUG_OBJECT (qtdemux, "size 0x%08" G_GINT64_MODIFIER "x", size);
+ gst_buffer_unmap (tmp, bdata, bsize);
gst_buffer_unref (tmp);
}
if (G_UNLIKELY (flow != GST_FLOW_OK))
return flow;
+ bsize = gst_buffer_get_size (*buf);
/* Catch short reads - we don't want any partial atoms */
- if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size)) {
+ if (G_UNLIKELY (bsize < size)) {
GST_WARNING_OBJECT (qtdemux, "short read: %u < %" G_GUINT64_FORMAT,
- GST_BUFFER_SIZE (*buf), size);
+ bsize, size);
gst_buffer_unref (*buf);
*buf = NULL;
return GST_FLOW_UNEXPECTED;
}
#endif
-static const GstQueryType *
-gst_qtdemux_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType src_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_CONVERT,
- GST_QUERY_FORMATS,
- GST_QUERY_SEEKING,
- 0
- };
-
- return src_types;
-}
-
static gboolean
gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
{
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_POSITION:
- if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.last_stop)) {
+ if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.position)) {
gst_query_set_position (query, GST_FORMAT_TIME,
- qtdemux->segment.last_stop);
+ qtdemux->segment.position);
res = TRUE;
}
break;
/* get the index of the sample with media time */
index = gst_qtdemux_find_index_linear (qtdemux, str, media_start);
- GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
- GST_TIME_ARGS (media_start), index);
+ GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u"
+ " at offset %" G_GUINT64_FORMAT,
+ GST_TIME_ARGS (media_start), index, str->samples[index].offset);
/* find previous keyframe */
kindex = gst_qtdemux_find_keyframe (qtdemux, str, index);
media_time =
gst_util_uint64_scale (str->samples[kindex].timestamp, GST_SECOND,
str->timescale);
- GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT,
- kindex, GST_TIME_ARGS (media_time));
+ GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT
+ " at offset %" G_GUINT64_FORMAT,
+ kindex, GST_TIME_ARGS (media_time), str->samples[kindex].offset);
/* keyframes in the segment get a chance to change the
* desired_offset. keyframes out of the segment are
GstSeekType cur_type, gint64 * cur, GstSeekType stop_type, gint64 * stop)
{
gboolean res;
- GstFormat fmt;
g_return_val_if_fail (format != NULL, FALSE);
g_return_val_if_fail (cur != NULL, FALSE);
if (*format == GST_FORMAT_TIME)
return TRUE;
- fmt = GST_FORMAT_TIME;
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)
*format = GST_FORMAT_TIME;
gint64 desired_offset;
gint n;
- desired_offset = segment->last_stop;
+ desired_offset = segment->position;
GST_DEBUG_OBJECT (qtdemux, "seeking to %" GST_TIME_FORMAT,
GST_TIME_ARGS (desired_offset));
- if (segment->flags & GST_SEEK_FLAG_KEY_UNIT) {
+ /* may not have enough fragmented info to do this adjustment,
+ * and we can't scan (and probably should not) at this time with
+ * possibly flushing upstream */
+ if ((segment->flags & GST_SEEK_FLAG_KEY_UNIT) && !qtdemux->fragmented) {
gint64 min_offset;
gst_qtdemux_adjust_seek (qtdemux, desired_offset, &min_offset, NULL);
stream->segment_index = -1;
stream->last_ret = GST_FLOW_OK;
stream->sent_eos = FALSE;
+
+ if (segment->flags & GST_SEEK_FLAG_FLUSH)
+ gst_segment_init (&stream->segment, GST_FORMAT_TIME);
}
- segment->last_stop = desired_offset;
+ segment->position = desired_offset;
segment->time = desired_offset;
/* we stop at the end */
if (event) {
/* configure the segment with the seek variables */
GST_DEBUG_OBJECT (qtdemux, "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);
}
/* prepare for streaming again */
if (flush) {
- gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop ());
- gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop ());
- } else if (qtdemux->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 (qtdemux, "closing running segment %" G_GINT64_FORMAT
- " to %" G_GINT64_FORMAT, qtdemux->segment.start,
- qtdemux->segment.last_stop);
-
- if (qtdemux->segment.rate >= 0) {
- /* FIXME, rate is the product of the global rate and the (quicktime)
- * segment rate. */
- qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
- qtdemux->segment.rate, qtdemux->segment.format,
- qtdemux->segment.start, qtdemux->segment.last_stop,
- qtdemux->segment.time);
- } else { /* For Reverse Playback */
- guint64 stop;
-
- if ((stop = qtdemux->segment.stop) == -1)
- stop = qtdemux->segment.duration;
- /* for reverse playback, we played from stop to last_stop. */
- qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
- qtdemux->segment.rate, qtdemux->segment.format,
- qtdemux->segment.last_stop, stop, qtdemux->segment.last_stop);
- }
+ gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop (TRUE));
+ gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop (TRUE));
}
/* commit the new segment */
if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
gst_message_new_segment_start (GST_OBJECT_CAST (qtdemux),
- qtdemux->segment.format, qtdemux->segment.last_stop));
+ qtdemux->segment.format, qtdemux->segment.position));
}
- /* restart streaming, NEWSEGMENT will be sent from the streaming
- * thread. */
- qtdemux->segment_running = TRUE;
+ /* restart streaming, NEWSEGMENT will be sent from the streaming thread. */
for (i = 0; i < qtdemux->n_streams; i++)
qtdemux->streams[i]->last_ret = GST_FLOW_OK;
GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (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;
+ gint64 offset = 0;
QtDemuxStream *stream;
gint idx;
- gboolean update;
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 (demux,
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
+ gst_event_copy_segment (event, &segment);
+ GST_DEBUG_OBJECT (demux, "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 (start > 0) {
+ if (segment.format == GST_FORMAT_BYTES) {
+ if (GST_CLOCK_TIME_IS_VALID (segment.start)) {
gint64 requested_seek_time;
guint64 seek_offset;
- offset = start;
+ offset = segment.start;
GST_OBJECT_LOCK (demux);
requested_seek_time = demux->requested_seek_time;
GST_OBJECT_UNLOCK (demux);
if (offset == seek_offset) {
- start = requested_seek_time;
+ segment.start = requested_seek_time;
} else {
- gst_qtdemux_find_sample (demux, start, TRUE, FALSE, NULL, NULL,
- &start);
- start = MAX (start, 0);
+ gst_qtdemux_find_sample (demux, segment.start, TRUE, FALSE, NULL,
+ NULL, (gint64 *) & segment.start);
+ if ((gint64) segment.start < 0)
+ segment.start = 0;
}
}
- if (stop > 0) {
- gst_qtdemux_find_sample (demux, stop, FALSE, FALSE, NULL, NULL,
- &stop);
+ if (GST_CLOCK_TIME_IS_VALID (segment.stop)) {
+ gst_qtdemux_find_sample (demux, segment.stop, FALSE, FALSE, NULL,
+ NULL, (gint64 *) & segment.stop);
/* keyframe seeking should already arrange for start >= stop,
* but make sure in other rare cases */
- stop = MAX (stop, start);
+ segment.stop = MAX (segment.stop, segment.start);
}
} else {
GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
}
/* accept upstream's notion of segment and distribute along */
- gst_segment_set_newsegment_full (&demux->segment, update, rate, arate,
- GST_FORMAT_TIME, start, stop, start);
- GST_DEBUG_OBJECT (demux, "Pushing newseg update %d, rate %g, "
- "applied rate %g, format %d, start %" GST_TIME_FORMAT ", "
- "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME,
- GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
+ segment.time = segment.start;
+ segment.duration = demux->segment.duration;
+ segment.base = gst_segment_to_running_time (&demux->segment,
+ GST_FORMAT_TIME, demux->segment.position);
- gst_qtdemux_push_event (demux,
- gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,
- start, stop, start));
+ gst_segment_copy_into (&segment, &demux->segment);
+ GST_DEBUG_OBJECT (demux, "Pushing newseg %" GST_SEGMENT_FORMAT, &segment);
+ gst_qtdemux_push_event (demux, gst_event_new_segment (&segment));
/* clear leftover in current segment, if any */
gst_adapter_clear (demux->adapter);
case GST_EVENT_FLUSH_STOP:
{
gint i;
+ GstClockTime dur;
/* clean up, force EOS if no more info follows */
gst_adapter_clear (demux->adapter);
demux->streams[i]->last_ret = GST_FLOW_OK;
demux->streams[i]->sent_eos = FALSE;
}
+ dur = demux->segment.duration;
+ gst_segment_init (&demux->segment, GST_FORMAT_TIME);
+ demux->segment.duration = dur;
break;
}
case GST_EVENT_EOS:
GST_DEBUG_OBJECT (qtdemux, "major brand: %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (qtdemux->major_brand));
buf = qtdemux->comp_brands = gst_buffer_new_and_alloc (length - 16);
- memcpy (GST_BUFFER_DATA (buf), buffer + 16, GST_BUFFER_SIZE (buf));
+ _gst_buffer_copy_into_mem (buf, buffer + 16, 0, length - 16);
}
}
GstBuffer *buf;
GstTagList *taglist;
- buf = gst_buffer_new ();
- GST_BUFFER_DATA (buf) = (guint8 *) buffer + offset + 16;
- GST_BUFFER_SIZE (buf) = length - offset - 16;
-
+ buf = _gst_buffer_new_wrapped ((guint8 *) buffer + offset + 16,
+ length - offset - 16, NULL);
taglist = gst_tag_list_from_xmp_buffer (buf);
gst_buffer_unref (buf);
stream->track_id, d_sample_duration, d_sample_size, d_sample_flags,
*base_offset);
+ /* presence of stss or not can't really tell us much,
+ * and flags and so on tend to be marginally reliable in these files */
+ if (stream->subtype == FOURCC_soun) {
+ GST_DEBUG_OBJECT (qtdemux,
+ "sound track in fragmented file; marking all keyframes");
+ stream->all_keyframe = TRUE;
+ }
+
if (!gst_byte_reader_skip (trun, 1) ||
!gst_byte_reader_get_uint24_be (trun, &flags))
goto fail;
GstBuffer *buf = NULL;
GstFlowReturn ret = GST_FLOW_OK;
guint64 cur_offset = qtdemux->offset;
+ guint8 *data;
+ gsize size;
ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, 16, &buf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto beach;
- if (G_LIKELY (GST_BUFFER_SIZE (buf) >= 8))
- extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf),
- GST_BUFFER_SIZE (buf), &length, &fourcc);
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ if (G_LIKELY (size >= 8))
+ extract_initial_length_and_fourcc (data, size, &length, &fourcc);
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
/* maybe we already got most we needed, so only consider this eof */
ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &moov);
if (ret != GST_FLOW_OK)
goto beach;
- if (length != GST_BUFFER_SIZE (moov)) {
+ data = gst_buffer_map (moov, &size, NULL, GST_MAP_READ);
+ if (length != size) {
/* Some files have a 'moov' atom at the end of the file which contains
* a terminal 'free' atom where the body of the atom is missing.
* Check for, and permit, this special case.
*/
- if (GST_BUFFER_SIZE (moov) >= 8) {
- guint8 *final_data = GST_BUFFER_DATA (moov) +
- (GST_BUFFER_SIZE (moov) - 8);
+ if (size >= 8) {
+ guint8 *final_data = data + (size - 8);
guint32 final_length = QT_UINT32 (final_data);
guint32 final_fourcc = QT_FOURCC (final_data + 4);
- if (final_fourcc == FOURCC_free &&
- GST_BUFFER_SIZE (moov) + final_length - 8 == length) {
+ gst_buffer_unmap (moov, data, size);
+ if (final_fourcc == FOURCC_free && size + final_length - 8 == length) {
/* Ok, we've found that special case. Allocate a new buffer with
* that free atom actually present. */
GstBuffer *newmoov = gst_buffer_new_and_alloc (length);
- gst_buffer_copy_metadata (newmoov, moov,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
- GST_BUFFER_COPY_CAPS);
- memcpy (GST_BUFFER_DATA (newmoov), GST_BUFFER_DATA (moov),
- GST_BUFFER_SIZE (moov));
- memset (GST_BUFFER_DATA (newmoov) + GST_BUFFER_SIZE (moov), 0,
- final_length - 8);
+ gst_buffer_copy_into (newmoov, moov, 0, 0, size);
+ data = gst_buffer_map (newmoov, &size, NULL, GST_MAP_WRITE);
+ memset (data + length - final_length + 8, 0, final_length - 8);
gst_buffer_unref (moov);
moov = newmoov;
}
}
}
- if (length != GST_BUFFER_SIZE (moov)) {
+ if (length != size) {
GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
(_("This file is incomplete and cannot be played.")),
("We got less than expected (received %u, wanted %u, offset %"
- G_GUINT64_FORMAT ")",
- GST_BUFFER_SIZE (moov), (guint) length, cur_offset));
+ G_GUINT64_FORMAT ")", size, (guint) length, cur_offset));
+ gst_buffer_unmap (moov, data, size);
gst_buffer_unref (moov);
ret = GST_FLOW_ERROR;
goto beach;
}
qtdemux->offset += length;
- qtdemux_parse_moov (qtdemux, GST_BUFFER_DATA (moov), length);
+ qtdemux_parse_moov (qtdemux, data, length);
qtdemux_node_dump (qtdemux, qtdemux->moov_node);
qtdemux_parse_tree (qtdemux);
g_node_destroy (qtdemux->moov_node);
+ gst_buffer_unmap (moov, data, size);
gst_buffer_unref (moov);
qtdemux->moov_node = NULL;
qtdemux->got_moov = TRUE;
if (ret != GST_FLOW_OK)
goto beach;
qtdemux->offset += length;
- qtdemux_parse_ftyp (qtdemux, GST_BUFFER_DATA (ftyp),
- GST_BUFFER_SIZE (ftyp));
+ data = gst_buffer_map (ftyp, &size, NULL, GST_MAP_READ);
+ qtdemux_parse_ftyp (qtdemux, data, size);
+ gst_buffer_unmap (ftyp, data, size);
gst_buffer_unref (ftyp);
break;
}
if (ret != GST_FLOW_OK)
goto beach;
qtdemux->offset += length;
- qtdemux_parse_uuid (qtdemux, GST_BUFFER_DATA (uuid),
- GST_BUFFER_SIZE (uuid));
+ data = gst_buffer_map (uuid, &size, NULL, GST_MAP_READ);
+ qtdemux_parse_uuid (qtdemux, data, size);
+ gst_buffer_unmap (uuid, data, size);
gst_buffer_unref (uuid);
break;
}
ret = gst_qtdemux_pull_atom (qtdemux, cur_offset, length, &unknown);
if (ret != GST_FLOW_OK)
goto beach;
- GST_MEMDUMP ("Unknown tag", GST_BUFFER_DATA (unknown),
- GST_BUFFER_SIZE (unknown));
+ data = gst_buffer_map (unknown, &size, NULL, GST_MAP_READ);
+ GST_MEMDUMP ("Unknown tag", data, size);
+ gst_buffer_unmap (unknown, data, size);
gst_buffer_unref (unknown);
qtdemux->offset += length;
break;
QtDemuxStream *str = qtdemux->streams[n];
seg_idx = gst_qtdemux_find_segment (qtdemux, str,
- qtdemux->segment.last_stop);
+ qtdemux->segment.position);
/* segment not found, continue with normal flow */
if (seg_idx == -1)
k_index, GST_TIME_ARGS (k_pos));
/* Set last_stop with the keyframe timestamp we pushed of that stream */
- gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, last_stop);
+ qtdemux->segment.position = last_stop;
GST_DEBUG_OBJECT (qtdemux, "last_stop now is %" GST_TIME_FORMAT,
GST_TIME_ARGS (last_stop));
/* update the segment values used for clipping */
gst_segment_init (&stream->segment, GST_FORMAT_TIME);
- gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME,
- start, stop, time);
+ /* accumulate previous segments */
+ if (GST_CLOCK_TIME_IS_VALID (stream->segment.stop))
+ stream->segment.base += (stream->segment.stop - stream->segment.start) /
+ ABS (stream->segment.rate);
+ stream->segment.rate = rate;
+ stream->segment.start = start;
+ stream->segment.stop = stop;
+ stream->segment.time = time;
/* now prepare and send the segment */
if (stream->pad) {
- event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,
- start, stop, time);
+ event = gst_event_new_segment (&stream->segment);
gst_pad_push_event (stream->pad, event);
/* assume we can send more data now */
stream->last_ret = GST_FLOW_OK;
end_time = stream->segments[stream->n_segments - 1].stop_time;
GST_LOG_OBJECT (demux, "current position: %" GST_TIME_FORMAT
", stream end: %" GST_TIME_FORMAT,
- GST_TIME_ARGS (demux->segment.last_stop), GST_TIME_ARGS (end_time));
- if (end_time + 2 * GST_SECOND < demux->segment.last_stop) {
+ GST_TIME_ARGS (demux->segment.position), GST_TIME_ARGS (end_time));
+ if (end_time + 2 * GST_SECOND < demux->segment.position) {
GST_DEBUG_OBJECT (demux, "sending EOS for stream %s",
GST_PAD_NAME (stream->pad));
stream->sent_eos = TRUE;
gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
GstBuffer * buf)
{
- gint64 start, stop, cstart, cstop, diff;
+ guint64 start, stop, cstart, cstop, diff;
GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
- guint8 *data;
guint size;
gint num_rate, denom_rate;
gint frame_size;
gboolean clip_data;
+ guint offset;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
+ size = gst_buffer_get_size (buf);
+ offset = 0;
/* depending on the type, setup the clip parameters */
if (stream->subtype == FOURCC_soun) {
"clipping start to %" GST_TIME_FORMAT " %"
G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff);
- data += diff;
+ offset = diff;
size -= diff;
}
}
}
}
+ gst_buffer_resize (buf, offset, size);
GST_BUFFER_TIMESTAMP (buf) = timestamp;
GST_BUFFER_DURATION (buf) = duration;
- GST_BUFFER_SIZE (buf) = size;
- GST_BUFFER_DATA (buf) = data;
return buf;
GstBuffer * buf)
{
guint8 *data;
- guint size, nsize = 0;
+ guint nsize = 0;
+ gsize size;
gchar *str;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
-
/* not many cases for now */
if (G_UNLIKELY (stream->fourcc == FOURCC_mp4s)) {
/* send a one time dvd clut event */
return buf;
}
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
if (G_LIKELY (size >= 2)) {
nsize = GST_READ_UINT16_BE (data);
nsize = MIN (nsize, size - 2);
/* takes care of UTF-8 validation or UTF-16 recognition,
* no other encoding expected */
str = gst_tag_freeform_string_to_utf8 ((gchar *) data + 2, nsize, NULL);
+ gst_buffer_unmap (buf, data, size);
if (str) {
gst_buffer_unref (buf);
- buf = gst_buffer_new ();
- GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = (guint8 *) str;
- GST_BUFFER_SIZE (buf) = strlen (str);
+ buf = _gst_buffer_new_wrapped (str, strlen (str), g_free);
} else {
/* may be 0-size subtitle, which is also sent to keep pipeline going */
- GST_BUFFER_DATA (buf) = data + 2;
- GST_BUFFER_SIZE (buf) = nsize;
+ gst_buffer_resize (buf, 2, nsize);
}
/* FIXME ? convert optional subsequent style info to markup */
if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) {
gchar *url;
+ guint8 *bdata;
+ gsize bsize;
- url = g_strndup ((gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ url = g_strndup ((gchar *) bdata, bsize);
+ gst_buffer_unmap (buf, bdata, bsize);
if (url != NULL && strlen (url) != 0) {
/* we have RTSP redirect now */
gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
/* position reporting */
if (qtdemux->segment.rate >= 0) {
- gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, position);
+ qtdemux->segment.position = position;
gst_qtdemux_sync_streams (qtdemux);
}
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
stream->discont = FALSE;
}
- gst_buffer_set_caps (buffer, stream->caps);
gst_pad_push (stream->pad, buffer);
}
/* we're going to modify the metadata */
- buf = gst_buffer_make_metadata_writable (buf);
+ buf = gst_buffer_make_writable (buf);
if (G_UNLIKELY (stream->need_process))
buf = gst_qtdemux_process_buffer (qtdemux, stream, buf);
GST_BUFFER_OFFSET_END (buf) = -1;
if (G_UNLIKELY (stream->padding)) {
- GST_BUFFER_DATA (buf) += stream->padding;
- GST_BUFFER_SIZE (buf) -= stream->padding;
+ gst_buffer_resize (buf, stream->padding, -1);
}
if (G_UNLIKELY (qtdemux->element_index)) {
if (!keyframe)
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
- gst_buffer_set_caps (buf, stream->caps);
-
GST_LOG_OBJECT (qtdemux,
"Pushing buffer with time %" GST_TIME_FORMAT ", duration %"
GST_TIME_FORMAT " on pad %s", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
{
GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED,
(NULL), ("streaming stopped, invalid state"));
- qtdemux->segment_running = FALSE;
gst_pad_pause_task (pad);
gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
goto done;
GST_LOG_OBJECT (qtdemux, "pausing task, reason %s", reason);
- qtdemux->segment_running = FALSE;
gst_pad_pause_task (pad);
/* fatal errors need special actions */
if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
gint64 stop;
- /* FIXME: I am not sure this is the right fix. If the sinks are
- * supposed to detect the segment is complete and accumulate
- * automatically, it does not seem to work here. Need more work */
- qtdemux->segment_running = TRUE;
-
if ((stop = qtdemux->segment.stop) == -1)
stop = qtdemux->segment.duration;
/* 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 (demux, "doing duration query to fix up unset stop");
- gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
+ gst_pad_query_peer_duration (demux->sinkpad, GST_FORMAT_BYTES, &stop);
}
/* if upstream doesn't know the size, it's likely that it's not seekable in
gst_qtdemux_check_seekability (demux);
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);
+ data = gst_adapter_map (demux->adapter, demux->neededbytes);
/* get fourcc/length, set neededbytes */
extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes,
&size, &fourcc);
+ gst_adapter_unmap (demux->adapter, 0);
+ data = NULL;
GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] "
"size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size);
if (size == 0) {
/* there may be multiple mdat (or alike) buffers */
/* sanity check */
if (demux->mdatbuffer)
- bs = GST_BUFFER_SIZE (demux->mdatbuffer);
+ bs = gst_buffer_get_size (demux->mdatbuffer);
else
bs = 0;
if (size + bs > 10 * (1 << 20))
GST_DEBUG_OBJECT (demux, "In header");
- data = gst_adapter_peek (demux->adapter, demux->neededbytes);
+ data = gst_adapter_map (demux->adapter, demux->neededbytes);
/* parse the header */
extract_initial_length_and_fourcc (data, demux->neededbytes, NULL,
demux->got_moov = TRUE;
/* prepare newsegment to send when streaming actually starts */
- if (!demux->pending_newsegment) {
- demux->pending_newsegment =
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
- 0, GST_CLOCK_TIME_NONE, 0);
- }
+ if (!demux->pending_newsegment)
+ demux->pending_newsegment = gst_event_new_segment (&demux->segment);
qtdemux_parse_moov (demux, data, demux->neededbytes);
qtdemux_node_dump (demux, demux->moov_node);
GST_DEBUG_OBJECT (demux, "Parsing [moof]");
if (!qtdemux_parse_moof (demux, data, demux->neededbytes,
demux->offset, NULL)) {
+ gst_adapter_unmap (demux->adapter, 0);
ret = GST_FLOW_ERROR;
goto done;
}
GST_FOURCC_ARGS (fourcc));
/* Let's jump that one and go back to initial state */
}
+ gst_adapter_unmap (demux->adapter, 0);
+ data = NULL;
if (demux->mdatbuffer && demux->n_streams) {
/* the mdat was before the header */
}
case QTDEMUX_STATE_BUFFER_MDAT:{
GstBuffer *buf;
+ guint8 fourcc[4];
GST_DEBUG_OBJECT (demux, "Got our buffer at offset %" G_GUINT64_FORMAT,
demux->offset);
buf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
+ gst_buffer_extract (buf, 0, fourcc, 4);
GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,
- GST_FOURCC_ARGS (QT_FOURCC (GST_BUFFER_DATA (buf) + 4)));
+ GST_FOURCC_ARGS (QT_FOURCC (fourcc)));
if (demux->mdatbuffer)
demux->mdatbuffer = gst_buffer_join (demux->mdatbuffer, buf);
else
static gboolean
qtdemux_sink_activate (GstPad * sinkpad)
{
- if (gst_pad_check_pull_range (sinkpad))
- return gst_pad_activate_pull (sinkpad, TRUE);
- else
+ 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);
+ }
}
static gboolean
if (active) {
demux->pullbased = TRUE;
- demux->segment_running = TRUE;
return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop,
sinkpad);
} else {
- demux->segment_running = FALSE;
return gst_pad_stop_task (sinkpad);
}
}
switch (type) {
case FOURCC_tCtH:
buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
+ _gst_buffer_copy_into_mem (buffer, buf, 0, size);
stream->buffers = g_slist_append (stream->buffers, buffer);
GST_LOG_OBJECT (qtdemux, "parsing theora header");
break;
case FOURCC_tCt_:
buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
+ _gst_buffer_copy_into_mem (buffer, buf, 0, size);
stream->buffers = g_slist_append (stream->buffers, buffer);
GST_LOG_OBJECT (qtdemux, "parsing theora comment");
break;
case FOURCC_tCtC:
buffer = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buffer), buf, size);
+ _gst_buffer_copy_into_mem (buffer, buf, 0, size);
stream->buffers = g_slist_append (stream->buffers, buffer);
GST_LOG_OBJECT (qtdemux, "parsing theora codebook");
break;
{
/* consistent default for push based mode */
gst_segment_init (&stream->segment, GST_FORMAT_TIME);
- gst_segment_set_newsegment (&stream->segment, FALSE, 1.0, GST_FORMAT_TIME,
- 0, GST_CLOCK_TIME_NONE, 0);
if (stream->subtype == FOURCC_vide) {
- gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams);
+ gchar *name = g_strdup_printf ("video_%u", qtdemux->n_video_streams);
stream->pad =
gst_pad_new_from_static_template (&gst_qtdemux_videosrc_template, name);
/* make sure it's not writable. We leave MALLOCDATA to NULL so that we
* don't free any of the buffer data. */
- palette = gst_buffer_new ();
- GST_BUFFER_FLAG_SET (palette, GST_BUFFER_FLAG_READONLY);
- GST_BUFFER_DATA (palette) = (guint8 *) palette_data;
- GST_BUFFER_SIZE (palette) = sizeof (guint32) * palette_count;
+ palette = _gst_buffer_new_wrapped ((gpointer) palette_data,
+ palette_count, NULL);
gst_caps_set_simple (stream->caps, "palette_data",
GST_TYPE_BUFFER, palette, NULL);
}
qtdemux->n_video_streams++;
} else if (stream->subtype == FOURCC_soun) {
- gchar *name = g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams);
+ gchar *name = g_strdup_printf ("audio_%u", qtdemux->n_audio_streams);
stream->pad =
gst_pad_new_from_static_template (&gst_qtdemux_audiosrc_template, name);
} else if (stream->subtype == FOURCC_strm) {
GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad");
} else if (stream->subtype == FOURCC_subp || stream->subtype == FOURCC_text) {
- gchar *name = g_strdup_printf ("subtitle_%02d", qtdemux->n_sub_streams);
+ gchar *name = g_strdup_printf ("subtitle_%u", qtdemux->n_sub_streams);
stream->pad =
gst_pad_new_from_static_template (&gst_qtdemux_subsrc_template, name);
gst_pad_use_fixed_caps (stream->pad);
gst_pad_set_event_function (stream->pad, gst_qtdemux_handle_src_event);
- gst_pad_set_query_type_function (stream->pad,
- gst_qtdemux_get_src_query_types);
gst_pad_set_query_function (stream->pad, gst_qtdemux_handle_src_query);
GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps);
if (stream->pending_tags)
gst_tag_list_free (stream->pending_tags);
stream->pending_tags = list;
- if (list) {
- /* post now, send event on pad later */
- GST_DEBUG_OBJECT (qtdemux, "Posting tags %" GST_PTR_FORMAT, list);
- gst_element_post_message (GST_ELEMENT (qtdemux),
- gst_message_new_tag_full (GST_OBJECT (qtdemux), stream->pad,
- gst_tag_list_copy (list)));
- }
/* global tags go on each pad anyway */
stream->send_global_tags = TRUE;
}
G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), *offset);
while (TRUE) {
+ guint8 *bdata;
+ gsize bsize;
+
ret = gst_pad_pull_range (qtdemux->sinkpad, *offset, 16, &buf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto locate_failed;
- if (G_LIKELY (GST_BUFFER_SIZE (buf) != 16)) {
+ if (G_UNLIKELY (gst_buffer_get_size (buf) != 16)) {
/* likely EOF */
ret = GST_FLOW_UNEXPECTED;
gst_buffer_unref (buf);
goto locate_failed;
}
- extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), 16, length,
- &lfourcc);
+ bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ extract_initial_length_and_fourcc (bdata, 16, length, &lfourcc);
+ gst_buffer_unmap (buf, bdata, bsize);
gst_buffer_unref (buf);
if (G_UNLIKELY (*length == 0)) {
guint64 length, offset;
GstBuffer *buf = NULL;
GstFlowReturn ret = GST_FLOW_OK;
- GstFlowReturn res = TRUE;
+ GstFlowReturn res = GST_FLOW_OK;
+ guint8 *bdata;
+ gsize bsize;
offset = qtdemux->moof_offset;
GST_DEBUG_OBJECT (qtdemux, "next moof at offset %" G_GUINT64_FORMAT, offset);
ret = gst_qtdemux_pull_atom (qtdemux, offset, length, &buf);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto flow_failed;
- if (!qtdemux_parse_moof (qtdemux, GST_BUFFER_DATA (buf),
- GST_BUFFER_SIZE (buf), offset, NULL)) {
+ bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+ if (!qtdemux_parse_moof (qtdemux, bdata, bsize, offset, NULL)) {
+ gst_buffer_unmap (buf, bdata, bsize);
gst_buffer_unref (buf);
buf = NULL;
goto parse_failed;
}
+ gst_buffer_unmap (buf, bdata, bsize);
gst_buffer_unref (buf);
buf = NULL;
seqh_size = QT_UINT32 (data + 4);
if (seqh_size > 0) {
_seqh = gst_buffer_new_and_alloc (seqh_size);
- memcpy (GST_BUFFER_DATA (_seqh), data + 8, seqh_size);
+ _gst_buffer_copy_into_mem (_seqh, data + 8, 0, seqh_size);
}
}
}
static const guint wb_bitrates[] = {
6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850
};
- const guint8 *data = GST_BUFFER_DATA (buf);
- guint size = QT_UINT32 (data), max_mode;
+ guint8 *data;
+ gsize size, max_mode;
guint16 mode_set;
- if (GST_BUFFER_SIZE (buf) != 0x11) {
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
+ if (size != 0x11) {
GST_DEBUG ("Atom should have size 0x11, not %u", size);
goto bad_data;
}
goto bad_data;
}
+ gst_buffer_unmap (buf, data, size);
return wb ? wb_bitrates[max_mode] : nb_bitrates[max_mode];
bad_data:
+ gst_buffer_unmap (buf, data, size);
return 0;
}
stream->caps =
qtdemux_video_caps (qtdemux, stream, fourcc, stsd_data, &codec);
if (codec) {
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_VIDEO_CODEC, codec, NULL);
g_free (codec);
avc_data + 8 + 1, size - 1);
buf = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size);
+ _gst_buffer_copy_into_mem (buf, avc_data + 0x8, 0, size);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
}
if (!list)
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
if (max_bitrate > 0 && max_bitrate < G_MAXUINT32) {
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
if (len > 0x8) {
len -= 0x8;
buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), data + 8, len);
+ _gst_buffer_copy_into_mem (buf, data + 8, 0, len);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
/* see annex I of the jpeg2000 spec */
GNode *jp2h, *ihdr, *colr, *mjp2, *field, *prefix, *cmap, *cdef;
const guint8 *data;
- guint32 fourcc = 0;
+ const gchar *colorspace;
gint ncomp = 0;
guint32 ncomp_map = 0;
gint32 *comp_map = NULL;
if (QT_UINT8 ((guint8 *) colr->data + 8) == 1) {
switch (QT_UINT32 ((guint8 *) colr->data + 11)) {
case 16:
- fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B');
+ colorspace = "sRGB";
break;
case 17:
- fourcc = GST_MAKE_FOURCC ('G', 'R', 'A', 'Y');
+ colorspace = "GRAY";
break;
case 18:
- fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V');
+ colorspace = "sYUV";
break;
default:
+ colorspace = NULL;
break;
}
}
- if (!fourcc)
+ if (!colorspace)
/* colr is required, and only values 16, 17, and 18 are specified,
- so error if we have no fourcc */
+ so error if we have no colorspace */
break;
/* extract component mapping */
gst_caps_set_simple (stream->caps,
"num-components", G_TYPE_INT, ncomp, NULL);
gst_caps_set_simple (stream->caps,
- "fourcc", GST_TYPE_FOURCC, fourcc, NULL);
+ "colorspace", G_TYPE_STRING, colorspace, NULL);
if (comp_map) {
GValue arr = { 0, };
if (len > 0x8) {
len -= 0x8;
buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), data + 8, len);
+ _gst_buffer_copy_into_mem (buf, data + 8, 0, len);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd");
buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), stsd_data, len);
+ _gst_buffer_copy_into_mem (buf, stsd_data, 0, len);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
case FOURCC_ovc1:
{
GNode *ovc1;
- gchar *ovc1_data;
+ guint8 *ovc1_data;
guint ovc1_len;
GstBuffer *buf;
break;
}
buf = gst_buffer_new_and_alloc (ovc1_len - 198);
- memcpy (GST_BUFFER_DATA (buf), ovc1_data + 198, ovc1_len - 198);
+ _gst_buffer_copy_into_mem (buf, ovc1_data + 198, 0, ovc1_len - 198);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
}
if (enda) {
gst_caps_set_simple (stream->caps,
- "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL);
+ "format", G_TYPE_STRING, "S24_3LE", NULL);
}
break;
}
case FOURCC_owma:
{
GNode *owma;
- const gchar *owma_data, *codec_name = NULL;
+ const guint8 *owma_data;
+ const gchar *codec_name = NULL;
guint owma_len;
GstBuffer *buf;
gint version = 1;
}
wfex = (WAVEFORMATEX *) (owma_data + 36);
buf = gst_buffer_new_and_alloc (owma_len - 54);
- memcpy (GST_BUFFER_DATA (buf), owma_data + 54, owma_len - 54);
+ _gst_buffer_copy_into_mem (buf, owma_data + 54, 0, owma_len - 54);
if (wfex->wFormatTag == 0x0161) {
codec_name = "Windows Media Audio";
version = 2;
GstStructure *s;
gint bitrate = 0;
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_AUDIO_CODEC, codec, NULL);
g_free (codec);
waveheader += 8;
headerlen -= 8;
- headerbuf = gst_buffer_new ();
- GST_BUFFER_DATA (headerbuf) = (guint8 *) waveheader;
- GST_BUFFER_SIZE (headerbuf) = headerlen;
+ headerbuf = gst_buffer_new_and_alloc (headerlen);
+ _gst_buffer_copy_into_mem (headerbuf, waveheader, 0, headerlen);
if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux),
headerbuf, &header, &extra)) {
if (len > 0x4C) {
GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x4C);
- memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x4C, len - 0x4C);
+ _gst_buffer_copy_into_mem (buf, stsd_data + 0x4C, 0, len - 0x4C);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
/* codec-data contains alac atom size and prefix,
* ffmpeg likes it that way, not quite gst-ish though ...*/
buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), alac->data, len);
+ _gst_buffer_copy_into_mem (buf, alac->data, 0, len);
gst_caps_set_simple (stream->caps,
"codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x34);
guint bitrate;
- memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x34, len - 0x34);
+ _gst_buffer_copy_into_mem (buf, stsd_data + 0x34, 0, len - 0x34);
/* If we have enough data, let's try to get the 'damr' atom. See
* the 3GPP container spec (26.244) for more details. */
if ((len - 0x34) > 8 &&
(bitrate = qtdemux_parse_amr_bitrate (buf, amrwb))) {
if (!list)
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_MAXIMUM_BITRATE, bitrate, NULL);
}
stream->caps =
qtdemux_sub_caps (qtdemux, stream, fourcc, stsd_data, &codec);
if (codec) {
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
GST_TAG_SUBTITLE_CODEC, codec, NULL);
g_free (codec);
const gchar *lang_code;
if (!list)
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
/* convert ISO 639-2 code to ISO 639-1 */
lang_code = gst_tag_get_language_code (stream->lang_id);
static void
gst_qtdemux_guess_bitrate (GstQTDemux * qtdemux)
{
- GstFormat format = GST_FORMAT_BYTES;
QtDemuxStream *stream = NULL;
gint64 size, duration, sys_bitrate, sum_bitrate = 0;
gint i;
GST_DEBUG_OBJECT (qtdemux, "Looking for streams with unknown bitrate");
- if (!gst_pad_query_peer_duration (qtdemux->sinkpad, &format, &size) ||
- format != GST_FORMAT_BYTES) {
+ if (!gst_pad_query_peer_duration (qtdemux->sinkpad, GST_FORMAT_BYTES, &size)) {
GST_DEBUG_OBJECT (qtdemux,
"Size in bytes of the stream not known - bailing");
return;
", Stream bitrate = %u", sys_bitrate, bitrate);
if (!stream->pending_tags)
- stream->pending_tags = gst_tag_list_new ();
+ stream->pending_tags = gst_tag_list_new_empty ();
gst_tag_list_add (stream->pending_tags, GST_TAG_MERGE_REPLACE,
GST_TAG_BITRATE, bitrate, NULL);
return ((qtdemux->major_brand & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
GST_MAKE_FOURCC ('3', 'g', 0, 0));
} else if (qtdemux->comp_brands != NULL) {
- guint8 *data = GST_BUFFER_DATA (qtdemux->comp_brands);
- guint size = GST_BUFFER_SIZE (qtdemux->comp_brands);
+ guint8 *data;
+ gsize size;
gboolean res = FALSE;
+ data = gst_buffer_map (qtdemux->comp_brands, &size, NULL, GST_MAP_READ);
while (size >= 4) {
res = res || ((QT_FOURCC (data) & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
GST_MAKE_FOURCC ('3', 'g', 0, 0));
data += 4;
size -= 4;
}
+ gst_buffer_unmap (qtdemux->comp_brands, data, size);
return res;
} else {
return FALSE;
}
}
+static void
+qtdemux_tag_add_id32 (GstQTDemux * demux, const char *tag,
+ const char *tag_bis, GNode * node)
+{
+ guint8 *data;
+ GstBuffer *buf;
+ guint len;
+ GstTagList *taglist = NULL;
+
+ GST_LOG_OBJECT (demux, "parsing ID32");
+
+ data = node->data;
+ len = GST_READ_UINT32_BE (data);
+
+ /* need at least full box and language tag */
+ if (len < 12 + 2)
+ return;
+
+ buf = gst_buffer_new_allocate (NULL, len - 14, 0);
+ gst_buffer_fill (buf, 0, data + 14, len - 14);
+
+ taglist = gst_tag_list_from_id3v2_tag (buf);
+ if (taglist) {
+ GST_LOG_OBJECT (demux, "parsing ok");
+ gst_tag_list_insert (demux->tag_list, taglist, GST_TAG_MERGE_KEEP);
+ } else {
+ GST_LOG_OBJECT (demux, "parsing failed");
+ }
+
+ if (taglist)
+ gst_tag_list_free (taglist);
+
+ gst_buffer_unref (buf);
+}
+
typedef void (*GstQTDemuxAddTagFunc) (GstQTDemux * demux,
const char *tag, const char *tag_bis, GNode * node);
* http://atomicparsley.sourceforge.net/mpeg-4files.html and
* bug #614471
*/
- FOURCC_____, "", NULL, qtdemux_tag_add_revdns}
+ FOURCC_____, "", NULL, qtdemux_tag_add_revdns}, {
+ /* see http://www.mp4ra.org/specs.html for ID32 in meta box */
+ FOURCC_ID32, "", NULL, qtdemux_tag_add_id32}
};
static void
data = node->data;
len = QT_UINT32 (data);
buf = gst_buffer_new_and_alloc (len);
- memcpy (GST_BUFFER_DATA (buf), data, len);
+ _gst_buffer_copy_into_mem (buf, data, 0, len);
/* heuristic to determine style of tag */
if (QT_FOURCC (data + 4) == FOURCC_____ ||
GST_DEBUG_OBJECT (demux, "media type %s", media_type);
caps = gst_caps_new_simple (media_type, "style", G_TYPE_STRING, style, NULL);
- gst_buffer_set_caps (buf, caps);
+ // TODO conver to metadata or ???
+// gst_buffer_set_caps (buf, caps);
gst_caps_unref (caps);
g_free (media_type);
GST_DEBUG_OBJECT (demux, "adding private tag; size %d, caps %" GST_PTR_FORMAT,
- GST_BUFFER_SIZE (buf), caps);
+ len, caps);
gst_tag_list_add (demux->tag_list, GST_TAG_MERGE_APPEND,
GST_QT_DEMUX_PRIVATE_TAG, buf, NULL);
GST_DEBUG_OBJECT (qtdemux, "new tag list");
if (!qtdemux->tag_list)
- qtdemux->tag_list = gst_tag_list_new ();
+ qtdemux->tag_list = gst_tag_list_new_empty ();
i = 0;
while (i < G_N_ELEMENTS (add_funcs)) {
GstBuffer *buf;
GstTagList *taglist;
- buf = gst_buffer_new ();
- GST_BUFFER_DATA (buf) = ((guint8 *) xmp_->data) + 8;
- GST_BUFFER_SIZE (buf) = QT_UINT32 ((guint8 *) xmp_->data) - 8;
-
+ buf = _gst_buffer_new_wrapped (((guint8 *) xmp_->data) + 8,
+ QT_UINT32 ((guint8 *) xmp_->data) - 8, NULL);
taglist = gst_tag_list_from_xmp_buffer (buf);
gst_buffer_unref (buf);
const gchar *fmt;
if (tags == NULL)
- tags = gst_tag_list_new ();
+ tags = gst_tag_list_new_empty ();
if (qtdemux->major_brand == FOURCC_mjp2)
fmt = "Motion JPEG 2000";
/* Moving qt creation time (secs since 1904) to unix time */
if (creation_time != 0) {
if (creation_time > QTDEMUX_SECONDS_FROM_1904_TO_1970) {
+ GTimeVal now;
+
creation_time -= QTDEMUX_SECONDS_FROM_1904_TO_1970;
- datetime = gst_date_time_new_from_unix_epoch_local_time (creation_time);
+ /* some data cleansing sanity */
+ g_get_current_time (&now);
+ if (now.tv_sec + 24 * 3600 < creation_time) {
+ GST_DEBUG_OBJECT (qtdemux, "discarding bogus future creation time");
+ } else {
+ datetime = gst_date_time_new_from_unix_epoch_local_time (creation_time);
+ }
} else {
GST_WARNING_OBJECT (qtdemux, "Can't handle datetimes before 1970 yet, "
"please file a bug at http://bugzilla.gnome.org");
}
if (datetime) {
if (!qtdemux->tag_list)
- qtdemux->tag_list = gst_tag_list_new ();
+ qtdemux->tag_list = gst_tag_list_new_empty ();
/* Use KEEP as explicit tags should have a higher priority than mvhd tag */
gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_KEEP, GST_TAG_DATE_TIME,
/* set duration in the segment info */
gst_qtdemux_get_duration (qtdemux, &duration);
- if (duration)
- gst_segment_set_duration (&qtdemux->segment, GST_FORMAT_TIME, duration);
+ if (duration) {
+ qtdemux->segment.duration = duration;
+ /* also do not exceed duration; stop is set that way post seek anyway,
+ * and segment activation falls back to duration,
+ * whereas loop only checks stop, so let's align this here as well */
+ qtdemux->segment.stop = duration;
+ }
/* parse all traks */
trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
GST_LOG_OBJECT (qtdemux, "No udta node found.");
}
+ /* maybe also some tags in meta box */
+ udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_meta);
+ if (udta) {
+ GST_DEBUG_OBJECT (qtdemux, "Parsing meta box for tags.");
+ qtdemux_parse_udta (qtdemux, udta);
+ } else {
+ GST_LOG_OBJECT (qtdemux, "No meta node found.");
+ }
+
qtdemux->tag_list = qtdemux_add_container_format (qtdemux, qtdemux->tag_list);
return TRUE;
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
break;
case 0x6C: /* MJPEG */
- caps = gst_caps_new_simple ("image/jpeg", NULL);
+ caps = gst_caps_new_empty_simple ("image/jpeg");
codec_name = "Motion-JPEG";
break;
case 0x6D: /* PNG */
- caps = gst_caps_new_simple ("image/png", NULL);
+ caps = gst_caps_new_empty_simple ("image/png");
codec_name = "PNG still images";
break;
case 0x6E: /* JPEG2000 */
break;
case 0xA4: /* Dirac */
codec_name = "Dirac";
- caps = gst_caps_new_simple ("video/x-dirac", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-dirac");
break;
case 0xA5: /* AC3 */
codec_name = "AC-3 audio";
case 0xE1: /* QCELP */
/* QCELP, the codec_data is a riff tag (little endian) with
* more info (http://ftp.3gpp2.org/TSGC/Working/2003/2003-05-SanDiego/TSG-C-2003-05-San%20Diego/WG1/SWG12/C12-20030512-006%20=%20C12-20030217-015_Draft_Baseline%20Text%20of%20FFMS_R2.doc). */
- caps = gst_caps_new_simple ("audio/qcelp", NULL);
+ caps = gst_caps_new_empty_simple ("audio/qcelp");
codec_name = "QCELP";
break;
default:
GstBuffer *buffer;
buffer = gst_buffer_new_and_alloc (data_len);
- memcpy (GST_BUFFER_DATA (buffer), data_ptr, data_len);
+ _gst_buffer_copy_into_mem (buffer, data_ptr, 0, data_len);
GST_DEBUG_OBJECT (qtdemux, "setting codec_data from esds");
GST_MEMDUMP_OBJECT (qtdemux, "codec_data from esds", data_ptr, data_len);
switch (fourcc) {
case GST_MAKE_FOURCC ('p', 'n', 'g', ' '):
_codec ("PNG still images");
- caps = gst_caps_new_simple ("image/png", NULL);
+ caps = gst_caps_new_empty_simple ("image/png");
break;
case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'):
_codec ("JPEG still images");
- caps = gst_caps_new_simple ("image/jpeg", NULL);
+ caps = gst_caps_new_empty_simple ("image/jpeg");
break;
case GST_MAKE_FOURCC ('m', 'j', 'p', 'a'):
case GST_MAKE_FOURCC ('A', 'V', 'D', 'J'):
case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'):
case GST_MAKE_FOURCC ('d', 'm', 'b', '1'):
_codec ("Motion-JPEG");
- caps = gst_caps_new_simple ("image/jpeg", NULL);
+ caps = gst_caps_new_empty_simple ("image/jpeg");
break;
case GST_MAKE_FOURCC ('m', 'j', 'p', 'b'):
_codec ("Motion-JPEG format B");
- caps = gst_caps_new_simple ("video/x-mjpeg-b", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-mjpeg-b");
break;
case GST_MAKE_FOURCC ('m', 'j', 'p', '2'):
_codec ("JPEG-2000");
_codec ("Raw RGB video");
bps = QT_UINT16 (stsd_data + 98);
/* set common stuff */
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "endianness", G_TYPE_INT, G_BYTE_ORDER, "depth", G_TYPE_INT, bps,
- NULL);
+ caps = gst_caps_new_empty_simple ("video/x-raw");
switch (bps) {
case 15:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0x7c00,
- "green_mask", G_TYPE_INT, 0x03e0,
- "blue_mask", G_TYPE_INT, 0x001f, NULL);
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB15", NULL);
break;
case 16:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 16,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0xf800,
- "green_mask", G_TYPE_INT, 0x07e0,
- "blue_mask", G_TYPE_INT, 0x001f, NULL);
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB16", NULL);
break;
case 24:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 24,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0xff0000,
- "green_mask", G_TYPE_INT, 0x00ff00,
- "blue_mask", G_TYPE_INT, 0x0000ff, NULL);
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB", NULL);
break;
case 32:
- gst_caps_set_simple (caps,
- "bpp", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "alpha_mask", G_TYPE_INT, 0xff000000,
- "red_mask", G_TYPE_INT, 0x00ff0000,
- "green_mask", G_TYPE_INT, 0x0000ff00,
- "blue_mask", G_TYPE_INT, 0x000000ff, NULL);
+ gst_caps_set_simple (caps, "format", G_TYPE_STRING, "ARGB", NULL);
break;
default:
/* unknown */
}
case GST_MAKE_FOURCC ('y', 'v', '1', '2'):
_codec ("Raw planar YUV 4:2:0");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
- NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "I420", NULL);
break;
case GST_MAKE_FOURCC ('y', 'u', 'v', '2'):
case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'):
_codec ("Raw packed YUV 4:2:2");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
- NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "YUY2", NULL);
break;
case GST_MAKE_FOURCC ('2', 'v', 'u', 'y'):
case GST_MAKE_FOURCC ('2', 'V', 'u', 'y'):
_codec ("Raw packed YUV 4:2:2");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
- NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "UYVY", NULL);
break;
case GST_MAKE_FOURCC ('v', '2', '1', '0'):
_codec ("Raw packed YUV 10-bit 4:2:2");
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('v', '2', '1', '0'),
- NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "v210", NULL);
break;
case GST_MAKE_FOURCC ('r', '2', '1', '0'):
_codec ("Raw packed RGB 10-bit 4:4:4");
- caps = gst_caps_new_simple ("video/x-raw-rgb",
- "endianness", G_TYPE_INT, G_BIG_ENDIAN, "depth", G_TYPE_INT, 30,
- "bpp", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "red_mask", G_TYPE_INT, 0x3ff00000,
- "green_mask", G_TYPE_INT, 0x000ffc00,
- "blue_mask", G_TYPE_INT, 0x000003ff, NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, "r210", NULL);
break;
case GST_MAKE_FOURCC ('m', 'p', 'e', 'g'):
case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
break;
case GST_MAKE_FOURCC ('g', 'i', 'f', ' '):
_codec ("GIF still images");
- caps = gst_caps_new_simple ("image/gif", NULL);
+ caps = gst_caps_new_empty_simple ("image/gif");
break;
case GST_MAKE_FOURCC ('h', '2', '6', '3'):
case GST_MAKE_FOURCC ('H', '2', '6', '3'):
case GST_MAKE_FOURCC ('U', '2', '6', '3'):
_codec ("H.263");
/* ffmpeg uses the height/width props, don't know why */
- caps = gst_caps_new_simple ("video/x-h263", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-h263");
break;
case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
case GST_MAKE_FOURCC ('M', 'P', '4', 'V'):
case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
_codec ("3ivX video");
- caps = gst_caps_new_simple ("video/x-3ivx", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-3ivx");
break;
case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
_codec ("DivX 3");
case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
_codec ("XVID MPEG-4");
- caps = gst_caps_new_simple ("video/x-xvid", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-xvid");
break;
case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
_codec ("Cinepak");
- caps = gst_caps_new_simple ("video/x-cinepak", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-cinepak");
break;
case GST_MAKE_FOURCC ('q', 'd', 'r', 'w'):
_codec ("Apple QuickDraw");
- caps = gst_caps_new_simple ("video/x-qdrw", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-qdrw");
break;
case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'):
_codec ("Apple video");
- caps = gst_caps_new_simple ("video/x-apple-video", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-apple-video");
break;
case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
_codec ("H.264 / AVC");
break;
case GST_MAKE_FOURCC ('s', 'm', 'c', ' '):
_codec ("Apple Graphics (SMC)");
- caps = gst_caps_new_simple ("video/x-smc", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-smc");
break;
case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
_codec ("VP3");
- caps = gst_caps_new_simple ("video/x-vp3", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-vp3");
break;
case GST_MAKE_FOURCC ('X', 'i', 'T', 'h'):
_codec ("Theora");
- caps = gst_caps_new_simple ("video/x-theora", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-theora");
/* theora uses one byte of padding in the data stream because it does not
* allow 0 sized packets while theora does */
stream->padding = 1;
break;
case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
_codec ("Dirac");
- caps = gst_caps_new_simple ("video/x-dirac", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-dirac");
break;
case GST_MAKE_FOURCC ('t', 'i', 'f', 'f'):
_codec ("TIFF still images");
- caps = gst_caps_new_simple ("image/tiff", NULL);
+ caps = gst_caps_new_empty_simple ("image/tiff");
break;
case GST_MAKE_FOURCC ('i', 'c', 'o', 'd'):
_codec ("Apple Intermediate Codec");
case FOURCC_ovc1:
_codec ("VC-1");
caps = gst_caps_new_simple ("video/x-wmv",
- "wmvversion", G_TYPE_INT, 3,
- "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),
- NULL);
+ "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
break;
case GST_MAKE_FOURCC ('k', 'p', 'c', 'd'):
default:
s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
+ caps = gst_caps_new_empty_simple (s);
break;
}
}
/* enable clipping for raw video streams */
s = gst_caps_get_structure (caps, 0);
name = gst_structure_get_name (s);
- if (g_str_has_prefix (name, "video/x-raw-")) {
+ if (g_str_has_prefix (name, "video/x-raw")) {
stream->need_clip = TRUE;
}
return caps;
case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):
case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
_codec ("Raw 8-bit PCM audio");
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 8,
- "depth", G_TYPE_INT, 8, "signed", G_TYPE_BOOLEAN, FALSE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, "U8", NULL);
break;
case GST_MAKE_FOURCC ('t', 'w', 'o', 's'):
endian = G_BIG_ENDIAN;
{
gchar *str;
gint depth;
+ GstAudioFormat format;
if (!endian)
endian = G_LITTLE_ENDIAN;
depth = stream->bytes_per_packet * 8;
+ format = gst_audio_format_build_integer (TRUE, endian, depth, depth);
+
str = g_strdup_printf ("Raw %d-bit PCM audio", depth);
_codec (str);
g_free (str);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, depth, "depth", G_TYPE_INT, depth,
- "endianness", G_TYPE_INT, endian,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, gst_audio_format_to_string (format), NULL);
break;
}
case GST_MAKE_FOURCC ('f', 'l', '6', '4'):
_codec ("Raw 64-bit floating-point audio");
- caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 64,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, "F64BE", NULL);
break;
case GST_MAKE_FOURCC ('f', 'l', '3', '2'):
_codec ("Raw 32-bit floating-point audio");
- caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, "F32BE", NULL);
break;
case FOURCC_in24:
_codec ("Raw 24-bit PCM audio");
/* we assume BIG ENDIAN, an enda box will tell us to change this to little
* endian later */
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 24,
- "depth", G_TYPE_INT, 24,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, "S24BE", NULL);
break;
case GST_MAKE_FOURCC ('i', 'n', '3', '2'):
_codec ("Raw 32-bit PCM audio");
- caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 32,
- "depth", G_TYPE_INT, 32,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, "S32BE", NULL);
break;
case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
_codec ("Mu-law audio");
- caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-mulaw");
break;
case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'):
_codec ("A-law audio");
- caps = gst_caps_new_simple ("audio/x-alaw", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-alaw");
break;
case 0x0200736d:
case 0x6d730002:
break;
case GST_MAKE_FOURCC ('O', 'g', 'g', 'V'):
/* ogg/vorbis */
- caps = gst_caps_new_simple ("application/ogg", NULL);
+ caps = gst_caps_new_empty_simple ("application/ogg");
break;
case GST_MAKE_FOURCC ('d', 'v', 'c', 'a'):
_codec ("DV audio");
- caps = gst_caps_new_simple ("audio/x-dv", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-dv");
break;
case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
_codec ("MPEG-4 AAC audio");
break;
case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'):
_codec ("QDesign Music");
- caps = gst_caps_new_simple ("audio/x-qdm", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-qdm");
break;
case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'):
_codec ("QDesign Music v.2");
"bitrate", G_TYPE_INT, QT_UINT32 (data + 40),
"blocksize", G_TYPE_INT, QT_UINT32 (data + 44), NULL);
} else {
- caps = gst_caps_new_simple ("audio/x-qdm2", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-qdm2");
}
break;
case GST_MAKE_FOURCC ('a', 'g', 's', 'm'):
_codec ("GSM audio");
- caps = gst_caps_new_simple ("audio/x-gsm", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-gsm");
break;
case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'):
_codec ("AMR audio");
- caps = gst_caps_new_simple ("audio/AMR", NULL);
+ caps = gst_caps_new_empty_simple ("audio/AMR");
break;
case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'):
_codec ("AMR-WB audio");
- caps = gst_caps_new_simple ("audio/AMR-WB", NULL);
+ caps = gst_caps_new_empty_simple ("audio/AMR-WB");
break;
case GST_MAKE_FOURCC ('i', 'm', 'a', '4'):
_codec ("Quicktime IMA ADPCM");
break;
case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'):
_codec ("Apple lossless audio");
- caps = gst_caps_new_simple ("audio/x-alac", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-alac");
break;
case GST_MAKE_FOURCC ('Q', 'c', 'l', 'p'):
_codec ("QualComm PureVoice");
break;
case FOURCC_owma:
_codec ("WMA");
- caps = gst_caps_new_simple ("audio/x-wma", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-wma");
break;
case GST_MAKE_FOURCC ('q', 't', 'v', 'r'):
/* ? */
s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
+ caps = gst_caps_new_empty_simple (s);
break;
}
}
/* enable clipping for raw audio streams */
s = gst_caps_get_structure (caps, 0);
name = gst_structure_get_name (s);
- if (g_str_has_prefix (name, "audio/x-raw-")) {
+ if (g_str_has_prefix (name, "audio/x-raw")) {
stream->need_clip = TRUE;
}
return caps;
switch (fourcc) {
case GST_MAKE_FOURCC ('m', 'p', '4', 's'):
_codec ("DVD subtitle");
- caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
break;
case GST_MAKE_FOURCC ('t', 'e', 'x', 't'):
_codec ("Quicktime timed text");
case GST_MAKE_FOURCC ('t', 'x', '3', 'g'):
_codec ("3GPP timed text");
text:
- caps = gst_caps_new_simple ("text/plain", NULL);
+ caps = gst_caps_new_empty_simple ("text/plain");
/* actual text piece needs to be extracted */
stream->need_process = TRUE;
break;
s = g_strdup_printf ("text/x-gst-fourcc-%" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fourcc));
- caps = gst_caps_new_simple (s, NULL);
+ caps = gst_caps_new_empty_simple (s);
break;
}
}