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函数进行输出流初始化时进行的。代码分别为:
- if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&
- ist->st->codec->codec_type == ost->st->codec->codec_type) {
- if(best_nb_frames < ist->st->codec_info_nb_frames){
- best_nb_frames= ist->st->codec_info_nb_frames;
- ost->source_index = j;
- found = 1;
- }
- }
- if (!found) {
- if(! opt_programid) {
- /* try again and reuse existing stream */
- for(j=0;j<nb_istreams;j++) {
- ist = ist_table[j];
- if ( ist->st->codec->codec_type == ost->st->codec->codec_type
- && ist->st->discard != AVDISCARD_ALL) {
- ost->source_index = j;
- found = 1;
- }
- }
- }
- ist = ist_table[ost->source_index];
- ist->discard = 0;
- ost->sync_ist = (nb_stream_maps > 0) ?
- ist_table[file_table[stream_maps[n].sync_file_index].ist_index +
- stream_maps[n].sync_stream_index] : ist;
2、 记录输出视频流ost的时间戳。输出为固定帧率,故可以简化为记录帧数,变量为ost->sync_opts。
3、 将ost对应的ist的pts转换成固定帧率的帧数形式。代码为
- 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进行求差。
- 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次。
- AVFrame* old_frame = enc->coded_frame;
- enc->coded_frame = dec->coded_frame; //FIXME/XXX remove this hack
- pkt.data= (uint8_t *)final_picture;
- pkt.size= sizeof(AVPicture);
- pkt.pts= av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
- pkt.flags |= AV_PKT_FLAG_KEY;
- write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);
- enc->coded_frame = old_frame;
输出的数据在pkt.data里,final_picture即为经过处理的输入Pic。
6、输出视频流的帧率,是从输入视频流的包头数据中获得的。Rmvb的vedio MDPR块里,保存有fps和fps2信息。Ffmpeg取fps作为帧率,fps2丢弃了。Fps2有什么用,还不清楚。介绍rmvb格式的文章里也没有看到过关于fps的任何介绍。
ffmpeg转码时对编码率和固定码率的处理的更多相关文章
- 使用ffmpeg转码时遇到aac报错
今天尝试用ffmpeg转一个视频的格式,结果报出这个错误: The encoder 'aac' is experimental but experimental codecs are not enab ...
- 最新版ffmpeg源码分析
最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...
- 修改FFMpeg源码—捕获丢包
概述 最近我们项目有一个需求就是解决客户端播放RTSP视频流花屏的问题,一般来说丢包就会引起花屏,导致客户端花屏的因素又有很多,比如说: 相机到服务器丢包 服务器到客户端丢包 等等... 其中服务器到 ...
- ffmpeg转码器移植VC的工程:ffmpeg for MFC
本文介绍一个自己做的FFMPEG移植到VC下的开源工程:ffmpeg for MFC.本工程将ffmpeg工程中的ffmpeg转码器(ffmpeg.c)移植到了VC环境下.并且使用MFC做了一套简单的 ...
- ffmpeg源码编译安装(Compile ffmpeg with source) Part 2 : 扩展安装
在Ubuntu,Debian,Mint上编译ffmpeg 本文主要为在Ubuntu,Debian和Mint上编译安装ffmpeg和库文件以及一些扩展的编解码器.当然这与从源中安装无关. 请首先看一下通 ...
- 【转】使用ffmpeg转码的MP4文件需要加载完了才能播放的解决办法
1.前一段时间做了一个ffmpeg转码MP4的项目,但是转出来的MP4部署在网站上需要把整个视频加载完成才能播放,到处找资料,最后找到解决方案记录于此备忘. FFMpeg转码由此得到的mp4文件中, ...
- ffmpeg转码器移植VC的project:ffmpeg for MFC
本文介绍一个自己做的FFMPEG移植到VC下的开源project:ffmpeg for MFC.本project将ffmpegproject中的ffmpeg转码器(ffmpeg.c)移植到了VC环境下 ...
- FFmpeg源码简单分析:结构体成员管理系统-AVOption
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- NVIDIA FFmpeg 转码技术分析
NVIDIA FFmpeg 转码技术分析 所有从 Kepler 一代开始的 NVIDIA GPUs 都支持完全加速的硬件视频编码,而从费米一代开始的所有 GPUs 都支持完全加速的硬件视频解码.截至 ...
随机推荐
- Entity Framework学习笔记(一)
请注明转载地址:http://www.cnblogs.com/arhat 哈哈!老魏回来了,4月份的内容开始更新了,由于3月份时间都在做项目,没有时间写了,那么4月份老魏会尽可能的多写点东西的.那么4 ...
- 初探Xamarin
Xamarin是一个基于mono的商业项目,收费,而且贼贵.官网地址是:http://xamarin.com/ 就我个人理解,收费的Xamarin提供一个for visual studio 2010/ ...
- 配置 Cocoapods的简单配置及胡思乱想
外部访问属性 & 重要属性变化 外部访问方法 监听方法 内部属性 swift编写 懒加载控件.布局.监听 使用第三方框架之前先需要配置 cocoapods环境 (唐巧博客) gib 查看自己的 ...
- snmp安装配置
只说一下在ubuntu下如何进行基本的配置. ubuntu Server 12.04 apt-get install snmp snmpd 安装完成之后还要安装snmp-mibs-downloader ...
- Node.js 学习(三) NPM 使用介绍
NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并 ...
- android开发 textview根据字数长度自动调整字体大小
需求:根据输入的值实时显示到textview中预览,但是字体大小是要自动适配的 网上有一个代码,但是在我这里不能用,注意方法:refitText 注释掉的是之前的代码 import com.cars ...
- MySQL中表格各页面的注意和操作项
- 《JavaScript高级程序设计》第5章 引用类型
5.2.2 转换方法 所有对象都有toString()和valueOf()方法调用数组的toString()方法,会返回一个字符串,由数组中的每个项通过逗号连接而成调用valueOf()还是返回数组 ...
- HDU 5151 Sit sit sit 区间dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5151 题解: 有n个椅子,编号为1到n. 现在有n个同学,编号为1到n,从第一个同学开始选择要坐的位 ...
- Java compiler level does not match the version of the instal
一.问题描述 新建了一个项目,workspace默认jdk编译版本是1.7的,新建项目使用的是jdk1.5的版本,肯定会报@override错误.这个时候,修改项目的compilor即可. 这时候,你 ...