h264.c
上传用户:chinavct
上传日期:2022-06-20
资源大小:330k
文件大小:325k
- 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=%dn", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );
- }
- }
- write_back_intra_pred_mode(h);
- if( check_intra4x4_pred_mode(h) < 0 ) return -1;
- } else {
- h->intra16x16_pred_mode= 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= 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]) ) {
- 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] >= h->ref_count[list]){
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %dn", 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 %dn", 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) ) {
- 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 >= h->ref_count[list])
- {
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %dn", 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 %dn", 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 >= h->ref_count[list])
- {
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %dn", 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 %dn", 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 >= h->ref_count[list])
- {
- av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %dn", 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 %dn", 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 %dn", 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 DCn" );
- 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:%dn", 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: %dn", 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-DCn",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 %dn",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 void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) {
- const int index_a = qp + h->slice_alpha_c0_offset;
- const int alpha = (alpha_table+52)[index_a];
- const int beta = (beta_table+52)[qp + h->slice_beta_offset];
- if( bS[0] < 4 ) {
- int8_t tc[4];
- tc[0] = (tc0_table+52)[index_a][bS[0]];
- tc[1] = (tc0_table+52)[index_a][bS[1]];
- tc[2] = (tc0_table+52)[index_a][bS[2]];
- tc[3] = (tc0_table+52)[index_a][bS[3]];
- h->s.dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc);
- } else {
- h->s.dsp.h264_h_loop_filter_luma_intra(pix, stride, alpha, beta);
- }
- }
- static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) {
- const int index_a = qp + h->slice_alpha_c0_offset;
- const int alpha = (alpha_table+52)[index_a];
- const int beta = (beta_table+52)[qp + h->slice_beta_offset];
- if( bS[0] < 4 ) {
- int8_t tc[4];
- tc[0] = (tc0_table+52)[index_a][bS[0]]+1;
- tc[1] = (tc0_table+52)[index_a][bS[1]]+1;
- tc[2] = (tc0_table+52)[index_a][bS[2]]+1;
- tc[3] = (tc0_table+52)[index_a][bS[3]]+1;
- h->s.dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc);
- } else {
- h->s.dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta);
- }
- }
- static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int16_t bS[8], int qp[2] ) {
- int i;
- for( i = 0; i < 16; i++, pix += stride) {
- int index_a;
- int alpha;
- int beta;
- int qp_index;
- int bS_index = (i >> 1);
- if (!MB_FIELD) {
- bS_index &= ~1;
- bS_index |= (i & 1);
- }
- if( bS[bS_index] == 0 ) {
- continue;
- }
- qp_index = MB_FIELD ? (i >> 3) : (i & 1);
- index_a = qp[qp_index] + h->slice_alpha_c0_offset;
- alpha = (alpha_table+52)[index_a];
- beta = (beta_table+52)[qp[qp_index] + h->slice_beta_offset];
- if( bS[bS_index] < 4 ) {
- const int tc0 = (tc0_table+52)[index_a][bS[bS_index]];
- const int p0 = pix[-1];
- const int p1 = pix[-2];
- const int p2 = pix[-3];
- const int q0 = pix[0];
- const int q1 = pix[1];
- const int q2 = pix[2];
- if( FFABS( p0 - q0 ) < alpha &&
- FFABS( p1 - p0 ) < beta &&
- FFABS( q1 - q0 ) < beta ) {
- int tc = tc0;
- int i_delta;
- if( FFABS( p2 - p0 ) < beta ) {
- pix[-2] = p1 + av_clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );
- tc++;
- }
- if( FFABS( q2 - q0 ) < beta ) {
- pix[1] = q1 + av_clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );
- tc++;
- }
- i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
- pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */
- pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */
- tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%dn# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1);
- }
- }else{
- const int p0 = pix[-1];
- const int p1 = pix[-2];
- const int p2 = pix[-3];
- const int q0 = pix[0];
- const int q1 = pix[1];
- const int q2 = pix[2];
- if( FFABS( p0 - q0 ) < alpha &&
- FFABS( p1 - p0 ) < beta &&
- FFABS( q1 - q0 ) < beta ) {
- if(FFABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){
- if( FFABS( p2 - p0 ) < beta)
- {
- const int p3 = pix[-4];
- /* p0', p1', p2' */
- pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
- pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
- pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
- } else {
- /* p0' */
- pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
- }
- if( FFABS( q2 - q0 ) < beta)
- {
- const int q3 = pix[3];
- /* q0', q1', q2' */
- pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
- pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
- pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
- } else {
- /* q0' */
- pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
- }
- }else{
- /* p0', q0' */
- pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
- pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
- }
- tprintf(h->s.avctx, "filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%dn# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]n", i, qp[qp_index], index_a, alpha, beta, p2, p1, p0, q0, q1, q2, pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]);
- }
- }
- }
- }
- static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, int16_t bS[8], int qp[2] ) {
- int i;
- for( i = 0; i < 8; i++, pix += stride) {
- int index_a;
- int alpha;
- int beta;
- int qp_index;
- int bS_index = i;
- if( bS[bS_index] == 0 ) {
- continue;
- }
- qp_index = MB_FIELD ? (i >> 2) : (i & 1);
- index_a = qp[qp_index] + h->slice_alpha_c0_offset;
- alpha = (alpha_table+52)[index_a];
- beta = (beta_table+52)[qp[qp_index] + h->slice_beta_offset];
- if( bS[bS_index] < 4 ) {
- const int tc = (tc0_table+52)[index_a][bS[bS_index]] + 1;
- const int p0 = pix[-1];
- const int p1 = pix[-2];
- const int q0 = pix[0];
- const int q1 = pix[1];
- if( FFABS( p0 - q0 ) < alpha &&
- FFABS( p1 - p0 ) < beta &&
- FFABS( q1 - q0 ) < beta ) {
- const int i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
- pix[-1] = av_clip_uint8( p0 + i_delta ); /* p0' */
- pix[0] = av_clip_uint8( q0 - i_delta ); /* q0' */
- tprintf(h->s.avctx, "filter_mb_mbaff_edgecv i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%dn# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1);
- }
- }else{
- const int p0 = pix[-1];
- const int p1 = pix[-2];
- const int q0 = pix[0];
- const int q1 = pix[1];
- if( FFABS( p0 - q0 ) < alpha &&
- FFABS( p1 - p0 ) < beta &&
- FFABS( q1 - q0 ) < beta ) {
- pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */
- pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */
- tprintf(h->s.avctx, "filter_mb_mbaff_edgecv i:%dn# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]n", i, pix[-3], p1, p0, q0, q1, pix[2], pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]);
- }
- }
- }
- }
- static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) {
- const int index_a = qp + h->slice_alpha_c0_offset;
- const int alpha = (alpha_table+52)[index_a];
- const int beta = (beta_table+52)[qp + h->slice_beta_offset];
- if( bS[0] < 4 ) {
- int8_t tc[4];
- tc[0] = (tc0_table+52)[index_a][bS[0]];
- tc[1] = (tc0_table+52)[index_a][bS[1]];
- tc[2] = (tc0_table+52)[index_a][bS[2]];
- tc[3] = (tc0_table+52)[index_a][bS[3]];
- h->s.dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);
- } else {
- h->s.dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);
- }
- }
- static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) {
- const int index_a = qp + h->slice_alpha_c0_offset;
- const int alpha = (alpha_table+52)[index_a];
- const int beta = (beta_table+52)[qp + h->slice_beta_offset];
- if( bS[0] < 4 ) {
- int8_t tc[4];
- tc[0] = (tc0_table+52)[index_a][bS[0]]+1;
- tc[1] = (tc0_table+52)[index_a][bS[1]]+1;
- tc[2] = (tc0_table+52)[index_a][bS[2]]+1;
- tc[3] = (tc0_table+52)[index_a][bS[3]]+1;
- h->s.dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc);
- } else {
- h->s.dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta);
- }
- }
- static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
- MpegEncContext * const s = &h->s;
- int mb_y_firstrow = s->picture_structure == PICT_BOTTOM_FIELD;
- int mb_xy, mb_type;
- int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh;
- mb_xy = h->mb_xy;
- if(mb_x==0 || mb_y==mb_y_firstrow || !s->dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff ||
- !(s->flags2 & CODEC_FLAG2_FAST) || //FIXME filter_mb_fast is broken, thus hasto be, but should not under CODEC_FLAG2_FAST
- (h->deblocking_filter == 2 && (h->slice_table[mb_xy] != h->slice_table[h->top_mb_xy] ||
- h->slice_table[mb_xy] != h->slice_table[mb_xy - 1]))) {
- filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
- return;
- }
- assert(!FRAME_MBAFF);
- mb_type = s->current_picture.mb_type[mb_xy];
- qp = s->current_picture.qscale_table[mb_xy];
- qp0 = s->current_picture.qscale_table[mb_xy-1];
- qp1 = s->current_picture.qscale_table[h->top_mb_xy];
- qpc = get_chroma_qp( h, 0, qp );
- qpc0 = get_chroma_qp( h, 0, qp0 );
- qpc1 = get_chroma_qp( h, 0, qp1 );
- qp0 = (qp + qp0 + 1) >> 1;
- qp1 = (qp + qp1 + 1) >> 1;
- qpc0 = (qpc + qpc0 + 1) >> 1;
- qpc1 = (qpc + qpc1 + 1) >> 1;
- qp_thresh = 15 - h->slice_alpha_c0_offset;
- if(qp <= qp_thresh && qp0 <= qp_thresh && qp1 <= qp_thresh &&
- qpc <= qp_thresh && qpc0 <= qp_thresh && qpc1 <= qp_thresh)
- return;
- if( IS_INTRA(mb_type) ) {
- int16_t bS4[4] = {4,4,4,4};
- int16_t bS3[4] = {3,3,3,3};
- int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
- if( IS_8x8DCT(mb_type) ) {
- filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 );
- filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp );
- filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 );
- filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp );
- } else {
- filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 );
- filter_mb_edgev( h, &img_y[4*1], linesize, bS3, qp );
- filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp );
- filter_mb_edgev( h, &img_y[4*3], linesize, bS3, qp );
- filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 );
- filter_mb_edgeh( h, &img_y[4*1*linesize], linesize, bS3, qp );
- filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp );
- filter_mb_edgeh( h, &img_y[4*3*linesize], linesize, bS3, qp );
- }
- filter_mb_edgecv( h, &img_cb[2*0], uvlinesize, bS4, qpc0 );
- filter_mb_edgecv( h, &img_cb[2*2], uvlinesize, bS3, qpc );
- filter_mb_edgecv( h, &img_cr[2*0], uvlinesize, bS4, qpc0 );
- filter_mb_edgecv( h, &img_cr[2*2], uvlinesize, bS3, qpc );
- filter_mb_edgech( h, &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1 );
- filter_mb_edgech( h, &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc );
- filter_mb_edgech( h, &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1 );
- filter_mb_edgech( h, &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc );
- return;
- } else {
- DECLARE_ALIGNED_8(int16_t, bS[2][4][4]);
- uint64_t (*bSv)[4] = (uint64_t(*)[4])bS;
- int edges;
- if( IS_8x8DCT(mb_type) && (h->cbp&7) == 7 ) {
- edges = 4;
- bSv[0][0] = bSv[0][2] = bSv[1][0] = bSv[1][2] = 0x0002000200020002ULL;
- } else {
- int mask_edge1 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16)) ? 3 :
- (mb_type & MB_TYPE_16x8) ? 1 : 0;
- int mask_edge0 = (mb_type & (MB_TYPE_16x16 | MB_TYPE_8x16))
- && (s->current_picture.mb_type[mb_xy-1] & (MB_TYPE_16x16 | MB_TYPE_8x16))
- ? 3 : 0;
- int step = IS_8x8DCT(mb_type) ? 2 : 1;
- edges = (mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
- s->dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,
- (h->slice_type_nos == FF_B_TYPE), edges, step, mask_edge0, mask_edge1, FIELD_PICTURE);
- }
- if( IS_INTRA(s->current_picture.mb_type[mb_xy-1]) )
- bSv[0][0] = 0x0004000400040004ULL;
- if( IS_INTRA(s->current_picture.mb_type[h->top_mb_xy]) )
- bSv[1][0] = FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL;
- #define FILTER(hv,dir,edge)
- if(bSv[dir][edge]) {
- filter_mb_edge##hv( h, &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir );
- if(!(edge&1)) {
- filter_mb_edgec##hv( h, &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );
- filter_mb_edgec##hv( h, &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir );
- }
- }
- if( edges == 1 ) {
- FILTER(v,0,0);
- FILTER(h,1,0);
- } else if( IS_8x8DCT(mb_type) ) {
- FILTER(v,0,0);
- FILTER(v,0,2);
- FILTER(h,1,0);
- FILTER(h,1,2);
- } else {
- FILTER(v,0,0);
- FILTER(v,0,1);
- FILTER(v,0,2);
- FILTER(v,0,3);
- FILTER(h,1,0);
- FILTER(h,1,1);
- FILTER(h,1,2);
- FILTER(h,1,3);
- }
- #undef FILTER
- }
- }
- static void av_always_inline filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) {
- MpegEncContext * const s = &h->s;
- int edge;
- const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
- const int mbm_type = s->current_picture.mb_type[mbm_xy];
- //int (*ref2frm) [64] = h->ref2frm[ h->slice_num &(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- //int (*ref2frmm)[64] = h->ref2frm[ h->slice_table[mbm_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- int* ref2frm[2];
- int* ref2frmm[2];
- int start = h->slice_table[mbm_xy] == 0xFFFF ? 1 : 0;
- const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP))
- == (MB_TYPE_16x16|MB_TYPE_SKIP) ? 1 : 4;
- // how often to recheck mv-based bS when iterating between edges
- const int mask_edge = (mb_type & (MB_TYPE_16x16 | (MB_TYPE_16x8 << dir))) ? 3 :
- (mb_type & (MB_TYPE_8x16 >> dir)) ? 1 : 0;
- // how often to recheck mv-based bS when iterating along each edge
- const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir));
- ref2frm[0] = h->ref2frm[ h->slice_num &(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- ref2frm[1] = h->ref2frm[ h->slice_num &(MAX_SLICES-1) ][1] + (MB_MBAFF ? 20 : 2);
-
- ref2frmm[0] = h->ref2frm[ h->slice_table[mbm_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
- ref2frmm[1] = h->ref2frm[ h->slice_table[mbm_xy]&(MAX_SLICES-1) ][1] + (MB_MBAFF ? 20 : 2);
- if (first_vertical_edge_done) {
- start = 1;
- }
- if (h->deblocking_filter==2 && h->slice_table[mbm_xy] != h->slice_table[mb_xy])
- start = 1;
- if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0) && start == 0
- && !IS_INTERLACED(mb_type)
- && IS_INTERLACED(mbm_type)
- ) {
- // This is a special case in the norm where the filtering must
- // be done twice (one each of the field) even if we are in a
- // frame macroblock.
- //
- static const int nnz_idx[4] = {4,5,6,3};
- unsigned int tmp_linesize = 2 * linesize;
- unsigned int tmp_uvlinesize = 2 * uvlinesize;
- int mbn_xy = mb_xy - 2 * s->mb_stride;
- int qp;
- int i, j;
- int16_t bS[4];
- for(j=0; j<2; j++, mbn_xy += s->mb_stride){
- if( IS_INTRA(mb_type) ||
- IS_INTRA(s->current_picture.mb_type[mbn_xy]) ) {
- bS[0] = bS[1] = bS[2] = bS[3] = 3;
- } else {
- const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy];
- for( i = 0; i < 4; i++ ) {
- if( h->non_zero_count_cache[scan8[0]+i] != 0 ||
- mbn_nnz[nnz_idx[i]] != 0 )
- bS[i] = 2;
- else
- bS[i] = 1;
- }
- }
- // Do not use s->qscale as luma quantizer because it has not the same
- // value in IPCM macroblocks.
- qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;
- tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
- { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "n"); }
- filter_mb_edgeh( h, &img_y[j*linesize], tmp_linesize, bS, qp );
- filter_mb_edgech( h, &img_cb[j*uvlinesize], tmp_uvlinesize, bS,
- ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- filter_mb_edgech( h, &img_cr[j*uvlinesize], tmp_uvlinesize, bS,
- ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- }
- start = 1;
- }
- /* Calculate bS */
- for( edge = start; edge < edges; edge++ ) {
- /* mbn_xy: neighbor macroblock */
- const int mbn_xy = edge > 0 ? mb_xy : mbm_xy;
- const int mbn_type = s->current_picture.mb_type[mbn_xy];
- //int (*ref2frmn)[64] = edge > 0 ? ref2frm : ref2frmm;
- int* ref2frmn[2];
- int16_t bS[4];
- int qp;
- ref2frmn[0] = edge > 0 ? ref2frm[0] : ref2frmm[0];
- ref2frmn[1] = edge > 0 ? ref2frm[1] : ref2frmm[1];
- if( (edge&1) && IS_8x8DCT(mb_type) )
- continue;
- if( IS_INTRA(mb_type) ||
- IS_INTRA(mbn_type) ) {
- int value;
- if (edge == 0) {
- if ( (!IS_INTERLACED(mb_type) && !IS_INTERLACED(mbm_type))
- || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
- ) {
- value = 4;
- } else {
- value = 3;
- }
- } else {
- value = 3;
- }
- bS[0] = bS[1] = bS[2] = bS[3] = value;
- } else {
- int i, l;
- int mv_done;
- if( edge & mask_edge ) {
- bS[0] = bS[1] = bS[2] = bS[3] = 0;
- mv_done = 1;
- }
- else if( FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbn_type)) {
- bS[0] = bS[1] = bS[2] = bS[3] = 1;
- mv_done = 1;
- }
- else if( mask_par0 && (edge || (mbn_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) {
- int b_idx= 8 + 4 + edge * (dir ? 8:1);
- int bn_idx= b_idx - (dir ? 8:1);
- int v = 0;
- for( l = 0; !v && l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
- v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
- FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
- FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit;
- }
- if(h->slice_type_nos == FF_B_TYPE && v){
- v=0;
- for( l = 0; !v && l < 2; l++ ) {
- int ln= 1-l;
- v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
- FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
- FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit;
- }
- }
- bS[0] = bS[1] = bS[2] = bS[3] = v;
- mv_done = 1;
- }
- else
- mv_done = 0;
- for( i = 0; i < 4; i++ ) {
- int x = dir == 0 ? edge : i;
- int y = dir == 0 ? i : edge;
- int b_idx= 8 + 4 + x + 8*y;
- int bn_idx= b_idx - (dir ? 8:1);
- if( h->non_zero_count_cache[b_idx] |
- h->non_zero_count_cache[bn_idx] ) {
- bS[i] = 2;
- }
- else if(!mv_done)
- {
- bS[i] = 0;
- for( l = 0; l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
- if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
- FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
- FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit ) {
- bS[i] = 1;
- break;
- }
- }
- if(h->slice_type_nos == FF_B_TYPE && bS[i]){
- bS[i] = 0;
- for( l = 0; l < 2; l++ ) {
- int ln= 1-l;
- if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
- FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
- FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit ) {
- bS[i] = 1;
- break;
- }
- }
- }
- }
- }
- if(bS[0]+bS[1]+bS[2]+bS[3] == 0)
- continue;
- }
- /* Filter edge */
- // Do not use s->qscale as luma quantizer because it has not the same
- // value in IPCM macroblocks.
- qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;
- //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%dn", mb_x, mb_y, dir, edge, qp, h->chroma_qp, s->current_picture.qscale_table[mbn_xy]);
- tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
- { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "n"); }
- if( dir == 0 ) {
- filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp );
- if( (edge&1) == 0 ) {
- filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS,
- ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS,
- ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- }
- } else {
- filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp );
- if( (edge&1) == 0 ) {
- filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS,
- ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS,
- ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1);
- }
- }
- }
- }
- static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
- MpegEncContext * const s = &h->s;
- const int mb_xy= mb_x + mb_y*s->mb_stride;
- const int mb_type = s->current_picture.mb_type[mb_xy];
- const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
- int first_vertical_edge_done = 0;
- //for sufficiently low qp, filtering wouldn't do anything
- //this is a conservative estimate: could also check beta_offset and more accurate chroma_qp
- if(!FRAME_MBAFF){
- int qp_thresh = 15 - h->slice_alpha_c0_offset - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]);
- int qp = s->current_picture.qscale_table[mb_xy];
- if(qp <= qp_thresh
- && (mb_x == 0 || ((qp + s->current_picture.qscale_table[mb_xy-1] + 1)>>1) <= qp_thresh)
- && (mb_y == 0 || ((qp + s->current_picture.qscale_table[h->top_mb_xy] + 1)>>1) <= qp_thresh)){
- return;
- }
- }
- // CAVLC 8x8dct requires NNZ values for residual decoding that differ from what the loop filter needs
- if(!h->pps.cabac && h->pps.transform_8x8_mode){
- int top_type, left_type[2];
- top_type = s->current_picture.mb_type[h->top_mb_xy] ;
- left_type[0] = s->current_picture.mb_type[h->left_mb_xy[0]];
- left_type[1] = s->current_picture.mb_type[h->left_mb_xy[1]];
- if(IS_8x8DCT(top_type)){
- h->non_zero_count_cache[4+8*0]=
- h->non_zero_count_cache[5+8*0]= h->cbp_table[h->top_mb_xy] & 4;
- h->non_zero_count_cache[6+8*0]=
- h->non_zero_count_cache[7+8*0]= h->cbp_table[h->top_mb_xy] & 8;
- }
- if(IS_8x8DCT(left_type[0])){
- h->non_zero_count_cache[3+8*1]=
- h->non_zero_count_cache[3+8*2]= h->cbp_table[h->left_mb_xy[0]]&2; //FIXME check MBAFF
- }
- if(IS_8x8DCT(left_type[1])){
- h->non_zero_count_cache[3+8*3]=
- h->non_zero_count_cache[3+8*4]= h->cbp_table[h->left_mb_xy[1]]&8; //FIXME check MBAFF
- }
- if(IS_8x8DCT(mb_type)){
- h->non_zero_count_cache[scan8[0 ]]= h->non_zero_count_cache[scan8[1 ]]=
- h->non_zero_count_cache[scan8[2 ]]= h->non_zero_count_cache[scan8[3 ]]= h->cbp & 1;
- h->non_zero_count_cache[scan8[0+ 4]]= h->non_zero_count_cache[scan8[1+ 4]]=
- h->non_zero_count_cache[scan8[2+ 4]]= h->non_zero_count_cache[scan8[3+ 4]]= h->cbp & 2;
- h->non_zero_count_cache[scan8[0+ 8]]= h->non_zero_count_cache[scan8[1+ 8]]=
- h->non_zero_count_cache[scan8[2+ 8]]= h->non_zero_count_cache[scan8[3+ 8]]= h->cbp & 4;
- h->non_zero_count_cache[scan8[0+12]]= h->non_zero_count_cache[scan8[1+12]]=
- h->non_zero_count_cache[scan8[2+12]]= h->non_zero_count_cache[scan8[3+12]]= h->cbp & 8;
- }
- }
- if (FRAME_MBAFF
- // left mb is in picture
- && h->slice_table[mb_xy-1] != 0xFFFF
- // and current and left pair do not have the same interlaced type
- && (IS_INTERLACED(mb_type) != IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]))
- // and left mb is in the same slice if deblocking_filter == 2
- && (h->deblocking_filter!=2 || h->slice_table[mb_xy-1] == h->slice_table[mb_xy])) {
- /* First vertical edge is different in MBAFF frames
- * There are 8 different bS to compute and 2 different Qp
- */
- const int pair_xy = mb_x + (mb_y&~1)*s->mb_stride;
- const int left_mb_xy[2] = { pair_xy-1, pair_xy-1+s->mb_stride };
- int16_t bS[8];
- int qp[2];
- int bqp[2];
- int rqp[2];
- int mb_qp, mbn0_qp, mbn1_qp;
- int i;
- first_vertical_edge_done = 1;
- if( IS_INTRA(mb_type) )
- bS[0] = bS[1] = bS[2] = bS[3] = bS[4] = bS[5] = bS[6] = bS[7] = 4;
- else {
- for( i = 0; i < 8; i++ ) {
- int mbn_xy = MB_FIELD ? left_mb_xy[i>>2] : left_mb_xy[i&1];
- if( IS_INTRA( s->current_picture.mb_type[mbn_xy] ) )
- bS[i] = 4;
- else if( h->non_zero_count_cache[12+8*(i>>1)] != 0 ||
- ((!h->pps.cabac && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])) ?
- (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2))
- :
- h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2]))
- bS[i] = 2;
- else
- bS[i] = 1;
- }
- }
- mb_qp = s->current_picture.qscale_table[mb_xy];
- mbn0_qp = s->current_picture.qscale_table[left_mb_xy[0]];
- mbn1_qp = s->current_picture.qscale_table[left_mb_xy[1]];
- qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
- bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
- get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
- rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) +
- get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1;
- qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1;
- bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) +
- get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1;
- rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) +
- get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
- /* Filter edge */
- tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
- { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "n"); }
- filter_mb_mbaff_edgev ( h, &img_y [0], linesize, bS, qp );
- filter_mb_mbaff_edgecv( h, &img_cb[0], uvlinesize, bS, bqp );
- filter_mb_mbaff_edgecv( h, &img_cr[0], uvlinesize, bS, rqp );
- }
- #ifdef CONFIG_SMALL
- for( dir = 0; dir < 2; dir++ )
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir);
- #else
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, 0);
- filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1);
- #endif
- }
- 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 ||
- (ENABLE_GRAY && (s->flags&CODEC_FLAG_GRAY)) || (ENABLE_H264_ENCODER && s->encoding);
- 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,
- ( s->gb.size_in_bits - get_bits_count(&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) 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) 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 %dn", 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) 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) hl_decode_mb(h);
- s->mb_y--;
- }
- if(ret<0){
- av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %dn", 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 %dn", 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 %dn", 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);
- hl_decode_mb(h);
- if(ret<0){
- av_log(s->avctx, AV_LOG_ERROR, "error while decoding MB %d %dn", 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;
- }
- }
- }
- s->mb_x=0;
- ff_draw_horiz_band(s, 16*s->mb_y, 16);
- }
- #endif
- return -1; //not reached
- }
- static int decode_picture_timing(H264Context *h){
- MpegEncContext * const s = &h->s;
- if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
- skip_bits(&s->gb, h->sps.cpb_removal_delay_length); /* cpb_removal_delay */
- skip_bits(&s->gb, h->sps.dpb_output_delay_length); /* dpb_output_delay */
- }
- if(h->sps.pic_struct_present_flag){
- unsigned int i, num_clock_ts;
- h->sei_pic_struct = (SEI_PicStructType)get_bits(&s->gb, 4);
- if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
- return -1;
- num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct];
- for (i = 0 ; i < num_clock_ts ; i++){
- if(get_bits(&s->gb, 1)){ /* clock_timestamp_flag */
- unsigned int full_timestamp_flag;
- skip_bits(&s->gb, 2); /* ct_type */
- skip_bits(&s->gb, 1); /* nuit_field_based_flag */
- skip_bits(&s->gb, 5); /* counting_type */
- full_timestamp_flag = get_bits(&s->gb, 1);
- skip_bits(&s->gb, 1); /* discontinuity_flag */
- skip_bits(&s->gb, 1); /* cnt_dropped_flag */
- skip_bits(&s->gb, 8); /* n_frames */
- if(full_timestamp_flag){
- skip_bits(&s->gb, 6); /* seconds_value 0..59 */
- skip_bits(&s->gb, 6); /* minutes_value 0..59 */
- skip_bits(&s->gb, 5); /* hours_value 0..23 */
- }else{
- if(get_bits(&s->gb, 1)){ /* seconds_flag */
- skip_bits(&s->gb, 6); /* seconds_value range 0..59 */
- if(get_bits(&s->gb, 1)){ /* minutes_flag */
- skip_bits(&s->gb, 6); /* minutes_value 0..59 */
- if(get_bits(&s->gb, 1)) /* hours_flag */
- skip_bits(&s->gb, 5); /* hours_value 0..23 */
- }
- }
- }
- if(h->sps.time_offset_length > 0)
- skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */
- }
- }
- }
- return 0;
- }
- static int decode_unregistered_user_data(H264Context *h, int size){
- MpegEncContext * const s = &h->s;
- uint8_t user_data[16+256];
- int e, build, i;
- if(size<16)
- return -1;
- for(i=0; i<sizeof(user_data)-1 && i<size; i++){
- user_data[i]= get_bits(&s->gb, 8);
- }
- user_data[i]= 0;
- e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
- if(e==1 && build>=0)
- h->x264_build= build;
- if(s->avctx->debug & FF_DEBUG_BUGS)
- av_log(s->avctx, AV_LOG_DEBUG, "user data:"%s"n", user_data+16);
- for(; i<size; i++)
- skip_bits(&s->gb, 8);
- return 0;
- }
- static int decode_sei(H264Context *h){
- MpegEncContext * const s = &h->s;
- while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){
- int size, type;
- type=0;
- do{
- type+= show_bits(&s->gb, 8);
- }while(get_bits(&s->gb, 8) == 255);
- size=0;
- do{
- size+= show_bits(&s->gb, 8);
- }while(get_bits(&s->gb, 8) == 255);
- switch(type){
- case 1: // Picture timing SEI
- if(decode_picture_timing(h) < 0)
- return -1;
- break;
- case 5:
- if(decode_unregistered_user_data(h, size) < 0)
- return -1;
- break;
- default:
- skip_bits(&s->gb, 8*size);
- }
- //FIXME check bits here
- align_get_bits(&s->gb);
- }
- return 0;
- }
- static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
- MpegEncContext * const s = &h->s;
- int cpb_count, i;
- cpb_count = get_ue_golomb_31(&s->gb) + 1;
- if(cpb_count > 32U){
- av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalidn", cpb_count);
- return -1;
- }
- get_bits(&s->gb, 4); /* bit_rate_scale */
- get_bits(&s->gb, 4); /* cpb_size_scale */
- for(i=0; i<cpb_count; i++){
- get_ue_golomb(&s->gb); /* bit_rate_value_minus1 */
- get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */
- get_bits1(&s->gb); /* cbr_flag */
- }
- get_bits(&s->gb, 5); /* initial_cpb_removal_delay_length_minus1 */
- sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
- sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
- sps->time_offset_length = get_bits(&s->gb, 5);
- return 0;
- }
- static inline int decode_vui_parameters(H264Context *h, SPS *sps){
- MpegEncContext * const s = &h->s;
- int aspect_ratio_info_present_flag;
- unsigned int aspect_ratio_idc;
- aspect_ratio_info_present_flag= get_bits1(&s->gb);
- if( aspect_ratio_info_present_flag ) {
- aspect_ratio_idc= get_bits(&s->gb, 8);
- if( aspect_ratio_idc == EXTENDED_SAR ) {
- sps->sar.num= get_bits(&s->gb, 16);
- sps->sar.den= get_bits(&s->gb, 16);
- }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){
- sps->sar= pixel_aspect[aspect_ratio_idc];
- }else{
- av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ration");
- return -1;
- }
- }else{
- sps->sar.num=
- sps->sar.den= 0;
- }
- // s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);
- if(get_bits1(&s->gb)){ /* overscan_info_present_flag */
- get_bits1(&s->gb); /* overscan_appropriate_flag */
- }
- if(get_bits1(&s->gb)){ /* video_signal_type_present_flag */
- get_bits(&s->gb, 3); /* video_format */
- get_bits1(&s->gb); /* video_full_range_flag */
- if(get_bits1(&s->gb)){ /* colour_description_present_flag */
- get_bits(&s->gb, 8); /* colour_primaries */
- get_bits(&s->gb, 8); /* transfer_characteristics */
- get_bits(&s->gb, 8); /* matrix_coefficients */
- }
- }
- if(get_bits1(&s->gb)){ /* chroma_location_info_present_flag */
- get_ue_golomb(&s->gb); /* chroma_sample_location_type_top_field */
- get_ue_golomb(&s->gb); /* chroma_sample_location_type_bottom_field */
- }
- sps->timing_info_present_flag = get_bits1(&s->gb);
- if(sps->timing_info_present_flag){
- sps->num_units_in_tick = get_bits_long(&s->gb, 32);
- sps->time_scale = get_bits_long(&s->gb, 32);
- sps->fixed_frame_rate_flag = get_bits1(&s->gb);
- }
- sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb);
- if(sps->nal_hrd_parameters_present_flag)
- if(decode_hrd_parameters(h, sps) < 0)
- return -1;
- sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb);
- if(sps->vcl_hrd_parameters_present_flag)
- if(decode_hrd_parameters(h, sps) < 0)
- return -1;
- if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)
- get_bits1(&s->gb); /* low_delay_hrd_flag */
- sps->pic_struct_present_flag = get_bits1(&s->gb);
- sps->bitstream_restriction_flag = get_bits1(&s->gb);
- if(sps->bitstream_restriction_flag){
- get_bits1(&s->gb); /* motion_vectors_over_pic_boundaries_flag */
- get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */
- get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */
- get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */
- get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */
- sps->num_reorder_frames= get_ue_golomb(&s->gb);
- get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
- if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
- av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %dn", sps->num_reorder_frames);
- return -1;
- }
- }
- return 0;
- }
- static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
- const uint8_t *jvt_list, const uint8_t *fallback_list){
- MpegEncContext * const s = &h->s;
- int i, last = 8, next = 8;
- const uint8_t *scan = size == 16 ? zigzag_scan : zigzag_scan8x8;
- if(!get_bits1(&s->gb)) /* matrix not written, we use the predicted one */
- memcpy(factors, fallback_list, size*sizeof(uint8_t));
- else
- for(i=0;i<size;i++){
- if(next)
- next = (last + get_se_golomb(&s->gb)) & 0xff;
- if(!i && !next){ /* matrix not written, we use the preset one */
- memcpy(factors, jvt_list, size*sizeof(uint8_t));
- break;
- }
- last = factors[scan[i]] = next ? next : last;
- }
- }
- static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps,
- uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){
- MpegEncContext * const s = &h->s;
- int fallback_sps = !is_sps && sps->scaling_matrix_present;
- const uint8_t *fallback[4] = {
- fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
- fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1],
- fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
- fallback_sps ? sps->scaling_matrix8[1] : default_scaling8[1]
- };
- if(get_bits1(&s->gb)){
- sps->scaling_matrix_present |= is_sps;
- decode_scaling_list(h,scaling_matrix4[0],16,default_scaling4[0],fallback[0]); // Intra, Y
- decode_scaling_list(h,scaling_matrix4[1],16,default_scaling4[0],scaling_matrix4[0]); // Intra, Cr
- decode_scaling_list(h,scaling_matrix4[2],16,default_scaling4[0],scaling_matrix4[1]); // Intra, Cb
- decode_scaling_list(h,scaling_matrix4[3],16,default_scaling4[1],fallback[1]); // Inter, Y
- decode_scaling_list(h,scaling_matrix4[4],16,default_scaling4[1],scaling_matrix4[3]); // Inter, Cr
- decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
- if(is_sps || pps->transform_8x8_mode){
- decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y
- decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y
- }
- }
- }
- static inline int decode_seq_parameter_set(H264Context *h){
- MpegEncContext * const s = &h->s;
- int profile_idc, level_idc;
- unsigned int sps_id;
- int i;
- SPS *sps;
- profile_idc= get_bits(&s->gb, 8);
- get_bits1(&s->gb); //constraint_set0_flag
- get_bits1(&s->gb); //constraint_set1_flag
- get_bits1(&s->gb); //constraint_set2_flag
- get_bits1(&s->gb); //constraint_set3_flag
- get_bits(&s->gb, 4); // reserved
- level_idc= get_bits(&s->gb, 8);
- sps_id= get_ue_golomb_31(&s->gb);
- if(sps_id >= MAX_SPS_COUNT) {
- av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of rangen", sps_id);
- return -1;
- }
- sps= av_mallocz(sizeof(SPS));
- if(sps == NULL)
- return -1;
- sps->profile_idc= profile_idc;
- sps->level_idc= level_idc;
- memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
- memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
- sps->scaling_matrix_present = 0;
- if(sps->profile_idc >= 100){ //high profile
- sps->chroma_format_idc= get_ue_golomb_31(&s->gb);
- if(sps->chroma_format_idc == 3)
- get_bits1(&s->gb); //residual_color_transform_flag
- get_ue_golomb(&s->gb); //bit_depth_luma_minus8
- get_ue_golomb(&s->gb); //bit_depth_chroma_minus8
- sps->transform_bypass = get_bits1(&s->gb);
- decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
- }else{
- sps->chroma_format_idc= 1;
- }
- sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4;
- sps->poc_type= get_ue_golomb_31(&s->gb);
- if(sps->poc_type == 0){ //FIXME #define
- sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4;
- } else if(sps->poc_type == 1){//FIXME #define
- sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);
- sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
- sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);
- sps->poc_cycle_length = get_ue_golomb(&s->gb);
- if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){
- av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %un", sps->poc_cycle_length);
- goto fail;
- }
- for(i=0; i<sps->poc_cycle_length; i++)
- sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb);
- }else if(sps->poc_type != 2){
- av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %dn", sps->poc_type);
- goto fail;
- }
- sps->ref_frame_count= get_ue_golomb_31(&s->gb);
- if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){
- av_log(h->s.avctx, AV_LOG_ERROR, "too many reference framesn");
- goto fail;
- }
- sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
- sps->mb_width = get_ue_golomb(&s->gb) + 1;
- sps->mb_height= get_ue_golomb(&s->gb) + 1;
- if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||
- avcodec_check_dimensions(NULL, 16*sps->mb_width, 16*sps->mb_height)){
- av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflown");
- goto fail;
- }
- sps->frame_mbs_only_flag= get_bits1(&s->gb);
- if(!sps->frame_mbs_only_flag)
- sps->mb_aff= get_bits1(&s->gb);
- else
- sps->mb_aff= 0;
- sps->direct_8x8_inference_flag= get_bits1(&s->gb);
- #ifndef ALLOW_INTERLACE
- if(sps->mb_aff)
- av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.n");
- #endif
- sps->crop= get_bits1(&s->gb);
- if(sps->crop){
- sps->crop_left = get_ue_golomb(&s->gb);
- sps->crop_right = get_ue_golomb(&s->gb);
- sps->crop_top = get_ue_golomb(&s->gb);
- sps->crop_bottom= get_ue_golomb(&s->gb);
- if(sps->crop_left || sps->crop_top){
- av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...n");
- }
- if((int)sps->crop_right >= 8 || (int)sps->crop_bottom >= (8>> !sps->frame_mbs_only_flag)){
- av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...n");
- }
- }else{
- sps->crop_left =
- sps->crop_right =
- sps->crop_top =
- sps->crop_bottom= 0;
- }
- sps->vui_parameters_present_flag= get_bits1(&s->gb);
- if( sps->vui_parameters_present_flag )
- decode_vui_parameters(h, sps);
- if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %sn",
- sps_id, sps->profile_idc, sps->level_idc,
- sps->poc_type,
- sps->ref_frame_count,
- sps->mb_width, sps->mb_height,
- sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"),
- sps->direct_8x8_inference_flag ? "8B8" : "",
- sps->crop_left, sps->crop_right,
- sps->crop_top, sps->crop_bottom,
- sps->vui_parameters_present_flag ? "VUI" : ""
- //((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc]
- );
- }
- av_free(h->sps_buffers[sps_id]);
- h->sps_buffers[sps_id]= sps;
- return 0;
- fail:
- av_free(sps);
- return -1;
- }
- static void
- build_qp_table(PPS *pps, int t, int index)
- {
- int i;
- for(i = 0; i < 52; i++)
- pps->chroma_qp_table[t][i] = chroma_qp[av_clip(i + index, 0, 51)];
- }
- static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
- MpegEncContext * const s = &h->s;
- unsigned int pps_id= get_ue_golomb(&s->gb);
- PPS *pps;
- if(pps_id >= MAX_PPS_COUNT) {
- av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of rangen", pps_id);
- return -1;
- }
- pps= av_mallocz(sizeof(PPS));
- if(pps == NULL)
- return -1;
- pps->sps_id= get_ue_golomb_31(&s->gb);
- if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){
- av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of rangen");
- goto fail;
- }
- pps->cabac= get_bits1(&s->gb);
- pps->pic_order_present= get_bits1(&s->gb);
- pps->slice_group_count= get_ue_golomb(&s->gb) + 1;
- if(pps->slice_group_count > 1 ){
- pps->mb_slice_group_map_type= get_ue_golomb(&s->gb);
- av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supportedn");
- switch(pps->mb_slice_group_map_type){
- case 0:
- #if 0
- | for( i = 0; i <= num_slice_groups_minus1; i++ ) | | |
- | run_length[ i ] |1 |ue(v) |
- #endif
- break;
- case 2:
- #if 0
- | for( i = 0; i < num_slice_groups_minus1; i++ ) | | |
- |{ | | |
- | top_left_mb[ i ] |1 |ue(v) |
- | bottom_right_mb[ i ] |1 |ue(v) |
- | } | | |
- #endif
- break;
- case 3:
- case 4:
- case 5:
- #if 0
- | slice_group_change_direction_flag |1 |u(1) |
- | slice_group_change_rate_minus1 |1 |ue(v) |
- #endif
- break;
- case 6:
- #if 0
- | slice_group_id_cnt_minus1 |1 |ue(v) |
- | for( i = 0; i <= slice_group_id_cnt_minus1; i++ | | |
- |) | | |
- | slice_group_id[ i ] |1 |u(v) |
- #endif
- break;
- }
- }
- pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
- pps->ref_count[1]= get_ue_golomb(&s->gb) + 1;
- if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){
- av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)n");
- goto fail;
- }
- pps->weighted_pred= get_bits1(&s->gb);
- pps->weighted_bipred_idc= get_bits(&s->gb, 2);
- pps->init_qp= get_se_golomb(&s->gb) + 26;
- pps->init_qs= get_se_golomb(&s->gb) + 26;
- pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);
- pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
- pps->constrained_intra_pred= get_bits1(&s->gb);
- pps->redundant_pic_cnt_present = get_bits1(&s->gb);
- pps->transform_8x8_mode= 0;
- h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit
- memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
- memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
- if(get_bits_count(&s->gb) < bit_length){
- pps->transform_8x8_mode= get_bits1(&s->gb);
- decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);
- pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset
- } else {
- pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
- }
- build_qp_table(pps, 0, pps->chroma_qp_index_offset[0]);
- build_qp_table(pps, 1, pps->chroma_qp_index_offset[1]);
- if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
- h->pps.chroma_qp_diff= 1;
- if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %sn",
- pps_id, pps->sps_id,
- pps->cabac ? "CABAC" : "CAVLC",
- pps->slice_group_count,
- pps->ref_count[0], pps->ref_count[1],
- pps->weighted_pred ? "weighted" : "",
- pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset[0], pps->chroma_qp_index_offset[1],
- pps->deblocking_filter_parameters_present ? "LPAR" : "",
- pps->constrained_intra_pred ? "CONSTR" : "",
- pps->redundant_pic_cnt_present ? "REDU" : "",
- pps->transform_8x8_mode ? "8x8DCT" : ""
- );
- }
- av_free(h->pps_buffers[pps_id]);
- h->pps_buffers[pps_id]= pps;
- return 0;
- fail:
- av_free(pps);
- return -1;
- }
- /**
- * Call decode_slice() for each context.
- *
- * @param h h264 master context
- * @param context_count number of contexts to execute
- */
- static void execute_decode_slices(H264Context *h, int context_count){
- MpegEncContext * const s = &h->s;
- AVCodecContext * const avctx= s->avctx;
- H264Context *hx;
- int i;
- if(avctx->codec_id == CODEC_ID_H264_VDPAU)
- return;
- if(context_count == 1)
- {
- decode_slice(avctx, &h);
- }
- else
- {
- for(i = 1; i < context_count; i++)
- {
- hx = h->thread_context[i];
- hx->s.error_recognition = avctx->error_recognition;
- hx->s.error_count = 0;
- }
- avctx->execute(avctx, decode_slice, (void **)h->thread_context, NULL, context_count, sizeof(void*));
- /* pull back stuff from slices to master context */
- hx = h->thread_context[context_count - 1];
- s->mb_x = hx->s.mb_x;
- s->mb_y = hx->s.mb_y;
- s->dropable = hx->s.dropable;
- s->picture_structure = hx->s.picture_structure;
- for(i = 1; i < context_count; i++)
- h->s.error_count += h->thread_context[i]->s.error_count;
- }
- }
- static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
- MpegEncContext * const s = &h->s;
- AVCodecContext * const avctx= s->avctx;
- int buf_index=0;
- H264Context *hx; ///< thread context
- int context_count = 0;
- h->max_contexts = avctx->thread_count;
- #if 0
- int i;
- for(i=0; i<50; i++){
- av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]);
- }
- #endif
- if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){
- h->current_slice = 0;
- if (!s->first_field)
- s->current_picture_ptr= NULL;
- }
- for(;;){
- int consumed;
- int dst_length;
- int bit_length;
- const uint8_t *ptr;
- int i, nalsize = 0;
- int err;
- if(h->is_avc) {
- if(buf_index >= buf_size) break;
- nalsize = 0;
- for(i = 0; i < h->nal_length_size; i++)
- nalsize = (nalsize << 8) | buf[buf_index++];
- if(nalsize <= 1 || (nalsize+buf_index > buf_size)){
- if(nalsize == 1){
- buf_index++;
- continue;
- }else{
- av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %dn", nalsize);
- break;
- }
- }
- } else {
- // start code prefix search
- for(; buf_index + 3 < buf_size; buf_index++){
- // This should always succeed in the first iteration.
- if(buf[buf_index] == 0 && buf[buf_index+1] == 0 && buf[buf_index+2] == 1)
- break;
- }
- if(buf_index+3 >= buf_size) break;
- buf_index+=3;
- }
- hx = h->thread_context[context_count];
- ptr= decode_nal(hx, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index);
- if (ptr==NULL || dst_length < 0){
- return -1;
- }
- while(ptr[dst_length - 1] == 0 && dst_length > 0)
- dst_length--;
- bit_length= !dst_length ? 0 : (8*dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1));
- if(s->avctx->debug&FF_DEBUG_STARTCODE){
- av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %dn", hx->nal_unit_type, buf_index, buf_size, dst_length);
- }
- if (h->is_avc && (nalsize != consumed)){
- av_log(h->s.avctx, AV_LOG_ERROR, "AVC: Consumed only %d bytes instead of %dn", consumed, nalsize);
- consumed= nalsize;
- }
- buf_index += consumed;
- if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME do not discard SEI id
- ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0))
- continue;
- again:
- err = 0;
- switch(hx->nal_unit_type){
- case NAL_IDR_SLICE:
- if (h->nal_unit_type != NAL_IDR_SLICE) {
- av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices");
- return -1;
- }
- idr(h); //FIXME ensure we don't loose some frames if there is reordering
- case NAL_SLICE:
- init_get_bits(&hx->s.gb, ptr, bit_length);
- hx->intra_gb_ptr=
- hx->inter_gb_ptr= &hx->s.gb;
- hx->s.data_partitioning = 0;
- if((err = decode_slice_header(hx, h)))
- break;
- s->current_picture_ptr->key_frame|= (hx->nal_unit_type == NAL_IDR_SLICE);
-
- if(hx->redundant_pic_count==0 && hx->s.hurry_up < 5
- &&
- (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc)
- &&
- (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=FF_B_TYPE)
- &&
- (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==FF_I_TYPE)
- &&
- avctx->skip_frame < AVDISCARD_ALL)
- {
- /*if(ENABLE_H264_VDPAU_DECODER && avctx->codec_id == CODEC_ID_H264_VDPAU)
- {
- static const uint8_t start_code[] = {0x00, 0x00, 0x01};
- ff_vdpau_add_data_chunk(s, start_code, sizeof(start_code));
- ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed], consumed );
- }
- else*/
- context_count++;
- }
- break;
- case NAL_DPA:
- init_get_bits(&hx->s.gb, ptr, bit_length);
- hx->intra_gb_ptr=
- hx->inter_gb_ptr= NULL;
- hx->s.data_partitioning = 1;
- err = decode_slice_header(hx, h);
- break;
- case NAL_DPB:
- init_get_bits(&hx->intra_gb, ptr, bit_length);
- hx->intra_gb_ptr= &hx->intra_gb;
- break;
- case NAL_DPC:
- init_get_bits(&hx->inter_gb, ptr, bit_length);
- hx->inter_gb_ptr= &hx->inter_gb;
- if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning
- && s->context_initialized
- && s->hurry_up < 5
- && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc)
- && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=FF_B_TYPE)
- && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type_nos==FF_I_TYPE)
- && avctx->skip_frame < AVDISCARD_ALL)
- context_count++;
- break;
- case NAL_SEI:
- init_get_bits(&s->gb, ptr, bit_length);
- decode_sei(h);
- break;
- case NAL_SPS:
- init_get_bits(&s->gb, ptr, bit_length);
- decode_seq_parameter_set(h);
- if(s->flags& CODEC_FLAG_LOW_DELAY)
- s->low_delay=1;
- if(avctx->has_b_frames < 2)
- avctx->has_b_frames= !s->low_delay;
- break;
- case NAL_PPS:
- init_get_bits(&s->gb, ptr, bit_length);
- decode_picture_parameter_set(h, bit_length);
- break;
- case NAL_AUD:
- case NAL_END_SEQUENCE:
- case NAL_END_STREAM:
- case NAL_FILLER_DATA:
- case NAL_SPS_EXT:
- case NAL_AUXILIARY_SLICE:
- break;
- default:
- av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)n", h->nal_unit_type, bit_length);
- }
- if(context_count == h->max_contexts) {
- execute_decode_slices(h, context_count);
- context_count = 0;
- }
- if (err < 0)
- av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header errorn");
- else if(err == 1) {
- /* Slice could not be decoded in parallel mode, copy down
- * NAL unit stuff to context 0 and restart. Note that
- * rbsp_buffer is not transferred, but since we no longer
- * run in parallel mode this should not be an issue. */
- h->nal_unit_type = hx->nal_unit_type;
- h->nal_ref_idc = hx->nal_ref_idc;
- hx = h;
- goto again;
- }
- }
- if(context_count)
- execute_decode_slices(h, context_count);
- return buf_index;
- }
- /**
- * returns the number of bytes consumed for building the current frame
- */
- static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){
- if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
- if(pos+10>buf_size) pos=buf_size; // oops ;)
- return pos;
- }
- static int decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- const uint8_t *buf, int buf_size)
- {
- H264Context *h = avctx->priv_data;
- MpegEncContext *s = &h->s;
- AVFrame *pict = data;
- int buf_index;
- s->flags= avctx->flags;
- s->flags2= avctx->flags2;
- /* end of stream, output what is still in the buffers */
- if (buf_size == 0) {
- Picture *out;
- int i, out_idx;
- //FIXME factorize this with the output code below
- out = h->delayed_pic[0];
- out_idx = 0;
- for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
- if(h->delayed_pic[i]->poc < out->poc){
- out = h->delayed_pic[i];
- out_idx = i;
- }
- for(i=out_idx; h->delayed_pic[i]; i++)
- h->delayed_pic[i] = h->delayed_pic[i+1];
- if(out){
- *data_size = sizeof(AVFrame);
- *pict= *(AVFrame*)out;
- }
- 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 shortn");
- return -1;
- }
- if(*p != 1) {
- av_log(avctx, AV_LOG_ERROR, "Unknown avcC version %dn", *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 failedn", 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 failedn", 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;
- if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){
- if (avctx->skip_frame >= AVDISCARD_NONREF || s->hurry_up) return 0;
- av_log(avctx, AV_LOG_ERROR, "no frame!n");
- return -1;
- }
- if(!(s->flags2 & CODEC_FLAG2_CHUNKS) || (s->mb_y >= s->mb_height && s->mb_height)){
- Picture *out = s->current_picture_ptr;
- Picture *cur = s->current_picture_ptr;
- int i, pics, cross_idr, out_of_order, out_idx;
- s->mb_y= 0;
- s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
- s->current_picture_ptr->pict_type= s->pict_type;
- //if (ENABLE_H264_VDPAU_DECODER && avctx->codec_id == CODEC_ID_H264_VDPAU)
- // ff_vdpau_h264_set_reference_frames(s);
- if(!s->dropable) {
- execute_ref_pic_marking(h, h->mmco, h->mmco_index);
- h->prev_poc_msb= h->poc_msb;
- h->prev_poc_lsb= h->poc_lsb;
- }
- h->prev_frame_num_offset= h->frame_num_offset;
- h->prev_frame_num= h->frame_num;
- //if (ENABLE_H264_VDPAU_DECODER && avctx->codec_id == CODEC_ID_H264_VDPAU)
- // ff_vdpau_h264_picture_complete(s);
- /*
- * FIXME: Error handling code does not seem to support interlaced
- * when slices span multiple rows
- * The ff_er_add_slice calls don't work right for bottom
- * fields; they cause massive erroneous error concealing
- * Error marking covers both fields (top and bottom).
- * This causes a mismatched s->error_count
- * and a bad error table. Further, the error count goes to
- * INT_MAX when called for bottom field, because mb_y is
- * past end by one (callers fault) and resync_mb_y != 0
- * causes problems for the first MB line, too.
- */
- if (!FIELD_PICTURE)
- ff_er_frame_end(s);
- MPV_frame_end(s);
- if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) {
- /* Wait for second field. */
- *data_size = 0;
- } else {
- cur->repeat_pict = 0;
- /* Signal interlacing information externally. */
- /* Prioritize picture timing SEI information over used decoding process if it exists. */
- if(h->sps.pic_struct_present_flag){
- switch (h->sei_pic_struct)
- {
- case SEI_PIC_STRUCT_FRAME:
- cur->interlaced_frame = 0;
- break;
- case SEI_PIC_STRUCT_TOP_FIELD:
- case SEI_PIC_STRUCT_BOTTOM_FIELD:
- case SEI_PIC_STRUCT_TOP_BOTTOM:
- case SEI_PIC_STRUCT_BOTTOM_TOP:
- cur->interlaced_frame = 1;
- break;
- case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
- case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
- // Signal the possibility of telecined film externally (pic_struct 5,6)
- // From these hints, let the applications decide if they apply deinterlacing.
- cur->repeat_pict = 1;
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
- break;
- case SEI_PIC_STRUCT_FRAME_DOUBLING:
- // Force progressive here, as doubling interlaced frame is a bad idea.
- cur->interlaced_frame = 0;
- cur->repeat_pict = 2;
- break;
- case SEI_PIC_STRUCT_FRAME_TRIPLING:
- cur->interlaced_frame = 0;
- cur->repeat_pict = 4;
- break;
- }
- }else{
- /* Derive interlacing flag from used decoding process. */
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
- }
- if (cur->field_poc[0] != cur->field_poc[1]){
- /* Derive top_field_first from field pocs. */
- cur->top_field_first = cur->field_poc[0] < cur->field_poc[1];
- }else{
- if(cur->interlaced_frame || h->sps.pic_struct_present_flag){
- /* Use picture timing SEI information. Even if it is a information of a past frame, better than nothing. */
- if(h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM
- || h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
- cur->top_field_first = 1;
- else
- cur->top_field_first = 0;
- }else{
- /* Most likely progressive */
- cur->top_field_first = 0;
- }
- }
- //FIXME do something with unavailable reference frames
- /* Sort B-frames into display order */
- 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;
- }
- if( s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT
- && !h->sps.bitstream_restriction_flag){
- s->avctx->has_b_frames= MAX_DELAYED_PIC_COUNT;
- s->low_delay= 0;
- }
- pics = 0;
- while(h->delayed_pic[pics]) pics++;
- assert(pics <= MAX_DELAYED_PIC_COUNT);
- h->delayed_pic[pics++] = cur;
- if(cur->reference == 0)
- cur->reference = DELAYED_PIC_REF;
- out = h->delayed_pic[0];
- out_idx = 0;
- for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
- if(h->delayed_pic[i]->poc < out->poc){
- out = h->delayed_pic[i];
- out_idx = i;
- }
- cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame;
- out_of_order = !cross_idr && out->poc < h->outputed_poc;
- if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames)
- { }
- else if((out_of_order && pics-1 == s->avctx->has_b_frames && s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT)
- || (s->low_delay &&
- ((!cross_idr && out->poc > h->outputed_poc + 2)
- || cur->pict_type == FF_B_TYPE)))
- {
- s->low_delay = 0;
- s->avctx->has_b_frames++;
- }
- if(out_of_order || pics > s->avctx->has_b_frames){
- out->reference &= ~DELAYED_PIC_REF;
- for(i=out_idx; h->delayed_pic[i]; i++)
- h->delayed_pic[i] = h->delayed_pic[i+1];
- }
- if(!out_of_order && pics > s->avctx->has_b_frames){
- *data_size = sizeof(AVFrame);
- h->outputed_poc = out->poc;
- *pict= *(AVFrame*)out;
- }else{
- av_log(avctx, AV_LOG_DEBUG, "no picturen");
- }
- }
- }
- assert(pict->data[0] || !*data_size);
- //ff_print_debug_info(s, pict);
- //printf("out %dn", (int)pict->data[0]);
- #if 0 //?
- /* Return the Picture timestamp as the frame number */
- /* we subtract 1 because it is added on utils.c */
- avctx->frame_number = s->picture_number - 1;
- #endif
- return get_consumed_bytes(s, buf_index, buf_size);
- }
- #if 0
- static inline void fill_mb_avail(H264Context *h){
- MpegEncContext * const s = &h->s;
- const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
- if(s->mb_y){
- h->mb_avail[0]= s->mb_x && h->slice_table[mb_xy - s->mb_stride - 1] == h->slice_num;
- h->mb_avail[1]= h->slice_table[mb_xy - s->mb_stride ] == h->slice_num;
- h->mb_avail[2]= s->mb_x+1 < s->mb_width && h->slice_table[mb_xy - s->mb_stride + 1] == h->slice_num;
- }else{
- h->mb_avail[0]=
- h->mb_avail[1]=
- h->mb_avail[2]= 0;
- }
- h->mb_avail[3]= s->mb_x && h->slice_table[mb_xy - 1] == h->slice_num;
- h->mb_avail[4]= 1; //FIXME move out
- h->mb_avail[5]= 0; //FIXME move out
- }
- #endif
- #ifdef TEST
- #undef printf
- #undef random
- #define COUNT 8000
- #define SIZE (COUNT*40)
- int main(void){
- int i;
- uint8_t temp[SIZE];
- PutBitContext pb;
- GetBitContext gb;
- // int int_temp[10000];
- DSPContext dsp;
- AVCodecContext avctx;
- dsputil_init(&dsp, &avctx);
- init_put_bits(&pb, temp, SIZE);
- printf("testing unsigned exp golombn");
- for(i=0; i<COUNT; i++){
- START_TIMER
- set_ue_golomb(&pb, i);
- STOP_TIMER("set_ue_golomb");
- }
- flush_put_bits(&pb);
- init_get_bits(&gb, temp, 8*SIZE);
- for(i=0; i<COUNT; i++){
- int j, s;
- s= show_bits(&gb, 24);
- START_TIMER
- j= get_ue_golomb(&gb);
- if(j != i){
- printf("mismatch! at %d (%d should be %d) bits:%6Xn", i, j, i, s);
- // return -1;
- }
- STOP_TIMER("get_ue_golomb");
- }
- init_put_bits(&pb, temp, SIZE);
- printf("testing signed exp golombn");
- for(i=0; i<COUNT; i++){
- START_TIMER
- set_se_golomb(&pb, i - COUNT/2);
- STOP_TIMER("set_se_golomb");
- }
- flush_put_bits(&pb);
- init_get_bits(&gb, temp, 8*SIZE);
- for(i=0; i<COUNT; i++){
- int j, s;
- s= show_bits(&gb, 24);
- START_TIMER
- j= get_se_golomb(&gb);
- if(j != i - COUNT/2){
- printf("mismatch! at %d (%d should be %d) bits:%6Xn", i, j, i, s);
- // return -1;
- }
- STOP_TIMER("get_se_golomb");
- }
- #if 0
- printf("testing 4x4 (I)DCTn");
- DCTELEM block[16];
- uint8_t src[16], ref[16];
- uint64_t error= 0, max_error=0;
- for(i=0; i<COUNT; i++){
- int j;
- // printf("%d %d %dn", r1, r2, (r2-r1)*16);
- for(j=0; j<16; j++){
- ref[j]= random()%255;
- src[j]= random()%255;
- }
- h264_diff_dct_c(block, src, ref, 4);
- //normalize
- for(j=0; j<16; j++){
- // printf("%d ", block[j]);
- block[j]= block[j]*4;
- if(j&1) block[j]= (block[j]*4 + 2)/5;
- if(j&4) block[j]= (block[j]*4 + 2)/5;
- }
- // printf("n");
- s->dsp.h264_idct_add(ref, block, 4);
- /* for(j=0; j<16; j++){
- printf("%d ", ref[j]);
- }
- printf("n");*/
- for(j=0; j<16; j++){
- int diff= FFABS(src[j] - ref[j]);
- error+= diff*diff;
- max_error= FFMAX(max_error, diff);
- }
- }
- printf("error=%f max_error=%dn", ((float)error)/COUNT/16, (int)max_error );
- printf("testing quantizern");
- for(qp=0; qp<52; qp++){
- for(i=0; i<16; i++)
- src1_block[i]= src2_block[i]= random()%255;
- }
- printf("Testing NAL layern");
- uint8_t bitstream[COUNT];
- uint8_t nal[COUNT*2];
- H264Context h;
- memset(&h, 0, sizeof(H264Context));
- for(i=0; i<COUNT; i++){
- int zeros= i;
- int nal_length;
- int consumed;
- int out_length;
- uint8_t *out;
- int j;
- for(j=0; j<COUNT; j++){
- bitstream[j]= (random() % 255) + 1;
- }
- for(j=0; j<zeros; j++){
- int pos= random() % COUNT;
- while(bitstream[pos] == 0){
- pos++;
- pos %= COUNT;
- }
- bitstream[pos]=0;
- }
- START_TIMER
- nal_length= encode_nal(&h, nal, bitstream, COUNT, COUNT*2);
- if(nal_length<0){
- printf("encoding failedn");
- return -1;
- }
- out= decode_nal(&h, nal, &out_length, &consumed, nal_length);
- STOP_TIMER("NAL")
- if(out_length != COUNT){
- printf("incorrect length %d %dn", out_length, COUNT);
- return -1;
- }
- if(consumed != nal_length){
- printf("incorrect consumed length %d %dn", nal_length, consumed);
- return -1;
- }
- if(memcmp(bitstream, out, COUNT)){
- printf("mismatchn");
- return -1;
- }
- }
- #endif
- printf("Testing RBSPn");
- return 0;
- }
- #endif /* TEST */
- static av_cold int decode_end(AVCodecContext *avctx)
- {
- H264Context *h = avctx->priv_data;
- MpegEncContext *s = &h->s;
- int i;
- av_freep(&h->rbsp_buffer[0]);
- av_freep(&h->rbsp_buffer[1]);
- free_tables(h); //FIXME cleanup init stuff perhaps
- for(i = 0; i < MAX_SPS_COUNT; i++)
- av_freep(h->sps_buffers + i);
- for(i = 0; i < MAX_PPS_COUNT; i++)
- av_freep(h->pps_buffers + i);
- MPV_common_end(s);
- // memset(h, 0, sizeof(H264Context));
- return 0;
- }
- AVCodec h264_decoder = {
- "h264",
- CODEC_TYPE_VIDEO,
- CODEC_ID_H264,
- sizeof(H264Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY,
- NULL,
- flush_dpb
- };
- #ifdef CONFIG_H264_VDPAU_DECODER
- AVCodec h264_vdpau_decoder = {
- "h264_vdpau",
- CODEC_TYPE_VIDEO,
- CODEC_ID_H264_VDPAU,
- sizeof(H264Context),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
- .flush= flush_dpb,
- .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
- };
- #endif
- #ifdef CONFIG_SVQ3_DECODER
- #include "svq3.c"
- #endif
- ///
- ///////////////////////////////////////////////////////////////////////
- static void h264_mmx_init()
- {
- static int inited = 0;
-
- if (inited != 0)
- return;
-
- inited = 1;
-
- __asm
- {
- push eax
- push ebx
- push ecx
- push edx
-
- mov eax,1
- cpuid
- test edx,00800000h
- jz ending_mmx
- mov mmx_detect,1
- ending_mmx:
- pop edx
- pop ecx
- pop ebx
- pop eax
- }
- }
- static int decoder_create(void* param)
- {
- h264_dec_create_t* dec_param;
- FFDECODER* dec_handle;
- AVCodec* codec;
- H264Context* h;
- MpegEncContext* s;
- dec_param = (h264_dec_create_t*) param;
- dec_handle = (FFDECODER*) av_malloc(sizeof(FFDECODER));
- codec = &h264_decoder;
-
- h264_mmx_init();
- init_dither_tab();
-
- avcodec_init();
- dec_handle->context = avcodec_alloc_context();
- dec_handle->picture = avcodec_alloc_frame();
- //if(codec->capabilities&CODEC_CAP_TRUNCATED) //file using, network no use
- // c->flags|= CODEC_FLAG_TRUNCATED;
-
- if (avcodec_open(dec_handle->context, codec) < 0)
- return -1;
-
- h = dec_handle->context->priv_data;
- s = &h->s;
- s->dsp.idct_permutation_type =1;
- dsputil_init(&s->dsp, dec_handle->context);
- dec_param->handle = dec_handle;
- return 0;
- }
- static int decoder_decode(void* handle, void* param)
- {
int consumed_bytes;
- int got_picture;
- H264Context* h;
-
- unsigned char* in_buf = NULL;
-
- FFDECODER* dec_handle = (FFDECODER*) handle;
- h264_dec_frame_t* frame = (h264_dec_frame_t*) param;
-
- in_buf = (unsigned char*)frame->bitstream;
- consumed_bytes = avcodec_decode_video(dec_handle->context, dec_handle->picture, &got_picture, in_buf, frame->size);
-
- if(got_picture > 0)
- {
- frame->width = dec_handle->context->width;
- frame->height = dec_handle->context->height;
- frame->strider_Y = dec_handle->picture->linesize[0];
- frame->strider_U = dec_handle->picture->linesize[1];
- frame->strider_V = dec_handle->picture->linesize[2];
- frame->output_Y = dec_handle->picture->data[0];
- frame->output_U = dec_handle->picture->data[1];
- frame->output_V = dec_handle->picture->data[2];
- if( mmx_detect )
- {
- YUV420_TO_ARGB32_MMX( dec_handle->picture->data[0],
- dec_handle->picture->linesize[0],
- dec_handle->picture->data[1],
- dec_handle->picture->data[2],
- dec_handle->picture->linesize[1],
- dec_handle->picture->linesize[2],
- (unsigned char*)frame->output_ARGB,
- frame->width,
- frame->height,
- frame->width*4 );
- }
- else
- {
- YUV420ToARGB32( dec_handle->picture->data[0],
- dec_handle->picture->data[1],
- dec_handle->picture->data[2],
- dec_handle->picture->linesize[0],
- dec_handle->picture->linesize[1],
- dec_handle->picture->linesize[2],
- (unsigned char*)frame->output_ARGB,
- frame->width,
- frame->height,
- frame->width*4 );
- }
- h = dec_handle->context->priv_data;
-
- switch( h->slice_type )
- {
- case FF_I_TYPE:
- case FF_SI_TYPE:
- frame->type = 1;
- break;
- case FF_P_TYPE:
- case FF_SP_TYPE:
- frame->type = 2;
- break;
- case FF_B_TYPE:
- frame->type = 3;
- break;
- default:
- frame->type = 4;
- break;
- }
- }
- else
- {
- if( consumed_bytes >= 0 )
- frame->type = 0;
- else
- frame->type = -1;
- }
- return consumed_bytes;
}
- static int decoder_destroy(void* handle)
- {
- FFDECODER* dec_handle = (FFDECODER*) handle;
- //H264Context* h = dec_handle->context->priv_data;
- //decode_destory_vlc(h);
-
- if(dec_handle->context)
- {
- avcodec_close(dec_handle->context);
- av_free(dec_handle->context);
- dec_handle->context = NULL;
- }
-
- if(dec_handle->picture)
- {
- av_free(dec_handle->picture);
- dec_handle->picture = NULL;
- }
- if( dec_handle )
- {
- av_free(dec_handle);
- dec_handle = NULL;
- }
-
- return 0;
- }
- int h264_decore(int opt, void* handle, void* param)
- {
- switch( opt )
- {
- case H264_DEC_CREATE:
- return decoder_create(param);
-
- case H264_DEC_DECODE:
- return decoder_decode(handle, param);
-
- case H264_DEC_DESTROY:
- return decoder_destroy(handle);
- }
- return -1;
- }