mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
avauddec: Ensure input buffers have FF_INPUT_BUFFER_PADDING_SIZE padding, which is required by avcodec_decode_audio4 ()
This commit is contained in:
parent
626152dd6f
commit
30a4a28793
2 changed files with 65 additions and 0 deletions
|
@ -43,6 +43,8 @@ static void gst_ffmpegauddec_base_init (GstFFMpegAudDecClass * klass);
|
||||||
static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
|
static void gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass);
|
||||||
static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
|
static void gst_ffmpegauddec_init (GstFFMpegAudDec * ffmpegdec);
|
||||||
static void gst_ffmpegauddec_finalize (GObject * object);
|
static void gst_ffmpegauddec_finalize (GObject * object);
|
||||||
|
static gboolean gst_ffmpegauddec_propose_allocation (GstAudioDecoder * decoder,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
static gboolean gst_ffmpegauddec_start (GstAudioDecoder * decoder);
|
static gboolean gst_ffmpegauddec_start (GstAudioDecoder * decoder);
|
||||||
static gboolean gst_ffmpegauddec_stop (GstAudioDecoder * decoder);
|
static gboolean gst_ffmpegauddec_stop (GstAudioDecoder * decoder);
|
||||||
|
@ -129,6 +131,8 @@ gst_ffmpegauddec_class_init (GstFFMpegAudDecClass * klass)
|
||||||
gstaudiodecoder_class->handle_frame =
|
gstaudiodecoder_class->handle_frame =
|
||||||
GST_DEBUG_FUNCPTR (gst_ffmpegauddec_handle_frame);
|
GST_DEBUG_FUNCPTR (gst_ffmpegauddec_handle_frame);
|
||||||
gstaudiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_flush);
|
gstaudiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_ffmpegauddec_flush);
|
||||||
|
gstaudiodecoder_class->propose_allocation =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_ffmpegauddec_propose_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -225,6 +229,9 @@ gst_ffmpegauddec_stop (GstAudioDecoder * decoder)
|
||||||
|
|
||||||
GST_OBJECT_LOCK (ffmpegdec);
|
GST_OBJECT_LOCK (ffmpegdec);
|
||||||
gst_ffmpegauddec_close (ffmpegdec, FALSE);
|
gst_ffmpegauddec_close (ffmpegdec, FALSE);
|
||||||
|
g_free (ffmpegdec->padded);
|
||||||
|
ffmpegdec->padded = NULL;
|
||||||
|
ffmpegdec->padded_size = 0;
|
||||||
GST_OBJECT_UNLOCK (ffmpegdec);
|
GST_OBJECT_UNLOCK (ffmpegdec);
|
||||||
gst_audio_info_init (&ffmpegdec->info);
|
gst_audio_info_init (&ffmpegdec->info);
|
||||||
gst_caps_replace (&ffmpegdec->last_caps, NULL);
|
gst_caps_replace (&ffmpegdec->last_caps, NULL);
|
||||||
|
@ -262,6 +269,24 @@ could_not_open:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_ffmpegauddec_propose_allocation (GstAudioDecoder * decoder,
|
||||||
|
GstQuery * query)
|
||||||
|
{
|
||||||
|
GstAllocationParams params;
|
||||||
|
|
||||||
|
gst_allocation_params_init (¶ms);
|
||||||
|
params.flags = GST_MEMORY_FLAG_ZERO_PADDED;
|
||||||
|
params.align = 15;
|
||||||
|
params.padding = FF_INPUT_BUFFER_PADDING_SIZE;
|
||||||
|
/* we would like to have some padding so that we don't have to
|
||||||
|
* memcpy. We don't suggest an allocator. */
|
||||||
|
gst_query_add_allocation_param (query, NULL, ¶ms);
|
||||||
|
|
||||||
|
return GST_AUDIO_DECODER_CLASS (parent_class)->propose_allocation (decoder,
|
||||||
|
query);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
gst_ffmpegauddec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
@ -669,6 +694,7 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
GstMapInfo map;
|
GstMapInfo map;
|
||||||
gint size, bsize, len, have_data;
|
gint size, bsize, len, have_data;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
gboolean do_padding;
|
||||||
|
|
||||||
ffmpegdec = (GstFFMpegAudDec *) decoder;
|
ffmpegdec = (GstFFMpegAudDec *) decoder;
|
||||||
|
|
||||||
|
@ -705,13 +731,47 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
bdata = map.data;
|
bdata = map.data;
|
||||||
bsize = map.size;
|
bsize = map.size;
|
||||||
|
|
||||||
|
if (bsize > 0 && (!GST_MEMORY_IS_ZERO_PADDED (map.memory)
|
||||||
|
|| (map.maxsize - map.size) < FF_INPUT_BUFFER_PADDING_SIZE)) {
|
||||||
|
/* add padding */
|
||||||
|
if (ffmpegdec->padded_size < bsize + FF_INPUT_BUFFER_PADDING_SIZE) {
|
||||||
|
ffmpegdec->padded_size = bsize + FF_INPUT_BUFFER_PADDING_SIZE;
|
||||||
|
ffmpegdec->padded = g_realloc (ffmpegdec->padded, ffmpegdec->padded_size);
|
||||||
|
GST_LOG_OBJECT (ffmpegdec, "resized padding buffer to %d",
|
||||||
|
ffmpegdec->padded_size);
|
||||||
|
}
|
||||||
|
GST_CAT_TRACE_OBJECT (GST_CAT_PERFORMANCE, ffmpegdec,
|
||||||
|
"Copy input to add padding");
|
||||||
|
memcpy (ffmpegdec->padded, bdata, bsize);
|
||||||
|
memset (ffmpegdec->padded + bsize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
|
||||||
|
bdata = ffmpegdec->padded;
|
||||||
|
do_padding = TRUE;
|
||||||
|
} else {
|
||||||
|
do_padding = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
guint8 tmp_padding[FF_INPUT_BUFFER_PADDING_SIZE];
|
||||||
|
|
||||||
data = bdata;
|
data = bdata;
|
||||||
size = bsize;
|
size = bsize;
|
||||||
|
|
||||||
|
if (do_padding) {
|
||||||
|
/* add temporary padding */
|
||||||
|
GST_CAT_TRACE_OBJECT (GST_CAT_PERFORMANCE, ffmpegdec,
|
||||||
|
"Add temporary input padding");
|
||||||
|
memcpy (tmp_padding, data + size, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
memset (data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
/* decode a frame of audio now */
|
/* decode a frame of audio now */
|
||||||
len = gst_ffmpegauddec_frame (ffmpegdec, data, size, &have_data, &ret);
|
len = gst_ffmpegauddec_frame (ffmpegdec, data, size, &have_data, &ret);
|
||||||
|
|
||||||
|
if (do_padding) {
|
||||||
|
memcpy (data + size, tmp_padding, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK) {
|
if (ret != GST_FLOW_OK) {
|
||||||
GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
|
GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
|
||||||
gst_flow_get_name (ret));
|
gst_flow_get_name (ret));
|
||||||
|
@ -738,6 +798,8 @@ gst_ffmpegauddec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
bsize -= len;
|
bsize -= len;
|
||||||
bdata += len;
|
bdata += len;
|
||||||
|
|
||||||
|
do_padding = TRUE;
|
||||||
|
|
||||||
GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0). bsize:%d , bdata:%p",
|
GST_LOG_OBJECT (ffmpegdec, "Before (while bsize>0). bsize:%d , bdata:%p",
|
||||||
bsize, bdata);
|
bsize, bdata);
|
||||||
} while (bsize > 0);
|
} while (bsize > 0);
|
||||||
|
|
|
@ -37,6 +37,9 @@ struct _GstFFMpegAudDec
|
||||||
|
|
||||||
AVFrame *frame;
|
AVFrame *frame;
|
||||||
|
|
||||||
|
guint8 *padded;
|
||||||
|
guint padded_size;
|
||||||
|
|
||||||
/* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
|
/* prevent reopening the decoder on GST_EVENT_CAPS when caps are same as last time. */
|
||||||
GstCaps *last_caps;
|
GstCaps *last_caps;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue