houxiao
2017-08-18 7f0053c8f0cd76ecff7f8aee060cd4fd5093b1a3
RtspFace/PL_AndroidMediaCodecDecoder_ndk.cpp
@@ -93,13 +93,18 @@
   internal= nullptr;
}
bool PL_AndroidMediaCodecDecoder::init(void* args)
bool PL_AndroidMediaCodecDecoder::init_codec()
{
   PL_AMCD_Internal* in = (PL_AMCD_Internal*)internal;
   in->reset();
   const PL_AndroidMediaCodecDecoder_Config* config(&(in->config));
   PL_AndroidMediaCodecDecoder_Config* config = (PL_AndroidMediaCodecDecoder_Config*)args;
   in->config = *config;
   if (in->codec != nullptr)
   {
      LOG_ERROR << "codec not null" << LOG_ENDL;
      return false;
   }
   in->auxIsSet = false;
    AMediaFormat* format = AMediaFormat_new();
@@ -148,6 +153,31 @@
//   AMediaFormat_setBuffer(format, "csd-0", sps, sizeof(sps)); // sps
//   AMediaFormat_setBuffer(format, "csd-1", pps, sizeof(pps)); // pps
   if (!in->auxIsSet)
   {
      std::string base64_sps = this->manager->get_param(PLGP_DEC_SPS_B64);
      std::string base64_pps = this->manager->get_param(PLGP_DEC_PPS_B64);
      if ((!base64_sps.empty()) && (!base64_pps.empty()))
      {
         size_t result_sps = 0;
         size_t result_pps = 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_pps);
         char tmp[100] = {0x00,0x00,0x00,0x01,0x00};
         memcpy(tmp + 4, uc_sps, result_sps);
         AMediaFormat_setBuffer(format, "csd-0", tmp, result_sps + 4); // sps
         memcpy(tmp + 4, uc_pps, result_pps);
         AMediaFormat_setBuffer(format, "csd-1", tmp, result_pps + 4); // pps
         in->auxIsSet = true;
         delete[] uc_sps;
         delete[] uc_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}
    const char* fmt =  AMediaFormat_toString(format);
@@ -160,6 +190,9 @@
    ANativeWindow* windowDecode = (ANativeWindow*)config->windowSurfaceDecode;
    if (AMediaCodec_configure(in->codec, format, windowDecode, NULL, 0) != AMEDIA_OK)
   {
      AMediaCodec_delete(in->codec);
      in->codec = nullptr;
      AMediaFormat_delete(format);
        LOG_ERROR << "AMediaCodec_configure error" << LOG_ENDL;
      return false;
@@ -167,6 +200,9 @@
    if (AMediaCodec_start(in->codec) != AMEDIA_OK)
   {
      AMediaCodec_delete(in->codec);
      in->codec = nullptr;
      AMediaFormat_delete(format);
        LOG_ERROR << "AMediaCodec_start error" << LOG_ENDL;
      return false;
@@ -176,14 +212,64 @@
   return true;
}
bool PL_AndroidMediaCodecDecoder::init(void* args)
{
   PL_AMCD_Internal* in = (PL_AMCD_Internal*)internal;
   in->reset();
   PL_AndroidMediaCodecDecoder_Config* config = (PL_AndroidMediaCodecDecoder_Config*)args;
   in->config = *config;
   if (!in->config.initCodecInPay)
      return init_codec();
   return true;
}
void PL_AndroidMediaCodecDecoder::finit()
{
   PL_AMCD_Internal* in = (PL_AMCD_Internal*)internal;
   AMediaCodec_stop(in->codec);
   AMediaCodec_delete(in->codec);
   in->codec = nullptr;
   in->reset();
}
void PL_AndroidMediaCodecDecoder::aux_is_set()
{
   // support only in android-26 (8.0)
#if 0
   PL_AMCD_Internal* in = (PL_AMCD_Internal*)internal;
   if (!in->auxIsSet)
   {
      std::string base64_sps = this->manager->get_param(PLGP_DEC_SPS_B64);
      std::string base64_pps = this->manager->get_param(PLGP_DEC_PPS_B64);
      if((!base64_sps.empty()) && (!base64_pps.empty()))
      {
         size_t result_sps = 0;
         size_t result_pps = 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_pps);
         AMediaFormat* format = AMediaCodec_getOutputFormat(in->codec);
         AMediaFormat_setBuffer(format, "csd-0", uc_sps, result_sps); // sps
         AMediaFormat_setBuffer(format, "csd-1", uc_pps, result_pps); // pps
         AMediaCodec_setParameters(in->codec,format);
         AMediaFormat_delete(format);
         delete[] uc_sps;
         uc_sps = nullptr;
         delete[] uc_pps;
         uc_pps = nullptr;
         in->auxIsSet = true;
      }
   }
#endif
}
bool PL_AndroidMediaCodecDecoder::pay(const PipeMaterial& pm)
@@ -200,34 +286,18 @@
   if (pm.buffer == nullptr)
      return false;
#ifdef 0
   if (!in->auxIsSet)
   if (in->config.initCodecInPay && in->codec == nullptr)
   {
      //#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()))
      if (!init_codec())
        {
            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;
         LOG_ERROR << "init_codec error" << std::endl;
         return false;
        }
   }
#endif
   else
   {
      aux_is_set();
   }
   MB_Frame* frame = (MB_Frame*)pm.buffer;
   if (frame->type != MB_Frame::MBFT_H264_NALU)