mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 16:52:42 +00:00
mxfdemux: Take temporal reordering from the index table into account
This is needed to know the PTS, without that we only know the DTS and using that also for the PTS is wrong unless we have an intra-only codec. If we can't get the temporal reordering from the index table, don't set any PTS for non-intra-only codecs and let decoders figure out something. https://bugzilla.gnome.org/show_bug.cgi?id=784027
This commit is contained in:
parent
ab9d87f168
commit
830e89b7e9
11 changed files with 154 additions and 39 deletions
|
@ -1233,6 +1233,7 @@ static const MXFUL mxf_sound_essence_compression_alaw =
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_bwf_create_caps (MXFMetadataTimelineTrack * track,
|
mxf_bwf_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
|
MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
|
||||||
|
gboolean * intra_only,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
GstCaps *ret = NULL;
|
GstCaps *ret = NULL;
|
||||||
|
@ -1348,13 +1349,16 @@ mxf_bwf_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_BITRATE,
|
||||||
wa_descriptor->avg_bps * 8, NULL);
|
wa_descriptor->avg_bps * 8, NULL);
|
||||||
|
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_aes3_create_caps (MXFMetadataTimelineTrack * track,
|
mxf_aes3_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
|
MXFMetadataGenericSoundEssenceDescriptor * descriptor, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
GstCaps *ret = NULL;
|
GstCaps *ret = NULL;
|
||||||
MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
|
MXFMetadataWaveAudioEssenceDescriptor *wa_descriptor = NULL;
|
||||||
|
@ -1404,13 +1408,15 @@ mxf_aes3_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
g_free (codec_name);
|
g_free (codec_name);
|
||||||
|
|
||||||
*handler = mxf_aes3_handle_essence_element;
|
*handler = mxf_aes3_handle_essence_element;
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
||||||
gboolean bwf = FALSE;
|
gboolean bwf = FALSE;
|
||||||
|
@ -1454,9 +1460,11 @@ mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
GST_ERROR ("No descriptor found for this track");
|
GST_ERROR ("No descriptor found for this track");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (bwf) {
|
} else if (bwf) {
|
||||||
return mxf_bwf_create_caps (track, s, tags, handler, mapping_data);
|
return mxf_bwf_create_caps (track, s, tags, intra_only, handler,
|
||||||
|
mapping_data);
|
||||||
} else {
|
} else {
|
||||||
return mxf_aes3_create_caps (track, s, tags, handler, mapping_data);
|
return mxf_aes3_create_caps (track, s, tags, intra_only, handler,
|
||||||
|
mapping_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -119,7 +119,8 @@ mxf_alaw_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -167,6 +168,8 @@ mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,8 @@ mxf_d10_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
||||||
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
MXFMetadataGenericSoundEssenceDescriptor *s = NULL;
|
||||||
|
@ -247,6 +248,8 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
|
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"SMPTE D-10 Audio", NULL);
|
"SMPTE D-10 Audio", NULL);
|
||||||
|
|
||||||
|
*intra_only = TRUE;
|
||||||
} else if (p) {
|
} else if (p) {
|
||||||
caps =
|
caps =
|
||||||
gst_caps_new_simple ("video/mpeg", "systemstream", G_TYPE_BOOLEAN,
|
gst_caps_new_simple ("video/mpeg", "systemstream", G_TYPE_BOOLEAN,
|
||||||
|
@ -256,6 +259,9 @@ mxf_d10_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*handler = mxf_d10_picture_handle_essence_element;
|
*handler = mxf_d10_picture_handle_essence_element;
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"SMPTE D-10 Video", NULL);
|
"SMPTE D-10 Video", NULL);
|
||||||
|
|
||||||
|
/* Does not allow temporal reordering */
|
||||||
|
*intra_only = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
|
@ -821,10 +821,11 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux)
|
||||||
|
|
||||||
caps = gst_caps_new_empty_simple (name);
|
caps = gst_caps_new_empty_simple (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
etrack->intra_only = FALSE;
|
||||||
} else {
|
} else {
|
||||||
caps =
|
caps =
|
||||||
etrack->handler->create_caps (track, &etrack->tags,
|
etrack->handler->create_caps (track, &etrack->tags,
|
||||||
&etrack->handle_func, &etrack->mapping_data);
|
&etrack->intra_only, &etrack->handle_func, &etrack->mapping_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "Created caps %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (demux, "Created caps %" GST_PTR_FORMAT, caps);
|
||||||
|
@ -1622,6 +1623,8 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
GstMXFDemuxEssenceTrack *etrack = NULL;
|
GstMXFDemuxEssenceTrack *etrack = NULL;
|
||||||
gboolean keyframe = TRUE;
|
gboolean keyframe = TRUE;
|
||||||
|
/* As in GstMXFDemuxIndex */
|
||||||
|
guint64 pts = G_MAXUINT64, dts = G_MAXUINT64;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"Handling generic container essence element of size %" G_GSIZE_FORMAT
|
"Handling generic container essence element of size %" G_GSIZE_FORMAT
|
||||||
|
@ -1680,7 +1683,8 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
GstMXFDemuxIndex *idx =
|
GstMXFDemuxIndex *idx =
|
||||||
&g_array_index (etrack->offsets, GstMXFDemuxIndex, i);
|
&g_array_index (etrack->offsets, GstMXFDemuxIndex, i);
|
||||||
|
|
||||||
if (idx->offset != 0 && idx->offset == demux->offset - demux->run_in) {
|
if (idx->initialized && idx->offset != 0
|
||||||
|
&& idx->offset == demux->offset - demux->run_in) {
|
||||||
etrack->position = i;
|
etrack->position = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1696,8 +1700,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
if (etrack->offsets && etrack->offsets->len > etrack->position) {
|
if (etrack->offsets && etrack->offsets->len > etrack->position) {
|
||||||
GstMXFDemuxIndex *index =
|
GstMXFDemuxIndex *index =
|
||||||
&g_array_index (etrack->offsets, GstMXFDemuxIndex, etrack->position);
|
&g_array_index (etrack->offsets, GstMXFDemuxIndex, etrack->position);
|
||||||
if (index->offset != 0)
|
if (index->initialized && index->offset != 0)
|
||||||
keyframe = index->keyframe;
|
keyframe = index->keyframe;
|
||||||
|
if (index->initialized && index->pts != G_MAXUINT64)
|
||||||
|
pts = index->pts;
|
||||||
|
if (index->initialized && index->dts != G_MAXUINT64)
|
||||||
|
dts = index->dts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create subbuffer to be able to change metadata */
|
/* Create subbuffer to be able to change metadata */
|
||||||
|
@ -1733,7 +1741,7 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
keyframe = !GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
keyframe = !GST_BUFFER_FLAG_IS_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
|
||||||
/* Prefer keyframe information from index tables over everything else */
|
/* Prefer keyframe information from index tables over everything else */
|
||||||
if (demux->index_tables && outbuf) {
|
if (demux->index_tables) {
|
||||||
GList *l;
|
GList *l;
|
||||||
GstMXFDemuxIndexTable *index_table = NULL;
|
GstMXFDemuxIndexTable *index_table = NULL;
|
||||||
|
|
||||||
|
@ -1751,14 +1759,21 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
GstMXFDemuxIndex *index =
|
GstMXFDemuxIndex *index =
|
||||||
&g_array_index (index_table->offsets, GstMXFDemuxIndex,
|
&g_array_index (index_table->offsets, GstMXFDemuxIndex,
|
||||||
etrack->position);
|
etrack->position);
|
||||||
if (index->offset != 0) {
|
if (index->initialized && index->offset != 0) {
|
||||||
keyframe = index->keyframe;
|
keyframe = index->keyframe;
|
||||||
|
|
||||||
if (keyframe)
|
if (outbuf) {
|
||||||
GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
if (keyframe)
|
||||||
else
|
GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
else
|
||||||
|
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (index->initialized && index->pts != G_MAXUINT64)
|
||||||
|
pts = index->pts;
|
||||||
|
if (index->initialized && index->dts != G_MAXUINT64)
|
||||||
|
dts = index->dts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1776,6 +1791,9 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
GstMXFDemuxIndex index;
|
GstMXFDemuxIndex index;
|
||||||
|
|
||||||
index.offset = demux->offset - demux->run_in;
|
index.offset = demux->offset - demux->run_in;
|
||||||
|
index.initialized = TRUE;
|
||||||
|
index.pts = pts;
|
||||||
|
index.dts = dts;
|
||||||
index.keyframe = keyframe;
|
index.keyframe = keyframe;
|
||||||
if (etrack->offsets->len < etrack->position)
|
if (etrack->offsets->len < etrack->position)
|
||||||
g_array_set_size (etrack->offsets, etrack->position);
|
g_array_set_size (etrack->offsets, etrack->position);
|
||||||
|
@ -1826,7 +1844,15 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
||||||
gst_buffer_get_size (inbuf));
|
gst_buffer_get_size (inbuf));
|
||||||
|
|
||||||
GST_BUFFER_DTS (outbuf) = pad->position;
|
GST_BUFFER_DTS (outbuf) = pad->position;
|
||||||
GST_BUFFER_PTS (outbuf) = pad->position;
|
if (pts != G_MAXUINT64)
|
||||||
|
GST_BUFFER_PTS (outbuf) = gst_util_uint64_scale (pts * GST_SECOND,
|
||||||
|
pad->current_essence_track->source_track->edit_rate.d,
|
||||||
|
pad->current_essence_track->source_track->edit_rate.n);
|
||||||
|
else if (etrack->intra_only)
|
||||||
|
GST_BUFFER_PTS (outbuf) = pad->position;
|
||||||
|
else
|
||||||
|
GST_BUFFER_PTS (outbuf) = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
GST_BUFFER_DURATION (outbuf) =
|
GST_BUFFER_DURATION (outbuf) =
|
||||||
gst_util_uint64_scale (GST_SECOND,
|
gst_util_uint64_scale (GST_SECOND,
|
||||||
pad->current_essence_track->source_track->edit_rate.d,
|
pad->current_essence_track->source_track->edit_rate.d,
|
||||||
|
@ -3575,8 +3601,6 @@ collect_index_table_segments (GstMXFDemux * demux)
|
||||||
|
|
||||||
for (i = 0; i < segment->n_index_entries && start + i < t->offsets->len;
|
for (i = 0; i < segment->n_index_entries && start + i < t->offsets->len;
|
||||||
i++) {
|
i++) {
|
||||||
GstMXFDemuxIndex *index =
|
|
||||||
&g_array_index (t->offsets, GstMXFDemuxIndex, start + i);
|
|
||||||
guint64 offset = segment->index_entries[i].stream_offset;
|
guint64 offset = segment->index_entries[i].stream_offset;
|
||||||
GList *m;
|
GList *m;
|
||||||
GstMXFDemuxPartition *offset_partition = NULL, *next_partition = NULL;
|
GstMXFDemuxPartition *offset_partition = NULL, *next_partition = NULL;
|
||||||
|
@ -3596,8 +3620,7 @@ collect_index_table_segments (GstMXFDemux * demux)
|
||||||
next_partition = NULL;
|
next_partition = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset_partition && offset >= offset_partition->partition.body_offset
|
if (offset_partition && offset >= offset_partition->partition.body_offset) {
|
||||||
&& (offset - offset_partition->partition.body_offset)) {
|
|
||||||
offset =
|
offset =
|
||||||
offset_partition->partition.this_partition +
|
offset_partition->partition.this_partition +
|
||||||
offset_partition->essence_container_offset + (offset -
|
offset_partition->essence_container_offset + (offset -
|
||||||
|
@ -3608,9 +3631,42 @@ collect_index_table_segments (GstMXFDemux * demux)
|
||||||
GST_ERROR_OBJECT (demux,
|
GST_ERROR_OBJECT (demux,
|
||||||
"Invalid index table segment going into next unrelated partition");
|
"Invalid index table segment going into next unrelated partition");
|
||||||
} else {
|
} else {
|
||||||
|
GstMXFDemuxIndex *index;
|
||||||
|
gint8 temporal_offset = segment->index_entries[i].temporal_offset;
|
||||||
|
guint64 pts_i = G_MAXUINT64;
|
||||||
|
|
||||||
|
if (temporal_offset > 0 ||
|
||||||
|
(temporal_offset < 0 && start + i >= -(gint) temporal_offset)) {
|
||||||
|
pts_i = start + i + temporal_offset;
|
||||||
|
|
||||||
|
if (t->offsets->len < pts_i)
|
||||||
|
g_array_set_size (t->offsets, pts_i);
|
||||||
|
|
||||||
|
index = &g_array_index (t->offsets, GstMXFDemuxIndex, pts_i);
|
||||||
|
if (!index->initialized) {
|
||||||
|
index->initialized = TRUE;
|
||||||
|
index->offset = 0;
|
||||||
|
index->pts = G_MAXUINT64;
|
||||||
|
index->dts = G_MAXUINT64;
|
||||||
|
index->keyframe = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
index->pts = start + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = &g_array_index (t->offsets, GstMXFDemuxIndex, start + i);
|
||||||
|
if (!index->initialized) {
|
||||||
|
index->initialized = TRUE;
|
||||||
|
index->offset = 0;
|
||||||
|
index->pts = G_MAXUINT64;
|
||||||
|
index->dts = G_MAXUINT64;
|
||||||
|
index->keyframe = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
index->offset = offset;
|
index->offset = offset;
|
||||||
index->keyframe = ! !(segment->index_entries[i].flags & 0x80)
|
index->keyframe = ! !(segment->index_entries[i].flags & 0x80)
|
||||||
|| (segment->index_entries[i].key_frame_offset == 0);
|
|| (segment->index_entries[i].key_frame_offset == 0);
|
||||||
|
index->dts = pts_i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,12 +56,6 @@ typedef struct
|
||||||
guint64 essence_container_offset;
|
guint64 essence_container_offset;
|
||||||
} GstMXFDemuxPartition;
|
} GstMXFDemuxPartition;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guint64 offset;
|
|
||||||
gboolean keyframe;
|
|
||||||
} GstMXFDemuxIndex;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint32 body_sid;
|
guint32 body_sid;
|
||||||
|
@ -86,12 +80,30 @@ typedef struct
|
||||||
GstTagList *tags;
|
GstTagList *tags;
|
||||||
|
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
gboolean intra_only;
|
||||||
} GstMXFDemuxEssenceTrack;
|
} GstMXFDemuxEssenceTrack;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* 0 if uninitialized */
|
||||||
|
guint64 offset;
|
||||||
|
|
||||||
|
/* PTS edit unit number or G_MAXUINT64 */
|
||||||
|
guint64 pts;
|
||||||
|
|
||||||
|
/* DTS edit unit number if we got here via PTS */
|
||||||
|
guint64 dts;
|
||||||
|
|
||||||
|
gboolean keyframe;
|
||||||
|
gboolean initialized;
|
||||||
|
} GstMXFDemuxIndex;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
guint32 body_sid;
|
guint32 body_sid;
|
||||||
guint32 index_sid;
|
guint32 index_sid;
|
||||||
|
|
||||||
|
/* offsets indexed by DTS */
|
||||||
GArray *offsets;
|
GArray *offsets;
|
||||||
} GstMXFDemuxIndexTable;
|
} GstMXFDemuxIndexTable;
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,8 @@ mxf_dv_dif_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_dv_dif_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_dv_dif_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -181,6 +182,8 @@ mxf_dv_dif_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
|
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, "DV-DIF", NULL);
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_CODEC, "DV-DIF", NULL);
|
||||||
|
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffe
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gboolean (*handles_track) (const MXFMetadataTimelineTrack *track);
|
gboolean (*handles_track) (const MXFMetadataTimelineTrack *track);
|
||||||
MXFEssenceWrapping (*get_track_wrapping) (const MXFMetadataTimelineTrack *track);
|
MXFEssenceWrapping (*get_track_wrapping) (const MXFMetadataTimelineTrack *track);
|
||||||
GstCaps * (*create_caps) (MXFMetadataTimelineTrack *track, GstTagList **tags, MXFEssenceElementHandleFunc *handler, gpointer *mapping_data);
|
GstCaps * (*create_caps) (MXFMetadataTimelineTrack *track, GstTagList **tags, gboolean * intra_only, MXFEssenceElementHandleFunc *handler, gpointer *mapping_data);
|
||||||
} MXFEssenceElementHandler;
|
} MXFEssenceElementHandler;
|
||||||
|
|
||||||
typedef GstFlowReturn (*MXFEssenceElementWriteFunc) (GstBuffer *buffer, gpointer mapping_data, GstAdapter *adapter, GstBuffer **outbuf, gboolean flush);
|
typedef GstFlowReturn (*MXFEssenceElementWriteFunc) (GstBuffer *buffer, gpointer mapping_data, GstAdapter *adapter, GstBuffer **outbuf, gboolean flush);
|
||||||
|
|
|
@ -126,7 +126,8 @@ mxf_jpeg2000_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataFileDescriptor *f = NULL;
|
MXFMetadataFileDescriptor *f = NULL;
|
||||||
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
||||||
|
@ -234,6 +235,8 @@ mxf_jpeg2000_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"JPEG 2000", NULL);
|
"JPEG 2000", NULL);
|
||||||
|
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -627,8 +627,8 @@ static const MXFUL sound_essence_compression_aac = { {
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data,
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
MXFMetadataGenericPictureEssenceDescriptor * p,
|
gpointer * mapping_data, MXFMetadataGenericPictureEssenceDescriptor * p,
|
||||||
MXFMetadataGenericSoundEssenceDescriptor * s)
|
MXFMetadataGenericSoundEssenceDescriptor * s)
|
||||||
{
|
{
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
|
@ -648,6 +648,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
codec_name = "MPEG-2 Video";
|
codec_name = "MPEG-2 Video";
|
||||||
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
||||||
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if (p->picture_essence_coding.u[0] != 0x06
|
} else if (p->picture_essence_coding.u[0] != 0x06
|
||||||
|| p->picture_essence_coding.u[1] != 0x0e
|
|| p->picture_essence_coding.u[1] != 0x0e
|
||||||
|| p->picture_essence_coding.u[2] != 0x2b
|
|| p->picture_essence_coding.u[2] != 0x2b
|
||||||
|
@ -669,12 +670,14 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
codec_name = "MPEG-2 Video";
|
codec_name = "MPEG-2 Video";
|
||||||
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
||||||
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if (p->picture_essence_coding.u[13] == 0x10) {
|
} else if (p->picture_essence_coding.u[13] == 0x10) {
|
||||||
caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 1,
|
caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 1,
|
||||||
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
|
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||||
codec_name = "MPEG-1 Video";
|
codec_name = "MPEG-1 Video";
|
||||||
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG2;
|
||||||
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
||||||
|
*intra_only = TRUE;
|
||||||
} else if (p->picture_essence_coding.u[13] == 0x20) {
|
} else if (p->picture_essence_coding.u[13] == 0x20) {
|
||||||
MXFLocalTag *local_tag =
|
MXFLocalTag *local_tag =
|
||||||
(((MXFMetadataBase *) p)->other_tags) ?
|
(((MXFMetadataBase *) p)->other_tags) ?
|
||||||
|
@ -698,6 +701,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
codec_name = "MPEG-4 Video";
|
codec_name = "MPEG-4 Video";
|
||||||
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG4;
|
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_MPEG4;
|
||||||
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if ((p->picture_essence_coding.u[13] >> 4) == 0x03) {
|
} else if ((p->picture_essence_coding.u[13] >> 4) == 0x03) {
|
||||||
/* RP 2008 */
|
/* RP 2008 */
|
||||||
|
|
||||||
|
@ -707,6 +711,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
codec_name = "h.264 Video";
|
codec_name = "h.264 Video";
|
||||||
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_AVC;
|
t = MXF_MPEG_ESSENCE_TYPE_VIDEO_AVC;
|
||||||
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
memcpy (mdata, &t, sizeof (MXFMPEGEssenceType));
|
||||||
|
*intra_only = FALSE;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR ("Unsupported MPEG picture essence coding 0x%02x",
|
GST_ERROR ("Unsupported MPEG picture essence coding 0x%02x",
|
||||||
p->picture_essence_coding.u[13]);
|
p->picture_essence_coding.u[13]);
|
||||||
|
@ -764,6 +769,7 @@ mxf_mpeg_es_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
mxf_metadata_generic_sound_essence_descriptor_set_caps (s, caps);
|
mxf_metadata_generic_sound_essence_descriptor_set_caps (s, caps);
|
||||||
*handler = mxf_mpeg_audio_handle_essence_element;
|
*handler = mxf_mpeg_audio_handle_essence_element;
|
||||||
}
|
}
|
||||||
|
*intra_only = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (caps) {
|
if (caps) {
|
||||||
|
@ -823,7 +829,8 @@ mxf_mpeg_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataFileDescriptor *f = NULL;
|
MXFMetadataFileDescriptor *f = NULL;
|
||||||
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
||||||
|
@ -866,7 +873,9 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
if (f->essence_container.u[13] == 0x04) {
|
if (f->essence_container.u[13] == 0x04) {
|
||||||
GST_DEBUG ("Found MPEG ES stream");
|
GST_DEBUG ("Found MPEG ES stream");
|
||||||
|
|
||||||
caps = mxf_mpeg_es_create_caps (track, tags, handler, mapping_data, p, s);
|
caps =
|
||||||
|
mxf_mpeg_es_create_caps (track, tags, intra_only, handler, mapping_data,
|
||||||
|
p, s);
|
||||||
} else if (f->essence_container.u[13] == 0x07) {
|
} else if (f->essence_container.u[13] == 0x07) {
|
||||||
GST_ERROR ("MPEG PES streams not supported yet");
|
GST_ERROR ("MPEG PES streams not supported yet");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -880,6 +889,7 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*tags = gst_tag_list_new_empty ();
|
*tags = gst_tag_list_new_empty ();
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"MPEG PS", NULL);
|
"MPEG PS", NULL);
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if (f->essence_container.u[13] == 0x09) {
|
} else if (f->essence_container.u[13] == 0x09) {
|
||||||
GST_DEBUG ("Found MPEG TS stream");
|
GST_DEBUG ("Found MPEG TS stream");
|
||||||
caps = gst_caps_new_empty_simple ("video/mpegts");
|
caps = gst_caps_new_empty_simple ("video/mpegts");
|
||||||
|
@ -888,6 +898,7 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*tags = gst_tag_list_new_empty ();
|
*tags = gst_tag_list_new_empty ();
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"MPEG TS", NULL);
|
"MPEG TS", NULL);
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if (f->essence_container.u[13] == 0x0f) {
|
} else if (f->essence_container.u[13] == 0x0f) {
|
||||||
GST_DEBUG ("Found h264 NAL unit stream");
|
GST_DEBUG ("Found h264 NAL unit stream");
|
||||||
/* RP 2008 */
|
/* RP 2008 */
|
||||||
|
@ -899,6 +910,7 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*tags = gst_tag_list_new_empty ();
|
*tags = gst_tag_list_new_empty ();
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"h.264 Video", NULL);
|
"h.264 Video", NULL);
|
||||||
|
*intra_only = FALSE;
|
||||||
} else if (f->essence_container.u[13] == 0x10) {
|
} else if (f->essence_container.u[13] == 0x10) {
|
||||||
GST_DEBUG ("Found h264 byte-stream stream");
|
GST_DEBUG ("Found h264 byte-stream stream");
|
||||||
/* RP 2008 */
|
/* RP 2008 */
|
||||||
|
@ -910,6 +922,7 @@ mxf_mpeg_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*tags = gst_tag_list_new_empty ();
|
*tags = gst_tag_list_new_empty ();
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"h.264 Video", NULL);
|
"h.264 Video", NULL);
|
||||||
|
*intra_only = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p && caps)
|
if (p && caps)
|
||||||
|
|
|
@ -240,7 +240,8 @@ mxf_up_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
|
mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
MXFMetadataRGBAPictureEssenceDescriptor * d, GstTagList ** tags,
|
MXFMetadataRGBAPictureEssenceDescriptor * d, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -280,6 +281,7 @@ mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
|
((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
|
||||||
|
|
||||||
*mapping_data = data;
|
*mapping_data = data;
|
||||||
|
*intra_only = TRUE;
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING ("Unsupported pixel layout");
|
GST_WARNING ("Unsupported pixel layout");
|
||||||
}
|
}
|
||||||
|
@ -290,7 +292,8 @@ mxf_up_rgba_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
|
mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
MXFMetadataCDCIPictureEssenceDescriptor * d, GstTagList ** tags,
|
MXFMetadataCDCIPictureEssenceDescriptor * d, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
@ -326,6 +329,7 @@ mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
|
((MXFMetadataGenericPictureEssenceDescriptor *) d)->image_end_offset;
|
||||||
|
|
||||||
*mapping_data = data;
|
*mapping_data = data;
|
||||||
|
*intra_only = TRUE;
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING ("Unsupported CDCI format");
|
GST_WARNING ("Unsupported CDCI format");
|
||||||
}
|
}
|
||||||
|
@ -335,7 +339,8 @@ mxf_up_cdci_create_caps (MXFMetadataTimelineTrack * track,
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
||||||
MXFMetadataCDCIPictureEssenceDescriptor *c = NULL;
|
MXFMetadataCDCIPictureEssenceDescriptor *c = NULL;
|
||||||
|
@ -378,9 +383,13 @@ mxf_up_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*handler = mxf_up_handle_essence_element;
|
*handler = mxf_up_handle_essence_element;
|
||||||
|
|
||||||
if (r) {
|
if (r) {
|
||||||
caps = mxf_up_rgba_create_caps (track, r, tags, handler, mapping_data);
|
caps =
|
||||||
|
mxf_up_rgba_create_caps (track, r, tags, intra_only, handler,
|
||||||
|
mapping_data);
|
||||||
} else if (c) {
|
} else if (c) {
|
||||||
caps = mxf_up_cdci_create_caps (track, c, tags, handler, mapping_data);
|
caps =
|
||||||
|
mxf_up_cdci_create_caps (track, c, tags, intra_only, handler,
|
||||||
|
mapping_data);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,8 @@ mxf_vc3_get_track_wrapping (const MXFMetadataTimelineTrack * track)
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
MXFEssenceElementHandleFunc * handler, gpointer * mapping_data)
|
gboolean * intra_only, MXFEssenceElementHandleFunc * handler,
|
||||||
|
gpointer * mapping_data)
|
||||||
{
|
{
|
||||||
MXFMetadataFileDescriptor *f = NULL;
|
MXFMetadataFileDescriptor *f = NULL;
|
||||||
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
MXFMetadataGenericPictureEssenceDescriptor *p = NULL;
|
||||||
|
@ -186,6 +187,7 @@ mxf_vc3_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
||||||
*tags = gst_tag_list_new_empty ();
|
*tags = gst_tag_list_new_empty ();
|
||||||
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
gst_tag_list_add (*tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
|
||||||
"VC-3 Video", NULL);
|
"VC-3 Video", NULL);
|
||||||
|
*intra_only = TRUE;
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue