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
This commit is contained in:
Michael Smith 2012-10-26 13:48:06 -07:00
parent 0a30ecba90
commit 0c8a7fa46f
18 changed files with 843 additions and 684 deletions

View file

@ -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 \

View file

@ -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

View file

@ -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;

View file

@ -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;
GstAudioInfo info;
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)) {
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)

View file

@ -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;

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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,43 +85,21 @@ 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;
return ret;
}
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;

View file

@ -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);
if (pack->type == MXF_PARTITION_PACK_HEADER)
GST_BUFFER_DATA (ret)[13] = 0x02;
else if (pack->type == MXF_PARTITION_PACK_BODY)
GST_BUFFER_DATA (ret)[13] = 0x03;
else if (pack->type == MXF_PARTITION_PACK_FOOTER)
GST_BUFFER_DATA (ret)[13] = 0x04;
GST_BUFFER_DATA (ret)[14] = 0;
if (pack->complete)
GST_BUFFER_DATA (ret)[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);
gst_buffer_map (ret, &map, GST_MAP_WRITE);
data = GST_BUFFER_DATA (ret) + 16 + slen;
memcpy (map.data, MXF_UL (PARTITION_PACK), 13);
if (pack->type == MXF_PARTITION_PACK_HEADER)
map.data[13] = 0x02;
else if (pack->type == MXF_PARTITION_PACK_BODY)
map.data[13] = 0x03;
else if (pack->type == MXF_PARTITION_PACK_FOOTER)
map.data[13] = 0x04;
map.data[14] = 0;
if (pack->complete)
map.data[14] |= 0x02;
if (pack->closed)
map.data[14] |= 0x01;
map.data[14] += 1;
map.data[15] = 0;
memcpy (map.data + 16, &ber, 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;
}

View file

@ -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),

View file

@ -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;