x264 帧由显示顺序到编码顺序的调整过程 框架
2013-04-12 16:10
357 查看
typedef struct x264_lookahead_t { volatile uint8_t b_exit_thread; uint8_t b_thread_active; uint8_t b_analyse_keyframe; int i_last_keyframe; int i_slicetype_length; x264_frame_t *last_nonb; x264_pthread_t thread_handle; x264_sync_frame_list_t ifbuf; x264_sync_frame_list_t next; x264_sync_frame_list_t ofbuf; } x264_lookahead_t_f; // void frame_buffer() { x264_picture_t pic; cli_opt_t *opt; x264_t* handle; int64_t last_dts; //step1 pic.i_type = X264_TYPE_AUTO; Encode_frame_fred( handle, opt->hout, &pic, &last_dts ); } int Encode_frame_fred( x264_t *h, hnd_t hout, x264_picture_t *pic, int64_t *last_dts ) { x264_picture_t pic_out; x264_nal_t *nal; int i_nal; int i_frame_size = 0; i_frame_size = x264_encoder_encode_fred( h, &nal, &i_nal, pic, &pic_out ); FAIL_IF_ERROR( i_frame_size < 0, "x264_encoder_encode failed\n" ); if( i_frame_size ) { i_frame_size = output.write_frame( hout, nal[0].p_payload, i_frame_size, &pic_out ); *last_dts = pic_out.i_dts; } return i_frame_size; } int x264_encoder_encode_fred( x264_t *h, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out ) { x264_t *thread_current, *thread_prev, *thread_oldest; int i_nal_type, i_nal_ref_idc, i_global_qp; int overhead = NALU_OVERHEAD; // ok to call this before encoding any frames, since the initial values of fdec have b_kept_as_ref=0 if( x264_reference_update( h ) ) return -1; h->fdec->i_lines_completed = -1; /* no data out */ *pi_nal = 0; *pp_nal = NULL; /* ------------------- Setup new frame from picture -------------------- */ if( pic_in != NULL ) { /* 1: Copy the picture to a frame and move it to a buffer */ x264_frame_t *fenc = x264_frame_pop_unused( h, 0 ); if( !fenc ) return -1; //move input to fenc if( x264_frame_copy_picture( h, fenc, pic_in ) < 0 ) return -1; if( h->param.i_width != 16 * h->mb.i_mb_width || h->param.i_height != 16 * h->mb.i_mb_height ) x264_frame_expand_border_mod16( h, fenc ); fenc->i_frame = h->frames.i_input++; if( h->frames.b_have_lowres ) x264_frame_init_lowres( h, fenc ); //step2 move fenc to lookahead->next x264_lookahead_put_frame( h, fenc ); //waiting for B if( h->frames.i_input <= h->frames.i_delay + 1 - h->i_thread_frames ) { /* Nothing yet to encode, waiting for filling of buffers */ pic_out->i_type = X264_TYPE_AUTO; return 0; } } else { /* signal kills for lookahead thread */ x264_pthread_mutex_lock( &h->lookahead->ifbuf.mutex ); h->lookahead->b_exit_thread = 1; x264_pthread_cond_broadcast( &h->lookahead->ifbuf.cv_fill ); x264_pthread_mutex_unlock( &h->lookahead->ifbuf.mutex ); } h->i_frame++; ///step3 pump data to current[], on needs if( !h->frames.current[0] ) x264_lookahead_get_frames_fred( h ); if( !h->frames.current[0] ) return x264_encoder_frame_end( thread_oldest, thread_current, pp_nal, pi_nal, pic_out ); //step4 Get frame to be encoded from current[0] h->fenc = x264_frame_shift( h->frames.current ); } void x264_lookahead_get_frames_fred( x264_t *h ) { //step3.1 decide frame type and reorder frame to encode order x264_slicetype_decide_fred( h ); //step 3.2 move frames from lookahead->next to lookahead->ofbuf // next.list[0] must be I Idr or P x264_lookahead_shift( &h->lookahead->ofbuf, &h->lookahead->next, h->lookahead->next.list[0]->i_bframes + 1 ); //step 3.3 move frames from lookahead->ofbuf to h->frames.current x264_lookahead_encoder_shift( h ); } void x264_slicetype_decide_fred( x264_t *h ) { x264_frame_t *frames[X264_BFRAME_MAX+2]; x264_frame_t *frm; int bframes; int brefs; // step 3.1.1 set frame type ; eg list[] = {b b b b ...P/I}; i b b b p-idr for( bframes = 0, brefs = 0;; bframes++ ) { frm = h->lookahead->next.list[bframes]; if( frm->i_type == X264_TYPE_KEYFRAME ) frm->i_type = h->param.i_open_gop ? X264_TYPE_I : X264_TYPE_IDR; /* force set I or Idr because Limit GOP size */ if( (!h->param.b_intra_refresh || frm->i_frame == 0) && frm->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_max ) { if( frm->i_type == X264_TYPE_AUTO || frm->i_type == X264_TYPE_I ) frm->i_type = h->param.i_open_gop && h->lookahead->i_last_keyframe >= 0 ? X264_TYPE_I : X264_TYPE_IDR; int warn = frm->i_type != X264_TYPE_IDR; if( warn && h->param.i_open_gop ) warn &= frm->i_type != X264_TYPE_I; if( warn ) x264_log( h, X264_LOG_WARNING, "specified frame type (%d) at %d is not compatible with keyframe interval\n", frm->i_type, frm->i_frame ); } if( frm->i_type == X264_TYPE_I && frm->i_frame - h->lookahead->i_last_keyframe >= h->param.i_keyint_min ) { if( h->param.i_open_gop ) { h->lookahead->i_last_keyframe = frm->i_frame; // Use display order frm->b_keyframe = 1; } else frm->i_type = X264_TYPE_IDR; } //current is idr, prev frame must be p if( frm->i_type == X264_TYPE_IDR ) { /* Close GOP */ h->lookahead->i_last_keyframe = frm->i_frame; frm->b_keyframe = 1; if( bframes > 0 ) { bframes--; h->lookahead->next.list[bframes]->i_type = X264_TYPE_P; } } //.....连续B帧数量到达最大B帧要求 或者已经遍历完next中所有帧,则设置P帧; if( bframes == h->param.i_bframe || !h->lookahead->next.list[bframes+1] ) { if( frm->i_type == X264_TYPE_AUTO || IS_X264_TYPE_B( frm->i_type ) ) frm->i_type = X264_TYPE_P; } if( frm->i_type == X264_TYPE_AUTO ) frm->i_type = X264_TYPE_B; else if( !IS_X264_TYPE_B( frm->i_type ) ) // fred normal is P, or I or IDR break; } if( bframes ) h->lookahead->next.list[bframes-1]->b_last_minigop_bframe = 1; h->lookahead->next.list[bframes]->i_bframes = bframes;//p or i or idr //step 3.1.2 reorder to pbbbb if( bframes ) { int idx_list[] = { brefs+1, 1 };//two type, count separately // for( int i = 0; i < bframes; i++ ) { int idx = idx_list[ h->lookahead->next.list[i]->i_type == X264_TYPE_BREF ]++; frames[idx] = h->lookahead->next.list[i]; frames[idx]->i_reordered_pts = h->lookahead->next.list[idx]->i_pts; } frames[0] = h->lookahead->next.list[bframes]; frames[0]->i_reordered_pts = h->lookahead->next.list[0]->i_pts; memcpy( h->lookahead->next.list, frames, (bframes+1) * sizeof(x264_frame_t*) ); } }
相关文章推荐
- x264编码详细文字全过程
- engine中调整Element的上下显示顺序(遮盖)
- x264编码详细文字全过程
- x264编码详细文字全过程
- 8/5 调整ECshop首页显示排名顺序
- 【显示技术 - 视频编码】硬件加速 - 对接FFMPEG框架的H.265编码
- x264源代码编码详细文字全过程
- engine中调整Element的上下显示顺序(遮盖)
- x264编码详细文字全过程
- x264编码详细文字全过程(转载)
- X264编码详细过程
- x264中不同帧类型的编码顺序
- 2013.11.28 Base64编码后的图片信息在JSP页面中的显示[JFinal框架项目]
- x264编码详细文字全过程
- x264编码详细文字全过程
- engine中调整Element的上下显示顺序(遮盖)
- 使用安卓注解时,Fragment显示过程中各方法执行的先后顺序
- IPB帧 编码顺序 解码顺序 显示顺序
- ArcGIS怎么调整要素类字段的物理显示顺序
- x264编码详细文字全过程