コード例 #1
0
//------------------------------------------------------------------------------
Archive & Archive::readBuffer(void * buffer,uint64_t len,AsyncFile & archive)
{
  while( len > 0 ){
    int64_t r = read(buffer,len);
    if( r == 0 ){
      int32_t cps; // compressed packet size
      archive.readBuffer(&cps,sizeof(cps));
      if( SHA256Filter::active() ) decrypt(&cps,sizeof(cps));
      if( cps < 0 ){
        rBufSize(-cps);
        archive.readBuffer(rBuf(),-cps);
        if( SHA256Filter::active() ) decrypt(rBuf(),-cps);
      }
      else if( cps >= 0 ){
        AutoPtrBuffer buf;
        buf.alloc(cps);
        archive.readBuffer(buf.ptr() + sizeof(int32_t),cps);
        *(int32_t *) buf.ptr() = cps;
        if( SHA256Filter::active() ) decrypt(buf.ptr() + sizeof(cps),cps - sizeof(cps));
        decompress(buf);
      }
      rBufPos(0);
    }
    buffer = (uint8_t *) buffer + (uintptr_t) r;
    len -= (uintptr_t) r;
  }
  return *this;
}
コード例 #2
0
MBOOL
CamIOPipe::
enqueBuf(PortID const ePortID, QBufInfo const& rQBufInfo)
{
    //FUNCTION_LOG_START;
    //MY_LOGD("QBufInfo:(user, reserved, num)=(%x, %d, %d)", rQBufInfo.u4User, rQBufInfo.u4Reserved, rQBufInfo.vBufInfo.size());
    for (MUINT32 i = 0; i < rQBufInfo.vBufInfo.size(); i++) 
    {
        MY_LOGD("+ tid(%d) type(%d,%d,%d), (VA,PA,Size,ID)(%x, %x, %d, %d)", 
            gettid(), 
            ePortID.type, ePortID.index, ePortID.inout,
            rQBufInfo.vBufInfo.at(i).u4BufVA, rQBufInfo.vBufInfo.at(i).u4BufPA, 
            rQBufInfo.vBufInfo.at(i).u4BufSize, rQBufInfo.vBufInfo.at(i).i4MemID);
    }

    // 
    if (EPortType_MemoryOut != ePortID.type) 
    {
        MY_LOGE("enqueBuf only support memory out port type"); 
        return MFALSE;
    }

    // Note:: can't update config, but address
    //
    NSImageio::NSIspio::QBufInfo rOutBufInfo; 
    NSImageio::NSIspio::PortID rPortID(NSImageio::NSIspio::EPortType_Memory, 
                                       NSImageio::NSIspio::EPortIndex_IMGO, 
                                       1); 

    // 
    if (1 == ePortID.index)      //yuv out buf 
    {
        rPortID.index = NSImageio::NSIspio::EPortIndex_IMG2O; 
    }

    //
    for (MUINT32 i = 0; i < rQBufInfo.vBufInfo.size(); i++) 
    {
         NSImageio::NSIspio::BufInfo rBuf(rQBufInfo.vBufInfo.at(i).u4BufSize, 
                                          rQBufInfo.vBufInfo.at(i).u4BufVA, 
                                          rQBufInfo.vBufInfo.at(i).u4BufPA, 
                                          rQBufInfo.vBufInfo.at(i).i4MemID,
                                          rQBufInfo.vBufInfo.at(i).i4BufSecu,
                                          rQBufInfo.vBufInfo.at(i).i4BufCohe
                                         );  
         rOutBufInfo.vBufInfo.push_back(rBuf);                                                
    }
    //
    mpCamIOPipe->enqueOutBuf(rPortID, rOutBufInfo);         
    //FUNCTION_LOG_END;
    return  MTRUE;
}
コード例 #3
0
/*******************************************************************************
*  Config CamIO Pipe /floria
********************************************************************************/
int
Ts_IT::
startPreview(int count)
{
    MY_LOGD("E");

    MUINT32 u4RawBufSize = (u4SensorWidth * u4SensorHeight * 10) / 8;
    MINT32 ret = 0;

    u4RawBufSize = ((u4RawBufSize + 0xFFF) & ~0xFFF); //align 4k

    /***************************************************
     * Pass 1 : CamIOPipe
     ***************************************************/
    MY_LOGD("ICamIOPipe::createInstance");
    //ICamIOPipe *pCamIOPipe = ICamIOPipe::createInstance(eScenarioID_VSS,//mapScenarioID(meSWScenarioID, ICamIOPipe::ePipeID)
    mpCamIOPipe = ICamIOPipe::createInstance(eScenarioID_VSS, eScenarioFmt_RAW);
    if (NULL == mpCamIOPipe)
    {
        return 0;
    }
    MY_LOGD("Pipe (Name, ID) = (%s, %d)", mpCamIOPipe->getPipeName(), mpCamIOPipe->getPipeId());

    MY_LOGD("mpCamIOPipe->init\n");
    if (!mpCamIOPipe->init())
    {
        MY_LOGD("mpCamIOPipe->init failed");
        return 0;
    }

    mpCamIOPipe->setCallbacks(NULL, NULL, NULL);

    MY_LOGD("setConfigPortInfo");
    if (setConfigPortInfo() == MFALSE)
    {
        goto TEST_EXIT;
    }

    if(vRawMem.size() > 0)
    {
        freeRawMem();
        TS_Thread_UnInit();
    }

    for (int i = 0; i < BUF_NUM; i++)
    {
        IMEM_BUF_INFO rBuf;
        rBuf.size = u4RawBufSize;
        allocMem(rBuf);
        vRawMem.push_back(rBuf);
    }

    for (int i = 0; i < BUF_NUM; i++)
    {
#if 1
        QBufInfo rOutBufInfo;
        PortID rPortID(EPortType_Memory, EPortIndex_IMGO, 1);
        NSImageio::NSIspio::BufInfo rBuf(vRawMem.at(i).size,
             vRawMem.at(i).virtAddr,
             vRawMem.at(i).phyAddr,
             vRawMem.at(i).memID,
             vRawMem.at(i).bufSecu,
             vRawMem.at(i).bufCohe);
        rOutBufInfo.vBufInfo.push_back(rBuf);

        mpCamIOPipe->enqueOutBuf(rPortID, rOutBufInfo);
#else
        rRawBuf.vBufInfo.clear();
        NSCamHW::BufInfo rBufInfo(vRawMem.at(i).size, vRawMem.at(i).virtAddr, vRawMem.at(i).phyAddr, vRawMem.at(i).memID);
        rRawBuf.vBufInfo.push_back(rBufInfo);
        MY_LOGD("enqueBuf(%d)", i);
        if (MFALSE == enqueBuf(NSCamPipe::PortID(NSCamPipe::EPortType_MemoryOut, 0, 1), rRawBuf))
        {
            goto TEST_EXIT;
        }
#endif
    }

    /***************************************************
     * Pass 2 : PostProc
     ***************************************************/
    mpPostProcPipe = IPostProcPipe::createInstance(eScenarioID_VSS, eScenarioFmt_RAW);
    if (NULL == mpPostProcPipe)
    {
        MY_LOGE("mpPostProcPipe create instance fail\n");
        goto TEST_EXIT;
    }
    ret = mpPostProcPipe->init();
    if (!mpPostProcPipe->init())
    {
        MY_LOGE("mpPostProcPipe init fail\n");
        goto TEST_EXIT;
    }

    dispoBuf.size = DISPO_WIDTH*DISPO_HEIGHT*2;
    allocMem(dispoBuf);
    vidoBuf.size = VIDO_WIDTH*VIDO_HEIGHT*2;
    allocMem(vidoBuf);

    ret = mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CQ_CHANNEL,
            (MINT32)NSImageio::NSIspio::EPIPE_PASS2_CQ1,0,0);
    ret = mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CONFIG_STAGE,
            (MINT32)NSImageio::NSIspio::eConfigSettingStage_Init,0,0);
    ret = mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CONFIG_STAGE,
            (MINT32)NSImageio::NSIspio::eConfigSettingStage_UpdateTrigger,0,0);

    start();

    TS_Thread_Init(count);

    if (!mpCamIOPipe->stop())
    {
       MY_LOGE("mpCamIOPipe->stop() fail");
    }

    //MY_LOGD("Preview stop, press to enter to exit");
    //getchar();

TEST_EXIT:

    if (NULL != mpCamIOPipe)
    {
        MY_LOGD("pCamIOPipe->uninit");
        if (MTRUE != mpCamIOPipe->uninit())
        {
            MY_LOGE("pCamIOPipe->uninit fail");
        }
        MY_LOGD("pCamIOPipe->destroyInstance");
        mpCamIOPipe->destroyInstance();
        mpCamIOPipe = NULL;
    }

    if (NULL != mpPostProcPipe)
    {
        if (MTRUE != mpPostProcPipe->uninit())
        {
            MY_LOGE("mpPostProcPipe uninit fail");
        }
        mpPostProcPipe->destroyInstance();
        mpPostProcPipe = NULL;
    }

    if (dispoBuf.size)
    {
        char filename[256];
        sprintf(filename, "/data/IT_%dx%d_dispo.yuv", DISPO_WIDTH, DISPO_HEIGHT);
        saveBufToFile(filename, reinterpret_cast<MUINT8*>(dispoBuf.virtAddr), dispoBuf.size);
        deallocMem(dispoBuf);
    }
    if (vidoBuf.size)
    {
        char filename[256];
        sprintf(filename, "/data/IT_%dx%d_vidio.yuv", VIDO_WIDTH, VIDO_HEIGHT);
        saveBufToFile(filename, reinterpret_cast<MUINT8*>(vidoBuf.virtAddr), vidoBuf.size);
        deallocMem(vidoBuf);
    }

    MY_LOGD("X");

    return 0;
}
コード例 #4
0
MVOID*
Ts_IT::
previewProc(MVOID * arg)
{
    MY_LOGD("E");
    int count = (int)arg, i = 0;
    MINT32 ret = 0;

    //  detach thread => cannot be join
    ::pthread_detach(::pthread_self());

    do
    {
        MY_LOGD("-----------------------------------");
#if 1
        QTimeStampBufInfo rQTimeOutBufInfo, rQTimeOutBufInfoYuv;
        PortID rPortID(EPortType_Memory, EPortIndex_IMGO, 1);

        //mpCamIOPipe->irq(NSImageio::NSIspio::EPipePass_PASS1_TG1,NSImageio::NSIspio::EPIPEIRQ_PATH_DONE);

        MY_LOGD(" mpCamIOPipe->dequeOutBuf(RAW)\n");
        pTestIT->mpCamIOPipe->dequeOutBuf(rPortID, rQTimeOutBufInfo);
        if (rQTimeOutBufInfo.vBufInfo.size() == 0)
        {
            MY_LOGE("Deque imgo buf no buf");
            goto EXIT_DEQ;
        }

        #if 1
        MY_LOGD("Deque buf count : %d", rQTimeOutBufInfo.vBufInfo.size());
        for (i = 0; i < rQTimeOutBufInfo.vBufInfo.size(); i++) {
            MY_LOGD("Deque buf #%d : size(%d), VA(x%x), PA(x%x), memID(%d)", i,
                    rQTimeOutBufInfo.vBufInfo.at(i).u4BufSize,
                    rQTimeOutBufInfo.vBufInfo.at(i).u4BufVA,
                    rQTimeOutBufInfo.vBufInfo.at(i).u4BufPA,
                    rQTimeOutBufInfo.vBufInfo.at(i).memID);
        }
        #endif
        if (pTestIT->mfgIsYUVPortON)
        {
            MY_LOGD(" mpCamIOPipe->dequeOutBuf(YUV)\n");
            rPortID.index = EPortIndex_IMG2O;
            pTestIT->mpCamIOPipe->dequeOutBuf(rPortID, rQTimeOutBufInfoYuv);
            if (rQTimeOutBufInfoYuv.vBufInfo.size() == 0)
            {
                MY_LOGE("Deque imgo buf no buf");
                goto EXIT_DEQ;
            }
        }
#endif

        /*****************************************************
         * Pass 2
         *****************************************************/
        vector<NSImageio::NSIspio::PortInfo const*> vPostProcInPorts;
        vector<NSImageio::NSIspio::PortInfo const*> vPostProcOutPorts;
        NSImageio::NSIspio::PortInfo port_imgi;
        NSImageio::NSIspio::PortInfo port_dispo, port_vido;

        vPostProcInPorts.resize(1);
#if 0 //temp vido
        vPostProcOutPorts.resize(1);
#else
        vPostProcOutPorts.resize(2);
#endif
        //input
        port_imgi.eImgFmt = eImgFmt_BAYER10;
        port_imgi.u4ImgWidth = pTestIT->u4SensorWidth;
        port_imgi.u4ImgHeight = pTestIT->u4SensorHeight;
        port_imgi.u4Stride[0] = pTestIT->u4SensorWidth;
        port_imgi.u4Stride[1] = 0;
        port_imgi.u4Stride[2] = 0;
        port_imgi.u4BufSize = rQTimeOutBufInfo.vBufInfo.at(0).u4BufSize;
        port_imgi.u4BufVA   = rQTimeOutBufInfo.vBufInfo.at(0).u4BufVA;
        port_imgi.u4BufPA   = rQTimeOutBufInfo.vBufInfo.at(0).u4BufPA;
        port_imgi.memID     = rQTimeOutBufInfo.vBufInfo.at(0).memID;
        port_imgi.crop.x = 0;
        port_imgi.crop.y = 0;
        port_imgi.crop.w = pTestIT->u4SensorWidth;
        port_imgi.crop.h = pTestIT->u4SensorHeight;
        port_imgi.u4IsRunSegment = 0;
        port_imgi.type  = NSImageio::NSIspio::EPortType_Memory;
        port_imgi.index = NSImageio::NSIspio::EPortIndex_IMGI;
        port_imgi.inout = NSImageio::NSIspio::EPortDirection_In;
        port_imgi.pipePass = NSImageio::NSIspio::EPipePass_PASS2;
        vPostProcInPorts.at(0) = &port_imgi;
        //output
        port_dispo.eImgFmt = eImgFmt_YUY2;
        port_dispo.u4ImgWidth = DISPO_WIDTH;//pTestIT->u4SensorWidth;
        port_dispo.u4ImgHeight = DISPO_HEIGHT;//pTestIT->u4SensorHeight;
        port_dispo.eImgRot  = NSImageio::NSIspio::eImgRot_0;            //dispo NOT support rotation
        port_dispo.eImgFlip = NSImageio::NSIspio::eImgFlip_OFF;         //dispo NOT support flip
        port_dispo.type     = NSImageio::NSIspio::EPortType_DISP_RDMA;
        port_dispo.index    = NSImageio::NSIspio::EPortIndex_DISPO;
        port_dispo.inout    = NSImageio::NSIspio::EPortDirection_Out;
        port_dispo.u4Stride[0] = DISPO_WIDTH;//pTestIT->u4SensorWidth;
        port_dispo.u4Stride[1] = 0;
        port_dispo.u4Stride[2] = 0;
        port_dispo.u4BufSize = pTestIT->dispoBuf.size;
        port_dispo.u4BufVA  = pTestIT->dispoBuf.virtAddr;
        port_dispo.u4BufPA  = pTestIT->dispoBuf.phyAddr;
        port_dispo.memID    = pTestIT->dispoBuf.memID;
        vPostProcOutPorts.at(0) = &port_dispo;
        //
        port_vido.eImgFmt   = eImgFmt_YUY2;
        port_vido.u4ImgWidth = VIDO_WIDTH;//pTestIT->u4SensorWidth;
        port_vido.u4ImgHeight = VIDO_HEIGHT;//pTestIT->u4SensorHeight;
        port_vido.eImgRot   = NSImageio::NSIspio::eImgRot_0;
        port_vido.eImgFlip  = NSImageio::NSIspio::eImgFlip_OFF;
        port_vido.type      = NSImageio::NSIspio::EPortType_VID_RDMA;
        port_vido.index     = NSImageio::NSIspio::EPortIndex_VIDO;
        port_vido.inout     = NSImageio::NSIspio::EPortDirection_Out;
        port_vido.u4Stride[0] = VIDO_WIDTH;//pTestIT->u4SensorWidth;
        port_vido.u4Stride[1] = 0;
        port_vido.u4Stride[2] = 0;
        port_vido.u4BufSize = pTestIT->vidoBuf.size;
        port_vido.u4BufVA   = pTestIT->vidoBuf.virtAddr;
        port_vido.u4BufPA   = pTestIT->vidoBuf.phyAddr;
        port_vido.memID     = pTestIT->vidoBuf.memID;
#if 1 //temp vido
        vPostProcOutPorts.at(1) = &port_vido;
#endif
        ret = pTestIT->mpPostProcPipe->configPipe(vPostProcInPorts, vPostProcOutPorts);
        if (!ret)
        {
            MY_LOGE("postprocPipe config fail");
            break;
        }
        ///////////////////////////////////////////////////////////
        //enque buffer
        NSImageio::NSIspio::QBufInfo rQBufInfo;

        rPortID.type = EPortType_Memory;
        rPortID.index = EPortIndex_IMGI;
        rPortID.inout = 0;
        for (int i = 0; i < vPostProcInPorts.size(); i++)
        {
            rQBufInfo.vBufInfo.resize(1);
            rQBufInfo.vBufInfo[0].u4BufSize = vPostProcInPorts[i]->u4BufSize; //bytes
            rQBufInfo.vBufInfo[0].u4BufVA = vPostProcInPorts[i]->u4BufVA;
            rQBufInfo.vBufInfo[0].u4BufPA = vPostProcInPorts[i]->u4BufPA;
            rQBufInfo.vBufInfo[0].memID = vPostProcInPorts[i]->memID;
            ret = pTestIT->mpPostProcPipe->enqueInBuf(rPortID, rQBufInfo);
            if (!ret)
            {
                MY_LOGE("postprocPipe enque in buffer fail");
                break;
            }
        }

        for (int i=0; i<vPostProcOutPorts.size(); i++)
        {
            switch(vPostProcOutPorts[i]->index)
            {
            case NSImageio::NSIspio::EPortIndex_VIDO:
                rPortID.type = NSImageio::NSIspio::EPortType_VID_RDMA;
                rPortID.index = NSImageio::NSIspio::EPortIndex_VIDO;
                break;
            case NSImageio::NSIspio::EPortIndex_DISPO:
                rPortID.type = NSImageio::NSIspio::EPortType_DISP_RDMA;
                rPortID.index = NSImageio::NSIspio::EPortIndex_DISPO;
                break;
            case NSImageio::NSIspio::EPortIndex_IMG2O:
            default:
                rPortID.type = NSImageio::NSIspio::EPortType_Memory;
                rPortID.index = NSImageio::NSIspio::EPortIndex_IMG2O;
                break;
            }
            rQBufInfo.vBufInfo.resize(1);
            rQBufInfo.vBufInfo[0].u4BufSize = vPostProcOutPorts[i]->u4BufSize; //bytes
            rQBufInfo.vBufInfo[0].u4BufVA = vPostProcOutPorts[i]->u4BufVA;
            rQBufInfo.vBufInfo[0].u4BufPA = vPostProcOutPorts[i]->u4BufPA;
            rQBufInfo.vBufInfo[0].memID = vPostProcOutPorts[i]->memID;
            ret = pTestIT->mpPostProcPipe->enqueOutBuf(rPortID, rQBufInfo);
            if (!ret)
            {
                MY_LOGE("postprocPipe enque in buffer fail");
                break;
            }
        }
        ///////////////////////////////////////////////////////////
        ret = pTestIT->mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CONFIG_STAGE,
                                      (MINT32)NSImageio::NSIspio::eConfigSettingStage_UpdateTrigger, 0,0);

        //set pass2 IN DMA register before pass2 start
        for(int i=0;i<vPostProcInPorts.size();i++)
        {
            pTestIT->mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CURRENT_BUFFER,
                                  (MINT32)(vPostProcInPorts[i]->index),0,0);
        }
        //set pass2 OUT DMA register before pass2 start
        for(int i=0;i<vPostProcOutPorts.size();i++)
        {
            pTestIT->mpPostProcPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CURRENT_BUFFER,
                                  (MINT32)(vPostProcOutPorts[i]->index),0,0);
        }

        ret = pTestIT->mpPostProcPipe->start();
        if(!ret)
        {
            MY_LOGE("P2 Start Fail!");
            break;
        }

        ///////////////////////////////////////////////////////////
        NSImageio::NSIspio::QTimeStampBufInfo rQTSBufInfo;
        rPortID.type = NSImageio::NSIspio::EPortType_DISP_RDMA;
        rPortID.index = NSImageio::NSIspio::EPortIndex_DISPO;
        ret = pTestIT->mpPostProcPipe->dequeOutBuf(rPortID,rQTSBufInfo);
        if (!ret)
        {
            MY_LOGE("deque dispo out buffer fail,whileeeeee");
            while(1);
            break;
        }
#if 1//temp vido
        rPortID.type = NSImageio::NSIspio::EPortType_VID_RDMA;
        rPortID.index = NSImageio::NSIspio::EPortIndex_VIDO;
        ret = pTestIT->mpPostProcPipe->dequeOutBuf(rPortID,rQTSBufInfo);
        if(!ret)
        {
            MY_LOGI("deque vido out buffer fail,whileeeeee");
            while(1);
            break;
        }
#endif
        rPortID.type = NSImageio::NSIspio::EPortType_Memory;
        rPortID.index = NSImageio::NSIspio::EPortIndex_IMGI;
        ret = pTestIT->mpPostProcPipe->dequeInBuf(rPortID,rQTSBufInfo);
        if(!ret)
        {
            MY_LOGE("deque imgi buffer fail,whileeeeee");
            while(1);
            break;
        }
        ret = pTestIT->mpPostProcPipe->stop();

#if 1
        /*****************************************************
         * Pass 1 Enqueue buffer back
         *****************************************************/
        QBufInfo rOutBufInfo;

        for (MUINT32 i = 0; i < rQTimeOutBufInfo.vBufInfo.size(); i++)
        {
             NSImageio::NSIspio::BufInfo rBuf(rQTimeOutBufInfo.vBufInfo.at(i).u4BufSize,
                     rQTimeOutBufInfo.vBufInfo.at(i).u4BufVA,
                     rQTimeOutBufInfo.vBufInfo.at(i).u4BufPA,
                     rQTimeOutBufInfo.vBufInfo.at(i).memID,
                     rQTimeOutBufInfo.vBufInfo.at(i).bufSecu,
                     rQTimeOutBufInfo.vBufInfo.at(i).bufCohe);
             rOutBufInfo.vBufInfo.push_back(rBuf);
        }

        rPortID.type = EPortType_Memory;
        rPortID.index = EPortIndex_IMGO;
        rPortID.inout = 1;
        pTestIT->mpCamIOPipe->enqueOutBuf(rPortID, rOutBufInfo);

        if (pTestIT->mfgIsYUVPortON)
        {
            QBufInfo rOutBufInfo;
            PortID rPortID(EPortType_Memory, EPortIndex_IMG2O, 1);

            for (MUINT32 i = 0; i < rQTimeOutBufInfoYuv.vBufInfo.size(); i++)
            {
                 NSImageio::NSIspio::BufInfo rBuf(rQTimeOutBufInfoYuv.vBufInfo.at(i).u4BufSize,
                         rQTimeOutBufInfoYuv.vBufInfo.at(i).u4BufVA,
                         rQTimeOutBufInfoYuv.vBufInfo.at(i).u4BufPA,
                         rQTimeOutBufInfoYuv.vBufInfo.at(i).memID,
                         rQTimeOutBufInfoYuv.vBufInfo.at(i).bufSecu,
                         rQTimeOutBufInfoYuv.vBufInfo.at(i).bufCohe);
                 rOutBufInfo.vBufInfo.push_back(rBuf);
            }

            pTestIT->mpCamIOPipe->enqueOutBuf(rPortID, rOutBufInfo);
        }
#else
        if(MFALSE == pTestIT->enqueBuf(NSCamPipe::PortID(NSCamPipe::EPortType_MemoryOut, 0, 1),pTestIT->rRawBuf))
        {
            MY_LOGD("enqueBuf failed");
            break;
        }
#endif
    } while(--count > 0);

EXIT_DEQ:
    MY_LOGD("X");
    MY_LOGD("-----------------------------------");

    pthread_exit(0);

    return NULL;
}