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
From 297702abfbf0922676188dcfc76f63df53273c93 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz <mfc...@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
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel