* H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
- * @file libavcodec/h264_cavlc.c
+ * @file
* H.264 / AVC / MPEG4 part10 cavlc bitstream decoding.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
MpegEncContext * const s = &h->s;
static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
int level[16];
- int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before;
+ int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
//FIXME put trailing_onex into the context
- if(n == CHROMA_DC_BLOCK_INDEX){
+ if(max_coeff <= 8){
coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
total_coeff= coeff_token>>2;
}else{
- if(n == LUMA_DC_BLOCK_INDEX){
- total_coeff= pred_non_zero_count(h, 0);
+ if(n >= LUMA_DC_BLOCK_INDEX){
+ total_coeff= pred_non_zero_count(h, (n - LUMA_DC_BLOCK_INDEX)*16);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2;
}else{
total_coeff= pred_non_zero_count(h, n);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2;
- h->non_zero_count_cache[ scan8[n] ]= total_coeff;
}
}
+ h->non_zero_count_cache[ scan8[n] ]= total_coeff;
//FIXME set last_non_zero?
if(trailing_ones<total_coeff) {
int mask, prefix;
- int suffix_length = total_coeff > 10 && trailing_ones < 3;
+ int suffix_length = total_coeff > 10 & trailing_ones < 3;
int bitsi= show_bits(gb, LEVEL_TAB_BITS);
int level_code= cavlc_level_tab[suffix_length][bitsi][0];
level_code= prefix + get_bits(gb, 4); //part
}else{
level_code= 30 + get_bits(gb, prefix-3); //part
- if(prefix>=16)
+ if(prefix>=16){
+ if(prefix > 25+3){
+ av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+ return -1;
+ }
level_code += (1<<(prefix-3))-4096;
+ }
}
if(trailing_ones < 3) level_code += 2;
mask= -(level_code&1);
level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask;
}else{
- if(trailing_ones < 3) level_code += (level_code>>31)|1;
+ level_code += ((level_code>>31)|1) & -(trailing_ones < 3);
- suffix_length = 1;
- if(level_code + 3U > 6U)
- suffix_length++;
+ suffix_length = 1 + (level_code + 3U > 6U);
level[trailing_ones]= level_code;
}
level_code= (((2+level_code)>>1) ^ mask) - mask;
}
level[i]= level_code;
-
- if(suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length])
- suffix_length++;
+ suffix_length+= suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length];
}
}
if(total_coeff == max_coeff)
zeros_left=0;
else{
- if(n == CHROMA_DC_BLOCK_INDEX)
- zeros_left= get_vlc2(gb, chroma_dc_total_zeros_vlc[ total_coeff-1 ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
+ /* FIXME: we don't actually support 4:2:2 yet. */
+ if(max_coeff <= 8)
+ zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
else
- zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff-1 ].table, TOTAL_ZEROS_VLC_BITS, 1);
+ zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
}
- coeff_num = zeros_left + total_coeff - 1;
- j = scantable[coeff_num];
- if(n > 24){
- block[j] = level[0];
- for(i=1;i<total_coeff;i++) {
- if(zeros_left <= 0)
- run_before = 0;
- else if(zeros_left < 7){
- run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1);
- }else{
- run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
- }
- zeros_left -= run_before;
- coeff_num -= 1 + run_before;
- j= scantable[ coeff_num ];
-
- block[j]= level[i];
- }
- }else{
- block[j] = (level[0] * qmul[j] + 32)>>6;
- for(i=1;i<total_coeff;i++) {
- if(zeros_left <= 0)
- run_before = 0;
- else if(zeros_left < 7){
- run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1);
- }else{
- run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
- }
- zeros_left -= run_before;
- coeff_num -= 1 + run_before;
- j= scantable[ coeff_num ];
+#define STORE_BLOCK(type) \
+ scantable += zeros_left + total_coeff - 1; \
+ if(n >= LUMA_DC_BLOCK_INDEX){ \
+ ((type*)block)[*scantable] = level[0]; \
+ for(i=1;i<total_coeff && zeros_left > 0;i++) { \
+ if(zeros_left < 7) \
+ run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
+ else \
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
+ zeros_left -= run_before; \
+ scantable -= 1 + run_before; \
+ ((type*)block)[*scantable]= level[i]; \
+ } \
+ for(;i<total_coeff;i++) { \
+ scantable--; \
+ ((type*)block)[*scantable]= level[i]; \
+ } \
+ }else{ \
+ ((type*)block)[*scantable] = ((int)(level[0] * qmul[*scantable] + 32))>>6; \
+ for(i=1;i<total_coeff && zeros_left > 0;i++) { \
+ if(zeros_left < 7) \
+ run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
+ else \
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
+ zeros_left -= run_before; \
+ scantable -= 1 + run_before; \
+ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
+ } \
+ for(;i<total_coeff;i++) { \
+ scantable--; \
+ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
+ } \
+ }
- block[j]= (level[i] * qmul[j] + 32)>>6;
- }
+ if (h->pixel_shift) {
+ STORE_BLOCK(int32_t)
+ } else {
+ STORE_BLOCK(int16_t)
}
if(zeros_left<0){
return 0;
}
+static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
+ int i4x4, i8x8;
+ MpegEncContext * const s = &h->s;
+ int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+ if(IS_INTRA16x16(mb_type)){
+ AV_ZERO128(h->mb_luma_dc[p]+0);
+ AV_ZERO128(h->mb_luma_dc[p]+8);
+ AV_ZERO128(h->mb_luma_dc[p]+16);
+ AV_ZERO128(h->mb_luma_dc[p]+24);
+ if( decode_residual(h, h->intra_gb_ptr, h->mb_luma_dc[p], LUMA_DC_BLOCK_INDEX+p, scan, NULL, 16) < 0){
+ return -1; //FIXME continue if partitioned and other return -1 too
+ }
+
+ assert((cbp&15) == 0 || (cbp&15) == 15);
+
+ if(cbp&15){
+ for(i8x8=0; i8x8<4; i8x8++){
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, h->intra_gb_ptr, h->mb + (16*index << pixel_shift),
+ index, scan + 1, h->dequant4_coeff[p][qscale], 15) < 0 ){
+ return -1;
+ }
+ }
+ }
+ return 0xf;
+ }else{
+ fill_rectangle(&h->non_zero_count_cache[scan8[p*16]], 4, 4, 8, 0, 1);
+ return 0;
+ }
+ }else{
+ int cqm = (IS_INTRA( mb_type ) ? 0:3)+p;
+ /* For CAVLC 4:4:4, we need to keep track of the luma 8x8 CBP for deblocking nnz purposes. */
+ int new_cbp = 0;
+ for(i8x8=0; i8x8<4; i8x8++){
+ if(cbp & (1<<i8x8)){
+ if(IS_8x8DCT(mb_type)){
+ DCTELEM *buf = &h->mb[64*i8x8+256*p << pixel_shift];
+ uint8_t *nnz;
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, gb, buf, index, scan8x8+16*i4x4,
+ h->dequant8_coeff[cqm][qscale], 16) < 0 )
+ return -1;
+ }
+ nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ];
+ nnz[0] += nnz[1] + nnz[8] + nnz[9];
+ new_cbp |= !!nnz[0] << i8x8;
+ }else{
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index,
+ scan, h->dequant4_coeff[cqm][qscale], 16) < 0 ){
+ return -1;
+ }
+ new_cbp |= h->non_zero_count_cache[ scan8[index] ] << i8x8;
+ }
+ }
+ }else{
+ uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ];
+ nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
+ }
+ }
+ return new_cbp;
+ }
+}
+
int ff_h264_decode_mb_cavlc(H264Context *h){
MpegEncContext * const s = &h->s;
int mb_xy;
int partition_count;
unsigned int mb_type, cbp;
int dct8x8_allowed= h->pps.transform_8x8_mode;
+ int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
+ const int pixel_shift = h->pixel_shift;
mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
cbp = 0; /* avoid warning. FIXME: find a solution without slowing
down the code */
- if(h->slice_type_nos != FF_I_TYPE){
+ if(h->slice_type_nos != AV_PICTURE_TYPE_I){
if(s->mb_skip_run==-1)
s->mb_skip_run= get_ue_golomb(&s->gb);
if(FRAME_MBAFF && (s->mb_y&1) == 0){
if(s->mb_skip_run==0)
h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
- else
- predict_field_decoding_flag(h);
}
decode_mb_skip(h);
return 0;
h->prev_mb_skipped= 0;
mb_type= get_ue_golomb(&s->gb);
- if(h->slice_type_nos == FF_B_TYPE){
+ if(h->slice_type_nos == AV_PICTURE_TYPE_B){
if(mb_type < 23){
partition_count= b_mb_type_info[mb_type].partition_count;
mb_type= b_mb_type_info[mb_type].type;
mb_type -= 23;
goto decode_intra_mb;
}
- }else if(h->slice_type_nos == FF_P_TYPE){
+ }else if(h->slice_type_nos == AV_PICTURE_TYPE_P){
if(mb_type < 5){
partition_count= p_mb_type_info[mb_type].partition_count;
mb_type= p_mb_type_info[mb_type].type;
goto decode_intra_mb;
}
}else{
- assert(h->slice_type_nos == FF_I_TYPE);
- if(h->slice_type == FF_SI_TYPE && mb_type)
+ assert(h->slice_type_nos == AV_PICTURE_TYPE_I);
+ if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)
mb_type--;
decode_intra_mb:
if(mb_type > 25){
- av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h->slice_type), s->mb_x, s->mb_y);
+ av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), s->mb_x, s->mb_y);
return -1;
}
partition_count=0;
if(IS_INTRA_PCM(mb_type)){
unsigned int x;
+ static const uint16_t mb_sizes[4] = {256,384,512,768};
+ const int mb_size = mb_sizes[h->sps.chroma_format_idc]*h->sps.bit_depth_luma >> 3;
// We assume these blocks are very rare so we do not optimize it.
align_get_bits(&s->gb);
// The pixels are stored in the same order as levels in h->mb array.
- for(x=0; x < (CHROMA ? 384 : 256); x++){
+ for(x=0; x < mb_size; x++){
((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
}
// In deblocking, the quantizer is 0
s->current_picture.qscale_table[mb_xy]= 0;
// All coeffs are present
- memset(h->non_zero_count[mb_xy], 16, 32);
+ memset(h->non_zero_count[mb_xy], 16, 48);
s->current_picture.mb_type[mb_xy]= mb_type;
return 0;
h->ref_count[1] <<= 1;
}
+ fill_decode_neighbors(h, mb_type);
fill_decode_caches(h, mb_type);
//mb_pred
if(h->intra16x16_pred_mode < 0)
return -1;
}
- if(CHROMA){
+ if(decode_chroma){
pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb));
if(pred_mode < 0)
return -1;
h->chroma_pred_mode= pred_mode;
+ } else {
+ h->chroma_pred_mode = DC_128_PRED8x8;
}
}else if(partition_count==4){
int i, j, sub_partition_count[4], list, ref[2][4];
- if(h->slice_type_nos == FF_B_TYPE){
+ if(h->slice_type_nos == AV_PICTURE_TYPE_B){
for(i=0; i<4; i++){
h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
if(h->sub_mb_type[i] >=13){
h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
}
}else{
- assert(h->slice_type_nos == FF_P_TYPE); //FIXME SP correct ?
+ assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
for(i=0; i<4; i++){
h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
if(h->sub_mb_type[i] >=4){
return -1;
}
}
- }else
- val= LIST_NOT_USED&0xFF;
fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
+ }
}
for(list=0; list<h->list_count; list++){
- unsigned int val;
if(IS_DIR(mb_type, 0, list)){
pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
mx += get_se_golomb(&s->gb);
my += get_se_golomb(&s->gb);
tprintf(s->avctx, "final mv:%d %d\n", mx, my);
- val= pack16to32(mx,my);
- }else
- val=0;
- fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, val, 4);
+ fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
+ }
}
}
else if(IS_16X8(mb_type)){
if(!IS_INTRA16x16(mb_type)){
cbp= get_ue_golomb(&s->gb);
- if(cbp > 47){
- av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
- return -1;
- }
- if(CHROMA){
+ if(decode_chroma){
+ if(cbp > 47){
+ av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+ return -1;
+ }
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
else cbp= golomb_to_inter_cbp [cbp];
}else{
+ if(cbp > 15){
+ av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+ return -1;
+ }
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
else cbp= golomb_to_inter_cbp_gray[cbp];
}
}
if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
- if(get_bits1(&s->gb)){
- mb_type |= MB_TYPE_8x8DCT;
- }
+ mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb);
}
h->cbp=
h->cbp_table[mb_xy]= cbp;
s->current_picture.mb_type[mb_xy]= mb_type;
if(cbp || IS_INTRA16x16(mb_type)){
- int i8x8, i4x4, chroma_idx;
+ int i4x4, chroma_idx;
int dquant;
+ int ret;
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;
- const uint8_t *scan, *scan8x8, *dc_scan;
-
-// fill_non_zero_count_cache(h);
+ const uint8_t *scan, *scan8x8;
+ const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
if(IS_INTERLACED(mb_type)){
scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
scan= s->qscale ? h->field_scan : h->field_scan_q0;
- dc_scan= luma_dc_field_scan;
}else{
scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
- dc_scan= luma_dc_zigzag_scan;
}
dquant= get_se_golomb(&s->gb);
- if( dquant > 25 || dquant < -26 ){
- av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
- return -1;
- }
-
s->qscale += dquant;
- if(((unsigned)s->qscale) > 51){
- if(s->qscale<0) s->qscale+= 52;
- else s->qscale-= 52;
+
+ if(((unsigned)s->qscale) > max_qp){
+ if(s->qscale<0) s->qscale+= max_qp+1;
+ else s->qscale-= max_qp+1;
+ if(((unsigned)s->qscale) > max_qp){
+ av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
+ return -1;
+ }
}
h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);
h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);
- if(IS_INTRA16x16(mb_type)){
- if( decode_residual(h, h->intra_gb_ptr, h->mb, LUMA_DC_BLOCK_INDEX, dc_scan, h->dequant4_coeff[0][s->qscale], 16) < 0){
- return -1; //FIXME continue if partitioned and other return -1 too
- }
- assert((cbp&15) == 0 || (cbp&15) == 15);
+ if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
+ return -1;
+ }
+ h->cbp_table[mb_xy] |= ret << 12;
+ if(CHROMA444){
+ if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){
+ return -1;
+ }
+ if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
+ return -1;
+ }
+ } else {
+ if(cbp&0x30){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++)
+ if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
+ return -1;
+ }
+ }
- if(cbp&15){
- for(i8x8=0; i8x8<4; i8x8++){
+ if(cbp&0x20){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++){
+ const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
for(i4x4=0; i4x4<4; i4x4++){
- const int index= i4x4 + 4*i8x8;
- if( decode_residual(h, h->intra_gb_ptr, h->mb + 16*index, index, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ){
+ const int index= 16 + 16*chroma_idx + i4x4;
+ if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){
return -1;
}
}
}
}else{
- fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
}
- }else{
- for(i8x8=0; i8x8<4; i8x8++){
- if(cbp & (1<<i8x8)){
- if(IS_8x8DCT(mb_type)){
- DCTELEM *buf = &h->mb[64*i8x8];
- uint8_t *nnz;
- for(i4x4=0; i4x4<4; i4x4++){
- if( decode_residual(h, gb, buf, i4x4+4*i8x8, scan8x8+16*i4x4,
- h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 16) <0 )
- return -1;
- }
- nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];
- nnz[0] += nnz[1] + nnz[8] + nnz[9];
- }else{
- for(i4x4=0; i4x4<4; i4x4++){
- const int index= i4x4 + 4*i8x8;
-
- if( decode_residual(h, gb, h->mb + 16*index, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) <0 ){
- return -1;
- }
- }
- }
- }else{
- uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];
- nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
- }
- }
- }
-
- if(cbp&0x30){
- for(chroma_idx=0; chroma_idx<2; chroma_idx++)
- if( decode_residual(h, gb, h->mb + 256 + 16*4*chroma_idx, CHROMA_DC_BLOCK_INDEX, chroma_dc_scan, NULL, 4) < 0){
- return -1;
- }
- }
-
- if(cbp&0x20){
- for(chroma_idx=0; chroma_idx<2; chroma_idx++){
- const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
- for(i4x4=0; i4x4<4; i4x4++){
- const int index= 16 + 4*chroma_idx + i4x4;
- if( decode_residual(h, gb, h->mb + 16*index, index, scan + 1, qmul, 15) < 0){
- return -1;
- }
- }
- }
- }else{
- uint8_t * const nnz= &h->non_zero_count_cache[0];
- nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =
- nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;
}
}else{
- uint8_t * const nnz= &h->non_zero_count_cache[0];
- fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1);
- nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =
- nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;
+ fill_rectangle(&h->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
}
s->current_picture.qscale_table[mb_xy]= s->qscale;
write_back_non_zero_count(h);