ffmpeg 解碼視頻流程

引用雷神原圖:


image.png

可以看出 av_register_all() 是必備的第一步 (?)
個(gè)人可用解碼流程

av_register_all();
avcodec_register_all();
avformat_network_init();
//初始化三個(gè)
//打開(kāi)視頻文件
av_format_open_input();
賦值:AVFormatContext,鏈接地址(可本地可網(wǎng)絡(luò)),AVInputFormat,AVDictionary。

int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
后二值可NULL,返回0則打開(kāi)失敗
//檢查數(shù)據(jù)流
avformat_find_stream_info();
av_find_stream_info();(棄用?)
賦值:AVFormatContext,AVDictionary

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
后值可NULL,返回小于0檢查失敗
//根據(jù)視頻流找到第一幀
av_find_best_stream();
賦值:AVFormatContext,AVMediaType,wanted_stream_nb,related_stream,AVCodec,flags。
int av_find_best_stream(AVFormatContext *ic,
                        enum AVMediaType type,
                        int wanted_stream_nb,
                        int related_stream,
                        AVCodec **decoder_ret,
                        int flags);
//舉例
if((videoStream = av_find_best_stream(spFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &pCodec, 0))< 0){
        NSLog(@"沒(méi)有找到第一個(gè)視頻流");    
}

此時(shí)已經(jīng)可以獲取第一幀數(shù)據(jù)流對(duì)應(yīng)的CodecContext

    stream = spFormatCtx ->streams[videoStream];
    spCodecCtx = stream ->codec;

打印視頻流的詳細(xì)信息

av_dump_format(spFormatCtx, videoStream, filePath, 0);
void av_dump_format(AVFormatContext *ic,
                    int index,
                    const char *url,
                    int is_output);
//打印關(guān)于輸入或輸出格式的詳細(xì)信息,例如
持續(xù)時(shí)間,比特率,流,容器,程序,元數(shù)據(jù),側(cè)數(shù)據(jù),
編解碼器和時(shí)基。

這里就可以算出幀率:fps

if(stream ->avg_frame_rate.den && stream ->avg_frame_rate.num){
  fps = av_q2d(stream->avg_frame_rate);
}else{
  fps=30.0;
//講道理這里應(yīng)該不給默認(rèn)值30的,誰(shuí)也不知道是多少,給個(gè)30讓人心里覺(jué)得很安慰
}

查找解碼器

avcodec_find_decoder();
AVCodec *avcodec_find_decoder(enum AVCodecID id);
//根據(jù)上文找到第一幀數(shù)據(jù)流中的解碼器id
AVFormatContext -> steams[找到的第一幀下標(biāo)] (AVSteam) -> AVCodecContext ->codec_id

打開(kāi)解碼器

avcodec_open2();
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
//最后值可NULL 返回值小于0 為打開(kāi)解碼器失敗

這里就可以知道源視頻的寬高
AVCodecContext -> width;
AVCodecContext -> height;

無(wú)限讀針(用在判斷,返回下一個(gè)幀是否存在,不存在結(jié)束循環(huán),有幀,是否為視頻包,不是視頻包接著返回讀取下一幀,是視頻幀調(diào)用解包,如下個(gè)方法)

//返回下一個(gè)針
av_read_frame();
int av_read_frame(AVFormatContext *s, AVPacket *pkt);

解碼

avcodec_decode_video2();
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                         int *got_picture_ptr,
                         const AVPacket *avpkt);
//其中AVFrame 已經(jīng)得到下一幀,就拿改AVFrame 中 data 字段進(jìn)行轉(zhuǎn)圖片操作。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,987評(píng)論 0 3
  • 原文地址:http://blog.csdn.net/yipie/article/details/7912291 摘...
    冬的天閱讀 7,274評(píng)論 1 6
  • 摘要 該配置文件定義了支持高質(zhì)量音頻分發(fā)所需的Bluetooth?設(shè)備的要求。這些要求以終端用戶服務(wù)的方式表達(dá),并...
    公子小水閱讀 10,405評(píng)論 0 4
  • 現(xiàn)狀:現(xiàn)在視頻直播非常的火,所以在視頻直播開(kāi)發(fā)中,使用的對(duì)視頻進(jìn)行遍解碼的框架顯得尤為重要了,其實(shí),這種框架蠻多的...
    ZHANG_GO閱讀 3,276評(píng)論 0 2
  • 那天從麗江回來(lái)陳宇皓就接到要調(diào)回成都的通知,他原本還想帶李賓和她女朋友一起去七星湖看看的,可惜就是崔茜鈴假期不夠,...
    春城一粟閱讀 941評(píng)論 0 1

友情鏈接更多精彩內(nèi)容