在網上找了很久這方面的內容,發現網上的代碼都太舊了,所使用的函數舊到連最新版本的ffmpeg都已經不包含了,所以對於我這個初學者來說太坑拉。不過經過多次查找ffmpeg的頭文件和結合網上的內容,終於成功可以解碼拉。現在貼出來。
首先是初始化一些參數
- //下面初始化h264解碼庫
- avcodec_init();
- av_register_all();
- AVFrame *pFrame_ = NULL;
- AVCodecContext *codec_ = avcodec_alloc_context();
- /* find the video encoder */
- AVCodec *videoCodec = avcodec_find_decoder(CODEC_ID_H264);
- if (!videoCodec)
- {
- cout << "codec not found!" << endl;
- return -1;
- }
- //初始化參數,下面的參數應該由具體的業務決定
- codec_->time_base.num = 1;
- codec_->frame_number = 1; //每包一個視頻幀
- codec_->codec_type = AVMEDIA_TYPE_VIDEO;
- codec_->bit_rate = 0;
- codec_->time_base.den = 30;//幀率
- codec_->width = 1280;//視頻寬
- codec_->height = 720;//視頻高
- if(avcodec_open(codec_, videoCodec) >= 0)
- pFrame_ = avcodec_alloc_frame();// Allocate video frame
- else
- return -1;
下面是具體的解碼的代碼
- AVPacket packet = {0};
- int frameFinished = dwBufsize;//這個是隨便填入數字,沒什么作用
- packet.data = pBuffer;//這里填入一個指向完整H264數據幀的指針
- packet.size = dwBufsize;//這個填入H264數據幀的大小
- //下面開始真正的解碼
- avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packet);
- if(frameFinished)//成功解碼
- {
- int picSize = codec_->height * codec_->width;
- int newSize = picSize * 1.5;
- //申請內存
- unsigned char *buf = new unsigned char[newSize];
- int height = p->codec->height;
- int width = p->codec->width;
- //寫入數據
- int a=0,i;
- for (i=0; i<height; i++)
- {
- memcpy(buf+a,pFrame_->data[0] + i * pFrame_->linesize[0], width);
- a+=width;
- }
- for (i=0; i<height/2; i++)
- {
- memcpy(buf+a,pFrame_->data[1] + i * pFrame_->linesize[1], width/2);
- a+=width/2;
- }
- for (i=0; i<height/2; i++)
- {
- memcpy(buf+a,pFrame_->data[2] + i * pFrame_->linesize[2], width/2);
- a+=width/2;
- }
- //===============
- //到這里,buf里面已經是yuv420p的數據了,可以對它做任何的處理拉!
- //===============
- delete [] buf;
- }
不過我發現這樣解碼很耗cpu資源,我的Core2 E7400 2.8G的處理器,解碼1920X1080分辨率每秒30幀的視頻時,CPU占用率能用到差不多50%。
PS:原來avcodec_decode_video2這個函數會修改codec_里面的參數的,也就是說如果原來里面填的分別率是1280X720,運行avcodec_decode_video2后codec_里面會變成實際視頻的分辨率。