[FFmpeg-devel] [PATCH V2 2/3] avcodec: add av1 hardware acceleration decoder
James Almer
jamrial at gmail.com
Thu Sep 3 00:28:26 EEST 2020
On 9/2/2020 12:18 PM, James Almer wrote:
> On 9/2/2020 4:31 AM, Fei Wang wrote:
>> This av1 decoder is now only used for av1 hardware acceleration
>> decoder. Consider it can be extend to a local decoder like hevc
>> or vp9 in the future, so define its name as "av1" and put it into
>> external libraries codec list.
>>
>> Signed-off-by: Fei Wang <fei.w.wang at intel.com>
>> ---
>> Changelog | 1 +
>> configure | 1 +
>> libavcodec/Makefile | 1 +
>> libavcodec/allcodecs.c | 1 +
>> libavcodec/av1dec.c | 728 +++++++++++++++++++++++++++++++++++++++++
>> libavcodec/av1dec.h | 70 ++++
>> libavcodec/version.h | 4 +-
>> 7 files changed, 804 insertions(+), 2 deletions(-)
>> create mode 100644 libavcodec/av1dec.c
>> create mode 100644 libavcodec/av1dec.h
[...]
>> +static av_cold int av1_decode_init(AVCodecContext *avctx)
>> +{
>> + AV1DecContext *s = avctx->priv_data;
>> + int ret = 0;
>> +
>> + for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
>> + s->ref[i].tf.f = av_frame_alloc();
>> + if (!s->ref[i].tf.f) {
>> + av1_decode_free(avctx);
>> + av_log(avctx, AV_LOG_ERROR,
>> + "Failed to allocate reference frame buffer %d.\n", i);
>> + return AVERROR(ENOMEM);
>> + }
>> + }
>> +
>> + s->cur_frame.tf.f = av_frame_alloc();
>> + if (!s->cur_frame.tf.f) {
>> + av1_decode_free(avctx);
>> + av_log(avctx, AV_LOG_ERROR,
>> + "Failed to allocate current frame buffer.\n");
>> + return AVERROR(ENOMEM);
>> + }
>> +
>> + s->avctx = avctx;
>> + s->pix_fmt = AV_PIX_FMT_NONE;
>> + s->seq_ref = NULL;
>> + s->header_ref = NULL;
>> +
>> + ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_AV1, avctx);
>> + if (ret < 0)
>> + return ret;
>
> You should parse avctx->extradata with ff_cbs_read(), if any, and
> initialize avctx with values taken from the filled AV1RawSequenceHeader.
> Profile, level, color info, timing info, the like.
For that matter, the same should be done in the loop in
av1_decode_frame() for all AV1_OBU_SEQUENCE_HEADER instances, since
extradata is not guaranteed to always be present.
So just add a function that takes an AV1RawSequenceHeader argument to
initialize avctx fields, and call it from here and av1_decode_frame() as
needed.
[...]
>> + }
>> + free_tile_data(s);
>> + raw_tile_group = NULL;
>> + }
>> + }
>
> You're duplicating a bit of code in the loop above. You could merge it
> even more. Frame header and Frame are both the same up to the point the
> Tile Group bits would start for the latter.
>
> You could do something like:
>
> /*****/
> switch (unit->type) {
> case AV1_OBU_REDUNDANT_FRAME_HEADER:
> if (s->cur_frame_header)
This was meant to be s->raw_frame_header, here and below.
> break; // In the middle of a frame, so ignore it
> // fall-through
> case AV1_OBU_FRAME:
> case AV1_OBU_FRAME_HEADER:
> /* s->cur_frame_header_buf set here */
>
> if (unit->type == AV1_OBU_FRAME)
> s->cur_frame_header = &obu->obu.frame.header;
> else
> s->cur_frame_header = &obu->obu.frame_header;
>
> /* Frame header handling code here */
>
> if (unit->type != AV1_OBU_FRAME)
> break; // Keep going only for Frame OBUs
> // fall-through
> case AV1_OBU_TILE_GROUP:
> if (!s->cur_frame_header) { // Sanity check
> ret = AVERROR_INVALIDDATA;
> goto end;
> }
> if (unit->type == AV1_OBU_FRAME)
> raw_tile_group = &obu->obu.frame.tile_group;
> else
> raw_tile_group = &obu->obu.tile_group;
>
> /* Tile group handling code here */
>
> break;
> }
>
> if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) {
> /* Finish frame, output it if show_frame == 1 */
>
> s->cur_frame_header = NULL;
> raw_tile_group = NULL;
> }
> /*****/
>
More information about the ffmpeg-devel
mailing list