#include "vdpau_internal.h"
#include "cabac.h"
-#if ARCH_X86
-#include "x86/h264_i386.h"
-#endif
//#undef NDEBUG
#include <assert.h>
-static VLC coeff_token_vlc[4];
-static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];
-static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
-
-static VLC chroma_dc_coeff_token_vlc;
-static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2];
-static const int chroma_dc_coeff_token_vlc_table_size = 256;
-
-static VLC total_zeros_vlc[15];
-static VLC_TYPE total_zeros_vlc_tables[15][512][2];
-static const int total_zeros_vlc_tables_size = 512;
-
-static VLC chroma_dc_total_zeros_vlc[3];
-static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2];
-static const int chroma_dc_total_zeros_vlc_tables_size = 8;
-
-static VLC run_vlc[6];
-static VLC_TYPE run_vlc_tables[6][8][2];
-static const int run_vlc_tables_size = 8;
-
-static VLC run7_vlc;
-static VLC_TYPE run7_vlc_table[96][2];
-static const int run7_vlc_table_size = 96;
-
-static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp);
-static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);
-
static const uint8_t rem6[52]={
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
};
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
};
-static const uint8_t left_block_options[4][8]={
- {0,1,2,3,7,10,8,11},
- {2,2,3,3,8,11,8,11},
- {0,0,1,1,7,10,7,10},
- {0,2,0,2,7,10,7,10}
-};
-
-#define LEVEL_TAB_BITS 8
-static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
-
-static void fill_caches(H264Context *h, int mb_type, int for_deblock){
- MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
- int topleft_xy, top_xy, topright_xy, left_xy[2];
- int topleft_type, top_type, topright_type, left_type[2];
- const uint8_t * left_block;
- int topleft_partition= -1;
- int i;
-
- top_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
-
- //FIXME deblocking could skip the intra and nnz parts.
- if(for_deblock && (h->slice_num == 1 || h->slice_table[mb_xy] == h->slice_table[top_xy]) && !FRAME_MBAFF)
- return;
-
- /* Wow, what a mess, why didn't they simplify the interlacing & intra
- * stuff, I can't imagine that these complex rules are worth it. */
-
- topleft_xy = top_xy - 1;
- topright_xy= top_xy + 1;
- left_xy[1] = left_xy[0] = mb_xy-1;
- left_block = left_block_options[0];
- if(FRAME_MBAFF){
- const int pair_xy = s->mb_x + (s->mb_y & ~1)*s->mb_stride;
- const int top_pair_xy = pair_xy - s->mb_stride;
- const int topleft_pair_xy = top_pair_xy - 1;
- const int topright_pair_xy = top_pair_xy + 1;
- const int topleft_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[topleft_pair_xy]);
- const int top_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]);
- const int topright_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[topright_pair_xy]);
- const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]);
- const int curr_mb_field_flag = IS_INTERLACED(mb_type);
- const int bottom = (s->mb_y & 1);
- tprintf(s->avctx, "fill_caches: curr_mb_field_flag:%d, left_mb_field_flag:%d, topleft_mb_field_flag:%d, top_mb_field_flag:%d, topright_mb_field_flag:%d\n", curr_mb_field_flag, left_mb_field_flag, topleft_mb_field_flag, top_mb_field_flag, topright_mb_field_flag);
-
- if (curr_mb_field_flag && (bottom || top_mb_field_flag)){
- top_xy -= s->mb_stride;
- }
- if (curr_mb_field_flag && (bottom || topleft_mb_field_flag)){
- topleft_xy -= s->mb_stride;
- } else if(bottom && !curr_mb_field_flag && left_mb_field_flag) {
- topleft_xy += s->mb_stride;
- // take top left mv from the middle of the mb, as opposed to all other modes which use the bottom right partition
- topleft_partition = 0;
- }
- if (curr_mb_field_flag && (bottom || topright_mb_field_flag)){
- topright_xy -= s->mb_stride;
- }
- if (left_mb_field_flag != curr_mb_field_flag) {
- left_xy[1] = left_xy[0] = pair_xy - 1;
- if (curr_mb_field_flag) {
- left_xy[1] += s->mb_stride;
- left_block = left_block_options[3];
- } else {
- left_block= left_block_options[2 - bottom];
- }
- }
- }
-
- h->top_mb_xy = top_xy;
- h->left_mb_xy[0] = left_xy[0];
- h->left_mb_xy[1] = left_xy[1];
- if(for_deblock){
- topleft_type = 0;
- topright_type = 0;
- top_type = h->slice_table[top_xy ] < 0xFFFF ? s->current_picture.mb_type[top_xy] : 0;
- left_type[0] = h->slice_table[left_xy[0] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[0]] : 0;
- left_type[1] = h->slice_table[left_xy[1] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[1]] : 0;
-
- if(MB_MBAFF && !IS_INTRA(mb_type)){
- int list;
- for(list=0; list<h->list_count; list++){
- //These values where changed for ease of performing MC, we need to change them back
- //FIXME maybe we can make MC and loop filter use the same values or prevent
- //the MC code from changing ref_cache and rather use a temporary array.
- if(USES_LIST(mb_type,list)){
- int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]];
- *(uint32_t*)&h->ref_cache[list][scan8[ 0]] =
- *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
- ref += h->b8_stride;
- *(uint32_t*)&h->ref_cache[list][scan8[ 8]] =
- *(uint32_t*)&h->ref_cache[list][scan8[10]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
- }
- }
- }
- }else{
- topleft_type = h->slice_table[topleft_xy ] == h->slice_num ? s->current_picture.mb_type[topleft_xy] : 0;
- top_type = h->slice_table[top_xy ] == h->slice_num ? s->current_picture.mb_type[top_xy] : 0;
- topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;
- left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;
- left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;
-
- if(IS_INTRA(mb_type)){
- int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
- h->topleft_samples_available=
- h->top_samples_available=
- h->left_samples_available= 0xFFFF;
- h->topright_samples_available= 0xEEEA;
-
- if(!(top_type & type_mask)){
- h->topleft_samples_available= 0xB3FF;
- h->top_samples_available= 0x33FF;
- h->topright_samples_available= 0x26EA;
- }
- if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){
- if(IS_INTERLACED(mb_type)){
- if(!(left_type[0] & type_mask)){
- h->topleft_samples_available&= 0xDFFF;
- h->left_samples_available&= 0x5FFF;
- }
- if(!(left_type[1] & type_mask)){
- h->topleft_samples_available&= 0xFF5F;
- h->left_samples_available&= 0xFF5F;
- }
- }else{
- int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num
- ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0;
- assert(left_xy[0] == left_xy[1]);
- if(!((left_typei & type_mask) && (left_type[0] & type_mask))){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
- }
- }
- }else{
- if(!(left_type[0] & type_mask)){
- h->topleft_samples_available&= 0xDF5F;
- h->left_samples_available&= 0x5F5F;
- }
- }
-
- if(!(topleft_type & type_mask))
- h->topleft_samples_available&= 0x7FFF;
-
- if(!(topright_type & type_mask))
- h->topright_samples_available&= 0xFBFF;
-
- if(IS_INTRA4x4(mb_type)){
- if(IS_INTRA4x4(top_type)){
- h->intra4x4_pred_mode_cache[4+8*0]= h->intra4x4_pred_mode[top_xy][4];
- h->intra4x4_pred_mode_cache[5+8*0]= h->intra4x4_pred_mode[top_xy][5];
- h->intra4x4_pred_mode_cache[6+8*0]= h->intra4x4_pred_mode[top_xy][6];
- h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];
- }else{
- int pred;
- if(!(top_type & type_mask))
- pred= -1;
- else{
- pred= 2;
- }
- h->intra4x4_pred_mode_cache[4+8*0]=
- h->intra4x4_pred_mode_cache[5+8*0]=
- h->intra4x4_pred_mode_cache[6+8*0]=
- h->intra4x4_pred_mode_cache[7+8*0]= pred;
- }
- for(i=0; i<2; i++){
- if(IS_INTRA4x4(left_type[i])){
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[0+2*i]];
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];
- }else{
- int pred;
- if(!(left_type[i] & type_mask))
- pred= -1;
- else{
- pred= 2;
- }
- h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=
- h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= pred;
- }
- }
- }
- }
- }
-
-
-/*
-0 . T T. T T T T
-1 L . .L . . . .
-2 L . .L . . . .
-3 . T TL . . . .
-4 L . .L . . . .
-5 L . .. . . . .
-*/
-//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
- if(top_type){
- h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][4];
- h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][5];
- h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][6];
- h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][3];
-
- h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][9];
- h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][8];
-
- h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][12];
- h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11];
-
- }else{
- h->non_zero_count_cache[4+8*0]=
- h->non_zero_count_cache[5+8*0]=
- h->non_zero_count_cache[6+8*0]=
- h->non_zero_count_cache[7+8*0]=
-
- h->non_zero_count_cache[1+8*0]=
- h->non_zero_count_cache[2+8*0]=
-
- h->non_zero_count_cache[1+8*3]=
- h->non_zero_count_cache[2+8*3]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64;
-
- }
-
- for (i=0; i<2; i++) {
- if(left_type[i]){
- h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[0+2*i]];
- h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[1+2*i]];
- h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[4+2*i]];
- h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[5+2*i]];
- }else{
- h->non_zero_count_cache[3+8*1 + 2*8*i]=
- h->non_zero_count_cache[3+8*2 + 2*8*i]=
- h->non_zero_count_cache[0+8*1 + 8*i]=
- h->non_zero_count_cache[0+8*4 + 8*i]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64;
- }
- }
-
- if( h->pps.cabac ) {
- // top_cbp
- if(top_type) {
- h->top_cbp = h->cbp_table[top_xy];
- } else if(IS_INTRA(mb_type)) {
- h->top_cbp = 0x1C0;
- } else {
- h->top_cbp = 0;
- }
- // left_cbp
- if (left_type[0]) {
- h->left_cbp = h->cbp_table[left_xy[0]] & 0x1f0;
- } else if(IS_INTRA(mb_type)) {
- h->left_cbp = 0x1C0;
- } else {
- h->left_cbp = 0;
- }
- if (left_type[0]) {
- h->left_cbp |= ((h->cbp_table[left_xy[0]]>>((left_block[0]&(~1))+1))&0x1) << 1;
- }
- if (left_type[1]) {
- h->left_cbp |= ((h->cbp_table[left_xy[1]]>>((left_block[2]&(~1))+1))&0x1) << 3;
- }
- }
-
-#if 1
- if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){
- int list;
- for(list=0; list<h->list_count; list++){
- if(!USES_LIST(mb_type, list) && !IS_DIRECT(mb_type) && !h->deblocking_filter){
- /*if(!h->mv_cache_clean[list]){
- memset(h->mv_cache [list], 0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all?
- memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t));
- h->mv_cache_clean[list]= 1;
- }*/
- continue;
- }
- h->mv_cache_clean[list]= 0;
-
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;
- const int b8_xy= h->mb2b8_xy[top_xy] + h->b8_stride;
- *(uint32_t*)h->mv_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 0];
- *(uint32_t*)h->mv_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 1];
- *(uint32_t*)h->mv_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 2];
- *(uint32_t*)h->mv_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 3];
- h->ref_cache[list][scan8[0] + 0 - 1*8]=
- h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][b8_xy + 0];
- h->ref_cache[list][scan8[0] + 2 - 1*8]=
- h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][b8_xy + 1];
- }else{
- *(uint32_t*)h->mv_cache [list][scan8[0] + 0 - 1*8]=
- *(uint32_t*)h->mv_cache [list][scan8[0] + 1 - 1*8]=
- *(uint32_t*)h->mv_cache [list][scan8[0] + 2 - 1*8]=
- *(uint32_t*)h->mv_cache [list][scan8[0] + 3 - 1*8]= 0;
- *(uint32_t*)&h->ref_cache[list][scan8[0] + 0 - 1*8]= ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101;
- }
-
- for(i=0; i<2; i++){
- int cache_idx = scan8[0] - 1 + i*2*8;
- if(USES_LIST(left_type[i], list)){
- const int b_xy= h->mb2b_xy[left_xy[i]] + 3;
- const int b8_xy= h->mb2b8_xy[left_xy[i]] + 1;
- *(uint32_t*)h->mv_cache[list][cache_idx ]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0+i*2]];
- *(uint32_t*)h->mv_cache[list][cache_idx+8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1+i*2]];
- h->ref_cache[list][cache_idx ]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[0+i*2]>>1)];
- h->ref_cache[list][cache_idx+8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[1+i*2]>>1)];
- }else{
- *(uint32_t*)h->mv_cache [list][cache_idx ]=
- *(uint32_t*)h->mv_cache [list][cache_idx+8]= 0;
- h->ref_cache[list][cache_idx ]=
- h->ref_cache[list][cache_idx+8]= left_type[i] ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
- }
-
- if(for_deblock || ((IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred) && !FRAME_MBAFF))
- continue;
-
- if(USES_LIST(topleft_type, list)){
- const int b_xy = h->mb2b_xy[topleft_xy] + 3 + h->b_stride + (topleft_partition & 2*h->b_stride);
- const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + (topleft_partition & h->b8_stride);
- *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];
- h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy];
- }else{
- *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0;
- h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
-
- if(USES_LIST(topright_type, list)){
- const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride;
- const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride;
- *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];
- h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy];
- }else{
- *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0;
- h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;
- }
-
- if((IS_SKIP(mb_type) || IS_DIRECT(mb_type)) && !FRAME_MBAFF)
- continue;
-
- h->ref_cache[list][scan8[5 ]+1] =
- h->ref_cache[list][scan8[7 ]+1] =
- h->ref_cache[list][scan8[13]+1] = //FIXME remove past 3 (init somewhere else)
- h->ref_cache[list][scan8[4 ]] =
- h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE;
- *(uint32_t*)h->mv_cache [list][scan8[5 ]+1]=
- *(uint32_t*)h->mv_cache [list][scan8[7 ]+1]=
- *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else)
- *(uint32_t*)h->mv_cache [list][scan8[4 ]]=
- *(uint32_t*)h->mv_cache [list][scan8[12]]= 0;
-
- if( h->pps.cabac ) {
- /* XXX beurk, Load mvd */
- if(USES_LIST(top_type, list)){
- const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;
- *(uint32_t*)h->mvd_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 0];
- *(uint32_t*)h->mvd_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 1];
- *(uint32_t*)h->mvd_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 2];
- *(uint32_t*)h->mvd_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 3];
- }else{
- *(uint32_t*)h->mvd_cache [list][scan8[0] + 0 - 1*8]=
- *(uint32_t*)h->mvd_cache [list][scan8[0] + 1 - 1*8]=
- *(uint32_t*)h->mvd_cache [list][scan8[0] + 2 - 1*8]=
- *(uint32_t*)h->mvd_cache [list][scan8[0] + 3 - 1*8]= 0;
- }
- if(USES_LIST(left_type[0], list)){
- const int b_xy= h->mb2b_xy[left_xy[0]] + 3;
- *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[0]];
- *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[1]];
- }else{
- *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 0*8]=
- *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 1*8]= 0;
- }
- if(USES_LIST(left_type[1], list)){
- const int b_xy= h->mb2b_xy[left_xy[1]] + 3;
- *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[2]];
- *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[3]];
- }else{
- *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 2*8]=
- *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 3*8]= 0;
- }
- *(uint32_t*)h->mvd_cache [list][scan8[5 ]+1]=
- *(uint32_t*)h->mvd_cache [list][scan8[7 ]+1]=
- *(uint32_t*)h->mvd_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else)
- *(uint32_t*)h->mvd_cache [list][scan8[4 ]]=
- *(uint32_t*)h->mvd_cache [list][scan8[12]]= 0;
-
- if(h->slice_type_nos == FF_B_TYPE){
- fill_rectangle(&h->direct_cache[scan8[0]], 4, 4, 8, 0, 1);
-
- if(IS_DIRECT(top_type)){
- *(uint32_t*)&h->direct_cache[scan8[0] - 1*8]= 0x01010101;
- }else if(IS_8X8(top_type)){
- int b8_xy = h->mb2b8_xy[top_xy] + h->b8_stride;
- h->direct_cache[scan8[0] + 0 - 1*8]= h->direct_table[b8_xy];
- h->direct_cache[scan8[0] + 2 - 1*8]= h->direct_table[b8_xy + 1];
- }else{
- *(uint32_t*)&h->direct_cache[scan8[0] - 1*8]= 0;
- }
-
- if(IS_DIRECT(left_type[0]))
- h->direct_cache[scan8[0] - 1 + 0*8]= 1;
- else if(IS_8X8(left_type[0]))
- h->direct_cache[scan8[0] - 1 + 0*8]= h->direct_table[h->mb2b8_xy[left_xy[0]] + 1 + h->b8_stride*(left_block[0]>>1)];
- else
- h->direct_cache[scan8[0] - 1 + 0*8]= 0;
-
- if(IS_DIRECT(left_type[1]))
- h->direct_cache[scan8[0] - 1 + 2*8]= 1;
- else if(IS_8X8(left_type[1]))
- h->direct_cache[scan8[0] - 1 + 2*8]= h->direct_table[h->mb2b8_xy[left_xy[1]] + 1 + h->b8_stride*(left_block[2]>>1)];
- else
- h->direct_cache[scan8[0] - 1 + 2*8]= 0;
- }
- }
-
- if(FRAME_MBAFF){
-#define MAP_MVS\
- MAP_F2F(scan8[0] - 1 - 1*8, topleft_type)\
- MAP_F2F(scan8[0] + 0 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 1 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 2 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 3 - 1*8, top_type)\
- MAP_F2F(scan8[0] + 4 - 1*8, topright_type)\
- MAP_F2F(scan8[0] - 1 + 0*8, left_type[0])\
- MAP_F2F(scan8[0] - 1 + 1*8, left_type[0])\
- MAP_F2F(scan8[0] - 1 + 2*8, left_type[1])\
- MAP_F2F(scan8[0] - 1 + 3*8, left_type[1])
- if(MB_FIELD){
-#define MAP_F2F(idx, mb_type)\
- if(!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] <<= 1;\
- h->mv_cache[list][idx][1] /= 2;\
- h->mvd_cache[list][idx][1] /= 2;\
- }
- MAP_MVS
-#undef MAP_F2F
- }else{
-#define MAP_F2F(idx, mb_type)\
- if(IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0){\
- h->ref_cache[list][idx] >>= 1;\
- h->mv_cache[list][idx][1] <<= 1;\
- h->mvd_cache[list][idx][1] <<= 1;\
- }
- MAP_MVS
-#undef MAP_F2F
- }
- }
- }
- }
-#endif
-
- h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[0]);
-}
-
void ff_h264_write_back_intra_pred_mode(H264Context *h){
- const int mb_xy= h->mb_xy;
+ int8_t *mode= h->intra4x4_pred_mode + h->mb2br_xy[h->mb_xy];
- h->intra4x4_pred_mode[mb_xy][0]= h->intra4x4_pred_mode_cache[7+8*1];
- h->intra4x4_pred_mode[mb_xy][1]= h->intra4x4_pred_mode_cache[7+8*2];
- h->intra4x4_pred_mode[mb_xy][2]= h->intra4x4_pred_mode_cache[7+8*3];
- h->intra4x4_pred_mode[mb_xy][3]= h->intra4x4_pred_mode_cache[7+8*4];
- h->intra4x4_pred_mode[mb_xy][4]= h->intra4x4_pred_mode_cache[4+8*4];
- h->intra4x4_pred_mode[mb_xy][5]= h->intra4x4_pred_mode_cache[5+8*4];
- h->intra4x4_pred_mode[mb_xy][6]= h->intra4x4_pred_mode_cache[6+8*4];
+ AV_COPY32(mode, h->intra4x4_pred_mode_cache + 4 + 8*4);
+ mode[4]= h->intra4x4_pred_mode_cache[7+8*3];
+ mode[5]= h->intra4x4_pred_mode_cache[7+8*2];
+ mode[6]= h->intra4x4_pred_mode_cache[7+8*1];
}
/**
return mode;
}
-/**
- * gets the predicted intra4x4 prediction mode.
- */
-static inline int pred_intra_mode(H264Context *h, int n){
- const int index8= scan8[n];
- const int left= h->intra4x4_pred_mode_cache[index8 - 1];
- const int top = h->intra4x4_pred_mode_cache[index8 - 8];
- const int min= FFMIN(left, top);
-
- tprintf(h->s.avctx, "mode:%d %d min:%d\n", left ,top, min);
-
- if(min<0) return DC_PRED;
- else return min;
-}
-
-static inline void write_back_non_zero_count(H264Context *h){
- const int mb_xy= h->mb_xy;
-
- h->non_zero_count[mb_xy][0]= h->non_zero_count_cache[7+8*1];
- h->non_zero_count[mb_xy][1]= h->non_zero_count_cache[7+8*2];
- h->non_zero_count[mb_xy][2]= h->non_zero_count_cache[7+8*3];
- h->non_zero_count[mb_xy][3]= h->non_zero_count_cache[7+8*4];
- h->non_zero_count[mb_xy][4]= h->non_zero_count_cache[4+8*4];
- h->non_zero_count[mb_xy][5]= h->non_zero_count_cache[5+8*4];
- h->non_zero_count[mb_xy][6]= h->non_zero_count_cache[6+8*4];
-
- h->non_zero_count[mb_xy][9]= h->non_zero_count_cache[1+8*2];
- h->non_zero_count[mb_xy][8]= h->non_zero_count_cache[2+8*2];
- h->non_zero_count[mb_xy][7]= h->non_zero_count_cache[2+8*1];
-
- h->non_zero_count[mb_xy][12]=h->non_zero_count_cache[1+8*5];
- h->non_zero_count[mb_xy][11]=h->non_zero_count_cache[2+8*5];
- h->non_zero_count[mb_xy][10]=h->non_zero_count_cache[2+8*4];
-}
-
-/**
- * gets the predicted number of non-zero coefficients.
- * @param n block index
- */
-static inline int pred_non_zero_count(H264Context *h, int n){
- const int index8= scan8[n];
- const int left= h->non_zero_count_cache[index8 - 1];
- const 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;
-}
-
-static inline void write_back_motion(H264Context *h, int mb_type){
- MpegEncContext * const s = &h->s;
- const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride;
- const int b8_xy= 2*s->mb_x + 2*s->mb_y*h->b8_stride;
- int list;
-
- if(!USES_LIST(mb_type, 0))
- fill_rectangle(&s->current_picture.ref_index[0][b8_xy], 2, 2, h->b8_stride, (uint8_t)LIST_NOT_USED, 1);
-
- for(list=0; list<h->list_count; list++){
- int y;
- if(!USES_LIST(mb_type, list))
- continue;
-
- for(y=0; y<4; y++){
- *(uint64_t*)s->current_picture.motion_val[list][b_xy + 0 + y*h->b_stride]= *(uint64_t*)h->mv_cache[list][scan8[0]+0 + 8*y];
- *(uint64_t*)s->current_picture.motion_val[list][b_xy + 2 + y*h->b_stride]= *(uint64_t*)h->mv_cache[list][scan8[0]+2 + 8*y];
- }
- if( h->pps.cabac ) {
- if(IS_SKIP(mb_type))
- fill_rectangle(h->mvd_table[list][b_xy], 4, 4, h->b_stride, 0, 4);
- else
- for(y=0; y<4; y++){
- *(uint64_t*)h->mvd_table[list][b_xy + 0 + y*h->b_stride]= *(uint64_t*)h->mvd_cache[list][scan8[0]+0 + 8*y];
- *(uint64_t*)h->mvd_table[list][b_xy + 2 + y*h->b_stride]= *(uint64_t*)h->mvd_cache[list][scan8[0]+2 + 8*y];
- }
- }
-
- {
- int8_t *ref_index = &s->current_picture.ref_index[list][b8_xy];
- ref_index[0+0*h->b8_stride]= h->ref_cache[list][scan8[0]];
- ref_index[1+0*h->b8_stride]= h->ref_cache[list][scan8[4]];
- ref_index[0+1*h->b8_stride]= h->ref_cache[list][scan8[8]];
- ref_index[1+1*h->b8_stride]= h->ref_cache[list][scan8[12]];
- }
- }
-
- if(h->slice_type_nos == FF_B_TYPE && h->pps.cabac){
- if(IS_8X8(mb_type)){
- uint8_t *direct_table = &h->direct_table[b8_xy];
- direct_table[1+0*h->b8_stride] = IS_DIRECT(h->sub_mb_type[1]) ? 1 : 0;
- direct_table[0+1*h->b8_stride] = IS_DIRECT(h->sub_mb_type[2]) ? 1 : 0;
- direct_table[1+1*h->b8_stride] = IS_DIRECT(h->sub_mb_type[3]) ? 1 : 0;
- }
- }
-}
-
const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){
int i, si, di;
uint8_t *dst;
# if HAVE_FAST_64BIT
# define RS 7
for(i=0; i+1<length; i+=9){
- if(!((~*(const uint64_t*)(src+i) & (*(const uint64_t*)(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))
+ if(!((~AV_RN64A(src+i) & (AV_RN64A(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))
# else
# define RS 3
for(i=0; i+1<length; i+=5){
- if(!((~*(const uint32_t*)(src+i) & (*(const uint32_t*)(src+i) - 0x01000101U)) & 0x80008080U))
+ if(!((~AV_RN32A(src+i) & (AV_RN32A(src+i) - 0x01000101U)) & 0x80008080U))
# endif
continue;
if(i>0 && !src[i]) i--;
x_offset, y_offset, qpix_put, chroma_put);
if(h->use_weight == 2){
- int weight0 = h->implicit_weight[refn0][refn1];
+ int weight0 = h->implicit_weight[refn0][refn1][s->mb_y&1];
int weight1 = 64 - weight0;
luma_weight_avg( dest_y, tmp_y, h-> mb_linesize, 5, weight0, weight1, 0);
chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, 5, weight0, weight1, 0);
chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, 5, weight0, weight1, 0);
}else{
luma_weight_avg(dest_y, tmp_y, h->mb_linesize, h->luma_log2_weight_denom,
- h->luma_weight[0][refn0], h->luma_weight[1][refn1],
- h->luma_offset[0][refn0] + h->luma_offset[1][refn1]);
+ h->luma_weight[refn0][0][0] , h->luma_weight[refn1][1][0],
+ h->luma_weight[refn0][0][1] + h->luma_weight[refn1][1][1]);
chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom,
- h->chroma_weight[0][refn0][0], h->chroma_weight[1][refn1][0],
- h->chroma_offset[0][refn0][0] + h->chroma_offset[1][refn1][0]);
+ h->chroma_weight[refn0][0][0][0] , h->chroma_weight[refn1][1][0][0],
+ h->chroma_weight[refn0][0][0][1] + h->chroma_weight[refn1][1][0][1]);
chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom,
- h->chroma_weight[0][refn0][1], h->chroma_weight[1][refn1][1],
- h->chroma_offset[0][refn0][1] + h->chroma_offset[1][refn1][1]);
+ h->chroma_weight[refn0][0][1][0] , h->chroma_weight[refn1][1][1][0],
+ h->chroma_weight[refn0][0][1][1] + h->chroma_weight[refn1][1][1][1]);
}
}else{
int list = list1 ? 1 : 0;
qpix_put, chroma_put);
luma_weight_op(dest_y, h->mb_linesize, h->luma_log2_weight_denom,
- h->luma_weight[list][refn], h->luma_offset[list][refn]);
+ h->luma_weight[refn][list][0], h->luma_weight[refn][list][1]);
if(h->use_weight_chroma){
chroma_weight_op(dest_cb, h->mb_uvlinesize, h->chroma_log2_weight_denom,
- h->chroma_weight[list][refn][0], h->chroma_offset[list][refn][0]);
+ h->chroma_weight[refn][list][0][0], h->chroma_weight[refn][list][0][1]);
chroma_weight_op(dest_cr, h->mb_uvlinesize, h->chroma_log2_weight_denom,
- h->chroma_weight[list][refn][1], h->chroma_offset[list][refn][1]);
+ h->chroma_weight[refn][list][1][0], h->chroma_weight[refn][list][1][1]);
}
}
}
h264_weight_func *weight_op, h264_biweight_func *weight_avg,
int list0, int list1){
if((h->use_weight==2 && list0 && list1
- && (h->implicit_weight[ h->ref_cache[0][scan8[n]] ][ h->ref_cache[1][scan8[n]] ] != 32))
+ && (h->implicit_weight[ h->ref_cache[0][scan8[n]] ][ h->ref_cache[1][scan8[n]] ][h->s.mb_y&1] != 32))
|| h->use_weight==1)
mc_part_weighted(h, n, square, chroma_height, delta, dest_y, dest_cb, dest_cr,
x_offset, y_offset, qpix_put, chroma_put,
if(IS_16X16(mb_type)){
mc_part(h, 0, 1, 8, 0, dest_y, dest_cb, dest_cr, 0, 0,
qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0],
- &weight_op[0], &weight_avg[0],
+ weight_op, weight_avg,
IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1));
}else if(IS_16X8(mb_type)){
mc_part(h, 0, 0, 4, 8, dest_y, dest_cb, dest_cr, 0, 0,
prefetch_motion(h, 1);
}
-static av_cold void init_cavlc_level_tab(void){
- int suffix_length, mask;
- unsigned 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;
- }
- }
- }
-}
-
-static av_cold void decode_init_vlc(void){
- static int done = 0;
-
- if (!done) {
- int i;
- int offset;
- done = 1;
-
- chroma_dc_coeff_token_vlc.table = chroma_dc_coeff_token_vlc_table;
- chroma_dc_coeff_token_vlc.table_allocated = chroma_dc_coeff_token_vlc_table_size;
- init_vlc(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5,
- &chroma_dc_coeff_token_len [0], 1, 1,
- &chroma_dc_coeff_token_bits[0], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
-
- offset = 0;
- for(i=0; i<4; i++){
- coeff_token_vlc[i].table = coeff_token_vlc_tables+offset;
- coeff_token_vlc[i].table_allocated = coeff_token_vlc_tables_size[i];
- init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17,
- &coeff_token_len [i][0], 1, 1,
- &coeff_token_bits[i][0], 1, 1,
- 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].table = chroma_dc_total_zeros_vlc_tables[i];
- chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size;
- init_vlc(&chroma_dc_total_zeros_vlc[i],
- 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,
- INIT_VLC_USE_NEW_STATIC);
- }
- for(i=0; i<15; i++){
- total_zeros_vlc[i].table = total_zeros_vlc_tables[i];
- total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;
- init_vlc(&total_zeros_vlc[i],
- TOTAL_ZEROS_VLC_BITS, 16,
- &total_zeros_len [i][0], 1, 1,
- &total_zeros_bits[i][0], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
- }
-
- for(i=0; i<6; i++){
- run_vlc[i].table = run_vlc_tables[i];
- run_vlc[i].table_allocated = run_vlc_tables_size;
- init_vlc(&run_vlc[i],
- RUN_VLC_BITS, 7,
- &run_len [i][0], 1, 1,
- &run_bits[i][0], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
- }
- run7_vlc.table = run7_vlc_table,
- run7_vlc.table_allocated = run7_vlc_table_size;
- init_vlc(&run7_vlc, RUN7_VLC_BITS, 16,
- &run_len [6][0], 1, 1,
- &run_bits[6][0], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
-
- init_cavlc_level_tab();
- }
-}
static void free_tables(H264Context *h){
int i;
av_freep(&h->non_zero_count);
av_freep(&h->slice_table_base);
h->slice_table= NULL;
+ av_freep(&h->list_counts);
av_freep(&h->mb2b_xy);
- av_freep(&h->mb2b8_xy);
+ av_freep(&h->mb2br_xy);
for(i = 0; i < MAX_THREADS; i++) {
hx = h->thread_context[i];
static void init_dequant8_coeff_table(H264Context *h){
int i,q,x;
- const int transpose = (h->s.dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly
+ const int transpose = (h->h264dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly
h->dequant8_coeff[0] = h->dequant8_buffer[0];
h->dequant8_coeff[1] = h->dequant8_buffer[1];
static void init_dequant4_coeff_table(H264Context *h){
int i,j,q,x;
- const int transpose = (h->s.dsp.h264_idct_add != ff_h264_idct_add_c); //FIXME ugly
+ const int transpose = (h->h264dsp.h264_idct_add != ff_h264_idct_add_c); //FIXME ugly
for(i=0; i<6; i++ ){
h->dequant4_coeff[i] = h->dequant4_buffer[i];
for(j=0; j<i; j++){
int ff_h264_alloc_tables(H264Context *h){
MpegEncContext * const s = &h->s;
const int big_mb_num= s->mb_stride * (s->mb_height+1);
+ const int row_mb_num= 2*s->mb_stride*s->avctx->thread_count;
int x,y;
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, row_mb_num * 8 * sizeof(uint8_t), fail)
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t), fail)
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count , big_mb_num * 32 * sizeof(uint8_t), fail)
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base), fail)
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table, big_mb_num * sizeof(uint16_t), fail)
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t), fail)
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t), fail);
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t), fail);
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 32*big_mb_num * sizeof(uint8_t) , fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 16*row_mb_num * sizeof(uint8_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 16*row_mb_num * sizeof(uint8_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 4*big_mb_num * sizeof(uint8_t) , fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts, big_mb_num * sizeof(uint8_t), fail)
memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base));
h->slice_table= h->slice_table_base + s->mb_stride*2 + 1;
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy , big_mb_num * sizeof(uint32_t), fail);
- FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b8_xy , big_mb_num * sizeof(uint32_t), fail);
+ FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2br_xy , big_mb_num * sizeof(uint32_t), fail);
for(y=0; y<s->mb_height; y++){
for(x=0; x<s->mb_width; x++){
const int mb_xy= x + y*s->mb_stride;
const int b_xy = 4*x + 4*y*h->b_stride;
- const int b8_xy= 2*x + 2*y*h->b8_stride;
h->mb2b_xy [mb_xy]= b_xy;
- h->mb2b8_xy[mb_xy]= b8_xy;
+ h->mb2br_xy[mb_xy]= 8*(FMO ? mb_xy : (mb_xy % (2*s->mb_stride)));
}
}
/**
* Mimic alloc_tables(), but for every context thread.
*/
-static void clone_tables(H264Context *dst, H264Context *src){
- dst->intra4x4_pred_mode = src->intra4x4_pred_mode;
+static void clone_tables(H264Context *dst, H264Context *src, int i){
+ MpegEncContext * const s = &src->s;
+ dst->intra4x4_pred_mode = src->intra4x4_pred_mode + i*8*2*s->mb_stride;
dst->non_zero_count = src->non_zero_count;
dst->slice_table = src->slice_table;
dst->cbp_table = src->cbp_table;
dst->mb2b_xy = src->mb2b_xy;
- dst->mb2b8_xy = src->mb2b8_xy;
+ dst->mb2br_xy = src->mb2br_xy;
dst->chroma_pred_mode_table = src->chroma_pred_mode_table;
- dst->mvd_table[0] = src->mvd_table[0];
- dst->mvd_table[1] = src->mvd_table[1];
+ dst->mvd_table[0] = src->mvd_table[0] + i*8*2*s->mb_stride;
+ dst->mvd_table[1] = src->mvd_table[1] + i*8*2*s->mb_stride;
dst->direct_table = src->direct_table;
+ dst->list_counts = src->list_counts;
dst->s.obmc_scratchpad = NULL;
ff_h264_pred_init(&dst->hpc, src->s.codec_id);
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail)
FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t), fail)
+ h->ref_cache[0][scan8[5 ]+1] = h->ref_cache[0][scan8[7 ]+1] = h->ref_cache[0][scan8[13]+1] =
+ h->ref_cache[1][scan8[5 ]+1] = h->ref_cache[1][scan8[7 ]+1] = h->ref_cache[1][scan8[13]+1] = PART_NOT_AVAILABLE;
+
return 0;
fail:
return -1; // free_tables will clean up for us
}
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size);
+
static av_cold void common_init(H264Context *h){
MpegEncContext * const s = &h->s;
s->height = s->avctx->height;
s->codec_id= s->avctx->codec->id;
+ ff_h264dsp_init(&h->h264dsp);
ff_h264_pred_init(&h->hpc, s->codec_id);
h->dequant_coeff_pps= -1;
avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
- decode_init_vlc();
-
- if(avctx->extradata_size > 0 && avctx->extradata &&
- *(char *)avctx->extradata == 1){
- h->is_avc = 1;
- h->got_avcC = 0;
- } else {
- h->is_avc = 0;
- }
+ ff_h264_decode_init_vlc();
h->thread_context[0] = h;
h->outputed_poc = INT_MIN;
h->prev_poc_msb= 1<<16;
+ h->x264_build = -1;
ff_h264_reset_sei(h);
if(avctx->codec_id == CODEC_ID_H264){
if(avctx->ticks_per_frame == 1){
}
avctx->ticks_per_frame = 2;
}
+
+ if(avctx->extradata_size > 0 && avctx->extradata && *(char *)avctx->extradata == 1){
+ int i, cnt, nalsize;
+ unsigned char *p = avctx->extradata;
+
+ h->is_avc = 1;
+
+ if(avctx->extradata_size < 7) {
+ av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
+ return -1;
+ }
+ /* sps and pps in the avcC always have length coded with 2 bytes,
+ so put a fake nal_length_size = 2 while parsing them */
+ h->nal_length_size = 2;
+ // Decode sps from avcC
+ cnt = *(p+5) & 0x1f; // Number of sps
+ p += 6;
+ for (i = 0; i < cnt; i++) {
+ nalsize = AV_RB16(p) + 2;
+ if(decode_nal_units(h, p, nalsize) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i);
+ return -1;
+ }
+ p += nalsize;
+ }
+ // Decode pps from avcC
+ cnt = *(p++); // Number of pps
+ for (i = 0; i < cnt; i++) {
+ nalsize = AV_RB16(p) + 2;
+ if(decode_nal_units(h, p, nalsize) != nalsize) {
+ av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i);
+ return -1;
+ }
+ p += nalsize;
+ }
+ // Now store right nal length size, that will be use to parse all other nals
+ h->nal_length_size = ((*(((char*)(avctx->extradata))+4))&0x03)+1;
+ } else {
+ h->is_avc = 0;
+ if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0)
+ return -1;
+ }
+ if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames < h->sps.num_reorder_frames){
+ s->avctx->has_b_frames = h->sps.num_reorder_frames;
+ s->low_delay = 0;
+ }
+
return 0;
}
if(!h->thread_context[i]->s.obmc_scratchpad)
h->thread_context[i]->s.obmc_scratchpad = av_malloc(16*2*s->linesize + 8*2*s->uvlinesize);
- /* some macroblocks will be accessed before they're available */
- if(FRAME_MBAFF || s->avctx->thread_count > 1)
- memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(*h->slice_table));
+ /* some macroblocks can be accessed before they're available in case of lost slices, mbaff or threading*/
+ memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(*h->slice_table));
// s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1;
static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int simple){
MpegEncContext * const s = &h->s;
- int i;
- int step = 1;
- int offset = 1;
- int uvoffset= 1;
+ uint8_t *top_border;
int top_idx = 1;
- int skiplast= 0;
src_y -= linesize;
src_cb -= uvlinesize;
if(!simple && FRAME_MBAFF){
if(s->mb_y&1){
- offset = MB_MBAFF ? 1 : 17;
- uvoffset= MB_MBAFF ? 1 : 9;
- if(!MB_MBAFF){
- *(uint64_t*)(h->top_borders[0][s->mb_x]+ 0)= *(uint64_t*)(src_y + 15*linesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+ 8)= *(uint64_t*)(src_y +8+15*linesize);
- if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+7*uvlinesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+7*uvlinesize);
- }
- }
- }else{
if(!MB_MBAFF){
- h->left_border[0]= h->top_borders[0][s->mb_x][15];
+ top_border = h->top_borders[0][s->mb_x];
+ AV_COPY128(top_border, src_y + 15*linesize);
if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7 ];
- h->left_border[34+18]= h->top_borders[0][s->mb_x][16+8+7];
+ AV_COPY64(top_border+16, src_cb+7*uvlinesize);
+ AV_COPY64(top_border+24, src_cr+7*uvlinesize);
}
- skiplast= 1;
}
- offset =
- uvoffset=
- top_idx = MB_MBAFF ? 0 : 1;
- }
- step= MB_MBAFF ? 2 : 1;
+ }else if(MB_MBAFF){
+ top_idx = 0;
+ }else
+ return;
}
+ top_border = h->top_borders[top_idx][s->mb_x];
// There are two lines saved, the line above the the top macroblock of a pair,
// and the line above the bottom macroblock
- h->left_border[offset]= h->top_borders[top_idx][s->mb_x][15];
- for(i=1; i<17 - skiplast; i++){
- h->left_border[offset+i*step]= src_y[15+i* linesize];
- }
-
- *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize);
- *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize);
+ AV_COPY128(top_border, src_y + 16*linesize);
if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- h->left_border[uvoffset+34 ]= h->top_borders[top_idx][s->mb_x][16+7];
- h->left_border[uvoffset+34+18]= h->top_borders[top_idx][s->mb_x][24+7];
- for(i=1; i<9 - skiplast; i++){
- h->left_border[uvoffset+34 +i*step]= src_cb[7+i*uvlinesize];
- h->left_border[uvoffset+34+18+i*step]= src_cr[7+i*uvlinesize];
- }
- *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize);
- *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24)= *(uint64_t*)(src_cr+8*uvlinesize);
+ AV_COPY64(top_border+16, src_cb+8*uvlinesize);
+ AV_COPY64(top_border+24, src_cr+8*uvlinesize);
}
}
static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg, int simple){
MpegEncContext * const s = &h->s;
- int temp8, i;
- uint64_t temp64;
int deblock_left;
int deblock_top;
- int mb_xy;
- int step = 1;
- int offset = 1;
- int uvoffset= 1;
int top_idx = 1;
+ uint8_t *top_border_m1;
+ uint8_t *top_border;
if(!simple && FRAME_MBAFF){
if(s->mb_y&1){
- offset = MB_MBAFF ? 1 : 17;
- uvoffset= MB_MBAFF ? 1 : 9;
+ if(!MB_MBAFF)
+ return;
}else{
- offset =
- uvoffset=
top_idx = MB_MBAFF ? 0 : 1;
}
- step= MB_MBAFF ? 2 : 1;
}
if(h->deblocking_filter == 2) {
- mb_xy = h->mb_xy;
- deblock_left = h->slice_table[mb_xy] == h->slice_table[mb_xy - 1];
- deblock_top = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy];
+ deblock_left = h->left_type[0];
+ deblock_top = h->top_type;
} else {
deblock_left = (s->mb_x > 0);
deblock_top = (s->mb_y > !!MB_FIELD);
src_cb -= uvlinesize + 1;
src_cr -= uvlinesize + 1;
-#define XCHG(a,b,t,xchg)\
-t= a;\
-if(xchg)\
- a= b;\
-b= t;
+ top_border_m1 = h->top_borders[top_idx][s->mb_x-1];
+ top_border = h->top_borders[top_idx][s->mb_x];
- if(deblock_left){
- for(i = !deblock_top; i<16; i++){
- XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, xchg);
- }
- XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, 1);
- }
+#define XCHG(a,b,xchg)\
+if (xchg) AV_SWAP64(b,a);\
+else AV_COPY64(b,a);
if(deblock_top){
- XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg);
- XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1);
+ if(deblock_left){
+ XCHG(top_border_m1+8, src_y -7, 1);
+ }
+ XCHG(top_border+0, src_y +1, xchg);
+ XCHG(top_border+8, src_y +9, 1);
if(s->mb_x+1 < s->mb_width){
- XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1);
+ XCHG(h->top_borders[top_idx][s->mb_x+1], src_y +17, 1);
}
}
if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- if(deblock_left){
- for(i = !deblock_top; i<8; i++){
- XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, xchg);
- XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, xchg);
- }
- XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, 1);
- XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, 1);
- }
if(deblock_top){
- XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1);
- XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1);
+ if(deblock_left){
+ XCHG(top_border_m1+16, src_cb -7, 1);
+ XCHG(top_border_m1+24, src_cr -7, 1);
+ }
+ XCHG(top_border+16, src_cb+1, 1);
+ XCHG(top_border+24, src_cr+1, 1);
}
}
}
s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + 64, s->linesize, 4);
s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + 64, dest_cr - dest_cb, 2);
+ h->list_counts[mb_xy]= h->list_count;
+
if (!simple && MB_FIELD) {
linesize = h->mb_linesize = s->linesize * 2;
uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
idct_dc_add =
idct_add = s->dsp.add_pixels8;
}else{
- idct_dc_add = s->dsp.h264_idct8_dc_add;
- idct_add = s->dsp.h264_idct8_add;
+ idct_dc_add = h->h264dsp.h264_idct8_dc_add;
+ idct_add = h->h264dsp.h264_idct8_add;
}
for(i=0; i<16; i+=4){
uint8_t * const ptr= dest_y + block_offset[i];
idct_dc_add =
idct_add = s->dsp.add_pixels4;
}else{
- idct_dc_add = s->dsp.h264_idct_dc_add;
- idct_add = s->dsp.h264_idct_add;
+ idct_dc_add = h->h264dsp.h264_idct_dc_add;
+ idct_add = h->h264dsp.h264_idct_add;
}
for(i=0; i<16; i++){
uint8_t * const ptr= dest_y + block_offset[i];
else
idct_add (ptr, h->mb + i*16, linesize);
}else
- svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0);
+ ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0);
}
}
}
if(!transform_bypass)
h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[0][s->qscale][0]);
}else
- svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);
+ ff_svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);
}
if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple);
hl_motion(h, dest_y, dest_cb, dest_cr,
s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
- s->dsp.weight_h264_pixels_tab, s->dsp.biweight_h264_pixels_tab);
+ h->h264dsp.weight_h264_pixels_tab, h->h264dsp.biweight_h264_pixels_tab);
}
}
}
}else{
- s->dsp.h264_idct_add16intra(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
+ h->h264dsp.h264_idct_add16intra(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
}
}else if(h->cbp&15){
if(transform_bypass){
}
}else{
if(IS_8x8DCT(mb_type)){
- s->dsp.h264_idct8_add4(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
+ h->h264dsp.h264_idct8_add4(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
}else{
- s->dsp.h264_idct_add16(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
+ h->h264dsp.h264_idct_add16(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);
}
}
}
for(i=0; i<16; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below
uint8_t * const ptr= dest_y + block_offset[i];
- svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);
+ ff_svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);
}
}
}
chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);
chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);
if(is_h264){
- idct_add = s->dsp.h264_idct_add;
- idct_dc_add = s->dsp.h264_idct_dc_add;
+ idct_add = h->h264dsp.h264_idct_add;
+ idct_dc_add = h->h264dsp.h264_idct_dc_add;
for(i=16; i<16+8; i++){
if(h->non_zero_count_cache[ scan8[i] ])
idct_add (dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize);
for(i=16; i<16+8; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i];
- svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2);
+ ff_svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2);
}
}
}
}
if(h->cbp || IS_INTRA(mb_type))
s->dsp.clear_blocks(h->mb);
-
- if(h->deblocking_filter) {
- backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple);
- fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb
- h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
- h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
- if (!simple && FRAME_MBAFF) {
- ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
- } else {
- ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
- }
- }
}
/**
luma_weight_flag= get_bits1(&s->gb);
if(luma_weight_flag){
- h->luma_weight[list][i]= get_se_golomb(&s->gb);
- h->luma_offset[list][i]= get_se_golomb(&s->gb);
- if( h->luma_weight[list][i] != luma_def
- || h->luma_offset[list][i] != 0) {
+ h->luma_weight[i][list][0]= get_se_golomb(&s->gb);
+ h->luma_weight[i][list][1]= get_se_golomb(&s->gb);
+ if( h->luma_weight[i][list][0] != luma_def
+ || h->luma_weight[i][list][1] != 0) {
h->use_weight= 1;
h->luma_weight_flag[list]= 1;
}
}else{
- h->luma_weight[list][i]= luma_def;
- h->luma_offset[list][i]= 0;
+ h->luma_weight[i][list][0]= luma_def;
+ h->luma_weight[i][list][1]= 0;
}
if(CHROMA){
if(chroma_weight_flag){
int j;
for(j=0; j<2; j++){
- h->chroma_weight[list][i][j]= get_se_golomb(&s->gb);
- h->chroma_offset[list][i][j]= get_se_golomb(&s->gb);
- if( h->chroma_weight[list][i][j] != chroma_def
- || h->chroma_offset[list][i][j] != 0) {
+ h->chroma_weight[i][list][j][0]= get_se_golomb(&s->gb);
+ h->chroma_weight[i][list][j][1]= get_se_golomb(&s->gb);
+ if( h->chroma_weight[i][list][j][0] != chroma_def
+ || h->chroma_weight[i][list][j][1] != 0) {
h->use_weight_chroma= 1;
h->chroma_weight_flag[list]= 1;
}
}else{
int j;
for(j=0; j<2; j++){
- h->chroma_weight[list][i][j]= chroma_def;
- h->chroma_offset[list][i][j]= 0;
+ h->chroma_weight[i][list][j][0]= chroma_def;
+ h->chroma_weight[i][list][j][1]= 0;
}
}
}
return 0;
}
-static void implicit_weight_table(H264Context *h){
+/**
+ * Initialize implicit_weight table.
+ * @param field, 0/1 initialize the weight for interlaced MBAFF
+ * -1 initializes the rest
+ */
+static void implicit_weight_table(H264Context *h, int field){
MpegEncContext * const s = &h->s;
- int ref0, ref1, i;
- int cur_poc = s->current_picture_ptr->poc;
+ int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1;
for (i = 0; i < 2; i++) {
h->luma_weight_flag[i] = 0;
h->chroma_weight_flag[i] = 0;
}
- if( h->ref_count[0] == 1 && h->ref_count[1] == 1
+ if(field < 0){
+ cur_poc = s->current_picture_ptr->poc;
+ if( h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF
&& h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){
h->use_weight= 0;
h->use_weight_chroma= 0;
return;
}
-
+ ref_start= 0;
+ ref_count0= h->ref_count[0];
+ ref_count1= h->ref_count[1];
+ }else{
+ cur_poc = s->current_picture_ptr->field_poc[field];
+ ref_start= 16;
+ ref_count0= 16+2*h->ref_count[0];
+ ref_count1= 16+2*h->ref_count[1];
+ }
+
h->use_weight= 2;
h->use_weight_chroma= 2;
h->luma_log2_weight_denom= 5;
h->chroma_log2_weight_denom= 5;
- for(ref0=0; ref0 < h->ref_count[0]; ref0++){
+ for(ref0=ref_start; ref0 < ref_count0; ref0++){
int poc0 = h->ref_list[0][ref0].poc;
- for(ref1=0; ref1 < h->ref_count[1]; ref1++){
+ for(ref1=ref_start; ref1 < ref_count1; ref1++){
int poc1 = h->ref_list[1][ref1].poc;
int td = av_clip(poc1 - poc0, -128, 127);
+ int w= 32;
if(td){
int tb = av_clip(cur_poc - poc0, -128, 127);
int tx = (16384 + (FFABS(td) >> 1)) / td;
- int dist_scale_factor = av_clip((tb*tx + 32) >> 6, -1024, 1023) >> 2;
- if(dist_scale_factor < -64 || dist_scale_factor > 128)
- h->implicit_weight[ref0][ref1] = 32;
- else
- h->implicit_weight[ref0][ref1] = 64 - dist_scale_factor;
- }else
- h->implicit_weight[ref0][ref1] = 32;
+ int dist_scale_factor = (tb*tx + 32) >> 8;
+ if(dist_scale_factor >= -64 && dist_scale_factor <= 128)
+ w = 64 - dist_scale_factor;
+ }
+ if(field<0){
+ h->implicit_weight[ref0][ref1][0]=
+ h->implicit_weight[ref0][ref1][1]= w;
+ }else{
+ h->implicit_weight[ref0][ref1][field]=w;
+ }
}
}
}
* initialize scan tables
*/
static void init_scan_tables(H264Context *h){
- MpegEncContext * const s = &h->s;
int i;
- if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly
+ if(h->h264dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly
memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t));
memcpy(h-> field_scan, field_scan, 16*sizeof(uint8_t));
}else{
#undef T
}
}
- if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){
+ if(h->h264dsp.h264_idct8_add == ff_h264_idct8_add_c){
memcpy(h->zigzag_scan8x8, ff_zigzag_direct, 64*sizeof(uint8_t));
memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t));
memcpy(h->field_scan8x8, field_scan8x8, 64*sizeof(uint8_t));
h->slice_type_nos= slice_type & 3;
s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though
- if (s->pict_type == FF_B_TYPE && s0->last_picture_ptr == NULL) {
- av_log(h->s.avctx, AV_LOG_ERROR,
- "B picture before any references, skipping\n");
- return -1;
- }
pps_id= get_ue_golomb(&s->gb);
if(pps_id>=MAX_PPS_COUNT){
s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
h->b_stride= s->mb_width*4;
- h->b8_stride= s->mb_width*2;
s->width = 16*s->mb_width - 2*FFMIN(h->sps.crop_right, 7);
if(h->sps.frame_mbs_only_flag)
s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 3);
if (s->context_initialized
- && ( s->width != s->avctx->width || s->height != s->avctx->height)) {
+ && ( s->width != s->avctx->width || s->height != s->avctx->height
+ || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
if(h != h0)
return -1; // width / height changed during parallelized decoding
free_tables(h);
}
if(h->sps.timing_info_present_flag){
- s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale};
- if(h->x264_build > 0 && h->x264_build < 44)
- s->avctx->time_base.den *= 2;
+ int64_t den= h->sps.time_scale;
+ if(h->x264_build < 44U)
+ den *= 2;
av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
- s->avctx->time_base.num, s->avctx->time_base.den, 1<<30);
+ h->sps.num_units_in_tick, den, 1<<30);
}
s->avctx->pix_fmt = s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts);
s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
c->sps = h->sps;
c->pps = h->pps;
init_scan_tables(c);
- clone_tables(c, h);
+ clone_tables(c, h, i);
}
for(i = 0; i < s->avctx->thread_count; i++)
if( (h->pps.weighted_pred && h->slice_type_nos == FF_P_TYPE )
|| (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) )
pred_weight_table(h);
- else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE)
- implicit_weight_table(h);
- else {
+ else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE){
+ implicit_weight_table(h, -1);
+ }else {
h->use_weight = 0;
for (i = 0; i < 2; i++) {
h->luma_weight_flag[i] = 0;
if(h->nal_ref_idc)
ff_h264_decode_ref_pic_marking(h0, &s->gb);
- if(FRAME_MBAFF)
+ if(FRAME_MBAFF){
ff_h264_fill_mbaff_ref_list(h);
+ if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE){
+ implicit_weight_table(h, 0);
+ implicit_weight_table(h, 1);
+ }
+ }
+
if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
ff_h264_direct_dist_scale_factor(h);
ff_h264_direct_ref_list_init(h);
}
h->deblocking_filter = 1;
- h->slice_alpha_c0_offset = 0;
- h->slice_beta_offset = 0;
+ h->slice_alpha_c0_offset = 52;
+ h->slice_beta_offset = 52;
if( h->pps.deblocking_filter_parameters_present ) {
tmp= get_ue_golomb_31(&s->gb);
if(tmp > 2){
h->deblocking_filter^= 1; // 1<->0
if( h->deblocking_filter ) {
- h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1;
- h->slice_beta_offset = get_se_golomb(&s->gb) << 1;
+ h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1;
+ h->slice_beta_offset += get_se_golomb(&s->gb) << 1;
+ if( h->slice_alpha_c0_offset > 104U
+ || h->slice_beta_offset > 104U){
+ av_log(s->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset);
+ return -1;
+ }
}
}
return 1; // deblocking switched inside frame
}
}
+ h->qp_thresh= 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]);
#if 0 //FMO
if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)
}
for(j=0; j<2; j++){
+ int id_list[16];
int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j];
+ for(i=0; i<16; i++){
+ id_list[i]= 60;
+ if(h->ref_list[j][i].data[0]){
+ int k;
+ uint8_t *base= h->ref_list[j][i].base[0];
+ for(k=0; k<h->short_ref_count; k++)
+ if(h->short_ref[k]->base[0] == base){
+ id_list[i]= k;
+ break;
+ }
+ for(k=0; k<h->long_ref_count; k++)
+ if(h->long_ref[k] && h->long_ref[k]->base[0] == base){
+ id_list[i]= h->short_ref_count + k;
+ break;
+ }
+ }
+ }
+
ref2frm[0]=
ref2frm[1]= -1;
for(i=0; i<16; i++)
- ref2frm[i+2]= 4*h->ref_list[j][i].frame_num
+ ref2frm[i+2]= 4*id_list[i]
+(h->ref_list[j][i].reference&3);
ref2frm[18+0]=
ref2frm[18+1]= -1;
for(i=16; i<48; i++)
- ref2frm[i+4]= 4*h->ref_list[j][i].frame_num
+ ref2frm[i+4]= 4*id_list[(i-16)>>1]
+(h->ref_list[j][i].reference&3);
}
s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],
h->ref_count[0], h->ref_count[1],
s->qscale,
- h->deblocking_filter, h->slice_alpha_c0_offset/2, h->slice_beta_offset/2,
+ h->deblocking_filter, h->slice_alpha_c0_offset/2-26, h->slice_beta_offset/2-26,
h->use_weight,
h->use_weight==1 && h->use_weight_chroma ? "c" : "",
h->slice_type == FF_B_TYPE ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : ""
return 0;
}
-int ff_h264_get_slice_type(H264Context *h)
+int ff_h264_get_slice_type(const H264Context *h)
{
switch (h->slice_type) {
case FF_P_TYPE: return 0;
}
}
-/**
- *
- */
-static inline int get_level_prefix(GetBitContext *gb){
- unsigned int buf;
- int log;
-
- OPEN_READER(re, gb);
- UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
-
- 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);
- CLOSE_READER(re, gb);
-
- return log-1;
-}
-
-static inline int get_dct8x8_allowed(H264Context *h){
- if(h->sps.direct_8x8_inference_flag)
- return !(*(uint64_t*)h->sub_mb_type & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8 )*0x0001000100010001ULL));
- else
- return !(*(uint64_t*)h->sub_mb_type & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8|MB_TYPE_DIRECT2)*0x0001000100010001ULL));
-}
-
-/**
- * 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
- */
-static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
+static void loop_filter(H264Context *h){
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;
-
- //FIXME put trailing_onex into the context
-
- if(n == CHROMA_DC_BLOCK_INDEX){
- 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);
- 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;
- }
- }
-
- //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);
- return -1;
- }
-
- trailing_ones= coeff_token&3;
- tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
- assert(total_coeff<=16);
-
- i = show_bits(gb, 3);
- skip_bits(gb, trailing_ones);
- level[0] = 1-((i&4)>>1);
- level[1] = 1-((i&2) );
- level[2] = 1-((i&1)<<1);
-
- if(trailing_ones<total_coeff) {
- int mask, prefix;
- 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];
-
- skip_bits(gb, 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);
-
- //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)
- level_code= (prefix<<1) + get_bits1(gb); //part
- else
- level_code= prefix; //part
- }else if(prefix==14){
- if(suffix_length)
- level_code= (prefix<<1) + get_bits1(gb); //part
- else
- level_code= prefix + get_bits(gb, 4); //part
- }else{
- level_code= 30 + get_bits(gb, prefix-3); //part
- if(prefix>=16)
- level_code += (1<<(prefix-3))-4096;
- }
-
- if(trailing_ones < 3) level_code += 2;
-
- suffix_length = 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;
-
- suffix_length = 1;
- if(level_code + 3U > 6U)
- suffix_length++;
- level[trailing_ones]= level_code;
- }
+ uint8_t *dest_y, *dest_cb, *dest_cr;
+ int linesize, uvlinesize, mb_x, mb_y;
+ const int end_mb_y= s->mb_y + FRAME_MBAFF;
+ const int old_slice_type= h->slice_type;
- //remaining coefficients have suffix_length > 0
- for(i=trailing_ones+1;i<total_coeff;i++) {
- static const unsigned int suffix_limit[7] = {0,3,6,12,24,48,INT_MAX };
- int bitsi= show_bits(gb, LEVEL_TAB_BITS);
- level_code= cavlc_level_tab[suffix_length][bitsi][0];
-
- skip_bits(gb, 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 = (prefix<<suffix_length) + get_bits(gb, suffix_length);
- }else{
- level_code = (15<<suffix_length) + get_bits(gb, prefix-3);
- if(prefix>=16)
- level_code += (1<<(prefix-3))-4096;
+ if(h->deblocking_filter) {
+ for(mb_x= 0; mb_x<s->mb_width; mb_x++){
+ for(mb_y=end_mb_y - FRAME_MBAFF; mb_y<= end_mb_y; mb_y++){
+ int mb_xy, mb_type;
+ mb_xy = h->mb_xy = mb_x + mb_y*s->mb_stride;
+ h->slice_num= h->slice_table[mb_xy];
+ mb_type= s->current_picture.mb_type[mb_xy];
+ h->list_count= h->list_counts[mb_xy];
+
+ if(FRAME_MBAFF)
+ h->mb_mbaff = h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);
+
+ s->mb_x= mb_x;
+ s->mb_y= mb_y;
+ dest_y = s->current_picture.data[0] + (mb_x + mb_y * s->linesize ) * 16;
+ dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8;
+ dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8;
+ //FIXME simplify above
+
+ if (MB_FIELD) {
+ linesize = h->mb_linesize = s->linesize * 2;
+ uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
+ if(mb_y&1){ //FIXME move out of this function?
+ dest_y -= s->linesize*15;
+ dest_cb-= s->uvlinesize*7;
+ dest_cr-= s->uvlinesize*7;
+ }
+ } else {
+ linesize = h->mb_linesize = s->linesize;
+ uvlinesize = h->mb_uvlinesize = s->uvlinesize;
}
- mask= -(level_code&1);
- 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++;
- }
- }
-
- 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);
- else
- zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff-1 ].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 ];
+ backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0);
+ if(fill_filter_caches(h, mb_type))
+ continue;
+ h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
+ h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
- 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);
+ if (FRAME_MBAFF) {
+ ff_h264_filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
+ } else {
+ ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
+ }
}
- zeros_left -= run_before;
- coeff_num -= 1 + run_before;
- j= scantable[ coeff_num ];
-
- block[j]= (level[i] * qmul[j] + 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);
- return -1;
- }
-
- return 0;
+ h->slice_type= old_slice_type;
+ s->mb_x= 0;
+ s->mb_y= end_mb_y - FRAME_MBAFF;
+ h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
+ h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
}
static void predict_field_decoding_flag(H264Context *h){
MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
+ const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
int mb_type = (h->slice_table[mb_xy-1] == h->slice_num)
? s->current_picture.mb_type[mb_xy-1]
: (h->slice_table[mb_xy-s->mb_stride] == h->slice_num)
h->mb_mbaff = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
}
-/**
- * decodes a P_SKIP or B_SKIP macroblock
- */
-static void decode_mb_skip(H264Context *h){
+static int decode_slice(struct AVCodecContext *avctx, void *arg){
+ H264Context *h = *(void**)arg;
MpegEncContext * const s = &h->s;
- const int mb_xy= h->mb_xy;
- int mb_type=0;
-
- memset(h->non_zero_count[mb_xy], 0, 16);
- memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui
-
- if(MB_FIELD)
- mb_type|= MB_TYPE_INTERLACED;
+ const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
- if( h->slice_type_nos == FF_B_TYPE )
- {
- // just for fill_caches. pred_direct_motion will set the real mb_type
- mb_type|= MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP;
+ s->mb_skip_run= -1;
- fill_caches(h, mb_type, 0); //FIXME check what is needed and what not ...
- ff_h264_pred_direct_motion(h, &mb_type);
- mb_type|= MB_TYPE_SKIP;
- }
- else
- {
- int mx, my;
- mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP;
-
- fill_caches(h, mb_type, 0); //FIXME check what is needed and what not ...
- pred_pskip_motion(h, &mx, &my);
- fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
- fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
- }
+ h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME || s->codec_id != CODEC_ID_H264 ||
+ (CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
- write_back_motion(h, mb_type);
- s->current_picture.mb_type[mb_xy]= mb_type;
- s->current_picture.qscale_table[mb_xy]= s->qscale;
- h->slice_table[ mb_xy ]= h->slice_num;
- h->prev_mb_skipped= 1;
-}
+ if( h->pps.cabac ) {
+ /* realign */
+ align_get_bits( &s->gb );
-/**
- * decodes a macroblock
- * @returns 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
- */
-static int 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;
+ /* init cabac */
+ ff_init_cabac_states( &h->cabac);
+ ff_init_cabac_decoder( &h->cabac,
+ s->gb.buffer + get_bits_count(&s->gb)/8,
+ (get_bits_left(&s->gb) + 7)/8);
- mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+ ff_h264_init_cabac_states(h);
- 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(s->mb_skip_run==-1)
- s->mb_skip_run= get_ue_golomb(&s->gb);
-
- if (s->mb_skip_run--) {
- 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;
- }
- }
- if(FRAME_MBAFF){
- if( (s->mb_y&1) == 0 )
- h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
- }
+ for(;;){
+//START_TIMER
+ int ret = ff_h264_decode_mb_cabac(h);
+ int eos;
+//STOP_TIMER("decode_mb_cabac")
- h->prev_mb_skipped= 0;
+ if(ret>=0) ff_h264_hl_decode_mb(h);
- mb_type= get_ue_golomb(&s->gb);
- if(h->slice_type_nos == FF_B_TYPE){
- if(mb_type < 23){
- partition_count= b_mb_type_info[mb_type].partition_count;
- mb_type= b_mb_type_info[mb_type].type;
- }else{
- mb_type -= 23;
- goto decode_intra_mb;
- }
- }else if(h->slice_type_nos == FF_P_TYPE){
- if(mb_type < 5){
- partition_count= p_mb_type_info[mb_type].partition_count;
- mb_type= p_mb_type_info[mb_type].type;
- }else{
- mb_type -= 5;
- goto decode_intra_mb;
- }
- }else{
- assert(h->slice_type_nos == FF_I_TYPE);
- if(h->slice_type == FF_SI_TYPE && 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);
- return -1;
- }
- partition_count=0;
- cbp= i_mb_type_info[mb_type].cbp;
- h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;
- mb_type= i_mb_type_info[mb_type].type;
- }
+ if( ret >= 0 && FRAME_MBAFF ) { //FIXME optimal? or let mb_decode decode 16x32 ?
+ s->mb_y++;
- if(MB_FIELD)
- mb_type |= MB_TYPE_INTERLACED;
+ ret = ff_h264_decode_mb_cabac(h);
- h->slice_table[ mb_xy ]= h->slice_num;
+ if(ret>=0) ff_h264_hl_decode_mb(h);
+ s->mb_y--;
+ }
+ eos = get_cabac_terminate( &h->cabac );
- if(IS_INTRA_PCM(mb_type)){
- unsigned int x;
+ if((s->workaround_bugs & FF_BUG_TRUNCATED) && h->cabac.bytestream > h->cabac.bytestream_end + 2){
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ return 0;
+ }
+ if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+ return -1;
+ }
- // We assume these blocks are very rare so we do not optimize it.
- align_get_bits(&s->gb);
+ if( ++s->mb_x >= s->mb_width ) {
+ s->mb_x = 0;
+ loop_filter(h);
+ ff_draw_horiz_band(s, 16*s->mb_y, 16);
+ ++s->mb_y;
+ if(FIELD_OR_MBAFF_PICTURE) {
+ ++s->mb_y;
+ if(FRAME_MBAFF && s->mb_y < s->mb_height)
+ predict_field_decoding_flag(h);
+ }
+ }
- // The pixels are stored in the same order as levels in h->mb array.
- for(x=0; x < (CHROMA ? 384 : 256); x++){
- ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
+ if( eos || s->mb_y >= s->mb_height ) {
+ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+ return 0;
+ }
}
- // 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, 16);
+ } else {
+ for(;;){
+ int ret = ff_h264_decode_mb_cavlc(h);
- s->current_picture.mb_type[mb_xy]= mb_type;
- return 0;
- }
+ if(ret>=0) ff_h264_hl_decode_mb(h);
- if(MB_MBAFF){
- h->ref_count[0] <<= 1;
- h->ref_count[1] <<= 1;
- }
+ if(ret>=0 && FRAME_MBAFF){ //FIXME optimal? or let mb_decode decode 16x32 ?
+ s->mb_y++;
+ ret = ff_h264_decode_mb_cavlc(h);
- fill_caches(h, mb_type, 0);
-
- //mb_pred
- if(IS_INTRA(mb_type)){
- int pred_mode;
-// init_top_left_availability(h);
- if(IS_INTRA4x4(mb_type)){
- int i;
- int di = 1;
- if(dct8x8_allowed && get_bits1(&s->gb)){
- mb_type |= MB_TYPE_8x8DCT;
- di = 4;
+ if(ret>=0) ff_h264_hl_decode_mb(h);
+ s->mb_y--;
}
-// fill_intra4x4_pred_table(h);
- for(i=0; i<16; i+=di){
- int mode= pred_intra_mode(h, i);
+ if(ret<0){
+ av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+
+ return -1;
+ }
- if(!get_bits1(&s->gb)){
- const int rem_mode= get_bits(&s->gb, 3);
- mode = rem_mode + (rem_mode >= mode);
+ if(++s->mb_x >= s->mb_width){
+ s->mb_x=0;
+ loop_filter(h);
+ ff_draw_horiz_band(s, 16*s->mb_y, 16);
+ ++s->mb_y;
+ if(FIELD_OR_MBAFF_PICTURE) {
+ ++s->mb_y;
+ if(FRAME_MBAFF && s->mb_y < s->mb_height)
+ predict_field_decoding_flag(h);
}
+ if(s->mb_y >= s->mb_height){
+ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
- if(di==4)
- fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );
- else
- h->intra4x4_pred_mode_cache[ scan8[i] ] = mode;
- }
- ff_h264_write_back_intra_pred_mode(h);
- if( ff_h264_check_intra4x4_pred_mode(h) < 0)
- return -1;
- }else{
- h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode);
- if(h->intra16x16_pred_mode < 0)
- return -1;
- }
- if(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 if(partition_count==4){
- int i, j, sub_partition_count[4], list, ref[2][4];
+ if(get_bits_count(&s->gb) == s->gb.size_in_bits ) {
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
- if(h->slice_type_nos == FF_B_TYPE){
- for(i=0; i<4; i++){
- h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
- 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;
+ return 0;
+ }else{
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+
+ return -1;
+ }
}
- sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
- h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type;
}
- if( IS_DIRECT(h->sub_mb_type[0]) || IS_DIRECT(h->sub_mb_type[1])
- || IS_DIRECT(h->sub_mb_type[2]) || IS_DIRECT(h->sub_mb_type[3])) {
- ff_h264_pred_direct_motion(h, &mb_type);
- h->ref_cache[0][scan8[4]] =
- h->ref_cache[1][scan8[4]] =
- h->ref_cache[0][scan8[12]] =
- h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
- }
- }else{
- assert(h->slice_type_nos == FF_P_TYPE); //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){
- 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);
+
+ if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){
+ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
+ if(get_bits_count(&s->gb) == s->gb.size_in_bits ){
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+
+ return 0;
+ }else{
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+
return -1;
}
- sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
- h->sub_mb_type[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].type;
}
}
+ }
+
+#if 0
+ for(;s->mb_y < s->mb_height; s->mb_y++){
+ for(;s->mb_x < s->mb_width; s->mb_x++){
+ int ret= decode_mb(h);
+
+ ff_h264_hl_decode_mb(h);
+
+ if(ret<0){
+ av_log(s->avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+
+ return -1;
+ }
+
+ if(++s->mb_x >= s->mb_width){
+ s->mb_x=0;
+ if(++s->mb_y >= s->mb_height){
+ if(get_bits_count(s->gb) == s->gb.size_in_bits){
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
- for(list=0; list<h->list_count; list++){
- int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list];
- for(i=0; i<4; i++){
- if(IS_DIRECT(h->sub_mb_type[i])) continue;
- if(IS_DIR(h->sub_mb_type[i], 0, list)){
- unsigned int tmp;
- if(ref_count == 1){
- tmp= 0;
- }else if(ref_count == 2){
- tmp= get_bits1(&s->gb)^1;
+ return 0;
}else{
- tmp= get_ue_golomb_31(&s->gb);
- if(tmp>=ref_count){
- av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
- return -1;
- }
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
+
+ return -1;
}
- ref[list][i]= tmp;
- }else{
- //FIXME
- ref[list][i] = -1;
}
}
- }
- if(dct8x8_allowed)
- dct8x8_allowed = get_dct8x8_allowed(h);
+ if(get_bits_count(s->?gb) >= s->gb?.size_in_bits){
+ if(get_bits_count(s->gb) == s->gb.size_in_bits){
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
- for(list=0; list<h->list_count; list++){
- for(i=0; i<4; i++){
- if(IS_DIRECT(h->sub_mb_type[i])) {
- h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ];
- continue;
- }
- h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]=
- h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
-
- if(IS_DIR(h->sub_mb_type[i], 0, list)){
- const int sub_mb_type= h->sub_mb_type[i];
- const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
- for(j=0; j<sub_partition_count[i]; j++){
- int mx, my;
- const int index= 4*i + block_width*j;
- int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
- pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
- mx += get_se_golomb(&s->gb);
- my += get_se_golomb(&s->gb);
- tprintf(s->avctx, "final mv:%d %d\n", mx, my);
-
- if(IS_SUB_8X8(sub_mb_type)){
- mv_cache[ 1 ][0]=
- mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
- mv_cache[ 1 ][1]=
- mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
- }else if(IS_SUB_8X4(sub_mb_type)){
- mv_cache[ 1 ][0]= mx;
- mv_cache[ 1 ][1]= my;
- }else if(IS_SUB_4X8(sub_mb_type)){
- mv_cache[ 8 ][0]= mx;
- mv_cache[ 8 ][1]= my;
- }
- mv_cache[ 0 ][0]= mx;
- mv_cache[ 0 ][1]= my;
- }
+ return 0;
}else{
- uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];
- p[0] = p[1]=
- p[8] = p[9]= 0;
- }
- }
- }
- }else if(IS_DIRECT(mb_type)){
- ff_h264_pred_direct_motion(h, &mb_type);
- dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
- }else{
- int list, mx, my, i;
- //FIXME we should set ref_idx_l? to 0 if we use that later ...
- if(IS_16X16(mb_type)){
- for(list=0; list<h->list_count; list++){
- unsigned int val;
- if(IS_DIR(mb_type, 0, list)){
- if(h->ref_count[list]==1){
- val= 0;
- }else if(h->ref_count[list]==2){
- val= get_bits1(&s->gb)^1;
- }else{
- val= get_ue_golomb_31(&s->gb);
- if(val >= h->ref_count[list]){
- av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- 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);
- }
- }
- else if(IS_16X8(mb_type)){
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- if(h->ref_count[list] == 1){
- val= 0;
- }else if(h->ref_count[list] == 2){
- val= get_bits1(&s->gb)^1;
- }else{
- val= get_ue_golomb_31(&s->gb);
- if(val >= h->ref_count[list]){
- av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- return -1;
- }
- }
- }else
- val= LIST_NOT_USED&0xFF;
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);
- }
- }
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &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] + 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++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){ //FIXME optimize
- if(h->ref_count[list]==1){
- val= 0;
- }else if(h->ref_count[list]==2){
- val= get_bits1(&s->gb)^1;
- }else{
- val= get_ue_golomb_31(&s->gb);
- if(val >= h->ref_count[list]){
- av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- return -1;
- }
- }
- }else
- val= LIST_NOT_USED&0xFF;
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);
- }
- }
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &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] + 2*i ], 2, 4, 8, val, 4);
- }
- }
- }
- }
-
- if(IS_INTER(mb_type))
- write_back_motion(h, 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(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
- else cbp= golomb_to_inter_cbp [cbp];
- }else{
- if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
- else cbp= golomb_to_inter_cbp_gray[cbp];
- }
- }
- h->cbp = cbp;
-
- if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
- if(get_bits1(&s->gb)){
- mb_type |= MB_TYPE_8x8DCT;
- 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 dquant;
- 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);
-
- 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;
- }
-
- 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(cbp&15){
- for(i8x8=0; i8x8<4; i8x8++){
- 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 ){
- return -1;
- }
- }
- }
- }else{
- fill_rectangle(&h->non_zero_count_cache[scan8[0]], 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;
- }
- s->current_picture.qscale_table[mb_xy]= s->qscale;
- write_back_non_zero_count(h);
-
- if(MB_MBAFF){
- h->ref_count[0] >>= 1;
- h->ref_count[1] >>= 1;
- }
-
- return 0;
-}
-
-static int decode_cabac_field_decoding_flag(H264Context *h) {
- MpegEncContext * const s = &h->s;
- const int mb_x = s->mb_x;
- const int mb_y = s->mb_y & ~1;
- const int mba_xy = mb_x - 1 + mb_y *s->mb_stride;
- const int mbb_xy = mb_x + (mb_y-2)*s->mb_stride;
-
- unsigned int ctx = 0;
-
- if( h->slice_table[mba_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) ) {
- ctx += 1;
- }
- if( h->slice_table[mbb_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) ) {
- ctx += 1;
- }
-
- return get_cabac_noinline( &h->cabac, &h->cabac_state[70 + ctx] );
-}
-
-static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_slice) {
- uint8_t *state= &h->cabac_state[ctx_base];
- int mb_type;
-
- if(intra_slice){
- MpegEncContext * const s = &h->s;
- const int mba_xy = h->left_mb_xy[0];
- const int mbb_xy = h->top_mb_xy;
- int ctx=0;
- if( h->slice_table[mba_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mba_xy] ) )
- ctx++;
- if( h->slice_table[mbb_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mbb_xy] ) )
- ctx++;
- if( get_cabac_noinline( &h->cabac, &state[ctx] ) == 0 )
- return 0; /* I4x4 */
- state += 2;
- }else{
- if( get_cabac_noinline( &h->cabac, &state[0] ) == 0 )
- return 0; /* I4x4 */
- }
-
- if( get_cabac_terminate( &h->cabac ) )
- return 25; /* PCM */
-
- mb_type = 1; /* I16x16 */
- mb_type += 12 * get_cabac_noinline( &h->cabac, &state[1] ); /* cbp_luma != 0 */
- if( get_cabac_noinline( &h->cabac, &state[2] ) ) /* cbp_chroma */
- mb_type += 4 + 4 * get_cabac_noinline( &h->cabac, &state[2+intra_slice] );
- mb_type += 2 * get_cabac_noinline( &h->cabac, &state[3+intra_slice] );
- mb_type += 1 * get_cabac_noinline( &h->cabac, &state[3+2*intra_slice] );
- return mb_type;
-}
-
-static int decode_cabac_mb_type_b( H264Context *h ) {
- MpegEncContext * const s = &h->s;
-
- const int mba_xy = h->left_mb_xy[0];
- const int mbb_xy = h->top_mb_xy;
- int ctx = 0;
- int bits;
- assert(h->slice_type_nos == FF_B_TYPE);
-
- if( h->slice_table[mba_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mba_xy] ) )
- ctx++;
- if( h->slice_table[mbb_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mbb_xy] ) )
- ctx++;
-
- if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+ctx] ) )
- return 0; /* B_Direct_16x16 */
-
- if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+3] ) ) {
- return 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */
- }
-
- bits = get_cabac_noinline( &h->cabac, &h->cabac_state[27+4] ) << 3;
- bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 2;
- bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 1;
- bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
- if( bits < 8 )
- return bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
- else if( bits == 13 ) {
- return decode_cabac_intra_mb_type(h, 32, 0) + 23;
- } else if( bits == 14 )
- return 11; /* B_L1_L0_8x16 */
- else if( bits == 15 )
- return 22; /* B_8x8 */
-
- bits= ( bits<<1 ) | get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
- return bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */
-}
-
-static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
- MpegEncContext * const s = &h->s;
- int mba_xy, mbb_xy;
- int ctx = 0;
-
- if(FRAME_MBAFF){ //FIXME merge with the stuff in fill_caches?
- int mb_xy = mb_x + (mb_y&~1)*s->mb_stride;
- mba_xy = mb_xy - 1;
- if( (mb_y&1)
- && h->slice_table[mba_xy] == h->slice_num
- && MB_FIELD == !!IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) )
- mba_xy += s->mb_stride;
- if( MB_FIELD ){
- mbb_xy = mb_xy - s->mb_stride;
- if( !(mb_y&1)
- && h->slice_table[mbb_xy] == h->slice_num
- && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) )
- mbb_xy -= s->mb_stride;
- }else
- mbb_xy = mb_x + (mb_y-1)*s->mb_stride;
- }else{
- int mb_xy = h->mb_xy;
- mba_xy = mb_xy - 1;
- mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
- }
-
- if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] ))
- ctx++;
- if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mbb_xy] ))
- ctx++;
-
- if( h->slice_type_nos == FF_B_TYPE )
- ctx += 13;
- return get_cabac_noinline( &h->cabac, &h->cabac_state[11+ctx] );
-}
-
-static int decode_cabac_mb_intra4x4_pred_mode( H264Context *h, int pred_mode ) {
- int mode = 0;
-
- if( get_cabac( &h->cabac, &h->cabac_state[68] ) )
- return pred_mode;
-
- mode += 1 * get_cabac( &h->cabac, &h->cabac_state[69] );
- mode += 2 * get_cabac( &h->cabac, &h->cabac_state[69] );
- mode += 4 * get_cabac( &h->cabac, &h->cabac_state[69] );
-
- if( mode >= pred_mode )
- return mode + 1;
- else
- return mode;
-}
-
-static int decode_cabac_mb_chroma_pre_mode( H264Context *h) {
- const int mba_xy = h->left_mb_xy[0];
- const int mbb_xy = h->top_mb_xy;
-
- int ctx = 0;
-
- /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */
- if( h->slice_table[mba_xy] == h->slice_num && h->chroma_pred_mode_table[mba_xy] != 0 )
- ctx++;
-
- if( h->slice_table[mbb_xy] == h->slice_num && h->chroma_pred_mode_table[mbb_xy] != 0 )
- ctx++;
-
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+ctx] ) == 0 )
- return 0;
-
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+3] ) == 0 )
- return 1;
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[64+3] ) == 0 )
- return 2;
- else
- return 3;
-}
-
-static int decode_cabac_mb_cbp_luma( H264Context *h) {
- int cbp_b, cbp_a, ctx, cbp = 0;
-
- cbp_a = h->slice_table[h->left_mb_xy[0]] == h->slice_num ? h->left_cbp : -1;
- cbp_b = h->slice_table[h->top_mb_xy] == h->slice_num ? h->top_cbp : -1;
-
- ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04);
- cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]);
- ctx = !(cbp & 0x01) + 2 * !(cbp_b & 0x08);
- cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 1;
- ctx = !(cbp_a & 0x08) + 2 * !(cbp & 0x01);
- cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 2;
- ctx = !(cbp & 0x04) + 2 * !(cbp & 0x02);
- cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 3;
- return cbp;
-}
-static int decode_cabac_mb_cbp_chroma( H264Context *h) {
- int ctx;
- int cbp_a, cbp_b;
-
- cbp_a = (h->left_cbp>>4)&0x03;
- cbp_b = (h-> top_cbp>>4)&0x03;
-
- ctx = 0;
- if( cbp_a > 0 ) ctx++;
- if( cbp_b > 0 ) ctx += 2;
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[77 + ctx] ) == 0 )
- return 0;
-
- ctx = 4;
- if( cbp_a == 2 ) ctx++;
- if( cbp_b == 2 ) ctx += 2;
- return 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[77 + ctx] );
-}
-static int decode_cabac_mb_dqp( H264Context *h) {
- int ctx= h->last_qscale_diff != 0;
- int val = 0;
-
- while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {
- ctx= 2+(ctx>>1);
- val++;
- if(val > 102) //prevent infinite loop
- return INT_MIN;
- }
-
- if( val&0x01 )
- return (val + 1)>>1 ;
- else
- return -((val + 1)>>1);
-}
-static int decode_cabac_p_mb_sub_type( H264Context *h ) {
- if( get_cabac( &h->cabac, &h->cabac_state[21] ) )
- return 0; /* 8x8 */
- if( !get_cabac( &h->cabac, &h->cabac_state[22] ) )
- return 1; /* 8x4 */
- if( get_cabac( &h->cabac, &h->cabac_state[23] ) )
- return 2; /* 4x8 */
- return 3; /* 4x4 */
-}
-static int decode_cabac_b_mb_sub_type( H264Context *h ) {
- int type;
- if( !get_cabac( &h->cabac, &h->cabac_state[36] ) )
- return 0; /* B_Direct_8x8 */
- if( !get_cabac( &h->cabac, &h->cabac_state[37] ) )
- return 1 + get_cabac( &h->cabac, &h->cabac_state[39] ); /* B_L0_8x8, B_L1_8x8 */
- type = 3;
- if( get_cabac( &h->cabac, &h->cabac_state[38] ) ) {
- if( get_cabac( &h->cabac, &h->cabac_state[39] ) )
- return 11 + get_cabac( &h->cabac, &h->cabac_state[39] ); /* B_L1_4x4, B_Bi_4x4 */
- type += 4;
- }
- type += 2*get_cabac( &h->cabac, &h->cabac_state[39] );
- type += get_cabac( &h->cabac, &h->cabac_state[39] );
- return type;
-}
-
-static inline int decode_cabac_mb_transform_size( H264Context *h ) {
- return get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] );
-}
-
-static int decode_cabac_mb_ref( H264Context *h, int list, int n ) {
- int refa = h->ref_cache[list][scan8[n] - 1];
- int refb = h->ref_cache[list][scan8[n] - 8];
- int ref = 0;
- int ctx = 0;
-
- if( h->slice_type_nos == FF_B_TYPE) {
- if( refa > 0 && !h->direct_cache[scan8[n] - 1] )
- ctx++;
- if( refb > 0 && !h->direct_cache[scan8[n] - 8] )
- ctx += 2;
- } else {
- if( refa > 0 )
- ctx++;
- if( refb > 0 )
- ctx += 2;
- }
-
- while( get_cabac( &h->cabac, &h->cabac_state[54+ctx] ) ) {
- ref++;
- ctx = (ctx>>2)+4;
- if(ref >= 32 /*h->ref_list[list]*/){
- return -1;
- }
- }
- return ref;
-}
-
-static int decode_cabac_mb_mvd( H264Context *h, int list, int n, int l ) {
- int amvd = abs( h->mvd_cache[list][scan8[n] - 1][l] ) +
- abs( h->mvd_cache[list][scan8[n] - 8][l] );
- int ctxbase = (l == 0) ? 40 : 47;
- int mvd;
- int ctx = (amvd>2) + (amvd>32);
-
- if(!get_cabac(&h->cabac, &h->cabac_state[ctxbase+ctx]))
- return 0;
-
- mvd= 1;
- ctx= 3;
- while( mvd < 9 && get_cabac( &h->cabac, &h->cabac_state[ctxbase+ctx] ) ) {
- mvd++;
- if( ctx < 6 )
- ctx++;
- }
-
- if( mvd >= 9 ) {
- int k = 3;
- while( get_cabac_bypass( &h->cabac ) ) {
- mvd += 1 << k;
- k++;
- if(k>24){
- av_log(h->s.avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
- return INT_MIN;
- }
- }
- while( k-- ) {
- if( get_cabac_bypass( &h->cabac ) )
- mvd += 1 << k;
- }
- }
- return get_cabac_bypass_sign( &h->cabac, -mvd );
-}
-
-static av_always_inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx, int is_dc ) {
- int nza, nzb;
- int ctx = 0;
-
- if( is_dc ) {
- if( cat == 0 ) {
- nza = h->left_cbp&0x100;
- nzb = h-> top_cbp&0x100;
- } else {
- nza = (h->left_cbp>>(6+idx))&0x01;
- nzb = (h-> top_cbp>>(6+idx))&0x01;
- }
- } else {
- assert(cat == 1 || cat == 2 || cat == 4);
- nza = h->non_zero_count_cache[scan8[idx] - 1];
- nzb = h->non_zero_count_cache[scan8[idx] - 8];
- }
-
- if( nza > 0 )
- ctx++;
-
- if( nzb > 0 )
- ctx += 2;
-
- return ctx + 4 * cat;
-}
-
-DECLARE_ASM_CONST(1, uint8_t, last_coeff_flag_offset_8x8[63]) = {
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8
-};
-
-static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff, int is_dc ) {
- static const int significant_coeff_flag_offset[2][6] = {
- { 105+0, 105+15, 105+29, 105+44, 105+47, 402 },
- { 277+0, 277+15, 277+29, 277+44, 277+47, 436 }
- };
- static const int last_coeff_flag_offset[2][6] = {
- { 166+0, 166+15, 166+29, 166+44, 166+47, 417 },
- { 338+0, 338+15, 338+29, 338+44, 338+47, 451 }
- };
- static const int coeff_abs_level_m1_offset[6] = {
- 227+0, 227+10, 227+20, 227+30, 227+39, 426
- };
- static const uint8_t significant_coeff_flag_offset_8x8[2][63] = {
- { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
- 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
- 7, 6,11,12,13,11, 6, 7, 8, 9,14,10, 9, 8, 6,11,
- 12,13,11, 6, 9,14,10, 9,11,12,13,11,14,10,12 },
- { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
- 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11,
- 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
- 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 }
- };
- /* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
- * 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
- * map node ctx => cabac ctx for level=1 */
- static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
- /* map node ctx => cabac ctx for level>1 */
- static const uint8_t coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 };
- static const uint8_t coeff_abs_level_transition[2][8] = {
- /* update node ctx after decoding a level=1 */
- { 1, 2, 3, 3, 4, 5, 6, 7 },
- /* update node ctx after decoding a level>1 */
- { 4, 4, 4, 4, 5, 6, 7, 7 }
- };
-
- int index[64];
-
- int av_unused last;
- int coeff_count = 0;
- int node_ctx = 0;
-
- uint8_t *significant_coeff_ctx_base;
- uint8_t *last_coeff_ctx_base;
- uint8_t *abs_level_m1_ctx_base;
-
-#if !ARCH_X86
-#define CABAC_ON_STACK
-#endif
-#ifdef CABAC_ON_STACK
-#define CC &cc
- CABACContext cc;
- cc.range = h->cabac.range;
- cc.low = h->cabac.low;
- cc.bytestream= h->cabac.bytestream;
-#else
-#define CC &h->cabac
-#endif
-
-
- /* cat: 0-> DC 16x16 n = 0
- * 1-> AC 16x16 n = luma4x4idx
- * 2-> Luma4x4 n = luma4x4idx
- * 3-> DC Chroma n = iCbCr
- * 4-> AC Chroma n = 16 + 4 * iCbCr + chroma4x4idx
- * 5-> Luma8x8 n = 4 * luma8x8idx
- */
-
- /* read coded block flag */
- if( is_dc || cat != 5 ) {
- if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n, is_dc ) ] ) == 0 ) {
- if( !is_dc )
- h->non_zero_count_cache[scan8[n]] = 0;
-
-#ifdef CABAC_ON_STACK
- h->cabac.range = cc.range ;
- h->cabac.low = cc.low ;
- h->cabac.bytestream= cc.bytestream;
-#endif
- return;
- }
- }
-
- significant_coeff_ctx_base = h->cabac_state
- + significant_coeff_flag_offset[MB_FIELD][cat];
- last_coeff_ctx_base = h->cabac_state
- + last_coeff_flag_offset[MB_FIELD][cat];
- abs_level_m1_ctx_base = h->cabac_state
- + coeff_abs_level_m1_offset[cat];
-
- if( !is_dc && cat == 5 ) {
-#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \
- for(last= 0; last < coefs; last++) { \
- uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \
- if( get_cabac( CC, sig_ctx )) { \
- uint8_t *last_ctx = last_coeff_ctx_base + last_off; \
- index[coeff_count++] = last; \
- if( get_cabac( CC, last_ctx ) ) { \
- last= max_coeff; \
- break; \
- } \
- } \
- }\
- if( last == max_coeff -1 ) {\
- index[coeff_count++] = last;\
- }
- const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD];
-#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
- coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index, sig_off);
- } else {
- coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index);
-#else
- DECODE_SIGNIFICANCE( 63, sig_off[last], last_coeff_flag_offset_8x8[last] );
- } else {
- DECODE_SIGNIFICANCE( max_coeff - 1, last, last );
-#endif
- }
- assert(coeff_count > 0);
-
- if( is_dc ) {
- if( cat == 0 )
- h->cbp_table[h->mb_xy] |= 0x100;
- else
- h->cbp_table[h->mb_xy] |= 0x40 << n;
- } else {
- if( cat == 5 )
- fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
- else {
- assert( cat == 1 || cat == 2 || cat == 4 );
- h->non_zero_count_cache[scan8[n]] = coeff_count;
- }
- }
-
- do {
- uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base;
-
- int j= scantable[index[--coeff_count]];
-
- if( get_cabac( CC, ctx ) == 0 ) {
- node_ctx = coeff_abs_level_transition[0][node_ctx];
- if( is_dc ) {
- block[j] = get_cabac_bypass_sign( CC, -1);
- }else{
- block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6;
- }
- } else {
- int coeff_abs = 2;
- ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base;
- node_ctx = coeff_abs_level_transition[1][node_ctx];
-
- while( coeff_abs < 15 && get_cabac( CC, ctx ) ) {
- coeff_abs++;
- }
-
- if( coeff_abs >= 15 ) {
- int j = 0;
- while( get_cabac_bypass( CC ) ) {
- j++;
- }
-
- coeff_abs=1;
- while( j-- ) {
- coeff_abs += coeff_abs + get_cabac_bypass( CC );
- }
- coeff_abs+= 14;
- }
-
- if( is_dc ) {
- block[j] = get_cabac_bypass_sign( CC, -coeff_abs );
- }else{
- block[j] = (get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32) >> 6;
- }
- }
- } while( coeff_count );
-#ifdef CABAC_ON_STACK
- h->cabac.range = cc.range ;
- h->cabac.low = cc.low ;
- h->cabac.bytestream= cc.bytestream;
-#endif
-
-}
-
-#if !CONFIG_SMALL
-static void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
- decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 1);
-}
-
-static void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
- decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0);
-}
-#endif
-
-static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
-#if CONFIG_SMALL
- decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, cat == 0 || cat == 3);
-#else
- if( cat == 0 || cat == 3 ) decode_cabac_residual_dc(h, block, cat, n, scantable, qmul, max_coeff);
- else decode_cabac_residual_nondc(h, block, cat, n, scantable, qmul, max_coeff);
-#endif
-}
-
-static inline void compute_mb_neighbors(H264Context *h)
-{
- MpegEncContext * const s = &h->s;
- const int mb_xy = h->mb_xy;
- h->top_mb_xy = mb_xy - s->mb_stride;
- h->left_mb_xy[0] = mb_xy - 1;
- if(FRAME_MBAFF){
- const int pair_xy = s->mb_x + (s->mb_y & ~1)*s->mb_stride;
- const int top_pair_xy = pair_xy - s->mb_stride;
- const int top_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]);
- const int left_mb_field_flag = IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]);
- const int curr_mb_field_flag = MB_FIELD;
- const int bottom = (s->mb_y & 1);
-
- if (curr_mb_field_flag && (bottom || top_mb_field_flag)){
- h->top_mb_xy -= s->mb_stride;
- }
- if (!left_mb_field_flag == curr_mb_field_flag) {
- h->left_mb_xy[0] = pair_xy - 1;
- }
- } else if (FIELD_PICTURE) {
- h->top_mb_xy -= s->mb_stride;
- }
- return;
-}
-
-/**
- * decodes a macroblock
- * @returns 0 if OK, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed
- */
-static int decode_mb_cabac(H264Context *h) {
- MpegEncContext * const s = &h->s;
- int mb_xy;
- int mb_type, partition_count, cbp = 0;
- int dct8x8_allowed= h->pps.transform_8x8_mode;
-
- 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);
- if( h->slice_type_nos != FF_I_TYPE ) {
- int skip;
- /* a skipped mb needs the aff flag from the following mb */
- if( FRAME_MBAFF && s->mb_x==0 && (s->mb_y&1)==0 )
- predict_field_decoding_flag(h);
- if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )
- skip = h->next_mb_skipped;
- else
- skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );
- /* read skip flags */
- if( skip ) {
- if( FRAME_MBAFF && (s->mb_y&1)==0 ){
- s->current_picture.mb_type[mb_xy] = MB_TYPE_SKIP;
- h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );
- if(!h->next_mb_skipped)
- h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
- }
-
- decode_mb_skip(h);
-
- h->cbp_table[mb_xy] = 0;
- h->chroma_pred_mode_table[mb_xy] = 0;
- h->last_qscale_diff = 0;
-
- return 0;
-
- }
- }
- if(FRAME_MBAFF){
- if( (s->mb_y&1) == 0 )
- h->mb_mbaff =
- h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
- }
-
- h->prev_mb_skipped = 0;
-
- compute_mb_neighbors(h);
-
- if( h->slice_type_nos == FF_B_TYPE ) {
- mb_type = decode_cabac_mb_type_b( h );
- if( mb_type < 23 ){
- partition_count= b_mb_type_info[mb_type].partition_count;
- mb_type= b_mb_type_info[mb_type].type;
- }else{
- mb_type -= 23;
- goto decode_intra_mb;
- }
- } else if( h->slice_type_nos == FF_P_TYPE ) {
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[14] ) == 0 ) {
- /* P-type */
- if( get_cabac_noinline( &h->cabac, &h->cabac_state[15] ) == 0 ) {
- /* P_L0_D16x16, P_8x8 */
- mb_type= 3 * get_cabac_noinline( &h->cabac, &h->cabac_state[16] );
- } else {
- /* P_L0_D8x16, P_L0_D16x8 */
- mb_type= 2 - get_cabac_noinline( &h->cabac, &h->cabac_state[17] );
- }
- 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, 17, 0);
- goto decode_intra_mb;
- }
- } else {
- mb_type= decode_cabac_intra_mb_type(h, 3, 1);
- if(h->slice_type == FF_SI_TYPE && mb_type)
- mb_type--;
- assert(h->slice_type_nos == FF_I_TYPE);
-decode_intra_mb:
- partition_count = 0;
- cbp= i_mb_type_info[mb_type].cbp;
- h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;
- mb_type= i_mb_type_info[mb_type].type;
- }
- if(MB_FIELD)
- mb_type |= MB_TYPE_INTERLACED;
-
- h->slice_table[ mb_xy ]= h->slice_num;
-
- if(IS_INTRA_PCM(mb_type)) {
- const uint8_t *ptr;
-
- // We assume these blocks are very rare so we do not optimize it.
- // FIXME The two following lines get the bitstream position in the cabac
- // decode, I think it should be done by a function in cabac.h (or cabac.c).
- ptr= h->cabac.bytestream;
- if(h->cabac.low&0x1) ptr--;
- if(CABAC_BITS==16){
- if(h->cabac.low&0x1FF) ptr--;
- }
-
- // The pixels are stored in the same order as levels in h->mb array.
- memcpy(h->mb, ptr, 256); ptr+=256;
- if(CHROMA){
- memcpy(h->mb+128, ptr, 128); ptr+=128;
- }
-
- ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
-
- // All blocks are present
- h->cbp_table[mb_xy] = 0x1ef;
- h->chroma_pred_mode_table[mb_xy] = 0;
- // 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, 16);
- s->current_picture.mb_type[mb_xy]= mb_type;
- h->last_qscale_diff = 0;
- return 0;
- }
-
- if(MB_MBAFF){
- h->ref_count[0] <<= 1;
- h->ref_count[1] <<= 1;
- }
-
- fill_caches(h, mb_type, 0);
-
- if( IS_INTRA( mb_type ) ) {
- int i, pred_mode;
- if( IS_INTRA4x4( mb_type ) ) {
- if( dct8x8_allowed && decode_cabac_mb_transform_size( h ) ) {
- mb_type |= MB_TYPE_8x8DCT;
- for( i = 0; i < 16; i+=4 ) {
- int pred = pred_intra_mode( h, i );
- int mode = decode_cabac_mb_intra4x4_pred_mode( h, pred );
- fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );
- }
- } else {
- for( i = 0; i < 16; i++ ) {
- int pred = pred_intra_mode( h, i );
- h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );
-
- //av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );
- }
- }
- ff_h264_write_back_intra_pred_mode(h);
- if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1;
- } else {
- h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode );
- if( h->intra16x16_pred_mode < 0 ) return -1;
- }
- if(CHROMA){
- h->chroma_pred_mode_table[mb_xy] =
- pred_mode = decode_cabac_mb_chroma_pre_mode( h );
-
- pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode );
- if( pred_mode < 0 ) return -1;
- h->chroma_pred_mode= pred_mode;
- }
- } else if( partition_count == 4 ) {
- int i, j, sub_partition_count[4], list, ref[2][4];
-
- if( h->slice_type_nos == FF_B_TYPE ) {
- for( i = 0; i < 4; i++ ) {
- h->sub_mb_type[i] = decode_cabac_b_mb_sub_type( h );
- sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
- h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type;
- }
- if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] |
- h->sub_mb_type[2] | h->sub_mb_type[3]) ) {
- ff_h264_pred_direct_motion(h, &mb_type);
- h->ref_cache[0][scan8[4]] =
- h->ref_cache[1][scan8[4]] =
- h->ref_cache[0][scan8[12]] =
- h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
- if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) {
- for( i = 0; i < 4; i++ )
- if( IS_DIRECT(h->sub_mb_type[i]) )
- fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, 1, 1 );
- }
- }
- } else {
- for( i = 0; i < 4; i++ ) {
- h->sub_mb_type[i] = decode_cabac_p_mb_sub_type( h );
- sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
- h->sub_mb_type[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].type;
- }
- }
-
- for( list = 0; list < h->list_count; list++ ) {
- for( i = 0; i < 4; i++ ) {
- if(IS_DIRECT(h->sub_mb_type[i])) continue;
- if(IS_DIR(h->sub_mb_type[i], 0, list)){
- if( h->ref_count[list] > 1 ){
- ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );
- if(ref[list][i] >= (unsigned)h->ref_count[list]){
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], h->ref_count[list]);
- return -1;
- }
- }else
- ref[list][i] = 0;
- } else {
- ref[list][i] = -1;
- }
- h->ref_cache[list][ scan8[4*i]+1 ]=
- h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
- }
- }
-
- if(dct8x8_allowed)
- dct8x8_allowed = get_dct8x8_allowed(h);
-
- for(list=0; list<h->list_count; list++){
- for(i=0; i<4; i++){
- h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ];
- if(IS_DIRECT(h->sub_mb_type[i])){
- fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 4);
- continue;
- }
-
- if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){
- const int sub_mb_type= h->sub_mb_type[i];
- const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
- for(j=0; j<sub_partition_count[i]; j++){
- int mpx, mpy;
- int mx, my;
- const int index= 4*i + block_width*j;
- int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
- int16_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];
- pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mpx, &mpy);
-
- mx = mpx + decode_cabac_mb_mvd( h, list, index, 0 );
- my = mpy + decode_cabac_mb_mvd( h, list, index, 1 );
- tprintf(s->avctx, "final mv:%d %d\n", mx, my);
-
- if(IS_SUB_8X8(sub_mb_type)){
- mv_cache[ 1 ][0]=
- mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
- mv_cache[ 1 ][1]=
- mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
-
- mvd_cache[ 1 ][0]=
- mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mx - mpx;
- mvd_cache[ 1 ][1]=
- mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= my - mpy;
- }else if(IS_SUB_8X4(sub_mb_type)){
- mv_cache[ 1 ][0]= mx;
- mv_cache[ 1 ][1]= my;
-
- mvd_cache[ 1 ][0]= mx - mpx;
- mvd_cache[ 1 ][1]= my - mpy;
- }else if(IS_SUB_4X8(sub_mb_type)){
- mv_cache[ 8 ][0]= mx;
- mv_cache[ 8 ][1]= my;
-
- mvd_cache[ 8 ][0]= mx - mpx;
- mvd_cache[ 8 ][1]= my - mpy;
- }
- mv_cache[ 0 ][0]= mx;
- mv_cache[ 0 ][1]= my;
-
- mvd_cache[ 0 ][0]= mx - mpx;
- mvd_cache[ 0 ][1]= my - mpy;
- }
- }else{
- uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];
- uint32_t *pd= (uint32_t *)&h->mvd_cache[list][ scan8[4*i] ][0];
- p[0] = p[1] = p[8] = p[9] = 0;
- pd[0]= pd[1]= pd[8]= pd[9]= 0;
- }
- }
- }
- } else if( IS_DIRECT(mb_type) ) {
- ff_h264_pred_direct_motion(h, &mb_type);
- fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4);
- fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 4);
- dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
- } else {
- int list, mx, my, i, mpx, mpy;
- if(IS_16X16(mb_type)){
- for(list=0; list<h->list_count; list++){
- if(IS_DIR(mb_type, 0, list)){
- int ref;
- if(h->ref_count[list] > 1){
- ref= decode_cabac_mb_ref(h, list, 0);
- if(ref >= (unsigned)h->ref_count[list]){
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);
- }else
- fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1); //FIXME factorize and the other fill_rect below too
- }
- for(list=0; list<h->list_count; list++){
- if(IS_DIR(mb_type, 0, list)){
- pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mpx, &mpy);
-
- mx = mpx + decode_cabac_mb_mvd( h, list, 0, 0 );
- my = mpy + decode_cabac_mb_mvd( h, list, 0, 1 );
- tprintf(s->avctx, "final mv:%d %d\n", mx, my);
-
- fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx-mpx,my-mpy), 4);
- fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
- }else
- fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, 0, 4);
- }
- }
- else if(IS_16X8(mb_type)){
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- int ref;
- if(h->ref_count[list] > 1){
- ref= decode_cabac_mb_ref( h, list, 8*i );
- if(ref >= (unsigned)h->ref_count[list]){
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);
- }else
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);
- }
- }
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mpx, &mpy);
- mx = mpx + decode_cabac_mb_mvd( h, list, 8*i, 0 );
- my = mpy + decode_cabac_mb_mvd( h, list, 8*i, 1 );
- tprintf(s->avctx, "final mv:%d %d\n", mx, my);
-
- fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx-mpx,my-mpy), 4);
- fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
- }else{
- fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);
- fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);
- }
- }
- }
- }else{
- assert(IS_8X16(mb_type));
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){ //FIXME optimize
- int ref;
- if(h->ref_count[list] > 1){
- ref= decode_cabac_mb_ref( h, list, 4*i );
- if(ref >= (unsigned)h->ref_count[list]){
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);
- }else
- fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);
- }
- }
- for(list=0; list<h->list_count; list++){
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mpx, &mpy);
- mx = mpx + decode_cabac_mb_mvd( h, list, 4*i, 0 );
- my = mpy + decode_cabac_mb_mvd( h, list, 4*i, 1 );
-
- tprintf(s->avctx, "final mv:%d %d\n", mx, my);
- fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx-mpx,my-mpy), 4);
- fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
- }else{
- fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);
- fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);
- }
- }
- }
- }
- }
-
- if( IS_INTER( mb_type ) ) {
- h->chroma_pred_mode_table[mb_xy] = 0;
- write_back_motion( h, mb_type );
- }
-
- if( !IS_INTRA16x16( mb_type ) ) {
- cbp = decode_cabac_mb_cbp_luma( h );
- if(CHROMA)
- cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;
- }
-
- h->cbp_table[mb_xy] = h->cbp = cbp;
-
- if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {
- if( decode_cabac_mb_transform_size( h ) )
- mb_type |= MB_TYPE_8x8DCT;
- }
- s->current_picture.mb_type[mb_xy]= mb_type;
-
- if( cbp || IS_INTRA16x16( mb_type ) ) {
- const uint8_t *scan, *scan8x8, *dc_scan;
- const uint32_t *qmul;
- int dqp;
-
- if(IS_INTERLACED(mb_type)){
- scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
- scan= s->qscale ? h->field_scan : h->field_scan_q0;
- dc_scan= luma_dc_field_scan;
- }else{
- scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
- scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
- dc_scan= luma_dc_zigzag_scan;
- }
-
- h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h );
- if( dqp == INT_MIN ){
- av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- s->qscale += dqp;
- if(((unsigned)s->qscale) > 51){
- if(s->qscale<0) s->qscale+= 52;
- else s->qscale-= 52;
- }
- 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 ) ) {
- int i;
- //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" );
- decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16);
-
- if( cbp&15 ) {
- qmul = h->dequant4_coeff[0][s->qscale];
- for( i = 0; i < 16; i++ ) {
- //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i );
- decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, qmul, 15);
- }
- } else {
- fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);
- }
- } else {
- int i8x8, i4x4;
- for( i8x8 = 0; i8x8 < 4; i8x8++ ) {
- if( cbp & (1<<i8x8) ) {
- if( IS_8x8DCT(mb_type) ) {
- decode_cabac_residual(h, h->mb + 64*i8x8, 5, 4*i8x8,
- scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64);
- } else {
- qmul = h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale];
- for( i4x4 = 0; i4x4 < 4; i4x4++ ) {
- const int index = 4*i8x8 + i4x4;
- //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index );
-//START_TIMER
- decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, qmul, 16);
-//STOP_TIMER("decode_residual")
- }
- }
- } 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 ){
- int c;
- for( c = 0; c < 2; c++ ) {
- //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );
- decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4);
- }
- }
-
- if( cbp&0x20 ) {
- int c, i;
- for( c = 0; c < 2; c++ ) {
- qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
- for( i = 0; i < 4; i++ ) {
- const int index = 16 + 4 * c + i;
- //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 );
- decode_cabac_residual(h, h->mb + 16*index, 4, index, scan + 1, qmul, 15);
- }
- }
- } 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;
- h->last_qscale_diff = 0;
- }
-
- s->current_picture.qscale_table[mb_xy]= s->qscale;
- write_back_non_zero_count(h);
-
- if(MB_MBAFF){
- h->ref_count[0] >>= 1;
- h->ref_count[1] >>= 1;
- }
-
- return 0;
-}
-
-static int decode_slice(struct AVCodecContext *avctx, void *arg){
- H264Context *h = *(void**)arg;
- MpegEncContext * const s = &h->s;
- const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
-
- s->mb_skip_run= -1;
-
- h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME || s->codec_id != CODEC_ID_H264 ||
- (CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
-
- if( h->pps.cabac ) {
- int i;
-
- /* realign */
- align_get_bits( &s->gb );
-
- /* init cabac */
- ff_init_cabac_states( &h->cabac);
- ff_init_cabac_decoder( &h->cabac,
- s->gb.buffer + get_bits_count(&s->gb)/8,
- (get_bits_left(&s->gb) + 7)/8);
- /* calculate pre-state */
- for( i= 0; i < 460; i++ ) {
- int pre;
- if( h->slice_type_nos == FF_I_TYPE )
- pre = av_clip( ((cabac_context_init_I[i][0] * s->qscale) >>4 ) + cabac_context_init_I[i][1], 1, 126 );
- else
- pre = av_clip( ((cabac_context_init_PB[h->cabac_init_idc][i][0] * s->qscale) >>4 ) + cabac_context_init_PB[h->cabac_init_idc][i][1], 1, 126 );
-
- if( pre <= 63 )
- h->cabac_state[i] = 2 * ( 63 - pre ) + 0;
- else
- h->cabac_state[i] = 2 * ( pre - 64 ) + 1;
- }
-
- for(;;){
-//START_TIMER
- int ret = decode_mb_cabac(h);
- int eos;
-//STOP_TIMER("decode_mb_cabac")
-
- if(ret>=0) ff_h264_hl_decode_mb(h);
-
- if( ret >= 0 && FRAME_MBAFF ) { //FIXME optimal? or let mb_decode decode 16x32 ?
- s->mb_y++;
-
- ret = decode_mb_cabac(h);
-
- if(ret>=0) ff_h264_hl_decode_mb(h);
- s->mb_y--;
- }
- eos = get_cabac_terminate( &h->cabac );
-
- if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
- av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
- return -1;
- }
-
- if( ++s->mb_x >= s->mb_width ) {
- s->mb_x = 0;
- ff_draw_horiz_band(s, 16*s->mb_y, 16);
- ++s->mb_y;
- if(FIELD_OR_MBAFF_PICTURE) {
- ++s->mb_y;
- }
- }
-
- if( eos || s->mb_y >= s->mb_height ) {
- tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
- return 0;
- }
- }
-
- } else {
- for(;;){
- int ret = decode_mb_cavlc(h);
-
- if(ret>=0) ff_h264_hl_decode_mb(h);
-
- if(ret>=0 && FRAME_MBAFF){ //FIXME optimal? or let mb_decode decode 16x32 ?
- s->mb_y++;
- ret = decode_mb_cavlc(h);
-
- if(ret>=0) ff_h264_hl_decode_mb(h);
- s->mb_y--;
- }
-
- if(ret<0){
- av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
- }
-
- if(++s->mb_x >= s->mb_width){
- s->mb_x=0;
- ff_draw_horiz_band(s, 16*s->mb_y, 16);
- ++s->mb_y;
- if(FIELD_OR_MBAFF_PICTURE) {
- ++s->mb_y;
- }
- if(s->mb_y >= s->mb_height){
- tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
-
- if(get_bits_count(&s->gb) == s->gb.size_in_bits ) {
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return -1;
- }
- }
- }
-
- if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){
- tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits);
- if(get_bits_count(&s->gb) == s->gb.size_in_bits ){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
- }
- }
- }
- }
-
-#if 0
- for(;s->mb_y < s->mb_height; s->mb_y++){
- for(;s->mb_x < s->mb_width; s->mb_x++){
- int ret= decode_mb(h);
-
- ff_h264_hl_decode_mb(h);
-
- if(ret<0){
- av_log(s->avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
- }
-
- if(++s->mb_x >= s->mb_width){
- s->mb_x=0;
- if(++s->mb_y >= s->mb_height){
- if(get_bits_count(s->gb) == s->gb.size_in_bits){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return -1;
- }
- }
- }
-
- if(get_bits_count(s->?gb) >= s->gb?.size_in_bits){
- if(get_bits_count(s->gb) == s->gb.size_in_bits){
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
-
- return 0;
- }else{
- ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
-
- return -1;
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
+
+ return -1;
}
}
}
if (ptr==NULL || dst_length < 0){
return -1;
}
+ i= buf_index + consumed;
+ if((s->workaround_bugs & FF_BUG_AUTODETECT) && i+3<next_avc &&
+ buf[i]==0x00 && buf[i+1]==0x00 && buf[i+2]==0x01 && buf[i+3]==0xE0)
+ s->workaround_bugs |= FF_BUG_TRUNCATED;
+
+ if(!(s->workaround_bugs & FF_BUG_TRUNCATED)){
while(ptr[dst_length - 1] == 0 && dst_length > 0)
dst_length--;
+ }
bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_decode_rbsp_trailing(h, ptr + dst_length - 1));
if(s->avctx->debug&FF_DEBUG_STARTCODE){
if((err = decode_slice_header(hx, h)))
break;
- if (s->avctx->hwaccel && h->current_slice == 1) {
- if (s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
+ avctx->profile = hx->sps.profile_idc;
+ avctx->level = hx->sps.level_idc;
+
+ if (h->current_slice == 1) {
+ if (s->avctx->hwaccel && s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
return -1;
+ if(CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ ff_vdpau_h264_picture_start(s);
}
s->current_picture_ptr->key_frame |=
if ((err = decode_slice_header(hx, h)) < 0)
break;
+ avctx->profile = hx->sps.profile_idc;
+ avctx->level = hx->sps.level_idc;
+
hx->s.data_partitioning = 1;
break;
return 0;
}
- if(h->is_avc && !h->got_avcC) {
- int i, cnt, nalsize;
- unsigned char *p = avctx->extradata;
- if(avctx->extradata_size < 7) {
- av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
- return -1;
- }
- if(*p != 1) {
- av_log(avctx, AV_LOG_ERROR, "Unknown avcC version %d\n", *p);
- return -1;
- }
- /* sps and pps in the avcC always have length coded with 2 bytes,
- so put a fake nal_length_size = 2 while parsing them */
- h->nal_length_size = 2;
- // Decode sps from avcC
- cnt = *(p+5) & 0x1f; // Number of sps
- p += 6;
- for (i = 0; i < cnt; i++) {
- nalsize = AV_RB16(p) + 2;
- if(decode_nal_units(h, p, nalsize) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i);
- return -1;
- }
- p += nalsize;
- }
- // Decode pps from avcC
- cnt = *(p++); // Number of pps
- for (i = 0; i < cnt; i++) {
- nalsize = AV_RB16(p) + 2;
- if(decode_nal_units(h, p, nalsize) != nalsize) {
- av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i);
- return -1;
- }
- p += nalsize;
- }
- // Now store right nal length size, that will be use to parse all other nals
- h->nal_length_size = ((*(((char*)(avctx->extradata))+4))&0x03)+1;
- // Do not reparse avcC
- h->got_avcC = 1;
- }
-
- if(!h->got_avcC && !h->is_avc && s->avctx->extradata_size){
- if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0)
- return -1;
- h->got_avcC = 1;
- }
-
buf_index=decode_nal_units(h, buf, buf_size);
if(buf_index < 0)
return -1;
}
// printf("\n");
- s->dsp.h264_idct_add(ref, block, 4);
+ h->h264dsp.h264_idct_add(ref, block, 4);
/* for(j=0; j<16; j++){
printf("%d ", ref[j]);
}