diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/androidmedia/gstamcaudiodec.c | 53 | ||||
-rw-r--r-- | sys/androidmedia/gstamcaudiodec.h | 3 |
2 files changed, 46 insertions, 10 deletions
diff --git a/sys/androidmedia/gstamcaudiodec.c b/sys/androidmedia/gstamcaudiodec.c index d381eec39..ca090c3c9 100644 --- a/sys/androidmedia/gstamcaudiodec.c +++ b/sys/androidmedia/gstamcaudiodec.c @@ -228,6 +228,7 @@ gst_amc_audio_dec_init (GstAmcAudioDec * self) g_mutex_init (&self->drain_lock); g_cond_init (&self->drain_cond); + self->output_adapter = gst_adapter_new (); } static gboolean @@ -283,6 +284,10 @@ gst_amc_audio_dec_finalize (GObject * object) { GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (object); + if (self->output_adapter) + gst_object_unref (self->output_adapter); + self->output_adapter = NULL; + g_mutex_clear (&self->drain_lock); g_cond_clear (&self->drain_cond); @@ -505,7 +510,6 @@ retry: GstBuffer *outbuf; GstAmcBuffer *buf; GstMapInfo minfo; - gint nframes; /* This sometimes happens at EOS or if the input is not properly framed, * let's handle it gracefully by allocating a new buffer for the current @@ -545,18 +549,39 @@ retry: } gst_buffer_unmap (outbuf, &minfo); - nframes = 1; if (self->spf != -1) { - nframes = buffer_info.size / self->info.bpf; - if (nframes % self->spf != 0) - GST_WARNING_OBJECT (self, "Output buffer does not contain an integer " - "number of input frames (frames: %d, spf: %d)", nframes, self->spf); - nframes = (nframes + self->spf - 1) / self->spf; + gst_adapter_push (self->output_adapter, outbuf); + } else { + flow_ret = + gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1); + } + } + + if (self->spf != -1) { + GstBuffer *outbuf; + guint avail = gst_adapter_available (self->output_adapter); + guint nframes; + + /* On EOS we take the complete adapter content, no matter + * if it is a multiple of the codec frame size or not. + * Otherwise we take a multiple of codec frames and push + * them downstream + */ + avail /= self->info.bpf; + if (!is_eos) { + nframes = avail / self->spf; + avail = nframes * self->spf; + } else { + nframes = (avail + self->spf - 1) / self->spf; } + avail *= self->info.bpf; - flow_ret = - gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, - nframes); + if (avail > 0) { + outbuf = gst_adapter_take_buffer (self->output_adapter, avail); + flow_ret = + gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, + nframes); + } } if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err)) { @@ -782,6 +807,9 @@ gst_amc_audio_dec_stop (GstAudioDecoder * decoder) memset (self->positions, 0, sizeof (self->positions)); + gst_adapter_flush (self->output_adapter, + gst_adapter_available (self->output_adapter)); + g_list_foreach (self->codec_datas, (GFunc) g_free, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; @@ -1014,6 +1042,8 @@ gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard) gst_amc_codec_flush (self->codec, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); + gst_adapter_flush (self->output_adapter, + gst_adapter_available (self->output_adapter)); self->flushing = FALSE; /* Start the srcpad loop again */ @@ -1295,5 +1325,8 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self) ret = GST_FLOW_ERROR; } + gst_adapter_flush (self->output_adapter, + gst_adapter_available (self->output_adapter)); + return ret; } diff --git a/sys/androidmedia/gstamcaudiodec.h b/sys/androidmedia/gstamcaudiodec.h index 6c6124ed0..9fff22105 100644 --- a/sys/androidmedia/gstamcaudiodec.h +++ b/sys/androidmedia/gstamcaudiodec.h @@ -59,6 +59,9 @@ struct _GstAmcAudioDec gboolean input_caps_changed; gint spf; + /* For collecting complete frames for the output */ + GstAdapter *output_adapter; + /* Output format of the codec */ GstAudioInfo info; /* AMC positions, might need reordering */ |