dnl Non ported plugins (non-dependant, then dependant)
dnl Make sure you have a space before and after all plugins
GST_PLUGINS_NONPORTED="deinterlace flx goom2k1 \
- imagefreeze interleave matroska monoscope smpte \
+ imagefreeze interleave monoscope smpte \
videobox videomixer \
cairo cairo_gobject dv1394 gdk_pixbuf libdv libpng \
oss oss4 shout2 \
guint64 offset)
{
GstEbmlMaster m;
+ gsize buf_size;
g_return_if_fail (el);
g_return_if_fail (buf);
ebml->el = el;
ebml->offset = offset;
ebml->buf = buf;
+ ebml->buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
ebml->readers = g_array_sized_new (FALSE, FALSE, sizeof (GstEbmlMaster), 10);
m.offset = ebml->offset;
- gst_byte_reader_init (&m.br, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ gst_byte_reader_init (&m.br, ebml->buf_data, buf_size);
g_array_append_val (ebml->readers, m);
}
if (ebml->readers)
g_array_free (ebml->readers, TRUE);
ebml->readers = NULL;
- if (ebml->buf)
+ if (ebml->buf) {
+ gst_buffer_unmap (ebml->buf, ebml->buf_data, -1);
gst_buffer_unref (ebml->buf);
+ }
ebml->buf = NULL;
ebml->el = NULL;
}
offset = gst_ebml_read_get_pos (ebml) - ebml->offset;
if (G_LIKELY (gst_byte_reader_skip (gst_ebml_read_br (ebml), length))) {
- *buf = gst_buffer_create_sub (ebml->buf, offset, length);
+ *buf = gst_buffer_copy_region (ebml->buf, GST_BUFFER_COPY_ALL,
+ offset, length);
} else {
*buf = NULL;
return GST_FLOW_PARSE;
GstElement *el;
GstBuffer *buf;
+ gpointer buf_data;
guint64 offset;
GArray *readers;
GST_DEBUG_CATEGORY_STATIC (gst_ebml_write_debug);
#define GST_CAT_DEFAULT gst_ebml_write_debug
-#define _do_init(thing) \
+#define _do_init \
GST_DEBUG_CATEGORY_INIT (gst_ebml_write_debug, "ebmlwrite", 0, "Write EBML structured data")
-GST_BOILERPLATE_FULL (GstEbmlWrite, gst_ebml_write, GstObject, GST_TYPE_OBJECT,
+#define parent_class gst_ebml_write_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstEbmlWrite, gst_ebml_write, GST_TYPE_OBJECT,
_do_init);
static void gst_ebml_write_finalize (GObject * object);
static void
-gst_ebml_write_base_init (gpointer g_class)
-{
-}
-
-static void
gst_ebml_write_class_init (GstEbmlWriteClass * klass)
{
GObjectClass *object = G_OBJECT_CLASS (klass);
}
static void
-gst_ebml_write_init (GstEbmlWrite * ebml, GstEbmlWriteClass * klass)
+gst_ebml_write_init (GstEbmlWrite * ebml)
{
ebml->srcpad = NULL;
ebml->pos = 0;
- ebml->last_pos = G_MAXUINT64; /* force newsegment event */
+ ebml->last_pos = G_MAXUINT64; /* force segment event */
ebml->cache = NULL;
ebml->streamheader = NULL;
ebml->caps = NULL;
}
- GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
gst_ebml_write_reset (GstEbmlWrite * ebml)
{
ebml->pos = 0;
- ebml->last_pos = G_MAXUINT64; /* force newsegment event */
+ ebml->last_pos = G_MAXUINT64; /* force segment event */
if (ebml->cache) {
gst_byte_writer_free (ebml->cache);
buffer = gst_byte_writer_free_and_get_buffer (ebml->streamheader);
ebml->streamheader = NULL;
- GST_DEBUG ("Streamheader was size %d", GST_BUFFER_SIZE (buffer));
+ GST_DEBUG ("Streamheader was size %d", gst_buffer_get_size (buffer));
ebml->writing_streamheader = FALSE;
return buffer;
}
static gboolean
-gst_ebml_writer_send_new_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
+gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
{
+ GstSegment segment;
gboolean res;
GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);
- res = gst_pad_push_event (ebml->srcpad,
- gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, new_pos, -1, 0));
+ gst_segment_init (&segment, GST_FORMAT_BYTES);
+ segment.start = new_pos;
+ segment.stop = -1;
+ segment.position = 0;
+
+ res = gst_pad_push_event (ebml->srcpad, gst_event_new_segment (&segment));
if (!res)
GST_WARNING ("seek to %" G_GUINT64_FORMAT "failed", new_pos);
buffer = gst_byte_writer_free_and_get_buffer (ebml->cache);
ebml->cache = NULL;
- GST_DEBUG ("Flushing cache of size %d", GST_BUFFER_SIZE (buffer));
- gst_buffer_set_caps (buffer, ebml->caps);
+ GST_DEBUG ("Flushing cache of size %d", gst_buffer_get_size (buffer));
GST_BUFFER_TIMESTAMP (buffer) = timestamp;
- GST_BUFFER_OFFSET (buffer) = ebml->pos - GST_BUFFER_SIZE (buffer);
+ GST_BUFFER_OFFSET (buffer) = ebml->pos - gst_buffer_get_size (buffer);
GST_BUFFER_OFFSET_END (buffer) = ebml->pos;
if (ebml->last_write_result == GST_FLOW_OK) {
if (GST_BUFFER_OFFSET (buffer) != ebml->last_pos) {
- gst_ebml_writer_send_new_segment_event (ebml, GST_BUFFER_OFFSET (buffer));
+ gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buffer));
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
}
if (ebml->writing_streamheader) {
buf = gst_buffer_new_and_alloc (size);
GST_BUFFER_TIMESTAMP (buf) = ebml->timestamp;
- *data_out = GST_BUFFER_DATA (buf);
+ *data_out = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
return buf;
}
{
guint data_size;
- if (!buf_data)
- buf_data = GST_BUFFER_DATA (buf);
-
- if (buf_data_end) {
+ if (buf_data_end)
data_size = buf_data_end - buf_data;
- GST_BUFFER_SIZE (buf) = data_size;
- } else {
- data_size = GST_BUFFER_SIZE (buf);
- }
+ else
+ data_size = gst_buffer_get_size (buf);
ebml->pos += data_size;
/* if there's no cache, then don't push it! */
if (ebml->writing_streamheader) {
+ if (!buf_data)
+ buf_data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
gst_byte_writer_put_data (ebml->streamheader, buf_data, data_size);
}
if (ebml->cache) {
+ if (!buf_data)
+ buf_data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
gst_byte_writer_put_data (ebml->cache, buf_data, data_size);
+ gst_buffer_unmap (buf, buf_data, -1);
gst_buffer_unref (buf);
return;
}
+ if (buf_data)
+ gst_buffer_unmap (buf, buf_data, -1);
+
if (ebml->last_write_result == GST_FLOW_OK) {
- buf = gst_buffer_make_metadata_writable (buf);
- gst_buffer_set_caps (buf, ebml->caps);
+ buf = gst_buffer_make_writable (buf);
GST_BUFFER_OFFSET (buf) = ebml->pos - data_size;
GST_BUFFER_OFFSET_END (buf) = ebml->pos;
if (ebml->writing_streamheader) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
if (GST_BUFFER_OFFSET (buf) != ebml->last_pos) {
- gst_ebml_writer_send_new_segment_event (ebml, GST_BUFFER_OFFSET (buf));
+ gst_ebml_writer_send_segment_event (ebml, GST_BUFFER_OFFSET (buf));
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
}
ebml->last_pos = ebml->pos;
guint64 extra_size)
{
guint64 pos = ebml->pos;
- GstBuffer *buf;
+ guint8 *data = g_malloc (8);
+ GstBuffer *buf = gst_buffer_new_wrapped (data, 8);
gst_ebml_write_seek (ebml, startpos);
- buf = gst_buffer_new_and_alloc (8);
- GST_WRITE_UINT64_BE (GST_BUFFER_DATA (buf),
+ GST_WRITE_UINT64_BE (data,
(G_GINT64_CONSTANT (1) << 56) | (pos - startpos - 8 + extra_size));
gst_ebml_write_element_push (ebml, buf, NULL, NULL);
gst_ebml_replace_uint (GstEbmlWrite * ebml, guint64 pos, guint64 num)
{
guint64 oldpos = ebml->pos;
- GstBuffer *buf = gst_buffer_new_and_alloc (8);
guint8 *data_start, *data_end;
+ GstBuffer *buf;
- data_start = GST_BUFFER_DATA (buf);
+ data_start = g_malloc (8);
data_end = data_start;
+ buf = gst_buffer_new_wrapped (data_start, 8);
gst_ebml_write_seek (ebml, pos);
gst_ebml_write_set_uint (&data_end, num, 8);
#include <gst/riff/riff-ids.h>
#include <gst/riff/riff-media.h>
+#include <gst/audio/audio.h>
#include <gst/tag/tag.h>
-
#include <gst/pbutils/pbutils.h>
#include "matroska-demux.h"
GstQuery * query);
/* pad functions */
-static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad,
- gboolean active);
-static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad);
+static gboolean gst_matroska_demux_sink_activate (GstPad * sinkpad,
+ GstObject * parent);
+static gboolean gst_matroska_demux_sink_activate_mode (GstPad * sinkpad,
+ GstObject * parent, GstPadMode mode, gboolean active);
static gboolean gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
GstPad * pad, GstEvent * event);
static gboolean gst_matroska_demux_handle_src_event (GstPad * pad,
- GstEvent * event);
-static const GstQueryType *gst_matroska_demux_get_src_query_types (GstPad *
- pad);
+ GstObject * parent, GstEvent * event);
static gboolean gst_matroska_demux_handle_src_query (GstPad * pad,
- GstQuery * query);
+ GstObject * parent, GstQuery * query);
static gboolean gst_matroska_demux_handle_sink_event (GstPad * pad,
- GstEvent * event);
+ GstObject * parent, GstEvent * event);
static GstFlowReturn gst_matroska_demux_chain (GstPad * pad,
- GstBuffer * buffer);
+ GstObject * object, GstBuffer * buffer);
static GstStateChangeReturn
gst_matroska_demux_change_state (GstElement * element,
guint prop_id, GValue * value, GParamSpec * pspec);
GType gst_matroska_demux_get_type (void);
-GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
- GST_TYPE_ELEMENT);
-
-static void
-gst_matroska_demux_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&video_src_templ));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&audio_src_templ));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&subtitle_src_templ));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_templ));
-
- gst_element_class_set_details_simple (element_class, "Matroska demuxer",
- "Codec/Demuxer",
- "Demuxes Matroska/WebM streams into video/audio/subtitles",
- "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-}
+#define parent_class gst_matroska_demux_parent_class
+G_DEFINE_TYPE (GstMatroskaDemux, gst_matroska_demux, GST_TYPE_ELEMENT);
static void
gst_matroska_demux_finalize (GObject * object)
g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
- "The demuxer sends out newsegment events for skipping "
+ "The demuxer sends out segment events for skipping "
"gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
GST_DEBUG_FUNCPTR (gst_matroska_demux_set_index);
gstelement_class->get_index =
GST_DEBUG_FUNCPTR (gst_matroska_demux_get_index);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&video_src_templ));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&audio_src_templ));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&subtitle_src_templ));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_templ));
+
+ gst_element_class_set_details_simple (gstelement_class, "Matroska demuxer",
+ "Codec/Demuxer",
+ "Demuxes Matroska/WebM streams into video/audio/subtitles",
+ "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
}
static void
-gst_matroska_demux_init (GstMatroskaDemux * demux,
- GstMatroskaDemuxClass * klass)
+gst_matroska_demux_init (GstMatroskaDemux * demux)
{
demux->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
"sink");
gst_pad_set_activate_function (demux->common.sinkpad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate));
- gst_pad_set_activatepull_function (demux->common.sinkpad,
- GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_pull));
+ gst_pad_set_activatemode_function (demux->common.sinkpad,
+ GST_DEBUG_FUNCPTR (gst_matroska_demux_sink_activate_mode));
gst_pad_set_chain_function (demux->common.sinkpad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_chain));
gst_pad_set_event_function (demux->common.sinkpad,
demux->next_cluster_offset = 0;
demux->index_offset = 0;
demux->seekable = FALSE;
- demux->need_newsegment = FALSE;
+ demux->need_segment = FALSE;
demux->building_index = FALSE;
if (demux->seek_event) {
gst_event_unref (demux->seek_event);
if (demux->common.global_tags) {
gst_tag_list_free (demux->common.global_tags);
}
- demux->common.global_tags = gst_tag_list_new ();
+ demux->common.global_tags = gst_tag_list_new_empty ();
if (demux->common.cached_buffer) {
+ if (demux->common.cached_data) {
+ gst_buffer_unmap (demux->common.cached_buffer,
+ demux->common.cached_data, -1);
+ demux->common.cached_data = NULL;
+ }
gst_buffer_unref (demux->common.cached_buffer);
demux->common.cached_buffer = NULL;
}
static GstBuffer *
gst_matroska_decode_buffer (GstMatroskaTrackContext * context, GstBuffer * buf)
{
- guint8 *data;
- guint size;
- GstBuffer *new_buf;
+ gpointer data, buf_data;
+ gsize size, buf_size;
g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
GST_DEBUG ("decoding buffer %p", buf);
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
+ buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
+
+ g_return_val_if_fail (buf_size > 0, buf);
- g_return_val_if_fail (data != NULL && size > 0, buf);
+ data = buf_data;
+ size = buf_size;
if (gst_matroska_decode_data (context->encodings, &data, &size,
GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME, FALSE)) {
- new_buf = gst_buffer_new ();
- GST_BUFFER_MALLOCDATA (new_buf) = (guint8 *) data;
- GST_BUFFER_DATA (new_buf) = (guint8 *) data;
- GST_BUFFER_SIZE (new_buf) = size;
-
+ gst_buffer_unmap (buf, buf_data, buf_size);
gst_buffer_unref (buf);
- buf = new_buf;
-
- return buf;
+ return gst_buffer_new_wrapped (data, size);
} else {
GST_DEBUG ("decode data failed");
+ gst_buffer_unmap (buf, buf_data, buf_size);
gst_buffer_unref (buf);
return NULL;
}
padname = g_strdup_printf ("video_%u", demux->num_v_streams++);
templ = gst_element_class_get_pad_template (klass, "video_%u");
caps = gst_matroska_demux_video_caps (videocontext,
- context->codec_id, (guint8 *) context->codec_priv,
+ context->codec_id, context->codec_priv,
context->codec_priv_size, &codec, &riff_fourcc);
if (codec) {
- list = gst_tag_list_new ();
- gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
- GST_TAG_VIDEO_CODEC, codec, NULL);
+ list = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec, NULL);
g_free (codec);
}
break;
&codec, &riff_audio_fmt);
if (codec) {
- list = gst_tag_list_new ();
- gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
- GST_TAG_AUDIO_CODEC, codec, NULL);
+ list = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec, NULL);
g_free (codec);
}
break;
const gchar *lang;
if (!list)
- list = gst_tag_list_new ();
+ list = gst_tag_list_new_empty ();
/* Matroska contains ISO 639-2B codes, we want ISO 639-1 */
lang = gst_tag_get_language_code (context->language);
"codec_id='%s'", context->codec_id);
switch (context->type) {
case GST_MATROSKA_TRACK_TYPE_VIDEO:
- caps = gst_caps_new_simple ("video/x-unknown", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-unknown");
break;
case GST_MATROSKA_TRACK_TYPE_AUDIO:
- caps = gst_caps_new_simple ("audio/x-unknown", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-unknown");
break;
case GST_MATROSKA_TRACK_TYPE_SUBTITLE:
- caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
break;
case GST_MATROSKA_TRACK_TYPE_COMPLEX:
default:
- caps = gst_caps_new_simple ("application/x-matroska-unknown", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-matroska-unknown");
break;
}
gst_caps_set_simple (caps, "codec-id", G_TYPE_STRING, context->codec_id,
/* add any unrecognised riff fourcc / audio format, but after codec-id */
if (context->type == GST_MATROSKA_TRACK_TYPE_AUDIO && riff_audio_fmt != 0)
gst_caps_set_simple (caps, "format", G_TYPE_INT, riff_audio_fmt, NULL);
- else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0)
- gst_caps_set_simple (caps, "fourcc", GST_TYPE_FOURCC, riff_fourcc, NULL);
+ else if (context->type == GST_MATROSKA_TRACK_TYPE_VIDEO && riff_fourcc != 0) {
+ gchar *fstr = g_strdup_printf ("%" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (riff_fourcc));
+ gst_caps_set_simple (caps, "fourcc", G_TYPE_STRING, fstr, NULL);
+ g_free (fstr);
+ }
}
/* the pad in here */
gst_pad_set_event_function (context->pad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_event));
- gst_pad_set_query_type_function (context->pad,
- GST_DEBUG_FUNCPTR (gst_matroska_demux_get_src_query_types));
gst_pad_set_query_function (context->pad,
GST_DEBUG_FUNCPTR (gst_matroska_demux_handle_src_query));
gst_pad_set_element_private (context->pad, context);
gst_pad_use_fixed_caps (context->pad);
- gst_pad_set_caps (context->pad, context->caps);
gst_pad_set_active (context->pad, TRUE);
+ gst_pad_set_caps (context->pad, context->caps);
gst_element_add_pad (GST_ELEMENT (demux), context->pad);
g_free (padname);
return ret;
}
-static const GstQueryType *
-gst_matroska_demux_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType query_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_SEEKING,
- 0
- };
-
- return query_types;
-}
-
static gboolean
gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
GstQuery * query)
context->pos - demux->stream_start_time);
else
gst_query_set_position (query, GST_FORMAT_TIME,
- demux->common.segment.last_stop - demux->stream_start_time);
+ demux->common.segment.position - demux->stream_start_time);
GST_OBJECT_UNLOCK (demux);
} else if (format == GST_FORMAT_DEFAULT && context
&& context->default_duration) {
break;
}
default:
- res = gst_pad_query_default (pad, query);
+ res = gst_pad_query_default (pad, (GstObject *) demux, query);
break;
}
}
static gboolean
-gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query)
+gst_matroska_demux_handle_src_query (GstPad * pad, GstObject * parent,
+ GstQuery * query)
{
- gboolean ret;
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
-
- ret = gst_matroska_demux_query (demux, pad, query);
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
- gst_object_unref (demux);
-
- return ret;
+ return gst_matroska_demux_query (demux, pad, query);
}
/* returns FALSE if there are no pads to deliver event to,
static gboolean
gst_matroska_demux_send_event (GstMatroskaDemux * demux, GstEvent * event)
{
- gboolean is_newsegment;
+ gboolean is_segment;
gboolean ret = FALSE;
gint i;
GST_DEBUG_OBJECT (demux, "Sending event of type %s to all source pads",
GST_EVENT_TYPE_NAME (event));
- is_newsegment = (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
+ is_segment = (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
g_assert (demux->common.src->len == demux->common.num_streams);
for (i = 0; i < demux->common.src->len; i++) {
ret = TRUE;
/* FIXME: send global tags before stream tags */
- if (G_UNLIKELY (is_newsegment && stream->pending_tags != NULL)) {
+ if (G_UNLIKELY (is_segment && stream->pending_tags != NULL)) {
GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
GST_PTR_FORMAT, stream->pending_tags,
GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
- gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad,
- stream->pending_tags);
+ gst_pad_push_event (stream->pad, gst_event_new_tag (stream->pending_tags));
stream->pending_tags = NULL;
}
}
- if (G_UNLIKELY (is_newsegment && demux->common.global_tags != NULL)) {
+ if (G_UNLIKELY (is_segment && demux->common.global_tags != NULL)) {
+ GstEvent *tag_event;
gst_tag_list_add (demux->common.global_tags, GST_TAG_MERGE_REPLACE,
GST_TAG_CONTAINER_FORMAT, "Matroska", NULL);
GST_DEBUG_OBJECT (demux, "Sending global_tags %p : %" GST_PTR_FORMAT,
demux->common.global_tags, demux->common.global_tags);
- gst_element_found_tags (GST_ELEMENT (demux), demux->common.global_tags);
+
+ tag_event = gst_event_new_tag (demux->common.global_tags);
+
+ for (i = 0; i < demux->common.src->len; i++) {
+ GstMatroskaTrackContext *stream;
+
+ stream = g_ptr_array_index (demux->common.src, i);
+ gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
+ }
+
+ gst_event_unref (tag_event);
demux->common.global_tags = NULL;
}
/* update the time */
gst_matroska_read_common_reset_streams (&demux->common, entry->time, TRUE);
- demux->common.segment.last_stop = entry->time;
+ demux->common.segment.position = entry->time;
demux->seek_block = entry->block;
demux->seek_first = TRUE;
demux->last_stop_end = GST_CLOCK_TIME_NONE;
GstFlowReturn ret = GST_FLOW_OK;
const guint chunk = 64 * 1024;
GstBuffer *buf = NULL;
+ gpointer data = NULL;
+ gsize size;
guint64 length;
guint32 id;
guint needed;
gint cluster_pos;
if (buf != NULL) {
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
buf = NULL;
}
if (ret != GST_FLOW_OK)
break;
GST_DEBUG_OBJECT (demux, "read buffer size %d at offset %" G_GINT64_FORMAT,
- GST_BUFFER_SIZE (buf), newpos);
- gst_byte_reader_init_from_buffer (&reader, buf);
+ gst_buffer_get_size (buf), newpos);
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ gst_byte_reader_init (&reader, data, size);
resume:
cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
GST_MATROSKA_ID_CLUSTER, 0, gst_byte_reader_get_remaining (&reader));
}
if (buf) {
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
buf = NULL;
}
/* estimate using start and current position */
GST_OBJECT_LOCK (demux);
opos = demux->common.offset - demux->common.ebml_segment_start;
- otime = demux->common.segment.last_stop;
+ otime = demux->common.segment.position;
GST_OBJECT_UNLOCK (demux);
/* avoid division by zero in first estimation below */
if (event) {
GST_DEBUG_OBJECT (demux, "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);
/* compensate for clip start time */
if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
- seeksegment.last_stop += demux->stream_start_time;
+ seeksegment.position += demux->stream_start_time;
seeksegment.start += demux->stream_start_time;
if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
seeksegment.stop += demux->stream_start_time;
GST_OBJECT_LOCK (demux);
track = gst_matroska_read_common_get_seek_track (&demux->common, track);
if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
- seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
+ seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
NULL) {
/* pull mode without index can scan later on */
if (demux->common.index || demux->streaming) {
if (demux->streaming) {
/* need to seek to cluster start to pick up cluster time */
/* upstream takes care of flushing and all that
- * ... and newsegment event handling takes care of the rest */
+ * ... and segment event handling takes care of the rest */
return perform_seek_to_offset (demux,
entry->pos + demux->common.ebml_segment_start);
}
if (!demux->streaming && !demux->common.index) {
/* need to stop flushing upstream as we need it next */
if (flush)
- gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
- entry = gst_matroska_demux_search_pos (demux, seeksegment.last_stop);
+ gst_pad_push_event (demux->common.sinkpad,
+ gst_event_new_flush_stop (TRUE));
+ entry = gst_matroska_demux_search_pos (demux, seeksegment.position);
/* keep local copy */
if (entry) {
scan_entry = *entry;
} else {
GST_DEBUG_OBJECT (demux, "Scan failed to find matching position");
if (flush)
- gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
+ gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
goto seek_error;
}
}
GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
seeksegment.start = entry->time;
- seeksegment.last_stop = entry->time;
+ seeksegment.position = entry->time;
seeksegment.time = entry->time - demux->stream_start_time;
}
exit:
if (flush) {
GST_DEBUG_OBJECT (demux, "Stopping flush");
- gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop ());
- gst_matroska_demux_send_event (demux, gst_event_new_flush_stop ());
+ gst_pad_push_event (demux->common.sinkpad, gst_event_new_flush_stop (TRUE));
+ gst_matroska_demux_send_event (demux, gst_event_new_flush_stop (TRUE));
} else if (demux->segment_running && update) {
+ GstSegment segment;
GST_DEBUG_OBJECT (demux, "Closing currently running segment");
GST_OBJECT_LOCK (demux);
if (demux->close_segment)
gst_event_unref (demux->close_segment);
- demux->close_segment = gst_event_new_new_segment (TRUE,
- demux->common.segment.rate, GST_FORMAT_TIME,
- demux->common.segment.start, demux->common.segment.last_stop,
- demux->common.segment.time);
+ segment = demux->common.segment;
+ segment.stop = segment.position;
+ demux->close_segment = gst_event_new_segment (&segment);
GST_OBJECT_UNLOCK (demux);
}
GST_OBJECT_LOCK (demux);
if (demux->new_segment)
gst_event_unref (demux->new_segment);
- demux->new_segment = gst_event_new_new_segment_full (!update,
- demux->common.segment.rate, demux->common.segment.applied_rate,
- demux->common.segment.format, demux->common.segment.start,
- demux->common.segment.stop, demux->common.segment.time);
+ /* On port from 0.10, discarded !update (for segment.update) here, FIXME? */
+ demux->new_segment = gst_event_new_segment (&demux->common.segment);
GST_OBJECT_UNLOCK (demux);
/* restart our task since it might have been stopped when we did the
}
static gboolean
-gst_matroska_demux_handle_src_event (GstPad * pad, GstEvent * event)
+gst_matroska_demux_handle_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad));
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
gboolean res = TRUE;
switch (GST_EVENT_TYPE (event)) {
GstClockTimeDiff diff;
GstClockTime timestamp;
- gst_event_parse_qos (event, &proportion, &diff, ×tamp);
+ gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
GST_OBJECT_LOCK (demux);
videocontext->earliest_time = timestamp + diff;
break;
}
- gst_object_unref (demux);
-
return res;
}
GST_OBJECT_LOCK (demux);
GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
- GST_TIME_ARGS (demux->common.segment.last_stop));
+ GST_TIME_ARGS (demux->common.segment.position));
g_assert (demux->common.num_streams == demux->common.src->len);
for (stream_nr = 0; stream_nr < demux->common.src->len; stream_nr++) {
/* does it lag? 0.5 seconds is a random threshold...
* lag need only be considered if we have advanced into requested segment */
if (GST_CLOCK_TIME_IS_VALID (context->pos) &&
- GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop) &&
- demux->common.segment.last_stop > demux->common.segment.start &&
- context->pos + (GST_SECOND / 2) < demux->common.segment.last_stop) {
+ GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
+ demux->common.segment.position > demux->common.segment.start &&
+ context->pos + (GST_SECOND / 2) < demux->common.segment.position) {
gint64 new_start;
+ GstSegment segment;
GstEvent *event;
- new_start = demux->common.segment.last_stop - (GST_SECOND / 2);
+ new_start = demux->common.segment.position - (GST_SECOND / 2);
if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop))
new_start = MIN (new_start, demux->common.segment.stop);
GST_DEBUG_OBJECT (demux,
context->pos = new_start;
/* advance stream time */
- event = gst_event_new_new_segment (TRUE, demux->common.segment.rate,
- demux->common.segment.format, new_start, demux->common.segment.stop,
- new_start);
+ segment = demux->common.segment;
+ segment.start = new_start;
+ segment.position = new_start;
+ event = gst_event_new_segment (&segment);
GST_OBJECT_UNLOCK (demux);
gst_pad_push_event (context->pad, event);
GST_OBJECT_LOCK (demux);
GstFlowReturn ret, cret;
GstBuffer *header_buf;
- header_buf = gst_buffer_new_and_alloc (len);
- gst_buffer_set_caps (header_buf, stream->caps);
- memcpy (GST_BUFFER_DATA (header_buf), data, len);
+ header_buf = gst_buffer_new_wrapped (g_memdup (data, len), len);
if (stream->set_discont) {
GST_BUFFER_FLAG_SET (header_buf, GST_BUFFER_FLAG_DISCONT);
GstMatroskaTrackContext * stream)
{
GstFlowReturn ret;
- guint8 *pdata;
+ guint8 *pdata = stream->codec_priv;
GST_LOG_OBJECT (demux, "priv data size = %u", stream->codec_priv_size);
- pdata = (guint8 *) stream->codec_priv;
-
/* need at least 'fLaC' marker + STREAMINFO metadata block */
if (stream->codec_priv_size < 80) {
GST_WARNING_OBJECT (demux, "not enough codec priv data for speex headers");
GstMatroskaTrackContext * stream)
{
GstFlowReturn ret;
- guint8 *p = (guint8 *) stream->codec_priv;
+ guint8 *p = stream->codec_priv;
gint i, offset, num_packets;
guint *length, last;
* elsewhere, but for now, only interested in a small part */
/* make sure we have terminating 0 */
- buf = g_strndup ((gchar *) stream->codec_priv, stream->codec_priv_size);
+ buf = g_strndup (stream->codec_priv, stream->codec_priv_size);
/* just locate and parse palette part */
start = strstr (buf, "palette:");
{
guint8 *seq_header;
guint seq_header_len;
- guint32 header;
+ guint32 header, tmp;
if (stream->codec_state) {
seq_header = stream->codec_state;
if (GST_BUFFER_FLAG_IS_SET (*buf, GST_BUFFER_FLAG_DELTA_UNIT))
return GST_FLOW_OK;
- if (GST_BUFFER_SIZE (*buf) < 4)
+ if (gst_buffer_get_size (*buf) < 4)
return GST_FLOW_OK;
- header = GST_READ_UINT32_BE (GST_BUFFER_DATA (*buf));
+ gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
+ header = GUINT32_FROM_BE (tmp);
+
/* Sequence start code, if not found prepend */
if (header != 0x000001b3) {
GstBuffer *newbuf;
- newbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + seq_header_len);
- gst_buffer_set_caps (newbuf, stream->caps);
-
GST_DEBUG_OBJECT (element, "Prepending MPEG sequence header");
- gst_buffer_copy_metadata (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
- GST_BUFFER_COPY_FLAGS);
- g_memmove (GST_BUFFER_DATA (newbuf), seq_header, seq_header_len);
- g_memmove (GST_BUFFER_DATA (newbuf) + seq_header_len,
- GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
+
+ newbuf = gst_buffer_new_wrapped (g_memdup (seq_header, seq_header_len),
+ seq_header_len);
+
+ gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0,
+ gst_buffer_get_size (*buf));
+
gst_buffer_unref (*buf);
*buf = newbuf;
}
GstMatroskaTrackAudioContext *audiocontext =
(GstMatroskaTrackAudioContext *) stream;
GstBuffer *newbuf = NULL;
- guint8 *data;
- guint newlen;
+ guint8 *buf_data, *data;
Wavpack4Header wvh;
wvh.ck_id[0] = 'w';
wvh.block_index = audiocontext->wvpk_block_index;
if (audiocontext->channels <= 2) {
- guint32 block_samples;
+ guint32 block_samples, tmp;
+ gsize size = gst_buffer_get_size (*buf);
- block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
+ gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
+ block_samples = GUINT32_FROM_LE (tmp);
/* we need to reconstruct the header of the wavpack block */
/* -20 because ck_size is the size of the wavpack block -8
* and lace_size is the size of the wavpack block + 12
* (the three guint32 of the header that already are in the buffer) */
- wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
+ wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
/* block_samples, flags and crc are already in the buffer */
- newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
- newbuf = gst_buffer_new_and_alloc (newlen);
- gst_buffer_set_caps (newbuf, stream->caps);
+ newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, 0);
- data = GST_BUFFER_DATA (newbuf);
+ data = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
data[0] = 'w';
data[1] = 'v';
data[2] = 'p';
GST_WRITE_UINT8 (data + 11, wvh.index_no);
GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
- g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
- gst_buffer_copy_metadata (newbuf, *buf,
- GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
+
+ /* Append data from buf: */
+ gst_buffer_copy_into (newbuf, *buf, GST_BUFFER_COPY_TIMESTAMPS |
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_MEMORY, 0, size);
+
gst_buffer_unref (*buf);
*buf = newbuf;
audiocontext->wvpk_block_index += block_samples;
} else {
guint8 *outdata;
guint outpos = 0;
- guint size;
+ gsize buf_size, size, out_size;
guint32 block_samples, flags, crc, blocksize;
- data = GST_BUFFER_DATA (*buf);
- size = GST_BUFFER_SIZE (*buf);
+ buf_data = gst_buffer_map (*buf, &buf_size, NULL, GST_MAP_READ);
- if (size < 4) {
+ if (buf_size < 4) {
GST_ERROR_OBJECT (element, "Too small wavpack buffer");
+ gst_buffer_unmap (*buf, buf_data, buf_size);
return GST_FLOW_ERROR;
}
+ data = buf_data;
+ size = buf_size;
+
block_samples = GST_READ_UINT32_LE (data);
data += 4;
size -= 4;
break;
if (newbuf == NULL) {
- newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
- gst_buffer_set_caps (newbuf, stream->caps);
+ out_size = sizeof (Wavpack4Header) + blocksize;
+ newbuf = gst_buffer_new_allocate (NULL, out_size, 0);
- gst_buffer_copy_metadata (newbuf, *buf,
- GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
+ gst_buffer_copy_into (newbuf, *buf,
+ GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
outpos = 0;
- outdata = GST_BUFFER_DATA (newbuf);
+ outdata = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
} else {
- GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
- GST_BUFFER_DATA (newbuf) =
- g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
- GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
- outdata = GST_BUFFER_DATA (newbuf);
+ gst_buffer_unmap (newbuf, outdata, out_size);
+ out_size += sizeof (Wavpack4Header) + blocksize;
+ gst_buffer_set_size (newbuf, out_size);
+ outdata = gst_buffer_map (newbuf, NULL, NULL, GST_MAP_WRITE);
}
outdata[outpos] = 'w';
data += blocksize;
size -= blocksize;
}
+ gst_buffer_unmap (*buf, buf_data, buf_size);
gst_buffer_unref (*buf);
+
+ if (newbuf)
+ gst_buffer_unmap (newbuf, outdata, out_size);
+
*buf = newbuf;
audiocontext->wvpk_block_index += block_samples;
}
GstMatroskaTrackContext * stream, GstBuffer ** buf)
{
GstMatroskaTrackSubtitleContext *sub_stream;
- const gchar *encoding, *data;
+ const gchar *encoding;
GError *err = NULL;
GstBuffer *newbuf;
gchar *utf8;
- guint size;
+ gpointer data;
+ gsize size;
sub_stream = (GstMatroskaTrackSubtitleContext *) stream;
- data = (const gchar *) GST_BUFFER_DATA (*buf);
- size = GST_BUFFER_SIZE (*buf);
+ data = gst_buffer_map (*buf, &size, NULL, GST_MAP_READ);
if (!sub_stream->invalid_utf8) {
if (g_utf8_validate (data, size, NULL)) {
if (utf8 == NULL)
utf8 = g_strdup ("invalid subtitle");
- newbuf = gst_buffer_new ();
- GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
- GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
- GST_BUFFER_SIZE (newbuf) = strlen (utf8);
- gst_buffer_copy_metadata (newbuf, *buf,
- GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
+ newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
+ gst_buffer_copy_into (newbuf, *buf,
+ GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
+ gst_buffer_unmap (*buf, data, size);
gst_buffer_unref (*buf);
*buf = newbuf;
- data = (const gchar *) GST_BUFFER_DATA (*buf);
- size = GST_BUFFER_SIZE (*buf);
+ data = gst_buffer_map (*buf, &size, NULL, GST_MAP_READ);
next:
/* caps claim markup text, so we need to escape text,
if (!sub_stream->seen_markup_tag) {
utf8 = g_markup_escape_text (data, size);
- newbuf = gst_buffer_new ();
- GST_BUFFER_MALLOCDATA (newbuf) = (guint8 *) utf8;
- GST_BUFFER_DATA (newbuf) = (guint8 *) utf8;
- GST_BUFFER_SIZE (newbuf) = strlen (utf8);
- gst_buffer_copy_metadata (newbuf, *buf,
- GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
+ newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
+ gst_buffer_copy_into (newbuf, *buf,
+ GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
+ gst_buffer_unmap (*buf, data, size);
gst_buffer_unref (*buf);
*buf = newbuf;
gst_matroska_demux_check_aac (GstElement * element,
GstMatroskaTrackContext * stream, GstBuffer ** buf)
{
- const guint8 *data;
+ guint8 data[2];
guint size;
- data = GST_BUFFER_DATA (*buf);
- size = GST_BUFFER_SIZE (*buf);
+ gst_buffer_extract (*buf, 0, data, 2);
+ size = gst_buffer_get_size (*buf);
if (size > 2 && data[0] == 0xff && (data[1] >> 4 == 0x0f)) {
GstCaps *new_caps;
gst_structure_remove_field (s, "codec_data");
gst_caps_replace (&stream->caps, new_caps);
gst_pad_set_caps (stream->pad, new_caps);
- gst_buffer_set_caps (*buf, new_caps);
GST_DEBUG_OBJECT (element, "ADTS AAC audio data; removing codec-data, "
"new caps: %" GST_PTR_FORMAT, new_caps);
gst_caps_unref (new_caps);
return GST_FLOW_OK;
}
+static GstBuffer *
+gst_matroska_demux_align_buffer (GstMatroskaDemux * demux,
+ GstBuffer * buffer, gsize alignment)
+{
+ gpointer data;
+ gsize size;
+
+ data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
+ if (size < sizeof (guintptr)) {
+ gst_buffer_unmap (buffer, data, size);
+ return buffer;
+ }
+
+ if (((guintptr) data) & (alignment - 1)) {
+ GstBuffer *new_buffer;
+ gpointer new_data;
+
+ new_buffer = gst_buffer_new_allocate (NULL,
+ gst_buffer_get_size (buffer), alignment);
+ /* Copy data "by hand", so ensure alignment is kept: */
+ new_data = gst_buffer_map (new_buffer, NULL, NULL, GST_MAP_WRITE);
+ memcpy (new_data, data, size);
+ gst_buffer_unmap (new_buffer, new_data, -1);
+ gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
+ GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
+ alignment);
+
+ gst_buffer_unmap (buffer, data, size);
+ gst_buffer_unref (buffer);
+
+ return new_buffer;
+ }
+
+ gst_buffer_unmap (buffer, data, size);
+ return buffer;
+}
+
static GstFlowReturn
gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
GstEbmlRead * ebml, guint64 cluster_time, guint64 cluster_offset,
guint32 id;
guint64 block_duration = -1;
GstBuffer *buf = NULL;
+ gpointer buf_data = NULL;
+ gsize buf_size;
gint stream_num = -1, n, laces = 0;
guint size = 0;
gint *lace_size = NULL;
guint8 *data;
if (buf) {
+ gst_buffer_unmap (buf, buf_data, buf_size);
gst_buffer_unref (buf);
buf = NULL;
}
if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
break;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
+ buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
+ data = buf_data;
+ size = buf_size;
/* first byte(s): blocknum */
if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
}
/* need to refresh segment info ASAP */
- if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_newsegment) {
+ if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
+ GstSegment *segment = &demux->common.segment;
+ guint64 segment_duration = 0;
+
GST_DEBUG_OBJECT (demux,
"generating segment starting at %" GST_TIME_FORMAT,
GST_TIME_ARGS (lace_time));
"Setting stream start time to %" GST_TIME_FORMAT,
GST_TIME_ARGS (lace_time));
}
- gst_segment_set_newsegment (&demux->common.segment, FALSE,
- demux->common.segment.rate, GST_FORMAT_TIME, lace_time,
- GST_CLOCK_TIME_NONE, lace_time - demux->stream_start_time);
+ if (GST_CLOCK_TIME_IS_VALID (segment->stop))
+ segment_duration = segment->stop - segment->start;
+ else if (GST_CLOCK_TIME_IS_VALID (segment->position))
+ segment_duration = segment->position - segment->start;
+ segment->base += segment_duration / fabs (segment->rate);
+ segment->start = lace_time;
+ segment->stop = GST_CLOCK_TIME_NONE;
+ segment->position = lace_time - demux->stream_start_time;
/* now convey our segment notion downstream */
- gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
- demux->common.segment.rate, demux->common.segment.format,
- demux->common.segment.start, demux->common.segment.stop,
- demux->common.segment.start));
- demux->need_newsegment = FALSE;
+ gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
+ demux->need_segment = FALSE;
}
if (block_duration != -1) {
}
}
- sub = gst_buffer_create_sub (buf,
- GST_BUFFER_SIZE (buf) - size, lace_size[n]);
+ sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
+ gst_buffer_get_size (buf) - size, lace_size[n]);
GST_DEBUG_OBJECT (demux, "created subbuffer %p", sub);
if (delta_unit)
GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
demux->common.segment.rate > 0.0) {
GstClockTimeDiff diff;
- GstEvent *event1, *event2;
- /* only send newsegments with increasing start times,
+ /* only send segments with increasing start times,
* otherwise if these go back and forth downstream (sinks) increase
* accumulated time and running_time */
diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
&& lace_time > demux->common.segment.start
&& (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
|| lace_time < demux->common.segment.stop)) {
+ GstSegment segment;
+ GstEvent *event1, *event2;
GST_DEBUG_OBJECT (demux,
"Gap of %" G_GINT64_FORMAT " ns detected in"
"stream %d (%" GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
- "Sending updated NEWSEGMENT events", diff,
+ "Sending updated SEGMENT events", diff,
stream->index, GST_TIME_ARGS (stream->pos),
GST_TIME_ARGS (lace_time));
- /* send newsegment events such that the gap is not accounted in
- * accum time, hence running_time */
+ /* send segment events such that the gap is not accounted in
+ * segment base time, hence running_time */
/* close ahead of gap */
- event1 = gst_event_new_new_segment (TRUE,
- demux->common.segment.rate, demux->common.segment.format,
- demux->last_stop_end, demux->last_stop_end,
- demux->last_stop_end);
+ segment = demux->common.segment;
+ segment.start = demux->last_stop_end;
+ segment.stop = demux->last_stop_end;
+ segment.position = demux->last_stop_end;
+ event1 = gst_event_new_segment (&segment);
/* skip gap */
- event2 = gst_event_new_new_segment (FALSE,
- demux->common.segment.rate,
- demux->common.segment.format, lace_time,
- demux->common.segment.stop, lace_time);
+ segment.start = lace_time;
+ segment.stop = demux->common.segment.stop;
+ segment.position = lace_time;
+ event2 = gst_event_new_segment (&segment);
GST_OBJECT_UNLOCK (demux);
gst_matroska_demux_send_event (demux, event1);
gst_matroska_demux_send_event (demux, event2);
GST_OBJECT_LOCK (demux);
/* align segment view with downstream,
- * prevents double-counting accum when closing segment */
- gst_segment_set_newsegment (&demux->common.segment, FALSE,
- demux->common.segment.rate, demux->common.segment.format,
- lace_time, demux->common.segment.stop, lace_time);
- demux->common.segment.last_stop = lace_time;
+ * prevents double-counting base time when closing segment */
+ /* FIXME: in 0.10, the segment base/accum got updated here, but
+ * maybe we don't need that because of the double accounting
+ * mentioned above? */
+ demux->common.segment = segment;
}
}
- if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.last_stop)
- || demux->common.segment.last_stop < lace_time) {
- demux->common.segment.last_stop = lace_time;
+ if (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.position)
+ || demux->common.segment.position < lace_time) {
+ demux->common.segment.position = lace_time;
}
GST_OBJECT_UNLOCK (demux);
if (demux->common.segment.duration == -1 ||
demux->common.segment.duration <
lace_time - demux->stream_start_time) {
- gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
- last_stop_end - demux->stream_start_time);
+ demux->common.segment.duration =
+ last_stop_end - demux->stream_start_time;
GST_OBJECT_UNLOCK (demux);
gst_element_post_message (GST_ELEMENT_CAST (demux),
gst_message_new_duration (GST_OBJECT_CAST (demux),
GST_DEBUG_OBJECT (demux,
"Pushing lace %d, data of size %d for stream %d, time=%"
GST_TIME_FORMAT " and duration=%" GST_TIME_FORMAT, n,
- GST_BUFFER_SIZE (sub), stream_num,
+ gst_buffer_get_size (sub), stream_num,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (sub)),
GST_TIME_ARGS (GST_BUFFER_DURATION (sub)));
cluster_offset, NULL);
}
- gst_buffer_set_caps (sub, GST_PAD_CAPS (stream->pad));
-
/* Postprocess the buffers depending on the codec used */
if (stream->postprocess_frame) {
GST_LOG_OBJECT (demux, "running post process");
elements typically assume minimal alignment.
Therefore, create an aligned copy if necessary. */
g_assert (stream->alignment <= G_MEM_ALIGN);
- if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) {
- GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub));
- memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub),
- GST_BUFFER_SIZE (sub));
- gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL);
- GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated",
- stream->alignment);
- gst_buffer_unref (sub);
- sub = buffer;
- }
+ sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
ret = gst_pad_push (stream->pad, sub);
if (demux->common.segment.rate < 0) {
}
done:
- if (buf)
+ if (buf) {
+ gst_buffer_unmap (buf, buf_data, buf_size);
gst_buffer_unref (buf);
+ }
g_free (lace_size);
return ret;
/* 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->common.sinkpad, &fmt, &stop);
+ gst_pad_peer_query_duration (demux->common.sinkpad, GST_FORMAT_BYTES,
+ &stop);
}
/* if upstream doesn't know the size, it's likely that it's not seekable in
demux->first_cluster_offset = demux->common.offset;
GST_DEBUG_OBJECT (demux, "signaling no more pads");
gst_element_no_more_pads (GST_ELEMENT (demux));
- /* send initial newsegment - we wait till we know the first
+ /* send initial segment - we wait till we know the first
incoming timestamp, so we can properly set the start of
the segment. */
- demux->need_newsegment = TRUE;
+ demux->need_segment = TRUE;
}
demux->cluster_time = GST_CLOCK_TIME_NONE;
demux->cluster_offset = demux->common.offset;
* if no stop was set */
if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)) {
- GstEvent *event =
- gst_event_new_new_segment_full (TRUE, demux->common.segment.rate,
- demux->common.segment.applied_rate, demux->common.segment.format,
- demux->common.segment.start,
- MAX (demux->last_stop_end, demux->common.segment.start),
- demux->common.segment.time);
+ GstSegment segment = demux->common.segment;
+ GstEvent *event;
+
+ segment.stop = MAX (demux->last_stop_end, segment.start);
+ event = gst_event_new_segment (&segment);
gst_matroska_demux_send_event (demux, event);
}
res = gst_pad_push_event (demux->common.sinkpad, event);
- /* newsegment event will update offset */
+ /* segment event will update offset */
return res;
}
static GstFlowReturn
-gst_matroska_demux_chain (GstPad * pad, GstBuffer * buffer)
+gst_matroska_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
guint available;
GstFlowReturn ret = GST_FLOW_OK;
guint needed = 0;
}
static gboolean
-gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
+gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
gboolean res = TRUE;
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (pad));
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
GST_DEBUG_OBJECT (demux,
"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 = 0;
- gboolean update;
- GstSegment segment;
+ const 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_event_parse_segment (event, &segment);
+ /* FIXME: do we need to update segment base here (like accum in 0.10)? */
GST_DEBUG_OBJECT (demux,
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
- &segment);
+ "received format %d segment %" GST_SEGMENT_FORMAT, segment->format,
+ segment);
if (demux->common.state < GST_MATROSKA_READ_STATE_DATA) {
GST_DEBUG_OBJECT (demux, "still starting");
}
/* 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 (demux, "unsupported segment format, ignoring");
goto exit;
}
/* clear current segment leftover */
gst_adapter_clear (demux->common.adapter);
/* and some streaming setup */
- demux->common.offset = start;
+ demux->common.offset = segment->start;
/* do not know where we are;
- * need to come across a cluster and generate newsegment */
- demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
+ * need to come across a cluster and generate segment */
+ demux->common.segment.position = GST_CLOCK_TIME_NONE;
demux->cluster_time = GST_CLOCK_TIME_NONE;
demux->cluster_offset = 0;
- demux->need_newsegment = TRUE;
+ demux->need_segment = TRUE;
/* but keep some of the upstream segment */
- demux->common.segment.rate = rate;
+ demux->common.segment.rate = segment->rate;
GST_OBJECT_UNLOCK (demux);
exit:
- /* chain will send initial newsegment after pads have been added,
+ /* chain will send initial segment after pads have been added,
* or otherwise come up with one */
GST_DEBUG_OBJECT (demux, "eating event");
gst_event_unref (event);
GST_OBJECT_LOCK (demux);
gst_matroska_read_common_reset_streams (&demux->common,
GST_CLOCK_TIME_NONE, TRUE);
- demux->common.segment.last_stop = GST_CLOCK_TIME_NONE;
+ demux->common.segment.position = GST_CLOCK_TIME_NONE;
demux->cluster_time = GST_CLOCK_TIME_NONE;
demux->cluster_offset = 0;
GST_OBJECT_UNLOCK (demux);
/* fall-through */
}
default:
- res = gst_pad_event_default (pad, event);
+ res = gst_pad_event_default (pad, parent, event);
break;
}
}
static gboolean
-gst_matroska_demux_sink_activate (GstPad * sinkpad)
+gst_matroska_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
{
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
+ GstQuery *query;
+ gboolean pull_mode = FALSE;
+
+ query = gst_query_new_scheduling ();
- if (gst_pad_check_pull_range (sinkpad)) {
+ if (gst_pad_peer_query (sinkpad, query))
+ pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
+
+ gst_query_unref (query);
+
+ if (pull_mode) {
GST_DEBUG ("going to pull mode");
demux->streaming = FALSE;
- return gst_pad_activate_pull (sinkpad, TRUE);
+ return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
} else {
GST_DEBUG ("going to push (streaming) mode");
demux->streaming = TRUE;
- return gst_pad_activate_push (sinkpad, TRUE);
+ return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
}
-
- return FALSE;
}
static gboolean
-gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
+gst_matroska_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
- GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (GST_PAD_PARENT (sinkpad));
-
- if (active) {
- /* if we have a scheduler we can start the task */
- demux->segment_running = TRUE;
- gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
- sinkpad);
- } else {
- demux->segment_running = FALSE;
- gst_pad_stop_task (sinkpad);
+ GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (parent);
+
+ switch (mode) {
+ case GST_PAD_MODE_PULL:
+ if (active) {
+ /* if we have a scheduler we can start the task */
+ demux->segment_running = TRUE;
+ gst_pad_start_task (sinkpad, (GstTaskFunction) gst_matroska_demux_loop,
+ sinkpad);
+ } else {
+ demux->segment_running = FALSE;
+ gst_pad_stop_task (sinkpad);
+ }
+ return TRUE;
+ case GST_PAD_MODE_PUSH:
+ return TRUE;
+ default:
+ return FALSE;
}
-
- return TRUE;
}
static void
vids->imp_colors = GUINT32_FROM_LE (vids->imp_colors);
if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
- buf = gst_buffer_new_and_alloc (size - sizeof (gst_riff_strf_vids));
- memcpy (GST_BUFFER_DATA (buf),
- (guint8 *) vids + sizeof (gst_riff_strf_vids),
- GST_BUFFER_SIZE (buf));
+ gsize offset = sizeof (gst_riff_strf_vids);
+
+ buf =
+ gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
+ size - offset), size - offset);
}
if (riff_fourcc)
g_free (vids);
}
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED)) {
- guint32 fourcc = 0;
+ const gchar *format = NULL;
switch (videocontext->fourcc) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'):
*codec_name = g_strdup ("Raw planar YUV 4:2:0");
- fourcc = videocontext->fourcc;
+ format = "I420";
break;
case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
*codec_name = g_strdup ("Raw packed YUV 4:2:2");
- fourcc = videocontext->fourcc;
+ format = "YUY2";
break;
case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
*codec_name = g_strdup ("Raw packed YUV 4:2:0");
- fourcc = videocontext->fourcc;
+ format = "YV12";
break;
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
*codec_name = g_strdup ("Raw packed YUV 4:2:2");
- fourcc = videocontext->fourcc;
+ format = "UYVY";
break;
case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
*codec_name = g_strdup ("Raw packed YUV 4:4:4 with alpha channel");
- fourcc = videocontext->fourcc;
+ format = "AYUV";
break;
default:
return NULL;
}
- caps = gst_caps_new_simple ("video/x-raw-yuv",
- "format", GST_TYPE_FOURCC, fourcc, NULL);
+ caps = gst_caps_new_simple ("video/x-raw",
+ "format", G_TYPE_STRING, format, NULL);
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_SP)) {
caps = gst_caps_new_simple ("video/x-divx",
"divxversion", G_TYPE_INT, 4, NULL);
"mpegversion", G_TYPE_INT, 4,
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
if (data) {
- GstBuffer *priv = gst_buffer_new_and_alloc (size);
+ GstBuffer *priv;
- memcpy (GST_BUFFER_DATA (priv), data, size);
+ priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
gst_buffer_unref (priv);
}
*codec_name = g_strdup_printf ("MPEG-%d video", mpegversion);
context->postprocess_frame = gst_matroska_demux_add_mpeg_seq_header;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG)) {
- caps = gst_caps_new_simple ("image/jpeg", NULL);
+ caps = gst_caps_new_empty_simple ("image/jpeg");
*codec_name = g_strdup ("Motion-JPEG");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC)) {
- caps = gst_caps_new_simple ("video/x-h264", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-h264");
if (data) {
- GstBuffer *priv = gst_buffer_new_and_alloc (size);
+ GstBuffer *priv;
/* First byte is the version, second is the profile indication, and third
* is the 5 contraint_set_flags and 3 reserved bits. Fourth byte is the
gst_codec_utils_h264_caps_set_level_and_profile (caps, data + 1,
size - 1);
- memcpy (GST_BUFFER_DATA (priv), data, size);
+ priv = gst_buffer_new_wrapped (g_memdup (data, size), size);
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
gst_buffer_unref (priv);
subformat = GST_READ_UINT32_BE (data + 0x1a);
rformat = GST_READ_UINT32_BE (data + 0x1e);
- priv = gst_buffer_new_and_alloc (size - 0x1a);
-
- memcpy (GST_BUFFER_DATA (priv), data + 0x1a, size - 0x1a);
- gst_caps_set_simple (caps,
- "codec_data", GST_TYPE_BUFFER, priv,
- "format", G_TYPE_INT, rformat,
- "subformat", G_TYPE_INT, subformat, NULL);
+ priv =
+ gst_buffer_new_wrapped (g_memdup (data + 0x1a, size - 0x1a),
+ size - 0x1a);
+ gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, "format",
+ G_TYPE_INT, rformat, "subformat", G_TYPE_INT, subformat, NULL);
gst_buffer_unref (priv);
}
*codec_name = g_strdup_printf ("RealVideo %d.0", rmversion);
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_THEORA)) {
- caps = gst_caps_new_simple ("video/x-theora", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-theora");
context->send_xiph_headers = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_DIRAC)) {
- caps = gst_caps_new_simple ("video/x-dirac", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-dirac");
*codec_name = g_strdup_printf ("Dirac");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP8)) {
- caps = gst_caps_new_simple ("video/x-vp8", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-vp8");
*codec_name = g_strdup_printf ("On2 VP8");
} else {
GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
*codec_name = g_strdup_printf ("MPEG-1 layer %d", layer);
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE) ||
!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE)) {
+ gboolean sign;
gint endianness;
+ GstAudioFormat format;
+ sign = (audiocontext->bitdepth != 8);
if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE))
endianness = G_BIG_ENDIAN;
else
endianness = G_LITTLE_ENDIAN;
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "width", G_TYPE_INT, audiocontext->bitdepth,
- "depth", G_TYPE_INT, audiocontext->bitdepth,
- "signed", G_TYPE_BOOLEAN, audiocontext->bitdepth != 8,
- "endianness", G_TYPE_INT, endianness, NULL);
+ format = gst_audio_format_build_integer (sign, endianness,
+ audiocontext->bitdepth, audiocontext->bitdepth);
+
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, gst_audio_format_to_string (format), NULL);
*codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
audiocontext->bitdepth);
context->alignment = audiocontext->bitdepth / 8;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) {
- caps = gst_caps_new_simple ("audio/x-raw-float",
- "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
- "width", G_TYPE_INT, audiocontext->bitdepth, NULL);
+ const gchar *format;
+ if (audiocontext->bitdepth == 32)
+ format = "F32LE";
+ else
+ format = "F64LE";
+ caps = gst_caps_new_simple ("audio/x-raw",
+ "format", G_TYPE_STRING, format, NULL);
*codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
audiocontext->bitdepth);
context->alignment = audiocontext->bitdepth / 8;
"framed", G_TYPE_BOOLEAN, TRUE, NULL);
*codec_name = g_strdup ("E-AC-3 audio");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_DTS)) {
- caps = gst_caps_new_simple ("audio/x-dts", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-dts");
*codec_name = g_strdup ("DTS audio");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) {
- caps = gst_caps_new_simple ("audio/x-vorbis", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-vorbis");
context->send_xiph_headers = TRUE;
/* vorbis decoder does tags */
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_FLAC)) {
- caps = gst_caps_new_simple ("audio/x-flac", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-flac");
context->send_flac_headers = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_SPEEX)) {
- caps = gst_caps_new_simple ("audio/x-speex", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-speex");
context->send_speex_headers = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
gst_riff_strf_auds auds;
if (data) {
- GstBuffer *codec_data = gst_buffer_new ();
+ GstBuffer *codec_data;
/* little-endian -> byte-order */
auds.format = GST_READ_UINT16_LE (data);
auds.size = GST_READ_UINT16_LE (data + 16);
/* 18 is the waveformatex size */
- gst_buffer_set_data (codec_data, data + 18, auds.size);
+ codec_data = gst_buffer_new_wrapped_full (data + 18, NULL, 0, auds.size);
if (riff_audio_fmt)
*riff_audio_fmt = auds.format;
if (freq_index == 15)
explicit_freq_bytes = 3;
GST_DEBUG ("obj_type = %u, freq_index = %u", obj_type, freq_index);
- priv = gst_buffer_new_and_alloc (context->codec_priv_size);
- memcpy (GST_BUFFER_DATA (priv), context->codec_priv,
- context->codec_priv_size);
+ priv = gst_buffer_new_wrapped (g_memdup (context->codec_priv,
+ context->codec_priv_size), context->codec_priv_size);
/* assume SBR if samplerate <= 24kHz */
if (obj_type == 5 || (freq_index >= 6 && freq_index != 15) ||
(context->codec_priv_size == (5 + explicit_freq_bytes))) {
/* make up decoder-specific data if it is not supplied */
if (priv == NULL) {
- priv = gst_buffer_new_and_alloc (5);
- data = GST_BUFFER_DATA (priv);
+ priv = gst_buffer_new_allocate (NULL, 5, 0);
+ data = gst_buffer_map (priv, NULL, NULL, GST_MAP_WRITE);
rate_idx = aac_rate_idx (audiocontext->samplerate);
profile = aac_profile_idx (codec_id);
data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
data[1] = ((rate_idx & 0x1) << 7) | (audiocontext->channels << 3);
- GST_BUFFER_SIZE (priv) = 2;
if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2,
strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG2))) {
mpegversion = 2;
+ gst_buffer_unmap (priv, data, 5);
+ gst_buffer_set_size (priv, 2);
} else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4,
strlen (GST_MATROSKA_CODEC_ID_AUDIO_AAC_MPEG4))) {
mpegversion = 4;
data[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
data[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
data[4] = (1 << 7) | (rate_idx << 3);
- GST_BUFFER_SIZE (priv) = 5;
+ gst_buffer_unmap (priv, data, 5);
+ } else {
+ gst_buffer_unmap (priv, data, 5);
+ gst_buffer_set_size (priv, 2);
}
} else {
+ gst_buffer_unmap (priv, data, 5);
gst_buffer_unref (priv);
priv = NULL;
GST_ERROR ("Unknown AAC profile and no codec private data");
G_TYPE_INT, leaf_size, "width", G_TYPE_INT, sample_width, NULL);
if ((size - 78) >= extra_data_size) {
- priv = gst_buffer_new_and_alloc (extra_data_size);
- memcpy (GST_BUFFER_DATA (priv), data + 78, extra_data_size);
+ priv = gst_buffer_new_wrapped (g_memdup (data + 78, extra_data_size),
+ extra_data_size);
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, priv, NULL);
gst_buffer_unref (priv);
}
*codec_name = g_strdup_printf ("RealAudio %d.0", raversion);
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_SIPR)) {
- caps = gst_caps_new_simple ("audio/x-sipro", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-sipro");
*codec_name = g_strdup ("Sipro/ACELP.NET Voice Codec");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_RALF)) {
- caps = gst_caps_new_simple ("audio/x-ralf-mpeg4-generic", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-ralf-mpeg4-generic");
*codec_name = g_strdup ("Real Audio Lossless");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_ATRC)) {
- caps = gst_caps_new_simple ("audio/x-vnd.sony.atrac3", NULL);
+ caps = gst_caps_new_empty_simple ("audio/x-vnd.sony.atrac3");
*codec_name = g_strdup ("Sony ATRAC3");
} else {
GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
* Check if we have to do something with codec_private */
if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_UTF8)) {
/* well, plain text simply does not have a lot of markup ... */
- caps = gst_caps_new_simple ("text/x-pango-markup", NULL);
+ caps = gst_caps_new_empty_simple ("text/x-pango-markup");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
- caps = gst_caps_new_simple ("application/x-ssa", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-ssa");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
- caps = gst_caps_new_simple ("application/x-ass", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-ass");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
- caps = gst_caps_new_simple ("application/x-usf", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-usf");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
- caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_HDMVPGS)) {
- caps = gst_caps_new_simple ("subpicture/x-pgs", NULL);
+ caps = gst_caps_new_empty_simple ("subpicture/x-pgs");
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_KATE)) {
- caps = gst_caps_new_simple ("subtitle/x-kate", NULL);
+ caps = gst_caps_new_empty_simple ("subtitle/x-kate");
context->send_xiph_headers = TRUE;
} else {
GST_DEBUG ("Unknown subtitle stream: codec_id='%s'", codec_id);
- caps = gst_caps_new_simple ("application/x-subtitle-unknown", NULL);
+ caps = gst_caps_new_empty_simple ("application/x-subtitle-unknown");
}
if (data != NULL && size > 0) {
GstBuffer *buf;
- buf = gst_buffer_new_and_alloc (size);
- memcpy (GST_BUFFER_DATA (buf), data, size);
+ buf = gst_buffer_new_wrapped (g_memdup (data, size), size);
gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
gst_buffer_unref (buf);
}
gboolean building_index;
guint64 index_offset;
GstEvent *seek_event;
- gboolean need_newsegment;
+ gboolean need_segment;
/* reverse playback */
GArray *seek_index;
/* some often-used info */
gchar *codec_id, *codec_name, *name, *language;
- guint8 *codec_priv;
- guint codec_priv_size;
- guint8 *codec_state;
- guint codec_state_size;
+ gpointer codec_priv;
+ gsize codec_priv_size;
+ gpointer codec_state;
+ gsize codec_state_size;
GstMatroskaTrackType type;
guint uid, num;
GstMatroskaTrackFlags flags;
#include <stdio.h>
#include <string.h>
+#include <gst/audio/audio.h>
#include <gst/riff/riff-media.h>
#include <gst/tag/tag.h>
COMMON_VIDEO_CAPS "; "
"video/x-vp8, "
COMMON_VIDEO_CAPS "; "
- "video/x-raw-yuv, "
- "format = (fourcc) { YUY2, I420, YV12, UYVY, AYUV }, "
+ "video/x-raw, "
+ "format = (string) { YUY2, I420, YV12, UYVY, AYUV }, "
COMMON_VIDEO_CAPS "; "
"video/x-wmv, " "wmvversion = (int) [ 1, 3 ], " COMMON_VIDEO_CAPS)
);
COMMON_AUDIO_CAPS "; "
"audio/x-speex, "
COMMON_AUDIO_CAPS "; "
- "audio/x-raw-int, "
- "width = (int) 8, "
- "depth = (int) 8, "
- "signed = (boolean) false, "
- COMMON_AUDIO_CAPS ";"
- "audio/x-raw-int, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
- "signed = (boolean) true, "
- COMMON_AUDIO_CAPS ";"
- "audio/x-raw-int, "
- "width = (int) 24, "
- "depth = (int) 24, "
- "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
- "signed = (boolean) true, "
- COMMON_AUDIO_CAPS ";"
- "audio/x-raw-int, "
- "width = (int) 32, "
- "depth = (int) 32, "
- "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
- "signed = (boolean) true, "
- COMMON_AUDIO_CAPS ";"
- "audio/x-raw-float, "
- "width = (int) [ 32, 64 ], "
- "endianness = (int) LITTLE_ENDIAN, "
+ "audio/x-raw, "
+ "format = (string) { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }, "
COMMON_AUDIO_CAPS ";"
"audio/x-tta, "
"width = (int) { 8, 16, 24 }, "
static GArray *used_uids;
G_LOCK_DEFINE_STATIC (used_uids);
-static void gst_matroska_mux_add_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstMatroskaMux, gst_matroska_mux, GstElement,
- GST_TYPE_ELEMENT, gst_matroska_mux_add_interfaces);
+#define parent_class gst_matroska_mux_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstMatroskaMux, gst_matroska_mux, GST_TYPE_ELEMENT,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
/* Matroska muxer destructor */
static void gst_matroska_mux_finalize (GObject * object);
/* pad functions */
static gboolean gst_matroska_mux_handle_src_event (GstPad * pad,
- GstEvent * event);
+ GstObject * parent, GstEvent * event);
static GstPad *gst_matroska_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * name);
+ GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_matroska_mux_release_pad (GstElement * element, GstPad * pad);
/* gst internal change state handler */
gpointer data);
static void
-gst_matroska_mux_add_interfaces (GType type)
-{
- static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
-
- g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
-}
-
-static void
-gst_matroska_mux_base_init (gpointer g_class)
-{
-}
-
-static void
gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
{
GObjectClass *gobject_class;
* Matroska muxer constructor.
*/
static void
-gst_matroska_mux_init (GstMatroskaMux * mux, GstMatroskaMuxClass * g_class)
+gst_matroska_mux_init (GstMatroskaMux * mux)
{
GstPadTemplate *templ;
templ =
- gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
+ gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mux), "src");
mux->srcpad = gst_pad_new_from_template (templ, "src");
gst_pad_set_event_function (mux->srcpad, gst_matroska_mux_handle_src_event);
* Returns: #TRUE on success.
*/
static gboolean
-gst_matroska_mux_handle_src_event (GstPad * pad, GstEvent * event)
+gst_matroska_mux_handle_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
GstEventType type;
break;
}
- return gst_pad_event_default (pad, event);
+ return gst_pad_event_default (pad, parent, event);
}
/**
* Returns: #TRUE on success.
*/
static gboolean
-gst_matroska_mux_handle_sink_event (GstPad * pad, GstEvent * event)
+gst_matroska_mux_handle_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
GstMatroskaTrackContext *context;
GstMatroskaPad *collect_pad;
- GstMatroskaMux *mux;
+ GstMatroskaMux *mux = GST_MATROSKA_MUX (parent);
GstTagList *list;
gboolean ret = TRUE;
- mux = GST_MATROSKA_MUX (gst_pad_get_parent (pad));
-
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:{
+ GstCaps *caps;
+
+ collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
+ gst_event_parse_caps (event, &caps);
+
+ ret = collect_pad->capsfunc (pad, caps);
+ gst_event_unref (event);
+ event = NULL;
+ break;
+ }
case GST_EVENT_TAG:{
gchar *lang = NULL;
event = NULL;
break;
}
- case GST_EVENT_NEWSEGMENT:{
- GstFormat format;
+ case GST_EVENT_SEGMENT:{
+ const GstSegment *segment;
- gst_event_parse_new_segment (event, NULL, NULL, &format, NULL, NULL,
- NULL);
- if (format != GST_FORMAT_TIME) {
+ gst_event_parse_segment (event, &segment);
+ if (segment->format != GST_FORMAT_TIME) {
ret = FALSE;
gst_event_unref (event);
event = NULL;
/* now GstCollectPads can take care of the rest, e.g. EOS */
if (event)
- ret = mux->collect_event (pad, event);
-
- gst_object_unref (mux);
+ ret = mux->collect_event (pad, parent, event);
return ret;
}
GstStructure *structure;
const gchar *mimetype;
const GValue *value = NULL;
- const GstBuffer *codec_buf = NULL;
+ GstBuffer *codec_buf = NULL;
gint width, height, pixel_width, pixel_height;
gint fps_d, fps_n;
gboolean interlaced = FALSE;
/* extract codec_data, may turn out needed */
value = gst_structure_get_value (structure, "codec_data");
if (value)
- codec_buf = gst_value_get_buffer (value);
+ codec_buf = (GstBuffer *) gst_value_get_buffer (value);
/* find type */
- if (!strcmp (mimetype, "video/x-raw-yuv")) {
+ if (!strcmp (mimetype, "video/x-raw")) {
+ const gchar *fstr;
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED);
- gst_structure_get_fourcc (structure, "format", &videocontext->fourcc);
+ fstr = gst_structure_get_string (structure, "format");
+ if (fstr && strlen (fstr) == 4)
+ videocontext->fourcc = GST_STR_FOURCC (fstr);
+ } else if (!strcmp (mimetype, "image/jpeg")) {
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_MJPEG);
} else if (!strcmp (mimetype, "video/x-xvid") /* MS/VfW compatibility cases */
||!strcmp (mimetype, "video/x-huffyuv")
|| !strcmp (mimetype, "video/x-divx")
}
} else if (!strcmp (mimetype, "video/x-wmv")) {
gint wmvversion;
- guint32 format;
- if (gst_structure_get_fourcc (structure, "format", &format)) {
- fourcc = format;
+ const gchar *fstr;
+
+ fstr = gst_structure_get_string (structure, "format");
+ if (fstr && strlen (fstr) == 4) {
+ fourcc = GST_STR_FOURCC (fstr);
} else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
if (wmvversion == 2) {
fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
/* process codec private/initialization data, if any */
if (codec_buf) {
- size += GST_BUFFER_SIZE (codec_buf);
+ size += gst_buffer_get_size (codec_buf);
bih = g_realloc (bih, size);
GST_WRITE_UINT32_LE (&bih->size, size);
- memcpy ((guint8 *) bih + sizeof (gst_riff_strf_vids),
- GST_BUFFER_DATA (codec_buf), GST_BUFFER_SIZE (codec_buf));
+ gst_buffer_extract (codec_buf, 0,
+ (guint8 *) bih + sizeof (gst_riff_strf_vids), -1);
}
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_VIDEO_VFW_FOURCC);
/* Create avcC header */
if (codec_buf != NULL) {
- context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+ context->codec_priv_size = gst_buffer_get_size (codec_buf);
context->codec_priv = g_malloc0 (context->codec_priv_size);
- memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
- context->codec_priv_size);
+ gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
}
} else if (!strcmp (mimetype, "video/x-theora")) {
const GValue *streamheader;
/* global headers may be in codec data */
if (codec_buf != NULL) {
- context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+ context->codec_priv_size = gst_buffer_get_size (codec_buf);
context->codec_priv = g_malloc0 (context->codec_priv_size);
- memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
- context->codec_priv_size);
+ gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
}
} else if (!strcmp (mimetype, "video/x-msmpeg")) {
msmpeg43:
GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
- priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+ priv_data_size = gst_buffer_get_size (codec_data_buf);
priv_data = g_malloc0 (priv_data_size);
- memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+ gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
priv_data_size = 1;
if (bufarr->len > 0) {
for (i = 0; i < bufarr->len - 1; i++) {
- priv_data_size += GST_BUFFER_SIZE (buf[i]) / 0xff + 1;
+ priv_data_size += gst_buffer_get_size (buf[i]) / 0xff + 1;
}
}
for (i = 0; i < bufarr->len; ++i) {
- priv_data_size += GST_BUFFER_SIZE (buf[i]);
+ priv_data_size += gst_buffer_get_size (buf[i]);
}
priv_data = g_malloc0 (priv_data_size);
if (bufarr->len > 0) {
for (bufi = 0; bufi < bufarr->len - 1; bufi++) {
- for (i = 0; i < GST_BUFFER_SIZE (buf[bufi]) / 0xff; ++i) {
+ for (i = 0; i < gst_buffer_get_size (buf[bufi]) / 0xff; ++i) {
priv_data[offset++] = 0xff;
}
- priv_data[offset++] = GST_BUFFER_SIZE (buf[bufi]) % 0xff;
+ priv_data[offset++] = gst_buffer_get_size (buf[bufi]) % 0xff;
}
}
for (i = 0; i < bufarr->len; ++i) {
- memcpy (priv_data + offset, GST_BUFFER_DATA (buf[i]),
- GST_BUFFER_SIZE (buf[i]));
- offset += GST_BUFFER_SIZE (buf[i]);
+ gst_buffer_extract (buf[i], 0, priv_data + offset, -1);
+ offset += gst_buffer_get_size (buf[i]);
}
context->codec_priv = priv_data;
if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
return FALSE;
- if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 1 + 6 + 4) {
+ if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 4) {
GST_WARNING ("First vorbis header too small, ignoring");
} else {
- if (memcmp (GST_BUFFER_DATA (buf0) + 1, "vorbis", 6) == 0) {
+ if (gst_buffer_memcmp (buf0, 1, "vorbis", 6) == 0) {
GstMatroskaTrackAudioContext *audiocontext;
- guint8 *hdr;
+ guint8 *data, *hdr;
- hdr = GST_BUFFER_DATA (buf0) + 1 + 6 + 4;
+ data = gst_buffer_map (buf0, NULL, NULL, GST_MAP_READ);
+ hdr = data + 1 + 6 + 4;
audiocontext = (GstMatroskaTrackAudioContext *) context;
audiocontext->channels = GST_READ_UINT8 (hdr);
audiocontext->samplerate = GST_READ_UINT32_LE (hdr + 1);
+ gst_buffer_unmap (buf0, data, -1);
}
}
if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
return FALSE;
- if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 1 + 6 + 26) {
+ if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 26) {
GST_WARNING ("First theora header too small, ignoring");
- } else if (memcmp (GST_BUFFER_DATA (buf0), "\200theora\003\002", 9) != 0) {
+ } else if (gst_buffer_memcmp (buf0, 0, "\200theora\003\002", 9) != 0) {
GST_WARNING ("First header not a theora identification header, ignoring");
} else {
GstMatroskaTrackVideoContext *videocontext;
guint fps_num, fps_denom, par_num, par_denom;
- guint8 *hdr;
+ guint8 *data, *hdr;
- hdr = GST_BUFFER_DATA (buf0) + 1 + 6 + 3 + 2 + 2;
+ data = gst_buffer_map (buf0, NULL, NULL, GST_MAP_READ);
+ hdr = data + 1 + 6 + 3 + 2 + 2;
videocontext = (GstMatroskaTrackVideoContext *) context;
videocontext->pixel_width = GST_READ_UINT32_BE (hdr) >> 8;
videocontext->display_height = 0;
}
hdr += 3 + 3;
+
+ gst_buffer_unmap (buf0, data, -1);
}
if (buf0)
if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, -1))
return FALSE;
- if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 64) { /* Kate ID header is 64 bytes */
+ if (buf0 == NULL || gst_buffer_get_size (buf0) < 64) { /* Kate ID header is 64 bytes */
GST_WARNING ("First kate header too small, ignoring");
- } else if (memcmp (GST_BUFFER_DATA (buf0), "\200kate\0\0\0", 8) != 0) {
+ } else if (gst_buffer_memcmp (buf0, 0, "\200kate\0\0\0", 8) != 0) {
GST_WARNING ("First header not a kate identification header, ignoring");
}
buffer = g_value_peek_pointer (bufval);
/* Need at least OggFLAC mapping header, fLaC marker and STREAMINFO block */
- if (GST_BUFFER_SIZE (buffer) < 9 + 4 + 4 + 34
- || memcmp (GST_BUFFER_DATA (buffer) + 1, "FLAC", 4) != 0
- || memcmp (GST_BUFFER_DATA (buffer) + 9, "fLaC", 4) != 0) {
+ if (gst_buffer_get_size (buffer) < 9 + 4 + 4 + 34
+ || gst_buffer_memcmp (buffer, 1, "FLAC", 4) != 0
+ || gst_buffer_memcmp (buffer, 9, "fLaC", 4) != 0) {
GST_WARNING ("Invalid streamheader for FLAC");
return FALSE;
}
- context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer) - 9);
- context->codec_priv_size = GST_BUFFER_SIZE (buffer) - 9;
- memcpy (context->codec_priv, GST_BUFFER_DATA (buffer) + 9,
- GST_BUFFER_SIZE (buffer) - 9);
+ context->codec_priv_size = gst_buffer_get_size (buffer) - 9;
+ context->codec_priv = g_malloc (context->codec_priv_size);
+ gst_buffer_extract (buffer, 9, context->codec_priv, -1);
for (i = 1; i < bufarr->len; i++) {
+ guint old_size;
bufval = &g_array_index (bufarr, GValue, i);
if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
buffer = g_value_peek_pointer (bufval);
- context->codec_priv =
- g_realloc (context->codec_priv,
- context->codec_priv_size + GST_BUFFER_SIZE (buffer));
- memcpy ((guint8 *) context->codec_priv + context->codec_priv_size,
- GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
- context->codec_priv_size =
- context->codec_priv_size + GST_BUFFER_SIZE (buffer);
+ old_size = context->codec_priv_size;
+ context->codec_priv_size += gst_buffer_get_size (buffer);
+
+ context->codec_priv = g_realloc (context->codec_priv,
+ context->codec_priv_size);
+ gst_buffer_extract (buffer, 0,
+ (guint8 *) context->codec_priv + old_size, -1);
}
return TRUE;
GArray *bufarr;
GValue *bufval;
GstBuffer *buffer;
+ guint old_size;
if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
GST_WARNING ("No or invalid streamheader field in the caps");
buffer = g_value_peek_pointer (bufval);
- if (GST_BUFFER_SIZE (buffer) < 80
- || memcmp (GST_BUFFER_DATA (buffer), "Speex ", 8) != 0) {
+ if (gst_buffer_get_size (buffer) < 80
+ || gst_buffer_memcmp (buffer, 0, "Speex ", 8) != 0) {
GST_WARNING ("Invalid streamheader for Speex");
return FALSE;
}
- context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer));
- context->codec_priv_size = GST_BUFFER_SIZE (buffer);
- memcpy (context->codec_priv, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
+ context->codec_priv_size = gst_buffer_get_size (buffer);
+ context->codec_priv = g_malloc (context->codec_priv_size);
+ gst_buffer_extract (buffer, 0, context->codec_priv, -1);
bufval = &g_array_index (bufarr, GValue, 1);
buffer = g_value_peek_pointer (bufval);
- context->codec_priv =
- g_realloc (context->codec_priv,
- context->codec_priv_size + GST_BUFFER_SIZE (buffer));
- memcpy ((guint8 *) context->codec_priv + context->codec_priv_size,
- GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
- context->codec_priv_size =
- context->codec_priv_size + GST_BUFFER_SIZE (buffer);
+ old_size = context->codec_priv_size;
+ context->codec_priv_size += gst_buffer_get_size (buffer);
+ context->codec_priv = g_realloc (context->codec_priv,
+ context->codec_priv_size);
+ gst_buffer_extract (buffer, 0, (guint8 *) context->codec_priv + old_size, -1);
return TRUE;
}
static const gchar *
-aac_codec_data_to_codec_id (const GstBuffer * buf)
+aac_codec_data_to_codec_id (GstBuffer * buf)
{
const gchar *result;
- gint profile;
+ guint8 profile;
/* default to MAIN */
profile = 1;
- if (GST_BUFFER_SIZE (buf) >= 2) {
- profile = GST_READ_UINT8 (GST_BUFFER_DATA (buf));
+ if (gst_buffer_get_size (buf) >= 2) {
+ gst_buffer_extract (buf, 0, &profile, 1);
profile >>= 3;
}
gint samplerate = 0, channels = 0;
GstStructure *structure;
const GValue *codec_data = NULL;
- const GstBuffer *buf = NULL;
+ GstBuffer *buf = NULL;
const gchar *stream_format = NULL;
mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
default:
goto refuse_caps;
}
- } else if (!strcmp (mimetype, "audio/x-raw-int")) {
- gint width, depth;
- gint endianness = G_LITTLE_ENDIAN;
- gboolean signedness = TRUE;
-
- if (!gst_structure_get_int (structure, "width", &width) ||
- !gst_structure_get_int (structure, "depth", &depth) ||
- !gst_structure_get_boolean (structure, "signed", &signedness)) {
- GST_DEBUG_OBJECT (mux, "broken caps, width/depth/signed field missing");
- goto refuse_caps;
- }
-
- if (depth > 8 &&
- !gst_structure_get_int (structure, "endianness", &endianness)) {
- GST_DEBUG_OBJECT (mux, "broken caps, no endianness specified");
- goto refuse_caps;
- }
-
- if (width != depth) {
- GST_DEBUG_OBJECT (mux, "width must be same as depth!");
- goto refuse_caps;
- }
+ } else if (!strcmp (mimetype, "audio/x-raw")) {
+ GstAudioInfo info;
- /* FIXME: where is this spec'ed out? (tpm) */
- if ((width == 8 && signedness) || (width >= 16 && !signedness)) {
- GST_DEBUG_OBJECT (mux, "8-bit PCM must be unsigned, 16-bit PCM signed");
+ gst_audio_info_init (&info);
+ if (!gst_audio_info_from_caps (&info, caps)) {
+ GST_DEBUG_OBJECT (mux,
+ "broken caps, rejected by gst_audio_info_from_caps");
goto refuse_caps;
}
- audiocontext->bitdepth = depth;
- if (endianness == G_BIG_ENDIAN)
- context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
- else
- context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
+ switch (GST_AUDIO_INFO_FORMAT (&info)) {
+ case GST_AUDIO_FORMAT_U8:
+ case GST_AUDIO_FORMAT_S16BE:
+ case GST_AUDIO_FORMAT_S16LE:
+ case GST_AUDIO_FORMAT_S24BE:
+ case GST_AUDIO_FORMAT_S24LE:
+ case GST_AUDIO_FORMAT_S32BE:
+ case GST_AUDIO_FORMAT_S32LE:
+ if (GST_AUDIO_INFO_WIDTH (&info) != GST_AUDIO_INFO_DEPTH (&info)) {
+ GST_DEBUG_OBJECT (mux, "width must be same as depth!");
+ goto refuse_caps;
+ }
+ if (GST_AUDIO_INFO_IS_BIG_ENDIAN (&info))
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
+ else
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
+ break;
- } else if (!strcmp (mimetype, "audio/x-raw-float")) {
- gint width;
+ case GST_AUDIO_FORMAT_F32LE:
+ case GST_AUDIO_FORMAT_F64LE:
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
+ break;
- if (!gst_structure_get_int (structure, "width", &width)) {
- GST_DEBUG_OBJECT (mux, "broken caps, width field missing");
- goto refuse_caps;
+ default:
+ GST_DEBUG_OBJECT (mux, "wrong format in raw audio caps");
+ goto refuse_caps;
}
- audiocontext->bitdepth = width;
- context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
+ audiocontext->bitdepth = GST_AUDIO_INFO_WIDTH (&info);
} else if (!strcmp (mimetype, "audio/x-vorbis")) {
const GValue *streamheader;
GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
- priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+ priv_data_size = gst_buffer_get_size (codec_data_buf);
priv_data = g_malloc0 (priv_data_size);
- memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+ gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
codec_priv_size = WAVEFORMATEX_SIZE;
if (buf)
- codec_priv_size += GST_BUFFER_SIZE (buf);
+ codec_priv_size += gst_buffer_get_size (buf);
/* serialize waveformatex structure */
codec_priv = g_malloc0 (codec_priv_size);
GST_WRITE_UINT16_LE (codec_priv + 12, block_align);
GST_WRITE_UINT16_LE (codec_priv + 14, 0);
if (buf)
- GST_WRITE_UINT16_LE (codec_priv + 16, GST_BUFFER_SIZE (buf));
+ GST_WRITE_UINT16_LE (codec_priv + 16, gst_buffer_get_size (buf));
else
GST_WRITE_UINT16_LE (codec_priv + 16, 0);
/* process codec private/initialization data, if any */
if (buf) {
- memcpy ((guint8 *) codec_priv + WAVEFORMATEX_SIZE,
- GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ gst_buffer_extract (buf, 0,
+ (guint8 *) codec_priv + WAVEFORMATEX_SIZE, -1);
}
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_ACM);
*/
static GstPad *
gst_matroska_mux_request_new_pad (GstElement * element,
- GstPadTemplate * templ, const gchar * req_name)
+ GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
GstPad *newpad = NULL;
gchar *name = NULL;
const gchar *pad_name = NULL;
- GstPadSetCapsFunction setcapsfunc = NULL;
+ GstMatroskaCapsFunc capsfunc = NULL;
GstMatroskaTrackContext *context = NULL;
gint pad_id;
name = g_strdup_printf ("audio_%u", mux->num_a_streams++);
pad_name = name;
}
- setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
+ capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackAudioContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_AUDIO;
name = g_strdup_printf ("video_%u", mux->num_v_streams++);
pad_name = name;
}
- setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
+ capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackVideoContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_VIDEO;
name = g_strdup_printf ("subtitle_%u", mux->num_t_streams++);
pad_name = name;
}
- setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
+ capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
context = (GstMatroskaTrackContext *)
g_new0 (GstMatroskaTrackSubtitleContext, 1);
context->type = GST_MATROSKA_TRACK_TYPE_SUBTITLE;
gst_pad_set_event_function (newpad,
GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_sink_event));
- gst_pad_set_setcaps_function (newpad, setcapsfunc);
+ collect_pad->capsfunc = capsfunc;
gst_pad_set_active (newpad, TRUE);
if (!gst_element_add_pad (element, newpad))
goto pad_add_failed;
GTimeVal time = { 0, 0 };
if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
- ebml->caps = gst_caps_new_simple ("video/webm", NULL);
+ ebml->caps = gst_caps_new_empty_simple ("video/webm");
} else {
- ebml->caps = gst_caps_new_simple ("video/x-matroska", NULL);
+ ebml->caps = gst_caps_new_empty_simple ("video/x-matroska");
}
/* we start with a EBML header */
doctype = mux->doctype;
for (collected = mux->collect->data; collected;
collected = g_slist_next (collected)) {
GstMatroskaPad *collect_pad;
- GstFormat format = GST_FORMAT_TIME;
GstPad *thepad;
gint64 trackduration;
/* Query the total length of the track. */
GST_DEBUG_OBJECT (thepad, "querying peer duration");
- if (gst_pad_query_peer_duration (thepad, &format, &trackduration)) {
+ if (gst_pad_peer_query_duration (thepad, GST_FORMAT_TIME, &trackduration)) {
GST_DEBUG_OBJECT (thepad, "duration: %" GST_TIME_FORMAT,
GST_TIME_ARGS (trackduration));
if (trackduration != GST_CLOCK_TIME_NONE && trackduration > duration) {
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (collect_pad->buffer)),
GST_TIME_ARGS (time));
collect_pad->buffer =
- gst_buffer_make_metadata_writable (collect_pad->buffer);
+ gst_buffer_make_writable (collect_pad->buffer);
GST_BUFFER_TIMESTAMP (collect_pad->buffer) = time;
}
}
gint16 relative_timestamp, int flags)
{
GstBuffer *hdr;
+ guint8 *data = g_malloc (4);
- hdr = gst_buffer_new_and_alloc (4);
+ hdr = gst_buffer_new_wrapped (data, 4);
/* track num - FIXME: what if num >= 0x80 (unlikely)? */
- GST_BUFFER_DATA (hdr)[0] = track->num | 0x80;
+ data[0] = track->num | 0x80;
/* time relative to clustertime */
- GST_WRITE_UINT16_BE (GST_BUFFER_DATA (hdr) + 1, relative_timestamp);
+ GST_WRITE_UINT16_BE (data + 1, relative_timestamp);
/* flags */
- GST_BUFFER_DATA (hdr)[3] = flags;
+ data[3] = flags;
return hdr;
}
{
GstMatroskaTrackVideoContext *ctx =
(GstMatroskaTrackVideoContext *) collect_pad->track;
- const guint8 *data = GST_BUFFER_DATA (buf);
- guint size = GST_BUFFER_SIZE (buf);
+ guint8 *buf_data, *data;
+ gsize size;
guint8 parse_code;
guint32 next_parse_offset;
GstBuffer *ret = NULL;
gboolean is_muxing_unit = FALSE;
- if (GST_BUFFER_SIZE (buf) < 13) {
+ buf_data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ data = buf_data;
+
+ if (size < 13) {
+ gst_buffer_unmap (buf, buf_data, -1);
gst_buffer_unref (buf);
return ret;
}
/* Check if this buffer contains a picture or end-of-sequence packet */
while (size >= 13) {
if (GST_READ_UINT32_BE (data) != 0x42424344 /* 'BBCD' */ ) {
+ gst_buffer_unmap (buf, buf_data, -1);
gst_buffer_unref (buf);
return ret;
}
else
ctx->dirac_unit = gst_buffer_ref (buf);
+ gst_buffer_unmap (buf, buf_data, -1);
+
if (is_muxing_unit) {
- ret = gst_buffer_make_metadata_writable (ctx->dirac_unit);
+ ret = gst_buffer_make_writable (ctx->dirac_unit);
ctx->dirac_unit = NULL;
- gst_buffer_copy_metadata (ret, buf,
- GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
- GST_BUFFER_COPY_CAPS);
+ gst_buffer_copy_into (ret, buf,
+ GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
gst_buffer_unref (buf);
} else {
gst_buffer_unref (buf);
streamheader_buffer = gst_ebml_stop_streamheader (ebml);
if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
- caps = gst_caps_new_simple ("video/webm", NULL);
+ caps = gst_caps_new_empty_simple ("video/webm");
} else {
- caps = gst_caps_new_simple ("video/x-matroska", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-matroska");
}
s = gst_caps_get_structure (caps, 0);
g_value_init (&streamheader, GST_TYPE_ARRAY);
relative_timestamp, flags);
gst_ebml_write_set_cache (ebml, 0x40);
gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
- GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
+ gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
gst_ebml_write_buffer (ebml, hdr);
gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
gst_ebml_write_buffer (ebml, buf);
return gst_ebml_last_write_result (ebml);
} else {
- gst_ebml_write_set_cache (ebml, GST_BUFFER_SIZE (buf) * 2);
+ gst_ebml_write_set_cache (ebml, gst_buffer_get_size (buf) * 2);
/* write and call order slightly unnatural,
* but avoids seek and minizes pushing */
blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
if (write_duration)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION, block_duration);
gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
- GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
+ gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
gst_ebml_write_buffer (ebml, hdr);
- gst_ebml_write_master_finish_full (ebml, blockgroup, GST_BUFFER_SIZE (buf));
+ gst_ebml_write_master_finish_full (ebml, blockgroup,
+ gst_buffer_get_size (buf));
gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
gst_ebml_write_buffer (ebml, buf);
guint64 pos;
} GstMatroskaMetaSeekIndex;
+typedef gboolean (*GstMatroskaCapsFunc) (GstPad *pad, GstCaps *caps);
+
/* all information needed for one matroska stream */
typedef struct
{
GstCollectData collect; /* we extend the CollectData */
+ GstMatroskaCapsFunc capsfunc;
GstMatroskaTrackContext *track;
GstBuffer *buffer; /* the queued buffer for this pad */
static gboolean gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
GstPad * pad, GstEvent * event);
static gboolean gst_matroska_parse_handle_src_event (GstPad * pad,
- GstEvent * event);
-static const GstQueryType *gst_matroska_parse_get_src_query_types (GstPad *
- pad);
+ GstObject * parent, GstEvent * event);
static gboolean gst_matroska_parse_handle_src_query (GstPad * pad,
- GstQuery * query);
+ GstObject * parent, GstQuery * query);
static gboolean gst_matroska_parse_handle_sink_event (GstPad * pad,
- GstEvent * event);
+ GstObject * parent, GstEvent * event);
static GstFlowReturn gst_matroska_parse_chain (GstPad * pad,
- GstBuffer * buffer);
+ GstObject * parent, GstBuffer * buffer);
static GstStateChangeReturn
gst_matroska_parse_change_state (GstElement * element,
guint64 offset);
GType gst_matroska_parse_get_type (void);
-GST_BOILERPLATE (GstMatroskaParse, gst_matroska_parse, GstElement,
- GST_TYPE_ELEMENT);
-
-static void
-gst_matroska_parse_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_templ));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_templ));
-
- gst_element_class_set_details_simple (element_class, "Matroska parser",
- "Codec/Parser",
- "Parses Matroska/WebM streams into video/audio/subtitles",
- "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-}
+#define parent_class gst_matroska_parse_parent_class
+G_DEFINE_TYPE (GstMatroskaParse, gst_matroska_parse, GST_TYPE_ELEMENT);
static void
gst_matroska_parse_finalize (GObject * object)
GST_DEBUG_FUNCPTR (gst_matroska_parse_set_index);
gstelement_class->get_index =
GST_DEBUG_FUNCPTR (gst_matroska_parse_get_index);
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&src_templ));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_templ));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "Matroska parser", "Codec/Parser",
+ "Parses Matroska/WebM streams into video/audio/subtitles",
+ "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
}
static void
-gst_matroska_parse_init (GstMatroskaParse * parse,
- GstMatroskaParseClass * klass)
+gst_matroska_parse_init (GstMatroskaParse * parse)
{
parse->common.sinkpad = gst_pad_new_from_static_template (&sink_templ,
"sink");
parse->srcpad = gst_pad_new_from_static_template (&src_templ, "src");
gst_pad_set_event_function (parse->srcpad,
GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_event));
- gst_pad_set_query_type_function (parse->srcpad,
- GST_DEBUG_FUNCPTR (gst_matroska_parse_get_src_query_types));
gst_pad_set_query_function (parse->srcpad,
GST_DEBUG_FUNCPTR (gst_matroska_parse_handle_src_query));
gst_pad_use_fixed_caps (parse->srcpad);
if (parse->common.global_tags) {
gst_tag_list_free (parse->common.global_tags);
}
- parse->common.global_tags = gst_tag_list_new ();
+ parse->common.global_tags = gst_tag_list_new_empty ();
if (parse->common.cached_buffer) {
gst_buffer_unref (parse->common.cached_buffer);
return ret;
}
-static const GstQueryType *
-gst_matroska_parse_get_src_query_types (GstPad * pad)
-{
- static const GstQueryType query_types[] = {
- GST_QUERY_POSITION,
- GST_QUERY_DURATION,
- GST_QUERY_SEEKING,
- 0
- };
-
- return query_types;
-}
-
static gboolean
gst_matroska_parse_query (GstMatroskaParse * parse, GstPad * pad,
GstQuery * query)
gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
else
gst_query_set_position (query, GST_FORMAT_TIME,
- parse->common.segment.last_stop);
+ parse->common.segment.position);
GST_OBJECT_UNLOCK (parse);
} else if (format == GST_FORMAT_DEFAULT && context
&& context->default_duration) {
break;
}
default:
- res = gst_pad_query_default (pad, query);
+ res = gst_pad_query_default (pad, (GstObject *) parse, query);
break;
}
}
static gboolean
-gst_matroska_parse_handle_src_query (GstPad * pad, GstQuery * query)
+gst_matroska_parse_handle_src_query (GstPad * pad, GstObject * parent,
+ GstQuery * query)
{
gboolean ret;
- GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
+ GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
ret = gst_matroska_parse_query (parse, pad, query);
- gst_object_unref (parse);
-
return ret;
}
GstFlowReturn ret = GST_FLOW_OK;
const guint chunk = 64 * 1024;
GstBuffer *buf = NULL;
+ gpointer data;
+ gsize size;
guint64 length;
guint32 id;
guint needed;
if (ret != GST_FLOW_OK)
break;
GST_DEBUG_OBJECT (parse, "read buffer size %d at offset %" G_GINT64_FORMAT,
- GST_BUFFER_SIZE (buf), newpos);
- gst_byte_reader_init_from_buffer (&reader, buf);
+ gst_buffer_get_size (buf), newpos);
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ gst_byte_reader_init (&reader, data, size);
cluster_pos = 0;
resume:
cluster_pos = gst_byte_reader_masked_scan_uint32 (&reader, 0xffffffff,
- GST_MATROSKA_ID_CLUSTER, cluster_pos,
- GST_BUFFER_SIZE (buf) - cluster_pos);
+ GST_MATROSKA_ID_CLUSTER, cluster_pos, size - cluster_pos);
if (cluster_pos >= 0) {
newpos += cluster_pos;
GST_DEBUG_OBJECT (parse,
goto resume;
} else {
/* partial cluster id may have been in tail of buffer */
- newpos += MAX (GST_BUFFER_SIZE (buf), 4) - 3;
+ newpos += MAX (size, 4) - 3;
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
buf = NULL;
}
}
if (buf) {
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
buf = NULL;
}
if (event) {
GST_DEBUG_OBJECT (parse, "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);
}
/* check sanity before we start flushing and all that */
GST_OBJECT_LOCK (parse);
if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
- seeksegment.last_stop, &parse->seek_index, &parse->seek_entry)) ==
+ seeksegment.position, &parse->seek_index, &parse->seek_entry)) ==
NULL) {
/* pull mode without index can scan later on */
GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
}
static gboolean
-gst_matroska_parse_handle_src_event (GstPad * pad, GstEvent * event)
+gst_matroska_parse_handle_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
- GstMatroskaParse *parse = GST_MATROSKA_PARSE (gst_pad_get_parent (pad));
+ GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
gboolean res = TRUE;
switch (GST_EVENT_TYPE (event)) {
GstClockTimeDiff diff;
GstClockTime timestamp;
- gst_event_parse_qos (event, &proportion, &diff, ×tamp);
+ gst_event_parse_qos (event, NULL, &proportion, &diff, ×tamp);
GST_OBJECT_LOCK (parse);
videocontext->earliest_time = timestamp + diff;
break;
}
- gst_object_unref (parse);
-
return res;
}
guint32 id;
guint64 block_duration = 0;
GstBuffer *buf = NULL;
+ gpointer buf_data = NULL;
+ gsize buf_size = 0;
gint stream_num = -1, n, laces = 0;
guint size = 0;
gint *lace_size = NULL;
if ((ret = gst_ebml_read_buffer (ebml, &id, &buf)) != GST_FLOW_OK)
break;
- data = GST_BUFFER_DATA (buf);
- size = GST_BUFFER_SIZE (buf);
+ buf_data = gst_buffer_map (buf, &buf_size, NULL, GST_MAP_READ);
+
+ data = buf_data;
+ size = buf_size;
/* first byte(s): blocknum */
if ((n = gst_matroska_ebmlnum_uint (data, size, &num)) < 0)
}
/* need to refresh segment info ASAP */
if (GST_CLOCK_TIME_IS_VALID (lace_time) && parse->need_newsegment) {
+ GstSegment segment;
GST_DEBUG_OBJECT (parse,
"generating segment starting at %" GST_TIME_FORMAT,
GST_TIME_ARGS (lace_time));
/* pretend we seeked here */
- gst_segment_set_seek (&parse->common.segment, parse->common.segment.rate,
+ gst_segment_do_seek (&parse->common.segment, parse->common.segment.rate,
GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
/* now convey our segment notion downstream */
- gst_matroska_parse_send_event (parse, gst_event_new_new_segment (FALSE,
- parse->common.segment.rate, parse->common.segment.format,
- parse->common.segment.start, parse->common.segment.stop,
- parse->common.segment.start));
+ segment = parse->common.segment;
+ segment.position = segment.start;
+ gst_matroska_parse_send_event (parse, gst_event_new_segment (&segment));
parse->need_newsegment = FALSE;
}
}
done:
- if (buf)
+ if (buf) {
+ gst_buffer_unmap (buf, buf_data, buf_size);
gst_buffer_unref (buf);
+ }
g_free (lace_size);
return ret;
/* 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 (parse, "doing duration query to fix up unset stop");
- gst_pad_query_peer_duration (parse->common.sinkpad, &fmt, &stop);
+ gst_pad_peer_query_duration (parse->common.sinkpad, GST_FORMAT_BYTES,
+ &stop);
}
/* if upstream doesn't know the size, it's likely that it's not seekable in
GstBuffer *buf;
buf = gst_buffer_span (parse->streamheader, 0, buffer,
- GST_BUFFER_SIZE (parse->streamheader) + GST_BUFFER_SIZE (buffer));
+ gst_buffer_get_size (parse->streamheader) +
+ gst_buffer_get_size (buffer));
gst_buffer_unref (parse->streamheader);
parse->streamheader = buf;
} else {
parse->streamheader = gst_buffer_ref (buffer);
}
- GST_DEBUG ("%d", GST_BUFFER_SIZE (parse->streamheader));
+ GST_DEBUG ("%d", gst_buffer_get_size (parse->streamheader));
}
static GstFlowReturn
GValue bufval = { 0 };
GstBuffer *buf;
- caps = gst_caps_new_simple ("video/x-matroska", NULL);
+ caps = gst_caps_new_empty_simple ("video/x-matroska");
s = gst_caps_get_structure (caps, 0);
g_value_init (&streamheader, GST_TYPE_ARRAY);
g_value_init (&bufval, GST_TYPE_BUFFER);
gst_pad_set_caps (parse->srcpad, caps);
buf = gst_buffer_copy (parse->streamheader);
- gst_buffer_set_caps (buf, caps);
gst_caps_unref (caps);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
} else {
GST_BUFFER_TIMESTAMP (buffer) = parse->last_timestamp;
}
- gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
ret = gst_pad_push (parse->srcpad, gst_buffer_ref (buffer));
return ret;
}
static GstFlowReturn
-gst_matroska_parse_chain (GstPad * pad, GstBuffer * buffer)
+gst_matroska_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
- GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
+ GstMatroskaParse *parse = GST_MATROSKA_PARSE (parent);
guint available;
GstFlowReturn ret = GST_FLOW_OK;
guint needed = 0;
}
static gboolean
-gst_matroska_parse_handle_sink_event (GstPad * pad, GstEvent * event)
+gst_matroska_parse_handle_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event)
{
gboolean res = TRUE;
GstMatroskaParse *parse = GST_MATROSKA_PARSE (GST_PAD_PARENT (pad));
"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 = 0;
- gboolean update;
- GstSegment segment;
+ const 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_event_parse_segment (event, &segment);
GST_DEBUG_OBJECT (parse,
- "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
- &segment);
+ "received format %d newsegment %" GST_SEGMENT_FORMAT,
+ segment->format, segment);
if (parse->common.state < GST_MATROSKA_READ_STATE_DATA) {
GST_DEBUG_OBJECT (parse, "still starting");
}
/* 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 (parse, "unsupported segment format, ignoring");
goto exit;
}
/* clear current segment leftover */
gst_adapter_clear (parse->common.adapter);
/* and some streaming setup */
- parse->common.offset = start;
+ parse->common.offset = segment->start;
/* do not know where we are;
* need to come across a cluster and generate newsegment */
- parse->common.segment.last_stop = GST_CLOCK_TIME_NONE;
+ parse->common.segment.position = GST_CLOCK_TIME_NONE;
parse->cluster_time = GST_CLOCK_TIME_NONE;
parse->cluster_offset = 0;
parse->need_newsegment = TRUE;
/* but keep some of the upstream segment */
- parse->common.segment.rate = rate;
+ parse->common.segment.rate = segment->rate;
exit:
/* chain will send initial newsegment after pads have been added,
* or otherwise come up with one */
gst_matroska_read_common_reset_streams (&parse->common,
GST_CLOCK_TIME_NONE, TRUE);
GST_OBJECT_UNLOCK (parse);
- parse->common.segment.last_stop = GST_CLOCK_TIME_NONE;
+ parse->common.segment.position = GST_CLOCK_TIME_NONE;
parse->cluster_time = GST_CLOCK_TIME_NONE;
parse->cluster_offset = 0;
/* fall-through */
}
default:
- res = gst_pad_event_default (pad, event);
+ res = gst_pad_event_default (pad, parent, event);
break;
}
static gboolean
gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
- guint8 ** data_out, guint * size_out,
+ gpointer * data_out, gsize * size_out,
GstMatroskaTrackCompressionAlgorithm algo)
{
guint8 *new_data = NULL;
for (i = 0; i < encodings->len; i++) {
GstMatroskaTrackEncoding *enc =
&g_array_index (encodings, GstMatroskaTrackEncoding, i);
- guint8 *data = NULL;
- guint size;
+ gpointer data = NULL;
+ gsize size;
if ((enc->scope & GST_MATROSKA_TRACK_ENCODING_SCOPE_NEXT_CONTENT_ENCODING)
== 0)
}
gboolean
-gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
- guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
+gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
+ gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free)
{
- guint8 *data;
- guint size;
+ gpointer data;
+ gsize size;
gboolean ret = TRUE;
gint i;
for (i = 0; i < encodings->len; i++) {
GstMatroskaTrackEncoding *enc =
&g_array_index (encodings, GstMatroskaTrackEncoding, i);
- guint8 *new_data = NULL;
- guint new_size = 0;
+ gpointer new_data = NULL;
+ gsize new_size = 0;
if ((enc->scope & scope) == 0)
continue;
gst_tag_list_insert (common->global_tags, taglist, GST_TAG_MERGE_APPEND);
gst_tag_list_free (taglist);
} else {
+ GstEvent *tag_event = gst_event_new_tag (taglist);
+ gint i;
+
/* hm, already sent, no need to cache and wait anymore */
GST_DEBUG_OBJECT (common, "Sending late global tags %" GST_PTR_FORMAT,
taglist);
- gst_element_found_tags (el, taglist);
+
+ for (i = 0; i < common->src->len; i++) {
+ GstMatroskaTrackContext *stream;
+
+ stream = g_ptr_array_index (common->src, i);
+ gst_pad_push_event (stream->pad, gst_event_ref (tag_event));
+ }
+
+ gst_event_unref (tag_event);
}
}
gint64
gst_matroska_read_common_get_length (GstMatroskaReadCommon * common)
{
- GstFormat fmt = GST_FORMAT_BYTES;
gint64 end = -1;
- if (!gst_pad_query_peer_duration (common->sinkpad, &fmt, &end) ||
- fmt != GST_FORMAT_BYTES || end < 0)
+ if (!gst_pad_peer_query_duration (common->sinkpad, GST_FORMAT_BYTES,
+ &end) || end < 0)
GST_DEBUG_OBJECT (common, "no upstream length");
return end;
if (filename && mimetype && data && datalen > 0) {
GstTagImageType image_type = GST_TAG_IMAGE_TYPE_NONE;
GstBuffer *tagbuffer = NULL;
- GstCaps *caps;
+ /* GstCaps *caps; */
gchar *filename_lc = g_utf8_strdown (filename, -1);
GST_DEBUG_OBJECT (common, "Creating tag for attachment with "
if (!tagbuffer)
image_type = GST_TAG_IMAGE_TYPE_NONE;
+ else
+ data = NULL;
}
/* if this failed create an attachment buffer */
if (!tagbuffer) {
- tagbuffer = gst_buffer_new_and_alloc (datalen);
-
- memcpy (GST_BUFFER_DATA (tagbuffer), data, datalen);
- GST_BUFFER_SIZE (tagbuffer) = datalen;
-
- caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL);
- if (caps == NULL)
- caps = gst_caps_new_simple (mimetype, NULL);
- gst_buffer_set_caps (tagbuffer, caps);
- gst_caps_unref (caps);
+ tagbuffer = gst_buffer_new_wrapped (g_memdup (data, datalen), datalen);
+
+ /* FIXME: We can't attach caps to buffers in 0.11. */
+ /* caps = gst_type_find_helper_for_buffer (NULL, tagbuffer, NULL); */
+ /* if (caps == NULL) */
+ /* caps = gst_caps_new_simple (mimetype, NULL); */
+ /* gst_buffer_set_caps (tagbuffer, caps); */
+ /* gst_caps_unref (caps); */
}
+ /* FIXME: We can't attach caps to buffers in 0.11. */
/* Set filename and description on the caps */
- caps = GST_BUFFER_CAPS (tagbuffer);
- gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL);
- if (description)
- gst_caps_set_simple (caps, "description", G_TYPE_STRING, description,
- NULL);
+ /* caps = GST_BUFFER_CAPS (tagbuffer); */
+ /* gst_caps_set_simple (caps, "filename", G_TYPE_STRING, filename, NULL); */
+ /* if (description) */
+ /* gst_caps_set_simple (caps, "description", G_TYPE_STRING, description, */
+ /* NULL); */
- GST_DEBUG_OBJECT (common,
- "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps);
+ /* GST_DEBUG_OBJECT (common, */
+ /* "Created attachment buffer with caps: %" GST_PTR_FORMAT, caps); */
/* and append to the tag list */
if (image_type != GST_TAG_IMAGE_TYPE_NONE)
return ret;
}
- taglist = gst_tag_list_new ();
+ taglist = gst_tag_list_new_empty ();
while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
break;
GST_DEBUG_OBJECT (common, "Title: %s", GST_STR_NULL (text));
- taglist = gst_tag_list_new ();
- gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, text,
- NULL);
+ taglist = gst_tag_list_new (GST_TAG_TITLE, text, NULL);
gst_matroska_read_common_found_global_tag (common, el, taglist);
g_free (text);
break;
dur_u = gst_gdouble_to_guint64 (dur_f *
gst_guint64_to_gdouble (common->time_scale));
if (GST_CLOCK_TIME_IS_VALID (dur_u) && dur_u <= G_MAXINT64)
- gst_segment_set_duration (&common->segment, GST_FORMAT_TIME, dur_u);
+ common->segment.duration = dur_u;
}
DEBUG_ELEMENT_STOP (common, ebml, "SegmentInfo", ret);
return ret;
}
- taglist = gst_tag_list_new ();
+ taglist = gst_tag_list_new_empty ();
while (ret == GST_FLOW_OK && gst_ebml_read_has_remaining (ebml, 1, TRUE)) {
if ((ret = gst_ebml_peek_id (ebml, &id)) != GST_FLOW_OK)
gst_matroska_read_common_peek_adapter (GstMatroskaReadCommon * common, guint
peek, const guint8 ** data)
{
- *data = gst_adapter_peek (common->adapter, peek);
+ /* Caller needs to gst_adapter_unmap. */
+ *data = gst_adapter_map (common->adapter, peek);
if (*data == NULL)
return GST_FLOW_UNEXPECTED;
* We do it mainly to avoid pulling buffers of 1 byte all the time */
if (common->cached_buffer) {
guint64 cache_offset = GST_BUFFER_OFFSET (common->cached_buffer);
- guint cache_size = GST_BUFFER_SIZE (common->cached_buffer);
+ gsize cache_size = gst_buffer_get_size (common->cached_buffer);
if (cache_offset <= common->offset &&
(common->offset + size) <= (cache_offset + cache_size)) {
if (p_buf)
- *p_buf = gst_buffer_create_sub (common->cached_buffer,
- common->offset - cache_offset, size);
- if (bytes)
- *bytes = GST_BUFFER_DATA (common->cached_buffer) + common->offset -
- cache_offset;
+ *p_buf = gst_buffer_copy_region (common->cached_buffer,
+ GST_BUFFER_COPY_ALL, common->offset - cache_offset, size);
+ if (bytes) {
+ if (!common->cached_data)
+ common->cached_data = gst_buffer_map (common->cached_buffer,
+ NULL, NULL, GST_MAP_READ);
+ *bytes = common->cached_data + common->offset - cache_offset;
+ }
return GST_FLOW_OK;
}
/* not enough data in the cache, free cache and get a new one */
+ if (common->cached_data) {
+ gst_buffer_unmap (common->cached_buffer, common->cached_data, -1);
+ common->cached_data = NULL;
+ }
gst_buffer_unref (common->cached_buffer);
common->cached_buffer = NULL;
}
return ret;
}
- if (GST_BUFFER_SIZE (common->cached_buffer) >= size) {
+ if (gst_buffer_get_size (common->cached_buffer) >= size) {
if (p_buf)
- *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size);
- if (bytes)
- *bytes = GST_BUFFER_DATA (common->cached_buffer);
+ *p_buf = gst_buffer_copy_region (common->cached_buffer,
+ GST_BUFFER_COPY_ALL, 0, size);
+ if (bytes) {
+ common->cached_data = gst_buffer_map (common->cached_buffer,
+ NULL, NULL, GST_MAP_READ);
+ *bytes = common->cached_data;
+ }
return GST_FLOW_OK;
}
return ret;
}
- if (GST_BUFFER_SIZE (common->cached_buffer) < size) {
+ if (gst_buffer_get_size (common->cached_buffer) < size) {
GST_WARNING_OBJECT (common, "Dropping short buffer at offset %"
G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", common->offset,
- size, GST_BUFFER_SIZE (common->cached_buffer));
+ size, gst_buffer_get_size (common->cached_buffer));
gst_buffer_unref (common->cached_buffer);
common->cached_buffer = NULL;
}
if (p_buf)
- *p_buf = gst_buffer_create_sub (common->cached_buffer, 0, size);
- if (bytes)
- *bytes = GST_BUFFER_DATA (common->cached_buffer);
+ *p_buf = gst_buffer_copy_region (common->cached_buffer,
+ GST_BUFFER_COPY_ALL, 0, size);
+ if (bytes) {
+ common->cached_data = gst_buffer_map (common->cached_buffer,
+ NULL, NULL, GST_MAP_READ);
+ *bytes = common->cached_data;
+ }
return GST_FLOW_OK;
}
gst_matroska_read_common_peek_id_length_push (GstMatroskaReadCommon * common,
GstElement * el, guint32 * _id, guint64 * _length, guint * _needed)
{
- return gst_ebml_peek_id_length (_id, _length, _needed,
+ GstFlowReturn ret;
+
+ ret = gst_ebml_peek_id_length (_id, _length, _needed,
(GstPeekData) gst_matroska_read_common_peek_adapter, (gpointer) common,
el, common->offset);
+
+ gst_adapter_unmap (common->adapter);
+
+ return ret;
}
static GstFlowReturn
/* pull mode caching */
GstBuffer *cached_buffer;
+ guint8 *cached_data;
/* push and pull mode */
guint64 offset;
} GstMatroskaReadCommon;
GstFlowReturn gst_matroska_decode_content_encodings (GArray * encodings);
-gboolean gst_matroska_decode_data (GArray * encodings, guint8 ** data_out,
- guint * size_out, GstMatroskaTrackEncodingScope scope, gboolean free);
+gboolean gst_matroska_decode_data (GArray * encodings, gpointer * data_out,
+ gsize * size_out, GstMatroskaTrackEncodingScope scope, gboolean free);
gint gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
gpointer user_data);
GstMatroskaIndex * gst_matroska_read_common_do_index_seek (
* ]| This pipeline re-encodes a video file of any format into a WebM file.
* |[
* gst-launch-0.10 webmmux name=mux ! filesink location=test.webm \
- * videotestsrc num-buffers=250 ! video/x-raw-yuv,framerate=25/1 ! ffmpegcolorspace ! vp8enc ! queue ! mux.video_0 \
- * audiotestsrc samplesperbuffer=44100 num-buffers=10 ! audio/x-raw-float,rate=44100 ! vorbisenc ! queue ! mux.audio_0
+ * videotestsrc num-buffers=250 ! video/x-raw,framerate=25/1 ! ffmpegcolorspace ! vp8enc ! queue ! mux.video_0 \
+ * audiotestsrc samplesperbuffer=44100 num-buffers=10 ! audio/x-raw,rate=44100 ! vorbisenc ! queue ! mux.audio_0
* ]| This pipeline muxes a test video and a sine wave into a WebM file.
* </refsect2>
*/
"channels = (int) [ 1, MAX ], " \
"rate = (int) [ 1, MAX ]"
-GST_BOILERPLATE (GstWebMMux, gst_webm_mux, GstMatroskaMux,
- GST_TYPE_MATROSKA_MUX);
+G_DEFINE_TYPE (GstWebMMux, gst_webm_mux, GST_TYPE_MATROSKA_MUX);
static GstStaticPadTemplate webm_src_templ = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
);
static void
-gst_webm_mux_base_init (gpointer g_class)
-{
-}
-
-static void
gst_webm_mux_class_init (GstWebMMuxClass * klass)
{
GstElementClass *gstelement_class = (GstElementClass *) klass;
}
static void
-gst_webm_mux_init (GstWebMMux * mux, GstWebMMuxClass * g_class)
+gst_webm_mux_init (GstWebMMux * mux)
{
GST_MATROSKA_MUX (mux)->doctype = GST_MATROSKA_DOCTYPE_WEBM;
}
setup_matroskamux (GstStaticPadTemplate * srctemplate)
{
GstElement *matroskamux;
+ GstSegment segment;
GST_DEBUG ("setup_matroskamux");
matroskamux = gst_check_setup_element ("matroskamux");
mysrcpad = setup_src_pad (matroskamux, srctemplate, NULL);
mysinkpad = setup_sink_pad (matroskamux, &sinktemplate, NULL);
+ fail_unless (gst_element_set_state (matroskamux,
+ GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
+ "could not set to playing");
+
+ gst_segment_init (&segment, GST_FORMAT_TIME);
+ fail_unless (gst_pad_push_event (mysrcpad,
+ gst_event_new_segment (&segment)), "Segment event rejected");
+
return matroskamux;
}
static void
check_buffer_data (GstBuffer * buffer, void *data, size_t data_size)
{
- fail_unless (GST_BUFFER_SIZE (buffer) == data_size);
- fail_unless (memcmp (data, GST_BUFFER_DATA (buffer), data_size) == 0);
+ fail_unless (gst_buffer_get_size (buffer) == data_size);
+ fail_unless (gst_buffer_memcmp (buffer, 0, data, data_size) == 0);
}
GST_START_TEST (test_ebml_header)
};
matroskamux = setup_matroskamux (&srcac3template);
- fail_unless (gst_element_set_state (matroskamux,
- GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
- "could not set to playing");
- inbuffer = gst_buffer_new_and_alloc (1);
+ inbuffer = gst_buffer_new_allocate (NULL, 1, 0);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
num_buffers = g_list_length (buffers);
};
matroskamux = setup_matroskamux (&srcvorbistemplate);
- fail_unless (gst_element_set_state (matroskamux,
- GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
- "could not set to playing");
- inbuffer = gst_buffer_new_and_alloc (1);
caps = gst_caps_from_string (VORBIS_CAPS_STRING);
- gst_buffer_set_caps (inbuffer, caps);
+ fail_unless (gst_pad_set_caps (mysrcpad, caps));
gst_caps_unref (caps);
+
+ inbuffer = gst_buffer_new_allocate (NULL, 1, 0);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
for (i = 0; i < num_buffers; ++i) {
gint j;
+ gsize buffer_size;
outbuffer = GST_BUFFER (buffers->data);
fail_if (outbuffer == NULL);
+ buffer_size = gst_buffer_get_size (outbuffer);
buffers = g_list_remove (buffers, outbuffer);
- if (!vorbis_header_found && GST_BUFFER_SIZE (outbuffer) >= sizeof (data)) {
- for (j = 0; j <= GST_BUFFER_SIZE (outbuffer) - sizeof (data); j++) {
- if (memcmp (GST_BUFFER_DATA (outbuffer) + j, data, sizeof (data)) == 0) {
+ if (!vorbis_header_found && buffer_size >= sizeof (data)) {
+ for (j = 0; j <= buffer_size - sizeof (data); j++) {
+ if (gst_buffer_memcmp (outbuffer, j, data, sizeof (data)) == 0) {
vorbis_header_found = TRUE;
break;
}
{
GstElement *matroskamux;
GstBuffer *inbuffer, *outbuffer;
+ guint8 *indata;
GstCaps *caps;
int num_buffers;
int i;
guint8 data1[] = { 0x42 };
matroskamux = setup_matroskamux (&srcac3template);
- fail_unless (gst_element_set_state (matroskamux,
- GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
- "could not set to playing");
- /* Generate the header */
- inbuffer = gst_buffer_new_and_alloc (1);
- GST_BUFFER_TIMESTAMP (inbuffer) = 0;
caps = gst_caps_from_string (AC3_CAPS_STRING);
- gst_buffer_set_caps (inbuffer, caps);
+ fail_unless (gst_pad_set_caps (mysrcpad, caps));
gst_caps_unref (caps);
+
+ /* Generate the header */
+ inbuffer = gst_buffer_new_allocate (NULL, 1, 0);
+ GST_BUFFER_TIMESTAMP (inbuffer) = 0;
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
buffers = NULL;
/* Now push a buffer */
- inbuffer = gst_buffer_new_and_alloc (1);
- GST_BUFFER_DATA (inbuffer)[0] = 0x42;
+ indata = g_malloc (1);
+ inbuffer = gst_buffer_new_wrapped (indata, 1);
+ indata[0] = 0x42;
GST_BUFFER_TIMESTAMP (inbuffer) = 1000000;
- caps = gst_caps_from_string (AC3_CAPS_STRING);
- gst_buffer_set_caps (inbuffer, caps);
- gst_caps_unref (caps);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
int i;
matroskamux = setup_matroskamux (&srcac3template);
- fail_unless (gst_element_set_state (matroskamux,
- GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
- "could not set to playing");
- inbuffer = gst_buffer_new_and_alloc (1);
+ inbuffer = gst_buffer_new_allocate (NULL, 1, 0);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
num_buffers = g_list_length (buffers);
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
"could not set to playing");
- inbuffer = gst_buffer_new_and_alloc (1);
+ inbuffer = gst_buffer_new_allocate (NULL, 1, 0);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK);
num_buffers = g_list_length (buffers);