MBOOL MultiShotCc:: onCreateImage() { FUNCTION_LOG_START; AutoCPTLog cptlog(Event_MShot_onCreateImage); MUINT32 u4ShotCount = 0; // mpJpegImageCreateThread->postCommand(Command(Command::eID_YUV_BUF)); // move in jpeg create CPTLogStr(Event_MShot_onCreateImage, CPTFlagSeparator, "callback EOF"); handleNotifyCallback(ECamShot_NOTIFY_MSG_EOF, 0, 0); // loop, trigger jpeg create while(u4ShotCount<mu4ShotCount) { CPTLogStr(Event_MShot_onCreateImage, CPTFlagSeparator, "wait jpeg done"); ::sem_wait(&semJpeg); CPTLogStr(Event_MShot_onCreateImage, CPTFlagSeparator, "handle callback"); if(mbIsLastShot || u4ShotCount==mu4ShotCount-1) // last frame { MY_LOGD("notify last shot will callback"); handleNotifyCallback(ECamShot_NOTIFY_MSG_CSHOT_END, 0, 0); handleNotifyCallback(ECamShot_NOTIFY_MSG_FOCUS_VALUE, mFocusVal.u4ValH, mFocusVal.u4ValL); handleDataCallback(ECamShot_DATA_MSG_JPEG, (mThumbImgBufInfoReady.u4BufVA), mu4ThumbnailSize, reinterpret_cast<MUINT8*>(mJpegImgBufInfoReady.u4BufVA), mu4JpegSize); break; } else // create next jpeg { // trigger next jpeg create // mpJpegImageCreateThread->postCommand(Command(Command::eID_YUV_BUF)); handleNotifyCallback(ECamShot_NOTIFY_MSG_EOF, 0, 0); handleNotifyCallback(ECamShot_NOTIFY_MSG_FOCUS_VALUE, mFocusVal.u4ValH, mFocusVal.u4ValL); handleDataCallback(ECamShot_DATA_MSG_JPEG, (mThumbImgBufInfoReady.u4BufVA), mu4ThumbnailSize, reinterpret_cast<MUINT8*>(mJpegImgBufInfoReady.u4BufVA), mu4JpegSize); u4ShotCount++; } } // (7) start end CPTLogStr(Event_MShot_start, CPTFlagSeparator, "post start end sem"); ::sem_post(&semStartEnd); FUNCTION_LOG_END; return MTRUE; }
MBOOL CamIOPipe:: dequeBuf(PortID const ePortID, QTimeStampBufInfo& rQBufInfo, MUINT32 const u4TimeoutMs /*= 0xFFFFFFFF*/) { //FUNCTION_LOG_START; MY_LOGD("+ tid(%d) type(%d, %d, %d, %d)", gettid(), ePortID.type, ePortID.index, ePortID.inout, u4TimeoutMs); // // (1) check if the buffer already dequeue // (2) if the buffer is not dequeue, dequeue from HW. QTimeStampBufInfo *pQTBufInfo = NULL; if (0 == ePortID.index) { pQTBufInfo = &mrRawQTBufInfo; } else { if (!mfgIsYUVPortON) { MY_LOGE("The YUV por is not on \n"); return MFALSE; } pQTBufInfo = &mrYuvQTBufInfo; } if (pQTBufInfo->vBufInfo.size() == 0) { dequeHWBuf(u4TimeoutMs); } // rQBufInfo.u4User = pQTBufInfo->u4User; rQBufInfo.u4Reserved = pQTBufInfo->u4Reserved; rQBufInfo.i4TimeStamp_sec = pQTBufInfo->i4TimeStamp_sec; rQBufInfo.i4TimeStamp_us = pQTBufInfo->i4TimeStamp_us; for (MUINT32 i = 0; i < pQTBufInfo->vBufInfo.size(); i++) { BufInfo rBufInfo(pQTBufInfo->vBufInfo.at(i).u4BufSize, pQTBufInfo->vBufInfo.at(i).u4BufVA, pQTBufInfo->vBufInfo.at(i).u4BufPA, pQTBufInfo->vBufInfo.at(i).i4MemID); rQBufInfo.vBufInfo.push_back(rBufInfo); } pQTBufInfo->vBufInfo.clear(); for (MUINT32 i = 0; i < rQBufInfo.vBufInfo.size(); i++) { MY_LOGD("(VA,PA,Size,ID)(0x%x,0x%x,%d,%d), ts(%d.%06d)", rQBufInfo.vBufInfo.at(i).u4BufVA, rQBufInfo.vBufInfo.at(i).u4BufPA, rQBufInfo.vBufInfo.at(i).u4BufSize, rQBufInfo.vBufInfo.at(i).i4MemID, rQBufInfo.i4TimeStamp_sec, rQBufInfo.i4TimeStamp_us); } handleNotifyCallback( ECamPipe_NOTIFY_MSG_EOF, 0, 0 ); FUNCTION_LOG_END; return MTRUE; }
MBOOL CamIOPipe:: start() { FUNCTION_LOG_START; MBOOL ret = MFALSE; // // (1) set buffer to current buffer ret = mpCamIOPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CURRENT_BUFFER, (MINT32)NSImageio::NSIspio::EPortIndex_IMGO, 0, 0 ); if (mfgIsYUVPortON) { ret = mpCamIOPipe->sendCommand((MINT32)NSImageio::NSIspio::EPIPECmd_SET_CURRENT_BUFFER, (MINT32)NSImageio::NSIspio::EPortIndex_IMG2O, 0, 0 ); } // // (2) start CQ ret = mpCamIOPipe->startCQ0(); // // ! let commond queue trigger mode as continuous mode ret = mpCamIOPipe->sendCommand(NSImageio::NSIspio::EPIPECmd_SET_CQ_CHANNEL, (MINT32)NSImageio::NSIspio::EPIPE_CQ_NONE, 0, 0 ); //[?] // ret = mpCamIOPipe->start(); // (3) sync vync ret = mpCamIOPipe->irq( ((mu4DeviceID == SENSOR_DEV_MAIN)||(mu4DeviceID == SENSOR_DEV_ATV)) ? (NSImageio::NSIspio::EPipePass_PASS1_TG1) : (NSImageio::NSIspio::EPipePass_PASS1_TG2), NSImageio::NSIspio::EPIPEIRQ_VSYNC ); MY_LOGD(" Wait for stable frame:%d", mu4SkipFrame); skipFrame(mu4SkipFrame); handleNotifyCallback( ECamPipe_NOTIFY_MSG_SOF, 0, 0 ); FUNCTION_LOG_END; return ret; }
MBOOL MultiShotNcc:: onCreateImage() { AutoCPTLog cptlog(Event_MShot_onCreateImage); mpYuvImageCreateThread->postCommand(Command(Command::eID_WAKEUP)); MUINT32 u4ShotCount = 0; //MBOOL bCShotEndCB = false; // (3) loop, handle jpeg buffer while(u4ShotCount<mu4ShotCount) { CPTLogStr(Event_MShot_onCreateImage, CPTFlagSeparator, "wait jpeg done"); ::sem_wait(&semJpeg); CPTLogStr(Event_MShot_onCreateImage, CPTFlagSeparator, "handle callback"); if(mbIsLastShot || u4ShotCount==mu4ShotCount-1) // last frame { MY_LOGD("notify last shot will callback"); handleNotifyCallback(ECamShot_NOTIFY_MSG_CSHOT_END, 0, 0); handleNotifyCallback(ECamShot_NOTIFY_MSG_FOCUS_VALUE, mFocusVal.u4ValH, mFocusVal.u4ValL); handleDataCallback(ECamShot_DATA_MSG_JPEG, (mThumbImgBufInfoReady.u4BufVA), mu4ThumbnailSize, reinterpret_cast<MUINT8*>(mJpegImgBufInfoReady.u4BufVA), mu4JpegSize); break; } handleNotifyCallback(ECamShot_NOTIFY_MSG_FOCUS_VALUE, mFocusVal.u4ValH, mFocusVal.u4ValL); handleDataCallback(ECamShot_DATA_MSG_JPEG, (mThumbImgBufInfoReady.u4BufVA), mu4ThumbnailSize, reinterpret_cast<MUINT8*>(mJpegImgBufInfoReady.u4BufVA), mu4JpegSize); u4ShotCount++; } // (7) start end CPTLogStr(Event_MShot_start, CPTFlagSeparator, "post start end sem"); ::sem_post(&semStartEnd); return MTRUE; }
MBOOL CamIOPipe:: skipFrame(MUINT32 const u4SkipCount) { MY_LOGD(" + (u4SkipCount) = (%d)", u4SkipCount); MBOOL ret = MTRUE; for (MUINT32 i = 0; i < u4SkipCount ; i++) { // NSImageio::NSIspio::QTimeStampBufInfo rQTimeOutBufInfo; NSImageio::NSIspio::PortID rPortID(NSImageio::NSIspio::EPortType_Memory, NSImageio::NSIspio::EPortIndex_IMGO, 1); // ret = mpCamIOPipe->dequeOutBuf(rPortID, rQTimeOutBufInfo); if (!ret) { MY_LOGE("mpCamIOPipe->dequeOutBuf(EPortIndex_IMGO) fail "); return ret; } // mpCamIOPipe->enqueOutBuf(rPortID, rQTimeOutBufInfo); if (mfgIsYUVPortON) { rPortID.index = NSImageio::NSIspio::EPortIndex_IMG2O; ret = mpCamIOPipe->dequeOutBuf(rPortID, rQTimeOutBufInfo); // if (!ret) { MY_LOGE("mpCamIOPipe->dequeOutBuf(EPortIndex_IMG2O) fail "); return ret; } // mpCamIOPipe->enqueOutBuf(rPortID, rQTimeOutBufInfo); } //ret = mpCamIOPipe->irq( ((mu4DeviceID == SENSOR_DEV_MAIN)||(mu4DeviceID == SENSOR_DEV_ATV)) ? (NSImageio::NSIspio::EPipePass_PASS1_TG1) : (NSImageio::NSIspio::EPipePass_PASS1_TG2), // NSImageio::NSIspio::EPIPEIRQ_VSYNC // ); handleNotifyCallback( ECamPipe_NOTIFY_MSG_DROPFRAME, u4SkipCount - i - 1, 0 ); } return ret; }
MBOOL CamIOPipe:: configPipe(vector<PortInfo const*>const& vInPorts, vector<PortInfo const*>const& vOutPorts) { //FUNCTION_LOG_START; MY_LOGD("+ tid(%d), %d in / %d out", gettid(), vInPorts.size(), vOutPorts.size()); MBOOL ret = MTRUE; // if (0 == vInPorts.size() || 0 == vOutPorts.size() || vOutPorts.size() > 2) { MY_LOGE("Port config error"); return MFALSE; } // if (EPortType_Sensor != vInPorts.at(0)->type) { MY_LOGE("The IN port type should be sensor type"); return MFALSE; } // for (MUINT32 i = 0; i < vOutPorts.size(); i++) { if (EPortType_MemoryOut != vOutPorts.at(i)->type) { MY_LOGE("The OUT port type should be EPortType_MemoryOut"); return MFALSE; } } // (1). callbacks mpCamIOPipe->setCallbacks(NULL, NULL, NULL); // (2). command queue config ret = ret && mpCamIOPipe->sendCommand(NSImageio::NSIspio::EPIPECmd_SET_CQ_CHANNEL, (MINT32)NSImageio::NSIspio::EPIPE_PASS1_CQ0, 0, 0 ) && mpCamIOPipe->sendCommand(NSImageio::NSIspio::EPIPECmd_SET_CQ_TRIGGER_MODE, (MINT32)NSImageio::NSIspio::EPIPE_PASS1_CQ0, (MINT32)NSImageio::NSIspio::EPIPECQ_TRIGGER_SINGLE_IMMEDIATE, (MINT32)NSImageio::NSIspio::EPIPECQ_TRIG_BY_START ) && mpCamIOPipe->sendCommand(NSImageio::NSIspio::EPIPECmd_SET_CONFIG_STAGE, (MINT32)NSImageio::NSIspio::eConfigSettingStage_Init, 0, 0 ); if (!ret) { MY_LOGE("Cammand queue config fail:%d", mpCamIOPipe->getLastErrorCode()); return ret; } // // (3). In sensor port vector<NSImageio::NSIspio::PortInfo const*> vCamIOInPorts; SensorPortInfo const* const pSensorPort = reinterpret_cast<SensorPortInfo const*> (vInPorts.at(0)); ::memcpy(&mrSensorPortInfo, const_cast<SensorPortInfo*>(pSensorPort),sizeof(SensorPortInfo)); MUINT32 u4SensorWidth = 0, u4SensorHeight = 0; MUINT32 u4RawPixelID = 0; EImageFormat eSensorFmt = eImgFmt_UNKNOWN; // (3.1) Sensor instance if (NULL == mpSensorHal) { mpSensorHal = SensorHal::createInstance(); if (NULL == mpSensorHal) { MY_LOGE("Null sensorHal object"); return MFALSE; } } // mpSensorHal->sendCommand(static_cast<halSensorDev_e>(pSensorPort->u4DeviceID), SENSOR_CMD_SET_SENSOR_DEV, 0, 0, 0 ); // //mpSensorHal->init(); ret = querySensorInfo( pSensorPort->u4DeviceID, pSensorPort->u4Scenario, pSensorPort->u4Bitdepth, eSensorFmt, u4SensorWidth, u4SensorHeight, u4RawPixelID); MY_LOGD("Sensor: (devID,scen)(%d,%d) (w,h,fmt,bits,pixID)(%d,%d,0x%x,%d,%d) (bpDelay,bpScen,rawType)(%d,%d,%d)", pSensorPort->u4DeviceID, pSensorPort->u4Scenario, u4SensorWidth, u4SensorHeight, eSensorFmt, pSensorPort->u4Bitdepth, u4RawPixelID, pSensorPort->fgBypassDelay, pSensorPort->fgBypassScenaio, pSensorPort->u4RawType); // MUINT32 u4SensorStride = u4SensorWidth; if (eImgFmt_BAYER8 == eSensorFmt || eImgFmt_BAYER10 == eSensorFmt || eImgFmt_BAYER12 == eSensorFmt) { u4SensorStride = NSImageio::NSIspio::queryRawStride(eSensorFmt, u4SensorWidth); } //MY_LOGD("SensorPortInfo: (width, height, format, stride) = (%d, %d, 0x%x, %d, %d, %d)", // u4SensorWidth, u4SensorHeight, eSensorFmt, u4SensorStride); // NSImageio::NSIspio::PortInfo tgi; tgi.eImgFmt = eSensorFmt; tgi.eRawPxlID = mapRawPixelID(u4RawPixelID); tgi.u4ImgWidth = u4SensorWidth; tgi.u4ImgHeight = u4SensorHeight; tgi.u4Stride[0] = u4SensorStride; tgi.u4Stride[1] = 0; tgi.u4Stride[2] = 0; tgi.type = NSImageio::NSIspio::EPortType_Sensor; mu4DeviceID = pSensorPort->u4DeviceID; tgi.index = ((mu4DeviceID == SENSOR_DEV_MAIN)||(mu4DeviceID == SENSOR_DEV_ATV)) ? (NSImageio::NSIspio::EPortIndex_TG1I) : (NSImageio::NSIspio::EPortIndex_TG2I); tgi.inout = NSImageio::NSIspio::EPortDirection_In; tgi.u4BufSize = (MUINT32)0; vCamIOInPorts.push_back(&tgi); // The raw type, 0: pure raw, 1: pre-process raw if(pSensorPort->u4RawType == 1) { ret = mpCamIOPipe->sendCommand(NSImageio::NSIspio::EPIPECmd_SET_IMGO_RAW_TYPE, (MINT32)NSImageio::NSIspio::eRawImageType_PreProc, 0, 0 ); } // // (4). Out Port vector<NSImageio::NSIspio::PortInfo const*> vCamIOOutPorts; NSImageio::NSIspio::PortInfo imgo; NSImageio::NSIspio::PortInfo img2o; for (MUINT32 i = 0; i < vOutPorts.size(); i++) { MemoryOutPortInfo const* const memOutPort= reinterpret_cast<MemoryOutPortInfo const*> (vOutPorts.at(i)); // if (0 == memOutPort->index) { MY_LOGD("Out 0: (fmt,w,h)(0x%x,%d,%d) stride(%d,%d,%d)", tgi.eImgFmt, tgi.u4ImgWidth, tgi.u4ImgHeight, memOutPort->u4Stride[0], memOutPort->u4Stride[1], memOutPort->u4Stride[2]); imgo.eImgFmt = tgi.eImgFmt; imgo.u4ImgWidth = tgi.u4ImgWidth; imgo.u4ImgHeight = tgi.u4ImgHeight; // no crop imgo.crop.y = 0; imgo.crop.h = imgo.u4ImgHeight; imgo.type = NSImageio::NSIspio::EPortType_Memory; imgo.index = NSImageio::NSIspio::EPortIndex_IMGO; imgo.inout = NSImageio::NSIspio::EPortDirection_Out; imgo.u4Stride[0] = memOutPort->u4Stride[0]; imgo.u4Stride[1] = memOutPort->u4Stride[1]; imgo.u4Stride[2] = memOutPort->u4Stride[2]; imgo.u4Offset = 0; vCamIOOutPorts.push_back(&imgo); } #warning [TODO] Should check the port config by scenario else if (1 == memOutPort->index) { MY_LOGD("Out 1: (fmt,w,h)(0x%x,%d,%d) stride(%d,%d,%d)", memOutPort->eImgFmt, memOutPort->u4ImgWidth, memOutPort->u4ImgHeight, memOutPort->u4Stride[0], memOutPort->u4Stride[1], memOutPort->u4Stride[2]); img2o.eImgFmt = memOutPort->eImgFmt; img2o.u4ImgWidth = memOutPort->u4ImgWidth; img2o.u4ImgHeight = memOutPort->u4ImgHeight; img2o.crop.y = 0; img2o.crop.h = img2o.u4ImgHeight; img2o.type = NSImageio::NSIspio::EPortType_Memory; img2o.index = NSImageio::NSIspio::EPortIndex_IMG2O; img2o.inout = NSImageio::NSIspio::EPortDirection_Out; img2o.u4Stride[0] = memOutPort->u4Stride[0]; img2o.u4Stride[1] = memOutPort->u4Stride[1]; img2o.u4Stride[2] = memOutPort->u4Stride[2]; vCamIOOutPorts.push_back(&img2o); mfgIsYUVPortON = MTRUE; } } ret = mpCamIOPipe->configPipe(vCamIOInPorts, vCamIOOutPorts); // ret = configSensor(pSensorPort->u4DeviceID, pSensorPort->u4Scenario, u4SensorWidth, u4SensorHeight, pSensorPort->fgBypassDelay, pSensorPort->fgBypassScenaio, MTRUE); // The raw type, 0: pure raw, 1: pre-process raw 2: sensor test pattern if(pSensorPort->u4RawType == 2) { MINT32 u32Enable = 1; mpSensorHal->sendCommand(static_cast<halSensorDev_e>(pSensorPort->u4DeviceID), SENSOR_CMD_SET_TEST_PATTERN_OUTPUT, (MINT32)&u32Enable, 0, 0); MY_LOGD("Sensor Test Pattern"); } // query skip frame to wait for stable mu4SkipFrame = 0; if (mrSensorPortInfo.fgBypassDelay == MFALSE) { MUINT32 u4Mode = SENSOR_CAPTURE_DELAY; switch (pSensorPort->u4Scenario) { case ACDK_SCENARIO_ID_CAMERA_PREVIEW: u4Mode = SENSOR_PREVIEW_DELAY; break; case ACDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: u4Mode = SENSOR_CAPTURE_DELAY; break; case ACDK_SCENARIO_ID_VIDEO_PREVIEW: u4Mode = SENSOR_VIDEO_DELAY; break; } // mpSensorHal->sendCommand(static_cast<halSensorDev_e>(mrSensorPortInfo.u4DeviceID), static_cast<int>(SENSOR_CMD_GET_UNSTABLE_DELAY_FRAME_CNT), reinterpret_cast<int>(&mu4SkipFrame), reinterpret_cast<int>(&u4Mode)); } handleNotifyCallback( ECamPipe_NOTIFY_MSG_DROPFRAME, mu4SkipFrame, 0 ); //FUNCTION_LOG_END; return ret; }