x264中关于编码帧存取lookahead的操作
编码帧的输入顺序是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的操作相关推荐
- x264中码率控制(三)rate_estimate_qscale函数
// 依据到目前为止编码bit数估算一帧的qscale 该函数主要进行qscale的初始化和调整,是码率控制部分的核心之一,另一个是get_scale. 0.计算SATD和图像的模糊复杂度 1.在ge ...
- x264中I,P,B帧和PTS,DTS的关系
基本概念: I frame :帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象. ...
- x264 n-th pass编码时候Stats文件的含义
2019独角兽企业重金招聘Python工程师标准>>> x264 n-th pass(一般是2pass)编码时所用的文件 包括 下述x264参数生成.stats文件 options: ...
- cacti不能实时刷新流量图_介绍一种编码帧内刷新算法
0.引言 本文主要介绍一种帧内刷新算法,解决I帧太大带来的延迟问题,可以在调优时,值得借鉴. 帧内刷新技术避免 I 帧尖峰带来的带宽压力,可以有效地降低视频通信中的缓冲区延迟.帧内刷新算法是一种视频错 ...
- x264中重要结构体参数解释,参数设置,函数说明
x264中重要结构体参数解释 http://www.usr.cc/thread-51995-1-3.html x264参数设置 http://www.usr.cc/thread-51996-1-3.h ...
- x264中码率控制(一)
x264码率控制方法:采用的码率控制算法并没有采用拉格朗日代价函数来控制编码,而是使用一种更简单的方法,即利用半精度帧的SATD(sum of absolute transformeddifferen ...
- mpeg4视频中,I帧、p帧、B帧的判定
mpeg4视频中,I帧.p帧.B帧的判定 mpeg4的每一帧开头是固定的:00 00 01 b6,那么我们如何判断当前帧属于什么帧呢?在接下来的2bit,将会告诉我们答案.注意:是2bit,不是byt ...
- 【音视频数据数据处理 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 ...
- x264中码率控制(二)x264_ratecontrol_start函数
在一帧的编码前就选择QP值.帧层码率控制,到这一步,一帧中所有宏块还是统一qp的 void x264_ratecontrol_start( x264_t *h, int i_force_qp ) {x ...
- QT界面中实现视频帧显示的多种方法及应用
QT界面中实现视频帧显示的多种方法及应用 (一) 引言 1.1 视频帧在QT界面中的应用场景 1.2 不同方法的性能和适用性分析 1.2.1 使用QLabel和QPixmap 1.2.2 使用QPai ...
最新文章
- Python使用scipy包将稀疏矩阵保存为Mtx格式和npz格式文件实战
- Oracle PL/SQL编程之包(packages)
- round robin权重轮循算法实现
- wxWidgets:支持插件的程序
- Base64 的那些事儿
- XP Sp2下双机通过无线网卡实现Internet共享
- do…while 第二讲
- 电脑自动配置IPV4地址169的解决办法
- 使用MVC2模式创建新闻网站
- php bt种子转换电驴地址,bt转换ed2k_BT文件转磁力链接工具 BT种子文件转换成ed2k链接...
- WML语言基础(WAP建站)三
- WORD表格排版案例之论文封面
- 三维全息显微镜成生物成像领域“新宠”
- java中计算文件的md5,Java计算文件MD5值代码
- 水星usb无线网卡MW150US驱动 for Mac
- win11怎么关闭自动更新系统
- FPGA学习网站、开源网站和论坛网站汇总
- 论文阅读:Personalizing Dialogue Agents via Meta-Learning
- Java实现 稀疏矩阵乘积
- css首字下沉_一个简单CSS首字下沉
热门文章
- 破解软件以及奇奇怪怪的网站集合
- 揭露培训机构以招聘名义变相招生的欺诈套路!莫被骗!附上企业黑名单!
- HTML页面基本结构介绍
- Graph_Master(连通分量_D_Trajan缩点+dfs)
- python控制灯开关_通过树莓派控制电灯开关
- Linux驱动开发|PWM驱动
- PHP长方体体积,长方体体积公式
- 球体积公式计算4/3PIr*r*r,编写一个程序输入半径,求体积
- 平均数 中位数 四分位数 方差 标准差
- python实现时序异常检测_时序预测 01 - 异常检测 Smoothed z-score algorithm 标准化的一些实践、调参总结 -Python/pandas/numpy...