diff options
author | Edward Hervey <bilboed@bilboed.com> | 2006-05-31 13:37:27 +0000 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2006-05-31 13:37:27 +0000 |
commit | 0050b26ee87669a533e46a35e75847d263c57120 (patch) | |
tree | 4d894712a7ae307fd120a72cc939b38c820c4ae9 /ext/faad | |
parent | 5956f87dd82fec00b197fc6c106c28218250a52b (diff) | |
download | gst-plugins-bad-0050b26ee87669a533e46a35e75847d263c57120.tar.gz gst-plugins-bad-0050b26ee87669a533e46a35e75847d263c57120.tar.bz2 gst-plugins-bad-0050b26ee87669a533e46a35e75847d263c57120.zip |
ext/faad/gstfaad.c: Added GstSegment to control segments.
Original commit message from CVS:
* ext/faad/gstfaad.c: (gst_faad_class_init), (gst_faad_init),
(gst_faad_dispose), (gst_faad_sink_event), (clip_outgoing_buffer),
(gst_faad_chain), (gst_faad_change_state):
Added GstSegment to control segments.
Added clipping/dropping of outgoing buffers in order to have accurate
seeking working properly.
Diffstat (limited to 'ext/faad')
-rw-r--r-- | ext/faad/gstfaad.c | 92 |
1 files changed, 86 insertions, 6 deletions
diff --git a/ext/faad/gstfaad.c b/ext/faad/gstfaad.c index c17c32a8..f7a06ece 100644 --- a/ext/faad/gstfaad.c +++ b/ext/faad/gstfaad.c @@ -113,6 +113,7 @@ static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", static void gst_faad_base_init (GstFaadClass * klass); static void gst_faad_class_init (GstFaadClass * klass); static void gst_faad_init (GstFaad * faad); +static void gst_faad_dispose (GObject * object); static gboolean gst_faad_setcaps (GstPad * pad, GstCaps * caps); static GstCaps *gst_faad_srcgetcaps (GstPad * pad); @@ -172,10 +173,13 @@ gst_faad_base_init (GstFaadClass * klass) static void gst_faad_class_init (GstFaadClass * klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_faad_dispose); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_faad_change_state); } @@ -195,6 +199,7 @@ gst_faad_init (GstFaad * faad) faad->sum_dur_out = 0; faad->packetised = FALSE; faad->error_count = 0; + faad->segment = gst_segment_new (); faad->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink"); gst_element_add_pad (GST_ELEMENT (faad), faad->sinkpad); @@ -217,6 +222,20 @@ gst_faad_init (GstFaad * faad) } static void +gst_faad_dispose (GObject * object) +{ + GstFaad *faad = GST_FAAD (object); + + if (faad->segment) { + gst_segment_free (faad->segment); + faad->segment = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); + +} + +static void gst_faad_send_tags (GstFaad * faad) { GstTagList *tags; @@ -778,6 +797,8 @@ gst_faad_sink_event (GstPad * pad, GstEvent * event) GST_DEBUG ("Got NEWSEGMENT event in GST_FORMAT_TIME, passing on (%" GST_TIME_FORMAT " - %" GST_TIME_FORMAT ")", GST_TIME_ARGS (start), GST_TIME_ARGS (end)); + gst_segment_set_newsegment (faad->segment, is_update, rate, fmt, start, + end, base); } else if (fmt == GST_FORMAT_BYTES) { gint64 new_start = 0; gint64 new_end = -1; @@ -800,6 +821,9 @@ gst_faad_sink_event (GstPad * pad, GstEvent * event) event = gst_event_new_new_segment (is_update, rate, GST_FORMAT_TIME, new_start, new_end, new_start); + gst_segment_set_newsegment (faad->segment, is_update, rate, + GST_FORMAT_TIME, new_start, new_end, new_start); + GST_DEBUG ("Sending new NEWSEGMENT event, time %" GST_TIME_FORMAT " - %" GST_TIME_FORMAT, GST_TIME_ARGS (new_start), GST_TIME_ARGS (new_end)); @@ -1074,6 +1098,55 @@ looks_like_valid_header (guint8 * input_data, guint input_size) return TRUE; } +/* + clips buffer to currently configured segment. Returns FALSE if the buffer + has to be dropped. +*/ + +static gboolean +clip_outgoing_buffer (GstFaad * faad, GstBuffer * buffer) +{ + gint64 start, stop, cstart, cstop, diff; + gboolean res = TRUE; + + if (faad->segment->format != GST_FORMAT_TIME) + goto beach; + + start = GST_BUFFER_TIMESTAMP (buffer); + stop = start + GST_BUFFER_DURATION (buffer); + + if (gst_segment_clip (faad->segment, GST_FORMAT_TIME, + start, stop, &cstart, &cstop)) { + diff = cstart - start; + if (diff > 0) { + GST_BUFFER_TIMESTAMP (buffer) = cstart; + GST_BUFFER_DURATION (buffer) -= diff; + + /* time->frames->bytes */ + diff = + faad->bps * faad->channels * GST_CLOCK_TIME_TO_FRAMES (diff, + faad->samplerate); + GST_BUFFER_DATA (buffer) += diff; + GST_BUFFER_SIZE (buffer) -= diff; + } + diff = cstop - stop; + if (diff > 0) { + GST_BUFFER_DURATION (buffer) -= diff; + /* time->frames->bytes */ + diff = + faad->bps * faad->channels * GST_CLOCK_TIME_TO_FRAMES (diff, + faad->samplerate); + /* update size */ + GST_BUFFER_SIZE (buffer) -= diff; + } + } else { + GST_DEBUG_OBJECT (faad, "buffer is outside configured segment"); + res = FALSE; + } + +beach: + return res; +} static GstFlowReturn gst_faad_chain (GstPad * pad, GstBuffer * buffer) @@ -1273,12 +1346,16 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer) faad->sum_dur_out += GST_BUFFER_DURATION (outbuf); GST_OBJECT_UNLOCK (faad); - GST_LOG_OBJECT (faad, "pushing buffer, off=%" G_GUINT64_FORMAT ", ts=%" - GST_TIME_FORMAT, GST_BUFFER_OFFSET (outbuf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); - if ((ret = gst_pad_push (faad->srcpad, outbuf)) != GST_FLOW_OK && - ret != GST_FLOW_NOT_LINKED) - goto out; + if (clip_outgoing_buffer (faad, outbuf)) { + GST_LOG_OBJECT (faad, + "pushing buffer, off=%" G_GUINT64_FORMAT ", ts=%" GST_TIME_FORMAT, + GST_BUFFER_OFFSET (outbuf), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); + if ((ret = gst_pad_push (faad->srcpad, outbuf)) != GST_FLOW_OK + && ret != GST_FLOW_NOT_LINKED) + goto out; + } else + gst_buffer_unref (outbuf); } } } @@ -1372,6 +1449,9 @@ gst_faad_change_state (GstElement * element, GstStateChange transition) if (!gst_faad_open_decoder (faad)) return GST_STATE_CHANGE_FAILURE; break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_segment_init (faad->segment, GST_FORMAT_UNDEFINED); + break; default: break; } |