x264源码分析三:x264_slices_write和x264_slice_write函数分析

2024-08-21 16:18

本文主要是介绍x264源码分析三:x264_slices_write和x264_slice_write函数分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面将分析x264编码的核心算法部分:

首先先了解一下x264中比特流的层次结构:每个比特都隶属于某个句法元素,句法元素被组织成有层次的结构,分别描述各个层次的信息。如下图所示:


x264分层结构由五层组成,分别是序列参数集、图像参数集、片(Slice)、和宏块和子块。参数集是一个独立的数据单位,不依赖于参数集外的其它句法元素。下图描述了参数集与参数集外的句法元素之间的关系。


而本文所要分析的就是对应的片编码。下面看源代码:

static void *x264_slices_write( x264_t *h )
{int i_slice_num = 0;int last_thread_mb = h->sh.i_last_mb;/* init stats *///初始化一些状态memset( &h->stat.frame, 0, sizeof(h->stat.frame) );h->mb.b_reencode_mb = 0;//循环每一个slicewhile( h->sh.i_first_mb + SLICE_MBAFF*h->mb.i_mb_stride <= last_thread_mb ){h->sh.i_last_mb = last_thread_mb;if( !i_slice_num || !x264_frame_new_slice( h, h->fdec ) ){if( h->param.i_slice_max_mbs ){if( SLICE_MBAFF ){// convert first to mbaff form, add slice-max-mbs, then convert back to normal formint last_mbaff = 2*(h->sh.i_first_mb % h->mb.i_mb_width)+ h->mb.i_mb_width*(h->sh.i_first_mb / h->mb.i_mb_width)+ h->param.i_slice_max_mbs - 1;int last_x = (last_mbaff % (2*h->mb.i_mb_width))/2;int last_y = (last_mbaff / (2*h->mb.i_mb_width))*2 + 1;h->sh.i_last_mb = last_x + h->mb.i_mb_stride*last_y;}else{h->sh.i_last_mb = h->sh.i_first_mb + h->param.i_slice_max_mbs - 1;if( h->sh.i_last_mb < last_thread_mb && last_thread_mb - h->sh.i_last_mb < h->param.i_slice_min_mbs )h->sh.i_last_mb = last_thread_mb - h->param.i_slice_min_mbs;}i_slice_num++;}else if( h->param.i_slice_count && !h->param.b_sliced_threads ){int height = h->mb.i_mb_height >> PARAM_INTERLACED;int width = h->mb.i_mb_width << PARAM_INTERLACED;i_slice_num++;h->sh.i_last_mb = (height * i_slice_num + h->param.i_slice_count/2) / h->param.i_slice_count * width - 1;}}h->sh.i_last_mb = X264_MIN( h->sh.i_last_mb, last_thread_mb );//利用函数指针进行具体的块编码操作if( x264_stack_align( x264_slice_write, h ) )goto fail;h->sh.i_first_mb = h->sh.i_last_mb + 1;// if i_first_mb is not the last mb in a row then go to the next mb in MBAFF orderif( SLICE_MBAFF && h->sh.i_first_mb % h->mb.i_mb_width )h->sh.i_first_mb -= h->mb.i_mb_stride;}return (void *)0;fail:/* Tell other threads we're done, so they wouldn't wait for it */if( h->param.b_sliced_threads )x264_threadslice_cond_broadcast( h, 2 );return (void *)-1;
}

下面分析具体的块编码函数源代码:

static intptr_t x264_slice_write( x264_t *h )
{int i_skip;int mb_xy, i_mb_x, i_mb_y;/* NALUs other than the first use a 3-byte startcode.* Add one extra byte for the rbsp, and one more for the final CABAC putbyt

这篇关于x264源码分析三:x264_slices_write和x264_slice_write函数分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093657

相关文章

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>