ffmpeg转码时对编码率和固定码率的处理

http://www.rosoo.net/a/201107/14663.html

一般fps在代码里这样表示

Fps = den/num

如果den = 15,num=1,则fps = 15。

如果帧率固定,pts*fps 就表示当前是第几帧。

当输入视频流的帧率不固定,如rmvb ,而输出视频流的帧率固定,ffmpeg作如下处理(参考ffmpeg代码版本0.6.1):

1、 
记录和输出视频流ost相对应的输入视频流ist,变量为ost->sync_ist。这是在av_transcode函数进行输出流初始化时进行的。代码分别为:

  1. if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&

  2. ist->st->codec->codec_type == ost->st->codec->codec_type) {

  3. if(best_nb_frames < ist->st->codec_info_nb_frames){

  4. best_nb_frames= ist->st->codec_info_nb_frames;

  5. ost->source_index = j;

  6. found = 1;

  7. }

  8. }

  9. if (!found) {

  10. if(! opt_programid) {

  11. /* try again and reuse existing stream */

  12. for(j=0;j<nb_istreams;j++) {

  13. ist = ist_table[j];

  14. if (   ist->st->codec->codec_type == ost->st->codec->codec_type

  15. && ist->st->discard != AVDISCARD_ALL) {

  16. ost->source_index = j;

  17. found = 1;

  18. }

  19. }

  20. }

  21. ist = ist_table[ost->source_index];

  22. ist->discard = 0;

  23. ost->sync_ist = (nb_stream_maps > 0) ?

  24. ist_table[file_table[stream_maps[n].sync_file_index].ist_index +

  25. stream_maps[n].sync_stream_index] : ist;

2、  记录输出视频流ost的时间戳。输出为固定帧率,故可以简化为记录帧数,变量为ost->sync_opts。

3、  将ost对应的ist的pts转换成固定帧率的帧数形式。代码为

  1. sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base);

get_sync_ipts计算ost对应的ist的pts,

av_q2d返回enc->time_base.num/ enc->time_base.den,即1/fps.

4、  将sync_ipts和ost->sync_opts进行求差。

  1. double vdelta = sync_ipts - ost->sync_opts;

5、  根据vdelta来判断不同的情况。

l  情况一:Vdelta<-1.1,表示当前输入帧的播放时间在当前输出帧的前一帧之前,故舍弃该帧,nb_frames = 0。

l  情况二: (video_sync_method == 2 || (video_sync_method<0 &&
(s->oformat->flags & AVFMT_VARIABLE_FPS))){

if(vdelta<=-0.6){

nb_frames=0;

}else if(vdelta>0.6)

ost->sync_opts= lrintf(sync_ipts);}

这里video_sync_method==2 和video_sync_method < 0
表示什么意义,不是很清楚。貌似ffmpeg里video_sync_method一直设为-1。AVFMT_VARIABLE_FPS应该是变帧率的意
思。这种情况下,vdelta<=0.6,表示位于当前帧之前,也舍弃该帧,nb_frames =
0;vdelta>0.6表示位于当前帧之后,直接把该帧的时间戳作为输出的时间出来输出该帧;0.6<vdelta<=0.6时,不
做任何处理,nb_frames 根据默认值为1。

l  情况三:vdelta > 1.1

此时nb_frames = lrintf(vdelta),需要做插帧操作。

Ffmpeg的插帧操作,貌似是把当前输出帧重复输出nb_frames次。

  1. AVFrame* old_frame = enc->coded_frame;

  2. enc->coded_frame = dec->coded_frame; //FIXME/XXX remove this hack

  3. pkt.data= (uint8_t *)final_picture;

  4. pkt.size=  sizeof(AVPicture);

  5. pkt.pts= av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);

  6. pkt.flags |= AV_PKT_FLAG_KEY;

  7. write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);

  8. enc->coded_frame = old_frame;

输出的数据在pkt.data里,final_picture即为经过处理的输入Pic。

6、输出视频流的帧率,是从输入视频流的包头数据中获得的。Rmvb的vedio
MDPR块里,保存有fps和fps2信息。Ffmpeg取fps作为帧率,fps2丢弃了。Fps2有什么用,还不清楚。介绍rmvb格式的文章里也没有看到过关于fps的任何介绍。

ffmpeg转码时对编码率和固定码率的处理,布布扣,bubuko.com

时间: 2024-10-22 16:50:22

ffmpeg转码时对编码率和固定码率的处理的相关文章

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的.对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug. sorry,废话多了.首先给个思路: 1.使opencv 的hi

ffmpeg转码MPEG2-TS的音视频同步机制分析

http://blog.chinaunix.net/uid-26000296-id-3483782.html 一.FFmpeg忽略了adaptation_field()数据FFmpeg忽略了包含PCR值的adaptation_filed数据; 代码(libavformat/mpegts.c)分析如下: /* 解析TS包 */int handle_packet(MpegTSContext *ts, const uint8_t *packet){  ...   pid = AV_RB16(packe

最新版ffmpeg源码分析

最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下把ffmpeg改名为avconv了. 到底libav与ffmpeg现在是什么个关系?我也搞得希里糊涂的,先不管它了. ffmpeg的主要功能是音视频的转换和处理.其功能之强大已经到了匪夷所思的地步(有点替它吹了).它的主要特点是能做到把多个输入文件中的任意几个流重新组合到输出文件中,当然输出文件也可

FFmpeg源码简单分析:结构体成员管理系统-AVOption

===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 - 编码 [通用] FFmpeg 源码简单分析:av_register_all() FFmpeg 源码简单分析:avcodec_register_all() FFmpeg 源码简单分析:内存的分配和释放(av_malloc().av_free()等) FFmpeg 源码简单分析:常

用jetty部署iMatrix平台源码时,静态资源应该放到哪里

大家在网站中下载源码之后,在eclipse中部署源码,用jetty插件做服务器. 静态资源(imatrix-static)给刚到tomcat里面的webapps里面.放的事war包,在官网中就可以下载.如下图配置静态资源在tomcat服务器中的位置. Ps 一定要下载站对应版本的war包.每个配置文件中关于静态资源的配置都有修改. 用jetty部署iMatrix平台源码时,静态资源应该放到哪里,布布扣,bubuko.com

js便签笔记(9)——解读jquery源码时记录的一些知识点

近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了.平时看的时候,做了一些笔记,贴出来分享. 1. Array.prototype.slice.call 可以将伪数组转化为真正的数组 其实,这里所谓的"伪数组"就是有length属性,并且有"0"."1"."2"等这些属性的对象,如下代码: var obj = { 0: "A", 1: "B", 2: "C&q

微信临时二维码时为32位非0整型

生成带参数的临时二维码时,需要指定场景值ID(scene_id), 由于项目中需要通过场景值来详细记录二维码的来源,故想对这个场景值id做出一个统一的生成机制. 微信文档中的表述如下: scene_id:场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1–100000). 然后团队中的人就以为这里的32位非0整型,是指长度为32位的数字就可以了. 结果当我们指定scene_id为 12345678901234567890123456789012 时, 我

FFmpeg源码结构图 - 解码

===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFmpeg源码结构图 - 编码 [通用] FFmpeg 源码简单分析:av_register_all() FFmpeg 源码简单分析:avcodec_register_all() FFmpeg 源码简单分析:内存的分配和释放(av_malloc().av_free()等) FFmpeg 源码简单分析:常

部署shiro官方源码时,执行maven命令出错

部署shiro官方源码时,执行maven命令会报下面错误: [INFO] ------------------------------------------------------------------------[ERROR] Failed to execute goal org.apache.maven.plugins:maven-toolchains-plugin:1.1:toolchain (default) on project shiro-root: Cannot find ma