diff --git a/configure b/configure index 712ed947ff..ca0f8e8c37 100755 --- a/configure +++ b/configure @@ -3155,7 +3155,7 @@ vp6a_decoder_select="vp6_decoder" vp6f_decoder_select="vp6_decoder" vp7_decoder_select="h264pred videodsp vp8dsp" vp8_decoder_select="h264pred videodsp vp8dsp" -vp9_decoder_select="videodsp vp9_parser vp9_superframe_split_bsf" +vp9_decoder_select="videodsp vp9_parser cbs_vp9 vp9_superframe_split_bsf" vvc_decoder_select="cabac cbs_h266 golomb videodsp vvc_sei" wcmv_decoder_select="inflate_wrapper" webp_decoder_select="vp8_decoder exif" diff --git a/libavcodec/cbs_vp9.h b/libavcodec/cbs_vp9.h index af15eb4bac..588765b873 100644 --- a/libavcodec/cbs_vp9.h +++ b/libavcodec/cbs_vp9.h @@ -206,6 +206,14 @@ typedef struct CodedBitstreamVP9Context { uint8_t subsampling_y; int bit_depth; + int8_t loop_filter_ref_deltas[VP9_MAX_REF_FRAMES]; + int8_t loop_filter_mode_deltas[2]; + uint8_t segmentation_tree_probs[7]; + uint8_t segmentation_pred_prob[3]; + uint8_t feature_enabled[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX]; + uint8_t feature_value[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX]; + uint8_t feature_sign[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX]; + VP9ReferenceFrameState ref[VP9_NUM_REF_FRAMES]; } CodedBitstreamVP9Context; diff --git a/libavcodec/cbs_vp9_syntax_template.c b/libavcodec/cbs_vp9_syntax_template.c index 2f08eccf18..9c4f09eac9 100644 --- a/libavcodec/cbs_vp9_syntax_template.c +++ b/libavcodec/cbs_vp9_syntax_template.c @@ -152,6 +152,7 @@ static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, VP9RawFrameHeader *current) { + CodedBitstreamVP9Context *vp9 = ctx->priv_data; int err, i; f(6, loop_filter_level); @@ -159,6 +160,8 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, f(1, loop_filter_delta_enabled); if (current->loop_filter_delta_enabled) { + memcpy(current->loop_filter_ref_deltas, vp9->loop_filter_ref_deltas, sizeof(vp9->loop_filter_ref_deltas)); + memcpy(current->loop_filter_mode_deltas, vp9->loop_filter_mode_deltas, sizeof(vp9->loop_filter_mode_deltas)); f(1, loop_filter_delta_update); if (current->loop_filter_delta_update) { for (i = 0; i < VP9_MAX_REF_FRAMES; i++) { @@ -171,6 +174,8 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, if (current->update_mode_delta[i]) ss(6, loop_filter_mode_deltas[i], 1, i); } + memcpy(vp9->loop_filter_ref_deltas, current->loop_filter_ref_deltas, sizeof(vp9->loop_filter_ref_deltas)); + memcpy(vp9->loop_filter_mode_deltas, current->loop_filter_mode_deltas, sizeof(vp9->loop_filter_mode_deltas)); } } @@ -197,11 +202,17 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, static const uint8_t segmentation_feature_bits[VP9_SEG_LVL_MAX] = { 8, 6, 2, 0 }; static const uint8_t segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 }; + CodedBitstreamVP9Context *vp9 = ctx->priv_data; int err, i, j; f(1, segmentation_enabled); if (current->segmentation_enabled) { + memcpy(current->segmentation_tree_probs, vp9->segmentation_tree_probs, sizeof(vp9->segmentation_tree_probs)); + memcpy(current->segmentation_pred_prob, vp9->segmentation_pred_prob, sizeof(vp9->segmentation_pred_prob)); + memcpy(current->feature_enabled, vp9->feature_enabled, sizeof(vp9->feature_enabled)); + memcpy(current->feature_value, vp9->feature_value, sizeof(vp9->feature_value)); + memcpy(current->feature_sign, vp9->feature_sign, sizeof(vp9->feature_sign)); f(1, segmentation_update_map); if (current->segmentation_update_map) { for (i = 0; i < 7; i++) @@ -213,6 +224,8 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, else infer(segmentation_pred_prob[i], 255); } + memcpy(vp9->segmentation_tree_probs, current->segmentation_tree_probs, sizeof(vp9->segmentation_tree_probs)); + memcpy(vp9->segmentation_pred_prob, current->segmentation_pred_prob, sizeof(vp9->segmentation_pred_prob)); } f(1, segmentation_update_data); @@ -235,6 +248,9 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, } } } + memcpy(vp9->feature_enabled, current->feature_enabled, sizeof(vp9->feature_enabled)); + memcpy(vp9->feature_value, current->feature_value, sizeof(vp9->feature_value)); + memcpy(vp9->feature_sign, current->feature_sign, sizeof(vp9->feature_sign)); } } @@ -352,6 +368,18 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, f(2, frame_context_idx); + if (current->frame_type == VP9_KEY_FRAME || current->error_resilient_mode || current->intra_only) { + infer(update_ref_delta[0], 1); + infer(update_ref_delta[1], 0); + infer(update_ref_delta[2], -1); + infer(update_ref_delta[3], -1); + infer(loop_filter_mode_deltas[0], 0); + infer(loop_filter_mode_deltas[1], 0); + memset(vp9->feature_enabled, 0, sizeof(current->feature_enabled)); + memset(vp9->feature_value, 0, sizeof(current->feature_value)); + memset(vp9->feature_sign, 0, sizeof(current->feature_sign)); + } + CHECK(FUNC(loop_filter_params)(ctx, rw, current)); CHECK(FUNC(quantization_params)(ctx, rw, current)); CHECK(FUNC(segmentation_params)(ctx, rw, current)); diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 141f0941b4..66ba572c78 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -97,6 +97,7 @@ static void vp9_tile_data_free(VP9TileData *td) static void vp9_frame_unref(VP9Frame *f) { ff_progress_frame_unref(&f->tf); + av_refstruct_unref(&f->header_ref); av_refstruct_unref(&f->extradata); av_refstruct_unref(&f->hwaccel_picture_private); f->segmentation_map = NULL; @@ -145,6 +146,9 @@ fail: static void vp9_frame_replace(VP9Frame *dst, const VP9Frame *src) { + av_refstruct_replace(&dst->header_ref, src->header_ref); + dst->frame_header = src->frame_header; + ff_progress_frame_replace(&dst->tf, &src->tf); av_refstruct_replace(&dst->extradata, src->extradata); @@ -1248,6 +1252,7 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) for (i = 0; i < 8; i++) { ff_progress_frame_unref(&s->s.refs[i]); ff_progress_frame_unref(&s->next_refs[i]); + vp9_frame_unref(&s->s.ref_frames[i]); } free_buffers(s); @@ -1255,6 +1260,11 @@ static av_cold int vp9_decode_free(AVCodecContext *avctx) av_freep(&s->entries); ff_pthread_free(s, vp9_context_offsets); #endif + + av_refstruct_unref(&s->header_ref); + ff_cbs_fragment_free(&s->current_frag); + ff_cbs_close(&s->cbc); + av_freep(&s->td); return 0; } @@ -1557,11 +1567,27 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, int size = pkt->size; VP9Context *s = avctx->priv_data; int ret, i, j, ref; + CodedBitstreamUnit *unit; + VP9RawFrame *rf; + int retain_segmap_ref = s->s.frames[REF_FRAME_SEGMAP].segmentation_map && (!s->s.h.segmentation.enabled || !s->s.h.segmentation.update_map); const VP9Frame *src; AVFrame *f; + ret = ff_cbs_read_packet(s->cbc, &s->current_frag, pkt); + if (ret < 0) { + ff_cbs_fragment_reset(&s->current_frag); + av_log(avctx, AV_LOG_ERROR, "Failed to read frame header.\n"); + return ret; + } + + unit = &s->current_frag.units[0]; + rf = unit->content; + + av_refstruct_replace(&s->header_ref, unit->content_ref); + s->frame_header = &rf->header; + if ((ret = decode_frame_header(avctx, data, size, &ref)) < 0) { return ret; } else if (ret == 0) { @@ -1573,6 +1599,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, ff_progress_frame_replace(&s->next_refs[i], &s->s.refs[i]); ff_thread_finish_setup(avctx); ff_progress_frame_await(&s->s.refs[ref], INT_MAX); + ff_cbs_fragment_reset(&s->current_frag); if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) return ret; @@ -1592,6 +1619,10 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, vp9_frame_unref(&s->s.frames[CUR_FRAME]); if ((ret = vp9_frame_alloc(avctx, &s->s.frames[CUR_FRAME])) < 0) return ret; + + s->s.frames[CUR_FRAME].header_ref = av_refstruct_ref(s->header_ref); + s->s.frames[CUR_FRAME].frame_header = s->frame_header; + f = s->s.frames[CUR_FRAME].tf.f; if (s->s.h.keyframe) f->flags |= AV_FRAME_FLAG_KEY; @@ -1628,6 +1659,15 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, ret = hwaccel->end_frame(avctx); if (ret < 0) return ret; + + for (i = 0; i < 8; i++) { + vp9_frame_replace(&s->s.ref_frames[i], + s->s.h.refreshrefmask & (1 << i) ? + &s->s.frames[CUR_FRAME] : &s->s.ref_frames[i]); + } + + ff_cbs_fragment_reset(&s->current_frag); + goto finish; } @@ -1776,8 +1816,14 @@ static void vp9_decode_flush(AVCodecContext *avctx) for (i = 0; i < 3; i++) vp9_frame_unref(&s->s.frames[i]); - for (i = 0; i < 8; i++) + + for (i = 0; i < 8; i++) { ff_progress_frame_unref(&s->s.refs[i]); + vp9_frame_unref(&s->s.ref_frames[i]); + } + + ff_cbs_fragment_reset(&s->current_frag); + ff_cbs_flush(s->cbc); if (FF_HW_HAS_CB(avctx, flush)) FF_HW_SIMPLE_CALL(avctx, flush); @@ -1791,6 +1837,10 @@ static av_cold int vp9_decode_init(AVCodecContext *avctx) s->last_bpp = 0; s->s.h.filter.sharpness = -1; + ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_VP9, avctx); + if (ret < 0) + return ret; + #if HAVE_THREADS if (avctx->active_thread_type & FF_THREAD_SLICE) { ret = ff_pthread_init(s, vp9_context_offsets); @@ -1814,6 +1864,13 @@ static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo av_refstruct_replace(&s->frame_extradata_pool, ssrc->frame_extradata_pool); s->frame_extradata_pool_size = ssrc->frame_extradata_pool_size; + av_refstruct_replace(&s->header_ref, ssrc->header_ref); + for (int i = 0; i < 8; i++) + vp9_frame_replace(&s->s.ref_frames[i], &ssrc->s.ref_frames[i]); + + s->frame_header = ssrc->frame_header; + memcpy(s->cbc->priv_data, ssrc->cbc->priv_data, sizeof(CodedBitstreamVP9Context)); + s->s.h.invisible = ssrc->s.h.invisible; s->s.h.keyframe = ssrc->s.h.keyframe; s->s.h.intraonly = ssrc->s.h.intraonly; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index e41f47a82a..c3ad2bbcdb 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -38,6 +38,7 @@ #include "vp9dsp.h" #include "vp9shared.h" #include "vpx_rac.h" +#include "cbs_vp9.h" #define REF_INVALID_SCALE 0xFFFF @@ -97,6 +98,11 @@ typedef struct VP9Context { VP9SharedContext s; VP9TileData *td; + CodedBitstreamContext *cbc; + CodedBitstreamFragment current_frag; + VP9RawFrame *header_ref; ///< RefStruct reference backing frame_header + VP9RawFrameHeader *frame_header; + VP9DSPContext dsp; VideoDSPContext vdsp; GetBitContext gb; diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h index 8a450c26a6..098372f8a4 100644 --- a/libavcodec/vp9shared.h +++ b/libavcodec/vp9shared.h @@ -30,6 +30,7 @@ #include "libavutil/mem_internal.h" #include "progressframe.h" +#include "cbs_vp9.h" #include "vp9.h" enum BlockPartition { @@ -63,6 +64,9 @@ typedef struct VP9mvrefPair { } VP9mvrefPair; typedef struct VP9Frame { + VP9RawFrame *header_ref; ///< RefStruct reference backing frame_header + VP9RawFrameHeader *frame_header; + ProgressFrame tf; void *extradata; ///< RefStruct reference uint8_t *segmentation_map; @@ -170,6 +174,7 @@ typedef struct VP9SharedContext { #define REF_FRAME_SEGMAP 2 #define BLANK_FRAME 3 VP9Frame frames[4]; + VP9Frame ref_frames[8]; } VP9SharedContext; #endif /* AVCODEC_VP9SHARED_H */ diff --git a/tests/ref/fate/cbs-vp9-vp90-2-03-deltaq b/tests/ref/fate/cbs-vp9-vp90-2-03-deltaq index f621d7a480..addf9a942a 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-03-deltaq +++ b/tests/ref/fate/cbs-vp9-vp90-2-03-deltaq @@ -1 +1 @@ -fe62460fe28202e0666e628afd8602ca +0f43cdcbdc97ea6651c56540d97610e5 diff --git a/tests/ref/fate/cbs-vp9-vp90-2-05-resize b/tests/ref/fate/cbs-vp9-vp90-2-05-resize index 8f036bba81..965bbb272e 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-05-resize +++ b/tests/ref/fate/cbs-vp9-vp90-2-05-resize @@ -1 +1 @@ -6838422ebb45df353a2bad62b9aff8e9 +af456bb18c4f5e6fb83c559769ce1b07 diff --git a/tests/ref/fate/cbs-vp9-vp90-2-06-bilinear b/tests/ref/fate/cbs-vp9-vp90-2-06-bilinear index 9359e21e40..ffa375790b 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-06-bilinear +++ b/tests/ref/fate/cbs-vp9-vp90-2-06-bilinear @@ -1 +1 @@ -179e228004c396a301c89f34b6c72f68 +af98321cd43a36f065f8c728e22f2c06 diff --git a/tests/ref/fate/cbs-vp9-vp90-2-09-lf_deltas b/tests/ref/fate/cbs-vp9-vp90-2-09-lf_deltas index 5b21675c76..313a531945 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-09-lf_deltas +++ b/tests/ref/fate/cbs-vp9-vp90-2-09-lf_deltas @@ -1 +1 @@ -1d1f0768c547461ae2abef57f0aabc24 +8b4ce818cde9621481b6bf7997b544b8 diff --git a/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame b/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame index 19b7a78dd8..d87d1b7185 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame +++ b/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame @@ -1 +1 @@ -13fa042ee1b4079c227a5c5c96e2db38 +ea65b698e86322709257caf9038da40a diff --git a/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame2 b/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame2 index e7bf2a078d..fa8d684e42 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame2 +++ b/tests/ref/fate/cbs-vp9-vp90-2-10-show-existing-frame2 @@ -1 +1 @@ -2ab7c95e4637fb6a15efd8c0a8d6af98 +c1047aeeb593f2f87818d9bd19cb12f2 diff --git a/tests/ref/fate/cbs-vp9-vp90-2-segmentation-aq-akiyo b/tests/ref/fate/cbs-vp9-vp90-2-segmentation-aq-akiyo index f30889dbdc..f2b03031a4 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-segmentation-aq-akiyo +++ b/tests/ref/fate/cbs-vp9-vp90-2-segmentation-aq-akiyo @@ -1 +1 @@ -b5be66a6a8792f7aac090beb9f3b4555 +cb14fde4f0f99d6e962fb109d3db36ee diff --git a/tests/ref/fate/cbs-vp9-vp90-2-segmentation-sf-akiyo b/tests/ref/fate/cbs-vp9-vp90-2-segmentation-sf-akiyo index dca77f2113..a7d074c28c 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-segmentation-sf-akiyo +++ b/tests/ref/fate/cbs-vp9-vp90-2-segmentation-sf-akiyo @@ -1 +1 @@ -7bde6532fc682bfa3f5170cf9d607865 +0f1cfba95edb2446689547fc012f741b diff --git a/tests/ref/fate/cbs-vp9-vp90-2-tiling-pedestrian b/tests/ref/fate/cbs-vp9-vp90-2-tiling-pedestrian index 0aa3cc8ce6..d029f01530 100644 --- a/tests/ref/fate/cbs-vp9-vp90-2-tiling-pedestrian +++ b/tests/ref/fate/cbs-vp9-vp90-2-tiling-pedestrian @@ -1 +1 @@ -1e40e8b48e4682e8b8004b9e0e60a5b6 +db40458891febf9f007c98e735e02ab9 diff --git a/tests/ref/fate/cbs-vp9-vp91-2-04-yuv440 b/tests/ref/fate/cbs-vp9-vp91-2-04-yuv440 index 947e1229eb..fe81cc0b39 100644 --- a/tests/ref/fate/cbs-vp9-vp91-2-04-yuv440 +++ b/tests/ref/fate/cbs-vp9-vp91-2-04-yuv440 @@ -1 +1 @@ -9bb416c0304a13c4f66c56aef8431cd4 +855cffb78a063ad0dfc432ae593974a2 diff --git a/tests/ref/fate/cbs-vp9-vp91-2-04-yuv444 b/tests/ref/fate/cbs-vp9-vp91-2-04-yuv444 index bf251138ed..1b7a1acc6f 100644 --- a/tests/ref/fate/cbs-vp9-vp91-2-04-yuv444 +++ b/tests/ref/fate/cbs-vp9-vp91-2-04-yuv444 @@ -1 +1 @@ -3a7ed001d30f96d4888f5ca16e6263ce +8f6c44c4098915261e7708ab270877ff diff --git a/tests/ref/fate/cbs-vp9-vp92-2-20-10bit-yuv420 b/tests/ref/fate/cbs-vp9-vp92-2-20-10bit-yuv420 index 2cad8b947c..23d980ea0f 100644 --- a/tests/ref/fate/cbs-vp9-vp92-2-20-10bit-yuv420 +++ b/tests/ref/fate/cbs-vp9-vp92-2-20-10bit-yuv420 @@ -1 +1 @@ -7315bb7b55693a87c350b48cd2ee9811 +0ed4ec02fd72c0b594d74c5cbd7e252f diff --git a/tests/ref/fate/cbs-vp9-vp93-2-20-10bit-yuv422 b/tests/ref/fate/cbs-vp9-vp93-2-20-10bit-yuv422 index bb1c0f7ea7..0a77ebbd58 100644 --- a/tests/ref/fate/cbs-vp9-vp93-2-20-10bit-yuv422 +++ b/tests/ref/fate/cbs-vp9-vp93-2-20-10bit-yuv422 @@ -1 +1 @@ -1a7b5bf86bf0bbef10c9a1b2c799b276 +1e8d7e1bd62a04bf47270c72a1c55bb7 diff --git a/tests/ref/fate/cbs-vp9-vp93-2-20-12bit-yuv444 b/tests/ref/fate/cbs-vp9-vp93-2-20-12bit-yuv444 index 9b7b358d04..9705dfeb50 100644 --- a/tests/ref/fate/cbs-vp9-vp93-2-20-12bit-yuv444 +++ b/tests/ref/fate/cbs-vp9-vp93-2-20-12bit-yuv444 @@ -1 +1 @@ -9b7a0b7fc081542d9be1074b23054861 +c2ca28679265c1c86d4a7ef60cc061ff