視頻解碼流程

視頻解碼流程

流程圖:
視頻解碼流程圖.png
  1. 注冊組件
    av_register_all();

  2. 打開文件
    avformat_open_input();

  3. 查找視頻流
    avformat_find_stream_info();

  4. 查找視頻解碼器

  5. 打開解碼器
    avcodec_open2();

  6. 讀取視頻壓縮數(shù)據(jù)

  7. 視頻解碼

  8. 關(guān)閉解碼器-〉解碼完成

示例:

+(void) ffmepgVideoDecode:(NSString*)inFilePath outFilePath:(NSString*)outFilePath{

    av_register_all();

    AVFormatContext *avformat_context = avformat_alloc_context();

    const char *url = [inFilePath UTF8String];

    int avformat_open_input_result = avformat_open_input(&avformat_context, url, NULL, NULL);
    if (avformat_open_input_result != 0) {
        NSLog(@"打開文件失斕几臁亡容!");
        return;
    }

    int avformat_find_stream_info_result = avformat_find_stream_info(avformat_context, NULL);
    if (avformat_find_stream_info_result < 0) {
        NSLog(@"查找失斃殴亍!");
        return;
        
    }
    
    int av_stream_index = -1;
    for (int i = 0; i < avformat_context->nb_streams; ++i) {

        if(avformat_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
            av_stream_index = i;
            break;
        }
    }
    
    AVCodecContext *avcodec_context = avformat_context->streams[av_stream_index]->codec;

    AVCodec *avcodec = avcodec_find_decoder(avcodec_context->codec_id);
    int avcodec_open2_result = avcodec_open2(avcodec_context, avcodec, NULL);
    if (avcodec_open2_result != 0) {
        NSLog(@"打開解碼器失斎饪怠!");
        return;
    }
    
    NSLog(@"解碼器名稱:%s",avcodec->name);
    AVPacket *packet = (AVPacket*)av_malloc(sizeof(AVPacket));
    AVFrame *avframe_in = av_frame_alloc();
    int decode_result = -1;
  
    struct SwsContext *swscontext = sws_getContext(avcodec_context->width,
                   avcodec_context->height,
                   avcodec_context->pix_fmt,
                   avcodec_context->width,
                   avcodec_context->height,
                   AV_PIX_FMT_YUV420P,
                   SWS_BICUBIC,
                   NULL,
                   NULL,
                   NULL);
   
    AVFrame *avframe_yuv420p = av_frame_alloc();
    int buffer_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P,
                                               avcodec_context->width,
                                               avcodec_context->height,
                                               1);
   
    uint8_t *out_buffer = (uint8_t*)av_malloc(buffer_size);
    
    av_image_fill_arrays(avframe_yuv420p->data,
                         avframe_yuv420p->linesize,
                         out_buffer,
                         AV_PIX_FMT_YUV420P,
                         avcodec_context->width,
                         avcodec_context->height,
                         1);
    

    int y_size,u_size,v_size;
   
    const char *outfile = [outFilePath UTF8String];
    FILE *file_yuv420p = fopen(outfile, "wb+");
    if (file_yuv420p == NULL) {
        NSLog(@"輸出文件打開失敗");
        return;
    }
    
    int current_index = 0;
    
    while (av_read_frame(avformat_context, packet) >= 0) {
      
        if (packet->stream_index == av_stream_index){
            
        
            avcodec_send_packet(avcodec_context, packet);
           
            decode_result = avcodec_receive_frame(avcodec_context, avframe_in);
            if (decode_result == 0) {
       
                sws_scale(swscontext,
                          (const uint8_t *const *)avframe_in->data,
                          avframe_in->linesize,
                          0,
                          avcodec_context->height,
                          avframe_yuv420p->data,
                          avframe_yuv420p->linesize);
                
     
                y_size = avcodec_context->width * avcodec_context->height;
                u_size = y_size / 4;
                v_size = y_size / 4;
                
                fwrite(avframe_yuv420p->data[0], 1, y_size, file_yuv420p);
                fwrite(avframe_yuv420p->data[1], 1, u_size, file_yuv420p);
                fwrite(avframe_yuv420p->data[2], 1, v_size, file_yuv420p);

                current_index ++;
                NSLog(@"當前解碼第%d幀",current_index);
  
            }
            
        }
    }
   
    av_packet_free(&packet);
    fclose(file_yuv420p);
    av_frame_free(&avframe_in);
    av_frame_free(&avframe_yuv420p);
    free(out_buffer);
    avcodec_close(avcodec_context);
    avformat_free_context(avformat_context);
    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末憔四,一起剝皮案震驚了整個濱河市伐憾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秒际,老刑警劉巖悬赏,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異娄徊,居然都是意外死亡闽颇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門寄锐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兵多,“玉大人,你說我怎么就攤上這事橄仆∈1欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵盆顾,是天一觀的道長怠褐。 經(jīng)常有香客問我,道長您宪,這世上最難降的妖魔是什么惫搏? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蚕涤,結(jié)果婚禮上筐赔,老公的妹妹穿的比我還像新娘。我一直安慰自己揖铜,他們只是感情好茴丰,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般贿肩。 火紅的嫁衣襯著肌膚如雪峦椰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天汰规,我揣著相機與錄音汤功,去河邊找鬼。 笑死溜哮,一個胖子當著我的面吹牛滔金,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播茂嗓,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼餐茵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了述吸?” 一聲冷哼從身側(cè)響起忿族,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝌矛,沒想到半個月后道批,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡入撒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年隆豹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衅金。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖簿煌,靈堂內(nèi)的尸體忽然破棺而出氮唯,到底是詐尸還是另有隱情,我是刑警寧澤姨伟,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布惩琉,位于F島的核電站,受9級特大地震影響夺荒,放射性物質(zhì)發(fā)生泄漏瞒渠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一技扼、第九天 我趴在偏房一處隱蔽的房頂上張望伍玖。 院中可真熱鬧,春花似錦剿吻、人聲如沸窍箍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椰棘。三九已至纺棺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邪狞,已是汗流浹背祷蝌。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帆卓,地道東北人巨朦。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像鳞疲,于是被迫代替她去往敵國和親罪郊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容