av_seek_frame() 定位为什么不准呢?

初次学习和使用ffmpeg,电脑系统有点老,没办法使用最新版的ffmpeg 3.3,只能从别处下载了一个2.8版的用用,官网提供的历史版本都没有我电脑可用的版本。

花了两天时间学习并写了一个简单的处理视频的程序,实现视频的截屏保存为jpg图片。

本来想用SDL写个播放器,但写着写着,感觉实现视频、音频同步什么的有点难,有点累,就没再继续。

今天在研究视频定位(seek)的时候,在测试代码时发现问题:

我测试了不同格式的视频: mp4,flv,mov,3gp,wmv,mkv,avi

定位,我用的是 av_seek_frame(),如果定位:wmv,avi,3gp 等,我只需简单的使用:

int64_t seekTime_us = 8 * AV_TIME_BASE; //单位: 微秒
av_seek_frame(pFormatCtx, -1 , seekTime_us, AVSEEK_FLAG_BACKWARD); // AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY | AVSEEK_FLAG_FRAME

结果:定位很准确。

但上面的代码用来定位:mp4,flv,mov,mkv等,经常会遇到定位不准的情况,误差在[0-5秒]左右。

在网上搜索了半天,找到下面另一种计算方法,经测试和上面的效果其实是一样的,误差在[0-5秒]左右,还不如上面的简单。

int startSecond = 8;
int64_t seekTime_us = startSecond * AV_TIME_BASE; //单位: 微秒
int64_t targetFrame = av_rescale_q(seekTime_us, AV_TIME_BASE_Q, pFormatCtx->streams[videoStream]->time_base);

int64_t seekStreamDuration = pFormatCtx->streams[videoStream]->duration;
int flags = AVSEEK_FLAG_BACKWARD; //默认使用
if(targetFrame > 0 && targetFrame < seekStreamDuration)
{
    // H.264 I frames don‘t always register as "keyframes" in FFmpeg
    flags |= AVSEEK_FLAG_ANY; //加了这个,有时定位更不准
}

av_seek_frame(pFormatCtx, videoStream, targetFrame, flags);
avcodec_flush_buffers(pCodecCtx);

我又换了个方式:先计算视频的总帧数(frameCount),然后通过fps计算出8秒位置的frame_index, 不用av_seek_frame,直接通过while(av_read_frame()),跳过frame_index,来实现seek,这个方法定位非常准,但不科学。因为如果要定位到60秒,我用的电脑光是花费在while(av_read_frame())上的时间就将近4秒,效率太低了,只适合定位开头几十秒内。

谁能告诉我,怎样用 av_seek_frame 来定位 mp4,flv 格式的视频精准一点,不要定位到8秒,显示的是5秒时的内容。

时间: 2024-10-12 22:41:32

av_seek_frame() 定位为什么不准呢?的相关文章

locationManager 定位地址不准,获取回调更准的方法

原来的写法,这种写法获取第一次返回的结果,然后就会停止更新经纬度 - (void)operationLocations:(NSArray *)locations{ [self.locationManager stopUpdatingLocation]; .... .... } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations [self operationLoc

Android附近基站+Wifi+IP+GPS多渠道定位方案

前言: 在移动客户端的开发中,地理位置定位是一个非常重要的环节,有些时候用户可能会限制web app或者Android app的一些权限,或者由于信号不佳的原因无法获得准确的GPS位置,甚至为了省电,用户可能对开启GPS开关可能会有抵触情绪.但是不能因为GPS的种种限制就放弃了对用户位置的追踪.要通过一切能发送出信号的物体尽可能准确的获取到用户的位置,有时可以牺牲一些精度,对于大数据和用户地区分布分析来说,有一个大体的位置已经够分析人员使用,而且绕开GPS的重重壁垒,为数据的完整性提供可靠方案

访问网址(使用CDN)时 智能DNS调度 与 用户定位调度(根据IP定位)

大型网站或多受众用户服务网站在中国特定网络环境下,离不开CDN(内容服务网络)及用户调度.而CDN与用户调度则涉及智能DNS解析与用户定位的问题. 大家知道,现在很多网站的 GLSB 都是基于 DNS 来做用户定位调度.DNS 的解析流程如下: 比如,我是北京的用户,我的 DNS 为 202.106.0.20.当我要打开 www.php-oa.com 时,先会给请求发给 ISP 告诉我的 DNS.这个叫 Local DNS .然后其它的向根域和二级域的查询,都是由 Local DNS 帮我完成的

linux服务器硬件报错,系统异常重启检测-MCElog

mcelog 是 x86 的 Linux 系统上用来检查硬件错误,特别是内存和CPU错误的工具.比如服务器隔一段时间莫名的重启一次,而message和syslog又检测不到有价值的信息. 通常发生MCE报错的原因有如下:1.内存报错或者ECC问题2.处理器过热3.系统总线错误4.CPU或者硬件缓存错误 一般来说当有错误提示时,需要优先注意内存问题,但由于现在内存控制器是集成在cpu里,所以有个别情况是由CPU问题引起的 一.如果是联网的情况下,yum源配置可用则yum install mcelo

第二次冲刺会议2

今天小组的成员都做了如下内容: 崔乐乐: 一.今天做了什么 尝试为图片分区 二 遇到的问题 进展缓慢,坐标定位位置不准 三 明天要做什么 寻找图片每一区域中心位置的坐标 黄肖飞: 一.今天做了什么 今天延续昨天的工作,选择了2048,开心消消乐,我叫MT等几款比较火爆的手游,学习他们的游戏界面. 二.遇到什么困难 这些游戏的选关界面,都是有动画效果的,我们在有限的时间内肯定做不出来. 三.怎么解决的 我们用静态的背景图片,加上稍微明亮的颜色来当做游戏背景图片. 赵玉璇: 昨天做了什么? 将截图存

第二次冲刺会议3

今天我们小组的成员都做了如下内容: 崔乐乐: 一.今天做了什么 尝试为图片分区 二 遇到的问题 进展缓慢,坐标定位位置不准 三 明天要做什么 寻找图片每一区域中心位置的坐标 黄肖飞: 一.今天做了什么 今天把已经处理好的背景图片更换到项目中,测试,观察展示效果. 二.遇到什么问题 图片的大小设置有点问题,不同的手机,不同的分辨率,不同屏幕的大小,图片的展示效果不一样. 三.怎么解决的 将图片根据手机屏幕的大小,屏幕的分辨率的高低,分别进行按比例缩放. 赵玉璇: 昨天做了什么? 将功能,代码进行完

IE8 textarea 滚动条定位不准解决方法

工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是js的问题,查看了代码感觉不是js的问题,于是借助索工具搜索了一番,这个问题感觉很少见,但是搜索之后发现确实有人遇到过这个问题. 也有些许的解决方案,经过几轮测试找到了最终的解决方案: textarea.fix-scroll{ width: 700px; min-width: 100%; max-wi

mcs的方式创建的虚拟机,鼠标定位不准的问题处理

如果是mcs的方式创建的虚拟机,鼠标定位不准的问题通过下面的方法解决 ?Get the uuid of your VM (ensure that xentools is installed) ?Shutdown the VM (otherwise, unexpected problems may occur) ?Open the console of sever and enter: xe vm-param-set uuid=<VM uuid> platform:usb=true platfo

一次定位不准的问题

花了三天时间试图做一个永远不能完成的任务.需求:程序逻辑出现错误 @Autowiredprivate TwoHoursTaskThread twoHoursTaskThread;// 该实例是实现Runnable的一个单例 for(int i=0,l=list.size();i<l;i++){ ForfeitVO forfeitVO = list.get(i); twoHoursTaskThread.setForfeitVO(forfeitVO); Executors.newScheduledT