1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

lavc/vp9dec: use cbs_vp9 to parse the frame header

This commit is contained in:
Lynne
2025-03-27 04:54:54 +00:00
parent 7f150dc4b7
commit c0bf1382a7
20 changed files with 120 additions and 16 deletions

2
configure vendored
View File

@@ -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"

View File

@@ -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;

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -1 +1 @@
fe62460fe28202e0666e628afd8602ca
0f43cdcbdc97ea6651c56540d97610e5

View File

@@ -1 +1 @@
6838422ebb45df353a2bad62b9aff8e9
af456bb18c4f5e6fb83c559769ce1b07

View File

@@ -1 +1 @@
179e228004c396a301c89f34b6c72f68
af98321cd43a36f065f8c728e22f2c06

View File

@@ -1 +1 @@
1d1f0768c547461ae2abef57f0aabc24
8b4ce818cde9621481b6bf7997b544b8

View File

@@ -1 +1 @@
13fa042ee1b4079c227a5c5c96e2db38
ea65b698e86322709257caf9038da40a

View File

@@ -1 +1 @@
2ab7c95e4637fb6a15efd8c0a8d6af98
c1047aeeb593f2f87818d9bd19cb12f2

View File

@@ -1 +1 @@
b5be66a6a8792f7aac090beb9f3b4555
cb14fde4f0f99d6e962fb109d3db36ee

View File

@@ -1 +1 @@
7bde6532fc682bfa3f5170cf9d607865
0f1cfba95edb2446689547fc012f741b

View File

@@ -1 +1 @@
1e40e8b48e4682e8b8004b9e0e60a5b6
db40458891febf9f007c98e735e02ab9

View File

@@ -1 +1 @@
9bb416c0304a13c4f66c56aef8431cd4
855cffb78a063ad0dfc432ae593974a2

View File

@@ -1 +1 @@
3a7ed001d30f96d4888f5ca16e6263ce
8f6c44c4098915261e7708ab270877ff

View File

@@ -1 +1 @@
7315bb7b55693a87c350b48cd2ee9811
0ed4ec02fd72c0b594d74c5cbd7e252f

View File

@@ -1 +1 @@
1a7b5bf86bf0bbef10c9a1b2c799b276
1e8d7e1bd62a04bf47270c72a1c55bb7

View File

@@ -1 +1 @@
9b7a0b7fc081542d9be1074b23054861
c2ca28679265c1c86d4a7ef60cc061ff