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 = (int64_t)8 * AV_TIME_BASE; //单位: 微秒, 必须加 (int64_t),否则有可能发生数据溢出。
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秒时的内容。
av_seek_frame() 定位为什么不准呢?的更多相关文章
- 用opencv检测人眼并定位瞳孔位置
最近的研究要用到定位瞳孔的位置,所以上网搜了下相关的代码.总结如下: 1) 定位瞳孔可以直接使用opencv中的自带的分类器(haarcascade_eye_tree_eyeglasses.xml)来 ...
- PHP EXCEL相关
这次的需求是在二次扫描的EXCEL报表中加入一列扫描时间. 扫描的时间之前已经写进日志里了,这次要做的就是把时间读取出来然后作为一列插入报表.其实日志也已经读出来了,要做的就是插入.但插入还是碰到不少 ...
- 通通玩blend美工(6)上——仿iPhone滚动选择器的ListBox(UI设计)
原文:通通玩blend美工(6)上--仿iPhone滚动选择器的ListBox(UI设计) 好久没更新博客了,由于项目比较紧,期间收到不少园友的短消息,感谢大家对我的支持~~. 相信各位都在自己的神机 ...
- datagridview 定位到最后一行,定位不准的原因
C# 写的 winform 程序,定位到最后一行 dgvGoods.FirstDisplayedScrollingRowIndex = dgvGoods.Rows.Count - 1; 测试中发现,一 ...
- 百度定位api 定位不准修正
https://www.zhihu.com/question/38313555 在安卓开发中需要设置 setCoorType("bd09lsetCoorType("bd09ll ...
- IE8 textarea 滚动条定位不准解决方法
工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是j ...
- EasyPR--开发详解(5)颜色定位与偏斜扭转
本篇文章介绍EasyPR里新的定位功能:颜色定位与偏斜扭正.希望这篇文档可以帮助开发者与使用者更好的理解EasyPR的设计思想. 让我们先看一下示例图片,这幅图片中的车牌通过颜色的定位法进行定位并从偏 ...
- IOS中GPS定位偏移纠正(适用于Google地图)
在这个神奇的国度里,我们总得学习一些有中国特色的东东,例如“火星坐标”.也许有人还不知道这是什么玩意,我就简要介绍一下吧. 如果你有带GPS模块的智能手机,打开定位功能,然后访问Google ...
- html5定位并在百度地图上显示
在开发移动端 web 或者webapp时,使用百度地图 API 的过程中,经常需要通过手机定位获取当前位置并在地图上居中显示出来,这就需要用到html5的地理定位功能. navigator.geolo ...
随机推荐
- 简单JQuery+AJAX+Servlet的计算器实现
index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- python 字符串常用操作方法
python 字符串常用操作方法 python 字符串操作常用操作,如字符串的替换.删除.截取.赋值.连接.比较.查找.分割等 1.去除空格 str.strip():删除字符串两边的指定字符,括号的写 ...
- JQ 动态修改/替换某个节点的内容
<div class="box">我们定位于中国心理行业第一<div> $(".box").html($(".box&quo ...
- 如何使用命令从linux服务器下载文件到windows
1.直接使用命令从linux下载文件到windows //登录linux服务器导出mysql数据 mysqldump -hrm-2ze8mpi5i65429l1q.mysql.rds.aliyuncs ...
- Lodop打印连续的纸张
连续的纸张,有时有会被误解为没有高度,高度自适应,其实不是,这属于纸张连续打印,纸张高度和实际单个纸张高度相同.纸张高度自适应适用于没有高度的那种小票打印(卷纸没有纸张分界线),不是这种连续纸张.关于 ...
- Nginx 负载均衡一致性算法
一般Hash负载算法都是%算法 比如key-5 如果有5台服务器 那么5%5=0 那么请求将落在server 0 上,当有服务器宕机或者添加新服务器时,hash算法会引发大量路由更改,可能导致缓存大 ...
- 找工作的程序员必懂的Linux
一.为什么要学习Linux 首先,我想先说一下:“为什么要学习Linux”?Linux 是什么,它是一款操作系统,是一个支持多用户.多任务.支持多线程和多CPU的操作系统:32位和64位的硬件可以在L ...
- 【嵌入式】Arduino编程基础到应用全解析
Arduino Author: Andrew.Du 基础 基础语法: setup() loop() pinMode(引脚,模式) pinMode(13,OUTPUT):设置13号引脚为输出 //在使用 ...
- windoows ftp的自动上传bat
@echo off set P=%cd% #获取脚本当前文件路径 del /f /s /q %P%\tmp.txt set Y=%DATE:~0,4% #获取年 set M=%DATE:~5,2% # ...
- 学习Android过程中遇到的未解决问题(个人笔记,细节补充,随时更新)
201811/13 使用HttpURLConnection对象调用方法又出现IO异常,我又百度个博客搜寻答案,未果.下午试试真机,完美.自己建了服务器tomcat,编写android访问自己tomca ...