diff options
author | Michael Smith <msmith@rdio.com> | 2012-10-26 13:48:06 -0700 |
---|---|---|
committer | Michael Smith <msmith@rdio.com> | 2012-10-26 13:48:06 -0700 |
commit | 0c8a7fa46f59177c31539eeb81e5c5277b474362 (patch) | |
tree | db96e69ee5e32fad43feec9360e48e10eb149d84 | |
parent | 0a30ecba90dbc8008ca0f9c39381f34f516e9190 (diff) |
mxf: Port mxfdemux to 1.0
Also ports mxfmux to 1.0 to the extent that it compiles, but is 100% untested,
so remains disabled.
Conflicts:
gst/mxf/mxfdemux.c
gst/mxf/mxfmux.c
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gst/mxf/Makefile.am | 3 | ||||
-rw-r--r-- | gst/mxf/mxf.c | 6 | ||||
-rw-r--r-- | gst/mxf/mxfaes-bwf.c | 149 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 6 | ||||
-rw-r--r-- | gst/mxf/mxfd10.c | 37 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.c | 497 | ||||
-rw-r--r-- | gst/mxf/mxfdemux.h | 6 | ||||
-rw-r--r-- | gst/mxf/mxfdv-dif.c | 4 | ||||
-rw-r--r-- | gst/mxf/mxfessence.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfjpeg2000.c | 38 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.c | 84 | ||||
-rw-r--r-- | gst/mxf/mxfmetadata.h | 2 | ||||
-rw-r--r-- | gst/mxf/mxfmpeg.c | 164 | ||||
-rw-r--r-- | gst/mxf/mxfmux.c | 256 | ||||
-rw-r--r-- | gst/mxf/mxftypes.c | 62 | ||||
-rw-r--r-- | gst/mxf/mxfup.c | 191 | ||||
-rw-r--r-- | gst/mxf/mxfvc3.c | 6 |
18 files changed, 837 insertions, 678 deletions
diff --git a/configure.ac b/configure.ac index 2fb00de11..52364ad5d 100644 --- a/configure.ac +++ b/configure.ac @@ -316,7 +316,7 @@ GST_PLUGINS_NONPORTED=" aiff \ freeverb \ hdvparse ivfparse jp2kdecimator \ kate librfb \ - mpegpsmux mve mxf mythtv nsf nuvdemux \ + mpegpsmux mve mythtv nsf nuvdemux \ patchdetect real \ sdi stereo tta videofilters \ videomeasure videosignal vmnc \ diff --git a/gst/mxf/Makefile.am b/gst/mxf/Makefile.am index 584991309..0067d0ab9 100644 --- a/gst/mxf/Makefile.am +++ b/gst/mxf/Makefile.am @@ -21,7 +21,8 @@ libgstmxf_la_SOURCES = \ libgstmxf_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) libgstmxf_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) \ - -lgstvideo-@GST_API_VERSION@ + -lgstvideo-@GST_API_VERSION@ \ + -lgstaudio-@GST_API_VERSION@ libgstmxf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstmxf_la_LIBTOOLFLAGS = --tag=disable-static diff --git a/gst/mxf/mxf.c b/gst/mxf/mxf.c index 091d5de3a..bfc280150 100644 --- a/gst/mxf/mxf.c +++ b/gst/mxf/mxf.c @@ -69,10 +69,10 @@ plugin_init (GstPlugin * plugin) mxf_up_init (); mxf_vc3_init (); + /* mxfmux is disabled for now - it compiles but is completely untested */ if (!gst_element_register (plugin, "mxfdemux", GST_RANK_PRIMARY, - GST_TYPE_MXF_DEMUX) || - !gst_element_register (plugin, "mxfmux", GST_RANK_PRIMARY, - GST_TYPE_MXF_MUX)) + GST_TYPE_MXF_DEMUX)) + /* || !gst_element_register (plugin, "mxfmux", GST_RANK_PRIMARY, GST_TYPE_MXF_MUX)) */ return FALSE; return TRUE; diff --git a/gst/mxf/mxfaes-bwf.c b/gst/mxf/mxfaes-bwf.c index b9217ba6e..63f618c35 100644 --- a/gst/mxf/mxfaes-bwf.c +++ b/gst/mxf/mxfaes-bwf.c @@ -33,6 +33,8 @@ #endif #include <gst/gst.h> +#include <gst/audio/audio.h> + #include <string.h> #include "mxfaes-bwf.h" @@ -295,9 +297,12 @@ mxf_metadata_wave_audio_essence_descriptor_to_structure (MXFMetadataBase * m) if (self->peak_envelope_data) { GstBuffer *buf = gst_buffer_new_and_alloc (self->peak_envelope_data_length); + GstMapInfo map; - memcpy (GST_BUFFER_DATA (buf), self->peak_envelope_data, + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->peak_envelope_data, self->peak_envelope_data_length); + gst_buffer_unmap (buf, &map); gst_structure_id_set (ret, MXF_QUARK (PEAK_ENVELOPE_DATA), GST_TYPE_BUFFER, buf, NULL); gst_buffer_unref (buf); @@ -821,9 +826,11 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) if (self->channel_status_mode) { GstBuffer *buf = gst_buffer_new_and_alloc (self->n_channel_status_mode); + GstMapInfo map; - memcpy (GST_BUFFER_DATA (buf), self->channel_status_mode, - self->n_channel_status_mode); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->channel_status_mode, self->n_channel_status_mode); + gst_buffer_unmap (buf, &map); gst_structure_id_set (ret, MXF_QUARK (CHANNEL_STATUS_MODE), GST_TYPE_BUFFER, buf, NULL); gst_buffer_unref (buf); @@ -831,9 +838,11 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) if (self->channel_status_mode) { GstBuffer *buf = gst_buffer_new_and_alloc (self->n_channel_status_mode); + GstMapInfo map; - memcpy (GST_BUFFER_DATA (buf), self->channel_status_mode, - self->n_channel_status_mode); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->channel_status_mode, self->n_channel_status_mode); + gst_buffer_unmap (buf, &map); gst_structure_id_set (ret, MXF_QUARK (CHANNEL_STATUS_MODE), GST_TYPE_BUFFER, buf, NULL); gst_buffer_unref (buf); @@ -845,6 +854,7 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) , v = { 0,}; GstBuffer *buf; + GstMapInfo map; g_value_init (&va, GST_TYPE_ARRAY); @@ -852,7 +862,9 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) buf = gst_buffer_new_and_alloc (24); g_value_init (&v, GST_TYPE_BUFFER); - memcpy (GST_BUFFER_DATA (buf), self->fixed_channel_status_data[i], 24); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->fixed_channel_status_data[i], 24); + gst_buffer_unmap (buf, &map); gst_value_set_buffer (&v, buf); gst_value_array_append_value (&va, &v); gst_buffer_unref (buf); @@ -868,9 +880,11 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) if (self->user_data_mode) { GstBuffer *buf = gst_buffer_new_and_alloc (self->n_user_data_mode); + GstMapInfo map; - memcpy (GST_BUFFER_DATA (buf), self->user_data_mode, - self->n_user_data_mode); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->user_data_mode, self->n_user_data_mode); + gst_buffer_unmap (buf, &map); gst_structure_id_set (ret, MXF_QUARK (USER_DATA_MODE), GST_TYPE_BUFFER, buf, NULL); gst_buffer_unref (buf); @@ -882,6 +896,7 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) , v = { 0,}; GstBuffer *buf; + GstMapInfo map; g_value_init (&va, GST_TYPE_ARRAY); @@ -889,7 +904,9 @@ mxf_metadata_aes3_audio_essence_descriptor_to_structure (MXFMetadataBase * m) buf = gst_buffer_new_and_alloc (24); g_value_init (&v, GST_TYPE_BUFFER); - memcpy (GST_BUFFER_DATA (buf), self->fixed_user_data[i], 24); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, self->fixed_user_data[i], 24); + gst_buffer_unmap (buf, &map); gst_value_set_buffer (&v, buf); gst_value_array_append_value (&va, &v); gst_buffer_unref (buf); @@ -1185,6 +1202,7 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, mxf_ul_is_subclass (&mxf_sound_essence_compression_uncompressed, &descriptor->sound_essence_compression)) { guint block_align; + GstAudioFormat audio_format; if (descriptor->channel_count == 0 || descriptor->quantization_bits == 0 || @@ -1200,13 +1218,13 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, (GST_ROUND_UP_8 (descriptor->quantization_bits) * descriptor->channel_count) / 8; - ret = gst_caps_new_simple ("audio/x-raw-int", - "signed", G_TYPE_BOOLEAN, - (block_align != 1), "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "depth", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, "width", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, NULL); - - mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret); + audio_format = + gst_audio_format_build_integer (block_align != 1, G_LITTLE_ENDIAN, + (block_align / descriptor->channel_count) * 8, + (block_align / descriptor->channel_count) * 8); + ret = + mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor, + &audio_format); codec_name = g_strdup_printf ("Uncompressed %u-bit little endian integer PCM audio", @@ -1214,6 +1232,7 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, } else if (mxf_ul_is_subclass (&mxf_sound_essence_compression_aiff, &descriptor->sound_essence_compression)) { guint block_align; + GstAudioFormat audio_format; if (descriptor->channel_count == 0 || descriptor->quantization_bits == 0 || @@ -1230,13 +1249,13 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, (GST_ROUND_UP_8 (descriptor->quantization_bits) * descriptor->channel_count) / 8; - ret = gst_caps_new_simple ("audio/x-raw-int", - "signed", G_TYPE_BOOLEAN, - (block_align != 1), "endianness", G_TYPE_INT, G_BIG_ENDIAN, "depth", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, "width", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, NULL); - - mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret); + audio_format = + gst_audio_format_build_integer (block_align != 1, G_BIG_ENDIAN, + (block_align / descriptor->channel_count) * 8, + (block_align / descriptor->channel_count) * 8); + ret = + mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor, + &audio_format); codec_name = g_strdup_printf ("Uncompressed %u-bit big endian integer PCM audio", @@ -1250,7 +1269,7 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, GST_ERROR ("Invalid descriptor"); return NULL; } - ret = gst_caps_new_simple ("audio/x-alaw", NULL); + ret = gst_caps_new_empty_simple ("audio/x-alaw"); mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret); codec_name = g_strdup ("A-law encoded audio"); @@ -1262,7 +1281,7 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track, *handler = mxf_bwf_handle_essence_element; if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); if (codec_name) { gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC, @@ -1285,6 +1304,7 @@ mxf_aes3_create_caps (MXFMetadataTimelineTrack * track, GstCaps *ret = NULL; MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL; gchar *codec_name = NULL; + GstAudioFormat audio_format; guint block_align; if (MXF_IS_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (descriptor)) @@ -1306,20 +1326,20 @@ mxf_aes3_create_caps (MXFMetadataTimelineTrack * track, (GST_ROUND_UP_8 (descriptor->quantization_bits) * descriptor->channel_count) / 8; - ret = gst_caps_new_simple ("audio/x-raw-int", - "signed", G_TYPE_BOOLEAN, - (block_align != 1), "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "depth", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, "width", - G_TYPE_INT, (block_align / descriptor->channel_count) * 8, NULL); - - mxf_metadata_generic_sound_essence_descriptor_set_caps (descriptor, ret); + audio_format = + gst_audio_format_build_integer (block_align != 1, G_LITTLE_ENDIAN, + (block_align / descriptor->channel_count) * 8, + (block_align / descriptor->channel_count) * 8); + ret = + mxf_metadata_generic_sound_essence_descriptor_create_caps (descriptor, + &audio_format); codec_name = g_strdup_printf ("Uncompressed %u-bit AES3 audio", (block_align / descriptor->channel_count) * 8); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC, codec_name, GST_TAG_BITRATE, @@ -1400,7 +1420,7 @@ typedef struct } BWFMappingData; static GstFlowReturn -mxf_bwf_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, +mxf_bwf_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { BWFMappingData *md = mapping_data; @@ -1445,16 +1465,10 @@ mxf_bwf_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, MXFEssenceElementWriteFunc * handler, gpointer * mapping_data) { MXFMetadataWaveAudioEssenceDescriptor *ret; - GstStructure *s; BWFMappingData *md; - gint width, rate, channels, endianness; - - s = gst_caps_get_structure (caps, 0); - if (strcmp (gst_structure_get_name (s), "audio/x-raw-int") != 0 || - !gst_structure_get_int (s, "width", &width) || - !gst_structure_get_int (s, "rate", &rate) || - !gst_structure_get_int (s, "channels", &channels) || - !gst_structure_get_int (s, "endianness", &endianness)) { + GstAudioInfo info; + + if (!gst_audio_info_from_caps (&info, caps)) { GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps); return NULL; } @@ -1463,16 +1477,16 @@ mxf_bwf_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, g_object_new (MXF_TYPE_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR, NULL); memcpy (&ret->parent.parent.essence_container, &bwf_essence_container_ul, 16); - if (endianness == G_LITTLE_ENDIAN) + if (info.finfo->endianness == G_LITTLE_ENDIAN) memcpy (&ret->parent.sound_essence_compression, &mxf_sound_essence_compression_uncompressed, 16); else memcpy (&ret->parent.sound_essence_compression, &mxf_sound_essence_compression_aiff, 16); - ret->block_align = (width / 8) * channels; - ret->parent.quantization_bits = width; - ret->avg_bps = ret->block_align * rate; + ret->block_align = (info.finfo->width / 8) * info.channels; + ret->parent.quantization_bits = info.finfo->width; + ret->avg_bps = ret->block_align * info.rate; if (!mxf_metadata_generic_sound_essence_descriptor_from_caps (&ret->parent, caps)) { @@ -1483,9 +1497,9 @@ mxf_bwf_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, *handler = mxf_bwf_write_func; md = g_new0 (BWFMappingData, 1); - md->width = width; - md->rate = rate; - md->channels = channels; + md->width = info.finfo->width; + md->rate = info.rate; + md->channels = info.channels; *mapping_data = md; return (MXFMetadataFileDescriptor *) ret; @@ -1547,34 +1561,13 @@ static MXFEssenceElementWriter mxf_bwf_essence_element_writer = { }; #define BWF_CAPS \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 32, " \ - "depth = (int) 32, " \ - "signed = (boolean) TRUE; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 24, " \ - "depth = (int) 24, " \ - "signed = (boolean) TRUE; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 16, " \ - "depth = (int) 16, " \ - "signed = (boolean) TRUE; " \ - "audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, MAX ], " \ - "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \ - "width = (int) 8, " \ - "depth = (int) 8, " \ - "signed = (boolean) FALSE" + GST_AUDIO_CAPS_MAKE ("S32LE") "; " \ + GST_AUDIO_CAPS_MAKE ("S32BE") "; " \ + GST_AUDIO_CAPS_MAKE ("S24LE") "; " \ + GST_AUDIO_CAPS_MAKE ("S24BE") "; " \ + GST_AUDIO_CAPS_MAKE ("S16LE") "; " \ + GST_AUDIO_CAPS_MAKE ("S16BE") "; " \ + GST_AUDIO_CAPS_MAKE ("U8") void mxf_aes_bwf_init (void) diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c index 49b37237b..01bba300e 100644 --- a/gst/mxf/mxfalaw.c +++ b/gst/mxf/mxfalaw.c @@ -118,13 +118,13 @@ mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (s && s->audio_sampling_rate.n != 0 && s->audio_sampling_rate.d != 0 && s->channel_count != 0) { - caps = gst_caps_new_simple ("audio/x-alaw", NULL); + caps = gst_caps_new_empty_simple ("audio/x-alaw"); mxf_metadata_generic_sound_essence_descriptor_set_caps (s, caps); /* TODO: Handle channel layout somehow? * Or is alaw limited to two channels? */ if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC, "A-law encoded audio", NULL); @@ -147,7 +147,7 @@ typedef struct } ALawMappingData; static GstFlowReturn -mxf_alaw_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, +mxf_alaw_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { ALawMappingData *md = mapping_data; diff --git a/gst/mxf/mxfd10.c b/gst/mxf/mxfd10.c index 71e818a48..1a6352bb0 100644 --- a/gst/mxf/mxfd10.c +++ b/gst/mxf/mxfd10.c @@ -26,6 +26,7 @@ #endif #include <gst/gst.h> +#include <gst/audio/audio.h> #include <string.h> #include "mxfd10.h" @@ -101,6 +102,8 @@ mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer, guint i, j, nsamples; const guint8 *indata; guint8 *outdata; + GstMapInfo map; + GstMapInfo outmap; MXFD10AudioMappingData *data = mapping_data; g_return_val_if_fail (data != NULL, GST_FLOW_ERROR); @@ -113,21 +116,23 @@ mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer, return GST_FLOW_ERROR; } + gst_buffer_map (buffer, &map, GST_MAP_READ); + /* Now transform raw AES3 into raw audio, see SMPTE 331M */ - if ((GST_BUFFER_SIZE (buffer) - 4) % 32 != 0) { + if ((map.size - 4) % 32 != 0) { + gst_buffer_unmap (buffer, &map); GST_ERROR ("Invalid D10 sound essence buffer size"); return GST_FLOW_ERROR; } - nsamples = ((GST_BUFFER_SIZE (buffer) - 4) / 4) / 8; + nsamples = ((map.size - 4) / 4) / 8; *outbuf = gst_buffer_new_and_alloc (nsamples * data->width * data->channels); - gst_buffer_copy_metadata (*outbuf, buffer, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | - GST_BUFFER_COPY_CAPS); + gst_buffer_copy_into (*outbuf, buffer, GST_BUFFER_COPY_METADATA, 0, -1); + gst_buffer_map (*outbuf, &outmap, GST_MAP_WRITE); - indata = GST_BUFFER_DATA (buffer); - outdata = GST_BUFFER_DATA (*outbuf); + indata = map.data; + outdata = outmap.data; /* Skip 32 bit header */ indata += 4; @@ -154,6 +159,8 @@ mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer, indata += 4 * (8 - data->channels); } + gst_buffer_unmap (*outbuf, &outmap); + gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); return GST_FLOW_OK; @@ -198,10 +205,11 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, } if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); if (s) { MXFD10AudioMappingData *data; + GstAudioFormat audio_format; if (s->channel_count == 0 || s->quantization_bits == 0 || @@ -217,13 +225,12 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, /* FIXME: set channel layout */ - caps = gst_caps_new_simple ("audio/x-raw-int", - "signed", G_TYPE_BOOLEAN, - (s->quantization_bits != 8), "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, - "depth", G_TYPE_INT, s->quantization_bits, "width", G_TYPE_INT, - s->quantization_bits, NULL); - - mxf_metadata_generic_sound_essence_descriptor_set_caps (s, caps); + audio_format = + gst_audio_format_build_integer (s->quantization_bits != 8, + G_LITTLE_ENDIAN, s->quantization_bits, s->quantization_bits); + caps = + mxf_metadata_generic_sound_essence_descriptor_create_caps (s, + &audio_format); *handler = mxf_d10_sound_handle_essence_element; diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c index 4758b8d62..bb372ff5e 100644 --- a/gst/mxf/mxfdemux.c +++ b/gst/mxf/mxfdemux.c @@ -106,7 +106,7 @@ static void gst_mxf_demux_pad_init (GstMXFDemuxPad * pad) { pad->last_flow = GST_FLOW_OK; - pad->last_stop = 0; + pad->position = 0; } enum @@ -117,12 +117,15 @@ enum PROP_STRUCTURE }; -static gboolean gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event); -static gboolean gst_mxf_demux_src_event (GstPad * pad, GstEvent * event); -static const GstQueryType *gst_mxf_demux_src_query_type (GstPad * pad); -static gboolean gst_mxf_demux_src_query (GstPad * pad, GstQuery * query); +static gboolean gst_mxf_demux_sink_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_mxf_demux_src_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_mxf_demux_src_query (GstPad * pad, GstObject * parent, + GstQuery * query); -GST_BOILERPLATE (GstMXFDemux, gst_mxf_demux, GstElement, GST_TYPE_ELEMENT); +#define gst_mxf_demux_parent_class parent_class +G_DEFINE_TYPE (GstMXFDemux, gst_mxf_demux, GST_TYPE_ELEMENT); static void gst_mxf_demux_remove_pad (GstMXFDemuxPad * pad, GstMXFDemux * demux) @@ -321,12 +324,12 @@ gst_mxf_demux_pull_range (GstMXFDemux * demux, guint64 offset, return ret; } - if (G_UNLIKELY (*buffer && GST_BUFFER_SIZE (*buffer) != size)) { + if (G_UNLIKELY (*buffer && gst_buffer_get_size (*buffer) != size)) { GST_WARNING_OBJECT (demux, "partial pull got %u when expecting %u from offset %" G_GUINT64_FORMAT, - GST_BUFFER_SIZE (*buffer), size, offset); + gst_buffer_get_size (*buffer), size, offset); gst_buffer_unref (*buffer); - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; *buffer = NULL; return ret; } @@ -390,10 +393,12 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key, MXFPartitionPack partition; GList *l; GstMXFDemuxPartition *p = NULL; + GstMapInfo map; + gboolean ret; GST_DEBUG_OBJECT (demux, "Handling partition pack of size %u at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + G_GUINT64_FORMAT, gst_buffer_get_size (buffer), demux->offset); for (l = demux->partitions; l; l = l->next) { GstMXFDemuxPartition *tmp = l->data; @@ -407,8 +412,10 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key, } - if (!mxf_partition_pack_parse (key, &partition, - GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { + gst_buffer_map (buffer, &map, GST_MAP_READ); + ret = mxf_partition_pack_parse (key, &partition, map.data, map.size); + gst_buffer_unmap (buffer, &map); + if (!ret) { GST_ERROR_OBJECT (demux, "Parsing partition pack failed"); return GST_FLOW_ERROR; } @@ -463,9 +470,12 @@ static GstFlowReturn gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key, GstBuffer * buffer) { + GstMapInfo map; + gboolean ret; + GST_DEBUG_OBJECT (demux, "Handling primer pack of size %u at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + G_GUINT64_FORMAT, gst_buffer_get_size (buffer), demux->offset); if (G_UNLIKELY (!demux->current_partition)) { GST_ERROR_OBJECT (demux, "Primer pack before partition pack"); @@ -477,8 +487,11 @@ gst_mxf_demux_handle_primer_pack (GstMXFDemux * demux, const MXFUL * key, return GST_FLOW_OK; } - if (!mxf_primer_pack_parse (key, &demux->current_partition->primer, - GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { + gst_buffer_map (buffer, &map, GST_MAP_READ); + ret = mxf_primer_pack_parse (key, &demux->current_partition->primer, + map.data, map.size); + gst_buffer_unmap (buffer, &map); + if (!ret) { GST_ERROR_OBJECT (demux, "Parsing primer pack failed"); return GST_FLOW_ERROR; } @@ -495,7 +508,6 @@ gst_mxf_demux_resolve_references (GstMXFDemux * demux) GHashTableIter iter; MXFMetadataBase *m = NULL; GstStructure *structure; - GstTagList *taglist; g_static_rw_lock_writer_lock (&demux->metadata_lock); @@ -529,12 +541,14 @@ gst_mxf_demux_resolve_references (GstMXFDemux * demux) demux->metadata_resolved = TRUE; - taglist = gst_tag_list_new (); structure = mxf_metadata_base_to_structure (MXF_METADATA_BASE (demux->preface)); - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_MXF_STRUCTURE, + if (!demux->tags) + demux->tags = gst_tag_list_new_empty (); + + gst_tag_list_add (demux->tags, GST_TAG_MERGE_REPLACE, GST_TAG_MXF_STRUCTURE, structure, NULL); - gst_element_found_tags (GST_ELEMENT (demux), taglist); + gst_structure_free (structure); g_static_rw_lock_writer_unlock (&demux->metadata_lock); @@ -615,11 +629,11 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux) for (i = 0; i < demux->preface->content_storage->n_packages; i++) { if (demux->preface->content_storage->packages[i] && - MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface->content_storage-> - packages[i])) { + MXF_IS_METADATA_MATERIAL_PACKAGE (demux->preface-> + content_storage->packages[i])) { ret = - MXF_METADATA_GENERIC_PACKAGE (demux->preface->content_storage-> - packages[i]); + MXF_METADATA_GENERIC_PACKAGE (demux->preface-> + content_storage->packages[i]); break; } } @@ -632,7 +646,6 @@ gst_mxf_demux_choose_package (GstMXFDemux * demux) done: if (mxf_umid_is_equal (&ret->package_uid, &demux->current_package_uid)) { gchar current_package_string[96]; - GstTagList *tags = gst_tag_list_new (); gst_mxf_demux_remove_pads (demux); memcpy (&demux->current_package_uid, &ret->package_uid, 32); @@ -641,9 +654,10 @@ done: demux->current_package_string = g_strdup (current_package_string); g_object_notify (G_OBJECT (demux), "package"); - gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_MXF_UMID, + if (!demux->tags) + demux->tags = gst_tag_list_new_empty (); + gst_tag_list_add (demux->tags, GST_TAG_MERGE_REPLACE, GST_TAG_MXF_UMID, demux->current_package_string, NULL); - gst_element_found_tags (GST_ELEMENT_CAST (demux), tags); } demux->current_package = ret; @@ -779,8 +793,8 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux) essence_container); if (track->parent.type == MXF_METADATA_TRACK_PICTURE_ESSENCE) { - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[0])) + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[0])) mxf_ul_to_string (&MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent.descriptor[0])->picture_essence_coding, essence_compression); @@ -789,8 +803,8 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux) g_strdup_printf ("video/x-mxf-%s-%s", essence_container, essence_compression); } else if (track->parent.type == MXF_METADATA_TRACK_SOUND_ESSENCE) { - if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent. - descriptor[0])) + if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[0])) mxf_ul_to_string (&MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.descriptor[0])->sound_essence_compression, essence_compression); @@ -799,8 +813,8 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux) g_strdup_printf ("audio/x-mxf-%s-%s", essence_container, essence_compression); } else if (track->parent.type == MXF_METADATA_TRACK_DATA_ESSENCE) { - if (MXF_IS_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (track->parent. - descriptor[0])) + if (MXF_IS_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[0])) mxf_ul_to_string (&MXF_METADATA_GENERIC_DATA_ESSENCE_DESCRIPTOR (track->parent.descriptor[0])->data_essence_coding, essence_compression); @@ -813,7 +827,7 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux) g_assert_not_reached (); } - caps = gst_caps_new_simple (name, NULL); + caps = gst_caps_new_empty_simple (name); g_free (name); } else { caps = @@ -920,6 +934,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) MXFMetadataTimelineTrack *source_track = NULL; GstMXFDemuxEssenceTrack *etrack = NULL; GstMXFDemuxPad *pad = NULL; + GstCaps *pad_caps; GST_DEBUG_OBJECT (demux, "Handling track %u", i); @@ -1100,6 +1115,9 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) pad->need_segment = TRUE; pad->eos = FALSE; g_free (pad_name); + + if (demux->tags) + pad->tags = gst_tag_list_copy (demux->tags); } if (!pad) { @@ -1154,28 +1172,37 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux) pad->tags = gst_tag_list_copy (etrack->tags); } - if (GST_PAD_CAPS (pad) - && !gst_caps_is_equal (GST_PAD_CAPS (pad), etrack->caps)) { - gst_pad_set_caps (GST_PAD_CAST (pad), etrack->caps); - } else if (!GST_PAD_CAPS (pad)) { + pad_caps = gst_pad_get_current_caps (GST_PAD_CAST (pad)); + if (pad_caps && !gst_caps_is_equal (pad_caps, etrack->caps)) { gst_pad_set_caps (GST_PAD_CAST (pad), etrack->caps); + } else if (!pad_caps) { + gchar *stream_id; gst_pad_set_event_function (GST_PAD_CAST (pad), GST_DEBUG_FUNCPTR (gst_mxf_demux_src_event)); - gst_pad_set_query_type_function (GST_PAD_CAST (pad), - GST_DEBUG_FUNCPTR (gst_mxf_demux_src_query_type)); gst_pad_set_query_function (GST_PAD_CAST (pad), GST_DEBUG_FUNCPTR (gst_mxf_demux_src_query)); gst_pad_use_fixed_caps (GST_PAD_CAST (pad)); gst_pad_set_active (GST_PAD_CAST (pad), TRUE); + stream_id = + gst_pad_create_stream_id_printf (GST_PAD_CAST (pad), + GST_ELEMENT_CAST (demux), "%u", pad->track_id); + gst_pad_push_event (GST_PAD_CAST (pad), + gst_event_new_stream_start (stream_id)); + g_free (stream_id); + + gst_pad_set_caps (GST_PAD_CAST (pad), etrack->caps); + pads = g_list_prepend (pads, gst_object_ref (pad)); g_ptr_array_add (demux->src, pad); pad->discont = TRUE; } + if (pad_caps) + gst_caps_unref (pad_caps); } if (demux->src->len > 0) { @@ -1216,13 +1243,14 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, { guint16 type; MXFMetadata *metadata = NULL, *old = NULL; + GstMapInfo map; GstFlowReturn ret = GST_FLOW_OK; type = GST_READ_UINT16_BE (key->u + 13); GST_DEBUG_OBJECT (demux, "Handling metadata of size %u at offset %" - G_GUINT64_FORMAT " of type 0x%04x", GST_BUFFER_SIZE (buffer), + G_GUINT64_FORMAT " of type 0x%04x", gst_buffer_get_size (buffer), demux->offset, type); if (G_UNLIKELY (!demux->current_partition)) { @@ -1240,9 +1268,11 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key, return GST_FLOW_OK; } + gst_buffer_map (buffer, &map, GST_MAP_READ); metadata = mxf_metadata_new (type, &demux->current_partition->primer, demux->offset, - GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); + map.data, map.size); + gst_buffer_unmap (buffer, &map); if (!metadata) { GST_WARNING_OBJECT (demux, @@ -1303,6 +1333,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, { guint32 type; guint8 scheme; + GstMapInfo map; GstFlowReturn ret = GST_FLOW_OK; MXFDescriptiveMetadata *m = NULL, *old = NULL; @@ -1312,7 +1343,7 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, GST_DEBUG_OBJECT (demux, "Handling descriptive metadata of size %u at offset %" G_GUINT64_FORMAT " with scheme 0x%02x and type 0x%06x", - GST_BUFFER_SIZE (buffer), demux->offset, scheme, type); + gst_buffer_get_size (buffer), demux->offset, scheme, type); if (G_UNLIKELY (!demux->current_partition)) { GST_ERROR_OBJECT (demux, "Partition pack doesn't exist"); @@ -1329,9 +1360,10 @@ gst_mxf_demux_handle_descriptive_metadata (GstMXFDemux * demux, return GST_FLOW_OK; } + gst_buffer_map (buffer, &map, GST_MAP_READ); m = mxf_descriptive_metadata_new (scheme, type, - &demux->current_partition->primer, demux->offset, - GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer)); + &demux->current_partition->primer, demux->offset, map.data, map.size); + gst_buffer_unmap (buffer, &map); if (!m) { GST_WARNING_OBJECT (demux, @@ -1389,7 +1421,8 @@ gst_mxf_demux_handle_generic_container_system_item (GstMXFDemux * demux, { GST_DEBUG_OBJECT (demux, "Handling generic container system item of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + " at offset %" G_GUINT64_FORMAT, gst_buffer_get_size (buffer), + demux->offset); if (demux->current_partition->essence_container_offset == 0) demux->current_partition->essence_container_offset = @@ -1405,6 +1438,7 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad, guint i) { GstFlowReturn ret = GST_FLOW_OK; + GstCaps *pad_caps; MXFMetadataSequence *sequence; guint k; MXFMetadataSourcePackage *source_package = NULL; @@ -1418,15 +1452,15 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad, if (pad->current_component_index >= sequence->n_structural_components) { GST_DEBUG_OBJECT (demux, "After last structural component"); pad->current_component_index = sequence->n_structural_components - 1; - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; } GST_DEBUG_OBJECT (demux, "Switching to component %u", pad->current_component_index); pad->current_component = - MXF_METADATA_SOURCE_CLIP (sequence->structural_components[pad-> - current_component_index]); + MXF_METADATA_SOURCE_CLIP (sequence-> + structural_components[pad->current_component_index]); if (pad->current_component == NULL) { GST_ERROR_OBJECT (demux, "No such structural component"); return GST_FLOW_ERROR; @@ -1434,8 +1468,8 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad, if (!pad->current_component->source_package || !pad->current_component->source_package->top_level - || !MXF_METADATA_GENERIC_PACKAGE (pad->current_component-> - source_package)->tracks) { + || !MXF_METADATA_GENERIC_PACKAGE (pad-> + current_component->source_package)->tracks) { GST_ERROR_OBJECT (demux, "Invalid component"); return GST_FLOW_ERROR; } @@ -1513,9 +1547,11 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad, pad->current_essence_track_position = pad->current_component_start; - if (!gst_caps_is_equal (GST_PAD_CAPS (pad), pad->current_essence_track->caps)) { + pad_caps = gst_pad_get_current_caps (GST_PAD_CAST (pad)); + if (!gst_caps_is_equal (pad_caps, pad->current_essence_track->caps)) { gst_pad_set_caps (GST_PAD_CAST (pad), pad->current_essence_track->caps); } + gst_caps_unref (pad_caps); if (update) { if (pad->tags) { @@ -1528,7 +1564,7 @@ gst_mxf_demux_pad_set_component (GstMXFDemux * demux, GstMXFDemuxPad * pad, } } - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { pad->current_essence_track_position += pad->current_component_duration; } @@ -1549,7 +1585,8 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, GST_DEBUG_OBJECT (demux, "Handling generic container essence element of size %u" - " at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + " at offset %" G_GUINT64_FORMAT, gst_buffer_get_size (buffer), + demux->offset); GST_DEBUG_OBJECT (demux, " type = 0x%02x", key->u[12]); GST_DEBUG_OBJECT (demux, " essence element count = 0x%02x", key->u[13]); @@ -1622,7 +1659,9 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, } /* Create subbuffer to be able to change metadata */ - inbuf = gst_buffer_create_sub (buffer, 0, GST_BUFFER_SIZE (buffer)); + inbuf = + gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, + gst_buffer_get_size (buffer)); if (!keyframe) GST_BUFFER_FLAG_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT); @@ -1681,8 +1720,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, inbuf = outbuf; outbuf = NULL; - gst_buffer_set_caps (inbuf, etrack->caps); - for (i = 0; i < demux->src->len; i++) { GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i); @@ -1702,17 +1739,20 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, { GstMXFDemuxPad *earliest = gst_mxf_demux_get_earliest_pad (demux); - if (earliest && earliest != pad && earliest->last_stop < pad->last_stop && - pad->last_stop - earliest->last_stop > demux->max_drift) { + if (earliest && earliest != pad && earliest->position < pad->position && + pad->position - earliest->position > demux->max_drift) { GST_DEBUG_OBJECT (demux, "Pad is too far ahead of time"); continue; } } /* Create another subbuffer to have writable metadata */ - outbuf = gst_buffer_create_sub (inbuf, 0, GST_BUFFER_SIZE (inbuf)); + outbuf = + gst_buffer_copy_region (inbuf, GST_BUFFER_COPY_ALL, 0, + gst_buffer_get_size (inbuf)); - GST_BUFFER_TIMESTAMP (outbuf) = pad->last_stop; + GST_BUFFER_DTS (outbuf) = pad->position; + GST_BUFFER_PTS (outbuf) = pad->position; GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale (GST_SECOND, pad->current_essence_track->source_track->edit_rate.d, @@ -1725,13 +1765,13 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, guint64 abs_error = (GST_SECOND * pad->current_essence_track->source_track->edit_rate.d) % pad->current_essence_track->source_track->edit_rate.n; - pad->last_stop_accumulated_error += + pad->position_accumulated_error += ((gdouble) abs_error) / ((gdouble) pad->current_essence_track->source_track->edit_rate.n); } - if (pad->last_stop_accumulated_error >= 1.0) { + if (pad->position_accumulated_error >= 1.0) { GST_BUFFER_DURATION (outbuf) += 1; - pad->last_stop_accumulated_error -= 1.0; + pad->position_accumulated_error -= 1.0; } if (pad->need_segment) { @@ -1741,25 +1781,22 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, gst_pad_push_event (GST_PAD_CAST (pad), gst_event_ref (demux->close_seg_event)); - e = gst_event_new_new_segment (FALSE, demux->segment.rate, - GST_FORMAT_TIME, demux->segment.start, demux->segment.stop, - GST_BUFFER_TIMESTAMP (outbuf)); + e = gst_event_new_segment (&demux->segment); gst_event_set_seqnum (e, demux->seqnum); gst_pad_push_event (GST_PAD_CAST (pad), e); pad->need_segment = FALSE; } if (pad->tags) { - gst_element_found_tags_for_pad (GST_ELEMENT_CAST (demux), - GST_PAD_CAST (pad), pad->tags); + gst_pad_push_event (GST_PAD_CAST (pad), gst_event_new_tag (pad->tags)); pad->tags = NULL; } - pad->last_stop += GST_BUFFER_DURATION (outbuf); + pad->position += GST_BUFFER_DURATION (outbuf); GST_DEBUG_OBJECT (demux, "Pushing buffer of size %u for track %u: timestamp %" GST_TIME_FORMAT - " duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (outbuf), + " duration %" GST_TIME_FORMAT, gst_buffer_get_size (outbuf), pad->material_track->parent.track_id, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)), GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf))); @@ -1773,9 +1810,8 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, outbuf = NULL; ret = gst_mxf_demux_combine_flows (demux, pad, ret); - if (pad->last_stop > demux->segment.last_stop) - gst_segment_set_last_stop (&demux->segment, GST_FORMAT_TIME, - pad->last_stop); + if (pad->position > demux->segment.position) + demux->segment.position = pad->position; if (ret != GST_FLOW_OK) goto out; @@ -1791,22 +1827,22 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux, ret = gst_mxf_demux_pad_set_component (demux, pad, pad->current_component_index + 1); - if (ret != GST_FLOW_OK && ret != GST_FLOW_UNEXPECTED) { + if (ret != GST_FLOW_OK && ret != GST_FLOW_EOS) { GST_ERROR_OBJECT (demux, "Switching component failed"); } } else if (etrack->duration > 0 && pad->current_essence_track_position >= etrack->duration) { GST_DEBUG_OBJECT (demux, "Current component position after end of essence track"); - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; } } else if (etrack->duration > 0 && pad->current_essence_track_position == etrack->duration) { GST_DEBUG_OBJECT (demux, "At the end of the essence track"); - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; } - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { GstEvent *e; GST_DEBUG_OBJECT (demux, "EOS for track"); @@ -1839,18 +1875,25 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key, { guint i; GList *l; + GstMapInfo map; + gboolean ret; GST_DEBUG_OBJECT (demux, "Handling random index pack of size %u at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + G_GUINT64_FORMAT, gst_buffer_get_size (buffer), demux->offset); if (demux->random_index_pack) { GST_DEBUG_OBJECT (demux, "Already parsed random index pack"); return GST_FLOW_OK; } - if (!mxf_random_index_pack_parse (key, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer), &demux->random_index_pack)) { + gst_buffer_map (buffer, &map, GST_MAP_READ); + ret = + mxf_random_index_pack_parse (key, map.data, map.size, + &demux->random_index_pack); + gst_buffer_unmap (buffer, &map); + + if (!ret) { GST_ERROR_OBJECT (demux, "Parsing random index pack failed"); return GST_FLOW_ERROR; } @@ -1904,10 +1947,12 @@ gst_mxf_demux_handle_index_table_segment (GstMXFDemux * demux, const MXFUL * key, GstBuffer * buffer) { MXFIndexTableSegment *segment; + GstMapInfo map; + gboolean ret; GST_DEBUG_OBJECT (demux, "Handling index table segment of size %u at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + G_GUINT64_FORMAT, gst_buffer_get_size (buffer), demux->offset); if (!demux->current_partition->primer.mappings) { GST_WARNING_OBJECT (demux, "Invalid primer pack"); @@ -1915,10 +1960,12 @@ gst_mxf_demux_handle_index_table_segment (GstMXFDemux * demux, segment = g_new0 (MXFIndexTableSegment, 1); - if (!mxf_index_table_segment_parse (key, segment, - &demux->current_partition->primer, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer))) { + gst_buffer_map (buffer, &map, GST_MAP_READ); + ret = mxf_index_table_segment_parse (key, segment, + &demux->current_partition->primer, map.data, map.size); + gst_buffer_unmap (buffer, &map); + if (!ret) { GST_ERROR_OBJECT (demux, "Parsing index table segment failed"); return GST_FLOW_ERROR; } @@ -1939,6 +1986,7 @@ gst_mxf_demux_pull_klv_packet (GstMXFDemux * demux, guint64 offset, MXFUL * key, guint64 data_offset = 0; guint64 length; GstFlowReturn ret = GST_FLOW_OK; + GstMapInfo map; memset (key, 0, sizeof (MXFUL)); @@ -1947,19 +1995,20 @@ gst_mxf_demux_pull_klv_packet (GstMXFDemux * demux, guint64 offset, MXFUL * key, gst_mxf_demux_pull_range (demux, offset, 17, &buffer)) != GST_FLOW_OK) goto beach; - data = GST_BUFFER_DATA (buffer); + gst_buffer_map (buffer, &map, GST_MAP_READ); - memcpy (key, GST_BUFFER_DATA (buffer), 16); + memcpy (key, map.data, 16); /* Decode BER encoded packet length */ - if ((data[16] & 0x80) == 0) { - length = data[16]; + if ((map.data[16] & 0x80) == 0) { + length = map.data[16]; data_offset = 17; } else { - guint slen = data[16] & 0x7f; + guint slen = map.data[16] & 0x7f; data_offset = 16 + 1 + slen; + gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); buffer = NULL; @@ -1974,8 +2023,10 @@ gst_mxf_demux_pull_klv_packet (GstMXFDemux * demux, guint64 offset, MXFUL * key, if ((ret = gst_mxf_demux_pull_range (demux, offset + 17, slen, &buffer)) != GST_FLOW_OK) goto beach; - data = GST_BUFFER_DATA (buffer); + gst_buffer_map (buffer, &map, GST_MAP_READ); + + data = map.data; length = 0; while (slen) { length = (length << 8) | *data; @@ -1984,6 +2035,7 @@ gst_mxf_demux_pull_klv_packet (GstMXFDemux * demux, guint64 offset, MXFUL * key, } } + gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); buffer = NULL; @@ -2023,8 +2075,9 @@ gst_mxf_demux_pull_random_index_pack (GstMXFDemux * demux) guint32 pack_size; guint64 old_offset = demux->offset; MXFUL key; + GstMapInfo map; - if (!gst_pad_query_peer_duration (demux->sinkpad, &fmt, &filesize) || + if (!gst_pad_peer_query_duration (demux->sinkpad, fmt, &filesize) || fmt != GST_FORMAT_BYTES || filesize == -1) { GST_DEBUG_OBJECT (demux, "Can't query upstream size"); return; @@ -2040,7 +2093,9 @@ gst_mxf_demux_pull_random_index_pack (GstMXFDemux * demux) return; } - pack_size = GST_READ_UINT32_BE (GST_BUFFER_DATA (buffer)); + gst_buffer_map (buffer, &map, GST_MAP_READ); + pack_size = GST_READ_UINT32_BE (map.data); + gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); @@ -2060,7 +2115,9 @@ gst_mxf_demux_pull_random_index_pack (GstMXFDemux * demux) return; } - memcpy (&key, GST_BUFFER_DATA (buffer), 16); + gst_buffer_map (buffer, &map, GST_MAP_READ); + memcpy (&key, map.data, 16); + gst_buffer_unmap (buffer, &map); gst_buffer_unref (buffer); if (!mxf_is_random_index_pack (&key)) { @@ -2279,8 +2336,8 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key, if (!mxf_is_mxf_packet (key)) { GST_WARNING_OBJECT (demux, "Skipping non-MXF packet of size %u at offset %" - G_GUINT64_FORMAT ", key: %s", GST_BUFFER_SIZE (buffer), demux->offset, - mxf_ul_to_string (key, key_str)); + G_GUINT64_FORMAT ", key: %s", gst_buffer_get_size (buffer), + demux->offset, mxf_ul_to_string (key, key_str)); } else if (mxf_is_partition_pack (key)) { ret = gst_mxf_demux_handle_partition_pack (demux, key, buffer); @@ -2323,12 +2380,12 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key, } else if (mxf_is_fill (key)) { GST_DEBUG_OBJECT (demux, "Skipping filler packet of size %u at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); + G_GUINT64_FORMAT, gst_buffer_get_size (buffer), demux->offset); } else { GST_DEBUG_OBJECT (demux, "Skipping unknown packet of size %u at offset %" - G_GUINT64_FORMAT ", key: %s", GST_BUFFER_SIZE (buffer), demux->offset, - mxf_ul_to_string (key, key_str)); + G_GUINT64_FORMAT ", key: %s", gst_buffer_get_size (buffer), + demux->offset, mxf_ul_to_string (key, key_str)); } /* In pull mode try to get the last metadata */ @@ -2489,7 +2546,7 @@ from_index: gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer, &read); - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { for (i = 0; i < demux->essence_tracks->len; i++) { GstMXFDemuxEssenceTrack *t = &g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, @@ -2528,7 +2585,7 @@ from_index: /* If we found the position read it from the index again */ if (((ret == GST_FLOW_OK && etrack->position == *position + 2) || - (ret == GST_FLOW_UNEXPECTED && etrack->position == *position + 1)) + (ret == GST_FLOW_EOS && etrack->position == *position + 1)) && etrack->offsets && etrack->offsets->len > *position && g_array_index (etrack->offsets, GstMXFDemuxIndex, *position).offset != 0) { @@ -2559,7 +2616,7 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux) if (demux->src->len > 0) { if (!gst_mxf_demux_get_earliest_pad (demux)) { - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; GST_DEBUG_OBJECT (demux, "All tracks are EOS"); goto beach; } @@ -2569,7 +2626,7 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux) gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer, &read); - if (ret == GST_FLOW_UNEXPECTED && demux->src->len > 0) { + if (ret == GST_FLOW_EOS && demux->src->len > 0) { guint i; GstMXFDemuxPad *p = NULL; @@ -2637,7 +2694,7 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux) GstMXFDemuxPad *earliest = NULL; /* We allow time drifts of at most 500ms */ while ((earliest = gst_mxf_demux_get_earliest_pad (demux)) && - demux->segment.last_stop - earliest->last_stop > demux->max_drift) { + demux->segment.position - earliest->position > demux->max_drift) { guint64 offset; gint64 position; @@ -2687,6 +2744,8 @@ gst_mxf_demux_loop (GstPad * pad) { GstMXFDemux *demux = NULL; GstFlowReturn ret = GST_FLOW_OK; + GstMapInfo map; + gboolean res; demux = GST_MXF_DEMUX (gst_pad_get_parent (pad)); @@ -2701,8 +2760,11 @@ gst_mxf_demux_loop (GstPad * pad) &buffer)) != GST_FLOW_OK) break; - if (mxf_is_header_partition_pack ((const MXFUL *) - GST_BUFFER_DATA (buffer))) { + gst_buffer_map (buffer, &map, GST_MAP_READ); + res = mxf_is_header_partition_pack ((const MXFUL *) map.data); + gst_buffer_unmap (buffer, &map); + + if (res) { GST_DEBUG_OBJECT (demux, "Found header partition pack at offset %" G_GUINT64_FORMAT, demux->offset); @@ -2738,21 +2800,21 @@ gst_mxf_demux_loop (GstPad * pad) /* check EOS condition */ if ((demux->segment.flags & GST_SEEK_FLAG_SEGMENT) && (demux->segment.stop != -1) && - (demux->segment.last_stop >= demux->segment.stop)) { + (demux->segment.position >= demux->segment.stop)) { guint i; gboolean eos = TRUE; for (i = 0; i < demux->src->len; i++) { GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i); - if (!p->eos && p->last_stop < demux->segment.stop) { + if (!p->eos && p->position < demux->segment.stop) { eos = FALSE; break; } } if (eos) { - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; goto pause; } } @@ -2768,7 +2830,7 @@ pause: GST_LOG_OBJECT (demux, "pausing task, reason %s", reason); gst_pad_pause_task (pad); - if (ret == GST_FLOW_UNEXPECTED) { + if (ret == GST_FLOW_EOS) { /* perform EOS logic */ if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) { gint64 stop; @@ -2799,7 +2861,7 @@ pause: GST_WARNING_OBJECT (demux, "failed pushing EOS on streams"); } } - } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) { + } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { GstEvent *e; GST_ELEMENT_ERROR (demux, STREAM, FAILED, @@ -2815,7 +2877,7 @@ pause: } static GstFlowReturn -gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) +gst_mxf_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * inbuf) { GstFlowReturn ret = GST_FLOW_OK; GstMXFDemux *demux = NULL; @@ -2824,15 +2886,16 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) guint64 length = 0; guint64 offset = 0; GstBuffer *buffer = NULL; + gboolean res; - demux = GST_MXF_DEMUX (gst_pad_get_parent (pad)); + demux = GST_MXF_DEMUX (parent); GST_LOG_OBJECT (demux, "received buffer of %u bytes at offset %" - G_GUINT64_FORMAT, GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf)); + G_GUINT64_FORMAT, gst_buffer_get_size (inbuf), GST_BUFFER_OFFSET (inbuf)); if (demux->src->len > 0) { if (!gst_mxf_demux_get_earliest_pad (demux)) { - ret = GST_FLOW_UNEXPECTED; + ret = GST_FLOW_EOS; GST_DEBUG_OBJECT (demux, "All tracks are EOS"); return ret; } @@ -2872,10 +2935,11 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) while (demux->offset < 64 * 1024 && gst_adapter_available (demux->adapter) >= 16) { - data = gst_adapter_peek (demux->adapter, 16); + data = gst_adapter_map (demux->adapter, 16); + res = mxf_is_header_partition_pack ((const MXFUL *) data); + gst_adapter_unmap (demux->adapter); - if (mxf_is_header_partition_pack ((const MXFUL *) - data)) { + if (res) { GST_DEBUG_OBJECT (demux, "Found header partition pack at offset %" G_GUINT64_FORMAT, demux->offset); @@ -2913,7 +2977,7 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) memset (&key, 0, sizeof (MXFUL)); /* Pull 16 byte key and first byte of BER encoded length */ - data = gst_adapter_peek (demux->adapter, 17); + data = gst_adapter_map (demux->adapter, 17); memcpy (&key, data, 16); @@ -2926,6 +2990,8 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) offset = 16 + 1 + slen; + gst_adapter_unmap (demux->adapter); + /* Must be at most 8 according to SMPTE-379M 5.3.4 and * GStreamer buffers can only have a 4 bytes length */ if (slen > 8) { @@ -2937,7 +3003,7 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) if (gst_adapter_available (demux->adapter) < 17 + slen) break; - data = gst_adapter_peek (demux->adapter, 17 + slen); + data = gst_adapter_map (demux->adapter, 17 + slen); data += 17; length = 0; @@ -2948,6 +3014,8 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) } } + gst_adapter_unmap (demux->adapter); + /* GStreamer's buffer sizes are stored in a guint so we * limit ourself to G_MAXUINT large buffers */ if (length > G_MAXUINT) { @@ -2972,13 +3040,11 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf) demux->offset += offset + length; } - gst_object_unref (demux); - return ret; } static void -gst_mxf_demux_pad_set_last_stop (GstMXFDemux * demux, GstMXFDemuxPad * p, +gst_mxf_demux_pad_set_position (GstMXFDemux * demux, GstMXFDemuxPad * p, GstClockTime start) { guint i; @@ -2993,14 +3059,14 @@ gst_mxf_demux_pad_set_last_stop (GstMXFDemux * demux, GstMXFDemuxPad * p, if (p->current_essence_track_position >= p->current_essence_track->duration && p->current_essence_track->duration > 0) { p->current_essence_track_position = p->current_essence_track->duration; - p->last_stop = + p->position = gst_util_uint64_scale (p->current_essence_track->duration, p->material_track->edit_rate.d * GST_SECOND, p->material_track->edit_rate.n); } else { - p->last_stop = start; + p->position = start; } - p->last_stop_accumulated_error = 0.0; + p->position_accumulated_error = 0.0; return; } @@ -3008,8 +3074,8 @@ gst_mxf_demux_pad_set_last_stop (GstMXFDemux * demux, GstMXFDemuxPad * p, for (i = 0; i < p->material_track->parent.sequence->n_structural_components; i++) { clip = - MXF_METADATA_SOURCE_CLIP (p->material_track->parent.sequence-> - structural_components[i]); + MXF_METADATA_SOURCE_CLIP (p->material_track->parent. + sequence->structural_components[i]); if (clip->parent.duration <= 0) break; @@ -3024,8 +3090,8 @@ gst_mxf_demux_pad_set_last_stop (GstMXFDemux * demux, GstMXFDemuxPad * p, } if (i == p->material_track->parent.sequence->n_structural_components) { - p->last_stop = sum; - p->last_stop_accumulated_error = 0.0; + p->position = sum; + p->position_accumulated_error = 0.0; gst_mxf_demux_pad_set_component (demux, p, i); return; @@ -3048,16 +3114,16 @@ gst_mxf_demux_pad_set_last_stop (GstMXFDemux * demux, GstMXFDemuxPad * p, p->current_essence_track_position += essence_offset; - p->last_stop = sum + gst_util_uint64_scale (essence_offset, + p->position = sum + gst_util_uint64_scale (essence_offset, GST_SECOND * p->material_track->edit_rate.d, p->material_track->edit_rate.n); - p->last_stop_accumulated_error = 0.0; + p->position_accumulated_error = 0.0; } if (p->current_essence_track_position >= p->current_essence_track->duration && p->current_essence_track->duration > 0) { p->current_essence_track_position = p->current_essence_track->duration; - p->last_stop = + p->position = sum + gst_util_uint64_scale (p->current_component->parent.duration, p->material_track->edit_rate.d * GST_SECOND, p->material_track->edit_rate.n); @@ -3097,13 +3163,13 @@ gst_mxf_demux_seek_push (GstMXFDemux * demux, GstEvent * event) &demux->segment); /* Apply the seek to our segment */ - gst_segment_set_seek (&seeksegment, rate, format, flags, + gst_segment_do_seek (&seeksegment, rate, format, flags, start_type, start, stop_type, stop, &update); GST_DEBUG_OBJECT (demux, "segment configured %" GST_SEGMENT_FORMAT, &seeksegment); - if (flush || seeksegment.last_stop != demux->segment.last_stop) { + if (flush || seeksegment.position != demux->segment.position) { gboolean ret; guint64 new_offset = -1; GstEvent *e; @@ -3124,7 +3190,7 @@ gst_mxf_demux_seek_push (GstMXFDemux * demux, GstEvent * event) /* Reset EOS flag on all pads */ p->eos = FALSE; p->last_flow = GST_FLOW_OK; - gst_mxf_demux_pad_set_last_stop (demux, p, start); + gst_mxf_demux_pad_set_position (demux, p, start); position = p->current_essence_track_position; off = gst_mxf_demux_find_essence_element (demux, p->current_essence_track, @@ -3244,7 +3310,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) GstEvent *e; /* Stop flushing upstream we need to pull */ - e = gst_event_new_flush_stop (); + e = gst_event_new_flush_stop (TRUE); gst_event_set_seqnum (e, seqnum); gst_pad_push_event (demux->sinkpad, e); } @@ -3256,13 +3322,13 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) &demux->segment); /* Apply the seek to our segment */ - gst_segment_set_seek (&seeksegment, rate, format, flags, + gst_segment_do_seek (&seeksegment, rate, format, flags, start_type, start, stop_type, stop, &update); GST_DEBUG_OBJECT (demux, "segment configured %" GST_SEGMENT_FORMAT, &seeksegment); - if (flush || seeksegment.last_stop != demux->segment.last_stop) { + if (flush || seeksegment.position != demux->segment.position) { guint64 new_offset = -1; if (!demux->metadata_resolved || demux->update_metadata) { @@ -3281,7 +3347,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) /* Reset EOS flag on all pads */ p->eos = FALSE; p->last_flow = GST_FLOW_OK; - gst_mxf_demux_pad_set_last_stop (demux, p, start); + gst_mxf_demux_pad_set_position (demux, p, start); position = p->current_essence_track_position; off = @@ -3322,7 +3388,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) GstEvent *e; /* Stop flushing, the sinks are at time 0 now */ - e = gst_event_new_flush_stop (); + e = gst_event_new_flush_stop (TRUE); gst_event_set_seqnum (e, seqnum); gst_mxf_demux_push_src_event (demux, e); } else { @@ -3330,9 +3396,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) &demux->segment); /* Close the current segment for a linear playback */ - demux->close_seg_event = gst_event_new_new_segment (TRUE, - demux->segment.rate, demux->segment.format, - demux->segment.start, demux->segment.last_stop, demux->segment.time); + demux->close_seg_event = gst_event_new_segment (&demux->segment); gst_event_set_seqnum (demux->close_seg_event, demux->seqnum); } @@ -3344,7 +3408,7 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event) GstMessage *m; m = gst_message_new_segment_start (GST_OBJECT (demux), - demux->segment.format, demux->segment.last_stop); + demux->segment.format, demux->segment.position); gst_message_set_seqnum (m, seqnum); gst_element_post_message (GST_ELEMENT (demux), m); } @@ -3392,9 +3456,9 @@ unresolved_metadata: } static gboolean -gst_mxf_demux_src_event (GstPad * pad, GstEvent * event) +gst_mxf_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) { - GstMXFDemux *demux = GST_MXF_DEMUX (gst_pad_get_parent (pad)); + GstMXFDemux *demux = GST_MXF_DEMUX (parent); gboolean ret; GST_DEBUG_OBJECT (pad, "handling event %s", GST_EVENT_TYPE_NAME (event)); @@ -3412,28 +3476,13 @@ gst_mxf_demux_src_event (GstPad * pad, GstEvent * event) break; } - gst_object_unref (demux); - return ret; } -static const GstQueryType * -gst_mxf_demux_src_query_type (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_SEEKING, - 0 - }; - - return types; -} - static gboolean -gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) +gst_mxf_demux_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { - GstMXFDemux *demux = GST_MXF_DEMUX (gst_pad_get_parent (pad)); + GstMXFDemux *demux = GST_MXF_DEMUX (parent); gboolean ret = FALSE; GstMXFDemuxPad *mxfpad = GST_MXF_DEMUX_PAD (pad); @@ -3450,7 +3499,7 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) if (format != GST_FORMAT_TIME && format != GST_FORMAT_DEFAULT) goto error; - pos = mxfpad->last_stop; + pos = mxfpad->position; g_static_rw_lock_reader_lock (&demux->metadata_lock); if (format == GST_FORMAT_DEFAULT && pos != GST_CLOCK_TIME_NONE) { @@ -3544,13 +3593,11 @@ gst_mxf_demux_src_query (GstPad * pad, GstQuery * query) break; } default: - /* else forward upstream */ - ret = gst_pad_peer_query (demux->sinkpad, query); + ret = gst_pad_query_default (pad, parent, query); break; } done: - gst_object_unref (demux); return ret; /* ERRORS */ @@ -3562,62 +3609,61 @@ error: } static gboolean -gst_mxf_demux_sink_activate (GstPad * sinkpad) -{ - if (gst_pad_check_pull_range (sinkpad)) { - return gst_pad_activate_pull (sinkpad, TRUE); - } else { - return gst_pad_activate_push (sinkpad, TRUE); - } -} - -static gboolean -gst_mxf_demux_sink_activate_push (GstPad * sinkpad, gboolean active) +gst_mxf_demux_sink_activate (GstPad * sinkpad, GstObject * parent) { - GstMXFDemux *demux; - - demux = GST_MXF_DEMUX (gst_pad_get_parent (sinkpad)); + GstQuery *query; + GstPadMode mode = GST_PAD_MODE_PUSH; - demux->random_access = FALSE; + query = gst_query_new_scheduling (); - gst_object_unref (demux); + if (gst_pad_peer_query (sinkpad, query)) { + if (gst_query_has_scheduling_mode_with_flags (query, + GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) + mode = GST_PAD_MODE_PULL; + } + gst_query_unref (query); - return TRUE; + return gst_pad_activate_mode (sinkpad, mode, TRUE); } static gboolean -gst_mxf_demux_sink_activate_pull (GstPad * sinkpad, gboolean active) +gst_mxf_demux_sink_activate_mode (GstPad * sinkpad, GstObject * parent, + GstPadMode mode, gboolean active) { GstMXFDemux *demux; - demux = GST_MXF_DEMUX (gst_pad_get_parent (sinkpad)); + demux = GST_MXF_DEMUX (parent); - if (active) { - demux->random_access = TRUE; - gst_object_unref (demux); - return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_mxf_demux_loop, - sinkpad, NULL); - } else { + if (mode == GST_PAD_MODE_PUSH) { demux->random_access = FALSE; - gst_object_unref (demux); - return gst_pad_stop_task (sinkpad); + } else { + if (active) { + demux->random_access = TRUE; + return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_mxf_demux_loop, + sinkpad, NULL); + } else { + demux->random_access = FALSE; + return gst_pad_stop_task (sinkpad); + } } + + return TRUE; } static gboolean -gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event) +gst_mxf_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { GstMXFDemux *demux; gboolean ret = FALSE; - demux = GST_MXF_DEMUX (gst_pad_get_parent (pad)); + demux = GST_MXF_DEMUX (parent); GST_DEBUG_OBJECT (pad, "handling event %s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: demux->flushing = TRUE; - ret = gst_mxf_demux_push_src_event (demux, event); + ret = gst_pad_event_default (pad, parent, event); break; case GST_EVENT_FLUSH_STOP: GST_DEBUG_OBJECT (demux, "flushing queued data in the MXF demuxer"); @@ -3625,7 +3671,7 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event) gst_adapter_clear (demux->adapter); demux->flushing = FALSE; demux->offset = 0; - ret = gst_mxf_demux_push_src_event (demux, event); + ret = gst_pad_event_default (pad, parent, event); break; case GST_EVENT_EOS:{ GstMXFDemuxPad *p = NULL; @@ -3686,11 +3732,11 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event) } } - if (!(ret = gst_mxf_demux_push_src_event (demux, event))) + if (!(ret = gst_pad_event_default (pad, parent, event))) GST_WARNING_OBJECT (pad, "failed pushing EOS on streams"); break; } - case GST_EVENT_NEWSEGMENT:{ + case GST_EVENT_SEGMENT:{ guint i; for (i = 0; i < demux->essence_tracks->len; i++) { @@ -3706,28 +3752,15 @@ gst_mxf_demux_sink_event (GstPad * pad, GstEvent * event) break; } default: - ret = gst_mxf_demux_push_src_event (demux, event); + ret = gst_pad_event_default (pad, parent, event); break; } out: - gst_object_unref (demux); return ret; } -static const GstQueryType * -gst_mxf_demux_get_query_types (GstElement * element) -{ - static const GstQueryType types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - 0 - }; - - return types; -} - static gboolean gst_mxf_demux_query (GstElement * element, GstQuery * query) { @@ -3747,7 +3780,7 @@ gst_mxf_demux_query (GstElement * element, GstQuery * query) if (format != GST_FORMAT_TIME) goto error; - pos = demux->segment.last_stop; + pos = demux->segment.position; GST_DEBUG_OBJECT (demux, "Returning position %" G_GINT64_FORMAT " in format %s", pos, @@ -3968,20 +4001,6 @@ gst_mxf_demux_finalize (GObject * object) } static void -gst_mxf_demux_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&mxf_sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&mxf_src_template)); - gst_element_class_set_static_metadata (element_class, "MXF Demuxer", - "Codec/Demuxer", - "Demux MXF files", "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); -} - -static void gst_mxf_demux_class_init (GstMXFDemuxClass * klass) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); @@ -3989,6 +4008,8 @@ gst_mxf_demux_class_init (GstMXFDemuxClass * klass) GST_DEBUG_CATEGORY_INIT (mxfdemux_debug, "mxfdemux", 0, "MXF demuxer"); + parent_class = g_type_class_peek_parent (klass); + gobject_class->finalize = gst_mxf_demux_finalize; gobject_class->set_property = gst_mxf_demux_set_property; gobject_class->get_property = gst_mxf_demux_get_property; @@ -4012,12 +4033,18 @@ gst_mxf_demux_class_init (GstMXFDemuxClass * klass) gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_mxf_demux_change_state); gstelement_class->query = GST_DEBUG_FUNCPTR (gst_mxf_demux_query); - gstelement_class->get_query_types = - GST_DEBUG_FUNCPTR (gst_mxf_demux_get_query_types); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&mxf_sink_template)); + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&mxf_src_template)); + gst_element_class_set_static_metadata (gstelement_class, "MXF Demuxer", + "Codec/Demuxer", + "Demux MXF files", "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); } static void -gst_mxf_demux_init (GstMXFDemux * demux, GstMXFDemuxClass * g_class) +gst_mxf_demux_init (GstMXFDemux * demux) { demux->sinkpad = gst_pad_new_from_static_template (&mxf_sink_template, "sink"); @@ -4028,10 +4055,8 @@ gst_mxf_demux_init (GstMXFDemux * demux, GstMXFDemuxClass * g_class) GST_DEBUG_FUNCPTR (gst_mxf_demux_chain)); gst_pad_set_activate_function (demux->sinkpad, GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate)); - gst_pad_set_activatepull_function (demux->sinkpad, - GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate_pull)); - gst_pad_set_activatepush_function (demux->sinkpad, - GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate_push)); + gst_pad_set_activatemode_function (demux->sinkpad, + GST_DEBUG_FUNCPTR (gst_mxf_demux_sink_activate_mode)); gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad); diff --git a/gst/mxf/mxfdemux.h b/gst/mxf/mxfdemux.h index e8b90261e..7e961b23f 100644 --- a/gst/mxf/mxfdemux.h +++ b/gst/mxf/mxfdemux.h @@ -93,8 +93,8 @@ struct _GstMXFDemuxPad guint32 track_id; gboolean need_segment; - GstClockTime last_stop; - gdouble last_stop_accumulated_error; + GstClockTime position; + gdouble position_accumulated_error; GstFlowReturn last_flow; gboolean eos, discont; @@ -166,6 +166,8 @@ struct _GstMXFDemux MXFMetadataGenericPackage *current_package; gchar *current_package_string; + GstTagList *tags; + /* Properties */ gchar *requested_package_string; GstClockTime max_drift; diff --git a/gst/mxf/mxfdv-dif.c b/gst/mxf/mxfdv-dif.c index cf56c7fcc..c58c2857f 100644 --- a/gst/mxf/mxfdv-dif.c +++ b/gst/mxf/mxfdv-dif.c @@ -142,7 +142,7 @@ mxf_dv_dif_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, mxf_metadata_generic_picture_essence_descriptor_set_caps (d, caps); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, "DV-DIF", NULL); @@ -155,7 +155,7 @@ static const MXFEssenceElementHandler mxf_dv_dif_essence_element_handler = { }; static GstFlowReturn -mxf_dv_dif_write_func (GstBuffer * buffer, GstCaps * caps, +mxf_dv_dif_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { diff --git a/gst/mxf/mxfessence.h b/gst/mxf/mxfessence.h index e5ee90c2a..4a2db39d6 100644 --- a/gst/mxf/mxfessence.h +++ b/gst/mxf/mxfessence.h @@ -33,7 +33,7 @@ typedef struct { GstCaps * (*create_caps) (MXFMetadataTimelineTrack *track, GstTagList **tags, MXFEssenceElementHandleFunc *handler, gpointer *mapping_data); } MXFEssenceElementHandler; -typedef GstFlowReturn (*MXFEssenceElementWriteFunc) (GstBuffer *buffer, GstCaps *caps, gpointer mapping_data, GstAdapter *adapter, GstBuffer **outbuf, gboolean flush); +typedef GstFlowReturn (*MXFEssenceElementWriteFunc) (GstBuffer *buffer, gpointer mapping_data, GstAdapter *adapter, GstBuffer **outbuf, gboolean flush); typedef struct { MXFMetadataFileDescriptor * (*get_descriptor) (GstPadTemplate *tmpl, GstCaps *caps, MXFEssenceElementWriteFunc *handler, gpointer *mapping_data); diff --git a/gst/mxf/mxfjpeg2000.c b/gst/mxf/mxfjpeg2000.c index 5ef7b843d..68dfb33a9 100644 --- a/gst/mxf/mxfjpeg2000.c +++ b/gst/mxf/mxfjpeg2000.c @@ -94,7 +94,7 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, MXFMetadataGenericPictureEssenceDescriptor *p = NULL; guint i; GstCaps *caps = NULL; - guint32 fourcc; + const gchar *colorspace; g_return_val_if_fail (track != NULL, NULL); @@ -107,10 +107,10 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; f = track->parent.descriptor[i]; break; } else if (MXF_IS_METADATA_FILE_DESCRIPTOR (track->parent.descriptor[i]) && @@ -124,9 +124,9 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, return NULL; } - fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B'); + colorspace = "sRGB"; if (p && MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (p)) { - fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V'); + colorspace = "sYUV"; } else if (p && MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (p)) { MXFMetadataRGBAPictureEssenceDescriptor *r = (MXFMetadataRGBAPictureEssenceDescriptor *) p; @@ -169,9 +169,9 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, } } if (rgb) { - fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B'); + colorspace = "sRGC"; } else if (yuv) { - fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V'); + colorspace = "sYUV"; } else if (xyz) { GST_ERROR ("JPEG2000 with XYZ colorspace not supported yet"); return NULL; @@ -183,8 +183,8 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, /* TODO: What about other field values? */ caps = - gst_caps_new_simple ("image/x-jpc", "fields", G_TYPE_INT, 1, "fourcc", - GST_TYPE_FOURCC, fourcc, NULL); + gst_caps_new_simple ("image/x-jpc", "fields", G_TYPE_INT, 1, "colorspace", + G_TYPE_STRING, colorspace, NULL); if (p) { mxf_metadata_generic_picture_essence_descriptor_set_caps (p, caps); } else { @@ -192,7 +192,7 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, } if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "JPEG 2000", NULL); @@ -205,7 +205,7 @@ static const MXFEssenceElementHandler mxf_jpeg2000_essence_element_handler = { }; static GstFlowReturn -mxf_jpeg2000_write_func (GstBuffer * buffer, GstCaps * caps, +mxf_jpeg2000_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { @@ -229,15 +229,17 @@ mxf_jpeg2000_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, { MXFMetadataRGBAPictureEssenceDescriptor *ret; GstStructure *s; - guint32 fourcc; + const gchar *colorspace; s = gst_caps_get_structure (caps, 0); if (strcmp (gst_structure_get_name (s), "image/x-jpc") != 0 || - !gst_structure_get_fourcc (s, "fourcc", &fourcc)) { + !gst_structure_get_string (s, "colorspace")) { GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps); return NULL; } + colorspace = gst_structure_get_string (s, "colorspace"); + ret = (MXFMetadataRGBAPictureEssenceDescriptor *) g_object_new (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR, NULL); @@ -246,7 +248,7 @@ mxf_jpeg2000_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, memcpy (&ret->parent.picture_essence_coding, &jpeg2000_picture_essence_coding, 16); - if (fourcc == GST_MAKE_FOURCC ('s', 'R', 'G', 'B')) { + if (g_str_equal (colorspace, "sRGB")) { ret->n_pixel_layout = 3; ret->pixel_layout = g_new0 (guint8, 6); ret->pixel_layout[0] = 'R'; @@ -255,7 +257,7 @@ mxf_jpeg2000_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, ret->pixel_layout[3] = 8; ret->pixel_layout[4] = 'B'; ret->pixel_layout[5] = 8; - } else if (fourcc == GST_MAKE_FOURCC ('s', 'Y', 'U', 'V')) { + } else if (g_str_equal (colorspace, "sYUV")) { ret->n_pixel_layout = 3; ret->pixel_layout = g_new0 (guint8, 6); ret->pixel_layout[0] = 'Y'; @@ -322,7 +324,7 @@ mxf_jpeg2000_init (void) gst_caps_from_string ("image/x-jpc, fields = 1, width = " GST_VIDEO_SIZE_RANGE ", height = " GST_VIDEO_SIZE_RANGE ", framerate = " GST_VIDEO_FPS_RANGE - ", fourcc = (GstFourcc) { sRGB, sYUV }")); + ", colorspace = (string) { \"sRGB\", \"sYUV\" }")); memcpy (&mxf_jpeg2000_essence_element_writer.data_definition, mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_PICTURE_ESSENCE), 16); diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c index cf3ccb655..282a9b324 100644 --- a/gst/mxf/mxfmetadata.c +++ b/gst/mxf/mxfmetadata.c @@ -70,7 +70,7 @@ mxf_metadata_base_to_structure_default (MXFMetadataBase * self) g_return_val_if_fail (klass->name_quark != 0, NULL); - ret = gst_structure_id_empty_new (klass->name_quark); + ret = gst_structure_new_id_empty (klass->name_quark); if (!mxf_uuid_is_zero (&self->instance_uid)) { mxf_uuid_to_string (&self->instance_uid, str); @@ -90,6 +90,7 @@ mxf_metadata_base_to_structure_default (MXFMetadataBase * self) GValue v = { 0, }; GstStructure *s; GstBuffer *buf; + GstMapInfo map; GHashTableIter iter; g_hash_table_iter_init (&iter, self->other_tags); @@ -97,12 +98,14 @@ mxf_metadata_base_to_structure_default (MXFMetadataBase * self) while (g_hash_table_iter_next (&iter, NULL, (gpointer) & tag)) { g_value_init (&v, GST_TYPE_STRUCTURE); - s = gst_structure_id_empty_new (MXF_QUARK (TAG)); + s = gst_structure_new_id_empty (MXF_QUARK (TAG)); mxf_ul_to_string (&tag->ul, str); buf = gst_buffer_new_and_alloc (tag->size); - memcpy (GST_BUFFER_DATA (buf), tag->data, tag->size); + gst_buffer_map (buf, &map, GST_MAP_WRITE); + memcpy (map.data, tag->data, tag->size); + gst_buffer_unmap (buf, &map); gst_structure_id_set (s, MXF_QUARK (NAME), G_TYPE_STRING, str, MXF_QUARK (DATA), GST_TYPE_BUFFER, buf, NULL); @@ -215,6 +218,7 @@ mxf_metadata_base_to_buffer (MXFMetadataBase * self, MXFPrimerPack * primer) { MXFMetadataBaseClass *klass; GstBuffer *ret; + GstMapInfo map; GList *tags, *l; guint size = 0, slen; guint8 ber[9]; @@ -266,13 +270,14 @@ mxf_metadata_base_to_buffer (MXFMetadataBase * self, MXFPrimerPack * primer) size += 16 + slen; ret = gst_buffer_new_and_alloc (size); + gst_buffer_map (ret, &map, GST_MAP_WRITE); - memcpy (GST_BUFFER_DATA (ret), &last->ul, 16); + memcpy (map.data, &last->ul, 16); mxf_local_tag_free (last); last = NULL; - memcpy (GST_BUFFER_DATA (ret) + 16, ber, slen); + memcpy (map.data + 16, ber, slen); - data = GST_BUFFER_DATA (ret) + 16 + slen; + data = map.data + 16 + slen; size -= 16 + slen; for (l = tags; l; l = l->next) { @@ -301,6 +306,8 @@ mxf_metadata_base_to_buffer (MXFMetadataBase * self, MXFPrimerPack * primer) g_list_free (tags); + gst_buffer_unmap (ret, &map); + return ret; } @@ -2066,8 +2073,8 @@ mxf_metadata_material_package_resolve (MXFMetadataBase * m, MXFMetadataTimelineTrack *tmp; if (!sc->source_package->parent.tracks[k] || - !MXF_IS_METADATA_TIMELINE_TRACK (sc->source_package-> - parent.tracks[k])) + !MXF_IS_METADATA_TIMELINE_TRACK (sc->source_package->parent. + tracks[k])) continue; tmp = @@ -4395,8 +4402,8 @@ mxf_metadata_generic_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -4417,8 +4424,8 @@ mxf_metadata_generic_picture_essence_descriptor_to_structure (MXFMetadataBase * { GstStructure *ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_picture_essence_descriptor_parent_class)-> - to_structure (m); + (mxf_metadata_generic_picture_essence_descriptor_parent_class)->to_structure + (m); MXFMetadataGenericPictureEssenceDescriptor *self = MXF_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (m); gchar str[48]; @@ -5012,8 +5019,8 @@ mxf_metadata_generic_sound_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_sound_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_sound_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -5209,10 +5216,9 @@ void mxf_metadata_generic_sound_essence_descriptor_set_caps if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) { GST_ERROR ("Invalid audio sampling rate"); } else { - gst_caps_set_simple (caps, - "rate", G_TYPE_INT, - (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) - + 0.5), NULL); + gst_caps_set_simple (caps, "rate", G_TYPE_INT, + (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) + 0.5), + NULL); } if (self->channel_count == 0) { @@ -5223,6 +5229,36 @@ void mxf_metadata_generic_sound_essence_descriptor_set_caps } } +GstCaps *mxf_metadata_generic_sound_essence_descriptor_create_caps + (MXFMetadataGenericSoundEssenceDescriptor * self, GstAudioFormat * format) +{ + GstAudioInfo info; + gint rate = 0; + gint channels = 0; + + g_return_val_if_fail (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (self), + NULL); + + gst_audio_info_init (&info); + + if (self->audio_sampling_rate.n == 0 || self->audio_sampling_rate.d == 0) { + GST_ERROR ("Invalid audio sampling rate"); + } else { + rate = (gint) (mxf_fraction_to_double (&self->audio_sampling_rate) + + 0.5); + } + + if (self->channel_count == 0) { + GST_ERROR ("Invalid number of channels (0)"); + } else { + channels = self->channel_count; + } + + gst_audio_info_set_format (&info, *format, rate, channels, NULL); + + return gst_audio_info_to_caps (&info); +} + gboolean mxf_metadata_generic_sound_essence_descriptor_from_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps) { @@ -5333,8 +5369,8 @@ mxf_metadata_cdci_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_cdci_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_cdci_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -5643,8 +5679,8 @@ mxf_metadata_rgba_picture_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_rgba_picture_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_rgba_picture_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } @@ -5840,8 +5876,8 @@ mxf_metadata_generic_data_essence_descriptor_handle_tag (MXFMetadataBase * default: ret = MXF_METADATA_BASE_CLASS - (mxf_metadata_generic_data_essence_descriptor_parent_class)-> - handle_tag (metadata, primer, tag, tag_data, tag_size); + (mxf_metadata_generic_data_essence_descriptor_parent_class)->handle_tag + (metadata, primer, tag, tag_data, tag_size); break; } diff --git a/gst/mxf/mxfmetadata.h b/gst/mxf/mxfmetadata.h index 2f32d98e0..8cebc4da0 100644 --- a/gst/mxf/mxfmetadata.h +++ b/gst/mxf/mxfmetadata.h @@ -23,6 +23,7 @@ #define __MXF_METADATA_H__ #include <gst/gst.h> +#include <gst/audio/audio.h> #include "mxftypes.h" #define MXF_TYPE_METADATA_BASE \ @@ -764,6 +765,7 @@ const MXFUL * mxf_metadata_track_identifier_get (MXFMetadataTrackType type); void mxf_metadata_generic_picture_essence_descriptor_set_caps (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps); gboolean mxf_metadata_generic_picture_essence_descriptor_from_caps (MXFMetadataGenericPictureEssenceDescriptor * self, GstCaps * caps); +GstCaps *mxf_metadata_generic_sound_essence_descriptor_create_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstAudioFormat *format); void mxf_metadata_generic_sound_essence_descriptor_set_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps); gboolean mxf_metadata_generic_sound_essence_descriptor_from_caps (MXFMetadataGenericSoundEssenceDescriptor * self, GstCaps * caps); diff --git a/gst/mxf/mxfmpeg.c b/gst/mxf/mxfmpeg.c index 30142486e..4302ae1f7 100644 --- a/gst/mxf/mxfmpeg.c +++ b/gst/mxf/mxfmpeg.c @@ -433,8 +433,13 @@ mxf_is_mpeg_essence_track (const MXFMetadataTimelineTrack * track) gboolean mxf_mpeg_is_mpeg2_keyframe (GstBuffer * buffer) { - GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer); + GstMapInfo map; + GstByteReader reader; guint32 tmp; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &map, GST_MAP_READ); + gst_byte_reader_init (&reader, map.data, map.size); while (gst_byte_reader_get_remaining (&reader) > 3) { if (gst_byte_reader_peek_uint24_be (&reader, &tmp) && tmp == 0x000001) { @@ -448,7 +453,8 @@ mxf_mpeg_is_mpeg2_keyframe (GstBuffer * buffer) /* GOP packets are meant as random access markers */ if (type == 0xb8) { - return TRUE; + ret = TRUE; + goto done; } else if (type == 0x00) { guint8 pic_type = 0; @@ -460,23 +466,30 @@ mxf_mpeg_is_mpeg2_keyframe (GstBuffer * buffer) pic_type = (pic_type >> 3) & 0x07; if (pic_type == 0x01) { - return TRUE; - } else { - return FALSE; + ret = TRUE; } + goto done; } } else if (gst_byte_reader_skip (&reader, 1) == FALSE) break; } - return FALSE; +done: + gst_buffer_unmap (buffer, &map); + + return ret; } static gboolean mxf_mpeg_is_mpeg4_keyframe (GstBuffer * buffer) { - GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer); + GstMapInfo map; + GstByteReader reader; guint32 tmp; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &map, GST_MAP_READ); + gst_byte_reader_init (&reader, map.data, map.size); while (gst_byte_reader_get_remaining (&reader) > 3) { if (gst_byte_reader_peek_uint24_be (&reader, &tmp) && tmp == 0x000001) { @@ -496,16 +509,18 @@ mxf_mpeg_is_mpeg4_keyframe (GstBuffer * buffer) pic_type = (pic_type >> 6) & 0x03; if (pic_type == 0) { - return TRUE; - } else { - return FALSE; + ret = TRUE; } + goto done; } } else if (gst_byte_reader_skip (&reader, 1) == FALSE) break; } - return FALSE; +done: + gst_buffer_unmap (buffer, &map); + + return ret; } static GstFlowReturn @@ -666,9 +681,12 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); if (local_tag) { + GstMapInfo map; GstBuffer *codec_data = NULL; codec_data = gst_buffer_new_and_alloc (local_tag->size); - memcpy (GST_BUFFER_DATA (codec_data), local_tag->data, local_tag->size); + gst_buffer_map (codec_data, &map, GST_MAP_WRITE); + memcpy (map.data, local_tag->data, local_tag->size); + gst_buffer_unmap (codec_data, &map); gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data, NULL); gst_buffer_unref (codec_data); @@ -680,7 +698,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, /* RP 2008 */ /* TODO: What about codec_data for AVC1 streams? */ - caps = gst_caps_new_simple ("video/x-h264", NULL); + caps = gst_caps_new_empty_simple ("video/x-h264"); codec_name = "h.264 Video"; t = MXF_MPEG_ESSENCE_TYPE_VIDEO_AVC; memcpy (mdata, &t, sizeof (MXFMPEGEssenceType)); @@ -700,7 +718,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, codec_name = "MPEG-1 Audio"; } else if (mxf_ul_is_equal (&s->sound_essence_compression, &sound_essence_compression_ac3)) { - caps = gst_caps_new_simple ("audio/x-ac3", NULL); + caps = gst_caps_new_empty_simple ("audio/x-ac3"); codec_name = "AC3 Audio"; } else if (mxf_ul_is_equal (&s->sound_essence_compression, &sound_essence_compression_mpeg1_layer1)) { @@ -728,7 +746,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, codec_name = "MPEG-2 Layer 1 Audio"; } else if (mxf_ul_is_equal (&s->sound_essence_compression, &sound_essence_compression_dts)) { - caps = gst_caps_new_simple ("audio/x-dts", NULL); + caps = gst_caps_new_empty_simple ("audio/x-dts"); codec_name = "Dolby DTS Audio"; } else if (mxf_ul_is_equal (&s->sound_essence_compression, &sound_essence_compression_aac)) { @@ -745,7 +763,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (caps) { if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); if (codec_name) gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, codec_name, NULL); @@ -781,17 +799,17 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { + if (MXF_IS_METADATA_GENERIC_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { f = track->parent.descriptor[i]; - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; break; - } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent. - descriptor[i])) { + } else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { f = track->parent.descriptor[i]; - s = (MXFMetadataGenericSoundEssenceDescriptor *) track-> - parent.descriptor[i]; + s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent. + descriptor[i]; break; } } @@ -816,34 +834,34 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, "systemstream", G_TYPE_BOOLEAN, TRUE, NULL); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "MPEG PS", NULL); } else if (f->essence_container.u[13] == 0x09) { GST_DEBUG ("Found MPEG TS stream"); - caps = gst_caps_new_simple ("video/mpegts", NULL); + caps = gst_caps_new_empty_simple ("video/mpegts"); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "MPEG TS", NULL); } else if (f->essence_container.u[13] == 0x0f) { GST_DEBUG ("Found h264 NAL unit stream"); /* RP 2008 */ /* TODO: What about codec_data? */ - caps = gst_caps_new_simple ("video/x-h264", NULL); + caps = gst_caps_new_empty_simple ("video/x-h264"); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "h.264 Video", NULL); } else if (f->essence_container.u[13] == 0x10) { GST_DEBUG ("Found h264 byte stream stream"); /* RP 2008 */ - caps = gst_caps_new_simple ("video/x-h264", NULL); + caps = gst_caps_new_empty_simple ("video/x-h264"); if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "h.264 Video", NULL); } @@ -866,7 +884,7 @@ typedef struct } MPEGAudioMappingData; static GstFlowReturn -mxf_mpeg_audio_write_func (GstBuffer * buffer, GstCaps * caps, +mxf_mpeg_audio_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { @@ -1014,8 +1032,13 @@ static MXFEssenceElementWriter mxf_mpeg_audio_essence_element_writer = { static gboolean mxf_mpeg_is_mpeg2_frame (GstBuffer * buffer) { - GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer); + GstByteReader reader; guint32 tmp; + GstMapInfo map; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &map, GST_MAP_READ); + gst_byte_reader_init (&reader, map.data, map.size); while (gst_byte_reader_get_remaining (&reader) > 3) { if (gst_byte_reader_peek_uint24_be (&reader, &tmp) && tmp == 0x000001) { @@ -1029,7 +1052,8 @@ mxf_mpeg_is_mpeg2_frame (GstBuffer * buffer) /* PICTURE */ if (type == 0x00) { - return TRUE; + ret = TRUE; + goto done; } } else { if (gst_byte_reader_skip (&reader, 1) == FALSE) @@ -1037,14 +1061,22 @@ mxf_mpeg_is_mpeg2_frame (GstBuffer * buffer) } } - return FALSE; +done: + gst_buffer_unmap (buffer, &map); + + return ret; } static gboolean mxf_mpeg_is_mpeg4_frame (GstBuffer * buffer) { - GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer); + GstByteReader reader; guint32 tmp; + GstMapInfo map; + gboolean ret = FALSE; + + gst_buffer_map (buffer, &map, GST_MAP_READ); + gst_byte_reader_init (&reader, map.data, map.size); while (gst_byte_reader_get_remaining (&reader) > 3) { if (gst_byte_reader_peek_uint24_be (&reader, &tmp) && tmp == 0x000001) { @@ -1058,7 +1090,8 @@ mxf_mpeg_is_mpeg4_frame (GstBuffer * buffer) /* PICTURE */ if (type == 0xb6) { - return TRUE; + ret = TRUE; + goto done; } } else { if (gst_byte_reader_skip (&reader, 1) == FALSE) @@ -1066,11 +1099,14 @@ mxf_mpeg_is_mpeg4_frame (GstBuffer * buffer) } } - return FALSE; +done: + gst_buffer_unmap (buffer, &map); + + return ret; } static GstFlowReturn -mxf_mpeg_video_write_func (GstBuffer * buffer, GstCaps * caps, +mxf_mpeg_video_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { @@ -1087,23 +1123,30 @@ mxf_mpeg_video_write_func (GstBuffer * buffer, GstCaps * caps, } else if (buffer || gst_adapter_available (adapter)) { guint av = gst_adapter_available (adapter); GstBuffer *ret; + GstMapInfo map; if (buffer) - ret = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) + av); + ret = gst_buffer_new_and_alloc (gst_buffer_get_size (buffer) + av); else ret = gst_buffer_new_and_alloc (av); + gst_buffer_map (ret, &map, GST_MAP_WRITE); if (av) { - GstBuffer *tmp = gst_adapter_take_buffer (adapter, av); - memcpy (GST_BUFFER_DATA (ret), GST_BUFFER_DATA (tmp), av); - gst_buffer_unref (tmp); + gconstpointer data = gst_adapter_map (adapter, av); + memcpy (map.data, data, av); + gst_adapter_unmap (adapter); } if (buffer) { - memcpy (GST_BUFFER_DATA (ret) + av, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer)); + GstMapInfo buffermap; + gst_buffer_map (buffer, &buffermap, GST_MAP_READ); + memcpy (map.data + av, buffermap.data, buffermap.size); + gst_buffer_unmap (buffer, &buffermap); gst_buffer_unref (buffer); } + + gst_buffer_unmap (ret, &map); + *outbuf = ret; return GST_FLOW_OK; } @@ -1115,23 +1158,30 @@ mxf_mpeg_video_write_func (GstBuffer * buffer, GstCaps * caps, } else if (buffer || gst_adapter_available (adapter)) { guint av = gst_adapter_available (adapter); GstBuffer *ret; + GstMapInfo map; if (buffer) - ret = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) + av); + ret = gst_buffer_new_and_alloc (gst_buffer_get_size (buffer) + av); else ret = gst_buffer_new_and_alloc (av); + gst_buffer_map (ret, &map, GST_MAP_WRITE); if (av) { - GstBuffer *tmp = gst_adapter_take_buffer (adapter, av); - memcpy (GST_BUFFER_DATA (ret), GST_BUFFER_DATA (tmp), av); - gst_buffer_unref (tmp); + gconstpointer data = gst_adapter_map (adapter, av); + memcpy (map.data, data, av); + gst_adapter_unmap (adapter); } if (buffer) { - memcpy (GST_BUFFER_DATA (ret) + av, GST_BUFFER_DATA (buffer), - GST_BUFFER_SIZE (buffer)); + GstMapInfo buffermap; + gst_buffer_map (buffer, &buffermap, GST_MAP_READ); + memcpy (map.data + av, buffermap.data, buffermap.size); + gst_buffer_unmap (buffer, &buffermap); gst_buffer_unref (buffer); } + + gst_buffer_unmap (ret, &map); + *outbuf = ret; return GST_FLOW_OK; } @@ -1194,9 +1244,13 @@ mxf_mpeg_video_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, ret->parent.parent.picture_essence_coding.u[13] = 0x20; if ((v = gst_structure_get_value (s, "codec_data"))) { MXFLocalTag *t = g_slice_new0 (MXFLocalTag); + GstMapInfo map; + codec_data = gst_value_get_buffer (v); - t->size = GST_BUFFER_SIZE (codec_data); - t->data = g_memdup (GST_BUFFER_DATA (codec_data), t->size); + gst_buffer_map ((GstBuffer *) codec_data, &map, GST_MAP_READ); + t->size = map.size; + t->data = g_memdup (map.data, map.size); + gst_buffer_unmap ((GstBuffer *) codec_data, &map); memcpy (&t->ul, &sony_mpeg4_extradata, 16); mxf_local_tag_insert (t, &MXF_METADATA_BASE (ret)->other_tags); } @@ -1212,8 +1266,8 @@ mxf_mpeg_video_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, } - if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret-> - parent.parent, caps)) { + if (!mxf_metadata_generic_picture_essence_descriptor_from_caps (&ret->parent. + parent, caps)) { g_object_unref (ret); return NULL; } diff --git a/gst/mxf/mxfmux.c b/gst/mxf/mxfmux.c index b1cc5dc4e..aabc4ddbc 100644 --- a/gst/mxf/mxfmux.c +++ b/gst/mxf/mxfmux.c @@ -57,7 +57,8 @@ enum PROP_0 }; -GST_BOILERPLATE (GstMXFMux, gst_mxf_mux, GstElement, GST_TYPE_ELEMENT); +#define gst_mxf_mux_parent_class parent_class +G_DEFINE_TYPE (GstMXFMux, gst_mxf_mux, GST_TYPE_ELEMENT); static void gst_mxf_mux_finalize (GObject * object); static void gst_mxf_mux_set_property (GObject * object, @@ -68,9 +69,12 @@ static void gst_mxf_mux_get_property (GObject * object, static GstFlowReturn gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data); -static gboolean gst_mxf_mux_handle_src_event (GstPad * pad, GstEvent * event); +static gboolean gst_mxf_mux_handle_src_event (GstPad * pad, GstObject * parent, + GstEvent * event); +static gboolean gst_mxf_mux_handle_sink_event (GstCollectPads * pads, + GstCollectData * data, GstEvent * event, gpointer user_data); static GstPad *gst_mxf_mux_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); + GstPadTemplate * templ, const gchar * name, const GstCaps * caps); static void gst_mxf_mux_release_pad (GstElement * element, GstPad * pad); static GstStateChangeReturn @@ -81,10 +85,9 @@ static void gst_mxf_mux_reset (GstMXFMux * mux); static GstFlowReturn gst_mxf_mux_push (GstMXFMux * mux, GstBuffer * buf) { - guint size = GST_BUFFER_SIZE (buf); + guint size = gst_buffer_get_size (buf); GstFlowReturn ret; - gst_buffer_set_caps (buf, GST_PAD_CAPS (mux->srcpad)); ret = gst_pad_push (mux->srcpad, buf); mux->offset += size; @@ -92,32 +95,11 @@ gst_mxf_mux_push (GstMXFMux * mux, GstBuffer * buf) } static void -gst_mxf_mux_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - const GstPadTemplate **p; - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_templ)); - - p = mxf_essence_element_writer_get_pad_templates (); - while (p && *p) { - gst_element_class_add_pad_template (element_class, - (GstPadTemplate *) gst_object_ref (GST_OBJECT (*p))); - p++; - } - - gst_element_class_set_static_metadata (element_class, "MXF muxer", - "Codec/Muxer", - "Muxes video/audio streams into a MXF stream", - "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); -} - -static void gst_mxf_mux_class_init (GstMXFMuxClass * klass) { GObjectClass *gobject_class; GstElementClass *gstelement_class; + const GstPadTemplate **p; GST_DEBUG_CATEGORY_INIT (mxfmux_debug, "mxfmux", 0, "MXF muxer"); @@ -132,23 +114,40 @@ gst_mxf_mux_class_init (GstMXFMuxClass * klass) gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_mxf_mux_request_new_pad); gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_mxf_mux_release_pad); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&src_templ)); + + p = mxf_essence_element_writer_get_pad_templates (); + while (p && *p) { + gst_element_class_add_pad_template (gstelement_class, + (GstPadTemplate *) gst_object_ref (GST_OBJECT (*p))); + p++; + } + + gst_element_class_set_static_metadata (gstelement_class, "MXF muxer", + "Codec/Muxer", + "Muxes video/audio streams into a MXF stream", + "Sebastian Dröge <sebastian.droege@collabora.co.uk>"); } static void -gst_mxf_mux_init (GstMXFMux * mux, GstMXFMuxClass * g_class) +gst_mxf_mux_init (GstMXFMux * mux) { GstCaps *caps; mux->srcpad = gst_pad_new_from_static_template (&src_templ, "src"); gst_pad_set_event_function (mux->srcpad, gst_mxf_mux_handle_src_event); - caps = gst_caps_new_simple ("application/mxf", NULL); + caps = gst_caps_new_empty_simple ("application/mxf"); gst_pad_set_caps (mux->srcpad, caps); gst_caps_unref (caps); gst_element_add_pad (GST_ELEMENT (mux), mux->srcpad); mux->collect = gst_collect_pads_new (); + gst_collect_pads_set_event_function (mux->collect, + GST_DEBUG_FUNCPTR (gst_mxf_mux_handle_sink_event), mux); gst_collect_pads_set_function (mux->collect, - (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_mxf_mux_collected), mux); + GST_DEBUG_FUNCPTR (gst_mxf_mux_collected), mux); gst_mxf_mux_reset (mux); } @@ -232,7 +231,8 @@ gst_mxf_mux_reset (GstMXFMux * mux) } static gboolean -gst_mxf_mux_handle_src_event (GstPad * pad, GstEvent * event) +gst_mxf_mux_handle_src_event (GstPad * pad, GstObject * parent, + GstEvent * event) { GstEventType type; @@ -246,38 +246,11 @@ gst_mxf_mux_handle_src_event (GstPad * pad, GstEvent * event) break; } - return gst_pad_event_default (pad, event); + return gst_pad_event_default (pad, parent, event); } static gboolean -gst_mxf_mux_handle_sink_event (GstPad * pad, GstEvent * event) -{ - GstMXFMux *mux = GST_MXF_MUX (gst_pad_get_parent (pad)); - gboolean ret = TRUE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_TAG: - /* TODO: do something with the tags */ - break; - case GST_EVENT_NEWSEGMENT: - /* We don't support NEWSEGMENT events */ - ret = FALSE; - gst_event_unref (event); - break; - default: - break; - } - - /* now GstCollectPads can take care of the rest, e.g. EOS */ - if (ret) - ret = mux->collect_event (pad, event); - gst_object_unref (mux); - - return ret; -} - -static gboolean -gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps) +gst_mxf_mux_event_caps (GstPad * pad, GstCaps * caps) { GstMXFMux *mux = GST_MXF_MUX (gst_pad_get_parent (pad)); GstMXFMuxPad *cpad = (GstMXFMuxPad *) gst_pad_get_element_private (pad); @@ -338,13 +311,13 @@ gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps) for (i = 0; i < mux->preface->content_storage->n_packages; i++) { MXFMetadataSourcePackage *package; - if (!MXF_IS_METADATA_SOURCE_PACKAGE (mux->preface->content_storage-> - packages[i])) + if (!MXF_IS_METADATA_SOURCE_PACKAGE (mux->preface-> + content_storage->packages[i])) continue; package = - MXF_METADATA_SOURCE_PACKAGE (mux->preface->content_storage-> - packages[i]); + MXF_METADATA_SOURCE_PACKAGE (mux->preface-> + content_storage->packages[i]); if (!package->descriptor) continue; @@ -376,6 +349,40 @@ gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps) return ret; } +static gboolean +gst_mxf_mux_handle_sink_event (GstCollectPads * pads, GstCollectData * data, + GstEvent * event, gpointer user_data) +{ + GstCaps *caps; + gboolean ret = TRUE; + + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_TAG: + /* TODO: do something with the tags */ + break; + case GST_EVENT_SEGMENT: + /* We don't support SEGMENT events */ + ret = FALSE; + gst_event_unref (event); + break; + case GST_EVENT_CAPS: + gst_event_parse_caps (event, &caps); + + gst_mxf_mux_event_caps (data->pad, caps); + + gst_caps_unref (caps); + break; + default: + break; + } + + /* now GstCollectPads can take care of the rest, e.g. EOS */ + if (ret) + ret = gst_collect_pads_event_default (pads, data, event, FALSE); + + return ret; +} + static char * gst_mxf_mux_create_pad_name (GstPadTemplate * templ, guint id) { @@ -390,7 +397,7 @@ gst_mxf_mux_create_pad_name (GstPadTemplate * templ, guint id) static GstPad * gst_mxf_mux_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * pad_name) + GstPadTemplate * templ, const gchar * pad_name, const GstCaps * caps) { GstMXFMux *mux = GST_MXF_MUX (element); GstMXFMuxPad *cpad; @@ -409,11 +416,7 @@ gst_mxf_mux_request_new_pad (GstElement * element, GST_ERROR_OBJECT (mux, "Not our template"); return NULL; } -#if GLIB_CHECK_VERSION(2,29,5) pad_number = g_atomic_int_add ((gint *) & mux->n_pads, 1); -#else - pad_number = g_atomic_int_exchange_and_add ((gint *) & mux->n_pads, 1); -#endif name = gst_mxf_mux_create_pad_name (templ, pad_number); GST_DEBUG_OBJECT (mux, "Creating pad '%s'", name); @@ -426,15 +429,6 @@ gst_mxf_mux_request_new_pad (GstElement * element, cpad->adapter = gst_adapter_new (); cpad->writer = writer; - /* FIXME: hacked way to override/extend the event function of - * GstCollectPads; because it sets its own event function giving the - * element no access to events. - */ - mux->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (pad); - gst_pad_set_event_function (pad, - GST_DEBUG_FUNCPTR (gst_mxf_mux_handle_sink_event)); - - gst_pad_set_setcaps_function (pad, gst_mxf_mux_setcaps); gst_pad_use_fixed_caps (pad); gst_pad_set_active (pad, TRUE); gst_element_add_pad (element, pad); @@ -466,14 +460,19 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) for (l = mux->collect->data; l; l = l->next) { GstMXFMuxPad *cpad = l->data; + GstCaps *caps; - if (!cpad || !cpad->descriptor || !GST_PAD_CAPS (cpad->collect.pad)) + if (!cpad || !cpad->descriptor) + return GST_FLOW_ERROR; + + caps = gst_pad_get_current_caps (cpad->collect.pad); + if (!caps) return GST_FLOW_ERROR; if (cpad->writer->update_descriptor) cpad->writer->update_descriptor (cpad->descriptor, - GST_PAD_CAPS (cpad->collect.pad), cpad->mapping_data, - cpad->collect.buffer); + caps, cpad->mapping_data, cpad->collect.buffer); + gst_caps_unref (caps); } /* Preface */ @@ -653,6 +652,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) MXFMetadataTimelineTrack *track; MXFMetadataSequence *sequence; MXFMetadataSourceClip *clip; + GstCaps *caps; p->parent.tracks[n] = (MXFMetadataTrack *) g_object_new (MXF_TYPE_METADATA_TIMELINE_TRACK, NULL); @@ -663,14 +663,16 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) &MXF_METADATA_BASE (track)->instance_uid, track); mux->metadata_list = g_list_prepend (mux->metadata_list, track); + caps = gst_pad_get_current_caps (cpad->collect.pad); track->parent.track_id = n + 1; track->parent.track_number = cpad->writer->get_track_number_template (cpad->descriptor, - GST_PAD_CAPS (cpad->collect.pad), cpad->mapping_data); + caps, cpad->mapping_data); cpad->writer->get_edit_rate (cpad->descriptor, - GST_PAD_CAPS (cpad->collect.pad), cpad->mapping_data, + caps, cpad->mapping_data, cpad->collect.buffer, p, track, &track->edit_rate); + gst_caps_unref (caps); sequence = track->parent.sequence = (MXFMetadataSequence *) g_object_new (MXF_TYPE_METADATA_SEQUENCE, NULL); @@ -707,8 +709,8 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) if (p->parent.n_tracks == 1) { p->descriptor = (MXFMetadataGenericDescriptor *) cpad->descriptor; } else { - MXF_METADATA_MULTIPLE_DESCRIPTOR (p->descriptor)-> - sub_descriptors[n] = + MXF_METADATA_MULTIPLE_DESCRIPTOR (p-> + descriptor)->sub_descriptors[n] = (MXFMetadataGenericDescriptor *) cpad->descriptor; } @@ -752,6 +754,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) /* Essence tracks */ for (l = mux->collect->data; l; l = l->next) { GstMXFMuxPad *cpad = l->data; + GstCaps *caps; MXFMetadataSourcePackage *source_package; MXFMetadataTimelineTrack *track, *source_track; MXFMetadataSequence *sequence; @@ -774,10 +777,12 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) track->parent.track_id = n + 1; track->parent.track_number = 0; + caps = gst_pad_get_current_caps (cpad->collect.pad); cpad->writer->get_edit_rate (cpad->descriptor, - GST_PAD_CAPS (cpad->collect.pad), cpad->mapping_data, + caps, cpad->mapping_data, cpad->collect.buffer, source_package, source_track, &track->edit_rate); + gst_caps_unref (caps); if (track->edit_rate.n != source_track->edit_rate.n || track->edit_rate.d != source_track->edit_rate.d) { @@ -930,8 +935,8 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux) g_new0 (MXFMetadataEssenceContainerData *, 1); cstorage->essence_container_data[0] = (MXFMetadataEssenceContainerData *) g_object_new (MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA, NULL); - mxf_uuid_init (&MXF_METADATA_BASE (cstorage-> - essence_container_data[0])->instance_uid, mux->metadata); + mxf_uuid_init (&MXF_METADATA_BASE (cstorage->essence_container_data[0])-> + instance_uid, mux->metadata); g_hash_table_insert (mux->metadata, &MXF_METADATA_BASE (cstorage->essence_container_data[0])->instance_uid, cstorage->essence_container_data[0]); @@ -1051,13 +1056,13 @@ gst_mxf_mux_write_header_metadata (GstMXFMux * mux) for (l = mux->metadata_list; l; l = l->next) { m = l->data; buf = mxf_metadata_base_to_buffer (m, &mux->primer); - header_byte_count += GST_BUFFER_SIZE (buf); + header_byte_count += gst_buffer_get_size (buf); buffers = g_list_prepend (buffers, buf); } buffers = g_list_reverse (buffers); buf = mxf_primer_pack_to_buffer (&mux->primer); - header_byte_count += GST_BUFFER_SIZE (buf); + header_byte_count += gst_buffer_get_size (buf); buffers = g_list_prepend (buffers, buf); mux->partition.header_byte_count = header_byte_count; @@ -1098,6 +1103,8 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad) GstBuffer *buf = NULL; GstBuffer *outbuf = NULL; GstBuffer *packet; + GstMapInfo map; + GstMapInfo readmap; GstFlowReturn ret = GST_FLOW_OK; guint8 slen, ber[9]; gboolean flush = ((cpad->collect.state & GST_COLLECT_PADS_STATE_EOS) @@ -1115,7 +1122,8 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad) if (buf) { GST_DEBUG_OBJECT (cpad->collect.pad, "Handling buffer of size %u for track %u at position %" G_GINT64_FORMAT, - GST_BUFFER_SIZE (buf), cpad->source_track->parent.track_id, cpad->pos); + gst_buffer_get_size (buf), cpad->source_track->parent.track_id, + cpad->pos); } else { flush = TRUE; GST_DEBUG_OBJECT (cpad->collect.pad, @@ -1123,7 +1131,7 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad) cpad->source_track->parent.track_id, cpad->pos); } - ret = cpad->write_func (buf, GST_PAD_CAPS (cpad->collect.pad), + ret = cpad->write_func (buf, cpad->mapping_data, cpad->adapter, &outbuf, flush); if (ret != GST_FLOW_OK && ret != GST_FLOW_CUSTOM_SUCCESS) { GST_ERROR_OBJECT (cpad->collect.pad, @@ -1143,19 +1151,22 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad) if (buf == NULL) return ret; - slen = mxf_ber_encode_size (GST_BUFFER_SIZE (buf), ber); - packet = gst_buffer_new_and_alloc (16 + slen + GST_BUFFER_SIZE (buf)); - memcpy (GST_BUFFER_DATA (packet), _gc_essence_element_ul, 16); - GST_BUFFER_DATA (packet)[7] = cpad->descriptor->essence_container.u[7]; - GST_WRITE_UINT32_BE (&GST_BUFFER_DATA (packet)[12], - cpad->source_track->parent.track_number); - memcpy (&GST_BUFFER_DATA (packet)[16], ber, slen); - memcpy (&GST_BUFFER_DATA (packet)[16 + slen], GST_BUFFER_DATA (buf), - GST_BUFFER_SIZE (buf)); + gst_buffer_map (buf, &readmap, GST_MAP_READ); + slen = mxf_ber_encode_size (readmap.size, ber); + packet = gst_buffer_new_and_alloc (16 + slen + readmap.size); + gst_buffer_map (packet, &map, GST_MAP_WRITE); + memcpy (map.data, _gc_essence_element_ul, 16); + map.data[7] = cpad->descriptor->essence_container.u[7]; + GST_WRITE_UINT32_BE (map.data + 12, cpad->source_track->parent.track_number); + memcpy (map.data + 16, ber, slen); + memcpy (map.data + 16 + slen, readmap.data, readmap.size); + gst_buffer_unmap (buf, &readmap); + gst_buffer_unref (buf); GST_DEBUG_OBJECT (cpad->collect.pad, "Pushing buffer of size %u for track %u", - GST_BUFFER_SIZE (packet), cpad->source_track->parent.track_id); + map.size, cpad->source_track->parent.track_id); + gst_buffer_unmap (packet, &map); if ((ret = gst_mxf_mux_push (mux, packet)) != GST_FLOW_OK) { GST_ERROR_OBJECT (cpad->collect.pad, @@ -1247,22 +1258,23 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux) /* Update durations */ cpad->source_track->parent.sequence->duration = cpad->pos; - MXF_METADATA_SOURCE_CLIP (cpad->source_track->parent.sequence-> - structural_components[0])->parent.duration = cpad->pos; + MXF_METADATA_SOURCE_CLIP (cpad->source_track->parent. + sequence->structural_components[0])->parent.duration = cpad->pos; for (i = 0; i < mux->preface->content_storage->packages[0]->n_tracks; i++) { MXFMetadataTimelineTrack *track; - if (!MXF_IS_METADATA_TIMELINE_TRACK (mux->preface->content_storage-> - packages[0]->tracks[i]) - || !MXF_IS_METADATA_SOURCE_CLIP (mux->preface->content_storage-> - packages[0]->tracks[i]->sequence->structural_components[0])) + if (!MXF_IS_METADATA_TIMELINE_TRACK (mux->preface-> + content_storage->packages[0]->tracks[i]) + || !MXF_IS_METADATA_SOURCE_CLIP (mux->preface-> + content_storage->packages[0]->tracks[i]->sequence-> + structural_components[0])) continue; track = - MXF_METADATA_TIMELINE_TRACK (mux->preface->content_storage-> - packages[0]->tracks[i]); - if (MXF_METADATA_SOURCE_CLIP (track->parent.sequence-> - structural_components[0])->source_track_id == + MXF_METADATA_TIMELINE_TRACK (mux->preface-> + content_storage->packages[0]->tracks[i]); + if (MXF_METADATA_SOURCE_CLIP (track->parent. + sequence->structural_components[0])->source_track_id == cpad->source_track->parent.track_id) { track->parent.sequence->structural_components[0]->duration = cpad->pos; track->parent.sequence->duration = cpad->pos; @@ -1273,8 +1285,8 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux) /* Update timecode track duration */ { MXFMetadataTimelineTrack *track = - MXF_METADATA_TIMELINE_TRACK (mux->preface->content_storage-> - packages[0]->tracks[0]); + MXF_METADATA_TIMELINE_TRACK (mux->preface-> + content_storage->packages[0]->tracks[0]); MXFMetadataSequence *sequence = track->parent.sequence; MXFMetadataTimecodeComponent *component = MXF_METADATA_TIMECODE_COMPONENT (sequence->structural_components[0]); @@ -1289,6 +1301,7 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux) guint64 footer_partition = mux->offset; GArray *rip; GstFlowReturn ret; + GstSegment segment; MXFRandomIndexPackEntry entry; mux->partition.type = MXF_PARTITION_PACK_FOOTER; @@ -1323,9 +1336,8 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux) g_array_free (rip, TRUE); /* Rewrite header partition with updated values */ - if (gst_pad_push_event (mux->srcpad, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, - 0))) { + gst_segment_init (&segment, GST_FORMAT_BYTES); + if (gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment))) { mux->offset = 0; mux->partition.type = MXF_PARTITION_PACK_HEADER; mux->partition.closed = TRUE; @@ -1374,6 +1386,7 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data) GstMXFMux *mux = GST_MXF_MUX (user_data); GstMXFMuxPad *best = NULL; GstFlowReturn ret; + GstSegment segment; GSList *sl; gboolean eos = TRUE; @@ -1382,7 +1395,7 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data) return GST_FLOW_ERROR; } else if (mux->state == GST_MXF_MUX_STATE_EOS) { GST_WARNING_OBJECT (mux, "EOS"); - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } if (mux->state == GST_MXF_MUX_STATE_HEADER) { @@ -1393,9 +1406,8 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data) goto error; } - if (gst_pad_push_event (mux->srcpad, - gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, - 0))) { + gst_segment_init (&segment, GST_FORMAT_BYTES); + if (gst_pad_push_event (mux->srcpad, gst_event_new_segment (&segment))) { if ((ret = gst_mxf_mux_create_metadata (mux)) != GST_FLOW_OK) goto error; @@ -1459,7 +1471,7 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data) gst_mxf_mux_handle_eos (mux); gst_pad_push_event (mux->srcpad, gst_event_new_eos ()); mux->state = GST_MXF_MUX_STATE_EOS; - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; } return GST_FLOW_OK; diff --git a/gst/mxf/mxftypes.c b/gst/mxf/mxftypes.c index 6fcfdeb1e..b02897401 100644 --- a/gst/mxf/mxftypes.c +++ b/gst/mxf/mxftypes.c @@ -191,15 +191,20 @@ GstBuffer * mxf_fill_to_buffer (guint size) { GstBuffer *ret; + GstMapInfo map; guint slen; guint8 ber[9]; slen = mxf_ber_encode_size (size, ber); ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (FILL), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); - memset (GST_BUFFER_DATA (ret) + slen, 0, size); + gst_buffer_map (ret, &map, GST_MAP_WRITE); + + memcpy (map.data, MXF_UL (FILL), 16); + memcpy (map.data + 16, &ber, slen); + memset (map.data + slen, 0, size); + + gst_buffer_unmap (ret, &map); return ret; } @@ -902,6 +907,7 @@ mxf_partition_pack_to_buffer (const MXFPartitionPack * pack) guint slen; guint8 ber[9]; GstBuffer *ret; + GstMapInfo map; guint8 *data; guint i; guint size = @@ -911,23 +917,25 @@ mxf_partition_pack_to_buffer (const MXFPartitionPack * pack) slen = mxf_ber_encode_size (size, ber); ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (PARTITION_PACK), 13); + gst_buffer_map (ret, &map, GST_MAP_WRITE); + + memcpy (map.data, MXF_UL (PARTITION_PACK), 13); if (pack->type == MXF_PARTITION_PACK_HEADER) - GST_BUFFER_DATA (ret)[13] = 0x02; + map.data[13] = 0x02; else if (pack->type == MXF_PARTITION_PACK_BODY) - GST_BUFFER_DATA (ret)[13] = 0x03; + map.data[13] = 0x03; else if (pack->type == MXF_PARTITION_PACK_FOOTER) - GST_BUFFER_DATA (ret)[13] = 0x04; - GST_BUFFER_DATA (ret)[14] = 0; + map.data[13] = 0x04; + map.data[14] = 0; if (pack->complete) - GST_BUFFER_DATA (ret)[14] |= 0x02; + map.data[14] |= 0x02; if (pack->closed) - GST_BUFFER_DATA (ret)[14] |= 0x01; - GST_BUFFER_DATA (ret)[14] += 1; - GST_BUFFER_DATA (ret)[15] = 0; - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); + map.data[14] |= 0x01; + map.data[14] += 1; + map.data[15] = 0; + memcpy (map.data + 16, &ber, slen); - data = GST_BUFFER_DATA (ret) + 16 + slen; + data = map.data + 16 + slen; GST_WRITE_UINT16_BE (data, pack->major_version); GST_WRITE_UINT16_BE (data + 2, pack->minor_version); @@ -970,6 +978,8 @@ mxf_partition_pack_to_buffer (const MXFPartitionPack * pack) for (i = 0; i < pack->n_essence_containers; i++) memcpy (data + 16 * i, &pack->essence_containers[i], 16); + gst_buffer_unmap (ret, &map); + return ret; } @@ -1019,6 +1029,7 @@ mxf_random_index_pack_to_buffer (const GArray * array) MXFRandomIndexPackEntry *entry; guint i; GstBuffer *ret; + GstMapInfo map; guint8 slen, ber[9]; guint size; guint8 *data; @@ -1029,10 +1040,12 @@ mxf_random_index_pack_to_buffer (const GArray * array) size = array->len * 12 + 4; slen = mxf_ber_encode_size (size, ber); ret = gst_buffer_new_and_alloc (16 + slen + size); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (RANDOM_INDEX_PACK), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, ber, slen); + gst_buffer_map (ret, &map, GST_MAP_WRITE); - data = GST_BUFFER_DATA (ret) + 16 + slen; + memcpy (map.data, MXF_UL (RANDOM_INDEX_PACK), 16); + memcpy (map.data + 16, ber, slen); + + data = map.data + 16 + slen; for (i = 0; i < array->len; i++) { entry = &g_array_index (array, MXFRandomIndexPackEntry, i); @@ -1040,7 +1053,9 @@ mxf_random_index_pack_to_buffer (const GArray * array) GST_WRITE_UINT64_BE (data + 4, entry->offset); data += 12; } - GST_WRITE_UINT32_BE (data, GST_BUFFER_SIZE (ret)); + GST_WRITE_UINT32_BE (data, gst_buffer_get_size (ret)); + + gst_buffer_unmap (ret, &map); return ret; } @@ -1435,6 +1450,7 @@ mxf_primer_pack_to_buffer (const MXFPrimerPack * pack) guint slen; guint8 ber[9]; GstBuffer *ret; + GstMapInfo map; guint n; guint8 *data; @@ -1446,10 +1462,12 @@ mxf_primer_pack_to_buffer (const MXFPrimerPack * pack) slen = mxf_ber_encode_size (8 + 18 * n, ber); ret = gst_buffer_new_and_alloc (16 + slen + 8 + 18 * n); - memcpy (GST_BUFFER_DATA (ret), MXF_UL (PRIMER_PACK), 16); - memcpy (GST_BUFFER_DATA (ret) + 16, &ber, slen); + gst_buffer_map (ret, &map, GST_MAP_WRITE); - data = GST_BUFFER_DATA (ret) + 16 + slen; + memcpy (map.data, MXF_UL (PRIMER_PACK), 16); + memcpy (map.data + 16, &ber, slen); + + data = map.data + 16 + slen; GST_WRITE_UINT32_BE (data, n); GST_WRITE_UINT32_BE (data + 4, 18); @@ -1470,6 +1488,8 @@ mxf_primer_pack_to_buffer (const MXFPrimerPack * pack) } } + gst_buffer_unmap (ret, &map); + return ret; } diff --git a/gst/mxf/mxfup.c b/gst/mxf/mxfup.c index cbe7af9c1..ce4150442 100644 --- a/gst/mxf/mxfup.c +++ b/gst/mxf/mxfup.c @@ -46,56 +46,54 @@ GST_DEBUG_CATEGORY_EXTERN (mxf_debug); static const struct { - const gchar *caps; + const gchar *format; guint32 n_pixel_layout; guint8 pixel_layout[10]; - guint32 fourcc; + const gchar *caps_string; } _rgba_mapping_table[] = { { - GST_VIDEO_CAPS_RGB, 3, { - 'R', 8, 'G', 8, 'B', 8}, GST_MAKE_FOURCC ('R', 'G', 'B', ' ')}, { - GST_VIDEO_CAPS_BGR, 3, { - 'B', 8, 'G', 8, 'R', 8}, GST_MAKE_FOURCC ('B', 'G', 'R', ' ')}, { - GST_VIDEO_CAPS_YUV ("v308"), 3, { - 'Y', 8, 'U', 8, 'V', 8}, GST_MAKE_FOURCC ('v', '3', '0', '8')}, { - GST_VIDEO_CAPS_xRGB, 4, { - 'F', 8, 'R', 8, 'G', 8, 'B', 8}, GST_MAKE_FOURCC ('x', 'R', 'G', 'B')}, { - GST_VIDEO_CAPS_RGBx, 4, { - 'R', 8, 'G', 8, 'B', 8, 'F', 8}, GST_MAKE_FOURCC ('R', 'G', 'B', 'x')}, { - GST_VIDEO_CAPS_xBGR, 4, { - 'F', 8, 'B', 8, 'G', 8, 'R', 8}, GST_MAKE_FOURCC ('x', 'B', 'G', 'R')}, { - GST_VIDEO_CAPS_BGRx, 4, { - 'B', 8, 'G', 8, 'R', 8, 'F', 8}, GST_MAKE_FOURCC ('B', 'G', 'R', 'x')}, { - GST_VIDEO_CAPS_RGBA, 4, { - 'R', 8, 'G', 8, 'B', 8, 'A', 8}, GST_MAKE_FOURCC ('R', 'G', 'B', 'A')}, { - GST_VIDEO_CAPS_ARGB, 4, { - 'A', 8, 'R', 8, 'G', 8, 'B', 8}, GST_MAKE_FOURCC ('A', 'R', 'G', 'B')}, { - GST_VIDEO_CAPS_BGRA, 4, { - 'B', 8, 'G', 8, 'R', 8, 'A', 8}, GST_MAKE_FOURCC ('B', 'G', 'R', 'A')}, { - GST_VIDEO_CAPS_ABGR, 4, { - 'A', 8, 'B', 8, 'G', 8, 'R', 8}, GST_MAKE_FOURCC ('A', 'B', 'G', 'R')}, { - GST_VIDEO_CAPS_YUV ("AYUV"), 4, { - 'A', 8, 'Y', 8, 'U', 8, 'V', 8}, GST_MAKE_FOURCC ('A', 'Y', 'U', 'V')} + "RGB", 3, { + 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGB")}, { + "BGR", 3, { + 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("BGR")}, { + "v308", 3, { + 'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("v308")}, { + "xRGB", 4, { + 'F', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("xRGB")}, { + "RGBx", 4, { + 'R', 8, 'G', 8, 'B', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("RGBx")}, { + "xBGR", 4, { + 'F', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("xBGR")}, { + "BGRx", 4, { + 'B', 8, 'G', 8, 'R', 8, 'F', 8}, GST_VIDEO_CAPS_MAKE ("BGRx")}, { + "RGBA", 4, { + 'R', 8, 'G', 8, 'B', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, { + "ARGB", 4, { + 'A', 8, 'R', 8, 'G', 8, 'B', 8}, GST_VIDEO_CAPS_MAKE ("RGBA")}, { + "BGRA", 4, { + 'B', 8, 'G', 8, 'R', 8, 'A', 8}, GST_VIDEO_CAPS_MAKE ("BGRA")}, { + "ABGR", 4, { + 'A', 8, 'B', 8, 'G', 8, 'R', 8}, GST_VIDEO_CAPS_MAKE ("ABGR")}, { + "AYUV", 4, { + 'A', 8, 'Y', 8, 'U', 8, 'V', 8}, GST_VIDEO_CAPS_MAKE ("AYUV")} }; static const struct { - const gchar *caps; + const gchar *format; guint bpp; guint horizontal_subsampling; guint vertical_subsampling; gboolean reversed_byte_order; - guint32 fourcc; + const gchar *caps_string; } _cdci_mapping_table[] = { { - GST_VIDEO_CAPS_YUV ("YUY2"), 2, 1, 0, TRUE, GST_MAKE_FOURCC ('Y', 'U', 'Y', - '2')}, { -GST_VIDEO_CAPS_YUV ("UYVY"), 2, 1, 0, FALSE, GST_MAKE_FOURCC ('U', 'Y', 'V', - 'Y')},}; + "YUY2", 2, 1, 0, TRUE, GST_VIDEO_CAPS_MAKE ("YUY2")}, { +"UYVY", 2, 1, 0, FALSE, GST_VIDEO_CAPS_MAKE ("UYVY")},}; typedef struct { - guint32 fourcc; /* fourcc or RGB format specifier */ + const gchar *format; /* video format string */ gint width, height; guint bpp; guint32 image_start_offset; @@ -147,18 +145,17 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer, if (!data || (data->image_start_offset == 0 && data->image_end_offset == 0)) { } else { if (data->image_start_offset + data->image_end_offset - > GST_BUFFER_SIZE (buffer)) { + > gst_buffer_get_size (buffer)) { gst_buffer_unref (buffer); GST_ERROR ("Invalid buffer size"); return GST_FLOW_ERROR; } else { - GST_BUFFER_DATA (buffer) += data->image_start_offset; - GST_BUFFER_SIZE (buffer) -= data->image_start_offset; - GST_BUFFER_SIZE (buffer) -= data->image_end_offset; + gst_buffer_resize (buffer, data->image_start_offset, + data->image_end_offset - data->image_start_offset); } } - if (GST_BUFFER_SIZE (buffer) != data->bpp * data->width * data->height) { + if (gst_buffer_get_size (buffer) != data->bpp * data->width * data->height) { GST_ERROR ("Invalid buffer size"); return GST_FLOW_ERROR; } @@ -167,13 +164,16 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer, || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) { guint y; GstBuffer *ret; + GstMapInfo inmap, outmap; guint8 *indata, *outdata; ret = gst_buffer_new_and_alloc (GST_ROUND_UP_4 (data->width * data->bpp) * data->height); - indata = GST_BUFFER_DATA (buffer); - outdata = GST_BUFFER_DATA (ret); + gst_buffer_map (buffer, &inmap, GST_MAP_READ); + gst_buffer_map (ret, &outmap, GST_MAP_WRITE); + indata = inmap.data; + outdata = outmap.data; for (y = 0; y < data->height; y++) { memcpy (outdata, indata, data->width * data->bpp); @@ -181,6 +181,9 @@ mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer, indata += data->width * data->bpp; } + gst_buffer_unmap (buffer, &inmap); + gst_buffer_unmap (ret, &outmap); + gst_buffer_unref (buffer); *outbuf = ret; } else { @@ -197,7 +200,7 @@ mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track, { GstCaps *caps = NULL; guint i; - guint32 fourcc; + const gchar *format = NULL; guint bpp; if (!d->pixel_layout) { @@ -211,8 +214,8 @@ mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track, if (memcmp (d->pixel_layout, &_rgba_mapping_table[i].pixel_layout, _rgba_mapping_table[i].n_pixel_layout * 2) == 0) { - caps = gst_caps_from_string (_rgba_mapping_table[i].caps); - fourcc = _rgba_mapping_table[i].fourcc; + caps = gst_caps_from_string (_rgba_mapping_table[i].caps_string); + format = _rgba_mapping_table[i].format; bpp = _rgba_mapping_table[i].n_pixel_layout; break; } @@ -225,7 +228,7 @@ mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track, data->width = d->parent.stored_width; data->height = d->parent.stored_height; - data->fourcc = fourcc; + data->format = format; data->bpp = bpp; data->image_start_offset = ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset; @@ -247,7 +250,7 @@ mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track, { GstCaps *caps = NULL; guint i; - guint32 fourcc; + const gchar *format; guint bpp; for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) { @@ -257,8 +260,8 @@ mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track, d->vertical_subsampling && _cdci_mapping_table[i].reversed_byte_order == d->reversed_byte_order) { - caps = gst_caps_from_string (_cdci_mapping_table[i].caps); - fourcc = _cdci_mapping_table[i].fourcc; + caps = gst_caps_from_string (_cdci_mapping_table[i].caps_string); + format = _cdci_mapping_table[i].format; bpp = _cdci_mapping_table[i].bpp; break; } @@ -271,7 +274,7 @@ mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track, data->width = d->parent.stored_width; data->height = d->parent.stored_height; - data->fourcc = fourcc; + data->format = format; data->bpp = bpp; data->image_start_offset = ((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_start_offset; @@ -307,19 +310,19 @@ mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, if (!track->parent.descriptor[i]) continue; - if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track-> - parent.descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - r = (MXFMetadataRGBAPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - break; - } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track->parent. + if (MXF_IS_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR (track->parent. descriptor[i])) { - p = (MXFMetadataGenericPictureEssenceDescriptor *) track-> - parent.descriptor[i]; - c = (MXFMetadataCDCIPictureEssenceDescriptor *) track-> - parent.descriptor[i]; + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; + r = (MXFMetadataRGBAPictureEssenceDescriptor *) track->parent. + descriptor[i]; + break; + } else if (MXF_IS_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR (track-> + parent.descriptor[i])) { + p = (MXFMetadataGenericPictureEssenceDescriptor *) track->parent. + descriptor[i]; + c = (MXFMetadataCDCIPictureEssenceDescriptor *) track->parent. + descriptor[i]; } } @@ -347,7 +350,7 @@ static const MXFEssenceElementHandler mxf_up_essence_element_handler = { }; static GstFlowReturn -mxf_up_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, +mxf_up_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { MXFUPMappingData *data = mapping_data; @@ -355,7 +358,7 @@ mxf_up_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, if (!buffer) return GST_FLOW_OK; - if (GST_BUFFER_SIZE (buffer) != + if (gst_buffer_get_size (buffer) != GST_ROUND_UP_4 (data->bpp * data->width) * data->height) { GST_ERROR ("Invalid buffer size"); return GST_FLOW_ERROR; @@ -365,11 +368,14 @@ mxf_up_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) { guint y; GstBuffer *ret; + GstMapInfo inmap, outmap; guint8 *indata, *outdata; ret = gst_buffer_new_and_alloc (data->width * data->bpp * data->height); - indata = GST_BUFFER_DATA (buffer); - outdata = GST_BUFFER_DATA (ret); + gst_buffer_map (buffer, &inmap, GST_MAP_READ); + gst_buffer_map (ret, &outmap, GST_MAP_WRITE); + indata = inmap.data; + outdata = outmap.data; for (y = 0; y < data->height; y++) { memcpy (outdata, indata, data->width * data->bpp); @@ -377,6 +383,8 @@ mxf_up_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, outdata += data->width * data->bpp; } + gst_buffer_unmap (buffer, &inmap); + gst_buffer_unmap (ret, &outmap); gst_buffer_unref (buffer); *outbuf = ret; @@ -407,7 +415,7 @@ mxf_up_get_rgba_descriptor (GstPadTemplate * tmpl, GstCaps * caps, g_object_new (MXF_TYPE_METADATA_RGBA_PICTURE_ESSENCE_DESCRIPTOR, NULL); for (i = 0; i < G_N_ELEMENTS (_rgba_mapping_table); i++) { - tmp = gst_caps_from_string (_rgba_mapping_table[i].caps); + tmp = gst_caps_from_string (_rgba_mapping_table[i].caps_string); intersection = gst_caps_intersect (caps, tmp); gst_caps_unref (tmp); @@ -415,7 +423,7 @@ mxf_up_get_rgba_descriptor (GstPadTemplate * tmpl, GstCaps * caps, gst_caps_unref (intersection); ret->n_pixel_layout = _rgba_mapping_table[i].n_pixel_layout; ret->pixel_layout = g_new0 (guint8, ret->n_pixel_layout * 2); - md->fourcc = _rgba_mapping_table[i].fourcc; + md->format = _rgba_mapping_table[i].format; md->bpp = _rgba_mapping_table[i].n_pixel_layout; memcpy (ret->pixel_layout, _rgba_mapping_table[i].pixel_layout, ret->n_pixel_layout * 2); @@ -424,7 +432,7 @@ mxf_up_get_rgba_descriptor (GstPadTemplate * tmpl, GstCaps * caps, gst_caps_unref (intersection); } - if (md->fourcc == 0) { + if (md->format == NULL) { GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps); g_object_unref (ret); return NULL; @@ -462,7 +470,7 @@ mxf_up_get_cdci_descriptor (GstPadTemplate * tmpl, GstCaps * caps, g_object_new (MXF_TYPE_METADATA_CDCI_PICTURE_ESSENCE_DESCRIPTOR, NULL); for (i = 0; i < G_N_ELEMENTS (_cdci_mapping_table); i++) { - tmp = gst_caps_from_string (_cdci_mapping_table[i].caps); + tmp = gst_caps_from_string (_cdci_mapping_table[i].caps_string); intersection = gst_caps_intersect (caps, tmp); gst_caps_unref (tmp); @@ -472,14 +480,14 @@ mxf_up_get_cdci_descriptor (GstPadTemplate * tmpl, GstCaps * caps, _cdci_mapping_table[i].horizontal_subsampling; ret->vertical_subsampling = _cdci_mapping_table[i].vertical_subsampling; ret->reversed_byte_order = _cdci_mapping_table[i].reversed_byte_order; - md->fourcc = _cdci_mapping_table[i].fourcc; + md->format = _cdci_mapping_table[i].format; md->bpp = _cdci_mapping_table[i].bpp; break; } gst_caps_unref (intersection); } - if (md->fourcc == 0) { + if (md->format == NULL) { GST_ERROR ("Invalid caps %" GST_PTR_FORMAT, caps); g_object_unref (ret); return NULL; @@ -508,19 +516,17 @@ mxf_up_get_descriptor (GstPadTemplate * tmpl, GstCaps * caps, GstStructure *s; s = gst_caps_get_structure (caps, 0); - if (strcmp (gst_structure_get_name (s), "video/x-raw-rgb") == 0) { - return mxf_up_get_rgba_descriptor (tmpl, caps, handler, mapping_data); - } else if (strcmp (gst_structure_get_name (s), "video/x-raw-yuv") == 0) { - guint32 fourcc; + if (strcmp (gst_structure_get_name (s), "video/x-raw") == 0) { + const gchar *format; - if (!gst_structure_get_fourcc (s, "format", &fourcc)) + format = gst_structure_get_string (s, "format"); + if (format == NULL) return NULL; - if (fourcc == GST_MAKE_FOURCC ('A', 'Y', 'U', 'V') || - fourcc == GST_MAKE_FOURCC ('v', '3', '0', '8')) + if (g_str_equal (format, "YUY2") || g_str_equal (format, "UYVY")) + return mxf_up_get_cdci_descriptor (tmpl, caps, handler, mapping_data); + else return mxf_up_get_rgba_descriptor (tmpl, caps, handler, mapping_data); - - return mxf_up_get_cdci_descriptor (tmpl, caps, handler, mapping_data); } g_assert_not_reached (); @@ -563,22 +569,21 @@ void mxf_up_init (void) { mxf_essence_element_handler_register (&mxf_up_essence_element_handler); - mxf_up_essence_element_writer.pad_template = gst_pad_template_new ("up_video_sink_%u", GST_PAD_SINK, GST_PAD_REQUEST, - gst_caps_from_string (GST_VIDEO_CAPS_RGB "; " - GST_VIDEO_CAPS_BGR "; " - GST_VIDEO_CAPS_RGBx "; " - GST_VIDEO_CAPS_xRGB "; " - GST_VIDEO_CAPS_BGRx "; " - GST_VIDEO_CAPS_xBGR "; " - GST_VIDEO_CAPS_ARGB "; " - GST_VIDEO_CAPS_RGBA "; " - GST_VIDEO_CAPS_ABGR "; " - GST_VIDEO_CAPS_BGRA "; " - GST_VIDEO_CAPS_YUV ("AYUV") "; " - GST_VIDEO_CAPS_YUV ("v308") "; " - GST_VIDEO_CAPS_YUV ("UYVY") "; " GST_VIDEO_CAPS_YUV ("YUY2"))); + gst_caps_from_string (GST_VIDEO_CAPS_MAKE ("RGB") "; " + GST_VIDEO_CAPS_MAKE ("BGR") "; " + GST_VIDEO_CAPS_MAKE ("RGBx") "; " + GST_VIDEO_CAPS_MAKE ("xRGB") "; " + GST_VIDEO_CAPS_MAKE ("BGRx") "; " + GST_VIDEO_CAPS_MAKE ("xBGR") "; " + GST_VIDEO_CAPS_MAKE ("ARGB") "; " + GST_VIDEO_CAPS_MAKE ("RGBA") "; " + GST_VIDEO_CAPS_MAKE ("ABGR") "; " + GST_VIDEO_CAPS_MAKE ("BGRA") "; " + GST_VIDEO_CAPS_MAKE ("AYUV") "; " + GST_VIDEO_CAPS_MAKE ("v308") "; " + GST_VIDEO_CAPS_MAKE ("UYVY") "; " GST_VIDEO_CAPS_MAKE ("YUY2"))); memcpy (&mxf_up_essence_element_writer.data_definition, mxf_metadata_track_identifier_get (MXF_METADATA_TRACK_PICTURE_ESSENCE), diff --git a/gst/mxf/mxfvc3.c b/gst/mxf/mxfvc3.c index b8cb6ecde..8a306348c 100644 --- a/gst/mxf/mxfvc3.c +++ b/gst/mxf/mxfvc3.c @@ -137,7 +137,7 @@ mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, *handler = mxf_vc3_handle_essence_element; - caps = gst_caps_new_simple ("video/x-dnxhd", NULL); + caps = gst_caps_new_empty_simple ("video/x-dnxhd"); if (p) { mxf_metadata_generic_picture_essence_descriptor_set_caps (p, caps); } else { @@ -145,7 +145,7 @@ mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags, } if (!*tags) - *tags = gst_tag_list_new (); + *tags = gst_tag_list_new_empty (); gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, "VC-3 Video", NULL); @@ -158,7 +158,7 @@ static const MXFEssenceElementHandler mxf_vc3_essence_element_handler = { }; static GstFlowReturn -mxf_vc3_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data, +mxf_vc3_write_func (GstBuffer * buffer, gpointer mapping_data, GstAdapter * adapter, GstBuffer ** outbuf, gboolean flush) { *outbuf = buffer; |