<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    用ffmpeg把H264數據流解碼成YUV420P

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    在網上找了很久這方面的內容,發現網上的代碼都太舊了,所使用的函數舊到連最新版本的ffmpeg都已經不包含了,所以對于我這個初學者來說太坑拉。不過經過多次查找ffmpeg的頭文件和結合網上的內容,終于成功可以解碼拉。現在貼出來。

    首先是初始化一些參數

    [cpp] view plaincopy
    1. //下面初始化h264解碼庫  
    2. avcodec_init();  
    3. av_register_all();  
    4.   
    5. AVFrame *pFrame_ = NULL;  
    6.   
    7. AVCodecContext *codec_ = avcodec_alloc_context();  
    8.   
    9. /* find the video encoder */  
    10. AVCodec *videoCodec = avcodec_find_decoder(CODEC_ID_H264);  
    11.   
    12. if (!videoCodec)   
    13. {  
    14.     cout << "codec not found!" << endl;  
    15.     return -1;  
    16. }  
    17.   
    18. //初始化參數,下面的參數應該由具體的業務決定  
    19. codec_->time_base.num = 1;  
    20. codec_->frame_number = 1; //每包一個視頻幀  
    21. codec_->codec_type = AVMEDIA_TYPE_VIDEO;  
    22. codec_->bit_rate = 0;  
    23. codec_->time_base.den = 30;//幀率  
    24. codec_->width = 1280;//視頻寬  
    25. codec_->height = 720;//視頻高  
    26.   
    27. if(avcodec_open(codec_, videoCodec) >= 0)  
    28.     pFrame_ = avcodec_alloc_frame();// Allocate video frame  
    29. else  
    30.     return -1;  

    下面是具體的解碼的代碼

    [cpp] view plaincopy
    1. AVPacket packet = {0};  
    2. int frameFinished = dwBufsize;//這個是隨便填入數字,沒什么作用  
    3.   
    4. packet.data = pBuffer;//這里填入一個指向完整H264數據幀的指針  
    5. packet.size = dwBufsize;//這個填入H264數據幀的大小  
    6.   
    7. //下面開始真正的解碼  
    8. avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);  
    9. if(frameFinished)//成功解碼  
    10. {  
    11.     int picSize = codec_->height * codec_->width;  
    12.     int newSize = picSize * 1.5;  
    13.   
    14.     //申請內存  
    15.     unsigned char *buf = new unsigned char[newSize];  
    16.   
    17.     int height = p->codec->height;  
    18.     int width = p->codec->width;  
    19.   
    20.   
    21.     //寫入數據  
    22.     int a=0,i;   
    23.     for (i=0; i<height; i++)   
    24.     {   
    25.         memcpy(buf+a,pFrame_->data[0] + i * pFrame_->linesize[0], width);   
    26.         a+=width;   
    27.     }   
    28.     for (i=0; i<height/2; i++)   
    29.     {   
    30.         memcpy(buf+a,pFrame_->data[1] + i * pFrame_->linesize[1], width/2);   
    31.         a+=width/2;   
    32.     }   
    33.     for (i=0; i<height/2; i++)   
    34.     {   
    35.         memcpy(buf+a,pFrame_->data[2] + i * pFrame_->linesize[2], width/2);   
    36.         a+=width/2;   
    37.     }  
    38.   
    39.     //===============  
    40.     //到這里,buf里面已經是yuv420p的數據了,可以對它做任何的處理拉!  
    41.     //===============  
    42.     delete [] buf;  
    43. }  


    不過我發現這樣解碼很耗cpu資源,我的Core2  E7400 2.8G的處理器,解碼1920X1080分辨率每秒30幀的視頻時,CPU占用率能用到差不多50%。


    PS:原來avcodec_decode_video2這個函數會修改codec_里面的參數的,也就是說如果原來里面填的分別率是1280X720,運行avcodec_decode_video2后codec_里面會變成實際視頻的分辨率。


    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全