Example #1
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #6
0
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;
}