From patchwork Fri Dec 6 10:16:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 16629 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id E528E44ABC2 for ; Fri, 6 Dec 2019 12:19:15 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D3C4368B69E; Fri, 6 Dec 2019 12:19:15 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D14A568B694 for ; Fri, 6 Dec 2019 12:19:12 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id A34C62945B4 for ; Fri, 6 Dec 2019 11:19:12 +0100 (CET) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id CaofFQwK8WRa for ; Fri, 6 Dec 2019 11:19:12 +0100 (CET) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id 0A2352945B6 for ; Fri, 6 Dec 2019 11:19:12 +0100 (CET) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 949BF7F924 for ; Fri, 6 Dec 2019 11:19:11 +0100 (CET) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id hgTevRGBjGwu for ; Fri, 6 Dec 2019 11:19:09 +0100 (CET) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id B91127F988 for ; Fri, 6 Dec 2019 11:18:47 +0100 (CET) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id 67BA520E0149; Fri, 6 Dec 2019 11:17:48 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 6 Dec 2019 11:16:58 +0100 Message-Id: <20191206101710.22028-4-anton@khirnov.net> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191206101710.22028-1-anton@khirnov.net> References: <20191206101710.22028-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 004/244] avframe: switch to the new channel layout API X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Vittorio Giovara --- libavutil/frame.c | 113 ++++++++++++++++++++++++++++++++++++++-------- libavutil/frame.h | 12 ++++- 2 files changed, 104 insertions(+), 21 deletions(-) diff --git a/libavutil/frame.c b/libavutil/frame.c index e4038096c2..600f82bbeb 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -267,18 +267,27 @@ fail: static int get_audio_buffer(AVFrame *frame, int align) { - int channels; int planar = av_sample_fmt_is_planar(frame->format); - int planes; + int channels, planes; int ret, i; - if (!frame->channels) - frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); - - channels = frame->channels; - planes = planar ? channels : 1; - - CHECK_CHANNELS_CONSISTENCY(frame); +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!frame->ch_layout.nb_channels) { + if (frame->channel_layout) { + av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout); + } else { + frame->ch_layout.nb_channels = frame->channels; + frame->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + } + } + frame->channels = frame->ch_layout.nb_channels; + frame->channel_layout = frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ? + frame->ch_layout.u.mask : 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + channels = frame->ch_layout.nb_channels; + planes = planar ? channels : 1; if (!frame->linesize[0]) { ret = av_samples_get_buffer_size(&frame->linesize[0], channels, frame->nb_samples, frame->format, @@ -326,10 +335,17 @@ int av_frame_get_buffer(AVFrame *frame, int align) if (frame->format < 0) return AVERROR(EINVAL); +FF_DISABLE_DEPRECATION_WARNINGS if (frame->width > 0 && frame->height > 0) return get_video_buffer(frame, align); - else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0)) + else if (frame->nb_samples > 0 && + (av_channel_layout_check(&frame->ch_layout) +#if FF_API_OLD_CHANNEL_LAYOUT + || frame->channel_layout || frame->channels > 0 +#endif + )) return get_audio_buffer(frame, align); +FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(EINVAL); } @@ -450,14 +466,33 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) dst->format = src->format; dst->width = src->width; dst->height = src->height; + dst->nb_samples = src->nb_samples; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS dst->channels = src->channels; dst->channel_layout = src->channel_layout; - dst->nb_samples = src->nb_samples; + if (!av_channel_layout_check(&src->ch_layout)) { + if (src->channel_layout) + av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout); + else { + dst->ch_layout.nb_channels = src->channels; + dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + } + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif ret = frame_copy_props(dst, src, 0); if (ret < 0) return ret; + // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out + if (av_channel_layout_check(&src->ch_layout)) { + ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); + if (ret < 0) + goto fail; + } + /* duplicate the frame data if it's not refcounted */ if (!src->buf[0]) { ret = av_frame_get_buffer(dst, 32); @@ -510,13 +545,12 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) /* duplicate extended data */ if (src->extended_data != src->data) { - int ch = src->channels; + int ch = dst->ch_layout.nb_channels; if (!ch) { ret = AVERROR(EINVAL); goto fail; } - CHECK_CHANNELS_CONSISTENCY(src); dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); if (!dst->extended_data) { @@ -576,6 +610,8 @@ FF_ENABLE_DEPRECATION_WARNINGS av_buffer_unref(&frame->opaque_ref); av_buffer_unref(&frame->private_ref); + av_channel_layout_uninit(&frame->ch_layout); + get_frame_defaults(frame); } @@ -623,9 +659,19 @@ int av_frame_make_writable(AVFrame *frame) tmp.format = frame->format; tmp.width = frame->width; tmp.height = frame->height; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS tmp.channels = frame->channels; tmp.channel_layout = frame->channel_layout; +FF_ENABLE_DEPRECATION_WARNINGS +#endif tmp.nb_samples = frame->nb_samples; + ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; + } + ret = av_frame_get_buffer(&tmp, 32); if (ret < 0) return ret; @@ -662,10 +708,16 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) int planes, i; if (frame->nb_samples) { - int channels = frame->channels; + int channels = frame->ch_layout.nb_channels; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!channels) + channels = av_get_channel_layout_nb_channels(frame->channel_layout); +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (!channels) return NULL; - CHECK_CHANNELS_CONSISTENCY(frame); planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; } else planes = 4; @@ -768,14 +820,28 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src) static int frame_copy_audio(AVFrame *dst, const AVFrame *src) { int planar = av_sample_fmt_is_planar(dst->format); - int channels = dst->channels; + int channels = dst->ch_layout.nb_channels; int planes = planar ? channels : 1; int i; - if (dst->nb_samples != src->nb_samples || - dst->channels != src->channels || - dst->channel_layout != src->channel_layout) +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!channels) { + channels = av_get_channel_layout_nb_channels(dst->channel_layout); + planes = planar ? channels : 1; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +FF_DISABLE_DEPRECATION_WARNINGS + if (dst->nb_samples != src->nb_samples || + av_channel_layout_compare(&dst->ch_layout, &src->ch_layout) +#if FF_API_OLD_CHANNEL_LAYOUT + || dst->channel_layout != src->channel_layout +#endif + ) return AVERROR(EINVAL); +FF_ENABLE_DEPRECATION_WARNINGS CHECK_CHANNELS_CONSISTENCY(src); @@ -794,10 +860,17 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src) if (dst->format != src->format || dst->format < 0) return AVERROR(EINVAL); +FF_DISABLE_DEPRECATION_WARNINGS if (dst->width > 0 && dst->height > 0) return frame_copy_video(dst, src); - else if (dst->nb_samples > 0 && dst->channels > 0) + else if (dst->nb_samples > 0 && + (av_channel_layout_check(&dst->ch_layout) +#if FF_API_OLD_CHANNEL_LAYOUT + || dst->channel_layout || dst->channels +#endif + )) return frame_copy_audio(dst, src); +FF_ENABLE_DEPRECATION_WARNINGS return AVERROR(EINVAL); } diff --git a/libavutil/frame.h b/libavutil/frame.h index b5afb58634..f9623ece20 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -30,6 +30,7 @@ #include "avutil.h" #include "buffer.h" +#include "channel_layout.h" #include "dict.h" #include "rational.h" #include "samplefmt.h" @@ -466,10 +467,14 @@ typedef struct AVFrame { */ int sample_rate; +#if FF_API_OLD_CHANNEL_LAYOUT /** * Channel layout of the audio data. + * @deprecated use ch_layout instead */ + attribute_deprecated uint64_t channel_layout; +#endif /** * AVBuffer references backing the data for this frame. If all elements of @@ -672,6 +677,11 @@ typedef struct AVFrame { * for the target frame's private_ref field. */ AVBufferRef *private_ref; + + /** + * Channel layout of the audio data. + */ + AVChannelLayout ch_layout; } AVFrame; #if FF_API_FRAME_GET_SET @@ -804,7 +814,7 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src); * The following fields must be set on frame before calling this function: * - format (pixel format for video, sample format for audio) * - width and height for video - * - nb_samples and channel_layout for audio + * - nb_samples and ch_layout for audio * * This function will fill AVFrame.data and AVFrame.buf arrays and, if * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.