使用FFMpeg进行H264编码

使用FFMpeg可以很方便的对音视频进行编码,并且写文件。

    下面的代码是将5幅1280*720大小的图片进行编码,并且写到文件中。

    代码有些乱,但希望能抛砖引玉,对学习这方面的朋友有帮助。

  1. CFile file[5];  
  2. BYTE *szTxt[5];  
  3.   
  4. int nWidth = 0;  
  5. int nHeight= 0;  
  6.   
  7. int nDataLen=0;  
  8.   
  9. int nLen;  
  10.   
  11. CString csFileName;  
  12. for (int fileI = 1; fileI <= 5; fileI ++)  
  13. {  
  14.   csFileName.Format("e:\\pics\\%d.bmp", fileI);  
  15.   file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);  
  16.   nLen = file[fileI - 1].GetLength();  
  17.   
  18.   szTxt[fileI -1] = new BYTE[nLen];  
  19.   file[fileI - 1].Read(szTxt[fileI - 1], nLen);  
  20.   file[fileI - 1].Close();  
  21.   
  22.   //BMP bmi;//BITMAPINFO bmi;  
  23.   //int nHeadLen = sizeof(BMP);  
  24.   BITMAPFILEHEADER bmpFHeader;  
  25.   BITMAPINFOHEADER bmpIHeader;  
  26.   memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));  
  27.   
  28.   int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);  
  29.   memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);  
  30.   
  31. nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;  
  32.   nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;  
  33.   
  34.   szTxt[fileI - 1] += bmpFHeader.bfOffBits;  
  35.   nDataLen = nLen-bmpFHeader.bfOffBits;  
  36. }  
  37.   
  38. av_register_all();  
  39. avcodec_register_all();  
  40. AVFrame *m_pRGBFrame =  new AVFrame[1];  //RGB帧数据    
  41. AVFrame *m_pYUVFrame = new AVFrame[1];;  //YUV帧数据  
  42. AVCodecContext *c= NULL;  
  43. AVCodecContext *in_c= NULL;  
  44. AVCodec *pCodecH264; //编码器  
  45. uint8_t * yuv_buff;//  
  46.   
  47. //查找h264编码器  
  48. pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);  
  49. if(!pCodecH264)  
  50. {  
  51.   fprintf(stderr, "h264 codec not found\n");  
  52.   exit(1);  
  53. }  
  54.   
  55. c= avcodec_alloc_context3(pCodecH264);  
  56. c->bit_rate = 3000000;// put sample parameters   
  57. c->width =nWidth;//   
  58. c->height = nHeight;//   
  59.   
  60. // frames per second   
  61. AVRational rate;  
  62. rate.num = 1;  
  63. rate.den = 25;  
  64. c->time_base= rate;//(AVRational){1,25};  
  65. c->gop_size = 10; // emit one intra frame every ten frames   
  66. c->max_b_frames=1;  
  67. c->thread_count = 1;  
  68. c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;  
  69.   
  70. //av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);  
  71. //打开编码器  
  72. if(avcodec_open2(c,pCodecH264,NULL)<0)  
  73.   TRACE("不能打开编码库");  
  74.   
  75. int size = c->width * c->height;  
  76.   
  77. yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420   
  78.   
  79. //将rgb图像数据填充rgb帧  
  80. uint8_t * rgb_buff = new uint8_t[nDataLen];  
  81.   
  82. //图象编码  
  83. int outbuf_size=100000;  
  84. uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);   
  85. int u_size = 0;  
  86. FILE *f=NULL;   
  87. char * filename = "e:\\pics\\myData.h264";  
  88. f = fopen(filename, "wb");  
  89. if (!f)  
  90. {  
  91.   TRACE( "could not open %s\n", filename);  
  92.   exit(1);  
  93. }  
  94.   
  95. //初始化SwsContext  
  96. SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);  
  97.   
  98. AVPacket avpkt;  
  99.   
  100. //AVFrame *pTFrame=new AVFrame  
  101. for (int i=0;i<250;++i)  
  102. {  
  103.   
  104.   //AVFrame *m_pYUVFrame = new AVFrame[1];  
  105.     
  106.   int index = (i / 25) % 5;  
  107.   memcpy(rgb_buff,szTxt[index],nDataLen);  
  108.   
  109.   avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);  
  110.     
  111.   //将YUV buffer 填充YUV Frame  
  112.   avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);  
  113.   
  114.   // 翻转RGB图像  
  115.   m_pRGBFrame->data[0]  += m_pRGBFrame->linesize[0] * (nHeight - 1);  
  116.   m_pRGBFrame->linesize[0] *= -1;                     
  117.   m_pRGBFrame->data[1]  += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);  
  118.   m_pRGBFrame->linesize[1] *= -1;  
  119.   m_pRGBFrame->data[2]  += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);  
  120.   m_pRGBFrame->linesize[2] *= -1;  
  121.   
  122.   
  123.   //将RGB转化为YUV  
  124.   sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);  
  125.     
  126.   int got_packet_ptr = 0;  
  127.   av_init_packet(&avpkt);  
  128.   avpkt.data = outbuf;  
  129.   avpkt.size = outbuf_size;  
  130.   u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);  
  131.   if (u_size == 0)  
  132.   {  
  133.    fwrite(avpkt.data, 1, avpkt.size, f);  
  134.   }  
  135. }  
  136.   
  137. fclose(f);   
  138. delete []m_pRGBFrame;  
  139. delete []m_pYUVFrame;  
  140. delete []rgb_buff;  
  141. free(outbuf);  
  142. avcodec_close(c);  
  143. av_free(c);  

原文地址:https://www.cnblogs.com/zjoch/p/3090036.html