xuxiuxi
2017-05-11 109ffe9a777658936a38d0c146579a67c60a0d17
RtspFace/PL_AVFrameBGRA.cpp
@@ -1,26 +1,31 @@
#include "PL_AVFrameBGRA.h"
#include "MaterialBuffer.h"
#include "logger.h"
extern "C"
{
   #include <libavcodec/avcodec.h>
   #include <libavutil/frame.h>
   #include <libavformat/avformat.h>
   #include <libyuv.h>
}
#include <libyuv.h>
struct PL_AVFrameBGRA_Internal
{
   uint8_t buffer[1920*1080*4];
   uint8_t buffer[1920*1080*4];//#todo from config
   size_t buffSize;
   size_t buffSizeMax;
   AVFormatContext* pAVFormatContext;//#todo delete
   MB_Frame lastFrame;
   bool payError;
   
   PL_AVFrameBGRA_Config config;
   PL_AVFrameBGRA_Internal() : 
      buffSize(0), buffSizeMax(sizeof(buffer)),
      pAVFormatContext(nullptr), payError(true)
      buffSize(0), buffSizeMax(sizeof(buffer)), lastFrame(),
      payError(true),
      config()
   {
   }
   
@@ -32,6 +37,12 @@
   {
      buffSize = 0;
      payError = true;
      MB_Frame _lastFrame;
      lastFrame = _lastFrame;
      PL_AVFrameBGRA_Config _config;
      config = _config;
   }
};
@@ -54,9 +65,13 @@
{
   PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
   in->reset();
   in->pAVFormatContext = avformat_alloc_context();
   
   if (args != nullptr)
   {
      PL_AVFrameBGRA_Config* _config = (PL_AVFrameBGRA_Config*)args;
      in->config = *_config;
   }
   return true;
}
@@ -66,37 +81,118 @@
   
}
#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
bool PL_AVFrameBGRA::pay(const PipeMaterial& pm)
{
#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
   PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
   
   AVFrame* pAVFrame = (AVFrame*)pm.buffer;
   if (pAVFrame == nullptr)
   if (pm.type != PipeMaterial::PMT_FRAME)
   {
      LOG_ERROR << "Only support PMT_FRAME" << std::endl;
      return false;
   int height = pAVFrame->height;
   int width = pAVFrame->width;
   }
   if (pm.buffer == nullptr)
      return false;
   int src_height = 0;
   int src_width = 0;
   const uint8* src_y = nullptr;
   const uint8* src_u = nullptr;
    const uint8* src_v = nullptr;
   MB_Frame* frame = (MB_Frame*)pm.buffer;
   if (frame->type == MB_Frame::MBFT_PTR_AVFRAME)
   {
      AVFrame* pAVFrame = (AVFrame*)frame->buffer;
      if (pAVFrame == nullptr)
         return false;
      src_height = pAVFrame->height;
      src_width = pAVFrame->width;
      src_y = pAVFrame->data[0];
      src_u = pAVFrame->data[1];
      src_v = pAVFrame->data[2];
   }
   if (frame->type == MB_Frame::MBFT_YUV420)
   {
      if (frame->buffer == nullptr)
         return false;
      src_height = frame->height;
      src_width = frame->width;
      src_y = (const uint8*)(frame->buffer);
      src_u = (const uint8*)(src_y + (src_height * src_width));
      src_v = (const uint8*)(src_u + (src_height * src_width / 4));
   }
   else
   {
      LOG_ERROR << "Only support MBFT_PTR_AVFRAME" << std::endl;
      return false;
   }
//int I420ToBGRA(const uint8* src_y, int src_stride_y,
//               const uint8* src_u, int src_stride_u,
//               const uint8* src_v, int src_stride_v,
//               uint8* dst_argb, int dst_stride_argb,
//            int width, int height);
//            int width, int src_height);
   libyuv::I420ToBGRA(pAVFrame->data[0], width,
                  pAVFrame->data[1], SUBSAMPLE(width, 2),
                  pAVFrame->data[2], SUBSAMPLE(width, 2),
                  in->buffer, 4 * width,
                  width, height);
   if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_BGRA8888)
   {
      libyuv::I420ToBGRA(src_y, src_width,
                     src_u, SUBSAMPLE(src_width, 2),
                     src_v, SUBSAMPLE(src_width, 2),
                     in->buffer, 4 * src_width,
                     src_width, src_height);
   in->buffSize = in->buffSizeMax;
      in->buffSize = src_width * src_height * 4; // #todo use ret value?
   }
   else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB8888)
   {
      libyuv::I420ToARGB(src_y, src_width,
                     src_u, SUBSAMPLE(src_width, 2),
                     src_v, SUBSAMPLE(src_width, 2),
                     in->buffer, 4 * src_width,
                     src_width, src_height);
      in->buffSize = src_width * src_height * 4; // #todo use ret value?
   }
   else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_RGBA8888)
   {
      libyuv::I420ToRGBA(src_y, src_width,
                     src_u, SUBSAMPLE(src_width, 2),
                     src_v, SUBSAMPLE(src_width, 2),
                     in->buffer, 4 * src_width,
                     src_width, src_height);
      in->buffSize = src_width * src_height * 4; // #todo use ret value?
   }
   else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB4444)
   {
   }
   else
   {
      LOG_ERROR << "PL_AVFrameBGRA_Config.convertTo not support" << std::endl;
      return false;
   }
   //in->buffer readly
   in->lastFrame.type = MB_Frame::MBFT_BGRA;
   in->lastFrame.buffer = in->buffer;
   in->lastFrame.buffSize = in->buffSize;
   in->lastFrame.width = src_width;
   in->lastFrame.height = src_height;
   in->lastFrame.pts = frame->pts;
   //#test
   static size_t f=0;
   char fname[50];
   sprintf(fname, "%u.bgra", ++f);
   sprintf(fname, "%u.rgba", ++f);
   FILE * pFile = fopen (fname,"wb");
   fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
   fclose(pFile);
@@ -108,8 +204,9 @@
{
   PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
   pm.buffer = in->buffer;
   pm.buffSize = in->buffSize;
   pm.type = PipeMaterial::PMT_FRAME;
   pm.buffer = &(in->lastFrame);
   pm.buffSize = 0;
   pm.former = this;
   return true;
}