Merge branch 'master' into 0.11

Conflicts:
	gst-libs/gst/audio/gstaudiodecoder.c
This commit is contained in:
Wim Taymans 2011-11-17 17:07:41 +01:00
commit 7afdff3575
4 changed files with 118 additions and 58 deletions

View file

@ -248,6 +248,8 @@ gst_vorbis_enc_stop (GstAudioEncoder * enc)
g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL);
vorbisenc->headers = NULL;
gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
return TRUE;
}

View file

@ -585,47 +585,95 @@ gst_audio_decoder_setup (GstAudioDecoder * dec)
dec->priv->agg = ! !res;
}
/* mini aggregator combining output buffers into fewer larger ones,
* if so allowed/configured */
static GstFlowReturn
gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf)
gst_audio_decoder_push_forward (GstAudioDecoder * dec, GstBuffer * buf)
{
GstAudioDecoderClass *klass;
GstAudioDecoderPrivate *priv;
GstAudioDecoderContext *ctx;
GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *inbuf = NULL;
klass = GST_AUDIO_DECODER_GET_CLASS (dec);
priv = dec->priv;
ctx = &dec->priv->ctx;
g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
if (G_UNLIKELY (!buf)) {
g_assert_not_reached ();
return GST_FLOW_OK;
}
GST_LOG_OBJECT (dec, "clipping buffer of size %d 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_DURATION (buf)));
/* clip buffer */
buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
ctx->info.bpf);
if (G_UNLIKELY (!buf)) {
GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
goto exit;
}
/* decorate */
if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (dec, "marking discont");
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
priv->discont = FALSE;
}
/* track where we are */
if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
/* duration should always be valid for raw audio */
g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
dec->segment.position =
GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
}
if (klass->pre_push) {
/* last chance for subclass to do some dirty stuff */
ret = klass->pre_push (dec, &buf);
if (ret != GST_FLOW_OK || !buf) {
GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
gst_flow_get_name (ret), buf);
if (buf)
gst_buffer_unref (buf);
goto exit;
}
}
GST_LOG_OBJECT (dec, "pushing buffer of size %d 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_DURATION (buf)));
ret = gst_pad_push (dec->srcpad, buf);
exit:
return ret;
}
/* mini aggregator combining output buffers into fewer larger ones,
* if so allowed/configured */
static GstFlowReturn
gst_audio_decoder_output (GstAudioDecoder * dec, GstBuffer * buf)
{
GstAudioDecoderPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *inbuf = NULL;
priv = dec->priv;
if (G_UNLIKELY (priv->agg < 0))
gst_audio_decoder_setup (dec);
if (G_LIKELY (buf)) {
g_return_val_if_fail (ctx->info.bpf != 0, GST_FLOW_ERROR);
GST_LOG_OBJECT (dec,
"output buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
GST_LOG_OBJECT (dec, "output buffer of size %d 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_DURATION (buf)));
/* clip buffer */
buf = gst_audio_buffer_clip (buf, &dec->segment, ctx->info.rate,
ctx->info.bpf);
if (G_UNLIKELY (!buf)) {
GST_DEBUG_OBJECT (dec, "no data after clipping to segment");
} else {
GST_LOG_OBJECT (dec,
"buffer after segment clipping has 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_DURATION (buf)));
}
} else {
GST_DEBUG_OBJECT (dec, "no output buffer");
}
again:
@ -675,39 +723,8 @@ again:
}
if (G_LIKELY (buf)) {
if (G_UNLIKELY (priv->discont)) {
GST_LOG_OBJECT (dec, "marking discont");
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
priv->discont = FALSE;
}
if (G_LIKELY (GST_BUFFER_TIMESTAMP_IS_VALID (buf))) {
/* duration should always be valid for raw audio */
g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
dec->segment.position =
GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
}
if (klass->pre_push) {
/* last chance for subclass to do some dirty stuff */
ret = klass->pre_push (dec, &buf);
if (ret != GST_FLOW_OK || !buf) {
GST_DEBUG_OBJECT (dec, "subclass returned %s, buf %p",
gst_flow_get_name (ret), buf);
if (buf)
gst_buffer_unref (buf);
goto exit;
}
}
GST_LOG_OBJECT (dec, "pushing buffer of size %d 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_DURATION (buf)));
if (dec->segment.rate > 0.0) {
ret = gst_pad_push (dec->srcpad, buf);
ret = gst_audio_decoder_push_forward (dec, buf);
GST_LOG_OBJECT (dec, "buffer pushed: %s", gst_flow_get_name (ret));
} else {
ret = GST_FLOW_OK;
@ -715,7 +732,6 @@ again:
GST_LOG_OBJECT (dec, "buffer queued");
}
exit:
if (inbuf) {
buf = inbuf;
goto again;
@ -1202,6 +1218,7 @@ gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
{
GstAudioDecoderPrivate *priv = dec->priv;
GstFlowReturn res = GST_FLOW_OK;
GstClockTime timestamp;
GList *walk;
walk = priv->decode;
@ -1239,9 +1256,28 @@ gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
gst_audio_decoder_drain (dec);
/* now send queued data downstream */
timestamp = GST_CLOCK_TIME_NONE;
while (priv->queued) {
GstBuffer *buf = GST_BUFFER_CAST (priv->queued->data);
/* duration should always be valid for raw audio */
g_assert (GST_BUFFER_DURATION_IS_VALID (buf));
/* interpolate (backward) if needed */
if (G_LIKELY (timestamp != -1))
timestamp -= GST_BUFFER_DURATION (buf);
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
GST_LOG_OBJECT (dec, "applying reverse interpolated ts %"
GST_TIME_FORMAT, GST_TIME_ARGS (timestamp));
GST_BUFFER_TIMESTAMP (buf) = timestamp;
} else {
/* track otherwise */
timestamp = GST_BUFFER_TIMESTAMP (buf);
GST_LOG_OBJECT (dec, "tracking ts %" GST_TIME_FORMAT,
GST_TIME_ARGS (timestamp));
}
if (G_LIKELY (res == GST_FLOW_OK)) {
GST_DEBUG_OBJECT (dec, "pushing buffer %p of size %u, "
"time %" GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT, buf,
@ -1252,7 +1288,7 @@ gst_audio_decoder_flush_decode (GstAudioDecoder * dec)
/* avoid stray DISCONT from forward processing,
* which have no meaning in reverse pushing */
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
res = gst_pad_push (dec->srcpad, buf);
res = gst_audio_decoder_push_forward (dec, buf);
} else {
gst_buffer_unref (buf);
}

View file

@ -1087,6 +1087,13 @@ gst_audio_encoder_sink_setcaps (GstAudioEncoder * enc, GstCaps * caps)
if (res)
ctx->info = state;
/* invalidate state to ensure no casual carrying on */
if (!res) {
GST_DEBUG_OBJECT (enc, "subclass did not accept format");
gst_audio_info_init (&state);
goto exit;
}
/* notify if new latency */
GST_OBJECT_LOCK (enc);
if ((ctx->min_latency > 0 && ctx->min_latency != old_min_latency) ||

View file

@ -63,10 +63,17 @@ typedef enum
* GstRTCPFBType:
* @GST_RTCP_FB_TYPE_INVALID: Invalid type
* @GST_RTCP_RTPFB_TYPE_NACK: Generic NACK
* @GST_RTCP_RTPFB_TYPE_TMMBR: Temporary Maximum Media Stream Bit Rate Request
* @GST_RTCP_RTPFB_TYPE_TMMBN: Temporary Maximum Media Stream Bit Rate
* Notification
* @GST_RTCP_PSFB_TYPE_PLI: Picture Loss Indication
* @GST_RTCP_PSFB_TYPE_SLI: Slice Loss Indication
* @GST_RTCP_PSFB_TYPE_RPSI: Reference Picture Selection Indication
* @GST_RTCP_PSFB_TYPE_AFB: Application layer Feedback
* @GST_RTCP_PSFB_TYPE_FIR: Full Intra Request Command
* @GST_RTCP_PSFB_TYPE_TSTR: Temporal-Spatial Trade-off Request
* @GST_RTCP_PSFB_TYPE_TSTN: Temporal-Spatial Trade-off Notification
* @GST_RTCP_PSFB_TYPE_VBCN: Video Back Channel Message
*
* Different types of feedback messages.
*
@ -78,11 +85,19 @@ typedef enum
GST_RTCP_FB_TYPE_INVALID = 0,
/* RTPFB types */
GST_RTCP_RTPFB_TYPE_NACK = 1,
/* RTPFB types assigned in RFC 5104 */
GST_RTCP_RTPFB_TYPE_TMMBR = 3,
GST_RTCP_RTPFB_TYPE_TMMBN = 4,
/* PSFB types */
GST_RTCP_PSFB_TYPE_PLI = 1,
GST_RTCP_PSFB_TYPE_SLI = 2,
GST_RTCP_PSFB_TYPE_RPSI = 3,
GST_RTCP_PSFB_TYPE_AFB = 15
GST_RTCP_PSFB_TYPE_AFB = 15,
/* PSFB types assigned in RFC 5104 */
GST_RTCP_PSFB_TYPE_FIR = 4,
GST_RTCP_PSFB_TYPE_TSTR = 5,
GST_RTCP_PSFB_TYPE_TSTN = 6,
GST_RTCP_PSFB_TYPE_VBCN = 7,
} GstRTCPFBType;
/**