编码帧的输入顺序是I B B B B P,设置4个B帧。
这里假设每次最多能缓存5帧图像,即lookahead的列表中能存5帧图像。编码的第一帧图像是I帧或者IDR帧,首先将第一帧图像存入h->lookahead->next->list中,它的size加1,接着依次存入四帧图像,它的size为5,此时h->lookahead->next->list中的图像是:


接着对列表中的图像进行依次编码,首先取索引为0的帧,确定帧类型为IDR帧,然后将此帧赋值给h->lookahead->last_nonb,具体操作如下:

h->lookahead->last_nonb=h->lookahead->next->list[0];

然后确定要移动的帧数shift_frames=1;
然后将这一帧移到另一个列表中,具体操作如下:

h->lookahead->ofbuf->list[0]=h->lookahead->next->list[0];

h->lookahead->ofbuf.size加1,h->lookahead->next.size减1,h->lookahead->next->list中后面的几帧依次向前移,
h->lookahead->next->list[i] = h->lookahead->next->list[i+1]

h->lookahead->next->list移动之后的情况


h->lookahead->ofbuf->list添加一帧之后的情况
然后又从h->lookahead->ofbuf->list中将这一帧取出存入到h->frames.current中

此时,h->frames.current中存入一帧,h->lookahead->ofbuf->list中为空。然后编码的时候从h->frames.current中取索引为0的帧作为当前编码帧。此时只有一帧,,不需要移动其他帧。
这一个IDR帧编码完后,又向h->lookahead->next->list中加入新的一帧,加到列表的最后,此时还是存5帧。
接着编码第二帧,第二帧一般是P帧。取第二帧之前要先确定这些帧的帧类型。
这些帧的类型是:

然后调整P帧B帧顺序,调整前:

调整后:

对其进行重新排序:

此时h->lookahead->next->list中的顺序就是重新排序后的顺序。
确定要移动的帧数shift_frames=5;
将h->lookahead->next->list中的5帧依次移到h->lookahead->ofbuf->list中,顺序保持不变,移动后h->lookahead->next的size为0,h->lookahead->ofbuf的size为5.
然后再将h->lookahead->ofbuf->list中的5帧依次移到h->frames.current中,顺序保持不变,移动后h->lookahead->ofbuf的size为0.
编码的时候是从h->frames.current中依次取,编完一帧,就将这帧从h->frames.current中移除,根据先入先出原则,所以总是取索引为0的帧。
当这些帧编码完后,又会重新存入5帧到h->lookahead->next->list中。重新执行这些操作。

代码如下:

int     x264_encoder_encode( x264_t *h,x264_nal_t **pp_nal, int *pi_nal,x264_picture_t *pic_in,x264_picture_t *pic_out )
{.....x264_lookahead_put_frame( h, fenc );//将当前帧加入到lookahead->next->list中......if( !h->frames.current[0] )x264_lookahead_get_frames( h );//实现存入h->frames.current中h->fenc = x264_frame_shift( h->frames.current );//实现从h->frames.current中获取要编码的帧.....
}
void x264_lookahead_get_frames( x264_t *h )
{if( h->param.i_sync_lookahead ){   /* We have a lookahead thread, so get frames from there */x264_pthread_mutex_lock( &h->lookahead->ofbuf.mutex );while( !h->lookahead->ofbuf.i_size && h->lookahead->b_thread_active )x264_pthread_cond_wait( &h->lookahead->ofbuf.cv_fill, &h->lookahead->ofbuf.mutex );lookahead_encoder_shift( h );x264_pthread_mutex_unlock( &h->lookahead->ofbuf.mutex );}else{   /* We are not running a lookahead thread, so perform all the slicetype decide on the fly */if( h->frames.current[0] || !h->lookahead->next.i_size )return;x264_slicetype_decide( h );//确定slice类型lookahead_update_last_nonb( h, h->lookahead->next.list[0] );int shift_frames = h->lookahead->next.list[0]->i_bframes + 1;lookahead_shift( &h->lookahead->ofbuf, &h->lookahead->next, shift_frames );//将h->lookahead->next->list中的frame赋值给h->lookahead->ofbuf->list/* For MB-tree and VBV lookahead, we have to perform propagation analysis on I-frames too. */if( h->lookahead->b_analyse_keyframe && IS_X264_TYPE_I( h->lookahead->last_nonb->i_type ) )x264_slicetype_analyse( h, shift_frames );lookahead_encoder_shift( h );//将h->lookahead->ofbuf->list中的帧移动到h->frames.current中}
}void x264_slicetype_decide( x264_t *h )
{......if( h->param.rc.b_stat_read ){/* Use the frame types from the first pass 二路编码之间使用第一次编码的帧类型*/for( int i = 0; i < h->lookahead->next.i_size; i++ )h->lookahead->next.list[i]->i_type =x264_ratecontrol_slice_type( h, h->lookahead->next.list[i]->i_frame );}else if( (h->param.i_bframe && h->param.i_bframe_adaptive)|| h->param.i_scenecut_threshold|| h->param.rc.b_mb_tree|| (h->param.rc.i_vbv_buffer_size && h->param.rc.i_lookahead) )x264_slicetype_analyse( h, 0 );//帧类型分析....../* insert a bref into the sequence */if( h->param.i_bframe_pyramid && bframes > 1 && !brefs ){h->lookahead->next.list[(bframes-1)/2]->i_type = X264_TYPE_BREF;//设置一个BREF帧brefs++;}.....if( bframes ){int idx_list[] = { brefs+1, 1 };for( int i = 0; i < bframes; i++ )//调整P帧B帧顺序{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*) );//重排序}......
}

PS:暂时理解这么多。

x264中关于编码帧存取lookahead的操作相关推荐

  1. x264中码率控制(三)rate_estimate_qscale函数

    // 依据到目前为止编码bit数估算一帧的qscale 该函数主要进行qscale的初始化和调整,是码率控制部分的核心之一,另一个是get_scale. 0.计算SATD和图像的模糊复杂度 1.在ge ...

  2. x264中I,P,B帧和PTS,DTS的关系

    基本概念: I frame :帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象. ...

  3. x264 n-th pass编码时候Stats文件的含义

    2019独角兽企业重金招聘Python工程师标准>>> x264 n-th pass(一般是2pass)编码时所用的文件 包括 下述x264参数生成.stats文件 options: ...

  4. cacti不能实时刷新流量图_介绍一种编码帧内刷新算法

    0.引言 本文主要介绍一种帧内刷新算法,解决I帧太大带来的延迟问题,可以在调优时,值得借鉴. 帧内刷新技术避免 I 帧尖峰带来的带宽压力,可以有效地降低视频通信中的缓冲区延迟.帧内刷新算法是一种视频错 ...

  5. x264中重要结构体参数解释,参数设置,函数说明

    x264中重要结构体参数解释 http://www.usr.cc/thread-51995-1-3.html x264参数设置 http://www.usr.cc/thread-51996-1-3.h ...

  6. x264中码率控制(一)

    x264码率控制方法:采用的码率控制算法并没有采用拉格朗日代价函数来控制编码,而是使用一种更简单的方法,即利用半精度帧的SATD(sum of absolute transformeddifferen ...

  7. mpeg4视频中,I帧、p帧、B帧的判定

    mpeg4视频中,I帧.p帧.B帧的判定 mpeg4的每一帧开头是固定的:00 00 01 b6,那么我们如何判断当前帧属于什么帧呢?在接下来的2bit,将会告诉我们答案.注意:是2bit,不是byt ...

  8. 【音视频数据数据处理 12】【H.264篇】解析H.264原始码流中的I帧 / P帧 / B帧数据(暂未解决,本文先放着,来日更新)

    [音视频数据数据处理 12][H.264篇]解析H.264原始码流中的I帧 / P帧 / B帧数据 一.如何判断是 I帧 / P帧 / B帧 1.1 slice_type 1.2 slice_head ...

  9. x264中码率控制(二)x264_ratecontrol_start函数

    在一帧的编码前就选择QP值.帧层码率控制,到这一步,一帧中所有宏块还是统一qp的 void x264_ratecontrol_start( x264_t *h, int i_force_qp ) {x ...

  10. QT界面中实现视频帧显示的多种方法及应用

    QT界面中实现视频帧显示的多种方法及应用 (一) 引言 1.1 视频帧在QT界面中的应用场景 1.2 不同方法的性能和适用性分析 1.2.1 使用QLabel和QPixmap 1.2.2 使用QPai ...

最新文章

  1. Python使用scipy包将稀疏矩阵保存为Mtx格式和npz格式文件实战
  2. Oracle PL/SQL编程之包(packages)
  3. round robin权重轮循算法实现
  4. wxWidgets:支持插件的程序
  5. Base64 的那些事儿
  6. XP Sp2下双机通过无线网卡实现Internet共享
  7. do…while 第二讲
  8. 电脑自动配置IPV4地址169的解决办法
  9. 使用MVC2模式创建新闻网站
  10. php bt种子转换电驴地址,bt转换ed2k_BT文件转磁力链接工具 BT种子文件转换成ed2k链接...
  11. WML语言基础(WAP建站)三
  12. WORD表格排版案例之论文封面
  13. 三维全息显微镜成生物成像领域“新宠”
  14. java中计算文件的md5,Java计算文件MD5值代码
  15. 水星usb无线网卡MW150US驱动 for Mac
  16. win11怎么关闭自动更新系统
  17. FPGA学习网站、开源网站和论坛网站汇总
  18. 论文阅读:Personalizing Dialogue Agents via Meta-Learning
  19. Java实现 稀疏矩阵乘积
  20. css首字下沉_一个简单CSS首字下沉

热门文章

  1. 破解软件以及奇奇怪怪的网站集合
  2. 揭露培训机构以招聘名义变相招生的欺诈套路!莫被骗!附上企业黑名单!
  3. HTML页面基本结构介绍
  4. Graph_Master(连通分量_D_Trajan缩点+dfs)
  5. python控制灯开关_通过树莓派控制电灯开关
  6. Linux驱动开发|PWM驱动
  7. PHP长方体体积,长方体体积公式
  8. 球体积公式计算4/3PIr*r*r,编写一个程序输入半径,求体积
  9. 平均数 中位数 四分位数 方差 标准差
  10. python实现时序异常检测_时序预测 01 - 异常检测 Smoothed z-score algorithm 标准化的一些实践、调参总结 -Python/pandas/numpy...