mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
Compare commits
39 Commits
n7.1.4
...
release/7.1
| Author | SHA1 | Date | |
|---|---|---|---|
| a5faeca88f | |||
| 920871999a | |||
| 1516faadef | |||
| 83c2f4b81d | |||
| 72a46d7802 | |||
| a72a11d8be | |||
| b10e9a5369 | |||
| bb69554165 | |||
| 07e3329458 | |||
| f0cf73f421 | |||
| e43f666a23 | |||
| 6e5d93b466 | |||
| 8c2bda5f61 | |||
| e2288cc6c0 | |||
| 0c816d8b89 | |||
| 8e9c768416 | |||
| 02aad54e2c | |||
| 7134d5b996 | |||
| 43e9c091dd | |||
| efd787107e | |||
| 912e77ba04 | |||
| 263ebe4ed2 | |||
| 2e5801fd82 | |||
| ff3725aa6d | |||
| eaee3cf584 | |||
| 78eabd954e | |||
| e8fc0e76b9 | |||
| 1b835805c7 | |||
| 3faa8b9cc0 | |||
| c0bf41a774 | |||
| c06af95f12 | |||
| 06f659b6d7 | |||
| adcf20da26 | |||
| 181cfa1008 | |||
| ed860ef7d9 | |||
| 939eff8718 | |||
| 9315150f9d | |||
| 24a6c067c3 | |||
| 5814ad356a |
@@ -1057,7 +1057,7 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
H266RawSPS *current)
|
||||
{
|
||||
CodedBitstreamH266Context *h266 = ctx->priv_data;
|
||||
int err, i, j;
|
||||
int err, i, j, max_width_minus1, max_height_minus1;
|
||||
unsigned int ctb_log2_size_y, min_cb_log2_size_y,
|
||||
min_qt_log2_size_intra_y, min_qt_log2_size_inter_y,
|
||||
ctb_size_y, max_num_merge_cand, tmp_width_val, tmp_height_val;
|
||||
@@ -1130,6 +1130,8 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
ctb_log2_size_y);
|
||||
tmp_height_val = AV_CEIL_RSHIFT(current->sps_pic_height_max_in_luma_samples,
|
||||
ctb_log2_size_y);
|
||||
max_width_minus1 = tmp_width_val - 1;
|
||||
max_height_minus1 = tmp_height_val - 1;
|
||||
|
||||
flag(sps_subpic_info_present_flag);
|
||||
if (current->sps_subpic_info_present_flag) {
|
||||
@@ -1145,13 +1147,13 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
infer(sps_subpic_ctu_top_left_x[0], 0);
|
||||
infer(sps_subpic_ctu_top_left_y[0], 0);
|
||||
if (current->sps_pic_width_max_in_luma_samples > ctb_size_y)
|
||||
ubs(wlen, sps_subpic_width_minus1[0], 1, 0);
|
||||
us(wlen, sps_subpic_width_minus1[0], 0, max_width_minus1, 1, 0);
|
||||
else
|
||||
infer(sps_subpic_width_minus1[0], tmp_width_val - 1);
|
||||
infer(sps_subpic_width_minus1[0], max_width_minus1);
|
||||
if (current->sps_pic_height_max_in_luma_samples > ctb_size_y)
|
||||
ubs(hlen, sps_subpic_height_minus1[0], 1, 0);
|
||||
us(hlen, sps_subpic_height_minus1[0], 0, max_height_minus1, 1, 0);
|
||||
else
|
||||
infer(sps_subpic_height_minus1[0], tmp_height_val - 1);
|
||||
infer(sps_subpic_height_minus1[0], max_height_minus1);
|
||||
if (!current->sps_independent_subpics_flag) {
|
||||
flags(sps_subpic_treated_as_pic_flag[0], 1, 0);
|
||||
flags(sps_loop_filter_across_subpic_enabled_flag[0], 1, 0);
|
||||
@@ -1161,58 +1163,54 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
}
|
||||
for (i = 1; i <= current->sps_num_subpics_minus1; i++) {
|
||||
if (!current->sps_subpic_same_size_flag) {
|
||||
if (current->sps_pic_width_max_in_luma_samples > ctb_size_y) {
|
||||
const int win_right_edge =
|
||||
current->sps_pic_width_max_in_luma_samples
|
||||
- current->sps_conf_win_right_offset * sub_width_c;
|
||||
us(wlen, sps_subpic_ctu_top_left_x[i], 0,
|
||||
AV_CEIL_RSHIFT(win_right_edge, ctb_log2_size_y) - 1,
|
||||
1, i);
|
||||
} else
|
||||
const int win_right_edge =
|
||||
current->sps_pic_width_max_in_luma_samples -
|
||||
current->sps_conf_win_right_offset * sub_width_c;
|
||||
const int win_bottom_edge =
|
||||
current->sps_pic_height_max_in_luma_samples -
|
||||
current->sps_conf_win_bottom_offset * sub_height_c;
|
||||
const int win_left_edge =
|
||||
current->sps_conf_win_left_offset * sub_width_c;
|
||||
const int win_top_edge =
|
||||
current->sps_conf_win_top_offset * sub_height_c;
|
||||
const int win_left_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_left_edge, ctb_log2_size_y);
|
||||
const int win_right_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_right_edge, ctb_log2_size_y);
|
||||
const int win_top_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_top_edge, ctb_log2_size_y);
|
||||
const int win_bottom_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_bottom_edge, ctb_log2_size_y);
|
||||
const int min_width =
|
||||
FFMAX(win_left_edge_ctus - current->sps_subpic_ctu_top_left_x[i], 0);
|
||||
const int min_height =
|
||||
FFMAX(win_top_edge_ctus - current->sps_subpic_ctu_top_left_y[i], 0);
|
||||
|
||||
if (current->sps_pic_width_max_in_luma_samples > ctb_size_y)
|
||||
us(wlen, sps_subpic_ctu_top_left_x[i], 0, win_right_edge_ctus - 1, 1, i);
|
||||
else
|
||||
infer(sps_subpic_ctu_top_left_x[i], 0);
|
||||
if (current->sps_pic_height_max_in_luma_samples >
|
||||
ctb_size_y) {
|
||||
const int win_bottom_edge =
|
||||
current->sps_pic_height_max_in_luma_samples
|
||||
- current->sps_conf_win_bottom_offset * sub_height_c;
|
||||
us(hlen, sps_subpic_ctu_top_left_y[i], 0,
|
||||
AV_CEIL_RSHIFT(win_bottom_edge, ctb_log2_size_y) - 1,
|
||||
1, i);
|
||||
} else
|
||||
|
||||
if (current->sps_pic_height_max_in_luma_samples > ctb_size_y)
|
||||
us(hlen, sps_subpic_ctu_top_left_y[i], 0, win_bottom_edge_ctus - 1, 1, i);
|
||||
else
|
||||
infer(sps_subpic_ctu_top_left_y[i], 0);
|
||||
|
||||
max_width_minus1 = tmp_width_val - current->sps_subpic_ctu_top_left_x[i] - 1;
|
||||
max_height_minus1 = tmp_height_val - current->sps_subpic_ctu_top_left_y[i] - 1;
|
||||
|
||||
if (i < current->sps_num_subpics_minus1 &&
|
||||
current->sps_pic_width_max_in_luma_samples >
|
||||
ctb_size_y) {
|
||||
const int win_left_edge =
|
||||
current->sps_conf_win_left_offset * sub_width_c;
|
||||
const int win_left_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_left_edge, ctb_log2_size_y);
|
||||
us(wlen, sps_subpic_width_minus1[i],
|
||||
win_left_edge_ctus > current->sps_subpic_ctu_top_left_x[i]
|
||||
? win_left_edge_ctus - current->sps_subpic_ctu_top_left_x[i]
|
||||
: 0,
|
||||
MAX_UINT_BITS(wlen), 1, i);
|
||||
current->sps_pic_width_max_in_luma_samples > ctb_size_y) {
|
||||
us(wlen, sps_subpic_width_minus1[i], min_width, max_width_minus1, 1, i);
|
||||
} else {
|
||||
infer(sps_subpic_width_minus1[i],
|
||||
tmp_width_val -
|
||||
current->sps_subpic_ctu_top_left_x[i] - 1);
|
||||
infer(sps_subpic_width_minus1[i], max_width_minus1);
|
||||
}
|
||||
|
||||
if (i < current->sps_num_subpics_minus1 &&
|
||||
current->sps_pic_height_max_in_luma_samples >
|
||||
ctb_size_y) {
|
||||
const int win_top_edge =
|
||||
current->sps_conf_win_top_offset * sub_height_c;
|
||||
const int win_top_edge_ctus =
|
||||
AV_CEIL_RSHIFT(win_top_edge, ctb_log2_size_y);
|
||||
us(hlen, sps_subpic_height_minus1[i],
|
||||
win_top_edge_ctus > current->sps_subpic_ctu_top_left_y[i]
|
||||
? win_top_edge_ctus - current->sps_subpic_ctu_top_left_y[i]
|
||||
: 0,
|
||||
MAX_UINT_BITS(hlen), 1, i);
|
||||
current->sps_pic_height_max_in_luma_samples > ctb_size_y) {
|
||||
us(hlen, sps_subpic_height_minus1[i], min_height, max_height_minus1, 1, i);
|
||||
} else {
|
||||
infer(sps_subpic_height_minus1[i],
|
||||
tmp_height_val -
|
||||
current->sps_subpic_ctu_top_left_y[i] - 1);
|
||||
infer(sps_subpic_height_minus1[i], max_height_minus1);
|
||||
}
|
||||
} else {
|
||||
int num_subpic_cols = tmp_width_val /
|
||||
@@ -1245,8 +1243,8 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
} else {
|
||||
infer(sps_subpic_ctu_top_left_x[0], 0);
|
||||
infer(sps_subpic_ctu_top_left_y[0], 0);
|
||||
infer(sps_subpic_width_minus1[0], tmp_width_val - 1);
|
||||
infer(sps_subpic_height_minus1[0], tmp_height_val - 1);
|
||||
infer(sps_subpic_width_minus1[0], max_width_minus1);
|
||||
infer(sps_subpic_height_minus1[0], max_height_minus1);
|
||||
}
|
||||
ue(sps_subpic_id_len_minus1, 0, 15);
|
||||
if ((1 << (current->sps_subpic_id_len_minus1 + 1)) <
|
||||
@@ -1273,8 +1271,8 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
|
||||
infer(sps_subpic_id_mapping_explicitly_signalled_flag, 0);
|
||||
infer(sps_subpic_ctu_top_left_x[0], 0);
|
||||
infer(sps_subpic_ctu_top_left_y[0], 0);
|
||||
infer(sps_subpic_width_minus1[0], tmp_width_val - 1);
|
||||
infer(sps_subpic_height_minus1[0], tmp_height_val - 1);
|
||||
infer(sps_subpic_width_minus1[0], max_width_minus1);
|
||||
infer(sps_subpic_height_minus1[0], max_height_minus1);
|
||||
}
|
||||
|
||||
|
||||
@@ -2024,7 +2022,7 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||
for (j = 0; j < current->pps_num_exp_slices_in_tile[i];
|
||||
j++) {
|
||||
ues(pps_exp_slice_height_in_ctus_minus1[i][j], 0,
|
||||
current->row_height_val[tile_y] - 1, 2,
|
||||
remaining_height_in_ctbs_y - (current->pps_num_exp_slices_in_tile[i] - j), 2,
|
||||
i, j);
|
||||
slice_height_in_ctus =
|
||||
current->
|
||||
@@ -2810,9 +2808,9 @@ static int FUNC(picture_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||
0, FFMIN(6, ctb_log2_size_y) - min_cb_log2_size_y);
|
||||
ue(ph_max_mtt_hierarchy_depth_intra_slice_chroma,
|
||||
0, 2 * (ctb_log2_size_y - min_cb_log2_size_y));
|
||||
if (sps->sps_max_mtt_hierarchy_depth_intra_slice_chroma != 0) {
|
||||
if (current->ph_max_mtt_hierarchy_depth_intra_slice_chroma != 0) {
|
||||
unsigned int min_qt_log2_size_intra_c =
|
||||
sps->sps_log2_diff_min_qt_min_cb_intra_slice_chroma +
|
||||
current->ph_log2_diff_min_qt_min_cb_intra_slice_chroma +
|
||||
min_cb_log2_size_y;
|
||||
ue(ph_log2_diff_max_bt_min_qt_intra_slice_chroma,
|
||||
0, FFMIN(6, ctb_log2_size_y) - min_qt_log2_size_intra_c);
|
||||
@@ -3136,7 +3134,7 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||
|
||||
if (!pps->pps_rect_slice_flag &&
|
||||
pps->num_tiles_in_pic - current->sh_slice_address > 1)
|
||||
ue(sh_num_tiles_in_slice_minus1, 0, pps->num_tiles_in_pic - 1);
|
||||
ue(sh_num_tiles_in_slice_minus1, 0, pps->num_tiles_in_pic - 1 - current->sh_slice_address);
|
||||
else
|
||||
infer(sh_num_tiles_in_slice_minus1, 0);
|
||||
|
||||
@@ -3254,6 +3252,12 @@ static int FUNC(slice_header) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||
FFMIN(ref_pic_lists->rpl_ref_list[i].num_ref_entries,
|
||||
pps->pps_num_ref_idx_default_active_minus1[i] + 1);
|
||||
}
|
||||
|
||||
if (current->num_ref_idx_active[i] <= 0) {
|
||||
av_log(ctx->log_ctx, AV_LOG_ERROR,
|
||||
"Inter slice but no reference pictures available for RPL%d.\n", i);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
} else {
|
||||
current->num_ref_idx_active[i] = 0;
|
||||
}
|
||||
|
||||
+10
-4
@@ -1136,8 +1136,11 @@ static int skipped_transform_tree_unit(VVCLocalContext *lc)
|
||||
const CodingUnit *cu = lc->cu;
|
||||
int ret;
|
||||
|
||||
if (cu->tree_type != DUAL_TREE_CHROMA)
|
||||
set_qp_y(lc, cu->x0, cu->y0, 0);
|
||||
if (cu->tree_type != DUAL_TREE_CHROMA) {
|
||||
ret = set_qp_y(lc, cu->x0, cu->y0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (rsps->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
|
||||
set_qp_c(lc);
|
||||
ret = skipped_transform_tree(lc, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
|
||||
@@ -1778,13 +1781,16 @@ static int inter_data(VVCLocalContext *lc)
|
||||
pu->general_merge_flag = ff_vvc_general_merge_flag(lc);
|
||||
|
||||
if (pu->general_merge_flag) {
|
||||
hls_merge_data(lc);
|
||||
ret = hls_merge_data(lc);
|
||||
} else if (cu->pred_mode == MODE_IBC){
|
||||
ret = mvp_data_ibc(lc);
|
||||
} else {
|
||||
ret = mvp_data(lc);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cu->pred_mode == MODE_IBC)
|
||||
{
|
||||
ff_vvc_update_hmvp(lc, mi);
|
||||
@@ -2286,6 +2292,7 @@ static void alf_params(VVCLocalContext *lc, const int rx, const int ry)
|
||||
ALFParams *alf = &CTB(fc->tab.alf, rx, ry);
|
||||
|
||||
alf->ctb_flag[LUMA] = alf->ctb_flag[CB] = alf->ctb_flag[CR] = 0;
|
||||
alf->ctb_cc_idc[0] = alf->ctb_cc_idc[1] = 0;
|
||||
if (sh->sh_alf_enabled_flag) {
|
||||
alf->ctb_flag[LUMA] = ff_vvc_alf_ctb_flag(lc, rx, ry, LUMA);
|
||||
if (alf->ctb_flag[LUMA]) {
|
||||
@@ -2316,7 +2323,6 @@ static void alf_params(VVCLocalContext *lc, const int rx, const int ry)
|
||||
const uint8_t cc_enabled[] = { sh->sh_alf_cc_cb_enabled_flag, sh->sh_alf_cc_cr_enabled_flag };
|
||||
const uint8_t cc_aps_id[] = { sh->sh_alf_cc_cb_aps_id, sh->sh_alf_cc_cr_aps_id };
|
||||
for (int i = 0; i < 2; i++) {
|
||||
alf->ctb_cc_idc[i] = 0;
|
||||
if (cc_enabled[i]) {
|
||||
const VVCALF *aps = fc->ps.alf_list[cc_aps_id[i]];
|
||||
alf->ctb_cc_idc[i] = ff_vvc_alf_ctb_cc_idc(lc, rx, ry, i, aps->num_cc_filters[i]);
|
||||
|
||||
@@ -672,8 +672,6 @@ static int frame_context_setup(VVCFrameContext *fc, VVCContext *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
fc->ref = NULL;
|
||||
|
||||
// copy refs from the last frame
|
||||
if (s->nb_frames && s->nb_fcs > 1) {
|
||||
VVCFrameContext *prev = get_frame_context(s, fc, -1);
|
||||
@@ -877,6 +875,7 @@ static int decode_nal_units(VVCContext *s, VVCFrameContext *fc, AVPacket *avpkt)
|
||||
int ret = 0;
|
||||
s->last_eos = s->eos;
|
||||
s->eos = 0;
|
||||
fc->ref = NULL;
|
||||
|
||||
ff_cbs_fragment_reset(frame);
|
||||
ret = ff_cbs_read_packet(s->cbc, frame, avpkt);
|
||||
@@ -1000,7 +999,7 @@ static int vvc_decode_frame(AVCodecContext *avctx, AVFrame *output,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!fc->ft)
|
||||
if (!fc->ft || !fc->ref)
|
||||
return avpkt->size;
|
||||
|
||||
ret = submit_frame(s, fc, output, got_output);
|
||||
|
||||
@@ -472,6 +472,9 @@ static void FUNC(apply_bdof)(uint8_t *_dst, const ptrdiff_t _dst_stride, const i
|
||||
(filter[0] * src[x] + \
|
||||
filter[1] * src[x + stride])
|
||||
|
||||
#define DMVR_FILTER2(filter, src0, src1) \
|
||||
(filter[0] * src0 + filter[1] * src1)
|
||||
|
||||
//8.5.3.2.2 Luma sample bilinear interpolation process
|
||||
static void FUNC(dmvr)(int16_t *dst, const uint8_t *_src, const ptrdiff_t _src_stride,
|
||||
const int height, const intptr_t mx, const intptr_t my, const int width)
|
||||
@@ -541,31 +544,31 @@ static void FUNC(dmvr_v)(int16_t *dst, const uint8_t *_src, const ptrdiff_t _src
|
||||
static void FUNC(dmvr_hv)(int16_t *dst, const uint8_t *_src, const ptrdiff_t _src_stride,
|
||||
const int height, const intptr_t mx, const intptr_t my, const int width)
|
||||
{
|
||||
int16_t tmp_array[(MAX_PB_SIZE + BILINEAR_EXTRA) * MAX_PB_SIZE];
|
||||
int16_t *tmp = tmp_array;
|
||||
int16_t tmp_array[MAX_PB_SIZE * 2];
|
||||
int16_t *tmp0 = tmp_array;
|
||||
int16_t *tmp1 = tmp_array + MAX_PB_SIZE;
|
||||
const pixel *src = (const pixel*)_src;
|
||||
const ptrdiff_t src_stride = _src_stride / sizeof(pixel);
|
||||
const int8_t *filter = ff_vvc_inter_luma_dmvr_filters[mx];
|
||||
const int8_t *filter_x = ff_vvc_inter_luma_dmvr_filters[mx];
|
||||
const int8_t *filter_y = ff_vvc_inter_luma_dmvr_filters[my];
|
||||
const int shift1 = BIT_DEPTH - 6;
|
||||
const int offset1 = 1 << (shift1 - 1);
|
||||
const int shift2 = 4;
|
||||
const int offset2 = 1 << (shift2 - 1);
|
||||
|
||||
src -= BILINEAR_EXTRA_BEFORE * src_stride;
|
||||
for (int y = 0; y < height + BILINEAR_EXTRA; y++) {
|
||||
for (int x = 0; x < width; x++)
|
||||
tmp[x] = (DMVR_FILTER(src, 1) + offset1) >> shift1;
|
||||
src += src_stride;
|
||||
tmp += MAX_PB_SIZE;
|
||||
}
|
||||
for (int x = 0; x < width; x++)
|
||||
tmp0[x] = (DMVR_FILTER2(filter_x, src[x], src[x + 1]) + offset1) >> shift1;
|
||||
src += src_stride;
|
||||
|
||||
tmp = tmp_array + BILINEAR_EXTRA_BEFORE * MAX_PB_SIZE;
|
||||
filter = ff_vvc_inter_luma_dmvr_filters[my];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++)
|
||||
dst[x] = (DMVR_FILTER(tmp, MAX_PB_SIZE) + offset2) >> shift2;
|
||||
tmp += MAX_PB_SIZE;
|
||||
for (int y = 1; y < height + BILINEAR_EXTRA; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
tmp1[x] = (DMVR_FILTER2(filter_x, src[x], src[x + 1]) + offset1) >> shift1;
|
||||
dst[x] = (DMVR_FILTER2(filter_y, tmp0[x], tmp1[x]) + offset2) >> shift2;
|
||||
}
|
||||
src += src_stride;
|
||||
dst += MAX_PB_SIZE;
|
||||
FFSWAP(int16_t *, tmp0, tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-11
@@ -243,21 +243,23 @@ static int get_chroma_predict_unit(const CodingUnit *cu, const TransformUnit *tu
|
||||
}
|
||||
|
||||
//8.4.5.1 General decoding process for intra blocks
|
||||
static void predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
|
||||
static int predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
|
||||
{
|
||||
const VVCFrameContext *fc = lc->fc;
|
||||
const CodingUnit *cu = lc->cu;
|
||||
const VVCTreeType tree_type = cu->tree_type;
|
||||
int x0, y0, w, h;
|
||||
int x0, y0, w, h, ret;
|
||||
if (cu->pred_mode != MODE_INTRA) {
|
||||
add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
|
||||
return;
|
||||
ret = add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
|
||||
return ret;
|
||||
}
|
||||
if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
|
||||
if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
|
||||
ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
|
||||
fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
|
||||
add_reconstructed_area(lc, 0, x0, y0, w, h);
|
||||
ret = add_reconstructed_area(lc, 0, x0, y0, w, h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
|
||||
@@ -269,9 +271,12 @@ static void predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const in
|
||||
fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
|
||||
fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
|
||||
}
|
||||
add_reconstructed_area(lc, 1, x0, y0, w, h);
|
||||
ret = add_reconstructed_area(lc, 1, x0, y0, w, h);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void scale_clip(int *coeff, const int nzw, const int w, const int h,
|
||||
@@ -571,11 +576,14 @@ static int reconstruct(VVCLocalContext *lc)
|
||||
CodingUnit *cu = lc->cu;
|
||||
const int start = cu->tree_type == DUAL_TREE_CHROMA;
|
||||
const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
|
||||
int ret;
|
||||
|
||||
for (int ch_type = start; ch_type <= end; ch_type++) {
|
||||
TransformUnit *tu = cu->tus.head;
|
||||
for (int i = 0; tu; i++) {
|
||||
predict_intra(lc, tu, i, ch_type);
|
||||
ret = predict_intra(lc, tu, i, ch_type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
itransform(lc, tu, i, ch_type);
|
||||
tu = tu->next;
|
||||
}
|
||||
@@ -681,10 +689,16 @@ int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const in
|
||||
if (cu->coded_flag) {
|
||||
ret = reconstruct(lc);
|
||||
} else {
|
||||
if (cu->tree_type != DUAL_TREE_CHROMA)
|
||||
add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
|
||||
if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA)
|
||||
add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
|
||||
if (cu->tree_type != DUAL_TREE_CHROMA) {
|
||||
ret = add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA) {
|
||||
ret = add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (sps->r->sps_ibc_enabled_flag)
|
||||
ibc_fill_vir_buf(lc, cu);
|
||||
|
||||
+129
-37
@@ -20,6 +20,7 @@
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libavcodec/cbs_h266.h"
|
||||
#include "libavutil/mem.h"
|
||||
@@ -238,9 +239,10 @@ static int decode_sps(VVCParamSets *ps, const H266RawSPS *rsps, void *log_ctx, i
|
||||
}
|
||||
|
||||
if (old_sps) {
|
||||
if (old_sps->r == rsps || !memcmp(old_sps->r, rsps, sizeof(*old_sps->r)))
|
||||
if (old_sps->r == rsps || !memcmp(old_sps->r, rsps, sizeof(*old_sps->r))) {
|
||||
ps->sps_id_used |= (1 << sps_id);
|
||||
return 0;
|
||||
else if (ps->sps_id_used & (1 << sps_id))
|
||||
} else if (ps->sps_id_used & (1 << sps_id))
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
@@ -358,6 +360,8 @@ static int pps_add_ctus(VVCPPS *pps, int *off, const int rx, const int ry,
|
||||
int start = *off;
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (*off >= pps->ctb_count)
|
||||
return AVERROR_INVALIDDATA;
|
||||
pps->ctb_addr_in_slice[*off] = ctu_rs(rx + x, ry + y, pps);
|
||||
(*off)++;
|
||||
}
|
||||
@@ -365,15 +369,21 @@ static int pps_add_ctus(VVCPPS *pps, int *off, const int rx, const int ry,
|
||||
return *off - start;
|
||||
}
|
||||
|
||||
static void pps_single_slice_picture(VVCPPS *pps, int *off)
|
||||
static int pps_single_slice_picture(VVCPPS *pps, int *off)
|
||||
{
|
||||
pps->num_ctus_in_slice[0] = 0;
|
||||
for (int j = 0; j < pps->r->num_tile_rows; j++) {
|
||||
for (int i = 0; i < pps->r->num_tile_columns; i++) {
|
||||
pps->num_ctus_in_slice[0] = pps_add_ctus(pps, off,
|
||||
const int ret = pps_add_ctus(pps, off,
|
||||
pps->col_bd[i], pps->row_bd[j],
|
||||
pps->r->col_width_val[i], pps->r->row_height_val[j]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pps->num_ctus_in_slice[0] += ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_end,
|
||||
@@ -400,25 +410,36 @@ static void subpic_tiles(int *tile_x, int *tile_y, int *tile_x_end, int *tile_y_
|
||||
(*tile_y_end)++;
|
||||
}
|
||||
|
||||
static void pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off)
|
||||
static int pps_subpic_less_than_one_tile_slice(VVCPPS *pps, const VVCSPS *sps, const int i, const int tx, const int ty, int *off)
|
||||
{
|
||||
pps->num_ctus_in_slice[i] = pps_add_ctus(pps, off,
|
||||
pps->col_bd[tx], pps->row_bd[ty],
|
||||
pps->r->col_width_val[tx], sps->r->sps_subpic_height_minus1[i] + 1);
|
||||
const int ret = pps_add_ctus(pps, off,
|
||||
sps->r->sps_subpic_ctu_top_left_x[i], sps->r->sps_subpic_ctu_top_left_y[i],
|
||||
sps->r->sps_subpic_width_minus1[i] + 1, sps->r->sps_subpic_height_minus1[i] + 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pps->num_ctus_in_slice[i] = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pps_subpic_one_or_more_tiles_slice(VVCPPS *pps, const int tile_x, const int tile_y, const int x_end, const int y_end, const int i, int *off)
|
||||
static int pps_subpic_one_or_more_tiles_slice(VVCPPS *pps, const int tile_x, const int tile_y, const int x_end, const int y_end,
|
||||
const int i, int *off)
|
||||
{
|
||||
for (int ty = tile_y; ty < y_end; ty++) {
|
||||
for (int tx = tile_x; tx < x_end; tx++) {
|
||||
pps->num_ctus_in_slice[i] += pps_add_ctus(pps, off,
|
||||
const int ret = pps_add_ctus(pps, off,
|
||||
pps->col_bd[tx], pps->row_bd[ty],
|
||||
pps->r->col_width_val[tx], pps->r->row_height_val[ty]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pps->num_ctus_in_slice[i] += ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pps_subpic_slice(VVCPPS *pps, const VVCSPS *sps, const int i, int *off)
|
||||
static int pps_subpic_slice(VVCPPS *pps, const VVCSPS *sps, const int i, int *off)
|
||||
{
|
||||
int tx, ty, x_end, y_end;
|
||||
|
||||
@@ -427,19 +448,27 @@ static void pps_subpic_slice(VVCPPS *pps, const VVCSPS *sps, const int i, int *o
|
||||
|
||||
subpic_tiles(&tx, &ty, &x_end, &y_end, sps, pps, i);
|
||||
if (ty + 1 == y_end && sps->r->sps_subpic_height_minus1[i] + 1 < pps->r->row_height_val[ty])
|
||||
pps_subpic_less_than_one_tile_slice(pps, sps, i, tx, ty, off);
|
||||
return pps_subpic_less_than_one_tile_slice(pps, sps, i, tx, ty, off);
|
||||
else
|
||||
pps_subpic_one_or_more_tiles_slice(pps, tx, ty, x_end, y_end, i, off);
|
||||
return pps_subpic_one_or_more_tiles_slice(pps, tx, ty, x_end, y_end, i, off);
|
||||
}
|
||||
|
||||
static void pps_single_slice_per_subpic(VVCPPS *pps, const VVCSPS *sps, int *off)
|
||||
static int pps_single_slice_per_subpic(VVCPPS *pps, const VVCSPS *sps, int *off)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!sps->r->sps_subpic_info_present_flag) {
|
||||
pps_single_slice_picture(pps, off);
|
||||
ret = pps_single_slice_picture(pps, off);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
for (int i = 0; i < pps->r->pps_num_slices_in_pic_minus1 + 1; i++)
|
||||
pps_subpic_slice(pps, sps, i, off);
|
||||
for (int i = 0; i < pps->r->pps_num_slices_in_pic_minus1 + 1; i++) {
|
||||
const int ret = pps_subpic_slice(pps, sps, i, off);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pps_one_tile_slices(VVCPPS *pps, const int tile_idx, int i, int *off)
|
||||
@@ -451,16 +480,20 @@ static int pps_one_tile_slices(VVCPPS *pps, const int tile_idx, int i, int *off)
|
||||
ctu_xy(&rx, &ry, tile_x, tile_y, pps);
|
||||
ctu_y_end = ry + r->row_height_val[tile_y];
|
||||
while (ry < ctu_y_end) {
|
||||
int ret;
|
||||
pps->slice_start_offset[i] = *off;
|
||||
pps->num_ctus_in_slice[i] = pps_add_ctus(pps, off, rx, ry,
|
||||
ret = pps_add_ctus(pps, off, rx, ry,
|
||||
r->col_width_val[tile_x], r->slice_height_in_ctus[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pps->num_ctus_in_slice[i] = ret;
|
||||
ry += r->slice_height_in_ctus[i++];
|
||||
}
|
||||
i--;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const int i, int *off)
|
||||
static int pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const int i, int *off, bool *tile_in_slice)
|
||||
{
|
||||
const H266RawPPS *r = pps->r;
|
||||
int rx, ry, tile_x, tile_y;
|
||||
@@ -470,57 +503,91 @@ static void pps_multi_tiles_slice(VVCPPS *pps, const int tile_idx, const int i,
|
||||
pps->num_ctus_in_slice[i] = 0;
|
||||
for (int ty = tile_y; ty <= tile_y + r->pps_slice_height_in_tiles_minus1[i]; ty++) {
|
||||
for (int tx = tile_x; tx <= tile_x + r->pps_slice_width_in_tiles_minus1[i]; tx++) {
|
||||
int ret;
|
||||
const int idx = ty * r->num_tile_columns + tx;
|
||||
if (tile_in_slice[idx])
|
||||
return AVERROR_INVALIDDATA;
|
||||
tile_in_slice[idx] = true;
|
||||
ctu_xy(&rx, &ry, tx, ty, pps);
|
||||
pps->num_ctus_in_slice[i] += pps_add_ctus(pps, off, rx, ry,
|
||||
ret = pps_add_ctus(pps, off, rx, ry,
|
||||
r->col_width_val[tx], r->row_height_val[ty]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
pps->num_ctus_in_slice[i] += ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pps_rect_slice(VVCPPS *pps, const VVCSPS *sps)
|
||||
static int pps_rect_slice(VVCPPS *pps, const VVCSPS *sps)
|
||||
{
|
||||
const H266RawPPS *r = pps->r;
|
||||
int tile_idx = 0, off = 0;
|
||||
bool tile_in_slice[VVC_MAX_TILES_PER_AU] = {false};
|
||||
int tile_idx = 0, off = 0, ret;
|
||||
|
||||
if (r->pps_single_slice_per_subpic_flag) {
|
||||
pps_single_slice_per_subpic(pps, sps, &off);
|
||||
return;
|
||||
return pps_single_slice_per_subpic(pps, sps, &off);
|
||||
}
|
||||
|
||||
for (int i = 0; i < r->pps_num_slices_in_pic_minus1 + 1; i++) {
|
||||
if (!r->pps_slice_width_in_tiles_minus1[i] &&
|
||||
!r->pps_slice_height_in_tiles_minus1[i]) {
|
||||
i = pps_one_tile_slices(pps, tile_idx, i, &off);
|
||||
if (tile_in_slice[tile_idx])
|
||||
return AVERROR_INVALIDDATA;
|
||||
tile_in_slice[tile_idx] = true;
|
||||
ret = pps_one_tile_slices(pps, tile_idx, i, &off);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
i = ret;
|
||||
} else {
|
||||
pps_multi_tiles_slice(pps, tile_idx, i, &off);
|
||||
ret = pps_multi_tiles_slice(pps, tile_idx, i, &off, tile_in_slice);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
tile_idx = next_tile_idx(tile_idx, i, r);
|
||||
}
|
||||
|
||||
for (int i = 0; i < r->num_tiles_in_pic; i++) {
|
||||
if (!tile_in_slice[i])
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pps_no_rect_slice(VVCPPS* pps)
|
||||
static int pps_no_rect_slice(VVCPPS* pps)
|
||||
{
|
||||
const H266RawPPS* r = pps->r;
|
||||
int rx, ry, off = 0;
|
||||
|
||||
for (int tile_y = 0; tile_y < r->num_tile_rows; tile_y++) {
|
||||
for (int tile_x = 0; tile_x < r->num_tile_columns; tile_x++) {
|
||||
int ret;
|
||||
ctu_xy(&rx, &ry, tile_x, tile_y, pps);
|
||||
pps_add_ctus(pps, &off, rx, ry, r->col_width_val[tile_x], r->row_height_val[tile_y]);
|
||||
ret = pps_add_ctus(pps, &off, rx, ry, r->col_width_val[tile_x], r->row_height_val[tile_y]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pps_slice_map(VVCPPS *pps, const VVCSPS *sps)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pps->ctb_addr_in_slice = av_calloc(pps->ctb_count, sizeof(*pps->ctb_addr_in_slice));
|
||||
if (!pps->ctb_addr_in_slice)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (pps->r->pps_rect_slice_flag)
|
||||
pps_rect_slice(pps, sps);
|
||||
else
|
||||
pps_no_rect_slice(pps);
|
||||
return pps_rect_slice(pps, sps);
|
||||
|
||||
ret = pps_no_rect_slice(pps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -649,6 +716,12 @@ static int decode_ps(VVCParamSets *ps, const CodedBitstreamH266Context *h266, vo
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (rsps->sps_log2_ctu_size_minus5 > 2) {
|
||||
// CTU > 128 are reserved in vvc spec v3
|
||||
av_log(log_ctx, AV_LOG_ERROR, "CTU size > 128. \n");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
ret = decode_pps(ps, rpps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -728,7 +801,7 @@ static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266Raw
|
||||
uint16_t input_pivot[LMCS_MAX_BIN_SIZE];
|
||||
uint16_t scale_coeff[LMCS_MAX_BIN_SIZE];
|
||||
uint16_t inv_scale_coeff[LMCS_MAX_BIN_SIZE];
|
||||
int i, delta_crs;
|
||||
int i, delta_crs, sum_cw = 0;
|
||||
if (bit_depth > LMCS_MAX_BIT_DEPTH)
|
||||
return AVERROR_PATCHWELCOME;
|
||||
|
||||
@@ -739,8 +812,12 @@ static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266Raw
|
||||
lmcs->max_bin_idx = LMCS_MAX_BIN_SIZE - 1 - rlmcs->lmcs_min_bin_idx;
|
||||
|
||||
memset(cw, 0, sizeof(cw));
|
||||
for (int i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++)
|
||||
for (int i = lmcs->min_bin_idx; i <= lmcs->max_bin_idx; i++) {
|
||||
cw[i] = org_cw + (1 - 2 * rlmcs->lmcs_delta_sign_cw_flag[i]) * rlmcs->lmcs_delta_abs_cw[i];
|
||||
sum_cw += cw[i];
|
||||
}
|
||||
if (sum_cw > (1 << bit_depth) - 1)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
delta_crs = (1 - 2 * rlmcs->lmcs_delta_sign_crs_flag) * rlmcs->lmcs_delta_abs_crs;
|
||||
|
||||
@@ -748,19 +825,26 @@ static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266Raw
|
||||
for (i = 0; i < LMCS_MAX_BIN_SIZE; i++) {
|
||||
input_pivot[i] = i * org_cw;
|
||||
lmcs->pivot[i + 1] = lmcs->pivot[i] + cw[i];
|
||||
if (i >= lmcs->min_bin_idx && i <= lmcs->max_bin_idx &&
|
||||
lmcs->pivot[i] % (1 << (bit_depth - 5)) != 0 &&
|
||||
lmcs->pivot[i] >> (bit_depth - 5) == lmcs->pivot[i + 1] >> (bit_depth - 5))
|
||||
return AVERROR_INVALIDDATA;
|
||||
scale_coeff[i] = (cw[i] * (1 << 11) + off) >> shift;
|
||||
if (cw[i] == 0) {
|
||||
inv_scale_coeff[i] = 0;
|
||||
lmcs->chroma_scale_coeff[i] = (1 << 11);
|
||||
} else {
|
||||
const int cw_plus_d = cw[i] + delta_crs;
|
||||
if (cw_plus_d < (org_cw >> 3) || cw_plus_d > ((org_cw << 3) - 1))
|
||||
return AVERROR_INVALIDDATA;
|
||||
inv_scale_coeff[i] = org_cw * (1 << 11) / cw[i];
|
||||
lmcs->chroma_scale_coeff[i] = org_cw * (1 << 11) / (cw[i] + delta_crs);
|
||||
lmcs->chroma_scale_coeff[i] = org_cw * (1 << 11) / cw_plus_d;
|
||||
}
|
||||
}
|
||||
|
||||
//derive lmcs_fwd_lut
|
||||
for (uint16_t sample = 0; sample < max; sample++) {
|
||||
const int idx_y = sample / org_cw;
|
||||
const int idx_y = sample >> shift;
|
||||
const uint16_t fwd_sample = lmcs_derive_lut_sample(sample, lmcs->pivot,
|
||||
input_pivot, scale_coeff, idx_y, max);
|
||||
if (bit_depth > 8)
|
||||
@@ -776,6 +860,7 @@ static int lmcs_derive_lut(VVCLMCS *lmcs, const H266RawAPS *rlmcs, const H266Raw
|
||||
uint16_t inv_sample;
|
||||
while (i <= lmcs->max_bin_idx && sample >= lmcs->pivot[i + 1])
|
||||
i++;
|
||||
i = FFMIN(i, LMCS_MAX_BIN_SIZE - 1);
|
||||
|
||||
inv_sample = lmcs_derive_lut_sample(sample, input_pivot, lmcs->pivot,
|
||||
inv_scale_coeff, i, max);
|
||||
@@ -1198,7 +1283,7 @@ static int sh_alf_aps(const VVCSH *sh, const VVCFrameParamSets *fps)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh_slice_address(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps)
|
||||
static int sh_slice_address(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps)
|
||||
{
|
||||
const int slice_address = sh->r->sh_slice_address;
|
||||
|
||||
@@ -1222,6 +1307,11 @@ static void sh_slice_address(VVCSH *sh, const H266RawSPS *sps, const VVCPPS *pps
|
||||
sh->num_ctus_in_curr_slice += pps->r->row_height_val[tile_y] * pps->r->col_width_val[tile_x];
|
||||
}
|
||||
}
|
||||
|
||||
if (!sh->num_ctus_in_curr_slice)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh_qp_y(VVCSH *sh, const H266RawPPS *pps, const H266RawPictureHeader *ph)
|
||||
@@ -1318,7 +1408,9 @@ static int sh_derive(VVCSH *sh, const VVCFrameParamSets *fps)
|
||||
const H266RawPictureHeader *ph = fps->ph.r;
|
||||
int ret;
|
||||
|
||||
sh_slice_address(sh, sps, fps->pps);
|
||||
ret = sh_slice_address(sh, sps, fps->pps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = sh_alf_aps(sh, fps);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+20
-5
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/thread.h"
|
||||
@@ -29,10 +30,6 @@
|
||||
|
||||
#include "refs.h"
|
||||
|
||||
#define VVC_FRAME_FLAG_OUTPUT (1 << 0)
|
||||
#define VVC_FRAME_FLAG_SHORT_REF (1 << 1)
|
||||
#define VVC_FRAME_FLAG_LONG_REF (1 << 2)
|
||||
#define VVC_FRAME_FLAG_BUMPING (1 << 3)
|
||||
|
||||
typedef struct FrameProgress {
|
||||
atomic_int progress[VVC_PROGRESS_LAST];
|
||||
@@ -50,6 +47,8 @@ void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags)
|
||||
return;
|
||||
|
||||
frame->flags &= ~flags;
|
||||
if (!(frame->flags & ~VVC_FRAME_FLAG_CORRUPT))
|
||||
frame->flags = 0;
|
||||
if (!frame->flags) {
|
||||
av_frame_unref(frame->frame);
|
||||
ff_refstruct_unref(&frame->sps);
|
||||
@@ -246,6 +245,9 @@ int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const
|
||||
if (nb_output) {
|
||||
VVCFrame *frame = &fc->DPB[min_idx];
|
||||
|
||||
if (frame->flags & VVC_FRAME_FLAG_CORRUPT)
|
||||
frame->frame->flags |= AV_FRAME_FLAG_CORRUPT;
|
||||
|
||||
ret = av_frame_ref(out, frame->frame);
|
||||
if (frame->flags & VVC_FRAME_FLAG_BUMPING)
|
||||
ff_vvc_unref_frame(fc, frame, VVC_FRAME_FLAG_OUTPUT | VVC_FRAME_FLAG_BUMPING);
|
||||
@@ -355,7 +357,7 @@ static VVCFrame *generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int po
|
||||
|
||||
frame->poc = poc;
|
||||
frame->sequence = s->seq_decode;
|
||||
frame->flags = 0;
|
||||
frame->flags = VVC_FRAME_FLAG_CORRUPT;
|
||||
|
||||
ff_vvc_report_frame_finished(frame);
|
||||
|
||||
@@ -390,6 +392,19 @@ static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList *lis
|
||||
if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (!IS_CVSS(s)) {
|
||||
const bool ref_corrupt = !ref || (ref->flags & VVC_FRAME_FLAG_CORRUPT);
|
||||
const bool recovering = s->no_output_before_recovery_flag && !GDR_IS_RECOVERED(s);
|
||||
|
||||
if (ref_corrupt && !recovering) {
|
||||
if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) &&
|
||||
!(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
fc->ref->flags |= VVC_FRAME_FLAG_CORRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ref) {
|
||||
ref = generate_missing_ref(s, fc, poc);
|
||||
if (!ref)
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
|
||||
#include "dec.h"
|
||||
|
||||
#define VVC_FRAME_FLAG_OUTPUT (1 << 0)
|
||||
#define VVC_FRAME_FLAG_SHORT_REF (1 << 1)
|
||||
#define VVC_FRAME_FLAG_LONG_REF (1 << 2)
|
||||
#define VVC_FRAME_FLAG_BUMPING (1 << 3)
|
||||
#define VVC_FRAME_FLAG_CORRUPT (1 << 4)
|
||||
|
||||
int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, struct AVFrame *out, int no_output_of_prior_pics_flag, int flush);
|
||||
void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc);
|
||||
int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, struct AVFrame **frame);
|
||||
|
||||
@@ -655,9 +655,9 @@ static void task_run_stage(VVCTask *t, VVCContext *s, VVCLocalContext *lc)
|
||||
"frame %5d, %s(%3d, %3d) failed with %d\r\n",
|
||||
(int)fc->decode_order, task_name[stage], t->rx, t->ry, ret);
|
||||
}
|
||||
if (!ret)
|
||||
task_stage_done(t, s);
|
||||
}
|
||||
|
||||
task_stage_done(t, s);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -822,6 +822,13 @@ int ff_vvc_frame_submit(VVCContext *s, VVCFrameContext *fc)
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int rs = 0; rs < ft->ctu_count; rs++) {
|
||||
const VVCTask *t = ft->tasks + rs;
|
||||
if (!t->sc) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "frame %5d, CTU(%d, %d) not belong to any slice\r\n", (int)fc->decode_order, t->rx, t->ry);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
frame_thread_add_score(s, ft, 0, 0, VVC_TASK_STAGE_INIT);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -446,7 +446,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
|
||||
av_freep(pb);
|
||||
av_dict_copy(&tmp, *opts, 0);
|
||||
av_dict_copy(&tmp, opts2, 0);
|
||||
ret = ffio_open_whitelist(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, s->protocol_whitelist, s->protocol_blacklist);
|
||||
ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
|
||||
if (ret >= 0) {
|
||||
// update cookies on http response with setcookies.
|
||||
char *new_cookies = NULL;
|
||||
@@ -1242,7 +1242,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in)
|
||||
close_in = 1;
|
||||
|
||||
av_dict_copy(&opts, c->avio_opts, 0);
|
||||
ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist);
|
||||
ret = s->io_open(s, &in, url, AVIO_FLAG_READ, &opts);
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -1385,7 +1385,7 @@ cleanup:
|
||||
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
if (close_in) {
|
||||
avio_close(in);
|
||||
ff_format_io_close(s, &in);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ static void dash_free(AVFormatContext *s)
|
||||
if (!c->single_file)
|
||||
ffio_free_dyn_buf(&os->ctx->pb);
|
||||
else
|
||||
avio_close(os->ctx->pb);
|
||||
ff_format_io_close(s, &os->ctx->pb);
|
||||
}
|
||||
ff_format_io_close(s, &os->out);
|
||||
avformat_free_context(os->ctx);
|
||||
@@ -1586,7 +1586,7 @@ static int dash_init(AVFormatContext *s)
|
||||
ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts);
|
||||
} else {
|
||||
ctx->url = av_strdup(filename);
|
||||
ret = avio_open2(&ctx->pb, filename, AVIO_FLAG_WRITE, NULL, &opts);
|
||||
ret = s->io_open(s, &ctx->pb, filename, AVIO_FLAG_WRITE, &opts);
|
||||
}
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0)
|
||||
|
||||
+1
-1
@@ -364,7 +364,7 @@ fail:
|
||||
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
|
||||
av_dict_free(&tmp);
|
||||
if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
|
||||
avio_closep(&s->pb);
|
||||
ff_format_io_close(s, &s->pb);
|
||||
avformat_free_context(s);
|
||||
*ps = NULL;
|
||||
return ret;
|
||||
|
||||
@@ -777,7 +777,7 @@ static int do_encrypt(AVFormatContext *s, VariantStream *vs)
|
||||
return ret;
|
||||
avio_seek(pb, 0, SEEK_CUR);
|
||||
avio_write(pb, key, KEYSIZE);
|
||||
avio_close(pb);
|
||||
ff_format_io_close(s, &pb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1215,9 +1215,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
|
||||
const char *end;
|
||||
double discont_program_date_time = 0;
|
||||
|
||||
if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
|
||||
&s->interrupt_callback, NULL,
|
||||
s->protocol_whitelist, s->protocol_blacklist)) < 0)
|
||||
if ((ret = s->io_open(s, &in, url, AVIO_FLAG_READ, NULL)) < 0)
|
||||
return ret;
|
||||
|
||||
ff_get_chomp_line(in, line, sizeof(line));
|
||||
@@ -1313,7 +1311,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs
|
||||
}
|
||||
|
||||
fail:
|
||||
avio_close(in);
|
||||
ff_format_io_close(s, &in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -1196,15 +1196,13 @@ static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
version = avio_r8(pb);
|
||||
flags = avio_rb24(pb);
|
||||
if (version != 0 || flags != 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR,
|
||||
"Unsupported 'chnl' box with version %d, flags: %#x",
|
||||
av_log(c->fc, AV_LOG_WARNING,
|
||||
"Unsupported 'chnl' box with version %d, flags: %#x\n",
|
||||
version, flags);
|
||||
return AVERROR_INVALIDDATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ff_mov_read_chnl(c->fc, pb, st);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ff_mov_read_chnl(c->fc, pb, st);
|
||||
|
||||
if (avio_tell(pb) != end) {
|
||||
av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n",
|
||||
|
||||
+23
-13
@@ -375,6 +375,7 @@ static int mov_get_channel_layout(AVChannelLayout *ch_layout, uint32_t tag, uint
|
||||
/* find the channel layout for the specified layout tag */
|
||||
layout_map = find_layout_map(tag, map);
|
||||
if (layout_map) {
|
||||
AVChannelLayout tmp = { 0 };
|
||||
int ret;
|
||||
int map_layout_nb_channels = tag & 0xFFFF;
|
||||
int nb_channels = ch_layout->nb_channels;
|
||||
@@ -383,19 +384,23 @@ static int mov_get_channel_layout(AVChannelLayout *ch_layout, uint32_t tag, uint
|
||||
if (omitted_channel_map >> map_layout_nb_channels)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
ret = av_channel_layout_custom_init(ch_layout, nb_channels);
|
||||
ret = av_channel_layout_custom_init(&tmp, nb_channels);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (int i = 0, idx = 0; i < map_layout_nb_channels && idx < nb_channels; i++, omitted_channel_map >>= 1) {
|
||||
if (!(omitted_channel_map & 1)) {
|
||||
enum AVChannel id = layout_map[i].id;
|
||||
ch_layout->u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN);
|
||||
tmp.u.map[idx++].id = (id != AV_CHAN_NONE ? id : AV_CHAN_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
return av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
*ch_layout = tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -543,6 +548,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st,
|
||||
return 0;
|
||||
|
||||
if (layout_tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) {
|
||||
AVChannelLayout tmp = { 0 };
|
||||
int nb_channels = ch_layout->nb_channels;
|
||||
|
||||
if (!num_descr || num_descr < nb_channels) {
|
||||
@@ -562,8 +568,7 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st,
|
||||
num_descr = nb_channels;
|
||||
}
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
ret = av_channel_layout_custom_init(ch_layout, nb_channels);
|
||||
ret = av_channel_layout_custom_init(&tmp, nb_channels);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@@ -580,12 +585,15 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st,
|
||||
avio_rl32(pb); // mCoordinates[1]
|
||||
avio_rl32(pb); // mCoordinates[2]
|
||||
size -= 20;
|
||||
ch_layout->u.map[i].id = mov_get_channel_id(label);
|
||||
tmp.u.map[i].id = mov_get_channel_id(label);
|
||||
}
|
||||
|
||||
ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
*ch_layout = tmp;
|
||||
} else if (layout_tag == MOV_CH_LAYOUT_USE_BITMAP) {
|
||||
if (!ch_layout->nb_channels || av_popcount(bitmap) == ch_layout->nb_channels) {
|
||||
if (bitmap < 0x40000) {
|
||||
@@ -737,11 +745,10 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
|
||||
|
||||
av_log(s, AV_LOG_TRACE, "'chnl' layout %d\n", layout);
|
||||
if (!layout) {
|
||||
AVChannelLayout *ch_layout = &st->codecpar->ch_layout;
|
||||
AVChannelLayout tmp = { 0 }, *ch_layout = &st->codecpar->ch_layout;
|
||||
int nb_channels = ch_layout->nb_channels;
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
ret = av_channel_layout_custom_init(ch_layout, nb_channels);
|
||||
ret = av_channel_layout_custom_init(&tmp, nb_channels);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -762,12 +769,15 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st)
|
||||
channel = AV_CHAN_UNKNOWN;
|
||||
}
|
||||
|
||||
ch_layout->u.map[i].id = channel;
|
||||
tmp.u.map[i].id = channel;
|
||||
}
|
||||
|
||||
ret = av_channel_layout_retype(ch_layout, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
ret = av_channel_layout_retype(&tmp, 0, AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
av_channel_layout_uninit(ch_layout);
|
||||
*ch_layout = tmp;
|
||||
} else {
|
||||
uint64_t omitted_channel_map = avio_rb64(pb);
|
||||
ret = ff_mov_get_channel_layout_from_config(layout, &st->codecpar->ch_layout, omitted_channel_map);
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "internal.h"
|
||||
#include "oggdec.h"
|
||||
|
||||
/* CELT-over-Ogg streams use at most a couple of vorbiscomment "extra" headers. */
|
||||
#define CELT_MAX_EXTRA_HEADERS 16
|
||||
|
||||
struct oggcelt_private {
|
||||
int extra_headers_left;
|
||||
};
|
||||
@@ -62,6 +65,12 @@ static int celt_header(AVFormatContext *s, int idx)
|
||||
overlap = AV_RL32(p + 48);
|
||||
/* unused bytes per packet field skipped */
|
||||
extra_headers = AV_RL32(p + 56);
|
||||
if (extra_headers > CELT_MAX_EXTRA_HEADERS) {
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
"Too many CELT extra headers (%u)\n", extra_headers);
|
||||
av_free(priv);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
st->codecpar->codec_id = AV_CODEC_ID_CELT;
|
||||
st->codecpar->sample_rate = sample_rate;
|
||||
|
||||
@@ -224,8 +224,11 @@ static int fixup_vorbis_headers(AVFormatContext *as,
|
||||
int i, offset, len, err;
|
||||
int buf_len;
|
||||
unsigned char *ptr;
|
||||
uint64_t total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
|
||||
if (total_len + total_len / 255 + 64 > INT_MAX)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
len = priv->len[0] + priv->len[1] + priv->len[2];
|
||||
len = total_len;
|
||||
buf_len = len + len / 255 + 64;
|
||||
|
||||
if (*buf)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "version_major.h"
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MINOR 7
|
||||
#define LIBAVFORMAT_VERSION_MICRO 102
|
||||
#define LIBAVFORMAT_VERSION_MICRO 103
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
|
||||
Reference in New Issue
Block a user