zoukankan      html  css  js  c++  java
  • 使用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);  

  • 相关阅读:
    数据库-自定义函数
    数据库-存储过程
    数据库配置
    水电费管理系统需求分析与设计_待完善
    SQL中Group By的使用
    部分查询功能语句
    10-11数据库练习
    Oracle-SQL
    开发环境之Gradle
    解决程序端口占用
  • 原文地址:https://www.cnblogs.com/zjoch/p/3090036.html
Copyright © 2011-2022 走看看