ffmpeg把H264数据流解码成YUV420P

整理了一下使用ffmpeg将H264数据流解码成YUV420p的代码块:

1、初始化一些参数

  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;  


2、具体的解码的代码

  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
  24.     {   
  25.         memcpy(buf+a,pFrame_->data[0] + i * pFrame_->linesize[0], width);   
  26.         a+=width;   
  27.     }   
  28.     for (i=0; 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
  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资源,原来avcodec_decode_video2这个函数会修改codec_里面的参数的,也就是说如果原来里面填的分别率是1280X720,运行avcodec_decode_video2后codec_里面会变成实际视频的分辨率。


你可能感兴趣的:(音视频编解码)