summaryrefslogtreecommitdiffstats
path: root/gst/mxf
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2009-01-29 20:27:28 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-01-31 11:02:26 +0100
commit02769b4a4d6d143bdad28e0143481bfd022e0143 (patch)
tree7b0bb2413ea458bbfdeebbeab690de815b367818 /gst/mxf
parent707136fe5dcc71b803359d5e06fbd57a5d5db74f (diff)
downloadgst-plugins-bad-02769b4a4d6d143bdad28e0143481bfd022e0143.tar.gz
gst-plugins-bad-02769b4a4d6d143bdad28e0143481bfd022e0143.tar.bz2
gst-plugins-bad-02769b4a4d6d143bdad28e0143481bfd022e0143.zip
Improve EOS detection and fix push mode for the last pushed in buffer
Diffstat (limited to 'gst/mxf')
-rw-r--r--gst/mxf/mxfdemux.c140
1 files changed, 80 insertions, 60 deletions
diff --git a/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c
index 8259e4fc..5b2e66e5 100644
--- a/gst/mxf/mxfdemux.c
+++ b/gst/mxf/mxfdemux.c
@@ -385,6 +385,28 @@ gst_mxf_demux_push_src_event (GstMXFDemux * demux, GstEvent * event)
return ret;
}
+static GstMXFDemuxPad *
+gst_mxf_demux_get_earliest_pad (GstMXFDemux * demux)
+{
+ guint i;
+ GstClockTime earliest = GST_CLOCK_TIME_NONE;
+ GstMXFDemuxPad *pad = NULL;
+
+ if (!demux->src)
+ return NULL;
+
+ for (i = 0; i < demux->src->len; i++) {
+ GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
+
+ if (!p->eos && p->last_flow < earliest) {
+ earliest = p->last_flow;
+ pad = p;
+ }
+ }
+
+ return pad;
+}
+
static gint
gst_mxf_demux_partition_compare (GstMXFDemuxPartition * a,
GstMXFDemuxPartition * b)
@@ -1492,7 +1514,6 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
for (i = 0; i < demux->src->len; i++) {
GstMXFDemuxPad *pad = g_ptr_array_index (demux->src, i);
- guint j;
if (pad->current_essence_track != etrack)
continue;
@@ -1507,18 +1528,15 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
continue;
}
- for (j = 0; j < demux->src->len; j++) {
- GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, j);
+ {
+ GstMXFDemuxPad *earliest = gst_mxf_demux_get_earliest_pad (demux);
- if (!opad->eos && opad->last_stop < pad->last_stop &&
- pad->last_stop - opad->last_stop > 500 * GST_MSECOND) {
- break;
+ if (earliest && earliest != pad && earliest->last_stop < pad->last_stop &&
+ pad->last_stop - earliest->last_stop > 500 * GST_MSECOND) {
+ GST_DEBUG_OBJECT (demux, "Pad is too far ahead of time");
+ continue;
}
}
- if (j != demux->src->len) {
- GST_DEBUG_OBJECT (demux, "Pad is too far ahead of time");
- continue;
- }
/* Create another subbuffer to have writable metadata */
outbuf = gst_buffer_create_sub (inbuf, 0, GST_BUFFER_SIZE (inbuf));
@@ -1612,20 +1630,7 @@ gst_mxf_demux_handle_generic_container_essence_element (GstMXFDemux * demux,
GST_DEBUG_OBJECT (demux, "EOS for track");
pad->eos = TRUE;
gst_pad_push_event (GST_PAD_CAST (pad), gst_event_new_eos ());
-
- for (i = 0; i < demux->src->len; i++) {
- GstMXFDemuxPad *opad = g_ptr_array_index (demux->src, i);
-
- if (!opad->eos) {
- ret = GST_FLOW_OK;
- break;
- }
- }
-
- if (ret == GST_FLOW_UNEXPECTED) {
- GST_DEBUG_OBJECT (demux, "All tracks are EOS");
- break;
- }
+ ret = GST_FLOW_OK;
}
if (ret != GST_FLOW_OK)
@@ -2302,46 +2307,59 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux)
GstFlowReturn ret = GST_FLOW_OK;
guint read = 0;
+ if (demux->src) {
+ if (!gst_mxf_demux_get_earliest_pad (demux)) {
+ ret = GST_FLOW_UNEXPECTED;
+ GST_DEBUG_OBJECT (demux, "All tracks are EOS");
+ goto beach;
+ }
+ }
+
ret =
gst_mxf_demux_pull_klv_packet (demux, demux->offset, &key, &buffer,
&read);
if (ret == GST_FLOW_UNEXPECTED && demux->src) {
guint i;
+ GstMXFDemuxPad *p = NULL;
- for (i = 0; i < demux->src->len; i++) {
- GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
+ for (i = 0; i < demux->essence_tracks->len; i++) {
+ GstMXFDemuxEssenceTrack *t =
+ &g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack, i);
- if (!p->eos) {
- guint64 offset;
- gint64 position;
+ if (t->position != -1)
+ t->duration = t->position;
+ }
- position = p->current_essence_track_position;
+ while ((p = gst_mxf_demux_get_earliest_pad (demux))) {
+ guint64 offset;
+ gint64 position;
- offset =
- gst_mxf_demux_find_essence_element (demux, p->current_essence_track,
- &position, FALSE);
- if (offset == -1) {
- GST_ERROR_OBJECT (demux, "Failed to find offset for essence track");
- p->eos = TRUE;
- gst_pad_push_event (GST_PAD_CAST (p), gst_event_new_eos ());
- continue;
- }
+ position = p->current_essence_track_position;
- demux->offset = offset + demux->run_in;
- gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
+ offset =
+ gst_mxf_demux_find_essence_element (demux, p->current_essence_track,
+ &position, FALSE);
+ if (offset == -1) {
+ GST_ERROR_OBJECT (demux, "Failed to find offset for essence track");
+ p->eos = TRUE;
+ gst_pad_push_event (GST_PAD_CAST (p), gst_event_new_eos ());
+ continue;
+ }
- for (i = 0; i < demux->essence_tracks->len; i++) {
- GstMXFDemuxEssenceTrack *etrack =
- &g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack,
- i);
- etrack->position = -1;
- }
- p->current_essence_track->position = position;
+ demux->offset = offset + demux->run_in;
+ gst_mxf_demux_set_partition_for_offset (demux, demux->offset);
- ret = GST_FLOW_OK;
- goto beach;
+ for (i = 0; i < demux->essence_tracks->len; i++) {
+ GstMXFDemuxEssenceTrack *etrack =
+ &g_array_index (demux->essence_tracks, GstMXFDemuxEssenceTrack,
+ i);
+ etrack->position = -1;
}
+ p->current_essence_track->position = position;
+
+ ret = GST_FLOW_OK;
+ goto beach;
}
}
@@ -2354,21 +2372,15 @@ gst_mxf_demux_pull_and_handle_klv_packet (GstMXFDemux * demux)
if (ret == GST_FLOW_OK && demux->src && demux->essence_tracks) {
guint i;
GstMXFDemuxPad *earliest = NULL;
- GstClockTime earliest_last_stop = demux->segment.last_stop;
guint64 offset;
gint64 position;
- for (i = 0; i < demux->src->len; i++) {
- GstMXFDemuxPad *p = g_ptr_array_index (demux->src, i);
-
- if (!p->eos && p->last_stop < earliest_last_stop) {
- earliest = p;
- earliest_last_stop = p->last_stop;
- }
- }
+ earliest = gst_mxf_demux_get_earliest_pad (demux);
+ if (!earliest)
+ goto beach;
/* We allow time drifts of at most 500ms */
- if (demux->segment.last_stop - earliest_last_stop <= 500 * GST_MSECOND)
+ if (demux->segment.last_stop - earliest->last_stop <= 500 * GST_MSECOND)
goto beach;
GST_WARNING_OBJECT (demux,
@@ -2533,6 +2545,14 @@ gst_mxf_demux_chain (GstPad * pad, GstBuffer * inbuf)
GST_LOG_OBJECT (demux, "received buffer of %u bytes at offset %"
G_GUINT64_FORMAT, GST_BUFFER_SIZE (inbuf), GST_BUFFER_OFFSET (inbuf));
+ if (demux->src) {
+ if (!gst_mxf_demux_get_earliest_pad (demux)) {
+ ret = GST_FLOW_UNEXPECTED;
+ GST_DEBUG_OBJECT (demux, "All tracks are EOS");
+ return ret;
+ }
+ }
+
if (G_UNLIKELY (GST_BUFFER_OFFSET (inbuf) == 0)) {
GST_DEBUG_OBJECT (demux, "beginning of file, expect header");
demux->run_in = -1;