]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/av1dec.c
avutil/timecode: allow drop frame timecodes for multiples of 30000/1001 fps
[ffmpeg] / libavcodec / av1dec.c
index 9e71a2e5f69b46e7fae42d020cab262854953ad3..1589b8f0c0087cdadd9e56df9366942fc757e4e8 100644 (file)
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "av1dec.h"
-#include "get_bits.h"
+#include "bytestream.h"
 #include "hwconfig.h"
 #include "internal.h"
 #include "profiles.h"
 
-static void setup_past_independence(AV1Frame *f)
-{
-    f->loop_filter_delta_enabled = 1;
-
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_INTRA] = 1;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST] = 0;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST2] = 0;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_LAST3] = 0;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_GOLDEN] = -1;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_BWDREF] = 0;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF2] = -1;
-    f->loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF] = -1;
-
-    f->loop_filter_mode_deltas[0] = 0;
-    f->loop_filter_mode_deltas[1] = 0;
-}
-
-static void load_previous_and_update(AV1DecContext *s)
-{
-    uint8_t primary_frame, prev_frame;
-
-    primary_frame = s->raw_frame_header->primary_ref_frame;
-    prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame];
-    memcpy(s->cur_frame.loop_filter_ref_deltas,
-           s->ref[prev_frame].loop_filter_ref_deltas,
-           AV1_NUM_REF_FRAMES * sizeof(int8_t));
-    memcpy(s->cur_frame.loop_filter_mode_deltas,
-           s->ref[prev_frame].loop_filter_mode_deltas,
-           2 * sizeof(int8_t));
-
-    if (s->raw_frame_header->loop_filter_delta_update) {
-        for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) {
-            if (s->raw_frame_header->update_ref_delta[i])
-                s->cur_frame.loop_filter_ref_deltas[i] =
-                    s->raw_frame_header->loop_filter_ref_deltas[i];
-        }
-
-        for (int i = 0; i < 2; i++) {
-            if (s->raw_frame_header->update_mode_delta[i])
-                s->cur_frame.loop_filter_mode_deltas[i] =
-                    s->raw_frame_header->loop_filter_mode_deltas[i];
-        }
-    }
-
-    s->cur_frame.loop_filter_delta_enabled =
-        s->raw_frame_header->loop_filter_delta_enabled;
-}
-
 static uint32_t inverse_recenter(int r, uint32_t v)
 {
     if (v > 2 * r)
@@ -105,13 +57,22 @@ static void read_global_param(AV1DecContext *s, int type, int ref, int idx)
 {
     uint8_t primary_frame, prev_frame;
     uint32_t abs_bits, prec_bits, round, prec_diff, sub, mx;
-    int32_t r;
+    int32_t r, prev_gm_param;
 
     primary_frame = s->raw_frame_header->primary_ref_frame;
     prev_frame = s->raw_frame_header->ref_frame_idx[primary_frame];
     abs_bits = AV1_GM_ABS_ALPHA_BITS;
     prec_bits = AV1_GM_ALPHA_PREC_BITS;
 
+    /* setup_past_independence() sets PrevGmParams to default values. We can
+     * simply point to the current's frame gm_params as they will be initialized
+     * with defaults at this point.
+     */
+    if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE)
+        prev_gm_param = s->cur_frame.gm_params[ref][idx];
+    else
+        prev_gm_param = s->ref[prev_frame].gm_params[ref][idx];
+
     if (idx < 2) {
         if (type == AV1_WARP_MODEL_TRANSLATION) {
             abs_bits = AV1_GM_ABS_TRANS_ONLY_BITS -
@@ -127,7 +88,7 @@ static void read_global_param(AV1DecContext *s, int type, int ref, int idx)
     prec_diff = AV1_WARPEDMODEL_PREC_BITS - prec_bits;
     sub = (idx % 3) == 2 ? (1 << prec_bits) : 0;
     mx = 1 << abs_bits;
-    r = (s->ref[prev_frame].gm_params[ref][idx] >> prec_diff) - sub;
+    r = (prev_gm_param >> prec_diff) - sub;
 
     s->cur_frame.gm_params[ref][idx] =
         (decode_signed_subexp_with_ref(s->raw_frame_header->gm_params[ref][idx],
@@ -184,6 +145,128 @@ static void global_motion_params(AV1DecContext *s)
     }
 }
 
+static int get_relative_dist(const AV1RawSequenceHeader *seq,
+                             unsigned int a, unsigned int b)
+{
+    unsigned int diff = a - b;
+    unsigned int m = 1 << seq->order_hint_bits_minus_1;
+    return (diff & (m - 1)) - (diff & m);
+}
+
+static void skip_mode_params(AV1DecContext *s)
+{
+    const AV1RawFrameHeader *header = s->raw_frame_header;
+    const AV1RawSequenceHeader *seq = s->raw_seq;
+
+    int forward_idx,  backward_idx;
+    int forward_hint, backward_hint;
+    int second_forward_idx, second_forward_hint;
+    int ref_hint, dist, i;
+
+    if (!header->skip_mode_present)
+        return;
+
+    forward_idx  = -1;
+    backward_idx = -1;
+    for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
+        ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint;
+        dist = get_relative_dist(seq, ref_hint, header->order_hint);
+        if (dist < 0) {
+            if (forward_idx < 0 ||
+                get_relative_dist(seq, ref_hint, forward_hint) > 0) {
+                forward_idx  = i;
+                forward_hint = ref_hint;
+            }
+        } else if (dist > 0) {
+            if (backward_idx < 0 ||
+                get_relative_dist(seq, ref_hint, backward_hint) < 0) {
+                backward_idx  = i;
+                backward_hint = ref_hint;
+            }
+        }
+    }
+
+    if (forward_idx < 0) {
+        return;
+    } else if (backward_idx >= 0) {
+        s->cur_frame.skip_mode_frame_idx[0] =
+            AV1_REF_FRAME_LAST + FFMIN(forward_idx, backward_idx);
+        s->cur_frame.skip_mode_frame_idx[1] =
+            AV1_REF_FRAME_LAST + FFMAX(forward_idx, backward_idx);
+        return;
+    }
+
+    second_forward_idx = -1;
+    for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
+        ref_hint = s->ref[header->ref_frame_idx[i]].raw_frame_header->order_hint;
+        if (get_relative_dist(seq, ref_hint, forward_hint) < 0) {
+            if (second_forward_idx < 0 ||
+                get_relative_dist(seq, ref_hint, second_forward_hint) > 0) {
+                second_forward_idx  = i;
+                second_forward_hint = ref_hint;
+            }
+        }
+    }
+
+    if (second_forward_idx < 0)
+        return;
+
+    s->cur_frame.skip_mode_frame_idx[0] =
+        AV1_REF_FRAME_LAST + FFMIN(forward_idx, second_forward_idx);
+    s->cur_frame.skip_mode_frame_idx[1] =
+        AV1_REF_FRAME_LAST + FFMAX(forward_idx, second_forward_idx);
+}
+
+static void coded_lossless_param(AV1DecContext *s)
+{
+    const AV1RawFrameHeader *header = s->raw_frame_header;
+    int i;
+
+    if (header->delta_q_y_dc || header->delta_q_u_ac ||
+        header->delta_q_u_dc || header->delta_q_v_ac ||
+        header->delta_q_v_dc) {
+        s->cur_frame.coded_lossless = 0;
+        return;
+    }
+
+    s->cur_frame.coded_lossless = 1;
+    for (i = 0; i < AV1_MAX_SEGMENTS; i++) {
+        int qindex;
+        if (header->feature_enabled[i][AV1_SEG_LVL_ALT_Q]) {
+            qindex = (header->base_q_idx +
+                      header->feature_value[i][AV1_SEG_LVL_ALT_Q]);
+        } else {
+            qindex = header->base_q_idx;
+        }
+        qindex = av_clip_uintp2(qindex, 8);
+
+        if (qindex) {
+            s->cur_frame.coded_lossless = 0;
+            return;
+        }
+    }
+}
+
+static void load_grain_params(AV1DecContext *s)
+{
+    const AV1RawFrameHeader *header = s->raw_frame_header;
+    const AV1RawFilmGrainParams *film_grain = &header->film_grain, *src;
+    AV1RawFilmGrainParams *dst = &s->cur_frame.film_grain;
+
+    if (!film_grain->apply_grain)
+        return;
+
+    if (film_grain->update_grain) {
+        memcpy(dst, film_grain, sizeof(*dst));
+        return;
+    }
+
+    src = &s->ref[film_grain->film_grain_params_ref_idx].film_grain;
+
+    memcpy(dst, src, sizeof(*dst));
+    dst->grain_seed = film_grain->grain_seed;
+}
+
 static int init_tile_data(AV1DecContext *s)
 
 {
@@ -205,18 +288,12 @@ static int init_tile_data(AV1DecContext *s)
 static int get_tiles_info(AVCodecContext *avctx, const AV1RawTileGroup *tile_group)
 {
     AV1DecContext *s = avctx->priv_data;
-    GetBitContext gb;
+    GetByteContext gb;
     uint16_t tile_num, tile_row, tile_col;
-    uint32_t size = 0, size_bytes = 0, offset = 0;
-    int ret;
-
-    if ((ret = init_get_bits8(&gb,
-                              tile_group->tile_data.data,
-                              tile_group->tile_data.data_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader.\n");
-        return ret;
-    }
+    uint32_t size = 0, size_bytes = 0;
 
+    bytestream2_init(&gb, tile_group->tile_data.data,
+                     tile_group->tile_data.data_size);
     s->tg_start = tile_group->tg_start;
     s->tg_end = tile_group->tg_end;
 
@@ -225,24 +302,28 @@ static int get_tiles_info(AVCodecContext *avctx, const AV1RawTileGroup *tile_gro
         tile_col = tile_num % s->raw_frame_header->tile_cols;
 
         if (tile_num == tile_group->tg_end) {
-            s->tile_group_info[tile_num].tile_size = get_bits_left(&gb) / 8;
-            s->tile_group_info[tile_num].tile_offset = offset;
+            s->tile_group_info[tile_num].tile_size = bytestream2_get_bytes_left(&gb);
+            s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb);
             s->tile_group_info[tile_num].tile_row = tile_row;
             s->tile_group_info[tile_num].tile_column = tile_col;
             return 0;
         }
         size_bytes = s->raw_frame_header->tile_size_bytes_minus1 + 1;
-        size = get_bits_le(&gb, size_bytes * 8) + 1;
-        skip_bits(&gb, size * 8);
-
-        offset += size_bytes;
+        if (bytestream2_get_bytes_left(&gb) < size_bytes)
+            return AVERROR_INVALIDDATA;
+        size = 0;
+        for (int i = 0; i < size_bytes; i++)
+            size |= bytestream2_get_byteu(&gb) << 8 * i;
+        if (bytestream2_get_bytes_left(&gb) <= size)
+            return AVERROR_INVALIDDATA;
+        size++;
 
         s->tile_group_info[tile_num].tile_size = size;
-        s->tile_group_info[tile_num].tile_offset = offset;
+        s->tile_group_info[tile_num].tile_offset = bytestream2_tell(&gb);
         s->tile_group_info[tile_num].tile_row = tile_row;
         s->tile_group_info[tile_num].tile_column = tile_col;
 
-        offset += size;
+        bytestream2_skipu(&gb, size);
     }
 
     return 0;
@@ -256,19 +337,11 @@ static int get_pixel_format(AVCodecContext *avctx)
     uint8_t bit_depth;
     int ret;
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
-#define HWACCEL_MAX (0)
-    enum AVPixelFormat pix_fmts[HWACCEL_MAX + 1], *fmtp = pix_fmts;
-
-    /**
-     * check if the HW accel is inited correctly. If not, return un-implemented.
-     * Since now the av1 decoder doesn't support native decode, if it will be
-     * implemented in the future, need remove this check.
-     */
-    if (!avctx->hwaccel) {
-        av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport"
-               " hardware accelerated AV1 decoding.\n");
-        return AVERROR(ENOSYS);
-    }
+#define HWACCEL_MAX (CONFIG_AV1_DXVA2_HWACCEL + \
+                     CONFIG_AV1_D3D11VA_HWACCEL * 2 + \
+                     CONFIG_AV1_NVDEC_HWACCEL + \
+                     CONFIG_AV1_VAAPI_HWACCEL)
+    enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
 
     if (seq->seq_profile == 2 && seq->color_config.high_bitdepth)
         bit_depth = seq->color_config.twelve_bit ? 12 : 10;
@@ -328,12 +401,57 @@ static int get_pixel_format(AVCodecContext *avctx)
         return -1;
     s->pix_fmt = pix_fmt;
 
+    switch (s->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+#if CONFIG_AV1_DXVA2_HWACCEL
+        *fmtp++ = AV_PIX_FMT_DXVA2_VLD;
+#endif
+#if CONFIG_AV1_D3D11VA_HWACCEL
+        *fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
+        *fmtp++ = AV_PIX_FMT_D3D11;
+#endif
+#if CONFIG_AV1_NVDEC_HWACCEL
+        *fmtp++ = AV_PIX_FMT_CUDA;
+#endif
+#if CONFIG_AV1_VAAPI_HWACCEL
+        *fmtp++ = AV_PIX_FMT_VAAPI;
+#endif
+        break;
+    case AV_PIX_FMT_YUV420P10:
+#if CONFIG_AV1_DXVA2_HWACCEL
+        *fmtp++ = AV_PIX_FMT_DXVA2_VLD;
+#endif
+#if CONFIG_AV1_D3D11VA_HWACCEL
+        *fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
+        *fmtp++ = AV_PIX_FMT_D3D11;
+#endif
+#if CONFIG_AV1_NVDEC_HWACCEL
+        *fmtp++ = AV_PIX_FMT_CUDA;
+#endif
+#if CONFIG_AV1_VAAPI_HWACCEL
+        *fmtp++ = AV_PIX_FMT_VAAPI;
+#endif
+        break;
+    }
+
+    *fmtp++ = s->pix_fmt;
     *fmtp = AV_PIX_FMT_NONE;
-    avctx->sw_pix_fmt = s->pix_fmt;
+
     ret = ff_thread_get_format(avctx, pix_fmts);
     if (ret < 0)
         return ret;
 
+    /**
+     * check if the HW accel is inited correctly. If not, return un-implemented.
+     * Since now the av1 decoder doesn't support native decode, if it will be
+     * implemented in the future, need remove this check.
+     */
+    if (!avctx->hwaccel) {
+        av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport"
+               " hardware accelerated AV1 decoding.\n");
+        return AVERROR(ENOSYS);
+    }
+
     avctx->pix_fmt = ret;
 
     return 0;
@@ -344,6 +462,13 @@ static void av1_frame_unref(AVCodecContext *avctx, AV1Frame *f)
     ff_thread_release_buffer(avctx, &f->tf);
     av_buffer_unref(&f->hwaccel_priv_buf);
     f->hwaccel_picture_private = NULL;
+    av_buffer_unref(&f->header_ref);
+    f->raw_frame_header = NULL;
+    f->spatial_id = f->temporal_id = 0;
+    memset(f->skip_mode_frame_idx, 0,
+           2 * sizeof(uint8_t));
+    memset(&f->film_grain, 0, sizeof(f->film_grain));
+    f->coded_lossless = 0;
 }
 
 static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *src)
@@ -354,6 +479,12 @@ static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *s
     if (ret < 0)
         return ret;
 
+    dst->header_ref = av_buffer_ref(src->header_ref);
+    if (!dst->header_ref)
+        goto fail;
+
+    dst->raw_frame_header = src->raw_frame_header;
+
     if (src->hwaccel_picture_private) {
         dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
         if (!dst->hwaccel_priv_buf)
@@ -361,19 +492,21 @@ static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *s
         dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
     }
 
-    dst->loop_filter_delta_enabled = src->loop_filter_delta_enabled;
-    memcpy(dst->loop_filter_ref_deltas,
-           src->loop_filter_ref_deltas,
-           AV1_NUM_REF_FRAMES * sizeof(int8_t));
-    memcpy(dst->loop_filter_mode_deltas,
-           src->loop_filter_mode_deltas,
-           2 * sizeof(int8_t));
+    dst->spatial_id = src->spatial_id;
+    dst->temporal_id = src->temporal_id;
     memcpy(dst->gm_type,
            src->gm_type,
            AV1_NUM_REF_FRAMES * sizeof(uint8_t));
     memcpy(dst->gm_params,
            src->gm_params,
            AV1_NUM_REF_FRAMES * 6 * sizeof(int32_t));
+    memcpy(dst->skip_mode_frame_idx,
+           src->skip_mode_frame_idx,
+           2 * sizeof(uint8_t));
+    memcpy(&dst->film_grain,
+           &src->film_grain,
+           sizeof(dst->film_grain));
+    dst->coded_lossless = src->coded_lossless;
 
     return 0;
 
@@ -387,12 +520,10 @@ static av_cold int av1_decode_free(AVCodecContext *avctx)
     AV1DecContext *s = avctx->priv_data;
 
     for (int i = 0; i < FF_ARRAY_ELEMS(s->ref); i++) {
-        if (s->ref[i].tf.f->buf[0])
-            av1_frame_unref(avctx, &s->ref[i]);
+        av1_frame_unref(avctx, &s->ref[i]);
         av_frame_free(&s->ref[i].tf.f);
     }
-    if (s->cur_frame.tf.f->buf[0])
-        av1_frame_unref(avctx, &s->cur_frame);
+    av1_frame_unref(avctx, &s->cur_frame);
     av_frame_free(&s->cur_frame.tf.f);
 
     av_buffer_unref(&s->seq_ref);
@@ -408,6 +539,9 @@ static av_cold int av1_decode_free(AVCodecContext *avctx)
 static int set_context_with_sequence(AVCodecContext *avctx,
                                      const AV1RawSequenceHeader *seq)
 {
+    int width = seq->max_frame_width_minus_1 + 1;
+    int height = seq->max_frame_height_minus_1 + 1;
+
     avctx->profile = seq->seq_profile;
     avctx->level = seq->seq_level_idx[0];
 
@@ -417,6 +551,22 @@ static int set_context_with_sequence(AVCodecContext *avctx,
     avctx->colorspace = seq->color_config.color_primaries;
     avctx->color_trc = seq->color_config.transfer_characteristics;
 
+    switch (seq->color_config.chroma_sample_position) {
+    case AV1_CSP_VERTICAL:
+        avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+        break;
+    case AV1_CSP_COLOCATED:
+        avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
+        break;
+    }
+
+    if (avctx->width != width || avctx->height != height) {
+        int ret = ff_set_dimensions(avctx, width, height);
+        if (ret < 0)
+            return ret;
+    }
+    avctx->sample_aspect_ratio = (AVRational) { 1, 1 };
+
     if (seq->timing_info.num_units_in_display_tick &&
         seq->timing_info.time_scale) {
         av_reduce(&avctx->framerate.den, &avctx->framerate.num,
@@ -472,7 +622,6 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
     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);
@@ -481,7 +630,6 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
 
     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);
@@ -492,11 +640,12 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
         return ret;
 
     if (avctx->extradata && avctx->extradata_size) {
-        ret = ff_cbs_read(s->cbc, &s->current_obu, avctx->extradata,
-                          avctx->extradata_size);
+        ret = ff_cbs_read_extradata_from_codec(s->cbc,
+                                               &s->current_obu,
+                                               avctx);
         if (ret < 0) {
             av_log(avctx, AV_LOG_WARNING, "Failed to read extradata.\n");
-            goto end;
+            return ret;
         }
 
         seq = ((CodedBitstreamAV1Context *)(s->cbc->priv_data))->sequence_header;
@@ -525,6 +674,12 @@ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f)
     AVFrame *frame;
     int ret;
 
+    f->header_ref = av_buffer_ref(s->header_ref);
+    if (!f->header_ref)
+        return AVERROR(ENOMEM);
+
+    f->raw_frame_header = s->raw_frame_header;
+
     ret = update_context_with_frame_header(avctx, header);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "Failed to update context with frame header\n");
@@ -571,15 +726,9 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame,
                             const AVPacket *pkt, int *got_frame)
 {
     AV1DecContext *s = avctx->priv_data;
-    const AV1RawFrameHeader *header = s->raw_frame_header;
-    const AVFrame *srcframe;
+    const AVFrame *srcframe = s->cur_frame.tf.f;
     int ret;
 
-    if (header->show_existing_frame)
-        srcframe = s->ref[header->frame_to_show_map_idx].tf.f;
-    else
-        srcframe = s->cur_frame.tf.f;
-
     ret = av_frame_ref(frame, srcframe);
     if (ret < 0)
         return ret;
@@ -634,12 +783,10 @@ static int get_current_frame(AVCodecContext *avctx)
         return ret;
     }
 
-    if (s->raw_frame_header->primary_ref_frame == AV1_PRIMARY_REF_NONE)
-        setup_past_independence(&s->cur_frame);
-    else
-        load_previous_and_update(s);
-
     global_motion_params(s);
+    skip_mode_params(s);
+    coded_lossless_param(s);
+    load_grain_params(s);
 
     return ret;
 }
@@ -662,6 +809,12 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
     for (int i = 0; i < s->current_obu.nb_units; i++) {
         CodedBitstreamUnit *unit = &s->current_obu.units[i];
         AV1RawOBU *obu = unit->content;
+        const AV1RawOBUHeader *header;
+
+        if (!obu)
+            continue;
+
+        header = &obu->header;
         av_log(avctx, AV_LOG_DEBUG, "Obu idx:%d, obu type:%d.\n", i, unit->type);
 
         switch (unit->type) {
@@ -678,6 +831,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
             ret = set_context_with_sequence(avctx, s->raw_seq);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Failed to set context.\n");
+                s->raw_seq = NULL;
                 goto end;
             }
 
@@ -686,6 +840,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                 if (ret < 0) {
                     av_log(avctx, AV_LOG_ERROR,
                            "Failed to get pixel format.\n");
+                    s->raw_seq = NULL;
                     goto end;
                 }
             }
@@ -695,6 +850,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                                                     unit->data_size);
                 if (ret < 0) {
                     av_log(avctx, AV_LOG_ERROR, "HW accel decode params fail.\n");
+                    s->raw_seq = NULL;
                     goto end;
                 }
             }
@@ -705,7 +861,7 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
         // fall-through
         case AV1_OBU_FRAME:
         case AV1_OBU_FRAME_HEADER:
-            if (!s->seq_ref) {
+            if (!s->raw_seq) {
                 av_log(avctx, AV_LOG_ERROR, "Missing Sequence Header.\n");
                 ret = AVERROR_INVALIDDATA;
                 goto end;
@@ -724,6 +880,22 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                 s->raw_frame_header = &obu->obu.frame_header;
 
             if (s->raw_frame_header->show_existing_frame) {
+                if (s->cur_frame.tf.f->buf[0])
+                    av1_frame_unref(avctx, &s->cur_frame);
+
+                ret = av1_frame_ref(avctx, &s->cur_frame,
+                                    &s->ref[s->raw_frame_header->frame_to_show_map_idx]);
+                if (ret < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "Failed to get reference frame.\n");
+                    goto end;
+                }
+
+                ret = update_reference_list(avctx);
+                if (ret < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "Failed to update reference list.\n");
+                    goto end;
+                }
+
                 ret = set_output_frame(avctx, frame, pkt, got_frame);
                 if (ret < 0)
                     av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
@@ -739,6 +911,9 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
                 goto end;
             }
 
+            s->cur_frame.spatial_id  = header->spatial_id;
+            s->cur_frame.temporal_id = header->temporal_id;
+
             if (avctx->hwaccel) {
                 ret = avctx->hwaccel->start_frame(avctx, unit->data,
                                                   unit->data_size);
@@ -762,7 +937,9 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
             else
                 raw_tile_group = &obu->obu.tile_group;
 
-            get_tiles_info(avctx, raw_tile_group);
+            ret = get_tiles_info(avctx, raw_tile_group);
+            if (ret < 0)
+                goto end;
 
             if (avctx->hwaccel) {
                 ret = avctx->hwaccel->decode_slice(avctx,
@@ -815,6 +992,8 @@ static int av1_decode_frame(AVCodecContext *avctx, void *frame,
 
 end:
     ff_cbs_fragment_reset(&s->current_obu);
+    if (ret < 0)
+        s->raw_frame_header = NULL;
     return ret;
 }
 
@@ -828,6 +1007,8 @@ static void av1_decode_flush(AVCodecContext *avctx)
     av1_frame_unref(avctx, &s->cur_frame);
     s->raw_frame_header = NULL;
     s->raw_seq = NULL;
+
+    ff_cbs_flush(s->cbc);
 }
 
 AVCodec ff_av1_decoder = {
@@ -846,6 +1027,21 @@ AVCodec ff_av1_decoder = {
     .flush                 = av1_decode_flush,
     .profiles              = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
     .hw_configs            = (const AVCodecHWConfigInternal * []) {
+#if CONFIG_AV1_DXVA2_HWACCEL
+        HWACCEL_DXVA2(av1),
+#endif
+#if CONFIG_AV1_D3D11VA_HWACCEL
+        HWACCEL_D3D11VA(av1),
+#endif
+#if CONFIG_AV1_D3D11VA2_HWACCEL
+        HWACCEL_D3D11VA2(av1),
+#endif
+#if CONFIG_AV1_NVDEC_HWACCEL
+        HWACCEL_NVDEC(av1),
+#endif
+#if CONFIG_AV1_VAAPI_HWACCEL
+        HWACCEL_VAAPI(av1),
+#endif
         NULL
     },
 };