msm: vidc: Separate meta buffers support in secure mode

Extradata is appended at the end of each output buffer
in non secure video use case but in secure video playback,
the client/CPU don't have access to the output buffer
to parse the extradata. This change allows the client/CPU
to parse the extradata by allocating separate buffers for
video hardware to store extradata.

Change-Id: I12927ea3d142b9cecd6fb1ae1086c5624d0e08d6
Signed-off-by: Deepak Verma <dverma@codeaurora.org>
This commit is contained in:
Deepak Verma 2013-01-25 11:57:52 +05:30 committed by Iliyan Malchev
parent 0567450fbf
commit f84beb65e4
10 changed files with 517 additions and 19 deletions

View file

@ -88,7 +88,7 @@ u32 ddl_device_init(struct ddl_init_config *ddl_init_config,
ddl_context->dram_base_a.align_virtual_addr;
}
if (!status) {
ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM;
ddl_context->metadata_shared_input.mem_type = DDL_CMD_MEM;
ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input,
DDL_METADATA_TOTAL_INPUTBUFSIZE,
DDL_LINEAR_BUFFER_ALIGN_BYTES);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -188,6 +188,7 @@ struct ddl_dec_buffers{
struct ddl_buf_addr h264_nb_ip;
struct ddl_buf_addr context;
struct ddl_buf_addr extnuserdata;
struct ddl_buf_addr meta_hdr[DDL_MAX_BUFFER_COUNT];
};
struct ddl_enc_buffer_size{
u32 sz_cur_y;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -780,7 +780,7 @@ u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl)
}
}
if (buf_size.sz_extnuserdata > 0) {
dec_bufs->extnuserdata.mem_type = DDL_FW_MEM;
dec_bufs->extnuserdata.mem_type = DDL_CMD_MEM;
ptr = ddl_pmem_alloc(&dec_bufs->extnuserdata,
buf_size.sz_extnuserdata, DDL_KILO_BYTE(2));
if (!ptr)

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -158,7 +158,8 @@ static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl)
ddl->codec_data.decoder.codec.codec;
flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH |
VCD_METADATA_QPARRAY);
VCD_METADATA_QPARRAY |
VCD_METADATA_SEPARATE_BUF);
if (codec == VCD_CODEC_H264)
flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI);
else if (codec == VCD_CODEC_VC1 ||
@ -249,6 +250,9 @@ void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data
DDL_METADATA_ALIGNSIZE(suffix);
decoder->suffix = suffix;
output_buf_req->sz += suffix;
output_buf_req->meta_buffer_size = suffix;
output_buf_req->meta_buffer_size =
(output_buf_req->meta_buffer_size + 8191) & (~8191);
decoder->meta_data_offset = 0;
DDL_MSG_LOW("metadata output buf size : %d", suffix);
}
@ -464,13 +468,14 @@ u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl)
void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
{
struct ddl_context *ddl_context;
u32 loopc, yuv_size;
u32 loopc, yuv_size, dpb;
u32 *buffer;
struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs;
if (!decoder->meta_data_enable_flag) {
decoder->meta_data_offset = 0;
return;
}
dpb = decoder->dp_buf.no_of_dec_pic_buf;
ddl_context = ddl_get_context();
yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size,
&decoder->buf_format, !decoder->progressive_only,
@ -478,15 +483,22 @@ void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder)
decoder->meta_data_offset = DDL_ALIGN_SIZE(yuv_size,
DDL_LINEAR_BUF_ALIGN_GUARD_BYTES, DDL_LINEAR_BUF_ALIGN_MASK);
buffer = (u32 *) decoder->meta_data_input.align_virtual_addr;
*buffer++ = decoder->suffix;
DDL_MSG_LOW("Metadata offset & size : %d/%d",
decoder->meta_data_offset, decoder->suffix);
for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf;
++loopc) {
*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)) {
*buffer++ = decoder->suffix;
for (loopc = 0; loopc < dpb; ++loopc) {
*buffer++ = (u32)(decoder->meta_data_offset + (u8 *)
DDL_OFFSET(ddl_context->dram_base_a.
align_physical_addr, decoder->dp_buf.
dec_pic_buffers[loopc].vcd_frm.physical));
}
} else {
*buffer++ = decoder->actual_output_buf_req.meta_buffer_size;
for (loopc = 0; loopc < dpb; ++loopc) {
*buffer++ = DDL_ADDR_OFFSET(ddl_context->dram_base_a,
dec_buffers->meta_hdr[loopc]);
}
}
}
@ -545,7 +557,8 @@ void ddl_process_decoder_metadata(struct ddl_client_context *ddl)
DDL_MSG_LOW("data_len/metadata_offset : %d/%d",
output_frame->data_len, decoder->meta_data_offset);
output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA;
if (output_frame->data_len != decoder->meta_data_offset) {
if (!(decoder->meta_data_enable_flag & VCD_METADATA_SEPARATE_BUF)
&& (output_frame->data_len != decoder->meta_data_offset)) {
qfiller = (u32 *)((u32)((output_frame->data_len +
output_frame->offset +
(u8 *) output_frame->virtual) + 3) & ~3);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -319,6 +319,61 @@ static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
}
}
break;
case VCD_I_SET_EXT_METABUFFER:
{
int index, buffer_size;
u8 *phys_addr;
u8 *virt_addr;
struct vcd_property_meta_buffer *meta_buffer =
(struct vcd_property_meta_buffer *) property_value;
DDL_MSG_LOW("Entered VCD_I_SET_EXT_METABUFFER Virt: %p,"\
"Phys %p, fd: %d size: %d count: %d",
meta_buffer->kernel_virtual_addr,
meta_buffer->physical_addr,
meta_buffer->pmem_fd,
meta_buffer->size, meta_buffer->count);
if ((property_hdr->sz == sizeof(struct
vcd_property_meta_buffer)) &&
(DDLCLIENT_STATE_IS(ddl,
DDL_CLIENT_WAIT_FOR_INITCODEC) ||
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
phys_addr = meta_buffer->dev_addr;
virt_addr = meta_buffer->kernel_virtual_addr;
buffer_size = meta_buffer->size/meta_buffer->count;
for (index = 0; index < meta_buffer->count; index++) {
ddl->codec_data.decoder.hw_bufs.
meta_hdr[index].align_physical_addr
= phys_addr;
ddl->codec_data.decoder.hw_bufs.
meta_hdr[index].align_virtual_addr
= virt_addr;
ddl->codec_data.decoder.hw_bufs.
meta_hdr[index].buffer_size
= buffer_size;
ddl->codec_data.decoder.hw_bufs.
meta_hdr[index].physical_base_addr
= phys_addr;
ddl->codec_data.decoder.hw_bufs.
meta_hdr[index].virtual_base_addr
= virt_addr;
DDL_MSG_LOW("Meta Buffer: "\
"Assigned %d buffer for "
"virt: %p, phys %p for "
"meta_buffers "
"of size: %d\n",
index, virt_addr,
phys_addr, buffer_size);
phys_addr += buffer_size;
virt_addr += buffer_size;
}
vcd_status = VCD_S_SUCCESS;
}
}
break;
case VCD_I_H264_MV_BUFFER:
{
int index, buffer_size;
@ -379,6 +434,13 @@ static u32 ddl_set_dec_property(struct ddl_client_context *ddl,
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_FREE_EXT_METABUFFER:
{
memset(&decoder->hw_bufs.meta_hdr, 0, sizeof(struct
ddl_buf_addr) * DDL_MAX_BUFFER_COUNT);
vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_OUTPUT_ORDER:
{
if (sizeof(u32) == property_hdr->sz &&

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -271,6 +271,38 @@ static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx,
&phy_addr, &pmem_fd, &file,
&buffer_index) ||
(vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) {
if (res_trk_check_for_sec_session() &&
event == VCD_EVT_RESP_OUTPUT_DONE) {
DBG("Buffer Index = %d", buffer_index);
if (buffer_index != -1) {
if (client_ctx->meta_addr_table[buffer_index].
kernel_vir_addr_iommu &&
client_ctx->
meta_addr_table[buffer_index].
kernel_vir_addr) {
memcpy(client_ctx->
meta_addr_table[buffer_index].
kernel_vir_addr_iommu,
client_ctx->
meta_addr_table[buffer_index].
kernel_vir_addr,
client_ctx->meta_buf_size);
DBG("Copying Meta Buffer from "\
"secure memory"
"kernel_virt_iommu = %p "
"kernel_virt = %p",
client_ctx->
meta_addr_table[buffer_index].
kernel_vir_addr_iommu,
client_ctx->
meta_addr_table[buffer_index].
kernel_vir_addr);
}
}
}
/* Buffer address in user space */
vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr =
(u8 *) user_vaddr;
@ -838,7 +870,263 @@ static u32 vid_dec_set_idr_only_decoding(struct video_client_ctx *client_ctx)
return false;
return true;
}
static u32 vid_dec_set_meta_buffers(struct video_client_ctx *client_ctx,
struct vdec_meta_buffers *meta_buffers)
{
struct vcd_property_hdr vcd_property_hdr;
struct vcd_property_meta_buffer *vcd_meta_buffer = NULL;
struct msm_mapped_buffer *mapped_buffer = NULL;
struct msm_mapped_buffer *mapped_buffer_iommu = NULL;
u32 vcd_status = VCD_ERR_FAIL;
u32 len = 0, flags = 0, len_iommu = 0, flags_iommu = 0, buf_size = 0;
struct file *file, *file_iommu;
int rc = 0;
unsigned long ionflag = 0, ionflag_iommu = 0;
unsigned long buffer_size = 0, buffer_size_iommu = 0;
unsigned long iova = 0, iova_iommu = 0;
int index = -1, num_buffers = 0;
u8 *ker_vir_addr = NULL, *ker_vir_addr_iommu = NULL;
if (!client_ctx || !meta_buffers)
return false;
vcd_property_hdr.prop_id = VCD_I_SET_EXT_METABUFFER;
vcd_property_hdr.sz = sizeof(struct vcd_property_meta_buffer);
vcd_meta_buffer = &client_ctx->vcd_meta_buffer;
memset(&client_ctx->vcd_meta_buffer, 0,
sizeof(struct vcd_property_meta_buffer));
vcd_meta_buffer->size = meta_buffers->size;
vcd_meta_buffer->count = meta_buffers->count;
vcd_meta_buffer->pmem_fd = meta_buffers->pmem_fd;
vcd_meta_buffer->offset = meta_buffers->offset;
vcd_meta_buffer->pmem_fd_iommu = meta_buffers->pmem_fd_iommu;
if (!vcd_get_ion_status()) {
if (get_pmem_file(vcd_meta_buffer->pmem_fd,
(unsigned long *) (&(vcd_meta_buffer->
physical_addr)),
(unsigned long *) (&vcd_meta_buffer->
kernel_virtual_addr),
(unsigned long *) (&len), &file)) {
ERR("%s(): get_pmem_file failed\n", __func__);
return false;
}
put_pmem_file(file);
flags = MSM_SUBSYSTEM_MAP_IOVA;
mapped_buffer = msm_subsystem_map_buffer(
(unsigned long)vcd_meta_buffer->physical_addr,
len, flags, vidc_mmu_subsystem,
sizeof(vidc_mmu_subsystem)/
sizeof(unsigned int));
if (IS_ERR(mapped_buffer)) {
pr_err("buffer map failed");
return false;
}
vcd_meta_buffer->client_data = (void *) mapped_buffer;
vcd_meta_buffer->dev_addr =
(u8 *)mapped_buffer->iova[0];
if (get_pmem_file(vcd_meta_buffer->pmem_fd_iommu,
(unsigned long *) (&(vcd_meta_buffer->
physical_addr_iommu)),
(unsigned long *) (&vcd_meta_buffer->
kernel_virt_addr_iommu),
(unsigned long *) (&len_iommu), &file_iommu)) {
ERR("%s(): get_pmem_file failed\n", __func__);
return false;
}
put_pmem_file(file_iommu);
flags_iommu = MSM_SUBSYSTEM_MAP_IOVA;
mapped_buffer_iommu = msm_subsystem_map_buffer(
(unsigned long)vcd_meta_buffer->physical_addr_iommu,
len_iommu, flags_iommu, vidc_mmu_subsystem,
sizeof(vidc_mmu_subsystem)/
sizeof(unsigned int));
if (IS_ERR(mapped_buffer_iommu)) {
pr_err("buffer map failed");
return false;
}
vcd_meta_buffer->client_data_iommu =
(void *) mapped_buffer_iommu;
vcd_meta_buffer->dev_addr_iommu =
(u8 *)mapped_buffer_iommu->iova[0];
} else {
client_ctx->meta_buffer_ion_handle = ion_import_dma_buf(
client_ctx->user_ion_client,
vcd_meta_buffer->pmem_fd);
if (IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
ERR("%s(): get_ION_handle failed\n", __func__);
goto import_ion_error;
}
rc = ion_handle_get_flags(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle,
&ionflag);
if (rc) {
ERR("%s():get_ION_flags fail\n",
__func__);
goto import_ion_error;
}
vcd_meta_buffer->kernel_virtual_addr =
(u8 *) ion_map_kernel(
client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle);
if (!vcd_meta_buffer->kernel_virtual_addr) {
ERR("%s(): get_ION_kernel virtual addr failed\n",
__func__);
goto import_ion_error;
}
if (res_trk_check_for_sec_session() ||
(res_trk_get_core_type() == (u32)VCD_CORE_720P)) {
rc = ion_phys(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle,
(unsigned long *) (&(vcd_meta_buffer->
physical_addr)), &len);
if (rc) {
ERR("%s():get_ION_kernel physical addr fail\n",
__func__);
goto ion_map_error;
}
vcd_meta_buffer->client_data = NULL;
vcd_meta_buffer->dev_addr = (u8 *)
vcd_meta_buffer->physical_addr;
} else {
rc = ion_map_iommu(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle,
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
SZ_4K, 0, (unsigned long *)&iova,
(unsigned long *)&buffer_size,
0, 0);
if (rc || !iova) {
ERR("%s():get_ION_kernel physical addr fail,"\
" rc = %d iova = 0x%lx\n",
__func__, rc, iova);
goto ion_map_error;
}
vcd_meta_buffer->physical_addr = (u8 *) iova;
vcd_meta_buffer->client_data = NULL;
vcd_meta_buffer->dev_addr = (u8 *) iova;
}
client_ctx->meta_buffer_iommu_ion_handle = ion_import_dma_buf(
client_ctx->user_ion_client,
vcd_meta_buffer->pmem_fd_iommu);
if (IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
ERR("%s(): get_ION_handle failed\n", __func__);
goto import_ion_error;
}
rc = ion_handle_get_flags(client_ctx->user_ion_client,
client_ctx->
meta_buffer_iommu_ion_handle,
&ionflag_iommu);
if (rc) {
ERR("%s():get_ION_flags fail\n",
__func__);
goto import_ion_error;
}
vcd_meta_buffer->kernel_virt_addr_iommu =
(u8 *) ion_map_kernel(
client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle);
if (!vcd_meta_buffer->kernel_virt_addr_iommu) {
ERR("%s(): get_ION_kernel virtual addr failed\n",
__func__);
goto import_ion_error;
}
if (res_trk_get_core_type() == (u32)VCD_CORE_720P) {
rc = ion_phys(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle,
(unsigned long *) (&(vcd_meta_buffer->
physical_addr_iommu)), &len_iommu);
if (rc) {
ERR("%s():get_ION_kernel physical addr fail\n",
__func__);
goto ion_map_error_iommu;
}
vcd_meta_buffer->client_data_iommu = NULL;
vcd_meta_buffer->dev_addr_iommu = (u8 *)
vcd_meta_buffer->physical_addr_iommu;
} else {
rc = ion_map_iommu(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle,
VIDEO_DOMAIN, VIDEO_MAIN_POOL,
SZ_4K, 0, (unsigned long *)&iova_iommu,
(unsigned long *)&buffer_size_iommu,
0, 0);
if (rc || !iova_iommu) {
ERR("%s():get_ION_kernel physical addr fail, "\
"rc = %d iova = 0x%lx\n",
__func__, rc, iova);
goto ion_map_error_iommu;
}
vcd_meta_buffer->physical_addr_iommu =
(u8 *) iova_iommu;
vcd_meta_buffer->client_data_iommu = NULL;
vcd_meta_buffer->dev_addr_iommu = (u8 *) iova_iommu;
}
}
/*fill the meta addr table*/
num_buffers = vcd_meta_buffer->count;
buf_size = vcd_meta_buffer->size/num_buffers;
ker_vir_addr = vcd_meta_buffer->kernel_virtual_addr;
ker_vir_addr_iommu = vcd_meta_buffer->kernel_virt_addr_iommu;
client_ctx->meta_buf_size = buf_size;
for (index = 0; index < num_buffers; index++) {
client_ctx->meta_addr_table[index].kernel_vir_addr =
ker_vir_addr;
client_ctx->meta_addr_table[index].kernel_vir_addr_iommu =
ker_vir_addr_iommu;
DBG("[%d] kernel_virtual = %p kernel_vir_iommu = %p",
index, ker_vir_addr, ker_vir_addr_iommu);
ker_vir_addr += buf_size;
ker_vir_addr_iommu += buf_size;
}
DBG("Meta Buffer: Virt: %p, Phys %p, fd: %d",
vcd_meta_buffer->kernel_virtual_addr,
vcd_meta_buffer->physical_addr,
vcd_meta_buffer->pmem_fd);
DBG("IOMMU Meta Buffer: Virt: %p, Phys %p, fd: %d",
vcd_meta_buffer->kernel_virt_addr_iommu,
vcd_meta_buffer->physical_addr_iommu,
vcd_meta_buffer->pmem_fd_iommu);
DBG("Meta_buffer: Dev addr %p", vcd_meta_buffer->dev_addr);
DBG("IOMMU Meta_buffer: Dev addr %p",
vcd_meta_buffer->dev_addr_iommu);
vcd_status = vcd_set_property(client_ctx->vcd_handle,
&vcd_property_hdr,
vcd_meta_buffer);
if (vcd_status)
return false;
else
return true;
ion_map_error_iommu:
if (vcd_meta_buffer->kernel_virt_addr_iommu) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle);
vcd_meta_buffer->kernel_virt_addr_iommu = NULL;
}
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
ion_free(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle);
client_ctx->meta_buffer_iommu_ion_handle = NULL;
}
ion_map_error:
if (vcd_meta_buffer->kernel_virtual_addr) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle);
vcd_meta_buffer->kernel_virtual_addr = NULL;
}
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
ion_free(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle);
client_ctx->meta_buffer_ion_handle = NULL;
}
import_ion_error:
return false;
}
static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
struct vdec_h264_mv *mv_data)
{
@ -1018,6 +1306,65 @@ static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx,
return true;
}
static u32 vid_dec_free_meta_buffers(struct video_client_ctx *client_ctx)
{
struct vcd_property_hdr vcd_property_hdr;
struct vcd_property_buffer_size meta_buffer_size;
u32 vcd_status = VCD_ERR_FAIL;
if (!client_ctx)
return false;
if (client_ctx->vcd_meta_buffer.client_data)
msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
client_ctx->vcd_meta_buffer.client_data);
if (client_ctx->vcd_meta_buffer.client_data_iommu)
msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
client_ctx->vcd_meta_buffer.client_data_iommu);
vcd_property_hdr.prop_id = VCD_I_FREE_EXT_METABUFFER;
vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
vcd_status = vcd_set_property(client_ctx->vcd_handle,
&vcd_property_hdr, &meta_buffer_size);
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_ion_handle)) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle);
if (!res_trk_check_for_sec_session() &&
(res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
ion_unmap_iommu(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle,
VIDEO_DOMAIN,
VIDEO_MAIN_POOL);
}
ion_free(client_ctx->user_ion_client,
client_ctx->meta_buffer_ion_handle);
client_ctx->meta_buffer_ion_handle = NULL;
}
if (!IS_ERR_OR_NULL(client_ctx->meta_buffer_iommu_ion_handle)) {
ion_unmap_kernel(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle);
if (res_trk_check_for_sec_session() &&
(res_trk_get_core_type() != (u32)VCD_CORE_720P)) {
ion_unmap_iommu(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle,
VIDEO_DOMAIN,
VIDEO_MAIN_POOL);
}
ion_free(client_ctx->user_ion_client,
client_ctx->meta_buffer_iommu_ion_handle);
client_ctx->meta_buffer_iommu_ion_handle = NULL;
}
if (vcd_status)
return false;
else
return true;
}
static u32 vid_dec_free_h264_mv_buffers(struct video_client_ctx *client_ctx)
{
struct vcd_property_hdr vcd_property_hdr;
@ -1085,6 +1432,7 @@ static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx,
vdec_buf_req->buffer_size = vcd_buf_req.sz;
vdec_buf_req->alignment = vcd_buf_req.align;
vdec_buf_req->buf_poolid = vcd_buf_req.buf_pool_id;
vdec_buf_req->meta_buffer_size = vcd_buf_req.meta_buffer_size;
return true;
}
@ -1977,6 +2325,29 @@ static long vid_dec_ioctl(struct file *file,
return -EIO;
break;
}
case VDEC_IOCTL_SET_META_BUFFERS:
{
struct vdec_meta_buffers meta_buffers;
DBG("VDEC_IOCTL_SET_META_BUFFERS\n");
if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg)))
return -EFAULT;
if (copy_from_user(&meta_buffers, vdec_msg.in,
sizeof(meta_buffers)))
return -EFAULT;
result = vid_dec_set_meta_buffers(client_ctx, &meta_buffers);
if (!result)
return -EIO;
break;
}
case VDEC_IOCTL_FREE_META_BUFFERS:
{
DBG("VDEC_IOCTL_FREE_META_BUFFERS\n");
result = vid_dec_free_meta_buffers(client_ctx);
if (!result)
return -EIO;
break;
}
case VDEC_IOCTL_SET_H264_MV_BUFFER:
{
struct vdec_h264_mv mv_data;

View file

@ -78,6 +78,7 @@
#define VDEC_EXTRADATA_EXT_DATA 0x0800
#define VDEC_EXTRADATA_USER_DATA 0x1000
#define VDEC_EXTRADATA_EXT_BUFFER 0x2000
#define VDEC_CMDBASE 0x800
#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE)
@ -213,6 +214,12 @@ struct vdec_ioctl_msg {
#define VDEC_IOCTL_SET_PERF_CLK \
_IOR(VDEC_IOCTL_MAGIC, 38, struct vdec_ioctl_msg)
#define VDEC_IOCTL_SET_META_BUFFERS \
_IOW(VDEC_IOCTL_MAGIC, 39, struct vdec_ioctl_msg)
#define VDEC_IOCTL_FREE_META_BUFFERS \
_IO(VDEC_IOCTL_MAGIC, 40)
enum vdec_picture {
PICTURE_TYPE_I,
PICTURE_TYPE_P,
@ -236,6 +243,7 @@ struct vdec_allocatorproperty {
size_t buffer_size;
uint32_t alignment;
uint32_t buf_poolid;
size_t meta_buffer_size;
};
struct vdec_bufferpayload {
@ -526,6 +534,11 @@ struct vdec_aspectratioinfo {
uint32_t par_height;
};
struct vdec_sep_metadatainfo {
void __user *metabufaddr;
uint32_t size;
};
struct vdec_output_frameinfo {
void __user *bufferaddr;
size_t offset;
@ -538,6 +551,7 @@ struct vdec_output_frameinfo {
struct vdec_framesize framesize;
enum vdec_interlaced_format interlaced_format;
struct vdec_aspectratioinfo aspect_ratio_info;
struct vdec_sep_metadatainfo metadata_info;
};
union vdec_msgdata {
@ -571,4 +585,12 @@ struct vdec_mv_buff_size{
int alignment;
};
struct vdec_meta_buffers {
size_t size;
int count;
int pmem_fd;
int pmem_fd_iommu;
int offset;
};
#endif /* end of macro _VDECDECODER_H_ */

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -100,6 +100,7 @@ struct vcd_buffer_requirement {
size_t sz;
u32 align;
u32 buf_pool_id;
size_t meta_buffer_size;
};
struct vcd_init_config {

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -57,7 +57,8 @@
#define VCD_I_SET_TURBO_CLK (VCD_START_BASE + 0x29)
#define VCD_I_ENABLE_DELIMITER_FLAG (VCD_START_BASE + 0x2A)
#define VCD_I_ENABLE_VUI_TIMING_INFO (VCD_START_BASE + 0x2B)
#define VCD_I_SET_EXT_METABUFFER (VCD_START_BASE + 0x2C)
#define VCD_I_FREE_EXT_METABUFFER (VCD_START_BASE + 0x2D)
#define VCD_START_REQ (VCD_START_BASE + 0x1000)
#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1)
@ -118,6 +119,7 @@ enum vcd_perf_level {
#define VCD_METADATA_EXT_DATA 0x0800
#define VCD_METADATA_USER_DATA 0x1000
#define VCD_METADATA_SEPARATE_BUF 0x2000
struct vcd_property_meta_data_enable {
u32 meta_data_enable_flag;
@ -384,4 +386,19 @@ struct vcd_property_vui_timing_info_enable {
u32 vui_timing_info;
};
struct vcd_property_meta_buffer {
u8 *kernel_virtual_addr;
u8 *physical_addr;
u32 size;
u32 count;
int pmem_fd;
u32 offset;
u8 *dev_addr;
void *client_data;
u8 *kernel_virt_addr_iommu;
u8 *physical_addr_iommu;
int pmem_fd_iommu;
u8 *dev_addr_iommu;
void *client_data_iommu;
};
#endif

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -19,6 +19,7 @@
#define VIDC_MAX_NUM_CLIENTS 4
#define MAX_VIDEO_NUM_OF_BUFF 100
#define MAX_META_BUFFERS 32
enum buffer_dir {
BUFFER_TYPE_INPUT,
@ -37,6 +38,11 @@ struct buf_addr_table {
void *client_data;
};
struct meta_buffer_addr_table {
u8 *kernel_vir_addr;
u8 *kernel_vir_addr_iommu;
};
struct video_client_ctx {
void *vcd_handle;
u32 num_of_input_buffers;
@ -49,17 +55,22 @@ struct video_client_ctx {
wait_queue_head_t msg_wait;
struct completion event;
struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
struct vcd_property_meta_buffer vcd_meta_buffer;
struct vcd_property_enc_recon_buffer recon_buffer[4];
u32 event_status;
u32 seq_header_set;
u32 stop_msg;
u32 stop_called;
u32 stop_sync_cb;
size_t meta_buf_size;
struct ion_client *user_ion_client;
struct ion_handle *seq_hdr_ion_handle;
struct ion_handle *h264_mv_ion_handle;
struct ion_handle *recon_buffer_ion_handle[4];
struct ion_handle *meta_buffer_ion_handle;
struct ion_handle *meta_buffer_iommu_ion_handle;
u32 dmx_disable;
struct meta_buffer_addr_table meta_addr_table[MAX_META_BUFFERS];
};
void __iomem *vidc_get_ioaddr(void);