(原)關於ffmpeg使用custom io-context遇到的一些坑

今天在使用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咱們也能夠參考代碼本身實現一個;
因而我本身的實現方式:
 1 int FileSource::ReadSeek( int offset, int whence){
 2     // 參數檢查.
 3     int ret=-1;
 4     if (offset > m_nFileSize || !m_file.is_open()){
 5         LOGI("seek offset=%d> file size:%d,or file is close.",offset,m_nFileSize);
 6         return -1;
 7     }
 8     if (m_bIsMultithread)
 9         m_mutex.Lock();
10 
11     std::ios_base::seekdir way = (std::ios_base::seekdir)whence;
12     // 進行seek操做.
13     if (whence != AVSEEK_SIZE) {
14         //先把錯誤位置給
15         m_file.clear();
16         //////////////////////////////
17         switch(whence){
18             case SEEK_SET:
19                 //基於文件開始位置進行seek跳轉
20                 m_file.seekg(offset,std::ios_base::beg);
21 //            ret = offset;
22                 break;
23             case SEEK_CUR:
24                 //基於文件當前位置進行seek跳轉
25                 m_file.seekg(offset,std::ios_base::cur);
26 //            ret=m_file.tellg();
27                 break;
28             case SEEK_END:
29                 //基於文件尾的位置進行seek跳轉
30                 m_file.seekg(offset,std::ios_base::end);
31 //            ret=m_file.tellg();
32                 break;
33         }
34         if (m_file.good())
35             ret = m_file.tellg();
36         else
37             ret = -1;
38     }else{
39         //等於AVSEEK_SIZE,這個主要是用於獲取文件大小
40 //        The whence-parameter has one  more option than fseek: AVSEEK_SIZE.
41 // When this option is passed to the seek function it should return the file size (if possible).
42 // 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.
43         ret=m_nFileSize;
44     }
45 
46     if (m_bIsMultithread)
47         m_mutex.Unlock();
48 
49     return ret;
50 }
而後,視頻就能正常解碼和播放了
 轉載請註明出處:https://www.cnblogs.com/lihaiping/p/10637615.html
相關文章
相關標籤/搜索