package com.twilight.h264.decoder;
import com.twilight.h264.util.*;;
public class CAVLCContext {
/*
* 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.
*
* FFmpeg 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,
* 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
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* H.264 / AVC / MPEG4 part10 cavlc bitstream decoding.
* @author Michael Niedermayer <michaelni@gmx.at>
*/
/*
#define CABAC 0
#include "internal.h"
#include "avcodec.h"
#include "mpegvideo.h"
#include "h264.h"
#include "h264data.h" // FIXME FIXME FIXME
#include "h264_mvpred.h"
#include "golomb.h"
//#undef NDEBUG
#include <assert.h>
*/
//static const uint8_t golomb_to_inter_cbp_gray[16]= {
public static final int[] golomb_to_inter_cbp_gray = {
0, 1, 2, 4, 8, 3, 5,10,12,15, 7,11,13,14, 6, 9,
};
//static const uint8_t golomb_to_intra4x4_cbp_gray[16]={
public static final int[] golomb_to_intra4x4_cbp_gray={
15, 0, 7,11,13,14, 3, 5,10,12, 1, 2, 4, 8, 6, 9,
};
//static const uint8_t chroma_dc_coeff_token_len[4*5]={
public static final int[] chroma_dc_coeff_token_len={
2, 0, 0, 0,
6, 1, 0, 0,
6, 6, 3, 0,
6, 7, 7, 6,
6, 8, 8, 7,
};
public static final int[] chroma_dc_coeff_token_bits={
// static const uint8_t chroma_dc_coeff_token_bits[4*5]={
1, 0, 0, 0,
7, 1, 0, 0,
4, 6, 1, 0,
3, 3, 2, 5,
2, 3, 2, 0,
};
public static final int[][] coeff_token_len={
// static const uint8_t coeff_token_len[4][4*17]={
{
1, 0, 0, 0,
6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6,
11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10,
14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14,
16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16,
},
{
2, 0, 0, 0,
6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4,
8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7,
12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12,
13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14,
},
{
4, 0, 0, 0,
6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4,
7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5,
8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8,
10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10,
},
{
6, 0, 0, 0,
6, 6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
}
};
public static final int[][] coeff_token_bits={
// static const uint8_t coeff_token_bits[4][4*17]={
{
1, 0, 0, 0,
5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3,
7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4,
15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8,
15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8,
},
{
3, 0, 0, 0,
11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4,
4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4,
15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12,
11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4,
},
{
15, 0, 0, 0,
15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11,
11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13,
11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8,
13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2,
},
{
3, 0, 0, 0,
0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15,
16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31,
32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47,
48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63,
}
};
public static final int[][] total_zeros_len= {
// static const uint8_t total_zeros_len[16][16]= {
{1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
{3,3,3,3,3,4,4,4,4,5,5,6,6,6,6,0},
{4,3,3,3,4,4,3,3,4,5,5,6,5,6,0,0},
{5,3,4,4,3,3,3,4,3,4,5,5,5,0,0,0},
{4,4,4,3,3,3,3,3,4,5,4,5,0,0,0,0},
{6,5,3,3,3,3,3,3,4,3,6,0,0,0,0,0},
{6,5,3,3,3,2,3,4,3,6,0,0,0,0,0,0},
{6,4,5,3,2,2,3,3,6,0,0,0,0,0,0,0},
{6,6,4,2,2,3,2,5,0,0,0,0,0,0,0,0},
{5,5,3,2,2,2,4,0,0,0,0,0,0,0,0,0},
{4,4,3,3,1,3,0,0,0,0,0,0,0,0,0,0},
{4,4,2,1,3,0,0,0,0,0,0,0,0,0,0,0},
{3,3,1,2,0,0,0,0,0,0,0,0,0,0,0,0},
{2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
public static final int[][] total_zeros_bits= {
// static const uint8_t total_zeros_bits[16][16]= {
{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
{7,6,5,4,3,5,4,3,2,3,2,3,2,1,0,0},
{5,7,6,5,4,3,4,3,2,3,2,1,1,0,0,0},
{3,7,5,4,6,5,4,3,3,2,2,1,0,0,0,0},
{5,4,3,7,6,5,4,3,2,1,1,0,0,0,0,0},
{1,1,7,6,5,4,3,2,1,1,0,0,0,0,0,0},
{1,1,5,4,3,3,2,1,1,0,0,0,0,0,0,0},
{1,1,1,3,3,2,2,1,0,0,0,0,0,0,0,0},
{1,0,1,3,2,1,1,1,0,0,0,0,0,0,0,0},
{1,0,1,3,2,1,1,0,0,0,0,0,0,0,0,0},
{0,1,1,2,1,3,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
public static final int[][] chroma_dc_total_zeros_len= {
// static uint8_t chroma_dc_total_zeros_len[3][4]= {
{ 1, 2, 3, 3,},
{ 1, 2, 2, 0,},
{ 1, 1, 0, 0,},
};
public static final int[][] chroma_dc_total_zeros_bits= {
// static uint8_t chroma_dc_total_zeros_bits[3][4]= {
{ 1, 1, 1, 0,},
{ 1, 1, 0, 0,},
{ 1, 0, 0, 0,},
};
public static final int[][] run_len={
// static uint8_t run_len[7][16]={
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0},
{2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0},
{2,2,2,3,3,0,0,0,0,0,0,0,0,0,0,0},
{2,2,3,3,3,3,0,0,0,0,0,0,0,0,0,0},
{2,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0},
{3,3,3,3,3,3,3,4,5,6,7,8,9,10,11,0},
};
public static final int[][] run_bits={
// static uint8_t run_bits[7][16]={
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{3,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{3,2,3,2,1,0,0,0,0,0,0,0,0,0,0,0},
{3,0,1,3,2,5,4,0,0,0,0,0,0,0,0,0},
{7,6,5,4,3,2,1,1,1,1,1,1,1,1,1,0},
};
//#define VLC_TYPE int16_t
public static VLC[] coeff_token_vlc = new VLC[4];
//public static short[][] coeff_token_vlc_tables = new short[520+332+280+256][2];
public static final int[] coeff_token_vlc_tables_size={520,332,280,256};
public static VLC chroma_dc_coeff_token_vlc = new VLC();
//public static short[][] chroma_dc_coeff_token_vlc_table = new short[256][2];
public static final int chroma_dc_coeff_token_vlc_table_size = 256;
public static VLC[] total_zeros_vlc = new VLC[15];
//public static short[][][] total_zeros_vlc_tables = new short[15][512][2];
public static final int total_zeros_vlc_tables_size = 512;
public static VLC[] chroma_dc_total_zeros_vlc = new VLC[3];
//public static short[][][] chroma_dc_total_zeros_vlc_tables = new short[3][8][2];
public static final int chroma_dc_total_zeros_vlc_tables_size = 8;
public static VLC[] run_vlc = new VLC[6];
//public static short[][][] run_vlc_tables = new short[6][8][2];
public static final int run_vlc_tables_size = 8;
public static VLC run7_vlc = new VLC();
//public static short[][] run7_vlc_table = new short[96][2];
public static final int run7_vlc_table_size = 96;
public static final int LEVEL_TAB_BITS = 8;
//static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
public static int[][][] cavlc_level_tab = new int[7][1<<LEVEL_TAB_BITS][2];
public static final int[/*256*/] ff_log2_tab = {
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
public static /*inline av_const*/ int av_log2(long v)
{
int n = 0;
if ((v & 0xffff0000L)!=0) {
v >>= 16;
n += 16;
}
if ((v & 0xff00L)!=0) {
v >>= 8;
n += 8;
}
n += ff_log2_tab[(int)v];
return n;
}
/**
* gets the predicted number of non-zero coefficients.
* @param n block index
*/
public static /*inline*/ int pred_non_zero_count(H264Context h, int n){
int index8= H264Context.scan8[n];
int left= h.non_zero_count_cache[index8 - 1];
int top = h.non_zero_count_cache[index8 - 8];
int i= left + top;
if(i<64) i= (i+1)>>1;
//tprintf(h.s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
return i&31;
}
public static void init_cavlc_level_tab(){
int suffix_length, mask;
int i;
for(suffix_length=0; suffix_length<7; suffix_length++){
for(i=0; i<(1<<LEVEL_TAB_BITS); i++){
int prefix= LEVEL_TAB_BITS - av_log2(2*i);
int level_code= (prefix<<suffix_length) + (i>>(LEVEL_TAB_BITS-prefix-1-suffix_length)) - (1<<suffix_length);
mask= -(level_code&1);
level_code= (((2+level_code)>>1) ^ mask) - mask;
if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){
cavlc_level_tab[suffix_length][i][0]= level_code;
cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length;
}else if(prefix + 1 <= LEVEL_TAB_BITS){
cavlc_level_tab[suffix_length][i][0]= prefix+100;
cavlc_level_tab[suffix_length][i][1]= prefix + 1;
}else{
cavlc_level_tab[suffix_length][i][0]= LEVEL_TAB_BITS+100;
cavlc_level_tab[suffix_length][i][1]= LEVEL_TAB_BITS;
}
}
}
}
public static int calvc_inited = 0;
public void ff_h264_decode_init_vlc(){
if (0==calvc_inited) {
int i;
int offset;
calvc_inited = 1;
//chroma_dc_coeff_token_vlc.table_base = chroma_dc_coeff_token_vlc_table;
chroma_dc_coeff_token_vlc.table_base = CAVLCTables.expandTable(CAVLCTables.chroma_dc_coeff_token_vlc_table);
chroma_dc_coeff_token_vlc.table_offset = 0;
chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size;
/*
GetBitContext.init_vlc(chroma_dc_coeff_token_vlc, H264Context.CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5,
chroma_dc_coeff_token_len,0, 1, 1,
chroma_dc_coeff_token_bits,0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
offset = 0;
for(i=0; i<4; i++){
coeff_token_vlc[i] = new VLC();
// coeff_token_vlc[i].table_base = coeff_token_vlc_tables;
// coeff_token_vlc[i].table_offset = offset;
coeff_token_vlc[i].table_base = CAVLCTables.expandTable(CAVLCTables.coeff_token_vlc_table[i]);
coeff_token_vlc[i].table_offset = 0;
coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];
/*
GetBitContext.init_vlc(coeff_token_vlc[i], H264Context.COEFF_TOKEN_VLC_BITS, 4*17,
coeff_token_len [i],0, 1, 1,
coeff_token_bits[i],0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
offset += coeff_token_vlc_tables_size[i];
}
/*
* This is a one time safety check to make sure that
* the packed static coeff_token_vlc table sizes
* were initialized correctly.
*/
////assert(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
for(i=0; i<3; i++){
chroma_dc_total_zeros_vlc[i] = new VLC();
// chroma_dc_total_zeros_vlc[i].table_base = chroma_dc_total_zeros_vlc_tables[i];
chroma_dc_total_zeros_vlc[i].table_base = CAVLCTables.expandTable(CAVLCTables.chroma_dc_total_zeros_vlc_table[i]);
chroma_dc_total_zeros_vlc[i].table_offset = 0;
chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size;
/*
GetBitContext.init_vlc(chroma_dc_total_zeros_vlc[i],
H264Context.CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4,
chroma_dc_total_zeros_len [i],0, 1, 1,
chroma_dc_total_zeros_bits[i],0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
}
for(i=0; i<15; i++){
total_zeros_vlc[i] = new VLC();
// total_zeros_vlc[i].table_base = total_zeros_vlc_tables[i];
total_zeros_vlc[i].table_base = CAVLCTables.expandTable(CAVLCTables.total_zeros_vlc[i]);
total_zeros_vlc[i].table_offset = 0;
total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;
/*
GetBitContext.init_vlc(total_zeros_vlc[i],
H264Context.TOTAL_ZEROS_VLC_BITS, 16,
total_zeros_len [i],0, 1, 1,
total_zeros_bits[i],0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
}
for(i=0; i<6; i++){
run_vlc[i] = new VLC();
// run_vlc[i].table_base = run_vlc_tables[i];
run_vlc[i].table_base = CAVLCTables.expandTable(CAVLCTables.run_vlc_table[i]);
run_vlc[i].table_offset = 0;
run_vlc[i].table_allocated = run_vlc_tables_size;
/*
GetBitContext.init_vlc(run_vlc[i],
H264Context.RUN_VLC_BITS, 7,
run_len [i],0, 1, 1,
run_bits[i],0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
}
// run7_vlc.table_base = run7_vlc_table;
run7_vlc.table_base = CAVLCTables.expandTable(CAVLCTables.run7_vlc_table);
run7_vlc.table_offset = 0;
run7_vlc.table_allocated = run7_vlc_table_size;
/*
GetBitContext.init_vlc(run7_vlc, H264Context.RUN7_VLC_BITS, 16,
run_len [6],0, 1, 1,
run_bits[6],0, 1, 1,
GetBitContext.INIT_VLC_USE_NEW_STATIC);
*/
init_cavlc_level_tab();
}
}
/**
*
*/
public static /*inline*/ int get_level_prefix(GetBitContext gb){
long buf;
int log;
//OPEN_READER(re, gb);
int re_index= gb.index;
long re_cache= 0;
//UPDATE_CACHE(re, gb);
int pos = gb.buffer_offset + (re_index>>3);
//re_cache = ((gb.buffer[pos+3]<<24)|(gb.buffer[pos+2]<<16)|(gb.buffer[pos+1]<<8)|(gb.buffer[pos])) >> (re_index&0x07);
re_cache = gb.buffer[pos+0];
re_cache = (re_cache << 8) | gb.buffer[pos+1];
re_cache = (re_cache << 8) | gb.buffer[pos+2];
re_cache = (re_cache << 8) | gb.buffer[pos+3];
re_cache = (re_cache << (re_index & 0x07));
re_cache = re_cache & 0xffffffffl; // Prevent 32-Bit over flow.
//buf=GET_CACHE(re, gb);
buf = (re_cache);
log= 32 - av_log2(buf);
/*
#ifdef TRACE
print_bin(buf>>(32-log), log);
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__);
#endif
*/
//LAST_SKIP_BITS(re, gb, log);
re_index += (log);
//System.out.println("get_level_prefix(,"+log+"): "+ (log-1));
//CLOSE_READER(re, gb);
gb.index= re_index;
return log-1;
}
/**
* decodes a residual block.
* @param n block index
* @param scantable scantable
* @param max_coeff number of coefficients in the block
* @return <0 if an error occurred
*/
public static int decode_residual(H264Context h, GetBitContext gb, short[] block_base, int block_offset
, int n, int[] scantable_base, int scantable_offset, long[] qmul_base, int qmul_offset, int max_coeff){
// , int n, uint8_t *scantable, uint32_t *qmul, int max_coeff){
//MpegEncContext s = h.s;
final int[/*17*/] coeff_token_table_index= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
int[] level = new int[16];
int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
//FIXME put trailing_onex into the context
if(n >= H264Context.CHROMA_DC_BLOCK_INDEX){
coeff_token= gb.get_vlc2(
chroma_dc_coeff_token_vlc.table_base, chroma_dc_coeff_token_vlc.table_offset,
H264Context.CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1, "coeff_token_CROMA_DC");
total_coeff= coeff_token>>2;
//System.out.println("get_vlc2(CHROMA_DC_COEFF_TOKEN) => total_coeff = " + total_coeff );
}else{
if(n == H264Context.LUMA_DC_BLOCK_INDEX){
total_coeff= pred_non_zero_count(h, 0);
//System.out.println("Prediected Non-Zero count = "+total_coeff);
coeff_token= gb.get_vlc2(
coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table_base,
coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table_offset,
H264Context.COEFF_TOKEN_VLC_BITS, 2, "coeff_token_LUMA_DC");
total_coeff= coeff_token>>2;
//System.out.println("get_vlc2(LUMA_DC_COEFF_TOKEN) => total_coeff = " + total_coeff );
}else{
total_coeff= pred_non_zero_count(h, n);
// DebugTool.printDebugString("predicted non_zero_count("+n+") = "+total_coeff+"\n");
coeff_token= gb.get_vlc2(
coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table_base,
coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table_offset,
H264Context.COEFF_TOKEN_VLC_BITS, 2, "coeff_token_LUMA(2)_DC");
total_coeff= coeff_token>>2;
// DebugTool.printDebugString("predicted non_zero_count-2 = "+total_coeff+"\n");
}
}
h.non_zero_count_cache[ H264Context.scan8[n] ]= total_coeff;
//FIXME set last_non_zero?
if(total_coeff==0)
return 0;
if(total_coeff > /*(unsigned)*/max_coeff) {
// av_log(h.s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s.mb_x, s.mb_y, total_coeff);
// DebugTool.printDebugString(" -------- Error type 1.0\n");
return -1;
}
trailing_ones= coeff_token&3;
// tprintf(h.s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
//assert(total_coeff<=16);
// DebugTool.printDebugString(" - trailing_ones = "+trailing_ones+"\n");
i = (int)gb.show_bits(3);
gb.skip_bits(trailing_ones);
level[0] = 1-((i&4)>>1);
level[1] = 1-((i&2) );
level[2] = 1-((i&1)<<1);
// DebugTool.printDebugString(" - i = "+i+"\n");
if(trailing_ones<total_coeff) {
int mask, prefix;
int suffix_length = ((total_coeff > 10)?1:0) & ((trailing_ones < 3)?1:0);
int bitsi= (int)gb.show_bits(LEVEL_TAB_BITS);
int level_code= cavlc_level_tab[suffix_length][bitsi][0];
// DebugTool.printDebugString(" - bitsi = "+bitsi+", level_code = "+level_code+", skip_bit = "+cavlc_level_tab[suffix_length][bitsi][1]+"\n");
gb.skip_bits(cavlc_level_tab[suffix_length][bitsi][1]);
if(level_code >= 100){
prefix= level_code - 100;
if(prefix == LEVEL_TAB_BITS)
prefix += get_level_prefix(gb);
// DebugTool.printDebugString(" - prefix = "+prefix+"\n");
//first coefficient has suffix_length equal to 0 or 1
if(prefix<14){ //FIXME try to build a large unified VLC table for all this
if(suffix_length!=0)
level_code= (int)((prefix<<1) + gb.get_bits1("level_code")); //part
else
level_code= prefix; //part
}else if(prefix==14){
if(suffix_length!=0)
level_code= (int)((prefix<<1) + gb.get_bits1("level_code")); //part
else
level_code= (int)(prefix + gb.get_bits(4,"level_code")); //part
}else{
// Nok: Prevent bug?? in ffmpeg that the decoder may overflow?
level_code= 30 + (int)(gb.get_bits(prefix-3,"level_code")); //part
if(prefix>=16){
if(prefix > 25+3){
// DebugTool.printDebugString(" -------- Error type 1.1\n");
//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;
// DebugTool.printDebugString(" - level_code(1) = "+level_code+"\n");
suffix_length = 2;
mask= -(level_code&1);
level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask;
}else{
level_code += ((level_code>>31)|1) & -((trailing_ones < 3)?1:0);
// DebugTool.printDebugString(" - level_code(2) = "+level_code+"\n");
// Fix: for difference between JAVA and C, we need to convert signed to unsigned when we compare
// signed and unsigned number because, in C, such comparing will be done in common part.
// In which, common part in C in unsigned, while java is signed. -= Nok =-
suffix_length = 1 + (( (0xffffffffL & (level_code + 3)) > 6)?1:0);
level[trailing_ones]= level_code;
}
// DebugTool.printDebugString(" - suffix_length(1) = "+suffix_length+"\n");
//remaining coefficients have suffix_length > 0
for(i=trailing_ones+1;i<total_coeff;i++) {
final int[/*7*/] suffix_limit = {0,3,6,12,24,48, Integer.MAX_VALUE };
bitsi= (int)gb.show_bits(LEVEL_TAB_BITS);
level_code= cavlc_level_tab[suffix_length][bitsi][0];
// DebugTool.printDebugString(" - cavlc_level_tab["+suffix_length+"]["+bitsi+"][0] = "+level_code+"\n");
gb.skip_bits(cavlc_level_tab[suffix_length][bitsi][1]);
if(level_code >= 100){
prefix= level_code - 100;
if(prefix == LEVEL_TAB_BITS){
prefix += get_level_prefix(gb);
}
if(prefix<15){
level_code = (int)((prefix<<suffix_length) + gb.get_bits(suffix_length,"level_code"));
}else{
level_code = (int)((15<<suffix_length) + gb.get_bits(prefix-3,"level_code"));
if(prefix>=16)
level_code += (1<<(prefix-3))-4096;
}
mask= -(level_code&1);
level_code= (((2+level_code)>>1) ^ mask) - mask;
}
level[i]= level_code;
// DebugTool.printDebugString(" - prefix(6) = "+level_code+"\n");
// Fix: for difference between JAVA and C, we need to convert signed to unsigned when we compare
// signed and unsigned number because, in C, such comparing will be done in common part.
// In which, common part in C in unsigned, while java is signed. -= Nok =-
suffix_length+= (( (0xffffffffL & (suffix_limit[suffix_length] + level_code)) > (2L*suffix_limit[suffix_length]))?1:0);
}
// DebugTool.printDebugString(" - suffix_length(2) = "+suffix_length+"\n");
}
if(total_coeff == max_coeff)
zeros_left=0;
else{
if(n >= H264Context.CHROMA_DC_BLOCK_INDEX) {
zeros_left= gb.get_vlc2(chroma_dc_total_zeros_vlc[ total_coeff-1 ].table_base,
chroma_dc_total_zeros_vlc[ total_coeff-1 ].table_offset,
H264Context.CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1, "coeff_token_CROMA_DC_TOTAL_ZERO");
// DebugTool.printDebugString("get_vlc2(CHROMA_DC_ZERO_LEFT) => zeros_left = " + zeros_left +"\n");
} else {
zeros_left= gb.get_vlc2(total_zeros_vlc[ total_coeff-1 ].table_base,
total_zeros_vlc[ total_coeff-1 ].table_offset,
H264Context.TOTAL_ZEROS_VLC_BITS, 1, "coeff_token_TOTAL_ZEROS");
// DebugTool.printDebugString("get_vlc2(LUMA_DC_ZERO_LEFT) => zeros_left = " + zeros_left +"\n");
} // if
}
/*
// DebugTool.printDebugString("scantable_offset(before) = {"
+scantable_base[scantable_offset+0]+","
+scantable_base[scantable_offset+1]+","
+scantable_base[scantable_offset+2]+","
+scantable_base[scantable_offset+3]+","
+scantable_base[scantable_offset+4]
+"}\n");
*/
scantable_offset += zeros_left + total_coeff - 1;
/*
// DebugTool.printDebugString("scantable_offset(after) = {"
+scantable_base[scantable_offset+0]+","
+scantable_base[scantable_offset+1]+","
+scantable_base[scantable_offset+2]+","
+scantable_base[scantable_offset+3]+","
+scantable_base[scantable_offset+4]
+"}\n");
*/
//!!????????????????????????????????? Magic about array resizing??
if(scantable_offset < 0) {
int[] new_scantable_base = new int[scantable_base.length + (-scantable_offset)];
System.arraycopy(scantable_base, 0, new_scantable_base, -scantable_offset, scantable_base.length);
scantable_base = new_scantable_base;
scantable_offset = 0;
}
if(n >= H264Context.LUMA_DC_BLOCK_INDEX){
// DebugTool.printDebugString("****RESE-CASE 1\n");
block_base[block_offset + scantable_base[scantable_offset]] = (short)level[0];
for(i=1;i<total_coeff && zeros_left > 0;i++) {
if(zeros_left < 7) {
//????????????????????????????????????????/
// run_before= gb.get_vlc2((run_vlc-1)[zeros_left].table, H264Context.RUN_VLC_BITS, 1);
run_before= gb.get_vlc2(run_vlc[zeros_left-1].table_base, run_vlc[zeros_left-1].table_offset, H264Context.RUN_VLC_BITS, 1, "RUN_VLC");
//System.out.println("get_vlc2(LUMA_RUN_VLC) => run_before = " + run_before );
} else {
run_before= gb.get_vlc2(run7_vlc.table_base, run7_vlc.table_offset, H264Context.RUN7_VLC_BITS, 2, "RUN7_VLC");
//System.out.println("get_vlc2(LUMA_RUN_VLC7) => run_before = " + run_before );
} // if
////System.out.println("run_before = "+run_before);
zeros_left -= run_before;
scantable_offset -= 1 + run_before;
block_base[block_offset + scantable_base[scantable_offset]]= (short)level[i];
}
for(;i<total_coeff;i++) {
scantable_offset--;
block_base[block_offset + scantable_base[scantable_offset]]= (short)level[i];
}
}else{
// DebugTool.printDebugString("****RESE-CASE 2\n");
block_base[block_offset + scantable_base[scantable_offset]] = (short)((level[0] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32)>>6);
for(i=1;i<total_coeff && zeros_left > 0;i++) {
if(zeros_left < 7) {
run_before= gb.get_vlc2(run_vlc[zeros_left-1].table_base, run_vlc[zeros_left-1].table_offset, H264Context.RUN_VLC_BITS, 1, "RUN_VLC");
//System.out.println("get_vlc2(CHROMA_RUN_VLC) => run_before = " + run_before );
} else {
run_before= gb.get_vlc2(run7_vlc.table_base, run7_vlc.table_offset, H264Context.RUN7_VLC_BITS, 2, "RUN7_VLC");
//System.out.println("get_vlc2(CHROMA_RUN_VLC7) => run_before = " + run_before );
} // if
////System.out.println("run_before = "+run_before);
zeros_left -= run_before;
scantable_offset -= (1 + run_before);
block_base[block_offset + scantable_base[scantable_offset]]= (short)((level[i] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32)>>6);
}
for(;i<total_coeff;i++) {
scantable_offset--;
block_base[block_offset + scantable_base[scantable_offset]]= (short)((level[i] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32)>>6);
}
}
if(zeros_left<0){
//av_log(h.s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s.mb_x, s.mb_y);
// DebugTool.printDebugString(" -------- Error type 1.2\n");
return -1;
}
return 0;
}
public int ff_h264_decode_mb_cavlc(H264Context h){
MpegEncContext s = h.s;
int mb_xy;
int partition_count;
int mb_type, cbp;
int dct8x8_allowed= h.pps.transform_8x8_mode;
// DebugTool.dumpDebugFrameData(h, "BEFORE-ff_h264_decode_mb_cavlc");
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 != H264Context.FF_I_TYPE){
if(s.mb_skip_run==-1)
s.mb_skip_run= s.gb.get_ue_golomb("mb_skip_run");
if (0 != s.mb_skip_run--) {
if(h.mb_aff_frame !=0 && (s.mb_y&1) == 0){
if(s.mb_skip_run==0)
h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_mbaff");
}
h.decode_mb_skip();
return 0;
}
}
if(h.mb_aff_frame != 0){
if( (s.mb_y&1) == 0 )
h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_field_decoding_flag");
}
h.prev_mb_skipped= 0;
mb_type= s.gb.get_ue_golomb("mb_type");
if(h.slice_type_nos == H264Context.FF_B_TYPE){
if(mb_type < 23){
partition_count= H264Data.b_mb_type_info[mb_type].partition_count;
mb_type= H264Data.b_mb_type_info[mb_type].type;
}else{
mb_type -= 23;
// goto decode_intra_mb;
// 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);
return -1;
}
partition_count=0;
cbp= H264Data.i_mb_type_info[mb_type].cbp;
h.intra16x16_pred_mode= H264Data.i_mb_type_info[mb_type].pred_mode;
mb_type= H264Data.i_mb_type_info[mb_type].type;
}
}else if(h.slice_type_nos == H264Context.FF_P_TYPE){
if(mb_type < 5){
partition_count= H264Data.p_mb_type_info[mb_type].partition_count;
mb_type= H264Data.p_mb_type_info[mb_type].type;
}else{
mb_type -= 5;
// goto decode_intra_mb;
// 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);
return -1;
}
partition_count=0;
cbp= H264Data.i_mb_type_info[mb_type].cbp;
h.intra16x16_pred_mode= H264Data.i_mb_type_info[mb_type].pred_mode;
mb_type= H264Data.i_mb_type_info[mb_type].type;
}
}else{
//assert(h.slice_type_nos == H264Context.FF_I_TYPE);
if(h.slice_type == H264Context.FF_SI_TYPE && mb_type!=0)
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);
return -1;
}
partition_count=0;
cbp= H264Data.i_mb_type_info[mb_type].cbp;
h.intra16x16_pred_mode= H264Data.i_mb_type_info[mb_type].pred_mode;
mb_type= H264Data.i_mb_type_info[mb_type].type;
}
if(h.mb_field_decoding_flag != 0)
mb_type |= H264Context.MB_TYPE_INTERLACED;
h.slice_table_base[h.slice_table_offset + mb_xy ]= h.slice_num;
if(0!= (mb_type & H264Context.MB_TYPE_INTRA_PCM)){
int x;
// We assume these blocks are very rare so we do not optimize it.
s.gb.align_get_bits();
// The pixels are stored in the same order as levels in h.mb array.
for(x=0; x < ((h.sps.chroma_format_idc!=0) ? 384 : 256); x+=2){
// Combine 2 byte to get a short.
//((uint8_t*)h.mb)[x]= (int)s.gb.get_bits(8);
int val = (int)s.gb.get_bits(8,"val");
val = val | (((int)s.gb.get_bits(8,"val"))<<8);
h.mb[x/2] = (short)val;
}
// 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);
Arrays.fill(h.non_zero_count[mb_xy],0,32,16);
s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy]= mb_type;
return 0;
}
if(h.mb_mbaff != 0){
h.ref_count[0] <<= 1;
h.ref_count[1] <<= 1;
}
h.fill_decode_neighbors(mb_type);
h.fill_decode_caches(mb_type);
//mb_pred
if(0!= (mb_type & 7)){
int pred_mode;
// init_top_left_availability(h);
if(0!=(mb_type & H264Context.MB_TYPE_INTRA4x4)){
int i;
int di = 1;
if(dct8x8_allowed!=0 && s.gb.get_bits1("MB_TYPE_8x8DCT?")!=0){
mb_type |= H264Context.MB_TYPE_8x8DCT;
di = 4;
}
// fill_intra4x4_pred_table(h);
for(i=0; i<16; i+=di){
int mode= h.pred_intra_mode(i);
if(0==s.gb.get_bits1("rem_mode")){
int rem_mode= (int)s.gb.get_bits(3,"rem_mode");
mode = rem_mode + ((rem_mode >= mode)?1:0);
}
if(di==4)
Rectangle.fill_rectangle_sign( h.intra4x4_pred_mode_cache, h.scan8[i] , 2, 2, 8, mode, 1 );
else
h.intra4x4_pred_mode_cache[ h.scan8[i] ] = mode;
}
h.ff_h264_write_back_intra_pred_mode();
if( h.ff_h264_check_intra4x4_pred_mode() < 0)
return -1;
}else{
h.intra16x16_pred_mode= h.ff_h264_check_intra_pred_mode(h.intra16x16_pred_mode);
if(h.intra16x16_pred_mode < 0)
return -1;
}
if(h.sps.chroma_format_idc != 0){
pred_mode= h.ff_h264_check_intra_pred_mode(s.gb.get_ue_golomb_31("pred_mode"));
if(pred_mode < 0)
return -1;
h.chroma_pred_mode= pred_mode;
}
}else if(partition_count==4){
int i, j;
int[] sub_partition_count = new int[4];
int list;
int[][]ref = new int[2][4];
if(h.slice_type_nos == H264Context.FF_B_TYPE){
for(i=0; i<4; i++){
h.sub_mb_type[i]= s.gb.get_ue_golomb_31("sub_mb_type");
if(h.sub_mb_type[i] >=13){
//av_log(h.s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y);
return -1;
}
sub_partition_count[i]= H264Data.b_sub_mb_type_info[ h.sub_mb_type[i] ].partition_count;
h.sub_mb_type[i]= H264Data.b_sub_mb_type_info[ h.sub_mb_type[i] ].type;
}
if( 0!=((h.sub_mb_type[0]|h.sub_mb_type[1]|h.sub_mb_type[2]|h.sub_mb_type[3])&H264Context.MB_TYPE_DIRECT2)) {
mb_type = h.ff_h264_pred_direct_motion(mb_type);
h.ref_cache[0][h.scan8[4]] =
h.ref_cache[1][h.scan8[4]] =
h.ref_cache[0][h.scan8[12]] =
h.ref_cache[1][h.scan8[12]] = H264Context.PART_NOT_AVAILABLE;
}
}else{
//assert(h.slice_type_nos == H264Context.FF_P_TYPE); //FIXME SP correct ?
for(i=0; i<4; i++){
h.sub_mb_type[i]= s.gb.get_ue_golomb_31("sub_mb_type");
if(h.sub_mb_type[i] >=4){
//av_log(h.s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y);
return -1;
}
sub_partition_count[i]= H264Data.p_sub_mb_type_info[ h.sub_mb_type[i] ].partition_count;
h.sub_mb_type[i]= H264Data.p_sub_mb_type_info[ h.sub_mb_type[i] ].type;
}
}
for(list=0; list<h.list_count; list++){
int ref_count= ((mb_type & H264Context.MB_TYPE_REF0)!=0) ? 1 : (int)h.ref_count[list];
for(i=0; i<4; i++){
if(0!=(h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2)) continue;
if(0!=((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0<<((0)+2*(list))))){
int tmp;
if(ref_count == 1){
tmp= 0;
}else if(ref_count == 2){
tmp= (int)s.gb.get_bits1("ref_count?")^1;
}else{
tmp= s.gb.get_ue_golomb_31("ref_count?");
if(tmp>=ref_count){
//av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
return -1;
}
}
ref[list][i]= tmp;
}else{
//FIXME
ref[list][i] = -1;
}
}
}
if(dct8x8_allowed!=0)
dct8x8_allowed = h.get_dct8x8_allowed();
for(list=0; list<h.list_count; list++){
for(i=0; i<4; i++){
if(0!=(h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2)) {
h.ref_cache[list][ h.scan8[4*i] ] = h.ref_cache[list][ h.scan8[4*i]+1 ];
continue;
}
h.ref_cache[list][ h.scan8[4*i] ]=h.ref_cache[list][ h.scan8[4*i]+1 ]=
h.ref_cache[list][ h.scan8[4*i]+8 ]=h.ref_cache[list][ h.scan8[4*i]+9 ]= ref[list][i];
if(((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0<<((0)+2*(list)))) != 0 ) {//IS_DIR(h.sub_mb_type[i], 0, list)){
int sub_mb_type= h.sub_mb_type[i];
int block_width= ((sub_mb_type & (H264Context.MB_TYPE_16x16|H264Context.MB_TYPE_16x8))!=0 ? 2 : 1);
for(j=0; j<sub_partition_count[i]; j++){
int mx, my;
int index= 4*i + block_width*j;
//int16_t (* mv_cache)[2]= &h.mv_cache[list][ h.scan8[index] ];
int[][] mv_cache_base = h.mv_cache[list];
int my_cache_offset = h.scan8[index];
int[] mxmy = new int[2];
h.pred_motion(index, block_width, list, h.ref_cache[list][ h.scan8[index] ], mxmy);
mx = mxmy[0];
my = mxmy[1];
mx += s.gb.get_se_golomb("mx?");
my += s.gb.get_se_golomb("my?");
//tprintf(s.avctx, "final mv:%d %d\n", mx, my);
if(0!=(sub_mb_type&H264Context.MB_TYPE_16x16)){
mv_cache_base[my_cache_offset + 1 ][0]=
mv_cache_base[my_cache_offset + 8 ][0]= mv_cache_base[my_cache_offset + 9 ][0]= mx;
mv_cache_base[my_cache_offset + 1 ][1]=
mv_cache_base[my_cache_offset + 8 ][1]= mv_cache_base[my_cache_offset + 9 ][1]= my;
}else if(0!=(sub_mb_type&H264Context.MB_TYPE_16x8)){
mv_cache_base[my_cache_offset + 1 ][0]= mx;
mv_cache_base[my_cache_offset + 1 ][1]= my;
}else if(0!=(sub_mb_type&H264Context.MB_TYPE_8x16)){
mv_cache_base[my_cache_offset + 8 ][0]= mx;
mv_cache_base[my_cache_offset + 8 ][1]= my;
}
mv_cache_base[my_cache_offset + 0 ][0]= mx;
mv_cache_base[my_cache_offset + 0 ][1]= my;
}
}else{
/*
uint32_t *p= (uint32_t *)&h.mv_cache[list][ scan8[4*i] ][0];
p[0] = p[1]=
p[8] = p[9]= 0;
*/
h.mv_cache[list][h.scan8[4*i] + 0][0] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 1][0] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 8][0] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 9][0] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 0][1] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 1][1] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 8][1] = (short)0;
h.mv_cache[list][h.scan8[4*i] + 9][1] = (short)0;
}
}
}
}else if(0!=(mb_type & H264Context.MB_TYPE_DIRECT2)){
mb_type = h.ff_h264_pred_direct_motion(mb_type);
dct8x8_allowed &= h.sps.direct_8x8_inference_flag;
}else{
int list, mx=0, my=0, i;
//FIXME we should set ref_idx_l? to 0 if we use that later ...
if(0!=(mb_type&H264Context.MB_TYPE_16x16)){
for(list=0; list<h.list_count; list++){
int val;
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((0)+2*(list)))) != 0 ){
if(h.ref_count[list]==1){
val= 0;
}else if(h.ref_count[list]==2){
val= (int)(s.gb.get_bits1("ref_count?")^1);
}else{
val= s.gb.get_ue_golomb_31("ref_count?");
if(val >= h.ref_count[list]){
//av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
}
Rectangle.fill_rectangle_sign(h.ref_cache[list], h.scan8[0], 4, 4, 8, val, 1);
}
}
for(list=0; list<h.list_count; list++){
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((0)+2*(list)))) != 0 ){
int[] mxmy = new int[] { mx, my };
h.pred_motion(0, 4, list, h.ref_cache[list][ h.scan8[0] ], mxmy);
mx = mxmy[0];
my = mxmy[1];
mx += s.gb.get_se_golomb("mx?");
my += s.gb.get_se_golomb("my?");
//int val = h.pack16to32(mx,my);
// DebugTool.printDebugString(" ****(1) mx="+mx+", my="+my+", val="+val+"\n");
//tprintf(s.avctx, "final mv:%d %d\n", mx, my);
Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], h.scan8[0] , 4, 4, 8, h.pack16to32(mx,my), 4);
}
}
}
else if(0!=(mb_type&H264Context.MB_TYPE_16x8)){
for(list=0; list<h.list_count; list++){
for(i=0; i<2; i++){
int val;
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((i)+2*(list)))) != 0 ){
if(h.ref_count[list] == 1){
val= 0;
}else if(h.ref_count[list] == 2){
val= (int)(s.gb.get_bits1("ref_count?")^1);
}else{
val= s.gb.get_ue_golomb_31("ref_count?");
if(val >= h.ref_count[list]){
//av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
}
}else {
//!!?????????????????????? Need unsigneded??
val= H264Context.LIST_NOT_USED;
} // if
Rectangle.fill_rectangle_sign(h.ref_cache[list], h.scan8[0] + 16*i , 4, 2, 8, val, 1);
}
}
for(list=0; list<h.list_count; list++){
for(i=0; i<2; i++){
int val;
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((i)+2*(list)))) != 0 ){
int[] mxmy = new int[] { mx, my };
h.pred_16x8_motion(8*i, list, h.ref_cache[list][h.scan8[0] + 16*i], mxmy);
mx = mxmy[0];
my = mxmy[1];
mx += s.gb.get_se_golomb("mx?");
my += s.gb.get_se_golomb("my?");
//tprintf(s.avctx, "final mv:%d %d\n", mx, my);
val= h.pack16to32(mx,my);
// DebugTool.printDebugString(" ****(2) mx="+mx+", my="+my+", val="+val+"\n");
}else
val=0;
Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], h.scan8[0] + 16*i, 4, 2, 8, val, 4);
}
}
}else{
////assert(IS_8X16(mb_type));
for(list=0; list<h.list_count; list++){
for(i=0; i<2; i++){
int val;
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((i)+2*(list)))) != 0 ){ //FIXME optimize
if(h.ref_count[list]==1){
val= 0;
}else if(h.ref_count[list]==2){
val= (int)(s.gb.get_bits1("ref-count?")^1);
}else{
val= s.gb.get_ue_golomb_31("ref-count?");
if(val >= h.ref_count[list]){
//av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
return -1;
}
}
}else {
// !!?????????? Need Unsigned
val= h.LIST_NOT_USED;
} // if
Rectangle.fill_rectangle_sign(h.ref_cache[list], h.scan8[0] + 2*i , 2, 4, 8, val, 1);
}
}
for(list=0; list<h.list_count; list++){
for(i=0; i<2; i++){
int val;
if(((mb_type) & (H264Context.MB_TYPE_P0L0<<((i)+2*(list)))) != 0 ){
int[] mxmy = new int[] { mx, my };
h.pred_8x16_motion(i*4, list, h.ref_cache[list][ h.scan8[0] + 2*i ], mxmy);
mx = mxmy[0];
my = mxmy[1];
mx += s.gb.get_se_golomb("mx?");
my += s.gb.get_se_golomb("my?");
//tprintf(s.avctx, "final mv:%d %d\n", mx, my);
val= h.pack16to32(mx,my);
// DebugTool.printDebugString(" ****(3) mx="+mx+", my="+my+", val="+val+"\n");
}else
val=0;
Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], h.scan8[0] + 2*i , 2, 4, 8, val, 4);
}
}
}
}
if(0!=(mb_type &(H264Context.MB_TYPE_16x16|H264Context.MB_TYPE_16x8|H264Context.MB_TYPE_8x16|H264Context.MB_TYPE_8x8)))
h.write_back_motion(mb_type);
if(0==(mb_type &H264Context.MB_TYPE_INTRA16x16)){
cbp= s.gb.get_ue_golomb("cbp");
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(h.sps.chroma_format_idc != 0){
if(0!=(mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp= H264Data.golomb_to_intra4x4_cbp[cbp];
else cbp= H264Data.golomb_to_inter_cbp [cbp];
}else{
if(0!=(mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
else cbp= golomb_to_inter_cbp_gray[cbp];
}
}
if(dct8x8_allowed!=0 && (cbp&15)!=0 && 0==(mb_type & 7)){
mb_type |= H264Context.MB_TYPE_8x8DCT*s.gb.get_bits1("mb_type");
}
h.cbp=
h.cbp_table[mb_xy]= cbp;
s.current_picture.mb_type_base[s.current_picture.mb_type_offset +mb_xy]= mb_type;
if(cbp !=0 ||0!= (mb_type & H264Context.MB_TYPE_INTRA16x16)){
int i8x8, i4x4, chroma_idx;
int dquant;
GetBitContext gb= (((mb_type & 7)!=0) ? h.intra_gb_ptr : h.inter_gb_ptr);
//uint8_t *scan, *scan8x8;
int[] scan;
int[] scan8x8;
if(0!=(mb_type & H264Context.MB_TYPE_INTERLACED)){
scan8x8= (s.qscale!=0 ? h.field_scan8x8_cavlc : h.field_scan8x8_cavlc_q0);
scan= (s.qscale!=0 ? h.field_scan : h.field_scan_q0);
}else{
scan8x8= (s.qscale!=0 ? h.zigzag_scan8x8_cavlc : h.zigzag_scan8x8_cavlc_q0);
scan= (s.qscale!=0 ? h.zigzag_scan : h.zigzag_scan_q0);
}
dquant= s.gb.get_se_golomb("dquant");
s.qscale += dquant;
if((/*(unsigned)*/s.qscale) > 51 || s.qscale < 0){
if(s.qscale<0) s.qscale+= 52;
else s.qscale-= 52;
if((/*(unsigned)*/s.qscale) > 51 || s.qscale < 0){
//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]= h.pps.chroma_qp_table[0][s.qscale];
h.chroma_qp[1]= h.pps.chroma_qp_table[1][s.qscale];
if(0!=(mb_type & H264Context.MB_TYPE_INTRA16x16)){
// Fill 16 uint16_t with 0
Arrays.fill(h.mb_luma_dc, 0, 16, (short)0);
//AV_ZERO128(h.mb_luma_dc+0);
//AV_ZERO128(h.mb_luma_dc+8);
if( decode_residual(h, h.intra_gb_ptr, h.mb_luma_dc, 0, H264Context.LUMA_DC_BLOCK_INDEX, scan, 0, h.dequant4_coeff[0][s.qscale], 0, 16) < 0){
return -1; //FIXME continue if partitioned and other return -1 too
}
//assert((cbp&15) == 0 || (cbp&15) == 15);
if((cbp&15)!=0){
/////////////////////////////////
for(i8x8=0; i8x8<4; i8x8++){
for(i4x4=0; i4x4<4; i4x4++){
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], 0, 15) < 0 ){
return -1;
}
}
}
}else{
Rectangle.fill_rectangle_unsign(h.non_zero_count_cache, h.scan8[0], 4, 4, 8, 0, 1);
}
}else{
for(i8x8=0; i8x8<4; i8x8++){
if((cbp & (1<<i8x8))!=0){
if(0!= (mb_type & H264Context.MB_TYPE_8x8DCT)){
short[] buf_base = h.mb;
int buf_offset = 64*i8x8;
for(i4x4=0; i4x4<4; i4x4++){
if( decode_residual(h, gb, buf_base, buf_offset, i4x4+4*i8x8, scan8x8, 16*i4x4,
h.dequant8_coeff[(0!=( mb_type & 7)) ? 0:1][s.qscale], 0, 16) <0 )
return -1;
}
int[] nnz_base = h.non_zero_count_cache;
int nnz_offset = h.scan8[4*i8x8];
nnz_base[nnz_offset + 0] += nnz_base[nnz_offset + 1] + nnz_base[nnz_offset + 8] + nnz_base[nnz_offset + 9];
}else{
for(i4x4=0; i4x4<4; i4x4++){
int index= i4x4 + 4*i8x8;
if( decode_residual(h, gb, h.mb, 16*index, index, scan, 0, h.dequant4_coeff[(mb_type &7)!=0 ? 0:3][s.qscale], 0, 16) <0 ){
return -1;
}
}
}
}else{
int[] nnz_base = h.non_zero_count_cache;
int nnz_offset = h.scan8[4*i8x8];
nnz_base[nnz_offset + 0] = nnz_base[nnz_offset + 1] = nnz_base[nnz_offset + 8] = nnz_base[nnz_offset + 9] = 0;
}
}
}
if((cbp&0x030)!=0){
// Fill 2x4 uint_16t with 0
Arrays.fill(h.mb_chroma_dc[0], (short)0);
Arrays.fill(h.mb_chroma_dc[1], (short)0);
//AV_ZERO128(h.mb_chroma_dc);
for(chroma_idx=0; chroma_idx<2; chroma_idx++) {
if( decode_residual(h, gb, h.mb_chroma_dc[chroma_idx], 0, H264Context.CHROMA_DC_BLOCK_INDEX+chroma_idx, H264Data.chroma_dc_scan, 0, null, 0 , 4) < 0){
// DebugTool.printDebugString("----Error type 16\n");
return -1;
}
}
}
if((cbp&0x020)!=0){
for(chroma_idx=0; chroma_idx<2; chroma_idx++){
long[] qmul = h.dequant4_coeff[chroma_idx+1+(( (mb_type & 7)!=0 ) ? 0:3)][h.chroma_qp[chroma_idx]];
for(i4x4=0; i4x4<4; i4x4++){
int index= 16 + 4*chroma_idx + i4x4;
if( decode_residual(h, gb, h.mb, 16*index, index, scan, 1, qmul, 0, 15) < 0){
return -1;
}
}
}
}else{
int[] nnz= h.non_zero_count_cache;
nnz[ h.scan8[16]+0 ] = nnz[ h.scan8[16]+1 ] =nnz[ h.scan8[16]+8 ] =nnz[ h.scan8[16]+9 ] =
nnz[ h.scan8[20]+0 ] = nnz[ h.scan8[20]+1 ] =nnz[ h.scan8[20]+8 ] =nnz[ h.scan8[20]+9 ] = 0;
}
}else{
int[] nnz= h.non_zero_count_cache;
Rectangle.fill_rectangle_unsign(nnz, h.scan8[0], 4, 4, 8, 0, 1);
nnz[ h.scan8[16]+0 ] = nnz[ h.scan8[16]+1 ] =nnz[ h.scan8[16]+8 ] =nnz[ h.scan8[16]+9 ] =
nnz[ h.scan8[20]+0 ] = nnz[ h.scan8[20]+1 ] =nnz[ h.scan8[20]+8 ] =nnz[ h.scan8[20]+9 ] = 0;
}
s.current_picture.qscale_table[mb_xy]= s.qscale;
h.write_back_non_zero_count();
if(h.mb_mbaff != 0){
h.ref_count[0] >>= 1;
h.ref_count[1] >>= 1;
}
// DebugTool.dumpDebugFrameData(h, "AFTER-ff_h264_decode_mb_cavlc");
return 0;
}
}