Esempio n. 1
0
SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info)
{
    int ret_code;
    _MFCLIB *pCTX;
    mfc_common_args user_addr_arg, phys_addr_arg;
    int y_size, c_size;
    int aligned_y_size, aligned_c_size;

    if (openHandle == NULL) {
        fprintf(stderr,"SsbSipMfcEncGetInBuf: openHandle is NULL\n");
        return MFC_RET_INVALID_PARAM;
    }

    pCTX = (_MFCLIB *)openHandle;

    user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type;

    y_size = pCTX->width * pCTX->height;
    c_size = (pCTX->width * pCTX->height) >> 1;

    aligned_y_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height));
    aligned_c_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height/2));

    /* Allocate luma & chroma buf */
    user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size;
    user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr;
    ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg);
    if (ret_code < 0) {
        fprintf(stderr,"SsbSipMfcEncGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n");
        return MFC_RET_ENC_GET_INBUF_FAIL;
    }
    pCTX->virFrmBuf.luma = user_addr_arg.args.mem_alloc.out_uaddr;
    pCTX->virFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_uaddr + (unsigned int)aligned_y_size;
    pCTX->phyFrmBuf.luma = user_addr_arg.args.mem_alloc.out_paddr;
    pCTX->phyFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_paddr + (unsigned int)aligned_y_size;

    pCTX->sizeFrmBuf.luma = (unsigned int)y_size;
    pCTX->sizeFrmBuf.chroma = (unsigned int)c_size;
    pCTX->inter_buff_status |= MFC_USE_YUV_BUFF;

    input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma;
    input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma;
    input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma;
    input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma;

    input_info->YSize    = aligned_y_size;
    input_info->CSize    = aligned_c_size;

    return MFC_RET_OK;
}
OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData)
{
    OMX_ERRORTYPE              ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT     *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_MPEG4ENC_HANDLE       *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle;
    OMX_HANDLETYPE             hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle;
    SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo);
    SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo;
    SEC_OMX_BASEPORT          *pSECPort = NULL;
    MFC_ENC_ADDR_INFO          addrInfo;
    OMX_U32                    oneFrameSize = pInputData->dataLen;
    OMX_S32                    returnCodec = 0;

    FunctionIn();

    if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) {
        returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo);
        if (returnCodec != MFC_RET_OK)
        {
            SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec);
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }

        pOutputData->dataBuffer = outputInfo.StrmVirAddr;
        pOutputData->allocSize = outputInfo.headerSize;
        pOutputData->dataLen = outputInfo.headerSize;
        pOutputData->timeStamp = pInputData->timeStamp;
        pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
        pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;

        pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE;

        if (pOutputData->dataLen > 0) {
            ret = OMX_ErrorNone;
            goto EXIT;
        } else {
            ret = OMX_ErrorInputDataEncodeYet;
            goto EXIT;
        }
    }

    if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) &&
        (pSECComponent->bUseFlagEOF == OMX_FALSE)) {
        pSECComponent->bUseFlagEOF = OMX_TRUE;
    }

    pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp;
    pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags;
    SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp));
    pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++;
    if (pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp >= MAX_TIMESTAMP)
        pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0;

    if (oneFrameSize <= 0) {
        pOutputData->timeStamp = pInputData->timeStamp;
        pOutputData->nFlags = pInputData->nFlags;

        ret = OMX_ErrorNone;
        goto EXIT;
    }

    pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX];
    if (pSECPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress) {
    /* input data from Real camera */
#define USE_FIMC_FRAME_BUFFER
#ifdef USE_FIMC_FRAME_BUFFER
        SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY));
        SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC));
        pInputInfo->YPhyAddr = addrInfo.pAddrY;
        pInputInfo->CPhyAddr = addrInfo.pAddrC;
        returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo);
        if (returnCodec != MFC_RET_OK) {
            SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, returnCodec);
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }
#else
        OMX_U32 width, height;

        width = pSECPort->portDefinition.format.video.nFrameWidth;
        height = pSECPort->portDefinition.format.video.nFrameHeight;

        SEC_OSAL_Memcpy(pInputInfo->YVirAddr, pInputData->dataBuffer, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)));
        SEC_OSAL_Memcpy(pInputInfo->CVirAddr, pInputData->dataBuffer + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2)));
#endif
    }

    returnCodec = SsbSipMfcEncExe(hMFCHandle);
    if (returnCodec == MFC_RET_OK) {
        OMX_S32 indexTimestamp = 0;

        returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo);

        if ((SsbSipMfcEncGetConfig(hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) ||
            (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))) {
            pOutputData->timeStamp = pInputData->timeStamp;
            pOutputData->nFlags = pInputData->nFlags;
        } else {
            pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp];
            pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp];
        }

        if (returnCodec == MFC_RET_OK) {
            /** Fill Output Buffer **/
            pOutputData->dataBuffer = outputInfo.StrmVirAddr;
            pOutputData->allocSize = outputInfo.dataSize;
            pOutputData->dataLen = outputInfo.dataSize;
            pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
            if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME)
                    pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;

            ret = OMX_ErrorNone;
        } else {
            SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec);
            ret = OMX_ErrorUndefined;
        }
    } else {
        SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, returnCodec);
        ret = OMX_ErrorUndefined;
    }

EXIT:
    FunctionOut();

    return ret;
}
Esempio n. 3
0
static long mfc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret, ex_ret;
	struct mfc_inst_ctx *mfc_ctx = NULL;
	struct mfc_common_args in_param;

	mutex_lock(&mfc_mutex);
	clk_enable(mfc_sclk);

	ret = copy_from_user(&in_param, (struct mfc_common_args *)arg, sizeof(struct mfc_common_args));
	if (ret < 0) {
		mfc_err("Inparm copy error\n");
		ret = -EIO;
		in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
		goto out_ioctl;
	}

	mfc_ctx = (struct mfc_inst_ctx *)file->private_data;
	mutex_unlock(&mfc_mutex);

	switch (cmd) {
	case IOCTL_MFC_ENC_INIT:
		mutex_lock(&mfc_mutex);

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_INITIALIZE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		/* MFC encode init */
		in_param.ret_code = mfc_init_encode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_ENC_EXE:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_ENC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_EXE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_exe_encode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_DEC_INIT:
		mutex_lock(&mfc_mutex);
		if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_INITIALIZE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		/* MFC decode init */
		in_param.ret_code = mfc_init_decode(mfc_ctx, &(in_param.args));
		if (in_param.ret_code < 0) {
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (in_param.args.dec_init.out_dpb_cnt <= 0) {
			mfc_err("MFC out_dpb_cnt error\n");
			mutex_unlock(&mfc_mutex);
			break;
		}

		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_DEC_EXE:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_EXE) < 0) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_exe_decode(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_CONFIG:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_get_config(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_SET_CONFIG:
		mutex_lock(&mfc_mutex);
		in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_IN_BUF:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if (in_param.args.mem_alloc.buff_size <= 0) {
			mfc_err("MFCINST_ERR_INVALID_PARAM\n");
			in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		if ((is_dec_codec(in_param.args.mem_alloc.codec_type)) &&
				(in_param.args.mem_alloc.buff_size < (CPB_BUF_SIZE + DESC_BUF_SIZE))) {
			in_param.args.mem_alloc.buff_size = CPB_BUF_SIZE + DESC_BUF_SIZE;
		}

		/* Buffer manager should have 64KB alignment for MFC base addresses */
		in_param.args.mem_alloc.buff_size = ALIGN_TO_8KB(in_param.args.mem_alloc.buff_size);

		/* allocate stream buf for decoder & current YC buf for encoder */
		if (is_dec_codec(in_param.args.mem_alloc.codec_type))
			in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 0);
		else
			in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 1);

		mfc_ctx->desc_buff_paddr = in_param.args.mem_alloc.out_paddr + CPB_BUF_SIZE;

		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_FREE_BUF:
		mutex_lock(&mfc_mutex);
		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_release_buffer((unsigned char *)in_param.args.mem_free.u_addr);
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_PHYS_ADDR:
		mutex_lock(&mfc_mutex);
		mfc_debug("IOCTL_MFC_GET_PHYS_ADDR\n");

		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFCINST_ERR_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;
			mutex_unlock(&mfc_mutex);
			break;
		}

		in_param.ret_code = mfc_get_phys_addr(mfc_ctx, &(in_param.args));
		ret = in_param.ret_code;
		mutex_unlock(&mfc_mutex);
		break;

	case IOCTL_MFC_GET_MMAP_SIZE:

		if (mfc_ctx->MfcState < MFCINST_STATE_OPENED) {
			mfc_err("MFC_RET_STATE_INVALID\n");
			in_param.ret_code = MFCINST_ERR_STATE_INVALID;
			ret = -EINVAL;

			break;
		}

		in_param.ret_code = MFCINST_RET_OK;
		ret = mfc_ctx->port0_mmap_size;

		break;

	case IOCTL_MFC_BUF_CACHE:
		mutex_lock(&mfc_mutex);

		in_param.ret_code = MFCINST_RET_OK;
		mfc_ctx->buf_type = in_param.args.buf_type;

		mutex_unlock(&mfc_mutex);
		break;

	default:
		mfc_err("Requested ioctl command is not defined. (ioctl cmd=0x%08x)\n", cmd);
		in_param.ret_code  = MFCINST_ERR_INVALID_PARAM;
		ret = -EINVAL;
	}

out_ioctl:
	clk_disable(mfc_sclk);

	ex_ret = copy_to_user((struct mfc_common_args *)arg, &in_param, sizeof(struct mfc_common_args));
	if (ex_ret < 0) {
		mfc_err("Outparm copy to user error\n");
		ret = -EIO;
	}

	mfc_debug_L0("---------------IOCTL return = %d ---------------\n", ret);

	return ret;
}
OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData)
{
    OMX_ERRORTYPE              ret = OMX_ErrorNone;
    SEC_OMX_BASECOMPONENT     *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
    SEC_H264ENC_HANDLE        *pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle;
    SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo;
    SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo;
    SEC_OMX_BASEPORT          *pSECPort = NULL;
    MFC_ENC_ADDR_INFO          addrInfo;
    OMX_U32                    oneFrameSize = pInputData->dataLen;
    OMX_S32                    returnCodec = 0;

    FunctionIn();

    if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) {
        returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo);
        if (returnCodec != MFC_RET_OK)
        {
            SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__);
            ret = OMX_ErrorUndefined;
            goto EXIT;
        } else {
            unsigned char *p = NULL;
            int iSpsSize = 0;
            int iPpsSize = 0;

            p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4);

            iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr;
            pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr;
            pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;

            iPpsSize = outputInfo.headerSize - iSpsSize;
            pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = outputInfo.StrmVirAddr + iSpsSize;
            pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
        }

        /* SEC_OSAL_Memcpy((void*)(pOutputData->dataBuffer), (const void*)(outputInfo.StrmVirAddr), outputInfo.headerSize); */
        pOutputData->dataBuffer = outputInfo.StrmVirAddr;
        pOutputData->allocSize = outputInfo.headerSize;
        pOutputData->dataLen = outputInfo.headerSize;
        pOutputData->timeStamp = pInputData->timeStamp;
        pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
        pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;

        pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE;

        ret = OMX_ErrorNone;
        goto EXIT;
    }

    if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) &&
        (pSECComponent->bUseFlagEOF == OMX_FALSE)) {
        pSECComponent->bUseFlagEOF = OMX_TRUE;
    }

    pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp;
    pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags;
    SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp));
    pH264Enc->hMFCH264Handle.indexTimestamp++;
    if (pH264Enc->hMFCH264Handle.indexTimestamp >= MAX_TIMESTAMP)
        pH264Enc->hMFCH264Handle.indexTimestamp = 0;

    if (oneFrameSize <= 0) {
        pOutputData->timeStamp = pInputData->timeStamp;
        pOutputData->nFlags = pInputData->nFlags;

        ret = OMX_ErrorNone;
        goto EXIT;
    }

    pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX];
    if (pSECPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress) {
#define USE_FIMC_FRAME_BUFFER
#ifdef USE_FIMC_FRAME_BUFFER
        SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY));
        SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC));
        pInputInfo->YPhyAddr = addrInfo.pAddrY;
        pInputInfo->CPhyAddr = addrInfo.pAddrC;
        ret = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo);
        if (ret != MFC_RET_OK) {
            SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n");
            ret = OMX_ErrorUndefined;
            goto EXIT;
        }
#else
        OMX_U32 width, height;

        width = pSECPort->portDefinition.format.video.nFrameWidth;
        height = pSECPort->portDefinition.format.video.nFrameHeight;

        SEC_OSAL_Memcpy(pInputInfo->YVirAddr, pInputData->dataBuffer, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)));
        SEC_OSAL_Memcpy(pInputInfo->CVirAddr, pInputData->dataBuffer + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2)));
#endif
    }

    returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle);
    if (returnCodec == MFC_RET_OK) {
        OMX_S32 indexTimestamp = 0;

        returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo);
        if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) ||
            (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))){
            pOutputData->timeStamp = pInputData->timeStamp;
            pOutputData->nFlags = pInputData->nFlags;
        } else {
            pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp];
            pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp];
        }

        if (returnCodec == MFC_RET_OK) {
            /** Fill Output Buffer **/
            pOutputData->dataBuffer = outputInfo.StrmVirAddr;
            pOutputData->allocSize = outputInfo.dataSize;
            pOutputData->dataLen = outputInfo.dataSize;
            pOutputData->usedDataLen = 0;

            pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
            if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME)
                    pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;

            SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");

            ret = OMX_ErrorNone;
        }
    }

    if (returnCodec != MFC_RET_OK) {
        SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe OR SsbSipMfcEncGetOutBuf Failed!!!\n", __func__);
        ret = OMX_ErrorUndefined;
    }

EXIT:
    FunctionOut();

    return ret;
}
Esempio n. 5
0
static int mfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int ret, ex_ret;
	mfc_inst_ctx *mfc_ctx = NULL;
	mfc_common_args in_param;

	mutex_lock(&mfc_mutex);
#if	Frame_Base_Power_CTR_ON
	if (s5pv210_pd_enable("mfc_pd") < 0) {
		printk(KERN_ERR "[Error]The power is not on for mfc\n");
		return -1;
	}
	clk_enable(mfc_clk);
#endif

	ret = copy_from_user(&in_param, (mfc_common_args *)arg, sizeof(mfc_common_args));
	if (ret < 0)
	{
		mfc_err("Inparm copy error\n");
		ret = -EIO;
		in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
		goto out_ioctl;
	}

	mfc_ctx = (mfc_inst_ctx *)file->private_data;
	mutex_unlock(&mfc_mutex);

	switch (cmd)
	{
		case IOCTL_MFC_ENC_INIT:
			mutex_lock(&mfc_mutex);

#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_ENC_INIT\n");
#endif
			if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_INITIALIZE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			/* MFC encode init */
			in_param.ret_code = mfc_init_encode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_ENC_EXE:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_ENC_EXE\n");
#endif

			if (mfc_ctx->MfcState < MFCINST_STATE_ENC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_ENC_EXE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_exe_encode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_DEC_INIT:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_DEC_INIT\n");
#endif

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_INITIALIZE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			/* MFC decode init */
			in_param.ret_code = mfc_init_decode(mfc_ctx, &(in_param.args));
			if (in_param.ret_code < 0)
			{
                                mfc_err("MFC_DEC_INIT ERROR ............. ret(%d)\n",in_param.ret_code);
				ret = in_param.ret_code;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (in_param.args.dec_init.out_dpb_cnt <= 0)
			{
				mfc_err("MFC out_dpb_cnt error\n");
				mutex_unlock(&mfc_mutex);
				break;
			}

			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_DEC_EXE:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_debug_L0("IOCTL_MFC_DEC_EXE\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (mfc_set_state(mfc_ctx, MFCINST_STATE_DEC_EXE) < 0)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_exe_decode(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_CONFIG:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_GET_CONFIG\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_DEC_INITIALIZE)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_get_config(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_SET_CONFIG:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_SET_CONFIG\n");
#endif
			in_param.ret_code = mfc_set_config(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_IN_BUF:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_GET_IN_BUF\n");
#endif
			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if (in_param.args.mem_alloc.buff_size <= 0)
			{
				mfc_err("MFCINST_ERR_INVALID_PARAM\n");
				in_param.ret_code = MFCINST_ERR_INVALID_PARAM;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			if ((is_dec_codec(in_param.args.mem_alloc.codec_type)) &&
				(in_param.args.mem_alloc.buff_size < (CPB_BUF_SIZE + DESC_BUF_SIZE)))
			{
				in_param.args.mem_alloc.buff_size = CPB_BUF_SIZE + DESC_BUF_SIZE;
			}

			/* Buffer manager should have 64KB alignment for MFC base addresses */
			in_param.args.mem_alloc.buff_size = ALIGN_TO_8KB(in_param.args.mem_alloc.buff_size);

			/* allocate stream buf for decoder & current YC buf for encoder */
			if (is_dec_codec(in_param.args.mem_alloc.codec_type))
			{
				in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 0);
			}
			else
			{
				in_param.ret_code = mfc_allocate_buffer(mfc_ctx, &in_param.args, 1);
			}

			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_FREE_BUF:
			mutex_lock(&mfc_mutex);
#if	ENABLE_MONITORING_MFC_DD
			mfc_info("IOCTL_MFC_FREE_BUF\n");
#endif

			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_release_buffer((unsigned char *)in_param.args.mem_free.u_addr);
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		case IOCTL_MFC_GET_PHYS_ADDR:
			mutex_lock(&mfc_mutex);
			mfc_debug("IOCTL_MFC_GET_PHYS_ADDR\n");

			if (mfc_ctx->MfcState < MFCINST_STATE_OPENED)
			{
				mfc_err("MFCINST_ERR_STATE_INVALID\n");
				in_param.ret_code = MFCINST_ERR_STATE_INVALID;
				ret = -EINVAL;
				mutex_unlock(&mfc_mutex);
				break;
			}

			in_param.ret_code = mfc_get_phys_addr(mfc_ctx, &(in_param.args));
			ret = in_param.ret_code;
			mutex_unlock(&mfc_mutex);
			break;

		default:
			mfc_err("Requested ioctl command is not defined. (ioctl cmd=0x%08x)\n", cmd);
			in_param.ret_code  = MFCINST_ERR_INVALID_PARAM;
			ret = -EINVAL;
	}

out_ioctl:
#if	Frame_Base_Power_CTR_ON
	clk_disable(mfc_clk);
	if (s5pv210_pd_disable("mfc_pd") < 0) {
		printk(KERN_ERR "[Error]The power is not off for mfc\n");
		return -1;
	}
#endif

	ex_ret = copy_to_user((mfc_common_args *)arg, &in_param, sizeof(mfc_common_args));
	if (ex_ret < 0)
	{
		mfc_err("Outparm copy to user error\n");
		ret = -EIO;
	}

	mfc_debug_L0("---------------IOCTL return = %d ---------------\n", ret);

	return ret;
}