[FFmpeg-devel] [PATCH 005/279] avframe: switch to the new channel layout API
James Almer
jamrial at gmail.com
Wed Dec 8 03:06:21 EET 2021
From: Anton Khirnov <anton at khirnov.net>
Signed-off-by: Vittorio Giovara <vittorio.giovara at gmail.com>
Signed-off-by: James Almer <jamrial at gmail.com>
---
libavutil/frame.c | 112 +++++++++++++++++++++++++++++++++++++---------
libavutil/frame.h | 12 ++++-
2 files changed, 103 insertions(+), 21 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 0912ad9131..d07d6d7984 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -186,18 +186,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,
@@ -245,10 +254,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);
}
@@ -332,14 +348,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)
goto fail;
+ // 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, 0);
@@ -392,13 +427,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) {
@@ -456,6 +490,8 @@ void av_frame_unref(AVFrame *frame)
if (frame->extended_data != frame->data)
av_freep(&frame->extended_data);
+ av_channel_layout_uninit(&frame->ch_layout);
+
get_frame_defaults(frame);
}
@@ -502,9 +538,18 @@ 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;
+ }
if (frame->hw_frames_ctx)
ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0);
@@ -545,10 +590,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;
@@ -654,14 +705,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);
@@ -680,10 +745,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 3f295f6b9e..7f6aa1c7c8 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"
@@ -486,10 +487,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. All the pointers in
@@ -674,6 +679,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;
@@ -753,7 +763,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.
--
2.34.1
More information about the ffmpeg-devel
mailing list