[FFmpeg-devel] [PATCH 004/244] avframe: switch to the new channel layout API
Anton Khirnov
anton at khirnov.net
Fri Dec 6 12:16:58 EET 2019
Signed-off-by: Vittorio Giovara <vittorio.giovara at gmail.com>
---
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.
--
2.24.0
More information about the ffmpeg-devel
mailing list