📄 decoder.c.svn-base
字号:
int i_max_poc_lsb = 1 << h->sps->i_log2_max_poc_lsb; if( h->sh.i_poc_lsb < h->i_poc_lsb && h->i_poc_lsb - h->sh.i_poc_lsb >= i_max_poc_lsb/2 ) { h->i_poc_msb += i_max_poc_lsb; } else if( h->sh.i_poc_lsb > h->i_poc_lsb && h->sh.i_poc_lsb - h->i_poc_lsb > i_max_poc_lsb/2 ) { h->i_poc_msb -= i_max_poc_lsb; } h->i_poc_lsb = h->sh.i_poc_lsb; h->i_poc = h->i_poc_msb + h->sh.i_poc_lsb; } else if( h->sps->i_poc_type == 1 ) { /* FIXME */ return -1; } else { if( nal->i_type == NAL_SLICE_IDR ) { h->i_frame_offset = 0; h->i_poc = 0; } else { if( h->sh.i_frame_num < h->i_frame_num ) { h->i_frame_offset += 1 << h->sps->i_log2_max_frame_num; } if( nal->i_ref_idc > 0 ) { h->i_poc = 2 * ( h->i_frame_offset + h->sh.i_frame_num ); } else { h->i_poc = 2 * ( h->i_frame_offset + h->sh.i_frame_num ) - 1; } } h->i_frame_num = h->sh.i_frame_num; } fprintf( stderr, "x264: pic type=%s poc:%d\n", h->sh.i_type == SLICE_TYPE_I ? "I" : (h->sh.i_type == SLICE_TYPE_P ? "P" : "B?" ), h->i_poc ); if( h->sh.i_type != SLICE_TYPE_I && h->sh.i_type != SLICE_TYPE_P ) { fprintf( stderr, "only SLICE I/P supported\n" ); return -1; } /* read and do the ref pic reordering */ if( x264_slice_header_ref_pic_reordering( h, s ) < 0 ) { return -1; } if( ( (h->sh.i_type == SLICE_TYPE_P || h->sh.i_type == SLICE_TYPE_SP) && h->sh.pps->b_weighted_pred ) || ( h->sh.i_type == SLICE_TYPE_B && h->sh.pps->b_weighted_bipred ) ) { if( x264_slice_header_pred_weight_table( h, s ) < 0 ) { return -1; } } if( nal->i_ref_idc != 0 ) { x264_slice_header_dec_ref_pic_marking( h, s, nal->i_type ); } if( x264_slice_header_part2_read( s, &h->sh ) < 0 ) { return -1; } return 0;}static int x264_slice_data_decode( x264_t *h, bs_t *s ){ int mb_xy = h->sh.i_first_mb; int i_ret = 0; if( h->pps->b_cabac ) { /* TODO: alignement and cabac init */ } /* FIXME field decoding */ for( ;; ) { x264_mb_context_t context; x264_macroblock_t *mb; if( mb_xy >= h->sps->i_mb_width * h->sps->i_mb_height ) { break; } mb = &h->mb[mb_xy]; /* load neighbour */ x264_macroblock_context_load( h, mb, &context ); if( h->pps->b_cabac ) { if( h->sh.i_type != SLICE_TYPE_I && h->sh.i_type != SLICE_TYPE_SI ) { /* TODO */ } i_ret = x264_macroblock_read_cabac( h, s, mb ); } else { if( h->sh.i_type != SLICE_TYPE_I && h->sh.i_type != SLICE_TYPE_SI ) { int i_skip = bs_read_ue( s ); while( i_skip > 0 ) { x264_macroblock_decode_skip( h, mb ); /* next macroblock */ mb_xy++; if( mb_xy >= h->sps->i_mb_width * h->sps->i_mb_height ) { break; } mb++; /* load neighbour */ x264_macroblock_context_load( h, mb, &context ); i_skip--; } if( mb_xy >= h->sps->i_mb_width * h->sps->i_mb_height ) { break; } } i_ret = x264_macroblock_read_cavlc( h, s, mb ); } if( i_ret < 0 ) { fprintf( stderr, "x264_macroblock_read failed [%d,%d]\n", mb->i_mb_x, mb->i_mb_y ); break; } if( x264_macroblock_decode( h, mb ) < 0 ) { fprintf( stderr, "x264_macroblock_decode failed\n" ); /* try to do some error correction ;) */ } mb_xy++; } if( i_ret >= 0 ) { int i; /* expand border for frame reference TODO avoid it when using b-frame */ x264_frame_expand_border( h->fdec ); /* 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 ); }#if 0 /* expand border for frame reference TODO avoid it when using b-frame */ x264_frame_expand_border( h->fdec );#endif h->picture->i_plane = h->fdec->i_plane; for( i = 0; i < h->picture->i_plane; i++ ) { h->picture->i_stride[i] = h->fdec->i_stride[i]; h->picture->plane[i] = h->fdec->plane[i]; } /* move frame in the buffer FIXME won't work for B-frame */ h->fdec = h->freference[h->sps->i_num_ref_frames]; for( i = h->sps->i_num_ref_frames; i > 0; i-- ) { h->freference[i] = h->freference[i-1]; } h->freference[0] = h->fdec; } 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 ) ); h->cpu = param->cpu; /* 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 predict_XxX */ x264_predict_16x16_init( h->cpu, h->predict_16x16 ); x264_predict_8x8_init( h->cpu, h->predict_8x8 ); x264_predict_4x4_init( h->cpu, h->predict_4x4 ); x264_pixel_init( h->cpu, &h->pixf ); x264_dct_init( h->cpu, &h->dctf ); x264_mc_init( h->cpu, h->mc ); /* 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 ); } /* 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->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; } /* 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->sps->i_num_ref_frames + 1; i++ ) { x264_frame_delete( h->freference[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] ); } x264_free( h->picture ); x264_free( h );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -