msm: vidc: Extract PAR info for MPEG4/DIVX.
Display needs the pixel aspect ratio information
from the video decoder to display the picture
with the right aspect ratio. Video decoder extracts
the pixel aspect ratio information from the
video core and passes it to the client/display
as extradata.
Change-Id: I4db2b8ba827af67bc01888d13c36c1b501934ccd
Signed-off-by: Arun Menon <menon@codeaurora.org>
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 8eba8bd..830c777c3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1236,6 +1236,9 @@
if (vidc_msg_timing)
ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
ddl_process_decoder_metadata(ddl);
+ vidc_sm_get_aspect_ratio_info(
+ &ddl->shared_mem[ddl->command_channel],
+ &output_vcd_frm->aspect_ratio_info);
ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
vcd_status, output_frame,
sizeof(struct ddl_frame_data_tag),
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index c46a349..cce779e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -184,6 +184,14 @@
#define VIDC_SM_METADATA_ENABLE_QP_BMSK 0x1
#define VIDC_SM_METADATA_ENABLE_QP_SHFT 0
+#define VIDC_SM_ASPECT_RATIO_INFO_ADDR 0x00c8
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_BMSK 0xf
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_SHFT 0x0
+#define VIDC_SM_EXTENDED_PAR_ADDR 0x00cc
+#define VIDC_SM_EXTENDED_PAR_WIDTH_BMSK 0xffff0000
+#define VIDC_SM_EXTENDED_PAR_WIDTH_SHFT 0xf
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK 0x0000ffff
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT 0x0
#define VIDC_SM_METADATA_STATUS_ADDR 0x003c
#define VIDC_SM_METADATA_STATUS_STATUS_BMSK 0x1
@@ -770,3 +778,24 @@
DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR,
consume_info);
}
+
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+ struct vcd_aspect_ratio *aspect_ratio_info)
+{
+ u32 extended_par_info = 0;
+ aspect_ratio_info->aspect_ratio = DDL_MEM_READ_32(shared_mem,
+ VIDC_SM_ASPECT_RATIO_INFO_ADDR);
+
+ if (aspect_ratio_info->aspect_ratio == 0x0f) {
+ extended_par_info = DDL_MEM_READ_32(shared_mem,
+ VIDC_SM_EXTENDED_PAR_ADDR);
+ aspect_ratio_info->extended_par_width =
+ VIDC_GETFIELD(extended_par_info,
+ VIDC_SM_EXTENDED_PAR_WIDTH_BMSK,
+ VIDC_SM_EXTENDED_PAR_WIDTH_SHFT);
+ aspect_ratio_info->extended_par_height =
+ VIDC_GETFIELD(extended_par_info,
+ VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK,
+ VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
+ }
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 798a537..b0e6758 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -179,4 +179,6 @@
void vidc_sm_set_decoder_stuff_bytes_consumption(
struct ddl_buf_addr *shared_mem,
enum vidc_sm_num_stuff_bytes_consume_info consume_info);
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+ struct vcd_aspect_ratio *aspect_ratio_info);
#endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 7fbad23..61deb8d 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -237,6 +237,7 @@
enum vdec_picture pic_type;
u32 ion_flag = 0;
struct ion_handle *buff_handle = NULL;
+ struct vdec_output_frameinfo *output_frame;
if (!client_ctx || !vcd_frame_data) {
ERR("vid_dec_input_frame_done() NULL pointer\n");
@@ -329,6 +330,13 @@
}
vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
pic_type;
+ output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame;
+ output_frame->aspect_ratio_info.aspect_ratio =
+ vcd_frame_data->aspect_ratio_info.aspect_ratio;
+ output_frame->aspect_ratio_info.par_width =
+ vcd_frame_data->aspect_ratio_info.extended_par_width;
+ output_frame->aspect_ratio_info.par_height =
+ vcd_frame_data->aspect_ratio_info.extended_par_height;
vdec_msg->vdec_msg_info.msgdatasize =
sizeof(struct vdec_output_frameinfo);
} else {
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index 9c742b5..0c03e13 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -514,6 +514,12 @@
uint32_t bottom;
};
+struct vdec_aspectratioinfo {
+ uint32_t aspect_ratio;
+ uint32_t par_width;
+ uint32_t par_height;
+};
+
struct vdec_output_frameinfo {
void __user *bufferaddr;
size_t offset;
@@ -525,6 +531,7 @@
void *input_frame_clientdata;
struct vdec_framesize framesize;
enum vdec_interlaced_format interlaced_format;
+ struct vdec_aspectratioinfo aspect_ratio_info;
};
union vdec_msgdata {
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 6304c93..20d3ef9 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -53,6 +53,12 @@
VCD_PWR_STATE_SLEEP,
};
+struct vcd_aspect_ratio {
+ u32 aspect_ratio;
+ u32 extended_par_width;
+ u32 extended_par_height;
+};
+
struct vcd_frame_data {
u8 *virtual;
u8 *physical;
@@ -71,6 +77,7 @@
u8 *desc_buf;
u32 desc_size;
struct ion_handle *buff_ion_handle;
+ struct vcd_aspect_ratio aspect_ratio_info;
};
struct vcd_sequence_hdr {