Commit 7cf6a67e authored by Mickaël Raulet's avatar Mickaël Raulet Committed by Michael Niedermayer

avcodec/hevc: adding support for monochrome sequences in hevc

cherry picked from commit 8e50557707d2ec11ccad657470b2e140f314348e
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent ecc92ee7
...@@ -553,8 +553,10 @@ static int hls_slice_header(HEVCContext *s) ...@@ -553,8 +553,10 @@ static int hls_slice_header(HEVCContext *s)
if (s->sps->sao_enabled) { if (s->sps->sao_enabled) {
sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb); sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb);
if (s->sps->chroma_format_idc) {
sh->slice_sample_adaptive_offset_flag[1] = sh->slice_sample_adaptive_offset_flag[1] =
sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb); sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);
}
} else { } else {
sh->slice_sample_adaptive_offset_flag[0] = 0; sh->slice_sample_adaptive_offset_flag[0] = 0;
sh->slice_sample_adaptive_offset_flag[1] = 0; sh->slice_sample_adaptive_offset_flag[1] = 0;
...@@ -813,7 +815,7 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry) ...@@ -813,7 +815,7 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry)
} }
} }
for (c_idx = 0; c_idx < 3; c_idx++) { for (c_idx = 0; c_idx < (s->sps->chroma_format_idc ? 3 : 1); c_idx++) {
int log2_sao_offset_scale = c_idx == 0 ? s->pps->log2_sao_offset_scale_luma : int log2_sao_offset_scale = c_idx == 0 ? s->pps->log2_sao_offset_scale_luma :
s->pps->log2_sao_offset_scale_chroma; s->pps->log2_sao_offset_scale_chroma;
...@@ -969,7 +971,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, ...@@ -969,7 +971,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
if (cbf_luma) if (cbf_luma)
ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0); ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) { if (s->sps->chroma_format_idc && (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_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]); int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
lc->tu.cross_pf = (s->pps->cross_component_prediction_enabled_flag && cbf_luma && lc->tu.cross_pf = (s->pps->cross_component_prediction_enabled_flag && cbf_luma &&
...@@ -1033,7 +1035,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, ...@@ -1033,7 +1035,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
s->hevcdsp.transform_add[log2_trafo_size_c-2](dst, coeffs, stride); s->hevcdsp.transform_add[log2_trafo_size_c-2](dst, coeffs, stride);
} }
} }
} else if (blk_idx == 3) { } else if (s->sps->chroma_format_idc && blk_idx == 3) {
int trafo_size_h = 1 << (log2_trafo_size + 1); int trafo_size_h = 1 << (log2_trafo_size + 1);
int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[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++) { for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
...@@ -1057,7 +1059,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, ...@@ -1057,7 +1059,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0,
log2_trafo_size, scan_idx_c, 2); log2_trafo_size, scan_idx_c, 2);
} }
} }
} else if (lc->cu.pred_mode == MODE_INTRA) { } else if (s->sps->chroma_format_idc && lc->cu.pred_mode == MODE_INTRA) {
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) { 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_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]); int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
...@@ -1154,7 +1156,7 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0, ...@@ -1154,7 +1156,7 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0,
inter_split; inter_split;
} }
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) { if (s->sps->chroma_format_idc && (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3)) {
if (trafo_depth == 0 || cbf_cb[0]) { if (trafo_depth == 0 || cbf_cb[0]) {
cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth); cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) { if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
...@@ -1254,6 +1256,7 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) ...@@ -1254,6 +1256,7 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
return ret; return ret;
s->hevcdsp.put_pcm(dst0, stride0, cb_size, cb_size, &gb, s->sps->pcm.bit_depth); s->hevcdsp.put_pcm(dst0, stride0, cb_size, cb_size, &gb, s->sps->pcm.bit_depth);
if (s->sps->chroma_format_idc) {
s->hevcdsp.put_pcm(dst1, stride1, s->hevcdsp.put_pcm(dst1, stride1,
cb_size >> s->sps->hshift[1], cb_size >> s->sps->hshift[1],
cb_size >> s->sps->vshift[1], cb_size >> s->sps->vshift[1],
...@@ -1262,6 +1265,8 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) ...@@ -1262,6 +1265,8 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
cb_size >> s->sps->hshift[2], cb_size >> s->sps->hshift[2],
cb_size >> s->sps->vshift[2], cb_size >> s->sps->vshift[2],
&gb, s->sps->pcm.bit_depth_chroma); &gb, s->sps->pcm.bit_depth_chroma);
}
return 0; return 0;
} }
...@@ -1717,12 +1722,14 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, ...@@ -1717,12 +1722,14 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
s->sh.luma_weight_l0[current_mv.ref_idx[0]], s->sh.luma_weight_l0[current_mv.ref_idx[0]],
s->sh.luma_offset_l0[current_mv.ref_idx[0]]); s->sh.luma_offset_l0[current_mv.ref_idx[0]]);
if (s->sps->chroma_format_idc) {
chroma_mc_uni(s, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1], chroma_mc_uni(s, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1],
0, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 0, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv,
s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0]); s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0]);
chroma_mc_uni(s, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2], chroma_mc_uni(s, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2],
0, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 0, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv,
s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]); s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]);
}
} else if (current_mv.pred_flag == PF_L1) { } else if (current_mv.pred_flag == PF_L1) {
int x0_c = x0 >> s->sps->hshift[1]; int x0_c = x0 >> s->sps->hshift[1];
int y0_c = y0 >> s->sps->vshift[1]; int y0_c = y0 >> s->sps->vshift[1];
...@@ -1734,6 +1741,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, ...@@ -1734,6 +1741,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
s->sh.luma_weight_l1[current_mv.ref_idx[1]], s->sh.luma_weight_l1[current_mv.ref_idx[1]],
s->sh.luma_offset_l1[current_mv.ref_idx[1]]); s->sh.luma_offset_l1[current_mv.ref_idx[1]]);
if (s->sps->chroma_format_idc) {
chroma_mc_uni(s, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1], chroma_mc_uni(s, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1],
1, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 1, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv,
s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]); s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]);
...@@ -1741,6 +1749,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, ...@@ -1741,6 +1749,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
chroma_mc_uni(s, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2], chroma_mc_uni(s, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2],
1, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 1, x0_c, y0_c, nPbW_c, nPbH_c, &current_mv,
s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]); s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]);
}
} else if (current_mv.pred_flag == PF_BI) { } else if (current_mv.pred_flag == PF_BI) {
int x0_c = x0 >> s->sps->hshift[1]; int x0_c = x0 >> s->sps->hshift[1];
int y0_c = y0 >> s->sps->vshift[1]; int y0_c = y0 >> s->sps->vshift[1];
...@@ -1751,12 +1760,14 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, ...@@ -1751,12 +1760,14 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
&current_mv.mv[0], x0, y0, nPbW, nPbH, &current_mv.mv[0], x0, y0, nPbW, nPbH,
ref1->frame, &current_mv.mv[1], &current_mv); ref1->frame, &current_mv.mv[1], &current_mv);
if (s->sps->chroma_format_idc) {
chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame, chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame,
x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 0); x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 0);
chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame, chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame,
x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 1); x0_c, y0_c, nPbW_c, nPbH_c, &current_mv, 1);
} }
}
} }
/** /**
......
...@@ -254,7 +254,7 @@ static void sao_filter_CTB(HEVCContext *s, int x, int y) ...@@ -254,7 +254,7 @@ static void sao_filter_CTB(HEVCContext *s, int x, int y)
} }
} }
for (c_idx = 0; c_idx < 3; c_idx++) { for (c_idx = 0; c_idx < (s->sps->chroma_format_idc ? 3 : 1); c_idx++) {
int x0 = x >> s->sps->hshift[c_idx]; int x0 = x >> s->sps->hshift[c_idx];
int y0 = y >> s->sps->vshift[c_idx]; int y0 = y >> s->sps->vshift[c_idx];
int stride_src = s->frame->linesize[c_idx]; int stride_src = s->frame->linesize[c_idx];
...@@ -447,6 +447,7 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0) ...@@ -447,6 +447,7 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
} }
} }
if (s->sps->chroma_format_idc) {
for (chroma = 1; chroma <= 2; chroma++) { for (chroma = 1; chroma <= 2; chroma++) {
int h = 1 << s->sps->hshift[chroma]; int h = 1 << s->sps->hshift[chroma];
int v = 1 << s->sps->vshift[chroma]; int v = 1 << s->sps->vshift[chroma];
...@@ -513,6 +514,7 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0) ...@@ -513,6 +514,7 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
} }
} }
} }
}
} }
static int boundary_strength(HEVCContext *s, MvField *curr, MvField *neigh, static int boundary_strength(HEVCContext *s, MvField *curr, MvField *neigh,
......
...@@ -755,11 +755,6 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) ...@@ -755,11 +755,6 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
} }
sps->chroma_format_idc = get_ue_golomb_long(gb); sps->chroma_format_idc = get_ue_golomb_long(gb);
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;
}
if (sps->chroma_format_idc == 3) if (sps->chroma_format_idc == 3)
sps->separate_colour_plane_flag = get_bits1(gb); sps->separate_colour_plane_flag = get_bits1(gb);
...@@ -799,7 +794,7 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) ...@@ -799,7 +794,7 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
sps->bit_depth = get_ue_golomb_long(gb) + 8; sps->bit_depth = get_ue_golomb_long(gb) + 8;
bit_depth_chroma = get_ue_golomb_long(gb) + 8; bit_depth_chroma = get_ue_golomb_long(gb) + 8;
if (bit_depth_chroma != sps->bit_depth) { if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) {
av_log(s->avctx, AV_LOG_ERROR, av_log(s->avctx, AV_LOG_ERROR,
"Luma bit depth (%d) is different from chroma bit depth (%d), " "Luma bit depth (%d) is different from chroma bit depth (%d), "
"this is unsupported.\n", "this is unsupported.\n",
...@@ -810,21 +805,25 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) ...@@ -810,21 +805,25 @@ int ff_hevc_decode_nal_sps(HEVCContext *s)
switch (sps->bit_depth) { switch (sps->bit_depth) {
case 8: case 8:
if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P; 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 == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P; if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
break; break;
case 9: case 9:
if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9; 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 == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9; if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;
break; break;
case 10: case 10:
if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10; 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 == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10; if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
break; break;
case 12: case 12:
if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12; 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 == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12; if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment