mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 07:16:55 +00:00
ffenc: avoid malloc more for audio encoders
Use _adapter_peek() to retrieve data so that we can reuse previously allocated memory.
This commit is contained in:
parent
9fdc5a5d64
commit
ff2f62ac8a
1 changed files with 19 additions and 20 deletions
|
@ -702,30 +702,24 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_ffmpegenc_encode_audio (GstFFMpegEnc * ffmpegenc, GstBuffer * inbuf,
|
gst_ffmpegenc_encode_audio (GstFFMpegEnc * ffmpegenc, guint8 * audio_in,
|
||||||
gint max_size, gboolean discont)
|
guint max_size, GstClockTime timestamp, GstClockTime duration,
|
||||||
|
gboolean discont)
|
||||||
{
|
{
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
AVCodecContext *ctx;
|
AVCodecContext *ctx;
|
||||||
guint8 *audio_out, *audio_in;
|
guint8 *audio_out;
|
||||||
GstClockTime timestamp, duration;
|
|
||||||
gint res;
|
gint res;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
|
||||||
ctx = ffmpegenc->context;
|
ctx = ffmpegenc->context;
|
||||||
|
|
||||||
/* caller should set timestamps on inbuf */
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (inbuf);
|
|
||||||
duration = GST_BUFFER_DURATION (inbuf);
|
|
||||||
audio_in = GST_BUFFER_DATA (inbuf);
|
|
||||||
|
|
||||||
outbuf = gst_buffer_new_and_alloc (max_size);
|
outbuf = gst_buffer_new_and_alloc (max_size);
|
||||||
audio_out = GST_BUFFER_DATA (outbuf);
|
audio_out = GST_BUFFER_DATA (outbuf);
|
||||||
|
|
||||||
GST_LOG_OBJECT (ffmpegenc, "encoding buffer of max size %d", max_size);
|
GST_LOG_OBJECT (ffmpegenc, "encoding buffer of max size %d", max_size);
|
||||||
|
|
||||||
res = avcodec_encode_audio (ctx, audio_out, max_size, (short *) audio_in);
|
res = avcodec_encode_audio (ctx, audio_out, max_size, (short *) audio_in);
|
||||||
gst_buffer_unref (inbuf);
|
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
GST_ERROR_OBJECT (ffmpegenc, "Failed to encode buffer: %d", res);
|
GST_ERROR_OBJECT (ffmpegenc, "Failed to encode buffer: %d", res);
|
||||||
|
@ -761,6 +755,7 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstBuffer * inbuf)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint out_size;
|
gint out_size;
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
|
guint8 *in_data;
|
||||||
|
|
||||||
ffmpegenc = (GstFFMpegEnc *) (GST_OBJECT_PARENT (pad));
|
ffmpegenc = (GstFFMpegEnc *) (GST_OBJECT_PARENT (pad));
|
||||||
oclass = (GstFFMpegEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
|
oclass = (GstFFMpegEncClass *) G_OBJECT_GET_CLASS (ffmpegenc);
|
||||||
|
@ -820,7 +815,7 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstBuffer * inbuf)
|
||||||
frame_bytes);
|
frame_bytes);
|
||||||
|
|
||||||
/* take an audio buffer out of the adapter */
|
/* take an audio buffer out of the adapter */
|
||||||
inbuf = gst_adapter_take_buffer (ffmpegenc->adapter, frame_bytes);
|
in_data = (guint8 *) gst_adapter_peek (ffmpegenc->adapter, frame_bytes);
|
||||||
ffmpegenc->adapter_consumed += frame_size;
|
ffmpegenc->adapter_consumed += frame_size;
|
||||||
|
|
||||||
/* calculate timestamp and duration relative to start of adapter and to
|
/* calculate timestamp and duration relative to start of adapter and to
|
||||||
|
@ -830,20 +825,20 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstBuffer * inbuf)
|
||||||
ctx->sample_rate);
|
ctx->sample_rate);
|
||||||
duration -= (timestamp - ffmpegenc->adapter_ts);
|
duration -= (timestamp - ffmpegenc->adapter_ts);
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (inbuf) = timestamp;
|
|
||||||
GST_BUFFER_DURATION (inbuf) = duration;
|
|
||||||
|
|
||||||
/* advance the adapter timestamp with the duration */
|
|
||||||
timestamp += duration;
|
|
||||||
|
|
||||||
/* 4 times the input size should be big enough... */
|
/* 4 times the input size should be big enough... */
|
||||||
out_size = MAX (frame_bytes * 4, FF_MIN_BUFFER_SIZE);
|
out_size = MAX (frame_bytes * 4, FF_MIN_BUFFER_SIZE);
|
||||||
|
|
||||||
ret = gst_ffmpegenc_encode_audio (ffmpegenc, inbuf, out_size,
|
ret = gst_ffmpegenc_encode_audio (ffmpegenc, in_data, out_size,
|
||||||
ffmpegenc->discont);
|
timestamp, duration, ffmpegenc->discont);
|
||||||
|
|
||||||
|
gst_adapter_flush (ffmpegenc->adapter, frame_bytes);
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto push_failed;
|
goto push_failed;
|
||||||
|
|
||||||
|
/* advance the adapter timestamp with the duration */
|
||||||
|
timestamp += duration;
|
||||||
|
|
||||||
ffmpegenc->discont = FALSE;
|
ffmpegenc->discont = FALSE;
|
||||||
avail = gst_adapter_available (ffmpegenc->adapter);
|
avail = gst_adapter_available (ffmpegenc->adapter);
|
||||||
}
|
}
|
||||||
|
@ -859,7 +854,11 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstBuffer * inbuf)
|
||||||
if (coded_bps)
|
if (coded_bps)
|
||||||
out_size *= coded_bps;
|
out_size *= coded_bps;
|
||||||
|
|
||||||
ret = gst_ffmpegenc_encode_audio (ffmpegenc, inbuf, out_size, discont);
|
in_data = (guint8 *) GST_BUFFER_DATA (inbuf);
|
||||||
|
ret = gst_ffmpegenc_encode_audio (ffmpegenc, in_data, out_size,
|
||||||
|
timestamp, duration, discont);
|
||||||
|
gst_buffer_unref (inbuf);
|
||||||
|
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto push_failed;
|
goto push_failed;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue