实际应用环境:iOS,Android

x264_param_t中有下面两个参数值得注意下
int i_threads;        /* encode multiple frames in parallel */
int b_annexb;        /* if set, place start codes (4 bytes) before NAL units,
i_threads 默认0,自动设置为 x264_cpu_num_processors() * (h->param.b_sliced_threads?2:3)/2;
实测 i_threads = 2, 则 x264_encoder_encode 出来的 pi_nal 通常也是2
可见编码出来每帧的NAL个数跟 i_threads 是相关的。
b_annexb 默认1,可参考 http://aviadr1.blogspot.com.au/2 ... -explained-for.html

我的需求:
x264编码出来的流需交给 librtmp 推流,并且交给ffmpeg录制本地mp4视频。

librtmp推流怎么封装,请参考小乙哥的 BLE
https://github.com/wenjiegit/Bul ... /BleX264Encoder.cpp
BLE 是设置b_annexb 为0,这样封装成flv直接用
我们再来看看另一篇博文 http://www.codeman.net/2014/01/439.html,这里 send_rtmp_video 是有封装是有问题,
这里buf 是 startcode 形式,如果只是一个 NAL 那没有问题,但是如果是多个NAL,这里就出问题了。
A,buf 里面就一个 NAL ,send_rtmp_video 前面先去掉 startcode,然后巧妙的在 body[5~8] 设置成4个字节的NAL数据长度。因为startcode 有3个字节或者4字节情况,
要是直接在buf修改,4个自己好处理,3个字节就麻烦了
B,buf 里面有多个NAL,那 send_rtmp_video 的封装就有问题了,并没有把buf 正确的转换成 AVCC 格式。但是目前国内很多CDN也兼容了这个错误。

可见,要是annexb格式,而且是多NAL,那这个封装就十分麻烦了,需要把buf 正确的转换成 AVCC格式。
所以,就像BLE的做法,把b_annexb设置为0,i_thread 无所谓,不管是一个NAL还是多个,封装时都很方便,直接memcpy就可以。

我这边需要交给ffmpeg保存视频,实测 av_write_frame 只支持 annexb 格式,
avformat_alloc_output_context2 传入的路径也是 .mp4,这里大家要是找到 av_write_frame 支持 AVCC格式输入的分享一下。

要满足这两个需求,想代码比较省事,建议设置b_annexb = 0。因为AVCC 转成 annexb 格式比较简单,反之很麻烦。
x264出来的数据先交给librtmp,再交给ffmpeg封装,因为给av_write_frame前,需要 AVCC 转成 annexb,为了避免少memcpy一次,就直接在原数据上修改,所以把录制本地放在后面。

x264 b_annexb格式和多slice的更多相关文章

  1. x264码率控制方法介绍

    转自:http://www.bubuko.com/infodetail-471698.html 1.  X264显式支持的一趟码率控制方法有:ABR, CQP, CRF. 缺省方法是CRF.这三种方式 ...

  2. X264码率控制总结

    ABR,CQP,CRF X264显式支持的一趟码率控制方法有:ABR, CQP, CRF. 缺省方法是CRF.这三种方式的优先级是ABR > CQP > CRF. if ( bitrate ...

  3. X264码率控制总结1——ABR,CQP,CRF

    1.  X264显式支持的一趟码率控制方法有:ABR, CQP, CRF. 缺省方法是CRF.这三种方式的优先级是ABR > CQP > CRF. if ( bitrate ) rc_me ...

  4. Golang 语法学习笔记

    Golang 语法学习笔记 包.变量和函数. 包 每个 Go 程序都是由包组成的. 程序运行的入口是包 main. 包名与导入路径的最后一个目录一致."math/rand" 包由 ...

  5. 谈JavaScript代码封装

    前言 也算老生常谈的问题了,再深入搞一搞怎么玩儿封装,如果看到这篇文章的你,正好你也是追求完美的代码洁癖狂者,那么这篇文章相信非常适合你. 举一个例子,编写一个Person类,具有name和birth ...

  6. Go语言循环判断的使用~

    Go 语言条件语句 条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句. 下图展示了程序语言中条件语句的结 ...

  7. 关于Java和JavaScript对字符串截取处理的总结

    在JavaWeb开发中,经常需要对字符串进行处理,包括Java语言和JS语言,总是容易弄混淆,这里简单对比一下两种语言对于字符串截取方法. 一.先看Java public class StringDe ...

  8. Array数组内函数

      concat() 功能:合并数组,并且生成新数组.对原数组没有改变. 不传参数的时候,相当于生成新数组. 格式:数组.concat(数据...数组); 返回值:生成的新数组 代码示例: //.co ...

  9. ethereumjs/ethereumjs-icap

    https://github.com/ethereumjs/ethereumjs-icap ethereumjs-icap 安装: npm install ethereumjs-icap --save ...

随机推荐

  1. python json dumps与loads

    json.dumps() 是将一个Python数据结构转换为一个JSON编码的字符串 json.loads() 是将一个JSON编码的字符串转换为一个Python数据结构   一般要求当要字符串通过l ...

  2. Mac 提示错误”xcrun: error“

    错误现象: Mac 安装python模块时出现异常错误 xcrun: error: invalid active developer path (/Library/Developer/CommandL ...

  3. Appium-desktop元素定位

    一.打开 appium-desktop ,点击 start session 二.打开后,点击屏幕右上角的搜索按钮 三.然后会打开配置页面,在本地服务配置信息同上面写的代码链接配置.填入正确的信息后,点 ...

  4. SpringBoot + Nginx 配置HTTPS的一次经历

    最近公司开发了一款小程序的应用,但是小程序为了保证数据安全,强制要求使用HTTPS,然后就不得不去配置了一下. 之前在php开发的项目上配置过一次,使用的是wdcp的控制台程序,配置起来很简单,不需要 ...

  5. Tensorflow中保存模型时生成的各种文件区别和作用

    假如我们得到了如下的checkpoints, 上面的文件主要可以分成三类:一种是在保存模型时生成的文件,一种是我们在使用tensorboard时生成的文件,还有一种就是plugins这个文件夹,这个是 ...

  6. Flutter初探与环境搭建

    最近组里有个前端的同事在疯狂学习Flutter,本来上半年就一直想学它,但是..由于个人的原因还有其它的东东想学就一直把它给无限搁置了,为了跟上时代的潮流所以接一来还是下定决定好好将它学一下,毕境如今 ...

  7. BZOJ-1042:硬币购物(背包+容斥)

    题意:硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 思路:这么老的题,居然今天才做到. ...

  8. 利用python jieba库统计政府工作报告词频

    1.安装jieba库 舍友帮装的,我也不会( ╯□╰ ) 2.上网寻找政府工作报告 3.参照课本三国演义词频统计代码编写 import jieba txt = open("D:\政府工作报告 ...

  9. Ruby break, next, redo, retry

    # -*- coding: UTF-8 -*- # E3.10-5.rb 演示break, next, redo, retry puts "演示break" c='a' for i ...

  10. 安装Matlab出现弹出DVD1插入DVD2的提示怎么办?

    此使,找到DVD1光驱,右键弹出,然后回到dvd2.iso文件右键装载,回到matlab安装页面,对提示框“弹出DVD1插入DVD2”点击确定,安装即可继续进行.