您的位置:首页 > 其它

用ffmpeg把H264数据流解码成YUV420P

2014-11-04 10:31 435 查看
在网上找了很久这方面的内容,发现网上的代码都太旧了,所使用的函数旧到连最新版本的ffmpeg都已经不包含了,所以对于我这个初学者来说太坑拉。不过经过多次查找ffmpeg的头文件和结合网上的内容,终于成功可以解码拉。现在贴出来。

首先是初始化一些参数

[cpp]
view plaincopy

//下面初始化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;  

下面是具体的解码的代码

[cpp]
view plaincopy

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后[b]codec_里面会变成实际视频的分辨率。[/b]

[/b]

[b]转自:[b]http://blog.csdn.net/vheavens/article/details/7528463

[/b][/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: