static ImxVpuEncReturnCodes imx_vpu_jpeg_enc_open_internal(ImxVpuJPEGEncoder *jpeg_encoder) { unsigned int i; ImxVpuEncOpenParams open_params; ImxVpuEncReturnCodes ret = IMX_VPU_ENC_RETURN_CODE_OK; assert(jpeg_encoder != NULL); assert(jpeg_encoder->frame_width > 0); assert(jpeg_encoder->frame_height > 0); assert(jpeg_encoder->encoder == NULL); imx_vpu_enc_set_default_open_params(IMX_VPU_CODEC_FORMAT_MJPEG, &open_params); open_params.frame_width = jpeg_encoder->frame_width; open_params.frame_height = jpeg_encoder->frame_height; open_params.codec_params.mjpeg_params.quality_factor = jpeg_encoder->quality_factor; if ((ret = imx_vpu_enc_open(&(jpeg_encoder->encoder), &open_params, jpeg_encoder->bitstream_buffer)) != IMX_VPU_ENC_RETURN_CODE_OK) goto error; if ((ret = imx_vpu_enc_get_initial_info(jpeg_encoder->encoder, &(jpeg_encoder->initial_info))) != IMX_VPU_ENC_RETURN_CODE_OK) goto error; jpeg_encoder->num_framebuffers = jpeg_encoder->initial_info.min_num_required_framebuffers; jpeg_encoder->framebuffers = IMX_VPU_ALLOC(sizeof(ImxVpuFramebuffer) * jpeg_encoder->num_framebuffers); jpeg_encoder->fb_dmabuffers = IMX_VPU_ALLOC(sizeof(ImxVpuDMABuffer *) * jpeg_encoder->num_framebuffers); memset(jpeg_encoder->framebuffers, 0, sizeof(ImxVpuFramebuffer) * jpeg_encoder->num_framebuffers); memset(jpeg_encoder->fb_dmabuffers, 0, sizeof(ImxVpuDMABuffer *) * jpeg_encoder->num_framebuffers); imx_vpu_calc_framebuffer_sizes(jpeg_encoder->color_format, jpeg_encoder->frame_width, jpeg_encoder->frame_height, jpeg_encoder->initial_info.framebuffer_alignment, 0, 0, &(jpeg_encoder->calculated_sizes)); for (i = 0; i < jpeg_encoder->num_framebuffers; ++i) { jpeg_encoder->fb_dmabuffers[i] = imx_vpu_dma_buffer_allocate(jpeg_encoder->dma_buffer_allocator, jpeg_encoder->calculated_sizes.total_size, jpeg_encoder->initial_info.framebuffer_alignment, 0); if (jpeg_encoder->fb_dmabuffers[i] == NULL) { IMX_VPU_ERROR("could not allocate DMA buffer for framebuffer #%u", i); ret = IMX_VPU_ENC_RETURN_CODE_ERROR; goto error; } imx_vpu_fill_framebuffer_params(&(jpeg_encoder->framebuffers[i]), &(jpeg_encoder->calculated_sizes), jpeg_encoder->fb_dmabuffers[i], 0); } if ((ret = imx_vpu_enc_register_framebuffers(jpeg_encoder->encoder, jpeg_encoder->framebuffers, jpeg_encoder->num_framebuffers)) != IMX_VPU_ENC_RETURN_CODE_OK) { IMX_VPU_ERROR("could not register framebuffers: %s", imx_vpu_enc_error_string(ret)); goto error; } return ret; error: imx_vpu_jpeg_enc_close_internal(jpeg_encoder); return ret; }
ImxVpuDecReturnCodes imx_vpu_dec_register_framebuffers(ImxVpuDecoder *decoder, ImxVpuFramebuffer *framebuffers, unsigned int num_framebuffers) { unsigned int i; VpuDecRetCode ret; VpuFrameBuffer *temp_fbs; IMX_VPU_TRACE("attempting to register %u framebuffers", num_framebuffers); decoder->wrapper_framebuffers = NULL; temp_fbs = IMX_VPU_ALLOC(sizeof(VpuFrameBuffer) * num_framebuffers); if (temp_fbs == NULL) { IMX_VPU_ERROR("allocating memory for framebuffers failed"); return IMX_VPU_DEC_RETURN_CODE_ERROR; } for (i = 0; i < num_framebuffers; ++i) convert_to_wrapper_framebuffer(&framebuffers[i], &(temp_fbs[i])); ret = VPU_DecRegisterFrameBuffer(decoder->handle, temp_fbs, num_framebuffers); IMX_VPU_FREE(temp_fbs, sizeof(VpuFrameBuffer) * num_framebuffers); if (ret != VPU_DEC_RET_SUCCESS) { ImxVpuDecReturnCodes imxret = dec_convert_retcode(ret); IMX_VPU_ERROR("registering framebuffers failed: %s", imx_vpu_dec_error_string(imxret)); return ret; } decoder->wrapper_framebuffers = IMX_VPU_ALLOC(sizeof(VpuFrameBuffer*) * num_framebuffers); { int out_num; VPU_DecAllRegFrameInfo(decoder->handle, decoder->wrapper_framebuffers, &out_num); IMX_VPU_LOG("out_num: %d num_framebuffers: %u", out_num, num_framebuffers); } decoder->framebuffers = framebuffers; decoder->num_framebuffers = num_framebuffers; decoder->num_available_framebuffers = num_framebuffers; decoder->user_data_for_frames = IMX_VPU_ALLOC(sizeof(void*) * num_framebuffers); if (decoder->user_data_for_frames == NULL) { IMX_VPU_ERROR("allocating memory for user data failed"); IMX_VPU_FREE(decoder->wrapper_framebuffers, sizeof(VpuFrameBuffer*) * num_framebuffers); decoder->wrapper_framebuffers = NULL; return IMX_VPU_DEC_RETURN_CODE_ERROR; } memset(decoder->user_data_for_frames, 0, sizeof(void*) * num_framebuffers); decoder->num_user_data = 0; return IMX_VPU_DEC_RETURN_CODE_OK; }
ImxVpuDecReturnCodes imx_vpu_jpeg_dec_open(ImxVpuJPEGDecoder **jpeg_decoder, ImxVpuDMABufferAllocator *dma_buffer_allocator, unsigned int num_extra_framebuffers) { ImxVpuDecOpenParams open_params; ImxVpuDecReturnCodes ret = IMX_VPU_DEC_RETURN_CODE_OK; ImxVpuJPEGDecoder *jpegdec = NULL; assert(jpeg_decoder != NULL); if ((ret = imx_vpu_dec_load()) != IMX_VPU_DEC_RETURN_CODE_OK) return ret; jpegdec = IMX_VPU_ALLOC(sizeof(ImxVpuJPEGDecoder)); if (jpegdec == NULL) { IMX_VPU_ERROR("allocating memory for JPEG decoder object failed"); return IMX_VPU_DEC_RETURN_CODE_ERROR; } memset(jpegdec, 0, sizeof(ImxVpuJPEGDecoder)); jpegdec->dma_buffer_allocator = (dma_buffer_allocator != NULL) ? dma_buffer_allocator : imx_vpu_dec_get_default_allocator(); jpegdec->num_extra_framebuffers = num_extra_framebuffers; memset(&open_params, 0, sizeof(open_params)); open_params.codec_format = IMX_VPU_CODEC_FORMAT_MJPEG; open_params.frame_width = 0; open_params.frame_height = 0; imx_vpu_dec_get_bitstream_buffer_info(&(jpegdec->bitstream_buffer_size), &(jpegdec->bitstream_buffer_alignment)); jpegdec->bitstream_buffer = imx_vpu_dma_buffer_allocate(jpegdec->dma_buffer_allocator, jpegdec->bitstream_buffer_size, jpegdec->bitstream_buffer_alignment, 0); if (jpegdec->bitstream_buffer == NULL) { IMX_VPU_ERROR("could not allocate DMA buffer for bitstream buffer with %u bytes and alignment %u", jpegdec->bitstream_buffer_size, jpegdec->bitstream_buffer_alignment); ret = IMX_VPU_DEC_RETURN_CODE_ERROR; goto error; } if ((ret = imx_vpu_dec_open(&(jpegdec->decoder), &open_params, jpegdec->bitstream_buffer, initial_info_callback, jpegdec)) != IMX_VPU_DEC_RETURN_CODE_OK) goto error; *jpeg_decoder = jpegdec; return IMX_VPU_DEC_RETURN_CODE_OK; error: if (jpegdec != NULL) { if (jpegdec->bitstream_buffer != NULL) imx_vpu_dma_buffer_deallocate(jpegdec->bitstream_buffer); IMX_VPU_FREE(jpegdec, sizeof(ImxVpuJPEGDecoder)); } return ret; }
ImxVpuEncReturnCodes imx_vpu_jpeg_enc_open(ImxVpuJPEGEncoder **jpeg_encoder, ImxVpuDMABufferAllocator *dma_buffer_allocator) { ImxVpuEncReturnCodes ret = IMX_VPU_ENC_RETURN_CODE_OK; ImxVpuJPEGEncoder *jpegenc = NULL; assert(jpeg_encoder != NULL); if ((ret = imx_vpu_enc_load()) != IMX_VPU_ENC_RETURN_CODE_OK) goto error; jpegenc = IMX_VPU_ALLOC(sizeof(ImxVpuJPEGEncoder)); if (jpegenc == NULL) { IMX_VPU_ERROR("allocating memory for JPEG encoder object failed"); ret = IMX_VPU_ENC_RETURN_CODE_ERROR; goto error; } memset(jpegenc, 0, sizeof(ImxVpuJPEGEncoder)); jpegenc->dma_buffer_allocator = (dma_buffer_allocator != NULL) ? dma_buffer_allocator : imx_vpu_enc_get_default_allocator(); imx_vpu_enc_get_bitstream_buffer_info(&(jpegenc->bitstream_buffer_size), &(jpegenc->bitstream_buffer_alignment)); jpegenc->bitstream_buffer = imx_vpu_dma_buffer_allocate(jpegenc->dma_buffer_allocator, jpegenc->bitstream_buffer_size, jpegenc->bitstream_buffer_alignment, 0); if (jpegenc->bitstream_buffer == NULL) { IMX_VPU_ERROR("could not allocate DMA buffer for bitstream buffer with %u bytes and alignment %u", jpegenc->bitstream_buffer_size, jpegenc->bitstream_buffer_alignment); ret = IMX_VPU_ENC_RETURN_CODE_ERROR; goto error; } /* imx_vpu_enc_open() is called later on demand during encoding, to accomodate * for potentially changing parameters like width, height, quality factor */ *jpeg_encoder = jpegenc; return IMX_VPU_ENC_RETURN_CODE_OK; error: if ((jpegenc != NULL) && (jpegenc->bitstream_buffer != NULL)) imx_vpu_dma_buffer_deallocate(jpegenc->bitstream_buffer); return ret; }
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; }
static int initial_info_callback(ImxVpuDecoder *decoder, ImxVpuDecInitialInfo *new_initial_info, unsigned int output_code, void *user_data) { unsigned int i; ImxVpuDecReturnCodes ret; ImxVpuJPEGDecoder *jpeg_decoder = (ImxVpuJPEGDecoder *)user_data; IMXVPUAPI_UNUSED_PARAM(decoder); IMXVPUAPI_UNUSED_PARAM(output_code); imx_vpu_jpeg_dec_deallocate_framebuffers(jpeg_decoder); jpeg_decoder->initial_info = *new_initial_info; IMX_VPU_DEBUG( "initial info: size: %ux%u pixel rate: %u/%u min num required framebuffers: %u interlacing: %d framebuffer alignment: %u color format: %s", new_initial_info->frame_width, new_initial_info->frame_height, new_initial_info->frame_rate_numerator, new_initial_info->frame_rate_denominator, new_initial_info->min_num_required_framebuffers, new_initial_info->interlacing, new_initial_info->framebuffer_alignment, imx_vpu_color_format_string(new_initial_info->color_format) ); jpeg_decoder->num_framebuffers = new_initial_info->min_num_required_framebuffers + jpeg_decoder->num_extra_framebuffers; imx_vpu_calc_framebuffer_sizes(new_initial_info->color_format, new_initial_info->frame_width, new_initial_info->frame_height, new_initial_info->framebuffer_alignment, new_initial_info->interlacing, 0, &(jpeg_decoder->calculated_sizes)); IMX_VPU_DEBUG( "calculated sizes: frame width&height: %dx%d Y stride: %u CbCr stride: %u Y size: %u CbCr size: %u MvCol size: %u total size: %u", jpeg_decoder->calculated_sizes.aligned_frame_width, jpeg_decoder->calculated_sizes.aligned_frame_height, jpeg_decoder->calculated_sizes.y_stride, jpeg_decoder->calculated_sizes.cbcr_stride, jpeg_decoder->calculated_sizes.y_size, jpeg_decoder->calculated_sizes.cbcr_size, jpeg_decoder->calculated_sizes.mvcol_size, jpeg_decoder->calculated_sizes.total_size ); jpeg_decoder->framebuffers = IMX_VPU_ALLOC(sizeof(ImxVpuFramebuffer) * jpeg_decoder->num_framebuffers); jpeg_decoder->fb_dmabuffers = IMX_VPU_ALLOC(sizeof(ImxVpuDMABuffer *) * jpeg_decoder->num_framebuffers); memset(jpeg_decoder->framebuffers, 0, sizeof(ImxVpuFramebuffer) * jpeg_decoder->num_framebuffers); memset(jpeg_decoder->fb_dmabuffers, 0, sizeof(ImxVpuDMABuffer *) * jpeg_decoder->num_framebuffers); for (i = 0; i < jpeg_decoder->num_framebuffers; ++i) { jpeg_decoder->fb_dmabuffers[i] = imx_vpu_dma_buffer_allocate(jpeg_decoder->dma_buffer_allocator, jpeg_decoder->calculated_sizes.total_size, jpeg_decoder->initial_info.framebuffer_alignment, 0); if (jpeg_decoder->fb_dmabuffers[i] == NULL) { IMX_VPU_ERROR("could not allocate DMA buffer for framebuffer #%u", i); goto error; } imx_vpu_fill_framebuffer_params(&(jpeg_decoder->framebuffers[i]), &(jpeg_decoder->calculated_sizes), jpeg_decoder->fb_dmabuffers[i], 0); } if ((ret = imx_vpu_dec_register_framebuffers(jpeg_decoder->decoder, jpeg_decoder->framebuffers, jpeg_decoder->num_framebuffers)) != IMX_VPU_DEC_RETURN_CODE_OK) { IMX_VPU_ERROR("could not register framebuffers: %s", imx_vpu_dec_error_string(ret)); goto error; } return 1; error: imx_vpu_jpeg_deallocate_dma_buffers(jpeg_decoder->fb_dmabuffers, jpeg_decoder->num_framebuffers); return 0; }