hevc/rext: basic infrastructure for supporting range extension

- support for 4:2:2 and 4:4:4 up to 12 bits
- add a new profile for range extension
(cherry picked from commit d3c067fa65bbc871758d28aa07f54123430ca346)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Mickaël Raulet 2014-07-15 00:16:53 +02:00 committed by Michael Niedermayer
parent 250430bf28
commit 5a41999d81
11 changed files with 422 additions and 135 deletions

View File

@ -2866,6 +2866,7 @@ typedef struct AVCodecContext {
#define FF_PROFILE_HEVC_MAIN 1
#define FF_PROFILE_HEVC_MAIN_10 2
#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3
#define FF_PROFILE_HEVC_REXT 4
/**
* level

View File

@ -157,7 +157,7 @@ static void pred_weight_table(HEVCContext *s, GetBitContext *gb)
s->sh.luma_offset_l0[i] = 0;
}
}
if (s->sps->chroma_format_idc != 0) { // FIXME: invert "if" and "for"
if (s->sps->chroma_format_idc != 0) {
for (i = 0; i < s->sh.nb_refs[L0]; i++)
chroma_weight_l0_flag[i] = get_bits1(gb);
} else {
@ -761,7 +761,6 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
HEVCLocalContext *lc = s->HEVClc;
int sao_merge_left_flag = 0;
int sao_merge_up_flag = 0;
int shift = s->sps->bit_depth - FFMIN(s->sps->bit_depth, 10);
SAOParams *sao = &CTB(s->sao, rx, ry);
int c_idx, i;
@ -778,6 +777,9 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
}
for (c_idx = 0; c_idx < 3; c_idx++) {
int log2_sao_offset_scale = c_idx == 0 ? s->pps->log2_sao_offset_scale_luma :
s->pps->log2_sao_offset_scale_chroma;
if (!s->sh.slice_sample_adaptive_offset_flag[c_idx]) {
sao->type_idx[c_idx] = SAO_NOT_APPLIED;
continue;
@ -813,13 +815,14 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
// Inferred parameters
sao->offset_val[c_idx][0] = 0;
for (i = 0; i < 4; i++) {
sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i] << shift;
sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i];
if (sao->type_idx[c_idx] == SAO_EDGE) {
if (i > 1)
sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
} else if (sao->offset_sign[c_idx][i]) {
sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
}
sao->offset_val[c_idx][i + 1] <<= log2_sao_offset_scale;
}
}
}
@ -833,31 +836,30 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
int trafo_depth, int blk_idx)
{
HEVCLocalContext *lc = s->HEVClc;
const int log2_trafo_size_c = log2_trafo_size - s->sps->hshift[1];
int i;
if (lc->cu.pred_mode == MODE_INTRA) {
int trafo_size = 1 << log2_trafo_size;
ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0);
if (log2_trafo_size > 2) {
trafo_size = trafo_size << (s->sps->hshift[1] - 1);
ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
s->hpc.intra_pred[log2_trafo_size - 3](s, x0, y0, 1);
s->hpc.intra_pred[log2_trafo_size - 3](s, x0, y0, 2);
} else if (blk_idx == 3) {
trafo_size = trafo_size << s->sps->hshift[1];
ff_hevc_set_neighbour_available(s, xBase, yBase,
trafo_size, trafo_size);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2);
}
}
if (lc->tt.cbf_luma ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << log2_trafo_size_c)) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << log2_trafo_size_c))))) {
int scan_idx = SCAN_DIAG;
int scan_idx_c = SCAN_DIAG;
int cbf_luma = lc->tt.cbf_luma;
int cbf_chroma = SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << log2_trafo_size_c)) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << log2_trafo_size_c))));
if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {
lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);
@ -881,37 +883,102 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
}
if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {
if (lc->tu.cur_intra_pred_mode >= 6 &&
lc->tu.cur_intra_pred_mode <= 14) {
if (lc->tu.intra_pred_mode >= 6 &&
lc->tu.intra_pred_mode <= 14) {
scan_idx = SCAN_VERT;
} else if (lc->tu.cur_intra_pred_mode >= 22 &&
lc->tu.cur_intra_pred_mode <= 30) {
} else if (lc->tu.intra_pred_mode >= 22 &&
lc->tu.intra_pred_mode <= 30) {
scan_idx = SCAN_HORIZ;
}
if (lc->pu.intra_pred_mode_c >= 6 &&
lc->pu.intra_pred_mode_c <= 14) {
if (lc->tu.intra_pred_mode_c >= 6 &&
lc->tu.intra_pred_mode_c <= 14) {
scan_idx_c = SCAN_VERT;
} else if (lc->pu.intra_pred_mode_c >= 22 &&
lc->pu.intra_pred_mode_c <= 30) {
} else if (lc->tu.intra_pred_mode_c >= 22 &&
lc->tu.intra_pred_mode_c <= 30) {
scan_idx_c = SCAN_HORIZ;
}
}
if (lc->tt.cbf_luma)
if (cbf_luma)
ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
if (log2_trafo_size > 2) {
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0))
ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 1);
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0))
ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 2);
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 1);
}
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (i << log2_trafo_size_c)))
ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 1);
}
for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 2);
}
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (i << log2_trafo_size_c)))
ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),
log2_trafo_size_c, scan_idx_c, 2);
}
} else if (blk_idx == 3) {
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase))
ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 1);
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase))
ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2);
int trafo_size_h = 1 << (log2_trafo_size + 1);
int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[1]);
for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 1);
}
if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase + (i << log2_trafo_size_c)))
ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 1);
}
for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
if (lc->cu.pred_mode == MODE_INTRA) {
ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 2);
}
if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase + (i << log2_trafo_size_c)))
ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),
log2_trafo_size, scan_idx_c, 2);
}
}
} else if (lc->cu.pred_mode == MODE_INTRA) {
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
ff_hevc_set_neighbour_available(s, x0, y0, trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 1);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 2);
if (s->sps->chroma_format_idc == 2) {
ff_hevc_set_neighbour_available(s, x0, y0 + (1 << log2_trafo_size_c),
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 1);
s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 2);
}
} else if (blk_idx == 3) {
int trafo_size_h = 1 << (log2_trafo_size + 1);
int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[1]);
ff_hevc_set_neighbour_available(s, xBase, yBase,
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2);
if (s->sps->chroma_format_idc == 2) {
ff_hevc_set_neighbour_available(s, xBase, yBase + (1 << (log2_trafo_size)),
trafo_size_h, trafo_size_v);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 1);
s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 2);
}
}
}
return 0;
}
@ -944,16 +1011,38 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase);
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase);
if (s->sps->chroma_format_idc == 2) {
int xBase_cb = xBase & ((1 << log2_trafo_size) - 1);
int yBase_cb = yBase & ((1 << log2_trafo_size) - 1);
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF2(lc->tt.cbf_cb[trafo_depth - 1], xBase_cb, yBase_cb + (1 << (log2_trafo_size)));
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF2(lc->tt.cbf_cr[trafo_depth - 1], xBase_cb, yBase_cb + (1 << (log2_trafo_size)));
}
} else {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) = 0;
if (s->sps->chroma_format_idc == 2) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) = 0;
}
}
if (lc->cu.intra_split_flag) {
if (trafo_depth == 1)
lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[blk_idx];
if (trafo_depth == 1) {
lc->tu.intra_pred_mode = lc->pu.intra_pred_mode[blk_idx];
if (s->sps->chroma_format_idc == 3) {
lc->tu.intra_pred_mode_c = lc->pu.intra_pred_mode_c[blk_idx];
lc->tu.chroma_mode_c = lc->pu.chroma_mode_c[blk_idx];
} else {
lc->tu.intra_pred_mode_c = lc->pu.intra_pred_mode_c[0];
lc->tu.chroma_mode_c = lc->pu.chroma_mode_c[0];
}
}
} else {
lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[0];
lc->tu.intra_pred_mode = lc->pu.intra_pred_mode[0];
lc->tu.intra_pred_mode_c = lc->pu.intra_pred_mode_c[0];
lc->tu.chroma_mode_c = lc->pu.chroma_mode_c[0];
}
lc->tt.cbf_luma = 1;
@ -974,17 +1063,25 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
lc->tt.inter_split_flag;
}
if (log2_trafo_size > 2) {
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
if (trafo_depth == 0 ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase)) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
}
}
if (trafo_depth == 0 ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) =
ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
}
}
}
@ -1019,7 +1116,10 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) ||
(s->sps->chroma_format_idc == 2 &&
(SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1))) ||
SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (1 << (log2_trafo_size - 1)))))) {
lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
}
@ -1061,7 +1161,10 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
int stride2 = s->frame->linesize[2];
uint8_t *dst2 = &s->frame->data[2][(y0 >> s->sps->vshift[2]) * stride2 + ((x0 >> s->sps->hshift[2]) << s->sps->pixel_shift)];
int length = cb_size * cb_size * s->sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->sps->pcm.bit_depth_chroma;
int length = cb_size * cb_size * s->sps->pcm.bit_depth +
(((cb_size >> s->sps->hshift[1]) * (cb_size >> s->sps->vshift[1])) +
((cb_size >> s->sps->hshift[2]) * (cb_size >> s->sps->vshift[2]))) *
s->sps->pcm.bit_depth_chroma;
const uint8_t *pcm = skip_bytes(&lc->cc, (length + 7) >> 3);
int ret;
@ -1072,9 +1175,15 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
if (ret < 0)
return ret;
s->hevcdsp.put_pcm(dst0, stride0, cb_size, &gb, s->sps->pcm.bit_depth);
s->hevcdsp.put_pcm(dst1, stride1, cb_size / 2, &gb, s->sps->pcm.bit_depth_chroma);
s->hevcdsp.put_pcm(dst2, stride2, cb_size / 2, &gb, s->sps->pcm.bit_depth_chroma);
s->hevcdsp.put_pcm(dst0, stride0, cb_size, cb_size, &gb, s->sps->pcm.bit_depth);
s->hevcdsp.put_pcm(dst1, stride1,
cb_size >> s->sps->hshift[1],
cb_size >> s->sps->vshift[1],
&gb, s->sps->pcm.bit_depth_chroma);
s->hevcdsp.put_pcm(dst2, stride2,
cb_size >> s->sps->hshift[2],
cb_size >> s->sps->vshift[2],
&gb, s->sps->pcm.bit_depth_chroma);
return 0;
}
@ -1415,7 +1524,7 @@ static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
int nPbW, int nPbH,
int log2_cb_size, int partIdx)
int log2_cb_size, int partIdx, int idx)
{
#define POS(c_idx, x, y) \
&s->frame->data[c_idx][((y) >> s->sps->vshift[c_idx]) * s->frame->linesize[c_idx] + \
@ -1521,7 +1630,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
x_pu = x0 >> s->sps->log2_min_pu_size;
y_pu = y0 >> s->sps->log2_min_pu_size;
for(j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
}
@ -1689,6 +1798,10 @@ static av_always_inline void set_ct_depth(HEVCContext *s, int x0, int y0,
ct_depth, length);
}
static const uint8_t tab_mode_idx[] = {
0, 1, 2, 2, 2, 2, 3, 5, 7, 8, 10, 12, 13, 15, 17, 18, 19, 20,
21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 31};
static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
int log2_cb_size)
{
@ -1718,14 +1831,42 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
}
}
chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
lc->pu.intra_pred_mode_c = 34;
else
lc->pu.intra_pred_mode_c = intra_chroma_table[chroma_mode];
} else {
lc->pu.intra_pred_mode_c = lc->pu.intra_pred_mode[0];
if (s->sps->chroma_format_idc == 3) {
for (i = 0; i < side; i++) {
for (j = 0; j < side; j++) {
lc->pu.chroma_mode_c[2 * i + j] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[2 * i + j] == intra_chroma_table[chroma_mode])
lc->pu.intra_pred_mode_c[2 * i + j] = 34;
else
lc->pu.intra_pred_mode_c[2 * i + j] = intra_chroma_table[chroma_mode];
} else {
lc->pu.intra_pred_mode_c[2 * i + j] = lc->pu.intra_pred_mode[2 * i + j];
}
}
}
} else if (s->sps->chroma_format_idc == 2) {
int mode_idx;
lc->pu.chroma_mode_c[0] = chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
mode_idx = 34;
else
mode_idx = intra_chroma_table[chroma_mode];
} else {
mode_idx = lc->pu.intra_pred_mode[0];
}
lc->pu.intra_pred_mode_c[0] = tab_mode_idx[mode_idx];
} else if (s->sps->chroma_format_idc != 0) {
chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
if (chroma_mode != 4) {
if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
lc->pu.intra_pred_mode_c[0] = 34;
else
lc->pu.intra_pred_mode_c[0] = intra_chroma_table[chroma_mode];
} else {
lc->pu.intra_pred_mode_c[0] = lc->pu.intra_pred_mode[0];
}
}
}
@ -1761,8 +1902,9 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
int min_cb_width = s->sps->min_cb_width;
int x_cb = x0 >> log2_min_cb_size;
int y_cb = y0 >> log2_min_cb_size;
int idx = log2_cb_size - 2;
int qp_block_mask = (1<<(s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1;
int x, y, ret;
int qp_block_mask = (1<<(s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1;
lc->cu.x = x0;
lc->cu.y = y0;
@ -1794,7 +1936,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
}
if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
if (!s->sh.disable_deblocking_filter_flag)
@ -1830,37 +1972,37 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
switch (lc->cu.part_mode) {
case PART_2Nx2N:
hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0, idx);
break;
case PART_2NxN:
hls_prediction_unit(s, x0, y0, cb_size, cb_size / 2, log2_cb_size, 0);
hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size, cb_size / 2, log2_cb_size, 0, idx);
hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1, idx);
break;
case PART_Nx2N:
hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size, log2_cb_size, 0);
hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size, log2_cb_size, 0, idx - 1);
hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1, idx - 1);
break;
case PART_2NxnU:
hls_prediction_unit(s, x0, y0, cb_size, cb_size / 4, log2_cb_size, 0);
hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size, cb_size / 4, log2_cb_size, 0, idx);
hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1, idx);
break;
case PART_2NxnD:
hls_prediction_unit(s, x0, y0, cb_size, cb_size * 3 / 4, log2_cb_size, 0);
hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size / 4, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size, cb_size * 3 / 4, log2_cb_size, 0, idx);
hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size / 4, log2_cb_size, 1, idx);
break;
case PART_nLx2N:
hls_prediction_unit(s, x0, y0, cb_size / 4, cb_size, log2_cb_size, 0);
hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size / 4, cb_size, log2_cb_size, 0, idx - 2);
hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1, idx - 2);
break;
case PART_nRx2N:
hls_prediction_unit(s, x0, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0);
hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size / 4, cb_size, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0, idx - 2);
hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size / 4, cb_size, log2_cb_size, 1, idx - 2);
break;
case PART_NxN:
hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size / 2, log2_cb_size, 0);
hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size / 2, log2_cb_size, 1);
hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2);
hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3);
hls_prediction_unit(s, x0, y0, cb_size / 2, cb_size / 2, log2_cb_size, 0, idx - 1);
hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size / 2, log2_cb_size, 1, idx - 1);
hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2, idx - 1);
hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3, idx - 1);
break;
}
}
@ -3216,6 +3358,7 @@ static const AVProfile profiles[] = {
{ FF_PROFILE_HEVC_MAIN, "Main" },
{ FF_PROFILE_HEVC_MAIN_10, "Main 10" },
{ FF_PROFILE_HEVC_MAIN_STILL_PICTURE, "Main Still Picture" },
{ FF_PROFILE_HEVC_REXT, "Rext" },
{ FF_PROFILE_UNKNOWN },
};

View File

@ -83,6 +83,7 @@
#define SAMPLE(tab, x, y) ((tab)[(y) * s->sps->width + (x)])
#define SAMPLE_CTB(tab, x, y) ((tab)[(y) * min_cb_width + (x)])
#define SAMPLE_CBF(tab, x, y) ((tab)[((y) & ((1<<log2_trafo_size)-1)) * MAX_CU_SIZE + ((x) & ((1<<log2_trafo_size)-1))])
#define SAMPLE_CBF2(tab, x, y) ((tab)[(y) * MAX_CU_SIZE + (x)])
#define IS_IDR(s) ((s)->nal_unit_type == NAL_IDR_W_RADL || (s)->nal_unit_type == NAL_IDR_N_LP)
#define IS_BLA(s) ((s)->nal_unit_type == NAL_BLA_W_RADL || (s)->nal_unit_type == NAL_BLA_W_LP || \
@ -457,6 +458,13 @@ typedef struct HEVCSPS {
int max_transform_hierarchy_depth_inter;
int max_transform_hierarchy_depth_intra;
int transform_skip_rotation_enabled_flag;
int transform_skip_context_enabled_flag;
int implicit_rdpcm_enabled_flag;
int explicit_rdpcm_enabled_flag;
int intra_smoothing_disabled_flag;
int persistent_rice_adaptation_enabled_flag;
///< coded frame dimension in various units
int width;
int height;
@ -526,6 +534,15 @@ typedef struct HEVCPPS {
int log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2
int num_extra_slice_header_bits;
uint8_t slice_header_extension_present_flag;
uint8_t log2_max_transform_skip_block_size;
uint8_t cross_component_prediction_enabled_flag;
uint8_t chroma_qp_offset_list_enabled_flag;
uint8_t diff_cu_chroma_qp_offset_depth;
uint8_t chroma_qp_offset_list_len_minus1;
int8_t cb_qp_offset_list[5];
int8_t cr_qp_offset_list[5];
uint8_t log2_sao_offset_scale_luma;
uint8_t log2_sao_offset_scale_chroma;
// Inferred parameters
unsigned int *column_width; ///< ColumnWidth
@ -661,7 +678,8 @@ typedef struct PredictionUnit {
uint8_t intra_pred_mode[4];
Mv mvd;
uint8_t merge_flag;
uint8_t intra_pred_mode_c;
uint8_t intra_pred_mode_c[4];
uint8_t chroma_mode_c[4];
} PredictionUnit;
typedef struct TransformTree {
@ -677,7 +695,9 @@ typedef struct TransformUnit {
int cu_qp_delta;
// Inferred parameters;
int cur_intra_pred_mode;
int intra_pred_mode;
int intra_pred_mode_c;
int chroma_mode_c;
uint8_t is_cu_qp_delta_coded;
} TransformUnit;
@ -968,7 +988,6 @@ int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s);
int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size);
int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth);
int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth);
int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx);
/**
* Get the number of candidate references for the current frame.

View File

@ -894,7 +894,7 @@ int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth)
return GET_CABAC(elem_offset[CBF_LUMA] + !trafo_depth);
}
int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx)
static int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx)
{
return GET_CABAC(elem_offset[TRANSFORM_SKIP_FLAG] + !!c_idx);
}
@ -1093,16 +1093,18 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0,
// Derive QP for dequant
if (!lc->cu.cu_transquant_bypass_flag) {
static const int qp_c[] = { 29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37 };
static const uint8_t rem6[51 + 2 * 6 + 1] = {
static const uint8_t rem6[51 + 4 * 6 + 1] = {
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2,
3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
4, 5, 0, 1, 2, 3, 4, 5, 0, 1
};
static const uint8_t div6[51 + 2 * 6 + 1] = {
static const uint8_t div6[51 + 4 * 6 + 1] = {
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3,
3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
10, 10, 11, 11, 11, 11, 11, 11, 12, 12
};
int qp_y = lc->qp_y;

View File

@ -61,12 +61,16 @@ static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
offset = s->pps->cr_qp_offset;
qp_i = av_clip(qp_y + offset, 0, 57);
if (qp_i < 30)
qp = qp_i;
else if (qp_i > 43)
qp = qp_i - 6;
else
qp = qp_c[qp_i - 30];
if (s->sps->chroma_format_idc == 1) {
if (qp_i < 30)
qp = qp_i;
else if (qp_i > 43)
qp = qp_i - 6;
else
qp = qp_c[qp_i - 30];
} else {
qp = av_clip(qp_i, 0, 51);
}
idxt = av_clip(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
return tctable[idxt];
@ -327,6 +331,9 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
if (x0) {
left_tc_offset = s->deblock[ctb - 1].tc_offset;
left_beta_offset = s->deblock[ctb - 1].beta_offset;
} else {
left_tc_offset = 0;
left_beta_offset = 0;
}
x_end = x0 + ctb_size;
@ -371,22 +378,25 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
// vertical filtering chroma
for (chroma = 1; chroma <= 2; chroma++) {
for (y = y0; y < y_end; y += 16) {
for (x = x0 ? x0 : 16; x < x_end; x += 16) {
const int bs0 = s->vertical_bs[(x >> 3) + (y >> 2) * s->bs_width];
const int bs1 = s->vertical_bs[(x >> 3) + ((y + 8) >> 2) * s->bs_width];
int h = 1 << s->sps->hshift[chroma];
int v = 1 << s->sps->vshift[chroma];
for (y = y0; y < y_end; y += (8 * v)) {
for (x = x0 ? x0 : 8 * h; x < x_end; x += (8 * h)) {
const int bs0 = s->vertical_bs[(x >> 3) + (y >> 2) * s->bs_width];
const int bs1 = s->vertical_bs[(x >> 3) + ((y + (4 * v)) >> 2) * s->bs_width];
if ((bs0 == 2) || (bs1 == 2)) {
const int qp0 = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
const int qp1 = (get_qPy(s, x - 1, y + 8) + get_qPy(s, x, y + 8) + 1) >> 1;
const int qp0 = (get_qPy(s, x - 1, y) + get_qPy(s, x, y) + 1) >> 1;
const int qp1 = (get_qPy(s, x - 1, y + (4 * v)) + get_qPy(s, x, y + (4 * v)) + 1) >> 1;
c_tc[0] = (bs0 == 2) ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
c_tc[1] = (bs1 == 2) ? chroma_tc(s, qp1, chroma, tc_offset) : 0;
src = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
src = &s->frame->data[chroma][(y >> s->sps->vshift[chroma]) * s->frame->linesize[chroma] + ((x >> s->sps->hshift[chroma]) << s->sps->pixel_shift)];
if (pcmf) {
no_p[0] = get_pcm(s, x - 1, y);
no_p[1] = get_pcm(s, x - 1, y + 8);
no_p[1] = get_pcm(s, x - 1, y + (4 * v));
no_q[0] = get_pcm(s, x, y);
no_q[1] = get_pcm(s, x, y + 8);
no_q[1] = get_pcm(s, x, y + (4 * v));
s->hevcdsp.hevc_v_loop_filter_chroma_c(src,
s->frame->linesize[chroma],
c_tc, no_p, no_q);
@ -436,35 +446,37 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
// horizontal filtering chroma
for (chroma = 1; chroma <= 2; chroma++) {
for (y = y0 ? y0 : 16; y < y_end; y += 16) {
for (x = x0 - 8; x < x_end; x += 16) {
int h = 1 << s->sps->hshift[chroma];
int v = 1 << s->sps->vshift[chroma];
for (y = y0 ? y0 : 8 * v; y < y_end; y += (8 * v)) {
for (x = x0 - 8; x < x_end; x += (8 * h)) {
int bs0, bs1;
// to make sure no memory access over boundary when x = -8
// TODO: simplify with row based deblocking
if (x < 0) {
bs0 = 0;
bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
} else if (x >= x_end - 8) {
bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
bs1 = s->horizontal_bs[(x + (4 * h) + y * s->bs_width) >> 2];
} else if (x >= x_end - 4 * h) {
bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
bs1 = 0;
} else {
bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
bs0 = s->horizontal_bs[(x + y * s->bs_width) >> 2];
bs1 = s->horizontal_bs[(x + (4 * h) + y * s->bs_width) >> 2];
}
if ((bs0 == 2) || (bs1 == 2)) {
const int qp0 = bs0 == 2 ? (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1 : 0;
const int qp1 = bs1 == 2 ? (get_qPy(s, x + 8, y - 1) + get_qPy(s, x + 8, y) + 1) >> 1 : 0;
const int qp0 = bs0 == 2 ? (get_qPy(s, x, y - 1) + get_qPy(s, x, y) + 1) >> 1 : 0;
const int qp1 = bs1 == 2 ? (get_qPy(s, x + (4 * h), y - 1) + get_qPy(s, x + (4 * h), y) + 1) >> 1 : 0;
tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
c_tc[0] = bs0 == 2 ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
c_tc[1] = bs1 == 2 ? chroma_tc(s, qp1, chroma, cur_tc_offset) : 0;
src = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
src = &s->frame->data[chroma][(y >> s->sps->vshift[1]) * s->frame->linesize[chroma] + ((x >> s->sps->hshift[1]) << s->sps->pixel_shift)];
if (pcmf) {
no_p[0] = get_pcm(s, x, y - 1);
no_p[1] = get_pcm(s, x + 8, y - 1);
no_q[0] = get_pcm(s, x, y);
no_q[1] = get_pcm(s, x + 8, y);
no_p[0] = get_pcm(s, x, y - 1);
no_p[1] = get_pcm(s, x + (4 * h), y - 1);
no_q[0] = get_pcm(s, x, y);
no_q[1] = get_pcm(s, x + (4 * h), y);
s->hevcdsp.hevc_h_loop_filter_chroma_c(src,
s->frame->linesize[chroma],
c_tc, no_p, no_q);

View File

@ -207,6 +207,8 @@ static void decode_profile_tier_level(HEVCContext *s, PTLCommon *ptl)
av_log(s->avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)
av_log(s->avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)
av_log(s->avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");
else
av_log(s->avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
@ -668,8 +670,8 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
}
sps->chroma_format_idc = get_ue_golomb_long(gb);
if (sps->chroma_format_idc != 1) {
avpriv_report_missing_feature(s->avctx, "chroma_format_idc != 1\n");
if (!(sps->chroma_format_idc == 1 || sps->chroma_format_idc == 2 || sps->chroma_format_idc == 3)) {
avpriv_report_missing_feature(s->avctx, "chroma_format_idc != {1, 2, 3}\n");
ret = AVERROR_PATCHWELCOME;
goto err;
}
@ -677,6 +679,9 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
if (sps->chroma_format_idc == 3)
sps->separate_colour_plane_flag = get_bits1(gb);
if (sps->separate_colour_plane_flag)
sps->chroma_format_idc = 0;
sps->width = get_ue_golomb_long(gb);
sps->height = get_ue_golomb_long(gb);
if ((ret = av_image_check_size(sps->width,
@ -718,20 +723,30 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
goto err;
}
if (sps->chroma_format_idc == 1) {
switch (sps->bit_depth) {
case 8: sps->pix_fmt = AV_PIX_FMT_YUV420P; break;
case 9: sps->pix_fmt = AV_PIX_FMT_YUV420P9; break;
case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;
default:
av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
sps->bit_depth);
ret = AVERROR_PATCHWELCOME;
goto err;
}
} else {
switch (sps->bit_depth) {
case 8:
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;
if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
break;
case 9:
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9;
if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;
break;
case 10:
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;
if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
break;
case 12:
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;
if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
break;
default:
av_log(s->avctx, AV_LOG_ERROR,
"non-4:2:0 support is currently unspecified.\n");
"4:2:0, 4:2:2, 4:4:4 supports are currently specified for 8, 10 and 12 bits.\n");
return AVERROR_PATCHWELCOME;
}
@ -862,8 +877,42 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
vui_present = get_bits1(gb);
if (vui_present)
decode_vui(s, sps);
skip_bits1(gb); // sps_extension_flag
if (get_bits1(gb)) { // sps_extension_flag
int sps_extension_flag[1];
for (i = 0; i < 1; i++)
sps_extension_flag[i] = get_bits1(gb);
skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
if (sps_extension_flag[0]) {
int extended_precision_processing_flag;
int high_precision_offsets_enabled_flag;
int cabac_bypass_alignment_enabled_flag;
sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
sps->transform_skip_context_enabled_flag = get_bits1(gb);
sps->implicit_rdpcm_enabled_flag = get_bits1(gb);
sps->explicit_rdpcm_enabled_flag = get_bits1(gb);
extended_precision_processing_flag = get_bits1(gb);
if (extended_precision_processing_flag)
av_log(s->avctx, AV_LOG_WARNING,
"extended_precision_processing_flag not yet implemented\n");
sps->intra_smoothing_disabled_flag = get_bits1(gb);
high_precision_offsets_enabled_flag = get_bits1(gb);
if (high_precision_offsets_enabled_flag)
av_log(s->avctx, AV_LOG_WARNING,
"high_precision_offsets_enabled_flag not yet implemented\n");
sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb);
cabac_bypass_alignment_enabled_flag = get_bits1(gb);
if (cabac_bypass_alignment_enabled_flag)
av_log(s->avctx, AV_LOG_WARNING,
"cabac_bypass_alignment_enabled_flag not yet implemented\n");
}
}
if (s->apply_defdispwin) {
sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
@ -997,6 +1046,46 @@ static void hevc_pps_free(void *opaque, uint8_t *data)
av_freep(&pps);
}
static int pps_range_extensions(HEVCContext *s, HEVCPPS *pps, HEVCSPS *sps) {
GetBitContext *gb = &s->HEVClc->gb;
int i;
if (pps->transform_skip_enabled_flag) {
pps->log2_max_transform_skip_block_size = get_ue_golomb_long(gb) + 2;
}
pps->cross_component_prediction_enabled_flag = get_bits1(gb);
if (pps->cross_component_prediction_enabled_flag) {
av_log(s->avctx, AV_LOG_WARNING,
"cross_component_prediction_enabled_flag is not yet implemented.\n");
}
pps->chroma_qp_offset_list_enabled_flag = get_bits1(gb);
if (pps->chroma_qp_offset_list_enabled_flag) {
pps->diff_cu_chroma_qp_offset_depth = get_ue_golomb_long(gb);
pps->chroma_qp_offset_list_len_minus1 = get_ue_golomb_long(gb);
if (pps->chroma_qp_offset_list_len_minus1 && pps->chroma_qp_offset_list_len_minus1 >= 5) {
av_log(s->avctx, AV_LOG_ERROR,
"chroma_qp_offset_list_len_minus1 shall be in the range [0, 5].\n");
return AVERROR_INVALIDDATA;
}
for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
pps->cb_qp_offset_list[i] = get_se_golomb_long(gb);
if (pps->cb_qp_offset_list[i]) {
av_log(s->avctx, AV_LOG_WARNING,
"cb_qp_offset_list not tested yet.\n");
}
pps->cr_qp_offset_list[i] = get_se_golomb_long(gb);
if (pps->cr_qp_offset_list[i]) {
av_log(s->avctx, AV_LOG_WARNING,
"cb_qp_offset_list not tested yet.\n");
}
}
}
pps->log2_sao_offset_scale_luma = get_ue_golomb_long(gb);
pps->log2_sao_offset_scale_chroma = get_ue_golomb_long(gb);
return(0);
}
int ff_hevc_decode_nal_pps(HEVCContext *s)
{
GetBitContext *gb = &s->HEVClc->gb;
@ -1030,6 +1119,7 @@ int ff_hevc_decode_nal_pps(HEVCContext *s)
pps->disable_dbf = 0;
pps->beta_offset = 0;
pps->tc_offset = 0;
pps->log2_max_transform_skip_block_size = 2;
// Coded parameters
pps_id = get_ue_golomb_long(gb);
@ -1190,7 +1280,16 @@ int ff_hevc_decode_nal_pps(HEVCContext *s)
}
pps->slice_header_extension_present_flag = get_bits1(gb);
skip_bits1(gb); // pps_extension_flag
if (get_bits1(gb)) { // pps_extension_present_flag
int pps_range_extensions_flag = get_bits1(gb);
/* int pps_extension_7bits = */ get_bits(gb, 7);
if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) {
av_log(s->avctx, AV_LOG_ERROR,
"PPS extension flag is partially implemented.\n");
pps_range_extensions(s, pps, sps);
}
}
// Inferred parameters
pps->col_bd = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));

View File

@ -119,6 +119,10 @@ DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_filters[3][16]) = {
#include "hevcdsp_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 12
#include "hevcdsp_template.c"
#undef BIT_DEPTH
void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth)
{
#undef FUNC
@ -235,6 +239,9 @@ int i = 0;
case 10:
HEVC_DSP(10);
break;
case 12:
HEVC_DSP(12);
break;
default:
HEVC_DSP(8);
break;

View File

@ -41,8 +41,8 @@ typedef struct SAOParams {
} SAOParams;
typedef struct HEVCDSPContext {
void (*put_pcm)(uint8_t *dst, ptrdiff_t stride, int size,
GetBitContext *gb, int pcm_bit_depth);
void (*put_pcm)(uint8_t *_dst, ptrdiff_t _stride, int width, int height,
struct GetBitContext *gb, int pcm_bit_depth);
void (*transform_add[4])(uint8_t *_dst, int16_t *coeffs, ptrdiff_t _stride);

View File

@ -27,7 +27,7 @@
#include "hevcdsp.h"
static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int size,
static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int width, int height,
GetBitContext *gb, int pcm_bit_depth)
{
int x, y;
@ -35,8 +35,8 @@ static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int size,
stride /= sizeof(pixel);
for (y = 0; y < size; y++) {
for (x = 0; x < size; x++)
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
dst[x] = get_bits(gb, pcm_bit_depth) << (BIT_DEPTH - pcm_bit_depth);
dst += stride;
}

View File

@ -36,6 +36,10 @@
#include "hevcpred_template.c"
#undef BIT_DEPTH
#define BIT_DEPTH 12
#include "hevcpred_template.c"
#undef BIT_DEPTH
void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth)
{
#undef FUNC
@ -63,6 +67,9 @@ void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth)
case 10:
HEVC_PRED(10);
break;
case 12:
HEVC_PRED(12);
break;
default:
HEVC_PRED(8);
break;

View File

@ -91,8 +91,8 @@ do { \
int min_pu_width = s->sps->min_pu_width;
enum IntraPredMode mode = c_idx ? lc->pu.intra_pred_mode_c :
lc->tu.cur_intra_pred_mode;
enum IntraPredMode mode = c_idx ? lc->tu.intra_pred_mode_c :
lc->tu.intra_pred_mode;
pixel4 a;
pixel left_array[2 * MAX_TB_SIZE + 1];
pixel filtered_left_array[2 * MAX_TB_SIZE + 1];
@ -207,7 +207,6 @@ do { \
j++;
EXTEND_LEFT_CIP(top, j, j + 1);
left[-1] = top[-1];
j = 0;
}
} else {
j = 0;
@ -221,7 +220,6 @@ do { \
top[-1] = top[0];
}
left[-1] = top[-1];
j = 0;
}
left[-1] = top[-1];
if (cand_bottom_left || cand_left) {
@ -238,7 +236,6 @@ do { \
if (!IS_INTRA(-1, - 1))
left[-1] = left[0];
} else if (x0 == 0) {
a = PIXEL_SPLAT_X4(left[size_max_y - 1]);
EXTEND(left, 0, size_max_y);
} else {
a = PIXEL_SPLAT_X4(left[size_max_y - 1]);
@ -290,7 +287,7 @@ do { \
top[-1] = left[-1];
// Filtering process
if (c_idx == 0) {
if (!s->sps->intra_smoothing_disabled_flag && (c_idx == 0 || s->sps->chroma_format_idc == 3)) {
if (mode != INTRA_DC && size != 4){
int intra_hor_ver_dist_thresh[] = { 7, 1, 0 };
int min_dist_vert_hor = FFMIN(FFABS((int)(mode - 26U)),