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:
Sebastian Dröge 2008-12-11 14:35:08 +00:00
parent db08161b6d
commit 1fe82925f5
5 changed files with 239 additions and 33 deletions

View file

@ -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> 2008-12-09 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps): * gst/mxf/mxfjpeg2000.c: (mxf_jpeg2000_create_caps):

View file

@ -720,17 +720,18 @@ gst_mxf_demux_handle_metadata_source_package (GstMXFDemux * demux,
static GstFlowReturn static GstFlowReturn
gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux, gst_mxf_demux_handle_metadata_track (GstMXFDemux * demux,
const MXFUL * key, GstBuffer * buffer) const MXFUL * key, guint16 type, GstBuffer * buffer)
{ {
MXFMetadataTrack track; MXFMetadataTrack track;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Handling metadata track of size %u" "Handling metadata track with type 0x%04x of size %u"
" at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset); " at offset %" G_GUINT64_FORMAT, type, GST_BUFFER_SIZE (buffer),
demux->offset);
if (!mxf_metadata_track_parse (key, &track, &demux->primer, if (!mxf_metadata_track_parse (key, &track, &demux->primer,
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) { type, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer))) {
GST_ERROR_OBJECT (demux, "Parsing metadata track timecode failed"); GST_ERROR_OBJECT (demux, "Parsing metadata track failed");
return GST_FLOW_ERROR; 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; demux->preface.content_storage = &demux->content_storage;
/* TODO: dm_schemes */
/* Content storage */ /* Content storage */
demux->content_storage.packages = demux->content_storage.packages =
g_new0 (MXFMetadataGenericPackage *, demux->content_storage.n_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); MXFMetadataEssenceContainerData, i);
for (j = 0; j < demux->content_storage.n_essence_container_data; j++) { for (j = 0; j < demux->content_storage.n_essence_container_data; j++) {
if (mxf_ul_is_equal (&demux->content_storage. if (mxf_ul_is_equal (&demux->
essence_container_data_uids[j], &data->instance_uid)) { content_storage.essence_container_data_uids[j],
&data->instance_uid)) {
demux->content_storage.essence_container_data[j] = data; demux->content_storage.essence_container_data[j] = data;
break; break;
} }
@ -1500,7 +1500,8 @@ gst_mxf_demux_handle_header_metadata_resolve_references (GstMXFDemux * demux)
&g_array_index (demux->structural_component, &g_array_index (demux->structural_component,
MXFMetadataStructuralComponent, i); MXFMetadataStructuralComponent, i);
if (component->type != MXF_METADATA_SOURCE_CLIP) if (component->type != MXF_METADATA_SOURCE_CLIP
&& component->type != MXF_METADATA_DM_SOURCE_CLIP)
continue; continue;
for (j = 0; j < demux->source_package->len; j++) { 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, &g_array_index (demux->source_package, MXFMetadataGenericPackage,
j); 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)) { &package->package_uid)) {
component->source_clip.source_package = package; component->source_clip.source_package = package;
break; 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, GST_DEBUG_OBJECT (demux,
"Handling metadata of size %u at offset %" "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); demux->offset, type);
if (G_UNLIKELY (!demux->partition.valid)) { 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); ret = gst_mxf_demux_handle_metadata_source_package (demux, key, buffer);
break; break;
case MXF_METADATA_TRACK: 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; break;
case MXF_METADATA_SEQUENCE: case MXF_METADATA_SEQUENCE:
ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer); ret = gst_mxf_demux_handle_metadata_sequence (demux, key, buffer);
break; break;
case MXF_METADATA_TIMECODE_COMPONENT: case MXF_METADATA_TIMECODE_COMPONENT:
case MXF_METADATA_SOURCE_CLIP: case MXF_METADATA_SOURCE_CLIP:
case MXF_METADATA_DM_SEGMENT:
case MXF_METADATA_DM_SOURCE_CLIP:
ret = ret =
gst_mxf_demux_handle_metadata_structural_component (demux, gst_mxf_demux_handle_metadata_structural_component (demux,
key, type, buffer); key, type, buffer);

View file

@ -1694,7 +1694,7 @@ void mxf_metadata_generic_package_reset
gboolean gboolean
mxf_metadata_track_parse (const MXFUL * key, mxf_metadata_track_parse (const MXFUL * key,
MXFMetadataTrack * track, const MXFPrimerPack * primer, MXFMetadataTrack * track, const MXFPrimerPack * primer,
const guint8 * data, guint size) guint16 type, const guint8 * data, guint size)
{ {
guint16 tag, tag_size; guint16 tag, tag_size;
const guint8 *tag_data; const guint8 *tag_data;
@ -1704,7 +1704,15 @@ mxf_metadata_track_parse (const MXFUL * key,
memset (track, 0, sizeof (MXFMetadataTrack)); 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)) { while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
if (tag_size == 0 || tag == 0x0000) 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)); GST_DEBUG (" track name = %s", GST_STR_NULL (track->track_name));
break; break;
case 0x4b01: case 0x4b01:
case 0x4901:
if (!mxf_fraction_parse (&track->edit_rate, tag_data, tag_size)) if (!mxf_fraction_parse (&track->edit_rate, tag_data, tag_size))
goto error; goto error;
GST_DEBUG (" edit rate = %d/%d", track->edit_rate.n, GST_DEBUG (" edit rate = %d/%d", track->edit_rate.n,
track->edit_rate.d); track->edit_rate.d);
break; break;
case 0x4b02: case 0x4b02:
case 0x4902:
if (tag_size != 8) if (tag_size != 8)
goto error; goto error;
track->origin = GST_READ_UINT64_BE (tag_data); 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:"); GST_DEBUG ("Parsing structural component:");
component->type = type; component->type = type;
GST_DEBUG (" type = %s", if (type == MXF_METADATA_TIMECODE_COMPONENT)
(component->type == GST_DEBUG (" type = timecode component");
MXF_METADATA_TIMECODE_COMPONENT) ? "timecode component" : else if (type == MXF_METADATA_SOURCE_CLIP)
"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)) { while (mxf_local_tag_parse (data, size, &tag, &tag_size, &tag_data)) {
if (tag_size == 0 || tag == 0x0000) if (tag_size == 0 || tag == 0x0000)
@ -2030,33 +2044,164 @@ mxf_metadata_structural_component_parse (const MXFUL * key,
break; break;
/* Source clip specifics */ /* Source clip specifics */
case 0x1201: case 0x1201:
if (type != MXF_METADATA_SOURCE_CLIP) if (type != MXF_METADATA_SOURCE_CLIP
&& type != MXF_METADATA_DM_SOURCE_CLIP)
goto DFLT; goto DFLT;
if (tag_size != 8) if (tag_size != 8)
goto error; goto error;
component->source_clip.start_position = GST_READ_UINT64_BE (tag_data);
GST_DEBUG (" start position = %" G_GINT64_FORMAT, if (type == MXF_METADATA_SOURCE_CLIP) {
component->source_clip.start_position); 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; break;
case 0x1101: case 0x1101:
if (type != MXF_METADATA_SOURCE_CLIP) if (type != MXF_METADATA_SOURCE_CLIP
&& type != MXF_METADATA_DM_SOURCE_CLIP)
goto DFLT; goto DFLT;
if (tag_size != 32) if (tag_size != 32)
goto error; goto error;
memcpy (&component->source_clip.source_package_id, tag_data, 32);
GST_DEBUG (" source package id = %s", if (type == MXF_METADATA_SOURCE_CLIP) {
mxf_umid_to_string (&component->source_clip.source_package_id, memcpy (&component->source_clip.source_package_id, tag_data, 32);
str)); 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; break;
case 0x1102: case 0x1102:
if (type != MXF_METADATA_SOURCE_CLIP) if (type != MXF_METADATA_SOURCE_CLIP
&& type != MXF_METADATA_DM_SOURCE_CLIP)
goto DFLT; goto DFLT;
if (tag_size != 4) if (tag_size != 4)
goto error; goto error;
component->source_clip.source_track_id = GST_READ_UINT32_BE (tag_data);
GST_DEBUG (" source track id = %u", if (type == MXF_METADATA_SOURCE_CLIP) {
component->source_clip.source_track_id); 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; 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: DFLT:
default: default:
if (!gst_metadata_add_custom_tag (primer, tag, tag_data, tag_size, 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); 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) if (component->other_tags)
g_hash_table_destroy (component->other_tags); g_hash_table_destroy (component->other_tags);

View file

@ -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); 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); 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); void mxf_metadata_track_reset (MXFMetadataTrack *track);
MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL *track_identifier); MXFMetadataTrackType mxf_metadata_track_identifier_parse (const MXFUL *track_identifier);

View file

@ -327,6 +327,12 @@ typedef enum {
MXF_METADATA_TRACK_PARSED_TEXT = 0x41 MXF_METADATA_TRACK_PARSED_TEXT = 0x41
} MXFMetadataTrackType; } MXFMetadataTrackType;
typedef enum {
MXF_METADATA_TRACK_VARIANT_TIMELINE,
MXF_METADATA_TRACK_VARIANT_EVENT,
MXF_METADATA_TRACK_VARIANT_STATIC
} MXFMetadataTrackVariant;
struct _MXFMetadataTrack { struct _MXFMetadataTrack {
MXFUL instance_uid; MXFUL instance_uid;
MXFUL generation_uid; MXFUL generation_uid;
@ -335,6 +341,7 @@ struct _MXFMetadataTrack {
guint32 track_number; guint32 track_number;
MXFMetadataTrackType type; MXFMetadataTrackType type;
MXFMetadataTrackVariant variant;
gchar *track_name; gchar *track_name;
@ -390,6 +397,27 @@ struct _MXFMetadataStructuralComponent {
guint32 source_track_id; guint32 source_track_id;
} source_clip; } 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; GHashTable *other_tags;