diff options
author | Mickaƫl Raulet <mraulet@insa-rennes.fr> | 2014-12-22 14:55:54 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-02-02 18:10:57 +0100 |
commit | 7cf6a67ef9c9ac95e57867c753f38104f481f6f1 (patch) | |
tree | 8ddd60834f270bb2a709d6fb68c647deaf3867c7 | |
parent | ecc92ee717eac18540e236ee27e9052cd2917800 (diff) | |
download | ffmpeg-7cf6a67ef9c9ac95e57867c753f38104f481f6f1.tar.gz |
avcodec/hevc: adding support for monochrome sequences in hevc
cherry picked from commit 8e50557707d2ec11ccad657470b2e140f314348e
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/hevc.c | 73 | ||||
-rw-r--r-- | libavcodec/hevc_filter.c | 118 | ||||
-rw-r--r-- | libavcodec/hevc_ps.c | 11 |
3 files changed, 107 insertions, 95 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index f24cd8f119..9459026814 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -553,8 +553,10 @@ static int hls_slice_header(HEVCContext *s) if (s->sps->sao_enabled) { sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb); - sh->slice_sample_adaptive_offset_flag[1] = - sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb); + if (s->sps->chroma_format_idc) { + sh->slice_sample_adaptive_offset_flag[1] = + sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb); + } } else { sh->slice_sample_adaptive_offset_flag[0] = 0; sh->slice_sample_adaptive_offset_flag[1] = 0; @@ -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 : s->pps->log2_sao_offset_scale_chroma; @@ -969,7 +971,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, if (cbf_luma) 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_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]); 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, 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_v = 1 << (log2_trafo_size + s->sps->vshift[1]); 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, 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) { 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]); @@ -1154,7 +1156,7 @@ static int hls_transform_tree(HEVCContext *s, int x0, int y0, 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]) { 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)) { @@ -1254,14 +1256,17 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) return ret; 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); + if (s->sps->chroma_format_idc) { + 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; } @@ -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_offset_l0[current_mv.ref_idx[0]]); - 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, ¤t_mv, - 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], - 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, - s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]); + if (s->sps->chroma_format_idc) { + 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, ¤t_mv, + 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], + 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, + 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) { int x0_c = x0 >> s->sps->hshift[1]; int y0_c = y0 >> s->sps->vshift[1]; @@ -1734,13 +1741,15 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, s->sh.luma_weight_l1[current_mv.ref_idx[1]], s->sh.luma_offset_l1[current_mv.ref_idx[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, ¤t_mv, - s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]); + if (s->sps->chroma_format_idc) { + 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, ¤t_mv, + s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]); - 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, ¤t_mv, - s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]); + 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, ¤t_mv, + 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) { int x0_c = x0 >> s->sps->hshift[1]; int y0_c = y0 >> s->sps->vshift[1]; @@ -1751,11 +1760,13 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, ¤t_mv.mv[0], x0, y0, nPbW, nPbH, ref1->frame, ¤t_mv.mv[1], ¤t_mv); - chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame, - x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 0); + if (s->sps->chroma_format_idc) { + chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame, + x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 0); - chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame, - x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 1); + chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame, + x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 1); + } } } diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index 7a0ec6d4be..6f1104183e 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -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 y0 = y >> s->sps->vshift[c_idx]; int stride_src = s->frame->linesize[c_idx]; @@ -447,68 +447,70 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0) } } - for (chroma = 1; chroma <= 2; chroma++) { - int h = 1 << s->sps->hshift[chroma]; - int v = 1 << s->sps->vshift[chroma]; - - // vertical filtering 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 + y * s->bs_width) >> 2]; - const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * s->bs_width) >> 2]; - - 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 + (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 >> 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 + (4 * v)); - no_q[0] = get_pcm(s, x, y); - 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); - } else - s->hevcdsp.hevc_v_loop_filter_chroma(src, - s->frame->linesize[chroma], - c_tc, no_p, no_q); + if (s->sps->chroma_format_idc) { + for (chroma = 1; chroma <= 2; chroma++) { + int h = 1 << s->sps->hshift[chroma]; + int v = 1 << s->sps->vshift[chroma]; + + // vertical filtering 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 + y * s->bs_width) >> 2]; + const int bs1 = s->vertical_bs[(x + (y + (4 * v)) * s->bs_width) >> 2]; + + 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 + (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 >> 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 + (4 * v)); + no_q[0] = get_pcm(s, x, y); + 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); + } else + s->hevcdsp.hevc_v_loop_filter_chroma(src, + s->frame->linesize[chroma], + c_tc, no_p, no_q); + } } - } if(!y) continue; - // horizontal filtering chroma - tc_offset = x0 ? left_tc_offset : cur_tc_offset; - x_end2 = x_end; - if (x_end != s->sps->width) - x_end2 = x_end - 8 * h; - for (x = x0 ? x0 - 8 * h : 0; x < x_end2; x += (8 * h)) { - const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2]; - const int 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 + (4 * h), y - 1) + get_qPy(s, x + (4 * h), y) + 1) >> 1 : 0; - - 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 >> 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 + (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); - } else - s->hevcdsp.hevc_h_loop_filter_chroma(src, - s->frame->linesize[chroma], - c_tc, no_p, no_q); + // horizontal filtering chroma + tc_offset = x0 ? left_tc_offset : cur_tc_offset; + x_end2 = x_end; + if (x_end != s->sps->width) + x_end2 = x_end - 8 * h; + for (x = x0 ? x0 - 8 * h : 0; x < x_end2; x += (8 * h)) { + const int bs0 = s->horizontal_bs[( x + y * s->bs_width) >> 2]; + const int 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 + (4 * h), y - 1) + get_qPy(s, x + (4 * h), y) + 1) >> 1 : 0; + + 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 >> 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 + (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); + } else + s->hevcdsp.hevc_h_loop_filter_chroma(src, + s->frame->linesize[chroma], + c_tc, no_p, no_q); + } } } } diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 464176beb0..08fe819d4d 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -755,11 +755,6 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) } 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) sps->separate_colour_plane_flag = get_bits1(gb); @@ -799,7 +794,7 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) sps->bit_depth = 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, "Luma bit depth (%d) is different from chroma bit depth (%d), " "this is unsupported.\n", @@ -810,21 +805,25 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) switch (sps->bit_depth) { 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 == 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 == 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 == 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 == 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 == 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 == 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 == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12; if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12; |