}
};
-void ff_h264_init_cabac_states(H264Context *h, H264SliceContext *sl)
+void ff_h264_init_cabac_states(const H264Context *h, H264SliceContext *sl)
{
int i;
const int8_t (*tab)[2];
}
}
-static int decode_cabac_field_decoding_flag(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_field_decoding_flag(const H264Context *h, H264SliceContext *sl)
{
const int mbb_xy = sl->mb_xy - 2*h->mb_stride;
return get_cabac_noinline( &sl->cabac, &(sl->cabac_state+70)[ctx] );
}
-static int decode_cabac_intra_mb_type(H264Context *h, H264SliceContext *sl,
+static int decode_cabac_intra_mb_type(H264SliceContext *sl,
int ctx_base, int intra_slice)
{
uint8_t *state= &sl->cabac_state[ctx_base];
return mb_type;
}
-static int decode_cabac_mb_skip(H264Context *h, H264SliceContext *sl,
+static int decode_cabac_mb_skip(const H264Context *h, H264SliceContext *sl,
int mb_x, int mb_y)
{
int mba_xy, mbb_xy;
return get_cabac_noinline( &sl->cabac, &sl->cabac_state[11+ctx] );
}
-static int decode_cabac_mb_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl, int pred_mode)
+static int decode_cabac_mb_intra4x4_pred_mode(H264SliceContext *sl, int pred_mode)
{
int mode = 0;
return mode + ( mode >= pred_mode );
}
-static int decode_cabac_mb_chroma_pre_mode(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_mb_chroma_pre_mode(const H264Context *h, H264SliceContext *sl)
{
const int mba_xy = sl->left_mb_xy[0];
const int mbb_xy = sl->top_mb_xy;
return 3;
}
-static int decode_cabac_mb_cbp_luma(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_mb_cbp_luma(H264SliceContext *sl)
{
int cbp_b, cbp_a, ctx, cbp = 0;
cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 3;
return cbp;
}
-static int decode_cabac_mb_cbp_chroma(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_mb_cbp_chroma(H264SliceContext *sl)
{
int ctx;
int cbp_a, cbp_b;
return 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[77 + ctx] );
}
-static int decode_cabac_p_mb_sub_type(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_p_mb_sub_type(H264SliceContext *sl)
{
if( get_cabac( &sl->cabac, &sl->cabac_state[21] ) )
return 0; /* 8x8 */
return 2; /* 4x8 */
return 3; /* 4x4 */
}
-static int decode_cabac_b_mb_sub_type(H264Context *h, H264SliceContext *sl)
+static int decode_cabac_b_mb_sub_type(H264SliceContext *sl)
{
int type;
if( !get_cabac( &sl->cabac, &sl->cabac_state[36] ) )
return type;
}
-static int decode_cabac_mb_ref(H264Context *h, H264SliceContext *sl, int list, int n)
+static int decode_cabac_mb_ref(H264SliceContext *sl, int list, int n)
{
int refa = sl->ref_cache[list][scan8[n] - 1];
int refb = sl->ref_cache[list][scan8[n] - 8];
return ref;
}
-static int decode_cabac_mb_mvd(H264Context *h, H264SliceContext *sl, int ctxbase, int amvd, int *mvda)
+static int decode_cabac_mb_mvd(H264SliceContext *sl, int ctxbase, int amvd, int *mvda)
{
int mvd;
mvd += 1 << k;
k++;
if(k>24){
- av_log(h->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
+ av_log(sl->h264->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
return INT_MIN;
}
}
return get_cabac_bypass_sign( &sl->cabac, -mvd );
}
-#define DECODE_CABAC_MB_MVD( h, list, n )\
+#define DECODE_CABAC_MB_MVD(sl, list, n )\
{\
int amvd0 = sl->mvd_cache[list][scan8[n] - 1][0] +\
sl->mvd_cache[list][scan8[n] - 8][0];\
int amvd1 = sl->mvd_cache[list][scan8[n] - 1][1] +\
sl->mvd_cache[list][scan8[n] - 8][1];\
\
- mx += decode_cabac_mb_mvd(h, sl, 40, amvd0, &mpx);\
- my += decode_cabac_mb_mvd(h, sl, 47, amvd1, &mpy);\
+ mx += decode_cabac_mb_mvd(sl, 40, amvd0, &mpx);\
+ my += decode_cabac_mb_mvd(sl, 47, amvd1, &mpy);\
}
-static av_always_inline int get_cabac_cbf_ctx(H264Context *h, H264SliceContext *sl,
+static av_always_inline int get_cabac_cbf_ctx(H264SliceContext *sl,
int cat, int idx, int max_coeff,
int is_dc)
{
}
static av_always_inline void
-decode_cabac_residual_internal(H264Context *h, H264SliceContext *sl,
+decode_cabac_residual_internal(const H264Context *h, H264SliceContext *sl,
int16_t *block,
int cat, int n, const uint8_t *scantable,
const uint32_t *qmul, int max_coeff,
}
-static av_noinline void decode_cabac_residual_dc_internal(H264Context *h,
+static av_noinline void decode_cabac_residual_dc_internal(const H264Context *h,
H264SliceContext *sl,
int16_t *block,
int cat, int n,
decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 0);
}
-static av_noinline void decode_cabac_residual_dc_internal_422(H264Context *h,
+static av_noinline void decode_cabac_residual_dc_internal_422(const H264Context *h,
H264SliceContext *sl,
int16_t *block,
int cat, int n,
decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 1);
}
-static av_noinline void decode_cabac_residual_nondc_internal(H264Context *h,
+static av_noinline void decode_cabac_residual_nondc_internal(const H264Context *h,
H264SliceContext *sl,
int16_t *block,
int cat, int n,
* because it allows improved constant propagation into get_cabac_cbf_ctx,
* as well as because most blocks have zero CBFs. */
-static av_always_inline void decode_cabac_residual_dc(H264Context *h,
+static av_always_inline void decode_cabac_residual_dc(const H264Context *h,
H264SliceContext *sl,
int16_t *block,
int cat, int n,
int max_coeff)
{
/* read coded block flag */
- if( get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(h, sl, cat, n, max_coeff, 1)]) == 0 ) {
+ if( get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0 ) {
sl->non_zero_count_cache[scan8[n]] = 0;
return;
}
}
static av_always_inline void
-decode_cabac_residual_dc_422(H264Context *h, H264SliceContext *sl,
+decode_cabac_residual_dc_422(const H264Context *h, H264SliceContext *sl,
int16_t *block,
int cat, int n, const uint8_t *scantable,
int max_coeff)
{
/* read coded block flag */
- if (get_cabac(&sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(h, sl, cat, n, max_coeff, 1)]) == 0) {
+ if (get_cabac(&sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0) {
sl->non_zero_count_cache[scan8[n]] = 0;
return;
}
decode_cabac_residual_dc_internal_422(h, sl, block, cat, n, scantable, max_coeff);
}
-static av_always_inline void decode_cabac_residual_nondc(H264Context *h,
+static av_always_inline void decode_cabac_residual_nondc(const H264Context *h,
H264SliceContext *sl,
int16_t *block,
int cat, int n,
int max_coeff)
{
/* read coded block flag */
- if( (cat != 5 || CHROMA444(h)) && get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(h, sl, cat, n, max_coeff, 0)]) == 0) {
+ if( (cat != 5 || CHROMA444(h)) && get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 0)]) == 0) {
if( max_coeff == 64 ) {
fill_rectangle(&sl->non_zero_count_cache[scan8[n]], 2, 2, 8, 0, 1);
} else {
decode_cabac_residual_nondc_internal(h, sl, block, cat, n, scantable, qmul, max_coeff);
}
-static av_always_inline void decode_cabac_luma_residual(H264Context *h, H264SliceContext *sl,
+static av_always_inline void decode_cabac_luma_residual(const H264Context *h, H264SliceContext *sl,
const uint8_t *scan, const uint8_t *scan8x8,
int pixel_shift, int mb_type, int cbp, int p)
{
* Decode a macroblock.
* @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
*/
-int ff_h264_decode_mb_cabac(H264Context *h, H264SliceContext *sl)
+int ff_h264_decode_mb_cabac(const H264Context *h, H264SliceContext *sl)
{
int mb_xy;
int mb_type, partition_count, cbp = 0;
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;
- unsigned local_ref_count[2];
mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;
if( bits < 8 ){
mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
}else if( bits == 13 ){
- mb_type = decode_cabac_intra_mb_type(h, sl, 32, 0);
+ mb_type = decode_cabac_intra_mb_type(sl, 32, 0);
goto decode_intra_mb;
}else if( bits == 14 ){
mb_type= 11; /* B_L1_L0_8x16 */
partition_count= p_mb_type_info[mb_type].partition_count;
mb_type= p_mb_type_info[mb_type].type;
} else {
- mb_type = decode_cabac_intra_mb_type(h, sl, 17, 0);
+ mb_type = decode_cabac_intra_mb_type(sl, 17, 0);
goto decode_intra_mb;
}
} else {
- mb_type = decode_cabac_intra_mb_type(h, sl, 3, 1);
+ mb_type = decode_cabac_intra_mb_type(sl, 3, 1);
if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
mb_type--;
av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
return 0;
}
- local_ref_count[0] = sl->ref_count[0] << MB_MBAFF(sl);
- local_ref_count[1] = sl->ref_count[1] << MB_MBAFF(sl);
-
fill_decode_caches(h, sl, mb_type);
if( IS_INTRA( mb_type ) ) {
mb_type |= MB_TYPE_8x8DCT;
for( i = 0; i < 16; i+=4 ) {
int pred = pred_intra_mode(h, sl, i);
- int mode = decode_cabac_mb_intra4x4_pred_mode(h, sl, pred);
+ int mode = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
fill_rectangle(&sl->intra4x4_pred_mode_cache[scan8[i]], 2, 2, 8, mode, 1);
}
} else {
for( i = 0; i < 16; i++ ) {
int pred = pred_intra_mode(h, sl, i);
- sl->intra4x4_pred_mode_cache[scan8[i]] = decode_cabac_mb_intra4x4_pred_mode(h, sl, pred);
+ sl->intra4x4_pred_mode_cache[scan8[i]] = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
av_dlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
sl->intra4x4_pred_mode_cache[scan8[i]]);
if (sl->slice_type_nos == AV_PICTURE_TYPE_B ) {
for( i = 0; i < 4; i++ ) {
- sl->sub_mb_type[i] = decode_cabac_b_mb_sub_type(h, sl);
+ sl->sub_mb_type[i] = decode_cabac_b_mb_sub_type(sl);
sub_partition_count[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
sl->sub_mb_type[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].type;
}
}
} else {
for( i = 0; i < 4; i++ ) {
- sl->sub_mb_type[i] = decode_cabac_p_mb_sub_type(h, sl);
+ sl->sub_mb_type[i] = decode_cabac_p_mb_sub_type(sl);
sub_partition_count[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
sl->sub_mb_type[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].type;
}
for( i = 0; i < 4; i++ ) {
if(IS_DIRECT(sl->sub_mb_type[i])) continue;
if(IS_DIR(sl->sub_mb_type[i], 0, list)){
- if (local_ref_count[list] > 1) {
- ref[list][i] = decode_cabac_mb_ref(h, sl, list, 4 * i);
- if (ref[list][i] >= (unsigned)local_ref_count[list]) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], local_ref_count[list]);
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref[list][i] = decode_cabac_mb_ref(sl, list, 4 * i);
+ if (ref[list][i] >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
return -1;
}
}else
int16_t (* mv_cache)[2] = &sl->mv_cache[list][ scan8[index] ];
uint8_t (* mvd_cache)[2]= &sl->mvd_cache[list][ scan8[index] ];
pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
- DECODE_CABAC_MB_MVD( h, list, index)
+ DECODE_CABAC_MB_MVD(sl, list, index)
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
if(IS_SUB_8X8(sub_mb_type)){
for (list = 0; list < sl->list_count; list++) {
if(IS_DIR(mb_type, 0, list)){
int ref;
- if (local_ref_count[list] > 1) {
- ref= decode_cabac_mb_ref(h, sl, list, 0);
- if (ref >= (unsigned)local_ref_count[list]) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref= decode_cabac_mb_ref(sl, list, 0);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
return -1;
}
}else
if(IS_DIR(mb_type, 0, list)){
int mx,my,mpx,mpy;
pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
- DECODE_CABAC_MB_MVD( h, list, 0)
+ DECODE_CABAC_MB_MVD(sl, list, 0)
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
fill_rectangle(sl->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
for(i=0; i<2; i++){
if(IS_DIR(mb_type, i, list)){
int ref;
- if (local_ref_count[list] > 1) {
- ref= decode_cabac_mb_ref(h, sl, list, 8 * i);
- if (ref >= (unsigned)local_ref_count[list]) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref= decode_cabac_mb_ref(sl, list, 8 * i);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
return -1;
}
}else
if(IS_DIR(mb_type, i, list)){
int mx,my,mpx,mpy;
pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
- DECODE_CABAC_MB_MVD( h, list, 8*i)
+ DECODE_CABAC_MB_MVD(sl, list, 8*i)
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
for(i=0; i<2; i++){
if(IS_DIR(mb_type, i, list)){ //FIXME optimize
int ref;
- if (local_ref_count[list] > 1) {
- ref= decode_cabac_mb_ref(h, sl, list, 4 * i);
- if (ref >= (unsigned)local_ref_count[list]) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref = decode_cabac_mb_ref(sl, list, 4 * i);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
return -1;
}
}else
if(IS_DIR(mb_type, i, list)){
int mx,my,mpx,mpy;
pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
- DECODE_CABAC_MB_MVD( h, list, 4*i)
+ DECODE_CABAC_MB_MVD(sl, list, 4*i)
tprintf(h->avctx, "final mv:%d %d\n", mx, my);
fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
}
if( !IS_INTRA16x16( mb_type ) ) {
- cbp = decode_cabac_mb_cbp_luma(h, sl);
+ cbp = decode_cabac_mb_cbp_luma(sl);
if(decode_chroma)
- cbp |= decode_cabac_mb_cbp_chroma(h, sl) << 4;
+ cbp |= decode_cabac_mb_cbp_chroma(sl) << 4;
} else {
if (!decode_chroma && cbp>15) {
av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");