[FFmpeg-devel] [PATCH 1/9] lavu/frame: avframe add type property
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Fri Aug 20 05:44:39 EEST 2021
Soft Works:
>
>
>> -----Original Message-----
>> From: ffmpeg-devel <ffmpeg-devel-bounces at ffmpeg.org> On Behalf Of Soft Works
>> Sent: Thursday, 19 August 2021 09:43
>> To: ffmpeg-devel at ffmpeg.org
>> Subject: [FFmpeg-devel] [PATCH 1/9] lavu/frame: avframe add type property
>>
>> Signed-off-by: softworkz <softworkz at hotmail.com>
>> ---
>> libavutil/frame.c | 74 ++++++++++++++++++++++++++++++++++++---------
>> libavutil/frame.h | 39 ++++++++++++++++++++++--
>> libavutil/version.h | 2 +-
>> 3 files changed, 97 insertions(+), 18 deletions(-)
>>
>> diff --git a/libavutil/frame.c b/libavutil/frame.c
>> index b0ceaf7145..7d95849cef 100644
>> --- a/libavutil/frame.c
>> +++ b/libavutil/frame.c
>> @@ -244,22 +244,39 @@ static int get_audio_buffer(AVFrame *frame, int align)
>> }
>>
>> int av_frame_get_buffer(AVFrame *frame, int align)
>> +{
>> + if (frame->width > 0 && frame->height > 0)
>> + return av_frame_get_buffer2(frame, AVMEDIA_TYPE_VIDEO, align);
>> + else if (frame->nb_samples > 0 && (frame->channel_layout || frame-
>>> channels > 0))
>> + return av_frame_get_buffer2(frame, AVMEDIA_TYPE_AUDIO, align);
>> +
>> + return AVERROR(EINVAL);
>> +}
>> +
>> +int av_frame_get_buffer2(AVFrame *frame, enum AVMediaType type, int align)
>> {
>> if (frame->format < 0)
>> return AVERROR(EINVAL);
>>
>> - if (frame->width > 0 && frame->height > 0)
>> + frame->type = type;
>> +
>> + switch(frame->type) {
>> + case AVMEDIA_TYPE_VIDEO:
>> return get_video_buffer(frame, align);
>> - else if (frame->nb_samples > 0 && (frame->channel_layout || frame-
>>> channels > 0))
>> + case AVMEDIA_TYPE_AUDIO:
>> return get_audio_buffer(frame, align);
>> -
>> - return AVERROR(EINVAL);
>> + case AVMEDIA_TYPE_SUBTITLE:
>> + return 0;
>> + default:
>> + return AVERROR(EINVAL);
>> + }
>> }
>>
>> static int frame_copy_props(AVFrame *dst, const AVFrame *src, int
>> force_copy)
>> {
>> int ret, i;
>>
>> + dst->type = src->type;
>> dst->key_frame = src->key_frame;
>> dst->pict_type = src->pict_type;
>> dst->sample_aspect_ratio = src->sample_aspect_ratio;
>> @@ -331,6 +348,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
>> av_assert1(dst->width == 0 && dst->height == 0);
>> av_assert1(dst->channels == 0);
>>
>> + dst->type = src->type;
>> dst->format = src->format;
>> dst->width = src->width;
>> dst->height = src->height;
>> @@ -499,6 +517,7 @@ int av_frame_make_writable(AVFrame *frame)
>> return 0;
>>
>> memset(&tmp, 0, sizeof(tmp));
>> + tmp.type = frame->type;
>> tmp.format = frame->format;
>> tmp.width = frame->width;
>> tmp.height = frame->height;
>> @@ -544,14 +563,22 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame,
>> int plane)
>> uint8_t *data;
>> int planes, i;
>>
>> - if (frame->nb_samples) {
>> - int channels = frame->channels;
>> - if (!channels)
>> - return NULL;
>> - CHECK_CHANNELS_CONSISTENCY(frame);
>> - planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
>> - } else
>> + switch(frame->type) {
>> + case AVMEDIA_TYPE_VIDEO:
>> planes = 4;
>> + break;
>> + case AVMEDIA_TYPE_AUDIO:
>> + {
>> + int channels = frame->channels;
>> + if (!channels)
>> + return NULL;
>> + CHECK_CHANNELS_CONSISTENCY(frame);
>> + planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
>> + break;
>> + }
>> + default:
>> + return NULL;
>> + }
>>
>> if (plane < 0 || plane >= planes || !frame->extended_data[plane])
>> return NULL;
>> @@ -675,17 +702,34 @@ static int frame_copy_audio(AVFrame *dst, const AVFrame
>> *src)
>> return 0;
>> }
>>
>> +static int frame_copy_subtitles(AVFrame *dst, const AVFrame *src)
>> +{
>> + dst->type = AVMEDIA_TYPE_SUBTITLE;
>> + dst->format = src->format;
>> +
>> + if (src->buf[0]) {
>> + dst->buf[0] = av_buffer_ref(src->buf[0]);
>> + dst->data[0] = src->data[0];
>> + }
>> +
>> + return 0;
>> +}
>> +
>> int av_frame_copy(AVFrame *dst, const AVFrame *src)
>> {
>> if (dst->format != src->format || dst->format < 0)
>> return AVERROR(EINVAL);
>>
>> - if (dst->width > 0 && dst->height > 0)
>> + switch(dst->type) {
>> + case AVMEDIA_TYPE_VIDEO:
>> return frame_copy_video(dst, src);
>> - else if (dst->nb_samples > 0 && dst->channels > 0)
>> + case AVMEDIA_TYPE_AUDIO:
>> return frame_copy_audio(dst, src);
>> -
>> - return AVERROR(EINVAL);
>> + case AVMEDIA_TYPE_SUBTITLE:
>> + return frame_copy_subtitles(dst, src);
>> + default:
>> + return AVERROR(EINVAL);
>> + }
>> }
>>
>> void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType
>> type)
>> diff --git a/libavutil/frame.h b/libavutil/frame.h
>> index ff2540a20f..c104815df9 100644
>> --- a/libavutil/frame.h
>> +++ b/libavutil/frame.h
>> @@ -271,7 +271,7 @@ typedef struct AVRegionOfInterest {
>> } AVRegionOfInterest;
>>
>> /**
>> - * This structure describes decoded (raw) audio or video data.
>> + * This structure describes decoded (raw) audio, video or subtitle data.
>> *
>> * AVFrame must be allocated using av_frame_alloc(). Note that this only
>> * allocates the AVFrame itself, the buffers for the data must be managed
>> @@ -302,6 +302,13 @@ typedef struct AVRegionOfInterest {
>> */
>> typedef struct AVFrame {
>> #define AV_NUM_DATA_POINTERS 8
>> + /**
>> + * Media type of the frame (audio, video, subtitles..)
>> + *
>> + * See AVMEDIA_TYPE_xxx
>> + */
>> + enum AVMediaType type;
>> +
>
> AFAIK, adding a member anywhere but the end of a structure would require
> a major version bump?
>
We are currently in an ABI unstable period (e.g. Lynne added some fields
to AVPacket, a structure whose size is part of the public ABI), so it
can be done now.
> I had done that major bump originally but it resulted in a fate error
> (checkasm av_tx)
>
Weird. What was the error?
- Andreas
More information about the ffmpeg-devel
mailing list