diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-03-26 08:11:20 +0100 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-03-26 08:11:20 +0100 |
commit | 3b88dce4d1bf82e290cbac5a68df2d6fc189b205 (patch) | |
tree | 04b65888aa4f7a26d9647e46e2e4becdb9034ddd | |
parent | 7146c027fe35beae3bc801e77c8881926dc30000 (diff) | |
download | gst-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.c | 66 | ||||
-rw-r--r-- | gst/mxf/mxfalaw.c | 66 | ||||
-rw-r--r-- | gst/mxf/mxfmux.c | 239 | ||||
-rw-r--r-- | gst/mxf/mxfmux.h | 2 |
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; |