在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉。不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成功可以解码拉。现在贴出来。
首先是初始化一些参数
- avcodec_init();
- av_register_all();
-
- AVFrame *pFrame_ = NULL;
-
- AVCodecContext *codec_ = avcodec_alloc_context();
-
- 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();
- else
- return -1;
下面是具体的解码的代码
- AVPacket packet = {0};
- int frameFinished = dwBufsize;
-
- packet.data = pBuffer;
- packet.size = dwBufsize;
-
- 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;
- }
-
-
-
-
- delete [] buf;
- }
不过我发现这样解码很耗cpu资源,我的Core2 E7400 2.8G的处理器,解码1920X1080分辨率每秒30帧的视频时,CPU占用率能用到差不多50%。
PS:原来avcodec_decode_video2这个函数会修改codec_里面的参数的,也就是说如果原来里面填的分别率是1280X720,运行avcodec_decode_video2后codec_里面会变成实际视频的分辨率。
用ffmpeg把H264数据流解码成YUV420P
原文:http://www.cnblogs.com/lidabo/p/4582387.html