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 "hwcontext.h"
#if FF_API_OLD_CHANNEL_LAYOUT
#define CHECK_CHANNELS_CONSISTENCY(frame) \
av_assert2(!(frame)->channel_layout || \
(frame)->channels == \
av_get_channel_layout_nb_channels((frame)->channel_layout))
#endif
#if FF_API_COLORSPACE_NAME
const char *av_get_colorspace_name(enum AVColorSpace val)
@ -186,18 +188,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 +256,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);
}
@ -327,19 +345,44 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
int i, ret = 0;
av_assert1(dst->width == 0 && dst->height == 0);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
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->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 +435,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,13 +498,21 @@ 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);
}
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
{
av_assert1(dst->width == 0 && dst->height == 0);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
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;
if (src->extended_data == src->data)
@ -502,9 +552,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 +604,18 @@ 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 = frame->channels;
CHECK_CHANNELS_CONSISTENCY(frame);
}
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,16 +721,26 @@ 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)
return AVERROR(EINVAL);
#if FF_API_OLD_CHANNEL_LAYOUT
FF_DISABLE_DEPRECATION_WARNINGS
if (!channels) {
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++)
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)
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);
}

View file

@ -30,6 +30,7 @@
#include "avutil.h"
#include "buffer.h"
#include "channel_layout.h"
#include "dict.h"
#include "rational.h"
#include "samplefmt.h"
@ -500,10 +501,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
@ -627,12 +632,16 @@ typedef struct AVFrame {
#define FF_DECODE_ERROR_CONCEALMENT_ACTIVE 4
#define FF_DECODE_ERROR_DECODE_SLICES 8
#if FF_API_OLD_CHANNEL_LAYOUT
/**
* number of audio channels, only used for audio.
* - encoding: unused
* - decoding: Read by user.
* @deprecated use ch_layout instead
*/
attribute_deprecated
int channels;
#endif
/**
* size of the corresponding packet containing the compressed
@ -688,6 +697,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;
@ -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:
* - 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.