summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2009-03-26 08:11:20 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-03-26 08:11:20 +0100
commit3b88dce4d1bf82e290cbac5a68df2d6fc189b205 (patch)
tree04b65888aa4f7a26d9647e46e2e4becdb9034ddd
parent7146c027fe35beae3bc801e77c8881926dc30000 (diff)
downloadgst-plugins-bad-3b88dce4d1bf82e290cbac5a68df2d6fc189b205.tar.gz
gst-plugins-bad-3b88dce4d1bf82e290cbac5a68df2d6fc189b205.tar.bz2
gst-plugins-bad-3b88dce4d1bf82e290cbac5a68df2d6fc189b205.zip
mxfmux: Fix handling of buffers with more than one edit unit and EOS handling
-rw-r--r--gst/mxf/mxfaes-bwf.c66
-rw-r--r--gst/mxf/mxfalaw.c66
-rw-r--r--gst/mxf/mxfmux.c239
-rw-r--r--gst/mxf/mxfmux.h2
4 files changed, 193 insertions, 180 deletions
diff --git a/gst/mxf/mxfaes-bwf.c b/gst/mxf/mxfaes-bwf.c
index cf61ea7e..df9c0047 100644
--- a/gst/mxf/mxfaes-bwf.c
+++ b/gst/mxf/mxfaes-bwf.c
@@ -1406,28 +1406,34 @@ mxf_bwf_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data,
{
BWFMappingData *md = mapping_data;
guint bytes;
+ guint64 speu =
+ gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
- if (buffer) {
- guint64 speu =
- gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
-
- md->error += (GST_SECOND * md->edit_rate.d * md->rate) % (md->edit_rate.n);
- if (md->error >= md->edit_rate.n) {
- md->error = 0;
- speu += 1;
- }
+ md->error += (md->edit_rate.d * md->rate) % (md->edit_rate.n);
+ if (md->error >= md->edit_rate.n) {
+ md->error = 0;
+ speu += 1;
+ }
- bytes = (speu * md->channels * md->width) / 8;
+ bytes = (speu * md->channels * md->width) / 8;
+ if (buffer)
gst_adapter_push (adapter, buffer);
- if (gst_adapter_available (adapter) >= bytes) {
- *outbuf = gst_adapter_take_buffer (adapter, bytes);
- }
- } else if (flush && (bytes = gst_adapter_available (adapter))) {
+
+ if (gst_adapter_available (adapter) == 0)
+ return GST_FLOW_OK;
+
+ if (flush)
+ bytes = MIN (gst_adapter_available (adapter), bytes);
+
+ if (gst_adapter_available (adapter) >= bytes) {
*outbuf = gst_adapter_take_buffer (adapter, bytes);
}
- return GST_FLOW_OK;
+ if (gst_adapter_available (adapter) >= bytes)
+ return GST_FLOW_CUSTOM_SUCCESS;
+ else
+ return GST_FLOW_OK;
}
static const guint8 bwf_essence_container_ul[] = {
@@ -1493,19 +1499,6 @@ mxf_bwf_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
return;
}
-static guint
-gst_greatest_common_divisor (guint a, guint b)
-{
- while (b != 0) {
- guint temp = a;
-
- a = b;
- b = temp % b;
- }
-
- return a;
-}
-
static void
mxf_bwf_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
@@ -1513,8 +1506,6 @@ mxf_bwf_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
{
guint i;
gdouble min = G_MAXDOUBLE;
- MXFMetadataWaveAudioEssenceDescriptor *d =
- MXF_METADATA_WAVE_AUDIO_ESSENCE_DESCRIPTOR (a);
BWFMappingData *md = mapping_data;
for (i = 0; i < package->parent.n_tracks; i++) {
@@ -1532,18 +1523,9 @@ mxf_bwf_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
}
if (min == G_MAXDOUBLE) {
- guint32 nu, de;
- guint gcd;
-
- /* 50ms edit units */
- nu = d->parent.audio_sampling_rate.n;
- de = d->parent.audio_sampling_rate.d * 20;
- gcd = gst_greatest_common_divisor (nu, de);
- nu /= gcd;
- de /= gcd;
-
- (*edit_rate).n = nu;
- (*edit_rate).d = de;
+ /* 100ms edit units */
+ edit_rate->n = 10;
+ edit_rate->d = 1;
}
memcpy (&md->edit_rate, edit_rate, sizeof (MXFFraction));
diff --git a/gst/mxf/mxfalaw.c b/gst/mxf/mxfalaw.c
index 52df480f..40517af0 100644
--- a/gst/mxf/mxfalaw.c
+++ b/gst/mxf/mxfalaw.c
@@ -152,28 +152,34 @@ mxf_alaw_write_func (GstBuffer * buffer, GstCaps * caps, gpointer mapping_data,
{
ALawMappingData *md = mapping_data;
guint bytes;
+ guint64 speu =
+ gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
- if (buffer) {
- guint64 speu =
- gst_util_uint64_scale (md->rate, md->edit_rate.d, md->edit_rate.n);
-
- md->error += (GST_SECOND * md->edit_rate.d * md->rate) % (md->edit_rate.n);
- if (md->error >= md->edit_rate.n) {
- md->error = 0;
- speu += 1;
- }
+ md->error += (md->edit_rate.d * md->rate) % (md->edit_rate.n);
+ if (md->error >= md->edit_rate.n) {
+ md->error = 0;
+ speu += 1;
+ }
- bytes = speu * md->channels;
+ bytes = speu * md->channels;
+ if (buffer)
gst_adapter_push (adapter, buffer);
- if (gst_adapter_available (adapter) >= bytes) {
- *outbuf = gst_adapter_take_buffer (adapter, bytes);
- }
- } else if (flush && (bytes = gst_adapter_available (adapter))) {
+
+ if (gst_adapter_available (adapter) == 0)
+ return GST_FLOW_OK;
+
+ if (flush)
+ bytes = MIN (gst_adapter_available (adapter), bytes);
+
+ if (gst_adapter_available (adapter) >= bytes) {
*outbuf = gst_adapter_take_buffer (adapter, bytes);
}
- return GST_FLOW_OK;
+ if (gst_adapter_available (adapter) >= bytes)
+ return GST_FLOW_CUSTOM_SUCCESS;
+ else
+ return GST_FLOW_OK;
}
static const guint8 alaw_essence_container_ul[] = {
@@ -232,19 +238,6 @@ mxf_alaw_update_descriptor (MXFMetadataFileDescriptor * d, GstCaps * caps,
return;
}
-static guint
-gst_greatest_common_divisor (guint a, guint b)
-{
- while (b != 0) {
- guint temp = a;
-
- a = b;
- b = temp % b;
- }
-
- return a;
-}
-
static void
mxf_alaw_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
gpointer mapping_data, GstBuffer * buf, MXFMetadataSourcePackage * package,
@@ -252,8 +245,6 @@ mxf_alaw_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
{
guint i;
gdouble min = G_MAXDOUBLE;
- MXFMetadataGenericSoundEssenceDescriptor *d =
- MXF_METADATA_GENERIC_SOUND_ESSENCE_DESCRIPTOR (a);
ALawMappingData *md = mapping_data;
for (i = 0; i < package->parent.n_tracks; i++) {
@@ -271,18 +262,9 @@ mxf_alaw_get_edit_rate (MXFMetadataFileDescriptor * a, GstCaps * caps,
}
if (min == G_MAXDOUBLE) {
- guint32 nu, de;
- guint gcd;
-
- /* 50ms edit units */
- nu = d->audio_sampling_rate.n;
- de = d->audio_sampling_rate.d * 20;
- gcd = gst_greatest_common_divisor (nu, de);
- nu /= gcd;
- de /= gcd;
-
- (*edit_rate).n = nu;
- (*edit_rate).d = de;
+ /* 100ms edit units */
+ edit_rate->n = 10;
+ edit_rate->d = 1;
}
memcpy (&md->edit_rate, edit_rate, sizeof (MXFFraction));
diff --git a/gst/mxf/mxfmux.c b/gst/mxf/mxfmux.c
index 26ba57c5..0052d2e1 100644
--- a/gst/mxf/mxfmux.c
+++ b/gst/mxf/mxfmux.c
@@ -307,13 +307,13 @@ gst_mxf_mux_setcaps (GstPad * pad, GstCaps * caps)
for (i = 0; i < mux->preface->content_storage->n_packages; i++) {
MXFMetadataSourcePackage *package;
- if (!MXF_IS_METADATA_SOURCE_PACKAGE (mux->preface->
- content_storage->packages[i]))
+ if (!MXF_IS_METADATA_SOURCE_PACKAGE (mux->preface->content_storage->
+ packages[i]))
continue;
package =
- MXF_METADATA_SOURCE_PACKAGE (mux->preface->
- content_storage->packages[i]);
+ MXF_METADATA_SOURCE_PACKAGE (mux->preface->content_storage->
+ packages[i]);
if (!package->descriptor)
continue;
@@ -398,14 +398,14 @@ gst_mxf_mux_request_new_pad (GstElement * element,
static void
gst_mxf_mux_release_pad (GstElement * element, GstPad * pad)
{
- GstMXFMux *mux = GST_MXF_MUX (GST_PAD_PARENT (pad));
- GstMXFMuxPad *cpad = (GstMXFMuxPad *) gst_pad_get_element_private (pad);
+ /*GstMXFMux *mux = GST_MXF_MUX (GST_PAD_PARENT (pad));
+ GstMXFMuxPad *cpad = (GstMXFMuxPad *) gst_pad_get_element_private (pad);
- gst_object_unref (cpad->adapter);
- g_free (cpad->mapping_data);
+ gst_object_unref (cpad->adapter);
+ g_free (cpad->mapping_data);
- gst_collect_pads_remove_pad (mux->collect, pad);
- gst_element_remove_pad (element, pad);
+ gst_collect_pads_remove_pad (mux->collect, pad);
+ gst_element_remove_pad (element, pad); */
}
static GstFlowReturn
@@ -549,7 +549,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
&MXF_METADATA_BASE (cstorage)->instance_uid, cstorage);
cstorage->n_packages = 2;
- cstorage->packages = g_new (MXFMetadataGenericPackage *, 2);
+ cstorage->packages = g_new0 (MXFMetadataGenericPackage *, 2);
/* Source package */
{
@@ -572,7 +572,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
&mux->preface->last_modified_date, sizeof (MXFTimestamp));
p->parent.n_tracks = g_slist_length (mux->collect->data);
- p->parent.tracks = g_new (MXFMetadataTrack *, p->parent.n_tracks);
+ p->parent.tracks = g_new0 (MXFMetadataTrack *, p->parent.n_tracks);
if (p->parent.n_tracks > 1) {
MXFMetadataMultipleDescriptor *d;
@@ -582,7 +582,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
d = (MXFMetadataMultipleDescriptor *) p->descriptor;
d->n_sub_descriptors = p->parent.n_tracks;
d->sub_descriptors =
- g_new (MXFMetadataGenericDescriptor *, p->parent.n_tracks);
+ g_new0 (MXFMetadataGenericDescriptor *, p->parent.n_tracks);
mxf_ul_set (&MXF_METADATA_BASE (d)->instance_uid, mux->metadata);
g_hash_table_insert (mux->metadata,
@@ -628,7 +628,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
sequence->n_structural_components = 1;
sequence->structural_components =
- g_new (MXFMetadataStructuralComponent *, 1);
+ g_new0 (MXFMetadataStructuralComponent *, 1);
clip = (MXFMetadataSourceClip *)
gst_mini_object_new (MXF_TYPE_METADATA_SOURCE_CLIP);
@@ -648,8 +648,8 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
if (p->parent.n_tracks == 1) {
p->descriptor = (MXFMetadataGenericDescriptor *) cpad->descriptor;
} else {
- MXF_METADATA_MULTIPLE_DESCRIPTOR (p->
- descriptor)->sub_descriptors[n] =
+ MXF_METADATA_MULTIPLE_DESCRIPTOR (p->descriptor)->
+ sub_descriptors[n] =
(MXFMetadataGenericDescriptor *) cpad->descriptor;
}
@@ -681,7 +681,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
sizeof (MXFTimestamp));
p->n_tracks = g_slist_length (mux->collect->data) + 1;
- p->tracks = g_new (MXFMetadataTrack *, p->n_tracks);
+ p->tracks = g_new0 (MXFMetadataTrack *, p->n_tracks);
/* Tracks */
{
@@ -745,7 +745,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
16);
sequence->n_structural_components = 1;
sequence->structural_components =
- g_new (MXFMetadataStructuralComponent *, 1);
+ g_new0 (MXFMetadataStructuralComponent *, 1);
clip = (MXFMetadataSourceClip *)
gst_mini_object_new (MXF_TYPE_METADATA_SOURCE_CLIP);
@@ -799,7 +799,7 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
sequence->n_structural_components = 1;
sequence->structural_components =
- g_new (MXFMetadataStructuralComponent *, 1);
+ g_new0 (MXFMetadataStructuralComponent *, 1);
component = (MXFMetadataTimecodeComponent *)
gst_mini_object_new (MXF_TYPE_METADATA_TIMECODE_COMPONENT);
@@ -857,11 +857,11 @@ gst_mxf_mux_create_metadata (GstMXFMux * mux)
cstorage->n_essence_container_data = 1;
cstorage->essence_container_data =
- g_new (MXFMetadataEssenceContainerData *, 1);
+ g_new0 (MXFMetadataEssenceContainerData *, 1);
cstorage->essence_container_data[0] = (MXFMetadataEssenceContainerData *)
gst_mini_object_new (MXF_TYPE_METADATA_ESSENCE_CONTAINER_DATA);
- mxf_ul_set (&MXF_METADATA_BASE (cstorage->
- essence_container_data[0])->instance_uid, mux->metadata);
+ mxf_ul_set (&MXF_METADATA_BASE (cstorage->essence_container_data[0])->
+ instance_uid, mux->metadata);
g_hash_table_insert (mux->metadata,
&MXF_METADATA_BASE (cstorage->essence_container_data[0])->instance_uid,
cstorage->essence_container_data[0]);
@@ -1006,25 +1006,51 @@ static const guint8 _gc_essence_element_ul[] = {
static GstFlowReturn
gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad)
{
- GstBuffer *buf = gst_collect_pads_pop (mux->collect, &cpad->collect);
+ GstBuffer *buf = NULL;
GstBuffer *outbuf = NULL;
GstBuffer *packet;
GstFlowReturn ret = GST_FLOW_OK;
guint8 slen, ber[9];
+ gboolean flush =
+ (cpad->collect.abidata.ABI.eos && !cpad->have_complete_edit_unit
+ && cpad->collect.buffer == NULL);
+
+ if (cpad->have_complete_edit_unit) {
+ GST_DEBUG_OBJECT (cpad->collect.pad,
+ "Handling remaining buffer for track %u at position %" G_GINT64_FORMAT,
+ cpad->source_track->parent.track_id, cpad->pos);
+ buf = NULL;
+ } else if (!flush) {
+ buf = gst_collect_pads_pop (mux->collect, &cpad->collect);
+ }
- GST_DEBUG_OBJECT (cpad->collect.pad,
- "Handling buffer of size %u for track %u at position %" G_GINT64_FORMAT,
- GST_BUFFER_SIZE (buf), cpad->source_track->parent.track_id, cpad->pos);
+ if (buf) {
+ GST_DEBUG_OBJECT (cpad->collect.pad,
+ "Handling buffer of size %u for track %u at position %" G_GINT64_FORMAT,
+ GST_BUFFER_SIZE (buf), cpad->source_track->parent.track_id, cpad->pos);
+ } else {
+ flush = TRUE;
+ GST_DEBUG_OBJECT (cpad->collect.pad,
+ "Flushing for track %u at position %" G_GINT64_FORMAT,
+ cpad->source_track->parent.track_id, cpad->pos);
+ }
- if ((ret =
- cpad->write_func (buf, GST_PAD_CAPS (cpad->collect.pad),
- cpad->mapping_data, cpad->adapter, &outbuf,
- FALSE) != GST_FLOW_OK)) {
- GST_ERROR_OBJECT (mux, "Failed handling buffer for track %u",
- cpad->source_track->parent.track_id);
+ ret = cpad->write_func (buf, GST_PAD_CAPS (cpad->collect.pad),
+ cpad->mapping_data, cpad->adapter, &outbuf, flush);
+ if (ret != GST_FLOW_OK && ret != GST_FLOW_CUSTOM_SUCCESS) {
+ GST_ERROR_OBJECT (cpad->collect.pad,
+ "Failed handling buffer for track %u, reason %s",
+ cpad->source_track->parent.track_id, gst_flow_get_name (ret));
return ret;
}
+ if (ret == GST_FLOW_CUSTOM_SUCCESS) {
+ cpad->have_complete_edit_unit = TRUE;
+ ret = GST_FLOW_OK;
+ } else {
+ cpad->have_complete_edit_unit = FALSE;
+ }
+
buf = outbuf;
if (buf == NULL)
return ret;
@@ -1040,9 +1066,13 @@ gst_mxf_mux_handle_buffer (GstMXFMux * mux, GstMXFMuxPad * cpad)
GST_BUFFER_SIZE (buf));
gst_buffer_unref (buf);
+ GST_DEBUG_OBJECT (cpad->collect.pad, "Pushing buffer of size %u for track %u",
+ GST_BUFFER_SIZE (packet), cpad->source_track->parent.track_id);
+
if ((ret = gst_mxf_mux_push (mux, packet)) != GST_FLOW_OK) {
- GST_ERROR_OBJECT (mux, "Failed pushing buffer for track %u",
- cpad->source_track->parent.track_id);
+ GST_ERROR_OBJECT (cpad->collect.pad,
+ "Failed pushing buffer for track %u, reason %s",
+ cpad->source_track->parent.track_id, gst_flow_get_name (ret));
return ret;
}
@@ -1082,58 +1112,72 @@ static GstFlowReturn
gst_mxf_mux_handle_eos (GstMXFMux * mux)
{
GSList *l;
- GstBuffer *packet, *buf;
+ gboolean have_data = FALSE;
+ GstBuffer *packet;
- for (l = mux->collect->data; l; l = l->next) {
- GstMXFMuxPad *cpad = l->data;
- GstFlowReturn ret;
- guint i;
+ do {
+ GstMXFMuxPad *best = NULL;
- buf = NULL;
- cpad->write_func (NULL, GST_PAD_CAPS (cpad->collect.pad),
- cpad->mapping_data, cpad->adapter, &buf, TRUE);
-
- if (buf) {
- guint8 slen, ber[9];
-
- slen = mxf_ber_encode_size (GST_BUFFER_SIZE (buf), ber);
- packet = gst_buffer_new_and_alloc (16 + slen + GST_BUFFER_SIZE (buf));
- memcpy (GST_BUFFER_DATA (packet), _gc_essence_element_ul, 16);
- GST_BUFFER_DATA (packet)[7] = cpad->descriptor->essence_container.u[7];
- GST_WRITE_UINT32_BE (&GST_BUFFER_DATA (packet)[12],
- cpad->source_track->parent.track_number);
- memcpy (&GST_BUFFER_DATA (packet)[16], ber, slen);
- memcpy (&GST_BUFFER_DATA (packet)[16 + slen], GST_BUFFER_DATA (buf),
- GST_BUFFER_SIZE (buf));
- gst_buffer_unref (buf);
-
- ret = gst_mxf_mux_push (mux, packet);
- if (ret != GST_FLOW_OK) {
- GST_WARNING_OBJECT (mux, "Failed handling EOS for track %u",
- cpad->source_track->parent.track_id);
+ have_data = FALSE;
+
+ for (l = mux->collect->data; l; l = l->next) {
+ GstMXFMuxPad *cpad = l->data;
+ GstClockTime next_gc_timestamp =
+ gst_util_uint64_scale ((mux->last_gc_position + 1) * GST_SECOND,
+ mux->min_edit_rate.d, mux->min_edit_rate.n);
+
+ best = NULL;
+
+ if (cpad->have_complete_edit_unit ||
+ gst_adapter_available (cpad->adapter) > 0 || cpad->collect.buffer) {
+ have_data = TRUE;
+ if (cpad->last_timestamp < next_gc_timestamp) {
+ best = cpad;
+ break;
+ }
+ } else if (have_data && !l->next) {
+ mux->last_gc_position++;
+ mux->last_gc_timestamp = next_gc_timestamp;
+ have_data = FALSE;
+ best = NULL;
+ break;
}
- cpad->pos++;
}
+ if (best) {
+ gst_mxf_mux_handle_buffer (mux, best);
+ have_data = TRUE;
+ }
+ } while (have_data);
+
+ mux->last_gc_position++;
+ mux->last_gc_timestamp =
+ gst_util_uint64_scale (mux->last_gc_position * GST_SECOND,
+ mux->min_edit_rate.d, mux->min_edit_rate.n);
+
+ /* Update essence track durations */
+ for (l = mux->collect->data; l; l = l->next) {
+ GstMXFMuxPad *cpad = l->data;
+ guint i;
+
/* Update durations */
cpad->source_track->parent.sequence->duration = cpad->pos;
- MXF_METADATA_SOURCE_CLIP (cpad->source_track->parent.
- sequence->structural_components[0])->parent.duration = cpad->pos;
+ MXF_METADATA_SOURCE_CLIP (cpad->source_track->parent.sequence->
+ structural_components[0])->parent.duration = cpad->pos;
for (i = 0; i < mux->preface->content_storage->packages[0]->n_tracks; i++) {
MXFMetadataTimelineTrack *track;
- if (!MXF_IS_METADATA_TIMELINE_TRACK (mux->preface->
- content_storage->packages[0]->tracks[i])
- || !MXF_IS_METADATA_SOURCE_CLIP (mux->preface->
- content_storage->packages[0]->tracks[i]->sequence->
- structural_components[0]))
+ if (!MXF_IS_METADATA_TIMELINE_TRACK (mux->preface->content_storage->
+ packages[0]->tracks[i])
+ || !MXF_IS_METADATA_SOURCE_CLIP (mux->preface->content_storage->
+ packages[0]->tracks[i]->sequence->structural_components[0]))
continue;
track =
- MXF_METADATA_TIMELINE_TRACK (mux->preface->
- content_storage->packages[0]->tracks[i]);
- if (MXF_METADATA_SOURCE_CLIP (track->parent.
- sequence->structural_components[0])->source_track_id ==
+ MXF_METADATA_TIMELINE_TRACK (mux->preface->content_storage->
+ packages[0]->tracks[i]);
+ if (MXF_METADATA_SOURCE_CLIP (track->parent.sequence->
+ structural_components[0])->source_track_id ==
cpad->source_track->parent.track_id) {
track->parent.sequence->structural_components[0]->duration = cpad->pos;
track->parent.sequence->duration = cpad->pos;
@@ -1144,8 +1188,8 @@ gst_mxf_mux_handle_eos (GstMXFMux * mux)
/* Update timecode track duration */
{
MXFMetadataTimelineTrack *track =
- MXF_METADATA_TIMELINE_TRACK (mux->preface->
- content_storage->packages[0]->tracks[0]);
+ MXF_METADATA_TIMELINE_TRACK (mux->preface->content_storage->
+ packages[0]->tracks[0]);
MXFMetadataSequence *sequence = track->parent.sequence;
MXFMetadataTimecodeComponent *component =
MXF_METADATA_TIMECODE_COMPONENT (sequence->structural_components[0]);
@@ -1257,6 +1301,9 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data)
if (mux->state == GST_MXF_MUX_STATE_ERROR) {
GST_ERROR_OBJECT (mux, "Had an error before -- returning");
return GST_FLOW_ERROR;
+ } else if (mux->state == GST_MXF_MUX_STATE_EOS) {
+ GST_WARNING_OBJECT (mux, "EOS");
+ return GST_FLOW_UNEXPECTED;
}
if (mux->state == GST_MXF_MUX_STATE_HEADER) {
@@ -1296,26 +1343,29 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data)
g_return_val_if_fail (g_hash_table_size (mux->metadata) > 0, GST_FLOW_ERROR);
- for (sl = mux->collect->data; sl; sl = sl->next) {
- GstMXFMuxPad *cpad = sl->data;
- GstClockTime next_gc_timestamp =
- gst_util_uint64_scale ((mux->last_gc_position + 1) * GST_SECOND,
- mux->min_edit_rate.d, mux->min_edit_rate.n);
+ do {
+ for (sl = mux->collect->data; sl; sl = sl->next) {
+ GstMXFMuxPad *cpad = sl->data;
+ GstClockTime next_gc_timestamp =
+ gst_util_uint64_scale ((mux->last_gc_position + 1) * GST_SECOND,
+ mux->min_edit_rate.d, mux->min_edit_rate.n);
- if (cpad->collect.abidata.ABI.eos)
- continue;
+ eos &= cpad->collect.abidata.ABI.eos;
- if (cpad->last_timestamp < next_gc_timestamp) {
- eos = FALSE;
- best = cpad;
- break;
- } else if (eos || !sl->next) {
- mux->last_gc_position++;
- mux->last_gc_timestamp = next_gc_timestamp;
- sl = mux->collect->data;
+ if ((!cpad->collect.abidata.ABI.eos || cpad->have_complete_edit_unit ||
+ gst_adapter_available (cpad->adapter) > 0 || cpad->collect.buffer)
+ && cpad->last_timestamp < next_gc_timestamp) {
+ best = cpad;
+ break;
+ } else if (!eos && !sl->next) {
+ mux->last_gc_position++;
+ mux->last_gc_timestamp = next_gc_timestamp;
+ eos = FALSE;
+ best = NULL;
+ break;
+ }
}
- eos = FALSE;
- }
+ } while (!eos && best == NULL);
if (!eos && best) {
ret = gst_mxf_mux_handle_buffer (mux, best);
@@ -1324,12 +1374,9 @@ gst_mxf_mux_collected (GstCollectPads * pads, gpointer user_data)
} else if (eos) {
GST_DEBUG_OBJECT (mux, "Handling EOS");
- mux->last_gc_position++;
- mux->last_gc_timestamp =
- gst_util_uint64_scale (mux->last_gc_position * GST_SECOND,
- mux->min_edit_rate.d, mux->min_edit_rate.n);
gst_mxf_mux_handle_eos (mux);
gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
+ mux->state = GST_MXF_MUX_STATE_EOS;
return GST_FLOW_UNEXPECTED;
}
diff --git a/gst/mxf/mxfmux.h b/gst/mxf/mxfmux.h
index 612dfff4..81f232ad 100644
--- a/gst/mxf/mxfmux.h
+++ b/gst/mxf/mxfmux.h
@@ -49,6 +49,7 @@ typedef struct
MXFMetadataFileDescriptor *descriptor;
GstAdapter *adapter;
+ gboolean have_complete_edit_unit;
gpointer mapping_data;
const MXFEssenceElementWriter *writer;
@@ -62,6 +63,7 @@ typedef enum
{
GST_MXF_MUX_STATE_HEADER,
GST_MXF_MUX_STATE_DATA,
+ GST_MXF_MUX_STATE_EOS,
GST_MXF_MUX_STATE_ERROR
} GstMXFMuxState;