u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx, struct venc_buffer *input_frame_info) { struct vcd_frame_data_type vcd_input_buffer; unsigned long kernel_vaddr, phy_addr, user_vaddr; int pmem_fd; struct file *file; s32 buffer_index = -1; u32 vcd_status = VCD_ERR_FAIL; if (!client_ctx || !input_frame_info) return FALSE; user_vaddr = (unsigned long)input_frame_info->ptrbuffer; if (vid_c_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, TRUE, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, &buffer_index)) { /* kernel_vaddr is found. send the frame to VCD */ memset((void *)&vcd_input_buffer, 0, sizeof(struct vcd_frame_data_type)); vcd_input_buffer.p_virtual = (u8 *) (kernel_vaddr + input_frame_info->offset); vcd_input_buffer.n_offset = input_frame_info->offset; vcd_input_buffer.n_frm_clnt_data = (u32) input_frame_info->clientdata; vcd_input_buffer.n_ip_frm_tag = (u32) input_frame_info->clientdata; vcd_input_buffer.n_data_len = input_frame_info->len; vcd_input_buffer.time_stamp = input_frame_info->timestamp; /* Rely on VCD using the same flags as OMX */ vcd_input_buffer.n_flags = input_frame_info->flags; vcd_status = vcd_encode_frame(client_ctx->vcd_handle, &vcd_input_buffer); if (!vcd_status) return TRUE; else { ERR("%s(): vcd_encode_frame failed = %u\n", __func__, vcd_status); return FALSE; } } else { ERR("%s(): kernel_vaddr not found\n", __func__); return FALSE; } }
static u32 vid_dec_free_buffer(struct video_client_ctx *client_ctx, struct vdec_setbuffer_cmd *buffer_info) { enum vcd_buffer_type buffer_type; enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; u32 vcd_status = VCD_ERR_FAIL; unsigned long user_vaddr, kernel_vaddr, phy_addr; int pmem_fd; struct file *file; s32 buffer_index = -1; if (!client_ctx || !buffer_info) return FALSE; user_vaddr = (unsigned long)buffer_info->buffer.bufferaddr; if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) dir_buffer = BUFFER_TYPE_OUTPUT; /*If buffer already set, ignore */ if (!vid_c_lookup_addr_table(client_ctx, dir_buffer, TRUE, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, &buffer_index)) { DBG("%s() : user_virt_addr = 0x%08lx is alreday set.", __func__, user_vaddr); return TRUE; } if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_INPUT) buffer_type = VCD_BUFFER_INPUT; else buffer_type = VCD_BUFFER_OUTPUT; vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_type, (u8 *)kernel_vaddr); if (!vcd_status) return TRUE; else return FALSE; }
static u32 vid_dec_fill_output_buffer(struct video_client_ctx *client_ctx, struct vdec_fillbuffer_cmd *fill_buffer_cmd) { unsigned long kernel_vaddr, phy_addr, user_vaddr; int pmem_fd; struct file *file; s32 buffer_index = -1; u32 vcd_status = VCD_ERR_FAIL; struct vcd_frame_data_type vcd_frame; if (!client_ctx || !fill_buffer_cmd) return FALSE; user_vaddr = (unsigned long)fill_buffer_cmd->buffer.bufferaddr; if (vid_c_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, TRUE, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, &buffer_index)) { memset((void *)&vcd_frame, 0, sizeof(struct vcd_frame_data_type)); vcd_frame.p_virtual = (u8 *) kernel_vaddr; vcd_frame.n_frm_clnt_data = (u32) fill_buffer_cmd->client_data; vcd_frame.n_alloc_len = fill_buffer_cmd->buffer.buffer_len; vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle, &vcd_frame); if (!vcd_status) return TRUE; else { ERR("%s(): vcd_fill_output_buffer failed = %u\n", __func__, vcd_status); return FALSE; } } else { ERR("%s(): kernel_vaddr not found\n", __func__); return FALSE; } }
static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx, struct vdec_setbuffer_cmd *buffer_info) { enum vcd_buffer_type buffer_type; enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; u32 vcd_status = VCD_ERR_FAIL; unsigned long user_vaddr, kernel_vaddr, phy_addr, len; int pmem_fd; struct file *file; struct buf_addr_table *buf_addr_table; s32 buffer_index = -1; if (!client_ctx || !buffer_info) return FALSE; user_vaddr = (unsigned long)buffer_info->buffer.bufferaddr; if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) dir_buffer = BUFFER_TYPE_OUTPUT; /*If buffer already set, ignore */ if (vid_c_lookup_addr_table(client_ctx, dir_buffer, TRUE, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, &buffer_index)) { DBG("%s() : user_virt_addr = 0x%08lx is alreday set.", __func__, user_vaddr); return TRUE; } if (get_pmem_file(buffer_info->buffer.pmem_fd, &phy_addr, &kernel_vaddr, &len, &file)) { ERR("%s(): get_pmem_file failed\n", __func__); return FALSE; } put_pmem_file(file); if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_INPUT) { buffer_type = VCD_BUFFER_INPUT; client_ctx->num_of_input_buffers++; if (client_ctx->num_of_input_buffers > MAX_VIDEO_NUM_OF_BUFF) { ERR("%s(): num_of_input_buffers reached max value" " MAX_VIDEO_NUM_OF_BUFF \n", __func__); client_ctx->num_of_input_buffers--; return FALSE; } buffer_index = client_ctx->num_of_input_buffers - 1; buf_addr_table = &client_ctx->input_buf_addr_table[buffer_index]; buf_addr_table->user_vaddr = (unsigned long)buffer_info->buffer.bufferaddr; buf_addr_table->kernel_vaddr = kernel_vaddr; buf_addr_table->phy_addr = phy_addr; buf_addr_table->pmem_fd = buffer_info->buffer.pmem_fd; buf_addr_table->file = file; } else { buffer_type = VCD_BUFFER_OUTPUT; client_ctx->num_of_output_buffers++; if (client_ctx->num_of_output_buffers > MAX_VIDEO_NUM_OF_BUFF) { ERR("%s(): num_of_outut_buffers reached max value" " MAX_VIDEO_NUM_OF_BUFF \n", __func__); client_ctx->num_of_output_buffers--; return FALSE; } buffer_index = client_ctx->num_of_output_buffers - 1; buf_addr_table = &client_ctx->output_buf_addr_table[buffer_index]; kernel_vaddr += (unsigned long)buffer_info->buffer.offset; phy_addr += (unsigned long)buffer_info->buffer.offset; buf_addr_table->user_vaddr = (unsigned long)buffer_info->buffer.bufferaddr; buf_addr_table->kernel_vaddr = kernel_vaddr; buf_addr_table->phy_addr = phy_addr; buf_addr_table->pmem_fd = buffer_info->buffer.pmem_fd; buf_addr_table->file = file; } vcd_status = vcd_set_buffer(client_ctx->vcd_handle, buffer_type, (u8 *) kernel_vaddr, buffer_info->buffer.buffer_len); if (!vcd_status) return TRUE; else return FALSE; }
static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx, u32 event, u32 status, struct vcd_frame_data_type *vcd_frame_data) { struct vid_dec_msg *vdec_msg; unsigned long kernel_vaddr, phy_addr, user_vaddr; int pmem_fd; struct file *file; s32 buffer_index = -1; if (!client_ctx || !vcd_frame_data) { ERR("vid_dec_input_frame_done() NULL pointer \n"); return; } vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); if (!vdec_msg) { ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg " " buffer\n"); return; } vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); if (event == VCD_EVT_RESP_OUTPUT_DONE) vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED) vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED; else { ERR("QVD: vid_dec_output_frame_done invalid cmd type \n"); return; } kernel_vaddr = (unsigned long)vcd_frame_data->p_virtual; if (vid_c_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, FALSE, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, &buffer_index)) { /* Buffer address in user space */ vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr = (u8 *) user_vaddr; /* Buffer address in user space */ vdec_msg->vdec_msg_info.msgdata.output_frame.phy_addr = vcd_frame_data->p_physical; /* Data length */ vdec_msg->vdec_msg_info.msgdata.output_frame.len = vcd_frame_data->n_data_len; vdec_msg->vdec_msg_info.msgdata.output_frame.flags = vcd_frame_data->n_flags; /* Timestamp pass-through from input frame */ vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp = vcd_frame_data->time_stamp; /* Output frame client data */ vdec_msg->vdec_msg_info.msgdata.output_frame.client_data = (void *)vcd_frame_data->n_frm_clnt_data; /* Associated input frame client data */ vdec_msg->vdec_msg_info.msgdata.output_frame. input_frame_clientdata = (void *)vcd_frame_data->n_ip_frm_tag; /* Decoded picture width and height */ vdec_msg->vdec_msg_info.msgdata.output_frame.framesize. n_bottom = vcd_frame_data->dec_op_prop.disp_frm.n_bottom; vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.n_left = vcd_frame_data->dec_op_prop.disp_frm.n_left; vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.n_right = vcd_frame_data->dec_op_prop.disp_frm.n_right; vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.n_top = vcd_frame_data->dec_op_prop.disp_frm.n_top; vdec_msg->vdec_msg_info.msgdatasize = sizeof(struct vdec_output_frameinfo); } else { ERR("vid_dec_output_frame_done UVA can not be found\n"); vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL; } mutex_lock(&client_ctx->msg_queue_lock); list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); mutex_unlock(&client_ctx->msg_queue_lock); wake_up(&client_ctx->msg_wait); }