mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
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:
parent
0a30ecba90
commit
0c8a7fa46f
18 changed files with 843 additions and 684 deletions
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
256
gst/mxf/mxfmux.c
256
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,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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
191
gst/mxf/mxfup.c
191
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),
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue