• (转)使用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);
  • 相关阅读:
    springMvc接口请求参数
    ThreadLocal 结构
    遇到的问题
    jsonview的安装
    Java
    学习资源
    Java
    Java
    Java
    Java
  • 原文地址:https://www.cnblogs.com/billcoco/p/2553948.html
Copyright © 2020-2023  润新知