国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于 FFMPEG 的跨平臺視頻播放器簡明教程(三):視頻解碼

這篇具有很好參考價(jià)值的文章主要介紹了基于 FFMPEG 的跨平臺視頻播放器簡明教程(三):視頻解碼。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

系列文章目錄

  1. 基于 FFmpeg 的跨平臺視頻播放器簡明教程(一):FFMPEG + Conan 環(huán)境集成
  2. 基于 FFmpeg 的跨平臺視頻播放器簡明教程(二):基礎(chǔ)知識和解封裝(demux)


前言

在前面章節(jié) 基于 FFMPEG 的跨平臺視頻播放器簡明教程(二):基礎(chǔ)知識和解封裝(demux) 中我們引入了視頻編解碼的基礎(chǔ)知識以及解封裝的概念。

請記住我們的任務(wù):使用 ffmpeg 解碼視頻,并將解碼后的視頻幀保存在本地(就像對視頻截圖一樣)。今天,圍繞這個(gè)任務(wù)讓我們繼續(xù)下一個(gè)知識點(diǎn):視頻解碼。

本文參考文章來自 An ffmpeg and SDL Tutorial - Tutorial 01: Making Screencaps。這個(gè)系列對新手較為友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已經(jīng)被棄用了。幸運(yùn)的是,有人對該教程的代碼進(jìn)行重寫,使用了較新的 api,你可以在 rambodrahmani/ffmpeg-video-player 找到這些代碼。

本文的代碼在 ffmpeg_video_player_tutorial-tutorial01。

使用 ffmpeg api 進(jìn)行視頻解碼的步驟

概括來說,視頻解碼的步驟包括:

  1. 創(chuàng)建解碼器
  2. 解封裝,從視頻流中讀取一個(gè) packet
  3. 將 packet 送給解碼器,解碼器進(jìn)行解碼
  4. 從解碼器中,取回解碼后的數(shù)據(jù)

創(chuàng)建解碼器

在 ffmpeg 中與解碼器相關(guān)的結(jié)構(gòu)體有兩個(gè):AVCodec 和 AVCodecContext。

AVCodec結(jié)構(gòu)體包含了編解碼器的特定信息,如編解碼器的類型、名稱、支持的像素格式或音頻樣本格式等。你可以使用 avcodec_find_decoder 從 ffmpeg 支持的編解碼器中找到你需要的那個(gè)。

AVCodec *avcodec_find_decoder(enum AVCodecID id);

avcodec_find_decoder 函數(shù)的主要目的是根據(jù)給定編解碼器ID(AVCodecID)找到合適的解碼器。在實(shí)現(xiàn)邏輯中,它對FFmpeg支持的所有編解碼器進(jìn)行迭代,并比較它們的AVCodecID與所需的AVCodecID。

如果發(fā)現(xiàn)有無法找到某個(gè) id,有可能是因?yàn)槟闶褂玫?ffmpeg 做了裁剪,不支持這種類型的 codec,這時(shí)候你可以在代碼中打印一下當(dāng)前 ffmpeg 支持的 codec 信息:

const AVCodec *codec = NULL;
  void *i = 0;
  printf("List of supported codecs:\n");

  // Iterate over all codecs using av_codec_iterate
  // Note: use av_codec_next(codec) instead for older versions of FFmpeg
  while ((codec = av_codec_iterate(&i))) {
    printf("Codec name: %s, codec type: %s\n", codec->name,
           codec->type == AVMEDIA_TYPE_AUDIO      ? "Audio"
           : codec->type == AVMEDIA_TYPE_VIDEO    ? "Video"
           : codec->type == AVMEDIA_TYPE_SUBTITLE ? "Subtitle"
                                                  : "Other/Unknown");
  }

AVCodec 結(jié)構(gòu)體僅僅是對某個(gè)編解碼器的描述,要進(jìn)行編解碼還需要 AVCodecContext 參與。

在 FFmpeg 中,AVCodecContext 是一個(gè)結(jié)構(gòu)體,它表示編解碼器的上下文,主要負(fù)責(zé)存儲與編解碼器相關(guān)的配置信息和狀態(tài)。AVCodecContext 的作用在于為音頻、視頻或字幕數(shù)據(jù)的編碼和解碼過程提供所需要的各種參數(shù)和數(shù)據(jù)。AVCodecContext 包含以下主要信息:

  1. 編解碼器類型(音頻、視頻或字幕)
  2. 編解碼器的 ID(用于標(biāo)識特定的編解碼器,例如 H.264,MP3 等)
  3. 時(shí)間基(用于計(jì)算時(shí)間戳)
  4. 幀率或采樣率(視頻或音頻播放的速度)
  5. 比特率(編解碼后的數(shù)據(jù)流的速率)
  6. 編碼或解碼期間使用的各種配置選項(xiàng)(如像素格式,音頻通道數(shù)量,視頻分辨率等)

要使用特定的 AVCodec 對象進(jìn)行編解碼,需要為其配置一個(gè)相應(yīng)的 AVCodecContext,并設(shè)置相應(yīng)的參數(shù)。然后使用 FFmpeg 提供的函數(shù)(如 avcodec_open2,avcodec_send_packet 等)對數(shù)據(jù)進(jìn)行編解碼。

因此,AVCodecContext 是連接原始數(shù)據(jù)、編解碼器(AVCodec)和輸出數(shù)據(jù)之間的橋梁。它幫助用戶在輸入和輸出之間傳遞數(shù)據(jù),并提供編解碼過程所需的參數(shù)。

在代碼中,使用 avcodec_alloc_context3 創(chuàng)建一個(gè) AVCodecContext

pCodecCtx = avcodec_alloc_context3(pCodec); 

接著,需要填充 AVCodecContext 中各種信息,一種簡便的方式是使用 avcodec_parameters_to_context

avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);

最后一步,使用 avcodec_open2 打開編解碼器并與 AVCodecContext 相關(guān)聯(lián)。

avcodec_open2(pCodecCtx, pCodec, NULL);

解封裝,讀取 packet

關(guān)于解封裝我們在 基于 FFMPEG 的跨平臺視頻播放器簡明教程(二):基礎(chǔ)知識和解封裝(demux) 已經(jīng)做了詳細(xì)的介紹。

從文件中讀取一個(gè) packet 非常簡單,代碼如下:

AVPacket * pPacket = av_packet_alloc(); 
av_read_frame(pFormatCtx, pPacket); // 從 AVFormatContext 中讀取一個(gè) packet
if(pPacket->stream_index == videoStream) // 只處理視頻流
{
	// do something
} 
  1. av_packet_alloc 用于申請一個(gè) AVPacket
  2. av_read_frame 從 AVFormatContext 中讀取一個(gè) packet
  3. 判斷當(dāng)前 packet 是否是視頻數(shù)據(jù)(或者其他你想要的數(shù)據(jù)),接著進(jìn)行處理

將 packet 送給解碼器,解碼器進(jìn)行解碼

這一步非常簡單,調(diào)用 avcodec_send_packet 即可。avcodec_send_packet函數(shù)的主要作用如下:

  1. 將輸入的壓縮數(shù)據(jù)包傳遞給解碼器進(jìn)行解碼。
  2. 在數(shù)據(jù)發(fā)送完畢時(shí)(例如,文件結(jié)束或流結(jié)束),傳遞NULL數(shù)據(jù)包以通知解碼器將剩余數(shù)據(jù)刷新。

avcodec_send_packet 函數(shù)的返回值是值得注意的,用于表示操作的結(jié)果。以下是可能的返回值及其含義:

  • 0:操作成功。這意味著輸入的壓縮數(shù)據(jù)包已成功傳遞給解碼器。

  • AVERROR(EAGAIN):當(dāng)前解碼器的狀態(tài)不允許接收更多的數(shù)據(jù)包。這通常意味著解碼器內(nèi)部緩沖區(qū)已滿,需要先調(diào)用avcodec_receive_frame()函數(shù)接收解碼幀才能繼續(xù)發(fā)送數(shù)據(jù)包。

  • AVERROR_EOF:解碼器已經(jīng)被刷新并且不再接受數(shù)據(jù)包。這意味著文件或流已結(jié)束,并且解碼器已經(jīng)清空。

  • AVERROR(EINVAL):提供的AVCodecContext或AVPacket無效,例如AVCodecContext為NULL。也可能意味著解碼器沒有被正確打開,或者在編碼器AVCodecContext上調(diào)用了avcodec_send_packet。

  • AVERROR(ENOMEM):解碼器內(nèi)部緩沖區(qū)分配失敗,內(nèi)存不足。

  • 其他負(fù)數(shù):其他庫錯誤或解碼器實(shí)現(xiàn)特定的錯誤代碼,具體的錯誤代碼可以通過 av_err2str 函數(shù)將錯誤碼轉(zhuǎn)為字符串進(jìn)行輸出。

從解碼器中,取回解碼后的數(shù)據(jù)

這一步也非常簡單,使用 avcodec_receive_frame 從 codec 中取回解碼后的數(shù)據(jù)。avcodec_receive_frame 函數(shù)的主要作用如下:

  1. 嘗試從解碼器獲得已解碼的幀(例如,解碼后的視頻或音頻幀)。
  2. 提供對解碼器內(nèi)部緩沖區(qū)和狀態(tài)管理的抽象,使得調(diào)用者不需要直接處理內(nèi)部緩沖區(qū)和狀態(tài)。
  3. 在解碼器已經(jīng)處理完所有輸入數(shù)據(jù)包且內(nèi)部緩沖區(qū)已空時(shí),返回AVERROR_EOF,從而告知調(diào)用者解碼過程已完成。
  4. 如果解碼器需要更多的輸入數(shù)據(jù)包才能生成解碼幀,則返回AVERROR(EAGAIN),告知調(diào)用者繼續(xù)發(fā)送數(shù)據(jù)包。

avcodec_send_packetavcodec_receive_frame 一般是成配對使用的,但是你看代碼通常這部分代碼會夾雜了一些 while/for 循環(huán),這是為啥?這是因?yàn)?packet 與 frame 的生成速度不一定是一對一的:avcodec_send_packet 發(fā)送了一個(gè) packet 之后,avcodec_receive_frame 可能沒有產(chǎn)生,也可能產(chǎn)出多幀。因此你需要用一個(gè) for/while 循環(huán)來處理。

while (ret >= 0) {
  ret = avcodec_receive_frame(pCodecCtx, pFrame); 

  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
    // EOF exit loop
    break;
  } else if (ret < 0) {
    // could not decode packet
    printf("Error while decoding.\n");

    // exit with error
    return -1;
  }
}

總結(jié)

本文說明了使用 ffmpeg api 進(jìn)行視頻解碼的流程,步驟順序?yàn)椋?mark hidden color="red">文章來源:http://www.zghlxwxcb.cn/news/detail-482580.html

  1. 創(chuàng)建解碼器
  2. 解封裝,從視頻流中讀取一個(gè) packet
  3. 將 packet 送給解碼器,解碼器進(jìn)行解碼
  4. 從解碼器中,取回解碼后的數(shù)據(jù)

整個(gè)過程中,最為關(guān)鍵的部分是使用 avcodec_send_packet 和 avcodec_receive_frame 進(jìn)行解碼操作。理解這兩個(gè) api 是理解視頻解碼的關(guān)鍵。文章來源地址http://www.zghlxwxcb.cn/news/detail-482580.html

參考

  • ffmpeg_video_player_tutorial-tutorial01
  • An ffmpeg and SDL Tutorial - Tutorial 01: Making Screencaps

到了這里,關(guān)于基于 FFMPEG 的跨平臺視頻播放器簡明教程(三):視頻解碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 基于 FFMPEG 的跨平臺視頻播放器簡明教程(二):基礎(chǔ)知識和解封裝(demux)

    基于 FFMPEG 的跨平臺視頻播放器簡明教程(二):基礎(chǔ)知識和解封裝(demux)

    基于 FFmpeg 的跨平臺視頻播放器簡明教程(一):FFMPEG + Conan 環(huán)境集成 前面一章中我們介紹了如何使用 conan 和 cmake 搭建 ffmpeg 運(yùn)行環(huán)境,你做的還順利嗎?如果遇到任何問題,請?jiān)谶M(jìn)行評論,我看到都會回復(fù)的。 從本章開始,將正式開始我們的 ffmpeg 播放器學(xué)習(xí)之旅。接下去

    2024年02月08日
    瀏覽(847)
  • QtAV:基于Qt和FFmpeg的跨平臺高性能音視頻播放框架

    QtAV:基于Qt和FFmpeg的跨平臺高性能音視頻播放框架

    目錄 一.簡介 1.特性 2.支持的平臺 3.簡單易用的接口 二.編譯 1.下載依賴包 2.開始編譯 2.1克隆 2.2修改配置文件 2.3編譯 三.試用 官網(wǎng)地址:http://www.qtav.org/ Github地址:https://github.com/wang-bin/QtAV ●支持大部分播放功能 ●播放、暫停、播放速度、快進(jìn)快退、字幕、音量、聲道、音

    2024年01月22日
    瀏覽(667)
  • 開源的跨平臺的音視頻處理工具FFmpeg

    FFmpeg是一個(gè)開源的跨平臺的音視頻處理工具,可以對音頻、視頻進(jìn)行轉(zhuǎn)碼、裁剪、調(diào)節(jié)音量、添加水印等操作。 廣泛的格式支持。 FFmpeg能夠解碼、編碼、轉(zhuǎn)碼、復(fù)用、分離、流式傳輸、過濾和播放幾乎人類和機(jī)器所創(chuàng)造的任何內(nèi)容。它支持最古老且晦澀難懂的格式,也支持

    2024年02月15日
    瀏覽(88)
  • FFmpeg——開源的開源的跨平臺音視頻處理框架簡介

    FFmpeg——開源的開源的跨平臺音視頻處理框架簡介

    引言: ????????FFmpeg是一個(gè)開源的跨平臺音視頻處理框架,可以處理多種音視頻格式。它由Fabrice Bellard于2000年創(chuàng)建,最初是一個(gè)只包括解碼器的項(xiàng)目。后來,很多開發(fā)者參與其中,為FFmpeg增加了多種新的功能,例如編碼器、過濾器、muxer、demuxer等等,使它成為了一個(gè)完整

    2024年03月23日
    瀏覽(90)
  • 基于FFmpeg的視頻播放器之三:拉取rtsp流

    拉取網(wǎng)絡(luò)流和打開本地文件流程差不多,詳見:基于FFmpeg的視頻播放器之二:解復(fù)用,下面是不同地方。 方法有很多,最方便的應(yīng)該是用VLC串流了,具體步驟如下:https://blog.csdn.net/m0_61353061/article/details/120388230 當(dāng)然也可以使用live555作為rtsp服務(wù)器,可參考:https://blog.csdn.net

    2023年04月25日
    瀏覽(89)
  • 音視頻項(xiàng)目—基于FFmpeg和SDL的音視頻播放器解析(三)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項(xiàng)目音視頻播放器,在這個(gè)項(xiàng)目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識。您對源代碼感興趣的話,請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項(xiàng)目—基于FFmpeg和SDL的音視

    2024年02月05日
    瀏覽(106)
  • 音視頻項(xiàng)目—基于FFmpeg和SDL的音視頻播放器解析(二十一)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項(xiàng)目音視頻播放器,在這個(gè)項(xiàng)目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識。您對源代碼感興趣的話,請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項(xiàng)目—基于FFmpeg和SDL的音視

    2024年02月02日
    瀏覽(101)
  • QT軟件開發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-軟解圖像(一)

    QT軟件開發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-軟解圖像(一)

    QT軟件開發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-CPU軟解視頻(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT軟件開發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-GPU硬解視頻(二) https://xiaolong.blog.csdn.net/article/details/126833434 QT軟件開發(fā)-基于FFMPEG設(shè)計(jì)視頻播放器-解碼音頻(三) https://xiaolong.blog.csdn.

    2023年04月08日
    瀏覽(95)
  • ffmpeg跨平臺arm編譯-ubuntu

    32位系統(tǒng): 64位系統(tǒng): 關(guān)鍵選項(xiàng): –arch=arm:指定ARM平臺 –target-os=linux:指定Linux系統(tǒng) –enable-cross-compile :指定交叉編譯 –cross-prefix=arm-linux-gnueabihf-:指定交叉編譯鏈 如果是64位系統(tǒng): –arch=aarch64:指定ARM平臺 –cross-prefix=aarch64-linux-gnu-:指定交叉編譯鏈

    2024年02月08日
    瀏覽(88)
  • 論文精講 | 基于昇思MindSpore打造首個(gè)深度學(xué)習(xí)開源視頻壓縮算法庫OpenDMC,支持跨平臺和多種評價(jià)指標(biāo)

    論文精講 | 基于昇思MindSpore打造首個(gè)深度學(xué)習(xí)開源視頻壓縮算法庫OpenDMC,支持跨平臺和多種評價(jià)指標(biāo)

    論文標(biāo)題 OpenDMC: An Open-Source Library and Performance Evaluation for Deep-learning-based Multi-frame Compression 論文來源 ACM MultiMedia 論文鏈接 https://www.acmmm2023.org/open-source-program/ 代碼鏈接 https://openi.pcl.ac.cn/OpenDMC/OpenDMC 昇思MindSpore作為開源的AI框架,為產(chǎn)學(xué)研和開發(fā)人員帶來端邊云全場景協(xié)同、

    2024年02月02日
    瀏覽(108)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包