[FFmpeg-devel] [PATCH 2/2] avdevice/lavfi: use wrapped_avframe
Muhammad Faiz
mfcc64 at gmail.com
Mon Nov 9 17:05:18 CET 2015
fix ticket #4985
avoid memory copying from AVFrame to rawvideo
benchmark:
time ffmpeg -f lavfi -i "amovie=audio.mp3, showcqt" -f null -y /dev/null
old:
real 1m3.766s
user 1m3.371s
sys 0m0.184s
new:
real 0m47.893s
user 0m47.399s
sys 0m0.054s
but higher memory usage on ffplay playback because of
packet queueing (it depends on packet size to calculate
memory usage, but wrappped_avframe packet size does not
represent actual allocated memory)
old: about ~40MB
new: about ~180MB
showspectrum filter does not work correctly because it does not
follow frame writability convention (use copy filter for workaround)
patch attached
thanks
-------------- next part --------------
From 297702abfbf0922676188dcfc76f63df53273c93 Mon Sep 17 00:00:00 2001
From: Muhammad Faiz <mfcc64 at gmail.com>
Date: Mon, 9 Nov 2015 17:27:02 +0700
Subject: [PATCH 2/2] avdevice/lavfi: use wrapped_avframe
fix ticket #4985
avoid memory copying from AVFrame to rawvideo
benchmark:
time ffmpeg -f lavfi -i "amovie=audio.mp3, showcqt" -f null -y /dev/null
old:
real 1m3.766s
user 1m3.371s
sys 0m0.184s
new:
real 0m47.893s
user 0m47.399s
sys 0m0.054s
but higher memory usage on ffplay playback because of
packet queueing (it depends on packet size to calculate
memory usage, but wrappped_avframe packet size does not
represent actual allocated memory)
old: about ~40MB
new: about ~180MB
showspectrum filter does not work correctly because it does not
follow frame writability convention (use copy filter for workaround)
---
libavdevice/lavfi.c | 39 ++++++++++++++++++++++++++-------------
libavdevice/version.h | 2 +-
2 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
index 3453b4d..93e2723 100644
--- a/libavdevice/lavfi.c
+++ b/libavdevice/lavfi.c
@@ -311,17 +311,13 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx)
st->codec->codec_type = link->type;
avpriv_set_pts_info(st, 64, link->time_base.num, link->time_base.den);
if (link->type == AVMEDIA_TYPE_VIDEO) {
- st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+ st->codec->codec_id = AV_CODEC_ID_WRAPPED_AVFRAME;
st->codec->pix_fmt = link->format;
st->codec->time_base = link->time_base;
st->codec->width = link->w;
st->codec->height = link->h;
st ->sample_aspect_ratio =
st->codec->sample_aspect_ratio = link->sample_aspect_ratio;
- avctx->probesize = FFMAX(avctx->probesize,
- link->w * link->h *
- av_get_padded_bits_per_pixel(av_pix_fmt_desc_get(link->format)) *
- 30);
} else if (link->type == AVMEDIA_TYPE_AUDIO) {
st->codec->codec_id = av_get_pcm_codec(link->format, -1);
st->codec->channels = avfilter_link_get_channels(link);
@@ -375,13 +371,20 @@ static int create_subcc_packet(AVFormatContext *avctx, AVFrame *frame,
return 0;
}
+/* duplicate from libavcodec/wrapped_avframe.c */
+static void wrapped_avframe_release_buffer(void *unused, uint8_t *data)
+{
+ AVFrame *frame = (AVFrame *)data;
+
+ av_frame_free(&frame);
+}
+
static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
{
LavfiContext *lavfi = avctx->priv_data;
double min_pts = DBL_MAX;
int stream_idx, min_pts_sink_idx = 0;
AVFrame *frame = lavfi->decoded_frame;
- AVPicture pict;
AVDictionary *frame_metadata;
int ret, i;
int size = 0;
@@ -430,15 +433,25 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
if (frame->width /* FIXME best way of testing a video */) {
- size = avpicture_get_size(frame->format, frame->width, frame->height);
- if ((ret = av_new_packet(pkt, size)) < 0)
- return ret;
+ /* duplicate from libavcodec/wrapped_avframe.c */
+ AVFrame *wrapped = av_frame_clone(frame);
- memcpy(pict.data, frame->data, 4*sizeof(frame->data[0]));
- memcpy(pict.linesize, frame->linesize, 4*sizeof(frame->linesize[0]));
+ if (!wrapped)
+ return AVERROR(ENOMEM);
+
+ size = sizeof(*wrapped);
+
+ pkt->buf = av_buffer_create((uint8_t *)wrapped, size,
+ wrapped_avframe_release_buffer, NULL,
+ AV_BUFFER_FLAG_READONLY);
+ if (!pkt->buf) {
+ av_frame_free(&wrapped);
+ return AVERROR(ENOMEM);
+ }
- avpicture_layout(&pict, frame->format, frame->width, frame->height,
- pkt->data, size);
+ pkt->data = (uint8_t *) wrapped;
+ pkt->size = size;
+ pkt->flags |= AV_PKT_FLAG_KEY;
} else if (av_frame_get_channels(frame) /* FIXME test audio */) {
size = frame->nb_samples * av_get_bytes_per_sample(frame->format) *
av_frame_get_channels(frame);
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 45c9e8d..b226a76 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -29,7 +29,7 @@
#define LIBAVDEVICE_VERSION_MAJOR 57
#define LIBAVDEVICE_VERSION_MINOR 0
-#define LIBAVDEVICE_VERSION_MICRO 100
+#define LIBAVDEVICE_VERSION_MICRO 101
#define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
LIBAVDEVICE_VERSION_MINOR, \
--
1.8.3.1
More information about the ffmpeg-devel
mailing list