forked from FFmpeg/FFmpeg
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:
parent
09b5d3fb44
commit
db6efa1815
2 changed files with 121 additions and 23 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue