avframe: switch to the new channel layout API

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
Anton Khirnov 2013-05-06 19:55:36 +02:00 committed by James Almer
parent 09b5d3fb44
commit db6efa1815
2 changed files with 121 additions and 23 deletions

View file

@ -28,10 +28,12 @@
#include "samplefmt.h" #include "samplefmt.h"
#include "hwcontext.h" #include "hwcontext.h"
#if FF_API_OLD_CHANNEL_LAYOUT
#define CHECK_CHANNELS_CONSISTENCY(frame) \ #define CHECK_CHANNELS_CONSISTENCY(frame) \
av_assert2(!(frame)->channel_layout || \ av_assert2(!(frame)->channel_layout || \
(frame)->channels == \ (frame)->channels == \
av_get_channel_layout_nb_channels((frame)->channel_layout)) av_get_channel_layout_nb_channels((frame)->channel_layout))
#endif
#if FF_API_COLORSPACE_NAME #if FF_API_COLORSPACE_NAME
const char *av_get_colorspace_name(enum AVColorSpace val) const char *av_get_colorspace_name(enum AVColorSpace val)
@ -186,18 +188,27 @@ fail:
static int get_audio_buffer(AVFrame *frame, int align) static int get_audio_buffer(AVFrame *frame, int align)
{ {
int channels;
int planar = av_sample_fmt_is_planar(frame->format); int planar = av_sample_fmt_is_planar(frame->format);
int planes; int channels, planes;
int ret, i; int ret, i;
if (!frame->channels) #if FF_API_OLD_CHANNEL_LAYOUT
frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); FF_DISABLE_DEPRECATION_WARNINGS
if (!frame->ch_layout.nb_channels) {
channels = frame->channels; if (frame->channel_layout) {
planes = planar ? channels : 1; av_channel_layout_from_mask(&frame->ch_layout, frame->channel_layout);
} else {
CHECK_CHANNELS_CONSISTENCY(frame); 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]) { if (!frame->linesize[0]) {
ret = av_samples_get_buffer_size(&frame->linesize[0], channels, ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
frame->nb_samples, frame->format, frame->nb_samples, frame->format,
@ -245,10 +256,17 @@ int av_frame_get_buffer(AVFrame *frame, int align)
if (frame->format < 0) if (frame->format < 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
FF_DISABLE_DEPRECATION_WARNINGS
if (frame->width > 0 && frame->height > 0) if (frame->width > 0 && frame->height > 0)
return get_video_buffer(frame, align); 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); return get_audio_buffer(frame, align);
FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
@ -327,19 +345,44 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
int i, ret = 0; int i, ret = 0;
av_assert1(dst->width == 0 && dst->height == 0); av_assert1(dst->width == 0 && dst->height == 0);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
av_assert1(dst->channels == 0); av_assert1(dst->channels == 0);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
av_assert1(dst->ch_layout.nb_channels == 0 &&
dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
dst->format = src->format; dst->format = src->format;
dst->width = src->width; dst->width = src->width;
dst->height = src->height; 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->channels = src->channels;
dst->channel_layout = src->channel_layout; 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); ret = frame_copy_props(dst, src, 0);
if (ret < 0) if (ret < 0)
goto fail; 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 */ /* duplicate the frame data if it's not refcounted */
if (!src->buf[0]) { if (!src->buf[0]) {
ret = av_frame_get_buffer(dst, 0); ret = av_frame_get_buffer(dst, 0);
@ -392,13 +435,12 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
/* duplicate extended data */ /* duplicate extended data */
if (src->extended_data != src->data) { if (src->extended_data != src->data) {
int ch = src->channels; int ch = dst->ch_layout.nb_channels;
if (!ch) { if (!ch) {
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto fail; goto fail;
} }
CHECK_CHANNELS_CONSISTENCY(src);
dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch);
if (!dst->extended_data) { if (!dst->extended_data) {
@ -456,13 +498,21 @@ void av_frame_unref(AVFrame *frame)
if (frame->extended_data != frame->data) if (frame->extended_data != frame->data)
av_freep(&frame->extended_data); av_freep(&frame->extended_data);
av_channel_layout_uninit(&frame->ch_layout);
get_frame_defaults(frame); get_frame_defaults(frame);
} }
void av_frame_move_ref(AVFrame *dst, AVFrame *src) void av_frame_move_ref(AVFrame *dst, AVFrame *src)
{ {
av_assert1(dst->width == 0 && dst->height == 0); av_assert1(dst->width == 0 && dst->height == 0);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
av_assert1(dst->channels == 0); av_assert1(dst->channels == 0);
FF_ENABLE_DEPRECATION_WARNINGS
#endif
av_assert1(dst->ch_layout.nb_channels == 0 &&
dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
*dst = *src; *dst = *src;
if (src->extended_data == src->data) if (src->extended_data == src->data)
@ -502,9 +552,18 @@ int av_frame_make_writable(AVFrame *frame)
tmp.format = frame->format; tmp.format = frame->format;
tmp.width = frame->width; tmp.width = frame->width;
tmp.height = frame->height; tmp.height = frame->height;
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
tmp.channels = frame->channels; tmp.channels = frame->channels;
tmp.channel_layout = frame->channel_layout; tmp.channel_layout = frame->channel_layout;
FF_ENABLE_DEPRECATION_WARNINGS
#endif
tmp.nb_samples = frame->nb_samples; 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) if (frame->hw_frames_ctx)
ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0); ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0);
@ -545,10 +604,18 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane)
int planes, i; int planes, i;
if (frame->nb_samples) { 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 = frame->channels;
CHECK_CHANNELS_CONSISTENCY(frame);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
if (!channels) if (!channels)
return NULL; return NULL;
CHECK_CHANNELS_CONSISTENCY(frame);
planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
} else } else
planes = 4; planes = 4;
@ -654,16 +721,26 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src)
static int frame_copy_audio(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 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 planes = planar ? channels : 1;
int i; int i;
if (dst->nb_samples != src->nb_samples || #if FF_API_OLD_CHANNEL_LAYOUT
dst->channels != src->channels || FF_DISABLE_DEPRECATION_WARNINGS
dst->channel_layout != src->channel_layout) if (!channels) {
return AVERROR(EINVAL); if (dst->channels != src->channels ||
dst->channel_layout != src->channel_layout)
return AVERROR(EINVAL);
channels = dst->channels;
planes = planar ? channels : 1;
CHECK_CHANNELS_CONSISTENCY(src);
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
CHECK_CHANNELS_CONSISTENCY(src); if (dst->nb_samples != src->nb_samples ||
av_channel_layout_compare(&dst->ch_layout, &src->ch_layout))
return AVERROR(EINVAL);
for (i = 0; i < planes; i++) for (i = 0; i < planes; i++)
if (!dst->extended_data[i] || !src->extended_data[i]) if (!dst->extended_data[i] || !src->extended_data[i])
@ -680,10 +757,17 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
if (dst->format != src->format || dst->format < 0) if (dst->format != src->format || dst->format < 0)
return AVERROR(EINVAL); return AVERROR(EINVAL);
FF_DISABLE_DEPRECATION_WARNINGS
if (dst->width > 0 && dst->height > 0) if (dst->width > 0 && dst->height > 0)
return frame_copy_video(dst, src); 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); return frame_copy_audio(dst, src);
FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }

View file

@ -30,6 +30,7 @@
#include "avutil.h" #include "avutil.h"
#include "buffer.h" #include "buffer.h"
#include "channel_layout.h"
#include "dict.h" #include "dict.h"
#include "rational.h" #include "rational.h"
#include "samplefmt.h" #include "samplefmt.h"
@ -500,10 +501,14 @@ typedef struct AVFrame {
*/ */
int sample_rate; int sample_rate;
#if FF_API_OLD_CHANNEL_LAYOUT
/** /**
* Channel layout of the audio data. * Channel layout of the audio data.
* @deprecated use ch_layout instead
*/ */
attribute_deprecated
uint64_t channel_layout; uint64_t channel_layout;
#endif
/** /**
* AVBuffer references backing the data for this frame. All the pointers in * AVBuffer references backing the data for this frame. All the pointers in
@ -627,12 +632,16 @@ typedef struct AVFrame {
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4 #define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4
#define FF_DECODE_ERROR_DECODE_SLICES 8 #define FF_DECODE_ERROR_DECODE_SLICES 8
#if FF_API_OLD_CHANNEL_LAYOUT
/** /**
* number of audio channels, only used for audio. * number of audio channels, only used for audio.
* - encoding: unused * - encoding: unused
* - decoding: Read by user. * - decoding: Read by user.
* @deprecated use ch_layout instead
*/ */
attribute_deprecated
int channels; int channels;
#endif
/** /**
* size of the corresponding packet containing the compressed * size of the corresponding packet containing the compressed
@ -688,6 +697,11 @@ typedef struct AVFrame {
* for the target frame's private_ref field. * for the target frame's private_ref field.
*/ */
AVBufferRef *private_ref; AVBufferRef *private_ref;
/**
* Channel layout of the audio data.
*/
AVChannelLayout ch_layout;
} AVFrame; } AVFrame;
@ -767,7 +781,7 @@ void av_frame_move_ref(AVFrame *dst, AVFrame *src);
* The following fields must be set on frame before calling this function: * The following fields must be set on frame before calling this function:
* - format (pixel format for video, sample format for audio) * - format (pixel format for video, sample format for audio)
* - width and height for video * - 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 * This function will fill AVFrame.data and AVFrame.buf arrays and, if
* necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf. * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.