houxiao
2017-08-17 6faf88ba05f174a80c68f01c0412cae9789dbc8c
RtspFace/PL_AndroidMediaCodecDecoder_ndk.cpp
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <liveMedia/liveMedia.hh>
// see: https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities.html#COLOR_FormatYUV420Flexible
#define AMEDIA_COLOR_FormatYUV420Flexible 0x7f420888
#define AMEDIA_COLOR_FormatYUV420Planar 0x00000013 // 19, I420
@@ -38,12 +39,15 @@
   AMediaCodec* codec;
   bool auxIsSet;
   PL_AMCD_Internal() : 
      buffSize(0), buffSizeMax(sizeof(buffer)), 
      inputFrameCount(0), lastOutputBuffIdx(-1), 
      lastMbfBuffIdx(), lastMbfBuffer(),
      config(), 
      codec(nullptr)
      codec(nullptr),
      auxIsSet(false)
   {
   }
   
@@ -53,6 +57,7 @@
   
   void reset()
   {
        auxIsSet = false;
      buffSize = 0;
      
      inputFrameCount = 0;
@@ -134,12 +139,14 @@
        AMediaFormat_setBuffer(format, "csd-0", sps.sPropBytes, sps.sPropLength); // sps
        AMediaFormat_setBuffer(format, "csd-1", pps.sPropBytes, pps.sPropLength); // pps
        //uint8_t sps[] = {0x0,0x0,0x0,0x1, 0x67, 0x42, 0x00, 0x2A, 0x95, 0xA8, 0x1E, 0x00, 0x89, 0xF9, 0x61, 0x00, 0x00, 0x07, 0x08, 0x00, 0x01, 0x5F, 0x90, 0x04};
        //uint8_t pps[] = {0x0,0x0,0x0,0x1, 0x68, 0xCE, 0x3C, 0x80};
        //AMediaFormat_setBuffer(format, "csd-0", sps, sizeof(sps)); // sps
        //AMediaFormat_setBuffer(format, "csd-1", pps, sizeof(pps)); // pps
    */
   // J0LgKI1oCgPaEAAAAwAQAAADAoDxB6gA,KM4ySA==
//   uint8_t sps[] = {0x27,0x42,0xe0,0x28,0x8d,0x68,0x0a,0x03,0xda,0x10,0x00,0x00,0x03,0x00,0x10,0x00,0x00,0x03,0x02,0x80,0xf1,0x07,0xa8,0x00};
//   uint8_t pps[] = {0x28,0xce,0x32,0x48};
//   AMediaFormat_setBuffer(format, "csd-0", sps, sizeof(sps)); // sps
//   AMediaFormat_setBuffer(format, "csd-1", pps, sizeof(pps)); // pps
    // should like:
    // mime: string(video/avc), durationUs: int64(10000000), width: int32(480), height: int32(360), max-input-size: int32(55067), csd-0: data, csd-1: data}
@@ -172,8 +179,11 @@
void PL_AndroidMediaCodecDecoder::finit()
{
   PL_AMCD_Internal* in = (PL_AMCD_Internal*)internal;
   //todo release codec
   // call AMediaCodec_stop
   AMediaCodec_stop(in->codec);
   AMediaCodec_delete(in->codec);
   in->reset();
}
bool PL_AndroidMediaCodecDecoder::pay(const PipeMaterial& pm)
@@ -189,13 +199,46 @@
   
   if (pm.buffer == nullptr)
      return false;
#ifdef 0
   if (!in->auxIsSet)
   {
      //#todo
        std::string base64_sps = this->manager->get_param(PLGP_DEC_SPS_B64);
        std::string base64_pps = this->manager->get_param(PLGP_DEC_PPS_B64);
      // find PLGP_DEC_SPS_B64 PLGP_DEC_PPS_B64 in this->manager else nothing
      // base64 decode
        if((!base64_sps.empty())
           &&(!base64_pps.empty()))
        {
            size_t result_sps = 0;
            size_t result_ps = 0;
            uint8_t* uc_sps = base64_decode(base64_sps.c_str(),base64_sps.length(),result_sps);
            uint8_t* uc_pps = base64_decode(base64_pps.c_str(),base64_pps.length(),result_ps);
            AMediaFormat* format = AMediaCodec_getOutputFormat(in->codec);
            AMediaFormat_setBuffer(format, "csd-0", uc_sps, result_sps); // sps
            AMediaFormat_setBuffer(format, "csd-1", uc_pps, result_sps); // pps
            AMediaCodec_setParameters(in->codec,format);
            // #todo delete format
            AMediaFormat_delete(format);
            in->auxIsSet = true;
        }
   }
#endif
   MB_Frame* frame = (MB_Frame*)pm.buffer;
   if (frame->type != MB_Frame::MBFT_H264_NALU)
   {
      LOG_ERROR << "Only support MBFT_H264_NALU" << std::endl;
      return false;
   }
//   static FILE *pFile = fopen("/data/bb.264", "wb");
//   fwrite(frame->buffer, sizeof(char), frame->buffSize, pFile);
//   fflush(pFile);
    ssize_t bufidx = AMediaCodec_dequeueInputBuffer(in->codec, 2000);
    LOGP(DEBUG, "input buffer bufidx=%zd, inputFrameCount=%d", bufidx, in->inputFrameCount++);
@@ -340,7 +383,11 @@
                in->lastMbfBuffer.buffSize = in->buffSize;
                in->lastMbfBuffer.width = in->config.ak_width;
                in->lastMbfBuffer.height = in->config.ak_height;
                microseconds_to_timeval(info.presentationTimeUs, in->lastMbfBuffer.pts);
            if (in->config.ptsUseAbsoluteTime)
               gettimeofday(&(in->lastMbfBuffer.pts), nullptr);
            else
               microseconds_to_timeval(info.presentationTimeUs, in->lastMbfBuffer.pts);
                //if (in->lastMbfBuffer.buffSize > 10)
            //{