mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
Generate an index table for essence streams
Generate an index table for essence streams during playback and make sure that only the correct essence elements are used for played tracks. Make it possible to have one essence stream used in multiple playback tracks. Fix some minor bugs.
This commit is contained in:
parent
dc42074fa9
commit
91b35975b5
11 changed files with 266 additions and 177 deletions
|
@ -576,8 +576,7 @@ static GstFlowReturn
|
|||
mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -595,8 +594,7 @@ mxf_bwf_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
|||
static GstFlowReturn
|
||||
mxf_aes3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps, MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -816,24 +814,24 @@ mxf_aes_bwf_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
|||
if (!track->parent.descriptor[i])
|
||||
continue;
|
||||
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
|
||||
descriptor[i])
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
|
||||
parent.descriptor[i])
|
||||
&& (track->parent.descriptor[i]->essence_container.u[14] == 0x01
|
||||
|| track->parent.descriptor[i]->essence_container.u[14] == 0x02
|
||||
|| track->parent.descriptor[i]->essence_container.u[14] == 0x08)) {
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
|
||||
descriptor[i];
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
|
||||
parent.descriptor[i];
|
||||
bwf = TRUE;
|
||||
break;
|
||||
} else
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
|
||||
descriptor[i])
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
|
||||
parent.descriptor[i])
|
||||
&& (track->parent.descriptor[i]->essence_container.u[14] == 0x03
|
||||
|| track->parent.descriptor[i]->essence_container.u[14] == 0x04
|
||||
|| track->parent.descriptor[i]->essence_container.u[14] == 0x09)) {
|
||||
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
|
||||
descriptor[i];
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
|
||||
parent.descriptor[i];
|
||||
bwf = FALSE;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,7 @@ static GstFlowReturn
|
|||
mxf_alaw_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -100,10 +99,10 @@ mxf_alaw_create_caps (MXFMetadataTimelineTrack * track, GstTagList ** tags,
|
|||
if (!track->parent.descriptor[i])
|
||||
continue;
|
||||
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
|
||||
parent.descriptor[i])) {
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
|
||||
parent.descriptor[i];
|
||||
if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
|
||||
descriptor[i])) {
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
|
||||
descriptor[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,7 @@ static GstFlowReturn
|
|||
mxf_d10_picture_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -89,8 +88,7 @@ static GstFlowReturn
|
|||
mxf_d10_sound_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
guint i, j, nsamples;
|
||||
const guint8 *indata;
|
||||
|
@ -173,15 +171,15 @@ mxf_d10_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];
|
||||
break;
|
||||
} else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->
|
||||
parent.descriptor[i])) {
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->parent.
|
||||
descriptor[i];
|
||||
} else if (MXF_IS_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (track->parent.
|
||||
descriptor[i])) {
|
||||
s = (MXFMetadataGenericSoundEssenceDescriptor *) track->
|
||||
parent.descriptor[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,7 +188,9 @@ gst_mxf_demux_reset_mxf_state (GstMXFDemux * demux)
|
|||
GstMXFDemuxEssenceTrack *t =
|
||||
&g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
|
||||
|
||||
g_free (t->offsets);
|
||||
if (t->offsets)
|
||||
g_array_free (t->offsets, TRUE);
|
||||
|
||||
g_free (t->mapping_data);
|
||||
|
||||
if (t->tags)
|
||||
|
@ -384,6 +386,13 @@ gst_mxf_demux_push_src_event (GstMXFDemux * demux, GstEvent * event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_mxf_demux_partition_compare (GstMXFDemuxPartition * a,
|
||||
GstMXFDemuxPartition * b)
|
||||
{
|
||||
return (a->partition.this_partition - b->partition.this_partition);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
|
||||
GstBuffer * buffer)
|
||||
|
@ -402,6 +411,7 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||
if (tmp->partition.this_partition + demux->run_in == demux->offset &&
|
||||
tmp->partition.major_version == 0x0001) {
|
||||
GST_DEBUG_OBJECT (demux, "Partition already parsed");
|
||||
p = tmp;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +446,21 @@ gst_mxf_demux_handle_partition_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||
} else {
|
||||
p = g_new0 (GstMXFDemuxPartition, 1);
|
||||
memcpy (&p->partition, &partition, sizeof (MXFPartitionPack));
|
||||
demux->partitions = g_list_prepend (demux->partitions, p);
|
||||
demux->partitions =
|
||||
g_list_insert_sorted (demux->partitions, p,
|
||||
(GCompareFunc) gst_mxf_demux_partition_compare);
|
||||
}
|
||||
|
||||
for (l = demux->partitions; l; l = l->next) {
|
||||
GstMXFDemuxPartition *a, *b;
|
||||
|
||||
if (l->next == NULL);
|
||||
break;
|
||||
|
||||
a = l->data;
|
||||
b = l->next->data;
|
||||
|
||||
b->partition.prev_partition = a->partition.this_partition;
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -692,22 +716,9 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux)
|
|||
goto next;
|
||||
}
|
||||
|
||||
if (track->parent.sequence->duration > etrack->duration) {
|
||||
guint64 old_duration = etrack->duration;
|
||||
|
||||
if (track->parent.sequence->duration > etrack->duration)
|
||||
etrack->duration = track->parent.sequence->duration;
|
||||
|
||||
if (etrack->offsets) {
|
||||
etrack->offsets =
|
||||
g_realloc (etrack->offsets,
|
||||
etrack->duration * sizeof (GstMXFDemuxIndex));
|
||||
memset (&etrack->offsets[old_duration - 1], 0,
|
||||
etrack->duration - old_duration);
|
||||
} else {
|
||||
etrack->offsets = g_new0 (GstMXFDemuxIndex, etrack->duration);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (etrack->mapping_data);
|
||||
etrack->mapping_data = NULL;
|
||||
etrack->handler = NULL;
|
||||
|
@ -740,7 +751,12 @@ gst_mxf_demux_update_essence_tracks (GstMXFDemux * demux)
|
|||
} else if (!caps) {
|
||||
GST_WARNING_OBJECT (demux, "Couldn't create updated caps for stream");
|
||||
} else if (!etrack->caps || !gst_caps_is_equal (etrack->caps, caps)) {
|
||||
gst_caps_replace (&etrack->caps, caps);
|
||||
if (etrack->caps)
|
||||
gst_caps_unref (etrack->caps);
|
||||
etrack->caps = caps;
|
||||
} else {
|
||||
gst_caps_unref (caps);
|
||||
caps = NULL;
|
||||
}
|
||||
|
||||
etrack->source_package = package;
|
||||
|
@ -975,7 +991,6 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
|||
/* If we just added the pad initialize for the current component */
|
||||
if (first_run && MXF_IS_METADATA_MATERIAL_PACKAGE (current_package)) {
|
||||
pad->current_component_index = 0;
|
||||
pad->current_component_position = 0;
|
||||
pad->current_component_start = source_track->origin;
|
||||
if (track->edit_rate.n != source_track->edit_rate.n ||
|
||||
track->edit_rate.n != source_track->edit_rate.n) {
|
||||
|
@ -987,6 +1002,7 @@ gst_mxf_demux_update_tracks (GstMXFDemux * demux)
|
|||
} else {
|
||||
pad->current_component_start += component->start_position;
|
||||
}
|
||||
pad->current_component_position = pad->current_component_start;
|
||||
}
|
||||
|
||||
/* NULL iff playing a source package */
|
||||
|
@ -1212,6 +1228,11 @@ gst_mxf_demux_handle_generic_container_system_item (GstMXFDemux * demux,
|
|||
"Handling generic container system item of size %u"
|
||||
" at offset %" G_GUINT64_FORMAT, GST_BUFFER_SIZE (buffer), demux->offset);
|
||||
|
||||
if (demux->current_partition->essence_container_offset == 0)
|
||||
demux->current_partition->essence_container_offset =
|
||||
demux->offset - demux->current_partition->partition.this_partition -
|
||||
demux->run_in;
|
||||
|
||||
/* TODO: parse this */
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
@ -1301,7 +1322,6 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
|
|||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
pad->current_component_position = 0;
|
||||
pad->current_component_start = source_track->origin;
|
||||
if (pad->material_track->edit_rate.n != source_track->edit_rate.n ||
|
||||
pad->material_track->edit_rate.n != source_track->edit_rate.n) {
|
||||
|
@ -1313,6 +1333,7 @@ gst_mxf_demux_pad_next_component (GstMXFDemux * demux, GstMXFDemuxPad * pad)
|
|||
} else {
|
||||
pad->current_component_start += pad->current_component->start_position;
|
||||
}
|
||||
pad->current_component_position = pad->current_component_start;
|
||||
|
||||
|
||||
if (!gst_caps_is_equal (GST_PAD_CAPS (pad), pad->current_essence_track->caps)) {
|
||||
|
@ -1331,7 +1352,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
guint i;
|
||||
GstBuffer *inbuf;
|
||||
GstBuffer *outbuf = NULL;
|
||||
GstMXFDemuxPad *pad = NULL;
|
||||
GstMXFDemuxEssenceTrack *etrack = NULL;
|
||||
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
|
@ -1343,6 +1363,12 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
GST_DEBUG_OBJECT (demux, " essence element type = 0x%02x", key->u[14]);
|
||||
GST_DEBUG_OBJECT (demux, " essence element number = 0x%02x", key->u[15]);
|
||||
|
||||
if (demux->current_partition->essence_container_offset == 0)
|
||||
demux->current_partition->essence_container_offset =
|
||||
demux->offset - demux->current_partition->partition.this_partition -
|
||||
demux->run_in;
|
||||
|
||||
|
||||
if (!demux->current_package) {
|
||||
GST_ERROR_OBJECT (demux, "No package selected yet");
|
||||
return GST_FLOW_ERROR;
|
||||
|
@ -1358,11 +1384,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
if (GST_BUFFER_SIZE (buffer) == 0) {
|
||||
GST_DEBUG_OBJECT (demux, "Zero sized essence element, ignoring");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
track_number = GST_READ_UINT32_BE (&key->u[12]);
|
||||
|
||||
for (i = 0; i < demux->essence_tracks->len; i++) {
|
||||
|
@ -1382,51 +1403,44 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
/* TODO update essence tracks offsets, position, etc... */
|
||||
if (etrack->position == -1) {
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Unknown essence track position, looking into index");
|
||||
if (etrack->offsets) {
|
||||
for (i = 0; i < etrack->offsets->len; i++) {
|
||||
GstMXFDemuxIndex *idx =
|
||||
&g_array_index (etrack->offsets, GstMXFDemuxIndex, i);
|
||||
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMXFDemuxPad *tmp = g_ptr_array_index (demux->src, i);
|
||||
|
||||
if (tmp->current_essence_track == etrack) {
|
||||
pad = tmp;
|
||||
break;
|
||||
if (idx->offset != 0 && idx->offset == demux->offset - demux->run_in) {
|
||||
etrack->position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pad) {
|
||||
GST_DEBUG_OBJECT (demux, "No pad for essence track found");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
if (pad->eos) {
|
||||
GST_DEBUG_OBJECT (demux, "Pad is already EOS");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
if (pad->current_component &&
|
||||
pad->current_component_position < pad->current_component_start) {
|
||||
GST_DEBUG_OBJECT (demux, "Before current component's start position");
|
||||
pad->current_component_position++;
|
||||
return GST_FLOW_OK;
|
||||
if (etrack->position == -1) {
|
||||
GST_WARNING_OBJECT (demux, "Essence track position not in index");
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create subbuffer to be able to change metadata */
|
||||
inbuf = gst_buffer_create_sub (buffer, 0, GST_BUFFER_SIZE (buffer));
|
||||
|
||||
GST_BUFFER_TIMESTAMP (inbuf) = pad->last_stop;
|
||||
GST_BUFFER_DURATION (inbuf) =
|
||||
gst_util_uint64_scale (GST_SECOND, pad->material_track->edit_rate.d,
|
||||
pad->material_track->edit_rate.n);
|
||||
GST_BUFFER_OFFSET (inbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (inbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
gst_buffer_set_caps (inbuf, etrack->caps);
|
||||
if (etrack->offsets && etrack->offsets->len > etrack->position) {
|
||||
if (!g_array_index (etrack->offsets, GstMXFDemuxIndex,
|
||||
etrack->position).keyframe)
|
||||
GST_BUFFER_FLAG_SET (inbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
}
|
||||
|
||||
if (etrack->duration <= etrack->position)
|
||||
etrack->duration = etrack->position + 1;
|
||||
|
||||
if (etrack->handle_func) {
|
||||
/* Takes ownership of inbuf */
|
||||
ret =
|
||||
etrack->handle_func (key, inbuf, etrack->caps,
|
||||
etrack->source_track, pad->current_component, etrack->mapping_data,
|
||||
&outbuf);
|
||||
etrack->source_track, etrack->mapping_data, &outbuf);
|
||||
inbuf = NULL;
|
||||
} else {
|
||||
outbuf = inbuf;
|
||||
|
@ -1440,25 +1454,87 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
gst_buffer_unref (outbuf);
|
||||
outbuf = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pad->need_segment) {
|
||||
gst_pad_push_event (GST_PAD_CAST (pad),
|
||||
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
|
||||
pad->need_segment = FALSE;
|
||||
if (!etrack->offsets)
|
||||
etrack->offsets = g_array_new (FALSE, TRUE, sizeof (GstMXFDemuxIndex));
|
||||
|
||||
{
|
||||
if (etrack->offsets->len > etrack->position) {
|
||||
GstMXFDemuxIndex *index =
|
||||
&g_array_index (etrack->offsets, GstMXFDemuxIndex, etrack->position);
|
||||
|
||||
index->offset = demux->offset - demux->run_in;
|
||||
index->keyframe =
|
||||
(outbuf) ? !GST_BUFFER_FLAG_IS_SET (outbuf,
|
||||
GST_BUFFER_FLAG_DELTA_UNIT) : TRUE;
|
||||
} else {
|
||||
GstMXFDemuxIndex index;
|
||||
|
||||
index.offset = demux->offset - demux->run_in;
|
||||
index.keyframe =
|
||||
(outbuf) ? !GST_BUFFER_FLAG_IS_SET (outbuf,
|
||||
GST_BUFFER_FLAG_DELTA_UNIT) : TRUE;
|
||||
g_array_insert_val (etrack->offsets, etrack->position, index);
|
||||
}
|
||||
}
|
||||
|
||||
if (pad->tags) {
|
||||
gst_element_found_tags_for_pad (GST_ELEMENT_CAST (demux),
|
||||
GST_PAD_CAST (pad), pad->tags);
|
||||
pad->tags = NULL;
|
||||
if (!outbuf) {
|
||||
GST_DEBUG_OBJECT (demux, "No output buffer created");
|
||||
goto out;
|
||||
}
|
||||
|
||||
inbuf = outbuf;
|
||||
outbuf = NULL;
|
||||
|
||||
gst_buffer_set_caps (inbuf, etrack->caps);
|
||||
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
|
||||
|
||||
if (pad->current_essence_track != etrack)
|
||||
continue;
|
||||
|
||||
if (pad->eos) {
|
||||
GST_DEBUG_OBJECT (demux, "Pad is already EOS");
|
||||
continue;
|
||||
}
|
||||
if (pad->current_component &&
|
||||
etrack->position < pad->current_component_position) {
|
||||
GST_DEBUG_OBJECT (demux, "Before current component's position");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create another subbuffer to have writable metadata */
|
||||
outbuf = gst_buffer_create_sub (inbuf, 0, GST_BUFFER_SIZE (inbuf));
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = pad->last_stop;
|
||||
/* FIXME: What about tracks with source track edit rate != material
|
||||
* track edit rate? Use one of them and set the relative rate
|
||||
* to the other one as "rate" for the segment?
|
||||
*/
|
||||
GST_BUFFER_DURATION (outbuf) =
|
||||
gst_util_uint64_scale (GST_SECOND, pad->material_track->edit_rate.d,
|
||||
pad->material_track->edit_rate.n);
|
||||
GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
|
||||
|
||||
if (pad->need_segment) {
|
||||
gst_pad_push_event (GST_PAD_CAST (pad),
|
||||
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
|
||||
GST_BUFFER_TIMESTAMP (outbuf)));
|
||||
pad->need_segment = FALSE;
|
||||
}
|
||||
|
||||
if (pad->tags) {
|
||||
gst_element_found_tags_for_pad (GST_ELEMENT_CAST (demux),
|
||||
GST_PAD_CAST (pad), pad->tags);
|
||||
pad->tags = NULL;
|
||||
}
|
||||
|
||||
if (outbuf)
|
||||
pad->last_stop += GST_BUFFER_DURATION (outbuf);
|
||||
|
||||
if (outbuf) {
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Pushing buffer of size %u for track %u: timestamp %" GST_TIME_FORMAT
|
||||
" duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (outbuf),
|
||||
|
@ -1473,48 +1549,52 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
|
|||
|
||||
ret = gst_pad_push (GST_PAD_CAST (pad), outbuf);
|
||||
ret = gst_mxf_demux_combine_flows (demux, pad, ret);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (demux, "Dropping buffer for track %u",
|
||||
pad->material_track->parent.track_id);
|
||||
}
|
||||
|
||||
if (ret != GST_FLOW_OK)
|
||||
return ret;
|
||||
if (ret != GST_FLOW_OK)
|
||||
break;
|
||||
|
||||
if (pad->current_component) {
|
||||
pad->current_component_position++;
|
||||
if (pad->current_component->parent.duration != -1 &&
|
||||
pad->current_component_position - pad->current_component_start
|
||||
>= pad->current_component->parent.duration) {
|
||||
GST_DEBUG_OBJECT (demux, "Switching to next component");
|
||||
if (pad->current_component) {
|
||||
pad->current_component_position++;
|
||||
if (pad->current_component->parent.duration != -1 &&
|
||||
pad->current_component_position - pad->current_component_start
|
||||
>= pad->current_component->parent.duration) {
|
||||
GST_DEBUG_OBJECT (demux, "Switching to next component");
|
||||
|
||||
if ((ret = gst_mxf_demux_pad_next_component (demux, pad)) != GST_FLOW_OK) {
|
||||
if (ret == GST_FLOW_UNEXPECTED) {
|
||||
gboolean eos = TRUE;
|
||||
if ((ret =
|
||||
gst_mxf_demux_pad_next_component (demux, pad)) != GST_FLOW_OK) {
|
||||
if (ret == GST_FLOW_UNEXPECTED) {
|
||||
gboolean eos = TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "EOS for track");
|
||||
pad->eos = TRUE;
|
||||
GST_DEBUG_OBJECT (demux, "EOS for track");
|
||||
pad->eos = TRUE;
|
||||
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, i);
|
||||
for (i = 0; i < demux->src->len; i++) {
|
||||
GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, i);
|
||||
|
||||
eos &= opad->eos;
|
||||
}
|
||||
eos &= opad->eos;
|
||||
}
|
||||
|
||||
if (eos) {
|
||||
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
if (eos) {
|
||||
GST_DEBUG_OBJECT (demux, "All tracks are EOS");
|
||||
ret = GST_FLOW_UNEXPECTED;
|
||||
break;
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
} else {
|
||||
return GST_FLOW_OK;
|
||||
GST_ERROR_OBJECT (demux, "Switching component failed");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
GST_ERROR_OBJECT (demux, "Switching component failed");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
gst_buffer_unref (inbuf);
|
||||
|
||||
etrack->position++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1523,6 +1603,7 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||
GstBuffer * buffer)
|
||||
{
|
||||
guint i;
|
||||
GList *l;
|
||||
|
||||
GST_DEBUG_OBJECT (demux,
|
||||
"Handling random index pack of size %u at offset %"
|
||||
|
@ -1540,7 +1621,6 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||
}
|
||||
|
||||
for (i = 0; i < demux->random_index_pack->len; i++) {
|
||||
GList *l;
|
||||
GstMXFDemuxPartition *p = NULL;
|
||||
MXFRandomIndexPackEntry *e =
|
||||
&g_array_index (demux->random_index_pack, MXFRandomIndexPackEntry, i);
|
||||
|
@ -1563,10 +1643,24 @@ gst_mxf_demux_handle_random_index_pack (GstMXFDemux * demux, const MXFUL * key,
|
|||
p = g_new0 (GstMXFDemuxPartition, 1);
|
||||
p->partition.this_partition = e->offset - demux->run_in;
|
||||
p->partition.body_sid = e->body_sid;
|
||||
demux->partitions = g_list_prepend (demux->partitions, p);
|
||||
demux->partitions =
|
||||
g_list_insert_sorted (demux->partitions, p,
|
||||
(GCompareFunc) gst_mxf_demux_partition_compare);
|
||||
}
|
||||
}
|
||||
|
||||
for (l = demux->partitions; l; l = l->next) {
|
||||
GstMXFDemuxPartition *a, *b;
|
||||
|
||||
if (l->next == NULL);
|
||||
break;
|
||||
|
||||
a = l->data;
|
||||
b = l->next->data;
|
||||
|
||||
b->partition.prev_partition = a->partition.this_partition;
|
||||
}
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
@ -1884,6 +1978,12 @@ next_try:
|
|||
demux->offset += read;
|
||||
gst_buffer_unref (buffer);
|
||||
buffer = NULL;
|
||||
} else if (mxf_is_generic_container_system_item (&key) ||
|
||||
mxf_is_generic_container_essence_element (&key)) {
|
||||
demux->offset += read;
|
||||
gst_buffer_unref (buffer);
|
||||
buffer = NULL;
|
||||
break;
|
||||
} else {
|
||||
demux->offset += read;
|
||||
gst_buffer_unref (buffer);
|
||||
|
@ -1921,9 +2021,11 @@ gst_mxf_demux_handle_klv_packet (GstMXFDemux * demux, const MXFUL * key,
|
|||
|
||||
if (demux->update_metadata
|
||||
&& demux->preface
|
||||
&& demux->offset >=
|
||||
demux->run_in + demux->current_partition->primer.offset +
|
||||
demux->current_partition->partition.header_byte_count) {
|
||||
&& (demux->offset >=
|
||||
demux->run_in + demux->current_partition->primer.offset +
|
||||
demux->current_partition->partition.header_byte_count ||
|
||||
mxf_is_generic_container_system_item (key) ||
|
||||
mxf_is_generic_container_essence_element (key))) {
|
||||
demux->current_partition->parsed_metadata = TRUE;
|
||||
if ((ret = gst_mxf_demux_resolve_references (demux)) != GST_FLOW_OK)
|
||||
goto beach;
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct
|
|||
MXFPartitionPack partition;
|
||||
MXFPrimerPack primer;
|
||||
gboolean parsed_metadata;
|
||||
guint64 essence_container_offset;
|
||||
} GstMXFDemuxPartition;
|
||||
|
||||
typedef struct
|
||||
|
@ -67,13 +68,10 @@ typedef struct
|
|||
guint32 body_sid;
|
||||
guint32 track_number;
|
||||
|
||||
guint64 position;
|
||||
guint64 duration;
|
||||
gint64 position;
|
||||
gint64 duration;
|
||||
|
||||
GstMXFDemuxIndex *offsets;
|
||||
|
||||
guint64 last_offset;
|
||||
guint64 last_indexed_offset;
|
||||
GArray *offsets;
|
||||
|
||||
MXFMetadataSourcePackage *source_package;
|
||||
MXFMetadataTimelineTrack *source_track;
|
||||
|
|
|
@ -70,8 +70,7 @@ static GstFlowReturn
|
|||
mxf_dv_dif_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
|
|
@ -70,8 +70,7 @@ static GstFlowReturn
|
|||
mxf_jpeg2000_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -106,10 +105,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]) &&
|
||||
|
|
|
@ -256,8 +256,7 @@ mxf_is_mpeg_essence_track (const MXFMetadataTimelineTrack * track)
|
|||
static GstFlowReturn
|
||||
mxf_mpeg_video_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps, MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -274,8 +273,7 @@ mxf_mpeg_video_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
|||
static GstFlowReturn
|
||||
mxf_mpeg_audio_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps, MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -488,17 +486,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "mxftypes.h"
|
||||
#include "mxfmetadata.h"
|
||||
|
||||
typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, MXFMetadataSourceClip *component, gpointer mapping_data, GstBuffer **outbuf);
|
||||
typedef GstFlowReturn (*MXFEssenceElementHandleFunc) (const MXFUL *key, GstBuffer *buffer, GstCaps *caps, MXFMetadataTimelineTrack *track, gpointer mapping_data, GstBuffer **outbuf);
|
||||
|
||||
typedef struct {
|
||||
gboolean (*handles_track) (const MXFMetadataTimelineTrack *track);
|
||||
|
|
|
@ -80,8 +80,7 @@ static GstFlowReturn
|
|||
mxf_up_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
MXFUPMappingData *data = mapping_data;
|
||||
|
||||
|
@ -222,19 +221,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->
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,8 +65,7 @@ static GstFlowReturn
|
|||
mxf_vc3_handle_essence_element (const MXFUL * key, GstBuffer * buffer,
|
||||
GstCaps * caps,
|
||||
MXFMetadataTimelineTrack * track,
|
||||
MXFMetadataSourceClip * component, gpointer mapping_data,
|
||||
GstBuffer ** outbuf)
|
||||
gpointer mapping_data, GstBuffer ** outbuf)
|
||||
{
|
||||
*outbuf = buffer;
|
||||
|
||||
|
@ -100,10 +99,10 @@ mxf_vc3_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]) &&
|
||||
|
|
Loading…
Reference in a new issue