houxiao
2017-08-18 7f0053c8f0cd76ecff7f8aee060cd4fd5093b1a3
bug fix for rtsp client

git-svn-id: http://192.168.1.226/svn/proxy@1026 454eff88-639b-444f-9e54-f578c98de674
3个文件已修改
144 ■■■■ 已修改文件
RtspFace/PL_AndroidMediaCodecDecoder.h 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RtspFace/PL_AndroidMediaCodecDecoder_ndk.cpp 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RtspFace/PL_RTSPClient.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
RtspFace/PL_AndroidMediaCodecDecoder.h
@@ -40,6 +40,8 @@
    bool ptsUseAbsoluteTime;
    bool initCodecInPay;
    PL_AndroidMediaCodecDecoder_Config() : 
        ak_height(0), 
        ak_mime(), 
@@ -51,7 +53,9 @@
        releaseOutputBuffIdx(true),
        releaseOutputBuffIdxInPay(false), 
        generateDecodedDataPerFrame(0),
        ptsUseAbsoluteTime(false)
        ptsUseAbsoluteTime(false),
        initCodecInPay(true)
    {}
};
@@ -69,6 +73,9 @@
    
private:
    void* internal;
    void aux_is_set();
    bool init_codec();
};
PipeLineElem* create_PL_AndroidMediaCodecDecoder();
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)
RtspFace/PL_RTSPClient.cpp
@@ -260,15 +260,14 @@
    sprintf(tmp, "%u", param.height); client->manager->set_param(PLGP_RTSP_HEIGHT, std::string(tmp));
    sprintf(tmp, "%u", param.fps); client->manager->set_param(PLGP_RTSP_FPS, std::string(tmp));
    size_t _flag = 0;
    size_t spl = 0;
    if (param.fmtp.find_first_of(',') != std::string::npos)
    {
        //#todo
        // split fmpt to base64 of sps,pps
        // set to PLGP_DEC_SPS_B64 PLGP_DEC_PPS_B64
        _flag = param.fmtp.find_first_of(',');
        std::string _base64_sps = param.fmtp.substr(0,_flag);
        std::string _base64_pps = param.fmtp.substr(_flag,param.fmtp.length());
        spl = param.fmtp.find_first_of(',');
        std::string _base64_sps = param.fmtp.substr(0, spl);
        std::string _base64_pps = param.fmtp.substr(spl + 1, param.fmtp.length());
        client->manager->set_param(PLGP_DEC_SPS_B64,_base64_sps);
        client->manager->set_param(PLGP_DEC_PPS_B64,_base64_pps);
    }