mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 13:06:23 +00:00
avauddec: accumulate buffers from a single input to push it all at once
The base audio decoder wants a 1:1 mapping for input and output buffers, so this decoder must accumulate data in an adapter and push it all at once after all input has been processed. https://bugzilla.gnome.org/show_bug.cgi?id=689565
This commit is contained in:
parent
faf985e8fb
commit
c445b614f9
2 changed files with 31 additions and 4 deletions
|
@ -54,6 +54,8 @@ static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec,
|
|||
gboolean force);
|
||||
|
||||
static void gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec);
|
||||
static GstFlowReturn
|
||||
gst_ffmpegauddec_push_output_buffer (GstFFMpegAudDec * ffmpegdec);
|
||||
|
||||
#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("avdec-params")
|
||||
|
||||
|
@ -138,6 +140,8 @@ gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec)
|
|||
ffmpegdec->context = avcodec_alloc_context3 (klass->in_plugin);
|
||||
ffmpegdec->opened = FALSE;
|
||||
|
||||
ffmpegdec->adapter = gst_adapter_new ();
|
||||
|
||||
gst_audio_decoder_set_drainable (GST_AUDIO_DECODER (ffmpegdec), TRUE);
|
||||
gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (ffmpegdec), TRUE);
|
||||
}
|
||||
|
@ -151,6 +155,9 @@ gst_ffmpegauddec_finalize (GObject * object)
|
|||
av_free (ffmpegdec->context);
|
||||
ffmpegdec->context = NULL;
|
||||
|
||||
gst_object_unref (ffmpegdec->adapter);
|
||||
ffmpegdec->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -164,6 +171,7 @@ gst_ffmpegauddec_close (GstFFMpegAudDec * ffmpegdec)
|
|||
GST_LOG_OBJECT (ffmpegdec, "closing libav codec");
|
||||
|
||||
gst_caps_replace (&ffmpegdec->last_caps, NULL);
|
||||
gst_adapter_clear (ffmpegdec->adapter);
|
||||
|
||||
if (ffmpegdec->opened)
|
||||
gst_ffmpeg_avcodec_close (ffmpegdec->context);
|
||||
|
@ -601,11 +609,9 @@ gst_ffmpegauddec_frame (GstFFMpegAudDec * ffmpegdec,
|
|||
}
|
||||
|
||||
if (outbuf) {
|
||||
GST_LOG_OBJECT (ffmpegdec, "Decoded data, now pushing buffer %p", outbuf);
|
||||
GST_LOG_OBJECT (ffmpegdec, "Decoded data, now storing buffer %p", outbuf);
|
||||
|
||||
*ret =
|
||||
gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec), outbuf,
|
||||
1);
|
||||
gst_adapter_push (ffmpegdec->adapter, outbuf);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "We didn't get a decoded buffer");
|
||||
}
|
||||
|
@ -642,6 +648,7 @@ gst_ffmpegauddec_drain (GstFFMpegAudDec * ffmpegdec)
|
|||
break;
|
||||
} while (try++ < 10);
|
||||
}
|
||||
gst_ffmpegauddec_push_output_buffer (ffmpegdec);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -739,6 +746,8 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
|||
gst_buffer_unmap (inbuf, &map);
|
||||
gst_buffer_unref (inbuf);
|
||||
|
||||
gst_ffmpegauddec_push_output_buffer (ffmpegdec);
|
||||
|
||||
if (bsize > 0) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize);
|
||||
}
|
||||
|
@ -756,6 +765,21 @@ not_negotiated:
|
|||
}
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_ffmpegauddec_push_output_buffer (GstFFMpegAudDec * ffmpegdec)
|
||||
{
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
if (gst_adapter_available (ffmpegdec->adapter) > 0) {
|
||||
outbuf = gst_adapter_take_buffer (ffmpegdec->adapter,
|
||||
gst_adapter_available (ffmpegdec->adapter));
|
||||
ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (ffmpegdec), outbuf,
|
||||
1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_ffmpegauddec_register (GstPlugin * plugin)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,9 @@ struct _GstFFMpegAudDec
|
|||
/* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
|
||||
GstCaps *last_caps;
|
||||
|
||||
/* Stores current buffers to push as GstAudioDecoder wants 1:1 mapping for input/output buffers */
|
||||
GstAdapter *adapter;
|
||||
|
||||
/* current output format */
|
||||
GstAudioInfo info;
|
||||
GstAudioChannelPosition ffmpeg_layout[64];
|
||||
|
|
Loading…
Reference in a new issue