用ffmpeg把H264數據流解碼成YUV420P


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

首先是初始化一些參數

[cpp]   view plain copy
  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 plain copy
  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_里面會變成實際視頻的分辨率。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM