From: Anton Khirnov <an...@khirnov.net> Signed-off-by: Vittorio Giovara <vittorio.giov...@gmail.com> --- 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 libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel