mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 00:01:23 +00:00
Make sure we provide ffmpeg with 128bit-aligned data.
Add a new function new_aligned_buffer() which creates a GstBuffer of the requested size/caps, with the memory being allocated/freed by ffmpeg's av_malloc/av_free which guarantees properly aligned memory. Added a can_allocate_aligned internal property which we use to figure out whether downstream can provide us with 128bit aligned buffers.
This commit is contained in:
parent
ea76b43723
commit
57e66c5a22
4 changed files with 48 additions and 10 deletions
|
@ -115,4 +115,7 @@ gst_ffmpeg_formatid_get_codecids (const gchar *format_name,
|
|||
|
||||
|
||||
|
||||
GstBuffer *
|
||||
new_aligned_buffer (gint size, GstCaps * caps);
|
||||
|
||||
#endif /* __GST_FFMPEG_CODECMAP_H__ */
|
||||
|
|
|
@ -110,6 +110,9 @@ struct _GstFFMpegDec
|
|||
|
||||
/* reverse playback queue */
|
||||
GList *queued;
|
||||
|
||||
/* Can downstream allocate 16bytes aligned data. */
|
||||
gboolean can_allocate_aligned;
|
||||
};
|
||||
|
||||
typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
|
||||
|
@ -366,6 +369,9 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
|
|||
ffmpegdec->format.video.fps_n = -1;
|
||||
ffmpegdec->format.video.old_fps_n = -1;
|
||||
gst_segment_init (&ffmpegdec->segment, GST_FORMAT_TIME);
|
||||
|
||||
/* We initially assume downstream can allocate 16 bytes aligned buffers */
|
||||
ffmpegdec->can_allocate_aligned = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -792,7 +798,7 @@ alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
|
|||
fsize = gst_ffmpeg_avpicture_get_size (ffmpegdec->context->pix_fmt,
|
||||
width, height);
|
||||
|
||||
if (!ffmpegdec->context->palctrl) {
|
||||
if (!ffmpegdec->context->palctrl && ffmpegdec->can_allocate_aligned) {
|
||||
GST_LOG_OBJECT (ffmpegdec, "calling pad_alloc");
|
||||
/* no pallete, we can use the buffer size to alloc */
|
||||
ret = gst_pad_alloc_buffer_and_set_caps (ffmpegdec->srcpad,
|
||||
|
@ -800,14 +806,23 @@ alloc_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf,
|
|||
GST_PAD_CAPS (ffmpegdec->srcpad), outbuf);
|
||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||
goto alloc_failed;
|
||||
|
||||
/* If buffer isn't 128-bit aligned, create a memaligned one ourselves */
|
||||
if (((uintptr_t) GST_BUFFER_DATA (*outbuf)) % 16) {
|
||||
GST_DEBUG_OBJECT (ffmpegdec,
|
||||
"Downstream can't allocate aligned buffers.");
|
||||
ffmpegdec->can_allocate_aligned = FALSE;
|
||||
gst_buffer_unref (*outbuf);
|
||||
*outbuf = new_aligned_buffer (fsize, GST_PAD_CAPS (ffmpegdec->srcpad));
|
||||
}
|
||||
} else {
|
||||
GST_LOG_OBJECT (ffmpegdec, "not calling pad_alloc, we have a pallete");
|
||||
GST_LOG_OBJECT (ffmpegdec,
|
||||
"not calling pad_alloc, we have a pallete or downstream can't give 16 byte aligned buffers.");
|
||||
/* for paletted data we can't use pad_alloc_buffer(), because
|
||||
* fsize contains the size of the palette, so the overall size
|
||||
* is bigger than ffmpegcolorspace's unit size, which will
|
||||
* prompt GstBaseTransform to complain endlessly ... */
|
||||
*outbuf = gst_buffer_new_and_alloc (fsize);
|
||||
gst_buffer_set_caps (*outbuf, GST_PAD_CAPS (ffmpegdec->srcpad));
|
||||
*outbuf = new_aligned_buffer (fsize, GST_PAD_CAPS (ffmpegdec->srcpad));
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1815,12 +1830,9 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
|
|||
in_offset, GST_TIME_ARGS (in_timestamp), GST_TIME_ARGS (in_duration),
|
||||
GST_TIME_ARGS (ffmpegdec->next_ts));
|
||||
|
||||
/* outgoing buffer. We use av_malloc() to have properly aligned memory. */
|
||||
*outbuf = gst_buffer_new ();
|
||||
GST_BUFFER_DATA (*outbuf) = GST_BUFFER_MALLOCDATA (*outbuf) =
|
||||
av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
||||
GST_BUFFER_SIZE (*outbuf) = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
GST_BUFFER_FREE_FUNC (*outbuf) = av_free;
|
||||
*outbuf =
|
||||
new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE,
|
||||
GST_PAD_CAPS (ffmpegdec->srcpad));
|
||||
|
||||
len = avcodec_decode_audio2 (ffmpegdec->context,
|
||||
(int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
|
||||
|
@ -2469,6 +2481,7 @@ gst_ffmpegdec_change_state (GstElement * element, GstStateChange transition)
|
|||
g_free (ffmpegdec->padded);
|
||||
ffmpegdec->padded = NULL;
|
||||
ffmpegdec->padded_size = 0;
|
||||
ffmpegdec->can_allocate_aligned = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -396,3 +396,22 @@ gst_ffmpeg_avpicture_fill (AVPicture * picture,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a GstBuffer of the requested size and caps.
|
||||
* The memory will be allocated by ffmpeg, making sure it's properly aligned
|
||||
* for any processing. */
|
||||
|
||||
GstBuffer *
|
||||
new_aligned_buffer (gint size, GstCaps * caps)
|
||||
{
|
||||
GstBuffer *buf;
|
||||
|
||||
buf = gst_buffer_new ();
|
||||
GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = av_malloc (size);
|
||||
GST_BUFFER_SIZE (buf) = size;
|
||||
GST_BUFFER_FREE_FUNC (buf) = av_free;
|
||||
if (caps)
|
||||
gst_buffer_set_caps (buf, caps);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -87,4 +87,7 @@ gst_ffmpeg_get_codecid_longname (enum CodecID codec_id);
|
|||
gint
|
||||
av_smp_format_depth(enum SampleFormat smp_fmt);
|
||||
|
||||
GstBuffer *
|
||||
new_aligned_buffer (gint size, GstCaps * caps);
|
||||
|
||||
#endif /* __GST_FFMPEG_UTILS_H__ */
|
||||
|
|
Loading…
Reference in a new issue