diff options
author | Jan Schmidt <thaytan@mad.scientist.com> | 2007-06-22 12:13:18 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@mad.scientist.com> | 2007-06-22 12:13:18 +0000 |
commit | b0aa56c7960dfb529502fb39fbddf599d4a387b7 (patch) | |
tree | 2b53f90f4ecd06cd0005fbb5647de288f23f619f | |
parent | d0920a38d7eec4c73e8d61b508a1e3ae90099c3c (diff) |
ext/ffmpeg/gstffmpegenc.*: Instead of allocating 512KB buffers and then setting BUFFER_SIZE to what ffmpeg produced, ...
Original commit message from CVS:
* ext/ffmpeg/gstffmpegenc.c: (ffmpegenc_setup_working_buf),
(gst_ffmpegenc_chain_video), (gst_ffmpegenc_flush_buffers),
(gst_ffmpegenc_change_state):
* ext/ffmpeg/gstffmpegenc.h:
Instead of allocating 512KB buffers and then setting BUFFER_SIZE
to what ffmpeg produced, we're better off by far to use a single
working buffer and copy data out into neat little buffers.
This prevents exhorbitant virtual memory wastage in the form
of allocated but untouched buffers.
-rw-r--r-- | ChangeLog | 13 | ||||
m--------- | common | 0 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegenc.c | 33 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegenc.h | 3 |
4 files changed, 42 insertions, 7 deletions
@@ -1,3 +1,16 @@ +2007-06-22 Jan Schmidt <thaytan@mad.scientist.com> + + * ext/ffmpeg/gstffmpegenc.c: (ffmpegenc_setup_working_buf), + (gst_ffmpegenc_chain_video), (gst_ffmpegenc_flush_buffers), + (gst_ffmpegenc_change_state): + * ext/ffmpeg/gstffmpegenc.h: + Instead of allocating 512KB buffers and then setting BUFFER_SIZE + to what ffmpeg produced, we're better off by far to use a single + working buffer and copy data out into neat little buffers. + + This prevents exhorbitant virtual memory wastage in the form + of allocated but untouched buffers. + 2007-06-20 Stefan Kost <ensonic@users.sf.net> * ext/ffmpeg/gstffmpegcodecmap.c: diff --git a/common b/common -Subproject 6cb0000a5a30d4fc580a06489106a637fca024c +Subproject 14c5a68981278f642e4ca5fd5ca08554fc78b34 diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 6e6d6f5..fefd4a9 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -567,6 +567,18 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) return TRUE; } +static void +ffmpegenc_setup_working_buf (GstFFMpegEnc *ffmpegenc) +{ + if (ffmpegenc->working_buf == NULL || + ffmpegenc->working_buf_size != ffmpegenc->buffer_size) { + if (ffmpegenc->working_buf) + g_free (ffmpegenc->working_buf); + ffmpegenc->working_buf_size = ffmpegenc->buffer_size; + ffmpegenc->working_buf = g_malloc (ffmpegenc->working_buf_size); + } +} + static GstFlowReturn gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf) { @@ -588,9 +600,11 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf) gst_ffmpeg_time_gst_to_ff (GST_BUFFER_TIMESTAMP (inbuf), ffmpegenc->context->time_base); - outbuf = gst_buffer_new_and_alloc (ffmpegenc->buffer_size); + ffmpegenc_setup_working_buf (ffmpegenc); + ret_size = avcodec_encode_video (ffmpegenc->context, - GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf), ffmpegenc->picture); + ffmpegenc->working_buf, ffmpegenc->working_buf_size, + ffmpegenc->picture); if (ret_size < 0) { #ifndef GST_DISABLE_GST_DEBUG @@ -600,7 +614,6 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf) "ffenc_%s: failed to encode buffer", oclass->in_plugin->name); #endif /* GST_DISABLE_GST_DEBUG */ gst_buffer_unref (inbuf); - gst_buffer_unref (outbuf); return GST_FLOW_OK; } @@ -620,7 +633,7 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf) (("Could not write to file \"%s\"."), ffmpegenc->filename), GST_ERROR_SYSTEM); - GST_BUFFER_SIZE (outbuf) = ret_size; + outbuf = gst_buffer_new_and_alloc (ret_size); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf); if (!ffmpegenc->context->coded_frame->key_frame) @@ -739,9 +752,10 @@ gst_ffmpegenc_flush_buffers (GstFFMpegEnc * ffmpegenc, gboolean send) while (!g_queue_is_empty (ffmpegenc->delay)) { - outbuf = gst_buffer_new_and_alloc (ffmpegenc->buffer_size); + ffmpegenc_setup_working_buf (ffmpegenc); + ret_size = avcodec_encode_video (ffmpegenc->context, - GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf), NULL); + ffmpegenc->working_buf, ffmpegenc->working_buf_size, NULL); if (ret_size < 0) { /* there should be something, notify and give up */ #ifndef GST_DISABLE_GST_DEBUG @@ -763,9 +777,10 @@ gst_ffmpegenc_flush_buffers (GstFFMpegEnc * ffmpegenc, gboolean send) /* handle b-frame delay when no output, so we don't output empty frames */ inbuf = g_queue_pop_head (ffmpegenc->delay); - GST_BUFFER_SIZE (outbuf) = ret_size; + outbuf = gst_buffer_new_and_alloc (ret_size); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (inbuf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (inbuf); + if (!ffmpegenc->context->coded_frame->key_frame) GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (ffmpegenc->srcpad)); @@ -898,6 +913,10 @@ gst_ffmpegenc_change_state (GstElement * element, GstStateChange transition) fclose (ffmpegenc->file); ffmpegenc->file = NULL; } + if (ffmpegenc->working_buf) { + g_free (ffmpegenc->working_buf); + ffmpegenc->working_buf = NULL; + } break; default: break; diff --git a/ext/ffmpeg/gstffmpegenc.h b/ext/ffmpeg/gstffmpegenc.h index 4c3c10e..ac9768a 100644 --- a/ext/ffmpeg/gstffmpegenc.h +++ b/ext/ffmpeg/gstffmpegenc.h @@ -48,6 +48,9 @@ struct _GstFFMpegEnc gulong buffer_size; gulong rtp_payload_size; + guint8 *working_buf; + gulong working_buf_size; + /* settings with some special handling */ guint pass; gfloat quantizer; |