mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
gst/mxf/: Implement parsing of Event Tracks, Static Tracks, DM Segments and DM Source Clips as a preparation for desc...
Original commit message from CVS: * gst/mxf/mxfdemux.c: (gst_mxf_demux_handle_metadata_track), (gst_mxf_demux_handle_header_metadata_resolve_references), (gst_mxf_demux_handle_metadata): * gst/mxf/mxfparse.c: (mxf_metadata_track_parse), (mxf_metadata_structural_component_parse), (mxf_metadata_structural_component_reset): * gst/mxf/mxfparse.h: * gst/mxf/mxftypes.h: Implement parsing of Event Tracks, Static Tracks, DM Segments and DM Source Clips as a preparation for descriptive metadata support. Next step is to implement SMPTE S380M, "Descriptive Metadata Scheme-1".
This commit is contained in:
parent
db08161b6d
commit
1fe82925f5
5 changed files with 239 additions and 33 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2008-12-11 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
* gst/mxf/mxfdemux.c: (gst_mxf_demux_handle_metadata_track),
|
||||
(gst_mxf_demux_handle_header_metadata_resolve_references),
|
||||
(gst_mxf_demux_handle_metadata):
|
||||
* gst/mxf/mxfparse.c: (mxf_metadata_track_parse),
|
||||
(mxf_metadata_structural_component_parse),
|
||||
(mxf_metadata_structural_component_reset):
|
||||
* gst/mxf/mxfparse.h:
|
||||
* gst/mxf/mxftypes.h:
|
||||
Implement parsing of Event Tracks, Static Tracks, DM Segments
|
||||
and DM Source Clips as a preparation for descriptive metadata
|
||||
support. Next step is to implement SMPTE S380M, "Descriptive
|
||||
Metadata Scheme-1".
|
||||
|
||||
2008-12-09 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||
|
||||
* gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps):
|
||||
|
|
|
@ -720,17 +720,18 @@ gst_mxf_demux_handle_metadata_source_package (GstMXFDemux * demux,
|
|||
|
||||
static GstFlowReturn
|
||||
gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux,
|
||||
const MXFUL * key, GstBuffer * buffer)
|
||||
const MXFUL * key, guint16 type, GstBuffer * buffer)
|
||||
{
|
||||
MXFMetadataTrack track;
|
||||
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Handling metadata track of size %u"
|
||||
" at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||
"Handling metadata track with type 0x%04x of size %u"
|
||||
" at offset %" G_GUINT64_FORMAT, type, GST_BUFFER_SIZE (buffer),
|
||||
demux->offset);
|
||||
|
||||
if (!mxf_metadata_track_parse (key, &track, &demux->primer,
|
||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
||||
GST_ERROR_OBJECT (demux, "Parsing metadata track timecode failed");
|
||||
type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
|
||||
GST_ERROR_OBJECT (demux, "Parsing metadata track failed");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1287,8 +1288,6 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
|||
}
|
||||
demux->preface.content_storage = &demux->content_storage;
|
||||
|
||||
/* TODO: dm_schemes */
|
||||
|
||||
/* Content storage */
|
||||
demux->content_storage.packages =
|
||||
g_new0 (MXFMetadataGenericPackage *, demux->content_storage.n_packages);
|
||||
|
@ -1317,8 +1316,9 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
|||
MXFMetadataEssenceContainerData, i);
|
||||
|
||||
for (j = 0; j < demux->content_storage.n_essence_container_data; j++) {
|
||||
if (mxf_ul_is_equal (&demux->content_storage.
|
||||
essence_container_data_uids[j], &data->instance_uid)) {
|
||||
if (mxf_ul_is_equal (&demux->
|
||||
content_storage.essence_container_data_uids[j],
|
||||
&data->instance_uid)) {
|
||||
demux->content_storage.essence_container_data[j] = data;
|
||||
break;
|
||||
}
|
||||
|
@ -1500,7 +1500,8 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
|||
&g_array_index (demux->structural_component,
|
||||
MXFMetadataStructuralComponent, i);
|
||||
|
||||
if (component->type != MXF_METADATA_SOURCE_CLIP)
|
||||
if (component->type != MXF_METADATA_SOURCE_CLIP
|
||||
&& component->type != MXF_METADATA_DM_SOURCE_CLIP)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < demux->source_package->len; j++) {
|
||||
|
@ -1508,10 +1509,16 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
|
|||
&g_array_index (demux->source_package, MXFMetadataGenericPackage,
|
||||
j);
|
||||
|
||||
if (mxf_umid_is_equal (&component->source_clip.source_package_id,
|
||||
if (component->type == MXF_METADATA_SOURCE_CLIP &&
|
||||
mxf_umid_is_equal (&component->source_clip.source_package_id,
|
||||
&package->package_uid)) {
|
||||
component->source_clip.source_package = package;
|
||||
break;
|
||||
} else if (component->type == MXF_METADATA_DM_SOURCE_CLIP &&
|
||||
mxf_umid_is_equal (&component->dm_source_clip.source_package_id,
|
||||
&package->package_uid)) {
|
||||
component->dm_source_clip.source_package = package;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1986,7 +1993,7 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
|||
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Handling metadata of size %u at offset %"
|
||||
G_GUINT64_FORMAT " of type 0x%04d", GST_BUFFER_SIZE (buffer),
|
||||
G_GUINT64_FORMAT " of type 0x%04x", GST_BUFFER_SIZE (buffer),
|
||||
demux->offset, type);
|
||||
|
||||
if (G_UNLIKELY (!demux->partition.valid)) {
|
||||
|
@ -2027,13 +2034,17 @@ gst_mxf_demux_handle_metadata (GstMXFDemux * demux, const MXFUL * key,
|
|||
ret = gst_mxf_demux_handle_metadata_source_package (demux, key, buffer);
|
||||
break;
|
||||
case MXF_METADATA_TRACK:
|
||||
ret = gst_mxf_demux_handle_metadata_track (demux, key, buffer);
|
||||
case MXF_METADATA_EVENT_TRACK:
|
||||
case MXF_METADATA_STATIC_TRACK:
|
||||
ret = gst_mxf_demux_handle_metadata_track (demux, key, type, buffer);
|
||||
break;
|
||||
case MXF_METADATA_SEQUENCE:
|
||||
ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer);
|
||||
break;
|
||||
case MXF_METADATA_TIMECODE_COMPONENT:
|
||||
case MXF_METADATA_SOURCE_CLIP:
|
||||
case MXF_METADATA_DM_SEGMENT:
|
||||
case MXF_METADATA_DM_SOURCE_CLIP:
|
||||
ret =
|
||||
gst_mxf_demux_handle_metadata_structural_component (demux,
|
||||
key, type, buffer);
|
||||
|
|
|
@ -1694,7 +1694,7 @@ void mxf_metadata_generic_package_reset
|
|||
gboolean
|
||||
mxf_metadata_track_parse (const MXFUL * key,
|
||||
MXFMetadataTrack * track, const MXFPrimerPack * primer,
|
||||
const guint8 * data, guint size)
|
||||
guint16 type, const guint8 * data, guint size)
|
||||
{
|
||||
guint16 tag, tag_size;
|
||||
const guint8 *tag_data;
|
||||
|
@ -1704,7 +1704,15 @@ mxf_metadata_track_parse (const MXFUL * key,
|
|||
|
||||
memset (track, 0, sizeof (MXFMetadataTrack));
|
||||
|
||||
GST_DEBUG ("Parsing track:");
|
||||
if (type == MXF_METADATA_TRACK)
|
||||
track->variant = MXF_METADATA_TRACK_VARIANT_TIMELINE;
|
||||
else if (type == MXF_METADATA_EVENT_TRACK)
|
||||
track->variant = MXF_METADATA_TRACK_VARIANT_EVENT;
|
||||
else
|
||||
track->variant = MXF_METADATA_TRACK_VARIANT_STATIC;
|
||||
|
||||
|
||||
GST_DEBUG ("Parsing track of type 0x%04x:", type);
|
||||
|
||||
while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
|
||||
if (tag_size == 0 || tag == 0x0000)
|
||||
|
@ -1742,12 +1750,14 @@ mxf_metadata_track_parse (const MXFUL * key,
|
|||
GST_DEBUG (" track name = %s", GST_STR_NULL (track->track_name));
|
||||
break;
|
||||
case 0x4b01:
|
||||
case 0x4901:
|
||||
if (!mxf_fraction_parse (&track->edit_rate, tag_data, tag_size))
|
||||
goto error;
|
||||
GST_DEBUG (" edit rate = %d/%d", track->edit_rate.n,
|
||||
track->edit_rate.d);
|
||||
break;
|
||||
case 0x4b02:
|
||||
case 0x4902:
|
||||
if (tag_size != 8)
|
||||
goto error;
|
||||
track->origin = GST_READ_UINT64_BE (tag_data);
|
||||
|
@ -1960,10 +1970,14 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
|
|||
GST_DEBUG ("Parsing structural component:");
|
||||
|
||||
component->type = type;
|
||||
GST_DEBUG (" type = %s",
|
||||
(component->type ==
|
||||
MXF_METADATA_TIMECODE_COMPONENT) ? "timecode component" :
|
||||
"source clip");
|
||||
if (type == MXF_METADATA_TIMECODE_COMPONENT)
|
||||
GST_DEBUG (" type = timecode component");
|
||||
else if (type == MXF_METADATA_SOURCE_CLIP)
|
||||
GST_DEBUG (" type = source clip");
|
||||
else if (type == MXF_METADATA_DM_SEGMENT)
|
||||
GST_DEBUG (" type = DM segment");
|
||||
else
|
||||
GST_DEBUG (" type = DM source clip");
|
||||
|
||||
while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
|
||||
if (tag_size == 0 || tag == 0x0000)
|
||||
|
@ -2030,33 +2044,164 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
|
|||
break;
|
||||
/* Source clip specifics */
|
||||
case 0x1201:
|
||||
if (type != MXF_METADATA_SOURCE_CLIP)
|
||||
if (type != MXF_METADATA_SOURCE_CLIP
|
||||
&& type != MXF_METADATA_DM_SOURCE_CLIP)
|
||||
goto DFLT;
|
||||
if (tag_size != 8)
|
||||
goto error;
|
||||
component->source_clip.start_position = GST_READ_UINT64_BE (tag_data);
|
||||
GST_DEBUG (" start position = %" G_GINT64_FORMAT,
|
||||
component->source_clip.start_position);
|
||||
|
||||
if (type == MXF_METADATA_SOURCE_CLIP) {
|
||||
component->source_clip.start_position = GST_READ_UINT64_BE (tag_data);
|
||||
GST_DEBUG (" start position = %" G_GINT64_FORMAT,
|
||||
component->source_clip.start_position);
|
||||
} else {
|
||||
component->dm_source_clip.start_position =
|
||||
GST_READ_UINT64_BE (tag_data);
|
||||
GST_DEBUG (" start position = %" G_GINT64_FORMAT,
|
||||
component->dm_source_clip.start_position);
|
||||
}
|
||||
break;
|
||||
case 0x1101:
|
||||
if (type != MXF_METADATA_SOURCE_CLIP)
|
||||
if (type != MXF_METADATA_SOURCE_CLIP
|
||||
&& type != MXF_METADATA_DM_SOURCE_CLIP)
|
||||
goto DFLT;
|
||||
if (tag_size != 32)
|
||||
goto error;
|
||||
memcpy (&component->source_clip.source_package_id, tag_data, 32);
|
||||
GST_DEBUG (" source package id = %s",
|
||||
mxf_umid_to_string (&component->source_clip.source_package_id,
|
||||
str));
|
||||
|
||||
if (type == MXF_METADATA_SOURCE_CLIP) {
|
||||
memcpy (&component->source_clip.source_package_id, tag_data, 32);
|
||||
GST_DEBUG (" source package id = %s",
|
||||
mxf_umid_to_string (&component->source_clip.source_package_id,
|
||||
str));
|
||||
} else {
|
||||
memcpy (&component->dm_source_clip.source_package_id, tag_data, 32);
|
||||
GST_DEBUG (" source package id = %s",
|
||||
mxf_umid_to_string (&component->dm_source_clip.source_package_id,
|
||||
str));
|
||||
}
|
||||
break;
|
||||
case 0x1102:
|
||||
if (type != MXF_METADATA_SOURCE_CLIP)
|
||||
if (type != MXF_METADATA_SOURCE_CLIP
|
||||
&& type != MXF_METADATA_DM_SOURCE_CLIP)
|
||||
goto DFLT;
|
||||
if (tag_size != 4)
|
||||
goto error;
|
||||
component->source_clip.source_track_id = GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" source track id = %u",
|
||||
component->source_clip.source_track_id);
|
||||
|
||||
if (type == MXF_METADATA_SOURCE_CLIP) {
|
||||
component->source_clip.source_track_id =
|
||||
GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" source track id = %u",
|
||||
component->source_clip.source_track_id);
|
||||
} else {
|
||||
component->dm_source_clip.source_track_id =
|
||||
GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" source track id = %u",
|
||||
component->dm_source_clip.source_track_id);
|
||||
}
|
||||
break;
|
||||
/* DM Segment specifics */
|
||||
case 0x0601:
|
||||
if (type != MXF_METADATA_DM_SEGMENT)
|
||||
goto DFLT;
|
||||
if (tag_size != 8)
|
||||
goto error;
|
||||
component->dm_segment.event_start_position =
|
||||
GST_READ_UINT64_BE (tag_data);
|
||||
GST_DEBUG (" event start position = %" G_GINT64_FORMAT,
|
||||
component->dm_segment.event_start_position);
|
||||
break;
|
||||
case 0x0602:
|
||||
if (type != MXF_METADATA_DM_SEGMENT)
|
||||
goto DFLT;
|
||||
component->dm_segment.event_comment =
|
||||
mxf_utf16_to_utf8 (tag_data, tag_size);
|
||||
GST_DEBUG (" event comment = %s",
|
||||
GST_STR_NULL (component->dm_segment.event_comment));
|
||||
break;
|
||||
case 0x6102:
|
||||
{
|
||||
guint32 len;
|
||||
guint i;
|
||||
|
||||
if (type != MXF_METADATA_DM_SEGMENT)
|
||||
goto DFLT;
|
||||
|
||||
if (tag_size < 8)
|
||||
goto error;
|
||||
len = GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" number of track ids = %u", len);
|
||||
if (len == 0)
|
||||
goto next;
|
||||
|
||||
if (GST_READ_UINT32_BE (tag_data + 4) != 4)
|
||||
goto error;
|
||||
|
||||
if (len * 4 + 8 < tag_size)
|
||||
goto error;
|
||||
|
||||
component->dm_segment.n_track_ids = len;
|
||||
component->dm_segment.track_ids = g_new0 (guint32, len);
|
||||
|
||||
tag_data += 8;
|
||||
tag_size -= 8;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
component->dm_segment.track_ids[i] = GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" track id %u = %u", i,
|
||||
component->dm_segment.track_ids[i]);
|
||||
tag_data += 4;
|
||||
tag_size -= 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x6101:
|
||||
if (type != MXF_METADATA_DM_SEGMENT)
|
||||
goto DFLT;
|
||||
if (tag_size != 16)
|
||||
goto error;
|
||||
|
||||
memcpy (&component->dm_segment.dm_framework, tag_data, 16);
|
||||
GST_DEBUG (" DM framework = %s",
|
||||
mxf_ul_to_string (&component->dm_segment.dm_framework, str));
|
||||
break;
|
||||
/* DM Source Clip specifics */
|
||||
case 0x6103:
|
||||
{
|
||||
guint32 len;
|
||||
guint i;
|
||||
|
||||
if (type != MXF_METADATA_DM_SOURCE_CLIP)
|
||||
goto DFLT;
|
||||
if (tag_size < 8)
|
||||
goto error;
|
||||
|
||||
len = GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" number of track ids = %u", len);
|
||||
if (len == 0)
|
||||
goto next;
|
||||
|
||||
if (GST_READ_UINT32_BE (tag_data + 4) != 4)
|
||||
goto error;
|
||||
|
||||
if (tag_size < 8 + 4 * len)
|
||||
goto error;
|
||||
|
||||
tag_data += 8;
|
||||
tag_size -= 8;
|
||||
|
||||
component->dm_source_clip.n_track_ids = len;
|
||||
component->dm_source_clip.track_ids = g_new0 (guint32, len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
component->dm_source_clip.track_ids[i] =
|
||||
GST_READ_UINT32_BE (tag_data);
|
||||
GST_DEBUG (" track id %u = %u", i,
|
||||
component->dm_source_clip.track_ids[i]);
|
||||
tag_data += 4;
|
||||
tag_size -= 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
DFLT:
|
||||
default:
|
||||
if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size,
|
||||
|
@ -2084,6 +2229,13 @@ void mxf_metadata_structural_component_reset
|
|||
{
|
||||
g_return_if_fail (component != NULL);
|
||||
|
||||
if (component->type == MXF_METADATA_DM_SEGMENT) {
|
||||
g_free (component->dm_segment.event_comment);
|
||||
g_free (component->dm_segment.track_ids);
|
||||
} else if (component->type == MXF_METADATA_DM_SOURCE_CLIP) {
|
||||
g_free (component->dm_source_clip.track_ids);
|
||||
}
|
||||
|
||||
if (component->other_tags)
|
||||
g_hash_table_destroy (component->other_tags);
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ void mxf_metadata_essence_container_data_reset (MXFMetadataEssenceContainerData
|
|||
gboolean mxf_metadata_generic_package_parse (const MXFUL *key, MXFMetadataGenericPackage *generic_package, const MXFPrimerPack *primer, const guint8 *data, guint size);
|
||||
void mxf_metadata_generic_package_reset (MXFMetadataGenericPackage *generic_package);
|
||||
|
||||
gboolean mxf_metadata_track_parse (const MXFUL *key, MXFMetadataTrack *track, const MXFPrimerPack *primer, const guint8 *data, guint size);
|
||||
gboolean mxf_metadata_track_parse (const MXFUL *key, MXFMetadataTrack *track, const MXFPrimerPack *primer, guint16 type, const guint8 *data, guint size);
|
||||
void mxf_metadata_track_reset (MXFMetadataTrack *track);
|
||||
|
||||
MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL *track_identifier);
|
||||
|
|
|
@ -327,6 +327,12 @@ typedef enum {
|
|||
MXF_METADATA_TRACK_PARSED_TEXT = 0x41
|
||||
} MXFMetadataTrackType;
|
||||
|
||||
typedef enum {
|
||||
MXF_METADATA_TRACK_VARIANT_TIMELINE,
|
||||
MXF_METADATA_TRACK_VARIANT_EVENT,
|
||||
MXF_METADATA_TRACK_VARIANT_STATIC
|
||||
} MXFMetadataTrackVariant;
|
||||
|
||||
struct _MXFMetadataTrack {
|
||||
MXFUL instance_uid;
|
||||
MXFUL generation_uid;
|
||||
|
@ -335,6 +341,7 @@ struct _MXFMetadataTrack {
|
|||
guint32 track_number;
|
||||
|
||||
MXFMetadataTrackType type;
|
||||
MXFMetadataTrackVariant variant;
|
||||
|
||||
gchar *track_name;
|
||||
|
||||
|
@ -390,6 +397,27 @@ struct _MXFMetadataStructuralComponent {
|
|||
|
||||
guint32 source_track_id;
|
||||
} source_clip;
|
||||
|
||||
struct {
|
||||
gint64 event_start_position;
|
||||
gchar *event_comment;
|
||||
|
||||
guint32 n_track_ids;
|
||||
guint32 *track_ids;
|
||||
|
||||
MXFUL dm_framework;
|
||||
} dm_segment;
|
||||
|
||||
struct {
|
||||
gint64 start_position;
|
||||
MXFUMID source_package_id;
|
||||
MXFMetadataGenericPackage *source_package;
|
||||
|
||||
guint32 source_track_id;
|
||||
|
||||
guint32 n_track_ids;
|
||||
guint32 *track_ids;
|
||||
} dm_source_clip;
|
||||
};
|
||||
|
||||
GHashTable *other_tags;
|
||||
|
|
Loading…
Reference in a new issue