base: port to 0.11

This commit is contained in:
Wim Taymans 2011-08-29 13:28:08 +02:00
parent 057aecc34e
commit e694528155
6 changed files with 155 additions and 218 deletions

View file

@ -149,7 +149,6 @@
#include "config.h" #include "config.h"
#endif #endif
#define GST_USE_UNSTABLE_API
#include "gstbaseaudiodecoder.h" #include "gstbaseaudiodecoder.h"
#include <gst/pbutils/descriptions.h> #include <gst/pbutils/descriptions.h>
@ -279,10 +278,6 @@ static gboolean gst_base_audio_decoder_sink_event (GstPad * pad,
GstEvent * event); GstEvent * event);
static gboolean gst_base_audio_decoder_src_event (GstPad * pad, static gboolean gst_base_audio_decoder_src_event (GstPad * pad,
GstEvent * event); GstEvent * event);
static gboolean gst_base_audio_decoder_sink_setcaps (GstPad * pad,
GstCaps * caps);
static gboolean gst_base_audio_decoder_src_setcaps (GstPad * pad,
GstCaps * caps);
static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad, static GstFlowReturn gst_base_audio_decoder_chain (GstPad * pad,
GstBuffer * buf); GstBuffer * buf);
static gboolean gst_base_audio_decoder_src_query (GstPad * pad, static gboolean gst_base_audio_decoder_src_query (GstPad * pad,
@ -294,14 +289,8 @@ static const GstQueryType *gst_base_audio_decoder_get_query_types (GstPad *
static void gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, static void gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec,
gboolean full); gboolean full);
#define gst_base_audio_decoder_parent_class parent_class
GST_BOILERPLATE (GstBaseAudioDecoder, gst_base_audio_decoder, GstElement, G_DEFINE_TYPE (GstBaseAudioDecoder, gst_base_audio_decoder, GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT);
static void
gst_base_audio_decoder_base_init (gpointer g_class)
{
}
static void static void
gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass) gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass)
@ -345,9 +334,9 @@ gst_base_audio_decoder_class_init (GstBaseAudioDecoderClass * klass)
} }
static void static void
gst_base_audio_decoder_init (GstBaseAudioDecoder * dec, gst_base_audio_decoder_init (GstBaseAudioDecoder * dec)
GstBaseAudioDecoderClass * klass)
{ {
GstBaseAudioDecoderClass *klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
GstPadTemplate *pad_template; GstPadTemplate *pad_template;
GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_init"); GST_DEBUG_OBJECT (dec, "gst_base_audio_decoder_init");
@ -362,8 +351,6 @@ gst_base_audio_decoder_init (GstBaseAudioDecoder * dec,
dec->sinkpad = gst_pad_new_from_template (pad_template, "sink"); dec->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_event_function (dec->sinkpad, gst_pad_set_event_function (dec->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_decoder_sink_event)); GST_DEBUG_FUNCPTR (gst_base_audio_decoder_sink_event));
gst_pad_set_setcaps_function (dec->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_decoder_sink_setcaps));
gst_pad_set_chain_function (dec->sinkpad, gst_pad_set_chain_function (dec->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_decoder_chain)); GST_DEBUG_FUNCPTR (gst_base_audio_decoder_chain));
gst_pad_set_query_function (dec->sinkpad, gst_pad_set_query_function (dec->sinkpad,
@ -377,8 +364,6 @@ gst_base_audio_decoder_init (GstBaseAudioDecoder * dec,
g_return_if_fail (pad_template != NULL); g_return_if_fail (pad_template != NULL);
dec->srcpad = gst_pad_new_from_template (pad_template, "src"); dec->srcpad = gst_pad_new_from_template (pad_template, "src");
gst_pad_set_setcaps_function (dec->srcpad,
GST_DEBUG_FUNCPTR (gst_base_audio_decoder_src_setcaps));
gst_pad_set_event_function (dec->srcpad, gst_pad_set_event_function (dec->srcpad,
GST_DEBUG_FUNCPTR (gst_base_audio_decoder_src_event)); GST_DEBUG_FUNCPTR (gst_base_audio_decoder_src_event));
gst_pad_set_query_function (dec->srcpad, gst_pad_set_query_function (dec->srcpad,
@ -418,7 +403,7 @@ gst_base_audio_decoder_reset (GstBaseAudioDecoder * dec, gboolean full)
dec->priv->error_count = 0; dec->priv->error_count = 0;
gst_base_audio_decoder_clear_queues (dec); gst_base_audio_decoder_clear_queues (dec);
gst_audio_info_clear (&dec->priv->ctx.info); gst_audio_info_init (&dec->priv->ctx.info);
memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
if (dec->priv->taglist) { if (dec->priv->taglist) {
@ -465,15 +450,12 @@ gst_base_audio_decoder_finalize (GObject * object)
/* automagically perform sanity checking of src caps; /* automagically perform sanity checking of src caps;
* also extracts output data format */ * also extracts output data format */
static gboolean gboolean
gst_base_audio_decoder_src_setcaps (GstPad * pad, GstCaps * caps) gst_base_audio_decoder_src_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
{ {
GstBaseAudioDecoder *dec;
gboolean res = TRUE; gboolean res = TRUE;
guint old_rate; guint old_rate;
dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
/* parse caps here to check subclass; /* parse caps here to check subclass;
@ -505,13 +487,11 @@ refuse_caps:
} }
static gboolean static gboolean
gst_base_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps) gst_base_audio_decoder_sink_setcaps (GstBaseAudioDecoder * dec, GstCaps * caps)
{ {
GstBaseAudioDecoder *dec;
GstBaseAudioDecoderClass *klass; GstBaseAudioDecoderClass *klass;
gboolean res = TRUE; gboolean res = TRUE;
dec = GST_BASE_AUDIO_DECODER (gst_pad_get_parent (pad));
klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec); klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (dec, "caps: %" GST_PTR_FORMAT, caps);
@ -527,7 +507,6 @@ gst_base_audio_decoder_sink_setcaps (GstPad * pad, GstCaps * caps)
if (klass->set_format) if (klass->set_format)
res = klass->set_format (dec, caps); res = klass->set_format (dec, caps);
g_object_unref (dec);
return res; return res;
} }
@ -571,8 +550,9 @@ gst_base_audio_decoder_output (GstBaseAudioDecoder * dec, GstBuffer * buf)
if (G_LIKELY (buf)) { if (G_LIKELY (buf)) {
g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR); g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
GST_LOG_OBJECT (dec, "output buffer of size %d with ts %" GST_TIME_FORMAT GST_LOG_OBJECT (dec,
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), "output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
@ -583,9 +563,9 @@ gst_base_audio_decoder_output (GstBaseAudioDecoder * dec, GstBuffer * buf)
GST_DEBUG_OBJECT (dec, "no data after clipping to segment"); GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
} else { } else {
GST_LOG_OBJECT (dec, GST_LOG_OBJECT (dec,
"buffer after segment clipping has size %d with ts %" GST_TIME_FORMAT "buffer after segment clipping has size %" G_GSIZE_FORMAT " with ts %"
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
} }
} else { } else {
@ -622,7 +602,7 @@ again:
} }
gst_adapter_push (priv->adapter_out, buf); gst_adapter_push (priv->adapter_out, buf);
priv->out_dur += GST_BUFFER_DURATION (buf); priv->out_dur += GST_BUFFER_DURATION (buf);
av += GST_BUFFER_SIZE (buf); av += gst_buffer_get_size (buf);
buf = NULL; buf = NULL;
} }
if (priv->out_dur > dec->priv->latency) if (priv->out_dur > dec->priv->latency)
@ -640,9 +620,6 @@ again:
if (G_LIKELY (buf)) { if (G_LIKELY (buf)) {
/* decorate */
gst_buffer_set_caps (buf, GST_PAD_CAPS (dec->srcpad));
if (G_UNLIKELY (priv->discont)) { if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (dec, "marking discont"); GST_LOG_OBJECT (dec, "marking discont");
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
@ -652,7 +629,7 @@ again:
if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) { if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
/* duration should always be valid for raw audio */ /* duration should always be valid for raw audio */
g_assert (GST_BUFFER_DURATION_IS_VALID (buf)); g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
dec->segment.last_stop = dec->segment.position =
GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf); GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
} }
@ -669,7 +646,7 @@ again:
} }
GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT GST_LOG_OBJECT (dec, "pushing buffer of size %d with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buf),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
@ -700,29 +677,30 @@ gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf,
GstBaseAudioDecoderContext *ctx; GstBaseAudioDecoderContext *ctx;
gint samples = 0; gint samples = 0;
GstClockTime ts, next_ts; GstClockTime ts, next_ts;
gsize size;
/* subclass should know what it is producing by now */ /* subclass should know what it is producing by now */
g_return_val_if_fail (buf == NULL || GST_PAD_CAPS (dec->srcpad) != NULL, g_return_val_if_fail (buf == NULL || gst_pad_has_current_caps (dec->srcpad),
GST_FLOW_ERROR); GST_FLOW_ERROR);
/* subclass should not hand us no data */ /* subclass should not hand us no data */
g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0, g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
GST_FLOW_ERROR); GST_FLOW_ERROR);
/* no dummy calls please */ /* no dummy calls please */
g_return_val_if_fail (frames != 0, GST_FLOW_ERROR); g_return_val_if_fail (frames != 0, GST_FLOW_ERROR);
priv = dec->priv; priv = dec->priv;
ctx = &dec->priv->ctx; ctx = &dec->priv->ctx;
size = buf ? gst_buffer_get_size (buf) : 0;
GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames", GST_LOG_OBJECT (dec, "accepting %d bytes == %d samples for %d frames",
buf ? GST_BUFFER_SIZE (buf) : -1, buf ? size : -1, buf ? size / ctx->info.bpf : -1, frames);
buf ? GST_BUFFER_SIZE (buf) / ctx->info.bpf : -1, frames);
/* output shoud be whole number of sample frames */ /* output shoud be whole number of sample frames */
if (G_LIKELY (buf && ctx->info.bpf)) { if (G_LIKELY (buf && ctx->info.bpf)) {
if (GST_BUFFER_SIZE (buf) % ctx->info.bpf) if (size % ctx->info.bpf)
goto wrong_buffer; goto wrong_buffer;
/* per channel least */ /* per channel least */
samples = GST_BUFFER_SIZE (buf) / ctx->info.bpf; samples = size / ctx->info.bpf;
} }
/* frame and ts book-keeping */ /* frame and ts book-keeping */
@ -802,7 +780,7 @@ gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstBuffer * buf,
priv->taglist = NULL; priv->taglist = NULL;
} }
buf = gst_buffer_make_metadata_writable (buf); buf = gst_buffer_make_writable (buf);
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) { if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (buf) =
priv->base_ts + priv->base_ts +
@ -829,8 +807,7 @@ exit:
wrong_buffer: wrong_buffer:
{ {
GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL), GST_ELEMENT_ERROR (dec, STREAM, ENCODE, (NULL),
("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buf), ("buffer size %d not a multiple of %d", size, ctx->info.bpf));
ctx->info.bpf));
gst_buffer_unref (buf); gst_buffer_unref (buf);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -850,13 +827,13 @@ gst_base_audio_decoder_handle_frame (GstBaseAudioDecoder * dec,
GstBaseAudioDecoderClass * klass, GstBuffer * buffer) GstBaseAudioDecoderClass * klass, GstBuffer * buffer)
{ {
if (G_LIKELY (buffer)) { if (G_LIKELY (buffer)) {
gsize size = gst_buffer_get_size (buffer);
/* keep around for admin */ /* keep around for admin */
GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT, GST_LOG_OBJECT (dec, "tracking frame size %d, ts %" GST_TIME_FORMAT,
GST_BUFFER_SIZE (buffer), size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
g_queue_push_tail (&dec->priv->frames, buffer); g_queue_push_tail (&dec->priv->frames, buffer);
dec->priv->ctx.delay = dec->priv->frames.length; dec->priv->ctx.delay = dec->priv->frames.length;
dec->priv->bytes_in += GST_BUFFER_SIZE (buffer); dec->priv->bytes_in += size;
} else { } else {
GST_LOG_OBJECT (dec, "providing subclass with NULL frame"); GST_LOG_OBJECT (dec, "providing subclass with NULL frame");
} }
@ -941,7 +918,7 @@ gst_base_audio_decoder_push_buffers (GstBaseAudioDecoder * dec, gboolean force)
priv->prev_ts = ts; priv->prev_ts = ts;
} }
buffer = gst_adapter_take_buffer (priv->adapter, len); buffer = gst_adapter_take_buffer (priv->adapter, len);
buffer = gst_buffer_make_metadata_writable (buffer); buffer = gst_buffer_make_writable (buffer);
GST_BUFFER_TIMESTAMP (buffer) = ts; GST_BUFFER_TIMESTAMP (buffer) = ts;
flush += len; flush += len;
} else { } else {
@ -1179,10 +1156,10 @@ gst_base_audio_decoder_flush_decode (GstBaseAudioDecoder * dec)
if (G_LIKELY (res == GST_FLOW_OK)) { if (G_LIKELY (res == GST_FLOW_OK)) {
GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, " GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, "
"time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf, "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
/* should be already, but let's be sure */ /* should be already, but let's be sure */
buf = gst_buffer_make_metadata_writable (buf); buf = gst_buffer_make_writable (buf);
/* avoid stray DISCONT from forward processing, /* avoid stray DISCONT from forward processing,
* which have no meaning in reverse pushing */ * which have no meaning in reverse pushing */
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
@ -1223,7 +1200,7 @@ gst_base_audio_decoder_chain_reverse (GstBaseAudioDecoder * dec,
if (G_LIKELY (buf)) { if (G_LIKELY (buf)) {
GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, " GST_DEBUG_OBJECT (dec, "gathering buffer %p of size %u, "
"time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf, "time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
/* add buffer to gather queue */ /* add buffer to gather queue */
@ -1243,7 +1220,7 @@ gst_base_audio_decoder_chain (GstPad * pad, GstBuffer * buffer)
GST_LOG_OBJECT (dec, GST_LOG_OBJECT (dec,
"received buffer of size %d with ts %" GST_TIME_FORMAT "received buffer of size %d with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer))); GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
@ -1292,46 +1269,35 @@ gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec,
gboolean handled = FALSE; gboolean handled = FALSE;
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT: case GST_EVENT_SEGMENT:
{ {
GstFormat format; GstSegment seg;
gdouble rate, arate;
gint64 start, stop, time;
gboolean update;
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, gst_event_copy_segment (event, &seg);
&start, &stop, &time);
if (format == GST_FORMAT_TIME) { if (seg.format == GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (dec, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT GST_DEBUG_OBJECT (dec, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
" -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
", rate %g, applied_rate %g",
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
rate, arate);
} else { } else {
GstFormat dformat = GST_FORMAT_TIME; gint64 nstart;
GST_DEBUG_OBJECT (dec, "received SEGMENT %" GST_PTR_FORMAT, &seg);
GST_DEBUG_OBJECT (dec, "received NEW_SEGMENT %" G_GINT64_FORMAT
" -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
", rate %g, applied_rate %g", start, stop, time, rate, arate);
/* handle newsegment resulting from legacy simple seeking */ /* handle newsegment resulting from legacy simple seeking */
/* note that we need to convert this whether or not enough data /* note that we need to convert this whether or not enough data
* to handle initial newsegment */ * to handle initial newsegment */
if (dec->priv->ctx.do_byte_time && if (dec->priv->ctx.do_byte_time &&
gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, start, gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, seg.start,
&dformat, &start)) { GST_FORMAT_TIME, &nstart)) {
/* best attempt convert */ /* best attempt convert */
/* as these are only estimates, stop is kept open-ended to avoid /* as these are only estimates, stop is kept open-ended to avoid
* premature cutting */ * premature cutting */
GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT, GST_DEBUG_OBJECT (dec, "converted to TIME start %" GST_TIME_FORMAT,
GST_TIME_ARGS (start)); GST_TIME_ARGS (nstart));
format = GST_FORMAT_TIME; seg.format = GST_FORMAT_TIME;
time = start; seg.start = nstart;
stop = GST_CLOCK_TIME_NONE; seg.time = nstart;
seg.stop = GST_CLOCK_TIME_NONE;
/* replace event */ /* replace event */
gst_event_unref (event); gst_event_unref (event);
event = gst_event_new_new_segment_full (update, rate, arate, event = gst_event_new_segment (&seg);
GST_FORMAT_TIME, start, stop, time);
} else { } else {
GST_DEBUG_OBJECT (dec, "unsupported format; ignoring"); GST_DEBUG_OBJECT (dec, "unsupported format; ignoring");
break; break;
@ -1341,41 +1307,42 @@ gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec,
/* finish current segment */ /* finish current segment */
gst_base_audio_decoder_drain (dec); gst_base_audio_decoder_drain (dec);
#if 0
if (update) { if (update) {
/* time progressed without data, see if we can fill the gap with /* time progressed without data, see if we can fill the gap with
* some concealment data */ * some concealment data */
GST_DEBUG_OBJECT (dec, GST_DEBUG_OBJECT (dec,
"segment update: plc %d, do_plc %d, last_stop %" GST_TIME_FORMAT, "segment update: plc %d, do_plc %d, position %" GST_TIME_FORMAT,
dec->priv->plc, dec->priv->ctx.do_plc, dec->priv->plc, dec->priv->ctx.do_plc,
GST_TIME_ARGS (dec->segment.last_stop)); GST_TIME_ARGS (dec->segment.position));
if (dec->priv->plc && dec->priv->ctx.do_plc && if (dec->priv->plc && dec->priv->ctx.do_plc &&
dec->segment.rate > 0.0 && dec->segment.last_stop < start) { dec->segment.rate > 0.0 && dec->segment.position < start) {
GstBaseAudioDecoderClass *klass; GstBaseAudioDecoderClass *klass;
GstBuffer *buf; GstBuffer *buf;
klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec); klass = GST_BASE_AUDIO_DECODER_GET_CLASS (dec);
/* hand subclass empty frame with duration that needs covering */ /* hand subclass empty frame with duration that needs covering */
buf = gst_buffer_new (); buf = gst_buffer_new ();
GST_BUFFER_DURATION (buf) = start - dec->segment.last_stop; GST_BUFFER_DURATION (buf) = start - dec->segment.position;
/* best effort, not much error handling */ /* best effort, not much error handling */
gst_base_audio_decoder_handle_frame (dec, klass, buf); gst_base_audio_decoder_handle_frame (dec, klass, buf);
} }
} else { } else
#endif
{
/* prepare for next one */ /* prepare for next one */
gst_base_audio_decoder_flush (dec, FALSE); gst_base_audio_decoder_flush (dec, FALSE);
/* and that's where we time from, /* and that's where we time from,
* in case upstream does not come up with anything better * in case upstream does not come up with anything better
* (e.g. upstream BYTE) */ * (e.g. upstream BYTE) */
if (format != GST_FORMAT_TIME) { if (seg.format != GST_FORMAT_TIME) {
dec->priv->base_ts = start; dec->priv->base_ts = seg.start;
dec->priv->samples = 0; dec->priv->samples = 0;
} }
} }
/* and follow along with segment */ /* and follow along with segment */
gst_segment_set_newsegment_full (&dec->segment, update, rate, arate, dec->segment = seg;
format, start, stop, time);
gst_pad_push_event (dec->srcpad, event); gst_pad_push_event (dec->srcpad, event);
handled = TRUE; handled = TRUE;
break; break;
@ -1393,6 +1360,16 @@ gst_base_audio_decoder_sink_eventfunc (GstBaseAudioDecoder * dec,
gst_base_audio_decoder_drain (dec); gst_base_audio_decoder_drain (dec);
break; break;
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
gst_base_audio_decoder_sink_setcaps (dec, caps);
gst_event_unref (event);
handled = TRUE;
break;
}
default: default:
break; break;
} }
@ -1466,13 +1443,12 @@ gst_base_audio_decoder_do_seek (GstBaseAudioDecoder * dec, GstEvent * event)
} }
memcpy (&seek_segment, &dec->segment, sizeof (seek_segment)); memcpy (&seek_segment, &dec->segment, sizeof (seek_segment));
gst_segment_set_seek (&seek_segment, rate, format, flags, start_type, gst_segment_do_seek (&seek_segment, rate, format, flags, start_type,
start_time, end_type, end_time, NULL); start_time, end_type, end_time, NULL);
start_time = seek_segment.last_stop; start_time = seek_segment.position;
format = GST_FORMAT_BYTES;
if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time, if (!gst_pad_query_convert (dec->sinkpad, GST_FORMAT_TIME, start_time,
&format, &start)) { GST_FORMAT_BYTES, &start)) {
GST_DEBUG_OBJECT (dec, "conversion failed"); GST_DEBUG_OBJECT (dec, "conversion failed");
return FALSE; return FALSE;
} }
@ -1502,7 +1478,7 @@ gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK: case GST_EVENT_SEEK:
{ {
GstFormat format, tformat; GstFormat format;
gdouble rate; gdouble rate;
GstSeekFlags flags; GstSeekFlags flags;
GstSeekType cur_type, stop_type; GstSeekType cur_type, stop_type;
@ -1527,10 +1503,12 @@ gst_base_audio_decoder_src_event (GstPad * pad, GstEvent * event)
/* ... though a non-time seek can be aided as well */ /* ... though a non-time seek can be aided as well */
/* First bring the requested format to time */ /* First bring the requested format to time */
tformat = GST_FORMAT_TIME; if (!(res =
if (!(res = gst_pad_query_convert (pad, format, cur, &tformat, &tcur))) gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &tcur)))
goto convert_error; goto convert_error;
if (!(res = gst_pad_query_convert (pad, format, stop, &tformat, &tstop))) if (!(res =
gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME,
&tstop)))
goto convert_error; goto convert_error;
/* then seek with time on the peer */ /* then seek with time on the peer */
@ -1711,12 +1689,11 @@ gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
if (format == GST_FORMAT_TIME && gst_base_audio_decoder_do_byte (dec)) { if (format == GST_FORMAT_TIME && gst_base_audio_decoder_do_byte (dec)) {
gint64 value; gint64 value;
format = GST_FORMAT_BYTES; if (gst_pad_query_peer_duration (dec->sinkpad, GST_FORMAT_BYTES,
if (gst_pad_query_peer_duration (dec->sinkpad, &format, &value)) { &value)) {
GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value); GST_LOG_OBJECT (dec, "upstream size %" G_GINT64_FORMAT, value);
format = GST_FORMAT_TIME;
if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value, if (gst_pad_query_convert (dec->sinkpad, GST_FORMAT_BYTES, value,
&format, &value)) { GST_FORMAT_TIME, &value)) {
gst_query_set_duration (query, GST_FORMAT_TIME, value); gst_query_set_duration (query, GST_FORMAT_TIME, value);
res = TRUE; res = TRUE;
} }
@ -1735,7 +1712,7 @@ gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
} }
/* we start from the last seen time */ /* we start from the last seen time */
time = dec->segment.last_stop; time = dec->segment.position;
/* correct for the segment values */ /* correct for the segment values */
time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time); time = gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, time);
@ -1745,7 +1722,7 @@ gst_base_audio_decoder_src_query (GstPad * pad, GstQuery * query)
/* and convert to the final format */ /* and convert to the final format */
gst_query_parse_position (query, &format, NULL); gst_query_parse_position (query, &format, NULL);
if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time, if (!(res = gst_pad_query_convert (pad, GST_FORMAT_TIME, time,
&format, &value))) format, &value)))
break; break;
gst_query_set_position (query, format, value); gst_query_set_position (query, format, value);
@ -1923,7 +1900,7 @@ gst_base_audio_decoder_change_state (GstElement * element,
break; break;
} }
ret = parent_class->change_state (element, transition); ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED: case GST_STATE_CHANGE_PLAYING_TO_PAUSED:

View file

@ -224,6 +224,8 @@ struct _GstBaseAudioDecoderClass
gpointer _gst_reserved[GST_PADDING_LARGE]; gpointer _gst_reserved[GST_PADDING_LARGE];
}; };
gboolean gst_base_audio_decoder_src_setcaps (GstBaseAudioDecoder * dec,
GstCaps * caps);
GstFlowReturn gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec, GstFlowReturn gst_base_audio_decoder_finish_frame (GstBaseAudioDecoder * dec,
GstBuffer * buf, gint frames); GstBuffer * buf, gint frames);

View file

@ -151,7 +151,6 @@
# include "config.h" # include "config.h"
#endif #endif
#define GST_USE_UNSTABLE_API
#include "gstbaseaudioencoder.h" #include "gstbaseaudioencoder.h"
#include <gst/base/gstadapter.h> #include <gst/base/gstadapter.h>
#include <gst/audio/audio.h> #include <gst/audio/audio.h>
@ -295,8 +294,6 @@ static gboolean gst_base_audio_encoder_sink_activate_push (GstPad * pad,
static gboolean gst_base_audio_encoder_sink_event (GstPad * pad, static gboolean gst_base_audio_encoder_sink_event (GstPad * pad,
GstEvent * event); GstEvent * event);
static gboolean gst_base_audio_encoder_sink_setcaps (GstPad * pad,
GstCaps * caps);
static GstFlowReturn gst_base_audio_encoder_chain (GstPad * pad, static GstFlowReturn gst_base_audio_encoder_chain (GstPad * pad,
GstBuffer * buffer); GstBuffer * buffer);
static gboolean gst_base_audio_encoder_src_query (GstPad * pad, static gboolean gst_base_audio_encoder_src_query (GstPad * pad,
@ -305,7 +302,8 @@ static gboolean gst_base_audio_encoder_sink_query (GstPad * pad,
GstQuery * query); GstQuery * query);
static const GstQueryType *gst_base_audio_encoder_get_query_types (GstPad * static const GstQueryType *gst_base_audio_encoder_get_query_types (GstPad *
pad); pad);
static GstCaps *gst_base_audio_encoder_sink_getcaps (GstPad * pad); static GstCaps *gst_base_audio_encoder_sink_getcaps (GstPad * pad,
GstCaps * filter);
static void static void
@ -363,8 +361,6 @@ gst_base_audio_encoder_init (GstBaseAudioEncoder * enc,
enc->sinkpad = gst_pad_new_from_template (pad_template, "sink"); enc->sinkpad = gst_pad_new_from_template (pad_template, "sink");
gst_pad_set_event_function (enc->sinkpad, gst_pad_set_event_function (enc->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_encoder_sink_event)); GST_DEBUG_FUNCPTR (gst_base_audio_encoder_sink_event));
gst_pad_set_setcaps_function (enc->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_encoder_sink_setcaps));
gst_pad_set_getcaps_function (enc->sinkpad, gst_pad_set_getcaps_function (enc->sinkpad,
GST_DEBUG_FUNCPTR (gst_base_audio_encoder_sink_getcaps)); GST_DEBUG_FUNCPTR (gst_base_audio_encoder_sink_getcaps));
gst_pad_set_query_function (enc->sinkpad, gst_pad_set_query_function (enc->sinkpad,
@ -412,7 +408,7 @@ gst_base_audio_encoder_reset (GstBaseAudioEncoder * enc, gboolean full)
enc->priv->active = FALSE; enc->priv->active = FALSE;
enc->priv->samples_in = 0; enc->priv->samples_in = 0;
enc->priv->bytes_out = 0; enc->priv->bytes_out = 0;
gst_audio_info_clear (&enc->priv->ctx.info); gst_audio_info_init (&enc->priv->ctx.info);
memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx)); memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
} }
@ -479,13 +475,13 @@ gst_base_audio_encoder_finish_frame (GstBaseAudioEncoder * enc, GstBuffer * buf,
ctx = &enc->priv->ctx; ctx = &enc->priv->ctx;
/* subclass should know what it is producing by now */ /* subclass should know what it is producing by now */
g_return_val_if_fail (GST_PAD_CAPS (enc->srcpad) != NULL, GST_FLOW_ERROR); g_return_val_if_fail (gst_pad_has_current_caps (enc->srcpad), GST_FLOW_ERROR);
/* subclass should not hand us no data */ /* subclass should not hand us no data */
g_return_val_if_fail (buf == NULL || GST_BUFFER_SIZE (buf) > 0, g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0,
GST_FLOW_ERROR); GST_FLOW_ERROR);
GST_LOG_OBJECT (enc, "accepting %d bytes encoded data as %d samples", GST_LOG_OBJECT (enc, "accepting %d bytes encoded data as %d samples",
buf ? GST_BUFFER_SIZE (buf) : -1, samples); buf ? gst_buffer_get_size (buf) : -1, samples);
/* mark subclass still alive and providing */ /* mark subclass still alive and providing */
priv->got_data = TRUE; priv->got_data = TRUE;
@ -563,11 +559,14 @@ gst_base_audio_encoder_finish_frame (GstBaseAudioEncoder * enc, GstBuffer * buf,
/* collect output */ /* collect output */
if (G_LIKELY (buf)) { if (G_LIKELY (buf)) {
GST_LOG_OBJECT (enc, "taking %d bytes for output", GST_BUFFER_SIZE (buf)); gsize size;
buf = gst_buffer_make_metadata_writable (buf);
size = gst_buffer_get_size (buf);
GST_LOG_OBJECT (enc, "taking %d bytes for output", size);
buf = gst_buffer_make_writable (buf);
/* decorate */ /* decorate */
gst_buffer_set_caps (buf, GST_PAD_CAPS (enc->srcpad));
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) { if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) {
/* FIXME ? lookahead could lead to weird ts and duration ? /* FIXME ? lookahead could lead to weird ts and duration ?
* (particularly if not in perfect mode) */ * (particularly if not in perfect mode) */
@ -599,11 +598,11 @@ gst_base_audio_encoder_finish_frame (GstBaseAudioEncoder * enc, GstBuffer * buf,
ctx->info.rate); ctx->info.rate);
} else { } else {
GST_BUFFER_OFFSET (buf) = priv->bytes_out; GST_BUFFER_OFFSET (buf) = priv->bytes_out;
GST_BUFFER_OFFSET_END (buf) = priv->bytes_out + GST_BUFFER_SIZE (buf); GST_BUFFER_OFFSET_END (buf) = priv->bytes_out + size;
} }
} }
priv->bytes_out += GST_BUFFER_SIZE (buf); priv->bytes_out += size;
if (G_UNLIKELY (priv->discont)) { if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (enc, "marking discont"); GST_LOG_OBJECT (enc, "marking discont");
@ -624,7 +623,7 @@ gst_base_audio_encoder_finish_frame (GstBaseAudioEncoder * enc, GstBuffer * buf,
} }
GST_LOG_OBJECT (enc, "pushing buffer of size %d with ts %" GST_TIME_FORMAT GST_LOG_OBJECT (enc, "pushing buffer of size %d with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buf), ", duration %" GST_TIME_FORMAT, size,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
@ -705,10 +704,12 @@ gst_base_audio_encoder_push_buffers (GstBaseAudioEncoder * enc, gboolean force)
} }
if (need) { if (need) {
buf = gst_buffer_new (); const guint8 *data;
GST_BUFFER_DATA (buf) = (guint8 *)
gst_adapter_peek (priv->adapter, priv->offset + need) + priv->offset; data = gst_adapter_map (priv->adapter, priv->offset + need);
GST_BUFFER_SIZE (buf) = need; buf =
gst_buffer_new_wrapped_full ((gpointer) data, NULL, priv->offset,
need);
} }
GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d", GST_LOG_OBJECT (enc, "providing subclass with %d bytes at offset %d",
@ -722,8 +723,10 @@ gst_base_audio_encoder_push_buffers (GstBaseAudioEncoder * enc, gboolean force)
priv->got_data = FALSE; priv->got_data = FALSE;
ret = klass->handle_frame (enc, buf); ret = klass->handle_frame (enc, buf);
if (G_LIKELY (buf)) if (G_LIKELY (buf)) {
gst_buffer_unref (buf); gst_buffer_unref (buf);
gst_adapter_unmap (priv->adapter, 0);
}
/* no data to feed, no leftover provided, then bail out */ /* no data to feed, no leftover provided, then bail out */
if (G_UNLIKELY (!buf && !priv->got_data)) { if (G_UNLIKELY (!buf && !priv->got_data)) {
@ -780,6 +783,7 @@ gst_base_audio_encoder_chain (GstPad * pad, GstBuffer * buffer)
GstBaseAudioEncoderContext *ctx; GstBaseAudioEncoderContext *ctx;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gboolean discont; gboolean discont;
gsize size;
enc = GST_BASE_AUDIO_ENCODER (GST_OBJECT_PARENT (pad)); enc = GST_BASE_AUDIO_ENCODER (GST_OBJECT_PARENT (pad));
@ -790,14 +794,16 @@ gst_base_audio_encoder_chain (GstPad * pad, GstBuffer * buffer)
if (!ctx->info.bpf) if (!ctx->info.bpf)
goto not_negotiated; goto not_negotiated;
size = gst_buffer_get_size (buffer);
GST_LOG_OBJECT (enc, GST_LOG_OBJECT (enc,
"received buffer of size %d with ts %" GST_TIME_FORMAT "received buffer of size %d with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), ", duration %" GST_TIME_FORMAT, size,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer))); GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
/* input shoud be whole number of sample frames */ /* input shoud be whole number of sample frames */
if (GST_BUFFER_SIZE (buffer) % ctx->info.bpf) if (size % ctx->info.bpf)
goto wrong_buffer; goto wrong_buffer;
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
@ -806,7 +812,7 @@ gst_base_audio_encoder_chain (GstPad * pad, GstBuffer * buffer)
GstClockTimeDiff diff; GstClockTimeDiff diff;
/* verify buffer duration */ /* verify buffer duration */
duration = gst_util_uint64_scale (GST_BUFFER_SIZE (buffer), GST_SECOND, duration = gst_util_uint64_scale (size, GST_SECOND,
ctx->info.rate * ctx->info.bpf); ctx->info.rate * ctx->info.bpf);
diff = GST_CLOCK_DIFF (duration, GST_BUFFER_DURATION (buffer)); diff = GST_CLOCK_DIFF (duration, GST_BUFFER_DURATION (buffer));
if (GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE && if (GST_BUFFER_DURATION (buffer) != GST_CLOCK_TIME_NONE &&
@ -835,9 +841,11 @@ gst_base_audio_encoder_chain (GstPad * pad, GstBuffer * buffer)
goto done; goto done;
} }
size = gst_buffer_get_size (buffer);
GST_LOG_OBJECT (enc, GST_LOG_OBJECT (enc,
"buffer after segment clipping has size %d with ts %" GST_TIME_FORMAT "buffer after segment clipping has size %d with ts %" GST_TIME_FORMAT
", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer), ", duration %" GST_TIME_FORMAT, size,
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
GST_TIME_ARGS (GST_BUFFER_DURATION (buffer))); GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
@ -888,13 +896,12 @@ gst_base_audio_encoder_chain (GstPad * pad, GstBuffer * buffer)
diff_bytes = diff_bytes =
GST_CLOCK_TIME_TO_FRAMES (-diff, ctx->info.rate) * ctx->info.bpf; GST_CLOCK_TIME_TO_FRAMES (-diff, ctx->info.rate) * ctx->info.bpf;
if (diff_bytes >= GST_BUFFER_SIZE (buffer)) { if (diff_bytes >= size) {
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
goto done; goto done;
} }
buffer = gst_buffer_make_metadata_writable (buffer); buffer = gst_buffer_make_writable (buffer);
GST_BUFFER_DATA (buffer) += diff_bytes; gst_buffer_resize (buffer, diff_bytes, size - diff_bytes);
GST_BUFFER_SIZE (buffer) -= diff_bytes;
GST_BUFFER_TIMESTAMP (buffer) += diff; GST_BUFFER_TIMESTAMP (buffer) += diff;
/* care even less about duration after this */ /* care even less about duration after this */
@ -930,7 +937,7 @@ not_negotiated:
wrong_buffer: wrong_buffer:
{ {
GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
("buffer size %d not a multiple of %d", GST_BUFFER_SIZE (buffer), ("buffer size %d not a multiple of %d", gst_buffer_get_size (buffer),
ctx->info.bpf)); ctx->info.bpf));
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
@ -955,23 +962,20 @@ audio_info_is_equal (GstAudioInfo * from, GstAudioInfo * to)
} }
static gboolean static gboolean
gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps) gst_base_audio_encoder_sink_setcaps (GstBaseAudioEncoder * enc, GstCaps * caps)
{ {
GstBaseAudioEncoder *enc;
GstBaseAudioEncoderClass *klass; GstBaseAudioEncoderClass *klass;
GstBaseAudioEncoderContext *ctx; GstBaseAudioEncoderContext *ctx;
GstAudioInfo *state, *old_state; GstAudioInfo state;
gboolean res = TRUE, changed = FALSE; gboolean res = TRUE, changed = FALSE;
guint old_rate; guint old_rate;
enc = GST_BASE_AUDIO_ENCODER (GST_PAD_PARENT (pad));
klass = GST_BASE_AUDIO_ENCODER_GET_CLASS (enc); klass = GST_BASE_AUDIO_ENCODER_GET_CLASS (enc);
/* subclass must do something here ... */ /* subclass must do something here ... */
g_return_val_if_fail (klass->set_format != NULL, FALSE); g_return_val_if_fail (klass->set_format != NULL, FALSE);
ctx = &enc->priv->ctx; ctx = &enc->priv->ctx;
state = &ctx->info;
GST_DEBUG_OBJECT (enc, "caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (enc, "caps: %" GST_PTR_FORMAT, caps);
@ -979,19 +983,17 @@ gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
goto refuse_caps; goto refuse_caps;
/* adjust ts tracking to new sample rate */ /* adjust ts tracking to new sample rate */
old_rate = GST_AUDIO_INFO_RATE (state); old_rate = GST_AUDIO_INFO_RATE (&ctx->info);
if (GST_CLOCK_TIME_IS_VALID (enc->priv->base_ts) && old_rate) { if (GST_CLOCK_TIME_IS_VALID (enc->priv->base_ts) && old_rate) {
enc->priv->base_ts += enc->priv->base_ts +=
GST_FRAMES_TO_CLOCK_TIME (enc->priv->samples, old_rate); GST_FRAMES_TO_CLOCK_TIME (enc->priv->samples, old_rate);
enc->priv->samples = 0; enc->priv->samples = 0;
} }
old_state = gst_audio_info_copy (state); if (!gst_audio_info_from_caps (&state, caps))
if (!gst_audio_info_from_caps (state, caps))
goto refuse_caps; goto refuse_caps;
changed = audio_info_is_equal (state, old_state); changed = audio_info_is_equal (&state, &ctx->info);
gst_audio_info_free (old_state);
if (changed) { if (changed) {
GstClockTime old_min_latency; GstClockTime old_min_latency;
@ -1012,7 +1014,7 @@ gst_base_audio_encoder_sink_setcaps (GstPad * pad, GstCaps * caps)
GST_OBJECT_UNLOCK (enc); GST_OBJECT_UNLOCK (enc);
if (klass->set_format) if (klass->set_format)
res = klass->set_format (enc, state); res = klass->set_format (enc, &state);
/* notify if new latency */ /* notify if new latency */
GST_OBJECT_LOCK (enc); GST_OBJECT_LOCK (enc);
@ -1109,7 +1111,7 @@ done:
} }
static GstCaps * static GstCaps *
gst_base_audio_encoder_sink_getcaps (GstPad * pad) gst_base_audio_encoder_sink_getcaps (GstPad * pad, GstCaps * filter)
{ {
GstBaseAudioEncoder *enc; GstBaseAudioEncoder *enc;
GstBaseAudioEncoderClass *klass; GstBaseAudioEncoderClass *klass;
@ -1120,7 +1122,7 @@ gst_base_audio_encoder_sink_getcaps (GstPad * pad)
g_assert (pad == enc->sinkpad); g_assert (pad == enc->sinkpad);
if (klass->getcaps) if (klass->getcaps)
caps = klass->getcaps (enc); caps = klass->getcaps (enc, filter);
else else
caps = gst_base_audio_encoder_proxy_getcaps (enc, NULL); caps = gst_base_audio_encoder_proxy_getcaps (enc, NULL);
gst_object_unref (enc); gst_object_unref (enc);
@ -1140,26 +1142,16 @@ gst_base_audio_encoder_sink_eventfunc (GstBaseAudioEncoder * enc,
klass = GST_BASE_AUDIO_ENCODER_GET_CLASS (enc); klass = GST_BASE_AUDIO_ENCODER_GET_CLASS (enc);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT: case GST_EVENT_SEGMENT:
{ {
GstFormat format; GstSegment seg;
gdouble rate, arate;
gint64 start, stop, time;
gboolean update;
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format, gst_event_copy_segment (event, &seg);
&start, &stop, &time);
if (format == GST_FORMAT_TIME) { if (seg.format == GST_FORMAT_TIME) {
GST_DEBUG_OBJECT (enc, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT GST_DEBUG_OBJECT (enc, "received TIME SEGMENT %" GST_PTR_FORMAT, &seg);
" -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
", rate %g, applied_rate %g",
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (time),
rate, arate);
} else { } else {
GST_DEBUG_OBJECT (enc, "received NEW_SEGMENT %" G_GINT64_FORMAT GST_DEBUG_OBJECT (enc, "received SEGMENT %" GST_PTR_FORMAT, &seg);
" -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
", rate %g, applied_rate %g", start, stop, time, rate, arate);
GST_DEBUG_OBJECT (enc, "unsupported format; ignoring"); GST_DEBUG_OBJECT (enc, "unsupported format; ignoring");
break; break;
} }
@ -1169,8 +1161,7 @@ gst_base_audio_encoder_sink_eventfunc (GstBaseAudioEncoder * enc,
/* reset partially for new segment */ /* reset partially for new segment */
gst_base_audio_encoder_reset (enc, FALSE); gst_base_audio_encoder_reset (enc, FALSE);
/* and follow along with segment */ /* and follow along with segment */
gst_segment_set_newsegment_full (&enc->segment, update, rate, arate, enc->segment = seg;
format, start, stop, time);
break; break;
} }
@ -1190,6 +1181,17 @@ gst_base_audio_encoder_sink_eventfunc (GstBaseAudioEncoder * enc,
gst_base_audio_encoder_drain (enc); gst_base_audio_encoder_drain (enc);
break; break;
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
gst_base_audio_encoder_sink_setcaps (enc, caps);
gst_event_unref (event);
handled = TRUE;
break;
}
default: default:
break; break;
} }
@ -1385,10 +1387,10 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query)
gst_query_parse_position (query, &req_fmt, NULL); gst_query_parse_position (query, &req_fmt, NULL);
fmt = GST_FORMAT_TIME; fmt = GST_FORMAT_TIME;
if (!(res = gst_pad_query_position (peerpad, &fmt, &pos))) if (!(res = gst_pad_query_position (peerpad, fmt, &pos)))
break; break;
if ((res = gst_pad_query_convert (peerpad, fmt, pos, &req_fmt, &val))) { if ((res = gst_pad_query_convert (peerpad, fmt, pos, req_fmt, &val))) {
gst_query_set_position (query, req_fmt, val); gst_query_set_position (query, req_fmt, val);
} }
break; break;
@ -1410,10 +1412,10 @@ gst_base_audio_encoder_src_query (GstPad * pad, GstQuery * query)
gst_query_parse_duration (query, &req_fmt, NULL); gst_query_parse_duration (query, &req_fmt, NULL);
fmt = GST_FORMAT_TIME; fmt = GST_FORMAT_TIME;
if (!(res = gst_pad_query_duration (peerpad, &fmt, &dur))) if (!(res = gst_pad_query_duration (peerpad, fmt, &dur)))
break; break;
if ((res = gst_pad_query_convert (peerpad, fmt, dur, &req_fmt, &val))) { if ((res = gst_pad_query_convert (peerpad, fmt, dur, req_fmt, &val))) {
gst_query_set_duration (query, req_fmt, val); gst_query_set_duration (query, req_fmt, val);
} }
break; break;

View file

@ -178,7 +178,7 @@ struct _GstBaseAudioEncoderClass {
gboolean (*event) (GstBaseAudioEncoder *enc, gboolean (*event) (GstBaseAudioEncoder *enc,
GstEvent *event); GstEvent *event);
GstCaps * (*getcaps) (GstBaseAudioEncoder *enc); GstCaps * (*getcaps) (GstBaseAudioEncoder *enc, GstCaps * filter);
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING_LARGE]; gpointer _gst_reserved[GST_PADDING_LARGE];

View file

@ -72,28 +72,6 @@ post_missing_element_message (GstPlaySinkAudioConvert * self,
gst_element_post_message (GST_ELEMENT_CAST (self), msg); gst_element_post_message (GST_ELEMENT_CAST (self), msg);
} }
static void
distribute_running_time (GstElement * element, const GstSegment * segment)
{
GstEvent *event;
GstPad *pad;
pad = gst_element_get_static_pad (element, "sink");
if (segment->accum) {
event = gst_event_new_new_segment_full (FALSE, segment->rate,
segment->applied_rate, segment->format, 0, segment->accum, 0);
gst_pad_send_event (pad, event);
}
event = gst_event_new_new_segment_full (FALSE, segment->rate,
segment->applied_rate, segment->format,
segment->start, segment->stop, segment->time);
gst_pad_send_event (pad, event);
gst_object_unref (pad);
}
static GstProbeReturn static GstProbeReturn
pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data,
gpointer user_data) gpointer user_data)

View file

@ -72,28 +72,6 @@ post_missing_element_message (GstPlaySinkVideoConvert * self,
gst_element_post_message (GST_ELEMENT_CAST (self), msg); gst_element_post_message (GST_ELEMENT_CAST (self), msg);
} }
static void
distribute_running_time (GstElement * element, const GstSegment * segment)
{
GstEvent *event;
GstPad *pad;
pad = gst_element_get_static_pad (element, "sink");
if (segment->accum) {
event = gst_event_new_new_segment_full (FALSE, segment->rate,
segment->applied_rate, segment->format, 0, segment->accum, 0);
gst_pad_send_event (pad, event);
}
event = gst_event_new_new_segment_full (FALSE, segment->rate,
segment->applied_rate, segment->format,
segment->start, segment->stop, segment->time);
gst_pad_send_event (pad, event);
gst_object_unref (pad);
}
static GstProbeReturn static GstProbeReturn
pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data, pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data,
gpointer user_data) gpointer user_data)