📄 decoder_new.c
字号:
{ // check for frames that were already output and no longer used for reference for ( i = 0; i < h->dpb.used_size; i++ ) { if ( h->dpb.fs[i]->is_output && (!h->dpb.fs[i]->is_reference) ) { remove_frame_from_dpb( h, i ); break; } } } if( h->dpb.used_size == h->dpb.size ) { get_smallest_poc( h, &poc, &pos, 0 ); remove_frame_from_dpb( h, pos ); } x264_update_ref_list( h ); return;}static void x264_output_one_frame( x264_t *h ){ int i; int poc, pos=0;#if 0 { int i; for( i = 0; i < h->dpb.used_size; i++ ) { printf("i %d poc %d %d ref %d\n", i, h->dpb.fs[i]->i_poc, h->dpb.fs[i]->is_output, h->dpb.fs[i]->is_reference); } }#endif h->out_picture = NULL; if( h->dpb.used_size > 1) { get_smallest_poc( h, &poc, &pos, 1 ); h->dpb.fs[pos]->is_output = 1; h->picture->img.i_plane = h->dpb.fs[pos]->i_plane; for( i = 0; i < h->picture->img.i_plane; i++ ) { h->picture->img.i_stride[i] = h->dpb.fs[pos]->i_stride[i]; h->picture->img.plane[i] = h->dpb.fs[pos]->plane[i]; } h->dpb.last_output_poc = poc; h->out_picture = h->picture; h->out_picture->i_poc = h->dpb.fs[pos]->i_poc; } else { if( h->dpb.last_nonb ) { // if new idr frame come then ouput dpb.last_nonb frame h->picture->img.i_plane = h->dpb.last_nonb->i_plane; for( i = 0; i < h->picture->img.i_plane; i++ ) { h->picture->img.i_stride[i] = h->dpb.last_nonb->i_stride[i]; h->picture->img.plane[i] = h->dpb.last_nonb->plane[i]; } h->dpb.last_nonb->is_output = 1; h->dpb.last_output_poc = h->dpb.last_nonb->i_poc; h->out_picture = h->picture; h->out_picture->i_poc = h->dpb.fs[pos]->i_poc; } } fprintf(logout, "output poc %d\n", h->dpb.last_output_poc); /* adaptive B decision needs a pointer, since it can't use the ref lists */ if( h->sh.i_type != SLICE_TYPE_B ) h->dpb.last_nonb = h->fdec;}static void x264_post_processing( x264_t *h ){ //int i; /* expand border */ x264_frame_expand_border( h->fdec ); /* create filtered images */ x264_frame_filter( h->param.cpu, h->fdec ); /* expand border of filtered images */ x264_frame_expand_border_filtered( h->fdec ); #if 0 if(h->fdec->i_poc == 20){ int i, j; uint8_t* dst_y, *dst_u, *dst_v; for (i = 0 ; i < h->sps->i_mb_height ; i ++) { for (j = 0 ; j < h->sps->i_mb_width ; j ++) { int k,l; x264_log(h, X264_LOG_DEBUG, "mb %d\n", i*(h->sps->i_mb_width) + j); dst_y = h->fdec->plane[0] + (i << 4) * h->fdec->i_stride[0] + (j << 4); dst_u = h->fdec->plane[1] + (i << 3) * h->fdec->i_stride[1] + (j << 3); dst_v = h->fdec->plane[2] + (i << 3) * h->fdec->i_stride[2] + (j << 3); for (k = 0 ; k < 16 ; k++) { for (l = 0 ; l < 16 ; l++) x264_log(h, X264_LOG_DEBUG, "%3d ", dst_y[l]); x264_log(h, X264_LOG_DEBUG, "\n"); dst_y += h->fdec->i_stride[0]; } #if 0 for (k = 0 ; k < 8 ; k++) { for (l = 0 ; l < 8 ; l++) x264_log(h, X264_LOG_DEBUG, "%3d ", dst_u[l]); x264_log(h, X264_LOG_DEBUG, "\n"); dst_u += h->fdec->i_stride[1]; } for (k = 0 ; k < 8 ; k++) { for (l = 0 ; l < 8 ; l++) x264_log(h, X264_LOG_DEBUG, "%3d ", dst_v[l]); x264_log(h, X264_LOG_DEBUG, "\n"); dst_v += h->fdec->i_stride[2]; } #endif } } } #endif}static int x264_slice_data_decode( x264_t *h, bs_t *s ){ int mb_xy = h->sh.i_first_mb; int i_ret = 0; int end_of_slice = 0; static int tmp = -1; int tmp1 = -1;#ifdef PROFILE int64_t count; h->read_cycles = 0;#endif //x264_log(h, X264_LOG_DEBUG, "frame %d poc %d\n", h->sh.i_frame_num, h->i_poc); if( h->pps->b_cabac ) { bs_align_1(s); x264_cabac_context_init( &h->cabac, h->sh.i_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta, h->sh.i_cabac_init_idc ); x264_cabac_decode_init(&h->cabac,s); } h->mb.i_last_qp = h->pps->i_pic_init_qp + h->sh.i_qp_delta; h->mb.i_last_dqp = 0; /* FIXME field decoding */ for( ; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ ) { //x264_mb_context_t context; //x264_macroblock_t *mb; //mb = &h->mb[mb_xy]; int i_mb_y = mb_xy / h->sps->i_mb_width; int i_mb_x = mb_xy % h->sps->i_mb_width; int skip = 0; tmp++; tmp1++; //if(tmp > 10) printf("\n********MB: %d %d*********",tmp,tmp1); if(tmp == 7771) getchar(); /* load neighbour */ x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); //x264_macroblock_context_load( h, mb, &context ); if( h->pps->b_cabac ) { if( mb_xy > h->sh.i_first_mb) { end_of_slice = x264_cabac_decode_terminal(&h->cabac); assert(end_of_slice == 0); } h->mb.cbp[h->mb.i_mb_xy] = h->mb.i_cbp_luma = h->mb.i_cbp_chroma = 0;//h->mb.i_qp = 0; //h->mb.i_qp = h->mb.i_last_qp; if (h->sh.i_type != SLICE_TYPE_I && h->sh.i_type != SLICE_TYPE_SI) { skip = x264_cabac_dec_mb_skip(h); } else skip = 0; if(!skip) { i_ret = x264_macroblock_read_cabac( h, s); //printf(" \nafter one Mb %d",*h->cabac.s->p); //printf(" \nafter one Mb %d",h->cabac.s->i_left); } else { h->mb.i_last_dqp = 0; x264_macroblock_decode_skip( h ); continue; } } else { if( h->sh.i_type != SLICE_TYPE_I && h->sh.i_type != SLICE_TYPE_SI ) { int i_skip = bs_read_ue( s ); //x264_log(h, X264_LOG_DEBUG, "skip %d\n", i_skip); while( i_skip > 0 ) { //printf("mb %d skip\n", mb_xy); x264_macroblock_decode_skip( h ); /* next macroblock */ mb_xy++; if( mb_xy >= h->sps->i_mb_width * h->sps->i_mb_height ) { break; } //mb++; /* load neighbour */ i_mb_y = mb_xy / h->sps->i_mb_width; i_mb_x = mb_xy % h->sps->i_mb_width; x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); i_skip--; } if( mb_xy >= h->sps->i_mb_width * h->sps->i_mb_height ) { break; } } x264_log(h, X264_LOG_DEBUG, "mb %d\n", mb_xy); //printf("mb %d\n", mb_xy); #ifdef PROFILE count = x264_get_ts(); #endif i_ret = x264_macroblock_read_cavlc( h, s ); #ifdef PROFILE count = x264_get_ts() - count; h->read_cycles += count; #endif } if( i_ret < 0 ) { fprintf( stderr, "x264_macroblock_read failed [%d,%d]\n", i_mb_x, i_mb_y ); break; } if( x264_macroblock_decode( h ) < 0 ) { fprintf( stderr, "x264_macroblock_decode failed\n" ); /* try to do some error correction ;) */ } x264_macroblock_cache_save( h ); } if( h->pps->b_cabac ) { end_of_slice = x264_cabac_decode_terminal(&h->cabac); assert(end_of_slice == 1); //bs_align(s); } if( h->pps->b_cabac ) { x264_cabac_model_update( &h->cabac, h->sh.i_type, h->sh.pps->i_pic_init_qp + h->sh.i_qp_delta ); } if( i_ret >= 0 ) { /* apply deblocking filter to the current decoded picture */ if( !h->pps->b_deblocking_filter_control || h->sh.i_disable_deblocking_filter_idc != 1 ) { x264_frame_deblocking_filter( h, h->sh.i_type ); } /* post processing like expand border */ x264_post_processing( h ); x264_output_one_frame( h ); x264_reference_update( h ); }#ifdef PROFILE fprintf(logout, "poc %d %d\n", h->i_poc, h->read_cycles/h->sps->i_mb_width/h->sps->i_mb_height);#endif return i_ret;}/**************************************************************************** * ******************************* x264 libs ********************************** * ****************************************************************************//**************************************************************************** * x264_decoder_open: ****************************************************************************/x264_t *x264_decoder_open ( x264_param_t *param ){ x264_t *h = x264_malloc( sizeof( x264_t ) ); int i; memcpy( &h->param, param, sizeof( x264_param_t ) ); /* no SPS and PPS active yet */ h->sps = NULL; h->pps = NULL; for( i = 0; i < 32; i++ ) { h->sps_array[i].i_id = -1; /* invalidate it */ } for( i = 0; i < 256; i++ ) { h->pps_array[i].i_id = -1; /* invalidate it */ } h->picture = x264_malloc( sizeof( x264_picture_t ) ); h->picture->i_width = 0; h->picture->i_height= 0; /* init CPU functions */ x264_predict_16x16_init( h->param.cpu, h->predict_16x16 ); x264_predict_8x8_init( h->param.cpu, h->predict_8x8 ); x264_predict_4x4_init( h->param.cpu, h->predict_4x4 ); x264_pixel_init( h->param.cpu, &h->pixf ); x264_dct_init( h->param.cpu, &h->dctf ); x264_mc_init( h->param.cpu, &h->mc ); //x264_csp_init( h->param.cpu, h->param.i_csp, &h->csp ); // for test logout = fopen("x264.txt", "w"); /* create the vlc table (we could remove it from x264_t but it will need * to introduce a x264_init() for global librarie) */ for( i = 0; i < 5; i++ ) { /* max 2 step */ h->x264_coeff_token_lookup[i] = x264_vlc_table_lookup_new( x264_coeff_token[i], 17*4, 4 ); } //printf("%x",&h->x264_coeff_token_lookup[0]); /* max 2 step */ h->x264_level_prefix_lookup = x264_vlc_table_lookup_new( x264_level_prefix, 16, 8 ); for( i = 0; i < 15; i++ ) { /* max 1 step */ h->x264_total_zeros_lookup[i] = x264_vlc_table_lookup_new( x264_total_zeros[i], 16, 9 ); } for( i = 0;i < 3; i++ ) { /* max 1 step */ h->x264_total_zeros_dc_lookup[i] = x264_vlc_table_lookup_new( x264_total_zeros_dc[i], 4, 3 ); } for( i = 0;i < 7; i++ ) { /* max 2 step */ h->x264_run_before_lookup[i] = x264_vlc_table_lookup_new( x264_run_before[i], 15, 6 ); } return h;}/**************************************************************************** * x264_decoder_decode: decode one nal unit ****************************************************************************/int x264_decoder_decode( x264_t *h, x264_picture_t **pp_pic, x264_nal_t *nal ){ int i_ret = 0; bs_t bs; /* no picture */ *pp_pic = NULL; /* init bitstream reader */ bs_init( &bs, nal->p_payload, nal->i_payload ); switch( nal->i_type ) { case NAL_SPS: if( ( i_ret = x264_sps_read( &bs, h->sps_array ) ) < 0 ) { fprintf( stderr, "x264: x264_sps_read failed\n" ); } break; case NAL_PPS: if( ( i_ret = x264_pps_read( &bs, h->pps_array ) ) < 0 ) { fprintf( stderr, "x264: x264_pps_read failed\n" ); } break; case NAL_SLICE_IDR: fprintf( stderr, "x264: NAL_SLICE_IDR\n" ); x264_slice_idr( h ); case NAL_SLICE: if( ( i_ret = x264_slice_header_decode( h, &bs, nal ) ) < 0 ) { fprintf( stderr, "x264: x264_slice_header_decode failed\n" ); } // if( h->sh.i_redundant_pic_cnt == 0 && i_ret == 0 ) //{ if( ( i_ret = x264_slice_data_decode( h, &bs ) ) < 0 ) { fprintf( stderr, "x264: x264_slice_data_decode failed\n" ); } else { *pp_pic = h->out_picture; } //} break; case NAL_SLICE_DPA: case NAL_SLICE_DPB: case NAL_SLICE_DPC: fprintf( stderr, "partitioned stream unsupported\n" ); i_ret = -1; break; case NAL_SEI: default: break; } //if( *pp_pic == NULL ) // return i_ret; /* restore CPU state (before using float again) */ //x264_cpu_restore( h->cpu ); return i_ret;}/**************************************************************************** * x264_decoder_close: ****************************************************************************/void x264_decoder_close ( x264_t *h ){ int i; if( h->picture->i_width != 0 && h->picture->i_height != 0 ) { for( i = 0; i < h->dpb.size; i++ ) { x264_frame_delete( h->dpb.fs[i] ); } //x264_free( h->mb ); } /* free vlc table */ for( i = 0; i < 5; i++ ) { x264_vlc_table_lookup_delete( h->x264_coeff_token_lookup[i] ); } x264_vlc_table_lookup_delete( h->x264_level_prefix_lookup ); for( i = 0; i < 15; i++ ) { x264_vlc_table_lookup_delete( h->x264_total_zeros_lookup[i] ); } for( i = 0;i < 3; i++ ) { x264_vlc_table_lookup_delete( h->x264_total_zeros_dc_lookup[i] ); } for( i = 0;i < 7; i++ ) { x264_vlc_table_lookup_delete( h->x264_run_before_lookup[i] ); } fclose(logout); x264_macroblock_cache_end( h ); x264_free( h->picture ); x264_free( h );}/**************************************************************************** * x264_flush_dpb: ****************************************************************************/void x264_flush_dpb ( x264_t *h, x264_picture_t **pp_pic ){ int i, pos; // output last frame for( pos = 0; pos < h->dpb.used_size; pos++ ) { if ( !h->dpb.fs[pos]->is_output ) { h->dpb.fs[pos]->is_output = 1; h->picture->img.i_plane = h->dpb.fs[pos]->i_plane; for( i = 0; i < h->picture->img.i_plane; i++ ) { h->picture->img.i_stride[i] = h->dpb.fs[pos]->i_stride[i]; h->picture->img.plane[i] = h->dpb.fs[pos]->plane[i]; } h->dpb.last_output_poc = h->dpb.fs[pos]->i_poc; break; } } *pp_pic = h->picture; printf("output poc %d\n", h->dpb.last_output_poc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -