/* ** Function Name : MFC_IOControl ** ** Function Description : This function support any process of MFC instance. */ BOOL MFC_IOControl( DWORD OpenHandle, DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned ) { MFC_HANDLE *handle; MFCInstCtx *pMfcInst; MFC_ARGS *args; int ret = MFCINST_RET_OK; unsigned char *p_buf = NULL; int n_bufsize = 0; PVOID pMarshalledInBuf = NULL; static CEDEVICE_POWER_STATE mfc_pwr_state; BOOL result = TRUE; handle = (MFC_HANDLE *) OpenHandle; ///////////////////// // Parameter Check // ///////////////////// if (handle == NULL) { LOG_MSG(LOG_TRACE, "MFC_IOControl", "OpenHandle == NULL\n"); return FALSE; } if (handle != gMfcHandlePower) { if (pInBuf == NULL) { LOG_MSG(LOG_TRACE, "MFC_IOControl", "pInBuf == NULL\n"); return FALSE; } if (nInBufSize == 0) { LOG_MSG(LOG_TRACE, "MFC_IOControl", "nInBufSize == 0\n"); return FALSE; } if ((pOutBuf != NULL) || (nOutBufSize != 0) || (pBytesReturned != NULL)) { LOG_MSG(LOG_TRACE, "MFC_IOControl", "others.....\n"); return FALSE; } } pMfcInst = handle->mfc_inst; MFC_Mutex_Lock(); switch ( dwIoControlCode ) { case IOCTL_POWER_CAPABILITIES: { RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES]\n")); PPOWER_CAPABILITIES ppc; if ( !pBytesReturned || !pOutBuf || (nOutBufSize < sizeof(POWER_CAPABILITIES)) ) { SetLastError (ERROR_INVALID_PARAMETER); MFC_Mutex_Release(); return FALSE; } __try { ppc = (PPOWER_CAPABILITIES)pOutBuf; memset(ppc, 0, sizeof(POWER_CAPABILITIES)); // support D0, D4 ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D4); // no wake // no inrush // Report our nominal power consumption in uAmps rather than mWatts. ppc->Flags = POWER_CAP_PREFIX_MICRO | POWER_CAP_UNIT_AMPS; *pBytesReturned = sizeof(POWER_CAPABILITIES); RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] leaving...\n")); } __except(EXCEPTION_EXECUTE_HANDLER) { RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] exception...\n")); MFC_Mutex_Release(); return FALSE; } break; } case IOCTL_POWER_SET: CEDEVICE_POWER_STATE NewDx; //if caller is not kernel mode, do not allow setting power state if (GetDirectCallerProcessId() != GetCurrentProcessId()) { RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] User mode access denied\r\n")); MFC_Mutex_Release(); return ERROR_ACCESS_DENIED; } __try { if (pOutBuf == NULL) { return FALSE; } NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf; switch ( NewDx ) { case D0: // Power Up *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerUp(OpenHandle, &mfc_pwr_state); break; case D4: // Power Down *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerDown(OpenHandle, &mfc_pwr_state); break; default: MFC_Mutex_Release(); return FALSE; } *pBytesReturned = sizeof(CEDEVICE_POWER_STATE); } __except(EXCEPTION_EXECUTE_HANDLER) { RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] exception...\n")); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_MPEG4_ENC_INIT: case IOCTL_MFC_H264_ENC_INIT: case IOCTL_MFC_H263_ENC_INIT: { MFC_CODECMODE codec_mode; enc_info_t enc_info; if (dwIoControlCode == IOCTL_MFC_MPEG4_ENC_INIT) codec_mode = MP4_ENC; else if (dwIoControlCode == IOCTL_MFC_H264_ENC_INIT) codec_mode = AVC_ENC; else codec_mode = H263_ENC; if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; // Input arguments for IOCTL_MFC_xxx_ENC_INIT enc_info.width = args->enc_init.in_width; enc_info.height = args->enc_init.in_height; enc_info.frameRateRes = args->enc_init.in_frameRateRes; enc_info.frameRateDiv = args->enc_init.in_frameRateDiv; enc_info.gopNum = args->enc_init.in_gopNum; enc_info.bitrate = args->enc_init.in_bitrate; enc_info.intraqp = args->enc_init.in_intraqp; enc_info.qpmax = args->enc_init.in_qpmax; enc_info.gamma = args->enc_init.in_gamma; /////////////////////////////////// /// Initialize MFC Instance /// /////////////////////////////////// Mfc_Clk_On(); ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info); Mfc_Clk_Off(); // Output arguments for IOCTL_MFC_xxx_ENC_INIT args->enc_init.ret_code = ret; if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; } case IOCTL_MFC_MPEG4_ENC_EXE: case IOCTL_MFC_H264_ENC_EXE: case IOCTL_MFC_H263_ENC_EXE: { int nStrmLen, nHdrLen; if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; MFCInst_GetFramBuf(pMfcInst, &p_buf, &n_bufsize); CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) ); // nStrmLen is size of output stream data Mfc_Clk_On(); ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen); Mfc_Clk_Off(); MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize); InvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) ); // Output arguments for IOCTL_MFC_xxx_ENC_EXE args->enc_exe.ret_code = ret; if (ret == MFCINST_RET_OK) { args->enc_exe.out_encoded_size = nStrmLen; args->enc_exe.out_header_size = nHdrLen; } if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; } case IOCTL_MFC_MPEG4_DEC_INIT: case IOCTL_MFC_H263_DEC_INIT: case IOCTL_MFC_H264_DEC_INIT: case IOCTL_MFC_VC1_DEC_INIT: { MFC_CODECMODE codec_mode; if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; if (dwIoControlCode == IOCTL_MFC_MPEG4_DEC_INIT) { codec_mode = MP4_DEC; } else if (dwIoControlCode == IOCTL_MFC_H263_DEC_INIT) { codec_mode = MP4_DEC; } else if (dwIoControlCode == IOCTL_MFC_H264_DEC_INIT) { codec_mode = AVC_DEC; } else { codec_mode = VC1_DEC; } ///////////////////////////////// // Initialize MFC Instance // ///////////////////////////////// Mfc_Clk_On(); ret = MFCInst_Dec_Init(pMfcInst, codec_mode, args->dec_init.in_strmSize); Mfc_Clk_Off(); // Output arguments for IOCTL_MFC_xxx_DEC_INIT args->dec_init.ret_code = ret; if (ret == MFCINST_RET_OK) { args->dec_init.out_width = pMfcInst->width; args->dec_init.out_height = pMfcInst->height; } if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; } case IOCTL_MFC_MPEG4_DEC_EXE: case IOCTL_MFC_H263_DEC_EXE: case IOCTL_MFC_H264_DEC_EXE: case IOCTL_MFC_VC1_DEC_EXE: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize); CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) ); Mfc_Clk_On(); ret = MFCInst_Decode(pMfcInst, args->dec_exe.in_strmSize); Mfc_Clk_Off(); // Output arguments for IOCTL_MFC_xxx_DEC_EXE args->dec_exe.ret_code = ret; if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_GET_LINE_BUF_ADDR: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_LINE_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; ret = MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize); if (ret != MFCINST_RET_OK) { goto GetLineBuffCleanup; } if (handle->pStrmBuf == NULL) { // Map the Line buffer for this instance to the caller's address space // handle->hUsrProc = (HANDLE) GetDirectCallerProcessId(); handle->pStrmBuf = (PBYTE) VirtualAllocEx(handle->hUsrProc, NULL, n_bufsize, MEM_RESERVE, PAGE_NOACCESS); if (handle->pStrmBuf == NULL) { RETAILMSG(1, (L"DD::MFC VirtualAllocEx(pStrmBuf) returns FALSE.\n")); ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL; goto GetLineBuffCleanup; } result = VirtualCopyEx(handle->hUsrProc, handle->pStrmBuf, (HANDLE) GetCurrentProcessId(), p_buf, n_bufsize, PAGE_READWRITE ); if (result == FALSE){ RETAILMSG(1, (L"DD::MFC VirtualCopyEx(pStrmBuf) returns FALSE.\n")); VirtualFreeEx(handle->hUsrProc, handle->pStrmBuf, 0, MEM_RELEASE); handle->pStrmBuf = NULL; ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL; goto GetLineBuffCleanup; } } // Output arguments for IOCTL_MFC_GET_FRAM_BUF_ADDR args->get_buf_addr.out_buf_size = n_bufsize; args->get_buf_addr.out_buf_addr = (int) handle->pStrmBuf; GetLineBuffCleanup: args->get_buf_addr.ret_code = ret; if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_LINE_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_GET_FRAM_BUF_ADDR: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_FRAM_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; // Decoder case ret = MFCInst_GetFramBuf(pMfcInst, &p_buf, &n_bufsize); if (ret != MFCINST_RET_OK) { goto GetFrameBuffCleanup; } // Check Paramter if (pMfcInst->run_index * n_bufsize < 0 || (pMfcInst->run_index * n_bufsize) > (int)(pMfcInst->nFramBufSize)) { RETAILMSG(1, (L"[MFC ERROR] IOCTL_MFC_GET_FRAM_BUF_ADDR: Run Index out of range.\r\n")); ret = MFCINST_ERR_ETC; goto GetFrameBuffCleanup; } if (handle->pFramBuf == NULL) { // Map the Frame buffer for this instance to the caller's address space // handle->hUsrProc = (HANDLE) GetDirectCallerProcessId(); handle->pFramBuf = (PBYTE) VirtualAllocEx(handle->hUsrProc, NULL, pMfcInst->nFramBufSize, MEM_RESERVE, PAGE_NOACCESS); if (handle->pFramBuf == NULL) { RETAILMSG(1, (L"DD::MFC VirtualAllocEx(pFramBuf) returns FALSE.\n")); ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL; goto GetFrameBuffCleanup; } result= VirtualCopyEx(handle->hUsrProc, // HANDLE hDstProc handle->pFramBuf, (HANDLE) GetCurrentProcessId(), // HANDLE hSrcProc pMfcInst->pFramBuf, pMfcInst->nFramBufSize, PAGE_READWRITE); if (result == FALSE) { RETAILMSG(1, (L"DD::MFC VirtualCopyEx(pFramBuf) returns FALSE.\n")); VirtualFreeEx(handle->hUsrProc, handle->pFramBuf, 0, MEM_RELEASE); handle->pFramBuf = NULL; ret = MFCINST_ERR_MEMORY_ALLOCATION_FAIL; goto GetFrameBuffCleanup; } } if (pMfcInst->run_index >= 0) { args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->run_index * n_bufsize)); #if (MFC_ROTATE_ENABLE == 1) // If PostRotMode is enabled, then the output YUV buffer will be different. // In VC-1 mode, the rotated output will be the original one. if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->frambufCnt * n_bufsize)); } #endif } else { args->get_buf_addr.out_buf_addr = 0; } args->get_buf_addr.out_buf_size = n_bufsize; GetFrameBuffCleanup: args->get_buf_addr.ret_code = ret; if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_FRAM_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; // Decoder case ret = MFCInst_GetFramBufPhysical(pMfcInst, &p_buf, &n_bufsize); // Output arguments for IOCTL_MFC_xxx_DEC_EXE args->get_buf_addr.ret_code = ret; if (ret == MFCINST_RET_OK) { // Output arguments for IOCTL_MFC_GET_FRAM_BUF_ADDR args->get_buf_addr.out_buf_addr = (int) p_buf; args->get_buf_addr.out_buf_size = n_bufsize; } if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_GET_MPEG4_ASP_PARAM: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_MPEG4_ASP_PARAM.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; #if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1)) ret = MFCINST_RET_OK; args->mpeg4_asp_param.ret_code = MFCINST_RET_OK; args->mpeg4_asp_param.mp4asp_vop_time_res = pMfcInst->RET_DEC_SEQ_INIT_BAK_MP4ASP_VOP_TIME_RES; args->mpeg4_asp_param.byte_consumed = pMfcInst->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED; args->mpeg4_asp_param.mp4asp_fcode = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE; args->mpeg4_asp_param.mp4asp_time_base_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST; args->mpeg4_asp_param.mp4asp_nonb_time_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST; args->mpeg4_asp_param.mp4asp_trd = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD; #if (_WIN32_WCE >= 600) if (handle->pFramBuf != NULL){ args->mpeg4_asp_param.mv_addr = ((unsigned int) handle->pFramBuf) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf); args->mpeg4_asp_param.mb_type_addr = args->mpeg4_asp_param.mv_addr + 25920; args->mpeg4_asp_param.mv_size = 25920; // '25920' is the maximum MV size (=45*36*16) args->mpeg4_asp_param.mb_type_size = 1620; // '1620' is the maximum MBTYE size (=45*36*1) } #else args->mpeg4_asp_param.mv_addr = ((unsigned int) pMfcInst->pFramBuf) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf); args->mpeg4_asp_param.mb_type_addr = args->mpeg4_asp_param.mv_addr + 25920; args->mpeg4_asp_param.mv_size = 25920; args->mpeg4_asp_param.mb_type_size = 1620; #endif InvalidateCacheRange((PBYTE )args->mpeg4_asp_param.mv_addr, (PBYTE )(args->mpeg4_asp_param.mv_addr + args->mpeg4_asp_param.mv_size) ); InvalidateCacheRange((PBYTE )args->mpeg4_asp_param.mb_type_addr , (PBYTE )(args->mpeg4_asp_param.mb_type_addr + args->mpeg4_asp_param.mb_type_size) ); #endif if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_MPEG4_ASP_PARAM.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_GET_CONFIG: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_CONFIG.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; ret = MFC_GetConfigParams(pMfcInst, args); if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_GET_CONFIG.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; case IOCTL_MFC_SET_CONFIG: if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_SET_CONFIG.\r\n"))); MFC_Mutex_Release(); return FALSE; } args = (MFC_ARGS *)pMarshalledInBuf; Mfc_Clk_On(); ret = MFC_SetConfigParams(pMfcInst, args); Mfc_Clk_Off(); if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR))) { RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_SET_CONFIG.\r\n"))); MFC_Mutex_Release(); return FALSE; } break; default: RETAILMSG(1, (L"[MFC IOControl] Requested ioctl command is not defined. (ioctl cmd=0x%X)\n", dwIoControlCode)); MFC_Mutex_Release(); return FALSE; } MFC_Mutex_Release(); switch (ret) { case MFCINST_RET_OK: return TRUE; default: return FALSE; } return FALSE; }
static int s3c_mfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; MFCInstCtx *pMfcInst; MFC_HANDLE *handle; unsigned char *OutBuf = NULL; MFC_CODECMODE codec_mode = 0; int buf_size; unsigned int tmp; MFC_ARGS args; enc_info_t enc_info; // modified by RainAde for header type of mpeg4 (+ VOS/VO) #if 1 // Hdr0 : SPS or VOL // Hdr1 : PPS or VOS // Hdr2 : VO (VIS) int nStrmLen, nHdrLen, nHdr0Len, nHdr1Len, nHdr2Len; #else // modified by RainAde for composer interface int nStrmLen, nHdrLen, nSps, nPps; #endif void *temp; unsigned int vir_mv_addr; unsigned int vir_mb_type_addr; ////////////////////// // Parameter Check // ////////////////////// handle = (MFC_HANDLE *)file->private_data; if (handle->mfc_inst == NULL) { return -EFAULT; } pMfcInst = handle->mfc_inst; switch(cmd) { case IOCTL_MFC_MPEG4_ENC_INIT: case IOCTL_MFC_H264_ENC_INIT: case IOCTL_MFC_H263_ENC_INIT: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "mfc_ioctl", "cmd = %d\r\n", cmd); Copy_From_User(&args.enc_init, (MFC_ENC_INIT_ARG *)arg, sizeof(MFC_ENC_INIT_ARG)); if ( cmd == IOCTL_MFC_MPEG4_ENC_INIT ) codec_mode = MP4_ENC; else if ( cmd == IOCTL_MFC_H264_ENC_INIT ) codec_mode = AVC_ENC; else if ( cmd == IOCTL_MFC_H263_ENC_INIT ) codec_mode = H263_ENC; ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// enc_info.width = args.enc_init.in_width; enc_info.height = args.enc_init.in_height; enc_info.bitrate = args.enc_init.in_bitrate; enc_info.gopNum = args.enc_init.in_gopNum; enc_info.frameRateRes = args.enc_init.in_frameRateRes; enc_info.frameRateDiv = args.enc_init.in_frameRateDiv; ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info); args.enc_init.ret_code = ret; Copy_To_User((MFC_ENC_INIT_ARG *)arg, &args.enc_init, sizeof(MFC_ENC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_ENC_EXE: case IOCTL_MFC_H264_ENC_EXE: case IOCTL_MFC_H263_ENC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.enc_exe, (MFC_ENC_EXE_ARG *)arg, sizeof(MFC_ENC_EXE_ARG)); tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; // from 2.8.5 //dmac_clean_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); //outer_clean_range(__pa(pMfcInst->pFramBuf), __pa(pMfcInst->pFramBuf + tmp)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); ////////////////////////// // Decode MFC Instance // ////////////////////////// // modified by RainAde for composer interface //ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len); // modified by RainAde for header type of mpeg4 (+ VOS/VO) ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len, &nHdr2Len); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); args.enc_exe.ret_code = ret; if (ret == MFCINST_RET_OK) { args.enc_exe.out_encoded_size = nStrmLen; args.enc_exe.out_header_size = nHdrLen; // modified by RainAde for composer interface args.enc_exe.out_header0_size = nHdr0Len; args.enc_exe.out_header1_size = nHdr1Len; // modified by RainAde for header type of mpeg4 (+ VOS/VO) args.enc_exe.out_header2_size = nHdr2Len; } Copy_To_User((MFC_ENC_EXE_ARG *)arg, &args.enc_exe, sizeof(MFC_ENC_EXE_ARG)); // added by RainAde for cache coherency cpu_cache.dma_inv_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_INIT: case IOCTL_MFC_H264_DEC_INIT: case IOCTL_MFC_H263_DEC_INIT: case IOCTL_MFC_VC1_DEC_INIT: MFC_Mutex_Lock(); #ifdef CONFIG_MACH_SATURN lcd_gamma_change(LCD_VIDEO); // when decoder init to start playing video, AMOLED gamma set to video mode #endif Copy_From_User(&args.dec_init, (MFC_DEC_INIT_ARG *)arg, sizeof(MFC_DEC_INIT_ARG)); // yj: fix the PiP problem cpu_cache.flush_kern_all(); if ( cmd == IOCTL_MFC_MPEG4_DEC_INIT ) codec_mode = MP4_DEC; else if ( cmd == IOCTL_MFC_H264_DEC_INIT ) codec_mode = AVC_DEC; else if ( cmd == IOCTL_MFC_H263_DEC_INIT) codec_mode = H263_DEC; else { codec_mode = VC1_DEC; } ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// ret = MFCInst_Init(pMfcInst, codec_mode, args.dec_init.in_strmSize); args.dec_init.ret_code = ret; if (ret == MFCINST_RET_OK) { args.dec_init.out_width = pMfcInst->width; args.dec_init.out_height = pMfcInst->height; args.dec_init.out_buf_width = pMfcInst->buf_width; args.dec_init.out_buf_height = pMfcInst->buf_height; } Copy_To_User((MFC_DEC_INIT_ARG *)arg, &args.dec_init, sizeof(MFC_DEC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_EXE: case IOCTL_MFC_H264_DEC_EXE: case IOCTL_MFC_H263_DEC_EXE: case IOCTL_MFC_VC1_DEC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.dec_exe, (MFC_DEC_EXE_ARG *)arg, sizeof(MFC_DEC_EXE_ARG)); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); if (pMfcInst->inbuf_type == DEC_INBUF_LINE_BUF) { ret = MFCInst_Decode(pMfcInst, args.dec_exe.in_strmSize); } else if (pMfcInst->inbuf_type == DEC_INBUF_RING_BUF) { ret = MFCInst_Decode_Stream(pMfcInst, args.dec_exe.in_strmSize); } else { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "Buffer type is not defined.\n"); MFC_Mutex_Release(); args.dec_exe.ret_code = -1; return -EINVAL; } args.dec_exe.ret_code = ret; Copy_To_User((MFC_DEC_EXE_ARG *)arg, &args.dec_exe, sizeof(MFC_DEC_EXE_ARG)); // added by RainAde for cache coherency tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; cpu_cache.dma_inv_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_RING_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetRingBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + ((int)(OutBuf - GetDataBufVirAddr())); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_LINE_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetLineBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (OutBuf - GetDataBufVirAddr()); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_DBK_BUF_ADDR: // newly added by yj: returns to DBK_BUF' virtual address and its size. MFC_Mutex_Lock(); Copy_From_User(&args.get_dbkbuf_addr, (MFC_GET_DBK_BUF_ARG *)arg, sizeof(MFC_GET_DBK_BUF_ARG)); if (pMfcInst->isMp4DbkOn != 1) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC DBK_BUF is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } args.get_dbkbuf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; args.get_dbkbuf_addr.out_buf_addr = args.get_dbkbuf_addr.in_usr_mapped_addr + ((unsigned int)GetDbkBufVirAddr() - (unsigned int)GetDataBufVirAddr()); args.get_dbkbuf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_DBK_BUF_ARG *)arg, &args.get_dbkbuf_addr, sizeof(MFC_GET_DBK_BUF_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); if (pMfcInst->pFramBuf == NULL) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC Frame buffer is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } // FRAM_BUF address is calculated differently for Encoder and Decoder. switch (pMfcInst->codec_mode) { case MP4_DEC: case AVC_DEC: case VC1_DEC: case H263_DEC: // Decoder case args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif args.get_buf_addr.out_buf_addr = tmp; break; case MP4_ENC: case AVC_ENC: case H263_ENC: // Encoder case tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (pMfcInst->idx * tmp) + (int)(pMfcInst->pFramBuf - GetDataBufVirAddr()); break; } args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; // args.get_buf_addr.out_buf_size = ((pMfcInst->width+2*DIVX_PADDING) * (pMfcInst->height+2*DIVX_PADDING) * 3) >> 1; tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); //.[ i: sichoi 081103 (ROTATE) #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif //.] sichoi 081103 args.get_buf_addr.out_buf_addr = tmp; args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_MPEG4_ASP_PARAM: #if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1)) Copy_From_User(&args.mpeg4_asp_param, (MFC_GET_MPEG4ASP_ARG *)arg, sizeof(MFC_GET_MPEG4ASP_ARG)); ret = MFCINST_RET_OK; args.mpeg4_asp_param.ret_code = MFCINST_RET_OK; args.mpeg4_asp_param.mp4asp_vop_time_res = pMfcInst->RET_DEC_SEQ_INIT_BAK_MP4ASP_VOP_TIME_RES; args.mpeg4_asp_param.byte_consumed = pMfcInst->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED; args.mpeg4_asp_param.mp4asp_fcode = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE; args.mpeg4_asp_param.mp4asp_time_base_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST; args.mpeg4_asp_param.mp4asp_nonb_time_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST; args.mpeg4_asp_param.mp4asp_trd = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD; args.mpeg4_asp_param.mv_addr = (args.mpeg4_asp_param.in_usr_mapped_addr + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf); args.mpeg4_asp_param.mb_type_addr = args.mpeg4_asp_param.mv_addr + 25920; args.mpeg4_asp_param.mv_size = 25920; args.mpeg4_asp_param.mb_type_size = 1620; vir_mv_addr = (unsigned int)((pMfcInst->pStrmBuf + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf)); vir_mb_type_addr = vir_mv_addr + 25920; Copy_To_User((MFC_GET_MPEG4ASP_ARG *)arg, &args.mpeg4_asp_param, sizeof(MFC_GET_MPEG4ASP_ARG)); // from 2.8.5 //dmac_clean_range(vir_mv_addr, vir_mv_addr + args.mpeg4_asp_param.mv_size); //outer_clean_range(__pa(vir_mv_addr), __pa(vir_mv_addr + args.mpeg4_asp_param.mv_size)); //dmac_clean_range(vir_mb_type_addr, vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size); //outer_clean_range(__pa(vir_mb_type_addr), __pa(vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size)); #endif break; case IOCTL_MFC_GET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_GetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_SetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_H263_MULTIPLE_SLICE: MFC_Mutex_Lock(); pMfcInst->multiple_slice = 1; MFC_Mutex_Release(); break; case IOCTL_VIRT_TO_PHYS: //MFC_Mutex_Lock(); temp = __virt_to_phys((void *)arg); return (int)temp; //MFC_Mutex_Release(); break; default: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "s3c_mfc_ioctl", "Requested ioctl command is not defined. (ioctl cmd=0x%X)\n", cmd); MFC_Mutex_Release(); return -EINVAL; } switch(ret) { case MFCINST_RET_OK: return TRUE; default: return -1; } return -1; }