日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

音视频播放器—快进快退及逐帧播放

發(fā)布時間:2023/12/14 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 音视频播放器—快进快退及逐帧播放 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

------------------------------------全系列文章目錄------------------------------------

快進(jìn)快退

大致流程

獲取跳轉(zhuǎn)的文件位置
  • 通過捕獲SDL_KEYDOWN按鍵按下事件,并通過標(biāo)志位判斷當(dāng)前的鍵位SDL_Event::SDL_KeyboardEvent::SDL_Keysym::SDL_KeycodeSDLK_LEFTSDLK_RIGHT,以此來確定是向前跳轉(zhuǎn)還是向后跳轉(zhuǎn)。

    switch (_event.type) {case SDL_KEYDOWN:switch (_event.key.keysym.sym) {case SDLK_LEFT:avc->set_seek_pos(-SEEK_POS_CHANGE);break;case SDLK_RIGHT:avc->set_seek_pos(SEEK_POS_CHANGE);break;default:break;} }
  • 使用一個標(biāo)志位seek_pos來表示跳轉(zhuǎn)到文件中的位置;每次發(fā)生跳轉(zhuǎn)時,先更新當(dāng)前文件位置,將seek_pos加上上次跳轉(zhuǎn)時時間和當(dāng)前時間的時間差作為最新的seek_pos;然后加上當(dāng)前的跳轉(zhuǎn)變化量,作為跳轉(zhuǎn)到文件中的位置。

    void AVCtrl::set_seek_pos(int64_t _pos) {int64_t _pos_time = av_gettime() / MICROSECOND_TO_SECOND; seek_flag = 1;//加上 距離上次跳轉(zhuǎn)到現(xiàn)在的時間差 作為最新的seek_pos, 并加上當(dāng)前的變化量seek_pos += (_pos + _pos_time - pos_time);seek_pos = seek_pos < 0 ? 0 : seek_pos;seek_pos = seek_pos > file_duration ? file_duration : seek_pos;pos_time = _pos_time; //更新發(fā)生跳轉(zhuǎn)時的時間 }
重定向文件
  • 重定向文件使用av_seek_frame函數(shù)來實(shí)現(xiàn),其函數(shù)定義如下:

    int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
    • s:多媒體文件的句柄,即打開文件時所使用的AVFormatContext結(jié)構(gòu)體;

    • stream_index:選擇跳轉(zhuǎn)后選取的數(shù)據(jù)流,如果為 -1,則選擇默認(rèn)流,并且時間戳?xí)詣訌?AV_TIME_BASE 單位轉(zhuǎn)換為特定于流的 time_base;

    • timestamp:以 AVStream.time_base 為單位的時間戳,如果未指定流,則以 AV_TIME_BASE 為單位。

    • flags:用于選擇方向和搜索模式的標(biāo)志位(主要是對關(guān)鍵幀的選取),可選標(biāo)志如下

      /*跳轉(zhuǎn)到非關(guān)鍵幀時, 往回找到關(guān)鍵幀, 作為跳轉(zhuǎn)點(diǎn)*/ #define AVSEEK_FLAG_BACKWARD 1 ///< seek backward #define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes /*可以跳轉(zhuǎn)到任何幀*/ #define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes /*跳轉(zhuǎn)到非關(guān)鍵幀時, 往后找到關(guān)鍵幀, 作為跳轉(zhuǎn)點(diǎn)*/ #define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number
    • 返回≥0表示成功

  • 因此在線程中檢測重定事件是否發(fā)生,若發(fā)生了,則通過av_seek_frame函數(shù)進(jìn)行文件重定向處理

    if (avc->get_seek_flag()) {avc->set_seek_flag(0);av_seek_frame(avc->pFormatCtx, -1, avc->get_seek_pos() * AV_TIME_BASE, AVSEEK_FLAG_BACKWARD); //重定位文件, 定位至關(guān)鍵幀........ }
  • 當(dāng)發(fā)生文件跳轉(zhuǎn)時,原本demux時存取在隊(duì)列中的數(shù)據(jù)包,以及解碼后的數(shù)據(jù)包都不能使用,因此要進(jìn)行清空隊(duì)列操作。

逐幀播放

事件捕獲
  • 通過捕獲SDL_KEYDOWN按鍵按下事件,并通過標(biāo)志位判斷當(dāng)前的鍵位SDL_Event::SDL_KeyboardEvent::SDL_Keysym::SDL_Keycode是否為一特定按鍵如SDLK_p來啟動逐幀播放操作。需要注意的是SDLK_p按鍵應(yīng)該在暫停時才會觸發(fā),并且需要保證播放完一幀后才會繼續(xù)觸發(fā)。
大致流程如下
  • 當(dāng)播放暫停時,若按下SDLK_p鍵,標(biāo)記該事件,同時暫停接收SDLK_p按鍵事件;
  • 視頻線程解碼一幀,并將其顯示出來;并判斷當(dāng)前視頻幀pts是否大于音頻幀pts,若大于則解鎖音頻播放標(biāo)志;最后取消SDLK_p按鍵事件,并解鎖再次接收SDLK_p按鍵事件;
  • 音頻線程若檢測到可以播放,則解碼音頻幀并播放,直到音頻幀pts大于等于視頻幀pts,則取消音頻播放事件;

總結(jié)

以上是生活随笔為你收集整理的音视频播放器—快进快退及逐帧播放的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。