status_t ExynosCameraPipeSCP::m_getBuffer(void)
{
    ExynosCameraFrame *curFrame = NULL;
    ExynosCameraBuffer curBuffer;
    int index = -1;
    int ret = 0;

    if (m_numOfRunningFrame <= 0 || m_flagStartPipe == false) {
        ALOGD("DEBUG(%s[%d]): skip getBuffer, flagStartPipe(%d), numOfRunningFrame = %d", __FUNCTION__, __LINE__, m_flagStartPipe, m_numOfRunningFrame);
        return NO_ERROR;
    }

    ret = m_mainNode->getBuffer(&curBuffer, &index);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):getBuffer fail", __FUNCTION__, __LINE__);
        /* TODO: doing exception handling */
        return ret;
    }

    if (index < 0) {
        CLOGE("ERR(%s[%d]):Invalid index(%d) fail", __FUNCTION__, __LINE__, index);
        return INVALID_OPERATION;
    }

    m_activityControl->activityAfterExecFunc(getPipeId(), (void *)&curBuffer);

    /* complete frame */
    ret = m_completeFrame(&curFrame, curBuffer);
    if (ret < 0) {
        CLOGE("ERR(%s):m_comleteFrame fail", __FUNCTION__);
        /* TODO: doing exception handling */
    }

    if (curFrame == NULL) {
        CLOGE("ERR(%s):curFrame is fail", __FUNCTION__);
    }

    ret = curFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_COMPLETE);
    if (ret < 0) {
        CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
        return ret;
    }

    m_outputFrameQ->pushProcessQ(&curFrame);

    return NO_ERROR;
}
status_t ExynosCameraPipeJpeg::create(int32_t *sensorIds)
{
    m_mainThread = ExynosCameraThreadFactory::createThread(this, &ExynosCameraPipeJpeg::m_mainThreadFunc, "JpegThread");

    m_mainNode = NULL;

    m_inputFrameQ = new frame_queue_t(m_mainThread);

    ALOGI("INFO(%s[%d]):create() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());

    return NO_ERROR;
}
status_t ExynosCameraPipeJpeg::destroy(void)
{

    if (m_inputFrameQ != NULL) {
        m_inputFrameQ->release();
        delete m_inputFrameQ;
        m_inputFrameQ = NULL;
    }

    ALOGI("INFO(%s[%d]):destroy() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());

    return NO_ERROR;
}
status_t ExynosCameraPipeSCP::setupPipe(camera_pipe_info_t *pipeInfos)
{
    CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
    status_t ret = NO_ERROR;

    /* TODO: check node state stream on? */

    /* initialize node */
    int maxW = pipeInfos[0].rectInfo.fullW;
    int maxH = pipeInfos[0].rectInfo.fullH;
    int colorFormat = pipeInfos[0].rectInfo.colorFormat;
    enum v4l2_buf_type bufType = (enum v4l2_buf_type)pipeInfos[0].bufInfo.type;
    enum v4l2_memory memType = (enum v4l2_memory)pipeInfos[0].bufInfo.memory;
    m_numBuffers = pipeInfos[0].bufInfo.count;

    m_mainNode->setSize(maxW, maxH);
    m_mainNode->setColorFormat(colorFormat, 4);
    m_mainNode->setBufferType(m_numBuffers, bufType, memType);

    m_mainNode->setFormat();
    m_mainNode->reqBuffers();

    /* setfile setting */
#ifdef SET_SETFILE_BY_SHOT
    /* nop */
#else
#if SET_SETFILE_BY_SET_CTRL_SCP
    int setfile = 0;
    int yuvRange = 0;
    m_parameters->getSetfileYuvRange(m_reprocessing, &setfile, &yuvRange);
    ret = m_mainNode->setControl(V4L2_CID_IS_COLOR_RANGE, yuvRange);
    if (ret != NO_ERROR) {
        CLOGE("ERR(%s[%d]):setControl(%d) fail(ret = %d)", __FUNCTION__, __LINE__, setfile, ret);
        return ret;
    }
#endif
#endif

    for (uint32_t i = 0; i < m_numBuffers; i++) {
        m_runningFrameList[i] = NULL;
    }
    m_numOfRunningFrame = 0;

    m_prepareBufferCount = m_exynosconfig->current->pipeInfo.prepare[getPipeId()];
    ALOGI("INFO(%s[%d]):setupPipe() is succeed (%d) setupPipe (%d)", __FUNCTION__, __LINE__, getPipeId(), m_prepareBufferCount);

    return NO_ERROR;
}
status_t ExynosCameraPipeJpeg::startThread(void)
{
    ALOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);

    start();

    if (m_outputFrameQ == NULL) {
        ALOGE("ERR(%s):outputFrameQ is NULL, cannot start", __FUNCTION__);
        return INVALID_OPERATION;
    }

    m_mainThread->run();

    ALOGI("INFO(%s[%d]):startThread is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());

    return NO_ERROR;
}
status_t ExynosCameraPipeSCP::create(int32_t *sensorIds)
{
    CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
    int ret = 0;

    if (sensorIds == NULL) {
        ALOGE("ERR(%s[%d]): Pipe need sensorId", __FUNCTION__, __LINE__);
        return BAD_VALUE;
    }

    m_mainNode = new ExynosCameraNode();
    ret = m_mainNode->create("SCP");
    if (ret < 0) {
        ALOGE("ERR(%s[%d]): mainNode create fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        return ret;
    }

    ret = m_mainNode->open(m_mainNodeNum);
    if (ret < 0) {
        ALOGE("ERR(%s[%d]): mainNode open fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        return ret;
    }
    ALOGD("DEBUG(%s):Node(%d) opened", __FUNCTION__, m_mainNodeNum);

    ret = m_mainNode->setInput(sensorIds[CAPTURE_NODE]);
    if (ret < 0) {
        ALOGE("ERR(%s[%d]): mainNode setInput fail, sensorId(%d), ret(%d)", __FUNCTION__, __LINE__, sensorIds[CAPTURE_NODE], ret);
        return ret;
    }

    m_mainThread = ExynosCameraThreadFactory::createThread(this, &ExynosCameraPipeSCP::m_mainThreadFunc, "SCPThread", PRIORITY_URGENT_DISPLAY);

    m_inputFrameQ = new frame_queue_t;


    m_prepareBufferCount = m_exynosconfig->current->pipeInfo.prepare[getPipeId()];
    ALOGI("INFO(%s[%d]):create() is succeed (%d) setupPipe (%d)", __FUNCTION__, __LINE__, getPipeId(), m_prepareBufferCount);

    return NO_ERROR;
}
status_t ExynosCameraPipeSCP::destroy(void)
{
    CLOGD("DEBUG(%s[%d])", __FUNCTION__, __LINE__);
    if (m_mainNode != NULL) {
        if (m_mainNode->close() != NO_ERROR) {
            CLOGE("ERR(%s):close fail", __FUNCTION__);
            return INVALID_OPERATION;
        }
        delete m_mainNode;
        m_mainNode = NULL;
        ALOGD("DEBUG(%s):Node(%d) closed", __FUNCTION__, FIMC_IS_VIDEO_SCP_NUM);
    }

    if (m_inputFrameQ != NULL) {
        m_inputFrameQ->release();
        delete m_inputFrameQ;
        m_inputFrameQ = NULL;
    }

    ALOGI("INFO(%s[%d]):destroy() is succeed (%d)", __FUNCTION__, __LINE__, getPipeId());

    return NO_ERROR;
}
예제 #8
0
MBOOL
PipeImp::
configMdpOutPort(PortInfo const* oImgInfo, MdpRotDMACfg &a_rotDma)
{
    MUINT32 plane_num = 1;
    MUINT32 uv_resample = 1;
    MUINT32 uv_h_ratio = 1;
    MUINT32 uv_v_ratio = 1;
    MUINT32 y_plane_size = 0;
    MUINT32 u_plane_size = 0;
    //
    PIPE_DBG("[oImgInfo]w(%d),h(%d),stride(%d/%d/%d),crop(%d,%d,%d,%d)_f(0x%x, 0x%x),rot(%d) eImgFmt(%d)",
        oImgInfo->u4ImgWidth,oImgInfo->u4ImgHeight,oImgInfo->u4Stride[ESTRIDE_1ST_PLANE],oImgInfo->u4Stride[ESTRIDE_2ND_PLANE],oImgInfo->u4Stride[ESTRIDE_3RD_PLANE], \
        oImgInfo->crop1.x,oImgInfo->crop1.y,oImgInfo->crop1.w,oImgInfo->crop1.h,oImgInfo->crop1.floatX,oImgInfo->crop1.floatY, \
        oImgInfo->eImgRot,oImgInfo->eImgFmt );
    //
    if ( ePipeID_1x1_Sensor_Tg_Mem == getPipeId() ) {
        PIPE_ERR("Pipe Not Support");
        return MFALSE;
    }
    //
    a_rotDma.uv_plane_swap = 0;
    //
    switch( oImgInfo->eImgFmt ) {
       case eImgFmt_YV12:      //= 0x00008,   //420 format, 3 plane(YVU)
       case eImgFmt_I420:      //= 0x20000,   //420 format, 3 plane(YUV)
           a_rotDma.Format = CRZ_DRV_FORMAT_YUV420;
           a_rotDma.Plane = CRZ_DRV_PLANE_3;
           a_rotDma.Sequence = CRZ_DRV_SEQUENCE_UVUV; //don't care, but cdp_drv need to set this value , why?
           plane_num = 3;
           uv_h_ratio = 2;
           uv_v_ratio = 2;
           a_rotDma.uv_plane_swap = (eImgFmt_YV12==oImgInfo->eImgFmt)?1:0;
           break;
        case eImgFmt_I422:      //422 format, 3 plane(YUV)
           a_rotDma.Format = CRZ_DRV_FORMAT_YUV422;
           a_rotDma.Plane = CRZ_DRV_PLANE_3;
           a_rotDma.Sequence = CRZ_DRV_SEQUENCE_UVUV; //don't care, but cdp_drv need to set this value , why?
           plane_num = 3;
           uv_h_ratio = 2;
           uv_v_ratio = 1;
           break;
        case eImgFmt_NV21:      //= 0x0010,   //420 format, 2 plane (VU)
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV420;
            a_rotDma.Plane = CRZ_DRV_PLANE_2;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_UVUV; //MSN->LSB
            plane_num = 2;
            uv_h_ratio = 2;
            uv_v_ratio = 2;
            break;
        case eImgFmt_NV12:      //= 0x0040,   //420 format, 2 plane (UV)
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV420;
            a_rotDma.Plane = CRZ_DRV_PLANE_2;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_VUVU; //MSN->LSB
            plane_num = 2;
            uv_h_ratio = 2;
            uv_v_ratio = 2;
            break;
        case eImgFmt_YUY2:      //= 0x0100,   //422 format, 1 plane (YUYV)
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV422;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_VYUY; //MSN->LSB
            break;
        case eImgFmt_UYVY:      //= 0x0200,   //422 format, 1 plane (UYVY)
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV422;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_YVYU; //MSN->LSB
            break;
        case eImgFmt_YV16:      //422 format, 3 plane
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV422;
            a_rotDma.Plane = CRZ_DRV_PLANE_3;
            a_rotDma.Sequence = (CRZ_DRV_SEQUENCE_ENUM)0; //MSN->LSB
            plane_num = 3;
            uv_h_ratio = 2;
            uv_v_ratio = 1;
            break;
        case eImgFmt_NV16:      //422 format, 2 plane
            a_rotDma.Format = CRZ_DRV_FORMAT_YUV422;
            a_rotDma.Plane = CRZ_DRV_PLANE_2;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_VUVU; //MSN->LSB
            plane_num = 2;
            uv_h_ratio = 2;
            uv_v_ratio = 1;
            break;
        case eImgFmt_RGB565:    //= 0x0400,   //RGB 565 (16-bit), 1 plane
            a_rotDma.Format = CRZ_DRV_FORMAT_RGB565;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_RGB; //MSN->LSB
            break;
        case eImgFmt_RGB888:    //= 0x0800,   //RGB 888 (24-bit), 1 plane
            a_rotDma.Format = CRZ_DRV_FORMAT_RGB888;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_BGR; //MSN->LSB
            break;
        case eImgFmt_ARGB8888:   //= 0x1000,   //ARGB (32-bit), 1 plane
            a_rotDma.Format = CRZ_DRV_FORMAT_XRGB8888;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_XBGR; //MSN->LSB
            break;
        case eImgFmt_Y800:		//= 0x040000, //Y plane only
            a_rotDma.Format = CRZ_DRV_FORMAT_Y;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_Y; //MSN->LSB
            break;
        case eImgFmt_JPG_I420:
            a_rotDma.Format = CRZ_DRV_FORMAT_JPEG_YUV420;
            a_rotDma.Plane = CRZ_DRV_PLANE_3;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_UVUV; //don't care,
            plane_num = 3;
            uv_h_ratio = 2;
            uv_v_ratio = 2;
            break;
        case eImgFmt_JPG_I422:
            a_rotDma.Format = CRZ_DRV_FORMAT_JPEG_YUV422;
            a_rotDma.Plane = CRZ_DRV_PLANE_3;
            a_rotDma.Sequence = CRZ_DRV_SEQUENCE_UVUV; //don't care,
            plane_num = 3;
            uv_h_ratio = 2;
            uv_v_ratio = 1;
            break;
        case eImgFmt_BAYER8:    //= 0x0001,   //Bayer format, 8-bit     // for imgo
            a_rotDma.Format = CRZ_DRV_FORMAT_RAW8;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            break;
        case eImgFmt_BAYER10:   //= 0x0002,   //Bayer format, 10-bit    // for imgo
            a_rotDma.Format = CRZ_DRV_FORMAT_RAW10;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            break;
        case eImgFmt_BAYER12:   //= 0x0004,   //Bayer format, 12-bit    // for imgo
            a_rotDma.Format = CRZ_DRV_FORMAT_RAW12;
            a_rotDma.Plane = CRZ_DRV_PLANE_1;
            break;
        case eImgFmt_NV21_BLK:  //= 0x0020,   //420 format block mode, 2 plane (UV)
        case eImgFmt_NV12_BLK:  //= 0x0080,   //420 format block mode, 2 plane (VU)
        case eImgFmt_JPEG:      //= 0x2000,   //JPEG format
        default:
            PIPE_ERR("vOutPorts[]->eImgFmt:Format(%d) NOT Support",oImgInfo->eImgFmt);
            break;
    }
    //
    //ROTATION, stride is after, others are before
    a_rotDma.Rotation = (CRZ_DRV_ROTATION_ENUM)oImgInfo->eImgRot;
    a_rotDma.Flip = (eImgFlip_ON == oImgInfo->eImgFlip)?MTRUE:MFALSE;
    //dma port capbility
    a_rotDma.capbility=oImgInfo->capbility;
    //Y
    a_rotDma.memBuf.base_pAddr = oImgInfo->u4BufPA[0];
    a_rotDma.memBuf.base_vAddr = oImgInfo->u4BufVA[0];
    a_rotDma.memBuf.size = oImgInfo->u4BufSize[0];
    a_rotDma.memBuf.ofst_addr = 0;
    a_rotDma.memBuf.alignment = 0;
    //after ROT
    a_rotDma.size.w = oImgInfo->u4ImgWidth;
    a_rotDma.size.h = oImgInfo->u4ImgHeight;
    //stride info after ROT
    a_rotDma.size.stride = oImgInfo->u4Stride[ESTRIDE_1ST_PLANE];
    //
    y_plane_size = oImgInfo->u4BufSize[ESTRIDE_1ST_PLANE];
    //tpipemain lib need image info before ROT. stride info after ROT
    //if ( CRZ_DRV_ROTATION_90 == a_rotDma.Rotation || CRZ_DRV_ROTATION_270 == a_rotDma.Rotation ) {
        //
    //    a_rotDma.size.w = oImgInfo->u4ImgHeight;
    //    a_rotDma.size.h = oImgInfo->u4ImgWidth;
    //}
    //
    if ( 2<=plane_num) {
        //U
        a_rotDma.memBuf_c.base_pAddr = oImgInfo->u4BufPA[ESTRIDE_2ND_PLANE];
        a_rotDma.memBuf_c.base_vAddr = oImgInfo->u4BufVA[ESTRIDE_2ND_PLANE];
        a_rotDma.memBuf_c.ofst_addr = 0;
        a_rotDma.memBuf_c.alignment = 0;
        //after ROT
        a_rotDma.size_c.w =         a_rotDma.size.w/uv_h_ratio;
        a_rotDma.size_c.h =         a_rotDma.size.h/uv_v_ratio;
        //stride info after ROT
        a_rotDma.size_c.stride =    oImgInfo->u4Stride[ESTRIDE_2ND_PLANE];
        //
        u_plane_size = oImgInfo->u4BufSize[ESTRIDE_2ND_PLANE];
        //tpipemain lib need image info before ROT. stride info after ROT
        //if ( CRZ_DRV_ROTATION_90 == a_rotDma.Rotation || CRZ_DRV_ROTATION_270 == a_rotDma.Rotation ) {
        //    a_rotDma.size_c.w = a_rotDma.size.h/uv_v_ratio;
        //    a_rotDma.size_c.h = a_rotDma.size.w/uv_h_ratio;
        //}
        //
		if ( 3 == plane_num ) {
	        //V
	        a_rotDma.memBuf_v.base_pAddr = oImgInfo->u4BufPA[ESTRIDE_3RD_PLANE];
	        a_rotDma.memBuf_v.base_vAddr = oImgInfo->u4BufVA[ESTRIDE_3RD_PLANE];
	        a_rotDma.memBuf_v.ofst_addr = 0;
	        a_rotDma.memBuf_v.alignment = 0;
            //after ROT
	        a_rotDma.size_v.w =        a_rotDma.size_c.w;
	        a_rotDma.size_v.h =        a_rotDma.size_c.h;
            //stride info after ROT
	        a_rotDma.size_v.stride =   oImgInfo->u4Stride[ESTRIDE_3RD_PLANE];
	        //tpipemain lib need image info BEFORE ROT. stride info AFTER ROT
	        //if ( CRZ_DRV_ROTATION_90 == a_rotDma.Rotation || CRZ_DRV_ROTATION_270 == a_rotDma.Rotation ) {
            //    a_rotDma.size_v.w = a_rotDma.size_c.h;
            //    a_rotDma.size_v.h = a_rotDma.size_c.w;
	        //}
		}
        //
        /*
        if ( a_rotDma.uv_plane_swap ) {
            a_rotDma.memBuf_c.base_pAddr = oImgInfo->u4BufPA[ESTRIDE_3RD_PLANE];
            a_rotDma.memBuf_c.base_vAddr = oImgInfo->u4BufVA[ESTRIDE_3RD_PLANE];
            a_rotDma.memBuf_v.base_pAddr = oImgInfo->u4BufPA[ESTRIDE_2ND_PLANE];
            a_rotDma.memBuf_v.base_vAddr = oImgInfo->u4BufVA[ESTRIDE_2ND_PLANE];
        }
        */
    }

    //tpipemain lib need image info before ROT. stride info after ROT
    //if ( CRZ_DRV_ROTATION_90 == a_rotDma.Rotation || CRZ_DRV_ROTATION_270 == a_rotDma.Rotation ) {
    //    //
    //    a_rotDma.size.w = oImgInfo->u4ImgHeight;
    //    a_rotDma.size.h = oImgInfo->u4ImgWidth;
    //}

    /*
        * DONOT USE CRZ CROP due to throughtput issue
        */
    //default set ENABLE, if need to be programmable, check cdp driver as well.
    a_rotDma.crop_en = 1; //always enable crop for rotation issue.
    //
    a_rotDma.crop.x = 0;
    a_rotDma.crop.floatX = 0;
    a_rotDma.crop.y = 0;
    a_rotDma.crop.floatY = 0;
    a_rotDma.crop.w = 0;
    a_rotDma.crop.h = 0;
    //
    PIPE_DBG("[a_rotDma]w(%d),h(%d),stride(pxl)(%d),pa(0x%x),va(0x%x),size(%d)",a_rotDma.size.w,a_rotDma.size.h,a_rotDma.size.stride,a_rotDma.memBuf.base_pAddr,a_rotDma.memBuf.base_vAddr,a_rotDma.memBuf.size);
    PIPE_DBG("[a_rotDma]crop(%d,%d,%d,%d)_f(0x%x,0x%x)",a_rotDma.crop.x,a_rotDma.crop.y,a_rotDma.crop.w,a_rotDma.crop.h,a_rotDma.crop.floatX,a_rotDma.crop.floatY);
    PIPE_DBG("[a_rotDma]rot(%d),fmt(%d),plane(%d),seq(%d),pxlByte((0x%x))",a_rotDma.Rotation,a_rotDma.Format,a_rotDma.Plane,a_rotDma.Sequence,a_rotDma.pixel_byte);
    PIPE_DBG("[a_rotDma]c_ofst_addr(0x%x),v_ofst_addr(0x%x),uv_plane_swap(%d)",a_rotDma.memBuf_c.ofst_addr,a_rotDma.memBuf_v.ofst_addr,a_rotDma.uv_plane_swap);
    PIPE_DBG("[a_rotDma]va[0x%x,0x%x,0x%x]--pa[0x%x,0x%x,0x%x]",
        a_rotDma.memBuf.base_vAddr,a_rotDma.memBuf_c.base_vAddr,a_rotDma.memBuf_v.base_vAddr,a_rotDma.memBuf.base_pAddr,a_rotDma.memBuf_c.base_pAddr,a_rotDma.memBuf_v.base_pAddr);


    return MTRUE;
}
status_t ExynosCameraPipeSCP::m_putBuffer(void)
{
    ExynosCameraFrame *newFrame = NULL;
    ExynosCameraBuffer newBuffer;
    int ret = 0;

retry:
    ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame);
    if (ret < 0) {
        /* TODO: We need to make timeout duration depends on FPS */
        if (ret == TIMED_OUT) {
            CLOGW("WARN(%s):wait timeout", __FUNCTION__);
            m_mainNode->dumpState();
        } else {
            CLOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret);
            /* TODO: doing exception handling */
        }
        return ret;
    }

    if (newFrame == NULL) {
        CLOGE("ERR(%s):newFrame is NULL", __FUNCTION__);
        return INVALID_OPERATION;
    }

    ret = newFrame->getDstBuffer(getPipeId(), &newBuffer);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    /* check buffer index */
    if (newBuffer.index < 0) {
        CLOGD("DEBUG(%s[%d]): no buffer to QBUF (%d)", __FUNCTION__, __LINE__, newFrame->getFrameCount());

        ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_REQUESTED);
        if (ret < 0) {
            CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
            return ret;
        }

        ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
        if (ret < 0) {
            CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
            /* TODO: doing exception handling */
            return OK;
        }

        CLOGV("DEBUG(%s):entity pipeId(%d), frameCount(%d), numOfRunningFrame(%d), requestCount(%d)",
                __FUNCTION__, getPipeId(), newFrame->getFrameCount(), m_numOfRunningFrame, m_requestCount);

        usleep(33000);
        m_outputFrameQ->pushProcessQ(&newFrame);

        goto retry;
    } else {
        if (m_runningFrameList[newBuffer.index] != NULL) {
            CLOGE("ERR(%s):new buffer is invalid, we already get buffer index(%d), newFrame->frameCount(%d)",
                __FUNCTION__, newBuffer.index, newFrame->getFrameCount());
            m_dumpRunningFrameList();

            return BAD_VALUE;
        }

        camera2_shot_ext *shot_ext = (struct camera2_shot_ext *)(newBuffer.addr[1]);

        if (shot_ext != NULL) {
            newFrame->getMetaData(shot_ext);
            m_parameters->duplicateCtrlMetadata((void *)shot_ext);
            m_activityControl->activityBeforeExecFunc(getPipeId(), (void *)&newBuffer);

            if (m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameNodeType == PERFRAME_NODE_TYPE_LEADER) {
                camera2_node_group node_group_info;
                memset(&shot_ext->node_group, 0x0, sizeof(camera2_node_group));
                newFrame->getNodeGroupInfo(&node_group_info, m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perframeInfoIndex);

                /* Per - Leader */
                if (node_group_info.leader.request == 1) {
                    setMetaNodeLeaderInputSize(shot_ext,
                        node_group_info.leader.input.cropRegion[0],
                        node_group_info.leader.input.cropRegion[1],
                        node_group_info.leader.input.cropRegion[2],
                        node_group_info.leader.input.cropRegion[3]);
                    setMetaNodeLeaderOutputSize(shot_ext,
                        node_group_info.leader.output.cropRegion[0],
                        node_group_info.leader.output.cropRegion[1],
                        node_group_info.leader.output.cropRegion[2],
                        node_group_info.leader.output.cropRegion[3]);
                    setMetaNodeLeaderRequest(shot_ext,
                        node_group_info.leader.request);
                    setMetaNodeLeaderVideoID(shot_ext,
                        m_perframeMainNodeGroupInfo.perFrameLeaderInfo.perFrameVideoID);
                }

                /* Per - Captures */
                for (int i = 0; i < m_perframeMainNodeGroupInfo.perframeSupportNodeNum - 1; i ++) {
                    if (node_group_info.capture[i].request == 1) {
                        setMetaNodeCaptureInputSize(shot_ext, i,
                            node_group_info.capture[i].input.cropRegion[0],
                            node_group_info.capture[i].input.cropRegion[1],
                            node_group_info.capture[i].input.cropRegion[2],
                            node_group_info.capture[i].input.cropRegion[3]);
                        setMetaNodeCaptureOutputSize(shot_ext, i,
                            node_group_info.capture[i].output.cropRegion[0],
                            node_group_info.capture[i].output.cropRegion[1],
                            node_group_info.capture[i].output.cropRegion[2],
                            node_group_info.capture[i].output.cropRegion[3]);
                        setMetaNodeCaptureRequest(shot_ext,  i, node_group_info.capture[i].request);
                        setMetaNodeCaptureVideoID(shot_ext, i, m_perframeMainNodeGroupInfo.perFrameCaptureInfo[i].perFrameVideoID);
                    }
                }
            }
        }

        ret = m_mainNode->putBuffer(&newBuffer);
        if (ret < 0) {
            CLOGE("ERR(%s):putBuffer fail", __FUNCTION__);
            return ret;
            /* TODO: doing exception handling */
        }

        ret = newFrame->setDstBufferState(getPipeId(), ENTITY_BUFFER_STATE_PROCESSING);
        if (ret < 0) {
            CLOGE("ERR(%s): setDstBuffer state fail", __FUNCTION__);
            return ret;
        }

        m_runningFrameList[newBuffer.index] = newFrame;
        m_numOfRunningFrame++;
    }

    return NO_ERROR;
}
status_t ExynosCameraPipeJpeg::m_run(void)
{
    ExynosCameraAutoTimer autoTimer(__FUNCTION__);
    status_t ret = 0;
    ExynosCameraFrame *newFrame = NULL;

    ExynosCameraBuffer yuvBuf;
    ExynosCameraBuffer jpegBuf;

    ExynosRect pictureRect;
    int jpegQuality = m_parameters->getJpegQuality();

    ExynosRect thumbnailRect;
    int thumbnailQuality = m_parameters->getThumbnailQuality();

    exif_attribute_t exifInfo;
    m_parameters->getFixedExifInfo(&exifInfo);
    struct camera2_shot_ext shot_ext;
    memset(&shot_ext, 0x00, sizeof(struct camera2_shot_ext));

    pictureRect.colorFormat = m_parameters->getPictureFormat();
    m_parameters->getPictureSize(&pictureRect.w, &pictureRect.h);
    m_parameters->getThumbnailSize(&thumbnailRect.w, &thumbnailRect.h);

    ALOGI("DEBUG(%s[%d]): -IN-", __FUNCTION__, __LINE__);
    ALOGD("DEBUG(%s[%d]):picture size(%dx%d), thumbnail size(%dx%d)",
            __FUNCTION__, __LINE__, pictureRect.w, pictureRect.h, thumbnailRect.w, thumbnailRect.h);

    ret = m_inputFrameQ->waitAndPopProcessQ(&newFrame);
    if (ret < 0) {
        /* TODO: We need to make timeout duration depends on FPS */
        if (ret == TIMED_OUT) {
            ALOGW("WARN(%s):wait timeout", __FUNCTION__);
        } else {
            ALOGE("ERR(%s):wait and pop fail, ret(%d)", __FUNCTION__, ret);
            /* TODO: doing exception handling */
        }
        return ret;
    }

    if (newFrame == NULL) {
        ALOGE("ERR(%s):new frame is NULL", __FUNCTION__);
        return NO_ERROR;
    }

    ret = newFrame->getSrcBuffer(getPipeId(), &yuvBuf);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get src buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    ret = newFrame->getDstBuffer(getPipeId(), &jpegBuf);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):frame get dst buffer fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    if (m_jpegEnc.create()) {
        ALOGE("ERR(%s):m_jpegEnc.create() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setQuality(jpegQuality)) {
        ALOGE("ERR(%s):m_jpegEnc.setQuality() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setSize(pictureRect.w, pictureRect.h)) {
        ALOGE("ERR(%s):m_jpegEnc.setSize() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setColorFormat(pictureRect.colorFormat)) {
        ALOGE("ERR(%s):m_jpegEnc.setColorFormat() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setJpegFormat(V4L2_PIX_FMT_JPEG_422)) {
        ALOGE("ERR(%s):m_jpegEnc.setJpegFormat() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (thumbnailRect.w != 0 && thumbnailRect.h != 0) {
        exifInfo.enableThumb = true;
        if (pictureRect.w < 320 || pictureRect.h < 240) {
            thumbnailRect.w = 160;
            thumbnailRect.h = 120;
        }
        if (m_jpegEnc.setThumbnailSize(thumbnailRect.w, thumbnailRect.h)) {
            ALOGE("ERR(%s):m_jpegEnc.setThumbnailSize(%d, %d) fail", __FUNCTION__, thumbnailRect.w, thumbnailRect.h);
            ret = INVALID_OPERATION;
            goto jpeg_encode_done;
        }
        if (0 < thumbnailQuality && thumbnailQuality <= 100) {
            if (m_jpegEnc.setThumbnailQuality(thumbnailQuality)) {
                ret = INVALID_OPERATION;
                ALOGE("ERR(%s):m_jpegEnc.setThumbnailQuality(%d) fail", __FUNCTION__, thumbnailQuality);
            }
        }
    } else {
        exifInfo.enableThumb = false;
    }

    /* wait for medata update */
    if(newFrame->getMetaDataEnable() == false) {
        CLOGD("DEBUG(%s[%d]): Waiting for update jpeg metadata failed (%d) ", __FUNCTION__, __LINE__, ret);
    }

    /* get dynamic meters for make exif info */
    newFrame->getDynamicMeta(&shot_ext);
    newFrame->getUserDynamicMeta(&shot_ext);

    m_parameters->setExifChangedAttribute(&exifInfo, &pictureRect, &thumbnailRect,&shot_ext.shot.dm, &shot_ext.shot.udm);

    if (m_jpegEnc.setInBuf((int *)&(yuvBuf.fd), (int *)yuvBuf.size)) {
        ALOGE("ERR(%s):m_jpegEnc.setInBuf() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.setOutBuf(jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2])) {
        ALOGE("ERR(%s):m_jpegEnc.setOutBuf() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.updateConfig()) {
        ALOGE("ERR(%s):m_jpegEnc.updateConfig() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    if (m_jpegEnc.encode((int *)&jpegBuf.size, &exifInfo, m_parameters->getDebugAttribute())) {
        ALOGE("ERR(%s):m_jpegEnc.encode() fail", __FUNCTION__);
        ret = INVALID_OPERATION;
        goto jpeg_encode_done;
    }

    newFrame->setJpegSize(jpegBuf.size[0]);

    ret = newFrame->setEntityState(getPipeId(), ENTITY_STATE_FRAME_DONE);
    if (ret < 0) {
        CLOGE("ERR(%s[%d]):set entity state fail, ret(%d)", __FUNCTION__, __LINE__, ret);
        /* TODO: doing exception handling */
        return OK;
    }

    m_outputFrameQ->pushProcessQ(&newFrame);

jpeg_encode_done:
    if (ret != NO_ERROR) {
        ALOGD("[jpegBuf.fd[0] %d][jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2] %d]",
            jpegBuf.fd[0], jpegBuf.size[0] + jpegBuf.size[1] + jpegBuf.size[2]);
        ALOGD("[pictureW %d][pictureH %d][pictureFormat %d]",
            pictureRect.w, pictureRect.h, pictureRect.colorFormat);
    }

    if (m_jpegEnc.flagCreate() == true)
        m_jpegEnc.destroy();

    ALOGI("DEBUG(%s[%d]): -OUT-", __FUNCTION__, __LINE__);

    return ret;
}