From: Anton Khirnov <[email protected]>
Signed-off-by: Vittorio Giovara <[email protected]>
---
libavcodec/decode.c | 67 ++++++++++++++++++++++++++++------------
libavcodec/encode.c | 9 ++++++
libavutil/frame.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++------
libavutil/frame.h | 12 +++++++-
4 files changed, 146 insertions(+), 30 deletions(-)
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 8ad5104d6b..8898caf1c0 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -132,7 +132,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame
*frame)
memcpy(frame->data, avci->to_free->data, sizeof(frame->data));
memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize));
if (avci->to_free->extended_data != avci->to_free->data) {
- int planes =
av_get_channel_layout_nb_channels(avci->to_free->channel_layout);
+ int planes = avci->to_free->ch_layout.nb_channels;
int size = planes * sizeof(*frame->extended_data);
if (!size) {
@@ -153,9 +153,19 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame
*frame)
frame->format = avci->to_free->format;
frame->width = avci->to_free->width;
frame->height = avci->to_free->height;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
frame->channel_layout = avci->to_free->channel_layout;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
frame->nb_samples = avci->to_free->nb_samples;
+ ret = av_channel_layout_copy(&frame->ch_layout, &avci->to_free->ch_layout);
+ if (ret < 0) {
+ av_frame_unref(frame);
+ return ret;
+ }
+
return 0;
}
@@ -881,10 +891,20 @@ static int update_frame_pool(AVCodecContext *avctx,
AVFrame *frame)
break;
}
case AVMEDIA_TYPE_AUDIO: {
- int ch = av_get_channel_layout_nb_channels(frame->channel_layout);
+ int ch = frame->ch_layout.nb_channels;
int planar = av_sample_fmt_is_planar(frame->format);
int planes = planar ? ch : 1;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!ch && frame->channel_layout) {
+ av_channel_layout_from_mask(&frame->ch_layout,
frame->channel_layout);
+ ch = frame->ch_layout.nb_channels;
+ planes = planar ? ch : 1;
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
if (pool->format == frame->format && pool->planes == planes &&
pool->channels == ch && frame->nb_samples == pool->samples)
return 0;
@@ -1101,28 +1121,35 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame
*frame, int flags)
frame->sample_rate = avctx->sample_rate;
if (frame->format < 0)
frame->format = avctx->sample_fmt;
+ if (!frame->ch_layout.nb_channels) {
+ if (avctx->channel_layout)
+ av_channel_layout_from_mask(&frame->ch_layout,
avctx->channel_layout);
+ else
+ av_channel_layout_default(&frame->ch_layout, avctx->channels);
+ }
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ /* set the deprecated channel_layout field for callers
+ * that didn't update to the new API yet */
+ if (frame->ch_layout.nb_channels > FF_SANE_NB_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many channels.\n");
+ return AVERROR(EINVAL);
+ }
if (!frame->channel_layout) {
- if (avctx->channel_layout) {
- if (av_get_channel_layout_nb_channels(avctx->channel_layout)
!=
- avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "Inconsistent channel "
- "configuration.\n");
- return AVERROR(EINVAL);
- }
-
- frame->channel_layout = avctx->channel_layout;
- } else {
- if (avctx->channels > FF_SANE_NB_CHANNELS) {
- av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n",
- avctx->channels);
- return AVERROR(ENOSYS);
- }
-
- frame->channel_layout =
av_get_default_channel_layout(avctx->channels);
+ if (frame->ch_layout.order == AV_CHANNEL_ORDER_NATIVE)
+ frame->channel_layout = frame->ch_layout.u.mask;
+ else {
+ frame->channel_layout =
av_get_default_channel_layout(frame->ch_layout.nb_channels);
if (!frame->channel_layout)
- frame->channel_layout = (1ULL << avctx->channels) - 1;
+ frame->channel_layout = (1ULL <<
frame->ch_layout.nb_channels) - 1;
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (!av_channel_layout_check(&frame->ch_layout)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid channel layout.\n");
+ return AVERROR_INVALIDDATA;
+ }
break;
default: return AVERROR(EINVAL);
}
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 9bb7ae5bde..cf77fa7cff 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -60,8 +60,17 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst,
const AVFrame *src)
return AVERROR(ENOMEM);
frame->format = src->format;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
frame->channel_layout = src->channel_layout;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
frame->nb_samples = s->frame_size;
+
+ ret = av_channel_layout_copy(&frame->ch_layout, &src->ch_layout);
+ if (ret < 0)
+ goto fail;
+
ret = av_frame_get_buffer(frame, 32);
if (ret < 0)
goto fail;
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 9cd5f9ab37..ad1a5273f6 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -140,11 +140,20 @@ fail:
static int get_audio_buffer(AVFrame *frame, int align)
{
- int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+ int channels = frame->ch_layout.nb_channels;
int planar = av_sample_fmt_is_planar(frame->format);
int planes = planar ? channels : 1;
int ret, i;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!channels) {
+ av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout);
+ channels = frame->ch_layout.nb_channels;
+ planes = planar ? channels : 1;
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (!frame->linesize[0]) {
ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
frame->nb_samples, frame->format,
@@ -194,7 +203,14 @@ int av_frame_get_buffer(AVFrame *frame, int align)
if (frame->width > 0 && frame->height > 0)
return get_video_buffer(frame, align);
- else if (frame->nb_samples > 0 && frame->channel_layout)
+ else if (frame->nb_samples > 0 &&
+ (av_channel_layout_check(&frame->ch_layout)
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ || frame->channel_layout
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ ))
return get_audio_buffer(frame, align);
return AVERROR(EINVAL);
@@ -207,13 +223,26 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
dst->format = src->format;
dst->width = src->width;
dst->height = src->height;
- dst->channel_layout = src->channel_layout;
dst->nb_samples = src->nb_samples;
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ dst->channel_layout = src->channel_layout;
+ if (!av_channel_layout_check(&src->ch_layout))
+ av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
ret = av_frame_copy_props(dst, src);
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);
@@ -264,7 +293,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
/* duplicate extended data */
if (src->extended_data != src->data) {
- int ch = av_get_channel_layout_nb_channels(src->channel_layout);
+ int ch = dst->ch_layout.nb_channels;
if (!ch) {
ret = AVERROR(EINVAL);
@@ -319,6 +348,8 @@ void av_frame_unref(AVFrame *frame)
av_buffer_unref(&frame->opaque_ref);
+ av_channel_layout_uninit(&frame->ch_layout);
+
get_frame_defaults(frame);
}
@@ -362,8 +393,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.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;
@@ -458,7 +499,14 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int
plane)
int planes, i;
if (frame->nb_samples) {
- int channels =
av_get_channel_layout_nb_channels(frame->channel_layout);
+ 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;
planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
@@ -552,12 +600,27 @@ 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 = av_get_channel_layout_nb_channels(dst->channel_layout);
+ int channels = dst->ch_layout.nb_channels;
int planes = planar ? channels : 1;
int i;
- if (dst->nb_samples != src->nb_samples ||
- 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
+
+ if (dst->nb_samples != src->nb_samples ||
+ av_channel_layout_compare(&dst->ch_layout, &src->ch_layout)
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ || dst->channel_layout != src->channel_layout
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ )
return AVERROR(EINVAL);
for (i = 0; i < planes; i++)
@@ -577,7 +640,14 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
if (dst->width > 0 && dst->height > 0)
return frame_copy_video(dst, src);
- else if (dst->nb_samples > 0 && dst->channel_layout)
+ else if (dst->nb_samples > 0 &&
+ (av_channel_layout_check(&dst->ch_layout)
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+ || dst->channel_layout
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ ))
return frame_copy_audio(dst, src);
return AVERROR(EINVAL);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index f9ffb5bbbf..afa655026f 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"
@@ -304,10 +305,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
@@ -406,6 +411,11 @@ typedef struct AVFrame {
* purpose.
*/
AVBufferRef *opaque_ref;
+
+ /**
+ * Channel layout of the audio data.
+ */
+ AVChannelLayout ch_layout;
} AVFrame;
/**
@@ -475,7 +485,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.12.0
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel