mbox series

[FFmpeg-devel,0/3,v2] Restructuring the encode API

Message ID 20200316213002.46612-1-jamrial@gmail.com
Headers show
Series Restructuring the encode API | expand

Message

James Almer March 16, 2020, 9:29 p.m. UTC
This set follows the same logic as 061a0c14bb, but for the encode API: The
new public API will no longer be a wrapper around the old deprecated one, and
the internal API used by the encoders now consists of a single receive_packet()
callback that pulls frames as required.

Because of the above, PATCH 1/3 can't be applied until all the relevant encoders
have been adapted, and said changes squashed into it. This means librav1e, nvenc,
amfenc, v4l2_m2m, and vaapi_enc.
I have ported librav1e both to test this set and for it to work as an example
for the maintainers of the other three encoders in order to get an idea of what
they should do. Similarly, Andriy Gelman ported v4l2_m2m_enc in 
http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2020-March/258192.html

James Almer (3):
  avcodec/encode: restructure the core encoding code
  avcodec/encode: restructure the old encode API
  avcodec/librav1e: adapt to the new internal encode API

 libavcodec/avcodec.h  |  12 +-
 libavcodec/decode.c   |   1 -
 libavcodec/encode.c   | 559 +++++++++++++++++++++---------------------
 libavcodec/encode.h   |  39 +++
 libavcodec/internal.h |   8 +-
 libavcodec/librav1e.c |  51 ++--
 libavcodec/utils.c    |  18 +-
 7 files changed, 381 insertions(+), 307 deletions(-)
 create mode 100644 libavcodec/encode.h

Comments

James Almer March 16, 2020, 11:30 p.m. UTC | #1
On 3/16/2020 6:30 PM, James Almer wrote:
> +static int encode_send_packet_internal(AVCodecContext *avctx, const AVFrame *src)
> +{
> +    AVCodecInternal *avci = avctx->internal;
> +    AVFrame *dst = avci->buffer_frame;
> +    int ret;
> +
> +    if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
> +        /* extract audio service type metadata */
> +        AVFrameSideData *sd = av_frame_get_side_data(src, AV_FRAME_DATA_AUDIO_SERVICE_TYPE);
> +        if (sd && sd->size >= sizeof(enum AVAudioServiceType))
> +            avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data;
> +
> +        /* check for valid frame size */
> +        if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) {
> +            if (src->nb_samples > avctx->frame_size) {
> +                av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n");
> +                return AVERROR(EINVAL);
> +            }
> +        } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) {
> +            /* if we already got an undersized frame, that must have been the last */
> +            if (avctx->internal->last_audio_frame) {
> +                av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size);
> +                return AVERROR(EINVAL);
> +            }
> +
> +            if (src->nb_samples < avctx->frame_size) {
> +                ret = pad_last_frame(avctx, &dst, src);
> +                if (ret < 0)
> +                    return ret;
> +
> +                avctx->internal->last_audio_frame = 1;
> +            } else if (src->nb_samples > avctx->frame_size) {
> +                av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", dst->nb_samples, avctx->frame_size);

Should be src->nb_samples. Changed locally.

> +                ret = AVERROR(EINVAL);
> +                goto end;

I guess i can remove this and the label below.

> +            }
> +        }
> +    }
> +
> +    if (!dst->data[0]) {
> +        ret = av_frame_ref(dst, src);
> +        if (ret < 0)
> +             return ret;
> +    }
> +
> +    return 0;
> +
> +end:
> +    av_frame_unref(dst);
> +
>      return ret;
>  }