You've already forked FFmpeg
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:
2
configure
vendored
2
configure
vendored
@@ -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"
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -1 +1 @@
|
||||
fe62460fe28202e0666e628afd8602ca
|
||||
0f43cdcbdc97ea6651c56540d97610e5
|
||||
|
@@ -1 +1 @@
|
||||
6838422ebb45df353a2bad62b9aff8e9
|
||||
af456bb18c4f5e6fb83c559769ce1b07
|
||||
|
@@ -1 +1 @@
|
||||
179e228004c396a301c89f34b6c72f68
|
||||
af98321cd43a36f065f8c728e22f2c06
|
||||
|
@@ -1 +1 @@
|
||||
1d1f0768c547461ae2abef57f0aabc24
|
||||
8b4ce818cde9621481b6bf7997b544b8
|
||||
|
@@ -1 +1 @@
|
||||
13fa042ee1b4079c227a5c5c96e2db38
|
||||
ea65b698e86322709257caf9038da40a
|
||||
|
@@ -1 +1 @@
|
||||
2ab7c95e4637fb6a15efd8c0a8d6af98
|
||||
c1047aeeb593f2f87818d9bd19cb12f2
|
||||
|
@@ -1 +1 @@
|
||||
b5be66a6a8792f7aac090beb9f3b4555
|
||||
cb14fde4f0f99d6e962fb109d3db36ee
|
||||
|
@@ -1 +1 @@
|
||||
7bde6532fc682bfa3f5170cf9d607865
|
||||
0f1cfba95edb2446689547fc012f741b
|
||||
|
@@ -1 +1 @@
|
||||
1e40e8b48e4682e8b8004b9e0e60a5b6
|
||||
db40458891febf9f007c98e735e02ab9
|
||||
|
@@ -1 +1 @@
|
||||
9bb416c0304a13c4f66c56aef8431cd4
|
||||
855cffb78a063ad0dfc432ae593974a2
|
||||
|
@@ -1 +1 @@
|
||||
3a7ed001d30f96d4888f5ca16e6263ce
|
||||
8f6c44c4098915261e7708ab270877ff
|
||||
|
@@ -1 +1 @@
|
||||
7315bb7b55693a87c350b48cd2ee9811
|
||||
0ed4ec02fd72c0b594d74c5cbd7e252f
|
||||
|
@@ -1 +1 @@
|
||||
1a7b5bf86bf0bbef10c9a1b2c799b276
|
||||
1e8d7e1bd62a04bf47270c72a1c55bb7
|
||||
|
@@ -1 +1 @@
|
||||
9b7a0b7fc081542d9be1074b23054861
|
||||
c2ca28679265c1c86d4a7ef60cc061ff
|
||||
|
Reference in New Issue
Block a user