summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@mad.scientist.com>2007-06-22 12:13:18 +0000
committerJan Schmidt <thaytan@mad.scientist.com>2007-06-22 12:13:18 +0000
commitb0aa56c7960dfb529502fb39fbddf599d4a387b7 (patch)
tree2b53f90f4ecd06cd0005fbb5647de288f23f619f
parentd0920a38d7eec4c73e8d61b508a1e3ae90099c3c (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--ChangeLog13
m---------common0
-rw-r--r--ext/ffmpeg/gstffmpegenc.c33
-rw-r--r--ext/ffmpeg/gstffmpegenc.h3
4 files changed, 42 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 70e5d11..e37f404 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;