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 "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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Reference in a new issue