今天在使用android-as_video_player这个开源的框架来实现自己项目中的一个播放器,中间关于ndk编译ffmpeg遇到的坑,现在想起来,对ndk的心态,现在心里都有一万个cnm在奔腾,此处略过ndk编译ffmpeg源码的过程,最后使用的ndk-r10d编译的ffmpeg2.8.5版本。其实这时候ffmpeg已经更新到了4.1版本,要求别这么多,先将就着作用。
第一个坑就是当我把代码码完了,lib也编译通过,程序也能调试了的时候,心里是愉悦的,但跑起来以后,运行不正常,本地文件视频播放不出来,这就很尴尬了哈。
然后通过接口观察数据,发现avformat_open_input这个接口失败了,然后呢?报错信息调试为:Invalid data found when processing input,于是百度,谷歌搜索一番先,然后大部分人说调用的lib被协议部分被禁用的原因,于是就有了自己ndk编译ffmpeg这么操蛋的事情发生了。可我自己编译的lib怎么也不行呢?搞了半天,没办法,自己先阅读一通ffmpeg源码,然后发现还是找不到问题,于是想起来,我可以给ffmpeg设置一个log的回调函数,然后把错误信息报错的更加详细一些,于是加log回调函数,然后获取报错信息: moov atom not found,然后又baidu,google一番,少有收获哈,在https://bbs.csdn.net/topics/300243359论坛上找到第一条有用的信息。
 
 
 
原因是lseek函数在custom的接口中实现的有问题。
而从ffmpeg的源码,我们获取这个报错的信息位置为:
 
 
 
因为mp4文件,moov在文件的末尾,所以这个地方可以判断可能真的是lseek的原因。
然后加断点,发现我写的seek函数在whence等于AVSEEK_SIZE的时候,返回的-1。那custom方式的seek到底怎么实现呢?
经过参考http://www.52ffmpeg.com/article/497.htmlhttps://www.codeproject.com/Tips/489450/Creating-Custom-FFmpeg-IO-Context这两个文件,AVSEEK_SIZE这whence应该是返回文件的大小,同时seek我们也可以参考代码自己实现一个;
于是我自己的实现方式:
 int FileSource::ReadSeek( int offset, int whence){
// 参数检查.
int ret=-;
if (offset > m_nFileSize || !m_file.is_open()){
LOGI("seek offset=%d> file size:%d,or file is close.",offset,m_nFileSize);
return -;
}
if (m_bIsMultithread)
m_mutex.Lock(); std::ios_base::seekdir way = (std::ios_base::seekdir)whence;
// 进行seek操作.
if (whence != AVSEEK_SIZE) {
//先把错误位置给
m_file.clear();
//////////////////////////////
switch(whence){
case SEEK_SET:
//基于文件开始位置进行seek跳转
m_file.seekg(offset,std::ios_base::beg);
// ret = offset;
break;
case SEEK_CUR:
//基于文件当前位置进行seek跳转
m_file.seekg(offset,std::ios_base::cur);
// ret=m_file.tellg();
break;
case SEEK_END:
//基于文件尾的位置进行seek跳转
m_file.seekg(offset,std::ios_base::end);
// ret=m_file.tellg();
break;
}
if (m_file.good())
ret = m_file.tellg();
else
ret = -;
}else{
//等于AVSEEK_SIZE,这个主要是用于获取文件大小
// The whence-parameter has one more option than fseek: AVSEEK_SIZE.
// When this option is passed to the seek function it should return the file size (if possible).
// If its not possible, the function may return and do nothing -1. In my implementation pStream->Seek(...) will fail with AVSEEK_SIZE and SeekFunc will return -1.
ret=m_nFileSize;
} if (m_bIsMultithread)
m_mutex.Unlock(); return ret;
}
然后,视频就能正常解码和播放了
 转载请注明出处:https://www.cnblogs.com/lihaiping/p/10637615.html

(原)关于ffmpeg使用custom io-context遇到的一些坑的更多相关文章

  1. [原] Android上使用native IO

    首先, 官方google play对APK大小有限制: 50M.( https://support.google.com/googleplay/android-developer/answer/113 ...

  2. [原]how to view custom provider's events(collected without provider registered) by wpa

    最近想使用etw作为高效的日志机制,也不想暴露机密信息(关键信息在msnifest文件中).也就是不能在客户机器上注册自己的provider,那需要manifest文件.这样采集回来的.etl文件如果 ...

  3. spring整合mybatis使用<context:property-placeholder>时的坑

    背景 最近项目要上线,需要开发一个数据迁移程序.程序的主要功能就是将一个数据库里的数据,查询出来经过一系列处理后导入另一个数据库.考虑到开发的方便快捷.自然想到用spring和mybatis整合一下. ...

  4. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

  5. 使用ByteArrayOutputStream解决IO乱码问题的踩坑记录

    经过:今天在用s3接口做ceph储存的时候,要实现一个io下载的接口.需要把InputStream转成byte[],一开始,是的写法是这样的: byte[] buf = new byte[(int) ...

  6. vue-socket.io使用教程与踩坑记录

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12018866.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 请先允许我狠狠吐个 ...

  7. FFmpeg内存IO模式(内存区作输入或输出)

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10318145.html 所谓内存IO,在FFmpeg中叫作"buffered ...

  8. ffmpeg的IO操作

    ffmpeg 可以通过IO操作将数据读取和存储在文件或网络中 作为数据的读取和写入地址,数据被存放在file,http, ffmpeg 不仅可以编解常用的音视频格式,还可以将数据导入/导出到各种媒介中 ...

  9. ffmpeg最全的命令参数

    Hyper fast Audio and Video encoderusage: ffmpeg [options] [[infile options] -i infile]... {[outfile ...

随机推荐

  1. 如何使用 ccs7.2调试代码

    首先将单片机连接在电脑USB口上 或者 或者F11快捷键 如果编译通过的话,会是这个样子 F11调试后会停在主函数开始处 第一个黄绿组合的按钮就是继续调试,快捷键为F8,按F8后它会停在断点处,如果为 ...

  2. JWTtoken的原理以及在django中的应用

    JWT 在用户注册或者登陆完成之后,记录用户状态,或者为用户创建身份凭证(功能类似于session的作用). 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而 ...

  3. 【翻译】Spark 调优 (Tuning Spark) 中文版

    由于Spark自己的调优guidance已经覆盖了很多很有价值的点,因此这里直接翻译一份过来.也作为一个积累. Spark 调优 (Tuning Spark) 由于大多数Spark计算任务是在内存中运 ...

  4. poi 升级至4.x 的问题总结(POI Excel 单元格内容类型判断并取值)

    POI Excel 单元格内容类型判断并取值 以前用 cell.getCachedFormulaResultType() 得到 type 升级到4后获取不到了 换为:cell.getCellType( ...

  5. VUE温习:nextTick、$refs、嵌套路由、keep-alive缓存、is特性、路由属性用法、路由钩子函数

    一.$nextTick 1.vue的dom执行异步更新,只要观察到数据变化,vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变. 2.vue.$nextTick(cb),数据发生变化,更新 ...

  6. python接口自动化测试(二)-requests.get()

    环境搭建好后,接下来我们先来了解一下requests的一些简单使用,主要包括: requests常用请求方法使用,包括:get,post requests库中的Session.Cookie的使用 其它 ...

  7. rpm 打包的时候 不进行strip

    http://blog.aka-cool.net/blog/2016/06/01/how-to-disable-strip-in-rpm-build/ https://www.ichenfu.com/ ...

  8. 1154:LETTERS

    题目链接http://bailian.openjudge.cn/practice/1154/ 总时间限制: 1000ms 内存限制: 65536kB 描述 A single-player game i ...

  9. 日志分析工具 Log Parser

    微软的Log Parser, 下载地址 https://www.microsoft.com/en-us/download/details.aspx?id=24659 支持多种文件格式的分析,输入输出, ...

  10. Android触摸事件(一)-TouchEventHelper

    文件夹 文件夹 概述 关于更新 2016-08-31 2016-06-20 关于单点触摸事件singleTouch 单击的两种方式 关于双击事件 双击事件的检測逻辑 双击事件触发的时机 关于多点触摸事 ...