天天看點

FFmpeg 3.0 版本視訊解碼淺析 - MPEG 封裝格式到 PCM 資料格式

作者:星隕

來源:

音視訊開發進階

有了上一篇文章基礎,這裡就隻關注 FFmpeg 如何解析的具體實踐了。

在開始工程之前,第一步要做的就是編譯 FFmpeg 源碼,生成 Android 平台上使用的 so 庫。

在生成完了之後,導入 Android 工程項目中,并且配置 CMake 檔案,添加對應的庫,就可以開始開發了。

如果覺得麻煩,也可以直接從網上找一個工程使用現成的東西,也可以參考的我的學習項目:

https://github.com/glumes/FFMPEGLearn

FFmpeg 3.0 與 2.0 的不同之處

如果是剛開始學習,完全可以參照雷神的部落格來寫例子,而且還能運作成功。不過,既然 FFmpeg 都出了 3.0 版本了,還是要跟進學習一下。

可以看到,在具體解析操作時發生了變化,不再是之前的

avcodec_decode_video2

函數,而是拆分成了兩個函數,

avcodec_send_packet

avcodec_receive_frame

avcodec_send_packet

負責發送編碼壓縮後的資料,也就是 Packet 資料,而

avcodec_receive_frame

負責接收解碼後的原始資料,也就是 Frame 資料,這麼一來一回的配合,每次從檔案中讀取一部分内容,直到将整個檔案解碼完成。

解碼流程代碼

FFmpge 的解碼流程大都是相同的,隻是在細節地方會有差異,主體流程還是沒變,看了好多解碼的代碼,大多也是這樣的,隻是在解碼成具體的某些格式時,對原始資料 Frame 的操作會有不同。

// 聲明一堆待會要用到的變量
    AVCodecContext *avCodecContext = nullptr;
    AVCodec *avCodec = nullptr;
    AVCodecParserContext *parserContext = nullptr;
    AVPacket *packet;
    AVFrame *frame;
    // 為上面聲明的變量在指派,并且檢查指派是否成功
    avcodec_register_all()
    // 為解碼器指派,并制定解碼器類型
    avCodec = avcodec_find_decoder(AV_CODEC_ID_HEVC);
    // 為 AVCodecParserContext 和 AVCodecContext 指派
    parserContext = av_parser_init(avCodec->id);
    avCodecContext = avcodec_alloc_context3(avCodec);
    // 打開解碼器
    avcodec_open2(avCodecContext, avCodec, nullptr);
    // 為 Packet 和 Frame 指派
    frame = av_frame_alloc();
    packet = av_packet_alloc();
    while // 開始一點點的解碼檔案内容,直到檔案末尾
        // 解碼從 while 中一次讀取到的内容
        av_parser_parse2
        // 發送讀取到的 packet
        avcodec_send_packet
        // 接收解析完的 frame
        avcodec_receive_frame
        // 對原生資料進行相關操作,解碼成不同資料格式,操作不同。
        // todo
    
    //最後,釋放上面聲明的變量
    av_frame_free
    av_packet_free
    avcodec_free_context
    av_parser_close      

MPEG->PCM 的解碼

在了解視訊檔案的相關基礎以及 FFmpeg 解碼的大緻流程後,就可以開始進行 MPEG->PCM 的解碼工作了。

不過,在這裡還是少了兩個重要的概念:

  1. FFmpeg 各種類以及變量的含義。
  2. 各種音視訊檔案的格式協定。

前半部分還好,對着雷神的部落格一點點的看,還是能看懂的。至于各種音視訊檔案的協定,那就要靠慢慢積累了。

這裡就不貼上全部的代碼了,可以參考如下兩個地方:

  1. http://ffmpeg.org/doxygen/trunk/decode_video_8c-example.html
  2. https://github.com/glumes/FFMPEGLearn/blob/master/FFmpegLib/src/main/cpp/ffmpeg_examples/decode_video.cpp

參考

  1. http://www.jianshu.com/p/7e96223ff329
  2. http://blog.csdn.net/leixiaohua1020/article/details/42181271
「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。
FFmpeg 3.0 版本視訊解碼淺析 - MPEG 封裝格式到 PCM 資料格式

繼續閱讀