houxiao
2016-12-28 4ef430e946e717d72e923c4708a9120f94d55dbd
RtspFace/PL_H264Encoder.cpp
@@ -19,11 +19,13 @@
   AVCodecContext* pAVCodecContext;
   AVFrame* pAVFrame;//#todo delete
   AVStream* pAVStream;
   AVFormatContext* pAVFormatContext;
   
   H264Encoder_Internal() : 
      buffSize(0), buffSizeMax(sizeof(buffer)), 
      payError(true), ffmpegInited(false), frameCount(0), 
      pAVCodecContext(nullptr), pAVFrame(nullptr)
      pAVCodecContext(nullptr), pAVFrame(nullptr), pAVStream(nullptr), pAVFormatContext(nullptr)
      
   {
   }
@@ -41,6 +43,8 @@
      
      pAVCodecContext = nullptr;
      pAVFrame = nullptr;
      pAVStream = nullptr;
      pAVFormatContext = nullptr;
   }
};
@@ -88,7 +92,7 @@
   in->pAVCodecContext = avcodec_alloc_context3(avCodec);
   in->pAVCodecContext->bit_rate = 3*1024*1024*8; // 3MB
   in->pAVCodecContext->bit_rate = 1*1024*1024*8; // 3MB
    in->pAVCodecContext->width = 1920;
    in->pAVCodecContext->height = 1080;//#todo from config
    in->pAVCodecContext->time_base.num=1;
@@ -96,6 +100,9 @@
    in->pAVCodecContext->gop_size = 20;
    in->pAVCodecContext->max_b_frames = 0;
    in->pAVCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
   //av_opt_set(c->priv_data, "preset", "superfast", 0);
   //av_opt_set(c->priv_data, "tune", "zerolatency", 0);
   if(avcodec_open2(in->pAVCodecContext, avCodec, NULL) >= 0)
   {
@@ -119,17 +126,36 @@
      return false;
   }
   
   //int ret = avformat_alloc_output_context2(&(in->pAVFormatContext), NULL, "avi", "");
   //if (ret < 0 || in->pAVFormatContext == nullptr)
   //{
   //   printf("avformat_alloc_output_context2 error\n");
   //   return false;
   //}
   //
   //in->pAVStream = avformat_new_stream(in->pAVFormatContext, avCodec);
   //if (in->pAVStream == nullptr)
   //{
   //   printf("avformat_new_stream error\n");
   //   return false;
   //}
   //in->pAVStream->id = in->pAVFormatContext->nb_streams-1;
   return true;
}
void copyAVFrame(AVFrame* dest, AVFrame* src)
{
   int height = dest->height;
   int width = dest->width;
   dest->data[0] = src->data[0];
   dest->data[1] = src->data[1];
   dest->data[2] = src->data[2];
   
   memcpy(dest->data[0], src->data[0], height * width); // Y
   memcpy(dest->data[1], src->data[1], height * width / 4); // U
   memcpy(dest->data[2], src->data[2], height * width / 4); // V
   //int height = dest->height;
   //int width = dest->width;
   //
   //memcpy(dest->data[0], src->data[0], height * width); // Y
   //memcpy(dest->data[1], src->data[1], height * width / 4); // U
   //memcpy(dest->data[2], src->data[2], height * width / 4); // V
}
bool encodeH264(H264Encoder_Internal* in, AVFrame* pAVFrame, size_t buffSize)  
@@ -138,13 +164,16 @@
   in->frameCount++;
   copyAVFrame(in->pAVFrame, pAVFrame);
   in->pAVFrame->pts = in->frameCount;
   //in->pAVFrame->pts = (1.0 / 25) * 90000 * in->frameCount;
   in->pAVFrame->pts = time(nullptr);
   AVPacket pAVPacket = {0};
   av_init_packet(&pAVPacket);
   // encode the image
   int gotPacket = 0;
   int ret = avcodec_encode_video2(in->pAVCodecContext, &pAVPacket, in->pAVFrame, &gotPacket);  
   if (ret < 0)
   {
@@ -154,9 +183,9 @@
   
   if (gotPacket > 0)
   {
      printf("Succeed to encode (1) frame=%d, size=%d\n", in->pAVFrame->pts, pAVPacket.size);
      memcpy(in->buffer + in->buffSize, pAVPacket.data, pAVPacket.size);
      in->buffSize += pAVPacket.size;
      printf("Succeed to encode (1) frame=%d, size=%d\n", in->frameCount, pAVPacket.size);
      memcpy(in->buffer, pAVPacket.data, pAVPacket.size);
      in->buffSize = pAVPacket.size;
      av_free_packet(&pAVPacket);
   }
   
@@ -172,12 +201,13 @@
   //   }  
   //   if (gotPacket > 0)
   //   {  
   //      printf("Succeed to encode (2) frame=%d, size=%d\n", in->pAVFrame->pts, pAVPacket.size);
   //      printf("Succeed to encode (2) frame=%d, size=%d\n", in->frameCount, pAVPacket.size);
   //      memcpy(in->buffer + in->buffSize, pAVPacket.data, pAVPacket.size);
   //      in->buffSize += pAVPacket.size; 
   //      av_free_packet(&pAVPacket);  
   //   }  
   //}
   //}
   
   //#test
   if (in->buffSize > 0)
@@ -186,7 +216,7 @@
      fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
      fflush(pFile);
   }
   in->payError = (in->buffSize == 0);
   return !(in->payError);
}