void imx_vpu_dec_get_bitstream_buffer_info(unsigned int *alignment, size_t *size) { int i; VpuMemInfo mem_info; VPU_DecQueryMem(&mem_info); /* only two sub blocks are ever present - get the VPU_MEM_PHY one */ for (i = 0; i < mem_info.nSubBlockNum; ++i) { if (mem_info.MemSubBlock[i].MemType == VPU_MEM_PHY) { *alignment = mem_info.MemSubBlock[i].nAlignment; *size = mem_info.MemSubBlock[i].nSize; IMX_VPU_TRACE("determined alignment %d and size %d for the physical memory for the bitstream buffer", *alignment, *size); break; } } /* virtual memory block is allocated internally inside imx_vpu_dec_open() */ }
bool CDVDVideoCodecIMX::VpuOpen(void) { VpuDecRetCode ret; VpuVersionInfo vpuVersion; VpuMemInfo memInfo; VpuDecConfig config; int param; memset(&memInfo, 0, sizeof(VpuMemInfo)); ret = VPU_DecLoad(); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - VPU load failed with error code %d.\n", __FUNCTION__, ret); goto VpuOpenError; } ret = VPU_DecGetVersionInfo(&vpuVersion); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - VPU version cannot be read (%d).\n", __FUNCTION__, ret); goto VpuOpenError; } else { if (g_advancedSettings.CanLogComponent(LOGVIDEO)) CLog::Log(LOGDEBUG, "VPU Lib version : major.minor.rel=%d.%d.%d.\n", vpuVersion.nLibMajor, vpuVersion.nLibMinor, vpuVersion.nLibRelease); } ret = VPU_DecQueryMem(&memInfo); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - iMX VPU query mem error (%d).\n", __FUNCTION__, ret); goto VpuOpenError; } VpuAllocBuffers(&memInfo); m_decOpenParam.nReorderEnable = 1; m_decOpenParam.nChromaInterleave = 1; m_decOpenParam.nMapType = 0; m_decOpenParam.nTiled2LinearEnable = 0; m_decOpenParam.nEnableFileMode = 0; ret = VPU_DecOpen(&m_vpuHandle, &m_decOpenParam, &memInfo); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - iMX VPU open failed (%d).\n", __FUNCTION__, ret); goto VpuOpenError; } config = VPU_DEC_CONF_SKIPMODE; param = VPU_DEC_SKIPNONE; ret = VPU_DecConfig(m_vpuHandle, config, ¶m); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - iMX VPU set skip mode failed (%d).\n", __FUNCTION__, ret); goto VpuOpenError; } // Note that libvpufsl (file vpu_wrapper.c) associates VPU_DEC_CAP_FRAMESIZE // capability to the value of nDecFrameRptEnabled which is in fact directly // related to the ability to generate VPU_DEC_ONE_FRM_CONSUMED even if the // naming is misleading... ret = VPU_DecGetCapability(m_vpuHandle, VPU_DEC_CAP_FRAMESIZE, ¶m); m_frameReported = (param != 0); if (ret != VPU_DEC_RET_SUCCESS) { CLog::Log(LOGERROR, "%s - iMX VPU get framesize capability failed (%d).\n", __FUNCTION__, ret); m_frameReported = false; } return true; VpuOpenError: Dispose(); return false; }
ImxVpuDecReturnCodes imx_vpu_dec_open(ImxVpuDecoder **decoder, ImxVpuDecOpenParams const *open_params, void *bitstream_buffer_virtual_address, imx_vpu_phys_addr_t bitstream_buffer_physical_addres) { int config_param; VpuDecRetCode ret; VpuMemInfo mem_info; VpuDecOpenParam open_param; *decoder = IMX_VPU_ALLOC(sizeof(ImxVpuDecoder)); if ((*decoder) == NULL) { IMX_VPU_ERROR("allocating memory for decoder object failed"); return IMX_VPU_DEC_RETURN_CODE_ERROR; } memset(*decoder, 0, sizeof(ImxVpuDecoder)); { int i; VPU_DecQueryMem(&mem_info); IMX_VPU_INFO("about to allocate %d memory sub blocks", mem_info.nSubBlockNum); for (i = 0; i < mem_info.nSubBlockNum; ++i) { char const *type_str = "<unknown>"; VpuMemSubBlockInfo *sub_block = &(mem_info.MemSubBlock[i]); switch (sub_block->MemType) { case VPU_MEM_VIRT: type_str = "virtual"; (*decoder)->virt_mem_sub_block_size = sub_block->nSize + sub_block->nAlignment; (*decoder)->virt_mem_sub_block = IMX_VPU_ALLOC((*decoder)->virt_mem_sub_block_size); if ((*decoder)->virt_mem_sub_block == NULL) { IMX_VPU_ERROR("allocating memory for sub block failed"); return IMX_VPU_DEC_RETURN_CODE_ERROR; } sub_block->pVirtAddr = (unsigned char *)IMX_VPU_ALIGN_VAL_TO((*decoder)->virt_mem_sub_block, sub_block->nAlignment); sub_block->pPhyAddr = 0; break; case VPU_MEM_PHY: type_str = "physical"; sub_block->pVirtAddr = (unsigned char *)(bitstream_buffer_virtual_address); sub_block->pPhyAddr = (unsigned char *)(bitstream_buffer_physical_addres); break; default: break; } IMX_VPU_INFO("allocated memory sub block #%d: type: %s size: %d alignment: %d virtual address: %p physical address: %p", i, type_str, sub_block->nSize, sub_block->nAlignment, sub_block->pVirtAddr, sub_block->pPhyAddr); } } dec_convert_to_wrapper_open_param(open_params, &open_param); IMX_VPU_TRACE("opening decoder"); switch (open_params->codec_format) { case IMX_VPU_CODEC_FORMAT_H264: case IMX_VPU_CODEC_FORMAT_H264_MVC: case IMX_VPU_CODEC_FORMAT_MPEG2: case IMX_VPU_CODEC_FORMAT_MPEG4: (*decoder)->consumption_info_available = TRUE; (*decoder)->flush_vpu_upon_reset = TRUE; break; case IMX_VPU_CODEC_FORMAT_H263: case IMX_VPU_CODEC_FORMAT_WMV3: case IMX_VPU_CODEC_FORMAT_WVC1: (*decoder)->consumption_info_available = FALSE; (*decoder)->flush_vpu_upon_reset = FALSE; break; case IMX_VPU_CODEC_FORMAT_MJPEG: case IMX_VPU_CODEC_FORMAT_VP8: (*decoder)->consumption_info_available = FALSE; (*decoder)->flush_vpu_upon_reset = TRUE; break; default: break; } ret = VPU_DecOpen(&((*decoder)->handle), &open_param, &mem_info); if (ret != VPU_DEC_RET_SUCCESS) { IMX_VPU_ERROR("opening decoder failed: %s", imx_vpu_dec_error_string(dec_convert_retcode(ret))); goto cleanup; } IMX_VPU_TRACE("setting configuration"); config_param = VPU_DEC_SKIPNONE; ret = VPU_DecConfig((*decoder)->handle, VPU_DEC_CONF_SKIPMODE, &config_param); if (ret != VPU_DEC_RET_SUCCESS) { IMX_VPU_ERROR("setting skipmode to NONE failed: %s", imx_vpu_dec_error_string(dec_convert_retcode(ret))); goto cleanup; } config_param = 0; ret = VPU_DecConfig((*decoder)->handle, VPU_DEC_CONF_BUFDELAY, &config_param); if (ret != VPU_DEC_RET_SUCCESS) { IMX_VPU_ERROR("setting bufdelay to 0 failed: %s", imx_vpu_dec_error_string(dec_convert_retcode(ret))); goto cleanup; } config_param = VPU_DEC_IN_NORMAL; ret = VPU_DecConfig((*decoder)->handle, VPU_DEC_CONF_INPUTTYPE, &config_param); if (ret != VPU_DEC_RET_SUCCESS) { IMX_VPU_ERROR("setting input type to \"normal\" failed: %s", imx_vpu_dec_error_string(dec_convert_retcode(ret))); goto cleanup; } (*decoder)->codec_format = open_params->codec_format; finish: if (ret == VPU_DEC_RET_SUCCESS) IMX_VPU_TRACE("successfully opened decoder"); return dec_convert_retcode(ret); cleanup: if ((*decoder)->virt_mem_sub_block != NULL) IMX_VPU_FREE((*decoder)->virt_mem_sub_block, (*decoder)->virt_mem_sub_block_size); IMX_VPU_FREE(*decoder, sizeof(ImxVpuDecoder)); *decoder = NULL; goto finish; }