📄 decoder_new.c
字号:
} } for( cIdx = h->sh.i_num_ref_idx_l1_active; cIdx > refIdxLX; cIdx-- ) h->fref1[cIdx] = h->fref1[cIdx-1]; h->fref1[ (refIdxLX)++ ] = picLx; nIdx = refIdxLX; for( cIdx = refIdxLX; cIdx <= h->sh.i_num_ref_idx_l1_active; cIdx++ ) if (h->fref1[ cIdx ]) if( (h->fref1[ cIdx ]->is_long_ref ) || (h->fref1[ cIdx ]->i_frame_num != picNumLX )) h->fref1[ nIdx++ ] = h->fref1[ cIdx ]; } if (reordering_of_pic_nums_idc == 2) { for ( i=0; i < h->dpb.used_size; i++) { if(( h->dpb.fs[i]->is_long_ref )&&( h->dpb.fs[i]->longtermpicnum == long_term_pic_num)) { picLx = h->dpb.fs[i]; break; } } for( cIdx = h->sh.i_num_ref_idx_l1_active; cIdx > refIdxLX; cIdx-- ) h->fref1[cIdx] = h->fref1[cIdx-1]; h->fref1[ (refIdxLX)++ ] = picLx; nIdx = refIdxLX; for( cIdx = refIdxLX; cIdx <= h->sh.i_num_ref_idx_l1_active; cIdx++ ) if (h->fref1[ cIdx ]) if( (!h->fref1[ cIdx ]->is_long_ref ) || (h->fref1[ cIdx ]->longtermpicnum != long_term_pic_num )) h->fref1[ nIdx++ ] = h->fref1[ cIdx ]; } } return 0;}static int x264_slice_header_pred_weight_table( x264_t *h, bs_t *s ){ int i,j; int luma_weight_l0_flag; int luma_weight_l1_flag; int chroma_weight_l0_flag; int chroma_weight_l1_flag; h->sh.pred_weight_table.luma_log2_weight_denom=bs_read_ue(s); h->sh.pred_weight_table.chroma_log2_weight_denom=bs_read_ue(s); for(i=0;i<=h->sh.i_num_ref_idx_l0_active;i++) { luma_weight_l0_flag=bs_read1(s); if(luma_weight_l0_flag) { h->sh.pred_weight_table.luma_weight_l0[i]=bs_read_se(s); h->sh.pred_weight_table.luma_offset_l0[i]=bs_read_se(s); } chroma_weight_l0_flag=bs_read1(s); if(chroma_weight_l0_flag) { for(j=0;j<2;j++) { h->sh.pred_weight_table.chroma_weight_l0[i][j]=bs_read_se(s); h->sh.pred_weight_table.chroma_offset_l0[i][j]=bs_read_se(s); } } } if(h->sh.i_type==SLICE_TYPE_B) { for(i=0;i<=h->sh.i_num_ref_idx_l1_active;i++) { luma_weight_l1_flag=bs_read1(s); if(luma_weight_l1_flag) { h->sh.pred_weight_table.luma_weight_l1[i]=bs_read_se(s); h->sh.pred_weight_table.luma_offset_l1[i]=bs_read_se(s); } chroma_weight_l1_flag=bs_read1(s); if(chroma_weight_l1_flag) { for(j=0;j<2;j++) { h->sh.pred_weight_table.chroma_weight_l1[i][j]=bs_read_se(s); h->sh.pred_weight_table.chroma_offset_l1[i][j]=bs_read_se(s); } } } } return 0;}static int x264_slice_header_dec_ref_pic_marking( x264_t *h, bs_t *s, int i_nal_type ){ int i ; int currpicnum;// x264_picture_t *pic; if( i_nal_type == NAL_SLICE_IDR ) { int b_no_output_of_prior_pics = bs_read1( s ); int b_long_term_reference_flag = bs_read1( s ); if( b_no_output_of_prior_pics ) { /*for (i=0; i < h->dpb.used_size; i++) { h->dpb.fs[i]=NULL; h->dpb.fs[i]->is_reference=0; } h->fdec = h->dpb.fs[0]; h->dpb.used_size=0;*/ } else { //x264_flush_dpb(h,&pic); } //x264_update_ref_list(h); if( b_long_term_reference_flag ) { h->dpb.maxltermfidx = 0; h->fdec->is_long_ref=1; h->fdec->is_reference = 1; h->fdec->ltfidx= 0; } else { h->dpb.maxltermfidx = -1; h->fdec->is_long_ref=0; h->fdec->is_reference = 1; } // x264_update_ref_list(h); } else { int b_adaptive_ref_pic_marking_mode = bs_read1( s ); int memory_management_control_operation; int difference_of_pic_nums_minus1; int long_term_pic_num; int long_term_frame_idx; int max_long_term_frame_idx_plus1; int picnumx; if( b_adaptive_ref_pic_marking_mode ) { do { memory_management_control_operation = bs_read_ue(s); if(memory_management_control_operation== 1 || memory_management_control_operation== 3) difference_of_pic_nums_minus1 = bs_read_ue(s); if(memory_management_control_operation== 2) long_term_pic_num=bs_read_ue(s); if(memory_management_control_operation== 3 || memory_management_control_operation== 6) long_term_frame_idx=bs_read_ue(s); if(memory_management_control_operation== 4) max_long_term_frame_idx_plus1=bs_read_ue(s); if( memory_management_control_operation== 1) { currpicnum= h->i_frame_num; picnumx=currpicnum-(difference_of_pic_nums_minus1 - 1); for (i = 0; i < h->dpb.used_size; i++) if (h->dpb.fs[i]->i_frame_num == picnumx && h->dpb.fs[i]->is_long_ref==0 ) { h->dpb.fs[i]->is_reference = 0; // x264_update_ref_list(h); } } if( memory_management_control_operation== 2) { for (i = 0; i < h->dpb.used_size; i++) if (h->dpb.fs[i]->longtermpicnum == long_term_pic_num && h->dpb.fs[i]->is_long_ref==1 ) { h->dpb.fs[i]->is_reference = 0; // x264_update_ref_list(h); } } if( memory_management_control_operation== 3) { currpicnum= h->i_frame_num; picnumx=currpicnum-(difference_of_pic_nums_minus1-1); for (i = 0; i < h->dpb.used_size; i++) { if (h->dpb.fs[i]->ltfidx ==long_term_frame_idx && h->dpb.fs[i]->is_long_ref==1 ) { h->dpb.fs[i]->is_reference = 0; // x264_update_ref_list(h); } } for (i = 0; i < h->dpb.used_size; i++) { if ((!h->dpb.fs[i]->is_long_ref)&&(h->dpb.fs[i]->i_frame_num == picnumx)) { h->dpb.fs[i]->is_long_ref=1; h->dpb.fs[i]->ltfidx=long_term_frame_idx; } // x264_update_ref_list(h); } } if( memory_management_control_operation== 4) { if(max_long_term_frame_idx_plus1==0) h->dpb.maxltermfidx=0; else if(max_long_term_frame_idx_plus1>0) { h->dpb.maxltermfidx=max_long_term_frame_idx_plus1-1; for (i = 0; i < h->dpb.used_size; i++) { if(h->dpb.fs[i]->ltfidx > h->dpb.maxltermfidx) { h->dpb.fs[i]->is_reference = 0; h->dpb.fs[i]->is_long_ref = 0; } // x264_update_ref_list(h); } } } if( memory_management_control_operation== 5) { for (i = 0; i < h->dpb.used_size; i++) h->dpb.fs[i]->is_reference=0; // x264_update_ref_list(h); } if( memory_management_control_operation== 6) { for(i=0; i<h->dpb.used_size; i++) { if (h->dpb.fs[i]->ltfidx == long_term_frame_idx) { h->dpb.fs[i]->is_reference = 0; h->dpb.fs[i]->is_long_ref = 0; } } // x264_update_ref_list(h); h->fdec->is_reference=1; h->fdec->is_long_ref=1; h->fdec->ltfidx=long_term_frame_idx; } x264_update_ref_list(h); }while(memory_management_control_operation != 0 ); } else { //sliding_window_memory_management(h); } } return 0;}/**************************************************************************** * Decode a slice header and setup h for mb decoding. ****************************************************************************/static int x264_slice_header_decode( x264_t *h, bs_t *s, x264_nal_t *nal ){ /* read the first part of the slice */ if( x264_slice_header_part1_read( s, &h->sh, h->sps_array, h->pps_array, nal->i_type == NAL_SLICE_IDR ? 1 : 0 ) < 0 ) { fprintf( stderr, "x264_slice_header_part1_read failed\n" ); return -1; } /* now reset h if needed for this frame */ if( h->sps != h->sh.sps || h->pps != h->sh.pps ) { int i; /* TODO */ h->sps = NULL; h->pps = NULL; 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_macroblock_cache_end( h ); } h->picture->i_width = 0; h->picture->i_height = 0; } /* and init if needed */ if( h->sps == NULL || h->pps == NULL ) { int i; h->sps = h->sh.sps; h->pps = h->sh.pps; h->param.i_width = h->picture->i_width = 16 * h->sps->i_mb_width; h->param.i_height= h->picture->i_height= 16 * h->sps->i_mb_height; h->out_picture = NULL; fprintf( stderr, "x264: %dx%d\n", h->picture->i_width, h->picture->i_height ); //h->mb = x264_macroblocks_new( h->sps->i_mb_width, h->sps->i_mb_height ); h->mb.i_mb_count = h->sps->i_mb_width * h->sps->i_mb_height; /* Init frames. */ h->dpb.size = 8; // temp assign h->dpb.used_size = 0; for( i = 0; i < h->dpb.size; i++ ) { h->dpb.fs[i] = x264_frame_new( h ); } h->i_ref0 = 0; h->i_ref1 = 0; h->i_poc_msb = 0; h->i_poc_lsb = 0; h->i_frame_offset = 0; h->i_frame_num = 0; h->is_reference = 0; h->dpb.last_nonb = NULL; //h->dpb.last_output_poc = INT_MIN; h->fdec = h->dpb.fs[0]; /* init mb cache */ x264_macroblock_cache_init( h ); } /* calculate poc for current frame */ if( h->sps->i_poc_type == 0 ) { 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; } h->is_reference = (nal->i_ref_idc != 0); /* use the no more use frame */ h->fdec = h->dpb.fs[h->dpb.used_size++]; h->fdec->is_output = 0; h->fdec->i_poc = h->i_poc; h->fdec->is_reference = h->is_reference; h->fdec->is_long_ref = 0; //printf("dec pos %d\n", h->dpb.used_size); h->fdec->i_frame_num = h->sh.i_frame_num; h->i_frame_num = h->sh.i_frame_num; if( h->sh.i_type != SLICE_TYPE_I ) { x264_bulid_ref_list( h ); } x264_log(h, X264_LOG_DEBUG, "frame %d poc %d\n", h->sh.i_frame_num, h->i_poc); #if 1 { int i; x264_log(h, X264_LOG_DEBUG, "num_ref_idx_l0_active %d\n", h->sh.i_num_ref_idx_l0_active); for (i = 0; i < h->i_ref0; i++) { x264_log(h, X264_LOG_DEBUG, "POC %d ", h->fref0[i]->i_poc); //fprintf( stderr,"POC %d ", h->fref0[i]->i_poc); } x264_log(h, X264_LOG_DEBUG, "\n"); for (i = 0; i < h->i_ref1; i++) { x264_log(h, X264_LOG_DEBUG, "POC %d ", h->fref1[i]->i_poc); //fprintf( stderr,"POC %d ", h->fref0[i]->i_poc); } x264_log(h, X264_LOG_DEBUG, "\n"); } #endif fprintf( stderr, "x264: pic type=%s poc:%d ref_idc:%d\n", h->sh.i_type == SLICE_TYPE_I ? "I" : (h->sh.i_type == SLICE_TYPE_P ? "P" : "B" ), h->i_poc, h->is_reference ); /* 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; } /* init mb */ if( h->sh.i_type == SLICE_TYPE_B && !h->sh.b_direct_spatial_mv_pred) x264_macroblock_bipred_init( h ); x264_macroblock_slice_init( h ); return 0;}static void remove_frame_from_dpb( x264_t *h, int pos){ x264_frame_t *tmp; int i; h->dpb.fs[pos]->is_used = 0; h->dpb.fs[pos]->is_long_ref = 0; h->dpb.fs[pos]->is_reference = 0; // move empty framestore to end of buffer tmp = h->dpb.fs[pos]; for ( i = pos; i < h->dpb.used_size - 1; i++ ) { h->dpb.fs[i] = h->dpb.fs[i+1]; } h->dpb.fs[h->dpb.used_size - 1] = tmp; h->dpb.used_size--;}/* get the frame with smallest poc* flag * 0: select within frames have been output* 1: select within frames have not been output*/static void get_smallest_poc( x264_t *h, int *poc, int * pos, int flag ){ int i, condition; *pos = -1; *poc = INT_MAX; for( i = 0; i < h->dpb.used_size; i++ ) { if( flag == 1) { condition = !h->dpb.fs[i]->is_output; } else { condition = h->dpb.fs[i]->is_output; } if ( (*poc > h->dpb.fs[i]->i_poc) && (condition) ) { *poc = h->dpb.fs[i]->i_poc; *pos = i; } }}static void x264_reference_update( x264_t *h ){ int i; int poc, pos; // sliding window, if necessary if( h->fdec->is_reference ) { sliding_window_memory_management( h ); } if( h->dpb.used_size == h->dpb.size )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -