From 4b5b72d7dd3fe944d75029ff0ca6db1e74600e59 Mon Sep 17 00:00:00 2001 From: "Liu, Shuo" Date: Fri, 7 Jan 2011 19:32:51 +0800 Subject: Update psb_video from medfield-meego 2010-12-15 release to enable stagefright based video playback Change-Id: I41ca5c27a819895ef3c0eed529b84edca0f1fa24 Signed-off-by: Liu, Shuo --- src/Android.mk | 122 +- src/Makefile.am | 2 +- src/android/psb_android_glue.cpp | 42 + src/android/psb_android_glue.h | 16 +- src/android/psb_output_android.c | 10 + src/android/psb_texstreaming.c | 4 +- src/hwdefs/dxva_cmdseq_msg.h | 117 + src/hwdefs/dxva_fw_ctrl.h | 22 +- src/hwdefs/dxva_msg.h | 6 + src/hwdefs/img_types.h | 2 + src/hwdefs/msvdx_cmds_io2.h | 12 + src/lnc_H263ES.c | 51 +- src/lnc_H264ES.c | 107 +- src/lnc_H264ES.h | 2 +- src/lnc_MPEG4ES.c | 54 +- src/lnc_cmdbuf.c | 7 +- src/lnc_cmdbuf.h | 2 +- src/lnc_hostcode.c | 374 +-- src/lnc_hostcode.h | 14 +- src/pnw_H263ES.c | 76 +- src/pnw_H264.c | 733 ++--- src/pnw_H264ES.c | 307 +- src/pnw_H264ES.h | 3 +- src/pnw_MPEG2.c | 242 +- src/pnw_MPEG4.c | 145 +- src/pnw_MPEG4ES.c | 87 +- src/pnw_VC1.c | 3326 ++++++++++++++++++++ src/pnw_VC1.h | 33 + src/pnw_cmdbuf.c | 28 +- src/pnw_cmdbuf.h | 25 +- src/pnw_hostcode.c | 481 +-- src/pnw_hostcode.h | 31 +- src/pnw_hostheader.c | 1065 +++++-- src/pnw_hostheader.h | 21 +- src/pnw_jpeg.c | 17 +- src/powervr_iep_lite/csc/csc2.c | 1946 ++++++------ src/powervr_iep_lite/csc/csc2_data.c | 1510 ++++----- src/powervr_iep_lite/csc/csc2_data.h | 212 +- .../fixedpointmaths/fixedpoint_sinetable.h | 908 +++--- .../fixedpointmaths/fixedpointmaths.c | 1118 +++---- src/powervr_iep_lite/iep_lite/iep_lite_api.c | 1040 +++--- src/powervr_iep_lite/iep_lite/iep_lite_api.h | 432 +-- src/powervr_iep_lite/iep_lite/iep_lite_hardware.c | 150 +- src/powervr_iep_lite/iep_lite/iep_lite_reg_defs.h | 2336 +++++++------- src/powervr_iep_lite/iep_lite/iep_lite_utils.c | 666 ++-- src/powervr_iep_lite/iep_lite/iep_lite_utils.h | 356 +-- src/powervr_iep_lite/iep_lite_demo/iep_lite_demo.c | 116 +- src/powervr_iep_lite/include/csc2.h | 234 +- src/powervr_iep_lite/include/fixedpointmaths.h | 796 ++--- src/powervr_iep_lite/include/win32/img_iep_defs.h | 428 +-- src/psb_H264.c | 6 +- src/psb_VC1.c | 36 + src/psb_buffer.c | 6 + src/psb_cmdbuf.c | 259 +- src/psb_cmdbuf.h | 27 + src/psb_drv_video.c | 301 +- src/psb_drv_video.h | 5 + src/psb_output.c | 21 +- src/psb_overlay.c | 199 +- src/psb_overlay.h | 25 + src/psb_surface.c | 2 +- src/psb_texture.c | 229 +- src/psb_texture.h | 11 +- src/psb_ws_driver.c | 28 - src/psb_ws_driver.h | 28 - src/pvr2d.h | 172 +- src/vc1_header.h | 30 + src/vc1_idx.c | 1 + src/vc1_vlc.c | 4 +- src/x11/psb_coverlay.c | 1234 +++++--- src/x11/psb_ctexture.c | 369 ++- src/x11/psb_x11.c | 110 +- src/x11/psb_xrandr.c | 895 +++--- src/x11/psb_xrandr.h | 292 +- src/x11/psb_xvva.c | 37 +- 75 files changed, 14847 insertions(+), 9314 deletions(-) create mode 100644 src/pnw_VC1.c create mode 100644 src/pnw_VC1.h (limited to 'src') diff --git a/src/Android.mk b/src/Android.mk index 7d2a32b..3c914b4 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -26,75 +26,75 @@ include $(CLEAR_VARS) PSBVIDEO_LOG_ENABLE := true LOCAL_SRC_FILES := \ - lnc_H263ES.c \ - lnc_H264ES.c \ - lnc_MPEG4ES.c \ - lnc_cmdbuf.c \ - lnc_hostcode.c \ - lnc_hostheader.c \ - lnc_ospm.c \ - object_heap.c \ - psb_H264.c \ - psb_MPEG2.c \ - psb_MPEG2MC.c \ - psb_MPEG4.c \ - psb_texture.c \ - psb_VC1.c \ - psb_buffer.c \ - psb_buffer_dm.c \ - psb_cmdbuf.c \ - psb_deblock.c \ - psb_drv_video.c \ - psb_output.c \ - android/psb_texstreaming.c \ - android/psb_output_android.c \ - android/psb_android_glue.cpp \ - psb_surface.c \ - psb_overlay.c \ - psb_ws_driver.c \ - vc1_idx.c \ - vc1_vlc.c \ - pnw_H263ES.c \ - pnw_H264.c \ - pnw_H264ES.c \ - pnw_MPEG2.c \ - pnw_MPEG4.c \ - pnw_MPEG4ES.c \ - pnw_cmdbuf.c \ - pnw_hostcode.c \ - pnw_hostheader.c \ - pnw_hostjpeg.c \ - pnw_jpeg.c \ - powervr_iep_lite/csc/csc2.c \ - powervr_iep_lite/csc/csc2_data.c \ - powervr_iep_lite/fixedpointmaths/fixedpointmaths.c \ - powervr_iep_lite/iep_lite/iep_lite_api.c \ - powervr_iep_lite/iep_lite/iep_lite_hardware.c \ - powervr_iep_lite/iep_lite/iep_lite_utils.c + lnc_H263ES.c \ + lnc_H264ES.c \ + lnc_MPEG4ES.c \ + lnc_cmdbuf.c \ + lnc_hostcode.c \ + lnc_hostheader.c \ + lnc_ospm.c \ + object_heap.c \ + psb_H264.c \ + psb_MPEG2.c \ + psb_MPEG2MC.c \ + psb_MPEG4.c \ + psb_VC1.c \ + psb_buffer.c \ + psb_buffer_dm.c \ + psb_cmdbuf.c \ + psb_deblock.c \ + psb_drv_video.c \ + psb_output.c \ + android/psb_texstreaming.c \ + android/psb_output_android.c \ + android/psb_android_glue.cpp \ + psb_surface.c \ + psb_overlay.c \ + psb_ws_driver.c \ + vc1_idx.c \ + vc1_vlc.c \ + pnw_H263ES.c \ + pnw_H264.c \ + pnw_H264ES.c \ + pnw_MPEG2.c \ + pnw_MPEG4.c \ + pnw_MPEG4ES.c \ + pnw_VC1.c \ + pnw_cmdbuf.c \ + pnw_hostcode.c \ + pnw_hostheader.c \ + pnw_hostjpeg.c \ + pnw_jpeg.c \ + powervr_iep_lite/csc/csc2.c \ + powervr_iep_lite/csc/csc2_data.c \ + powervr_iep_lite/fixedpointmaths/fixedpointmaths.c \ + powervr_iep_lite/iep_lite/iep_lite_api.c \ + powervr_iep_lite/iep_lite/iep_lite_hardware.c \ + powervr_iep_lite/iep_lite/iep_lite_utils.c LOCAL_CFLAGS := -DLINUX -DANDROID -g -Wall -Wno-unused LOCAL_C_INCLUDES := \ - $(TOPDIR)hardware/intel/include \ - $(TOPDIR)hardware/intel/include/eurasia/pvr2d \ - $(TARGET_OUT_HEADERS)/libva \ - $(TOPDIR)hardware/intel/include/drm \ - $(TARGET_OUT_HEADERS)/libttm \ - $(TARGET_OUT_HEADERS)/libmemrar \ - $(TARGET_OUT_HEADERS)/libwsbm \ - $(TARGET_OUT_HEADERS)/libpsb_drm\ - $(TARGET_OUT_HEADERS)/opengles \ - $(LOCAL_PATH)/hwdefs \ - $(LOCAL_PATH)/powervr_iep_lite/include \ - $(LOCAL_PATH)/powervr_iep_lite/include/win32 \ - $(LOCAL_PATH)/powervr_iep_lite/csc \ - $(LOCAL_PATH)/powervr_iep_lite/iep_lite \ - $(LOCAL_PATH)/powervr_iep_lite/fixedpointmaths + $(TOPDIR)hardware/intel/include \ + $(TOPDIR)hardware/intel/include/eurasia/pvr2d \ + $(TARGET_OUT_HEADERS)/libva \ + $(TOPDIR)hardware/intel/include/drm \ + $(TARGET_OUT_HEADERS)/libttm \ + $(TARGET_OUT_HEADERS)/libmemrar \ + $(TARGET_OUT_HEADERS)/libwsbm \ + $(TARGET_OUT_HEADERS)/libpsb_drm\ + $(TARGET_OUT_HEADERS)/opengles \ + $(LOCAL_PATH)/hwdefs \ + $(LOCAL_PATH)/powervr_iep_lite/include \ + $(LOCAL_PATH)/powervr_iep_lite/include/win32 \ + $(LOCAL_PATH)/powervr_iep_lite/csc \ + $(LOCAL_PATH)/powervr_iep_lite/iep_lite \ + $(LOCAL_PATH)/powervr_iep_lite/fixedpointmaths LOCAL_MODULE := pvr_drv_video LOCAL_SHARED_LIBRARIES := libdl libdrm libwsbm libmemrar libpvr2d libcutils \ - libui libutils libbinder libsurfaceflinger_client + libui libutils libbinder libsurfaceflinger_client ifeq ($(strip $(PSBVIDEO_LOG_ENABLE)),true) LOCAL_CFLAGS += -DPSBVIDEO_LOG_ENABLE diff --git a/src/Makefile.am b/src/Makefile.am index 67f0c9a..6a6be51 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,7 @@ pvr_drv_video_la_SOURCES = psb_drv_video.c object_heap.c psb_buffer.c psb_buffer lnc_hostcode.c lnc_hostheader.c lnc_ospm.c psb_ws_driver.c \ pnw_hostheader.c pnw_hostcode.c \ pnw_cmdbuf.c pnw_H264ES.c pnw_H263ES.c pnw_MPEG4ES.c \ - pnw_H264.c pnw_MPEG2.c pnw_MPEG4.c pnw_hostjpeg.c pnw_jpeg.c \ + pnw_H264.c pnw_MPEG2.c pnw_MPEG4.c pnw_hostjpeg.c pnw_jpeg.c pnw_VC1.c\ psb_output.c psb_overlay.c psb_texture.c \ x11/psb_x11.c x11/psb_coverlay.c x11/psb_xrandr.c x11/psb_xvva.c x11/psb_ctexture.c \ powervr_iep_lite/csc/csc2.c \ diff --git a/src/android/psb_android_glue.cpp b/src/android/psb_android_glue.cpp index d8f77d1..5c747e2 100644 --- a/src/android/psb_android_glue.cpp +++ b/src/android/psb_android_glue.cpp @@ -88,6 +88,48 @@ void psb_android_register_isurface(void** android_isurface, int bcd_id, int srcw isurface->setTextureStreamDim(srcw, srch-1); } +void psb_android_texture_streaming_set_crop( short srcx, + short srcy, + unsigned short srcw, + unsigned short srch ) +{ + if (isurface.get()) { + isurface->setTextureStreamClipRect(srcx, srcy, srcw, srch); + } +} + +void psb_android_texture_streaming_set_blend( short destx, + short desty, + unsigned short destw, + unsigned short desth, + unsigned int blend_enabled, + unsigned int background_color, + unsigned int blend_color, + unsigned short blend_mode ) +{ + unsigned short bg_red, bg_green, bg_blue, bg_alpha; + unsigned short blend_red, blend_green, blend_blue, blend_alpha; + bg_alpha = (background_color & 0xff000000) >> 24; + bg_red = (background_color & 0xff0000) >> 16; + bg_green = (background_color & 0xff00) >> 8; + bg_blue = background_color & 0xff; + + blend_alpha = (blend_color & 0xff000000) >> 24; + blend_red = (blend_color & 0xff0000) >> 16; + blend_green = (blend_color & 0xff00) >> 8; + blend_blue = blend_color & 0xff; + + if (isurface.get()) { + if (blend_enabled) { + isurface->setTextureStreamPosRect(destx, desty, destw, desth); + isurface->setTextureStreamBorderColor(bg_red, bg_green, bg_blue, bg_alpha); + isurface->setTextureStreamVideoColor(blend_red, blend_green, blend_blue, blend_alpha); + isurface->setTextureStreamBlendMode(blend_mode); + } else + isurface->resetTextureStreamParams(); + } +} + void psb_android_texture_streaming_display(int buffer_index) { if (isurface.get()) diff --git a/src/android/psb_android_glue.h b/src/android/psb_android_glue.h index bc2d06a..ab33704 100644 --- a/src/android/psb_android_glue.h +++ b/src/android/psb_android_glue.h @@ -27,7 +27,7 @@ extern "C" { /* add for texture streaming */ -#define DRM_BUFFER_CLASS_VIDEO 0x2C +#define DRM_BUFFER_CLASS_VIDEO 0x32 #define BC_FOURCC(a,b,c,d) \ ((unsigned long) ((a) | (b)<<8 | (c)<<16 | (d)<<24)) @@ -93,6 +93,20 @@ void psb_android_clearHeap(); void psb_android_texture_streaming_display(int buffer_index); +void psb_android_texture_streaming_set_crop( short srcx, + short srcy, + unsigned short srcw, + unsigned short srch); + +void psb_android_texture_streaming_set_blend( short destx, + short desty, + unsigned short destw, + unsigned short desth, + unsigned int blend_enabled, + unsigned int border_color, + unsigned int blend_color, + unsigned short blend_mode); + void psb_android_texture_streaming_destroy(); void psb_android_register_isurface(void** surface, int bcd_id, int srcw, int srch); diff --git a/src/android/psb_output_android.c b/src/android/psb_output_android.c index b1d440f..fd4cca4 100644 --- a/src/android/psb_output_android.c +++ b/src/android/psb_output_android.c @@ -120,6 +120,7 @@ void *psb_android_output_init(VADriverContextP ctx) /* TS by default */ driver_data->output_method = PSB_PUTSURFACE_TEXSTREAMING; + driver_data->color_key = 0x0; /*black*/ if (psb_parse_config("PSB_VIDEO_COVERLAY", &put_surface[0]) == 0) { psb__information_message("Putsurface use client overlay\n"); @@ -292,6 +293,15 @@ VAStatus psb_PutSurface( output->register_flag = 1; } + psb_android_texture_streaming_set_blend(destx, desty, destw, desth, + flags & VA_ENABLE_BLEND, + driver_data->clear_color, + driver_data->blend_color, + driver_data->blend_mode); + + if ((srcx != 0) || (srcy != 0) || (obj_surface->width != srcw) || (obj_surface->height_origin != srch)) + psb_android_texture_streaming_set_crop(srcx, srcy, srcw, srch); + BC_Video_ioctl_package ioctl_package; psb_surface_p psb_surface; psb_surface = obj_surface->psb_surface; diff --git a/src/android/psb_texstreaming.c b/src/android/psb_texstreaming.c index 85bd14f..6c456c1 100644 --- a/src/android/psb_texstreaming.c +++ b/src/android/psb_texstreaming.c @@ -63,7 +63,7 @@ VAStatus psb_register_video_bcd( return VA_STATUS_ERROR_UNKNOWN; } buffer_device_id = ioctl_package.outputparam; - + LOGD("In psb_register_video_bcd, the allocated bc device id is %d.\n", buffer_device_id); LOGD("In psb_register_video_bcd, call BC_Video_ioctl_get_buffer_count to get buffer count.\n"); ioctl_package.ioctl_cmd = BC_Video_ioctl_get_buffer_count; ioctl_package.device_id = buffer_device_id; @@ -111,7 +111,7 @@ VAStatus psb_release_video_bcd( VADriverContextP ctx ) if (driver_data->output_method == PSB_PUTSURFACE_TEXSTREAMING || driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING) { - LOGD("In psb_register_video_bcd, call BC_Video_ioctl_release_buffer_device to release video buffer device id.\n"); + LOGD("In psb_release_video_bcd, call BC_Video_ioctl_release_buffer_device to release video buffer device id.\n"); ioctl_package.ioctl_cmd = BC_Video_ioctl_release_buffer_device; ioctl_package.device_id = buffer_device_id; if (drmCommandWriteRead(driver_data->drm_fd, DRM_BUFFER_CLASS_VIDEO, &ioctl_package, sizeof(ioctl_package)) != 0) diff --git a/src/hwdefs/dxva_cmdseq_msg.h b/src/hwdefs/dxva_cmdseq_msg.h index d38c4ce..2a6d084 100644 --- a/src/hwdefs/dxva_cmdseq_msg.h +++ b/src/hwdefs/dxva_cmdseq_msg.h @@ -50,6 +50,47 @@ typedef struct { uint32_t pad[3]; } DEBLOCKPARAMS; +typedef struct { + union { + struct { + uint32_t msg_size : 8; + uint32_t msg_type : 8; + uint32_t msg_fence : 16; + } bits; + uint32_t value; + } header; + union { + struct { + uint32_t flags : 16; + uint32_t slice_type : 8; + uint32_t padding : 8; + } bits; + uint32_t value; + } flags; + uint32_t operating_mode; + union { + struct { + uint32_t context : 8; + uint32_t mmu_ptd : 24; + } bits; + uint32_t value; + } mmu_context; + union { + struct { + uint32_t frame_height_mb : 16; + uint32_t pic_width_mb : 16; + } bits; + uint32_t value; + } pic_size; + uint32_t address_a0; + uint32_t address_a1; + uint32_t mb_param_address; + uint32_t ext_stride_a; + uint32_t address_b0; + uint32_t address_b1; + uint32_t rotation_flags; +} FW_VA_DEBLOCK_MSG; + /* OOLD message */ typedef struct { uint32_t pad[5]; @@ -152,7 +193,83 @@ typedef struct { #define FW_DXVA_RENDER_FLAGS_OFFSET (0x001C) #define FW_DXVA_RENDER_FLAGS_SHIFT (0) +#define FW_DEVA_DECODE_SIZE (20) + +// FW_DEVA_DECODE MSG_ID +#define FW_DEVA_DECODE_MSG_ID_ALIGNMENT (2) +#define FW_DEVA_DECODE_MSG_ID_TYPE IMG_UINT16 +#define FW_DEVA_DECODE_MSG_ID_MASK (0xFFFF) +#define FW_DEVA_DECODE_MSG_ID_LSBMASK (0xFFFF) +#define FW_DEVA_DECODE_MSG_ID_OFFSET (0x0002) +#define FW_DEVA_DECODE_MSG_ID_SHIFT (0) + +// FW_DEVA_DECODE ID +#define FW_DEVA_DECODE_ID_ALIGNMENT (1) +#define FW_DEVA_DECODE_ID_TYPE IMG_UINT8 +#define FW_DEVA_DECODE_ID_MASK (0xFF) +#define FW_DEVA_DECODE_ID_LSBMASK (0xFF) +#define FW_DEVA_DECODE_ID_OFFSET (0x0001) +#define FW_DEVA_DECODE_ID_SHIFT (0) + +// FW_DEVA_DECODE MSG_SIZE +#define FW_DEVA_DECODE_MSG_SIZE_ALIGNMENT (1) +#define FW_DEVA_DECODE_MSG_SIZE_TYPE IMG_UINT8 +#define FW_DEVA_DECODE_MSG_SIZE_MASK (0xFF) +#define FW_DEVA_DECODE_MSG_SIZE_LSBMASK (0xFF) +#define FW_DEVA_DECODE_MSG_SIZE_OFFSET (0x0000) +#define FW_DEVA_DECODE_MSG_SIZE_SHIFT (0) + +// FW_DEVA_DECODE FLAGS +#define FW_DEVA_DECODE_FLAGS_ALIGNMENT (2) +#define FW_DEVA_DECODE_FLAGS_TYPE IMG_UINT16 +#define FW_DEVA_DECODE_FLAGS_MASK (0xFFFF) +#define FW_DEVA_DECODE_FLAGS_LSBMASK (0xFFFF) +#define FW_DEVA_DECODE_FLAGS_OFFSET (0x0004) +#define FW_DEVA_DECODE_FLAGS_SHIFT (0) + +// FW_DEVA_DECODE BUFFER_SIZE +#define FW_DEVA_DECODE_BUFFER_SIZE_ALIGNMENT (2) +#define FW_DEVA_DECODE_BUFFER_SIZE_TYPE IMG_UINT16 +#define FW_DEVA_DECODE_BUFFER_SIZE_MASK (0xFFFF) +#define FW_DEVA_DECODE_BUFFER_SIZE_LSBMASK (0xFFFF) +#define FW_DEVA_DECODE_BUFFER_SIZE_OFFSET (0x0006) +#define FW_DEVA_DECODE_BUFFER_SIZE_SHIFT (0) + +// FW_DEVA_DECODE LLDMA_ADDRESS +#define FW_DEVA_DECODE_LLDMA_ADDRESS_ALIGNMENT (4) +#define FW_DEVA_DECODE_LLDMA_ADDRESS_TYPE IMG_UINT32 +#define FW_DEVA_DECODE_LLDMA_ADDRESS_MASK (0xFFFFFFFF) +#define FW_DEVA_DECODE_LLDMA_ADDRESS_LSBMASK (0xFFFFFFFF) +#define FW_DEVA_DECODE_LLDMA_ADDRESS_OFFSET (0x0008) +#define FW_DEVA_DECODE_LLDMA_ADDRESS_SHIFT (0) + +// FW_DEVA_DECODE MMUPTD +#define FW_DEVA_DECODE_MMUPTD_ALIGNMENT (4) +#define FW_DEVA_DECODE_MMUPTD_TYPE IMG_UINT32 +#define FW_DEVA_DECODE_MMUPTD_MASK (0xFFFFFF00) +#define FW_DEVA_DECODE_MMUPTD_LSBMASK (0x00FFFFFF) +#define FW_DEVA_DECODE_MMUPTD_OFFSET (0x000C) +#define FW_DEVA_DECODE_MMUPTD_SHIFT (8) + +// FW_DEVA_DECODE CONTEXT +#define FW_DEVA_DECODE_CONTEXT_ALIGNMENT (1) +#define FW_DEVA_DECODE_CONTEXT_TYPE IMG_UINT8 +#define FW_DEVA_DECODE_CONTEXT_MASK (0xFF) +#define FW_DEVA_DECODE_CONTEXT_LSBMASK (0xFF) +#define FW_DEVA_DECODE_CONTEXT_OFFSET (0x000C) + #define FW_DXVA_DEBLOCK_SIZE (16 + 32) /* 32 bytes for DEBLOCKPARAMS */ +#define FW_DEVA_DEBLOCK_SIZE (48) + +#define FW_DEVA_DECODE_CONTEXT_SHIFT (0) + +// FW_DEVA_DECODE OPERATING_MODE +#define FW_DEVA_DECODE_OPERATING_MODE_ALIGNMENT (4) +#define FW_DEVA_DECODE_OPERATING_MODE_TYPE IMG_UINT32 +#define FW_DEVA_DECODE_OPERATING_MODE_MASK (0xFFFFFFFF) +#define FW_DEVA_DECODE_OPERATING_MODE_LSBMASK (0xFFFFFFFF) +#define FW_DEVA_DECODE_OPERATING_MODE_OFFSET (0x0010) +#define FW_DEVA_DECODE_OPERATING_MODE_SHIFT (0) // FW_DXVA_DEBLOCK MSG_SIZE #define FW_DXVA_DEBLOCK_MSG_SIZE_ALIGNMENT (1) diff --git a/src/hwdefs/dxva_fw_ctrl.h b/src/hwdefs/dxva_fw_ctrl.h index c8eb803..7793dfd 100644 --- a/src/hwdefs/dxva_fw_ctrl.h +++ b/src/hwdefs/dxva_fw_ctrl.h @@ -49,16 +49,22 @@ #define CMD_REGVALPAIR_FLAG_MB_LAYER (0x00100000) #define CMD_REGVALPAIR_FLAG_HL_LAYER (0x00200000) #define CMD_REGVALPAIR_FLAG_PRELOAD (0x00400000) - - +#define CMD_REGVALPAIR_FLAG_VC1PATCH (0x00800000) #define CMD_REGVALPAIR_FORCE_MASK (0x08000000) /* Rendec Write Block */ #define CMD_RENDEC_WRITE (0x20000000) +#define CMD_RENDEC_BLOCK (0x50000000) #define CMD_RENDEC_COUNT_MASK (0x000FFFFF) #define CMD_RENDEC_COUNT_SHIFT (0) +/* Rendec Block */ +#define CMD_RENDEC_BLOCK_FLAG_VC1_CMD_PATCH (0x01000000) +#define CMD_RENDEC_BLOCK_FLAG_VC1_BE_PATCH (0x02000000) +#define CMD_RENDEC_BLOCK_FLAG_VC1_SP_PATCH (0x04000000) +#define CMD_RENDEC_BLOCK_FLAG_VC1_IC_PATCH (0x08000000) + /* Command Allocation temination Commands */ #define CMD_COMPLETION (0x60000000) @@ -70,6 +76,9 @@ #define CMD_HEADER_VC1 (0x90000000) +#define CMD_PARSE_HEADER (0xF0000000) +#define CMD_PARSE_HEADER_NEWSLICE (0x00000001) + typedef struct _RENDER_BUFFER_HEADER_VC1_TAG { @@ -109,6 +118,15 @@ typedef struct _RENDER_BUFFER_HEADER_TAG } RENDER_BUFFER_HEADER; +typedef struct _PARSE_HEADER_CMD_TAG { + IMG_UINT32 ui32Cmd; + IMG_UINT32 ui32SeqHdrData; + IMG_UINT32 ui32PicDimensions; + IMG_UINT32 ui32BitplaneAddr[3]; + IMG_UINT32 ui32VLCTableAddr; + IMG_UINT32 ui32ICParamData[2]; +} PARSE_HEADER_CMD; + /* Linked list DMA Command */ #define CMD_LLDMA (0xA0000000) #define CMD_SLLDMA (0xC0000000) /* Syncronose LLDMA */ diff --git a/src/hwdefs/dxva_msg.h b/src/hwdefs/dxva_msg.h index ac735d8..a52f1d3 100644 --- a/src/hwdefs/dxva_msg.h +++ b/src/hwdefs/dxva_msg.h @@ -45,6 +45,9 @@ extern "C" { #define FWRK_MSGID_START_PSR_HOSTMTX_MSG (0x80) //!< Start of parser specific Host->MTX messages. #define FWRK_MSGID_START_PSR_MTXHOST_MSG (0xC0) //!< Start of parser specific MTX->Host messages. #define FWRK_MSGID_PADDING ( 0 ) + +#define FWRK_MSGID_HOST_EMULATED (0x40) + /*! ****************************************************************************** @@ -71,6 +74,9 @@ enum /*! Sent by the mtx firmware to itself. */ DXVA_MSGID_RENDER_MC_INTERRUPT, + + VA_MSGID_DEBLOCK_MFLD = FWRK_MSGID_HOST_EMULATED, + VA_MSGID_OOLD_MFLD, /*! Sent by the DXVA firmware on the MTX to the host. */ diff --git a/src/hwdefs/img_types.h b/src/hwdefs/img_types.h index e7a5771..8add1e6 100644 --- a/src/hwdefs/img_types.h +++ b/src/hwdefs/img_types.h @@ -52,6 +52,8 @@ typedef unsigned short IMG_UINT16, *IMG_PUINT16; typedef signed short IMG_INT16, *IMG_PINT16; typedef unsigned long IMG_UINT32, *IMG_PUINT32; typedef signed long IMG_INT32, *IMG_PINT32; +typedef unsigned long long IMG_UINT64, *IMG_PUINT64; +typedef signed long long IMG_INT64, *IMG_PINT64; #if defined(_WIN32) diff --git a/src/hwdefs/msvdx_cmds_io2.h b/src/hwdefs/msvdx_cmds_io2.h index 13a33e5..3f5be71 100644 --- a/src/hwdefs/msvdx_cmds_io2.h +++ b/src/hwdefs/msvdx_cmds_io2.h @@ -1247,6 +1247,18 @@ extern "C" { #define MSVDX_CMDS_ALTERNATIVE_OUTPUT_PICTURE_ROTATION_ROTATION_MODE_LSBMASK (0x00000003) #define MSVDX_CMDS_ALTERNATIVE_OUTPUT_PICTURE_ROTATION_ROTATION_MODE_SHIFT (0) +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_OFFSET (0x0040) + +// MSVDX_CMDS, EXTENDED_ROW_STRIDE, RPR_ROW_STRIDE +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_RPR_ROW_STRIDE_MASK (0xFFC00000) +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_RPR_ROW_STRIDE_LSBMASK (0x000003FF) +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_RPR_ROW_STRIDE_SHIFT (22) + +// MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_EXT_ROW_STRIDE_MASK (0x0000FFC0) +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_EXT_ROW_STRIDE_LSBMASK (0x000003FF) +#define MSVDX_CMDS_EXTENDED_ROW_STRIDE_EXT_ROW_STRIDE_SHIFT (6) + #ifdef __cplusplus } #endif diff --git a/src/lnc_H263ES.c b/src/lnc_H263ES.c index 991a9c4..dedb71b 100644 --- a/src/lnc_H263ES.c +++ b/src/lnc_H263ES.c @@ -306,6 +306,7 @@ static VAStatus lnc__H263ES_process_slice_param(context_ENC_p ctx, object_buffer lnc_cmdbuf_p cmdbuf=ctx->obj_context->lnc_cmdbuf; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); int i; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); @@ -328,8 +329,31 @@ static VAStatus lnc__H263ES_process_slice_param(context_ENC_p ctx, object_buffer RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); } + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) + { + ctx->slice_param_num = obj_buffer->num_elements; + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + } + for(i = 0; i < obj_buffer->num_elements; i++) { - /*Todo list: + /*Todo list: *1.Insert Do header command *2.setup InRowParams *3.setup Slice params @@ -352,9 +376,12 @@ static VAStatus lnc__H263ES_process_slice_param(context_ENC_p ctx, object_buffer if( (ctx->obj_context->frame_count == 0) && (pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra) lnc_reset_encoder_params(ctx); - if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], pBuffer) == 0) { + /*The corresponding slice buffer cache*/ + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + i; + + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer) == 0) { /* cache current param parameters */ - memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], + memcpy(&ctx->slice_param_cache[slice_param_idx], pBuffer, sizeof(VAEncSliceParameterBuffer)); /* Setup InParams value*/ @@ -394,7 +421,7 @@ static VAStatus lnc__H263ES_process_misc_param(context_ENC_p ctx, object_buffer_ { /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */ VAEncMiscParameterBuffer *pBuffer; - VAEncMiscParameterBitRate *bitrate_param; + VAEncMiscParameterRateControl *rate_control_param; VAEncMiscParameterAIR *air_param; VAEncMiscParameterMaxSliceSize *max_slice_size_param; VAEncMiscParameterFrameRate *frame_rate_param; @@ -403,7 +430,7 @@ static VAStatus lnc__H263ES_process_misc_param(context_ENC_p ctx, object_buffer_ ASSERT(obj_buffer->type == VAEncMiscParameterBufferType); - pBuffer = (VAEncSliceParameterBuffer *) obj_buffer->buffer_data; + pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data; obj_buffer->size = 0; switch (pBuffer->type) { @@ -413,26 +440,26 @@ static VAStatus lnc__H263ES_process_misc_param(context_ENC_p ctx, object_buffer_ frame_rate_param->framerate); break; - case VAEncMiscParameterTypeBitRate: - bitrate_param = (VAEncMiscParameterBitRate *)pBuffer->data; + case VAEncMiscParameterTypeRateControl: + rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data; psb__information_message("%s: bit rate changed to %d\n", - bitrate_param->bitrate); + rate_control_param->bits_per_second); - if (bitrate_param->bitrate == ctx->sRCParams.BitsPerSecond) + if (rate_control_param->bits_per_second == ctx->sRCParams.BitsPerSecond) break; else ctx->update_rc_control = 1; - if (bitrate_param->bitrate > TOPAZ_H263_MAX_BITRATE) { + if (rate_control_param->bits_per_second > TOPAZ_H263_MAX_BITRATE) { ctx->sRCParams.BitsPerSecond = TOPAZ_H263_MAX_BITRATE; psb__information_message(" bits_per_second(%d) exceeds \ the maximum bitrate, set it with %d\n", - bitrate_param->bitrate, + rate_control_param->bits_per_second, TOPAZ_H263_MAX_BITRATE); } else - ctx->sRCParams.BitsPerSecond = bitrate_param->bitrate; + ctx->sRCParams.BitsPerSecond = rate_control_param->bits_per_second; break; diff --git a/src/lnc_H264ES.c b/src/lnc_H264ES.c index 5d8dfd7..53059a5 100644 --- a/src/lnc_H264ES.c +++ b/src/lnc_H264ES.c @@ -243,7 +243,7 @@ static VAStatus lnc__H264ES_process_sequence_param(context_ENC_p ctx, object_buf VUI_Params.Time_Scale = ctx->sRCParams.FrameRate*2; VUI_Params.bit_rate_value_minus1 = ctx->sRCParams.BitsPerSecond/64 -1; - VUI_Params.cbp_size_value_minus1 = ctx->sRCParams.BitsPerSecond*3/32 -1; + VUI_Params.cbp_size_value_minus1 = ctx->sRCParams.BufferSize/64 - 1; VUI_Params.CBR = 1; VUI_Params.initial_cpb_removal_delay_length_minus1 = 0; VUI_Params.cpb_removal_delay_length_minus1 = 0; @@ -290,7 +290,8 @@ static VAStatus lnc__H264ES_process_picture_param(context_ENC_p ctx, object_buff VAEncPictureParameterBufferH264 *pBuffer; lnc_cmdbuf_p cmdbuf = ctx->obj_context->lnc_cmdbuf; struct coded_buf_aux_info *p_aux_info; - + int need_sps = 0; + ASSERT(obj_buffer->type == VAEncPictureParameterBufferType); if ((obj_buffer->num_elements != 1) || @@ -325,6 +326,11 @@ static VAStatus lnc__H264ES_process_picture_param(context_ENC_p ctx, object_buff /* current frame is I frame (suppose), and an IDR frame is desired*/ if ((is_intra) && ((intra_cnt % ctx->sRCParams.IDRFreq) == 0)) { ctx->force_idr_h264 = 1; + + /* it is periodic IDR in the middle of one sequence encoding, need SPS */ + if (ctx->obj_context->frame_count > 0) + need_sps = 1; + ctx->obj_context->frame_count = 0; } } @@ -332,11 +338,17 @@ static VAStatus lnc__H264ES_process_picture_param(context_ENC_p ctx, object_buff /* For H264, PicHeader only needed in the first picture*/ if (!ctx->obj_context->frame_count) { cmdbuf = ctx->obj_context->lnc_cmdbuf; - + + if (need_sps) { + /* reuse the previous SPS */ + lnc_cmdbuf_insert_command(cmdbuf, MTX_CMDID_DO_HEADER, 2, 0); /* sequence header */ + RELOC_CMDBUF(cmdbuf->cmd_idx++, ctx->seq_header_ofs, &cmdbuf->header_mem); + } + + lnc__H264_prepare_picture_header(cmdbuf->header_mem_p + ctx->pic_header_ofs); + lnc_cmdbuf_insert_command(cmdbuf, MTX_CMDID_DO_HEADER, 2,1);/* picture header */ RELOC_CMDBUF(cmdbuf->cmd_idx++, ctx->pic_header_ofs, &cmdbuf->header_mem); - - lnc__H264_prepare_picture_header(cmdbuf->header_mem_p + ctx->pic_header_ofs); } /*Record if EOSEQ or EOSTREAM should be appended to the coded buffer.*/ @@ -374,6 +386,7 @@ static VAStatus lnc__H264ES_process_slice_param(context_ENC_p ctx, object_buffer unsigned int MBSkipRun, FirstMBAddress; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); int i; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); @@ -397,6 +410,29 @@ static VAStatus lnc__H264ES_process_slice_param(context_ENC_p ctx, object_buffer RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); } + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) + { + ctx->slice_param_num = obj_buffer->num_elements; + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + } + for(i = 0; i < obj_buffer->num_elements; i++) { /*Todo list: *1.Insert Do header command @@ -406,6 +442,14 @@ static VAStatus lnc__H264ES_process_slice_param(context_ENC_p ctx, object_buffer * */ int deblock_on, force_idr = 0; + if ((pBuffer->slice_height == 0) || (pBuffer->start_row_number >= ctx->Height )) { + psb__information_message("slice number is %d, but it seems the last %d buffers are empty\n", + obj_buffer->num_elements, obj_buffer->num_elements - i); + free(obj_buffer->buffer_data ); + obj_buffer->buffer_data = NULL; + return VA_STATUS_SUCCESS; + } + /* set to INTRA frame */ if (ctx->force_idr_h264 || (ctx->obj_context->frame_count == 0)) { force_idr = 1; @@ -441,9 +485,14 @@ static VAStatus lnc__H264ES_process_slice_param(context_ENC_p ctx, object_buffer if ((ctx->obj_context->frame_count == 0) && (pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra) lnc_reset_encoder_params(ctx); - if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], pBuffer) == 0) { + /*The corresponding slice buffer cache*/ + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + i; + + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer) == 0) { + psb__information_message("Cache slice%d's parameter buffer at index %d\n", i, slice_param_idx); + /* cache current param parameters */ - memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], + memcpy(&ctx->slice_param_cache[slice_param_idx], pBuffer, sizeof(VAEncSliceParameterBuffer)); /* Setup InParams value*/ @@ -483,7 +532,7 @@ static VAStatus lnc__H264ES_process_misc_param(context_ENC_p ctx, object_buffer_ { /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */ VAEncMiscParameterBuffer *pBuffer; - VAEncMiscParameterBitRate *bitrate_param; + VAEncMiscParameterRateControl *rate_control_param; VAEncMiscParameterAIR *air_param; VAEncMiscParameterMaxSliceSize *max_slice_size_param; VAEncMiscParameterFrameRate *frame_rate_param; @@ -503,27 +552,40 @@ static VAStatus lnc__H264ES_process_misc_param(context_ENC_p ctx, object_buffer_ frame_rate_param->framerate); break; - case VAEncMiscParameterTypeBitRate: - bitrate_param = (VAEncMiscParameterBitRate *)pBuffer->data; + case VAEncMiscParameterTypeRateControl: + rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data; - psb__information_message("%s: bit rate changed to %d\n", - bitrate_param->bitrate); + psb__information_message("%s: rate control changed to %d\n", + rate_control_param->bits_per_second); - if (bitrate_param->bitrate == ctx->sRCParams.BitsPerSecond) + if ((rate_control_param->bits_per_second == ctx->sRCParams.BitsPerSecond) && + (ctx->sRCParams.VCMBitrateMargin == rate_control_param->target_percentage * 128 / 100) && + (ctx->sRCParams.BufferSize == ctx->sRCParams.BitsPerSecond /1000 * rate_control_param->window_size) && + (ctx->sRCParams.MinQP == rate_control_param->min_qp) && + (ctx->sRCParams.InitialQp == rate_control_param->initial_qp)) break; else ctx->update_rc_control = 1; - if (bitrate_param->bitrate > TOPAZ_H264_MAX_BITRATE) { + if (rate_control_param->bits_per_second > TOPAZ_H264_MAX_BITRATE) { ctx->sRCParams.BitsPerSecond = TOPAZ_H264_MAX_BITRATE; psb__information_message(" bits_per_second(%d) exceeds \ the maximum bitrate, set it with %d\n", - bitrate_param->bitrate, + rate_control_param->bits_per_second, TOPAZ_H264_MAX_BITRATE); } else - ctx->sRCParams.BitsPerSecond = bitrate_param->bitrate; - + ctx->sRCParams.BitsPerSecond = rate_control_param->bits_per_second; + + if (rate_control_param->target_percentage != 0) + ctx->sRCParams.VCMBitrateMargin = rate_control_param->target_percentage * 128 / 100; + if (rate_control_param->window_size != 0) + ctx->sRCParams.BufferSize = ctx->sRCParams.BitsPerSecond * rate_control_param->window_size / 1000; + if (rate_control_param->initial_qp != 0) + ctx->sRCParams.InitialQp = rate_control_param->initial_qp; + if (rate_control_param->min_qp != 0) + ctx->sRCParams.MinQP = rate_control_param->min_qp; + break; case VAEncMiscParameterTypeMaxSliceSize: @@ -547,6 +609,11 @@ static VAStatus lnc__H264ES_process_misc_param(context_ENC_p ctx, object_buffer_ air_param->air_num_mbs, air_param->air_threshold, air_param->air_auto); + if (((ctx->Height * ctx->Width) >> 8) < air_param->air_num_mbs) + air_param->air_num_mbs = ((ctx->Height * ctx->Width) >> 8); + if (air_param->air_threshold == 0) + psb__information_message("%s: air threshold is set to zero\n", + __FUNCTION__); ctx->num_air_mbs = air_param->air_num_mbs; ctx->air_threshold = air_param->air_threshold; ctx->autotune_air_flag = air_param->air_auto; @@ -642,7 +709,7 @@ struct format_vtable_s lnc_H264ES_vtable = { endPicture: lnc_H264ES_EndPicture }; -static inline void lnc_H264_append_EOSEQ(unsigned char *p_buf, unsigned long *p_size) +static inline void lnc_H264_append_EOSEQ(unsigned char *p_buf, unsigned int *p_size) { /*nal_ref_idc should be 0 and nal_ref_idc should be 10 for End of Sequence RBSP*/ const unsigned char EOSEQ[] = {0x00, 0x00, 0x00, 0x01, 0xa}; @@ -655,7 +722,7 @@ static inline void lnc_H264_append_EOSEQ(unsigned char *p_buf, unsigned long *p_ *p_size += sizeof(EOSEQ); } -static inline void lnc_H264_append_EOSTREAM(unsigned char *p_buf, unsigned long *p_size) +static inline void lnc_H264_append_EOSTREAM(unsigned char *p_buf, unsigned int *p_size) { /*nal_ref_idc should be 0 and nal_ref_idc should be 11 for End of Stream RBSP*/ const unsigned char EOSTREAM[] = {0x00, 0x00, 0x00, 0x01, 0xb}; @@ -669,7 +736,7 @@ static inline void lnc_H264_append_EOSTREAM(unsigned char *p_buf, unsigned long VAStatus lnc_H264_append_aux_info(object_context_p obj_context, object_buffer_p obj_buffer, unsigned char *buf, - unsigned long *p_size) + unsigned int *p_size) { INIT_CONTEXT_H264ES; struct coded_buf_aux_info *p_aux_info; diff --git a/src/lnc_H264ES.h b/src/lnc_H264ES.h index 2252bfb..65bb59e 100644 --- a/src/lnc_H264ES.h +++ b/src/lnc_H264ES.h @@ -31,6 +31,6 @@ extern struct format_vtable_s lnc_H264ES_vtable; extern VAStatus lnc_H264_append_aux_info(object_context_p obj_context, object_buffer_p obj_buffer, unsigned char *buf, - unsigned long *p_size); + unsigned int *p_size); #endif /* _LNC_H264_H_ */ diff --git a/src/lnc_MPEG4ES.c b/src/lnc_MPEG4ES.c index 746f4e2..21dbc24 100644 --- a/src/lnc_MPEG4ES.c +++ b/src/lnc_MPEG4ES.c @@ -321,6 +321,7 @@ static VAStatus lnc__MPEG4ES_process_slice_param(context_ENC_p ctx, object_buffe lnc_cmdbuf_p cmdbuf = ctx->obj_context->lnc_cmdbuf; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); int i; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); @@ -333,14 +334,41 @@ static VAStatus lnc__MPEG4ES_process_slice_param(context_ENC_p ctx, object_buffe else RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); } + + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) + { + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_num = obj_buffer->num_elements; + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + } + for(i = 0; i < obj_buffer->num_elements; i++) { - if (!(ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) { + if (!(ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) { if ((ctx->obj_context->frame_count == 0) && (pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra) - lnc_reset_encoder_params(ctx); + lnc_reset_encoder_params(ctx); + + /*The corresponding slice buffer cache*/ + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + i; - if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], pBuffer) == 0) { + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer) == 0) { /* cache current param parameters */ - memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], + memcpy(&ctx->slice_param_cache[slice_param_idx], pBuffer, sizeof(VAEncSliceParameterBuffer)); /* Setup InParams value*/ @@ -380,7 +408,7 @@ static VAStatus lnc__MPEG4ES_process_misc_param(context_ENC_p ctx, object_buffer { /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */ VAEncMiscParameterBuffer *pBuffer; - VAEncMiscParameterBitRate *bitrate_param; + VAEncMiscParameterRateControl *rate_control_param; VAEncMiscParameterAIR *air_param; VAEncMiscParameterMaxSliceSize *max_slice_size_param; VAEncMiscParameterFrameRate *frame_rate_param; @@ -389,7 +417,7 @@ static VAStatus lnc__MPEG4ES_process_misc_param(context_ENC_p ctx, object_buffer ASSERT(obj_buffer->type == VAEncMiscParameterBufferType); - pBuffer = (VAEncSliceParameterBuffer *) obj_buffer->buffer_data; + pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data; obj_buffer->size = 0; switch (pBuffer->type) { @@ -399,26 +427,26 @@ static VAStatus lnc__MPEG4ES_process_misc_param(context_ENC_p ctx, object_buffer frame_rate_param->framerate); break; - case VAEncMiscParameterTypeBitRate: - bitrate_param = (VAEncMiscParameterBitRate *)pBuffer->data; + case VAEncMiscParameterTypeRateControl: + rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data; psb__information_message("%s: bit rate changed to %d\n", - bitrate_param->bitrate); + rate_control_param->bits_per_second); - if (bitrate_param->bitrate == ctx->sRCParams.BitsPerSecond) + if (rate_control_param->bits_per_second == ctx->sRCParams.BitsPerSecond) break; else ctx->update_rc_control = 1; - if (bitrate_param->bitrate > TOPAZ_MPEG4_MAX_BITRATE) { + if (rate_control_param->bits_per_second > TOPAZ_MPEG4_MAX_BITRATE) { ctx->sRCParams.BitsPerSecond = TOPAZ_MPEG4_MAX_BITRATE; psb__information_message(" bits_per_second(%d) exceeds \ the maximum bitrate, set it with %d\n", - bitrate_param->bitrate, + rate_control_param->bits_per_second, TOPAZ_MPEG4_MAX_BITRATE); } else - ctx->sRCParams.BitsPerSecond = bitrate_param->bitrate; + ctx->sRCParams.BitsPerSecond = rate_control_param->bits_per_second; break; diff --git a/src/lnc_cmdbuf.c b/src/lnc_cmdbuf.c index f8797fc..ce9e038 100644 --- a/src/lnc_cmdbuf.c +++ b/src/lnc_cmdbuf.c @@ -503,16 +503,11 @@ int lnc_context_submit_cmdbuf( object_context_p obj_context ) * vaQuerySurfaceStatus is supposed only to be called after vaEndPicture/vaSyncSurface, * The caller should ensure the surface pertains to an encode context */ -int lnc_surface_get_frameskip(object_context_p obj_context, psb_surface_p surface, int *frame_skip) +int lnc_surface_get_frameskip(psb_driver_data_p driver_data, psb_surface_p surface, int *frame_skip) { struct drm_lnc_video_getparam_arg arg; unsigned long temp; int ret = 0; - psb_driver_data_p driver_data = obj_context->driver_data; - context_ENC_p ctx = (context_ENC_p) obj_context->format_data; - - if (ctx->sRCParams.RCEnable == 0) - return 0; /* bit31 indicate if frameskip is already settled, it is used to record the frame skip flag for old surfaces * because current FRAMESKIP in hardware can't be applied to the old surfaces diff --git a/src/lnc_cmdbuf.h b/src/lnc_cmdbuf.h index facd071..05ce45f 100644 --- a/src/lnc_cmdbuf.h +++ b/src/lnc_cmdbuf.h @@ -167,7 +167,7 @@ int lnc_context_submit_cmdbuf( object_context_p obj_context ); * * Returns 0 on success */ -int lnc_surface_get_frameskip( object_context_p obj_context, psb_surface_p surface, int *frame_skip); +int lnc_surface_get_frameskip( psb_driver_data_p driver_data, psb_surface_p psb_surface, int *frame_skip); /* * Flushes the pending cmdbuf diff --git a/src/lnc_hostcode.c b/src/lnc_hostcode.c index 654d0bd..64da29a 100644 --- a/src/lnc_hostcode.c +++ b/src/lnc_hostcode.c @@ -117,6 +117,10 @@ unsigned int lnc__get_ipe_control(enum drm_lnc_topaz_codec eEncodingFormat) void lnc_DestroyContext(object_context_p obj_context) { + context_ENC_p ctx; + ctx = (context_ENC_p)obj_context->format_data; + if (NULL != ctx->slice_param_cache) + free(ctx->slice_param_cache); free(obj_context->format_data); obj_context->format_data = NULL; } @@ -153,6 +157,11 @@ VAStatus lnc_CreateContext( ctx->HeightMinusLRBSearchHeight = ctx->Height - MVEA_LRB_SEARCH_HEIGHT; ctx->FCode = 0; + + ctx->sRCParams.VCMBitrateMargin = 0; + ctx->sRCParams.BufferSize = 0; + ctx->sRCParams.InitialQp = 0; + ctx->sRCParams.MinQP = 0; vaStatus = lnc__alloc_context_buffer(ctx); @@ -455,8 +464,6 @@ static VAStatus lnc__PatchBitsConsumedInRCParam(context_ENC_p ctx) { lnc_cmdbuf_p cmdbuf = ctx->obj_context->lnc_cmdbuf; PIC_PARAMS *psPicParams = cmdbuf->pic_params_p; - void *pBuffer; - IMG_UINT32 BitsPerFrame; VAStatus vaStatus; /* it will wait until last encode session is done */ @@ -468,11 +475,6 @@ static VAStatus lnc__PatchBitsConsumedInRCParam(context_ENC_p ctx) if (vaStatus) return vaStatus; } - - BitsPerFrame = ctx->sRCParams.BitsPerSecond / ctx->sRCParams.FrameRate; - - /* patch IN_RC_PARAMS here */ - psPicParams->sInParams.BitsTransmitted = BitsPerFrame; return VA_STATUS_SUCCESS; } @@ -561,7 +563,6 @@ static VAStatus lnc_SetupRCParam(context_ENC_p ctx) psPicParams->Flags |= ISRC_FLAGS; lnc__setup_rcdata(ctx, psPicParams, &ctx->sRCParams); - psPicParams->sInParams.BitsTransmitted = 0; /* restore it, just keep same with DDK */ ctx->sRCParams.InitialQp = origin_qp; @@ -579,7 +580,7 @@ static VAStatus lnc_UpdateRCParam(context_ENC_p ctx) psb__information_message("will update rc data\n"); lnc__update_rcdata(ctx, psPicParams, &ctx->sRCParams); - + /* save IN_RC_PARAMS into the cache */ memcpy(&ctx->in_params_cache, (void *)&psPicParams->sInParams, sizeof(IN_RC_PARAMS)); @@ -595,7 +596,7 @@ static VAStatus lnc_PatchRCMode(context_ENC_p ctx) lnc__PatchBitsConsumedInRCParam(ctx); /* get frameskip flag */ - lnc_surface_get_frameskip(ctx->obj_context, ctx->src_surface->psb_surface, &frame_skip); + lnc_surface_get_frameskip(ctx->obj_context->driver_data, ctx->src_surface->psb_surface, &frame_skip); /* current frame is skipped * redo RenderPicture with FrameSkip set */ @@ -770,10 +771,8 @@ void lnc__setup_rcdata( PIC_PARAMS *psPicParams, IMG_RC_PARAMS *psRCParams) { - IMG_INT32 FrameRate; - double L1, L2, L3,L4, L5, flBpp; - int tmp_qp = 0; IMG_INT32 max_bitrate = psContext->Width * psContext->Height * 1.5 * 8 *60; + IMG_UINT8 InitialSeInitQP = 0; /* frameskip is always cleared, specially handled at vaEndPicture */ psRCParams->FrameSkip = 0; @@ -786,278 +785,37 @@ void lnc__setup_rcdata( if (!psRCParams->FrameRate) psRCParams->FrameRate = 30; - if (psRCParams->BitsPerSecond < 256000) - psRCParams->BufferSize = (9 * psRCParams->BitsPerSecond) >> 1; - else - psRCParams->BufferSize = (5 * psRCParams->BitsPerSecond) >> 1; + if (psRCParams->BufferSize == 0) { + if (psRCParams->BitsPerSecond < 256000) + psRCParams->BufferSize = (9 * psRCParams->BitsPerSecond) >> 1; + else + psRCParams->BufferSize = (5 * psRCParams->BitsPerSecond) >> 1; + } psRCParams->InitialLevel = (3 * psRCParams->BufferSize) >> 4; psRCParams->InitialDelay = (13 * psRCParams->BufferSize) >> 4; lnc__setup_busize(psContext); /* calculate BasicUnitSize */ - /* Calculate Bits Per Pixel */ - FrameRate = psRCParams->FrameRate; - flBpp = 1.0 * psRCParams->BitsPerSecond / (FrameRate * psContext->Width * psContext->Height); - psPicParams->sInParams.SeInitQP = psRCParams->InitialQp; psPicParams->sInParams.MBPerRow = (psContext->Width>>4); psPicParams->sInParams.MBPerBU = psRCParams->BUSize; psPicParams->sInParams.MBPerFrm = (psContext->Width>>4) * (psContext->Height>>4); psPicParams->sInParams.BUPerFrm = (psPicParams->sInParams.MBPerFrm) / psRCParams->BUSize; - psPicParams->sInParams.BUPerSlice = (psPicParams->sInParams.BUPerFrm) / psRCParams->Slices; - - psPicParams->sInParams.IntraPeriod = psRCParams->IntraFreq; - psPicParams->sInParams.BitRate = psRCParams->BitsPerSecond; - - psPicParams->sInParams.BitsPerFrm = (psRCParams->BitsPerSecond + psRCParams->FrameRate/2) / psRCParams->FrameRate; - psPicParams->sInParams.BitsPerGOP = (psRCParams->BitsPerSecond / psRCParams->FrameRate) * psRCParams->IntraFreq; - psPicParams->sInParams.BitsPerBU = psPicParams->sInParams.BitsPerFrm / (4 * psPicParams->sInParams.BUPerFrm); - psPicParams->sInParams.BitsPerMB = psPicParams->sInParams.BitsPerBU / psRCParams->BUSize; - - psPicParams->sInParams.AvQPVal = psRCParams->InitialQp; - psPicParams->sInParams.MyInitQP = psRCParams->InitialQp; - - /* select thresholds and initial Qps etc that are codec dependent */ - switch (psContext->eCodec) - { - case IMG_CODEC_H264_CBR: - case IMG_CODEC_H264_VBR: - case IMG_CODEC_H264_VCM: - L1 = 0.1; L2 = 0.15; L3 = 0.2; - psPicParams->sInParams.MaxQPVal = 51; - - /* Set THSkip Values */ - if(flBpp <= 0.07) - psPicParams->THSkip = TH_SKIP_24; - else if(flBpp <= 0.14) - psPicParams->THSkip = TH_SKIP_12; - else - psPicParams->THSkip = TH_SKIP_0; - - if(flBpp <= 0.3) - psPicParams->Flags |= ISRC_I16BIAS; - - /* Setup MAX and MIN Quant Values */ - if(psRCParams->MinQP == 0) - { - if(flBpp >= 0.50) - tmp_qp = 4; - else if(flBpp > 0.133) - tmp_qp = (INT16)(24 - (40*flBpp)); - else - tmp_qp = (INT16)(32 - (100 * flBpp)); - } - else - psPicParams->sInParams.MinQPVal = (IMG_UINT8)psRCParams->MinQP; - psPicParams->sInParams.MinQPVal = (max(min(psPicParams->sInParams.MaxQPVal, - tmp_qp), 7)); - - /* Calculate Initial QP if it has not been specified */ - if(psPicParams->sInParams.SeInitQP==0) - { - L1 = 0.050568; L2 = 0.202272; L3 = 0.40454321; L4 = 0.80908642; L5 = 1.011358025; - if(flBpp < L1) - tmp_qp = (INT16)(47 - 78.10*flBpp); - - else if(flBpp>=L1 && flBpp=L2 && flBpp=L3 && flBpp=L4 && flBpp=L5) - tmp_qp = (INT16) (20 - 4.95*flBpp); - psPicParams->sInParams.SeInitQP = (IMG_UINT8)(max(min(psPicParams->sInParams.MaxQPVal, - tmp_qp), psPicParams->sInParams.MinQPVal)); - } - break; - - case IMG_CODEC_MPEG4_CBR: - case IMG_CODEC_MPEG4_VBR: - psPicParams->sInParams.MaxQPVal = 31; - - if(psContext->Width == 176) - { - L1 = 0.1; L2 = 0.3; L3 = 0.6; - } - else if(psContext->Width == 352) - { - L1 = 0.2; L2 = 0.6; L3 = 1.2; - } - else - { - L1 = 0.25; L2 = 1.4; L3 = 2.4; - } - - /* Calculate Initial QP if it has not been specified */ - if(psPicParams->sInParams.SeInitQP==0) - { - if(flBpp <= L1) - psPicParams->sInParams.SeInitQP = 31; - else - { - if(flBpp <= L2) - psPicParams->sInParams.SeInitQP = 25; - else - psPicParams->sInParams.SeInitQP = (flBpp <= L3) ? 20 : 10; - } - } - if(flBpp >= 0.25) - { - psPicParams->sInParams.MinQPVal = 1; - } - else - { - psPicParams->sInParams.MinQPVal = 2; - } - break; - - case IMG_CODEC_H263_CBR: - case IMG_CODEC_H263_VBR: - psPicParams->sInParams.MaxQPVal = 31; - - if(psContext->Width == 176) - { - L1 = 0.1; L2 = 0.3; L3 = 0.6; - } - else if(psContext->Width == 352) - { - L1 = 0.2; L2 = 0.6; L3 = 1.2; - } - else - { - L1 = 0.25; L2 = 1.4; L3 = 2.4; - } - - /* Calculate Initial QP if it has not been specified */ - if(psPicParams->sInParams.SeInitQP==0) - { - if(flBpp <= L1) - psPicParams->sInParams.SeInitQP = 31; - else - { - if(flBpp <= L2) - psPicParams->sInParams.SeInitQP = 25; - else - psPicParams->sInParams.SeInitQP = (flBpp <= L3) ? 20 : 10; - } - } - - psPicParams->sInParams.MinQPVal = 2; - - break; - - default: - /* the NO RC cases will fall here */ - break; - } - - /* Set up Input Parameters that are mode dependent */ - switch (psContext->eCodec) - { - case IMG_CODEC_H264_NO_RC: - case IMG_CODEC_H263_NO_RC: - case IMG_CODEC_MPEG4_NO_RC: - return ; - case IMG_CODEC_H264_VCM: - psPicParams->Flags |= ISVCM_FLAGS; - /* drop throught to CBR case */ - case IMG_CODEC_H264_CBR: - psPicParams->Flags |= ISCBR_FLAGS; - /* ------------------- H264 CBR RC ------------------- */ - /* Initialize the parameters of fluid flow traffic model. */ - psPicParams->sInParams.BufferSize = psRCParams->BufferSize; + InitialSeInitQP = psPicParams->sInParams.SeInitQP; - /* HRD consideration - These values are used by H.264 reference code. */ - if(psRCParams->BitsPerSecond < 1000000) /* 1 Mbits/s */ - { - psPicParams->sInParams.ScaleFactor = 0; - } - else if(psRCParams->BitsPerSecond < 2000000) /* 2 Mbits/s */ - { - psPicParams->sInParams.ScaleFactor = 1; - } - else if(psRCParams->BitsPerSecond < 4000000) /* 4 Mbits/s */ - { - psPicParams->sInParams.ScaleFactor = 2; - } - else if(psRCParams->BitsPerSecond < 8000000) /* 8 Mbits/s */ - { - psPicParams->sInParams.ScaleFactor = 3; - } - else - { - psPicParams->sInParams.ScaleFactor = 4; - } - break; + lnc__update_rcdata(psContext, psPicParams, psRCParams); + /* set minQP if hosts set minQP */ + if (psRCParams->MinQP) + psPicParams->sInParams.MinQPVal = psRCParams->MinQP; - case IMG_CODEC_MPEG4_CBR: - case IMG_CODEC_H263_CBR: - psPicParams->Flags |= ISCBR_FLAGS; - - flBpp = 256 * (psRCParams->BitsPerSecond/psContext->Width); - flBpp /= (psContext->Height * psRCParams->FrameRate); - - if((psPicParams->sInParams.MBPerFrm > 1024 && flBpp < 16) || (psPicParams->sInParams.MBPerFrm <= 1024 && flBpp < 24)) - psPicParams->sInParams.HalfFrameRate = 1; - else - psPicParams->sInParams.HalfFrameRate = 0; - - if(psPicParams->sInParams.HalfFrameRate >= 1) - { - psPicParams->sInParams.SeInitQP = 31; - psPicParams->sInParams.AvQPVal = 31; - psPicParams->sInParams.MyInitQP = 31; - } - - if (psRCParams->BitsPerSecond <= 384000) - psPicParams->sInParams.BufferSize = ((psRCParams->BitsPerSecond * 5) >> 1); - else - psPicParams->sInParams.BufferSize = psRCParams->BitsPerSecond * 4; - break; - - case IMG_CODEC_MPEG4_VBR: - case IMG_CODEC_H263_VBR: - case IMG_CODEC_H264_VBR: - psPicParams->Flags |= ISVBR_FLAGS; - - psPicParams->sInParams.MBPerBU = psPicParams->sInParams.MBPerFrm; - psPicParams->sInParams.BUPerFrm = 1; - - /* Initialize the parameters of fluid flow traffic model. */ - psPicParams->sInParams.BufferSize = ((5 * psRCParams->BitsPerSecond) >> 1); - - /* These scale factor are used only for rate control to avoid overflow */ - /* in fixed-point calculation these scale factors are decided by bit rate */ - if(psRCParams->BitsPerSecond < 640000) - { - psPicParams->sInParams.ScaleFactor = 2; /* related to complexity */ - } - else if(psRCParams->BitsPerSecond < 2000000) - { - psPicParams->sInParams.ScaleFactor = 4; - } - else - { - psPicParams->sInParams.ScaleFactor = 6; - } - break; - default: - break; + /* if seinitqp is set, restore the value hosts want */ + if (InitialSeInitQP) { + psPicParams->sInParams.SeInitQP = InitialSeInitQP; + psPicParams->sInParams.MyInitQP = InitialSeInitQP; + psRCParams->InitialQp = InitialSeInitQP; } - - psPicParams->sInParams.MyInitQP = psPicParams->sInParams.SeInitQP; - psPicParams->sInParams.InitialDelay = psRCParams->InitialDelay; - psPicParams->sInParams.InitialLevel = psRCParams->InitialLevel; - psRCParams->InitialQp = psPicParams->sInParams.SeInitQP; } void lnc__update_rcdata(context_ENC_p psContext, @@ -1066,20 +824,24 @@ void lnc__update_rcdata(context_ENC_p psContext, { double L1, L2, L3,L4, L5, flBpp; INT16 i16TempQP; + IMG_INT32 i32BufferSizeInFrames; flBpp = 1.0 * psRCParams->BitsPerSecond / (psRCParams->FrameRate * psContext->Width * psContext->Height); + /* recalculate for small frames */ + if (psContext->Width <= 176) + flBpp = flBpp / 2.0; + psPicParams->sInParams.IntraPeriod = psRCParams->IntraFreq; psPicParams->sInParams.BitRate = psRCParams->BitsPerSecond; psPicParams->sInParams.IntraPeriod = psRCParams->IntraFreq; - psPicParams->sInParams.BitsPerFrm = (psRCParams->BitsPerSecond + psRCParams->FrameRate/2)/ psRCParams->FrameRate; - psPicParams->sInParams.BitsTransmitted = psPicParams->sInParams.BitsPerFrm; - + psPicParams->sInParams.BitsPerFrm = psRCParams->BitsPerSecond / psRCParams->FrameRate; psPicParams->sInParams.BitsPerGOP = psPicParams->sInParams.BitsPerFrm * psRCParams->IntraFreq; psPicParams->sInParams.BitsPerBU = psPicParams->sInParams.BitsPerFrm / (4 * psPicParams->sInParams.BUPerFrm); psPicParams->sInParams.BitsPerMB = psPicParams->sInParams.BitsPerBU / psRCParams->BUSize; + i32BufferSizeInFrames = psRCParams->BufferSize/psPicParams->sInParams.BitsPerFrm; // select thresholds and initial Qps etc that are codec dependent switch (psContext->eCodec) @@ -1113,23 +875,23 @@ void lnc__update_rcdata(context_ENC_p psContext, // Calculate Initial QP if it has not been specified L1 = 0.050568; L2 = 0.202272; L3 = 0.40454321; L4 = 0.80908642; L5 = 1.011358025; - if(flBpp < L1) - i16TempQP = (IMG_INT16)(47 - 78.10*flBpp); + if(flBpp < L1) + i16TempQP = (IMG_INT16)(47 - 78.10*flBpp); - else if(flBpp>=L1 && flBpp=L1 && flBpp=L2 && flBpp=L2 && flBpp=L3 && flBpp=L3 && flBpp=L4 && flBpp=L4 && flBpp=L5) - i16TempQP = (IMG_INT16)(20 - 4.95*flBpp); + else if(flBpp>=L5) + i16TempQP = (IMG_INT16)(20 - 4.95*flBpp); psPicParams->sInParams.SeInitQP = (IMG_UINT8)(max(min(psPicParams->sInParams.MaxQPVal,i16TempQP),0)); break; @@ -1200,7 +962,7 @@ void lnc__update_rcdata(context_ENC_p psContext, psPicParams->sInParams.SeInitQP = (flBpp <= L3) ? 20 : 10; } - psPicParams->sInParams.MinQPVal = 2; + psPicParams->sInParams.MinQPVal = 3; break; @@ -1218,8 +980,46 @@ void lnc__update_rcdata(context_ENC_p psContext, return ; case IMG_CODEC_H264_VCM: - psPicParams->Flags |= ISVCM_FLAGS; + psPicParams->Flags |= ISVCM_FLAGS | ISCBR_FLAGS; /* drop through to CBR case */ + /* for SD and above we can target 95% (122/128) of maximum bitrate */ + if (psRCParams->VCMBitrateMargin) { + psPicParams->sInParams.VCMBitrateMargin = psRCParams->VCMBitrateMargin; + } else { + if (psContext->Height >= 480) + psPicParams->sInParams.VCMBitrateMargin = 122; + else + psPicParams->sInParams.VCMBitrateMargin = 115; /* for less and SD we target 90% (115/128) of maximum bitrate */ + if (i32BufferSizeInFrames < 15) + psPicParams->sInParams.VCMBitrateMargin -= 5;/* when we have a very small window size we reduce the target further to avoid too much skipping */ + } + psPicParams->sInParams.ForceSkipMargin = 500;/* start skipping MBs when within 500 bits of slice or frame limit */ + + // Set a scale factor to avoid overflows in maths + if(psRCParams->BitsPerSecond < 1000000) // 1 Mbits/s + { + psPicParams->sInParams.ScaleFactor = 0; + } + else if(psRCParams->BitsPerSecond < 2000000) // 2 Mbits/s + { + psPicParams->sInParams.ScaleFactor = 1; + } + else if(psRCParams->BitsPerSecond < 4000000) // 4 Mbits/s + { + psPicParams->sInParams.ScaleFactor = 2; + } + else if(psRCParams->BitsPerSecond < 8000000) // 8 Mbits/s + { + psPicParams->sInParams.ScaleFactor = 3; + } + else + { + psPicParams->sInParams.ScaleFactor = 4; + } + + psPicParams->sInParams.BufferSize = i32BufferSizeInFrames; + break; + case IMG_CODEC_H264_CBR: psPicParams->Flags |= ISCBR_FLAGS; // ------------------- H264 CBR RC ------------------- // diff --git a/src/lnc_hostcode.h b/src/lnc_hostcode.h index 48cefa9..695a7f6 100644 --- a/src/lnc_hostcode.h +++ b/src/lnc_hostcode.h @@ -90,7 +90,7 @@ typedef struct _RC_PARAMS_ IMG_BOOL FrameSkip; IMG_UINT8 Slices; - IMG_UINT32 BitsTransmitted; + IMG_UINT8 VCMBitrateMargin; IMG_INT32 InitialLevel; IMG_INT32 InitialDelay; } IMG_RC_PARAMS; @@ -126,7 +126,10 @@ typedef struct IMG_INT32 InitialDelay; /* Initial Delay of Buffer */ IMG_UINT8 ScaleFactor; /* Scale Factor (H264 only) */ - IMG_UINT8 BUPerSlice; /* Number of Slices per Picture */ + IMG_UINT8 VCMBitrateMargin; /* Bitrate that should be + targetted as a fraction of + 128 relative to maximum bitrate + i32BitRate (VCM mode only) */ IMG_UINT8 HalfFrameRate; /* Half Frame Rate (MP4 only) */ IMG_UINT8 FCode; /* F Code (MP4 only) */ @@ -135,7 +138,9 @@ typedef struct IMG_UINT16 AvQPVal; /* Average QP in Current Picture */ IMG_UINT16 MyInitQP; /* Initial Quantizer */ - IMG_UINT32 BitsTransmitted;/* The number of bits taken from the encode buffer during the last frame period */ + IMG_INT32 ForceSkipMargin; /* The number of bits of margin + to leave before forcing skipped + macroblocks (VCM mode only) */ IMG_UINT32 RCScaleFactor; /* A constant used in rate control = (GopSize/(BufferSize-InitialLevel))*256 */ } IN_RC_PARAMS; @@ -213,7 +218,8 @@ struct context_ENC_s { IN_RC_PARAMS in_params_cache; /* following frames reuse the first frame's IN_RC_PARAMS, cache it */ - VAEncSliceParameterBuffer slice_param_cache[2]; + VAEncSliceParameterBuffer *slice_param_cache; + uint16_t slice_param_num; IMG_UINT16 MPEG4_vop_time_increment_resolution; diff --git a/src/pnw_H263ES.c b/src/pnw_H263ES.c index 981e17c..cf0e0fb 100644 --- a/src/pnw_H263ES.c +++ b/src/pnw_H263ES.c @@ -316,35 +316,45 @@ static VAStatus pnw__H263ES_process_slice_param(context_ENC_p ctx, object_buffer pnw_cmdbuf_p cmdbuf=ctx->obj_context->pnw_cmdbuf; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); int i; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); - /*In DDK186, firmware handles the frame skip*/ - /* do nothing for skip frame if RC enabled */ - /*if ((ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) { - free(obj_buffer->buffer_data); - obj_buffer->buffer_data = NULL; - return VA_STATUS_SUCCESS; - }*/ - /* Transfer ownership of VAEncPictureParameterBufferH263 data */ pBuffer = (VAEncSliceParameterBuffer *) obj_buffer->buffer_data; obj_buffer->size = 0; - /* + if (0 == pBuffer->start_row_number) { - if (pBuffer->slice_flags.bits.is_intra) - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_I); + RELOC_PIC_PARAMS_PNW(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_I); else - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); - + RELOC_PIC_PARAMS_PNW(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); } - */ - /* - if (0 == pBuffer->start_row_number) - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, &cmdbuf->topaz_in_params); - */ + + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) + { + ctx->slice_param_num = obj_buffer->num_elements; + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + } + for(i = 0; i < obj_buffer->num_elements; i++) { /*Todo list: *1.Insert Do header command @@ -393,26 +403,20 @@ static VAStatus pnw__H263ES_process_slice_param(context_ENC_p ctx, object_buffer ctx->BelowParamsBufIdx = (ctx->BelowParamsBufIdx + 1) & 0x1; } -// if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], pBuffer) == 0) { -// /* cache current param parameters */ -// memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], -// pBuffer, sizeof(VAEncSliceParameterBuffer)); + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + i; + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer) == 0) { + /* cache current param parameters */ + memcpy(&ctx->slice_param_cache[slice_param_idx], + pBuffer, sizeof(VAEncSliceParameterBuffer)); /* Setup InParams value*/ -// pnw_setup_slice_params(ctx, -// pBuffer->start_row_number * 16, -// pBuffer->slice_height*16, -// pBuffer->slice_flags.bits.is_intra, -// ctx->obj_context->frame_count > 0, -// psPicParams->sInParams.SeInitQP); -// } FIXME Not use slice_param_cache temporary for simplify - - pnw_setup_slice_params(ctx, - pBuffer->start_row_number * 16, - pBuffer->slice_height*16, - pBuffer->slice_flags.bits.is_intra, - ctx->obj_context->frame_count > 0, - psPicParams->sInParams.SeInitQP); + pnw_setup_slice_params(ctx, + pBuffer->start_row_number * 16, + pBuffer->slice_height*16, + pBuffer->slice_flags.bits.is_intra, + ctx->obj_context->frame_count > 0, + psPicParams->sInParams.SeInitQP); + } /* Insert do slice command and setup related buffer value */ pnw__send_encode_slice_params(ctx, diff --git a/src/pnw_H264.c b/src/pnw_H264.c index 58e560b..bff0078 100644 --- a/src/pnw_H264.c +++ b/src/pnw_H264.c @@ -100,6 +100,13 @@ static const char *slice2str[] = { "ST_SI" }; +typedef enum +{ + DEBLOCK_NONE, + DEBLOCK_STD, + DEBLOCK_INTRA_OOLD +}DEBLOCK_MODE_2NDPASS; + struct context_H264_s { object_context_p obj_context; /* back reference */ @@ -131,13 +138,6 @@ struct context_H264_s { uint32_t raw_mb_bits; /* Number of bits per macroblock */ - struct { - VAPictureH264 RefFrameList[16]; - VAPictureH264 RefPicList[2][32]; - int field_order_cnt_list[16][2]; - unsigned int ref_frame_list_eviction[16]; - } Reordered; - uint32_t picture_width_samples_l; uint32_t picture_height_samples_l; uint32_t picture_width_samples_c; @@ -149,9 +149,9 @@ struct context_H264_s { PICTYPE pic_type; uint32_t field_type; - uint32_t ref_frame_list_used; uint32_t long_term_frame_flags; uint32_t two_pass_mode; + uint32_t deblock_mode; uint32_t slice_count; /* Registers */ @@ -185,7 +185,12 @@ struct context_H264_s { /* Reference Cache */ struct psb_buffer_s reference_cache; + uint32_t *p_range_mapping_base0; + uint32_t *p_range_mapping_base1; uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER */ + uint32_t *slice_first_pic_last; + uint32_t *alt_output_flags; + /* CoLocated buffers - aka ParamMemInfo */ struct psb_buffer_s *colocated_buffers; int colocated_buffers_size; @@ -390,180 +395,12 @@ static VAStatus psb__H264_check_legal_picture(object_context_p obj_context, obje static void pnw_H264_DestroyContext(object_context_p obj_context); -// RefPicList[ 0|1 ][ rplidx ] --> RefFrameList[ rflidx ] --> frame - - /*********************************************************************************** - Function Name : psb__H264_find_reordered_list_idx - Inputs : ctx, frame - Outputs : - Returns : Index into Reordered.RefFrameList - Description : Finds an entry in the Reordered.RefFrameList with the same frame id - otherwise returns -1 - ************************************************************************************/ - static int psb__H264_find_reordered_list_idx(context_H264_p ctx, int frame) - { - unsigned int uiReRflIdx ; - for( uiReRflIdx = 0; uiReRflIdx < 16 ; uiReRflIdx++) - { - if( ctx->Reordered.RefFrameList[ uiReRflIdx ].picture_id == frame ) - { - return uiReRflIdx; - } - } - - return -1; - } - - - /*********************************************************************************** - Function Name : FindReRflIdxToEvict - Inputs : ctx - Outputs : - Returns : Index into Reordered.RefFrameList - Description : Finds an index in the Index into Reordered.RefFrameList which can - be reused. - ************************************************************************************/ - static int FindReRflIdxToEvict(context_H264_p ctx) - { - IMG_UINT lowestEvict = ~0; - IMG_UINT lowestIdx = 0 ; - IMG_UINT uiReRflIdx ; - for( uiReRflIdx =0; uiReRflIdx < 16 ; uiReRflIdx++) - { - if( ctx->Reordered.ref_frame_list_eviction[ uiReRflIdx ] < lowestEvict) - { - lowestEvict = ctx->Reordered.ref_frame_list_eviction[ uiReRflIdx ]; - lowestIdx = uiReRflIdx; - } - } - return lowestIdx; - } - - /*********************************************************************************** - Function Name : UpdatePictureLists - Inputs : ctx , pSliceCtrl - Outputs : - Returns : - Description : Updates the picture lists to maintain consisten index for a particular - frame in the RefFrameList. This requires RefFrameList and RefPicLists to - be modified. - ************************************************************************************/ -static void psb__H264_update_picture_lists(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) -{ - unsigned int uiList; - unsigned int uiListCount = ( slice_param->slice_type == ST_B) ? 2 : 1 ; - int i; - - /* default reordered RPL to ff */ - for(i = 0; i < 32; i++) { - ctx->Reordered.RefPicList[0][i].flags = VA_PICTURE_H264_BOTTOM_FIELD; - ctx->Reordered.RefPicList[0][i].frame_idx = 0x7f; /* 0x7f means idle/spare */ - ctx->Reordered.RefPicList[1][i].flags = VA_PICTURE_H264_BOTTOM_FIELD; - ctx->Reordered.RefPicList[1][i].frame_idx = 0x7f; - } - - for( uiList=0; uiList < uiListCount ; uiList++ ) /* For list0 and List1 */ - { - unsigned int uiRplIdx = 0; - for( uiRplIdx=0; uiRplIdx<32 ; uiRplIdx++ ) /* For each Reference Picture */ - { - int picture_id = ((uiList == 0) ? slice_param->RefPicList0[ uiRplIdx ].picture_id: - slice_param->RefPicList1[ uiRplIdx ].picture_id); - - if(picture_id == -1) /* Need app follow default value, spare picture_id is -1 */ - continue; - - object_surface_p ref_surface = SURFACE(picture_id); - - /* Get the Referecnce Frame List Idx */ - unsigned int uiRflIdx; - - if (NULL == ref_surface) - { - psb__error_message("%s L%d Invalid ref_surface handle\n", __FUNCTION__, __LINE__); - return; - } - - uiRflIdx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface); - ASSERT(uiRflIdx < 16); - - if( uiRflIdx < 16 ) - { - /* Get the Decode Render Target Idx, using surface id */ - unsigned int uiDrtIdx = ctx->pic_params->ReferenceFrames[uiRflIdx].picture_id; - ASSERT(uiDrtIdx == picture_id); - - if( uiDrtIdx != 0 ) /* surface id 0 means error */ - { - /* Find the corresponding DRT idx in the reordered Frame list */ - int iReRflIdx = psb__H264_find_reordered_list_idx( ctx , uiDrtIdx ); - if( iReRflIdx == -1 ) - { - /* If not found, add it */ - iReRflIdx = psb__H264_find_reordered_list_idx( ctx , 0 ); /* find a spare */ - if( iReRflIdx == -1 ) - { - /* TODO : Handle this situation somehow */ - iReRflIdx = FindReRflIdxToEvict( ctx ) ; - } - ctx->Reordered.RefFrameList[ iReRflIdx ].picture_id = uiDrtIdx; - } - - /* incrament the Eviction counter */ - ctx->Reordered.ref_frame_list_eviction[ iReRflIdx ] = ctx->obj_context->frame_count; - - /* modify the RPL to point to the reordered RFL */ - ctx->Reordered.RefPicList[ uiList ][ uiRplIdx ].frame_idx = iReRflIdx; - ctx->Reordered.RefPicList[ uiList ][ uiRplIdx ].flags = ( (uiList == 0) ? - slice_param->RefPicList0[ uiRplIdx ].flags : - slice_param->RefPicList1[ uiRplIdx ].flags ); - - /* Update the LT flag in the Reordered RFL */ - ctx->Reordered.RefFrameList[ iReRflIdx ].flags = ctx->pic_params->ReferenceFrames[ uiRflIdx ].flags; - - /* Mark for used */ - ctx->Reordered.RefFrameList[ iReRflIdx ].frame_idx = iReRflIdx; - - /* Update reordered FieldOrderCntList */ - ctx->Reordered.field_order_cnt_list[iReRflIdx][0] = - ctx->pic_params->ReferenceFrames[uiRflIdx].TopFieldOrderCnt; - ctx->Reordered.RefFrameList[iReRflIdx].TopFieldOrderCnt = - ctx->pic_params->ReferenceFrames[uiRflIdx].TopFieldOrderCnt; - - ctx->Reordered.field_order_cnt_list[iReRflIdx][1] = - ctx->pic_params->ReferenceFrames[uiRflIdx].BottomFieldOrderCnt; - ctx->Reordered.RefFrameList[iReRflIdx].BottomFieldOrderCnt = - ctx->pic_params->ReferenceFrames[uiRflIdx].BottomFieldOrderCnt; - - } - } - } - } - - { - unsigned int uiReRflIdx, uiRefFrameListUsed = 0; - ctx->long_term_frame_flags = 0; - - for ( uiReRflIdx = 0; uiReRflIdx < 16; uiReRflIdx++) - { - if( ctx->Reordered.RefFrameList[uiReRflIdx].frame_idx != 0x7F)/* Unused list entry should be 0x7f value */ - { - ctx->long_term_frame_flags |= ctx->Reordered.RefFrameList[uiReRflIdx].flags << uiReRflIdx; - uiRefFrameListUsed = uiReRflIdx+1; - } - } - ctx->ref_frame_list_used = uiRefFrameListUsed; - } -} - static VAStatus pnw_H264_CreateContext( object_context_p obj_context, object_config_p obj_config ) { VAStatus vaStatus = VA_STATUS_SUCCESS; context_H264_p ctx; - int i; - /* Validate flag */ /* Validate picture dimensions */ vaStatus = psb__H264_check_legal_picture(obj_context, obj_config); @@ -598,12 +435,6 @@ static VAStatus pnw_H264_CreateContext( return vaStatus; } - for(i = 0; i < 16; i++) { - ctx->Reordered.RefFrameList[i].flags = VA_PICTURE_H264_BOTTOM_FIELD; - ctx->Reordered.RefFrameList[i].frame_idx = 0x7f; - ctx->Reordered.RefFrameList[i].picture_id = 0; - } - ctx->colocated_buffers_size = obj_context->num_render_targets; ctx->colocated_buffers_idx = 0; ctx->colocated_buffers = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)*ctx->colocated_buffers_size); @@ -681,47 +512,6 @@ static VAStatus pnw_H264_CreateContext( } } - /* allocate in-loop targets for oold */ - if(obj_context->is_oold) - { - - for(i = 0; i < obj_context->num_render_targets; i++) - { - object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); - psb_surface_p psb_surface; - - if (NULL == obj_surface) - { - vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; - free(ctx->slice_param_list); - free(ctx->colocated_buffers); - free(ctx); - DEBUG_FAILURE; - return vaStatus; - } - - psb_surface = obj_surface->psb_surface; - - psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s)); - if (NULL == psb_surface->in_loop_buf) - { - vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; - free(ctx->slice_param_list); - free(ctx->colocated_buffers); - free(ctx); - DEBUG_FAILURE; - return vaStatus; - } - - /* FIXME: For RAR surface, need allocate RAR buffer */ - vaStatus = psb_buffer_create( obj_context->driver_data, - psb_surface->size, - psb_bt_surface, - psb_surface->in_loop_buf ); - } - - } - if (vaStatus != VA_STATUS_SUCCESS) { pnw_H264_DestroyContext(obj_context); @@ -774,7 +564,7 @@ static VAStatus psb__H264_allocate_colocated_buffer(context_H264_p ctx, object_s { psb_surface_p surface = obj_surface->psb_surface; - psb__information_message("psb_H264: Allocating colocated buffer for surface %08x size = %08x\n", surface, size); + psb__information_message("pnw_H264: Allocating colocated buffer for surface %08x size = %08x\n", surface, size); if (!GET_SURFACE_INFO_colocated_index(surface)) { @@ -799,7 +589,7 @@ static VAStatus psb__H264_allocate_colocated_buffer(context_H264_p ctx, object_s static psb_buffer_p psb__H264_lookup_colocated_buffer(context_H264_p ctx, psb_surface_p surface) { - psb__information_message("psb_H264: Looking up colocated buffer for surface %08x\n", surface); + psb__information_message("pnw_H264: Looking up colocated buffer for surface %08x\n", surface); int index = GET_SURFACE_INFO_colocated_index(surface); if (!index) { @@ -937,12 +727,10 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe for( i = pic_params->num_ref_frames; i--;) { object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id); - /* if (pic_params->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) { ctx->long_term_frame_flags |= 0x01 << i; } - */ // move long_term_frame_flags setting in "Reordered list update" if (ref_surface) { SET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface, i); @@ -950,7 +738,7 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe } /* If the MB are not guarenteed to be consecutive - we must do a 2pass */ - ctx->two_pass_mode = ( pic_params->num_slice_groups_minus1 > 0 ); + ctx->two_pass_mode = ( pic_params->num_slice_groups_minus1 > 0 ) && (!ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag); ctx->reg_SPS0 = 0; REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_DEFAULT_MATRIX_FLAG, ( ctx->profile == H264_BASELINE_PROFILE ) ); /* Always use suplied matrix non baseline otherwise use default*/ @@ -1061,7 +849,7 @@ static void psb__H264_build_SCA_chunk(context_H264_p ctx) memset(iq_matrix, 0, sizeof(VAIQMatrixBufferH264) ); } - psb_cmdbuf_rendec_start_chunk( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); + psb_cmdbuf_rendec_start( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); /* 8x8 Inter Y */ psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList8x8[1], SCALING_LIST_8x8_SIZE); @@ -1087,7 +875,7 @@ static void psb__H264_build_SCA_chunk(context_H264_p ctx) /* 4x4 Intra Cr */ psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[2], SCALING_LIST_4x4_SIZE); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__H264_build_picture_order_chunk(context_H264_p ctx) @@ -1100,7 +888,7 @@ static void psb__H264_build_picture_order_chunk(context_H264_p ctx) /* CHUNK: POC */ /* send Picture Order Counts (b frame only?) */ /* maybe need a state variable to track if this has already been sent for the frame */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_FOC0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_FOC0) ); reg_value = 0; REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC0, TOPFIELDORDERCNT_CURR, @@ -1112,33 +900,12 @@ static void psb__H264_build_picture_order_chunk(context_H264_p ctx) SIGNTRUNC(pic_params->CurrPic.BottomFieldOrderCnt) ); psb_cmdbuf_rendec_write(cmdbuf, reg_value ); - for ( i = 0; i < ctx->ref_frame_list_used; i++ ) + if (pic_params->num_ref_frames > 16) { - reg_value = 0; - REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_TOP_FOC, TOPFIELDORDERCNT, - SIGNTRUNC(ctx->Reordered.field_order_cnt_list[i][0]) ); - psb_cmdbuf_rendec_write(cmdbuf, reg_value ); - - reg_value = 0; - REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_BOT_FOC, BOTTOMFIELDORDERCNT, - SIGNTRUNC(ctx->Reordered.field_order_cnt_list[i][1]) ); - psb_cmdbuf_rendec_write(cmdbuf, reg_value ); + psb__error_message("Invalid reference number %d, set to 16\n", pic_params->num_ref_frames); + pic_params->num_ref_frames = 16; } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); -#if 0 - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_FOC0) ); - - reg_value = 0; - REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC0, TOPFIELDORDERCNT_CURR, - SIGNTRUNC(pic_params->CurrPic.TopFieldOrderCnt) ); - psb_cmdbuf_rendec_write(cmdbuf, reg_value ); - - reg_value = 0; - REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC1, BOTTOMFIELDORDERCNT_CURR, - SIGNTRUNC(pic_params->CurrPic.BottomFieldOrderCnt) ); - psb_cmdbuf_rendec_write(cmdbuf, reg_value ); - for ( i = 0; i < pic_params->num_ref_frames; i++ ) { reg_value = 0; @@ -1152,8 +919,7 @@ static void psb__H264_build_picture_order_chunk(context_H264_p ctx) psb_cmdbuf_rendec_write(cmdbuf, reg_value ); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); -#endif + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) @@ -1161,16 +927,12 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; VAPictureParameterBufferH264 *pic_params = ctx->pic_params; uint32_t reg_value; - int i, ReRflIdx; - object_surface_p colocated_surface; + int i; - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_COL_PIC0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_COL_PIC0) ); /* Colocated picture is picture 0 in list 1*/ - ReRflIdx = ctx->Reordered.RefPicList[1][0].frame_idx; - //colocated_surface = SURFACE(slice_param->RefPicList1[0].picture_id); - colocated_surface = SURFACE(ctx->Reordered.RefFrameList[ReRflIdx].picture_id); - + object_surface_p colocated_surface = SURFACE(slice_param->RefPicList1[0].picture_id); if (colocated_surface) { uint32_t bottom_field_flag; @@ -1191,11 +953,8 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu i32Cur = (i32Top < i32Bot)? i32Top: i32Bot; /* col pic */ - /* i32Top = slice_param->RefPicList1[0].TopFieldOrderCnt; - i32Bot = slice_param->RefPicList1[0].BottomFieldOrderCnt; */ - i32Top = ctx->Reordered.field_order_cnt_list[ReRflIdx][0]; - i32Bot = ctx->Reordered.field_order_cnt_list[ReRflIdx][1]; + i32Bot = slice_param->RefPicList1[0].BottomFieldOrderCnt; i32TopAbsDiffPoc = (i32Cur < i32Top)? i32Top - i32Cur: i32Cur - i32Top; i32BotAbsDiffPoc = (i32Cur < i32Bot)? i32Bot - i32Cur: i32Cur - i32Bot; @@ -1230,7 +989,16 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu { IMG_UINT8 list0_inverse[32]; memset(list0_inverse, 0xff, 32); /* Unused entries get 0xff */ - /* + + if (slice_param->num_ref_idx_l0_active_minus1 + 1 > 32) + { + psb__error_message("num_ref_idx_l0_active_minus1(%d) is too big. Set it with 31\n", + slice_param->num_ref_idx_l0_active_minus1); + slice_param->num_ref_idx_l0_active_minus1 = 31; + } + + if (slice_param->num_ref_idx_l0_active_minus1 > 30) + slice_param->num_ref_idx_l0_active_minus1 = 30; for(i = slice_param->num_ref_idx_l0_active_minus1 + 1; i--;) { object_surface_p surface = SURFACE(slice_param->RefPicList0[i].picture_id); @@ -1247,24 +1015,6 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu } } } - */ - for(i = 32 -1 ; i >= 0; i--) - { - object_surface_p surface = SURFACE(ctx->Reordered.RefPicList[0][i].picture_id); - if (surface) - { - uint32_t dpb_idx = ctx->Reordered.RefPicList[0][i].frame_idx; - if (dpb_idx != 0x7f) - { - if (ctx->Reordered.RefPicList[0][i].flags & VA_PICTURE_H264_BOTTOM_FIELD) - { - dpb_idx |= 0x10; - } - list0_inverse[dpb_idx] = i; - } - } - } - for(i = 0; i < 32; i += 4) { reg_value = 0; @@ -1276,8 +1026,10 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu } } + if (slice_param->num_ref_idx_l1_active_minus1 > 28) + slice_param->num_ref_idx_l1_active_minus1 = 28; + /* Write Ref List 1 - but only need the valid ones */ - /* for(i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i += 4) { reg_value = 0; @@ -1287,18 +1039,8 @@ static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBu reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+3]) << 24; psb_cmdbuf_rendec_write(cmdbuf, reg_value); } - */ - for(i = 0; i <= (32 -4) ; i += 4) - { - reg_value = 0; - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[1][i]); - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[1][i+1]) << 8; - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[1][i+2]) << 16; - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[1][i+3]) << 24; - psb_cmdbuf_rendec_write(cmdbuf, reg_value); - } - - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__H264_build_register(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) @@ -1336,6 +1078,48 @@ static void psb__H264_build_register(context_H264_p ctx, VASliceParameterBufferH psb_cmdbuf_reg_end_block( cmdbuf ); } +/* Programme the Alt output if there is a rotation*/ +static void psb__H264_setup_alternative_frame( context_H264_p ctx ) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + if(rotate_surface->extra_info[5] != obj_context->rotate) + psb__error_message("Display rotate mode does not match surface rotate mode!\n"); + + + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* Set the rotation registers */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + psb_cmdbuf_rendec_write( cmdbuf, cmd ); + + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64 ); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + psb_cmdbuf_rendec_end( cmdbuf ); + + *ctx->alt_output_flags = cmd; + RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); + RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); +} + + static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) { psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; @@ -1344,25 +1128,25 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu uint32_t reg_value; int i; - psb_cmdbuf_rendec_start_block( cmdbuf ); + /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ /* CHUNK: Entdec back-end profile and level */ { - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); reg_value = 0; REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile ); REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 1); /* 1 - H.264 */ psb_cmdbuf_rendec_write(cmdbuf, reg_value); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } /* CHUNK: SEQ Registers */ /* send Slice Data for every slice */ /* MUST be the last slice sent */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_SPS0) ); - + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_SPS0) ); + psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_SPS0); psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PPS0); psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PIC0); @@ -1386,7 +1170,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_REF0, BE_LONGTERMFRAMEFLAG, ctx->long_term_frame_flags ); psb_cmdbuf_rendec_write(cmdbuf, reg_value); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); #warning "TODO: MUST be done after fe slice1 (which gives MB address) " /* REGIO_WRITE_REGISTER(0, MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM, gui32SliceGroupType6BaseAddressHack); */ @@ -1417,91 +1201,43 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu /* send P+B-slice information for P and B slices */ if ( slice_param->slice_type == ST_B || slice_param->slice_type == ST_P ) { - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_LIST0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_LIST0) ); - if (slice_param->num_ref_idx_l0_active_minus1 > 28) + if (slice_param->num_ref_idx_l0_active_minus1 > (32-4)) + { + psb__error_message("num_ref_idx_l0_active_minus1(%d) is too big. Set it with 28\n", + slice_param->num_ref_idx_l0_active_minus1); slice_param->num_ref_idx_l0_active_minus1 = 28; + } for(i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i += 4) { reg_value = 0; - /* reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i]); reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+1]) << 8; reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+2]) << 16; reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+3]) << 24; - */ - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[0][i]); - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[0][i+1]) << 8; - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[0][i+2]) << 16; - reg_value |= PICTURE2INDEX(ctx, &ctx->Reordered.RefPicList[0][i+3]) << 24; psb_cmdbuf_rendec_write(cmdbuf, reg_value); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } /* CHUNK: DPB */ /* send DPB information (for P and B slices?) only needed once per frame */ // if ( sh->slice_type == ST_B || sh->slice_type == ST_P ) - - if ( pic_params->num_ref_frames > 0 ) - { - unsigned int rfl_idx; - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); - - // Mark onlys frame that are actualy used - for(rfl_idx = 0; rfl_idx < ctx->ref_frame_list_used; rfl_idx++) { - object_surface_p ref_surface = SURFACE(ctx->Reordered.RefFrameList[rfl_idx].picture_id); - psb_buffer_p buffer; - psb__information_message("Reordered.RefFrameList[%d] = %08x --> %08x frame_idx:0x%08x flags:%02x TopFieldOrderCnt: 0x%08x BottomFieldOrderCnt: 0x%08x %s\n", - rfl_idx, - ctx->Reordered.RefFrameList[rfl_idx].picture_id, - ref_surface, - ctx->Reordered.RefFrameList[rfl_idx].frame_idx, - ctx->Reordered.RefFrameList[rfl_idx].flags, - ctx->Reordered.RefFrameList[rfl_idx].TopFieldOrderCnt, - ctx->Reordered.RefFrameList[rfl_idx].BottomFieldOrderCnt, - (ctx->Reordered.RefFrameList[rfl_idx].frame_idx != 0x7f) ? "used" : ""); - - if(ctx->Reordered.RefFrameList[rfl_idx].frame_idx != 0x7f && ref_surface) { - if(ctx->obj_context->is_oold) - buffer = ref_surface->psb_surface->in_loop_buf; - else - buffer = &ref_surface->psb_surface->buf; - - psb_cmdbuf_rendec_write_address(cmdbuf, buffer, - buffer->buffer_ofs); - psb_cmdbuf_rendec_write_address(cmdbuf, buffer, - buffer->buffer_ofs + - ref_surface->psb_surface->chroma_offset); - } - else { - /* Generate an address which will cause a pagefault if accessed */ - unsigned int err = 0xff000000; - err |= (ctx->Reordered.RefFrameList[rfl_idx].picture_id & 0xff) << 16; - err |= (rfl_idx & 0xf) << 12; - psb_cmdbuf_rendec_write(cmdbuf, err); - psb_cmdbuf_rendec_write(cmdbuf, err); - ASSERT(0); - } - - } - - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - } - -#if 0 if ( pic_params->num_ref_frames > 0 ) { int i; IMG_BOOL is_used[16]; - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); - // Mark all surfaces as unused + /* Mark all surfaces as unused */ memset(is_used, 0, sizeof(is_used)); - // Mark onlys frame that are actualy used + if (slice_param->num_ref_idx_l0_active_minus1 > 31) + slice_param->num_ref_idx_l0_active_minus1 = 31; + /* Mark onlys frame that are actualy used */ for(i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { object_surface_p ref_surface = SURFACE(slice_param->RefPicList0[i].picture_id); @@ -1515,7 +1251,10 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu } } - // Mark onlys frame that are actualy used + if (slice_param->num_ref_idx_l1_active_minus1 > 31) + slice_param->num_ref_idx_l1_active_minus1 = 31; + + /* Mark onlys frame that are actualy used */ for(i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { object_surface_p ref_surface = SURFACE(slice_param->RefPicList1[i].picture_id); @@ -1529,10 +1268,22 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu } } - // Only load used surfaces + if (pic_params->num_ref_frames > 16) + pic_params->num_ref_frames = 16; + /* Only load used surfaces */ for(i = 0; i < pic_params->num_ref_frames; i++) { object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id); + psb_buffer_p buffer; + + if (NULL == ref_surface) + { + psb__error_message("%s L%d Invalide reference surface handle\n", + __FUNCTION__, __LINE__); + return; + } + + buffer = ref_surface->psb_surface->ref_buf; psb__information_message("pic_params->ReferenceFrames[%d] = %08x --> %08x frame_idx:0x%08x flags:%02x TopFieldOrderCnt: 0x%08x BottomFieldOrderCnt: 0x%08x %s\n", i, pic_params->ReferenceFrames[i].picture_id, @@ -1546,8 +1297,11 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu if (ref_surface && is_used[i]) // GET_SURFACE_INFO_is_used(ref_surface->psb_surface)) { - psb_cmdbuf_rendec_write_address(cmdbuf, &ref_surface->psb_surface->buf, ref_surface->psb_surface->buf.buffer_ofs); - psb_cmdbuf_rendec_write_address(cmdbuf, &ref_surface->psb_surface->buf, ref_surface->psb_surface->buf.buffer_ofs + ref_surface->psb_surface->chroma_offset); + psb_cmdbuf_rendec_write_address(cmdbuf, buffer, + buffer->buffer_ofs); + psb_cmdbuf_rendec_write_address(cmdbuf, buffer, + buffer->buffer_ofs + + ref_surface->psb_surface->chroma_offset); } else { @@ -1555,9 +1309,8 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef); } } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } -#endif /* CHUNK: MVA and MVB */ /* works as long as weighted factors A and B commands remain the same */ @@ -1565,11 +1318,12 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu ( (pic_params->pic_fields.bits.weighted_bipred_idc != 0) && (slice_param->slice_type == ST_B) )) { IMG_UINT32 num_ref_0 = slice_param->num_ref_idx_l0_active_minus1; - - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_A) ); - - if (num_ref_0 > 31) - num_ref_0 = 31; + + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_A) ); + + if (num_ref_0 > 31 ) + num_ref_0 = 31; + /* weighted factors */ for ( i = 0; i <= num_ref_0; i++ ) { @@ -1601,16 +1355,20 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu { psb_cmdbuf_rendec_write(cmdbuf, 0); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); if (slice_param->slice_type == ST_B) { IMG_UINT32 num_ref_1 = slice_param->num_ref_idx_l1_active_minus1; - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_B) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_B) ); if (num_ref_1 > 31) + { + psb__error_message("num_ref_1 shouldn't be larger than 31\n"); num_ref_1 = 31; + } + /* weighted factors */ for ( i = 0; i <= num_ref_1; i++ ) { @@ -1642,14 +1400,15 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu { psb_cmdbuf_rendec_write(cmdbuf, 0); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } } + /* CHUNK: SEQ Commands 1 */ /* send Slice Data for every slice */ /* MUST be the last slice sent */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); reg_value = 0; REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (ctx->picture_height_mb*16)-1 ); @@ -1667,27 +1426,27 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode ); REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, ctx->profile ); REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 1 ); /* H.264 */ - REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, ctx->two_pass_mode ); + REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, (ctx->two_pass_mode && !ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag)); REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, pic_params->seq_fields.bits.chroma_format_idc); psb_cmdbuf_rendec_write(cmdbuf, reg_value); ctx->obj_context->operating_mode = reg_value; - if(ctx->obj_context->is_oold){ + if((ctx->deblock_mode == DEBLOCK_INTRA_OOLD) && ctx->two_pass_mode) /* Need to mark which buf is to be used as ref*/ + { /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs); /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs + target_surface->chroma_offset); + target_surface->ref_buf = target_surface->in_loop_buf; } - else { - /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ + else + { psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); - - /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + target_surface->ref_buf = &target_surface->buf; } - /* Aux Msb Buffer base address: H.264 does not use this command */ reg_value = 0; psb_cmdbuf_rendec_write(cmdbuf, reg_value); @@ -1709,7 +1468,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTOR_DENOMINATOR, Y_LOG2_WEIGHT_DENOM, slice_param->luma_log2_weight_denom); psb_cmdbuf_rendec_write(cmdbuf, reg_value); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); /* CHUNK: SEQ Commands 2 */ /* send Slice Data for every slice */ @@ -1717,7 +1476,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu { IMG_UINT32 ui32Mode = pic_params->pic_fields.bits.weighted_pred_flag | (pic_params->pic_fields.bits.weighted_bipred_idc << 1); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); reg_value = 0; REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, CONSTRAINED_INTRA_PRED, pic_params->pic_fields.bits.constrained_intra_pred_flag ); @@ -1732,11 +1491,16 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu /* Store slice parameters in header */ *(ctx->p_slice_params) = reg_value; - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } + /* If this a two pass mode deblock, then we will perform the rotation as part of the + * 2nd pass deblock procedure + */ + if(!ctx->two_pass_mode && ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not issue */ + psb__H264_setup_alternative_frame(ctx); - psb_cmdbuf_rendec_end_block( cmdbuf ); + /* psb_cmdbuf_rendec_end_block( cmdbuf ); */ } /* @@ -1770,17 +1534,42 @@ static void psb__H264_write_kick(context_H264_p ctx, VASliceParameterBufferH264 *cmdbuf->cmd_idx++ = CMD_COMPLETION; } - +/* static void psb__H264_FE_state(context_H264_p ctx) { uint32_t lldma_record_offset; psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; - /* See RENDER_BUFFER_HEADER */ - *cmdbuf->cmd_idx++ = CMD_HEADER; + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + ctx->p_slice_params = cmdbuf->cmd_idx; + *cmdbuf->cmd_idx++ = 0; + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->preload_buffer), 0, + sizeof(PRELOAD), 0, LLDMA_TYPE_H264_PRELOAD_SAVE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->preload_buffer), 0, + sizeof(PRELOAD), 0, LLDMA_TYPE_H264_PRELOAD_RESTORE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; +} +*/ + +static void psb__H264_FE_state(context_H264_p ctx) +{ + uint32_t lldma_record_offset; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; ctx->p_slice_params = cmdbuf->cmd_idx; - *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ + *cmdbuf->cmd_idx++ = 0; + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->preload_buffer), 0, sizeof(PRELOAD), 0, LLDMA_TYPE_H264_PRELOAD_SAVE ); @@ -1791,6 +1580,14 @@ static void psb__H264_FE_state(context_H264_p ctx) sizeof(PRELOAD), 0, LLDMA_TYPE_H264_PRELOAD_RESTORE ); RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); cmdbuf->cmd_idx++; + + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; + + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + + ctx->alt_output_flags = cmdbuf->cmd_idx++; + *ctx->alt_output_flags = 0; } static void psb__H264_preprocess_slice(context_H264_p ctx, @@ -1833,6 +1630,24 @@ static void psb__H264_preprocess_slice(context_H264_p ctx, REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, SLICEQPY, slice_qpy ); REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L0_ACTIVE_MINUS1, slice_param->num_ref_idx_l0_active_minus1); REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L1_ACTIVE_MINUS1, slice_param->num_ref_idx_l1_active_minus1); + + IMG_BOOL deblocker_disable = (slice_param->disable_deblocking_filter_idc == 1); + + if(deblocker_disable) + { + if(ctx->obj_context->is_oold) + { + ctx->deblock_mode = DEBLOCK_INTRA_OOLD; + ctx->two_pass_mode = 1; + REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_2PASS_FLAG, ctx->two_pass_mode ); + } + else + ctx->deblock_mode = DEBLOCK_STD; + } + else + { + ctx->deblock_mode = DEBLOCK_STD; + } } /* **************************************************************************************************************** */ @@ -1904,7 +1719,7 @@ static VAStatus psb__H264_process_slice(context_H264_p ctx, psb__information_message(" first mb = %d macroblock offset = %d\n", slice_param->first_mb_in_slice, slice_param->slice_data_bit_offset); psb__information_message(" slice_data_flag = %d\n", slice_param->slice_data_flag); psb__information_message(" coded size = %dx%d\n", ctx->picture_width_mb, ctx->picture_height_mb); - psb__information_message(" slice type = %s\n", slice2str[slice_param->slice_type % 5]); + psb__information_message(" slice type = %s\n", slice2str[(slice_param->slice_type % 5)]); psb__information_message(" weighted_pred_flag = %d weighted_bipred_idc = %d\n", ctx->pic_params->pic_fields.bits.weighted_pred_flag, ctx->pic_params->pic_fields.bits.weighted_bipred_idc); if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || @@ -1919,8 +1734,6 @@ static VAStatus psb__H264_process_slice(context_H264_p ctx, ASSERT( !ctx->split_buffer_pending ); psb__H264_preprocess_slice(ctx, slice_param); - - psb__H264_update_picture_lists(ctx, slice_param); /* Initialise the command buffer */ /* TODO: Reuse current command buffer until full */ @@ -1987,6 +1800,8 @@ static VAStatus psb__H264_process_slice(context_H264_p ctx, ctx->obj_context->first_mb = (ctx->first_mb_y << 8) | ctx->first_mb_x; ctx->obj_context->last_mb = (((ctx->picture_height_mb >> ctx->pic_params->pic_fields.bits.field_pic_flag) - 1) << 8) | (ctx->picture_width_mb - 1); + *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); + if (psb_context_submit_cmdbuf(ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; @@ -2063,6 +1878,8 @@ static VAStatus pnw_H264_BeginPicture( } ctx->slice_count = 0; ctx->slice_group_map_buffer = NULL; + ctx->deblock_mode = DEBLOCK_NONE; + return VA_STATUS_SUCCESS; } @@ -2130,67 +1947,87 @@ static VAStatus pnw_H264_EndPicture( { INIT_CONTEXT_H264 - if(obj_context->is_oold && !ctx->two_pass_mode) - { - psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; - psb_buffer_p colocated_target_buffer = psb__H264_lookup_colocated_buffer(ctx, target_surface); - - psb_context_submit_oold(ctx->obj_context, - target_surface->in_loop_buf, - &target_surface->buf, - colocated_target_buffer, - ctx->picture_width_mb, - ctx->picture_height_mb, - ctx->field_type, - target_surface->chroma_offset); - } - - if (psb_context_flush_cmdbuf(ctx->obj_context)) - { - return VA_STATUS_ERROR_UNKNOWN; - } - if (ctx->two_pass_mode) { - void *pMbData = NULL; - psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; psb_buffer_p colocated_target_buffer = psb__H264_lookup_colocated_buffer(ctx, target_surface); + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + uint32_t rotation_flags = 0; + uint32_t ext_stride_a = 0; psb__information_message("pnw_H264_EndPicture got two pass mode frame\n"); + if(ctx->obj_context->rotate != VA_ROTATION_NONE) + { + ASSERT(rotate_surface); + REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + } - psb_surface_sync(target_surface); - - psb_context_get_next_cmdbuf(ctx->obj_context); + REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64 ); - if( (colocated_target_buffer == NULL) || psb_buffer_map(colocated_target_buffer, &pMbData) ) { - psb__information_message("psb_H264: map colocated buffer error!\n"); + /* Issue two pass deblock cmd, HW can handle deblock instead of host when using DE2.x firmware */ + if(ctx->deblock_mode == DEBLOCK_STD) + { + if(psb_context_submit_hw_deblock(ctx->obj_context, + &target_surface->buf, + rotate_surface ? (&rotate_surface->buf) : NULL, + colocated_target_buffer, + ctx->picture_width_mb, + ctx->picture_height_mb, + rotation_flags, + ctx->field_type, + ext_stride_a, + target_surface->chroma_offset + target_surface->buf.buffer_ofs, + rotate_surface ? (rotate_surface->chroma_offset + rotate_surface->buf.buffer_ofs) : 0, + ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) + { + return VA_STATUS_ERROR_UNKNOWN; + } } - else { - int ret; - pMbData += colocated_target_buffer->buffer_ofs; - - ret = psb_cmdbuf_second_pass(ctx->obj_context, - ctx->obj_context->operating_mode, /* Write RegIO pairs into cmdbuf->buf */ - pMbData, - ctx->picture_width_mb, - ctx->picture_height_mb, - &target_surface->buf, - target_surface->chroma_offset); - - psb_buffer_unmap(colocated_target_buffer); - - //printf("Ret of psb_cmdbuf_second_pass is %d\n", ret); - if(!ret) { - //printf("Submit deblock msg and flush cmdbuf\n"); - psb_context_submit_deblock(ctx->obj_context); - - if (psb_context_flush_cmdbuf(ctx->obj_context)) - psb__information_message("psb_H264: flush deblock cmdbuf error\n"); - } + else if(ctx->deblock_mode == DEBLOCK_INTRA_OOLD) + { + psb_buffer_p buffer_dst; + uint32_t chroma_offset_dst; + + if(ctx->obj_context->rotate == VA_ROTATION_NONE) + { + buffer_dst = &target_surface->buf; + chroma_offset_dst = target_surface->chroma_offset; + } + else + { + if(!rotate_surface) + ASSERT(0); + + buffer_dst = &rotate_surface->buf; + chroma_offset_dst = rotate_surface->chroma_offset; + } + + if(psb_context_submit_hw_deblock(ctx->obj_context, + target_surface->in_loop_buf, + buffer_dst, + colocated_target_buffer, + ctx->picture_width_mb, + ctx->picture_height_mb, + rotation_flags, + ctx->field_type, + ext_stride_a, + target_surface->chroma_offset + target_surface->buf.buffer_ofs, + chroma_offset_dst, + ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) + { + return VA_STATUS_ERROR_UNKNOWN; + } } } + if (psb_context_flush_cmdbuf(ctx->obj_context)) + { + return VA_STATUS_ERROR_UNKNOWN; + } + if (ctx->pic_params) { free(ctx->pic_params); diff --git a/src/pnw_H264ES.c b/src/pnw_H264ES.c index 7ef4fcf..180d21a 100644 --- a/src/pnw_H264ES.c +++ b/src/pnw_H264ES.c @@ -127,7 +127,7 @@ static VAStatus pnw_H264ES_CreateContext( ctx->Slices = 1; - if (getenv("PSB_VIDEO_DUAL_CORE") != NULL) + if (getenv("PSB_VIDEO_SIG_CORE") == NULL) { ctx->Slices = 2; ctx->NumCores = 2; @@ -217,6 +217,7 @@ static VAStatus pnw__H264ES_process_sequence_param(context_ENC_p ctx, object_buf ctx->sRCParams.QCPOffset = 0;/* FIXME */ ctx->sRCParams.IntraFreq = pSequenceParams->intra_period; + ctx->sRCParams.IDRFreq = pSequenceParams->intra_idr_period; /*if (ctx->sRCParams.BitsPerSecond < 256000) ctx->sRCParams.BufferSize = (9 * ctx->sRCParams.BitsPerSecond) >> 1; else @@ -239,12 +240,12 @@ static VAStatus pnw__H264ES_process_sequence_param(context_ENC_p ctx, object_buf VUI_Params.Time_Scale = ctx->sRCParams.FrameRate*2; VUI_Params.bit_rate_value_minus1 = ctx->sRCParams.BitsPerSecond/64 -1; - VUI_Params.cbp_size_value_minus1 = ctx->sRCParams.BitsPerSecond*3/32 -1; - VUI_Params.CBR = 1; - VUI_Params.initial_cpb_removal_delay_length_minus1 = 0; - VUI_Params.cpb_removal_delay_length_minus1 = 0; - VUI_Params.dpb_output_delay_length_minus1 = 0; - VUI_Params.time_offset_length = 0; + VUI_Params.cbp_size_value_minus1 = ctx->sRCParams.BitsPerSecond/16 -1; + VUI_Params.CBR = ((IMG_CODEC_H264_CBR == ctx->eCodec) ? 1 : 0); + VUI_Params.initial_cpb_removal_delay_length_minus1 = BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE - 1; + VUI_Params.cpb_removal_delay_length_minus1 = PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE - 1; + VUI_Params.dpb_output_delay_length_minus1 = PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE - 1; + VUI_Params.time_offset_length = 24; sCrop.bClip = IMG_FALSE; sCrop.LeftCropOffset = 0; @@ -284,6 +285,7 @@ static VAStatus pnw__H264ES_process_sequence_param(context_ENC_p ctx, object_buf pSequenceParams->picture_height_in_mbs,IMG_TRUE,&VUI_Params,&sCrop, pSequenceParams->level_idc, ctx->profile_idc); + cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx; pnw_cmdbuf_insert_command_package(ctx->obj_context, ctx->ParallelCores - 1, /* Send to the last core as this will complete first */ MTX_CMDID_DO_HEADER, @@ -327,10 +329,28 @@ static VAStatus pnw__H264ES_process_picture_param(context_ENC_p ctx, object_buff free(pBuffer); return VA_STATUS_ERROR_INVALID_BUFFER; } + if (ctx->sRCParams.IDRFreq != 0) { /* period IDR is desired */ + unsigned int is_intra = 0; + unsigned int intra_cnt = 0; + + ctx->force_idr_h264 = 0; + + if ((ctx->obj_context->frame_count % ctx->sRCParams.IntraFreq) == 0) { + is_intra = 1; /* suppose current frame is I frame */ + intra_cnt = ctx->obj_context->frame_count / ctx->sRCParams.IntraFreq; + } + + /* current frame is I frame (suppose), and an IDR frame is desired*/ + if ((is_intra) && ((intra_cnt % ctx->sRCParams.IDRFreq) == 0)) { + ctx->force_idr_h264 = 1; + ctx->obj_context->frame_count = 0; + } + } /* For H264, PicHeader only needed in the first picture*/ if( !(ctx->obj_context->frame_count) ) { cmdbuf = ctx->obj_context->pnw_cmdbuf; + cmdbuf->cmd_idx_saved[PNW_CMDBUF_PIC_HEADER_IDX] = cmdbuf->cmd_idx; pnw_cmdbuf_insert_command_package(ctx->obj_context, ctx->ParallelCores - 1, /* Send to the last core as this will complete first */ MTX_CMDID_DO_HEADER, @@ -366,12 +386,13 @@ static VAStatus pnw__H264ES_process_picture_param(context_ENC_p ctx, object_buff static VAStatus pnw__H264ES_process_slice_param(context_ENC_p ctx, object_buffer_p obj_buffer) { /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */ - VAEncSliceParameterBuffer *pBuffer; + VAEncSliceParameterBuffer *pBuf_per_core, *pBuffer; pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf; unsigned int MBSkipRun, FirstMBAddress; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); - int i; + int i, j, slice_per_core; unsigned char is_intra = 0; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); @@ -385,135 +406,157 @@ static VAStatus pnw__H264ES_process_slice_param(context_ENC_p ctx, object_buffer /* H264: Calculate number of Mskip to skip IF this was a skip frame */ MBSkipRun = (ctx->Width * ctx->Height) / 256; - /* - if (0 == pBuffer->start_row_number) + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) { - if (pBuffer->slice_flags.bits.is_intra) - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_I); - else - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); + ctx->slice_param_num = obj_buffer->num_elements; + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } } - */ - /* - if (0 == pBuffer->start_row_number) - RELOC_PIC_PARAMS_PNW(&psPicParams->InParamsBase, ctx->in_params_ofs, &cmdbuf->topaz_in_params); - */ - - if (getenv("PSB_VIDEO_DUAL_CORE") != NULL) + if (getenv("PSB_VIDEO_SIG_CORE") == NULL) { + if ( (ctx->ParallelCores == 2) && (obj_buffer->num_elements == 1)) + { /*Need to replace unneccesary MTX_CMDID_STARTPICs with MTX_CMDID_PAD*/ - for (i = 0; i < (ctx->ParallelCores - obj_buffer->num_elements); i++) + for (i = 0; i < (ctx->ParallelCores - 1); i++) { - *(cmdbuf->cmd_idx_saved + i * 4) &= (~MTX_CMDWORD_ID_MASK); - *(cmdbuf->cmd_idx_saved + i * 4) |= MTX_CMDID_PAD; + *(cmdbuf->cmd_idx_saved[PNW_CMDBUF_START_PIC_IDX] + i * 4) &= (~MTX_CMDWORD_ID_MASK); + *(cmdbuf->cmd_idx_saved[PNW_CMDBUF_START_PIC_IDX] + i * 4) |= MTX_CMDID_PAD; } - if (ctx->ParallelCores > obj_buffer->num_elements) - { - psb__information_message(" Remove unneccesary %d MTX_CMDID_STARTPIC commands from cmdbuf\n", - ctx->ParallelCores - obj_buffer->num_elements); - ctx->ParallelCores = obj_buffer->num_elements; - } - } - - for(i = 0; i < obj_buffer->num_elements; i++) { - /*Todo list: - *1.Insert Do header command - *2.setup InRowParams - *3.setup Slice params - *4.Insert Do slice command - * */ - unsigned char deblock_idc; - - /*If the frame is skipped, it shouldn't be a I frame*/ - is_intra = (ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip) ? 0 : pBuffer->slice_flags.bits.is_intra; - deblock_idc = pBuffer->slice_flags.bits.disable_deblocking_filter_idc; - - if((ctx->NumCores > 1) && (deblock_idc == 0)) - deblock_idc = 2; - - FirstMBAddress = (pBuffer->start_row_number * ctx->Width) / 16; - - memset(cmdbuf->header_mem_p + ctx->slice_header_ofs - + ctx->obj_context->slice_count * HEADER_SIZE, - 0, - HEADER_SIZE); - - /* Insert Do Header command, relocation is needed */ - pnw__H264_prepare_slice_header(cmdbuf->header_mem_p + ctx->slice_header_ofs - + ctx->obj_context->slice_count * HEADER_SIZE, - is_intra, - pBuffer->slice_flags.bits.disable_deblocking_filter_idc, - ctx->obj_context->frame_count, - FirstMBAddress, - MBSkipRun, 0); - - /* ensure that this slice is consequtive to that last processed by the target core */ - /* - ASSERT( -1 == ctx->LastSliceNum[ctx->SliceToCore] - || ctx->obj_context->slice_count == 1 + ctx->LastSliceNum[ctx->SliceToCore] ); - */ - /* note the slice number the target core is now processing */ - ctx->LastSliceNum[ctx->SliceToCore] = ctx->obj_context->slice_count; - - pnw_cmdbuf_insert_command_package(ctx->obj_context, - ctx->SliceToCore, - MTX_CMDID_DO_HEADER, - &cmdbuf->header_mem, - ctx->slice_header_ofs + ctx->obj_context->slice_count * HEADER_SIZE); - - if ( 0 == ctx->SliceToCore ) - { - ctx->SliceToCore = ctx->ParallelCores; + psb__information_message(" Remove unneccesary %d MTX_CMDID_STARTPIC commands from cmdbuf\n", + ctx->ParallelCores - obj_buffer->num_elements); + ctx->ParallelCores = obj_buffer->num_elements; + *(cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEQ_HEADER_IDX]) &= + ~(MTX_CMDWORD_CORE_MASK<cmd_idx_saved[PNW_CMDBUF_PIC_HEADER_IDX]) &= + ~(MTX_CMDWORD_CORE_MASK<SliceToCore = ctx->ParallelCores - 1; + ctx->EncodeToCore = ctx->ParallelCores - 1; } - ctx->SliceToCore--; + } - if (!(ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) + slice_per_core = obj_buffer->num_elements / ctx->ParallelCores; + pBuf_per_core = pBuffer; + for(i = 0; i < slice_per_core; i++) { + pBuffer = pBuf_per_core; + for(j = 0; j < ctx->ParallelCores; j++) { - /*Only reset on the first frame. It's more effective than DDK. Have confirmed with IMG*/ - if (ctx->obj_context->frame_count==0) - pnw_reset_encoder_params(ctx); - if((pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra){ - ctx->BelowParamsBufIdx = (ctx->BelowParamsBufIdx + 1) & 0x1; + /*Slice encoding Order: + *1.Insert Do header command + *2.setup InRowParams + *3.setup Slice params + *4.Insert Do slice command + * */ + unsigned char deblock_idc; + + deblock_idc = pBuffer->slice_flags.bits.disable_deblocking_filter_idc; + + /*If the frame is skipped, it shouldn't be a I frame*/ + if (ctx->force_idr_h264 || (ctx->obj_context->frame_count == 0)) { + is_intra = 1; } + else + is_intra = (ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip) ? 0 : pBuffer->slice_flags.bits.is_intra; + + + if((ctx->NumCores > 1) && (deblock_idc == 0)) + deblock_idc = 2; - // if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra? 0:1)], pBuffer)==0) { - ///* cache current param parameters */ - //memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], - //pBuffer, sizeof(VAEncSliceParameterBuffer)); - // - ///* Setup InParams value*/ - //pnw_setup_slice_params(ctx, - //pBuffer->start_row_number * 16, - //pBuffer->slice_height*16, - //pBuffer->slice_flags.bits.is_intra, - //ctx->obj_context->frame_count > 0, - //psPicParams->sInParams.SeInitQP); - //}FIXME Not use slice_param_cache temporary for simplify - - pnw_setup_slice_params(ctx, - pBuffer->start_row_number * 16, - pBuffer->slice_height*16, - pBuffer->slice_flags.bits.is_intra, - ctx->obj_context->frame_count > 0, - psPicParams->sInParams.SeInitQP); - - /* Insert do slice command and setup related buffer value */ - pnw__send_encode_slice_params(ctx, - pBuffer->slice_flags.bits.is_intra, - pBuffer->start_row_number * 16, - deblock_idc, + FirstMBAddress = (pBuffer->start_row_number * ctx->Width) / 16; + + memset(cmdbuf->header_mem_p + ctx->slice_header_ofs + + ctx->obj_context->slice_count * HEADER_SIZE, + 0, + HEADER_SIZE); + + /* Insert Do Header command, relocation is needed */ + pnw__H264_prepare_slice_header(cmdbuf->header_mem_p + ctx->slice_header_ofs + + ctx->obj_context->slice_count * HEADER_SIZE, + is_intra, + pBuffer->slice_flags.bits.disable_deblocking_filter_idc, ctx->obj_context->frame_count, - pBuffer->slice_height*16, - ctx->obj_context->slice_count); + FirstMBAddress, + MBSkipRun, 0, ctx->force_idr_h264); + + /* ensure that this slice is consequtive to that last processed by the target core */ + /* + ASSERT( -1 == ctx->LastSliceNum[ctx->SliceToCore] + || ctx->obj_context->slice_count == 1 + ctx->LastSliceNum[ctx->SliceToCore] ); + */ + /* note the slice number the target core is now processing */ + ctx->LastSliceNum[ctx->SliceToCore] = ctx->obj_context->slice_count; + + pnw_cmdbuf_insert_command_package(ctx->obj_context, + ctx->SliceToCore, + MTX_CMDID_DO_HEADER, + &cmdbuf->header_mem, + ctx->slice_header_ofs + ctx->obj_context->slice_count * HEADER_SIZE); + + if ( 0 == ctx->SliceToCore ) + { + ctx->SliceToCore = ctx->ParallelCores; + } + ctx->SliceToCore--; - psb__information_message("Now frame_count/slice_count is %d/%d\n", - ctx->obj_context->frame_count, ctx->obj_context->slice_count); - } - ctx->obj_context->slice_count++; - pBuffer++; /* Move to the next buffer */ + if (!(ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) + { + /*Only reset on the first frame. It's more effective than DDK. Have confirmed with IMG*/ + if (ctx->obj_context->frame_count==0) + pnw_reset_encoder_params(ctx); + if((pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra){ + ctx->BelowParamsBufIdx = (ctx->BelowParamsBufIdx + 1) & 0x1; + } + + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + + ctx->obj_context->slice_count; + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer)==0) { + /* cache current param parameters */ + memcpy(&ctx->slice_param_cache[slice_param_idx], + pBuffer, sizeof(VAEncSliceParameterBuffer)); + + /* Setup InParams value*/ + pnw_setup_slice_params(ctx, + pBuffer->start_row_number * 16, + pBuffer->slice_height*16, + pBuffer->slice_flags.bits.is_intra, + ctx->obj_context->frame_count > 0, + psPicParams->sInParams.SeInitQP); + } + + /* Insert do slice command and setup related buffer value */ + pnw__send_encode_slice_params(ctx, + pBuffer->slice_flags.bits.is_intra, + pBuffer->start_row_number * 16, + deblock_idc, + ctx->obj_context->frame_count, + pBuffer->slice_height*16, + ctx->obj_context->slice_count); + + psb__information_message("Now frame_count/slice_count is %d/%d\n", + ctx->obj_context->frame_count, ctx->obj_context->slice_count); + } + ctx->obj_context->slice_count++; - ASSERT(ctx->obj_context->slice_count < MAX_SLICES_PER_PICTURE); + ASSERT(ctx->obj_context->slice_count < MAX_SLICES_PER_PICTURE); + pBuffer += slice_per_core; /*Move to the next buffer which will be sent to core j*/ + } + pBuf_per_core++; /* Move to the next buffer */ } free(obj_buffer->buffer_data ); @@ -592,3 +635,21 @@ struct format_vtable_s pnw_H264ES_vtable = { renderPicture: pnw_H264ES_RenderPicture, endPicture: pnw_H264ES_EndPicture }; + +VAStatus pnw_set_frame_skip_flag( + object_context_p obj_context) +{ + INIT_CONTEXT_H264ES; + VAStatus vaStatus = VA_STATUS_SUCCESS; + + + if (ctx && ctx->src_surface ) + { + SET_SURFACE_INFO_skipped_flag(ctx->src_surface->psb_surface, 1); + psb__information_message("Detected a skipped frame for surface 0x%08x.\n", ctx->src_surface->psb_surface); + } + + return vaStatus; +} + + diff --git a/src/pnw_H264ES.h b/src/pnw_H264ES.h index 1fd8ce4..522e605 100644 --- a/src/pnw_H264ES.h +++ b/src/pnw_H264ES.h @@ -27,5 +27,6 @@ #include "psb_drv_video.h" extern struct format_vtable_s pnw_H264ES_vtable; - +extern VAStatus pnw_set_frame_skip_flag( + object_context_p obj_context); #endif /* _PNW_H264ES_H_ */ diff --git a/src/pnw_MPEG2.c b/src/pnw_MPEG2.c index 95b53e1..96206e8 100644 --- a/src/pnw_MPEG2.c +++ b/src/pnw_MPEG2.c @@ -515,7 +515,10 @@ struct context_MPEG2_s { /* Misc */ unsigned int previous_slice_vertical_position; + uint32_t *p_range_mapping_base0; + uint32_t *p_range_mapping_base1; uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER */ + uint32_t *slice_first_pic_last; }; typedef struct context_MPEG2_s *context_MPEG2_p; @@ -801,7 +804,7 @@ static VAStatus psb__MPEG2_process_picture_param(context_MPEG2_p ctx, object_buf REGIO_WRITE_FIELD_LITE (ctx->BE_SPS0,MSVDX_VEC_MPEG2,CR_VEC_MPEG2_BE_SPS0,BE_HORIZONTAL_SIZE_MINUS1, ctx->picture_width_mb - 1); ctx->BE_SPS1 = 0; - REGIO_WRITE_FIELD_LITE (ctx->BE_SPS1,MSVDX_VEC_MPEG2,CR_VEC_MPEG2_BE_SPS1,BE_VERTICAL_SIZE_MINUS1, ctx->picture_height_mb - 1); + REGIO_WRITE_FIELD_LITE (ctx->BE_SPS1,MSVDX_VEC_MPEG2,CR_VEC_MPEG2_BE_SPS1,BE_VERTICAL_SIZE_MINUS1, ctx->picture_height_mb); ctx->FE_PPS0 = 0; REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_ALTERNATE_SCAN, !!(ctx->pic_params->picture_coding_extension.bits.alternate_scan)); @@ -926,6 +929,13 @@ static void psb__MPEG2_write_VLC_tables(context_MPEG2_p ctx) { psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_cmdbuf_skip_start_block( cmdbuf, SKIP_ON_CONTEXT_SWITCH ); + /* VLC Table */ + /* Write a LLDMA Cmd to transfer VLD Table data */ + psb_cmdbuf_lldma_write_cmdbuf( cmdbuf, &ctx->vlc_packed_table, 0, + sizeof(gaui16mpeg2VlcTableDataPacked), + 0, LLDMA_TYPE_VLC_TABLE ); + /* Write the vec registers with the index data for each of the tables and then write */ /* the actual table data. */ psb_cmdbuf_reg_start_block( cmdbuf ); @@ -937,11 +947,45 @@ static void psb__MPEG2_write_VLC_tables(context_MPEG2_p ctx) psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0),OPCODE0 ); psb_cmdbuf_reg_end_block( cmdbuf ); - /* VLC Table */ - /* Write a LLDMA Cmd to transfer VLD Table data */ - psb_cmdbuf_lldma_write_cmdbuf( cmdbuf, &ctx->vlc_packed_table, 0, - sizeof(gaui16mpeg2VlcTableDataPacked), - 0, LLDMA_TYPE_VLC_TABLE ); + psb_cmdbuf_skip_end_block( cmdbuf ); +} + +/* Programme the Alt output if there is a rotation*/ +static void psb__MPEG2_setup_alternative_frame( context_MPEG2_p ctx, IMG_BOOL write_reg ) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + if(rotate_surface->extra_info[5] != obj_context->rotate) + psb__error_message("Display rotate mode does not match surface rotate mode!\n"); + + + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + + RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); + RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); + + psb_cmdbuf_rendec_end( cmdbuf ); + + if(write_reg) { + /* Set the rotation registers */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always has Rec */ + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + + psb_cmdbuf_rendec_write( cmdbuf, cmd ); + + psb_cmdbuf_rendec_end( cmdbuf ); + } } static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx) @@ -949,8 +993,10 @@ static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx) psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); + if(ctx->obj_context->rotate != VA_ROTATION_NONE) + psb__MPEG2_setup_alternative_frame( ctx, ctx->pic_params->picture_coding_extension.bits.progressive_frame); + + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); psb_cmdbuf_rendec_write( cmdbuf, ctx->display_picture_size ); psb_cmdbuf_rendec_write( cmdbuf, ctx->coded_picture_size ); psb_cmdbuf_rendec_write( cmdbuf, ctx->obj_context->operating_mode ); @@ -961,8 +1007,7 @@ static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx) /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx) @@ -970,8 +1015,7 @@ static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx) psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); /* In MPEG2, the registers at N=0 are always used to store the base address of the luma and chroma buffers of the most recently decoded reference picture. The registers at N=1 are used to store the base address @@ -1044,8 +1088,7 @@ static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx) break; } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param) @@ -1089,8 +1132,7 @@ static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterB /* BE Section */ - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG2_CR_VEC_MPEG2_BE_SPS0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG2_CR_VEC_MPEG2_BE_SPS0) ); psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS0 ); psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS1 ); @@ -1156,8 +1198,7 @@ psb__information_message("BE_slice = %08x first_field = %d\n", BE_slice, ctx->pi psb_cmdbuf_rendec_write( cmdbuf, BE_slice ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); ctx->previous_slice_vertical_position = slice_param->slice_vertical_position; } @@ -1168,8 +1209,7 @@ static void psb__MPEG2_set_slice_params(context_MPEG2_p ctx) uint32_t cmd_data; - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); cmd_data = 0; /* Build slice parameters */ REGIO_WRITE_FIELD (cmd_data, @@ -1188,8 +1228,7 @@ static void psb__MPEG2_set_slice_params(context_MPEG2_p ctx) *ctx->p_slice_params = cmd_data; - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__MPEG2_write_qmatrices(context_MPEG2_p ctx) @@ -1200,8 +1239,7 @@ static void psb__MPEG2_write_qmatrices(context_MPEG2_p ctx) /* Since we only decode 4:2:0 We only need to the Intra tables. Chroma quant tables are only used in Mpeg 4:2:2 and 4:4:4. The hardware wants non-intra followed by intra */ - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); + psb_cmdbuf_rendec_start( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); /* todo : optimisation here is to only load the need table */ @@ -1218,8 +1256,7 @@ static void psb__MPEG2_write_qmatrices(context_MPEG2_p ctx) // psb__information_message("INTRA_LUMA_Q[i] = %08x\n", ctx->qmatrix_data[INTRA_LUMA_Q][i]); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx) @@ -1238,8 +1275,7 @@ static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx) psb_cmdbuf_reg_end_block( cmdbuf ); - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); cmd_data = 0; /* Entdec Back-End controls */ REGIO_WRITE_FIELD (cmd_data, @@ -1256,8 +1292,7 @@ static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx) psb_cmdbuf_rendec_write( cmdbuf, cmd_data ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } static void psb__MPEG2_write_kick(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param) @@ -1274,14 +1309,21 @@ static void psb__MPEG2_FE_state(context_MPEG2_p ctx) psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; /* See RENDER_BUFFER_HEADER */ - *cmdbuf->cmd_idx++ = CMD_HEADER; - + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + + *ctx->p_range_mapping_base0 = 0; + *ctx->p_range_mapping_base1 = 0; + ctx->p_slice_params = cmdbuf->cmd_idx; *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ - cmdbuf->cmd_idx++; /* skip two lldma addr field */ + *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */ - cmdbuf->cmd_idx++; + *cmdbuf->cmd_idx++ = 0; + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; } static VAStatus psb__MPEG2_process_slice(context_MPEG2_p ctx, @@ -1365,9 +1407,16 @@ static VAStatus psb__MPEG2_process_slice(context_MPEG2_p ctx, ctx->split_buffer_pending = FALSE; ctx->obj_context->video_op = psb_video_vld; - ctx->obj_context->flags = 0; + ctx->obj_context->flags = FW_DXVA_RENDER_IS_VLD_NOT_MC; ctx->obj_context->first_mb = 0; - ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); + + if(ctx->pic_params->picture_coding_extension.bits.progressive_frame) + ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); + else + ctx->obj_context->last_mb = ((ctx->picture_height_mb/2 - 1 ) << 8) | (ctx->picture_width_mb - 1); + + *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); + if (psb_context_submit_cmdbuf(ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; @@ -1426,6 +1475,120 @@ static VAStatus psb__MPEG2_process_slice_data(context_MPEG2_p ctx, object_buffer return vaStatus; } +static void psb__MEPG2_send_highlevel_cmd(context_MPEG2_p ctx) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + psb_cmdbuf_reg_start_block( cmdbuf ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE), ctx->display_picture_size); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CODED_PICTURE_SIZE), ctx->coded_picture_size); + + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1); + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1); // 0 = VDMC and VDEB active. 1 = VDEB pass-thru. + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3); // MPEG2 + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1); // MAIN + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, OPERATING_MODE), cmd); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES), + &target_surface->buf, target_surface->buf.buffer_ofs); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES), + &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (0 * 8), + &target_surface->buf, target_surface->buf.buffer_ofs); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (0 * 8), + &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (1 * 8), + &target_surface->buf, target_surface->buf.buffer_ofs); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (1 * 8), + &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, 2); /* FRAME PICTURE -- ui8SliceFldType */ + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, 1); /* P PICTURE -- (ui8PicType == WMF_PTYPE_BI) ? WMF_PTYPE_I : (ui8PicType & 0x3) */ + psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET (MSVDX_CMDS, SLICE_PARAMS), cmd ); + *ctx->p_slice_params = cmd; + psb_cmdbuf_reg_end_block( cmdbuf ); + + + psb_cmdbuf_reg_start_block( cmdbuf ); + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS), + &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + + psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET (MSVDX_CMDS, VC1_CHROMA_RANGE_MAPPING_BASE_ADDRESS), + &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + psb_cmdbuf_reg_end_block( cmdbuf ); + + RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); + RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); +} + +static void psb__MEPG2_send_blit_cmd(context_MPEG2_p ctx) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + psb_cmdbuf_reg_start_block( cmdbuf ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION), cmd); + psb_cmdbuf_reg_end_block( cmdbuf ); + + *cmdbuf->cmd_idx++ = 0x40000000; /* CMD_BLIT_CMD */ + *cmdbuf->cmd_idx++ = ctx->picture_width_mb; + *cmdbuf->cmd_idx++ = ctx->picture_height_mb; /* FIXME */ + *cmdbuf->cmd_idx++ = CMD_COMPLETION; +} + +static void psb__MPEG2_insert_blit_cmd_to_rotate( context_MPEG2_p ctx ) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + /* See RENDER_BUFFER_HEADER */ + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + + *ctx->p_range_mapping_base0 = 0; + *ctx->p_range_mapping_base1 = 0; + + ctx->p_slice_params = cmdbuf->cmd_idx; + *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ + + *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */ + *cmdbuf->cmd_idx++ = 0; + + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; + *ctx->slice_first_pic_last = 0; + + psb__MEPG2_send_highlevel_cmd(ctx); + psb__MEPG2_send_blit_cmd(ctx); + + ctx->obj_context->video_op = psb_video_mc; + ctx->obj_context->flags = FW_DXVA_RENDER_IS_LAST_SLICE; + + if (psb_context_submit_cmdbuf(ctx->obj_context)) + { + ASSERT(0); + } +} + static VAStatus pnw_MPEG2_BeginPicture( object_context_p obj_context) { @@ -1504,6 +1667,13 @@ static VAStatus pnw_MPEG2_EndPicture( psb__information_message("pnw_MPEG2_EndPicture\n"); + if(ctx->obj_context->rotate != VA_ROTATION_NONE) + { + if( !(ctx->pic_params->picture_coding_extension.bits.progressive_frame) && + !(ctx->pic_params->picture_coding_extension.bits.is_first_field)) + psb__MPEG2_insert_blit_cmd_to_rotate(ctx); + } + if (psb_context_flush_cmdbuf(ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; diff --git a/src/pnw_MPEG4.c b/src/pnw_MPEG4.c index c55a525..a2b0d1b 100644 --- a/src/pnw_MPEG4.c +++ b/src/pnw_MPEG4.c @@ -325,7 +325,11 @@ struct context_MPEG4_s { int colocated_buffers_size; int colocated_buffers_idx; + uint32_t *p_range_mapping_base0; + uint32_t *p_range_mapping_base1; uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER */ + uint32_t *slice_first_pic_last; + uint32_t *alt_output_flags; }; typedef struct context_MPEG4_s *context_MPEG4_p; @@ -868,8 +872,8 @@ static void psb__MPEG4_write_qmatrices(context_MPEG4_p ctx) /* Since we only decode 4:2:0 We only need to the Intra tables. Chroma quant tables are only used in Mpeg 4:2:2 and 4:4:4. The hardware wants non-intra followed by intra */ - psb_cmdbuf_rendec_start_block( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); + /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ + psb_cmdbuf_rendec_start( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET ); /* todo : optimisation here is to only load the need table */ if (ctx->load_non_intra_quant_mat) @@ -903,8 +907,8 @@ static void psb__MPEG4_write_qmatrices(context_MPEG4_p ctx) } } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); + /* psb_cmdbuf_rendec_end_block( cmdbuf ); */ } @@ -985,6 +989,44 @@ static void psb__MPEG4_write_kick(context_MPEG4_p ctx, VASliceParameterBufferMPE *cmdbuf->cmd_idx++ = CMD_COMPLETION; } +/* Programme the Alt output if there is a rotation*/ +static void psb__MPEG4_setup_alternative_frame( context_MPEG4_p ctx ) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + if(rotate_surface->extra_info[5] != obj_context->rotate) + psb__error_message("Display rotate mode does not match surface rotate mode!\n"); + + + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* Set the rotation registers */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + + psb_cmdbuf_rendec_write( cmdbuf, cmd ); + + psb_cmdbuf_rendec_end( cmdbuf ); + + *ctx->alt_output_flags = cmd; + RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf); + RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf); +} + + static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterBufferMPEG4 *slice_param) { uint32_t cmd; @@ -992,14 +1034,14 @@ static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterB psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; psb_buffer_p colocated_target_buffer = psb__MPEG4_lookup_colocated_buffer(ctx, target_surface); - psb_buffer_p colocated_ref_buffer = psb__MPEG4_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface); + psb_buffer_p colocated_ref_buffer = psb__MPEG4_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface); /* FIXME DE2.0 use backward ref surface */ ASSERT(colocated_target_buffer); ASSERT(colocated_ref_buffer); - psb_cmdbuf_rendec_start_block( cmdbuf ); + /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ /* BE_PARAM_BASE_ADDR */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_PARAM_BASE_ADDR) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_PARAM_BASE_ADDR) ); if (colocated_target_buffer) { psb_cmdbuf_rendec_write_address( cmdbuf, colocated_target_buffer, 0); @@ -1009,10 +1051,10 @@ static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterB /* This is an error */ psb_cmdbuf_rendec_write( cmdbuf, 0 ); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); /* PARAM_BASE_ADDRESS */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_COLPARAM_BASE_ADDR) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_COLPARAM_BASE_ADDR) ); if (colocated_ref_buffer) { psb_cmdbuf_rendec_write_address( cmdbuf, colocated_ref_buffer, 0 ); @@ -1022,10 +1064,13 @@ static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterB /* This is an error */ psb_cmdbuf_rendec_write( cmdbuf, 0 ); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); + + if(ctx->obj_context->rotate != VA_ROTATION_NONE) + psb__MPEG4_setup_alternative_frame( ctx ); /* Send VDMC and VDEB commands */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); /* Display picture size cmd */ cmd = 0; @@ -1059,10 +1104,10 @@ static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterB /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); /* Reference pictures base addresses */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); //psb__information_message("Target surface = %08x\n", target_surface); //psb__information_message("Forward ref = %08x\n", ctx->forward_ref_surface->psb_surface); @@ -1080,8 +1125,8 @@ static void psb__MPEG4_set_picture_params(context_MPEG4_p ctx, VASliceParameterB /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs + ctx->backward_ref_surface->psb_surface->chroma_offset); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); + /* psb_cmdbuf_rendec_end_block( cmdbuf ); */ } static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParameterBufferMPEG4 *slice_param) @@ -1090,19 +1135,19 @@ static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParamet uint32_t cmd; unsigned short width_mb = PIXELS_TO_MB(ctx->pic_params->vop_width); - psb_cmdbuf_rendec_start_block( cmdbuf ); + /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ /* Write Back-End EntDec registers */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_SPS0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_SPS0) ); /* BE_SPS0 */ /* Common for VOPs and pictures with short header */ psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS0 ); /* BE_SPS1 */ /* Common for VOPs and pictures with short header */ psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS1 ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_VOP_SPS0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_VOP_SPS0) ); if (0 == ctx->pic_params->vol_fields.bits.short_video_header) { /* BE_VOP_SPS0 */ @@ -1123,13 +1168,13 @@ static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParamet /* BE_PICSH_PPS0 */ psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_PICSH_PPS0 ); } - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); if (0 == ctx->pic_params->vol_fields.bits.short_video_header) { if ((GMC == ctx->pic_params->vol_fields.bits.sprite_enable) && (PICTURE_CODING_S == ctx->pic_params->vop_fields.bits.vop_coding_type)) { - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_GMC_X) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_GMC_X) ); /* TODO: GMC Motion Vectors */ /* It is still needed to specify the precision of the motion vectors (should they be in */ @@ -1149,11 +1194,11 @@ static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParamet REGIO_WRITE_FIELD_LITE (cmd, MSVDX_VEC_MPEG4, CR_VEC_MPEG4_BE_GMC_Y, GMC_Y, ctx->pic_params->sprite_trajectory_dv[sprite_index] & 0x3FFF); psb_cmdbuf_rendec_write( cmdbuf, cmd ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); } } - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_SLICE0) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG4_CR_VEC_MPEG4_BE_SLICE0) ); /* BE_SLICE0 */ cmd = 0; @@ -1170,12 +1215,12 @@ static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParamet REGIO_WRITE_FIELD_LITE (cmd, MSVDX_VEC_MPEG4, CR_VEC_MPEG4_BE_VOP_TRD, BE_TRD, ctx->pic_params->TRD); psb_cmdbuf_rendec_write( cmdbuf, cmd ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); /* Send Slice Data for every slice */ /* MUST be the last slice sent */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); /* Slice params command */ cmd = 0; @@ -1193,20 +1238,20 @@ static void psb__MPEG4_set_backend_registers(context_MPEG4_p ctx, VASliceParamet REGIO_WRITE_FIELD_LITE (cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, ctx->pic_params->vop_fields.bits.vop_coding_type); psb_cmdbuf_rendec_write( cmdbuf, cmd ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); *ctx->p_slice_params = cmd; /* CHUNK: Entdec back-end profile and level */ - psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) ); cmd = 0; REGIO_WRITE_FIELD_LITE (cmd, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile); /* MPEG4 SP / ASP profile*/ REGIO_WRITE_FIELD_LITE (cmd, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 4); /* 4 - MPEG4 */ psb_cmdbuf_rendec_write( cmdbuf, cmd ); - psb_cmdbuf_rendec_end_chunk( cmdbuf ); - psb_cmdbuf_rendec_end_block( cmdbuf ); + psb_cmdbuf_rendec_end( cmdbuf ); + /* psb_cmdbuf_rendec_end_block( cmdbuf ); */ /* Send IQ matrices to Rendec */ psb__MPEG4_write_qmatrices(ctx); @@ -1250,16 +1295,18 @@ static void psb__MPEG4_set_frontend_registers(context_MPEG4_p ctx, VASliceParame psb_cmdbuf_reg_end_block( cmdbuf ); } +/* static void psb__MPEG4_FE_state(context_MPEG4_p ctx) { uint32_t lldma_record_offset; psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; - /* See RENDER_BUFFER_HEADER */ - *cmdbuf->cmd_idx++ = CMD_HEADER; + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; ctx->p_slice_params = cmdbuf->cmd_idx; - *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ + *cmdbuf->cmd_idx++ = 0; lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->FE_state_buffer), 0, FE_STATE_SAVE_SIZE, 0, LLDMA_TYPE_MPEG4_FESTATE_SAVE ); @@ -1270,6 +1317,37 @@ static void psb__MPEG4_FE_state(context_MPEG4_p ctx) FE_STATE_SAVE_SIZE, 0, LLDMA_TYPE_MPEG4_FESTATE_RESTORE ); RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); cmdbuf->cmd_idx++; + + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; +} +*/ +static void psb__MPEG4_FE_state(context_MPEG4_p ctx) +{ + uint32_t lldma_record_offset; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + ctx->p_slice_params = cmdbuf->cmd_idx; + *cmdbuf->cmd_idx++ = 0; + + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->FE_state_buffer), 0, + FE_STATE_SAVE_SIZE, 0, LLDMA_TYPE_MPEG4_FESTATE_SAVE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &(ctx->FE_state_buffer), 0, + FE_STATE_SAVE_SIZE, 0, LLDMA_TYPE_MPEG4_FESTATE_RESTORE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; + + ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + + ctx->alt_output_flags = cmdbuf->cmd_idx++; + *ctx->alt_output_flags = 0; } static VAStatus psb__MPEG4_process_slice(context_MPEG4_p ctx, @@ -1352,6 +1430,9 @@ static VAStatus psb__MPEG4_process_slice(context_MPEG4_p ctx, ctx->obj_context->flags = 0; ctx->obj_context->first_mb = 0; ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); + + *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); + if (psb_context_submit_cmdbuf(ctx->obj_context)) { vaStatus = VA_STATUS_ERROR_UNKNOWN; diff --git a/src/pnw_MPEG4ES.c b/src/pnw_MPEG4ES.c index b05de29..8500a5f 100644 --- a/src/pnw_MPEG4ES.c +++ b/src/pnw_MPEG4ES.c @@ -353,32 +353,44 @@ static VAStatus pnw__MPEG4ES_process_slice_param(context_ENC_p ctx, object_buffe pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf; PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p); int i; + int slice_param_idx; ASSERT(obj_buffer->type == VAEncSliceParameterBufferType); pBuffer = (VAEncSliceParameterBuffer *) obj_buffer->buffer_data; - /*In DDK186, firmware handles the frame skip*/ - /* do nothing for skip frame if RC enabled */ - /*if ((ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) { - free(obj_buffer->buffer_data); - obj_buffer->buffer_data = NULL; - psb__information_message("MPEG4 : will skip current frame.\n"); - return VA_STATUS_SUCCESS; - }*/ - /* if (0 == pBuffer->start_row_number) { if (pBuffer->slice_flags.bits.is_intra) - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_I); + RELOC_PIC_PARAMS_PNW(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_I); else - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); + RELOC_PIC_PARAMS_PNW(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P); } - */ - /* - if (0 == pBuffer->start_row_number) - RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, &cmdbuf->topaz_in_params); - */ + + /*In case the slice number changes*/ + if ( (ctx->slice_param_cache != NULL ) && (obj_buffer->num_elements != ctx->slice_param_num)) + { + psb__information_message("Slice number changes. Previous value is %d. Now it's %d\n", + ctx->slice_param_num, obj_buffer->num_elements); + free(ctx->slice_param_cache); + ctx->slice_param_cache = NULL; + ctx->slice_param_num = 0; + } + + if (NULL == ctx->slice_param_cache) + { + psb__information_message("Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2*ctx->slice_param_num); + ctx->slice_param_num = obj_buffer->num_elements; + ctx->slice_param_cache = calloc( 2*ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer)); + if (NULL == ctx->slice_param_cache) + { + psb__error_message("Run out of memory!\n"); + free(obj_buffer->buffer_data); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + } + + for(i = 0; i < obj_buffer->num_elements; i++) { unsigned char deblock_idc; @@ -393,29 +405,26 @@ static VAStatus pnw__MPEG4ES_process_slice_param(context_ENC_p ctx, object_buffe ctx->BelowParamsBufIdx = (ctx->BelowParamsBufIdx + 1) & 0x1; } - //if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra?0:1)],pBuffer) == 0) { - // /* cache current param parameters */ -// memcpy(&ctx->slice_param_cache[(pBuffer->slice_flags.bits.is_intra ? 0:1)], -// pBuffer, sizeof(VAEncSliceParameterBuffer)); -// -// /* Setup InParams value*/ -// pnw_setup_slice_params(ctx, -// pBuffer->start_row_number * 16, -// pBuffer->slice_height*16, -// pBuffer->slice_flags.bits.is_intra, -// ctx->obj_context->frame_count > 0, -// psPicParams->sInParams.SeInitQP); -// } - pnw_setup_slice_params(ctx, - pBuffer->start_row_number * 16, - pBuffer->slice_height*16, - pBuffer->slice_flags.bits.is_intra, - ctx->obj_context->frame_count > 0, - psPicParams->sInParams.SeInitQP); - - pnw__send_encode_slice_params(ctx, - pBuffer->slice_flags.bits.is_intra, - pBuffer->start_row_number * 16, + /*The corresponding slice buffer cache*/ + slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0:1) * ctx->slice_param_num + i; + + if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx],pBuffer) == 0) { + /* cache current param parameters */ + memcpy(&ctx->slice_param_cache[slice_param_idx], + pBuffer, sizeof(VAEncSliceParameterBuffer)); + + /* Setup InParams value*/ + pnw_setup_slice_params(ctx, + pBuffer->start_row_number * 16, + pBuffer->slice_height*16, + pBuffer->slice_flags.bits.is_intra, + ctx->obj_context->frame_count > 0, + psPicParams->sInParams.SeInitQP); + } + + pnw__send_encode_slice_params(ctx, + pBuffer->slice_flags.bits.is_intra, + pBuffer->start_row_number * 16, deblock_idc, ctx->obj_context->frame_count, pBuffer->slice_height*16, diff --git a/src/pnw_VC1.c b/src/pnw_VC1.c new file mode 100644 index 0000000..f12f4d1 --- /dev/null +++ b/src/pnw_VC1.c @@ -0,0 +1,3326 @@ +/* + * Copyright (c) 2007 Intel Corporation. All Rights Reserved. + * Copyright (c) Imagination Technologies Limited, UK + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "pnw_VC1.h" +#include "psb_def.h" +#include "psb_surface.h" +#include "psb_cmdbuf.h" + +#include "vc1_header.h" +#include "vc1_defs.h" + +#include "hwdefs/reg_io2.h" +#include "hwdefs/msvdx_offsets.h" +#include "hwdefs/msvdx_cmds_io2.h" +#include "hwdefs/msvdx_vec_reg_io2.h" +#include "hwdefs/msvdx_vec_vc1_reg_io2.h" +#include "hwdefs/msvdx_rendec_vc1_reg_io2.h" +#include "hwdefs/dxva_fw_ctrl.h" + +#include +#include +#include + +static int VC1_Header_Parser_HW = 1; + +#define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0])) +#define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val; +#define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1]) +#define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val; +#define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2])) +#define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val; +#define GET_SURFACE_INFO_colocated_index(psb_surface) ((int) (psb_surface->extra_info[3])) +#define SET_SURFACE_INFO_colocated_index(psb_surface, val) psb_surface->extra_info[3] = (uint32_t) val; + +#define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType") + +#define PIXELS_TO_MB(x) ((x + 15) / 16) + +#define PRELOAD_BUFFER_SIZE (4*1024) +#define AUXMSB_BUFFER_SIZE (1024*1024) + + +typedef struct +{ + IMG_UINT32 ui32ContextId; + IMG_UINT32 ui32SliceParams; + IMG_UINT32 ui32MacroblockNumber; +} VC1PRELOAD; + +#define FWPARSER_VC1PRELOAD_SIZE (0x60) + +/*! +****************************************************************************** + @LUTs VLC table selection Look-up Tables +******************************************************************************/ + +typedef enum +{ + VC1_VLC_Code_3x2_2x3_tiles = 0x0, + VC1_VLC_FourMV_Pattern_0, + VC1_VLC_FourMV_Pattern_1, + VC1_VLC_FourMV_Pattern_2, + VC1_VLC_FourMV_Pattern_3, + VC1_VLC_High_Mot_Chroma_DC_Diff_VLC, + VC1_VLC_High_Mot_Inter_VLC, + VC1_VLC_High_Mot_Intra_VLC, + VC1_VLC_High_Mot_Luminance_DC_Diff_VLC, + VC1_VLC_High_Rate_Inter_VLC, + VC1_VLC_High_Rate_Intra_VLC, + VC1_VLC_High_Rate_SUBBLKPAT, + VC1_VLC_High_Rate_TTBLK, + VC1_VLC_High_Rate_TTMB, + VC1_VLC_I_Picture_CBPCY_VLC, + VC1_VLC_Interlace_2_MVP_Pattern_0, + VC1_VLC_Interlace_2_MVP_Pattern_1, + VC1_VLC_Interlace_2_MVP_Pattern_2, + VC1_VLC_Interlace_2_MVP_Pattern_3, + VC1_VLC_Interlace_4MV_MB_0, + VC1_VLC_Interlace_4MV_MB_1, + VC1_VLC_Interlace_4MV_MB_2, + VC1_VLC_Interlace_4MV_MB_3, + VC1_VLC_Interlace_Non_4MV_MB_0, + VC1_VLC_Interlace_Non_4MV_MB_1, + VC1_VLC_Interlace_Non_4MV_MB_2, + VC1_VLC_Interlace_Non_4MV_MB_3, + VC1_VLC_Interlaced_CBPCY_0, + VC1_VLC_Interlaced_CBPCY_1, + VC1_VLC_Interlaced_CBPCY_2, + VC1_VLC_Interlaced_CBPCY_3, + VC1_VLC_Interlaced_CBPCY_4, + VC1_VLC_Interlaced_CBPCY_5, + VC1_VLC_Interlaced_CBPCY_6, + VC1_VLC_Interlaced_CBPCY_7, + VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC, + VC1_VLC_Low_Mot_Inter_VLC, + VC1_VLC_Low_Mot_Intra_VLC, + VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC, + VC1_VLC_Low_Rate_SUBBLKPAT, + VC1_VLC_Low_Rate_TTBLK, + VC1_VLC_Low_Rate_TTMB, + VC1_VLC_Medium_Rate_SUBBLKPAT, + VC1_VLC_Medium_Rate_TTBLK, + VC1_VLC_Medium_Rate_TTMB, + VC1_VLC_Mid_Rate_Inter_VLC, + VC1_VLC_Mid_Rate_Intra_VLC, + VC1_VLC_Mixed_MV_MB_0, + VC1_VLC_Mixed_MV_MB_1, + VC1_VLC_Mixed_MV_MB_2, + VC1_VLC_Mixed_MV_MB_3, + VC1_VLC_Mixed_MV_MB_4, + VC1_VLC_Mixed_MV_MB_5, + VC1_VLC_Mixed_MV_MB_6, + VC1_VLC_Mixed_MV_MB_7, + VC1_VLC_Mot_Vector_Diff_VLC_0, + VC1_VLC_Mot_Vector_Diff_VLC_1, + VC1_VLC_Mot_Vector_Diff_VLC_2, + VC1_VLC_Mot_Vector_Diff_VLC_3, + VC1_VLC_One_Field_Ref_Ilace_MV_0, + VC1_VLC_One_Field_Ref_Ilace_MV_1, + VC1_VLC_One_Field_Ref_Ilace_MV_2, + VC1_VLC_One_Field_Ref_Ilace_MV_3, + VC1_VLC_One_MV_MB_0, + VC1_VLC_One_MV_MB_1, + VC1_VLC_One_MV_MB_2, + VC1_VLC_One_MV_MB_3, + VC1_VLC_One_MV_MB_4, + VC1_VLC_One_MV_MB_5, + VC1_VLC_One_MV_MB_6, + VC1_VLC_One_MV_MB_7, + VC1_VLC_P_Picture_CBPCY_VLC_0, + VC1_VLC_P_Picture_CBPCY_VLC_1, + VC1_VLC_P_Picture_CBPCY_VLC_2, + VC1_VLC_P_Picture_CBPCY_VLC_3, + VC1_VLC_Two_Field_Ref_Ilace_MV_0, + VC1_VLC_Two_Field_Ref_Ilace_MV_1, + VC1_VLC_Two_Field_Ref_Ilace_MV_2, + VC1_VLC_Two_Field_Ref_Ilace_MV_3, + VC1_VLC_Two_Field_Ref_Ilace_MV_4, + VC1_VLC_Two_Field_Ref_Ilace_MV_5, + VC1_VLC_Two_Field_Ref_Ilace_MV_6, + VC1_VLC_Two_Field_Ref_Ilace_MV_7, + +} VC1_eVLCTables; + +static IMG_UINT8 MBMODETableFLDI[][2] = { + {VC1_VLC_One_MV_MB_0, VC1_VLC_Mixed_MV_MB_0}, + {VC1_VLC_One_MV_MB_1, VC1_VLC_Mixed_MV_MB_1}, + {VC1_VLC_One_MV_MB_2, VC1_VLC_Mixed_MV_MB_2}, + {VC1_VLC_One_MV_MB_3, VC1_VLC_Mixed_MV_MB_3}, + {VC1_VLC_One_MV_MB_4, VC1_VLC_Mixed_MV_MB_4}, + {VC1_VLC_One_MV_MB_5, VC1_VLC_Mixed_MV_MB_5}, + {VC1_VLC_One_MV_MB_6, VC1_VLC_Mixed_MV_MB_6}, + {VC1_VLC_One_MV_MB_7, VC1_VLC_Mixed_MV_MB_7}, +}; + +static IMG_UINT8 MBMODETableFRMI[][2] = { + {VC1_VLC_Interlace_4MV_MB_0, VC1_VLC_Interlace_Non_4MV_MB_0}, + {VC1_VLC_Interlace_4MV_MB_1, VC1_VLC_Interlace_Non_4MV_MB_1}, + {VC1_VLC_Interlace_4MV_MB_2, VC1_VLC_Interlace_Non_4MV_MB_2}, + {VC1_VLC_Interlace_4MV_MB_3, VC1_VLC_Interlace_Non_4MV_MB_3}, +}; + +static IMG_UINT8 CBPCYTableProg[] = { + VC1_VLC_P_Picture_CBPCY_VLC_0, + VC1_VLC_P_Picture_CBPCY_VLC_1, + VC1_VLC_P_Picture_CBPCY_VLC_2, + VC1_VLC_P_Picture_CBPCY_VLC_3, +}; + +static IMG_UINT8 CBPCYTableInterlaced[] = { + VC1_VLC_Interlaced_CBPCY_0, + VC1_VLC_Interlaced_CBPCY_1, + VC1_VLC_Interlaced_CBPCY_2, + VC1_VLC_Interlaced_CBPCY_3, + VC1_VLC_Interlaced_CBPCY_4, + VC1_VLC_Interlaced_CBPCY_5, + VC1_VLC_Interlaced_CBPCY_6, + VC1_VLC_Interlaced_CBPCY_7, +}; + +static IMG_UINT8 FourMVTable[] = { + VC1_VLC_FourMV_Pattern_0, + VC1_VLC_FourMV_Pattern_1, + VC1_VLC_FourMV_Pattern_2, + VC1_VLC_FourMV_Pattern_3, +}; + +static IMG_UINT8 Interlace2MVTable[] = { + VC1_VLC_Interlace_2_MVP_Pattern_0, + VC1_VLC_Interlace_2_MVP_Pattern_1, + VC1_VLC_Interlace_2_MVP_Pattern_2, + VC1_VLC_Interlace_2_MVP_Pattern_3, +}; + +static IMG_UINT8 ProgressiveMVTable[] = { + VC1_VLC_Mot_Vector_Diff_VLC_0, + VC1_VLC_Mot_Vector_Diff_VLC_1, + VC1_VLC_Mot_Vector_Diff_VLC_2, + VC1_VLC_Mot_Vector_Diff_VLC_3, +}; + +static IMG_UINT8 Interlaced1RefMVTable[] = { + VC1_VLC_One_Field_Ref_Ilace_MV_0, + VC1_VLC_One_Field_Ref_Ilace_MV_1, + VC1_VLC_One_Field_Ref_Ilace_MV_2, + VC1_VLC_One_Field_Ref_Ilace_MV_3, +}; + +static IMG_UINT8 MVTable2RefIlace[] = { + VC1_VLC_Two_Field_Ref_Ilace_MV_0, + VC1_VLC_Two_Field_Ref_Ilace_MV_1, + VC1_VLC_Two_Field_Ref_Ilace_MV_2, + VC1_VLC_Two_Field_Ref_Ilace_MV_3, + VC1_VLC_Two_Field_Ref_Ilace_MV_4, + VC1_VLC_Two_Field_Ref_Ilace_MV_5, + VC1_VLC_Two_Field_Ref_Ilace_MV_6, + VC1_VLC_Two_Field_Ref_Ilace_MV_7, +}; + +static IMG_UINT8 IntraTablePQIndexLT9[] = { + VC1_VLC_High_Rate_Intra_VLC, + VC1_VLC_High_Mot_Intra_VLC, + VC1_VLC_Mid_Rate_Intra_VLC, +}; + +static IMG_UINT8 InterTablePQIndexLT9[] = { + VC1_VLC_High_Rate_Inter_VLC, + VC1_VLC_High_Mot_Inter_VLC, + VC1_VLC_Mid_Rate_Inter_VLC, +}; + +static IMG_UINT8 IntraTablePQIndexGT8[] = { + VC1_VLC_Low_Mot_Intra_VLC, + VC1_VLC_High_Mot_Intra_VLC, + VC1_VLC_Mid_Rate_Intra_VLC, +}; + +static IMG_UINT8 InterTablePQIndexGT8[] = { + VC1_VLC_Low_Mot_Inter_VLC, + VC1_VLC_High_Mot_Inter_VLC, + VC1_VLC_Mid_Rate_Inter_VLC, +}; + +/* TODO: Make tables const, don't polute namespace */ +extern IMG_UINT16 gaui16vc1VlcTableData[]; +extern const IMG_UINT16 gui16vc1VlcTableSize; +extern IMG_UINT16 gaui16vc1VlcIndexData[VLC_INDEX_TABLE_SIZE][3]; +extern const IMG_UINT8 gui8vc1VlcIndexSize; + + +static IMG_UINT16 gaui16Inverse[] = {256, 128, 85, 64, 51, 43, 37, 32}; /* figure 66 */ +static IMG_BOOL gDMVRANGE_ExtHorizontal_RemapTable[]= {0, 1, 0, 1}; +static IMG_BOOL gDMVRANGE_ExtVertical_RemapTable[]= {0, 0, 1, 1}; +static IMG_BYTE gBFRACTION_DenRemapTable[] = {2,3,3,4,4,5,5,5,5,6,6,7,7,7,7,7,7,8,8,8,8,255,255}; +static IMG_BYTE gBFRACTION_NumRemapTable[] = {1,1,2,1,3,1,2,3,4,1,5,1,2,3,4,5,6,1,3,5,7,255,255}; + + +#define INIT_CONTEXT_VC1 context_VC1_p ctx = (context_VC1_p) obj_context->format_data; + +#define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) + + +static void pnw_VC1_QueryConfigAttributes( + VAProfile profile, + VAEntrypoint entrypoint, + VAConfigAttrib *attrib_list, + int num_attribs ) +{ + /* No VC1 specific attributes */ +} + +static VAStatus pnw_VC1_ValidateConfig( + object_config_p obj_config ) +{ + int i; + /* Check all attributes */ + for(i = 0; i < obj_config->attrib_count; i++) + { + switch (obj_config->attrib_list[i].type) + { + case VAConfigAttribRTFormat: + /* Ignore */ + break; + + default: + return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; + } + } + + return VA_STATUS_SUCCESS; +} + + +static void psb__VC1_pack_vlc_tables(uint16_t *vlc_packed_data, + uint16_t *gaui16vc1VlcTableData, + int gui16vc1VlcTableSize) +{ + int i, j; + /************************************************************************************/ + /* Pack the VLC tables into 32-bit format ready for DMA into 15-bit wide RAM. */ + /************************************************************************************/ + for (i = 0; i < gui16vc1VlcTableSize; i++) + { + j = i * 3; + vlc_packed_data[i] = 0; + /* opcode 14:12 *//* width 11:9 *//* symbol 8:0 */ + vlc_packed_data[i] = ((gaui16vc1VlcTableData[j + 0]) << 12) | + ((gaui16vc1VlcTableData[j + 1]) << 9) | + (gaui16vc1VlcTableData[j + 2]); + } +} + +static void psb__VC1_pack_index_table_info( uint32_t *packed_index_table, + uint16_t index_data[VLC_INDEX_TABLE_SIZE][3]) +{ + uint32_t start = 0, end = 0, length = 0, opcode = 0, width = 0; + int i; + + for (i=0; istart = %08x length = %08x (%d)\n", i, start*2, length*2, length*2); + + packed_index_table[i] = opcode; + packed_index_table[i] <<= 3; + packed_index_table[i] |= width; + packed_index_table[i] <<= 9; + packed_index_table[i] |= length; + packed_index_table[i] <<= 16; + packed_index_table[i] |= start; + } +} + +static VAStatus psb__VC1_check_legal_picture(object_context_p obj_context, object_config_p obj_config) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + + if (NULL == obj_context) + { + vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; + DEBUG_FAILURE; + return vaStatus; + } + + if (NULL == obj_config) + { + vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; + DEBUG_FAILURE; + return vaStatus; + } + + /* MSVDX decode capability for VC-1: + * SP@ML + * MP@HL + * AP@L3 + * + * Refer to Table 253 (Limitations of profiles and levels) of SMPTE-421M + */ + switch (obj_config->profile) + { + case VAProfileVC1Simple: + if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 352) + || (obj_context->picture_height <= 0) || (obj_context->picture_height > 288)) + { + vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; + } + break; + + case VAProfileVC1Main: + if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920) + || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088)) + { + vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; + } + break; + + case VAProfileVC1Advanced: + if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 2048) + || (obj_context->picture_height <= 0) || (obj_context->picture_height > 2048)) + { + vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; + } + break; + + default: + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + break; + } + + return vaStatus; +} + +static void pnw_VC1_DestroyContext(object_context_p obj_context); + +static VAStatus pnw_VC1_CreateContext( + object_context_p obj_context, + object_config_p obj_config ) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + context_VC1_p ctx; + /* Validate flag */ + /* Validate picture dimensions */ + vaStatus = psb__VC1_check_legal_picture(obj_context, obj_config); + if (VA_STATUS_SUCCESS != vaStatus) + { + DEBUG_FAILURE; + return vaStatus; + } + + ctx = (context_VC1_p) malloc(sizeof(struct context_VC1_s)); + if (NULL == ctx) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + return vaStatus; + } + memset(ctx, 0, sizeof(struct context_VC1_s)); + obj_context->format_data = (void*) ctx; + ctx->obj_context = obj_context; + ctx->pic_params = NULL; + + ctx->split_buffer_pending = FALSE; + + ctx->slice_param_list_size = 8; + ctx->slice_param_list = (object_buffer_p*) malloc(sizeof(object_buffer_p)*ctx->slice_param_list_size); + ctx->slice_param_list_idx = 0; + + if (NULL == ctx->slice_param_list) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + } + + ctx->colocated_buffers_size = obj_context->num_render_targets; + ctx->colocated_buffers_idx = 0; + ctx->colocated_buffers = (psb_buffer_p) malloc(sizeof(struct psb_buffer_s)*ctx->colocated_buffers_size); + if (NULL == ctx->colocated_buffers) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + } + + switch (obj_config->profile ) + { + case VAProfileVC1Simple: + ctx->profile = WMF_PROFILE_SIMPLE; + break; + + case VAProfileVC1Main: + ctx->profile = WMF_PROFILE_MAIN; + break; + + case VAProfileVC1Advanced: + ctx->profile = WMF_PROFILE_ADVANCED; + break; + + default: + ASSERT(0 == 1); + vaStatus = VA_STATUS_ERROR_UNKNOWN; + } + + // TODO + + if (vaStatus == VA_STATUS_SUCCESS) + { + vaStatus = psb_buffer_create( obj_context->driver_data, + PRELOAD_BUFFER_SIZE, + psb_bt_vpu_only, + &ctx->preload_buffer ); + DEBUG_FAILURE; + } + + if (vaStatus == VA_STATUS_SUCCESS) + { + void *preload; + if (0 == psb_buffer_map( &ctx->preload_buffer, &preload )) + { + memset(preload, 0, PRELOAD_BUFFER_SIZE); + psb_buffer_unmap( &ctx->preload_buffer ); + } + else + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + } + } + + if (vaStatus == VA_STATUS_SUCCESS) + { + vaStatus = psb_buffer_create( obj_context->driver_data, + AUXMSB_BUFFER_SIZE, + psb_bt_vpu_only, + &ctx->aux_msb_buffer ); + DEBUG_FAILURE; + } + + if (vaStatus == VA_STATUS_SUCCESS) + { + if(VC1_Header_Parser_HW) + { + vaStatus = psb_buffer_create( obj_context->driver_data, + 0xa000*3, //0x8800 + psb_bt_vpu_only, + &ctx->bitplane_hw_buffer ); + DEBUG_FAILURE; + } + else + { + vaStatus = psb_buffer_create( obj_context->driver_data, + 0x8000, + psb_bt_vpu_only, + &ctx->bitplane_hw_buffer ); + DEBUG_FAILURE; + } + + } + + if (vaStatus == VA_STATUS_SUCCESS) + { + vaStatus = psb_buffer_create( obj_context->driver_data, + (gui16vc1VlcTableSize * sizeof(IMG_UINT16) + 0xfff) & ~0xfff, + psb_bt_cpu_vpu, + &ctx->vlc_packed_table ); + DEBUG_FAILURE; + } + if (vaStatus == VA_STATUS_SUCCESS) + { + void *vlc_packed_data_address; + if (0 == psb_buffer_map( &ctx->vlc_packed_table, &vlc_packed_data_address )) + { + psb__VC1_pack_vlc_tables(vlc_packed_data_address, gaui16vc1VlcTableData, gui16vc1VlcTableSize); + psb_buffer_unmap( &ctx->vlc_packed_table ); + psb__VC1_pack_index_table_info( ctx->vlc_packed_index_table, gaui16vc1VlcIndexData); + } + else + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + } + } + + if (vaStatus != VA_STATUS_SUCCESS) + { + pnw_VC1_DestroyContext(obj_context); + } + + return vaStatus; +} + +static void pnw_VC1_DestroyContext( + object_context_p obj_context) +{ + INIT_CONTEXT_VC1 + int i; + + psb_buffer_destroy( &ctx->vlc_packed_table ); + psb_buffer_destroy( &ctx->aux_msb_buffer ); + psb_buffer_destroy( &ctx->preload_buffer ); + psb_buffer_destroy( &ctx->bitplane_hw_buffer ); + + if (ctx->pic_params) + { + free(ctx->pic_params); + ctx->pic_params = NULL; + } + + if (ctx->slice_param_list) + { + free(ctx->slice_param_list); + ctx->slice_param_list = NULL; + } + + if (ctx->colocated_buffers) + { + for (i = 0; i < ctx->colocated_buffers_idx; ++i) + psb_buffer_destroy(&(ctx->colocated_buffers[i])); + + free(ctx->colocated_buffers); + ctx->colocated_buffers = NULL; + } + + free(obj_context->format_data); + obj_context->format_data = NULL; +} + +static VAStatus psb__VC1_allocate_colocated_buffer(context_VC1_p ctx, object_surface_p obj_surface, uint32_t size){ + psb_surface_p surface = obj_surface->psb_surface; + + psb__information_message("pnw_VC1: Allocationg colocated buffer for surface %08x\n", surface); + + if (!GET_SURFACE_INFO_colocated_index(surface)) + { + VAStatus vaStatus; + psb_buffer_p buf; + int index = ctx->colocated_buffers_idx; + if (index >= ctx->colocated_buffers_size) + { + return VA_STATUS_ERROR_UNKNOWN; + } + buf = &(ctx->colocated_buffers[index]); + vaStatus = psb_buffer_create( ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf); + if (VA_STATUS_SUCCESS != vaStatus) + { + return vaStatus; + } + ctx->colocated_buffers_idx++; + SET_SURFACE_INFO_colocated_index(surface, index+1); /* 0 means unset, index is offset by 1 */ + } + return VA_STATUS_SUCCESS; +} + +static psb_buffer_p psb__VC1_lookup_colocated_buffer(context_VC1_p ctx, psb_surface_p surface) +{ + psb__information_message("pnw_VC1: Looking up colocated buffer for surface %08x\n", surface); + int index = GET_SURFACE_INFO_colocated_index(surface); + if (!index) + { + return NULL; + } + return &(ctx->colocated_buffers[index-1]); /* 0 means unset, index is offset by 1 */ +} + +static uint32_t psb__vc1_get_izz_scan_index(context_VC1_p ctx) +{ + if(ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) + { + // P_PICTURE_ADV_FRAME_INTERLACE + return 3; + } + if(PIC_TYPE_IS_INTRA(ctx->pic_params->picture_fields.bits.picture_type)) + { + // I-picture tables + return 4; + } + else + { + /* Assume P frame */ + if((ctx->profile == WMF_PROFILE_SIMPLE) || + (ctx->profile == WMF_PROFILE_MAIN) ) + { + // P-picture Simple/Main tables + return 0; + } + else /* Advanced profile */ + { + if(ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P) + { + // P-picture Advanced Progressive tables + return 1; + } + else /* Interlaced Field */ + { + // P-picture Advanced Field Interlaced tables + return 2; + } + } + } +} + + +#ifdef DEBUG_TRACE +#define psb__trace_message(...) + +#define P(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->x) +static void psb__VC1_trace_pic_params(VAPictureParameterBufferVC1 *p) +{ +#define P0(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->sequence_fields.bits.x) + P0(interlace); + P0(syncmarker); + P0(overlap); + + P(coded_width); + P(coded_height); + +#define P2(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->picture_fields.bits.x) + /* picture_fields */ + P2(picture_type); + P2(frame_coding_mode); + P2(top_field_first); + P2(is_first_field); + P2(intensity_compensation); + +#define P4(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->entrypoint_fields.bits.x) + P4(closed_entry); + P4(broken_link); + P4(loopfilter); + + P(conditional_overlap_flag); + P(fast_uvmc_flag); + +#define P3(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->range_mapping_fields.bits.x) + /* range_mapping_fields */ + P3(luma_flag); + P3(luma); + P3(chroma_flag); + P3(chroma); + + P(b_picture_fraction); + P(cbp_table); + P(mb_mode_table); + P(range_reduction_frame); + P(rounding_control); + P(post_processing); + P(picture_resolution_index); + P(luma_scale); + P(luma_shift); + + P(raw_coding.value); + P(bitplane_present.value); + +#define P4(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->reference_fields.bits.x) + P4(reference_distance_flag); + P4(reference_distance); + P4(num_reference_pictures); + P4(reference_field_pic_indicator); + +#define P5(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->mv_fields.bits.x) + P5(mv_mode); + P5(mv_mode2); + + P5(mv_table); + P5(two_mv_block_pattern_table); + P5(four_mv_switch); + P5(four_mv_block_pattern_table); + P5(extended_mv_flag); + P5(extended_mv_range); + P5(extended_dmv_flag); + P5(extended_dmv_range); + +#define P6(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->pic_quantizer_fields.bits.x) + + P6(dquant); + P6(quantizer); + P6(half_qp); + P6(pic_quantizer_scale); + P6(pic_quantizer_type); + P6(dq_frame); + P6(dq_profile); + P6(dq_sb_edge); + P6(dq_db_edge); + P6(dq_binary_level); + P6(alt_pic_quantizer); + +#define P7(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->transform_fields.bits.x) + + P7(variable_sized_transform_flag); + P7(mb_level_transform_type_flag); + P7(frame_level_transform_type); + P7(transform_ac_codingset_idx1); + P7(transform_ac_codingset_idx2); + P7(intra_transform_dc_table); +} +#endif + +static VAStatus psb__VC1_process_picture_param(context_VC1_p ctx, object_buffer_p obj_buffer) +{ + VAStatus vaStatus; + VAPictureParameterBufferVC1 *pic_params; + IMG_UINT8 ui8LumaScale1 = 0, ui8LumaShift1 = 0, ui8LumaScale2 = 0, ui8LumaShift2 = 0; + + ASSERT(obj_buffer->type == VAPictureParameterBufferType); + ASSERT(obj_buffer->num_elements == 1); + ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferVC1)); + + if ((obj_buffer->num_elements != 1) || + (obj_buffer->size != sizeof(VAPictureParameterBufferVC1))) + { + vaStatus = VA_STATUS_ERROR_UNKNOWN; + DEBUG_FAILURE; + return vaStatus; + } + + /* Transfer ownership of VAPictureParameterBufferVC1 data */ + pic_params = (VAPictureParameterBufferVC1 *) obj_buffer->buffer_data; + if (ctx->pic_params) + { + free(ctx->pic_params); + } + ctx->pic_params = pic_params; + obj_buffer->buffer_data = NULL; + obj_buffer->size = 0; + +#ifdef DEBUG_TRACE + psb__VC1_trace_pic_params(pic_params); +#endif + + if (pic_params->pic_quantizer_fields.bits.quantizer == 0) + { + /* Non uniform quantizer indicates PQINDEX > 8 */ + ctx->pqindex_gt8 = (pic_params->pic_quantizer_fields.bits.pic_quantizer_type == 0); + } + else + { + /* PQUANT (pic_quantizer_scale) == PQINDEX */ + ctx->pqindex_gt8 = (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale > 8); + } + + /* + * We decode to ctx->decoded_surface This is inloop target + * the out of loop decoded picture is stored in ctx->obj_context->current_render_target + */ + if (pic_params->inloop_decoded_picture == VA_INVALID_SURFACE) + { + /* No out of loop deblocking */ + ctx->decoded_surface = ctx->obj_context->current_render_target; + } + else + { + ctx->decoded_surface = SURFACE(pic_params->inloop_decoded_picture); + if (NULL == ctx->decoded_surface) + { + vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; + DEBUG_FAILURE; + return vaStatus; + } + } + /* Lookup surfaces for backward/forward references */ + ctx->forward_ref_surface = NULL; + ctx->backward_ref_surface = NULL; + if (pic_params->forward_reference_picture != VA_INVALID_SURFACE) + { + ctx->forward_ref_surface = SURFACE(pic_params->forward_reference_picture); + } + if (pic_params->backward_reference_picture != VA_INVALID_SURFACE) + { + ctx->backward_ref_surface = SURFACE(pic_params->backward_reference_picture); + } + +#if 0 + if (NULL == ctx->forward_ref_surface) + { + /* for mmu fault protection */ + ctx->forward_ref_surface = ctx->decoded_surface; + } + if (NULL == ctx->backward_ref_surface) + { + /* for mmu fault protection */ + ctx->backward_ref_surface = ctx->decoded_surface; + } +#endif + + psb__information_message("Target ref = %08x ID = %08x\n", ctx->obj_context->current_render_target->psb_surface, ctx->obj_context->current_render_target->surface_id); + psb__information_message("Decoded ref = %08x ID = %08x\n", ctx->decoded_surface->psb_surface, pic_params->inloop_decoded_picture); + psb__information_message("Forward ref = %08x ID = %08x\n", ctx->forward_ref_surface ? ctx->forward_ref_surface->psb_surface : 0, pic_params->forward_reference_picture); + psb__information_message("Backwrd ref = %08x ID = %08x\n", ctx->backward_ref_surface ? ctx->backward_ref_surface->psb_surface : 0, pic_params->backward_reference_picture); + + // NOTE: coded_width and coded_height do not have to be an exact multiple of MBs + + ctx->display_picture_width = pic_params->coded_width; + ctx->display_picture_height = pic_params->coded_height; + ctx->picture_width_mb = PIXELS_TO_MB(ctx->display_picture_width); + ctx->picture_height_mb = PIXELS_TO_MB(ctx->display_picture_height); + ctx->coded_picture_width = ctx->picture_width_mb * 16; + ctx->coded_picture_height = ctx->picture_height_mb * 16; + if ((WMF_PROFILE_ADVANCED == ctx->profile) && (VC1_FCM_FLDI == pic_params->picture_fields.bits.frame_coding_mode)) + { + ctx->picture_height_mb /= 2; + ctx->coded_picture_height = ctx->picture_height_mb * 16 * 2; + } + + ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; + + uint32_t colocated_size = ((ctx->size_mb + 1) * 2 + 128) * VC1_MB_PARAM_STRIDE; + //uint32_t colocated_size = (ctx->size_mb + 1) * 2 * VC1_MB_PARAM_STRIDE + 0x2000; + + vaStatus = psb__VC1_allocate_colocated_buffer(ctx, ctx->decoded_surface, colocated_size); + vaStatus = psb__VC1_allocate_colocated_buffer(ctx, ctx->obj_context->current_render_target, colocated_size); + + if (VA_STATUS_SUCCESS != vaStatus) + { + DEBUG_FAILURE; + return vaStatus; + } + + /* TODO: Store top_field_first and frame_coding_mode (or even all of pic_params) for the current frame + * so that it can be referenced when the same frame is used as reference frame + */ + + if (ctx->profile != WMF_PROFILE_ADVANCED) + { + /* Simple and Main profiles always use progressive pictures*/ + pic_params->picture_fields.bits.frame_coding_mode = VC1_FCM_P; + } + + if ((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI)) + { + pic_params->picture_fields.bits.top_field_first = 1; + } + + ctx->bitplane_present = 0; + switch(pic_params->picture_fields.bits.picture_type) + { + case WMF_PTYPE_I: + case WMF_PTYPE_BI: + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_overflags && !pic_params->raw_coding.flags.overflags) ? 0x04 : 0; + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_ac_pred && !pic_params->raw_coding.flags.ac_pred) ? 0x02 : 0; + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_field_tx && !pic_params->raw_coding.flags.field_tx) ? 0x01 : 0; + break; + + case WMF_PTYPE_P: + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_mv_type_mb && !pic_params->raw_coding.flags.mv_type_mb) ? 0x04 : 0; + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_skip_mb && !pic_params->raw_coding.flags.skip_mb) ? 0x02 : 0; + break; + + case WMF_PTYPE_B: /* B picture */ + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_forward_mb && !pic_params->raw_coding.flags.forward_mb) ? 0x04 : 0; + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_skip_mb && !pic_params->raw_coding.flags.skip_mb) ? 0x02 : 0; + ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_direct_mb && !pic_params->raw_coding.flags.direct_mb) ? 0x01 : 0; + break; + + default: + break; + } + psb__information_message("bitplane_present_flag = %02x raw_coding_flag = %02x bitplane_present = %02x\n", + pic_params->bitplane_present.value, pic_params->raw_coding.value, ctx->bitplane_present); + + if (pic_params->reference_fields.bits.reference_distance_flag == 0) + { + pic_params->reference_fields.bits.reference_distance = 0; + } + + /* conditional_overlap_flag is not always defined, but MSVDX expects it to be set in those cases anyway */ + if (ctx->profile == WMF_PROFILE_ADVANCED) + { + if (pic_params->sequence_fields.bits.overlap == FALSE) + { + ctx->condover = 0; /* No overlap smoothing */ + } + else if (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale < 9) + { + ctx->condover = pic_params->conditional_overlap_flag; + } + else + { + ctx->condover = 2; + } + } + else + { + if ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (pic_params->sequence_fields.bits.overlap == FALSE) || (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale < 9)) + { + ctx->condover = 0; /* No overlap smoothing */ + } + else + { + ctx->condover = 2; + } + } + + /************************** Calculate the IZZ scan index ****************************/ + ctx->scan_index = psb__vc1_get_izz_scan_index(ctx); + /************************************************************************************/ + + /**************************** Calculate MVMODE and MVMODE2 **************************/ + ctx->mv_mode = pic_params->mv_fields.bits.mv_mode; + if(ctx->mv_mode == WMF_MVMODE_INTENSITY_COMPENSATION) + { + ctx->mv_mode = pic_params->mv_fields.bits.mv_mode2; + } + + /* Neither MVMODE nor MVMODE2 are signaled at the picture level for interlaced frame pictures, + but MVMODE can be determine for P pictures depending on the value of MV4SWITCH, and for B + pictures it is by default 1MV mode. */ + if((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) && PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) + { + if((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && (pic_params->mv_fields.bits.four_mv_switch == 1)) + { + ctx->mv_mode = WMF_MVMODE_MIXED_MV; + pic_params->mv_fields.bits.mv_mode = WMF_MVMODE_MIXED_MV; + } + else + { + ctx->mv_mode = WMF_MVMODE_1MV; + pic_params->mv_fields.bits.mv_mode = WMF_MVMODE_1MV; + } + } + /************************************************************************************/ + + + /******************************** Calculate HALFPEL *********************************/ + if((ctx->mv_mode == WMF_MVMODE_1MV) || (ctx->mv_mode == WMF_MVMODE_MIXED_MV)) + { + ctx->half_pel = 0; + } + else + { + ctx->half_pel = 1; + } + /************************************************************************************/ + + /* TODO: Are we using the correct size for this ? */ + ctx->pull_back_x = COMPUTE_PULLBACK(pic_params->coded_width); + ctx->pull_back_y = COMPUTE_PULLBACK(pic_params->coded_height); + + if(pic_params->mv_fields.bits.extended_dmv_flag == 1) + { + ctx->extend_x = gDMVRANGE_ExtHorizontal_RemapTable[pic_params->mv_fields.bits.extended_dmv_range]; + ctx->extend_y = gDMVRANGE_ExtVertical_RemapTable[pic_params->mv_fields.bits.extended_dmv_range]; + } + else + { + ctx->extend_x = IMG_FALSE; + ctx->extend_y = IMG_FALSE; + } + + /* B interlaced field picture and ...?? */ + ctx->ui32ScaleFactor = 0; + ctx->i8FwrdRefFrmDist = 0; + ctx->i8BckwrdRefFrmDist = 0; + if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) + { + IMG_UINT32 ui32BFractionDen; + IMG_UINT32 ui32BFractionNum; + + IMG_UINT32 ui32FrameReciprocal; + + if (pic_params->b_picture_fraction > (sizeof(gBFRACTION_DenRemapTable) / sizeof(IMG_BYTE) - 1)) + pic_params->b_picture_fraction = sizeof(gBFRACTION_DenRemapTable) / sizeof(IMG_BYTE) - 1; + + ui32BFractionDen = gBFRACTION_DenRemapTable[pic_params->b_picture_fraction]; + ui32BFractionNum = gBFRACTION_NumRemapTable[pic_params->b_picture_fraction]; + + if (ui32BFractionDen > (sizeof(gaui16Inverse) / sizeof(IMG_UINT16))) + ui32BFractionDen = sizeof(gaui16Inverse) / sizeof(IMG_UINT16); + + if (ui32BFractionDen == 0) + { + psb__error_message("Invalid ui32BFractionDen value %d\n", ui32BFractionDen); + ui32BFractionDen = 1; + } + + ui32FrameReciprocal = gaui16Inverse[ui32BFractionDen - 1]; + ctx->ui32ScaleFactor = ui32BFractionNum * ui32FrameReciprocal; + + if(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) + { + ctx->i8FwrdRefFrmDist = (IMG_INT8)((ctx->ui32ScaleFactor * pic_params->reference_fields.bits.reference_distance) >> 8); /* 10.4.6.2 */ + ctx->i8BckwrdRefFrmDist = pic_params->reference_fields.bits.reference_distance - ctx->i8FwrdRefFrmDist - 1; + + if(ctx->i8BckwrdRefFrmDist < 0) + { + ctx->i8BckwrdRefFrmDist = 0; + } + } + } + + /* Compute the mode config parameter */ + /* + MODE_CONFIG[1:0] = + VC-1 intensity compensation flag, derived from MVMODE = Intensity compensation, and INTCOMPFIELD + 00 – No intensity compensation + 01 – Intensity compensation for top field + 10 – Intensity compensation for bottom field + 11 – Intensity compensation for the frame + + MODE_CONFIG[3:2] = + VC-1 reference range scaling, derived from RANGERED, RANGEREDFRM for current frame and reference frame. + 00 – No scaling + 01 – Scale down + 10 – Scale up + 11 – No scaling + */ + + /****************************** INTENSITY COMPENSATION ******************************/ + /* For each NEW reference frame, rotate IC history */ + if (PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) && + pic_params->picture_fields.bits.is_first_field && + (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) + { + /* + This is the first field picture of a new frame, so move the IC params for both field + pictures of the last frame (from position [1][0] for the first field and position [1][1] for + the second field to positions [0][0] and [0][1] respectevely). + */ + memcpy(&ctx->sICparams[0][0], &ctx->sICparams[1][0], sizeof(IC_PARAM)); + memcpy(&ctx->sICparams[0][1], &ctx->sICparams[1][1], sizeof(IC_PARAM)); + + memset(&ctx->sICparams[1][0], 0, sizeof(IC_PARAM)); + memset(&ctx->sICparams[1][1], 0, sizeof(IC_PARAM)); + } + + if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) + { + ctx->ui8CurrLumaScale1 = 0; + ctx->ui8CurrLumaShift1 = 0; + ctx->ui8CurrLumaScale2 = 0; + ctx->ui8CurrLumaShift2 = 0; + + if(pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FRMI) + { + if(pic_params->picture_fields.bits.intensity_compensation) + { + /* Intensity compensation of reference */ + if(pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) // progressive picture + { + ctx->mode_config = 0x3; + + ui8LumaScale1 = pic_params->luma_scale & 0x3F; + ui8LumaShift1 = pic_params->luma_shift & 0x3F; + + if(ui8LumaScale1 != 0 || ui8LumaShift1 != 0) + { + ctx->ui8CurrLumaScale1 = ui8LumaScale1; + ctx->ui8CurrLumaShift1 = ui8LumaShift1; + } + } + else // field interlaced picture + { + // top field + ui8LumaScale1 = pic_params->luma_scale & 0x3F; + ui8LumaShift1 = pic_params->luma_shift & 0x3F; + + // bottom field + ui8LumaScale2 = ui8LumaScale1; /* TODO: How to keep track of top/bottom field intensity comp? */ + ui8LumaShift2 = ui8LumaShift1; /* TODO: How to keep track of top/bottom field intensity comp? */ + + /* Check what fields undergo intensity compensation */ + ctx->ui8IntCompField = 0; + if(ui8LumaScale1 != 0 || ui8LumaShift1 != 0) + { + ctx->ui8IntCompField = 1; + } + if(ui8LumaScale2 != 0 || ui8LumaShift2 != 0) + { + ctx->ui8IntCompField |= 2; + } + + switch(ctx->ui8IntCompField) + { + case 0: /* none */ + ctx->mode_config = 0x0; + break; + + case 1: /* top */ + ctx->mode_config = 0x1; + + // IC parameters for top field + ctx->ui8CurrLumaScale1 = ui8LumaScale1; + ctx->ui8CurrLumaShift1 = ui8LumaShift1; + break; + + case 2: /* bottom */ + ctx->mode_config = 0x2; + + // IC parameters for bottom field + ctx->ui8CurrLumaScale2 = ui8LumaScale2; + ctx->ui8CurrLumaShift2 = ui8LumaShift2; + break; + + case 3: /* both */ + ctx->mode_config = 0x3; + + // IC parameters for top field + ctx->ui8CurrLumaScale1 = ui8LumaScale1; + ctx->ui8CurrLumaShift1 = ui8LumaShift1; + + // IC parameters for bottom field + ctx->ui8CurrLumaScale2 = ui8LumaScale2; + ctx->ui8CurrLumaShift2 = ui8LumaShift2; + break; + } + } + } + else + { + ctx->mode_config = 0; + } + } + else // interlaced frame P picture + { + if(pic_params->picture_fields.bits.intensity_compensation) /* iINSO */ + { + ctx->mode_config = 0x3; // intensity compensate whole frame + } + else + { + ctx->mode_config = 0; + } + } + } + else if(PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) + { + ctx->mode_config = 0; + } + + /* + 10.3.8 Intensity Compensation: + If intensity compensation is performed on a reference field, then after decoding the field, + the post-compensated pixel values shall be retained and shall be used when decoding the next + field. If the next field indicates that the field that was intensity compensated by the + previous field is to have intensity compensation performed again then the post-compensated + field shall be used. Therefore, when a reference field has intensity compensation performed + twice, the result of the first intensity compensation operation shall be used as input + for the second intensity compensation. + */ + /* + Don't forget point 9.1.1.4 in VC1 Spec: + + If the current frame, coded as two interlace field pictures, contains at least one P or B + field, and if this P or B field uses one or both field in another frame as a reference, where + the reference frame was also coded as a interlace field pictue, then the TFF of the current + frame and reference frame shall be the same. + */ + if((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) + { + if(pic_params->picture_fields.bits.top_field_first) // top field first + { + if(!pic_params->picture_fields.bits.is_first_field) // this is the second field picture (and bottom) + { + if(ctx->ui8IntCompField & 0x1) + { + /* The second and bottom field picture of the current frame + intensity compensates the top field of the current frame. */ + ctx->sICparams[1][0].ui8LumaScale1 = ui8LumaScale1; + ctx->sICparams[1][0].ui8LumaShift1 = ui8LumaShift1; + ctx->sICparams[1][0].ui8IC1 = 1; + } + if(ctx->ui8IntCompField & 0x2) + { + /* The second and bottom field picture of the current frame + intensity compensates the bottom field of the previous frame. */ + ctx->sICparams[0][1].ui8LumaScale2 = ui8LumaScale2; + ctx->sICparams[0][1].ui8LumaShift2 = ui8LumaShift2; + ctx->sICparams[0][1].ui8IC2 = 2; + } + } + else // first field picture (and top) + { + if(ctx->ui8IntCompField & 0x1) + { + /* The first and top field picture of the current frame + intensity compensates the top field of the previous frame. */ + ctx->sICparams[0][0].ui8LumaScale2 = ui8LumaScale1; + ctx->sICparams[0][0].ui8LumaShift2 = ui8LumaShift1; + ctx->sICparams[0][0].ui8IC2 = 1; + } + if(ctx->ui8IntCompField & 0x2) + { + /* The first and top field picture of the current frame + intensity compensates the bottom field of the previous frame. */ + ctx->sICparams[0][1].ui8LumaScale1 = ui8LumaScale2; + ctx->sICparams[0][1].ui8LumaShift1 = ui8LumaShift2; + ctx->sICparams[0][1].ui8IC1 = 2; + } + } + } + else // bottom field first + { + if(!pic_params->picture_fields.bits.is_first_field) // this is the second field picture (and top) + { + if(ctx->ui8IntCompField & 0x2) + { + /* The second and top field picture of the current frame + intensity compensates the bottom field of the current frame. */ + ctx->sICparams[1][1].ui8LumaScale1 = ui8LumaScale2; + ctx->sICparams[1][1].ui8LumaShift1 = ui8LumaShift2; + ctx->sICparams[1][1].ui8IC1 = 2; + } + if(ctx->ui8IntCompField & 0x1) + { + /* The second and top field picture of the current frame + intensity compensates the top field of the previous frame. */ + ctx->sICparams[0][0].ui8LumaScale2 = ui8LumaScale1; + ctx->sICparams[0][0].ui8LumaShift2 = ui8LumaShift1; + ctx->sICparams[0][0].ui8IC2 = 1; + } + } + else // first field picture (and bottom) + { + if(ctx->ui8IntCompField & 0x1) + { + /* The first and bottom field picture of the current frame + intensity compensates the top field of the previous frame. */ + ctx->sICparams[0][0].ui8LumaScale1 = ui8LumaScale1; + ctx->sICparams[0][0].ui8LumaShift1 = ui8LumaShift1; + ctx->sICparams[0][0].ui8IC1 = 1; + } + if(ctx->ui8IntCompField & 0x2) + { + /* The first and bottom field picture of the current frame + intensity compensates the bottom field of the previous frame. */ + ctx->sICparams[0][1].ui8LumaScale2 = ui8LumaScale2; + ctx->sICparams[0][1].ui8LumaShift2 = ui8LumaShift2; + ctx->sICparams[0][1].ui8IC2 = 2; + } + } + } + } + /************************************************************************************/ + + /********************************* RANGE REDUCTION **********************************/ + /* Determine the difference between the range reduction of current and reference picture */ + if(ctx->profile == WMF_PROFILE_MAIN) + { + /* Range Reduction is only enabled for Main Profile */ + /* The RANGEREDFRM values from the reference pictures are; + psVLDContext->bRef0RangeRed + psVLDContext->bRef1RangeRed */ + + switch(pic_params->picture_fields.bits.picture_type) + { + case WMF_PTYPE_I: + case WMF_PTYPE_BI: + /* no reference picture scaling */ + break; + + case WMF_PTYPE_P: /* P picture */ + /* + 8.3.4.11 also need to scale the previously reconstructed anchor frame prior to using it for MC if: + - RANGEREDFRM == 1 and ref RANGEREDFRM flag is not signalled scale down previous reconstructed frame. + - RANGEREDFRM == 0 and ref RANGEREDFRM flag is set scale up previous reconstructed frame. + */ + if(ctx->pic_params->range_reduction_frame && !ctx->bRef0RangeRed) + { + ctx->mode_config |= (0x1 << 2); // scale down previous reconstructed frame + } + else if(!ctx->pic_params->range_reduction_frame && ctx->bRef0RangeRed) + { + ctx->mode_config |= (0x2 << 2); // scale up previous reconstructed frame + } + else /* neither or both are set */ + { + ctx->mode_config |= (0x0 << 2); // no scaling of reference + } + break; + + case WMF_PTYPE_B: /* B picture */ + /* + 8.4.4.14 RANGEREDFRM shall be the same as for the temporally subsequent anchor frame (display order) + If this is set then the current decoded frame shall be scalled up similar to P frame. + Scaling for the temporally (display order) preceeding frame will be applied as for P frames + */ + if(ctx->bRef0RangeRed && !ctx->bRef1RangeRed) + { + ctx->mode_config |= (0x1 << 2); + } + else if(!ctx->bRef0RangeRed && ctx->bRef1RangeRed) + { + ctx->mode_config |= (0x2 << 2); + } + else /* neither or both are set */ + { + ctx->mode_config |= (0x0 << 2); // no scaling of reference + } + break; + + default: + break; + } + } + else + { + ctx->mode_config |= (0x0 << 2); + } + /************************************************************************************/ + + /********************************** Slice structure *********************************/ + if (VC1_FCM_FLDI == pic_params->picture_fields.bits.frame_coding_mode) + { + if ((pic_params->picture_fields.bits.top_field_first && pic_params->picture_fields.bits.is_first_field) || + (!pic_params->picture_fields.bits.top_field_first && !pic_params->picture_fields.bits.is_first_field)) + { + // Top field + ctx->slice_field_type = 0; + ctx->bottom_field = 0; + } + else + { + // Bottom field + ctx->slice_field_type = 1; + ctx->bottom_field = 1; + } + } + else + { + // progressive or interlaced frame + ctx->slice_field_type = 2; + ctx->bottom_field = 1; + } + /************************************************************************************/ + + /************************* FCM for the reference pictures ***************************/ + ctx->ui8FCM_Ref0Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; + ctx->ui8FCM_Ref1Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; + if(ctx->obj_context->frame_count == 0) + ctx->ui8FCM_Ref2Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; + + if(PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) || + ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) && /* The second B field picture in an */ + (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && /* interlaced field coded frame shall */ + !pic_params->picture_fields.bits.is_first_field)) /* reference the first field picture. */ + { + if(ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI && !pic_params->picture_fields.bits.is_first_field) + { + /* The current picture is the second field of the frame, then the previous field picture + is in the same frame. Therefore the FCM of the first field is the same as the FCM of the + current field and the first field will be reference 0. */ + ctx->ui8FCM_Ref0Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; + } + else if(ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI && pic_params->picture_fields.bits.is_first_field) + { + /* The current picture is the first field of the frame, then the previous field picture + is in a different frame and will be reference 1. */ + ctx->ui8FCM_Ref1Pic = ctx->ui8FCM_Ref2Pic; + } + else // progresive or interlaced frame picture + { + ctx->ui8FCM_Ref1Pic = ctx->ui8FCM_Ref2Pic; + } + } + /************************************************************************************/ + + /************************* TFF for the reference pictures ***************************/ + if(ctx->obj_context->frame_count == 0) + { + ctx->bTFF_FwRefFrm = pic_params->picture_fields.bits.top_field_first; + ctx->bTFF_BwRefFrm = pic_params->picture_fields.bits.top_field_first; + } + if(PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) && + ((ctx->pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) || + pic_params->picture_fields.bits.is_first_field)) + { + ctx->bTFF_FwRefFrm = ctx->bTFF_BwRefFrm; + } + /************************************************************************************/ + + return VA_STATUS_SUCCESS; +} + +static VAStatus psb__VC1_process_bitplane(context_VC1_p ctx, object_buffer_p obj_buffer) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + ASSERT(obj_buffer->type == VABitPlaneBufferType); + ASSERT(ctx->pic_params); + + if ((NULL == obj_buffer->psb_buffer) || + (0 == obj_buffer->size)) + { + /* We need to have data in the bitplane buffer */ + vaStatus = VA_STATUS_ERROR_UNKNOWN; + return vaStatus; + } + + ctx->bitplane_buffer = obj_buffer->psb_buffer; + ctx->has_bitplane = TRUE; + return vaStatus; +} + +/* + * Adds a VASliceParameterBuffer to the list of slice params + */ +static VAStatus psb__VC1_add_slice_param(context_VC1_p ctx, object_buffer_p obj_buffer) +{ + ASSERT(obj_buffer->type == VASliceParameterBufferType); + if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) + { + void *new_list; + ctx->slice_param_list_size += 8; + new_list = realloc(ctx->slice_param_list, + sizeof(object_buffer_p)*ctx->slice_param_list_size); + if (NULL == new_list) + { + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + ctx->slice_param_list = (object_buffer_p*) new_list; + } + ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer; + ctx->slice_param_list_idx++; + return VA_STATUS_SUCCESS; +} + + +/* + * This function extracts the information about a given table from the index of VLC tables. + */ +static void psb__VC1_extract_table_info(context_VC1_p ctx, sTableData *psInfo, int idx) +{ + IMG_UINT32 tmp; + + if (idx >= VLC_INDEX_TABLE_SIZE) + idx = VLC_INDEX_TABLE_SIZE - 1; + + tmp = ctx->vlc_packed_index_table[idx]; + psInfo->aui16StartLocation = (IMG_UINT16)(tmp & 0xffff); + psInfo->aui16VLCTableLength = (IMG_UINT16)((tmp >> 16) & 0x1ff); + psInfo->aui16InitialWidth = (IMG_UINT16)((tmp >> 25) & 0x7); + psInfo->aui16InitialOpcode = (IMG_UINT16)((tmp >> 28) & 0x3); +} + +/* + * This function selects the VLD tables from the picture layer parameters. + */ +static void psb__VC1_write_VLC_tables(context_VC1_p ctx) +{ + VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; + IMG_UINT16 ui16Table = 0, ui16IntraTable = 0, ui16InterTable = 0, aui16Table[3]; + IMG_UINT32 i, ui32TableNum = 0; + + /* select the required table from the n different types + A - vc1DEC_I_Picture_CBPCY_VLC (1) ¬ + B - vc1DEC_P_Picture_CBPCY_VLC_N (4) | + C - vc1DEC_Interlaced_CBPCY_N (8) | + D - vc1DEC_FourMV_Pattern_N (4) | + E - vc1DEC_INTERLACE_2_MVP_Pattern_N (4) | + F - vc1DEC_Mot_Vector_Diff_VLC_N (4) | MB Layer + G - vc1DEC_One_Field_Ref_Ilace_MV_N (4) | + H - vc1DEC_Two_Field_Ref_Ilace_MV_N (8) | + I - vc1DEC_Mixed_MV_MB_N (8) | + J - vc1DEC_One_MV_MB_N (8) | + K - vc1DEC_INTERLACE_4MV_MB_N (4) | + L - vc1DEC_INTERLACE_Non_4MV_MB_N (4) | + M - vc1DEC_X_Rate_TTMB (3) - + N - vc1DEC_X_Rate_TTBLK (3) ¬ + O - vc1DEC_X_Rate_SUBBLKPAT (3) | + P - vc1DEC_X_X_Inter_VLC (4) | Block Layer + Q - vc1DEC_X_X_Intra_VLC (4) | + R - vc1DEC_X_Mot_Luminance_DC_Diff_VLC (2) | + S - vc1DEC_X_Mot_Chroma_DC_Diff_VLC (2) - + + X - vc1DEC_Code_3x2_2x3_tiles (1) NOT USED */ + + /*! + *********************************************************************************** + @ Table A,B,C VLC CBPCY Tables + + [VC1] 7.1.3.1 Coded Block Pattern (CBPCY) (Variable size)[I, P,B] + + CBPCY is a variable-sized syntax element that shall be present in all + I and BI picture macroblocks, and may be present in P and B picture + macroblocks. In P and B pictures, CBPCY shall be decoded using + the VLC table specified by the CBPTAB syntax element as described in + section 7.1.1.39. The CBP tables for P and B pictures are listed in + section 11.6. + + + [VC1] 9.1.3.2 Coded Block Pattern (CBPCY) (Variable size)[I, P,B] + + Table 102: ICBPTAB code-table + + A vc1DEC_I_Picture_CBPCY_VLC (1) + B vc1DEC_P_Picture_CBPCY_VLC_N (4) + C vc1DEC_Interlaced_CBPCY_N (8) + + ***********************************************************************************/ + + if((!pic_params->sequence_fields.bits.interlace) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) + { + if(PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) + { + ui16Table = VC1_VLC_I_Picture_CBPCY_VLC; + } + else if(PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) + { + psb__bounds_check(pic_params->cbp_table, 4); + ui16Table = CBPCYTableProg[pic_params->cbp_table]; + } + } + else /* Interlaced */ + { + if(PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) + { + ui16Table = VC1_VLC_I_Picture_CBPCY_VLC; + } + else + { + psb__bounds_check(pic_params->cbp_table, 8); + ui16Table = CBPCYTableInterlaced[pic_params->cbp_table]; /* LUT */ + } + } + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); + ui32TableNum++; + + /*! + ************************************************************ + @ Table D VLC 4MV Pattern + + [VC1] Table 104: 4MVBP code-table + + Tables 116-119 + + D vc1DEC_FourMV_Pattern_N (4) + ************************************************************/ + psb__bounds_check(pic_params->mv_fields.bits.four_mv_block_pattern_table, 4); + ui16Table = FourMVTable[pic_params->mv_fields.bits.four_mv_block_pattern_table]; + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); + ui32TableNum++; + + /*! + ************************************************************************************ + @ Table E VLC 2MVBP Tables + + + Table 103: 2MVBP code-table + + for Tables 120-123 + + E vc1DEC_INTERLACE_2_MVP_Pattern_N (4) + ***********************************************************************************/ + psb__bounds_check(pic_params->mv_fields.bits.two_mv_block_pattern_table, 4); + ui16Table = Interlace2MVTable[pic_params->mv_fields.bits.two_mv_block_pattern_table]; + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); + ui32TableNum++; + + /*! + ************************************************************************************ + @ Table F,G,H VLC MV Tables + + [VC1] MVDATA Variable size vlclbf 7.1.3.8 + + 7.1.3.8 Motion Vector Data (MVDATA)(Variable size)[P] + + MVDATA is a variable sized syntax element that may be present in P picture + macroblocks. This syntax element decodes to the motion vector(s) for the + macroblock. The table used to decode this syntax element is specified by the + MVTAB syntax element in the picture layer as specified in section 7.1.1.38. + + F vc1DEC_Mot_Vector_Diff_VLC_N (4) + + [VC1] 9.1.1.34 INTERLACE Motion Vector Table (IMVTAB) (2 or 3 bits) + + Table 100: IMVTAB code-table for P INTERLACE field picture with NUMREF = 0, + and for P/B INTERLACE frame pictures + + IMVTAB Motion Vector Table + 00 1-Reference Table 0 + 01 1-Reference Table 1 + 10 1-Reference Table 2 + 11 1-Reference Table 3 + + Table 101: IMVTAB code-table for P INTERLACE field pictures with NUMREF = 1, + and for B INTERLACE field pictures + + IMVTAB Motion Vector Table + 000 2-Reference Table 0 + 001 2-Reference Table 1 + 010 2-Reference Table 2 + 011 2-Reference Table 3 + 100 2-Reference Table 4 + 101 2-Reference Table 5 + 110 2-Reference Table 6 + 111 2-Reference Table 7 + + G vc1DEC_One_Field_Ref_Ilace_MV_N (4) + H vc1DEC_Two_Field_Ref_Ilace_MV_N (8) + + ***********************************************************************************/ + if((!pic_params->sequence_fields.bits.interlace) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) + { + psb__bounds_check(pic_params->mv_fields.bits.mv_table, 4); + ui16Table = ProgressiveMVTable[pic_params->mv_fields.bits.mv_table]; + } + else + { + if( + ( + PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type) && + (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) + ) + || + ( + (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && + (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && + (pic_params->reference_fields.bits.num_reference_pictures == 0) + ) + ) + { + /* One field */ + psb__bounds_check(pic_params->mv_fields.bits.mv_table, 4); + ui16Table = Interlaced1RefMVTable[pic_params->mv_fields.bits.mv_table]; + } + else /*if (((FCM == VC1_FCM_FLDI) && (NUMREF == 0) && (PTYPE == WMF_PTYPE_P)) || ((PTYPE == WMF_PTYPE_B) && (FCM == VC1_FCM_FLDI))) */ + { + /* two field */ + psb__bounds_check(pic_params->mv_fields.bits.mv_table, 8); + ui16Table = MVTable2RefIlace[pic_params->mv_fields.bits.mv_table]; /* LUT */ + } + } + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); + ui32TableNum++; + + /*! + ************************************************************************************ + @ Table I,J,K,L VLC MBMODE Tables + + I vc1DEC_Mixed_MV_MB_N (8) + J vc1DEC_One_MV_MB_N (8) + K vc1DEC_INTERLACE_4MV_MB_N (4) + L vc1DEC_INTERLACE_Non_4MV_MB_N (4) + ***********************************************************************************/ + ui16Table = 0; + if(pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode > VC1_FCM_P)) + { + if(PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) + { + if(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) + { + psb__bounds_check(pic_params->mb_mode_table, 8); + /* 9.1.1.33 use MBMODETAB and MVMODE to select field interlaced tables */ + ui16Table = MBMODETableFLDI[pic_params->mb_mode_table][(pic_params->mv_fields.bits.mv_mode == WMF_MVMODE_MIXED_MV) ? 1 : 0]; + } + else if(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) + { + psb__bounds_check(pic_params->mb_mode_table, 4); + /* 9.1.1.33 use MBMODETAB and MV4SWITCH to select frame interlaced tables */ + ui16Table = MBMODETableFRMI[pic_params->mb_mode_table][(pic_params->mv_fields.bits.four_mv_switch) ? 0 : 1]; + } + } + } + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); + ui32TableNum++; + + /*! + ************************************************************************************ + @ Table M,N,O VLC PQUANT Tables + + [WMV9] 3.2.2.10 MB-level Transform Type (TTMB)(Variable size)[P,B] + [WMV9] 3.2.3.15 Block-level Transform Type (TTBLK)(Variable size)[inter] + + [WMV9] 3.2.3.16 Transform sub-block pattern (SUBBLKPAT)(Variable size)[inter] + + M vc1DEC_X_Rate_TTMB (3) + N vc1DEC_X_Rate_TTBLK (3) + O vc1DEC_X_Rate_SUBBLKPAT (3) + + TTBLK and TTMB P and B Pictures only + + ***********************************************************************************/ + aui16Table[0] = 0; aui16Table[1] = 0; aui16Table[2] = 0; + + if(pic_params->pic_quantizer_fields.bits.pic_quantizer_scale <= 4) /* high rate */ + { + aui16Table[2] = VC1_VLC_High_Rate_SUBBLKPAT; + aui16Table[1] = VC1_VLC_High_Rate_TTBLK; + aui16Table[0] = VC1_VLC_High_Rate_TTMB; + } + else if(pic_params->pic_quantizer_fields.bits.pic_quantizer_scale <= 12) /* med rate */ + { + aui16Table[2] = VC1_VLC_Medium_Rate_SUBBLKPAT; + aui16Table[1] = VC1_VLC_Medium_Rate_TTBLK; + aui16Table[0] = VC1_VLC_Medium_Rate_TTMB; + } + else /* low rate */ + { + aui16Table[2] = VC1_VLC_Low_Rate_SUBBLKPAT; + aui16Table[1] = VC1_VLC_Low_Rate_TTBLK; + aui16Table[0] = VC1_VLC_Low_Rate_TTMB; + } + + for(i=ui32TableNum; isTableInfo[i], aui16Table[i-ui32TableNum]); + } + + ui32TableNum = ui32TableNum+3; + + { + /*! + *********************************************************************************************** + Inter Coded Blocks + + Table 54: Index/Coding Set Correspondence for PQINDEX <= 7 + Y, Cb and Cr blocks + + Index Table + 0 High Rate Inter + 1 High Motion Inter + 2 Mid Rate Inter + + Table 55: Index/Coding Set Correspondence for PQINDEX > 7 + Y, Cb and Cr blocks + + Index Table + 0 Low Motion Inter + 1 High Motion Inter + 2 Mid Rate Inter + + ---------------------------------------------------------------------------------- + Intra Blocks + + 8 AC Coeff Coding Sets: + 4 x INTRA, 4 x INTER + + Y use Intra, CrCb use Inter + + Table 38: Coding Set Correspondence for PQINDEX <= 7 + + Y blocks Cb and Cr blocks + Index Table Index Table + 0 High Rate Intra 0 High Rate Inter + 1 High Motion Intra 1 High Motion Inter + 2 Mid Rate Intra 2 Mid Rate Inter + + Table 39: Coding Set Correspondence for PQINDEX > 7 + + Y blocks Cb and Cr blocks + Index Table Index Table + 0 Low Motion Intra 0 Low Motion Inter + 1 High Motion Intra 1 High Motion Inter + 2 Mid Rate Intra 2 Mid Rate Inter + + The value decoded from the DCTACFRM2 syntax element shall be used + as the coding set index for Y blocks and the value decoded from the + DCTACFRM syntax element shall be used as the coding set + index for Cb and Cr blocks. + + P vc1DEC_X_X_Inter_VLC + Q vc1DEC_X_X_Intra_VLC + + + for I pictures TRANSACFRM specifies the Inter Coding set + TRANSACFRM2 specifies the Intra Coding set + + for P pictures TRANSACFRM specifies Inter and Intra Coding set + + + ***************************************************************************************************/ + IMG_UINT32 ui32IntraCodingSetIndex = PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type) + ? pic_params->transform_fields.bits.transform_ac_codingset_idx2 + : pic_params->transform_fields.bits.transform_ac_codingset_idx1; + + IMG_UINT32 ui32InterCodingSetIndex = pic_params->transform_fields.bits.transform_ac_codingset_idx1; + + /* For PQINDEX < 9 the uniform quantizer should be used, as indicated by PQUANTIZER == 1 */ + if( !ctx->pqindex_gt8 ) + { + ui16IntraTable = IntraTablePQIndexLT9[ui32IntraCodingSetIndex]; + ui16InterTable = InterTablePQIndexLT9[ui32InterCodingSetIndex]; + } + else + { + ui16IntraTable = IntraTablePQIndexGT8[ui32IntraCodingSetIndex]; + ui16InterTable = InterTablePQIndexGT8[ui32InterCodingSetIndex]; + } + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16IntraTable); + ui32TableNum++; + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16InterTable); + ui32TableNum++; + } + + /*! + ************************************************************************************ + @ Table R & S VLC TRANSDCTAB Tables + + R vc1DEC_X_Mot_Luminance_DC_Diff_VLC (2) + S vc1DEC_X_Mot_Chroma_DC_Diff_VLC (2) + + [VC1] 8.1.1.2 Intra Transform DC Table + TRANSDCTAB is a one-bit syntax element that shall specify which of two + tables is used to decode the Transform DC coefficients in intra-coded blocks. + If TRANSDCTAB = 0, then the low motion table of Section 11.7 shall be used. + If TRANSDCTAB = 1, then the high motion table of Section 11.7 shall be used. + + [VC1] 8.1.1.2 Intra Transform DC Table + TRANSDCTAB is a one-bit syntax element that shall specify which of two + tables is used to decode the Transform DC coefficients in intra-coded blocks. + If TRANSDCTAB = 0, then the low motion table of Section 11.7 shall be used. + If TRANSDCTAB = 1, then the high motion table of Section 11.7 shall be used. + + ***********************************************************************************/ + if(pic_params->transform_fields.bits.intra_transform_dc_table == 0) + { + /* low motion */ + + /* VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC */ + ui16IntraTable = VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC; + + /* VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC */ + ui16InterTable = VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC; + } + else /* TRANSDCTAB == 1 */ + { + /* high motion */ + /* VC1_VLC_High_Mot_Luminance_DC_Diff_VLC */ + ui16IntraTable = VC1_VLC_High_Mot_Luminance_DC_Diff_VLC; + + /* VC1_VLC_High_Mot_Chroma_DC_Diff_VLC */ + ui16InterTable = VC1_VLC_High_Mot_Chroma_DC_Diff_VLC; + } + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16IntraTable); + ui32TableNum++; + + psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16InterTable); + ui32TableNum++; + + /* at the end determine how many tables have been chosen + this should be constant and equal 12 */ + ctx->ui32NumTables = ui32TableNum; + ASSERT(ctx->ui32NumTables == 12); +} + +static void psb__VC1_build_VLC_tables(context_VC1_p ctx) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + int i; + uint16_t RAM_location = 0; + uint32_t reg_value; + + for(i = 0; i < ctx->ui32NumTables; i++) + { + if (RAM_location & 0x03) + { + /* Align */ + RAM_location += 4 - (RAM_location & 0x03); + } + ctx->sTableInfo[i].aui16RAMLocation = RAM_location; + + /* VLC Table */ + /* Write a LLDMA Cmd to transfer VLD Table data */ + + psb_cmdbuf_lldma_write_cmdbuf( cmdbuf, &ctx->vlc_packed_table, + ctx->sTableInfo[i].aui16StartLocation * sizeof(IMG_UINT16), /* origin */ + ctx->sTableInfo[i].aui16VLCTableLength * sizeof(IMG_UINT16), /* size */ + RAM_location * sizeof(IMG_UINT32), /* destination */ + LLDMA_TYPE_VLC_TABLE ); +psb__information_message("table[%02d] start_loc = %08x RAM_location = %08x | %08x\n", i, ctx->sTableInfo[i].aui16StartLocation * sizeof(IMG_UINT16), RAM_location, RAM_location * sizeof(IMG_UINT32)); + RAM_location += ctx->sTableInfo[i].aui16VLCTableLength; + } + + /* Write the vec registers with the index data for each of the tables */ + psb_cmdbuf_reg_start_block( cmdbuf ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR0, ctx->sTableInfo[0].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR1, ctx->sTableInfo[1].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1, VLC_TABLE_ADDR2, ctx->sTableInfo[2].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1, VLC_TABLE_ADDR3, ctx->sTableInfo[3].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR4, ctx->sTableInfo[4].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR5, ctx->sTableInfo[5].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3, VLC_TABLE_ADDR6, ctx->sTableInfo[6].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3, VLC_TABLE_ADDR7, ctx->sTableInfo[7].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4, VLC_TABLE_ADDR8, ctx->sTableInfo[8].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4, VLC_TABLE_ADDR9, ctx->sTableInfo[9].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5, VLC_TABLE_ADDR10, ctx->sTableInfo[10].aui16RAMLocation ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5, VLC_TABLE_ADDR11, ctx->sTableInfo[11].aui16RAMLocation ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH0, ctx->sTableInfo[0].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH1, ctx->sTableInfo[1].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH2, ctx->sTableInfo[2].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH3, ctx->sTableInfo[3].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH4, ctx->sTableInfo[4].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH5, ctx->sTableInfo[5].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH6, ctx->sTableInfo[6].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH7, ctx->sTableInfo[7].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH8, ctx->sTableInfo[8].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH9, ctx->sTableInfo[9].aui16InitialWidth ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1, VLC_TABLE_INITIAL_WIDTH10, ctx->sTableInfo[10].aui16InitialWidth ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1, VLC_TABLE_INITIAL_WIDTH11, ctx->sTableInfo[11].aui16InitialWidth ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1), reg_value ); + + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE0, ctx->sTableInfo[0].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE1, ctx->sTableInfo[1].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE2, ctx->sTableInfo[2].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE3, ctx->sTableInfo[3].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE4, ctx->sTableInfo[4].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE5, ctx->sTableInfo[5].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE6, ctx->sTableInfo[6].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE7, ctx->sTableInfo[7].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE8, ctx->sTableInfo[8].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE9, ctx->sTableInfo[9].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE10, ctx->sTableInfo[10].aui16InitialOpcode ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE11, ctx->sTableInfo[11].aui16InitialOpcode ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0), reg_value ); + + psb_cmdbuf_reg_end_block( cmdbuf ); +} + + +static void psb__VC1_write_kick(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + (void) slice_param; /* Unused for now */ + + *cmdbuf->cmd_idx++ = CMD_COMPLETION; +} + +/* Programme the Alt output if there is a rotation*/ +static void psb__VC1_setup_alternative_frame( context_VC1_p ctx ) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + if(rotate_surface->extra_info[5] != obj_context->rotate) + psb__error_message("Display rotate mode does not match surface rotate mode!\n"); + + + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* Set the rotation registers */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + + psb_cmdbuf_rendec_write( cmdbuf, cmd ); + + psb_cmdbuf_rendec_end( cmdbuf ); +} + +static void psb__VC1_program_output_register(context_VC1_p ctx, IMG_BOOL first_two_pass) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + uint32_t alt_output_flags = 0; + uint32_t cmd; + *ctx->p_range_mapping_base = 0; + *ctx->p_range_mapping_base1 = 0; + //rotate_surface = ctx->decoded_surface->psb_surface_rotate; + + if((first_two_pass == 0) && (obj_context->rotate != VA_ROTATION_NONE) ) + { + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->chroma_offset + rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_end( cmdbuf ); + + //target_surface = rotate_surface; + + REGIO_WRITE_FIELD_LITE(alt_output_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(alt_output_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(alt_output_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(alt_output_flags, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + } + + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + psb_cmdbuf_rendec_write(cmdbuf, alt_output_flags); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64 ); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + psb_cmdbuf_rendec_end(cmdbuf); + *ctx->alt_output_flags = alt_output_flags; +} + +static void psb__VC1_send_rendec_params(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) +{ + VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p deblock_surface = ctx->decoded_surface->psb_surface; + psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; + uint32_t cmd; + IMG_UINT32 ui32MBParamMemOffset; + IMG_UINT8 ui8PrevLumaScale = 0, ui8PrevLumaShift = 0; + IMG_UINT8 ui8BackLumaScale = 0, ui8BackLumaShift = 0; + IMG_UINT8 ui8PrevBotLumaShift = 0, ui8PrevBotLumaScale = 0; + IMG_UINT8 ui8PrevIC = 0, ui8BackIC = 0, ui8PrevBotIC = 0; + + /* Align MB Parameter memory */ + ui32MBParamMemOffset = ((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && (!pic_params->picture_fields.bits.is_first_field)) ? + (ctx->size_mb * VC1_MB_PARAM_STRIDE) : 0; + ui32MBParamMemOffset += 0x00000fff; + ui32MBParamMemOffset &= 0xfffff000; + + /****************************** INTENSITY COMPENSATION ******************************/ + if(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) + { + if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) + { + if(pic_params->picture_fields.bits.top_field_first) // top field first + { + if(!pic_params->picture_fields.bits.is_first_field) // this is the second field picture (and bottom) + { + if(ctx->sICparams[0][1].ui8IC1 == 2) + { + /* The first and top field picture of the current frame + intensity compensates the bottom field of the previous frame. */ + ui8PrevLumaScale = ctx->sICparams[0][1].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][1].ui8LumaShift1; + ui8PrevIC = 2; + } + } + else // first field picture (and top) + { + if(ctx->sICparams[0][0].ui8IC1 == 1) + { + /* The second and bottom field picture of the previous frame + intensity compensates the top field of the previous frame. */ + ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; + ui8PrevIC = 1; + } + } + } + else // botom field first + { + if(!pic_params->picture_fields.bits.is_first_field) // this is the second field picture (and top) + { + if(ctx->sICparams[0][0].ui8IC1 == 1) + { + /* The first and bottom field picture of the current frame + intensity compensates the top field of the previous frame. */ + ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; + ui8PrevIC = 1; + } + } + else // first field picture (and bottom) + { + if(ctx->sICparams[0][1].ui8IC1 == 2) + { + /* The second and top field picture of the previous frame + intensity compensates the bottom field of the previous frame. */ + ui8PrevLumaScale = ctx->sICparams[0][1].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][1].ui8LumaShift1; + ui8PrevIC = 2; + } + } + } + } + else if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) + { + /* + First frame - second temporally closest reference frame to the B frame + Second frame - first temporally closest reference frame to the B frame + */ + if(pic_params->picture_fields.bits.top_field_first) // top field first + { + if(ctx->sICparams[0][0].ui8IC1 == 1) + { + /* The second and bottom field of the first reference frame intensity + compensates the first and top field of the first reference frame. */ + ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; + ui8PrevIC = 1; + } + if(ctx->sICparams[0][0].ui8IC2 == 1) + { + /* The first and top field of the second reference frame intensity + compensates the first and top field of the first reference frame. */ + ui8BackLumaScale = ctx->sICparams[0][0].ui8LumaScale2; + ui8BackLumaShift = ctx->sICparams[0][0].ui8LumaShift2; + ui8BackIC = 1; + } + if(ctx->sICparams[0][1].ui8IC2 == 2) + { + /* The first and top field of the second reference frame intensity + compensates the second and bottom field of the first reference frame. */ + ui8PrevBotLumaScale = ctx->sICparams[0][1].ui8LumaScale2; + ui8PrevBotLumaShift = ctx->sICparams[0][1].ui8LumaShift2; + ui8PrevBotIC = 2; + } + } + else // botom field first + { + if(ctx->sICparams[0][1].ui8IC1 == 2) + { + /* The second and top field of the first reference frame intensity + compensates the first and bottom field of the first reference frame. */ + ui8BackLumaScale = ctx->sICparams[0][1].ui8LumaScale1; + ui8BackLumaShift = ctx->sICparams[0][1].ui8LumaShift1; + ui8BackIC = 2; + } + if(ctx->sICparams[0][1].ui8IC2 == 2) + { + /* The first and bottom field of the second reference frame intensity + compensates the first and bottom field of the first reference frame. */ + ui8PrevBotLumaScale = ctx->sICparams[0][1].ui8LumaScale2; + ui8PrevBotLumaShift = ctx->sICparams[0][1].ui8LumaShift2; + ui8PrevBotIC = 2; + } + if(ctx->sICparams[0][0].ui8IC1 == 1) + { + /* The first and bottom field of the second reference frame intensity + compensates the second and top field of the first reference frame. */ + ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; + ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; + ui8PrevIC = 1; + } + } + } + } + /************************************************************************************/ + + /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ + +// if(ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not issue */ +// psb__VC1_setup_alternative_frame(ctx); + + /* CHUNK: 1 - VC1SEQUENCE00 */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); + *cmdbuf->rendec_chunk_start |= CMD_RENDEC_BLOCK_FLAG_VC1_CMD_PATCH; + + /* VC1SEQUENCE00 Command: Display Picture Size (sequence) */ + cmd = 0; + /* TODO: Can "display size" and "coded size" be different? */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_HEIGHT, (ctx->display_picture_height - 1)); /* display picture size - 1 */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_WIDTH, (ctx->display_picture_width - 1)); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* VC1SEQUENCE00 Command: Coded Picture Size (sequence) */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_HEIGHT, (ctx->coded_picture_height - 1)); /* coded picture size - 1 */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_WIDTH, (ctx->coded_picture_width - 1)); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* VC1SEQUENCE01 Command: Operating Mode (sequence) */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CHROMA_INTERLEAVED, 0); /* 0 = CbCr - MSVDX default */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, ROW_STRIDE, target_surface->stride_mode); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CODEC_MODE, 2); /* MODE_VC1 */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CODEC_PROFILE, ctx->profile); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, ASYNC_MODE, 0/*((pPicParams->bPicDeblocked & 0x02) ? 0:1)*/); // @TODO: async mode should be synchronous or pre-load for VC1 + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CHROMA_FORMAT, 1); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, INTERLACED, ((pic_params->picture_fields.bits.frame_coding_mode & 0x02) >> 1)); /* if progressive, INTERLACE is always 0 */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, VC1_OVERLAP, pic_params->sequence_fields.bits.overlap); + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, PIC_CONDOVER, ctx->condover); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, PIC_QUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); + } + ctx->obj_context->operating_mode = cmd; + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ + psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); + //psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs); + + /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ + psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + //psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset); + + /* Aux MSB buffer */ + psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->aux_msb_buffer, 0); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* CHUNK: 2 - VC1SLICE00 */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, MC_CACHE_CONFIGURATION) ); + + /* VC1SLICE00 Command: Cache Configuration (picture?) */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE00, CONFIG_REF_OFFSET, 72); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE00, CONFIG_ROW_OFFSET, 4); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* VC1SLICE01 Command: VC1 Intensity Compensation Parameter (picture or slice) */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSHIFT2, ctx->ui8CurrLumaShift2); /* INTERLACE field P pictures */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSCALE2, ctx->ui8CurrLumaScale2); /* INTERLACE field P pictures */ + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSHIFT1, ctx->ui8CurrLumaShift1); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSCALE1, ctx->ui8CurrLumaScale1); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + psb_cmdbuf_rendec_end( cmdbuf ); + + psb__VC1_program_output_register(ctx, ctx->pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_P); + + if( ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P && ctx->obj_context->rotate != VA_ROTATION_NONE) + //deblock_surface = ctx->decoded_surface->psb_surface_rotate; + deblock_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + + /* CHUNK: 3 */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + /* VC1 Luma Range Mapping Base Address */ + //psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs); + + /* VC1 Chroma Range Mapping Base Address */ + //psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->chroma_offset + target_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->chroma_offset + deblock_surface->buf.buffer_ofs); + + /* VC1SLICE03 Range Map Control (current picture) */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPUV_FLAG, pic_params->range_mapping_fields.bits.chroma_flag /*RANGE_MAPUV_FLAG*/); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPUV, pic_params->range_mapping_fields.bits.chroma); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPY_FLAG, pic_params->range_mapping_fields.bits.luma_flag /*RANGE_MAPY_FLAG*/); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPY, pic_params->range_mapping_fields.bits.luma); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* Store VC1SLICE03 bits in lower bits of Range Mapping Base Address */ + /* VC1 Luma Range Mapping Base Address */ + RELOC(*ctx->p_range_mapping_base, /*cmd + */deblock_surface->buf.buffer_ofs, &deblock_surface->buf); + RELOC(*ctx->p_range_mapping_base1, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset, &deblock_surface->buf); + //RELOC(*ctx->p_range_mapping_base, /*cmd + */target_surface->buf.buffer_ofs, &target_surface->buf); + //RELOC(*ctx->p_range_mapping_base1, target_surface->buf.buffer_ofs + target_surface->chroma_offset, &target_surface->buf); + *ctx->p_range_mapping_base = (*ctx->p_range_mapping_base) | cmd; /* FIXME If kernel apply reloc, this value may be override */ + + /* VC1 Intensity Compensation Backward/Previous */ + /* + 3.3.10 VC1 Intensity Compensation Backward/Previous: + The parameters applied in VC1 Intensity Compensation Parameters are the Intensity Compensation + applied to forward prediction. In the case of Interlaced P field pictures, the second field can + be Intensity Compensated relative to the first P field picture. If this is done, when decoding + B pictures the first field backward MV reference to P picture needs to be Intensity Compensated + with VC1_LUMSCALE_BACK and VC1_LUMSHIFT_BACK. (The command should contain the Intensity + Compensation parameters that were used for opposite parity field when decoding 2nd P field picture). + + The parameters will only be used if VC1_BACK_INT_COMP in Slice Params command indicates + Backward Intensity Compensation is used. + */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSHIFT_PREV, ui8PrevLumaShift); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSCALE_PREV, ui8PrevLumaScale); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSHIFT_BACK, ui8BackLumaShift); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSCALE_BACK, ui8BackLumaScale); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + +#if 0 + /* VC1 Intensity Compensation Previous Bottom */ + if(ui8PrevBotIC) + { + /* + The VDMC dynamically applies intensity compensation when generating reference predicted data + for P/B fields/frames. In the case of Interlaced B field pictures, both the top field and + bottom field could be Intensity Compensated twice (if all previous P field pictures applied + separate top and bottom Intensity Compensation). If this is the case, the VC1 previous field + defined in 3.3.10 should apply to top field, whilst the parameters defined in this register + apply to the bottom field. The VC1_PREV_BOT_INT_COMP field of Slice Params command indicates + if the fields in this register are used. + */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_, VC1_LUMSHIFT_PREV_BOT, ui8PrevBotLumaShift); + REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_, VC1_LUMSCALE_PREV_BOT, ui8PrevBotLumaScale); + pcmdBuffer[i++] = REGISTER_OFFSET(MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_); + pcmdBuffer[i++] = cmd; + } +#endif + psb_cmdbuf_rendec_end( cmdbuf ); + + /* + Reference Picture Base Addresses + + The reference picture pointers always include the current picture at first location (0) and + the oldest reference in the next location (1). For B pictures the subsequent reference + frame (display order) is 2. + */ + if((pic_params->picture_fields.bits.picture_type != WMF_PTYPE_I) && (pic_params->picture_fields.bits.picture_type != WMF_PTYPE_BI)) + { + /* CHUNK: 4 */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) ); + + /********************** CURRENT PICTURE **********************/ + psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); + //psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs); + //psb_cmdbuf_rendec_write_address( cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset); + + /*************** FORWARD REFERENCE *****************/ + if(ctx->forward_ref_surface) + { + /* + In VC1, if a P field picture references both top field and bottom field, but the two fields + are stored in different frame stores, then the most recently decoded field will use reference + index 0, and the other field will use reference index 1. + + Progressive P pictures use always reference index 1. + */ + psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->\ + buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset); + } + + /*************** BACKWARD REFERENCE *****************/ + if (ctx->backward_ref_surface) + { + psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface\ + ->buf.buffer_ofs + ctx->backward_ref_surface->psb_surface->chroma_offset); + } + psb_cmdbuf_rendec_end( cmdbuf ); + } + + /* CHUNK: 5 - VC1SLICE02 */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS) ); + *cmdbuf->rendec_chunk_start |= CMD_RENDEC_BLOCK_FLAG_VC1_SP_PATCH; + + /* VC1SLICE02 Command: Slice Params (picture or slice) */ + cmd = 0; + + //REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, VC1_PREV_BOT_INT_COMP, ui8PrevBotIC); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_PREV_INT_COMP, ui8PrevIC); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_BACK_INT_COMP, ui8BackIC); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, RND_CTRL_BIT, pic_params->rounding_control); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, MODE_CONFIG, ctx->mode_config); + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SUBPEL_FILTER_MODE, ((ctx->mv_mode == WMF_MVMODE_1MV_HALF_PEL_BILINEAR) && !(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI)) ? 0:1); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SLICE_CODE_TYPE, (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_BI) ? 0 : (pic_params->picture_fields.bits.picture_type & 0x3)); /* BI is sent as I */ + } + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_FASTUVMC, pic_params->fast_uvmc_flag); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_LOOPFILTER, pic_params->entrypoint_fields.bits.loopfilter); + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SLICE_FIELD_TYPE, ctx->slice_field_type); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + psb_cmdbuf_rendec_end( cmdbuf ); + if(VC1_Header_Parser_HW) + REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SLICE_CODE_TYPE, (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_BI) ? 0 : (pic_params->picture_fields.bits.picture_type & 0x3)); + + *ctx->p_slice_params = cmd; + + /* ------------------------------- Back-End Registers --------------------------------- */ + + /* CHUNK: 6 (Back-end registers) */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_SPS0) ); + + /* CR_VEC_VC1_BE_SPS0 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_EXTENDED_DMV, pic_params->mv_fields.bits.extended_dmv_flag); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_EXTENDED_MV, pic_params->mv_fields.bits.extended_mv_flag); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_FASTUVMC, pic_params->fast_uvmc_flag); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_INTERLACE, pic_params->sequence_fields.bits.interlace); + //REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_PROFILE, ctx->profile); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_SPS1 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS1, VC1_BE_PIC_HEIGHT_IN_MBS_LESS1, ctx->picture_height_mb - 1); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_SPS2 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS2, VC1_BE_PIC_WIDTH_IN_MBS_LESS1, ctx->picture_width_mb - 1); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* CHUNK: 6b (Back-end registers) */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_PPS2) ); + *cmdbuf->rendec_chunk_start |= CMD_RENDEC_BLOCK_FLAG_VC1_BE_PATCH; + + /* CR_VEC_VC1_BE_PPS2 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF2, ctx->ui8FCM_Ref2Pic); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF1, ctx->ui8FCM_Ref1Pic); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF0, ctx->ui8FCM_Ref0Pic); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_COLLOCATED_SKIPPED, 0); // @TODO: Really need this? + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_PPS0 */ + cmd = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_IQ_OVERLAP, ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (ctx->condover == 0)) ? 0 : 1); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_UNIFORM_QUANTIZER, pic_params->pic_quantizer_fields.bits.pic_quantizer_type); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_HALFQP, pic_params->pic_quantizer_fields.bits.half_qp); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_BFRACTION, pic_params->b_picture_fraction); + } + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF_FWD, ctx->bTFF_FwRefFrm); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF_BWD, ctx->bTFF_BwRefFrm); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF, pic_params->picture_fields.bits.top_field_first); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_SECOND_FIELD, !pic_params->picture_fields.bits.is_first_field); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_FCM, pic_params->picture_fields.bits.frame_coding_mode); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_RNDCTRL, pic_params->rounding_control); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_PPS1 */ + cmd = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_EXTEND_Y, ctx->extend_y); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_EXTEND_X, ctx->extend_x); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_QUANTIZER, (pic_params->pic_quantizer_fields.bits.pic_quantizer_type ? 0x03 /* uniform */ : 0x02 /* non-uniform */)); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_PQUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_MVMODE, pic_params->mv_fields.bits.mv_mode); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_MVMODE2, pic_params->mv_fields.bits.mv_mode2); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_PTYPE, pic_params->picture_fields.bits.picture_type); + } + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD0 */ + cmd = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD0, VC1_BE_BRPD, ctx->i8BckwrdRefFrmDist); /* 10.4.6.2 */ + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD0, VC1_BE_FRPD, ctx->i8FwrdRefFrmDist); + } + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD1 */ + cmd = 0; + if(!VC1_Header_Parser_HW) + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD1, VC1_BE_SCALEFACTOR, ctx->ui32ScaleFactor); /* figure 66 */ + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD2 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD2, VC1_BE_PULLBACK_X, ctx->pull_back_x); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD3 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD3, VC1_BE_PULLBACK_Y, ctx->pull_back_y); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD4 */ + cmd = 0; + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD4, VC1_BE_FIRST_MB_IN_SLICE_Y, slice_param->slice_vertical_position); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + /* CR_VEC_VC1_BE_MVD5 */ + cmd = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_REFDIST, pic_params->reference_fields.bits.reference_distance); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_NUMREF, pic_params->reference_fields.bits.num_reference_pictures); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_REFFIELD, pic_params->reference_fields.bits.reference_field_pic_indicator); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_MVRANGE, pic_params->mv_fields.bits.extended_mv_range); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_HALFPEL_FLAG, ctx->half_pel); + } + //REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_FRAME_CODING_MODE, pic_params->picture_fields.bits.frame_coding_mode); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_BOTTOM_FIELD_FLAG, ctx->bottom_field); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_ADVANCED_PROFILE, (ctx->profile == WMF_PROFILE_ADVANCED) ? 1:0); + REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_SCAN_INDEX, ctx->scan_index); + psb_cmdbuf_rendec_write(cmdbuf, cmd); + + psb_cmdbuf_rendec_end( cmdbuf ); + + /* CHUNK: 6c (Back-end registers) */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_PARAM_BASE_ADDR) ); + + psb__information_message("pnw_VC1: picture_type = %d\n", pic_params->picture_fields.bits.picture_type); + + if(PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type) || (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P)) + { + psb_buffer_p colocated_target_buffer = psb__VC1_lookup_colocated_buffer(ctx, target_surface); + ASSERT(colocated_target_buffer); + if (colocated_target_buffer) + { + psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, ui32MBParamMemOffset); + } + else + { + /* This is an error */ + psb_cmdbuf_rendec_write(cmdbuf, 0); + } + } + else if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) + { + ASSERT(ctx->forward_ref_surface); + psb_buffer_p colocated_forward_ref_buffer = ctx->forward_ref_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface) : 0; + ASSERT(colocated_forward_ref_buffer); + if (colocated_forward_ref_buffer) + { + psb_cmdbuf_rendec_write_address(cmdbuf, colocated_forward_ref_buffer, ui32MBParamMemOffset); + } + else + { + /* This is an error */ + psb_cmdbuf_rendec_write(cmdbuf, 0); + } + } + psb_cmdbuf_rendec_end( cmdbuf ); + + if(!PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) + { + /* CHUNK: 6d (Back-end registers) */ + psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_COLPARAM_BASE_ADDR) ); + + if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) + { + /* CR_VEC_VC1_BE_COLPARAM_BASE_ADDR */ + ASSERT(ctx->forward_ref_surface); + psb_buffer_p colocated_forward_ref_buffer = ctx->forward_ref_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface) : NULL; + ASSERT(colocated_forward_ref_buffer); + if (colocated_forward_ref_buffer) + { + psb_cmdbuf_rendec_write_address(cmdbuf, colocated_forward_ref_buffer, ui32MBParamMemOffset); + } + else + { + /* This is an error */ + psb_cmdbuf_rendec_write(cmdbuf, 0); + } + } + else if(pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) + { + /* CR_VEC_VC1_BE_COLPARAM_BASE_ADDR */ + ASSERT(ctx->backward_ref_surface); + psb_buffer_p colocated_backward_ref_buffer; + + if (NULL == ctx->backward_ref_surface) + { + psb__error_message("%s L%d Invalid backward_ref_surface handle\n", __FUNCTION__, __LINE__); + return; + } + + colocated_backward_ref_buffer = ctx->backward_ref_surface->psb_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->backward_ref_surface->psb_surface) : NULL; + ASSERT(colocated_backward_ref_buffer); + if (colocated_backward_ref_buffer) + { + psb_cmdbuf_rendec_write_address(cmdbuf, colocated_backward_ref_buffer, ui32MBParamMemOffset); + } + else + { + /* This is an error */ + psb_cmdbuf_rendec_write(cmdbuf, 0); + } + } + + psb_cmdbuf_rendec_end( cmdbuf ); + } + + /* psb_cmdbuf_rendec_end_block( cmdbuf ); */ +} + + +static void psb__VC1_load_sequence_registers(context_VC1_p ctx) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + uint32_t reg_value; + + psb_cmdbuf_reg_start_block( cmdbuf ); + + /* FE_CONTROL */ + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_PROFILE, ctx->profile); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 2); /* 2 - VC1 */ + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), reg_value ); + + /* FE_SPS0 */ + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_SYNCMARKER, ctx->pic_params->sequence_fields.bits.syncmarker ); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_VSTRANSFORM, ctx->pic_params->transform_fields.bits.variable_sized_transform_flag); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_INTERLACE, ctx->pic_params->sequence_fields.bits.interlace ); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0), reg_value ); + + psb_cmdbuf_reg_end_block( cmdbuf ); + +} + +static void psb__VC1_load_picture_registers(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) +{ + VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + uint32_t reg_value; + int bEnableMVDLite = FALSE; + + psb_cmdbuf_rendec_start( cmdbuf, REG_MSVDX_VEC_OFFSET + MSVDX_VEC_CR_VEC_ENTDEC_BE_CONTROL_OFFSET ); + reg_value = 0; + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile); + REGIO_WRITE_FIELD( reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 2); /* 2 - VC1 */ + psb_cmdbuf_rendec_write( cmdbuf, reg_value ); + psb_cmdbuf_rendec_end( cmdbuf ); + + psb_cmdbuf_reg_start_block_flag( cmdbuf, (VC1_Header_Parser_HW) ? CMD_REGVALPAIR_FLAG_VC1PATCH : 0); + + /* Enable MVD lite for Progressive or FLDI P */ + if( + ( + (pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) || + (!pic_params->sequence_fields.bits.interlace) || + (pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) + ) && + (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) + ) + { + bEnableMVDLite = TRUE; + } + + /* FE_PPS0 */ + reg_value = 0; + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PIC_WIDTH_IN_MBS_LESS1, ctx->picture_width_mb - 1); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PIC_HEIGHT_IN_MBS_LESS1, ctx->picture_height_mb - 1); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_FIRST_MB_IN_SLICE_Y, slice_param->slice_vertical_position); + if(!VC1_Header_Parser_HW) + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PTYPE, pic_params->picture_fields.bits.picture_type); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_FCM, pic_params->picture_fields.bits.frame_coding_mode); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0), reg_value ); + + /* FE_PPS1 */ + reg_value = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BP_FORMAT, IMG_FALSE); // interleaved format + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BP_PRESENT, ctx->bitplane_present); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_RAWCODINGFLAG, (pic_params->raw_coding.value & 0x7F)); // 7-bits + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_MVMODE, pic_params->mv_fields.bits.mv_mode); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_MVMODE2, pic_params->mv_fields.bits.mv_mode2); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_TTMBF, pic_params->transform_fields.bits.mb_level_transform_type_flag); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_TTFRM, pic_params->transform_fields.bits.frame_level_transform_type); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BFRACTION, pic_params->b_picture_fraction); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_CONDOVER, ctx->condover); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_EXTEND_X, ctx->extend_x); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_EXTEND_Y, ctx->extend_y); + } + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1), reg_value ); + + /* FE_PPS2 */ + reg_value = 0; + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQXBEDGE, (pic_params->pic_quantizer_fields.bits.dq_profile == 1) ? pic_params->pic_quantizer_fields.bits.dq_db_edge : pic_params->pic_quantizer_fields.bits.dq_sb_edge); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANT, pic_params->pic_quantizer_fields.bits.dquant); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_PQUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_HALFQP, pic_params->pic_quantizer_fields.bits.half_qp); + if (((ctx->profile == WMF_PROFILE_ADVANCED) && (pic_params->pic_quantizer_fields.bits.dquant != 0)) + || ((ctx->profile != WMF_PROFILE_ADVANCED) && ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P))) && (pic_params->pic_quantizer_fields.bits.dquant != 0)) + { + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_VOPDQUANT_PRESENT, 1); + } + else + { + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_VOPDQUANT_PRESENT, 0); + } + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANTFRM, pic_params->pic_quantizer_fields.bits.dq_frame); + { + IMG_BOOL DQUANT_INFRAME = (pic_params->pic_quantizer_fields.bits.dquant == 2) || + ((pic_params->pic_quantizer_fields.bits.dquant == 1) && pic_params->pic_quantizer_fields.bits.dq_frame) || + ((pic_params->pic_quantizer_fields.bits.dquant == 3) && pic_params->pic_quantizer_fields.bits.dq_frame); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANT_INFRAME, DQUANT_INFRAME); + } + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_ALTPQUANT, pic_params->pic_quantizer_fields.bits.alt_pic_quantizer); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQPROFILE, pic_params->pic_quantizer_fields.bits.dq_profile); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQBILEVEL, pic_params->pic_quantizer_fields.bits.dq_binary_level); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_PQINDEX_GT8, ctx->pqindex_gt8 ); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_TRANSACFRM, pic_params->transform_fields.bits.transform_ac_codingset_idx1); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_TRANSACFRM2, pic_params->transform_fields.bits.transform_ac_codingset_idx2); + } + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANT, pic_params->pic_quantizer_fields.bits.dquant); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2), reg_value ); + + /* MVD_LITE0 */ + reg_value = 0; + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_MVD_LITE_ENABLE, bEnableMVDLite); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_PULLBACK_X, ctx->pull_back_x); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_PULLBACK_Y, ctx->pull_back_y); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0), reg_value ); + + /* MVD_LITE1 */ + reg_value = 0; + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_TFF, pic_params->picture_fields.bits.top_field_first); + if(!VC1_Header_Parser_HW) + { + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_REFDIST, pic_params->reference_fields.bits.reference_distance); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_NUMREF, pic_params->reference_fields.bits.num_reference_pictures); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_REFFIELD, pic_params->reference_fields.bits.reference_field_pic_indicator); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_MVRANGE, pic_params->mv_fields.bits.extended_mv_range); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_HALFPEL_FLAG, ctx->half_pel); + //REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_FRAME_CODING_MODE, pic_params->picture_fields.bits.frame_coding_mode); + } + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_BOTTOM_FIELD_FLAG, ctx->bottom_field); + REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_ADVANCED_PROFILE, (ctx->profile == WMF_PROFILE_ADVANCED) ? 1:0); + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1), reg_value ); + + psb_cmdbuf_reg_end_block( cmdbuf ); +} + +static void psb__VC1_setup_bitplane(context_VC1_p ctx) +{ + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + psb_cmdbuf_reg_start_block( cmdbuf ); + + if(VC1_Header_Parser_HW) + { + psb_cmdbuf_reg_set_address( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR0), + &ctx->bitplane_hw_buffer, 0); + psb_cmdbuf_reg_set_address( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR1), + &ctx->bitplane_hw_buffer, 0xa000); + psb_cmdbuf_reg_set_address( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR2), + &ctx->bitplane_hw_buffer, 0xa000 * 2); + } + else + { + if (ctx->bitplane_present) + psb_cmdbuf_reg_set_address( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR0), + ctx->bitplane_buffer, 0); + else + psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR0), 0); + } + psb_cmdbuf_reg_end_block( cmdbuf ); +} + +//static void psb__VC1_FE_state(context_VC1_p ctx) +//{ +// uint32_t lldma_record_offset; +// psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; +// psb_surface_p deblock_surface = ctx->decoded_surface->psb_surface; + + /* See RENDER_BUFFER_HEADER */ +// *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + +// ctx->p_range_mapping_base = cmdbuf->cmd_idx++; /* Fill Luma Range Mapping Base later */ + + /* VC1 Chroma Range Mapping Base Address */ +// RELOC(*cmdbuf->cmd_idx++, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset, &deblock_surface->buf); + +// ctx->p_slice_params = cmdbuf->cmd_idx; +// *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ + +// lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &ctx->preload_buffer, 0, +// sizeof( VC1PRELOAD ), 0, LLDMA_TYPE_VC1_PRELOAD_SAVE ); +// RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); +// cmdbuf->cmd_idx++; + +// lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &ctx->preload_buffer, 0, +// sizeof( VC1PRELOAD ), 0, LLDMA_TYPE_VC1_PRELOAD_RESTORE ); +// RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); +// cmdbuf->cmd_idx++; + +// ctx->slice_first_pic_last = cmdbuf->cmd_idx++; +//} +static void psb__VC1_FE_state(context_VC1_p ctx) +{ + uint32_t lldma_record_offset; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + uint32_t preload_size; + + if(VC1_Header_Parser_HW) + preload_size = FWPARSER_VC1PRELOAD_SIZE; + else + preload_size = sizeof( VC1PRELOAD ); + //psb_surface_p deblock_surface = ctx->decoded_surface->psb_surface; + + *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; + ctx->p_slice_params = cmdbuf->cmd_idx; + *cmdbuf->cmd_idx++ = 0; + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &ctx->preload_buffer, 0, + preload_size, 0, LLDMA_TYPE_VC1_PRELOAD_SAVE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + + lldma_record_offset = psb_cmdbuf_lldma_create( cmdbuf, &ctx->preload_buffer, 0, + preload_size, 0, LLDMA_TYPE_VC1_PRELOAD_RESTORE ); + RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); + cmdbuf->cmd_idx++; + + ctx->slice_first_pic_last = cmdbuf->cmd_idx++; + + ctx->p_range_mapping_base = cmdbuf->cmd_idx++; + ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++; + //RELOC(*cmdbuf->cmd_idx++, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset, &deblock_surface->buf); + + ctx->alt_output_flags = cmdbuf->cmd_idx++; + *ctx->alt_output_flags = 0; +} + +static void psb__VC1_Send_Parse_Header_Cmd(context_VC1_p ctx, IMG_BOOL new_pic) +{ + PARSE_HEADER_CMD* pParseHeaderCMD; + VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + + //pParseHeaderCMD = (PARSE_HEADER_CMD*)mCtrlAlloc.AllocateSpace(sizeof(PARSE_HEADER_CMD)); + pParseHeaderCMD = (void *)cmdbuf->cmd_idx; + cmdbuf->cmd_idx += sizeof(PARSE_HEADER_CMD)/sizeof(uint32_t); + + pParseHeaderCMD->ui32Cmd = CMD_PARSE_HEADER; + if(!new_pic) + { + pParseHeaderCMD->ui32Cmd |= CMD_PARSE_HEADER_NEWSLICE; + } + +// pParseHeaderCMD->ui32SeqHdrData = (sVC1HeaderParser.sSeqHdr.EXTENDED_DMV&0x1) << VC1_SEQHDR_EXTENDED_DMV; + pParseHeaderCMD->ui32SeqHdrData = (pic_params->mv_fields.bits.extended_dmv_flag) << VC1_SEQHDR_EXTENDED_DMV; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.PSF&0x1) << VC1_SEQHDR_PSF; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.psf) << VC1_SEQHDR_PSF; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.FINTERPFLAG&0x1) << VC1_SEQHDR_FINTERPFLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.finterpflag) << VC1_SEQHDR_FINTERPFLAG; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.TFCNTRFLAG&0x1) << VC1_SEQHDR_TFCNTRFLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.tfcntrflag) << VC1_SEQHDR_TFCNTRFLAG;; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.INTERLACE&0x1) << VC1_SEQHDR_INTERLACE; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.interlace) << VC1_SEQHDR_INTERLACE; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.PULLDOWN&0x1) << VC1_SEQHDR_PULLDOWN; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.pulldown) << VC1_SEQHDR_PULLDOWN; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.POSTPROCFLAG&0x1) << VC1_SEQHDR_POSTPROCFLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->post_processing & 0x1) << VC1_SEQHDR_POSTPROCFLAG; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.VSTRANSFORM&0x1) << VC1_SEQHDR_VSTRANSFORM; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->transform_fields.bits.variable_sized_transform_flag) << VC1_SEQHDR_VSTRANSFORM; + +// pParseHeaderCMD->ui32SeqHdrData |= (rser.sSeqHdr.DQUANT&0x3) << VC1_SEQHDR_DQUANT; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->pic_quantizer_fields.bits.dquant) << VC1_SEQHDR_DQUANT; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.EXTENDED_MV&0x1) << VC1_SEQHDR_EXTENDED_MV; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->mv_fields.bits.extended_mv_flag)<< VC1_SEQHDR_EXTENDED_MV; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.FASTUVMC&0x1) << VC1_SEQHDR_FASTUVMC; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->fast_uvmc_flag & 0x1) << VC1_SEQHDR_FASTUVMC; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.LOOPFILTER&0x1) << VC1_SEQHDR_LOOPFILTER; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->entrypoint_fields.bits.loopfilter) << VC1_SEQHDR_LOOPFILTER; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.REFDIST_FLAG&0x1) << VC1_SEQHDR_REFDIST_FLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->reference_fields.bits.reference_distance_flag) << VC1_SEQHDR_REFDIST_FLAG; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.PANSCAN_FLAG&0x1) << VC1_SEQHDR_PANSCAN_FLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->entrypoint_fields.bits.panscan_flag) << VC1_SEQHDR_PANSCAN_FLAG; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.MAXBFRAMES&0x7) << VC1_SEQHDR_MAXBFRAMES; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.max_b_frames) << VC1_SEQHDR_MAXBFRAMES; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.RANGERED&0x1) << VC1_SEQHDR_RANGERED; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.rangered) << VC1_SEQHDR_RANGERED; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.SYNCMARKER&0x1) << VC1_SEQHDR_SYNCMARKER; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.syncmarker) << VC1_SEQHDR_SYNCMARKER; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.MULTIRES&0x1) << VC1_SEQHDR_MULTIRES; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.multires) << VC1_SEQHDR_MULTIRES; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.QUANTIZER&0x3) << VC1_SEQHDR_QUANTIZER; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->pic_quantizer_fields.bits.quantizer) << VC1_SEQHDR_QUANTIZER; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.OVERLAP&0x1) << VC1_SEQHDR_OVERLAP; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->sequence_fields.bits.overlap) << VC1_SEQHDR_OVERLAP; + +// pParseHeaderCMD->ui32SeqHdrData |= (sVC1HeaderParser.sSeqHdr.PROFILE&0x3) << VC1_SEQHDR_PROFILE; + pParseHeaderCMD->ui32SeqHdrData |= (ctx->profile) << VC1_SEQHDR_PROFILE; + +// pParseHeaderCMD->ui32SeqHdrData |= (msPicParam.bSecondField&0x1) << VC1_SEQHDR_SECONDFIELD; + pParseHeaderCMD->ui32SeqHdrData |= (!pic_params->picture_fields.bits.is_first_field) << VC1_SEQHDR_SECONDFIELD; + +// pParseHeaderCMD->ui32SeqHdrData |= (mpDestFrame->FrameCodingMode()&0x3) << VC1_SEQHDR_FCM_CURRPIC; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->picture_fields.bits.frame_coding_mode & 0x3) << VC1_SEQHDR_FCM_CURRPIC; + +// pParseHeaderCMD->ui32SeqHdrData |= (mui8PicType&0x3) << VC1_SEQHDR_PICTYPE; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->picture_fields.bits.picture_type & 0x3) << VC1_SEQHDR_PICTYPE; + +// pParseHeaderCMD->ui32SeqHdrData |= ((msPicParam.bBidirectionalAveragingMode>>4)&0x1) << VC1_SEQHDR_ICFLAG; + pParseHeaderCMD->ui32SeqHdrData |= (pic_params->picture_fields.bits.intensity_compensation) << VC1_SEQHDR_ICFLAG; + + pParseHeaderCMD->ui32PicDimensions = ctx->picture_width_mb; + pParseHeaderCMD->ui32PicDimensions |= (ctx->picture_height_mb << 16); + +// pParseHeaderCMD->ui32BitplaneAddr[0] = (psBitplaneHWBuffer[0]->GetTopDeviceMemAlloc())->GetDeviceVirtAddress(); +// pParseHeaderCMD->ui32BitplaneAddr[1] = (psBitplaneHWBuffer[1]->GetTopDeviceMemAlloc())->GetDeviceVirtAddress(); +// pParseHeaderCMD->ui32BitplaneAddr[2] = (psBitplaneHWBuffer[2]->GetTopDeviceMemAlloc())->GetDeviceVirtAddress(); + RELOC(pParseHeaderCMD->ui32BitplaneAddr[0], ctx->bitplane_hw_buffer.buffer_ofs, &ctx->bitplane_hw_buffer); + RELOC(pParseHeaderCMD->ui32BitplaneAddr[1], ctx->bitplane_hw_buffer.buffer_ofs + 0xa000, &ctx->bitplane_hw_buffer); + RELOC(pParseHeaderCMD->ui32BitplaneAddr[2], ctx->bitplane_hw_buffer.buffer_ofs + 0xa000*2, &ctx->bitplane_hw_buffer); + +// pParseHeaderCMD->ui32VLCTableAddr = psVlcPackedTableData->GetTopDeviceMemAlloc()->GetDeviceVirtAddress(); + RELOC(pParseHeaderCMD->ui32VLCTableAddr, ctx->vlc_packed_table.buffer_ofs, &ctx->vlc_packed_table); + /* + pParseHeaderCMD->ui32ICParamData[0] = ((msPicParam.wBitstreamFcodes >> 8) & 0xFF); + pParseHeaderCMD->ui32ICParamData[0] |= ((msPicParam.wBitstreamPCEelements >> 8) & 0xFF) << 8; + if( mpForwardRefFrame->TopFieldFirst() ) + pParseHeaderCMD->ui32ICParamData[0] |= (1 << 16); + */ + pParseHeaderCMD->ui32ICParamData[0] = ((pic_params->luma_scale >> 8) & 0xFF); + pParseHeaderCMD->ui32ICParamData[0] |= ((pic_params->luma_shift >> 8) & 0xFF) << 8; + if( ctx->bTFF_FwRefFrm ) + pParseHeaderCMD->ui32ICParamData[0] |= (1 << 16); + /* + pParseHeaderCMD->ui32ICParamData[1] = (msPicParam.wBitstreamFcodes & 0xFF); + pParseHeaderCMD->ui32ICParamData[1] |= (msPicParam.wBitstreamPCEelements & 0xFF) << 8; + if( mpDestFrame->TopFieldFirst() ) + pParseHeaderCMD->ui32ICParamData[1] |= (1 << 16); + */ + pParseHeaderCMD->ui32ICParamData[1] = (pic_params->luma_scale & 0xFF); + pParseHeaderCMD->ui32ICParamData[1] |= (pic_params->luma_shift & 0xFF) << 8; + if( pic_params->picture_fields.bits.top_field_first ) + pParseHeaderCMD->ui32ICParamData[1] |= (1 << 16); + + pParseHeaderCMD->ui32ICParamData[0] = 0x00010000; + pParseHeaderCMD->ui32ICParamData[1] = 0x00010020; + PARSE_HEADER_CMD tmp = *pParseHeaderCMD; + tmp; + +} + +static VAStatus psb__VC1_process_slice(context_VC1_p ctx, + VASliceParameterBufferVC1 *slice_param, + object_buffer_p obj_buffer) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + + ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); + + psb__information_message("VC1 process slice\n"); + psb__information_message(" size = %08x offset = %08x\n", slice_param->slice_data_size, slice_param->slice_data_offset); + psb__information_message(" vertical pos = %d offset = %d\n", slice_param->slice_vertical_position, slice_param->macroblock_offset); + psb__information_message(" slice_data_flag = %d\n", slice_param->slice_data_flag); + + if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || + (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) + { + if (0 == slice_param->slice_data_size) + { + vaStatus = VA_STATUS_ERROR_UNKNOWN; + DEBUG_FAILURE; + return vaStatus; + } + ASSERT( !ctx->split_buffer_pending ); + + /* Initialise the command buffer */ + /* TODO: Reuse current command buffer until full */ + psb_context_get_next_cmdbuf(ctx->obj_context); + + psb__VC1_FE_state(ctx); +// psb__VC1_write_VLC_tables(ctx); +// psb__VC1_build_VLC_tables(ctx); + + psb_cmdbuf_lldma_write_bitstream(ctx->obj_context->cmdbuf, + obj_buffer->psb_buffer, + obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset, + (slice_param->slice_data_size), + slice_param->macroblock_offset, + (ctx->profile == WMF_PROFILE_ADVANCED) ? CMD_ENABLE_RBDU_EXTRACTION : 0); + + if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) + { + ctx->split_buffer_pending = TRUE; + } + } + else + { + ASSERT( ctx->split_buffer_pending ); + ASSERT(0 == slice_param->slice_data_offset); + /* Create LLDMA chain to continue buffer */ + if (slice_param->slice_data_size) + { + psb_cmdbuf_lldma_write_bitstream_chained(ctx->obj_context->cmdbuf, + obj_buffer->psb_buffer, + slice_param->slice_data_size); + } + } + + if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) || + (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)) + { + if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END) + { + ASSERT( ctx->split_buffer_pending ); + } + + psb__VC1_load_sequence_registers(ctx); + + if(!VC1_Header_Parser_HW) + { + psb__VC1_write_VLC_tables(ctx); + psb__VC1_build_VLC_tables(ctx); + } + else { + psb__VC1_Send_Parse_Header_Cmd(ctx, ctx->is_first_slice); + } + + psb__VC1_load_picture_registers(ctx, slice_param); + + psb__VC1_setup_bitplane(ctx); + + psb__VC1_send_rendec_params(ctx, slice_param); + + psb__VC1_write_kick(ctx, slice_param); + + ctx->split_buffer_pending = FALSE; + ctx->obj_context->video_op = psb_video_vld; + ctx->obj_context->first_mb = 0; + ctx->obj_context->flags = 0; + if (ctx->is_first_slice) + { + ctx->obj_context->flags |= FW_DXVA_RENDER_IS_FIRST_SLICE; + } + //if (ctx->bitplane_present) + { + ctx->obj_context->flags |= FW_DXVA_RENDER_VC1_BITPLANE_PRESENT; + } + ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); + + *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); +#ifdef DEBUG_TRACE_VERBOSE + psb__debug_schedule_hexdump("Preload buffer", &ctx->preload_buffer, 0, PRELOAD_BUFFER_SIZE); + psb__debug_schedule_hexdump("AUXMSB buffer", &ctx->aux_msb_buffer, 0, 0x8000 /* AUXMSB_BUFFER_SIZE */); + psb__debug_schedule_hexdump("VLC Table", &ctx->vlc_packed_table, 0, gui16vc1VlcTableSize * sizeof(IMG_UINT16)); +#endif + + if (psb_context_submit_cmdbuf(ctx->obj_context)) + { + vaStatus = VA_STATUS_ERROR_UNKNOWN; + } + + ctx->is_first_slice = FALSE; /* Reset */ + } + return vaStatus; +} + +static VAStatus psb__VC1_process_slice_data(context_VC1_p ctx, object_buffer_p obj_buffer) +{ + VAStatus vaStatus = VA_STATUS_SUCCESS; + VASliceParameterBufferVC1 *slice_param; + int buffer_idx = 0; + int element_idx = 0; + + ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); + + ASSERT(ctx->pic_params); + ASSERT(ctx->slice_param_list_idx); + + if (!ctx->pic_params) + { + /* Picture params missing */ + vaStatus = VA_STATUS_ERROR_UNKNOWN; + DEBUG_FAILURE; + return vaStatus; + } + if ((NULL == obj_buffer->psb_buffer) || + (0 == obj_buffer->size)) + { + /* We need to have data in the bitstream buffer */ + vaStatus = VA_STATUS_ERROR_UNKNOWN; + DEBUG_FAILURE; + return vaStatus; + } + + while(buffer_idx < ctx->slice_param_list_idx) + { + object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx]; + if (element_idx >= slice_buf->num_elements) + { + /* Move to next buffer */ + element_idx = 0; + buffer_idx++; + continue; + } + + slice_param = (VASliceParameterBufferVC1 *) slice_buf->buffer_data; + slice_param += element_idx; + element_idx++; + vaStatus = psb__VC1_process_slice(ctx, slice_param, obj_buffer); + if (vaStatus != VA_STATUS_SUCCESS) + { + DEBUG_FAILURE; + break; + } + } + ctx->slice_param_list_idx = 0; + + return vaStatus; +} + +static VAStatus pnw_VC1_BeginPicture( + object_context_p obj_context) +{ + INIT_CONTEXT_VC1 + + if (ctx->pic_params) + { + free(ctx->pic_params); + ctx->pic_params = NULL; + } + ctx->is_first_slice = TRUE; + + return VA_STATUS_SUCCESS; +} + +static VAStatus pnw_VC1_RenderPicture( + object_context_p obj_context, + object_buffer_p *buffers, + int num_buffers) +{ + int i; + INIT_CONTEXT_VC1 + VAStatus vaStatus = VA_STATUS_SUCCESS; + + for(i = 0; i < num_buffers; i++) + { + object_buffer_p obj_buffer = buffers[i]; + + switch( obj_buffer->type) + { + case VAPictureParameterBufferType: + psb__information_message("pnw_VC1_RenderPicture got VAPictureParameterBuffer\n"); + vaStatus = psb__VC1_process_picture_param(ctx, obj_buffer); + DEBUG_FAILURE; + break; + + case VABitPlaneBufferType: + psb__information_message("pnw_VC1_RenderPicture got VABitPlaneBuffer\n"); + vaStatus = psb__VC1_process_bitplane(ctx, obj_buffer); + DEBUG_FAILURE; + break; + + case VASliceParameterBufferType: + psb__information_message("pnw_VC1_RenderPicture got VASliceParameterBufferType\n"); + vaStatus = psb__VC1_add_slice_param(ctx, obj_buffer); + DEBUG_FAILURE; + break; + + case VASliceDataBufferType: + case VAProtectedSliceDataBufferType: + + psb__information_message("pnw_VC1_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); + vaStatus = psb__VC1_process_slice_data(ctx, obj_buffer); + DEBUG_FAILURE; + break; + + default: + vaStatus = VA_STATUS_ERROR_UNKNOWN; + DEBUG_FAILURE; + } + if (vaStatus != VA_STATUS_SUCCESS) + { + break; + } + } + + return vaStatus; +} + +static VAStatus pnw_VC1_EndPicture( + object_context_p obj_context) +{ + INIT_CONTEXT_VC1 + + if (psb_context_flush_cmdbuf(ctx->obj_context)) + { + return VA_STATUS_ERROR_UNKNOWN; + } + + ASSERT(ctx->pic_params); + if (!ctx->pic_params) + { + return VA_STATUS_ERROR_UNKNOWN; + } + + /********* Keep some picture parameters of the previously decoded picture ***********/ + if(PIC_TYPE_IS_REF(ctx->pic_params->picture_fields.bits.picture_type)) // I or P + { + /* Assume that the picture that we just decoded (the picture previous to the one that + is about to be decoded) is the backward reference picture for a B picture. */ + /* TODO: Make this more robust */ + ctx->ui8FCM_Ref2Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; + + /* For interlaced field pictures only */ + if((ctx->pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) || !ctx->pic_params->picture_fields.bits.is_first_field) + { + ctx->bTFF_BwRefFrm = ctx->pic_params->picture_fields.bits.top_field_first; + } + } + + ctx->bRef1RangeRed = ctx->bRef0RangeRed; + if(PIC_TYPE_IS_REF(ctx->pic_params->picture_fields.bits.picture_type)) + { + ctx->bRef0RangeRed = ctx->pic_params->range_reduction_frame; + } + /***********************************************************************************/ + + free(ctx->pic_params); + ctx->pic_params = NULL; + + return VA_STATUS_SUCCESS; +} + +struct format_vtable_s pnw_VC1_vtable = { + queryConfigAttributes: pnw_VC1_QueryConfigAttributes, + validateConfig: pnw_VC1_ValidateConfig, + createContext: pnw_VC1_CreateContext, + destroyContext: pnw_VC1_DestroyContext, + beginPicture: pnw_VC1_BeginPicture, + renderPicture: pnw_VC1_RenderPicture, + endPicture: pnw_VC1_EndPicture +}; diff --git a/src/pnw_VC1.h b/src/pnw_VC1.h new file mode 100644 index 0000000..8d3e286 --- /dev/null +++ b/src/pnw_VC1.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2007 Intel Corporation. All Rights Reserved. + * Copyright (c) Imagination Technologies Limited, UK + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _PNW_VC1_H_ +#define _PNW_VC1_H_ + +#include "psb_drv_video.h" + +extern struct format_vtable_s pnw_VC1_vtable; + +#endif /* _PNW_VC1_H_ */ diff --git a/src/pnw_cmdbuf.c b/src/pnw_cmdbuf.c index 590a32d..c62fcbf 100644 --- a/src/pnw_cmdbuf.c +++ b/src/pnw_cmdbuf.c @@ -96,19 +96,11 @@ VAStatus pnw_cmdbuf_create( cmdbuf->buffer_refs_allocated = 0; return vaStatus; } - - if (IMG_CODEC_JPEG != ctx->eCodec) - { - /* create topaz parameter buffer */ - vaStatus = psb_buffer_create(driver_data, ctx->in_params_size * MAX_SLICES_PER_PICTURE, psb_bt_cpu_vpu, &cmdbuf->topaz_in_params); - if(VA_STATUS_SUCCESS != vaStatus) - goto error_out5; - - } + /* create topaz parameter buffer */ vaStatus = psb_buffer_create(driver_data, ctx->pic_params_size * MAX_TOPAZ_CORES, psb_bt_cpu_vpu, &cmdbuf->pic_params); if(VA_STATUS_SUCCESS != vaStatus) - goto error_out4; + goto error_out5; /* create header buffer */ vaStatus = psb_buffer_create(driver_data, ctx->header_buffer_size, psb_bt_cpu_vpu, &cmdbuf->header_mem); @@ -123,11 +115,10 @@ VAStatus pnw_cmdbuf_create( /* all cmdbuf share one MTX_CURRENT_IN_PARAMS since every MB has a MTX_CURRENT_IN_PARAMS structure * and filling this structure for all MB is very time-consuming */ - /* + cmdbuf->topaz_in_params_I = &ctx->topaz_in_params_I; cmdbuf->topaz_in_params_P = &ctx->topaz_in_params_P; - cmdbuf->topaz_above_bellow_params = &ctx->topaz_above_bellow_params; - */ + cmdbuf->topaz_below_params = &ctx->topaz_below_params; cmdbuf->topaz_above_params = &ctx->topaz_above_params; @@ -137,8 +128,6 @@ VAStatus pnw_cmdbuf_create( psb_buffer_destroy(&cmdbuf->header_mem); error_out2: psb_buffer_destroy(&cmdbuf->pic_params); - error_out4: - psb_buffer_destroy(&cmdbuf->topaz_in_params); error_out5: pnw_cmdbuf_destroy(cmdbuf); @@ -575,13 +564,10 @@ int pnw_context_submit_cmdbuf( object_context_p obj_context ) * vaQuerySurfaceStatus is supposed only to be called after vaEndPicture/vaSyncSurface, * The caller should ensure the surface pertains to an encode context */ -int pnw_surface_get_frameskip( object_context_p obj_context, psb_surface_p surface, int *frame_skip) +int pnw_surface_get_frameskip( psb_driver_data_p driver_data, + psb_surface_p surface, + int *frame_skip) { - context_ENC_p ctx = (context_ENC_p) obj_context->format_data; - - if (ctx->sRCParams.RCEnable == 0) - return 0; - /* bit31 indicate if frameskip is already settled, it is used to record the frame skip flag for old surfaces * bit31 is cleared when the surface is used as encode render target or reference/reconstrucure target */ diff --git a/src/pnw_cmdbuf.h b/src/pnw_cmdbuf.h index 2601a07..311ee62 100644 --- a/src/pnw_cmdbuf.h +++ b/src/pnw_cmdbuf.h @@ -39,6 +39,10 @@ #define MTX_CMDWORD_INT_SHIFT (7) #define MTX_CMDWORD_INT_MASK (1) +#define PNW_CMDBUF_START_PIC_IDX (0) +#define PNW_CMDBUF_SEQ_HEADER_IDX (1) +#define PNW_CMDBUF_PIC_HEADER_IDX (2) + struct pnw_cmdbuf_s { struct psb_buffer_s buf; unsigned int size; @@ -52,27 +56,20 @@ struct pnw_cmdbuf_s { void *cmd_base; void *cmd_start; uint32_t *cmd_idx; - uint32_t *cmd_idx_saved; /* idx saved for frameskip redo */ + uint32_t *cmd_idx_saved[3]; /* idx saved for dual-core adjustion */ /* all frames share one topaz param buffer which contains InParamBase * AboveParam/BellowParam, and the buffer allocated when the context is created */ -/* struct psb_buffer_s *topaz_in_params_I; - struct psb_buffer_s *topaz_in_params_P; - struct psb_buffer_s *topaz_above_bellow_params; -*/ - struct psb_buffer_s *topaz_below_params; - void *topaz_below_params_p; - - /* void *topaz_in_params_I_p; - void *topaz_in_params_P_p; - */ - struct psb_buffer_s topaz_in_params; - void *topaz_in_params_P; + struct psb_buffer_s *topaz_in_params_P; + void *topaz_in_params_P_p; + struct psb_buffer_s *topaz_below_params; + void *topaz_below_params_p; + /* Every frame has its own PIC_PARAMS, SLICE_PARAMS and HEADER mem */ @@ -199,7 +196,7 @@ int pnw_context_submit_cmdbuf( object_context_p obj_context ); * * Returns 0 on success */ -int pnw_surface_get_frameskip( object_context_p obj_context, psb_surface_p surface, int *frame_skip); +int pnw_surface_get_frameskip( psb_driver_data_p driver_data, psb_surface_p psb_surface, int *frame_skip); /* * Flushes the pending cmdbuf diff --git a/src/pnw_hostcode.c b/src/pnw_hostcode.c index f09c941..f85670e 100644 --- a/src/pnw_hostcode.c +++ b/src/pnw_hostcode.c @@ -38,7 +38,7 @@ #define ALIGN_TO(value, align) ((value + align - 1) & ~(align - 1)) #define PAGE_ALIGN(value) ALIGN_TO(value, 4096) -static VAStatus pnw_DetectFrameSkip(context_ENC_p ctx); +/*static VAStatus pnw_DetectFrameSkip(context_ENC_p ctx);*/ IMG_UINT32 MVEARegBase[4] = {0x13000, 0x23000, 0x33000, 0x43000}; /* From TopazSC TRM */ @@ -391,13 +391,16 @@ static VAStatus pnw__alloc_context_buffer(context_ENC_p ctx, unsigned char is_JP { ctx->pic_params_size = 256; - ctx->header_buffer_size = 4 * HEADER_SIZE + MAX_SLICES_PER_PICTURE * HEADER_SIZE; + ctx->header_buffer_size = 7 * HEADER_SIZE + MAX_SLICES_PER_PICTURE * HEADER_SIZE; ctx->seq_header_ofs = 0; ctx->pic_header_ofs = HEADER_SIZE; ctx->eoseq_header_ofs = 2 * HEADER_SIZE; ctx->eostream_header_ofs = 3 * HEADER_SIZE; - ctx->slice_header_ofs = 4 * HEADER_SIZE; + ctx->aud_header_ofs = 4 * HEADER_SIZE; + ctx->sei_buf_prd_ofs = 5 * HEADER_SIZE; + ctx->sei_pic_tm_ofs = 6 * HEADER_SIZE; + ctx->slice_header_ofs = 7 * HEADER_SIZE; ctx->in_params_ofs = 0; ctx->sliceparam_buffer_size = ((sizeof(SLICE_PARAMS) + 15) & 0xfff0)* MAX_SLICES_PER_PICTURE; @@ -406,29 +409,36 @@ static VAStatus pnw__alloc_context_buffer(context_ENC_p ctx, unsigned char is_JP * every MB has one MTX_CURRENT_IN_PARAMS structure, and the (N+1) frame can * reuse (N) frame's structure */ - ctx->in_params_size = ((~0xf) & (15 + width * height / (16*16))) * sizeof(MTX_CURRENT_IN_PARAMS); + ctx->in_params_size = ((~0xf) & (15 + 1 + (width + 15) * (height + 15) / (16*16))) * sizeof(MTX_CURRENT_IN_PARAMS); ctx->below_params_size = ((BELOW_PARAMS_SIZE * width * height / (16*16)) + 0xf) & (~0xf); ctx->above_params_size = ((width / 16) * 128 + 15) & (~0xf) ; - // ctx->topaz_buffer_size = ctx->in_params_size + /* MTX_CURRENT_IN_PARAMS size */ - // ctx->below_params_size + /* above_params */ - // ctx->above_params_size; /* above_params */ - /* - vaStatus = psb_buffer_create(ctx->obj_context->driver_data, ctx->in_params_size, psb_bt_cpu_vpu, &ctx->topaz_in_params_I); - vaStatus |= psb_buffer_create(ctx->obj_context->driver_data, ctx->in_params_size, psb_bt_cpu_vpu, &ctx->topaz_in_params_P); - vaStatus |= psb_buffer_create(ctx->obj_context->driver_data, ctx->above_params_size + ctx->bellow_params_size, psb_bt_cpu_vpu, &ctx->topaz_above_bellow_params); - */ + vaStatus = psb_buffer_create(ctx->obj_context->driver_data, ctx->in_params_size, psb_bt_cpu_vpu, &ctx->topaz_in_params_I); + if(VA_STATUS_SUCCESS != vaStatus) + { + return vaStatus; + } + + vaStatus = psb_buffer_create(ctx->obj_context->driver_data, ctx->in_params_size, psb_bt_cpu_vpu, &ctx->topaz_in_params_P); + if(VA_STATUS_SUCCESS != vaStatus) + { + psb_buffer_destroy(&ctx->topaz_in_params_I); + return vaStatus; + } + vaStatus = psb_buffer_create(ctx->obj_context->driver_data, ctx->below_params_size * 4, psb_bt_cpu_vpu, &ctx->topaz_below_params); - if(VA_STATUS_SUCCESS != vaStatus) { + psb_buffer_destroy(&ctx->topaz_in_params_P); + psb_buffer_destroy(&ctx->topaz_in_params_I); return vaStatus; } vaStatus = psb_buffer_create(ctx->obj_context->driver_data, ctx->above_params_size * 4, psb_bt_cpu_vpu, &ctx->topaz_above_params); - if(VA_STATUS_SUCCESS != vaStatus) { + psb_buffer_destroy(&ctx->topaz_in_params_P); + psb_buffer_destroy(&ctx->topaz_in_params_I); psb_buffer_destroy(&ctx->topaz_below_params); return vaStatus; } @@ -480,6 +490,10 @@ unsigned int pnw__get_ipe_control(enum drm_pnw_topaz_codec eEncodingFormat) void pnw_DestroyContext(object_context_p obj_context) { + context_ENC_p ctx; + ctx = (context_ENC_p)obj_context->format_data; + if (NULL != ctx->slice_param_cache) + free(ctx->slice_param_cache); free(obj_context->format_data); obj_context->format_data = NULL; } @@ -593,7 +607,7 @@ VAStatus pnw_BeginPicture(context_ENC_p ctx) /* clear frameskip flag to 0 */ CLEAR_SURFACE_INFO_skipped_flag(ctx->src_surface->psb_surface); - if (ctx->sRCParams.RCEnable == IMG_TRUE) + /*if (ctx->sRCParams.RCEnable == IMG_TRUE) { pnw_DetectFrameSkip(ctx); if (0 != (GET_SURFACE_INFO_skipped_flag(ctx->src_surface->psb_surface) @@ -601,7 +615,7 @@ VAStatus pnw_BeginPicture(context_ENC_p ctx) ctx->sRCParams.FrameSkip = IMG_TRUE; else ctx->sRCParams.FrameSkip = IMG_FALSE; - } + }*/ /* Initialise the command buffer */ ret = pnw_context_get_next_cmdbuf(ctx->obj_context); @@ -633,14 +647,10 @@ VAStatus pnw_BeginPicture(context_ENC_p ctx) } /* only map topaz param when necessary */ - cmdbuf->topaz_in_params_P = NULL; cmdbuf->topaz_above_params_p = NULL; cmdbuf->topaz_below_params_p = NULL; - /* cmdbuf->topaz_in_params_I_p = NULL; cmdbuf->topaz_in_params_P_p = NULL; - cmdbuf->topaz_below_params_p = NULL; - */ if ( ctx->obj_context->frame_count==0) { /* first picture */ @@ -666,7 +676,7 @@ VAStatus pnw_BeginPicture(context_ENC_p ctx) /*If ParallelCores > 1(H264) and encode one slice per frame, the unnecessary start picture *commands will be replaced with MTX_CMDID_PAD and ignored by kernel*/ - cmdbuf->cmd_idx_saved = cmdbuf->cmd_idx; + cmdbuf->cmd_idx_saved[PNW_CMDBUF_START_PIC_IDX] = cmdbuf->cmd_idx; /* insert START_PIC command for each core */ /* ensure that the master (core #0) will be last to complete this batch */ @@ -957,25 +967,12 @@ VAStatus pnw_RenderPictureParameter(context_ENC_p ctx, int core) break; } - /* - * Do not forget this! But this is not needed in DDKv186 - * MTXWriteMem(MTXData.ui32CCBCtrlAddr + MTX_CCBCTRL_QP, sRCParams.ui32InitialQp); - */ - /* following START_PIC, insert initial QP */ - /* *ctx->initial_qp_in_cmdbuf = ctx->sRCParams.InitialQp; */ - - RELOC_PIC_PARAMS_PNW(&psPicParams->DstYBase, 0, &rec_surface->psb_surface->buf); RELOC_PIC_PARAMS_PNW(&psPicParams->DstUVBase, rec_surface->psb_surface->stride * rec_surface->height, &rec_surface->psb_surface->buf); - /* MTX_CURRENT_IN_PARAMS buffer is seperate buffer now */ - /*The type of frame will decide psPicParams->InParamsBase should - * use cmdbuf->topaz_in_params_P or cmdbuf->topaz_in_params_I*/ - /*RELOC_PIC_PARAMS(&psPicParams->InParamsBase, ctx->in_params_ofs, cmdbuf->topaz_in_params_P);*/ - RELOC_PIC_PARAMS_PNW(&psPicParams->BelowParamsInBase, ctx->below_params_ofs + ctx->below_params_size * ( ((ctx->AccessUnitNum)&0x1)), cmdbuf->topaz_below_params); @@ -991,7 +988,7 @@ VAStatus pnw_RenderPictureParameter(context_ENC_p ctx, int core) RELOC_PIC_PARAMS_PNW(&psPicParams->CodedBase, ctx->coded_buf_per_slice * core, ctx->coded_buf->psb_buffer); psb__information_message("For core %d, above_parmas_off %x\n", core, ctx->above_params_ofs + ctx->above_params_size * (core * 2 + ((ctx->AccessUnitNum) & 0x1))); -#if TOPAZ_PIC_PARAMS_VERBOS +#if TOPAZ_PIC_PARAMS_VERBOSE psb__information_message("PicParams->SrcYBase 0x%08x\n",psPicParams->SrcYBase); psb__information_message("PicParams->SrcUBase 0x%08x\n",psPicParams->SrcUBase); psb__information_message("PicParams->SrcVBase 0x%08x\n",psPicParams->SrcVBase); @@ -1060,6 +1057,7 @@ static VAStatus pnw_SetupRCParam(context_ENC_p ctx) return VA_STATUS_SUCCESS; } +#if 0 static VAStatus pnw_DetectFrameSkip(context_ENC_p ctx) { int frame_skip = 0; @@ -1092,6 +1090,7 @@ static VAStatus pnw_DetectFrameSkip(context_ENC_p ctx) return VA_STATUS_SUCCESS; } +#endif VAStatus pnw_EndPicture(context_ENC_p ctx) { @@ -1110,6 +1109,10 @@ VAStatus pnw_EndPicture(context_ENC_p ctx) #if TOPAZ_PIC_PARAMS_VERBOSE psb__information_message("End Picture for frame %d\n", ctx->obj_context->frame_count); + psb__information_message("psPicParams->bInsertHRDparams %d\n", psPicParams->InsertHRDparams); + psb__information_message("psPicParams->ClockDivBitrate %lld\n", psPicParams->ClockDivBitrate); + psb__information_message("psPicParams->MaxBufferMultClockDivBitrate %d\n", + psPicParams->MaxBufferMultClockDivBitrate); psb__information_message("psPicParams->sInParams.SeInitQP %d\n",psPicParams->sInParams.SeInitQP); psb__information_message("psPicParams->sInParams.MinQPVal %d\n",psPicParams->sInParams.MinQPVal); psb__information_message("psPicParams->sInParams.MaxQPVal %d\n",psPicParams->sInParams.MaxQPVal); @@ -1159,7 +1162,6 @@ VAStatus pnw_EndPicture(context_ENC_p ctx) psb_buffer_unmap(&cmdbuf->slice_params); /* unmap MTX_CURRENT_IN_PARAMS buffer only when it is mapped */ - /* if (cmdbuf->topaz_in_params_I_p != NULL) { psb_buffer_unmap(cmdbuf->topaz_in_params_I); cmdbuf->topaz_in_params_I_p= NULL; @@ -1169,12 +1171,6 @@ VAStatus pnw_EndPicture(context_ENC_p ctx) psb_buffer_unmap(cmdbuf->topaz_in_params_P); cmdbuf->topaz_in_params_P_p= NULL; } - */ - - if (cmdbuf->topaz_in_params_P != NULL) { - psb_buffer_unmap(&cmdbuf->topaz_in_params); - cmdbuf->topaz_in_params_P= NULL; - } if (cmdbuf->topaz_above_params_p != NULL) { psb_buffer_unmap(cmdbuf->topaz_above_params); @@ -1328,7 +1324,10 @@ void pnw__setup_rcdata( pnw__setup_busize(psContext); /* calculate BasicUnitSize */ /* Calculate Bits Per Pixel */ - FrameRate = psRCParams->FrameRate; + if (psContext->Width <= 176) + FrameRate = 30; + else + FrameRate = psRCParams->FrameRate; flBpp = 1.0 * psRCParams->BitsPerSecond / (FrameRate * psContext->Width * psContext->Height); psPicParams->sInParams.SeInitQP = psRCParams->InitialQp; @@ -1542,7 +1541,7 @@ void pnw__setup_rcdata( psPicParams->sInParams.MyInitQP = 31; } - psPicParams->sInParams.BufferSize = (psRCParams->BitsPerSecond * 5)>>1; + psPicParams->sInParams.BufferSize = psRCParams->BufferSize; if(psPicParams->sInParams.BufferSize > 112*16384) // Simple Profile L5 Constraints psPicParams->sInParams.BufferSize = 112*16384; break; @@ -1556,7 +1555,7 @@ void pnw__setup_rcdata( psPicParams->sInParams.BUPerFrm = 1; /* Initialize the parameters of fluid flow traffic model. */ - psPicParams->sInParams.BufferSize = ((5 * psRCParams->BitsPerSecond) >> 1); + psPicParams->sInParams.BufferSize = psRCParams->BufferSize; if(psContext->eCodec==IMG_CODEC_H264_VBR) { @@ -1590,6 +1589,21 @@ void pnw__setup_rcdata( psPicParams->sInParams.MyInitQP = psPicParams->sInParams.SeInitQP; + if (psContext->bInserHRDParams && (psRCParams->BitsPerSecond != 0)) + { + /*HRD parameters are meaningless without a bitrate */ + psPicParams->InsertHRDparams = IMG_FALSE; + } + else + { + psPicParams->InsertHRDparams = IMG_TRUE; + psPicParams->ClockDivBitrate = (90000 * 0x100000000LL); + psPicParams->ClockDivBitrate /= psRCParams->BitsPerSecond; + psPicParams->MaxBufferMultClockDivBitrate = (IMG_UINT32) + (((IMG_UINT64)(psRCParams->BufferSize) * (IMG_UINT64) 90000) + /(IMG_UINT64) psRCParams->BitsPerSecond); + } + if(psContext->SyncSequencer) psPicParams->Flags |= SYNC_SEQUENCER; @@ -1646,7 +1660,7 @@ static void pnw__setup_slice_row_params( IMG_INT16 iPos,iYPos,srcY; IMG_UINT16 ui16tmp; IMG_UINT16 ui16SearchWidth,ui16SearchHeight,ui16SearchLeftOffset,ui16SearchTopOffset,ui16CurBlockX; - /* + if (IsIntra && cmdbuf->topaz_in_params_I_p == NULL) { VAStatus vaStatus = psb_buffer_map(cmdbuf->topaz_in_params_I, &cmdbuf->topaz_in_params_I_p); if (vaStatus != VA_STATUS_SUCCESS) { @@ -1662,217 +1676,208 @@ static void pnw__setup_slice_row_params( return; } } - */ - if ( cmdbuf->topaz_in_params_P == NULL) { - VAStatus vaStatus = psb_buffer_map(&cmdbuf->topaz_in_params, &cmdbuf->topaz_in_params_P); - if (vaStatus != VA_STATUS_SUCCESS) { - psb__error_message("map topaz MTX_CURRENT_IN_PARAMS failed\n"); - return; - } - } - /* + if (IsIntra) psCurrent = (MTX_CURRENT_IN_PARAMS* ) (cmdbuf->topaz_in_params_I_p + ctx->in_params_ofs); else psCurrent = (MTX_CURRENT_IN_PARAMS* ) (cmdbuf->topaz_in_params_P_p + ctx->in_params_ofs); - */ - psCurrent = (MTX_CURRENT_IN_PARAMS* ) (cmdbuf->topaz_in_params_P + - ctx->in_params_ofs + - ctx->obj_context->slice_count * ctx->in_params_size); + + psCurrent += (CurrentRowY * (ctx->Width)/256); - psCurrent += (CurrentRowY * (ctx->Width)/256 ); + // Note: CurrentRowY and iSliceStartRowY are now in pixels (not MacroBlocks) - saves needless multiplications and divisions - // Note: CurrentRowY and iSliceStartRowY are now in pixels (not MacroBlocks) - saves needless multiplications and divisions + ui16SearchHeight = min(MVEA_LRB_SEARCH_HEIGHT,ctx->Height); + ui16SearchWidth = min (MVEA_LRB_SEARCH_WIDTH,ctx->Width); + ui16SearchLeftOffset = (((ui16SearchWidth /2) / 16)*16); // this is the amount of data that gets preloaded + ui16SearchTopOffset = (((ui16SearchHeight /2) / 16)*16); + ui16CurBlockX = MVEA_LRB_SEARCH_WIDTH - (ui16SearchLeftOffset+16); // this is our block position relative to the start of the LRB - ui16SearchHeight = min(MVEA_LRB_SEARCH_HEIGHT,ctx->Height); - ui16SearchWidth = min (MVEA_LRB_SEARCH_WIDTH,ctx->Width); - ui16SearchLeftOffset = (((ui16SearchWidth /2) / 16)*16); // this is the amount of data that gets preloaded - ui16SearchTopOffset = (((ui16SearchHeight /2) / 16)*16); - ui16CurBlockX = MVEA_LRB_SEARCH_WIDTH - (ui16SearchLeftOffset+16); // this is our block position relative to the start of the LRB + if ((iYPos=srcY=CurrentRowY-ui16SearchTopOffset)<0) + srcY = 0; + else if ( iYPos > ctx->HeightMinusLRB_TopAndBottom_OffsetsPlus16) + srcY = ctx->HeightMinusLRBSearchHeight; - if ((iYPos=srcY=CurrentRowY-ui16SearchTopOffset)<0) - srcY = 0; - else if ( iYPos > ctx->HeightMinusLRB_TopAndBottom_OffsetsPlus16) - srcY = ctx->HeightMinusLRBSearchHeight; + /*DDK 243 removed this block of code.*/ + /*if((ctx->eCodec==IMG_CODEC_H263_NO_RC)||(ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) + ui16tmp = CurrentRowY; + else*/ + ui16tmp = (CurrentRowY!=SliceStartRowY); - /*DDK 243 removed this block of code.*/ - /*if((ctx->eCodec==IMG_CODEC_H263_NO_RC)||(ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) - ui16tmp = CurrentRowY; - else*/ - ui16tmp = (CurrentRowY!=SliceStartRowY); + for(iPos=0;iPosWidth;iPos+=16,psCurrent++) + { + memset(psCurrent,0,sizeof(MTX_CURRENT_IN_PARAMS)); + psCurrent->MVValid =0; + psCurrent->ParamsValid = 0; - for(iPos=0;iPosWidth;iPos+=16,psCurrent++) + if(SliceStartRowY) { - memset(psCurrent,0,sizeof(MTX_CURRENT_IN_PARAMS)); - psCurrent->MVValid =0; - psCurrent->ParamsValid = 0; - - if(SliceStartRowY) - { - psCurrent->MVValid = VECTORS_ABOVE_VALID; - } - /* Setup the parameters and motion vectors*/ - if(ui16tmp) + psCurrent->MVValid = VECTORS_ABOVE_VALID; + } + /* Setup the parameters and motion vectors*/ + if(ui16tmp) + { + psCurrent->MVValid = VECTORS_ABOVE_VALID|DO_INTRA_PRED; + psCurrent->ParamsValid |= PARAMS_ABOVE_VALID; + + if(iPos+16 < ctx->Width) + { + psCurrent->ParamsValid |= PARAMS_ABOVER_VALID; + psCurrent->MVValid|= /*VECTORS_LEFT_VALID; //*/(1<<2); /* Vectors left valid define looks wrong*/ + } + + if(iPos>0 && (iPosWidth)) + { + psCurrent->ParamsValid |= PARAMS_ABOVEL_VALID; + psCurrent->MVValid|= VECTORS_ABOVE_LEFT_VALID; //(1<<0) + } + } + else + { + // are we the first MB in a new slice? + if(iPos==0) + { + if((ctx->eCodec==IMG_CODEC_H263_NO_RC) || (ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) { - psCurrent->MVValid = VECTORS_ABOVE_VALID|DO_INTRA_PRED; - psCurrent->ParamsValid |= PARAMS_ABOVE_VALID; - - if(iPos+16 < ctx->Width) - { - psCurrent->ParamsValid |= PARAMS_ABOVER_VALID; - psCurrent->MVValid|= /*VECTORS_LEFT_VALID; //*/(1<<2); /* Vectors left valid define looks wrong*/ - } - - if(iPos>0 && (iPosWidth)) - { - psCurrent->ParamsValid |= PARAMS_ABOVEL_VALID; - psCurrent->MVValid|= VECTORS_ABOVE_LEFT_VALID; //(1<<0) - } + if(iYPos==-ui16SearchTopOffset) + psCurrent->ParamsValid|=MB_START_OF_SLICE;// OPTI? } else { - // are we the first MB in a new slice? - if(iPos==0) - { - if((ctx->eCodec==IMG_CODEC_H263_NO_RC) || (ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) - { - if(iYPos==-ui16SearchTopOffset) - psCurrent->ParamsValid|=MB_START_OF_SLICE;// OPTI? - } - else - { - psCurrent->ParamsValid|=MB_START_OF_SLICE;// OPTI? - } - } - } - /*DDK 243 removed this block of code.*/ - /*if((ctx->eCodec==IMG_CODEC_H263_NO_RC) || (ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) - { - // clear the above params valid bits - psCurrent->ParamsValid &=~(PARAMS_ABOVEL_VALID|PARAMS_ABOVER_VALID|PARAMS_ABOVE_VALID); // OPTI - }*/ - // Have to fill in the right hand row of 4x4 vectors into the the left block - if(iPos) - { - psCurrent->MVValid|= DO_INTRA_PRED| (1<<3); /*MV_VALID define looks wrong?! so use hard coded value for now*/ - psCurrent->ParamsValid |= 8; //(1<<3) - } - if(iPos==ctx->Width-16) - { - // indicate the last MB in a row - psCurrent->ParamsValid|=MB_END_OF_ROW; - // are we the last mb in the slice? - if(iYPos==(SliceStartRowY+SliceHeight - (ui16SearchTopOffset + 16))) - { - psCurrent->ParamsValid|=MB_END_OF_SLICE; - if(iYPos==ctx->HeightMinus16MinusLRBTopOffset) - { - psCurrent->ParamsValid|=MB_END_OF_PICTURE; - } - } + psCurrent->ParamsValid|=MB_START_OF_SLICE;// OPTI? } - // And now the below block - // should do some kind of check to see if we are the first inter block, as otherwise the vectors will be invalid! - if(VectorsValid) + } + } + /*DDK 243 removed this block of code.*/ + /*if((ctx->eCodec==IMG_CODEC_H263_NO_RC) || (ctx->eCodec==IMG_CODEC_H263_CBR)||(ctx->eCodec==IMG_CODEC_H263_VBR)) + { + // clear the above params valid bits + psCurrent->ParamsValid &=~(PARAMS_ABOVEL_VALID|PARAMS_ABOVER_VALID|PARAMS_ABOVE_VALID); // OPTI + }*/ + // Have to fill in the right hand row of 4x4 vectors into the the left block + if(iPos) + { + psCurrent->MVValid|= DO_INTRA_PRED| (1<<3); /*MV_VALID define looks wrong?! so use hard coded value for now*/ + psCurrent->ParamsValid |= 8; //(1<<3) + } + if(iPos==ctx->Width-16) + { + // indicate the last MB in a row + psCurrent->ParamsValid|=MB_END_OF_ROW; + // are we the last mb in the slice? + if(iYPos==(SliceStartRowY+SliceHeight - (ui16SearchTopOffset + 16))) + { + psCurrent->ParamsValid|=MB_END_OF_SLICE; + if(iYPos==ctx->HeightMinus16MinusLRBTopOffset) { - if(iYPos < ctx->HeightMinus16MinusLRBTopOffset) - { - psCurrent->MVValid|=VECTORS_BELOW_VALID; //(1<<4) - - if(iYPos < ctx->HeightMinus32MinusLRBTopOffset) - { - psCurrent->MVValid|=VECTORS_2BELOW_VALID; //(1<<5) - } - } + psCurrent->ParamsValid|=MB_END_OF_PICTURE; } + } + } + // And now the below block + // should do some kind of check to see if we are the first inter block, as otherwise the vectors will be invalid! + if(VectorsValid) + { + if(iYPos < ctx->HeightMinus16MinusLRBTopOffset) + { + psCurrent->MVValid|=VECTORS_BELOW_VALID; //(1<<4) - /*Set up IPEMin and Max for coordinate X in the search reference region*/ - /*And set up flags in SPEMax when needed*/ - if(iPos<=ui16SearchLeftOffset) + if(iYPos < ctx->HeightMinus32MinusLRBTopOffset) { - psCurrent->IPEMin[0] = ui16CurBlockX - iPos; - psCurrent->RealEdge |= SPE_EDGE_LEFT; - } - else - { - psCurrent->IPEMin[0] = ui16CurBlockX/16; + psCurrent->MVValid|=VECTORS_2BELOW_VALID; //(1<<5) } + } + } - if((iPos + ui16SearchLeftOffset + 16)>ctx->Width ) - { - psCurrent->IPEMax[0]=(ui16CurBlockX-1 + ctx->Width) - iPos; //(112 - 1) - ((iPos + 48+16) - ctx->psVideo->ui16Width); - psCurrent->RealEdge |=SPE_EDGE_RIGHT; - } - else - { - psCurrent->IPEMax[0] = (ui16CurBlockX + 16 + ui16SearchLeftOffset) - 1 - 3; //(112 - 1) - 3; - } - - /*Set up IPEMin and Max for Y coordinate in the search reference region*/ - /*And set up flags in SPEMax when needed*/ - if(iYPos <= 0) - { - psCurrent->IPEMin[1] = 0; - psCurrent->RealEdge |= SPE_EDGE_TOP; - } - else - { - psCurrent->IPEMin[1] = 3; - } + /*Set up IPEMin and Max for coordinate X in the search reference region*/ + /*And set up flags in SPEMax when needed*/ + if(iPos<=ui16SearchLeftOffset) + { + psCurrent->IPEMin[0] = ui16CurBlockX - iPos; + psCurrent->RealEdge |= SPE_EDGE_LEFT; + } + else + { + psCurrent->IPEMin[0] = ui16CurBlockX/16; + } - //Max Y - if(iYPos > ctx->HeightMinusLRB_TopAndBottom_OffsetsPlus16) - { - psCurrent->IPEMax[1]= ui16SearchHeight - 1; - psCurrent->RealEdge |= ui16SearchHeight - 4; - } - else - { - psCurrent->IPEMax[1] = ui16SearchHeight - 4; - } + if((iPos + ui16SearchLeftOffset + 16)>ctx->Width ) + { + psCurrent->IPEMax[0]=(ui16CurBlockX-1 + ctx->Width) - iPos; //(112 - 1) - ((iPos + 48+16) - ctx->psVideo->ui16Width); + psCurrent->RealEdge |=SPE_EDGE_RIGHT; + } + else + { + psCurrent->IPEMax[0] = (ui16CurBlockX + 16 + ui16SearchLeftOffset) - 1 - 3; //(112 - 1) - 3; + } - psCurrent->CurBlockAddr = ((ui16CurBlockX)/16); - psCurrent->CurBlockAddr |=((IMG_UINT8)(( (iYPos + ui16SearchTopOffset) - srcY )/16)<<4); - - /* Setup the control register values - These will get setup and transferred to a different location within the macroblock parameter structure. - They are then read out of the esb by the mtx and used to control the hardware units - */ - psCurrent->IPEControl = ctx->IPEControl; + /*Set up IPEMin and Max for Y coordinate in the search reference region*/ + /*And set up flags in SPEMax when needed*/ + if(iYPos <= 0) + { + psCurrent->IPEMin[1] = 0; + psCurrent->RealEdge |= SPE_EDGE_TOP; + } + else + { + psCurrent->IPEMin[1] = 3; + } - switch(ctx->eCodec) - { - case IMG_CODEC_H263_NO_RC: - case IMG_CODEC_H263_VBR: - case IMG_CODEC_H263_CBR: - pnw__setup_qpvalues_mpeg4(psCurrent,bySliceQP); - psCurrent->JMCompControl = F_ENCODE(2,MVEA_CR_JMCOMP_MODE); - psCurrent->VLCControl = F_ENCODE(3,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); - break; - case IMG_CODEC_MPEG4_NO_RC: - case IMG_CODEC_MPEG4_VBR: - case IMG_CODEC_MPEG4_CBR: - pnw__setup_qpvalues_mpeg4(psCurrent,bySliceQP); - psCurrent->JMCompControl = F_ENCODE(1,MVEA_CR_JMCOMP_MODE) | F_ENCODE(1,MVEA_CR_JMCOMP_AC_ENABLE); - psCurrent->VLCControl = F_ENCODE(2,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); - break; - default: - case IMG_CODEC_H264_NO_RC: - case IMG_CODEC_H264_VBR: - case IMG_CODEC_H264_CBR: - pnw__setup_qpvalue_h264(psCurrent,bySliceQP); - psCurrent->JMCompControl = F_ENCODE(0,MVEA_CR_JMCOMP_MODE); - psCurrent->VLCControl = F_ENCODE(1,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); - break; - } + //Max Y + if(iYPos > ctx->HeightMinusLRB_TopAndBottom_OffsetsPlus16) + { + psCurrent->IPEMax[1]= ui16SearchHeight - 1; + psCurrent->RealEdge |= ui16SearchHeight - 4; + } + else + { + psCurrent->IPEMax[1] = ui16SearchHeight - 4; + } + + psCurrent->CurBlockAddr = ((ui16CurBlockX)/16); + psCurrent->CurBlockAddr |=((IMG_UINT8)(( (iYPos + ui16SearchTopOffset) - srcY )/16)<<4); + + /* Setup the control register values + These will get setup and transferred to a different location within the macroblock parameter structure. + They are then read out of the esb by the mtx and used to control the hardware units + */ + psCurrent->IPEControl = ctx->IPEControl; + + switch(ctx->eCodec) + { + case IMG_CODEC_H263_NO_RC: + case IMG_CODEC_H263_VBR: + case IMG_CODEC_H263_CBR: + pnw__setup_qpvalues_mpeg4(psCurrent,bySliceQP); + psCurrent->JMCompControl = F_ENCODE(2,MVEA_CR_JMCOMP_MODE); + psCurrent->VLCControl = F_ENCODE(3,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); + break; + case IMG_CODEC_MPEG4_NO_RC: + case IMG_CODEC_MPEG4_VBR: + case IMG_CODEC_MPEG4_CBR: + pnw__setup_qpvalues_mpeg4(psCurrent,bySliceQP); + psCurrent->JMCompControl = F_ENCODE(1,MVEA_CR_JMCOMP_MODE) | F_ENCODE(1,MVEA_CR_JMCOMP_AC_ENABLE); + psCurrent->VLCControl = F_ENCODE(2,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); + break; + default: + case IMG_CODEC_H264_NO_RC: + case IMG_CODEC_H264_VBR: + case IMG_CODEC_H264_CBR: + pnw__setup_qpvalue_h264(psCurrent,bySliceQP); + psCurrent->JMCompControl = F_ENCODE(0,MVEA_CR_JMCOMP_MODE); + psCurrent->VLCControl = F_ENCODE(1,TOPAZ_VLC_CR_CODEC) | F_ENCODE(IsIntra? 0:1,TOPAZ_VLC_CR_SLICE_CODING_TYPE); + break; } + } - // now setup the dummy end of frame macroblock. + // now setup the dummy end of frame macroblock. + if ((CurrentRowY + 16) >= ctx->Height) + { memset(psCurrent,0,sizeof(MTX_CURRENT_IN_PARAMS)); psCurrent->MVValid =DO_INTRA_PRED; psCurrent->ParamsValid = 0; psCurrent->RealEdge =0; + } } void pnw_setup_slice_params( @@ -1925,6 +1930,10 @@ IMG_UINT32 pnw__send_encode_slice_params( pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf; + psb__information_message("Send encode slice parmas, Is Intra:%d, CurrentRow:%d" \ + "DeblockIDC:%d, FrameNum:%d, SliceHeight:%d, CurrentSlice:%d\n", + IsIntra, CurrentRow, DeblockIDC, FrameNum, SliceHeight, CurrentSlice); + ref_surface = ctx->ref_surface; psRef = &ctx->ref_surface->psb_surface->buf; psCoded = ctx->coded_buf->psb_buffer; @@ -1936,10 +1945,10 @@ IMG_UINT32 pnw__send_encode_slice_params( psSliceParams->SliceStartRowNum = CurrentRow/16; /* We want multiple ones of these so we can submit multiple slices without having to wait for the next */ - psSliceParams->CodedDataPos=0; psSliceParams->CodedData=0; psSliceParams->TotalCoded=0; psSliceParams->Flags=0; + psSliceParams->HostCtx = 0xdafed123; #ifdef VA_EMULATOR psSliceParams->RefYStride = ref_surface->psb_surface->stride; @@ -2016,12 +2025,18 @@ IMG_UINT32 pnw__send_encode_slice_params( RELOC_SLICE_PARAMS_PNW(&(psSliceParams->RefUVBase), ref_surface->psb_surface->stride * ref_surface->height + (RowOffset * 128 / 16), psRef); - /* RELOC_SLICE_PARAMS_PNW(&(psSliceParams->CodedData),0,psCoded); */ //unused - RELOC_SLICE_PARAMS_PNW(&(psSliceParams->InParamsBase), - ctx->in_params_ofs + CurrentSlice * ctx->in_params_size, - &cmdbuf->topaz_in_params); + if (IsIntra) + RELOC_SLICE_PARAMS_PNW(&(psSliceParams->InParamsBase), + ctx->in_params_ofs, + //((CurrentRow * (ctx->Width)) / 256 + ctx->obj_context->slice_count) * sizeof(MTX_CURRENT_IN_PARAMS), + cmdbuf->topaz_in_params_I); + else + RELOC_SLICE_PARAMS_PNW(&(psSliceParams->InParamsBase), + ctx->in_params_ofs, + //((CurrentRow * (ctx->Width)) / 256 + ctx->obj_context->slice_count) * sizeof(MTX_CURRENT_IN_PARAMS), + cmdbuf->topaz_in_params_P); -#if 0 +#if TOPAZ_PIC_PARAMS_VERBOSE psb__information_message("psSliceParams->SliceStartRowNum %d\n", psSliceParams->SliceStartRowNum); psb__information_message("psSliceParams->SliceHeight %d\n", psSliceParams->SliceHeight); psb__information_message("psSliceParams->RefYBase %x\n", psSliceParams->RefYBase ); @@ -2030,9 +2045,9 @@ IMG_UINT32 pnw__send_encode_slice_params( psb__information_message("psSliceParams->RefUVStride %d\n", psSliceParams->RefUVStride); psb__information_message("psSliceParams->RefYRowStride %d\n", psSliceParams->RefYRowStride); psb__information_message("psSliceParams->RefUVRowStride %d\n", psSliceParams->RefUVRowStride); - psb__information_message("psSliceParams->CodedData %x\n", psSliceParams->CodedData); + psb__information_message("psSliceParams->HostCtx %d\n", psSliceParams->HostCtx); psb__information_message("psSliceParams->Flags %x\n", psSliceParams->Flags); - psb__information_message("psSliceParams->CodedDataPos %d\n", psSliceParams->CodedDataPos); + psb__information_message("psSliceParams->CodedData %x\n", psSliceParams->CodedData); psb__information_message("psSliceParams->TotalCoded %d\n", psSliceParams->TotalCoded); psb__information_message("psSliceParams->FCode %x\n", psSliceParams->FCode); psb__information_message("psSliceParams->InParamsBase %x\n", psSliceParams->InParamsBase); diff --git a/src/pnw_hostcode.h b/src/pnw_hostcode.h index 93213f6..5973b5c 100644 --- a/src/pnw_hostcode.h +++ b/src/pnw_hostcode.h @@ -28,7 +28,7 @@ #include "pnw_cmdbuf.h" #include "pnw_hostjpeg.h" -#define TOPAZ_PIC_PARAMS_VERBOS 0 +#define TOPAZ_PIC_PARAMS_VERBOSE 0 #define MAX_SLICES_PER_PICTURE 72 #define MAX_TOPAZ_CORES 4 @@ -94,6 +94,7 @@ typedef struct _RC_PARAMS_ IMG_UINT32 BufferSize; IMG_UINT32 BitsConsumed; IMG_UINT32 IntraFreq; + IMG_UINT16 IDRFreq; IMG_INT16 MinQP; IMG_BOOL RCEnable; IMG_BOOL FrameSkip; @@ -216,10 +217,8 @@ struct context_ENC_s { */ /* 0 and 1 are for in_parms, 2 is for bellow and above params*/ - /* struct psb_buffer_s topaz_in_params_I; struct psb_buffer_s topaz_in_params_P; - */ struct psb_buffer_s topaz_below_params; /* MB MVs read & written by HW */ struct psb_buffer_s topaz_above_params; /* MB MVs read & written by HW */ @@ -244,6 +243,10 @@ struct context_ENC_s { uint32_t eoseq_header_ofs; uint32_t eostream_header_ofs; uint32_t slice_header_ofs; + /*HRD SEI header*/ + uint32_t aud_header_ofs; + uint32_t sei_buf_prd_ofs; + uint32_t sei_pic_tm_ofs; uint32_t sliceparam_buffer_size; @@ -251,7 +254,8 @@ struct context_ENC_s { TH_SKIP_SCALE THSkip; uint32_t pic_params_flags; - VAEncSliceParameterBuffer slice_param_cache[2]; + VAEncSliceParameterBuffer *slice_param_cache; + uint16_t slice_param_num; IMG_UINT16 MPEG4_vop_time_increment_resolution; @@ -260,12 +264,16 @@ struct context_ENC_s { uint32_t MPEG4_picture_type_frameskip; uint8_t profile_idc; + uint8_t force_idr_h264; + /*If only one slice, it's zero. Otherwise it indicates size of parted coded_buf per slice*/ uint32_t coded_buf_per_slice; /*JPEG context*/ TOPAZSC_JPEG_ENCODER_CONTEXT *jpeg_ctx; + /*H264 SEI_INSERTION*/ + IMG_BOOL bInserHRDParams; }; typedef struct context_ENC_s *context_ENC_p; @@ -300,6 +308,10 @@ typedef struct context_ENC_s *context_ENC_p; #define SPE_EDGE_TOP 4 /* ->bMinYRealEdge*/ #define SPE_EDGE_BOTTOM 8 /* ->bMaxYRealEdge*/ +#define BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE 23 +#define PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE 23 +#define PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE 7 + typedef struct { /* Transferred into the input params area of the macroblock parameter structure*/ @@ -393,6 +405,13 @@ typedef struct _PIC_PARAMS_ IMG_UINT16 SearchHeight; IMG_UINT16 NumSlices; //!< Number of slices in the picture + + // SEI_INSERTION + IMG_UINT32 InitialCPBremovaldelayoffset; + IMG_UINT64 ClockDivBitrate; + IMG_UINT32 MaxBufferMultClockDivBitrate; + IMG_BOOL InsertHRDparams; + }PIC_PARAMS; @@ -411,9 +430,9 @@ typedef struct _SLICE_PARAMS_ IMG_UINT16 RefYRowStride; IMG_UINT16 RefUVRowStride; - IMG_UINT32 CodedData; + IMG_UINT32 HostCtx; IMG_UINT32 Flags; - IMG_UINT32 CodedDataPos; + IMG_UINT32 CodedData; IMG_UINT32 TotalCoded; IMG_UINT32 FCode; diff --git a/src/pnw_hostheader.c b/src/pnw_hostheader.c index b6e6a1b..684cef4 100644 --- a/src/pnw_hostheader.c +++ b/src/pnw_hostheader.c @@ -393,105 +393,6 @@ static void pnw__H264_writebits_startcode_prefix_element( return; } -static void pnw__H264_writebits_sequence_header0( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - H264_SEQUENCE_HEADER_PARAMS *pSHParams) -{ - /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */ - - /* 4 Byte StartCodePrefix Pregenerated in: pnw__H264_writebits_startcode_prefix_element() - * Byte aligned (bit 32) - */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p,(0 << 7) |/* forbidden_zero_bit=0 */ - (0x3 << 5) |/* nal_ref_idc=01 (may be 11) */ - (7), /* nal_unit_type=00111 */ - 8); - - - /* Byte aligned (bit 40) - * profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP) - */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (pSHParams->ucProfile==SH_PROFILE_BP ? 66 : 77), - 8); - - /* Byte aligned (bit 48) */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (1 << 7) |/* constrain_set0_flag = 0 for MP, 1 for BP */ - (1 << 6) |/* constrain_set1_flag = 0 for BP, 1 for MP */ - (0 << 5) | /* constrain_set2_flag = always 0 in BP/MP */ - ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4), /* constrain_set3_flag = 1 for level 1b, 0 for others */ - /* reserved_zero_4bits = 0 */ - 8); - - /* Byte aligned (bit 56) */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (IMG_UINT8)( (pSHParams->ucLevel > 100) ? (pSHParams->ucLevel - 100): pSHParams->ucLevel ) , - 8);/* level_idc (8 bits) = 11 for 1b, 10xlevel for others */ - - /* Byte aligned (bit 64) */ - pnw__write_upto8bits_elements( - mtx_hdr, elt_p,(1 << 7) | /* seq_parameter_Set_id = 0 in Topaz -> ue(0)= 1b */ - (2 << 4) | /* log2_max_frame_num_minus4 = 1 in Topaz -> ue(1)= 010b */ - (1 << 3) | /* pic_order_cnt_type = 0 in Topaz -> ue(0)= 1b */ - (3), /* log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz -> ue(2)= 011b */ - 8); - - /* Bytes aligned (bit 72) */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (2 << 1) | /* num_ref_frames = 1 ue(1)= 010b, */ - (0),/* gaps_in_frame_num_value_allowed_Flag - (1 bit) - Not supported in Topaz (0) */ - 4); -} - -static void pnw__H264_writebits_sequence_header1( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - H264_SEQUENCE_HEADER_PARAMS *pSHParams, - H264_CROP_PARAMS *psCropParams) -{ - /* GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE - * ELEMENT BITCOUNT: xx - * pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row) - */ - pnw__generate_ue(mtx_hdr, elt_p, pSHParams->ucWidth_in_mbs_minus1); - - /* pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column) */ - pnw__generate_ue(mtx_hdr, elt_p, pSHParams->ucHeight_in_maps_units_minus1); - - /* We don't know the alignment at this point, so will have to use bit writing functions */ - pnw__write_upto8bits_elements( - mtx_hdr, elt_p, - (1 << 2) | /* frame_mb_only_flag (always 1) */ - (1 << 1), /* direct_8x8_inference_flag=1 in Topaz */ - 2); - - if(psCropParams && psCropParams->bClip) - { - pnw__write_upto8bits_elements(mtx_hdr, elt_p,1,1); - pnw__generate_ue(mtx_hdr, elt_p, psCropParams->LeftCropOffset); - pnw__generate_ue(mtx_hdr, elt_p, psCropParams->RightCropOffset); - pnw__generate_ue(mtx_hdr, elt_p, psCropParams->TopCropOffset); - pnw__generate_ue(mtx_hdr, elt_p, psCropParams->BottomCropOffset); - - } - else - { - pnw__write_upto8bits_elements(mtx_hdr, elt_p,0,1); - } -} - static void pnw__H264_writebits_VUI_params( MTX_HEADER_PARAMS *mtx_hdr, @@ -530,7 +431,8 @@ static void pnw__H264_writebits_VUI_params( */ pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* bit_rate_scale (4 bits) = 0 in Topaz, cpb_size_scale (4 bits) = 0 in Topaz */ - pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); + pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4); + pnw__write_upto8bits_elements(mtx_hdr, elt_p, 2, 4); /* bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2] */ pnw__generate_ue(mtx_hdr, elt_p, VUIParams->bit_rate_value_minus1); @@ -589,102 +491,88 @@ static void pnw__H264_writebits_VUI_params( 0, 1);/* bitstream_restriction_flag (1 bit) = 0 in Topaz */ } -static void pnw__H264_writebits_sequence_header2( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - H264_SEQUENCE_HEADER_PARAMS *pSHParams) -{ - /* GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE - * ELEMENT BITCOUNT: xx - */ - IMG_UINT8 SBP; - pnw__write_upto8bits_elements( - mtx_hdr, elt_p, - (pSHParams->VUI_Params_Present),/* vui_parameters_present_flag (VUI only in 1st sequence of stream) */ - 1); - - if (pSHParams->VUI_Params_Present>0) - pnw__H264_writebits_VUI_params(mtx_hdr, elt_p, &(pSHParams->VUI_Params)); - - /* Finally we need to align to the next byte - * We know the size of the data in the sequence header (no MTX variables) - * and start is byte aligned, so it's possible to add this field here rather than - * MTX ELEMENT_INSERTBYTEALIGN_H264 command. - */ - - pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); - SBP=(elt_p[mtx_hdr->Elements]->Size)&7; - - if (SBP>0) pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8-(SBP)); -} - -static void pnw__H264_writebits_picture_header0( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - IMG_BOOL bCabacEnabled) -{ - IMG_UINT8 ECMF = (bCabacEnabled ? 1 : 0); - /* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE - * ELEMENT BITCOUNT: 18 - */ - - /* 4 Byte StartCodePrefix Pregenerated in: pnw__H264_writebits_startcode_prefix_element() - * Byte aligned (bit 32) - */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p,(0 << 7) | /* forbidden_zero_bit */ - (1 << 5) | /* nal_ref_idc (2 bits) = 1 */ - (8),/* nal_unit_tpye (5 bits) = 8 */ - 8); - /* Byte aligned (bit 40) */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (1 << 7) | /* pic_parameter_set_id ue(v) = 0 in Topaz */ - (1 << 6) | /* seq_parameter_set_id ue(v) = 0 in Topaz */ - (ECMF << 5) | /* entropy_coding_mode_flag (1 bit) 0 for CAVLC */ - (0 << 4) | /* pic_order_present_flag (1 bit) = 0 */ - (1 << 3) | /* num_slice_group_minus1 ue(v) = 0 in Topaz */ - (1 << 2) | /* num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz */ - (1 << 1) | /* num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz */ - (0), /* weighted_pred_flag (1 bit) = 0 in Topaz */ - 8); - - /* Byte aligned (bit 48) */ - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, 0, - 2);/* weighted_bipred_flag (2 bits) = 0 in Topaz */ -} - -static void pnw__H264_writebits_picture_header1( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - IMG_INT8 CQPOffset) +static void pnw__H264_writebits_picture_header( + MTX_HEADER_PARAMS *pMTX_Header, + MTX_HEADER_ELEMENT **aui32ElementPointers, + IMG_BOOL bCabacEnabled, + IMG_BOOL b_8x8transform, + IMG_BOOL bIntraConstrained, + IMG_INT8 i8CbQPOffset, + IMG_INT8 i8CrQPOffset) { - /* GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE - * ELEMENT BITCOUNT: 5 - */ - - /* The following field will be generated as a special case by MTX - so not here - * pnw__generate_se(mtx_hdr, pPHParams->pic_init_qp_minus26); // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz - */ - pnw__generate_se(mtx_hdr, elt_p, 0); /* pic_int_qs_minus26 se(v) = 0 in Topaz */ - pnw__generate_se(mtx_hdr, elt_p, CQPOffset); /* chroma_qp_index_offset se(v) = 0 in Topaz */ - - pnw__write_upto8bits_elements( - mtx_hdr, - elt_p, - (1 << 2) | /* deblocking_filter_control_present_flag (1 bit) = 1 in Topaz */ - (0 << 1) | /* constrained_intra_pred_Flag (1 bit) = 0 in Topaz */ - (0), /* redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz */ - 3); + //**-- Begin building the picture header element + IMG_UINT8 ui8ECMF = (bCabacEnabled ? 1 : 0); + + pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA); + + pnw__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4); + + ///* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE */// + ///**** ELEMENT BITCOUNT: 18 + + // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element() + // Byte aligned (bit 32) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + (0 << 7) | // forbidden_zero_bit + (1 << 5) | // nal_ref_idc (2 bits) = 1 + (8), // nal_unit_tpye (5 bits) = 8 + 8); + // Byte aligned (bit 40) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + (1 << 7) | // pic_parameter_set_id ue(v) = 0 in Topaz + (1 << 6) | // seq_parameter_set_id ue(v) = 0 in Topaz + (ui8ECMF << 5) | // entropy_coding_mode_flag (1 bit) 0 for CAVLC + (0 << 4) | // pic_order_present_flag (1 bit) = 0 + (1 << 3) | // num_slice_group_minus1 ue(v) = 0 in Topaz + (1 << 2) | // num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz + (1 << 1) | // num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz + (0), // weighted_pred_flag (1 bit) = 0 in Topaz + 8); + // Byte aligned (bit 48) + // weighted_bipred_flag (2 bits) = 0 in Topaz + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2); + + //MTX fills this value in + pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_QP); + pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA); + + ///**** GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE ****/// + ///**** ELEMENT BITCOUNT: 5 + //The following field will be generated as a special case by MTX - so not here + // pnw__generate_se(pMTX_Header, pPHParams->pic_init_qp_minus26); + // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz + // pic_int_qs_minus26 se(v) = 0 in Topaz + //chroma_qp_index_offset se(v) = 0 in Topaz + pnw__generate_se(pMTX_Header, aui32ElementPointers, 0); + pnw__generate_se(pMTX_Header, aui32ElementPointers, i8CbQPOffset); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + // deblocking_filter_control_present_flag (1 bit) = 1 in Topaz + (1 << 2) | + // constrained_intra_pred_Flag (1 bit) = 0 in Topaz + ((bIntraConstrained?1:0) << 1) | + (0),// redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz + 3); + // Byte align is done using an element command (MTX elements in this structure, we don't know it's size) + + if(b_8x8transform || (i8CbQPOffset != i8CrQPOffset)) + { + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, + (b_8x8transform << 1) | // 8x8 transform flag + (0), // pic_scaling_matrix_present_flag + 2); + pnw__generate_se(pMTX_Header, aui32ElementPointers, i8CrQPOffset); + // second_chroma_qp_index_offset se(v) = 0 in Topaz + } + // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) + pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264); - /* Byte align is done using an element command (MTX elements in this structure, we don't know it's size) */ + return; } - + static void pnw__H264_writebits_slice_header0( MTX_HEADER_PARAMS *mtx_hdr, @@ -817,52 +705,176 @@ static void pnw__H264_writebits_slice_header2( */ } - - static void pnw__H264_writebits_sequence_header( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - H264_SEQUENCE_HEADER_PARAMS *pSHParams, - H264_CROP_PARAMS *psCropParams) + MTX_HEADER_PARAMS *pMTX_Header, + MTX_HEADER_ELEMENT **aui32ElementPointers, + H264_SEQUENCE_HEADER_PARAMS *pSHParams,H264_CROP_PARAMS *psCrop) { - pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); + IMG_UINT8 ui8SBP; - pnw__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4); - pnw__H264_writebits_sequence_header0(mtx_hdr, elt_p, pSHParams); - pnw__H264_writebits_sequence_header1(mtx_hdr, elt_p, pSHParams, psCropParams); - pnw__H264_writebits_sequence_header2(mtx_hdr, elt_p, pSHParams); -} + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + pnw__H264_writebits_startcode_prefix_element(pMTX_Header, + aui32ElementPointers, + 4); -static void pnw__H264_writebits_picture_header( - MTX_HEADER_PARAMS *mtx_hdr, - MTX_HEADER_ELEMENT **elt_p, - IMG_BOOL bCabacEnabled, - IMG_INT8 CQPOffset) -{ - /* Begin building the picture header element */ -#ifdef USESTATICWHEREPOSSIBLE - IMG_UINT32 *p; - p=(IMG_UINT32 *) mtx_hdr; - p[0]=3;p[1]=0;p[2]=50; - p[3]=13510657; - p[4]=2;p[5]=1;p[6]=57349;p[7]=6; -#else - pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); - - pnw__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4); - pnw__H264_writebits_picture_header0(mtx_hdr, elt_p, bCabacEnabled); + ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****/// - pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_QP); /* MTX fills this value in */ + // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element() + // Byte aligned (bit 32) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers,(0 << 7) | // forbidden_zero_bit=0 + (0x3 << 5) | // nal_ref_idc=01 (may be 11) + (7), // nal_unit_type=00111 + 8); - pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); - pnw__H264_writebits_picture_header1(mtx_hdr, elt_p, CQPOffset); + if (pSHParams->ucProfile != SH_PROFILE_HP) + { + // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + (pSHParams->ucProfile==SH_PROFILE_BP ? 66 : 77),8); + + // Byte aligned (bit 48) + pnw__write_upto8bits_elements(pMTX_Header, + // constrain_set0_flag = 1 for BP constraints + aui32ElementPointers,(0 << 7) | + (0 << 6) | // constrain_set1_flag = 1 for MP constraints + (0 << 5) | // constrain_set2_flag = 1 for HP + // constrain_set3_flag = 1 for level 1b, 0 for others + ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4), + // reserved_zero_4bits = 0 + 8); + // Byte aligned (bit 56) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + // level_idc (8 bits) = 11 for 1b, 10xlevel for others + (IMG_UINT8) pSHParams->ucLevel,8); + + // Byte aligned (bit 64) + pnw__write_upto8bits_elements(pMTX_Header, + // seq_parameter_Set_id = 0 in Topaz -> ue(0)= 1b + aui32ElementPointers,(1 << 7) | + (2 << 4) |// log2_max_frame_num_minus4 = 1 in Topaz -> ue(1)= 010b + (1 << 3) | // pic_order_cnt_type = 0 in Topaz -> ue(0)= 1b + (3), // log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz -> ue(2)= 011b + 8); + // Bytes aligned (bit 72) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers,(2 << 1) | // num_ref_frames = 1 ue(1)= 010b, + (pSHParams->gaps_in_frame_num_value), + // gaps_in_frame_num_value_allowed_Flag - (1 bit) + 4); + } + else + { + // Byte aligned (bit 40) + // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP) + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 100, 8); + + // Byte aligned (bit 48) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers,(1 << 7) | + // constrain_set0_flag = 1 for MP + BP constraints + (1 << 6) | // constrain_set1_flag = 1 for MP + BP constraints + (0 << 5) | // constrain_set2_flag = always 0 in BP/MP + (0 << 4), // constrain_set3_flag = 1 for level 1b, 0 for others + // reserved_zero_4bits = 0 + 8); + + // Byte aligned (bit 56) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers,(IMG_UINT8) pSHParams->ucLevel,8); + // level_idc (8 bits) = 11 for 1b, 10xlevel for others + + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0); + // seq_parameter_Set_id = 0 + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 1); + // chroma_format_idc = 1 + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0); + // bit_depth_luma_minus8 = 0 + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0); + // bit_depth_chroma_minus8 = 0 + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); + // qpprime_y_zero_transform_bypass_flag = 0 + + //if (pSHParams->bUseDefaultScalingList) + //{ + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); + // seq_scaling_matrix_present_flag + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8); + // seq_scaling_matrix_present_flag[i] = 0; 0 < i < 8 + //} + //else + //{ + // pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // seq_scaling_matrix_present_flag + //} + + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 1); + // log2_max_frame_num_minus4 = 1 + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0); + // pic_order_cnt_type = 0 + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 2); + // log2_max_pic_order_cnt_Isb_minus4 = 2 + + // Bytes aligned (bit 72) + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,(3 << 1) | + // num_ref_frames = 2 ue(2)= 011b, + (pSHParams->gaps_in_frame_num_value), + // gaps_in_frame_num_value_allowed_Flag - (1 bit) + 4); + } - /* Tell MTX to insert the byte align field */ - /* (we don't know final stream size for alignment at this point) */ - pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264); -#endif - + ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****/// + ///**** ELEMENT BITCOUNT: xx + pnw__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1); + //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row) + pnw__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1); + //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column) + + // We don't know the alignment at this point, so will have to use bit writing functions + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,pSHParams->ucFrame_mbs_only_flag,1); + // frame_mb_only_flag 1=frame encoding, 0=field encoding + + if(!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1); + // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level) + + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1); + // direct_8x8_inference_flag=1 in Topaz + + if(psCrop->bClip) + { + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1); + pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->LeftCropOffset); + pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->RightCropOffset); + pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->TopCropOffset); + pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->BottomCropOffset); + + } + else + { + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1); + } + + ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****/// + ///**** ELEMENT BITCOUNT: xx + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, + (pSHParams->VUI_Params_Present), + // vui_parameters_present_flag (VUI only in 1st sequence of stream) + 1); + if (pSHParams->VUI_Params_Present>0) + pnw__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params)); + + // Finally we need to align to the next byte + // We know the size of the data in the sequence header (no MTX variables) and start is byte aligned, so it's possible to add this field here rather than MTX ELEMENT_INSERTBYTEALIGN_H264 command. + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); + ui8SBP=(aui32ElementPointers[pMTX_Header->Elements]->Size)&7; + if (ui8SBP>0) + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8-(ui8SBP)); + return; } @@ -1801,15 +1813,6 @@ static void H263_writebits_VideoPictureHeader( IMG_UINT8 UFEP; IMG_UINT8 OCPCF = 0; -#ifdef USESTATICWHEREPOSSIBLE - IMG_UINT16 *p; - - p=(IMG_UINT16 *) mtx_hdr; - p[0]=p[1]=p[2]=p[3]=0; - p[4]=38;p[5]=32768 | ((Temporal_Ref >> 6) << 8); - p[6]= ((Temporal_Ref & 63) <<2) | 2 | (SourceFormatType << 10); -#else - /* Essential we insert the element before we try to fill it! */ pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); @@ -1836,7 +1839,7 @@ static void H263_writebits_VideoPictureHeader( /* source_format = 3 Bits = 1-4 See note */ pnw__write_upto8bits_elements(mtx_hdr, elt_p, SourceFormatType, 3); -#endif + /*Write optional Custom Picture Clock Frequency(OCPCF)*/ if (FrameRate == 30 || FrameRate == 0/* unspecified */) { @@ -1872,6 +1875,19 @@ static void H263_writebits_VideoPictureHeader( { pnw__write_upto8bits_elements(mtx_hdr, elt_p, 6, 3); pnw__write_upto8bits_elements(mtx_hdr, elt_p, OCPCF , 1); + + /* 10 reserve bits ( Optional support for the encoding). All are OFF(0). + * - Optional Unrestricted Motion Vector (UMV) + * - Optional Syntax-based Arithmetic Coding (SAC) + * - Optional Advanced Prediction (AP) mode + * - Optional Advanced INTRA Coding (AIC) mode + * - Optional Deblocking Filter (DF) mode + * - Optional Slice Structured (SS) mode + * - Optional Reference Picture Selection(RPS) mode. + * - Optional Independent Segment Decoding (ISD) mode + * - Optional Alternative INTER VLC (AIV) mode + * - Optional Modified Quantization (MQ) mode */ + pnw__write_upto32bits_elements(mtx_hdr, elt_p, 0, 10); // 10 reserve bits pnw__write_upto8bits_elements(mtx_hdr, elt_p, 8, 4); @@ -1963,18 +1979,6 @@ static void H263_writebits_GOBSliceHeader( IMG_UINT8 GOBNumber, IMG_UINT8 GOBFrameId) { -#ifdef USESTATICWHEREPOSSIBLE - IMG_UINT16 *p; - p=(IMG_UINT16 *) mtx_hdr; - /* - p[0]=1; - p[1]=p[2]=p[3]=0; - */ - *(int *)mtx_hdr = 1; - p[4]=24; - p[5]=(128 | ((GOBNumber & 31) << 2) | (GOBFrameId & 3)) << 8; - p[6]=5; -#else /* Essential we insert the element before we try to fill it! */ pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); @@ -1994,7 +1998,7 @@ static void H263_writebits_GOBSliceHeader( * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale)) */ pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_SLICEQSCALE); -#endif + return; } /* @@ -2063,6 +2067,539 @@ static void H263_writebits_GOBSliceHeader( //mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count //} +// SEI_INSERTION +static void pnw__H264_writebits_AUD_header( + MTX_HEADER_PARAMS *pMTX_Header, + MTX_HEADER_ELEMENT **aui32ElementPointers) +{ + // Essential we insert the element before we try to fill it! + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + + pnw__H264_writebits_startcode_prefix_element(pMTX_Header, + aui32ElementPointers, 4); // 00 00 00 01 start code prefix + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 9, + 8); // AUD nal_unit_type = 09 + + // primary_pic_type u(3) 0=I slice, 1=P or I slice, 2=P,B or I slice + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 2, + 3); + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 1 << 4, 5); // rbsp_trailing_bits + + // Write terminator + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, 0x80, 8); + return; +} + +static void pnw__H264_writebits_SEI_buffering_period_header( + MTX_HEADER_PARAMS *pMTX_Header, + MTX_HEADER_ELEMENT **aui32ElementPointers, + IMG_UINT8 ui8NalHrdBpPresentFlag, + IMG_UINT8 ui8nal_cpb_cnt_minus1, + IMG_UINT8 ui8nal_initial_cpb_removal_delay_length, + IMG_UINT32 ui32nal_initial_cpb_removal_delay, + IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset, + IMG_UINT8 ui8VclHrdBpPresentFlag, + IMG_UINT8 ui8vcl_cpb_cnt_minus1, + IMG_UINT32 ui32vcl_initial_cpb_removal_delay, + IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset) +{ + IMG_UINT8 ui8SchedSelIdx; + IMG_UINT8 ui8PayloadSizeBits; +#ifdef SEI_NOT_USE_TOKEN_ALIGN + IMG_UINT8 ui8Pad; +#endif + // Essential we insert the element before we try to fill it! + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + + pnw__H264_writebits_startcode_prefix_element(pMTX_Header, + aui32ElementPointers, + 3); // 00 00 01 start code prefix + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 6, 8); // nal_unit_type = 06 (SEI Message) + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 0, 8); // SEI payload type (buffering period) + + ui8PayloadSizeBits=1; // seq_parameter_set_id bitsize = 1 + if(ui8NalHrdBpPresentFlag) + ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1) + * ui8nal_initial_cpb_removal_delay_length * 2); + if(ui8VclHrdBpPresentFlag) + ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1) + * ui8nal_initial_cpb_removal_delay_length * 2); + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ((ui8PayloadSizeBits+7)/8), + 8); + // SEI payload size = No of bytes required for SEI payload + // (including seq_parameter_set_id) + + //seq_parameter_set_id ue(v) = 0 default? = 1 (binary) + //= sequence parameter set containing HRD attributes + pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0); + + if( ui8NalHrdBpPresentFlag ) + { + for( ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++ ) + { + // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access + // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit. + // Delay is based on the time taken for a 90 kHz clock. + // Range >0 and < 90000 * (CPBsize / BitRate) + // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation. + // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required + + //pnw__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32nal_initial_cpb_removal_delay, ui8nal_initial_cpb_removal_delay_length); + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY); + + // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to + // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset + // Delay is based on the time taken for a 90 kHz clock. + // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C + + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET); + } + } + if( ui8VclHrdBpPresentFlag ) + { + for( ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++ ) + { + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + ui32vcl_initial_cpb_removal_delay, + ui8nal_initial_cpb_removal_delay_length); + // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + ui32vcl_initial_cpb_removal_delay_offset, + ui8nal_initial_cpb_removal_delay_length); + } + } + + // Pad to end of byte +#ifdef SEI_NOT_USE_TOKEN_ALIGN + if(!ui8VclHrdBpPresentFlag) + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + ui8Pad = (ui8PayloadSizeBits+7)/8; + ui8Pad = (ui8Pad*8)-ui8PayloadSizeBits; + if (ui8Pad>0) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 1 << (ui8Pad-1), + ui8Pad); // SEI payload type (buffering period) +#else + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_INSERTBYTEALIGN_H264); + // Tell MTX to insert the byte align field + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); +#endif + + // Write terminator + pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8); + + return; +} + + +static void pnw__H264_writebits_SEI_picture_timing_header( + MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers, + IMG_UINT8 ui8CpbDpbDelaysPresentFlag, + IMG_UINT32 ui32cpb_removal_delay_length_minus1, + IMG_UINT32 ui32dpb_output_delay_length_minus1, + IMG_UINT32 ui32cpb_removal_delay, + IMG_UINT32 ui32dpb_output_delay, + IMG_UINT8 ui8pic_struct_present_flag, + IMG_UINT8 ui8pic_struct, + IMG_UINT8 ui8NumClockTS, + IMG_UINT8 *aui8clock_timestamp_flag, + IMG_UINT8 ui8full_timestamp_flag, + IMG_UINT8 ui8seconds_flag, + IMG_UINT8 ui8minutes_flag, + IMG_UINT8 ui8hours_flag, + IMG_UINT8 ui8seconds_value, + IMG_UINT8 ui8minutes_value, + IMG_UINT8 ui8hours_value, + IMG_UINT8 ui8ct_type, + IMG_UINT8 ui8nuit_field_based_flag, + IMG_UINT8 ui8counting_type, + IMG_UINT8 ui8discontinuity_flag, + IMG_UINT8 ui8cnt_dropped_flag, + IMG_UINT8 ui8n_frames, + IMG_UINT8 ui8time_offset_length, + IMG_UINT32 i32time_offset) +{ + IMG_UINT8 ui8PayloadSizeBits, ui8Tmp; +#ifdef SEI_NOT_USE_TOKEN_ALIGN + IMG_UINT8 ui8Pad; +#endif + + // Essential we insert the element before we try to fill it! + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + + pnw__H264_writebits_startcode_prefix_element(pMTX_Header, + aui32ElementPointers, + 3); // 00 00 01 start code prefix + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 6, 8); // nal_unit_type = 06 (SEI Message) + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 1, 8); // SEI payload type (picture timing) + + + // Precalculate the payload bit size + ui8PayloadSizeBits=0; + if (ui8CpbDpbDelaysPresentFlag) + ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1 + + 1 + ui32dpb_output_delay_length_minus1 + 1; + + if (ui8pic_struct_present_flag) + { + ui8PayloadSizeBits += 4; + for( ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++ ) + { + ui8PayloadSizeBits += 1; + + if(aui8clock_timestamp_flag[ui8Tmp]) + { + ui8PayloadSizeBits += 2+1+5+1+1+1+8; + if(ui8full_timestamp_flag) + ui8PayloadSizeBits += 6+6+5; + else + { + ui8PayloadSizeBits += 1; + if(ui8seconds_flag) + { + ui8PayloadSizeBits += 6+1; + if(ui8minutes_flag) + { + ui8PayloadSizeBits += 6+1; + if(ui8hours_flag) + ui8PayloadSizeBits += 5; + } + } + } + + if(ui8time_offset_length > 0) + ui8PayloadSizeBits += ui8time_offset_length; + } + } + } + + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ((ui8PayloadSizeBits+7)/8), 8); + // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id) + + + if (ui8CpbDpbDelaysPresentFlag) + { + //SEI_INSERTION +#ifdef SEI_HOSTCALC_CPB_DPB + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + ui32cpb_removal_delay, + ui32cpb_removal_delay_length_minus1+1 ); // cpb_removal_delay + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + ui32dpb_output_delay, + ui32dpb_output_delay_length_minus1+1 ); // dpb_output_delay +#else + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + PTH_SEI_NAL_CPB_REMOVAL_DELAY); + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + PTH_SEI_NAL_DPB_OUTPUT_DELAY); +#endif + } + + if (ui8pic_struct_present_flag) + { + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8pic_struct, 4); // See TRM able D 1 – Interpretation of pic_struct + + for( ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++ ) + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + aui8clock_timestamp_flag[ui8Tmp], 1); + + if(aui8clock_timestamp_flag[ui8Tmp]) + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8ct_type, 2); + // (2=Unknown) See TRM Table D 2 – Mapping of ct_type to source picture scan + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8nuit_field_based_flag, 1); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8counting_type, 5); + // See TRM Table D 3 – Definition of counting_type values + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8full_timestamp_flag, 1); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8discontinuity_flag, 1); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8cnt_dropped_flag, 1); + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8n_frames, 8); + + if(ui8full_timestamp_flag) + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8seconds_value, 6); // 0 - 59 + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8minutes_value, 6); // 0 - 59 + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8hours_value, 5); // 0 - 23 + } + else + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8seconds_flag, 1); + + if(ui8seconds_flag) + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8seconds_value, 6); // 0 - 59 + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8minutes_flag, 1); + + if(ui8minutes_flag) + { + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8minutes_value, 6); // 0 - 59 + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8hours_flag, 1); + + if(ui8hours_flag) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + ui8hours_value, 5); // 0 - 23 + } + } + } + + if(ui8time_offset_length > 0) + { + // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset) + if (i32time_offset < 0) + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + (IMG_UINT32) ((2 ^ ui8time_offset_length) + i32time_offset), + ui8time_offset_length); + else + pnw__write_upto32bits_elements(pMTX_Header, + aui32ElementPointers, + (IMG_UINT32) i32time_offset, + ui8time_offset_length); + } + } + } + } + +#ifdef SEI_NOT_USE_TOKEN_ALIGN + // Pad to end of byte + if (!ui8pic_struct_present_flag) + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); + ui8Pad = (ui8PayloadSizeBits+7)/8; + ui8Pad = (ui8Pad*8)-ui8PayloadSizeBits; + if (ui8Pad>0) + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 1 << (ui8Pad-1), + ui8Pad); // SEI payload type (buffering period) +#else + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field + pnw__insert_element_token(pMTX_Header, + aui32ElementPointers, + ELEMENT_STARTCODE_RAWDATA); +#endif + + // Write terminator + pnw__write_upto8bits_elements(pMTX_Header, + aui32ElementPointers, + 0x80, 8); + return; +} + + + +void pnw__H264_prepare_AUD_header(MTX_HEADER_PARAMS * pMTX_Header) +{ + // Essential we initialise our header structures before building + MTX_HEADER_ELEMENT *This_Element; + MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS]; + pMTX_Header->Elements=ELEMENTS_EMPTY; + This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream; + aui32ElementPointers[0]=This_Element; + + pnw__H264_writebits_AUD_header(pMTX_Header, aui32ElementPointers); + + pMTX_Header->Elements++; //Has been used as an index, so need to add 1 for a valid element count +} + + +void pnw__H264_prepare_SEI_buffering_period_header( + MTX_HEADER_PARAMS * pMTX_Header, + IMG_UINT8 ui8NalHrdBpPresentFlag, + IMG_UINT8 ui8nal_cpb_cnt_minus1, + IMG_UINT8 ui8nal_initial_cpb_removal_delay_length, + IMG_UINT32 ui32nal_initial_cpb_removal_delay, + IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset, + IMG_UINT8 ui8VclHrdBpPresentFlag, + IMG_UINT8 ui8vcl_cpb_cnt_minus1, + IMG_UINT32 ui32vcl_initial_cpb_removal_delay, + IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset) +{ + // Essential we initialise our header structures before building + MTX_HEADER_ELEMENT *This_Element; + MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS]; + pMTX_Header->Elements=ELEMENTS_EMPTY; + This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream; + aui32ElementPointers[0]=This_Element; + + pnw__H264_writebits_SEI_buffering_period_header( + pMTX_Header, aui32ElementPointers, + ui8NalHrdBpPresentFlag, + ui8nal_cpb_cnt_minus1, + ui8nal_initial_cpb_removal_delay_length, + ui32nal_initial_cpb_removal_delay, + ui32nal_initial_cpb_removal_delay_offset, + ui8VclHrdBpPresentFlag, + ui8vcl_cpb_cnt_minus1, + ui32vcl_initial_cpb_removal_delay, + ui32vcl_initial_cpb_removal_delay_offset); + + pMTX_Header->Elements++; + //Has been used as an index, so need to add 1 for a valid element count + return; +} + +void pnw__H264_prepare_SEI_picture_timing_header( + MTX_HEADER_PARAMS * pMTX_Header, + IMG_UINT8 ui8CpbDpbDelaysPresentFlag, + IMG_UINT32 ui32cpb_removal_delay_length_minus1, + IMG_UINT32 ui32dpb_output_delay_length_minus1, + IMG_UINT32 ui32cpb_removal_delay, + IMG_UINT32 ui32dpb_output_delay, + IMG_UINT8 ui8pic_struct_present_flag, + IMG_UINT8 ui8pic_struct, + IMG_UINT8 ui8NumClockTS, + IMG_UINT8 *aui8clock_timestamp_flag, + IMG_UINT8 ui8full_timestamp_flag, + IMG_UINT8 ui8seconds_flag, + IMG_UINT8 ui8minutes_flag, + IMG_UINT8 ui8hours_flag, + IMG_UINT8 ui8seconds_value, + IMG_UINT8 ui8minutes_value, + IMG_UINT8 ui8hours_value, + IMG_UINT8 ui8ct_type, + IMG_UINT8 ui8nuit_field_based_flag, + IMG_UINT8 ui8counting_type, + IMG_UINT8 ui8discontinuity_flag, + IMG_UINT8 ui8cnt_dropped_flag, + IMG_UINT8 ui8n_frames, + IMG_UINT8 ui8time_offset_length, + IMG_INT32 i32time_offset) +{ + // Essential we initialise our header structures before building + MTX_HEADER_ELEMENT *This_Element; + MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS]; + pMTX_Header->Elements=ELEMENTS_EMPTY; + This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream; + aui32ElementPointers[0]=This_Element; + + pnw__H264_writebits_SEI_picture_timing_header( + pMTX_Header, aui32ElementPointers, + ui8CpbDpbDelaysPresentFlag, + ui32cpb_removal_delay_length_minus1, + ui32dpb_output_delay_length_minus1, + ui32cpb_removal_delay, + ui32dpb_output_delay, + ui8pic_struct_present_flag, + ui8pic_struct, + ui8NumClockTS, + aui8clock_timestamp_flag, + ui8full_timestamp_flag, + ui8seconds_flag, + ui8minutes_flag, + ui8hours_flag, + ui8seconds_value, + ui8minutes_value, + ui8hours_value, + ui8ct_type, + ui8nuit_field_based_flag, + ui8counting_type, + ui8discontinuity_flag, + ui8cnt_dropped_flag, + ui8n_frames, + ui8time_offset_length, + i32time_offset); + + pMTX_Header->Elements++; + //Has been used as an index, so need to add 1 for a valid element count + return; +} + + void pnw__H264_prepare_sequence_header( @@ -2133,7 +2670,9 @@ void pnw__H264_prepare_sequence_header( SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8) (uiPicWidthInMbs-1); SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8) (uiPicHeightInMbs-1); SHParams.VUI_Params_Present = VUI_present; - SHParams.VUI_Params= *VUI_params; + SHParams.VUI_Params = *VUI_params; + SHParams.gaps_in_frame_num_value = IMG_FALSE; + SHParams.ucFrame_mbs_only_flag = IMG_TRUE; /* All picture header information is static * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway) @@ -2170,7 +2709,9 @@ void pnw__H264_prepare_picture_header(IMG_UINT32 *pHeaderMemory, IMG_BOOL bCabac This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; elt_p[0]=This_Element; - pnw__H264_writebits_picture_header(mtx_hdr, elt_p, bCabacEnabled, CQPOffset); + pnw__H264_writebits_picture_header(mtx_hdr, elt_p, bCabacEnabled, + 0, 0, + CQPOffset, CQPOffset); mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ } @@ -2181,17 +2722,23 @@ void pnw__H264_prepare_slice_header( IMG_UINT32 uiFrameNumber, IMG_UINT32 uiFirst_MB_Address, IMG_UINT32 uiMBSkipRun, - IMG_BOOL bCabacEnabled) + IMG_BOOL bCabacEnabled, + IMG_BOOL bForceIDR) { - H264_SLICE_HEADER_PARAMS SlHParams; + H264_SLICE_HEADER_PARAMS SlHParams = {0}; MTX_HEADER_PARAMS *mtx_hdr; /* Route output elements to memory provided */ mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; SlHParams.Start_Code_Prefix_Size_Bytes = 4; - /* pcb - I think that this is more correct now*/ - SlHParams.SliceFrame_Type = bIntraSlice ? (((uiFrameNumber%(1<<5))==0) ? SLHP_IDR_SLICEFRAME_TYPE :SLHP_I_SLICEFRAME_TYPE ) : SLHP_P_SLICEFRAME_TYPE; + + if (bForceIDR || (uiFrameNumber == 0) ) + SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE; + else + SlHParams.SliceFrame_Type = bIntraSlice ? SLHP_I_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE; + + /*SlHParams.SliceFrame_Type = bIntraSlice ? (((uiFrameNumber%(1<<5))==0) ? SLHP_IDR_SLICEFRAME_TYPE :SLHP_I_SLICEFRAME_TYPE ) : SLHP_P_SLICEFRAME_TYPE;*/ SlHParams.Frame_Num_DO = (IMG_UINT8) uiFrameNumber%(1<<5); SlHParams.Picture_Num_DO = (IMG_UINT8) (SlHParams.Frame_Num_DO * 2); diff --git a/src/pnw_hostheader.h b/src/pnw_hostheader.h index 1d85604..9f77ec1 100644 --- a/src/pnw_hostheader.h +++ b/src/pnw_hostheader.h @@ -54,7 +54,13 @@ typedef enum ELEMENT_FRAMEQSCALE, /* Insert the H263/MPEG4 Frame Q_scale parameter (vob_quant field) (no rawdata) */ ELEMENT_SLICEQSCALE, /* Insert the H263/MPEG4 Slice Q_scale parameter (quant_scale field) (no rawdata) */ ELEMENT_INSERTBYTEALIGN_H264,/* Insert the byte align field (no rawdata) */ - ELEMENT_INSERTBYTEALIGN_MPG4 /* Insert the byte align field (no rawdata) */ + ELEMENT_INSERTBYTEALIGN_MPG4, /* Insert the byte align field (no rawdata) */ + + /*SEI_INSERTION*/ + BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY, + BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET, + PTH_SEI_NAL_CPB_REMOVAL_DELAY, + PTH_SEI_NAL_DPB_OUTPUT_DELAY } HEADER_ELEMENT_TYPE; @@ -81,7 +87,8 @@ typedef struct _MTX_HEADER_PARAMS_ typedef enum _SHPROFILES { SH_PROFILE_BP=0, - SH_PROFILE_MP=1 + SH_PROFILE_MP=1, + SH_PROFILE_HP=2, } SH_PROFILE_TYPE; /* Level number definitions (integer level numbers, non-intermediary only.. except level 1b) */ @@ -91,7 +98,10 @@ typedef enum _SHLEVELS SH_LEVEL_1B=111, SH_LEVEL_11=11, SH_LEVEL_12=12, + SH_LEVEL_13=13, SH_LEVEL_2=20, + SH_LEVEL_21=21, + SH_LEVEL_22=22, SH_LEVEL_3=30, SH_LEVEL_31=31, SH_LEVEL_32=32, @@ -147,6 +157,8 @@ typedef struct _H264_SEQUENCE_HEADER_PARAMS_STRUC SH_LEVEL_TYPE ucLevel; IMG_UINT8 ucWidth_in_mbs_minus1; IMG_UINT8 ucHeight_in_maps_units_minus1; + IMG_UINT8 gaps_in_frame_num_value; + IMG_UINT8 ucFrame_mbs_only_flag; IMG_UINT8 VUI_Params_Present; H264_VUI_PARAMS VUI_Params; } H264_SEQUENCE_HEADER_PARAMS; @@ -160,6 +172,8 @@ typedef struct _H264_SLICE_HEADER_PARAMS_STRUC IMG_UINT8 Frame_Num_DO; IMG_UINT8 Picture_Num_DO; IMG_UINT8 Disable_Deblocking_Filter_Idc; + IMG_INT8 iDebAlphaOffsetDiv2; + IMG_INT8 iDebBetaOffsetDiv2; } H264_SLICE_HEADER_PARAMS; @@ -237,7 +251,8 @@ void pnw__H264_prepare_slice_header( IMG_UINT32 uiFrameNumber, IMG_UINT32 uiFirst_MB_Address, IMG_UINT32 uiMBSkipRun, - IMG_BOOL bCabacEnabled); + IMG_BOOL bCabacEnabled, + IMG_BOOL bForceIDR); void pnw__H264_prepare_eodofstream_header(IMG_UINT32 *pHeaderMemory); void pnw__H264_prepare_endofpicture_header(IMG_UINT32 *pHeaderMemory); diff --git a/src/pnw_jpeg.c b/src/pnw_jpeg.c index 8642664..f970709 100644 --- a/src/pnw_jpeg.c +++ b/src/pnw_jpeg.c @@ -144,12 +144,9 @@ static VAStatus pnw_jpeg_CreateContext( if (NULL == jpeg_ctx_p->sScan_Encode_Info.aBufferTable) return VA_STATUS_ERROR_ALLOCATION_FAILED; - memset(jpeg_ctx_p->sScan_Encode_Info.aBufferTable, 0, - sizeof(TOPAZSC_JPEG_BUFFER_INFO) * jpeg_ctx_p->sScan_Encode_Info.ui8NumberOfCodedBuffers); - jpeg_ctx_p->ui32OutputWidth = ctx->Width; jpeg_ctx_p->ui32OutputHeight = ctx->Height; - + /*It will be figured out when known the size of whole coded buffer.*/ jpeg_ctx_p->ui32SizePerCodedBuffer = 0; @@ -192,7 +189,7 @@ static VAStatus pnw_jpeg_BeginPicture( int ret; pnw_cmdbuf_p cmdbuf; - psb__information_message("pnw_jpeg_BeginPicture\n"); + psb__information_message("pnw_jpeg_BeginPicture: Frame %d\n", ctx->obj_context->frame_count); ctx->src_surface = ctx->obj_context->current_render_target; @@ -215,12 +212,9 @@ static VAStatus pnw_jpeg_BeginPicture( psb_buffer_unmap(&cmdbuf->pic_params); return vaStatus; } - /*vaStatus = psb_buffer_map(&cmdbuf->slice_params, &cmdbuf->slice_params_p); - if (vaStatus) { - psb_buffer_unmap(&cmdbuf->pic_params); - psb_buffer_unmap(&cmdbuf->header_mem); - return vaStatus; - }*/ + + memset(ctx->jpeg_ctx->sScan_Encode_Info.aBufferTable, 0, + sizeof(TOPAZSC_JPEG_BUFFER_INFO) * ctx->jpeg_ctx->sScan_Encode_Info.ui8NumberOfCodedBuffers); /*Store the QMatrix data*/ ctx->jpeg_ctx->pMemInfoTableBlock = cmdbuf->pic_params_p; @@ -489,6 +483,7 @@ static VAStatus pnw_jpeg_EndPicture( return vaStatus; } + ctx->obj_context->frame_count++; return VA_STATUS_SUCCESS; } diff --git a/src/powervr_iep_lite/csc/csc2.c b/src/powervr_iep_lite/csc/csc2.c index e7176ce..d99d0dd 100644 --- a/src/powervr_iep_lite/csc/csc2.c +++ b/src/powervr_iep_lite/csc/csc2.c @@ -1,973 +1,973 @@ -/****************************************************************************** - @file : csc2.c - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - This module contains functions for calculating a 3x3 colour - space conversion matrix. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#include - -#include "img_iep_defs.h" -#include "csc2.h" -#include "csc2_data.h" -#include "fixedpointmaths.h" - -/************************************************************************************************************* - - The combined equations for a general purpose transfer (CSC combined with Procamp) are shown below: - (matrices in CAPITALS, scaler multiplies in lower case). - - As the colour primary conversions needs to be performed on RGB data, and the procamp (H/S/C) adjustment - needs to be performed on YUV data, there are 4 cases to consider. All cases have the same input and - output offsets shown in YUV to RGB. - - If no HSBC adjustment is required, leave out the conSatHue matrix, though see the RGB-RGB case - for the exception. If no primary adjustment is required, leave out the inoutPrimaries matrix, - though see YUV-YUV case for the exception. - - Where a matrix name begins with 'INOUT_', the matrix has been pre-generated to convert from one - thing to another (e.g.: from an input colour space to an output colour space, or from an input primary - to an output primary) - the 'INOUT_' matrix is just chosen from a table of pregenerated matrices - based on the user's input and output selections. - - Input and output offsets - In all cases, the input offsets are negative and account for differences in range. As the internal - range for these calculations is always 0-255 (the pre-calculated matrices are based on this internal - range), the input offsets are always either 0 (for input range 0->255), -16 (for input range 16->235), - or -48 (for input range 48->208). The same principle applies to the output ranges, but the output - offsets based on the output range are positive rather than negative (0, +16 or +48). In addition, the - user can specify a brightness value in the range -50 -> +50, which is added to the output offsets - (only the Y offset in the case of YUV output). - - ------------------------------------------------------------------------------------------------------- - CASE 1) Input YUV and output YUV: - - combinedMatrix = (outputrangeScale*OUT_TRANSFER_RGB_TO_YUV)*INOUT_PRIMARIES* - (inputrangeScale*IN_TRANSFER_YUV_TO_RGB)*CON_SAT_HUE - - An arbitrary intermediate RGB format is used to perform the primary conversion - (colour space=RGB, range=0-255). Note: The pregenerated primary conversion matrices are created - based on this arbitrary intermediate format. - - So IN_TRANSFER_YUV_TO_RGB is the same as INOUT_TRANSFER[(user defined input colour space) to RGB] - And OUT_TRANSFER_RGB_TO_YUV is the same as INOUT_TRANSFER[RGB to (user defined output colour space)] - - OPTIMISATION FOR CASE 1) - If no primaries adjustment is required (i.e.:input primary = output primary), then the equation - simplifies to: - - combinedMatrix = CON_SAT_HUE*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_YUV_TO_YUV) - ------------------------------------------------------------------------------------------------------- - - ------------------------------------------------------------------------------------------------------- - CASE 2) Input YUV and output RGB: - - combinedMatrix = INOUT_PRIMARIES*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_YUV_TO_RGB) - *CON_SAT_HUE - ------------------------------------------------------------------------------------------------------- - - ------------------------------------------------------------------------------------------------------- - CASE 3) Input RGB and output YUV - - combinedMatrix = CON_SAT_HUE*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_RGB_TO_YUV) - *INOUT_PRIMARIES - ------------------------------------------------------------------------------------------------------- - - ------------------------------------------------------------------------------------------------------- - CASE 4) Input RGB and output RGB: - - combinedMatrix = OUT_PRIMARY_BT709_TO_USER*(outputrangeScale*OUT_TRANSFER_YUV_TO_RGB)* - CON_SAT_HUE*(inputrangeScale*IN_TRANSFER_RGB_TO_YUV) - *IN_PRIMARY_USER_TO_BT709 - - An arbitrary intermediate YUV format is used to perform the H/S/C operation - (colour space=BT709, range=0-255, primary=BT709). - - So OUT_TRANSFER_YUV_TO_RGB is the same as INOUT_TRANSFER[BT709 to RGB] - And IN_TRANSFER_RGB_TO_YUV is the same as INOUT_TRANSFER[RGB to BT709] - - In addition, the primary conversion is split into two separate matrices. This is because it was - found that when doing an HSC adjustment, combining the primaries conversion in to one matrix at - either end of the equation gives slightly different results, the correct way is to convert to - the primaries used for the intermediate YUV format (BT709). - - OPTIMISATION FOR CASE 4) - If no HSBC adjustment is required the conversion to the intermediate YUV format is not - required, the two primaries matrices can be combined into one, and the equation simplifies to: - - combinedMatrix = outputrangeScale*inputrangeScale*INOUT_PRIMARIES - ------------------------------------------------------------------------------------------------------- - -*************************************************************************************************************/ - -static img_bool CSC_bAPIInitialised = IMG_FALSE; - -#define CSC_PRINT_DEBUG_INFO 0 - -#define CSC_MULTIPLY_MATRICES(pIn_a,pIn_b,pResult) FIXEDPT_MatrixMultiply(3,3,3,3,3,3,(img_int32*)&((pIn_a)->ai32Coefficients),(img_int32*)&((pIn_b)->ai32Coefficients),(img_int32*)&((pResult)->ai32Coefficients),CSC_FRACTIONAL_BITS) - -img_result CSC_GenerateHSCMatrix ( CSC_psHSBCSettings psHSBCSettings, - CSC_ps3x3Matrix psHSCMatrix ); - -#if CSC_PRINT_DEBUG_INFO - img_void CSC_PRINT_3x3_MATRIX ( CSC_ps3x3Matrix psMatrix ) - { - img_uint32 ui32Row; - img_uint32 ui32Column; - - IMG_ASSERT ( psMatrix != IMG_NULL ); - - for ( ui32Row=0; ui32Row<3; ui32Row++ ) - { - printf ( "(" ); - for ( ui32Column=0; ui32Column<3; ui32Column++ ) - { - printf ( "%f", (((img_float) psMatrix->ai32Coefficients [ui32Row][ui32Column]) / (1 << CSC_FRACTIONAL_BITS)) ); - - if ( ui32Column != 2 ) - { - printf ( ", " ); - } - else - { - printf ( ")\n" ); - } - } - } - } -#endif - -img_result CSC_GenerateMatrix ( CSC_eColourSpace eInputColourSpace, - CSC_eColourSpace eOutputColourSpace, - CSC_eRange eInputRange, - CSC_eRange eOutputRange, - CSC_eColourPrimary eInputPrimary, - CSC_eColourPrimary eOutputPrimary, - CSC_psHSBCSettings psHSBCSettings, - CSC_psConfiguration psResultantConfigurationData ) -{ - CSC_s3x3Matrix sCombinedRangeScaleMatrix; - CSC_s3x3Matrix sInputRangeScaleMatrix; - CSC_s3x3Matrix sOutputRangeScaleMatrix; - CSC_s3x3Matrix sScaledMatrix; - CSC_s3x3Matrix sHSCMatrix; - img_int32 i32InvertedScaleFactor; - img_int32 i32FirstColumnValue_In; - img_int32 i32SecondAndThirdColumnValue_In; - img_int32 i32FirstColumnValue_Out; - img_int32 i32SecondAndThirdColumnValue_Out; - img_int32 i32InputYOffset; - img_int32 i32InputUVOffset; - img_int32 i32OutputYOffset; - img_int32 i32OutputUVOffset; - - CSC_sColourSpaceConversionMatrix * psThisColourSpaceConversion; - CSC_sColourPrimaryConversionMatrix * psThisColourPrimaryConversion; - CSC_s3x3Matrix * psCombinedRangeScaleMatrix; - CSC_s3x3Matrix * psInputRangeScaleMatrix; - CSC_s3x3Matrix * psOutputRangeScaleMatrix; - CSC_s3x3Matrix * psScaledMatrix; - - /* We need to keep two result matrices, as the matrix multiply function will not allow us to use a given */ - /* matrix as both an input and an output. */ - CSC_s3x3Matrix sResultMatrices [2]; - - CSC_ps3x3Matrix psLatestResult = IMG_NULL; - img_uint8 ui8FreeResultMatrix = 0; /* Index to currently unused member of 'sResultMatrices' */ - - IMG_ASSERT ( psResultantConfigurationData != IMG_NULL ); - IMG_ASSERT ( eInputColourSpace < CSC_NO_OF_COLOURSPACES ); - IMG_ASSERT ( eOutputColourSpace < CSC_NO_OF_COLOURSPACES ); - - if ( CSC_bAPIInitialised == IMG_FALSE ) - { - /* Safety check static data */ - csc_StaticDataSafetyCheck (); - - CSC_bAPIInitialised = IMG_TRUE; - } - - /* Calculate scaling matrices */ - - /* For both input and output ranges, if we are dealing with RGB */ - /* then all columns of the scalar matrix are set to identical */ - /* values. If we are dealing with YUV, then the left hand */ - /* column is the Y scaling value, while the middle and right */ - /* hand columns are the UV scaling values. */ - - /* Input range scaling */ - if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) - { - i32FirstColumnValue_In = asCSC_RangeInfo [eInputRange].i32YScale; - i32SecondAndThirdColumnValue_In = asCSC_RangeInfo [eInputRange].i32UVScale; - } - else - { - i32FirstColumnValue_In = asCSC_RangeInfo [eInputRange].i32RGBScale; - i32SecondAndThirdColumnValue_In = i32FirstColumnValue_In; - } - - if (( i32FirstColumnValue_In == CSC_FP(1.0) ) && - ( i32SecondAndThirdColumnValue_In == CSC_FP(1.0) )) - { - psInputRangeScaleMatrix = IMG_NULL; - } - else - { - /* Complete input scaling matrix */ - sInputRangeScaleMatrix.ai32Coefficients[0][0]=i32FirstColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[1][0]=i32FirstColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[2][0]=i32FirstColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[0][1]=i32SecondAndThirdColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[1][1]=i32SecondAndThirdColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[2][1]=i32SecondAndThirdColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[0][2]=i32SecondAndThirdColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[1][2]=i32SecondAndThirdColumnValue_In; - sInputRangeScaleMatrix.ai32Coefficients[2][2]=i32SecondAndThirdColumnValue_In; - - psInputRangeScaleMatrix = &sInputRangeScaleMatrix; - } - - /* Output range scaling - output scale values are inverted (e.g.: */ - /* if a given range requires that RGB values be scaled by a factor */ - /* of 255/219 on the inputs, then the scaling range for the same */ - /* range selected as an output will be 219/255). */ - if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) - { - if ( asCSC_RangeInfo [eOutputRange].i32YScale == CSC_FP(1.0) ) - { - i32InvertedScaleFactor = asCSC_RangeInfo [eOutputRange].i32YScale; - } - else - { - i32InvertedScaleFactor = FIXEDPT_64BitDivide_Signed( (1<primary conversion is supported */ - psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[eInputPrimary][eOutputPrimary]); - IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); - - if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) - { - if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) - { - /****************************/ - /* CASE 1 */ - /* Input YUV, Output YUV */ - /****************************/ - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_TRUE ) - { - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Optimised form of case 1, Input YUV/Output YUV\n" ); - #endif - - /* Case 1 optimisation */ - /* Can simplify equation, as we don't need to convert to RGB to do primary calculations */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if ( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) - { - psLatestResult = &(psThisColourSpaceConversion->sMatrix); - } - - /* Apply scaling */ - if ( psCombinedRangeScaleMatrix != IMG_NULL ) - { - if ( psLatestResult == IMG_NULL ) - { - /* We need a matrix to scale - in the absence of anything else, use the identity matrix */ - psLatestResult = &sCSC_IdentityMatrix; - } - - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(psLatestResult->ai32Coefficients), - (img_int32 *) (&(sResultMatrices[ui8FreeResultMatrix].ai32Coefficients)), - CSC_FRACTIONAL_BITS ); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - - /* Perform con/sat/hue calculations */ - if ( psHSBCSettings != IMG_NULL ) - { - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = &sHSCMatrix; - } - } - } - else - { - /* Non optimised form of case 1 */ - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Case 1, Input YUV/Output YUV\n" ); - #endif - - /* Perform con/sat/hue calculations */ - if ( psHSBCSettings != IMG_NULL ) - { - psLatestResult = &sHSCMatrix; - } - - /* We must convert to RGB prior to performing primary calculations */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][CSC_COLOURSPACE_RGB]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psInputRangeScaleMatrix != IMG_NULL )) - { - if ( psInputRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psInputRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = psScaledMatrix; - } - } - - /* Now multiply by primaries (we have already covered the identity matrix case, above) */ - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); - } - - /* Should definitely have an intermediate matrix by now */ - IMG_ASSERT ( psLatestResult != IMG_NULL ); - - /* Now convert back to YUV */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[CSC_COLOURSPACE_RGB][eOutputColourSpace]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psOutputRangeScaleMatrix != IMG_NULL )) - { - if ( psOutputRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of OUT_TRANSFER_RGB_TO_YUV matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psOutputRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - } - } - else - { - /****************************/ - /* CASE 2 */ - /* Input YUV, Output RGB */ - /****************************/ - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Case 2, Input YUV/Output RGB\n" ); - #endif - - /* Perform con/sat/hue calculations */ - if ( psHSBCSettings != IMG_NULL ) - { - psLatestResult = &sHSCMatrix; - } - - /* Perform colour space conversion */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psCombinedRangeScaleMatrix != IMG_NULL )) - { - if ( psCombinedRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = psScaledMatrix; - } - } - - /* Now perform colour primary conversion */ - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) - { - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); - } - } - } - } - else - { - if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) - { - /****************************/ - /* CASE 3 */ - /* Input RGB, Output YUV */ - /****************************/ - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Case 3, Input RGB/Output YUV\n" ); - #endif - - /* Perform colour primary conversion */ - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) - { - psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); - } - - /* Now perform colour space conversion */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psCombinedRangeScaleMatrix != IMG_NULL )) - { - if ( psCombinedRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = psScaledMatrix; - } - } - - /* Perform con/sat/hue calculations */ - if ( psHSBCSettings != IMG_NULL ) - { - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = &sHSCMatrix; - } - } - } - else - { - /****************************/ - /* CASE 4 */ - /* Input RGB, Output RGB */ - /****************************/ - - /* If no HSBC modification, then the equation can be simplified */ - if ( psHSBCSettings == IMG_NULL ) - { - /* Optimised case 4 */ - /* As no HSBC information has been provided, the equation can be simplified */ - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Optimised form of case 4, Input RGB/Output RGB\n" ); - #endif - - /* Perform colour primary conversion */ - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) - { - psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); - } - - /* Scale result */ - if ( psCombinedRangeScaleMatrix != IMG_NULL ) - { - /* If there is no result to work with (to scale) then just use the identity matrix */ - if ( psLatestResult == IMG_NULL ) - { - psLatestResult = &sCSC_IdentityMatrix; - } - - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) (&(psLatestResult->ai32Coefficients)), - (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - - psLatestResult = &sScaledMatrix; - } - } - else - { - /* Non optimised form of case 4 */ - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC - Case 4, Input RGB/Output RGB\n" ); - #endif - - /* Perform colour primary conversion - when HSBC modification is also being performed, */ - /* this must be performed in two steps, so that the HSBC modification is performed in */ - /* a fixed format (BT709 in the case of this algorithm). */ - psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[eInputPrimary][CSC_COLOUR_PRIMARY_BT709]); - IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); - - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) - { - psLatestResult = &(psThisColourPrimaryConversion->sMatrix); - } - - /* We must convert to YUV prior to performing con/sat/hue calculations */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][CSC_COLOURSPACE_YCC_BT709]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psInputRangeScaleMatrix != IMG_NULL )) - { - if ( psInputRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psInputRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = psScaledMatrix; - } - } - - /* Perform con/sat/hue calculations */ - IMG_ASSERT ( psHSBCSettings != IMG_NULL ); /* There is an optimised case for dealing with no HSBC input - see above */ - - if ( psLatestResult != IMG_NULL ) - { - CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - else - { - psLatestResult = &sHSCMatrix; - } - - /* Should definitely have an intermediate matrix by now */ - IMG_ASSERT ( psLatestResult != IMG_NULL ); - - /* Now convert back to RGB */ - psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[CSC_COLOURSPACE_YCC_BT709][eOutputColourSpace]); - IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); - if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || - ( psOutputRangeScaleMatrix != IMG_NULL )) - { - if ( psOutputRangeScaleMatrix != IMG_NULL ) - { - /* Produce scaled version of OUT_TRANSFER_RGB_TO_YUV matrix */ - FIXEDPT_ScalarMatrixMultiply ( 3, 3, - (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), - (img_int32 *) &(psOutputRangeScaleMatrix->ai32Coefficients), - (img_int32 *) &(sScaledMatrix.ai32Coefficients), - CSC_FRACTIONAL_BITS ); - psScaledMatrix = &sScaledMatrix; - } - else - { - psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); - } - - /* Now merge latest result with scaled matrix */ - CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - - /* Now convert to the requested output primary */ - psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[CSC_COLOUR_PRIMARY_BT709][eOutputPrimary]); - IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); - - if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) - { - CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); - psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); - ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ - } - } - } - } - - /* Entire calculation resulted in no result - use identity matrix */ - if ( psLatestResult == IMG_NULL ) - { - #if CSC_PRINT_DEBUG_INFO - printf ( "\nCSC final output defaulting to identity matrix\n" ); - #endif - - psLatestResult = &sCSC_IdentityMatrix; - } - - #if CSC_PRINT_DEBUG_INFO - printf ( "\nFinal CSC matrix :\n" ); - CSC_PRINT_3x3_MATRIX(psLatestResult); - #endif - - /* Now copy the final results into the user supplied matrix */ - IMG_MEMCPY ( &(psResultantConfigurationData->sCoefficients), - psLatestResult, - sizeof(CSC_s3x3Matrix) ); - - /* Finally, calculate input and output offsets */ - if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) - { - i32InputYOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32YOffset; - i32InputUVOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32UVOffset; - } - else - { - i32InputYOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32RGBOffset; - i32InputUVOffset = i32InputYOffset; - } - - if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) - { - i32OutputYOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32YOffset; - i32OutputUVOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32UVOffset; - } - else - { - i32OutputYOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32RGBOffset; - i32OutputUVOffset = i32OutputYOffset; - } - - /* Output offsets are specified with a fractional part */ - i32OutputYOffset = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(i32OutputYOffset,0,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS); - i32OutputUVOffset = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(i32OutputUVOffset,0,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS); - - if ( psHSBCSettings != IMG_NULL ) - { - i32OutputYOffset += psHSBCSettings->i32Brightness; - - /* For YUV outputs, brightness is only applied to the Y output */ - if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_FALSE ) - { - i32OutputUVOffset += psHSBCSettings->i32Brightness; - } - } - - /* Copy offsets into user provided structure */ - psResultantConfigurationData->ai32InputOffsets[0] = i32InputYOffset; - psResultantConfigurationData->ai32InputOffsets[1] = i32InputUVOffset; - psResultantConfigurationData->ai32InputOffsets[2] = i32InputUVOffset; - - psResultantConfigurationData->ai32OutputOffsets[0] = i32OutputYOffset; - psResultantConfigurationData->ai32OutputOffsets[1] = i32OutputUVOffset; - psResultantConfigurationData->ai32OutputOffsets[2] = i32OutputUVOffset; - - #if CSC_PRINT_DEBUG_INFO - printf ( "\nInput offsets:\n" ); - printf ( " [0] %03i\n", psResultantConfigurationData->ai32InputOffsets[0] ); - printf ( " [1] %03i\n", psResultantConfigurationData->ai32InputOffsets[1] ); - printf ( " [2] %03i\n", psResultantConfigurationData->ai32InputOffsets[2] ); - - printf ( "\nOutput offsets:\n" ); - printf ( " [0] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[0]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); - printf ( " [1] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[1]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); - printf ( " [2] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[2]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); - #endif - - return IMG_SUCCESS; -}; - -img_result CSC_GenerateHSCMatrix ( CSC_psHSBCSettings psHSBCSettings, - CSC_ps3x3Matrix psHSCMatrix ) -{ - img_int32 i32CosHue; - img_int32 i32SinHue; - img_int32 i32HueInRadians; - img_int32 i32ContrastTimesSaturation; - - IMG_ASSERT ( psHSBCSettings != IMG_NULL ); - IMG_ASSERT ( psHSCMatrix != IMG_NULL ); - - /* Check all supplied values are in range */ - IMG_ASSERT ( psHSBCSettings->i32Hue <= CSC_MAX_HUE ); - IMG_ASSERT ( psHSBCSettings->i32Hue >= CSC_MIN_HUE ); - IMG_ASSERT ( psHSBCSettings->i32Saturation <= CSC_MAX_SATURATION ); - IMG_ASSERT ( psHSBCSettings->i32Saturation >= CSC_MIN_SATURATION ); - IMG_ASSERT ( psHSBCSettings->i32Brightness <= CSC_MAX_BRIGHTNESS ); - IMG_ASSERT ( psHSBCSettings->i32Brightness >= CSC_MIN_BRIGHTNESS ); - IMG_ASSERT ( psHSBCSettings->i32Contrast <= CSC_MAX_CONTRAST ); - IMG_ASSERT ( psHSBCSettings->i32Contrast >= CSC_MIN_CONTRAST ); - - /* conSatHue matrix is constructed as follows : */ - /* */ - /* [ con, 0, 0 ] */ - /* [ 0, (con*sat*cos(hue)), (con*sat*sin(hue)) ] */ - /* [ 0, -(con*sat*cos(hue)), (con*sat*cos(hue)) ] */ - - /* Generate some useful values */ - i32HueInRadians = psHSBCSettings->i32Hue; - if ( i32HueInRadians < 0 ) - { - i32HueInRadians = i32HueInRadians * -1; - } - i32HueInRadians = FIXEDPT_64BitMultiply_Signed ( (img_int32) FIXEDPT_ONE_DEGREE_IN_RADIANS, /* x.FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS */ - i32HueInRadians, /* x.CSC_HSC_FRACTIONAL_BITS */ - CSC_HSC_FRACTIONAL_BITS ); /* Result is in x.FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS format */ - - i32CosHue = FIXEDPT_Cosine( (img_uint32) i32HueInRadians ); /* Cosine is symmetrical about 0 degrees, hence cos(theta)=cos(-theta) */ - i32CosHue = FIXEDPT_CONVERT_FRACTIONAL_BITS(i32CosHue,FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); - - i32SinHue = FIXEDPT_Sine( (img_uint32) i32HueInRadians ); /* Sine is not symmetrical, however sin(theta)=-1 * sin(-theta) */ - if ( psHSBCSettings->i32Hue < 0 ) - { - i32SinHue = -1 * i32SinHue; - } - i32SinHue = FIXEDPT_CONVERT_FRACTIONAL_BITS(i32SinHue,FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); - - i32ContrastTimesSaturation = FIXEDPT_64BitMultiply_Signed ( psHSBCSettings->i32Contrast, - psHSBCSettings->i32Saturation, - ((2*CSC_HSC_FRACTIONAL_BITS)-CSC_FRACTIONAL_BITS) ); /* Result is in x.CSC_FRACTIONAL_BITS format */ - - /* Now complete matrix */ - /* Row 0 */ - psHSCMatrix->ai32Coefficients [0][0] = FIXEDPT_CONVERT_FRACTIONAL_BITS(psHSBCSettings->i32Contrast,CSC_HSC_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); - psHSCMatrix->ai32Coefficients [0][1] = 0; - psHSCMatrix->ai32Coefficients [0][2] = 0; - - /* Row 1 */ - psHSCMatrix->ai32Coefficients [1][0] = 0; - psHSCMatrix->ai32Coefficients [1][1] = FIXEDPT_64BitMultiply_Signed ( i32ContrastTimesSaturation, - i32CosHue, - CSC_FRACTIONAL_BITS ); /* Result is in x.CSC_FRACTIONAL_BITS format */ - psHSCMatrix->ai32Coefficients [1][2] = FIXEDPT_64BitMultiply_Signed ( i32ContrastTimesSaturation, - i32SinHue, - CSC_FRACTIONAL_BITS ); /* Result is in x.CSC_FRACTIONAL_BITS format */ - - /* Row 2 */ - psHSCMatrix->ai32Coefficients [2][0] = 0; - psHSCMatrix->ai32Coefficients [2][1] = -1 * psHSCMatrix->ai32Coefficients [1][2]; - psHSCMatrix->ai32Coefficients [2][2] = psHSCMatrix->ai32Coefficients [1][1]; - - #if CSC_PRINT_DEBUG_INFO - printf ( "\nHSC matrix :\n" ); - CSC_PRINT_3x3_MATRIX(psHSCMatrix); - #endif - - return IMG_SUCCESS; -} +/****************************************************************************** + @file : csc2.c + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + This module contains functions for calculating a 3x3 colour + space conversion matrix. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#include + +#include "img_iep_defs.h" +#include "csc2.h" +#include "csc2_data.h" +#include "fixedpointmaths.h" + +/************************************************************************************************************* + + The combined equations for a general purpose transfer (CSC combined with Procamp) are shown below: + (matrices in CAPITALS, scaler multiplies in lower case). + + As the colour primary conversions needs to be performed on RGB data, and the procamp (H/S/C) adjustment + needs to be performed on YUV data, there are 4 cases to consider. All cases have the same input and + output offsets shown in YUV to RGB. + + If no HSBC adjustment is required, leave out the conSatHue matrix, though see the RGB-RGB case + for the exception. If no primary adjustment is required, leave out the inoutPrimaries matrix, + though see YUV-YUV case for the exception. + + Where a matrix name begins with 'INOUT_', the matrix has been pre-generated to convert from one + thing to another (e.g.: from an input colour space to an output colour space, or from an input primary + to an output primary) - the 'INOUT_' matrix is just chosen from a table of pregenerated matrices + based on the user's input and output selections. + + Input and output offsets + In all cases, the input offsets are negative and account for differences in range. As the internal + range for these calculations is always 0-255 (the pre-calculated matrices are based on this internal + range), the input offsets are always either 0 (for input range 0->255), -16 (for input range 16->235), + or -48 (for input range 48->208). The same principle applies to the output ranges, but the output + offsets based on the output range are positive rather than negative (0, +16 or +48). In addition, the + user can specify a brightness value in the range -50 -> +50, which is added to the output offsets + (only the Y offset in the case of YUV output). + + ------------------------------------------------------------------------------------------------------- + CASE 1) Input YUV and output YUV: + + combinedMatrix = (outputrangeScale*OUT_TRANSFER_RGB_TO_YUV)*INOUT_PRIMARIES* + (inputrangeScale*IN_TRANSFER_YUV_TO_RGB)*CON_SAT_HUE + + An arbitrary intermediate RGB format is used to perform the primary conversion + (colour space=RGB, range=0-255). Note: The pregenerated primary conversion matrices are created + based on this arbitrary intermediate format. + + So IN_TRANSFER_YUV_TO_RGB is the same as INOUT_TRANSFER[(user defined input colour space) to RGB] + And OUT_TRANSFER_RGB_TO_YUV is the same as INOUT_TRANSFER[RGB to (user defined output colour space)] + + OPTIMISATION FOR CASE 1) + If no primaries adjustment is required (i.e.:input primary = output primary), then the equation + simplifies to: + + combinedMatrix = CON_SAT_HUE*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_YUV_TO_YUV) + ------------------------------------------------------------------------------------------------------- + + ------------------------------------------------------------------------------------------------------- + CASE 2) Input YUV and output RGB: + + combinedMatrix = INOUT_PRIMARIES*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_YUV_TO_RGB) + *CON_SAT_HUE + ------------------------------------------------------------------------------------------------------- + + ------------------------------------------------------------------------------------------------------- + CASE 3) Input RGB and output YUV + + combinedMatrix = CON_SAT_HUE*(outputrangeScale*inputrangeScale*INOUT_TRANSFER_RGB_TO_YUV) + *INOUT_PRIMARIES + ------------------------------------------------------------------------------------------------------- + + ------------------------------------------------------------------------------------------------------- + CASE 4) Input RGB and output RGB: + + combinedMatrix = OUT_PRIMARY_BT709_TO_USER*(outputrangeScale*OUT_TRANSFER_YUV_TO_RGB)* + CON_SAT_HUE*(inputrangeScale*IN_TRANSFER_RGB_TO_YUV) + *IN_PRIMARY_USER_TO_BT709 + + An arbitrary intermediate YUV format is used to perform the H/S/C operation + (colour space=BT709, range=0-255, primary=BT709). + + So OUT_TRANSFER_YUV_TO_RGB is the same as INOUT_TRANSFER[BT709 to RGB] + And IN_TRANSFER_RGB_TO_YUV is the same as INOUT_TRANSFER[RGB to BT709] + + In addition, the primary conversion is split into two separate matrices. This is because it was + found that when doing an HSC adjustment, combining the primaries conversion in to one matrix at + either end of the equation gives slightly different results, the correct way is to convert to + the primaries used for the intermediate YUV format (BT709). + + OPTIMISATION FOR CASE 4) + If no HSBC adjustment is required the conversion to the intermediate YUV format is not + required, the two primaries matrices can be combined into one, and the equation simplifies to: + + combinedMatrix = outputrangeScale*inputrangeScale*INOUT_PRIMARIES + ------------------------------------------------------------------------------------------------------- + +*************************************************************************************************************/ + +static img_bool CSC_bAPIInitialised = IMG_FALSE; + +#define CSC_PRINT_DEBUG_INFO 0 + +#define CSC_MULTIPLY_MATRICES(pIn_a,pIn_b,pResult) FIXEDPT_MatrixMultiply(3,3,3,3,3,3,(img_int32*)&((pIn_a)->ai32Coefficients),(img_int32*)&((pIn_b)->ai32Coefficients),(img_int32*)&((pResult)->ai32Coefficients),CSC_FRACTIONAL_BITS) + +img_result CSC_GenerateHSCMatrix ( CSC_psHSBCSettings psHSBCSettings, + CSC_ps3x3Matrix psHSCMatrix ); + +#if CSC_PRINT_DEBUG_INFO + img_void CSC_PRINT_3x3_MATRIX ( CSC_ps3x3Matrix psMatrix ) + { + img_uint32 ui32Row; + img_uint32 ui32Column; + + IMG_ASSERT ( psMatrix != IMG_NULL ); + + for ( ui32Row=0; ui32Row<3; ui32Row++ ) + { + printf ( "(" ); + for ( ui32Column=0; ui32Column<3; ui32Column++ ) + { + printf ( "%f", (((img_float) psMatrix->ai32Coefficients [ui32Row][ui32Column]) / (1 << CSC_FRACTIONAL_BITS)) ); + + if ( ui32Column != 2 ) + { + printf ( ", " ); + } + else + { + printf ( ")\n" ); + } + } + } + } +#endif + +img_result CSC_GenerateMatrix ( CSC_eColourSpace eInputColourSpace, + CSC_eColourSpace eOutputColourSpace, + CSC_eRange eInputRange, + CSC_eRange eOutputRange, + CSC_eColourPrimary eInputPrimary, + CSC_eColourPrimary eOutputPrimary, + CSC_psHSBCSettings psHSBCSettings, + CSC_psConfiguration psResultantConfigurationData ) +{ + CSC_s3x3Matrix sCombinedRangeScaleMatrix; + CSC_s3x3Matrix sInputRangeScaleMatrix; + CSC_s3x3Matrix sOutputRangeScaleMatrix; + CSC_s3x3Matrix sScaledMatrix; + CSC_s3x3Matrix sHSCMatrix; + img_int32 i32InvertedScaleFactor; + img_int32 i32FirstColumnValue_In; + img_int32 i32SecondAndThirdColumnValue_In; + img_int32 i32FirstColumnValue_Out; + img_int32 i32SecondAndThirdColumnValue_Out; + img_int32 i32InputYOffset; + img_int32 i32InputUVOffset; + img_int32 i32OutputYOffset; + img_int32 i32OutputUVOffset; + + CSC_sColourSpaceConversionMatrix * psThisColourSpaceConversion; + CSC_sColourPrimaryConversionMatrix * psThisColourPrimaryConversion; + CSC_s3x3Matrix * psCombinedRangeScaleMatrix; + CSC_s3x3Matrix * psInputRangeScaleMatrix; + CSC_s3x3Matrix * psOutputRangeScaleMatrix; + CSC_s3x3Matrix * psScaledMatrix; + + /* We need to keep two result matrices, as the matrix multiply function will not allow us to use a given */ + /* matrix as both an input and an output. */ + CSC_s3x3Matrix sResultMatrices [2]; + + CSC_ps3x3Matrix psLatestResult = IMG_NULL; + img_uint8 ui8FreeResultMatrix = 0; /* Index to currently unused member of 'sResultMatrices' */ + + IMG_ASSERT ( psResultantConfigurationData != IMG_NULL ); + IMG_ASSERT ( eInputColourSpace < CSC_NO_OF_COLOURSPACES ); + IMG_ASSERT ( eOutputColourSpace < CSC_NO_OF_COLOURSPACES ); + + if ( CSC_bAPIInitialised == IMG_FALSE ) + { + /* Safety check static data */ + csc_StaticDataSafetyCheck (); + + CSC_bAPIInitialised = IMG_TRUE; + } + + /* Calculate scaling matrices */ + + /* For both input and output ranges, if we are dealing with RGB */ + /* then all columns of the scalar matrix are set to identical */ + /* values. If we are dealing with YUV, then the left hand */ + /* column is the Y scaling value, while the middle and right */ + /* hand columns are the UV scaling values. */ + + /* Input range scaling */ + if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) + { + i32FirstColumnValue_In = asCSC_RangeInfo [eInputRange].i32YScale; + i32SecondAndThirdColumnValue_In = asCSC_RangeInfo [eInputRange].i32UVScale; + } + else + { + i32FirstColumnValue_In = asCSC_RangeInfo [eInputRange].i32RGBScale; + i32SecondAndThirdColumnValue_In = i32FirstColumnValue_In; + } + + if (( i32FirstColumnValue_In == CSC_FP(1.0) ) && + ( i32SecondAndThirdColumnValue_In == CSC_FP(1.0) )) + { + psInputRangeScaleMatrix = IMG_NULL; + } + else + { + /* Complete input scaling matrix */ + sInputRangeScaleMatrix.ai32Coefficients[0][0]=i32FirstColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[1][0]=i32FirstColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[2][0]=i32FirstColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[0][1]=i32SecondAndThirdColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[1][1]=i32SecondAndThirdColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[2][1]=i32SecondAndThirdColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[0][2]=i32SecondAndThirdColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[1][2]=i32SecondAndThirdColumnValue_In; + sInputRangeScaleMatrix.ai32Coefficients[2][2]=i32SecondAndThirdColumnValue_In; + + psInputRangeScaleMatrix = &sInputRangeScaleMatrix; + } + + /* Output range scaling - output scale values are inverted (e.g.: */ + /* if a given range requires that RGB values be scaled by a factor */ + /* of 255/219 on the inputs, then the scaling range for the same */ + /* range selected as an output will be 219/255). */ + if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) + { + if ( asCSC_RangeInfo [eOutputRange].i32YScale == CSC_FP(1.0) ) + { + i32InvertedScaleFactor = asCSC_RangeInfo [eOutputRange].i32YScale; + } + else + { + i32InvertedScaleFactor = FIXEDPT_64BitDivide_Signed( (1<primary conversion is supported */ + psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[eInputPrimary][eOutputPrimary]); + IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); + + if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) + { + if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) + { + /****************************/ + /* CASE 1 */ + /* Input YUV, Output YUV */ + /****************************/ + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_TRUE ) + { + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Optimised form of case 1, Input YUV/Output YUV\n" ); + #endif + + /* Case 1 optimisation */ + /* Can simplify equation, as we don't need to convert to RGB to do primary calculations */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if ( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) + { + psLatestResult = &(psThisColourSpaceConversion->sMatrix); + } + + /* Apply scaling */ + if ( psCombinedRangeScaleMatrix != IMG_NULL ) + { + if ( psLatestResult == IMG_NULL ) + { + /* We need a matrix to scale - in the absence of anything else, use the identity matrix */ + psLatestResult = &sCSC_IdentityMatrix; + } + + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(psLatestResult->ai32Coefficients), + (img_int32 *) (&(sResultMatrices[ui8FreeResultMatrix].ai32Coefficients)), + CSC_FRACTIONAL_BITS ); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + + /* Perform con/sat/hue calculations */ + if ( psHSBCSettings != IMG_NULL ) + { + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = &sHSCMatrix; + } + } + } + else + { + /* Non optimised form of case 1 */ + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Case 1, Input YUV/Output YUV\n" ); + #endif + + /* Perform con/sat/hue calculations */ + if ( psHSBCSettings != IMG_NULL ) + { + psLatestResult = &sHSCMatrix; + } + + /* We must convert to RGB prior to performing primary calculations */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][CSC_COLOURSPACE_RGB]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psInputRangeScaleMatrix != IMG_NULL )) + { + if ( psInputRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psInputRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = psScaledMatrix; + } + } + + /* Now multiply by primaries (we have already covered the identity matrix case, above) */ + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); + } + + /* Should definitely have an intermediate matrix by now */ + IMG_ASSERT ( psLatestResult != IMG_NULL ); + + /* Now convert back to YUV */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[CSC_COLOURSPACE_RGB][eOutputColourSpace]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psOutputRangeScaleMatrix != IMG_NULL )) + { + if ( psOutputRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of OUT_TRANSFER_RGB_TO_YUV matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psOutputRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + } + } + else + { + /****************************/ + /* CASE 2 */ + /* Input YUV, Output RGB */ + /****************************/ + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Case 2, Input YUV/Output RGB\n" ); + #endif + + /* Perform con/sat/hue calculations */ + if ( psHSBCSettings != IMG_NULL ) + { + psLatestResult = &sHSCMatrix; + } + + /* Perform colour space conversion */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psCombinedRangeScaleMatrix != IMG_NULL )) + { + if ( psCombinedRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = psScaledMatrix; + } + } + + /* Now perform colour primary conversion */ + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) + { + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); + } + } + } + } + else + { + if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) + { + /****************************/ + /* CASE 3 */ + /* Input RGB, Output YUV */ + /****************************/ + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Case 3, Input RGB/Output YUV\n" ); + #endif + + /* Perform colour primary conversion */ + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) + { + psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); + } + + /* Now perform colour space conversion */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][eOutputColourSpace]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psCombinedRangeScaleMatrix != IMG_NULL )) + { + if ( psCombinedRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = psScaledMatrix; + } + } + + /* Perform con/sat/hue calculations */ + if ( psHSBCSettings != IMG_NULL ) + { + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = &sHSCMatrix; + } + } + } + else + { + /****************************/ + /* CASE 4 */ + /* Input RGB, Output RGB */ + /****************************/ + + /* If no HSBC modification, then the equation can be simplified */ + if ( psHSBCSettings == IMG_NULL ) + { + /* Optimised case 4 */ + /* As no HSBC information has been provided, the equation can be simplified */ + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Optimised form of case 4, Input RGB/Output RGB\n" ); + #endif + + /* Perform colour primary conversion */ + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) + { + psLatestResult = (&(psThisColourPrimaryConversion->sMatrix)); + } + + /* Scale result */ + if ( psCombinedRangeScaleMatrix != IMG_NULL ) + { + /* If there is no result to work with (to scale) then just use the identity matrix */ + if ( psLatestResult == IMG_NULL ) + { + psLatestResult = &sCSC_IdentityMatrix; + } + + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) (&(psLatestResult->ai32Coefficients)), + (img_int32 *) &(psCombinedRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + + psLatestResult = &sScaledMatrix; + } + } + else + { + /* Non optimised form of case 4 */ + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC - Case 4, Input RGB/Output RGB\n" ); + #endif + + /* Perform colour primary conversion - when HSBC modification is also being performed, */ + /* this must be performed in two steps, so that the HSBC modification is performed in */ + /* a fixed format (BT709 in the case of this algorithm). */ + psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[eInputPrimary][CSC_COLOUR_PRIMARY_BT709]); + IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); + + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) + { + psLatestResult = &(psThisColourPrimaryConversion->sMatrix); + } + + /* We must convert to YUV prior to performing con/sat/hue calculations */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[eInputColourSpace][CSC_COLOURSPACE_YCC_BT709]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psInputRangeScaleMatrix != IMG_NULL )) + { + if ( psInputRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of IN_TRANSFER_YUV_TO_RGB matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psInputRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = psScaledMatrix; + } + } + + /* Perform con/sat/hue calculations */ + IMG_ASSERT ( psHSBCSettings != IMG_NULL ); /* There is an optimised case for dealing with no HSBC input - see above */ + + if ( psLatestResult != IMG_NULL ) + { + CSC_MULTIPLY_MATRICES((&sHSCMatrix),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + else + { + psLatestResult = &sHSCMatrix; + } + + /* Should definitely have an intermediate matrix by now */ + IMG_ASSERT ( psLatestResult != IMG_NULL ); + + /* Now convert back to RGB */ + psThisColourSpaceConversion = &(asCSC_ColourSpaceConversionMatrices[CSC_COLOURSPACE_YCC_BT709][eOutputColourSpace]); + IMG_ASSERT ( psThisColourSpaceConversion->bIsSupported == IMG_TRUE ); + if (( psThisColourSpaceConversion->bIsIdentityMatrix == IMG_FALSE ) || + ( psOutputRangeScaleMatrix != IMG_NULL )) + { + if ( psOutputRangeScaleMatrix != IMG_NULL ) + { + /* Produce scaled version of OUT_TRANSFER_RGB_TO_YUV matrix */ + FIXEDPT_ScalarMatrixMultiply ( 3, 3, + (img_int32 *) &(psThisColourSpaceConversion->sMatrix.ai32Coefficients), + (img_int32 *) &(psOutputRangeScaleMatrix->ai32Coefficients), + (img_int32 *) &(sScaledMatrix.ai32Coefficients), + CSC_FRACTIONAL_BITS ); + psScaledMatrix = &sScaledMatrix; + } + else + { + psScaledMatrix = &(psThisColourSpaceConversion->sMatrix); + } + + /* Now merge latest result with scaled matrix */ + CSC_MULTIPLY_MATRICES(psScaledMatrix,psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + + /* Now convert to the requested output primary */ + psThisColourPrimaryConversion = &(asCSCColourPrimaryConversionMatrices[CSC_COLOUR_PRIMARY_BT709][eOutputPrimary]); + IMG_ASSERT ( psThisColourPrimaryConversion->bIsSupported == IMG_TRUE ); + + if ( psThisColourPrimaryConversion->bIsIdentityMatrix == IMG_FALSE ) + { + CSC_MULTIPLY_MATRICES((&(psThisColourPrimaryConversion->sMatrix)),psLatestResult,(&(sResultMatrices[ui8FreeResultMatrix]))); + psLatestResult = &(sResultMatrices[ui8FreeResultMatrix]); + ui8FreeResultMatrix = (1 - ui8FreeResultMatrix); /* Swap 'free result matrix' index */ + } + } + } + } + + /* Entire calculation resulted in no result - use identity matrix */ + if ( psLatestResult == IMG_NULL ) + { + #if CSC_PRINT_DEBUG_INFO + printf ( "\nCSC final output defaulting to identity matrix\n" ); + #endif + + psLatestResult = &sCSC_IdentityMatrix; + } + + #if CSC_PRINT_DEBUG_INFO + printf ( "\nFinal CSC matrix :\n" ); + CSC_PRINT_3x3_MATRIX(psLatestResult); + #endif + + /* Now copy the final results into the user supplied matrix */ + IMG_MEMCPY ( &(psResultantConfigurationData->sCoefficients), + psLatestResult, + sizeof(CSC_s3x3Matrix) ); + + /* Finally, calculate input and output offsets */ + if ( asColourspaceInfo [eInputColourSpace].bIsYUV == IMG_TRUE ) + { + i32InputYOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32YOffset; + i32InputUVOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32UVOffset; + } + else + { + i32InputYOffset = -1 * (img_int32) asCSC_RangeInfo [eInputRange].ui32RGBOffset; + i32InputUVOffset = i32InputYOffset; + } + + if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_TRUE ) + { + i32OutputYOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32YOffset; + i32OutputUVOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32UVOffset; + } + else + { + i32OutputYOffset = (img_int32) asCSC_RangeInfo [eOutputRange].ui32RGBOffset; + i32OutputUVOffset = i32OutputYOffset; + } + + /* Output offsets are specified with a fractional part */ + i32OutputYOffset = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(i32OutputYOffset,0,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS); + i32OutputUVOffset = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(i32OutputUVOffset,0,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS); + + if ( psHSBCSettings != IMG_NULL ) + { + i32OutputYOffset += psHSBCSettings->i32Brightness; + + /* For YUV outputs, brightness is only applied to the Y output */ + if ( asColourspaceInfo [eOutputColourSpace].bIsYUV == IMG_FALSE ) + { + i32OutputUVOffset += psHSBCSettings->i32Brightness; + } + } + + /* Copy offsets into user provided structure */ + psResultantConfigurationData->ai32InputOffsets[0] = i32InputYOffset; + psResultantConfigurationData->ai32InputOffsets[1] = i32InputUVOffset; + psResultantConfigurationData->ai32InputOffsets[2] = i32InputUVOffset; + + psResultantConfigurationData->ai32OutputOffsets[0] = i32OutputYOffset; + psResultantConfigurationData->ai32OutputOffsets[1] = i32OutputUVOffset; + psResultantConfigurationData->ai32OutputOffsets[2] = i32OutputUVOffset; + + #if CSC_PRINT_DEBUG_INFO + printf ( "\nInput offsets:\n" ); + printf ( " [0] %03i\n", psResultantConfigurationData->ai32InputOffsets[0] ); + printf ( " [1] %03i\n", psResultantConfigurationData->ai32InputOffsets[1] ); + printf ( " [2] %03i\n", psResultantConfigurationData->ai32InputOffsets[2] ); + + printf ( "\nOutput offsets:\n" ); + printf ( " [0] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[0]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); + printf ( " [1] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[1]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); + printf ( " [2] %f\n", (((img_float) psResultantConfigurationData->ai32OutputOffsets[2]) / (1 << CSC_OUTPUT_OFFSET_FRACTIONAL_BITS))); + #endif + + return IMG_SUCCESS; +}; + +img_result CSC_GenerateHSCMatrix ( CSC_psHSBCSettings psHSBCSettings, + CSC_ps3x3Matrix psHSCMatrix ) +{ + img_int32 i32CosHue; + img_int32 i32SinHue; + img_int32 i32HueInRadians; + img_int32 i32ContrastTimesSaturation; + + IMG_ASSERT ( psHSBCSettings != IMG_NULL ); + IMG_ASSERT ( psHSCMatrix != IMG_NULL ); + + /* Check all supplied values are in range */ + IMG_ASSERT ( psHSBCSettings->i32Hue <= CSC_MAX_HUE ); + IMG_ASSERT ( psHSBCSettings->i32Hue >= CSC_MIN_HUE ); + IMG_ASSERT ( psHSBCSettings->i32Saturation <= CSC_MAX_SATURATION ); + IMG_ASSERT ( psHSBCSettings->i32Saturation >= CSC_MIN_SATURATION ); + IMG_ASSERT ( psHSBCSettings->i32Brightness <= CSC_MAX_BRIGHTNESS ); + IMG_ASSERT ( psHSBCSettings->i32Brightness >= CSC_MIN_BRIGHTNESS ); + IMG_ASSERT ( psHSBCSettings->i32Contrast <= CSC_MAX_CONTRAST ); + IMG_ASSERT ( psHSBCSettings->i32Contrast >= CSC_MIN_CONTRAST ); + + /* conSatHue matrix is constructed as follows : */ + /* */ + /* [ con, 0, 0 ] */ + /* [ 0, (con*sat*cos(hue)), (con*sat*sin(hue)) ] */ + /* [ 0, -(con*sat*cos(hue)), (con*sat*cos(hue)) ] */ + + /* Generate some useful values */ + i32HueInRadians = psHSBCSettings->i32Hue; + if ( i32HueInRadians < 0 ) + { + i32HueInRadians = i32HueInRadians * -1; + } + i32HueInRadians = FIXEDPT_64BitMultiply_Signed ( (img_int32) FIXEDPT_ONE_DEGREE_IN_RADIANS, /* x.FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS */ + i32HueInRadians, /* x.CSC_HSC_FRACTIONAL_BITS */ + CSC_HSC_FRACTIONAL_BITS ); /* Result is in x.FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS format */ + + i32CosHue = FIXEDPT_Cosine( (img_uint32) i32HueInRadians ); /* Cosine is symmetrical about 0 degrees, hence cos(theta)=cos(-theta) */ + i32CosHue = FIXEDPT_CONVERT_FRACTIONAL_BITS(i32CosHue,FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); + + i32SinHue = FIXEDPT_Sine( (img_uint32) i32HueInRadians ); /* Sine is not symmetrical, however sin(theta)=-1 * sin(-theta) */ + if ( psHSBCSettings->i32Hue < 0 ) + { + i32SinHue = -1 * i32SinHue; + } + i32SinHue = FIXEDPT_CONVERT_FRACTIONAL_BITS(i32SinHue,FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); + + i32ContrastTimesSaturation = FIXEDPT_64BitMultiply_Signed ( psHSBCSettings->i32Contrast, + psHSBCSettings->i32Saturation, + ((2*CSC_HSC_FRACTIONAL_BITS)-CSC_FRACTIONAL_BITS) ); /* Result is in x.CSC_FRACTIONAL_BITS format */ + + /* Now complete matrix */ + /* Row 0 */ + psHSCMatrix->ai32Coefficients [0][0] = FIXEDPT_CONVERT_FRACTIONAL_BITS(psHSBCSettings->i32Contrast,CSC_HSC_FRACTIONAL_BITS,CSC_FRACTIONAL_BITS); + psHSCMatrix->ai32Coefficients [0][1] = 0; + psHSCMatrix->ai32Coefficients [0][2] = 0; + + /* Row 1 */ + psHSCMatrix->ai32Coefficients [1][0] = 0; + psHSCMatrix->ai32Coefficients [1][1] = FIXEDPT_64BitMultiply_Signed ( i32ContrastTimesSaturation, + i32CosHue, + CSC_FRACTIONAL_BITS ); /* Result is in x.CSC_FRACTIONAL_BITS format */ + psHSCMatrix->ai32Coefficients [1][2] = FIXEDPT_64BitMultiply_Signed ( i32ContrastTimesSaturation, + i32SinHue, + CSC_FRACTIONAL_BITS ); /* Result is in x.CSC_FRACTIONAL_BITS format */ + + /* Row 2 */ + psHSCMatrix->ai32Coefficients [2][0] = 0; + psHSCMatrix->ai32Coefficients [2][1] = -1 * psHSCMatrix->ai32Coefficients [1][2]; + psHSCMatrix->ai32Coefficients [2][2] = psHSCMatrix->ai32Coefficients [1][1]; + + #if CSC_PRINT_DEBUG_INFO + printf ( "\nHSC matrix :\n" ); + CSC_PRINT_3x3_MATRIX(psHSCMatrix); + #endif + + return IMG_SUCCESS; +} diff --git a/src/powervr_iep_lite/csc/csc2_data.c b/src/powervr_iep_lite/csc/csc2_data.c index 27f5235..2cc4558 100644 --- a/src/powervr_iep_lite/csc/csc2_data.c +++ b/src/powervr_iep_lite/csc/csc2_data.c @@ -1,755 +1,755 @@ -/****************************************************************************** - @file : csc2_data.c - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - This module contains data used by the CSC library. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#include "img_iep_defs.h" -#include "fixedpointmaths.h" -#include "csc2.h" -#include "csc2_data.h" - -img_result csc_StaticDataSafetyCheck ( img_void ) -{ - img_uint32 ui32i, ui32j; - - for ( ui32i=0; ui32i ? */ - /**************/ - { - /* BT601 -> BT601 */ - { - CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* BT601 -> BT709 */ - { - CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(-0.11819), CSC_FP(-0.21268) }, - { CSC_FP(0.00000), CSC_FP(1.01864), CSC_FP(0.11462) }, - { CSC_FP(0.00000), CSC_FP(0.07505), CSC_FP(1.02532) }, - } - } - }, - - /* BT601 -> SMPTE240 */ - { - CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ - CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(-0.08708), CSC_FP(-0.20345) }, - { CSC_FP(0.00000), CSC_FP(1.01813), CSC_FP(0.11121) }, - { CSC_FP(0.00000), CSC_FP(0.05568), CSC_FP(1.01883) }, - } - } - }, - - /* BT601 -> RGB */ - { - CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ - CSC_COLOURSPACE_RGB, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(1.40200) }, - { CSC_FP(1.00000), CSC_FP(-0.34414), CSC_FP(-0.71414)}, - { CSC_FP(1.00000), CSC_FP(1.77200), CSC_FP(0.00000) }, - } - } - } - }, - - /**************/ - /* BT709 -> ? */ - /**************/ - { - /* BT709 -> BT601 */ - { - CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.10158), CSC_FP(0.19607) }, - { CSC_FP(0.00000), CSC_FP(0.98985), CSC_FP(-0.11065) }, - { CSC_FP(0.00000), CSC_FP(-0.07245), CSC_FP(0.98340) }, - } - } - }, - - /* BT709 -> BT709 */ - { - CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* BT709 -> SMPTE240 */ - { - CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ - CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.03012), CSC_FP(0.00563) }, - { CSC_FP(0.00000), CSC_FP(0.99974), CSC_FP(-0.00329) }, - { CSC_FP(0.00000), CSC_FP(-0.01870), CSC_FP(0.99576) }, - } - } - }, - - /* BT709 -> RGB */ - { - CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ - CSC_COLOURSPACE_RGB, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(1.57480) }, - { CSC_FP(1.00000), CSC_FP(-0.18732), CSC_FP(-0.46813)}, - { CSC_FP(1.00000), CSC_FP(1.85560), CSC_FP(0.00000) }, - } - } - } - }, - - /*****************/ - /* SMPTE240 -> ? */ - /*****************/ - { - /* SMPTE240 -> BT601 */ - { - CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.07506), CSC_FP(0.19150) }, - { CSC_FP(0.00000), CSC_FP(0.98809), CSC_FP(-0.10786) }, - { CSC_FP(0.00000), CSC_FP(-0.05400), CSC_FP(0.98741) }, - } - } - }, - - /* SMPTE240 -> BT709 */ - { - CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(-0.03024), CSC_FP(-0.00576) }, - { CSC_FP(0.00000), CSC_FP(1.00032), CSC_FP(0.00331) }, - { CSC_FP(0.00000), CSC_FP(0.01879), CSC_FP(1.00432) }, - } - } - }, - - /* SMPTE240 -> SMPTE240 */ - { - CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ - CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* SMPTE240 -> RGB */ - { - CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ - CSC_COLOURSPACE_RGB, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(-0.00066), CSC_FP(1.57585) }, - { CSC_FP(1.00000), CSC_FP(-0.22642), CSC_FP(-0.47653) }, - { CSC_FP(1.00000), CSC_FP(1.82596), CSC_FP(0.00038) }, - } - } - } - }, - - /************/ - /* RGB -> ? */ - /************/ - { - /* RGB -> BT601 */ - { - CSC_COLOURSPACE_RGB, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.29900), CSC_FP(0.58700), CSC_FP(0.11400) }, - { CSC_FP(-0.16874), CSC_FP(-0.33126), CSC_FP(0.50000) }, - { CSC_FP(0.50000), CSC_FP(-0.41869), CSC_FP(-0.08131) }, - } - } - }, - - /* RGB -> BT709 */ - { - CSC_COLOURSPACE_RGB, /* Input colour space */ - CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.21260), CSC_FP(0.71520), CSC_FP(0.07220) }, - { CSC_FP(-0.11457), CSC_FP(-0.38543), CSC_FP(0.50000) }, - { CSC_FP(0.50000), CSC_FP(-0.45415), CSC_FP(-0.04585) }, - } - } - }, - - /* RGB -> SMPTE240 */ - { - CSC_COLOURSPACE_RGB, /* Input colour space */ - CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.21197), CSC_FP(0.70103), CSC_FP(0.08700) }, - { CSC_FP(-0.11619), CSC_FP(-0.38383), CSC_FP(0.50002) }, - { CSC_FP(0.50002), CSC_FP(-0.44502), CSC_FP(-0.05500) }, - } - } - }, - - /* RGB -> RGB */ - { - CSC_COLOURSPACE_RGB, /* Input colour space */ - CSC_COLOURSPACE_RGB, /* Output colour space */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - } - } -}; - -/* Stores additional information about input and output ranges */ -CSC_sAdditionalRangeInformation asCSC_RangeInfo [CSC_NO_OF_RANGES] = -{ - /* 0 -> 255 */ - { - CSC_RANGE_0_255, - - CSC_FP(1), /* RGB scale */ - CSC_FP(1), /* Y scale */ - CSC_FP(1), /* UV scale */ - - 0, /* RGB offset */ - 0, /* Y offset */ - 0 /* UV offset */ - }, - - /* 16 -> 235 */ - { - CSC_RANGE_16_235, - - CSC_FP((255.0f/219.0f)), /* RGB scale */ - CSC_FP((255.0f/219.0f)), /* Y scale */ - CSC_FP((255.0f/224.0f)), /* UV scale */ - - 16, /* RGB offset */ - 16, /* Y offset */ - 0 /* UV offset */ - }, - - /* 48 -> 208 */ - { - CSC_RANGE_48_208, - - CSC_FP((255.0f/160.0f)), /* RGB scale */ - CSC_FP((255.0f/160.0f)), /* Y scale */ - CSC_FP((255.0f/160.0f)), /* UV scale */ - - 48, /* RGB offset */ - 48, /* Y offset */ - 0 /* UV offset */ - } -}; - -/* Stores conversion matrices for all combinations of input and output colour primaries */ -CSC_sColourPrimaryConversionMatrix asCSCColourPrimaryConversionMatrices [CSC_NO_OF_COLOUR_PRIMARIES][CSC_NO_OF_COLOUR_PRIMARIES] = -{ - /**************/ - /* BT709 -> ? */ - /**************/ - { - /* BT709 -> BT709 */ - { - CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* BT709 -> BT601 */ - { - CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.0654), CSC_FP(-0.0554), CSC_FP(-0.0100) }, - { CSC_FP(-0.0196), CSC_FP(1.0364), CSC_FP(-0.0167) }, - { CSC_FP(0.0016), CSC_FP(0.0044), CSC_FP(0.9940) }, - } - } - }, - - /* BT709 -> BT470_2_SYSBG */ - { - CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.9578), CSC_FP(0.0422), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(-0.0119), CSC_FP(1.0119) }, - } - } - }, - - /* BT709 -> BT470_2_SYSM */ - { - CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.6688), CSC_FP(0.2678), CSC_FP(0.0323) }, - { CSC_FP(0.0185), CSC_FP(1.0746), CSC_FP(-0.0603) }, - { CSC_FP(0.0162), CSC_FP(0.0431), CSC_FP(0.8542) }, - } - } - } - }, - - /**************/ - /* BT601 -> ? */ - /**************/ - { - /* BT601 -> BT709 */ - { - CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.9395), CSC_FP(0.0502), CSC_FP(0.0103) }, - { CSC_FP(0.0178), CSC_FP(0.9658), CSC_FP(0.0164) }, - { CSC_FP(-0.0016), CSC_FP(-0.0044), CSC_FP(1.0060) }, - } - } - }, - - /* BT601 -> BT601 */ - { - CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* BT601 -> BT470_2_SYSBG */ - { - CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.9007), CSC_FP(0.0888), CSC_FP(0.0105) }, - { CSC_FP(0.0178), CSC_FP(0.9658), CSC_FP(0.0164) }, - { CSC_FP(-0.0019), CSC_FP(-0.0159), CSC_FP(1.0178) }, - } - } - }, - - /* BT601 -> BT470_2_SYSM */ - { - CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.6330), CSC_FP(0.2920), CSC_FP(0.0438) }, - { CSC_FP(0.0366), CSC_FP(1.0390), CSC_FP(-0.0428) }, - { CSC_FP(0.0146), CSC_FP(0.0387), CSC_FP(0.8602) }, - } - } - } - }, - - /**********************/ - /* BT470_2_SYSBG -> ? */ - /**********************/ - { - /* BT470_2_SYSBG -> BT709 */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.0440), CSC_FP(-0.0440), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.0118), CSC_FP(0.9882) }, - } - } - }, - - /* BT470_2_SYSBG -> BT601 */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.1123), CSC_FP(-0.1024), CSC_FP(-0.0099) }, - { CSC_FP(-0.0205), CSC_FP(1.0370), CSC_FP(-0.0165) }, - { CSC_FP(0.0017), CSC_FP(0.0161), CSC_FP(0.9822) }, - } - } - }, - - /* BT470_2_SYSBG -> BT470_2_SYSBG */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - }, - - /* BT470_2_SYSBG -> BT470_2_SYSM */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(0.6982), CSC_FP(0.2387), CSC_FP(0.0319) }, - { CSC_FP(0.0193), CSC_FP(1.0731), CSC_FP(-0.0596) }, - { CSC_FP(0.0169), CSC_FP(0.0525), CSC_FP(0.8441) }, - } - } - } - }, - - /*********************/ - /* BT470_2_SYSM -> ? */ - /*********************/ - { - /* BT470_2_SYSM -> BT709 */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.5076), CSC_FP(-0.3724), CSC_FP(-0.0833) }, - { CSC_FP(-0.0275), CSC_FP(0.9347), CSC_FP(0.0670) }, - { CSC_FP(-0.0272), CSC_FP(-0.0401), CSC_FP(1.1689) }, - } - } - }, - - /* BT470_2_SYSM -> BT601 */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.6080), CSC_FP(-0.4481), CSC_FP(-0.1042) }, - { CSC_FP(-0.0576), CSC_FP(0.9767), CSC_FP(0.0516) }, - { CSC_FP(-0.0247), CSC_FP(-0.0364), CSC_FP(1.1620) }, - } - } - }, - - /* BT470_2_SYSM -> BT470_2_SYSBG */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ - - IMG_FALSE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.4429), CSC_FP(-0.3172), CSC_FP(-0.0770) }, - { CSC_FP(-0.0275), CSC_FP(0.9347), CSC_FP(0.0670) }, - { CSC_FP(-0.0272), CSC_FP(-0.0518), CSC_FP(1.1821) }, - } - } - }, - - /* BT470_2_SYSM -> BT470_2_SYSM */ - { - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ - CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ - - IMG_TRUE, /* Is identity matrix? */ - IMG_TRUE, /* Is supported? */ - - /* Coefficients */ - { - { - { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, - { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, - } - } - } - } -}; +/****************************************************************************** + @file : csc2_data.c + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + This module contains data used by the CSC library. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#include "img_iep_defs.h" +#include "fixedpointmaths.h" +#include "csc2.h" +#include "csc2_data.h" + +img_result csc_StaticDataSafetyCheck ( img_void ) +{ + img_uint32 ui32i, ui32j; + + for ( ui32i=0; ui32i ? */ + /**************/ + { + /* BT601 -> BT601 */ + { + CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* BT601 -> BT709 */ + { + CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(-0.11819), CSC_FP(-0.21268) }, + { CSC_FP(0.00000), CSC_FP(1.01864), CSC_FP(0.11462) }, + { CSC_FP(0.00000), CSC_FP(0.07505), CSC_FP(1.02532) }, + } + } + }, + + /* BT601 -> SMPTE240 */ + { + CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ + CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(-0.08708), CSC_FP(-0.20345) }, + { CSC_FP(0.00000), CSC_FP(1.01813), CSC_FP(0.11121) }, + { CSC_FP(0.00000), CSC_FP(0.05568), CSC_FP(1.01883) }, + } + } + }, + + /* BT601 -> RGB */ + { + CSC_COLOURSPACE_YCC_BT601, /* Input colour space */ + CSC_COLOURSPACE_RGB, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(1.40200) }, + { CSC_FP(1.00000), CSC_FP(-0.34414), CSC_FP(-0.71414)}, + { CSC_FP(1.00000), CSC_FP(1.77200), CSC_FP(0.00000) }, + } + } + } + }, + + /**************/ + /* BT709 -> ? */ + /**************/ + { + /* BT709 -> BT601 */ + { + CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.10158), CSC_FP(0.19607) }, + { CSC_FP(0.00000), CSC_FP(0.98985), CSC_FP(-0.11065) }, + { CSC_FP(0.00000), CSC_FP(-0.07245), CSC_FP(0.98340) }, + } + } + }, + + /* BT709 -> BT709 */ + { + CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* BT709 -> SMPTE240 */ + { + CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ + CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.03012), CSC_FP(0.00563) }, + { CSC_FP(0.00000), CSC_FP(0.99974), CSC_FP(-0.00329) }, + { CSC_FP(0.00000), CSC_FP(-0.01870), CSC_FP(0.99576) }, + } + } + }, + + /* BT709 -> RGB */ + { + CSC_COLOURSPACE_YCC_BT709, /* Input colour space */ + CSC_COLOURSPACE_RGB, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(1.57480) }, + { CSC_FP(1.00000), CSC_FP(-0.18732), CSC_FP(-0.46813)}, + { CSC_FP(1.00000), CSC_FP(1.85560), CSC_FP(0.00000) }, + } + } + } + }, + + /*****************/ + /* SMPTE240 -> ? */ + /*****************/ + { + /* SMPTE240 -> BT601 */ + { + CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.07506), CSC_FP(0.19150) }, + { CSC_FP(0.00000), CSC_FP(0.98809), CSC_FP(-0.10786) }, + { CSC_FP(0.00000), CSC_FP(-0.05400), CSC_FP(0.98741) }, + } + } + }, + + /* SMPTE240 -> BT709 */ + { + CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(-0.03024), CSC_FP(-0.00576) }, + { CSC_FP(0.00000), CSC_FP(1.00032), CSC_FP(0.00331) }, + { CSC_FP(0.00000), CSC_FP(0.01879), CSC_FP(1.00432) }, + } + } + }, + + /* SMPTE240 -> SMPTE240 */ + { + CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ + CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* SMPTE240 -> RGB */ + { + CSC_COLOURSPACE_YCC_SMPTE_240, /* Input colour space */ + CSC_COLOURSPACE_RGB, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(-0.00066), CSC_FP(1.57585) }, + { CSC_FP(1.00000), CSC_FP(-0.22642), CSC_FP(-0.47653) }, + { CSC_FP(1.00000), CSC_FP(1.82596), CSC_FP(0.00038) }, + } + } + } + }, + + /************/ + /* RGB -> ? */ + /************/ + { + /* RGB -> BT601 */ + { + CSC_COLOURSPACE_RGB, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT601, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.29900), CSC_FP(0.58700), CSC_FP(0.11400) }, + { CSC_FP(-0.16874), CSC_FP(-0.33126), CSC_FP(0.50000) }, + { CSC_FP(0.50000), CSC_FP(-0.41869), CSC_FP(-0.08131) }, + } + } + }, + + /* RGB -> BT709 */ + { + CSC_COLOURSPACE_RGB, /* Input colour space */ + CSC_COLOURSPACE_YCC_BT709, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.21260), CSC_FP(0.71520), CSC_FP(0.07220) }, + { CSC_FP(-0.11457), CSC_FP(-0.38543), CSC_FP(0.50000) }, + { CSC_FP(0.50000), CSC_FP(-0.45415), CSC_FP(-0.04585) }, + } + } + }, + + /* RGB -> SMPTE240 */ + { + CSC_COLOURSPACE_RGB, /* Input colour space */ + CSC_COLOURSPACE_YCC_SMPTE_240, /* Output colour space */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.21197), CSC_FP(0.70103), CSC_FP(0.08700) }, + { CSC_FP(-0.11619), CSC_FP(-0.38383), CSC_FP(0.50002) }, + { CSC_FP(0.50002), CSC_FP(-0.44502), CSC_FP(-0.05500) }, + } + } + }, + + /* RGB -> RGB */ + { + CSC_COLOURSPACE_RGB, /* Input colour space */ + CSC_COLOURSPACE_RGB, /* Output colour space */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + } + } +}; + +/* Stores additional information about input and output ranges */ +CSC_sAdditionalRangeInformation asCSC_RangeInfo [CSC_NO_OF_RANGES] = +{ + /* 0 -> 255 */ + { + CSC_RANGE_0_255, + + CSC_FP(1), /* RGB scale */ + CSC_FP(1), /* Y scale */ + CSC_FP(1), /* UV scale */ + + 0, /* RGB offset */ + 0, /* Y offset */ + 0 /* UV offset */ + }, + + /* 16 -> 235 */ + { + CSC_RANGE_16_235, + + CSC_FP((255.0f/219.0f)), /* RGB scale */ + CSC_FP((255.0f/219.0f)), /* Y scale */ + CSC_FP((255.0f/224.0f)), /* UV scale */ + + 16, /* RGB offset */ + 16, /* Y offset */ + 0 /* UV offset */ + }, + + /* 48 -> 208 */ + { + CSC_RANGE_48_208, + + CSC_FP((255.0f/160.0f)), /* RGB scale */ + CSC_FP((255.0f/160.0f)), /* Y scale */ + CSC_FP((255.0f/160.0f)), /* UV scale */ + + 48, /* RGB offset */ + 48, /* Y offset */ + 0 /* UV offset */ + } +}; + +/* Stores conversion matrices for all combinations of input and output colour primaries */ +CSC_sColourPrimaryConversionMatrix asCSCColourPrimaryConversionMatrices [CSC_NO_OF_COLOUR_PRIMARIES][CSC_NO_OF_COLOUR_PRIMARIES] = +{ + /**************/ + /* BT709 -> ? */ + /**************/ + { + /* BT709 -> BT709 */ + { + CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* BT709 -> BT601 */ + { + CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.0654), CSC_FP(-0.0554), CSC_FP(-0.0100) }, + { CSC_FP(-0.0196), CSC_FP(1.0364), CSC_FP(-0.0167) }, + { CSC_FP(0.0016), CSC_FP(0.0044), CSC_FP(0.9940) }, + } + } + }, + + /* BT709 -> BT470_2_SYSBG */ + { + CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.9578), CSC_FP(0.0422), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(-0.0119), CSC_FP(1.0119) }, + } + } + }, + + /* BT709 -> BT470_2_SYSM */ + { + CSC_COLOUR_PRIMARY_BT709, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.6688), CSC_FP(0.2678), CSC_FP(0.0323) }, + { CSC_FP(0.0185), CSC_FP(1.0746), CSC_FP(-0.0603) }, + { CSC_FP(0.0162), CSC_FP(0.0431), CSC_FP(0.8542) }, + } + } + } + }, + + /**************/ + /* BT601 -> ? */ + /**************/ + { + /* BT601 -> BT709 */ + { + CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.9395), CSC_FP(0.0502), CSC_FP(0.0103) }, + { CSC_FP(0.0178), CSC_FP(0.9658), CSC_FP(0.0164) }, + { CSC_FP(-0.0016), CSC_FP(-0.0044), CSC_FP(1.0060) }, + } + } + }, + + /* BT601 -> BT601 */ + { + CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* BT601 -> BT470_2_SYSBG */ + { + CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.9007), CSC_FP(0.0888), CSC_FP(0.0105) }, + { CSC_FP(0.0178), CSC_FP(0.9658), CSC_FP(0.0164) }, + { CSC_FP(-0.0019), CSC_FP(-0.0159), CSC_FP(1.0178) }, + } + } + }, + + /* BT601 -> BT470_2_SYSM */ + { + CSC_COLOUR_PRIMARY_BT601, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.6330), CSC_FP(0.2920), CSC_FP(0.0438) }, + { CSC_FP(0.0366), CSC_FP(1.0390), CSC_FP(-0.0428) }, + { CSC_FP(0.0146), CSC_FP(0.0387), CSC_FP(0.8602) }, + } + } + } + }, + + /**********************/ + /* BT470_2_SYSBG -> ? */ + /**********************/ + { + /* BT470_2_SYSBG -> BT709 */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.0440), CSC_FP(-0.0440), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.0118), CSC_FP(0.9882) }, + } + } + }, + + /* BT470_2_SYSBG -> BT601 */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.1123), CSC_FP(-0.1024), CSC_FP(-0.0099) }, + { CSC_FP(-0.0205), CSC_FP(1.0370), CSC_FP(-0.0165) }, + { CSC_FP(0.0017), CSC_FP(0.0161), CSC_FP(0.9822) }, + } + } + }, + + /* BT470_2_SYSBG -> BT470_2_SYSBG */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + }, + + /* BT470_2_SYSBG -> BT470_2_SYSM */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(0.6982), CSC_FP(0.2387), CSC_FP(0.0319) }, + { CSC_FP(0.0193), CSC_FP(1.0731), CSC_FP(-0.0596) }, + { CSC_FP(0.0169), CSC_FP(0.0525), CSC_FP(0.8441) }, + } + } + } + }, + + /*********************/ + /* BT470_2_SYSM -> ? */ + /*********************/ + { + /* BT470_2_SYSM -> BT709 */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT709, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.5076), CSC_FP(-0.3724), CSC_FP(-0.0833) }, + { CSC_FP(-0.0275), CSC_FP(0.9347), CSC_FP(0.0670) }, + { CSC_FP(-0.0272), CSC_FP(-0.0401), CSC_FP(1.1689) }, + } + } + }, + + /* BT470_2_SYSM -> BT601 */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT601, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.6080), CSC_FP(-0.4481), CSC_FP(-0.1042) }, + { CSC_FP(-0.0576), CSC_FP(0.9767), CSC_FP(0.0516) }, + { CSC_FP(-0.0247), CSC_FP(-0.0364), CSC_FP(1.1620) }, + } + } + }, + + /* BT470_2_SYSM -> BT470_2_SYSBG */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, /* Output colour primary */ + + IMG_FALSE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.4429), CSC_FP(-0.3172), CSC_FP(-0.0770) }, + { CSC_FP(-0.0275), CSC_FP(0.9347), CSC_FP(0.0670) }, + { CSC_FP(-0.0272), CSC_FP(-0.0518), CSC_FP(1.1821) }, + } + } + }, + + /* BT470_2_SYSM -> BT470_2_SYSM */ + { + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Input colour primary */ + CSC_COLOUR_PRIMARY_BT470_2_SYSM, /* Output colour primary */ + + IMG_TRUE, /* Is identity matrix? */ + IMG_TRUE, /* Is supported? */ + + /* Coefficients */ + { + { + { CSC_FP(1.00000), CSC_FP(0.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(1.00000), CSC_FP(0.00000) }, + { CSC_FP(0.00000), CSC_FP(0.00000), CSC_FP(1.00000) }, + } + } + } + } +}; diff --git a/src/powervr_iep_lite/csc/csc2_data.h b/src/powervr_iep_lite/csc/csc2_data.h index 7254d6c..58e82ae 100644 --- a/src/powervr_iep_lite/csc/csc2_data.h +++ b/src/powervr_iep_lite/csc/csc2_data.h @@ -1,108 +1,108 @@ -/*! -****************************************************************************** - @file : csc2_data.h - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#if !defined (__CSC_DATA_H__) -#define __CSC_DATA_H__ -#if (__cplusplus) -extern "C" { +/*! +****************************************************************************** + @file : csc2_data.h + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__CSC_DATA_H__) +#define __CSC_DATA_H__ +#if (__cplusplus) +extern "C" { +#endif + +/* Macros and definitions */ +#define CSC_FP(floating_num) ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(floating_num,CSC_FRACTIONAL_BITS)) +#define CSC_FP_HSC(floating_num) ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(floating_num,CSC_HSC_FRACTIONAL_BITS)) + +#define CSC_MAX_HUE CSC_FP_HSC(30) +#define CSC_MIN_HUE CSC_FP_HSC(-30) +#define CSC_MAX_SATURATION CSC_FP_HSC(2) +#define CSC_MIN_SATURATION CSC_FP_HSC(0) +#define CSC_MAX_CONTRAST CSC_FP_HSC(2) +#define CSC_MIN_CONTRAST CSC_FP_HSC(0) +#define CSC_MAX_BRIGHTNESS ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(50,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS)) +#define CSC_MIN_BRIGHTNESS ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(-50,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS)) + +/* Typedefs */ +typedef struct +{ + CSC_eColourSpace eColourspace; + + img_bool bIsYUV; /* If TRUE, is YUV - if FALSE, is RGB */ + +} CSC_sAdditionalColourSpaceInformation; + +typedef struct +{ + CSC_eColourSpace eInputColourspace; + CSC_eColourSpace eOutputColourspace; + + img_bool bIsIdentityMatrix; + img_bool bIsSupported; + + CSC_s3x3Matrix sMatrix; + +} CSC_sColourSpaceConversionMatrix; + +typedef struct +{ + CSC_eColourPrimary eInputColourPrimary; + CSC_eColourPrimary eOutputColourPrimary; + + img_bool bIsIdentityMatrix; + img_bool bIsSupported; + + CSC_s3x3Matrix sMatrix; + +} CSC_sColourPrimaryConversionMatrix; + +typedef struct +{ + CSC_eRange eRange; + + img_int32 i32RGBScale; + img_int32 i32YScale; + img_int32 i32UVScale; + + img_uint32 ui32RGBOffset; + img_uint32 ui32YOffset; + img_uint32 ui32UVOffset; + +} CSC_sAdditionalRangeInformation; + +/* Data */ +extern CSC_s3x3Matrix sCSC_IdentityMatrix; +extern CSC_sAdditionalColourSpaceInformation asColourspaceInfo [CSC_NO_OF_COLOURSPACES]; +extern CSC_sColourSpaceConversionMatrix asCSC_ColourSpaceConversionMatrices [CSC_NO_OF_COLOURSPACES][CSC_NO_OF_COLOURSPACES]; +extern CSC_sAdditionalRangeInformation asCSC_RangeInfo [CSC_NO_OF_RANGES]; +extern CSC_sColourPrimaryConversionMatrix asCSCColourPrimaryConversionMatrices [CSC_NO_OF_COLOUR_PRIMARIES][CSC_NO_OF_COLOUR_PRIMARIES]; + +/* Functions */ +img_result csc_StaticDataSafetyCheck ( img_void ); + +#if (__cplusplus) +} #endif - -/* Macros and definitions */ -#define CSC_FP(floating_num) ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(floating_num,CSC_FRACTIONAL_BITS)) -#define CSC_FP_HSC(floating_num) ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(floating_num,CSC_HSC_FRACTIONAL_BITS)) - -#define CSC_MAX_HUE CSC_FP_HSC(30) -#define CSC_MIN_HUE CSC_FP_HSC(-30) -#define CSC_MAX_SATURATION CSC_FP_HSC(2) -#define CSC_MIN_SATURATION CSC_FP_HSC(0) -#define CSC_MAX_CONTRAST CSC_FP_HSC(2) -#define CSC_MIN_CONTRAST CSC_FP_HSC(0) -#define CSC_MAX_BRIGHTNESS ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(50,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS)) -#define CSC_MIN_BRIGHTNESS ((img_int32)FIXEDPT_CONVERT_FLOAT_TO_FIXED(-50,CSC_OUTPUT_OFFSET_FRACTIONAL_BITS)) - -/* Typedefs */ -typedef struct -{ - CSC_eColourSpace eColourspace; - - img_bool bIsYUV; /* If TRUE, is YUV - if FALSE, is RGB */ - -} CSC_sAdditionalColourSpaceInformation; - -typedef struct -{ - CSC_eColourSpace eInputColourspace; - CSC_eColourSpace eOutputColourspace; - - img_bool bIsIdentityMatrix; - img_bool bIsSupported; - - CSC_s3x3Matrix sMatrix; - -} CSC_sColourSpaceConversionMatrix; - -typedef struct -{ - CSC_eColourPrimary eInputColourPrimary; - CSC_eColourPrimary eOutputColourPrimary; - - img_bool bIsIdentityMatrix; - img_bool bIsSupported; - - CSC_s3x3Matrix sMatrix; - -} CSC_sColourPrimaryConversionMatrix; - -typedef struct -{ - CSC_eRange eRange; - - img_int32 i32RGBScale; - img_int32 i32YScale; - img_int32 i32UVScale; - - img_uint32 ui32RGBOffset; - img_uint32 ui32YOffset; - img_uint32 ui32UVOffset; - -} CSC_sAdditionalRangeInformation; - -/* Data */ -extern CSC_s3x3Matrix sCSC_IdentityMatrix; -extern CSC_sAdditionalColourSpaceInformation asColourspaceInfo [CSC_NO_OF_COLOURSPACES]; -extern CSC_sColourSpaceConversionMatrix asCSC_ColourSpaceConversionMatrices [CSC_NO_OF_COLOURSPACES][CSC_NO_OF_COLOURSPACES]; -extern CSC_sAdditionalRangeInformation asCSC_RangeInfo [CSC_NO_OF_RANGES]; -extern CSC_sColourPrimaryConversionMatrix asCSCColourPrimaryConversionMatrices [CSC_NO_OF_COLOUR_PRIMARIES][CSC_NO_OF_COLOUR_PRIMARIES]; - -/* Functions */ -img_result csc_StaticDataSafetyCheck ( img_void ); - -#if (__cplusplus) -} -#endif #endif /* __CSC_DATA_H__ */ \ No newline at end of file diff --git a/src/powervr_iep_lite/fixedpointmaths/fixedpoint_sinetable.h b/src/powervr_iep_lite/fixedpointmaths/fixedpoint_sinetable.h index aa4af0d..577053f 100644 --- a/src/powervr_iep_lite/fixedpointmaths/fixedpoint_sinetable.h +++ b/src/powervr_iep_lite/fixedpointmaths/fixedpoint_sinetable.h @@ -1,454 +1,454 @@ -/*! -****************************************************************************** - @file : fixedpoint_sinetable.h - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - Lookup table for fixed point trig functions. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#if !defined (__FIXEDPOINTSINETABLE_H__) -#define __FIXEDPOINTSINETABLE_H__ - -#if (__cplusplus) -extern "C" { -#endif - -/* Table should be referenced using a 1.8 fixed point index, in the range 0->PI/2 */ -/* Values of Sine (x) are in 1.30 fixed point format. */ -img_uint32 FIXEDPT_aui32FixedPointSineTable [] = -{ - 0x00000000, /* 0) Sine 0.000000 = 0.000000 */ - 0x003ffff5, /* 1) Sine 0.003906 = 0.003906 */ - 0x007fffaa, /* 2) Sine 0.007813 = 0.007812 */ - 0x00bffee0, /* 3) Sine 0.011719 = 0.011718 */ - 0x00fffd55, /* 4) Sine 0.015625 = 0.015624 */ - 0x013ffaca, /* 5) Sine 0.019531 = 0.019530 */ - 0x017ff700, /* 6) Sine 0.023438 = 0.023435 */ - 0x01bff1b6, /* 7) Sine 0.027344 = 0.027340 */ - 0x01ffeaaa, /* 8) Sine 0.031250 = 0.031245 */ - 0x023fe1a0, /* 9) Sine 0.035156 = 0.035149 */ - 0x027fd658, /* 10) Sine 0.039063 = 0.039053 */ - 0x02bfc88c, /* 11) Sine 0.042969 = 0.042956 */ - 0x02ffb804, /* 12) Sine 0.046875 = 0.046858 */ - 0x033fa478, /* 13) Sine 0.050781 = 0.050759 */ - 0x037f8db0, /* 14) Sine 0.054688 = 0.054660 */ - 0x03bf7368, /* 15) Sine 0.058594 = 0.058560 */ - 0x03ff555c, /* 16) Sine 0.062500 = 0.062459 */ - 0x043f3358, /* 17) Sine 0.066406 = 0.066357 */ - 0x047f0d10, /* 18) Sine 0.070313 = 0.070255 */ - 0x04bee248, /* 19) Sine 0.074219 = 0.074151 */ - 0x04feb2c8, /* 20) Sine 0.078125 = 0.078046 */ - 0x053e7e40, /* 21) Sine 0.082031 = 0.081939 */ - 0x057e4480, /* 22) Sine 0.085938 = 0.085832 */ - 0x05be0540, /* 23) Sine 0.089844 = 0.089723 */ - 0x05fdc040, /* 24) Sine 0.093750 = 0.093613 */ - 0x063d7548, /* 25) Sine 0.097656 = 0.097501 */ - 0x067d2408, /* 26) Sine 0.101563 = 0.101388 */ - 0x06bccc58, /* 27) Sine 0.105469 = 0.105273 */ - 0x06fc6de0, /* 28) Sine 0.109375 = 0.109157 */ - 0x073c0870, /* 29) Sine 0.113281 = 0.113039 */ - 0x077b9bc8, /* 30) Sine 0.117188 = 0.116919 */ - 0x07bb27a0, /* 31) Sine 0.121094 = 0.120798 */ - 0x07faabb8, /* 32) Sine 0.125000 = 0.124675 */ - 0x083a27e0, /* 33) Sine 0.128906 = 0.128550 */ - 0x08799bc0, /* 34) Sine 0.132813 = 0.132422 */ - 0x08b90730, /* 35) Sine 0.136719 = 0.136293 */ - 0x08f869f0, /* 36) Sine 0.140625 = 0.140162 */ - 0x0937c3b0, /* 37) Sine 0.144531 = 0.144029 */ - 0x09771430, /* 38) Sine 0.148438 = 0.147893 */ - 0x09b65b40, /* 39) Sine 0.152344 = 0.151755 */ - 0x09f59890, /* 40) Sine 0.156250 = 0.155615 */ - 0x0a34cc00, /* 41) Sine 0.160156 = 0.159472 */ - 0x0a73f520, /* 42) Sine 0.164063 = 0.163327 */ - 0x0ab313e0, /* 43) Sine 0.167969 = 0.167180 */ - 0x0af227e0, /* 44) Sine 0.171875 = 0.171030 */ - 0x0b313100, /* 45) Sine 0.175781 = 0.174877 */ - 0x0b702ee0, /* 46) Sine 0.179688 = 0.178722 */ - 0x0baf2150, /* 47) Sine 0.183594 = 0.182564 */ - 0x0bee0810, /* 48) Sine 0.187500 = 0.186403 */ - 0x0c2ce2f0, /* 49) Sine 0.191406 = 0.190240 */ - 0x0c6bb190, /* 50) Sine 0.195313 = 0.194073 */ - 0x0caa73d0, /* 51) Sine 0.199219 = 0.197904 */ - 0x0ce92970, /* 52) Sine 0.203125 = 0.201731 */ - 0x0d27d210, /* 53) Sine 0.207031 = 0.205555 */ - 0x0d666d90, /* 54) Sine 0.210938 = 0.209377 */ - 0x0da4fbb0, /* 55) Sine 0.214844 = 0.213195 */ - 0x0de37c20, /* 56) Sine 0.218750 = 0.217010 */ - 0x0e21eec0, /* 57) Sine 0.222656 = 0.220821 */ - 0x0e605330, /* 58) Sine 0.226563 = 0.224629 */ - 0x0e9ea940, /* 59) Sine 0.230469 = 0.228434 */ - 0x0edcf0b0, /* 60) Sine 0.234375 = 0.232235 */ - 0x0f1b2940, /* 61) Sine 0.238281 = 0.236033 */ - 0x0f5952c0, /* 62) Sine 0.242188 = 0.239827 */ - 0x0f976ce0, /* 63) Sine 0.246094 = 0.243617 */ - 0x0fd57770, /* 64) Sine 0.250000 = 0.247404 */ - 0x10137220, /* 65) Sine 0.253906 = 0.251187 */ - 0x10515cc0, /* 66) Sine 0.257813 = 0.254966 */ - 0x108f3700, /* 67) Sine 0.261719 = 0.258741 */ - 0x10cd00c0, /* 68) Sine 0.265625 = 0.262512 */ - 0x110ab9c0, /* 69) Sine 0.269531 = 0.266280 */ - 0x114861a0, /* 70) Sine 0.273438 = 0.270043 */ - 0x1185f840, /* 71) Sine 0.277344 = 0.273802 */ - 0x11c37d60, /* 72) Sine 0.281250 = 0.277557 */ - 0x1200f0c0, /* 73) Sine 0.285156 = 0.281307 */ - 0x123e5220, /* 74) Sine 0.289063 = 0.285054 */ - 0x127ba120, /* 75) Sine 0.292969 = 0.288796 */ - 0x12b8ddc0, /* 76) Sine 0.296875 = 0.292533 */ - 0x12f607a0, /* 77) Sine 0.300781 = 0.296266 */ - 0x13331ea0, /* 78) Sine 0.304688 = 0.299995 */ - 0x13702240, /* 79) Sine 0.308594 = 0.303719 */ - 0x13ad12a0, /* 80) Sine 0.312500 = 0.307439 */ - 0x13e9ef40, /* 81) Sine 0.316406 = 0.311153 */ - 0x1426b7e0, /* 82) Sine 0.320313 = 0.314863 */ - 0x14636c80, /* 83) Sine 0.324219 = 0.318568 */ - 0x14a00ca0, /* 84) Sine 0.328125 = 0.322269 */ - 0x14dc9820, /* 85) Sine 0.332031 = 0.325964 */ - 0x15190ec0, /* 86) Sine 0.335938 = 0.329654 */ - 0x15557060, /* 87) Sine 0.339844 = 0.333340 */ - 0x1591bca0, /* 88) Sine 0.343750 = 0.337020 */ - 0x15cdf340, /* 89) Sine 0.347656 = 0.340695 */ - 0x160a1420, /* 90) Sine 0.351563 = 0.344365 */ - 0x16461f00, /* 91) Sine 0.355469 = 0.348030 */ - 0x16821380, /* 92) Sine 0.359375 = 0.351689 */ - 0x16bdf1a0, /* 93) Sine 0.363281 = 0.355343 */ - 0x16f9b8e0, /* 94) Sine 0.367188 = 0.358992 */ - 0x17356940, /* 95) Sine 0.371094 = 0.362635 */ - 0x17710260, /* 96) Sine 0.375000 = 0.366273 */ - 0x17ac8400, /* 97) Sine 0.378906 = 0.369905 */ - 0x17e7ee00, /* 98) Sine 0.382813 = 0.373531 */ - 0x18234020, /* 99) Sine 0.386719 = 0.377152 */ - 0x185e7a20, /* 100) Sine 0.390625 = 0.380766 */ - 0x18999ba0, /* 101) Sine 0.394531 = 0.384375 */ - 0x18d4a4a0, /* 102) Sine 0.398438 = 0.387979 */ - 0x190f94e0, /* 103) Sine 0.402344 = 0.391576 */ - 0x194a6be0, /* 104) Sine 0.406250 = 0.395167 */ - 0x198529c0, /* 105) Sine 0.410156 = 0.398753 */ - 0x19bfce00, /* 106) Sine 0.414063 = 0.402332 */ - 0x19fa5880, /* 107) Sine 0.417969 = 0.405905 */ - 0x1a34c920, /* 108) Sine 0.421875 = 0.409472 */ - 0x1a6f1f80, /* 109) Sine 0.425781 = 0.413032 */ - 0x1aa95b60, /* 110) Sine 0.429688 = 0.416587 */ - 0x1ae37ca0, /* 111) Sine 0.433594 = 0.420135 */ - 0x1b1d8300, /* 112) Sine 0.437500 = 0.423676 */ - 0x1b576e40, /* 113) Sine 0.441406 = 0.427211 */ - 0x1b913e40, /* 114) Sine 0.445313 = 0.430740 */ - 0x1bcaf280, /* 115) Sine 0.449219 = 0.434262 */ - 0x1c048b20, /* 116) Sine 0.453125 = 0.437777 */ - 0x1c3e07a0, /* 117) Sine 0.457031 = 0.441286 */ - 0x1c7767e0, /* 118) Sine 0.460938 = 0.444788 */ - 0x1cb0abc0, /* 119) Sine 0.464844 = 0.448283 */ - 0x1ce9d2e0, /* 120) Sine 0.468750 = 0.451771 */ - 0x1d22dd20, /* 121) Sine 0.472656 = 0.455253 */ - 0x1d5bca40, /* 122) Sine 0.476563 = 0.458727 */ - 0x1d9499e0, /* 123) Sine 0.480469 = 0.462195 */ - 0x1dcd4c20, /* 124) Sine 0.484375 = 0.465655 */ - 0x1e05e060, /* 125) Sine 0.488281 = 0.469109 */ - 0x1e3e56c0, /* 126) Sine 0.492188 = 0.472555 */ - 0x1e76aee0, /* 127) Sine 0.496094 = 0.475994 */ - 0x1eaee880, /* 128) Sine 0.500000 = 0.479426 */ - 0x1ee70360, /* 129) Sine 0.503906 = 0.482850 */ - 0x1f1eff60, /* 130) Sine 0.507813 = 0.486267 */ - 0x1f56dc60, /* 131) Sine 0.511719 = 0.489677 */ - 0x1f8e99e0, /* 132) Sine 0.515625 = 0.493079 */ - 0x1fc637e0, /* 133) Sine 0.519531 = 0.496473 */ - 0x1ffdb620, /* 134) Sine 0.523438 = 0.499860 */ - 0x20351480, /* 135) Sine 0.527344 = 0.503240 */ - 0x206c5280, /* 136) Sine 0.531250 = 0.506611 */ - 0x20a37000, /* 137) Sine 0.535156 = 0.509975 */ - 0x20da6d00, /* 138) Sine 0.539063 = 0.513332 */ - 0x21114940, /* 139) Sine 0.542969 = 0.516680 */ - 0x21480440, /* 140) Sine 0.546875 = 0.520021 */ - 0x217e9e00, /* 141) Sine 0.550781 = 0.523353 */ - 0x21b51640, /* 142) Sine 0.554688 = 0.526678 */ - 0x21eb6d00, /* 143) Sine 0.558594 = 0.529994 */ - 0x2221a180, /* 144) Sine 0.562500 = 0.533303 */ - 0x2257b400, /* 145) Sine 0.566406 = 0.536603 */ - 0x228da440, /* 146) Sine 0.570313 = 0.539895 */ - 0x22c37200, /* 147) Sine 0.574219 = 0.543179 */ - 0x22f91cc0, /* 148) Sine 0.578125 = 0.546455 */ - 0x232ea4c0, /* 149) Sine 0.582031 = 0.549722 */ - 0x23640940, /* 150) Sine 0.585938 = 0.552981 */ - 0x23994ac0, /* 151) Sine 0.589844 = 0.556231 */ - 0x23ce6880, /* 152) Sine 0.593750 = 0.559473 */ - 0x24036240, /* 153) Sine 0.597656 = 0.562707 */ - 0x24383840, /* 154) Sine 0.601563 = 0.565931 */ - 0x246cea00, /* 155) Sine 0.605469 = 0.569148 */ - 0x24a17740, /* 156) Sine 0.609375 = 0.572355 */ - 0x24d5dfc0, /* 157) Sine 0.613281 = 0.575554 */ - 0x250a2380, /* 158) Sine 0.617188 = 0.578744 */ - 0x253e4240, /* 159) Sine 0.621094 = 0.581925 */ - 0x25723bc0, /* 160) Sine 0.625000 = 0.585097 */ - 0x25a61000, /* 161) Sine 0.628906 = 0.588261 */ - 0x25d9be40, /* 162) Sine 0.632813 = 0.591415 */ - 0x260d46c0, /* 163) Sine 0.636719 = 0.594560 */ - 0x2640a980, /* 164) Sine 0.640625 = 0.597697 */ - 0x2673e5c0, /* 165) Sine 0.644531 = 0.600824 */ - 0x26a6fb80, /* 166) Sine 0.648438 = 0.603942 */ - 0x26d9ea80, /* 167) Sine 0.652344 = 0.607051 */ - 0x270cb300, /* 168) Sine 0.656250 = 0.610150 */ - 0x273f5440, /* 169) Sine 0.660156 = 0.613240 */ - 0x2771ce40, /* 170) Sine 0.664063 = 0.616321 */ - 0x27a420c0, /* 171) Sine 0.667969 = 0.619393 */ - 0x27d64bc0, /* 172) Sine 0.671875 = 0.622455 */ - 0x28084ec0, /* 173) Sine 0.675781 = 0.625507 */ - 0x283a29c0, /* 174) Sine 0.679688 = 0.628550 */ - 0x286bdc80, /* 175) Sine 0.683594 = 0.631583 */ - 0x289d6700, /* 176) Sine 0.687500 = 0.634607 */ - 0x28cec8c0, /* 177) Sine 0.691406 = 0.637621 */ - 0x290001c0, /* 178) Sine 0.695313 = 0.640625 */ - 0x293111c0, /* 179) Sine 0.699219 = 0.643620 */ - 0x2961f880, /* 180) Sine 0.703125 = 0.646605 */ - 0x2992b600, /* 181) Sine 0.707031 = 0.649580 */ - 0x29c349c0, /* 182) Sine 0.710938 = 0.652544 */ - 0x29f3b3c0, /* 183) Sine 0.714844 = 0.655499 */ - 0x2a23f400, /* 184) Sine 0.718750 = 0.658444 */ - 0x2a540a00, /* 185) Sine 0.722656 = 0.661379 */ - 0x2a83f580, /* 186) Sine 0.726563 = 0.664304 */ - 0x2ab3b6c0, /* 187) Sine 0.730469 = 0.667219 */ - 0x2ae34d40, /* 188) Sine 0.734375 = 0.670123 */ - 0x2b12b8c0, /* 189) Sine 0.738281 = 0.673018 */ - 0x2b41f940, /* 190) Sine 0.742188 = 0.675902 */ - 0x2b710e80, /* 191) Sine 0.746094 = 0.678775 */ - 0x2b9ff840, /* 192) Sine 0.750000 = 0.681639 */ - 0x2bceb640, /* 193) Sine 0.753906 = 0.684492 */ - 0x2bfd48c0, /* 194) Sine 0.757813 = 0.687334 */ - 0x2c2baf00, /* 195) Sine 0.761719 = 0.690166 */ - 0x2c59e940, /* 196) Sine 0.765625 = 0.692988 */ - 0x2c87f700, /* 197) Sine 0.769531 = 0.695799 */ - 0x2cb5d840, /* 198) Sine 0.773438 = 0.698599 */ - 0x2ce38d00, /* 199) Sine 0.777344 = 0.701389 */ - 0x2d111480, /* 200) Sine 0.781250 = 0.704167 */ - 0x2d3e6f40, /* 201) Sine 0.785156 = 0.706936 */ - 0x2d6b9cc0, /* 202) Sine 0.789063 = 0.709693 */ - 0x2d989c80, /* 203) Sine 0.792969 = 0.712440 */ - 0x2dc56f00, /* 204) Sine 0.796875 = 0.715175 */ - 0x2df21380, /* 205) Sine 0.800781 = 0.717900 */ - 0x2e1e8a40, /* 206) Sine 0.804688 = 0.720614 */ - 0x2e4ad2c0, /* 207) Sine 0.808594 = 0.723317 */ - 0x2e76ed00, /* 208) Sine 0.812500 = 0.726009 */ - 0x2ea2d8c0, /* 209) Sine 0.816406 = 0.728689 */ - 0x2ece9600, /* 210) Sine 0.820313 = 0.731359 */ - 0x2efa2440, /* 211) Sine 0.824219 = 0.734017 */ - 0x2f2583c0, /* 212) Sine 0.828125 = 0.736665 */ - 0x2f50b3c0, /* 213) Sine 0.832031 = 0.739301 */ - 0x2f7bb4c0, /* 214) Sine 0.835938 = 0.741925 */ - 0x2fa68640, /* 215) Sine 0.839844 = 0.744539 */ - 0x2fd12800, /* 216) Sine 0.843750 = 0.747141 */ - 0x2ffb99c0, /* 217) Sine 0.847656 = 0.749731 */ - 0x3025dbc0, /* 218) Sine 0.851563 = 0.752311 */ - 0x304fedc0, /* 219) Sine 0.855469 = 0.754878 */ - 0x3079cf40, /* 220) Sine 0.859375 = 0.757435 */ - 0x30a38040, /* 221) Sine 0.863281 = 0.759979 */ - 0x30cd0080, /* 222) Sine 0.867188 = 0.762512 */ - 0x30f65040, /* 223) Sine 0.871094 = 0.765034 */ - 0x311f6ec0, /* 224) Sine 0.875000 = 0.767543 */ - 0x31485c40, /* 225) Sine 0.878906 = 0.770042 */ - 0x31711880, /* 226) Sine 0.882813 = 0.772528 */ - 0x3199a340, /* 227) Sine 0.886719 = 0.775002 */ - 0x31c1fc80, /* 228) Sine 0.890625 = 0.777465 */ - 0x31ea2400, /* 229) Sine 0.894531 = 0.779916 */ - 0x32121980, /* 230) Sine 0.898438 = 0.782355 */ - 0x3239dcc0, /* 231) Sine 0.902344 = 0.784782 */ - 0x32616e00, /* 232) Sine 0.906250 = 0.787197 */ - 0x3288cd00, /* 233) Sine 0.910156 = 0.789600 */ - 0x32aff940, /* 234) Sine 0.914063 = 0.791991 */ - 0x32d6f2c0, /* 235) Sine 0.917969 = 0.794369 */ - 0x32fdb980, /* 236) Sine 0.921875 = 0.796736 */ - 0x33244d40, /* 237) Sine 0.925781 = 0.799091 */ - 0x334aae00, /* 238) Sine 0.929688 = 0.801433 */ - 0x3370db40, /* 239) Sine 0.933594 = 0.803763 */ - 0x3396d540, /* 240) Sine 0.937500 = 0.806081 */ - 0x33bc9b80, /* 241) Sine 0.941406 = 0.808387 */ - 0x33e22e00, /* 242) Sine 0.945313 = 0.810680 */ - 0x34078cc0, /* 243) Sine 0.949219 = 0.812961 */ - 0x342cb780, /* 244) Sine 0.953125 = 0.815229 */ - 0x3451ae00, /* 245) Sine 0.957031 = 0.817485 */ - 0x34767040, /* 246) Sine 0.960938 = 0.819729 */ - 0x349afdc0, /* 247) Sine 0.964844 = 0.821960 */ - 0x34bf5700, /* 248) Sine 0.968750 = 0.824178 */ - 0x34e37b40, /* 249) Sine 0.972656 = 0.826384 */ - 0x35076ac0, /* 250) Sine 0.976563 = 0.828578 */ - 0x352b2540, /* 251) Sine 0.980469 = 0.830758 */ - 0x354eaa80, /* 252) Sine 0.984375 = 0.832926 */ - 0x3571fa80, /* 253) Sine 0.988281 = 0.835082 */ - 0x35951500, /* 254) Sine 0.992188 = 0.837224 */ - 0x35b7fa00, /* 255) Sine 0.996094 = 0.839354 */ - 0x35daa900, /* 256) Sine 1.000000 = 0.841471 */ - 0x35fd2280, /* 257) Sine 1.003906 = 0.843575 */ - 0x361f65c0, /* 258) Sine 1.007813 = 0.845666 */ - 0x36417300, /* 259) Sine 1.011719 = 0.847745 */ - 0x36634a00, /* 260) Sine 1.015625 = 0.849810 */ - 0x3684eac0, /* 261) Sine 1.019531 = 0.851863 */ - 0x36a654c0, /* 262) Sine 1.023438 = 0.853902 */ - 0x36c78840, /* 263) Sine 1.027344 = 0.855928 */ - 0x36e88500, /* 264) Sine 1.031250 = 0.857942 */ - 0x37094ac0, /* 265) Sine 1.035156 = 0.859942 */ - 0x3729d940, /* 266) Sine 1.039063 = 0.861929 */ - 0x374a3100, /* 267) Sine 1.042969 = 0.863903 */ - 0x376a5140, /* 268) Sine 1.046875 = 0.865864 */ - 0x378a3a00, /* 269) Sine 1.050781 = 0.867812 */ - 0x37a9eb40, /* 270) Sine 1.054688 = 0.869746 */ - 0x37c96500, /* 271) Sine 1.058594 = 0.871667 */ - 0x37e8a6c0, /* 272) Sine 1.062500 = 0.873575 */ - 0x3807b0c0, /* 273) Sine 1.066406 = 0.875469 */ - 0x382682c0, /* 274) Sine 1.070313 = 0.877351 */ - 0x38451c80, /* 275) Sine 1.074219 = 0.879218 */ - 0x38637e00, /* 276) Sine 1.078125 = 0.881073 */ - 0x3881a700, /* 277) Sine 1.082031 = 0.882913 */ - 0x389f97c0, /* 278) Sine 1.085938 = 0.884741 */ - 0x38bd4fc0, /* 279) Sine 1.089844 = 0.886555 */ - 0x38dacf00, /* 280) Sine 1.093750 = 0.888355 */ - 0x38f81540, /* 281) Sine 1.097656 = 0.890142 */ - 0x391522c0, /* 282) Sine 1.101563 = 0.891915 */ - 0x3931f700, /* 283) Sine 1.105469 = 0.893675 */ - 0x394e9240, /* 284) Sine 1.109375 = 0.895421 */ - 0x396af400, /* 285) Sine 1.113281 = 0.897153 */ - 0x39871c80, /* 286) Sine 1.117188 = 0.898872 */ - 0x39a30b40, /* 287) Sine 1.121094 = 0.900576 */ - 0x39bec080, /* 288) Sine 1.125000 = 0.902268 */ - 0x39da3c00, /* 289) Sine 1.128906 = 0.903945 */ - 0x39f57dc0, /* 290) Sine 1.132813 = 0.905609 */ - 0x3a108580, /* 291) Sine 1.136719 = 0.907258 */ - 0x3a2b5300, /* 292) Sine 1.140625 = 0.908894 */ - 0x3a45e680, /* 293) Sine 1.144531 = 0.910516 */ - 0x3a603fc0, /* 294) Sine 1.148438 = 0.912125 */ - 0x3a7a5e80, /* 295) Sine 1.152344 = 0.913719 */ - 0x3a9442c0, /* 296) Sine 1.156250 = 0.915299 */ - 0x3aadec80, /* 297) Sine 1.160156 = 0.916865 */ - 0x3ac75bc0, /* 298) Sine 1.164063 = 0.918418 */ - 0x3ae09000, /* 299) Sine 1.167969 = 0.919956 */ - 0x3af98980, /* 300) Sine 1.171875 = 0.921481 */ - 0x3b1247c0, /* 301) Sine 1.175781 = 0.922991 */ - 0x3b2acb40, /* 302) Sine 1.179688 = 0.924487 */ - 0x3b431380, /* 303) Sine 1.183594 = 0.925969 */ - 0x3b5b2040, /* 304) Sine 1.187500 = 0.927437 */ - 0x3b72f200, /* 305) Sine 1.191406 = 0.928891 */ - 0x3b8a8800, /* 306) Sine 1.195313 = 0.930330 */ - 0x3ba1e2c0, /* 307) Sine 1.199219 = 0.931756 */ - 0x3bb901c0, /* 308) Sine 1.203125 = 0.933167 */ - 0x3bcfe500, /* 309) Sine 1.207031 = 0.934564 */ - 0x3be68c40, /* 310) Sine 1.210938 = 0.935947 */ - 0x3bfcf7c0, /* 311) Sine 1.214844 = 0.937315 */ - 0x3c132780, /* 312) Sine 1.218750 = 0.938669 */ - 0x3c291b00, /* 313) Sine 1.222656 = 0.940009 */ - 0x3c3ed240, /* 314) Sine 1.226563 = 0.941334 */ - 0x3c544d40, /* 315) Sine 1.230469 = 0.942645 */ - 0x3c698c00, /* 316) Sine 1.234375 = 0.943942 */ - 0x3c7e8e40, /* 317) Sine 1.238281 = 0.945224 */ - 0x3c935440, /* 318) Sine 1.242188 = 0.946492 */ - 0x3ca7dd80, /* 319) Sine 1.246094 = 0.947746 */ - 0x3cbc2a00, /* 320) Sine 1.250000 = 0.948985 */ - 0x3cd039c0, /* 321) Sine 1.253906 = 0.950209 */ - 0x3ce40d00, /* 322) Sine 1.257813 = 0.951419 */ - 0x3cf7a300, /* 323) Sine 1.261719 = 0.952615 */ - 0x3d0afc40, /* 324) Sine 1.265625 = 0.953795 */ - 0x3d1e1880, /* 325) Sine 1.269531 = 0.954962 */ - 0x3d30f780, /* 326) Sine 1.273438 = 0.956114 */ - 0x3d439940, /* 327) Sine 1.277344 = 0.957251 */ - 0x3d55fdc0, /* 328) Sine 1.281250 = 0.958373 */ - 0x3d682500, /* 329) Sine 1.285156 = 0.959481 */ - 0x3d7a0f00, /* 330) Sine 1.289063 = 0.960575 */ - 0x3d8bbb40, /* 331) Sine 1.292969 = 0.961654 */ - 0x3d9d2a00, /* 332) Sine 1.296875 = 0.962718 */ - 0x3dae5b40, /* 333) Sine 1.300781 = 0.963767 */ - 0x3dbf4ec0, /* 334) Sine 1.304688 = 0.964801 */ - 0x3dd00480, /* 335) Sine 1.308594 = 0.965821 */ - 0x3de07c80, /* 336) Sine 1.312500 = 0.966827 */ - 0x3df0b680, /* 337) Sine 1.316406 = 0.967817 */ - 0x3e00b2c0, /* 338) Sine 1.320313 = 0.968793 */ - 0x3e1070c0, /* 339) Sine 1.324219 = 0.969753 */ - 0x3e1ff100, /* 340) Sine 1.328125 = 0.970700 */ - 0x3e2f32c0, /* 341) Sine 1.332031 = 0.971631 */ - 0x3e3e3680, /* 342) Sine 1.335938 = 0.972547 */ - 0x3e4cfc40, /* 343) Sine 1.339844 = 0.973449 */ - 0x3e5b8340, /* 344) Sine 1.343750 = 0.974335 */ - 0x3e69cc40, /* 345) Sine 1.347656 = 0.975207 */ - 0x3e77d6c0, /* 346) Sine 1.351563 = 0.976064 */ - 0x3e85a2c0, /* 347) Sine 1.355469 = 0.976906 */ - 0x3e933000, /* 348) Sine 1.359375 = 0.977734 */ - 0x3ea07f00, /* 349) Sine 1.363281 = 0.978546 */ - 0x3ead8f40, /* 350) Sine 1.367188 = 0.979343 */ - 0x3eba60c0, /* 351) Sine 1.371094 = 0.980126 */ - 0x3ec6f3c0, /* 352) Sine 1.375000 = 0.980893 */ - 0x3ed347c0, /* 353) Sine 1.378906 = 0.981646 */ - 0x3edf5d00, /* 354) Sine 1.382813 = 0.982383 */ - 0x3eeb3340, /* 355) Sine 1.386719 = 0.983105 */ - 0x3ef6cac0, /* 356) Sine 1.390625 = 0.983813 */ - 0x3f022340, /* 357) Sine 1.394531 = 0.984505 */ - 0x3f0d3cc0, /* 358) Sine 1.398438 = 0.985183 */ - 0x3f181740, /* 359) Sine 1.402344 = 0.985845 */ - 0x3f22b280, /* 360) Sine 1.406250 = 0.986493 */ - 0x3f2d0ec0, /* 361) Sine 1.410156 = 0.987125 */ - 0x3f372bc0, /* 362) Sine 1.414063 = 0.987742 */ - 0x3f410980, /* 363) Sine 1.417969 = 0.988345 */ - 0x3f4aa840, /* 364) Sine 1.421875 = 0.988932 */ - 0x3f540780, /* 365) Sine 1.425781 = 0.989504 */ - 0x3f5d2780, /* 366) Sine 1.429688 = 0.990061 */ - 0x3f660800, /* 367) Sine 1.433594 = 0.990602 */ - 0x3f6ea940, /* 368) Sine 1.437500 = 0.991129 */ - 0x3f770ac0, /* 369) Sine 1.441406 = 0.991641 */ - 0x3f7f2d40, /* 370) Sine 1.445313 = 0.992137 */ - 0x3f871000, /* 371) Sine 1.449219 = 0.992619 */ - 0x3f8eb340, /* 372) Sine 1.453125 = 0.993085 */ - 0x3f961700, /* 373) Sine 1.457031 = 0.993536 */ - 0x3f9d3b00, /* 374) Sine 1.460938 = 0.993972 */ - 0x3fa41f80, /* 375) Sine 1.464844 = 0.994392 */ - 0x3faac440, /* 376) Sine 1.468750 = 0.994798 */ - 0x3fb12980, /* 377) Sine 1.472656 = 0.995188 */ - 0x3fb74f00, /* 378) Sine 1.476563 = 0.995563 */ - 0x3fbd34c0, /* 379) Sine 1.480469 = 0.995923 */ - 0x3fc2dac0, /* 380) Sine 1.484375 = 0.996268 */ - 0x3fc84140, /* 381) Sine 1.488281 = 0.996598 */ - 0x3fcd67c0, /* 382) Sine 1.492188 = 0.996912 */ - 0x3fd24e40, /* 383) Sine 1.496094 = 0.997211 */ - 0x3fd6f540, /* 384) Sine 1.500000 = 0.997495 */ - 0x3fdb5c40, /* 385) Sine 1.503906 = 0.997764 */ - 0x3fdf8380, /* 386) Sine 1.507813 = 0.998017 */ - 0x3fe36ac0, /* 387) Sine 1.511719 = 0.998255 */ - 0x3fe71240, /* 388) Sine 1.515625 = 0.998478 */ - 0x3fea79c0, /* 389) Sine 1.519531 = 0.998686 */ - 0x3feda140, /* 390) Sine 1.523438 = 0.998879 */ - 0x3ff08900, /* 391) Sine 1.527344 = 0.999056 */ - 0x3ff330c0, /* 392) Sine 1.531250 = 0.999218 */ - 0x3ff59880, /* 393) Sine 1.535156 = 0.999365 */ - 0x3ff7c040, /* 394) Sine 1.539063 = 0.999497 */ - 0x3ff9a800, /* 395) Sine 1.542969 = 0.999613 */ - 0x3ffb5000, /* 396) Sine 1.546875 = 0.999714 */ - 0x3ffcb800, /* 397) Sine 1.550781 = 0.999800 */ - 0x3ffddfc0, /* 398) Sine 1.554688 = 0.999870 */ - 0x3ffec7c0, /* 399) Sine 1.558594 = 0.999926 */ - 0x3fff6fc0, /* 400) Sine 1.562500 = 0.999966 */ - 0x3fffd780, /* 401) Sine 1.566406 = 0.999990 */ - 0x3fffff80, /* 402) Sine 1.570313 = 1.000000 */ - 0x40000000 /* 403) Final entry hard coded to 1.000000 */ -}; - -#if (__cplusplus) -} -#endif - -#endif /* __FIXEDPOINTSINETABLE_H__ */ - +/*! +****************************************************************************** + @file : fixedpoint_sinetable.h + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + Lookup table for fixed point trig functions. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__FIXEDPOINTSINETABLE_H__) +#define __FIXEDPOINTSINETABLE_H__ + +#if (__cplusplus) +extern "C" { +#endif + +/* Table should be referenced using a 1.8 fixed point index, in the range 0->PI/2 */ +/* Values of Sine (x) are in 1.30 fixed point format. */ +img_uint32 FIXEDPT_aui32FixedPointSineTable [] = +{ + 0x00000000, /* 0) Sine 0.000000 = 0.000000 */ + 0x003ffff5, /* 1) Sine 0.003906 = 0.003906 */ + 0x007fffaa, /* 2) Sine 0.007813 = 0.007812 */ + 0x00bffee0, /* 3) Sine 0.011719 = 0.011718 */ + 0x00fffd55, /* 4) Sine 0.015625 = 0.015624 */ + 0x013ffaca, /* 5) Sine 0.019531 = 0.019530 */ + 0x017ff700, /* 6) Sine 0.023438 = 0.023435 */ + 0x01bff1b6, /* 7) Sine 0.027344 = 0.027340 */ + 0x01ffeaaa, /* 8) Sine 0.031250 = 0.031245 */ + 0x023fe1a0, /* 9) Sine 0.035156 = 0.035149 */ + 0x027fd658, /* 10) Sine 0.039063 = 0.039053 */ + 0x02bfc88c, /* 11) Sine 0.042969 = 0.042956 */ + 0x02ffb804, /* 12) Sine 0.046875 = 0.046858 */ + 0x033fa478, /* 13) Sine 0.050781 = 0.050759 */ + 0x037f8db0, /* 14) Sine 0.054688 = 0.054660 */ + 0x03bf7368, /* 15) Sine 0.058594 = 0.058560 */ + 0x03ff555c, /* 16) Sine 0.062500 = 0.062459 */ + 0x043f3358, /* 17) Sine 0.066406 = 0.066357 */ + 0x047f0d10, /* 18) Sine 0.070313 = 0.070255 */ + 0x04bee248, /* 19) Sine 0.074219 = 0.074151 */ + 0x04feb2c8, /* 20) Sine 0.078125 = 0.078046 */ + 0x053e7e40, /* 21) Sine 0.082031 = 0.081939 */ + 0x057e4480, /* 22) Sine 0.085938 = 0.085832 */ + 0x05be0540, /* 23) Sine 0.089844 = 0.089723 */ + 0x05fdc040, /* 24) Sine 0.093750 = 0.093613 */ + 0x063d7548, /* 25) Sine 0.097656 = 0.097501 */ + 0x067d2408, /* 26) Sine 0.101563 = 0.101388 */ + 0x06bccc58, /* 27) Sine 0.105469 = 0.105273 */ + 0x06fc6de0, /* 28) Sine 0.109375 = 0.109157 */ + 0x073c0870, /* 29) Sine 0.113281 = 0.113039 */ + 0x077b9bc8, /* 30) Sine 0.117188 = 0.116919 */ + 0x07bb27a0, /* 31) Sine 0.121094 = 0.120798 */ + 0x07faabb8, /* 32) Sine 0.125000 = 0.124675 */ + 0x083a27e0, /* 33) Sine 0.128906 = 0.128550 */ + 0x08799bc0, /* 34) Sine 0.132813 = 0.132422 */ + 0x08b90730, /* 35) Sine 0.136719 = 0.136293 */ + 0x08f869f0, /* 36) Sine 0.140625 = 0.140162 */ + 0x0937c3b0, /* 37) Sine 0.144531 = 0.144029 */ + 0x09771430, /* 38) Sine 0.148438 = 0.147893 */ + 0x09b65b40, /* 39) Sine 0.152344 = 0.151755 */ + 0x09f59890, /* 40) Sine 0.156250 = 0.155615 */ + 0x0a34cc00, /* 41) Sine 0.160156 = 0.159472 */ + 0x0a73f520, /* 42) Sine 0.164063 = 0.163327 */ + 0x0ab313e0, /* 43) Sine 0.167969 = 0.167180 */ + 0x0af227e0, /* 44) Sine 0.171875 = 0.171030 */ + 0x0b313100, /* 45) Sine 0.175781 = 0.174877 */ + 0x0b702ee0, /* 46) Sine 0.179688 = 0.178722 */ + 0x0baf2150, /* 47) Sine 0.183594 = 0.182564 */ + 0x0bee0810, /* 48) Sine 0.187500 = 0.186403 */ + 0x0c2ce2f0, /* 49) Sine 0.191406 = 0.190240 */ + 0x0c6bb190, /* 50) Sine 0.195313 = 0.194073 */ + 0x0caa73d0, /* 51) Sine 0.199219 = 0.197904 */ + 0x0ce92970, /* 52) Sine 0.203125 = 0.201731 */ + 0x0d27d210, /* 53) Sine 0.207031 = 0.205555 */ + 0x0d666d90, /* 54) Sine 0.210938 = 0.209377 */ + 0x0da4fbb0, /* 55) Sine 0.214844 = 0.213195 */ + 0x0de37c20, /* 56) Sine 0.218750 = 0.217010 */ + 0x0e21eec0, /* 57) Sine 0.222656 = 0.220821 */ + 0x0e605330, /* 58) Sine 0.226563 = 0.224629 */ + 0x0e9ea940, /* 59) Sine 0.230469 = 0.228434 */ + 0x0edcf0b0, /* 60) Sine 0.234375 = 0.232235 */ + 0x0f1b2940, /* 61) Sine 0.238281 = 0.236033 */ + 0x0f5952c0, /* 62) Sine 0.242188 = 0.239827 */ + 0x0f976ce0, /* 63) Sine 0.246094 = 0.243617 */ + 0x0fd57770, /* 64) Sine 0.250000 = 0.247404 */ + 0x10137220, /* 65) Sine 0.253906 = 0.251187 */ + 0x10515cc0, /* 66) Sine 0.257813 = 0.254966 */ + 0x108f3700, /* 67) Sine 0.261719 = 0.258741 */ + 0x10cd00c0, /* 68) Sine 0.265625 = 0.262512 */ + 0x110ab9c0, /* 69) Sine 0.269531 = 0.266280 */ + 0x114861a0, /* 70) Sine 0.273438 = 0.270043 */ + 0x1185f840, /* 71) Sine 0.277344 = 0.273802 */ + 0x11c37d60, /* 72) Sine 0.281250 = 0.277557 */ + 0x1200f0c0, /* 73) Sine 0.285156 = 0.281307 */ + 0x123e5220, /* 74) Sine 0.289063 = 0.285054 */ + 0x127ba120, /* 75) Sine 0.292969 = 0.288796 */ + 0x12b8ddc0, /* 76) Sine 0.296875 = 0.292533 */ + 0x12f607a0, /* 77) Sine 0.300781 = 0.296266 */ + 0x13331ea0, /* 78) Sine 0.304688 = 0.299995 */ + 0x13702240, /* 79) Sine 0.308594 = 0.303719 */ + 0x13ad12a0, /* 80) Sine 0.312500 = 0.307439 */ + 0x13e9ef40, /* 81) Sine 0.316406 = 0.311153 */ + 0x1426b7e0, /* 82) Sine 0.320313 = 0.314863 */ + 0x14636c80, /* 83) Sine 0.324219 = 0.318568 */ + 0x14a00ca0, /* 84) Sine 0.328125 = 0.322269 */ + 0x14dc9820, /* 85) Sine 0.332031 = 0.325964 */ + 0x15190ec0, /* 86) Sine 0.335938 = 0.329654 */ + 0x15557060, /* 87) Sine 0.339844 = 0.333340 */ + 0x1591bca0, /* 88) Sine 0.343750 = 0.337020 */ + 0x15cdf340, /* 89) Sine 0.347656 = 0.340695 */ + 0x160a1420, /* 90) Sine 0.351563 = 0.344365 */ + 0x16461f00, /* 91) Sine 0.355469 = 0.348030 */ + 0x16821380, /* 92) Sine 0.359375 = 0.351689 */ + 0x16bdf1a0, /* 93) Sine 0.363281 = 0.355343 */ + 0x16f9b8e0, /* 94) Sine 0.367188 = 0.358992 */ + 0x17356940, /* 95) Sine 0.371094 = 0.362635 */ + 0x17710260, /* 96) Sine 0.375000 = 0.366273 */ + 0x17ac8400, /* 97) Sine 0.378906 = 0.369905 */ + 0x17e7ee00, /* 98) Sine 0.382813 = 0.373531 */ + 0x18234020, /* 99) Sine 0.386719 = 0.377152 */ + 0x185e7a20, /* 100) Sine 0.390625 = 0.380766 */ + 0x18999ba0, /* 101) Sine 0.394531 = 0.384375 */ + 0x18d4a4a0, /* 102) Sine 0.398438 = 0.387979 */ + 0x190f94e0, /* 103) Sine 0.402344 = 0.391576 */ + 0x194a6be0, /* 104) Sine 0.406250 = 0.395167 */ + 0x198529c0, /* 105) Sine 0.410156 = 0.398753 */ + 0x19bfce00, /* 106) Sine 0.414063 = 0.402332 */ + 0x19fa5880, /* 107) Sine 0.417969 = 0.405905 */ + 0x1a34c920, /* 108) Sine 0.421875 = 0.409472 */ + 0x1a6f1f80, /* 109) Sine 0.425781 = 0.413032 */ + 0x1aa95b60, /* 110) Sine 0.429688 = 0.416587 */ + 0x1ae37ca0, /* 111) Sine 0.433594 = 0.420135 */ + 0x1b1d8300, /* 112) Sine 0.437500 = 0.423676 */ + 0x1b576e40, /* 113) Sine 0.441406 = 0.427211 */ + 0x1b913e40, /* 114) Sine 0.445313 = 0.430740 */ + 0x1bcaf280, /* 115) Sine 0.449219 = 0.434262 */ + 0x1c048b20, /* 116) Sine 0.453125 = 0.437777 */ + 0x1c3e07a0, /* 117) Sine 0.457031 = 0.441286 */ + 0x1c7767e0, /* 118) Sine 0.460938 = 0.444788 */ + 0x1cb0abc0, /* 119) Sine 0.464844 = 0.448283 */ + 0x1ce9d2e0, /* 120) Sine 0.468750 = 0.451771 */ + 0x1d22dd20, /* 121) Sine 0.472656 = 0.455253 */ + 0x1d5bca40, /* 122) Sine 0.476563 = 0.458727 */ + 0x1d9499e0, /* 123) Sine 0.480469 = 0.462195 */ + 0x1dcd4c20, /* 124) Sine 0.484375 = 0.465655 */ + 0x1e05e060, /* 125) Sine 0.488281 = 0.469109 */ + 0x1e3e56c0, /* 126) Sine 0.492188 = 0.472555 */ + 0x1e76aee0, /* 127) Sine 0.496094 = 0.475994 */ + 0x1eaee880, /* 128) Sine 0.500000 = 0.479426 */ + 0x1ee70360, /* 129) Sine 0.503906 = 0.482850 */ + 0x1f1eff60, /* 130) Sine 0.507813 = 0.486267 */ + 0x1f56dc60, /* 131) Sine 0.511719 = 0.489677 */ + 0x1f8e99e0, /* 132) Sine 0.515625 = 0.493079 */ + 0x1fc637e0, /* 133) Sine 0.519531 = 0.496473 */ + 0x1ffdb620, /* 134) Sine 0.523438 = 0.499860 */ + 0x20351480, /* 135) Sine 0.527344 = 0.503240 */ + 0x206c5280, /* 136) Sine 0.531250 = 0.506611 */ + 0x20a37000, /* 137) Sine 0.535156 = 0.509975 */ + 0x20da6d00, /* 138) Sine 0.539063 = 0.513332 */ + 0x21114940, /* 139) Sine 0.542969 = 0.516680 */ + 0x21480440, /* 140) Sine 0.546875 = 0.520021 */ + 0x217e9e00, /* 141) Sine 0.550781 = 0.523353 */ + 0x21b51640, /* 142) Sine 0.554688 = 0.526678 */ + 0x21eb6d00, /* 143) Sine 0.558594 = 0.529994 */ + 0x2221a180, /* 144) Sine 0.562500 = 0.533303 */ + 0x2257b400, /* 145) Sine 0.566406 = 0.536603 */ + 0x228da440, /* 146) Sine 0.570313 = 0.539895 */ + 0x22c37200, /* 147) Sine 0.574219 = 0.543179 */ + 0x22f91cc0, /* 148) Sine 0.578125 = 0.546455 */ + 0x232ea4c0, /* 149) Sine 0.582031 = 0.549722 */ + 0x23640940, /* 150) Sine 0.585938 = 0.552981 */ + 0x23994ac0, /* 151) Sine 0.589844 = 0.556231 */ + 0x23ce6880, /* 152) Sine 0.593750 = 0.559473 */ + 0x24036240, /* 153) Sine 0.597656 = 0.562707 */ + 0x24383840, /* 154) Sine 0.601563 = 0.565931 */ + 0x246cea00, /* 155) Sine 0.605469 = 0.569148 */ + 0x24a17740, /* 156) Sine 0.609375 = 0.572355 */ + 0x24d5dfc0, /* 157) Sine 0.613281 = 0.575554 */ + 0x250a2380, /* 158) Sine 0.617188 = 0.578744 */ + 0x253e4240, /* 159) Sine 0.621094 = 0.581925 */ + 0x25723bc0, /* 160) Sine 0.625000 = 0.585097 */ + 0x25a61000, /* 161) Sine 0.628906 = 0.588261 */ + 0x25d9be40, /* 162) Sine 0.632813 = 0.591415 */ + 0x260d46c0, /* 163) Sine 0.636719 = 0.594560 */ + 0x2640a980, /* 164) Sine 0.640625 = 0.597697 */ + 0x2673e5c0, /* 165) Sine 0.644531 = 0.600824 */ + 0x26a6fb80, /* 166) Sine 0.648438 = 0.603942 */ + 0x26d9ea80, /* 167) Sine 0.652344 = 0.607051 */ + 0x270cb300, /* 168) Sine 0.656250 = 0.610150 */ + 0x273f5440, /* 169) Sine 0.660156 = 0.613240 */ + 0x2771ce40, /* 170) Sine 0.664063 = 0.616321 */ + 0x27a420c0, /* 171) Sine 0.667969 = 0.619393 */ + 0x27d64bc0, /* 172) Sine 0.671875 = 0.622455 */ + 0x28084ec0, /* 173) Sine 0.675781 = 0.625507 */ + 0x283a29c0, /* 174) Sine 0.679688 = 0.628550 */ + 0x286bdc80, /* 175) Sine 0.683594 = 0.631583 */ + 0x289d6700, /* 176) Sine 0.687500 = 0.634607 */ + 0x28cec8c0, /* 177) Sine 0.691406 = 0.637621 */ + 0x290001c0, /* 178) Sine 0.695313 = 0.640625 */ + 0x293111c0, /* 179) Sine 0.699219 = 0.643620 */ + 0x2961f880, /* 180) Sine 0.703125 = 0.646605 */ + 0x2992b600, /* 181) Sine 0.707031 = 0.649580 */ + 0x29c349c0, /* 182) Sine 0.710938 = 0.652544 */ + 0x29f3b3c0, /* 183) Sine 0.714844 = 0.655499 */ + 0x2a23f400, /* 184) Sine 0.718750 = 0.658444 */ + 0x2a540a00, /* 185) Sine 0.722656 = 0.661379 */ + 0x2a83f580, /* 186) Sine 0.726563 = 0.664304 */ + 0x2ab3b6c0, /* 187) Sine 0.730469 = 0.667219 */ + 0x2ae34d40, /* 188) Sine 0.734375 = 0.670123 */ + 0x2b12b8c0, /* 189) Sine 0.738281 = 0.673018 */ + 0x2b41f940, /* 190) Sine 0.742188 = 0.675902 */ + 0x2b710e80, /* 191) Sine 0.746094 = 0.678775 */ + 0x2b9ff840, /* 192) Sine 0.750000 = 0.681639 */ + 0x2bceb640, /* 193) Sine 0.753906 = 0.684492 */ + 0x2bfd48c0, /* 194) Sine 0.757813 = 0.687334 */ + 0x2c2baf00, /* 195) Sine 0.761719 = 0.690166 */ + 0x2c59e940, /* 196) Sine 0.765625 = 0.692988 */ + 0x2c87f700, /* 197) Sine 0.769531 = 0.695799 */ + 0x2cb5d840, /* 198) Sine 0.773438 = 0.698599 */ + 0x2ce38d00, /* 199) Sine 0.777344 = 0.701389 */ + 0x2d111480, /* 200) Sine 0.781250 = 0.704167 */ + 0x2d3e6f40, /* 201) Sine 0.785156 = 0.706936 */ + 0x2d6b9cc0, /* 202) Sine 0.789063 = 0.709693 */ + 0x2d989c80, /* 203) Sine 0.792969 = 0.712440 */ + 0x2dc56f00, /* 204) Sine 0.796875 = 0.715175 */ + 0x2df21380, /* 205) Sine 0.800781 = 0.717900 */ + 0x2e1e8a40, /* 206) Sine 0.804688 = 0.720614 */ + 0x2e4ad2c0, /* 207) Sine 0.808594 = 0.723317 */ + 0x2e76ed00, /* 208) Sine 0.812500 = 0.726009 */ + 0x2ea2d8c0, /* 209) Sine 0.816406 = 0.728689 */ + 0x2ece9600, /* 210) Sine 0.820313 = 0.731359 */ + 0x2efa2440, /* 211) Sine 0.824219 = 0.734017 */ + 0x2f2583c0, /* 212) Sine 0.828125 = 0.736665 */ + 0x2f50b3c0, /* 213) Sine 0.832031 = 0.739301 */ + 0x2f7bb4c0, /* 214) Sine 0.835938 = 0.741925 */ + 0x2fa68640, /* 215) Sine 0.839844 = 0.744539 */ + 0x2fd12800, /* 216) Sine 0.843750 = 0.747141 */ + 0x2ffb99c0, /* 217) Sine 0.847656 = 0.749731 */ + 0x3025dbc0, /* 218) Sine 0.851563 = 0.752311 */ + 0x304fedc0, /* 219) Sine 0.855469 = 0.754878 */ + 0x3079cf40, /* 220) Sine 0.859375 = 0.757435 */ + 0x30a38040, /* 221) Sine 0.863281 = 0.759979 */ + 0x30cd0080, /* 222) Sine 0.867188 = 0.762512 */ + 0x30f65040, /* 223) Sine 0.871094 = 0.765034 */ + 0x311f6ec0, /* 224) Sine 0.875000 = 0.767543 */ + 0x31485c40, /* 225) Sine 0.878906 = 0.770042 */ + 0x31711880, /* 226) Sine 0.882813 = 0.772528 */ + 0x3199a340, /* 227) Sine 0.886719 = 0.775002 */ + 0x31c1fc80, /* 228) Sine 0.890625 = 0.777465 */ + 0x31ea2400, /* 229) Sine 0.894531 = 0.779916 */ + 0x32121980, /* 230) Sine 0.898438 = 0.782355 */ + 0x3239dcc0, /* 231) Sine 0.902344 = 0.784782 */ + 0x32616e00, /* 232) Sine 0.906250 = 0.787197 */ + 0x3288cd00, /* 233) Sine 0.910156 = 0.789600 */ + 0x32aff940, /* 234) Sine 0.914063 = 0.791991 */ + 0x32d6f2c0, /* 235) Sine 0.917969 = 0.794369 */ + 0x32fdb980, /* 236) Sine 0.921875 = 0.796736 */ + 0x33244d40, /* 237) Sine 0.925781 = 0.799091 */ + 0x334aae00, /* 238) Sine 0.929688 = 0.801433 */ + 0x3370db40, /* 239) Sine 0.933594 = 0.803763 */ + 0x3396d540, /* 240) Sine 0.937500 = 0.806081 */ + 0x33bc9b80, /* 241) Sine 0.941406 = 0.808387 */ + 0x33e22e00, /* 242) Sine 0.945313 = 0.810680 */ + 0x34078cc0, /* 243) Sine 0.949219 = 0.812961 */ + 0x342cb780, /* 244) Sine 0.953125 = 0.815229 */ + 0x3451ae00, /* 245) Sine 0.957031 = 0.817485 */ + 0x34767040, /* 246) Sine 0.960938 = 0.819729 */ + 0x349afdc0, /* 247) Sine 0.964844 = 0.821960 */ + 0x34bf5700, /* 248) Sine 0.968750 = 0.824178 */ + 0x34e37b40, /* 249) Sine 0.972656 = 0.826384 */ + 0x35076ac0, /* 250) Sine 0.976563 = 0.828578 */ + 0x352b2540, /* 251) Sine 0.980469 = 0.830758 */ + 0x354eaa80, /* 252) Sine 0.984375 = 0.832926 */ + 0x3571fa80, /* 253) Sine 0.988281 = 0.835082 */ + 0x35951500, /* 254) Sine 0.992188 = 0.837224 */ + 0x35b7fa00, /* 255) Sine 0.996094 = 0.839354 */ + 0x35daa900, /* 256) Sine 1.000000 = 0.841471 */ + 0x35fd2280, /* 257) Sine 1.003906 = 0.843575 */ + 0x361f65c0, /* 258) Sine 1.007813 = 0.845666 */ + 0x36417300, /* 259) Sine 1.011719 = 0.847745 */ + 0x36634a00, /* 260) Sine 1.015625 = 0.849810 */ + 0x3684eac0, /* 261) Sine 1.019531 = 0.851863 */ + 0x36a654c0, /* 262) Sine 1.023438 = 0.853902 */ + 0x36c78840, /* 263) Sine 1.027344 = 0.855928 */ + 0x36e88500, /* 264) Sine 1.031250 = 0.857942 */ + 0x37094ac0, /* 265) Sine 1.035156 = 0.859942 */ + 0x3729d940, /* 266) Sine 1.039063 = 0.861929 */ + 0x374a3100, /* 267) Sine 1.042969 = 0.863903 */ + 0x376a5140, /* 268) Sine 1.046875 = 0.865864 */ + 0x378a3a00, /* 269) Sine 1.050781 = 0.867812 */ + 0x37a9eb40, /* 270) Sine 1.054688 = 0.869746 */ + 0x37c96500, /* 271) Sine 1.058594 = 0.871667 */ + 0x37e8a6c0, /* 272) Sine 1.062500 = 0.873575 */ + 0x3807b0c0, /* 273) Sine 1.066406 = 0.875469 */ + 0x382682c0, /* 274) Sine 1.070313 = 0.877351 */ + 0x38451c80, /* 275) Sine 1.074219 = 0.879218 */ + 0x38637e00, /* 276) Sine 1.078125 = 0.881073 */ + 0x3881a700, /* 277) Sine 1.082031 = 0.882913 */ + 0x389f97c0, /* 278) Sine 1.085938 = 0.884741 */ + 0x38bd4fc0, /* 279) Sine 1.089844 = 0.886555 */ + 0x38dacf00, /* 280) Sine 1.093750 = 0.888355 */ + 0x38f81540, /* 281) Sine 1.097656 = 0.890142 */ + 0x391522c0, /* 282) Sine 1.101563 = 0.891915 */ + 0x3931f700, /* 283) Sine 1.105469 = 0.893675 */ + 0x394e9240, /* 284) Sine 1.109375 = 0.895421 */ + 0x396af400, /* 285) Sine 1.113281 = 0.897153 */ + 0x39871c80, /* 286) Sine 1.117188 = 0.898872 */ + 0x39a30b40, /* 287) Sine 1.121094 = 0.900576 */ + 0x39bec080, /* 288) Sine 1.125000 = 0.902268 */ + 0x39da3c00, /* 289) Sine 1.128906 = 0.903945 */ + 0x39f57dc0, /* 290) Sine 1.132813 = 0.905609 */ + 0x3a108580, /* 291) Sine 1.136719 = 0.907258 */ + 0x3a2b5300, /* 292) Sine 1.140625 = 0.908894 */ + 0x3a45e680, /* 293) Sine 1.144531 = 0.910516 */ + 0x3a603fc0, /* 294) Sine 1.148438 = 0.912125 */ + 0x3a7a5e80, /* 295) Sine 1.152344 = 0.913719 */ + 0x3a9442c0, /* 296) Sine 1.156250 = 0.915299 */ + 0x3aadec80, /* 297) Sine 1.160156 = 0.916865 */ + 0x3ac75bc0, /* 298) Sine 1.164063 = 0.918418 */ + 0x3ae09000, /* 299) Sine 1.167969 = 0.919956 */ + 0x3af98980, /* 300) Sine 1.171875 = 0.921481 */ + 0x3b1247c0, /* 301) Sine 1.175781 = 0.922991 */ + 0x3b2acb40, /* 302) Sine 1.179688 = 0.924487 */ + 0x3b431380, /* 303) Sine 1.183594 = 0.925969 */ + 0x3b5b2040, /* 304) Sine 1.187500 = 0.927437 */ + 0x3b72f200, /* 305) Sine 1.191406 = 0.928891 */ + 0x3b8a8800, /* 306) Sine 1.195313 = 0.930330 */ + 0x3ba1e2c0, /* 307) Sine 1.199219 = 0.931756 */ + 0x3bb901c0, /* 308) Sine 1.203125 = 0.933167 */ + 0x3bcfe500, /* 309) Sine 1.207031 = 0.934564 */ + 0x3be68c40, /* 310) Sine 1.210938 = 0.935947 */ + 0x3bfcf7c0, /* 311) Sine 1.214844 = 0.937315 */ + 0x3c132780, /* 312) Sine 1.218750 = 0.938669 */ + 0x3c291b00, /* 313) Sine 1.222656 = 0.940009 */ + 0x3c3ed240, /* 314) Sine 1.226563 = 0.941334 */ + 0x3c544d40, /* 315) Sine 1.230469 = 0.942645 */ + 0x3c698c00, /* 316) Sine 1.234375 = 0.943942 */ + 0x3c7e8e40, /* 317) Sine 1.238281 = 0.945224 */ + 0x3c935440, /* 318) Sine 1.242188 = 0.946492 */ + 0x3ca7dd80, /* 319) Sine 1.246094 = 0.947746 */ + 0x3cbc2a00, /* 320) Sine 1.250000 = 0.948985 */ + 0x3cd039c0, /* 321) Sine 1.253906 = 0.950209 */ + 0x3ce40d00, /* 322) Sine 1.257813 = 0.951419 */ + 0x3cf7a300, /* 323) Sine 1.261719 = 0.952615 */ + 0x3d0afc40, /* 324) Sine 1.265625 = 0.953795 */ + 0x3d1e1880, /* 325) Sine 1.269531 = 0.954962 */ + 0x3d30f780, /* 326) Sine 1.273438 = 0.956114 */ + 0x3d439940, /* 327) Sine 1.277344 = 0.957251 */ + 0x3d55fdc0, /* 328) Sine 1.281250 = 0.958373 */ + 0x3d682500, /* 329) Sine 1.285156 = 0.959481 */ + 0x3d7a0f00, /* 330) Sine 1.289063 = 0.960575 */ + 0x3d8bbb40, /* 331) Sine 1.292969 = 0.961654 */ + 0x3d9d2a00, /* 332) Sine 1.296875 = 0.962718 */ + 0x3dae5b40, /* 333) Sine 1.300781 = 0.963767 */ + 0x3dbf4ec0, /* 334) Sine 1.304688 = 0.964801 */ + 0x3dd00480, /* 335) Sine 1.308594 = 0.965821 */ + 0x3de07c80, /* 336) Sine 1.312500 = 0.966827 */ + 0x3df0b680, /* 337) Sine 1.316406 = 0.967817 */ + 0x3e00b2c0, /* 338) Sine 1.320313 = 0.968793 */ + 0x3e1070c0, /* 339) Sine 1.324219 = 0.969753 */ + 0x3e1ff100, /* 340) Sine 1.328125 = 0.970700 */ + 0x3e2f32c0, /* 341) Sine 1.332031 = 0.971631 */ + 0x3e3e3680, /* 342) Sine 1.335938 = 0.972547 */ + 0x3e4cfc40, /* 343) Sine 1.339844 = 0.973449 */ + 0x3e5b8340, /* 344) Sine 1.343750 = 0.974335 */ + 0x3e69cc40, /* 345) Sine 1.347656 = 0.975207 */ + 0x3e77d6c0, /* 346) Sine 1.351563 = 0.976064 */ + 0x3e85a2c0, /* 347) Sine 1.355469 = 0.976906 */ + 0x3e933000, /* 348) Sine 1.359375 = 0.977734 */ + 0x3ea07f00, /* 349) Sine 1.363281 = 0.978546 */ + 0x3ead8f40, /* 350) Sine 1.367188 = 0.979343 */ + 0x3eba60c0, /* 351) Sine 1.371094 = 0.980126 */ + 0x3ec6f3c0, /* 352) Sine 1.375000 = 0.980893 */ + 0x3ed347c0, /* 353) Sine 1.378906 = 0.981646 */ + 0x3edf5d00, /* 354) Sine 1.382813 = 0.982383 */ + 0x3eeb3340, /* 355) Sine 1.386719 = 0.983105 */ + 0x3ef6cac0, /* 356) Sine 1.390625 = 0.983813 */ + 0x3f022340, /* 357) Sine 1.394531 = 0.984505 */ + 0x3f0d3cc0, /* 358) Sine 1.398438 = 0.985183 */ + 0x3f181740, /* 359) Sine 1.402344 = 0.985845 */ + 0x3f22b280, /* 360) Sine 1.406250 = 0.986493 */ + 0x3f2d0ec0, /* 361) Sine 1.410156 = 0.987125 */ + 0x3f372bc0, /* 362) Sine 1.414063 = 0.987742 */ + 0x3f410980, /* 363) Sine 1.417969 = 0.988345 */ + 0x3f4aa840, /* 364) Sine 1.421875 = 0.988932 */ + 0x3f540780, /* 365) Sine 1.425781 = 0.989504 */ + 0x3f5d2780, /* 366) Sine 1.429688 = 0.990061 */ + 0x3f660800, /* 367) Sine 1.433594 = 0.990602 */ + 0x3f6ea940, /* 368) Sine 1.437500 = 0.991129 */ + 0x3f770ac0, /* 369) Sine 1.441406 = 0.991641 */ + 0x3f7f2d40, /* 370) Sine 1.445313 = 0.992137 */ + 0x3f871000, /* 371) Sine 1.449219 = 0.992619 */ + 0x3f8eb340, /* 372) Sine 1.453125 = 0.993085 */ + 0x3f961700, /* 373) Sine 1.457031 = 0.993536 */ + 0x3f9d3b00, /* 374) Sine 1.460938 = 0.993972 */ + 0x3fa41f80, /* 375) Sine 1.464844 = 0.994392 */ + 0x3faac440, /* 376) Sine 1.468750 = 0.994798 */ + 0x3fb12980, /* 377) Sine 1.472656 = 0.995188 */ + 0x3fb74f00, /* 378) Sine 1.476563 = 0.995563 */ + 0x3fbd34c0, /* 379) Sine 1.480469 = 0.995923 */ + 0x3fc2dac0, /* 380) Sine 1.484375 = 0.996268 */ + 0x3fc84140, /* 381) Sine 1.488281 = 0.996598 */ + 0x3fcd67c0, /* 382) Sine 1.492188 = 0.996912 */ + 0x3fd24e40, /* 383) Sine 1.496094 = 0.997211 */ + 0x3fd6f540, /* 384) Sine 1.500000 = 0.997495 */ + 0x3fdb5c40, /* 385) Sine 1.503906 = 0.997764 */ + 0x3fdf8380, /* 386) Sine 1.507813 = 0.998017 */ + 0x3fe36ac0, /* 387) Sine 1.511719 = 0.998255 */ + 0x3fe71240, /* 388) Sine 1.515625 = 0.998478 */ + 0x3fea79c0, /* 389) Sine 1.519531 = 0.998686 */ + 0x3feda140, /* 390) Sine 1.523438 = 0.998879 */ + 0x3ff08900, /* 391) Sine 1.527344 = 0.999056 */ + 0x3ff330c0, /* 392) Sine 1.531250 = 0.999218 */ + 0x3ff59880, /* 393) Sine 1.535156 = 0.999365 */ + 0x3ff7c040, /* 394) Sine 1.539063 = 0.999497 */ + 0x3ff9a800, /* 395) Sine 1.542969 = 0.999613 */ + 0x3ffb5000, /* 396) Sine 1.546875 = 0.999714 */ + 0x3ffcb800, /* 397) Sine 1.550781 = 0.999800 */ + 0x3ffddfc0, /* 398) Sine 1.554688 = 0.999870 */ + 0x3ffec7c0, /* 399) Sine 1.558594 = 0.999926 */ + 0x3fff6fc0, /* 400) Sine 1.562500 = 0.999966 */ + 0x3fffd780, /* 401) Sine 1.566406 = 0.999990 */ + 0x3fffff80, /* 402) Sine 1.570313 = 1.000000 */ + 0x40000000 /* 403) Final entry hard coded to 1.000000 */ +}; + +#if (__cplusplus) +} +#endif + +#endif /* __FIXEDPOINTSINETABLE_H__ */ + diff --git a/src/powervr_iep_lite/fixedpointmaths/fixedpointmaths.c b/src/powervr_iep_lite/fixedpointmaths/fixedpointmaths.c index a22e58a..ef1603c 100644 --- a/src/powervr_iep_lite/fixedpointmaths/fixedpointmaths.c +++ b/src/powervr_iep_lite/fixedpointmaths/fixedpointmaths.c @@ -1,559 +1,559 @@ -/*! -****************************************************************************** - @file : fixedpointmaths.c - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - This module contains various utility functions to assist in - performing fixed point calculations. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#include "img_iep_defs.h" -#include "fixedpointmaths.h" -#include "fixedpoint_sinetable.h" - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitMultiply - -******************************************************************************/ - -img_uint32 FIXEDPT_64BitMultiply ( img_uint32 ui32X, - img_uint32 ui32Y, - img_uint32 ui32PostShiftResult ) -{ - - /* Note : */ - /* */ - /* Works on the principle that a 32 bit value, X, can be split into two 16 bit parts, */ - /* X0 (the lower 16 bits of X) and X1 (the upper sixteen bits of X), where X = X0 + X1. */ - /* Hence TWO 32 bit numbers, X and Y, can be expanded in this way and the */ - /* multiplication expanded : */ - /* X * Y = (X0 + X1)(Y0 + Y1) */ - /* = X0.Y0 + X0.Y1 + X1.Y0 + X1.Y1 */ - - img_uint32 ui32X0, ui32X1, ui32Y0, ui32Y1; - img_uint32 ui32C0, ui32C1, ui32C2, ui32C3; - - img_uint32 ui32Temp; - - /* Extract 16 bit portions */ - ui32X0 = ui32X & 0xFFFF; - ui32Y0 = ui32Y & 0xFFFF; - - ui32X1 = (ui32X >> 16) & 0xFFFF; - ui32Y1 = (ui32Y >> 16) & 0xFFFF; - - ui32Temp = ui32X0 * ui32Y0; - - ui32C0 = ui32Temp & 0xFFFF; - ui32C1 = ui32Temp >> 16; - - ui32Temp = ui32X1 * ui32Y0; - - ui32C1 += ui32Temp & 0xFFFF; - ui32C2 = ui32Temp >> 16; - - ui32Temp = ui32X0 * ui32Y1; - - ui32C1 += ui32Temp & 0xFFFF; - ui32C2 += ui32Temp >> 16; - - ui32Temp = ui32X1 * ui32Y1; - - ui32C2 += ui32Temp & 0xFFFF; - ui32C3 = ui32Temp >> 16; - - /* Now ripple up the overflows */ - ui32C2 += ui32C1 >> 16; - ui32C3 += ui32C2 >> 16; - - /* Combine 16 bit pairs into 2 32 bit values */ - ui32C0 = ui32C0 | (ui32C1 << 16); - ui32C2 = (ui32C2 & 0xFFFF) | (ui32C3 << 16); - - /* Pick the required 32 bits */ - if(ui32PostShiftResult >= 32) - { - ui32C0 = ui32C2; - ui32C2 = 0; - ui32PostShiftResult -= 32; - } - - ui32Temp = (ui32C0 >> ui32PostShiftResult) | (ui32C2 << (32 - ui32PostShiftResult)); - - /* Ensure nothing is left in the upper 32 bit word following the downshift */ - IMG_ASSERT ( (ui32C2 >> ui32PostShiftResult) == 0 ); - - return ui32Temp; -} - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitDivide - -******************************************************************************/ - -img_uint32 FIXEDPT_64BitDivide ( img_uint32 ui32Numerator, - img_uint32 ui32Denominator, - img_uint32 ui32PostShiftResult ) -{ - img_uint32 ui32Remainder; - img_uint32 ui32Divisor; - img_uint32 ui32ResultTop; - img_uint32 ui32ResultBot; - img_uint32 ui32FinalResult; - img_uint32 ui32DivBit; - - img_int32 i32DivisionShift; - - /* No divisions by zero thankyou */ - IMG_ASSERT ( ui32Denominator ); - - /* special case of zero numerator */ - if(!ui32Numerator) - { - return 0; - } - - /* Set Numerator/Remainder to be "A * 2^32" */ - ui32Remainder = ui32Numerator; - ui32Divisor = ui32Denominator; - - i32DivisionShift = 32; - ui32ResultTop = 0; - ui32ResultBot = 0; - - /* Do a pre-normalising step so that at least one of A or B has the MSB set */ - while(((ui32Remainder | ui32Divisor) & 0x80000000) == 0) - { - ui32Remainder <<= 1; - ui32Divisor <<= 1; - } - - /* Now make adjust either remainder or numerator so that the other also has the */ - /* top bit set */ - if((ui32Remainder & 0x80000000) == 0) - { - do - { - ui32Remainder <<= 1; - i32DivisionShift--; - - } - while((ui32Remainder & 0x80000000) == 0); - } - else if((ui32Divisor & 0x80000000) == 0) - { - do - { - ui32Divisor <<= 1; - i32DivisionShift++; - - } - while((ui32Divisor & 0x80000000) == 0); - } - - /* Set the "divbit" to access the correct bit in the 64 bit result */ - if(i32DivisionShift >= 32) - { - ui32DivBit = 1 << (i32DivisionShift -32); - } - else - { - ui32DivBit = 1 << i32DivisionShift; - } - - /* Start doing the division */ - while(ui32Remainder && (i32DivisionShift >= 0)) - { - /* Shift the remainder until the MSB is set */ - while((ui32Remainder & 0x80000000) == 0) - { - ui32Remainder <<= 1; - i32DivisionShift --; - - ui32DivBit >>= 1; - if(ui32DivBit == 0) - { - ui32DivBit = 0x80000000; - } - } - - /* If we've run out of sig digits, exit */ - if(i32DivisionShift < 0) - { - break; - } - - - /* If we can subtract the divisor from the current remainder... */ - if(ui32Remainder >= ui32Divisor) - { - ui32Remainder -= ui32Divisor; - - IMG_ASSERT (ui32Remainder < ui32Divisor); - - if(i32DivisionShift >= 32) - { - ui32ResultTop |= ui32DivBit; - } - else - { - ui32ResultBot |= ui32DivBit; - } - - /* Move to the next bit... */ - ui32Remainder <<= 1; - - i32DivisionShift --; - ui32DivBit >>= 1; - if(i32DivisionShift == 31) - { - ui32DivBit = 0x80000000; - } - - } - /* else we MUST be able to subtract 1/2 of the divisor from the remainder.. */ - /* Multiply the remainder by 2 (which loses the top bit which we know to be */ - /* set) and subtract the divisor. */ - else - { - ui32Remainder = (ui32Remainder << 1) - ui32Divisor; - - /* Because we are subtracting 1/2 the divisor pre-adjust our position. */ - /* */ - /* Note that it doesnt matter if division shift goes negative here */ - /* because the DivBit will hit zero as well. */ - i32DivisionShift --; - ui32DivBit >>= 1; - if(i32DivisionShift == 31) - { - ui32DivBit = 0x80000000; - } - - if(i32DivisionShift >= 32) - { - ui32ResultTop |= ui32DivBit; - } - else - { - ui32ResultBot |= ui32DivBit; - } - }/*end if/else*/ - - }/*end while*/ - - ui32FinalResult = (ui32ResultBot >> ui32PostShiftResult) | - (ui32ResultTop << (32 - ui32PostShiftResult)); - - IMG_ASSERT ( (ui32ResultTop >> ui32PostShiftResult) == 0 ); - - return ui32FinalResult; -} - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitMultiply_Signed - -******************************************************************************/ - -img_int32 FIXEDPT_64BitMultiply_Signed ( img_int32 i32X, - img_int32 i32Y, - img_uint32 ui32PostShiftResult ) -{ - img_int64 i64IntermediateResult; - - i64IntermediateResult = (img_int64) i32X * (img_int64) i32Y; - i64IntermediateResult >>= ui32PostShiftResult; - - /* After the shift, the signed bit in the resultant 32 bit value (i.e.: bit 31) */ - /* should be replicated in every bit above it in the 64 bit value. As such, we */ - /* can compare bits 31 and 63 in the intermediate result and if they do not */ - /* match we can assume we have overflowed. */ - IMG_ASSERT (( i64IntermediateResult >> 63 ) == ( i64IntermediateResult >> 31 )); - - return ((img_int32) i64IntermediateResult); -} - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitDivide_Signed - -******************************************************************************/ - -/*INLINE*/ img_int32 FIXEDPT_64BitDivide_Signed ( img_int32 ui32Numerator, - img_int32 ui32Denominator, - img_uint32 ui32PostShiftResult ) -{ - img_int64 i64IntermediateResult; - - i64IntermediateResult = (img_int64) ui32Numerator << 32; - i64IntermediateResult = i64IntermediateResult / (img_int64) ui32Denominator; - i64IntermediateResult >>= ui32PostShiftResult; - - /* After the shift, the signed bit in the resultant 32 bit value (i.e.: bit 31) */ - /* should be replicated in every bit above it in the 64 bit value. As such, we */ - /* can compare bits 31 and 63 in the intermediate result and if they do not */ - /* match we can assume we have overflowed. */ - IMG_ASSERT (( i64IntermediateResult >> 63 ) == ( i64IntermediateResult >> 31 )); - - return ((img_int32) i64IntermediateResult); -} - -/*! -****************************************************************************** - - @Function FIXEDPT_Sine - -******************************************************************************/ - -img_int32 FIXEDPT_Sine ( img_uint32 ui32Theta ) -{ - /* Note : This function uses a lookup table for basic reference, then improves on the */ - /* result by interpolating linearly. A possible future enhancement would be to use */ - /* quadratic interpolation instead of linear. */ - - img_uint32 ui32LookupRef; - img_uint32 ui32TableRef; - img_uint32 ui32TableValueBelow, ui32TableValueAbove; - img_uint32 ui32Offset; - img_uint32 ui32Difference; - img_uint32 ui32LinearAddition; - img_int32 i32InterpolatedValue; - - /* Theta must be no greater than 2PI */ - IMG_ASSERT ( ui32Theta <= (FIXEDPT_PI << 1) ); - - if ( ui32Theta > (FIXEDPT_PI >> 1) ) - { - if ( ui32Theta > FIXEDPT_PI ) - { - if ( ui32Theta > (FIXEDPT_PI + (FIXEDPT_PI >> 1)) ) - { - /* Between 3PI/2 and 2PI */ - - ui32LookupRef = (ui32Theta - (FIXEDPT_PI + (FIXEDPT_PI >> 1))); /* Fit into range of table, 0 to PI/2 */ - ui32LookupRef = (FIXEDPT_PI >> 1) - ui32LookupRef; /* Reference table 'backwards' */ - } - else - { - /* Between PI and 3PI/2 */ - ui32LookupRef = (ui32Theta - FIXEDPT_PI); - } - } - else - { - /* Between PI/2 and PI */ - - /* Fit into range of table, 0 to PI/2 */ - ui32LookupRef = (ui32Theta - (FIXEDPT_PI >> 1)); - /* Reference table 'backwards' */ - ui32LookupRef = (FIXEDPT_PI >> 1) - ui32LookupRef; - } - } - else - { - /* Between 0 and PI/2 */ - ui32LookupRef = ui32Theta; - } - - /********************************/ - /* Perform linear interpolation */ - /********************************/ - - /* Lookup reference is a 1.29 bit unsigned fixed point value between 0 and PI/2 */ - ui32TableRef = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(ui32LookupRef,FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS,FIXEDPT_SINE_TABLE_FRACTION_SIZE); /* Adjust to granularity of table. */ - - ui32TableValueBelow = FIXEDPT_aui32FixedPointSineTable [ ui32TableRef ]; - ui32TableValueAbove = FIXEDPT_aui32FixedPointSineTable [ (ui32TableRef+1) ]; - - ui32Difference = ui32TableValueAbove - ui32TableValueBelow; /* (Difference between two nearest points in table) */ - - ui32Offset = ui32LookupRef - (FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(ui32TableRef,FIXEDPT_SINE_TABLE_FRACTION_SIZE,FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS)); /* Horizontal difference between nearest point below */ - /* and actual requested point. Result is in 1.29 fmt */ - - /* y=mx+c. m=(diff y)/(diff x). therefore linear addition = (diff y * offset)/(diff x) */ - /* We know that (diff x) is one increment of an x.8 number. As such, a divide by (diff x) */ - /* is the same as multiplying by 256 (which we can achieve by not downshifting the multiply */ - /* as much as we otherwise would). */ - ui32LinearAddition = FIXEDPT_64BitMultiply ( ui32Difference, /* (1.30 * 1.29)/(2^-FIXEDPT_SINE_TABLE_FRACTION_SIZE) */ - ui32Offset, - (FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS-FIXEDPT_SINE_TABLE_FRACTION_SIZE) ); - - i32InterpolatedValue = ui32TableValueBelow + ui32LinearAddition; /* Result is 1.30 */ - - if ( ui32Theta > FIXEDPT_PI ) - { - i32InterpolatedValue = -1 * i32InterpolatedValue; - } - - return i32InterpolatedValue; -} - -/*! -****************************************************************************** - - @Function FIXEDPT_Cosine - -******************************************************************************/ - -img_int32 FIXEDPT_Cosine ( img_uint32 ui32Theta ) -{ - img_uint32 ui32SinTheta; - - /* Theta must be no greater than 2PI */ - IMG_ASSERT ( ui32Theta <= (FIXEDPT_PI << 1) ); - - /* Cos(Theta) = Sin(Theta+(PI/2 radians)) */ - if ( ui32Theta >= (FIXEDPT_PI + (FIXEDPT_PI >> 1)) ) - { - ui32SinTheta = ui32Theta - (FIXEDPT_PI + (FIXEDPT_PI >> 1)); - } - else - { - ui32SinTheta = ui32Theta + (FIXEDPT_PI >> 1); - } - - return (FIXEDPT_Sine(ui32SinTheta)); -} - -/*! -****************************************************************************** - - @Function FIXEDPT_MatrixMultiply - -******************************************************************************/ - -img_void FIXEDPT_MatrixMultiply ( img_uint32 ui32MatrixARows, - img_uint32 ui32MatrixAColumns, - img_uint32 ui32MatrixBRows, - img_uint32 ui32MatrixBColumns, - img_uint32 ui32ResultRows, - img_uint32 ui32ResultColumns, - img_int32 * pai32MatrixA, - img_int32 * pai32MatrixB, - img_int32 * pai32ResultMatrix, - img_uint32 ui32PostShiftResults ) -{ - img_uint32 ui32m; - img_uint32 ui32n; - img_uint32 ui32p; - img_int64 i64Sum; - - /* Check that matrix pointers are valid */ - IMG_ASSERT ( pai32MatrixA != IMG_NULL ); - IMG_ASSERT ( pai32MatrixB != IMG_NULL ); - IMG_ASSERT ( pai32ResultMatrix != IMG_NULL ); - - /* Check matrix dimensions are sensible */ - IMG_ASSERT ( ui32MatrixARows != 0 ); - IMG_ASSERT ( ui32MatrixAColumns != 0 ); - IMG_ASSERT ( ui32MatrixBRows != 0 ); - IMG_ASSERT ( ui32MatrixBColumns != 0 ); - IMG_ASSERT ( ui32ResultRows != 0 ); - IMG_ASSERT ( ui32ResultColumns != 0 ); - - /* Can only multiply matrices where the number of columns in the left hand matrix */ - /* (matrix A) is the same as the number of rows in the right hand matrix (matrix B) */ - IMG_ASSERT ( ui32MatrixAColumns == ui32MatrixBRows ); - - /* If matrix A has m rows and n columns, and matrix B has n rows and p columns, */ - /* then the matrix resulting from multiplying A by B will have m rows and p columns */ - IMG_ASSERT ( ui32ResultRows == ui32MatrixARows ); - IMG_ASSERT ( ui32ResultColumns == ui32MatrixBColumns ); - - for ( ui32m=0; ui32m> 63 ) == ( i64Sum >> 31 )); - } - - /* Set appropriate element in result */ - /* ResultMatrix [m,p] = Sum */ - pai32ResultMatrix [((ui32m*ui32ResultColumns)+ui32p)] = (img_int32) i64Sum; - } - } -} - -/*! -****************************************************************************** - - @Function FIXEDPT_ScalarMatrixMultiply - -******************************************************************************/ - -img_void FIXEDPT_ScalarMatrixMultiply ( img_uint32 ui32MatrixRows, - img_uint32 ui32MatrixColumns, - img_int32 * pai32MatrixA, - img_int32 * pai32MatrixB, - img_int32 * pai32ResultantMatrix, - img_uint32 ui32PostShiftResults ) -{ - img_uint32 ui32m; - img_uint32 ui32n; - - /* Check that matrix pointer is valid */ - IMG_ASSERT ( pai32MatrixA != IMG_NULL ); - IMG_ASSERT ( pai32MatrixB != IMG_NULL ); - IMG_ASSERT ( pai32ResultantMatrix != IMG_NULL ); - - /* Resultant matrix cannot be the same as either of the input matrices, as this */ - /* will result in an incorrect result (as the result matrix is written as the */ - /* calculation proceeds, so it cannot be read from as well as written to as */ - /* of the same calculation). */ - IMG_ASSERT ( pai32ResultantMatrix != pai32MatrixA ); - IMG_ASSERT ( pai32ResultantMatrix != pai32MatrixB ); - - /* Check matrix dimensions are sensible */ - IMG_ASSERT ( ui32MatrixRows != 0 ); - IMG_ASSERT ( ui32MatrixColumns != 0 ); - - for ( ui32m=0; ui32mCopyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + This module contains various utility functions to assist in + performing fixed point calculations. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#include "img_iep_defs.h" +#include "fixedpointmaths.h" +#include "fixedpoint_sinetable.h" + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitMultiply + +******************************************************************************/ + +img_uint32 FIXEDPT_64BitMultiply ( img_uint32 ui32X, + img_uint32 ui32Y, + img_uint32 ui32PostShiftResult ) +{ + + /* Note : */ + /* */ + /* Works on the principle that a 32 bit value, X, can be split into two 16 bit parts, */ + /* X0 (the lower 16 bits of X) and X1 (the upper sixteen bits of X), where X = X0 + X1. */ + /* Hence TWO 32 bit numbers, X and Y, can be expanded in this way and the */ + /* multiplication expanded : */ + /* X * Y = (X0 + X1)(Y0 + Y1) */ + /* = X0.Y0 + X0.Y1 + X1.Y0 + X1.Y1 */ + + img_uint32 ui32X0, ui32X1, ui32Y0, ui32Y1; + img_uint32 ui32C0, ui32C1, ui32C2, ui32C3; + + img_uint32 ui32Temp; + + /* Extract 16 bit portions */ + ui32X0 = ui32X & 0xFFFF; + ui32Y0 = ui32Y & 0xFFFF; + + ui32X1 = (ui32X >> 16) & 0xFFFF; + ui32Y1 = (ui32Y >> 16) & 0xFFFF; + + ui32Temp = ui32X0 * ui32Y0; + + ui32C0 = ui32Temp & 0xFFFF; + ui32C1 = ui32Temp >> 16; + + ui32Temp = ui32X1 * ui32Y0; + + ui32C1 += ui32Temp & 0xFFFF; + ui32C2 = ui32Temp >> 16; + + ui32Temp = ui32X0 * ui32Y1; + + ui32C1 += ui32Temp & 0xFFFF; + ui32C2 += ui32Temp >> 16; + + ui32Temp = ui32X1 * ui32Y1; + + ui32C2 += ui32Temp & 0xFFFF; + ui32C3 = ui32Temp >> 16; + + /* Now ripple up the overflows */ + ui32C2 += ui32C1 >> 16; + ui32C3 += ui32C2 >> 16; + + /* Combine 16 bit pairs into 2 32 bit values */ + ui32C0 = ui32C0 | (ui32C1 << 16); + ui32C2 = (ui32C2 & 0xFFFF) | (ui32C3 << 16); + + /* Pick the required 32 bits */ + if(ui32PostShiftResult >= 32) + { + ui32C0 = ui32C2; + ui32C2 = 0; + ui32PostShiftResult -= 32; + } + + ui32Temp = (ui32C0 >> ui32PostShiftResult) | (ui32C2 << (32 - ui32PostShiftResult)); + + /* Ensure nothing is left in the upper 32 bit word following the downshift */ + IMG_ASSERT ( (ui32C2 >> ui32PostShiftResult) == 0 ); + + return ui32Temp; +} + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitDivide + +******************************************************************************/ + +img_uint32 FIXEDPT_64BitDivide ( img_uint32 ui32Numerator, + img_uint32 ui32Denominator, + img_uint32 ui32PostShiftResult ) +{ + img_uint32 ui32Remainder; + img_uint32 ui32Divisor; + img_uint32 ui32ResultTop; + img_uint32 ui32ResultBot; + img_uint32 ui32FinalResult; + img_uint32 ui32DivBit; + + img_int32 i32DivisionShift; + + /* No divisions by zero thankyou */ + IMG_ASSERT ( ui32Denominator ); + + /* special case of zero numerator */ + if(!ui32Numerator) + { + return 0; + } + + /* Set Numerator/Remainder to be "A * 2^32" */ + ui32Remainder = ui32Numerator; + ui32Divisor = ui32Denominator; + + i32DivisionShift = 32; + ui32ResultTop = 0; + ui32ResultBot = 0; + + /* Do a pre-normalising step so that at least one of A or B has the MSB set */ + while(((ui32Remainder | ui32Divisor) & 0x80000000) == 0) + { + ui32Remainder <<= 1; + ui32Divisor <<= 1; + } + + /* Now make adjust either remainder or numerator so that the other also has the */ + /* top bit set */ + if((ui32Remainder & 0x80000000) == 0) + { + do + { + ui32Remainder <<= 1; + i32DivisionShift--; + + } + while((ui32Remainder & 0x80000000) == 0); + } + else if((ui32Divisor & 0x80000000) == 0) + { + do + { + ui32Divisor <<= 1; + i32DivisionShift++; + + } + while((ui32Divisor & 0x80000000) == 0); + } + + /* Set the "divbit" to access the correct bit in the 64 bit result */ + if(i32DivisionShift >= 32) + { + ui32DivBit = 1 << (i32DivisionShift -32); + } + else + { + ui32DivBit = 1 << i32DivisionShift; + } + + /* Start doing the division */ + while(ui32Remainder && (i32DivisionShift >= 0)) + { + /* Shift the remainder until the MSB is set */ + while((ui32Remainder & 0x80000000) == 0) + { + ui32Remainder <<= 1; + i32DivisionShift --; + + ui32DivBit >>= 1; + if(ui32DivBit == 0) + { + ui32DivBit = 0x80000000; + } + } + + /* If we've run out of sig digits, exit */ + if(i32DivisionShift < 0) + { + break; + } + + + /* If we can subtract the divisor from the current remainder... */ + if(ui32Remainder >= ui32Divisor) + { + ui32Remainder -= ui32Divisor; + + IMG_ASSERT (ui32Remainder < ui32Divisor); + + if(i32DivisionShift >= 32) + { + ui32ResultTop |= ui32DivBit; + } + else + { + ui32ResultBot |= ui32DivBit; + } + + /* Move to the next bit... */ + ui32Remainder <<= 1; + + i32DivisionShift --; + ui32DivBit >>= 1; + if(i32DivisionShift == 31) + { + ui32DivBit = 0x80000000; + } + + } + /* else we MUST be able to subtract 1/2 of the divisor from the remainder.. */ + /* Multiply the remainder by 2 (which loses the top bit which we know to be */ + /* set) and subtract the divisor. */ + else + { + ui32Remainder = (ui32Remainder << 1) - ui32Divisor; + + /* Because we are subtracting 1/2 the divisor pre-adjust our position. */ + /* */ + /* Note that it doesnt matter if division shift goes negative here */ + /* because the DivBit will hit zero as well. */ + i32DivisionShift --; + ui32DivBit >>= 1; + if(i32DivisionShift == 31) + { + ui32DivBit = 0x80000000; + } + + if(i32DivisionShift >= 32) + { + ui32ResultTop |= ui32DivBit; + } + else + { + ui32ResultBot |= ui32DivBit; + } + }/*end if/else*/ + + }/*end while*/ + + ui32FinalResult = (ui32ResultBot >> ui32PostShiftResult) | + (ui32ResultTop << (32 - ui32PostShiftResult)); + + IMG_ASSERT ( (ui32ResultTop >> ui32PostShiftResult) == 0 ); + + return ui32FinalResult; +} + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitMultiply_Signed + +******************************************************************************/ + +img_int32 FIXEDPT_64BitMultiply_Signed ( img_int32 i32X, + img_int32 i32Y, + img_uint32 ui32PostShiftResult ) +{ + img_int64 i64IntermediateResult; + + i64IntermediateResult = (img_int64) i32X * (img_int64) i32Y; + i64IntermediateResult >>= ui32PostShiftResult; + + /* After the shift, the signed bit in the resultant 32 bit value (i.e.: bit 31) */ + /* should be replicated in every bit above it in the 64 bit value. As such, we */ + /* can compare bits 31 and 63 in the intermediate result and if they do not */ + /* match we can assume we have overflowed. */ + IMG_ASSERT (( i64IntermediateResult >> 63 ) == ( i64IntermediateResult >> 31 )); + + return ((img_int32) i64IntermediateResult); +} + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitDivide_Signed + +******************************************************************************/ + +/*INLINE*/ img_int32 FIXEDPT_64BitDivide_Signed ( img_int32 ui32Numerator, + img_int32 ui32Denominator, + img_uint32 ui32PostShiftResult ) +{ + img_int64 i64IntermediateResult; + + i64IntermediateResult = (img_int64) ui32Numerator << 32; + i64IntermediateResult = i64IntermediateResult / (img_int64) ui32Denominator; + i64IntermediateResult >>= ui32PostShiftResult; + + /* After the shift, the signed bit in the resultant 32 bit value (i.e.: bit 31) */ + /* should be replicated in every bit above it in the 64 bit value. As such, we */ + /* can compare bits 31 and 63 in the intermediate result and if they do not */ + /* match we can assume we have overflowed. */ + IMG_ASSERT (( i64IntermediateResult >> 63 ) == ( i64IntermediateResult >> 31 )); + + return ((img_int32) i64IntermediateResult); +} + +/*! +****************************************************************************** + + @Function FIXEDPT_Sine + +******************************************************************************/ + +img_int32 FIXEDPT_Sine ( img_uint32 ui32Theta ) +{ + /* Note : This function uses a lookup table for basic reference, then improves on the */ + /* result by interpolating linearly. A possible future enhancement would be to use */ + /* quadratic interpolation instead of linear. */ + + img_uint32 ui32LookupRef; + img_uint32 ui32TableRef; + img_uint32 ui32TableValueBelow, ui32TableValueAbove; + img_uint32 ui32Offset; + img_uint32 ui32Difference; + img_uint32 ui32LinearAddition; + img_int32 i32InterpolatedValue; + + /* Theta must be no greater than 2PI */ + IMG_ASSERT ( ui32Theta <= (FIXEDPT_PI << 1) ); + + if ( ui32Theta > (FIXEDPT_PI >> 1) ) + { + if ( ui32Theta > FIXEDPT_PI ) + { + if ( ui32Theta > (FIXEDPT_PI + (FIXEDPT_PI >> 1)) ) + { + /* Between 3PI/2 and 2PI */ + + ui32LookupRef = (ui32Theta - (FIXEDPT_PI + (FIXEDPT_PI >> 1))); /* Fit into range of table, 0 to PI/2 */ + ui32LookupRef = (FIXEDPT_PI >> 1) - ui32LookupRef; /* Reference table 'backwards' */ + } + else + { + /* Between PI and 3PI/2 */ + ui32LookupRef = (ui32Theta - FIXEDPT_PI); + } + } + else + { + /* Between PI/2 and PI */ + + /* Fit into range of table, 0 to PI/2 */ + ui32LookupRef = (ui32Theta - (FIXEDPT_PI >> 1)); + /* Reference table 'backwards' */ + ui32LookupRef = (FIXEDPT_PI >> 1) - ui32LookupRef; + } + } + else + { + /* Between 0 and PI/2 */ + ui32LookupRef = ui32Theta; + } + + /********************************/ + /* Perform linear interpolation */ + /********************************/ + + /* Lookup reference is a 1.29 bit unsigned fixed point value between 0 and PI/2 */ + ui32TableRef = FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(ui32LookupRef,FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS,FIXEDPT_SINE_TABLE_FRACTION_SIZE); /* Adjust to granularity of table. */ + + ui32TableValueBelow = FIXEDPT_aui32FixedPointSineTable [ ui32TableRef ]; + ui32TableValueAbove = FIXEDPT_aui32FixedPointSineTable [ (ui32TableRef+1) ]; + + ui32Difference = ui32TableValueAbove - ui32TableValueBelow; /* (Difference between two nearest points in table) */ + + ui32Offset = ui32LookupRef - (FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(ui32TableRef,FIXEDPT_SINE_TABLE_FRACTION_SIZE,FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS)); /* Horizontal difference between nearest point below */ + /* and actual requested point. Result is in 1.29 fmt */ + + /* y=mx+c. m=(diff y)/(diff x). therefore linear addition = (diff y * offset)/(diff x) */ + /* We know that (diff x) is one increment of an x.8 number. As such, a divide by (diff x) */ + /* is the same as multiplying by 256 (which we can achieve by not downshifting the multiply */ + /* as much as we otherwise would). */ + ui32LinearAddition = FIXEDPT_64BitMultiply ( ui32Difference, /* (1.30 * 1.29)/(2^-FIXEDPT_SINE_TABLE_FRACTION_SIZE) */ + ui32Offset, + (FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS-FIXEDPT_SINE_TABLE_FRACTION_SIZE) ); + + i32InterpolatedValue = ui32TableValueBelow + ui32LinearAddition; /* Result is 1.30 */ + + if ( ui32Theta > FIXEDPT_PI ) + { + i32InterpolatedValue = -1 * i32InterpolatedValue; + } + + return i32InterpolatedValue; +} + +/*! +****************************************************************************** + + @Function FIXEDPT_Cosine + +******************************************************************************/ + +img_int32 FIXEDPT_Cosine ( img_uint32 ui32Theta ) +{ + img_uint32 ui32SinTheta; + + /* Theta must be no greater than 2PI */ + IMG_ASSERT ( ui32Theta <= (FIXEDPT_PI << 1) ); + + /* Cos(Theta) = Sin(Theta+(PI/2 radians)) */ + if ( ui32Theta >= (FIXEDPT_PI + (FIXEDPT_PI >> 1)) ) + { + ui32SinTheta = ui32Theta - (FIXEDPT_PI + (FIXEDPT_PI >> 1)); + } + else + { + ui32SinTheta = ui32Theta + (FIXEDPT_PI >> 1); + } + + return (FIXEDPT_Sine(ui32SinTheta)); +} + +/*! +****************************************************************************** + + @Function FIXEDPT_MatrixMultiply + +******************************************************************************/ + +img_void FIXEDPT_MatrixMultiply ( img_uint32 ui32MatrixARows, + img_uint32 ui32MatrixAColumns, + img_uint32 ui32MatrixBRows, + img_uint32 ui32MatrixBColumns, + img_uint32 ui32ResultRows, + img_uint32 ui32ResultColumns, + img_int32 * pai32MatrixA, + img_int32 * pai32MatrixB, + img_int32 * pai32ResultMatrix, + img_uint32 ui32PostShiftResults ) +{ + img_uint32 ui32m; + img_uint32 ui32n; + img_uint32 ui32p; + img_int64 i64Sum; + + /* Check that matrix pointers are valid */ + IMG_ASSERT ( pai32MatrixA != IMG_NULL ); + IMG_ASSERT ( pai32MatrixB != IMG_NULL ); + IMG_ASSERT ( pai32ResultMatrix != IMG_NULL ); + + /* Check matrix dimensions are sensible */ + IMG_ASSERT ( ui32MatrixARows != 0 ); + IMG_ASSERT ( ui32MatrixAColumns != 0 ); + IMG_ASSERT ( ui32MatrixBRows != 0 ); + IMG_ASSERT ( ui32MatrixBColumns != 0 ); + IMG_ASSERT ( ui32ResultRows != 0 ); + IMG_ASSERT ( ui32ResultColumns != 0 ); + + /* Can only multiply matrices where the number of columns in the left hand matrix */ + /* (matrix A) is the same as the number of rows in the right hand matrix (matrix B) */ + IMG_ASSERT ( ui32MatrixAColumns == ui32MatrixBRows ); + + /* If matrix A has m rows and n columns, and matrix B has n rows and p columns, */ + /* then the matrix resulting from multiplying A by B will have m rows and p columns */ + IMG_ASSERT ( ui32ResultRows == ui32MatrixARows ); + IMG_ASSERT ( ui32ResultColumns == ui32MatrixBColumns ); + + for ( ui32m=0; ui32m> 63 ) == ( i64Sum >> 31 )); + } + + /* Set appropriate element in result */ + /* ResultMatrix [m,p] = Sum */ + pai32ResultMatrix [((ui32m*ui32ResultColumns)+ui32p)] = (img_int32) i64Sum; + } + } +} + +/*! +****************************************************************************** + + @Function FIXEDPT_ScalarMatrixMultiply + +******************************************************************************/ + +img_void FIXEDPT_ScalarMatrixMultiply ( img_uint32 ui32MatrixRows, + img_uint32 ui32MatrixColumns, + img_int32 * pai32MatrixA, + img_int32 * pai32MatrixB, + img_int32 * pai32ResultantMatrix, + img_uint32 ui32PostShiftResults ) +{ + img_uint32 ui32m; + img_uint32 ui32n; + + /* Check that matrix pointer is valid */ + IMG_ASSERT ( pai32MatrixA != IMG_NULL ); + IMG_ASSERT ( pai32MatrixB != IMG_NULL ); + IMG_ASSERT ( pai32ResultantMatrix != IMG_NULL ); + + /* Resultant matrix cannot be the same as either of the input matrices, as this */ + /* will result in an incorrect result (as the result matrix is written as the */ + /* calculation proceeds, so it cannot be read from as well as written to as */ + /* of the same calculation). */ + IMG_ASSERT ( pai32ResultantMatrix != pai32MatrixA ); + IMG_ASSERT ( pai32ResultantMatrix != pai32MatrixB ); + + /* Check matrix dimensions are sensible */ + IMG_ASSERT ( ui32MatrixRows != 0 ); + IMG_ASSERT ( ui32MatrixColumns != 0 ); + + for ( ui32m=0; ui32m -#include -#include - -#include "img_iep_defs.h" -#include "csc2.h" -#include "iep_lite_reg_defs.h" -#include "iep_lite_api.h" - -#define EXTERNAL -#include "iep_lite_utils.h" -#undef EXTERNAL - -FILE * pfDebugOutput = IMG_NULL; - -/*-------------------------------------------------------------------------------*/ - -/* - Functions -*/ - -/*! -****************************************************************************** - - @Function IEP_LITE_Initialise - -******************************************************************************/ - -img_result -IEP_LITE_Initialise(void * p_iep_lite_context, img_uint32 ui32RegBaseAddr) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - DEBUG_PRINT ( "Entering IEP_LITE_Initialise\n" ); - - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - /* If the API is already initialised, just return */ - if ( sIEP_LITE_Context->bInitialised == IMG_TRUE ) - { - return IMG_SUCCESS; - } - - /* Check enumerated arrays are consistent with size & order of enumerations */ - iep_lite_StaticDataSafetyCheck ( ); - - /* Register 'render complete' callback - this is a function which is called */ - /* automatically after the h/w has finished rendering. */ - REGISTER_CALLBACK(RENDER_COMPLETE,iep_lite_RenderCompleteCallback); - - IMG_MEMSET ( sIEP_LITE_Context, - 0x00, - sizeof ( IEP_LITE_sContext ) ); - - sIEP_LITE_Context->bInitialised = IMG_TRUE; - sIEP_LITE_Context->ui32RegBaseAddr = ui32RegBaseAddr; - - DEBUG_PRINT ( "Leaving IEP_LITE_Initialise\n" ); - - return IMG_SUCCESS; -} - - -/*! -****************************************************************************** - - @Function IEP_LITE_IEPCSCConfigure - -******************************************************************************/ -img_result IEP_LITE_CSCConfigure ( - void * p_iep_lite_context, - CSC_eColourSpace eInputColourSpace, - CSC_eColourSpace eOutputColourSpace, - CSC_psHSBCSettings psHSBCSettings - ) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - CSC_sConfiguration sInternalConfig; - img_uint32 ui32MyReg; - - DEBUG_PRINT ( "Entering IEP_LITE_IEPCSCConfigure\n" ); - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - /* Ensure API is initialised */ - IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); - - /* Generate the CSC matrix coefficients */ - CSC_GenerateMatrix ( eInputColourSpace, - eOutputColourSpace, - CSC_RANGE_0_255, - CSC_RANGE_0_255, - CSC_COLOUR_PRIMARY_BT709, - CSC_COLOUR_PRIMARY_BT709, - psHSBCSettings, - &sInternalConfig ); - - READ_REGISTER ( sIEP_LITE_Context,IEP_LITE_HS_CONF_STATUS_OFFSET, &ui32MyReg); - /* Colour configuration matrix */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_C11C12_HS_C11, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_C11C12_HS_C12, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_C11C12_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_C13C21_HS_C13, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_C13C21_HS_C21, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_C13C21_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_C22C23_HS_C22, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_C22C23_HS_C23, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_C22C23_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_C31C32_HS_C31, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_C31C32_HS_C32, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_C31C32_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_C33_HS_C33, - (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_C33_OFFSET, - ui32MyReg ); - - /* Input Offset Cb0, Cr0, Y0 */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_CBOCRO_HS_CBO, - sInternalConfig.ai32InputOffsets [1], - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_CBOCRO_HS_CRO, - sInternalConfig.ai32InputOffsets [2], - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_CBOCRO_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_YO_HS_YO, - sInternalConfig.ai32InputOffsets [0], - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_YO_OFFSET, - ui32MyReg ); - - /* Output Offset R0, G0, B0 */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_ROGO_HS_RO, - (sInternalConfig.ai32OutputOffsets [0] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_HS_ROGO_HS_GO, - (sInternalConfig.ai32OutputOffsets [1] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_ROGO_OFFSET, - ui32MyReg ); - - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_HS_BO_HS_BO, - (sInternalConfig.ai32OutputOffsets [2] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_HS_BO_OFFSET, - ui32MyReg ); - - /* Enable the CSC */ - WRITE_REGISTER ( IEP_LITE_HS_CONF_STATUS_OFFSET, - IEP_LITE_HS_CONF_STATUS_HS_EN_MASK ); - - READ_REGISTER ( sIEP_LITE_Context, IEP_LITE_HS_CONF_STATUS_OFFSET, &ui32MyReg); - DEBUG_PRINT ( "Leaving IEP_LITE_IEPCSCConfigure\n" ); - - return IMG_SUCCESS; -} - -/*! -****************************************************************************** - - @Function IEP_LITE_BlackLevelExpanderConfigure - -******************************************************************************/ -img_result IEP_LITE_BlackLevelExpanderConfigure ( - void * p_iep_lite_context, - IEP_LITE_eBLEMode eBLEBlackMode, - IEP_LITE_eBLEMode eBLEWhiteMode - ) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - IEP_LITE_eBLEMode eCurrentBlackMode; - IEP_LITE_eBLEMode eCurrentWhiteMode; - - DEBUG_PRINT ( "Entering IEP_LITE_BlackLevelExpanderConfigure\n" ); - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - /* Ensure API is initialised */ - IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); - - /* Store current mode */ - eCurrentBlackMode = sIEP_LITE_Context->eBLEBlackMode; - eCurrentWhiteMode = sIEP_LITE_Context->eBLEWhiteMode; - - sIEP_LITE_Context->eBLEBlackMode = eBLEBlackMode; - sIEP_LITE_Context->eBLEWhiteMode = eBLEWhiteMode; - - /* Are we switching the hardware off ? */ - if ( - (( eBLEBlackMode == IEP_LITE_BLE_OFF ) && - ( eBLEWhiteMode == IEP_LITE_BLE_OFF )) - && - (( eCurrentBlackMode != IEP_LITE_BLE_OFF ) || - ( eCurrentWhiteMode != IEP_LITE_BLE_OFF )) - ) - { - WRITE_REGISTER ( IEP_LITE_BLE_CONF_STATUS_OFFSET, - 0 ); - - sIEP_LITE_Context->bFirstLUTValuesWritten = IMG_FALSE; - } - - DEBUG_PRINT ( "Leaving IEP_LITE_BlackLevelExpanderConfigure\n" ); - - return IMG_SUCCESS; -} - - -/*! -****************************************************************************** - - @Function IEP_LITE_BlueStretchConfigure - -******************************************************************************/ -img_result IEP_LITE_BlueStretchConfigure ( - void * p_iep_lite_context, - img_uint8 ui8Gain - ) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - img_uint32 ui32Offset = 0; - img_uint32 ui32MyReg = 0; - img_uint32 ui32EnableReg = 0; - - DEBUG_PRINT ( "Entering IEP_LITE_BlueStretchConfigure\n" ); - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - /* Ensure API is initialised */ - IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); - - /* Standard setup using gain slider */ - READ_REGISTER ( sIEP_LITE_Context, - IEP_LITE_BSSCC_CTRL_OFFSET, - &ui32EnableReg ); - - if ( ui8Gain == 0 ) - { - /* Blue stretch off */ - WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_BS_EN, - 0, - ui32EnableReg ); - - WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, - ui32EnableReg ); - } - else - { - /* Blue stretch radius chroma parameters */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_RADIUS_R3, - IEP_LITE_BS_R3_DEFAULT_VALUE, - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_RADIUS_R4, - IEP_LITE_BS_R4_DEFAULT_VALUE, - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_BS_CHROMA_RADIUS_OFFSET, - ui32MyReg ); - - /* Blue stretch angle chroma preferences */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_ANGLE_THETA3, - ((IEP_LITE_BS_THETA3_DEFAULT_VALUE * (1 << 10)) / 360), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_ANGLE_THETA4, - ((IEP_LITE_BS_THETA4_DEFAULT_VALUE * (1 << 10)) / 360), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_BS_CHROMA_ANGLE_OFFSET, - ui32MyReg ); - - /* Blue stretch area luma parameters */ - WRITE_REGISTER ( IEP_LITE_BS_LUMA_OFFSET, - IEP_LITE_BS_YMIN_DEFAULT_VALUE ); - - /* Blue stretch correction parameters - controlled by gain slider */ - - /* Scale between 0 and IEP_LITE_BS_OFFSET_MAX_VALUE, using ui8Gain */ - ui32Offset = IEP_LITE_BS_OFFSET_MAX_VALUE * ui8Gain; /* 0.23 * 8.0 = 8.23 */ - - /* Rather than dividing by (1 << 8) and losing precision, just promote the decimal */ - /* point i.e.: Consider it a 0.31 value instead of an 8.23. */ - - ui32Offset += (1 << (31 - 7)) >> 1; /* Prevent error when rounding down */ - ui32Offset >>= (31 - 7); /* Adjust for register */ - - WRITE_REGISTER ( IEP_LITE_BS_CORR_OFFSET, - ui32Offset ); - - /* Turn blue stretch module on */ - WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_BS_EN, - 1, - ui32EnableReg ); - - WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, - ui32EnableReg ); - } - - /* Store current setting in context structure */ - sIEP_LITE_Context->ui8BSGain = ui8Gain; - - DEBUG_PRINT ( "Leaving IEP_LITE_BlueStretchConfigure\n" ); - - return IMG_SUCCESS; -} - -/*! -****************************************************************************** - - @Function IEP_LITE_SkinColourCorrectionConfigure - -******************************************************************************/ -img_result IEP_LITE_SkinColourCorrectionConfigure ( - void * p_iep_lite_context, - img_uint8 ui8Gain - ) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - img_uint32 ui32MyReg = 0; - img_uint32 ui32Offset = 0; - img_uint32 ui32EnableReg = 0; - - DEBUG_PRINT ( "Entering IEP_LITE_SkinColourCorrectionConfigure\n" ); - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - /* Ensure API is initialised */ - IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); - - READ_REGISTER ( sIEP_LITE_Context, - IEP_LITE_BSSCC_CTRL_OFFSET, - &ui32EnableReg ); - - /* Standard setup using gain slider */ - if ( ui8Gain == 0 ) - { - /* Skin colour correction off */ - WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_SCC_EN, - 0, - ui32EnableReg ); - - /* FIXME: forget to disable control bit in register ? by Daniel Miao */ - WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, ui32EnableReg ); - } - else - { - /* Skin colour correction on */ - WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_SCC_EN, - 1, - ui32EnableReg ); - - /* FIXME: forget to enable control bit in register ? by Daniel Miao */ - WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, ui32EnableReg ); - - /* Skin colour correction colour radius parameters */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_SCC_RADIUS_R2, - IEP_LITE_SCC_R2_DEFAULT_VALUE, - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_SCC_RADIUS_R1, - IEP_LITE_SCC_R1_DEFAULT_VALUE, - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_SCC_RADIUS_OFFSET, - ui32MyReg ); - - /* Skin colour correction colour angle parameters */ - ui32MyReg = 0; - - WRITE_BITFIELD ( IEP_LITE_SCC_ANGLE_THETA2, - ((IEP_LITE_SCC_THETA2_DEFAULT_VALUE * (1 << 10)) / 360), - ui32MyReg ); - - WRITE_BITFIELD ( IEP_LITE_SCC_ANGLE_THETA1, - ((IEP_LITE_SCC_THETA1_DEFAULT_VALUE * (1 << 10)) / 360), - ui32MyReg ); - - WRITE_REGISTER ( IEP_LITE_SCC_ANGLE_OFFSET, - ui32MyReg ); - - /* Skin colour correction parameters - controlled by gain slider */ - - /* Scale between 0 and IEP_LITE_SCC_OFFSET_MAX_VALUE, using ui8Gain */ - ui32Offset = IEP_LITE_SCC_OFFSET_MAX_VALUE * ui8Gain; /* 0.23 * 8.0 = 8.23 */ - - /* Rather than dividing by (1 << 8) and losing precision, just promote the decimal */ - /* point i.e.: Consider it a 0.31 value instead of an 8.23. */ - - /* Note: gain register in hardware 'works backwards' */ - /* (i.e.: 1023 is min gain, 0 is max gain). */ - ui32Offset = (1 << 31) - ui32Offset; - - ui32Offset += (1 << (31 - 10)) >> 1; /* Prevent error when rounding down */ - ui32Offset >>= (31 - 10); /* Adjust for register */ - - WRITE_REGISTER ( IEP_LITE_SCC_CORR_OFFSET, - ui32Offset ); - } - - /* Store current setting in context structure */ - sIEP_LITE_Context->ui8SCCGain = ui8Gain; - - DEBUG_PRINT ( "Leaving IEP_LITE_SkinColourCorrectionConfigure\n" ); - - return IMG_SUCCESS; -} - -/*--------------------------- End of File --------------------------------*/ - - - - +/********************************************************************************* + ********************************************************************************* + ** + ** Name : IEP_LITE_api.c + ** Author : Imagination Technologies + ** + ** Copyright : 2001 by Imagination Technologies Limited. All rights reserved + ** : No part of this software, either material or conceptual + ** : may be copied or distributed, transmitted, transcribed, + ** : stored in a retrieval system or translated into any + ** : human or computer language in any form by any means, + ** : electronic, mechanical, manual or other-wise, or + ** : disclosed to third parties without the express written + ** : permission of Imagination Technologies Limited, Unit 8, + ** : HomePark Industrial Estate, King's Langley, Hertfordshire, + ** : WD4 8LZ, U.K. + ** + ** Description : Contains the main IEP Lite control functions. + ** + ********************************************************************************* + *********************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +/* + Includes +*/ + +#include +#include +#include + +#include "img_iep_defs.h" +#include "csc2.h" +#include "iep_lite_reg_defs.h" +#include "iep_lite_api.h" + +#define EXTERNAL +#include "iep_lite_utils.h" +#undef EXTERNAL + +FILE * pfDebugOutput = IMG_NULL; + +/*-------------------------------------------------------------------------------*/ + +/* + Functions +*/ + +/*! +****************************************************************************** + + @Function IEP_LITE_Initialise + +******************************************************************************/ + +img_result +IEP_LITE_Initialise(void * p_iep_lite_context, img_uint32 ui32RegBaseAddr) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + DEBUG_PRINT ( "Entering IEP_LITE_Initialise\n" ); + + if (NULL == sIEP_LITE_Context) + { + return IMG_FAILED; + } + /* If the API is already initialised, just return */ + if ( sIEP_LITE_Context->bInitialised == IMG_TRUE ) + { + return IMG_SUCCESS; + } + + /* Check enumerated arrays are consistent with size & order of enumerations */ + iep_lite_StaticDataSafetyCheck ( ); + + /* Register 'render complete' callback - this is a function which is called */ + /* automatically after the h/w has finished rendering. */ + REGISTER_CALLBACK(RENDER_COMPLETE,iep_lite_RenderCompleteCallback); + + IMG_MEMSET ( sIEP_LITE_Context, + 0x00, + sizeof ( IEP_LITE_sContext ) ); + + sIEP_LITE_Context->bInitialised = IMG_TRUE; + sIEP_LITE_Context->ui32RegBaseAddr = ui32RegBaseAddr; + + DEBUG_PRINT ( "Leaving IEP_LITE_Initialise\n" ); + + return IMG_SUCCESS; +} + + +/*! +****************************************************************************** + + @Function IEP_LITE_IEPCSCConfigure + +******************************************************************************/ +img_result IEP_LITE_CSCConfigure ( + void * p_iep_lite_context, + CSC_eColourSpace eInputColourSpace, + CSC_eColourSpace eOutputColourSpace, + CSC_psHSBCSettings psHSBCSettings + ) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + CSC_sConfiguration sInternalConfig; + img_uint32 ui32MyReg; + + DEBUG_PRINT ( "Entering IEP_LITE_IEPCSCConfigure\n" ); + if (NULL == sIEP_LITE_Context) + { + return IMG_FAILED; + } + /* Ensure API is initialised */ + IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); + + /* Generate the CSC matrix coefficients */ + CSC_GenerateMatrix ( eInputColourSpace, + eOutputColourSpace, + CSC_RANGE_0_255, + CSC_RANGE_0_255, + CSC_COLOUR_PRIMARY_BT709, + CSC_COLOUR_PRIMARY_BT709, + psHSBCSettings, + &sInternalConfig ); + + READ_REGISTER ( sIEP_LITE_Context,IEP_LITE_HS_CONF_STATUS_OFFSET, &ui32MyReg); + /* Colour configuration matrix */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_C11C12_HS_C11, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_C11C12_HS_C12, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_C11C12_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_C13C21_HS_C13, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [0][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_C13C21_HS_C21, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_C13C21_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_C22C23_HS_C22, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_C22C23_HS_C23, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [1][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_C22C23_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_C31C32_HS_C31, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][0]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_C31C32_HS_C32, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][1]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_C31C32_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_C33_HS_C33, + (((img_uint32) sInternalConfig.sCoefficients.ai32Coefficients [2][2]) >> (CSC_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_C33_OFFSET, + ui32MyReg ); + + /* Input Offset Cb0, Cr0, Y0 */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_CBOCRO_HS_CBO, + sInternalConfig.ai32InputOffsets [1], + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_CBOCRO_HS_CRO, + sInternalConfig.ai32InputOffsets [2], + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_CBOCRO_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_YO_HS_YO, + sInternalConfig.ai32InputOffsets [0], + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_YO_OFFSET, + ui32MyReg ); + + /* Output Offset R0, G0, B0 */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_ROGO_HS_RO, + (sInternalConfig.ai32OutputOffsets [0] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_HS_ROGO_HS_GO, + (sInternalConfig.ai32OutputOffsets [1] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_ROGO_OFFSET, + ui32MyReg ); + + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_HS_BO_HS_BO, + (sInternalConfig.ai32OutputOffsets [2] >> (CSC_OUTPUT_OFFSET_FRACTIONAL_BITS - IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS)), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_HS_BO_OFFSET, + ui32MyReg ); + + /* Enable the CSC */ + WRITE_REGISTER ( IEP_LITE_HS_CONF_STATUS_OFFSET, + IEP_LITE_HS_CONF_STATUS_HS_EN_MASK ); + + READ_REGISTER ( sIEP_LITE_Context, IEP_LITE_HS_CONF_STATUS_OFFSET, &ui32MyReg); + DEBUG_PRINT ( "Leaving IEP_LITE_IEPCSCConfigure\n" ); + + return IMG_SUCCESS; +} + +/*! +****************************************************************************** + + @Function IEP_LITE_BlackLevelExpanderConfigure + +******************************************************************************/ +img_result IEP_LITE_BlackLevelExpanderConfigure ( + void * p_iep_lite_context, + IEP_LITE_eBLEMode eBLEBlackMode, + IEP_LITE_eBLEMode eBLEWhiteMode + ) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + IEP_LITE_eBLEMode eCurrentBlackMode; + IEP_LITE_eBLEMode eCurrentWhiteMode; + + DEBUG_PRINT ( "Entering IEP_LITE_BlackLevelExpanderConfigure\n" ); + if (NULL == sIEP_LITE_Context) + { + return IMG_FAILED; + } + /* Ensure API is initialised */ + IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); + + /* Store current mode */ + eCurrentBlackMode = sIEP_LITE_Context->eBLEBlackMode; + eCurrentWhiteMode = sIEP_LITE_Context->eBLEWhiteMode; + + sIEP_LITE_Context->eBLEBlackMode = eBLEBlackMode; + sIEP_LITE_Context->eBLEWhiteMode = eBLEWhiteMode; + + /* Are we switching the hardware off ? */ + if ( + (( eBLEBlackMode == IEP_LITE_BLE_OFF ) && + ( eBLEWhiteMode == IEP_LITE_BLE_OFF )) + && + (( eCurrentBlackMode != IEP_LITE_BLE_OFF ) || + ( eCurrentWhiteMode != IEP_LITE_BLE_OFF )) + ) + { + WRITE_REGISTER ( IEP_LITE_BLE_CONF_STATUS_OFFSET, + 0 ); + + sIEP_LITE_Context->bFirstLUTValuesWritten = IMG_FALSE; + } + + DEBUG_PRINT ( "Leaving IEP_LITE_BlackLevelExpanderConfigure\n" ); + + return IMG_SUCCESS; +} + + +/*! +****************************************************************************** + + @Function IEP_LITE_BlueStretchConfigure + +******************************************************************************/ +img_result IEP_LITE_BlueStretchConfigure ( + void * p_iep_lite_context, + img_uint8 ui8Gain + ) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + img_uint32 ui32Offset = 0; + img_uint32 ui32MyReg = 0; + img_uint32 ui32EnableReg = 0; + + DEBUG_PRINT ( "Entering IEP_LITE_BlueStretchConfigure\n" ); + if (NULL == sIEP_LITE_Context) + { + return IMG_FAILED; + } + /* Ensure API is initialised */ + IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); + + /* Standard setup using gain slider */ + READ_REGISTER ( sIEP_LITE_Context, + IEP_LITE_BSSCC_CTRL_OFFSET, + &ui32EnableReg ); + + if ( ui8Gain == 0 ) + { + /* Blue stretch off */ + WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_BS_EN, + 0, + ui32EnableReg ); + + WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, + ui32EnableReg ); + } + else + { + /* Blue stretch radius chroma parameters */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_RADIUS_R3, + IEP_LITE_BS_R3_DEFAULT_VALUE, + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_RADIUS_R4, + IEP_LITE_BS_R4_DEFAULT_VALUE, + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_BS_CHROMA_RADIUS_OFFSET, + ui32MyReg ); + + /* Blue stretch angle chroma preferences */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_ANGLE_THETA3, + ((IEP_LITE_BS_THETA3_DEFAULT_VALUE * (1 << 10)) / 360), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_BS_CHROMA_ANGLE_THETA4, + ((IEP_LITE_BS_THETA4_DEFAULT_VALUE * (1 << 10)) / 360), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_BS_CHROMA_ANGLE_OFFSET, + ui32MyReg ); + + /* Blue stretch area luma parameters */ + WRITE_REGISTER ( IEP_LITE_BS_LUMA_OFFSET, + IEP_LITE_BS_YMIN_DEFAULT_VALUE ); + + /* Blue stretch correction parameters - controlled by gain slider */ + + /* Scale between 0 and IEP_LITE_BS_OFFSET_MAX_VALUE, using ui8Gain */ + ui32Offset = IEP_LITE_BS_OFFSET_MAX_VALUE * ui8Gain; /* 0.23 * 8.0 = 8.23 */ + + /* Rather than dividing by (1 << 8) and losing precision, just promote the decimal */ + /* point i.e.: Consider it a 0.31 value instead of an 8.23. */ + + ui32Offset += (1 << (31 - 7)) >> 1; /* Prevent error when rounding down */ + ui32Offset >>= (31 - 7); /* Adjust for register */ + + WRITE_REGISTER ( IEP_LITE_BS_CORR_OFFSET, + ui32Offset ); + + /* Turn blue stretch module on */ + WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_BS_EN, + 1, + ui32EnableReg ); + + WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, + ui32EnableReg ); + } + + /* Store current setting in context structure */ + sIEP_LITE_Context->ui8BSGain = ui8Gain; + + DEBUG_PRINT ( "Leaving IEP_LITE_BlueStretchConfigure\n" ); + + return IMG_SUCCESS; +} + +/*! +****************************************************************************** + + @Function IEP_LITE_SkinColourCorrectionConfigure + +******************************************************************************/ +img_result IEP_LITE_SkinColourCorrectionConfigure ( + void * p_iep_lite_context, + img_uint8 ui8Gain + ) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + img_uint32 ui32MyReg = 0; + img_uint32 ui32Offset = 0; + img_uint32 ui32EnableReg = 0; + + DEBUG_PRINT ( "Entering IEP_LITE_SkinColourCorrectionConfigure\n" ); + if (NULL == sIEP_LITE_Context) + { + return IMG_FAILED; + } + /* Ensure API is initialised */ + IMG_ASSERT ( sIEP_LITE_Context->bInitialised == IMG_TRUE ); + + READ_REGISTER ( sIEP_LITE_Context, + IEP_LITE_BSSCC_CTRL_OFFSET, + &ui32EnableReg ); + + /* Standard setup using gain slider */ + if ( ui8Gain == 0 ) + { + /* Skin colour correction off */ + WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_SCC_EN, + 0, + ui32EnableReg ); + + /* FIXME: forget to disable control bit in register ? by Daniel Miao */ + WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, ui32EnableReg ); + } + else + { + /* Skin colour correction on */ + WRITE_BITFIELD ( IEP_LITE_BSSCC_CTRL_SCC_EN, + 1, + ui32EnableReg ); + + /* FIXME: forget to enable control bit in register ? by Daniel Miao */ + WRITE_REGISTER ( IEP_LITE_BSSCC_CTRL_OFFSET, ui32EnableReg ); + + /* Skin colour correction colour radius parameters */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_SCC_RADIUS_R2, + IEP_LITE_SCC_R2_DEFAULT_VALUE, + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_SCC_RADIUS_R1, + IEP_LITE_SCC_R1_DEFAULT_VALUE, + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_SCC_RADIUS_OFFSET, + ui32MyReg ); + + /* Skin colour correction colour angle parameters */ + ui32MyReg = 0; + + WRITE_BITFIELD ( IEP_LITE_SCC_ANGLE_THETA2, + ((IEP_LITE_SCC_THETA2_DEFAULT_VALUE * (1 << 10)) / 360), + ui32MyReg ); + + WRITE_BITFIELD ( IEP_LITE_SCC_ANGLE_THETA1, + ((IEP_LITE_SCC_THETA1_DEFAULT_VALUE * (1 << 10)) / 360), + ui32MyReg ); + + WRITE_REGISTER ( IEP_LITE_SCC_ANGLE_OFFSET, + ui32MyReg ); + + /* Skin colour correction parameters - controlled by gain slider */ + + /* Scale between 0 and IEP_LITE_SCC_OFFSET_MAX_VALUE, using ui8Gain */ + ui32Offset = IEP_LITE_SCC_OFFSET_MAX_VALUE * ui8Gain; /* 0.23 * 8.0 = 8.23 */ + + /* Rather than dividing by (1 << 8) and losing precision, just promote the decimal */ + /* point i.e.: Consider it a 0.31 value instead of an 8.23. */ + + /* Note: gain register in hardware 'works backwards' */ + /* (i.e.: 1023 is min gain, 0 is max gain). */ + ui32Offset = (1 << 31) - ui32Offset; + + ui32Offset += (1 << (31 - 10)) >> 1; /* Prevent error when rounding down */ + ui32Offset >>= (31 - 10); /* Adjust for register */ + + WRITE_REGISTER ( IEP_LITE_SCC_CORR_OFFSET, + ui32Offset ); + } + + /* Store current setting in context structure */ + sIEP_LITE_Context->ui8SCCGain = ui8Gain; + + DEBUG_PRINT ( "Leaving IEP_LITE_SkinColourCorrectionConfigure\n" ); + + return IMG_SUCCESS; +} + +/*--------------------------- End of File --------------------------------*/ + + + + diff --git a/src/powervr_iep_lite/iep_lite/iep_lite_api.h b/src/powervr_iep_lite/iep_lite/iep_lite_api.h index cfa1765..c06f3df 100644 --- a/src/powervr_iep_lite/iep_lite/iep_lite_api.h +++ b/src/powervr_iep_lite/iep_lite/iep_lite_api.h @@ -1,216 +1,216 @@ -/*! -****************************************************************************** - @file : iep_lite_api.h - - @Author Imagination Technologies - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - \nDescription:\n - This file contains the headers & definitions for the top level - IEP_Lite control functions. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#if !defined (__IEP_LITE_API_H__) -#define __IEP_LITE_API_H__ - -#if (__cplusplus) -extern "C" { -#endif - -extern FILE * pfDebugOutput; - -#define DEBUG_PRINT(msg) \ -{ \ - if ( pfDebugOutput == IMG_NULL ) \ - { \ - /*pfDebugOutput = fopen ( "/tmp/iep_lite_demo_output.txt", "w" );*/ \ - /*IMG_ASSERT ( pfDebugOutput != IMG_NULL );*/ \ - } \ - \ - /*fprintf ( pfDebugOutput, (msg) );*/ \ -} - -/*-------------------------------------------------------------------------------*/ - -/* - Enumerations -*/ - -/*! -****************************************************************************** - - This type defines how the mode in which the black level expander should - operate. - -******************************************************************************/ -typedef enum -{ - /*! Black level expander off */ - IEP_LITE_BLE_OFF = 0x00, - /*! Black level expander low */ - IEP_LITE_BLE_LOW, - /*! Black level expander medium */ - IEP_LITE_BLE_MEDIUM, - /*! Black level expander high */ - IEP_LITE_BLE_HIGH, - - /* PLACE HOLDER ONLY - NOT A VALID MODE */ - IEP_LITE_BLE_NO_OF_MODES - -} IEP_LITE_eBLEMode; - -/*-------------------------------------------------------------------------------*/ - -/* - Function prototypes -*/ - -/* API command functions */ - -/*! -****************************************************************************** - - @Function IEP_LITE_Initialise - - @Description - This function initialises the IEP Lite hardware I must be called prior to - any other IEP Lite functions. - - @Input None - - @Return img_result : This function will always return IMG_SUCCESS - -******************************************************************************/ - -extern img_result IEP_LITE_Initialise (void * p_iep_lite_context, img_uint32 ui32RegBaseAddr ); -/*! -****************************************************************************** - - @Function IEP_LITE_BlackLevelExpanderConfigure - - @Description - - This function is used to enable/disable and configure the black level - expander (note : The Black Level Expander can be used to independently - control the levels of Black AND White level expansion). - - @Input eBLEBlackMode : Selects the level of black level expansion to be - applied. If the black level mode is set to - 'IEP_LITE_BLE_OFF' then no black level expansion will - be applied. - - @Input eBLEWhiteMode : Selects the level of white level expansion to be - applied. If the white level mode is set to - 'IEP_LITE_BLE_OFF' then no white level expansion will - be applied. - - Note : If both 'eBLEBlackMode' and 'eBLEWhiteMode' - are set to 'IEP_LITE_BLE_OFF' the BLE hardware will be - disabled. - - @Return img_result : This function will always return IMG_SUCCESS - -******************************************************************************/ - -extern img_result IEP_LITE_BlackLevelExpanderConfigure ( - void * p_iep_lite_context, - IEP_LITE_eBLEMode eBLEBlackMode, - IEP_LITE_eBLEMode eBLEWhiteMode - ); - -/*! -****************************************************************************** - - - @Function IEP_LITE_BlueStretchConfigure - - @Description - - This function is used to enable/disable and configure the blue stretch. - - @Input ui8Gain : Specifies the extent to which blue stretch should - be applied. When set to zero, the blue stretch block - is turned off, when set to 0xFF, maximum blue stretch - is applied. - - @Return img_result : This function will always return IMG_SUCCESS - -******************************************************************************/ - -extern img_result IEP_LITE_BlueStretchConfigure ( - void * p_iep_lite_context, - img_uint8 ui8Gain - ); - -/*! -****************************************************************************** - - @Function IEP_LITE_SkinColourCorrectionConfigure - - @Description - - This function is used to enable/disable and configure the skin colour - correction block. - - @Input ui8Gain : Specifies the extent to which skin colour correction - should be applied. When set to zero, the skin colour - correction block is turned off, when set to 0xFF, - maximum skin colour correction is applied. - - @Return img_result : This function will always return IMG_SUCCESS - -******************************************************************************/ - -extern img_result IEP_LITE_SkinColourCorrectionConfigure ( - void * p_iep_lite_context, - img_uint8 ui8Gain - ); -/*! -****************************************************************************** - - @Function IEP_LITE_CSCConfigure - - @Description - This function is used to configure the colour space converter - - @Return img_result : This function will always return IMG_SUCCESS - -******************************************************************************/ - -extern img_result IEP_LITE_CSCConfigure ( - void * p_iep_lite_context, - CSC_eColourSpace eInputColourSpace, - CSC_eColourSpace eOutputColourSpace, - CSC_psHSBCSettings psHSBCSettings - ); - -#if (__cplusplus) -} -#endif - -#endif /* __IEP_LITE_API_H__ */ - - -/*--------------------------- End of File --------------------------------*/ +/*! +****************************************************************************** + @file : iep_lite_api.h + + @Author Imagination Technologies + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + \nDescription:\n + This file contains the headers & definitions for the top level + IEP_Lite control functions. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__IEP_LITE_API_H__) +#define __IEP_LITE_API_H__ + +#if (__cplusplus) +extern "C" { +#endif + +extern FILE * pfDebugOutput; + +#define DEBUG_PRINT(msg) \ +{ \ + if ( pfDebugOutput == IMG_NULL ) \ + { \ + /*pfDebugOutput = fopen ( "/tmp/iep_lite_demo_output.txt", "w" );*/ \ + /*IMG_ASSERT ( pfDebugOutput != IMG_NULL );*/ \ + } \ + \ + /*fprintf ( pfDebugOutput, (msg) );*/ \ +} + +/*-------------------------------------------------------------------------------*/ + +/* + Enumerations +*/ + +/*! +****************************************************************************** + + This type defines how the mode in which the black level expander should + operate. + +******************************************************************************/ +typedef enum +{ + /*! Black level expander off */ + IEP_LITE_BLE_OFF = 0x00, + /*! Black level expander low */ + IEP_LITE_BLE_LOW, + /*! Black level expander medium */ + IEP_LITE_BLE_MEDIUM, + /*! Black level expander high */ + IEP_LITE_BLE_HIGH, + + /* PLACE HOLDER ONLY - NOT A VALID MODE */ + IEP_LITE_BLE_NO_OF_MODES + +} IEP_LITE_eBLEMode; + +/*-------------------------------------------------------------------------------*/ + +/* + Function prototypes +*/ + +/* API command functions */ + +/*! +****************************************************************************** + + @Function IEP_LITE_Initialise + + @Description + This function initialises the IEP Lite hardware I must be called prior to + any other IEP Lite functions. + + @Input None + + @Return img_result : This function will always return IMG_SUCCESS + +******************************************************************************/ + +extern img_result IEP_LITE_Initialise (void * p_iep_lite_context, img_uint32 ui32RegBaseAddr ); +/*! +****************************************************************************** + + @Function IEP_LITE_BlackLevelExpanderConfigure + + @Description + + This function is used to enable/disable and configure the black level + expander (note : The Black Level Expander can be used to independently + control the levels of Black AND White level expansion). + + @Input eBLEBlackMode : Selects the level of black level expansion to be + applied. If the black level mode is set to + 'IEP_LITE_BLE_OFF' then no black level expansion will + be applied. + + @Input eBLEWhiteMode : Selects the level of white level expansion to be + applied. If the white level mode is set to + 'IEP_LITE_BLE_OFF' then no white level expansion will + be applied. + + Note : If both 'eBLEBlackMode' and 'eBLEWhiteMode' + are set to 'IEP_LITE_BLE_OFF' the BLE hardware will be + disabled. + + @Return img_result : This function will always return IMG_SUCCESS + +******************************************************************************/ + +extern img_result IEP_LITE_BlackLevelExpanderConfigure ( + void * p_iep_lite_context, + IEP_LITE_eBLEMode eBLEBlackMode, + IEP_LITE_eBLEMode eBLEWhiteMode + ); + +/*! +****************************************************************************** + + + @Function IEP_LITE_BlueStretchConfigure + + @Description + + This function is used to enable/disable and configure the blue stretch. + + @Input ui8Gain : Specifies the extent to which blue stretch should + be applied. When set to zero, the blue stretch block + is turned off, when set to 0xFF, maximum blue stretch + is applied. + + @Return img_result : This function will always return IMG_SUCCESS + +******************************************************************************/ + +extern img_result IEP_LITE_BlueStretchConfigure ( + void * p_iep_lite_context, + img_uint8 ui8Gain + ); + +/*! +****************************************************************************** + + @Function IEP_LITE_SkinColourCorrectionConfigure + + @Description + + This function is used to enable/disable and configure the skin colour + correction block. + + @Input ui8Gain : Specifies the extent to which skin colour correction + should be applied. When set to zero, the skin colour + correction block is turned off, when set to 0xFF, + maximum skin colour correction is applied. + + @Return img_result : This function will always return IMG_SUCCESS + +******************************************************************************/ + +extern img_result IEP_LITE_SkinColourCorrectionConfigure ( + void * p_iep_lite_context, + img_uint8 ui8Gain + ); +/*! +****************************************************************************** + + @Function IEP_LITE_CSCConfigure + + @Description + This function is used to configure the colour space converter + + @Return img_result : This function will always return IMG_SUCCESS + +******************************************************************************/ + +extern img_result IEP_LITE_CSCConfigure ( + void * p_iep_lite_context, + CSC_eColourSpace eInputColourSpace, + CSC_eColourSpace eOutputColourSpace, + CSC_psHSBCSettings psHSBCSettings + ); + +#if (__cplusplus) +} +#endif + +#endif /* __IEP_LITE_API_H__ */ + + +/*--------------------------- End of File --------------------------------*/ diff --git a/src/powervr_iep_lite/iep_lite/iep_lite_hardware.c b/src/powervr_iep_lite/iep_lite/iep_lite_hardware.c index 8dc9c8d..7bd2165 100644 --- a/src/powervr_iep_lite/iep_lite/iep_lite_hardware.c +++ b/src/powervr_iep_lite/iep_lite/iep_lite_hardware.c @@ -1,75 +1,75 @@ -/********************************************************************************* - ********************************************************************************* - ** - ** Name : iep_lite_hardware.c - ** Author : Imagination Technologies - ** - ** Copyright : 2008 by Imagination Technologies Limited. All rights reserved - ** : No part of this software, either material or conceptual - ** : may be copied or distributed, transmitted, transcribed, - ** : stored in a retrieval system or translated into any - ** : human or computer language in any form by any means, - ** : electronic, mechanical, manual or other-wise, or - ** : disclosed to third parties without the express written - ** : permission of Imagination Technologies Limited, Unit 8, - ** : HomePark Industrial Estate, King's Langley, Hertfordshire, - ** : WD4 8LZ, U.K. - ** - ** Description : This module contains hardware specific data for the - ** IEP LITE module. - ** - ********************************************************************************* - *********************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -/*-------------------------------------------------------------------------------*/ - -/* - Includes -*/ - -#include "img_iep_defs.h" -#include "csc2.h" - -#define EXTERNAL -#include "iep_lite_api.h" -#include "iep_lite_utils.h" -#undef EXTERNAL - -/*-------------------------------------------------------------------------------*/ - -/* - Data -*/ - -const IEP_LITE_sBLEModeSpecificSettings asBLEBlackModes [ IEP_LITE_BLE_NO_OF_MODES ] = -{ - /* Safety check D Slope */ - { IEP_LITE_BLE_OFF, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (1.0 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Off */ - - { IEP_LITE_BLE_LOW, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.9 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Low */ - { IEP_LITE_BLE_MEDIUM, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.6 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Medium */ - { IEP_LITE_BLE_HIGH, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.4 * (1ul << IEP_LITE_BLE_RES_PAR)) } /* High */ -}; - -const IEP_LITE_sBLEModeSpecificSettings asBLEWhiteModes [ IEP_LITE_BLE_NO_OF_MODES ] = -{ - /* Safety check D Slope */ - { IEP_LITE_BLE_OFF, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (1.0 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Off */ - - { IEP_LITE_BLE_LOW, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.9 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Low */ - { IEP_LITE_BLE_MEDIUM, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.6 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Medium */ - { IEP_LITE_BLE_HIGH, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.4 * (1ul << IEP_LITE_BLE_RES_PAR)) } /* High */ -}; - -/*--------------------------- End of File --------------------------------*/ +/********************************************************************************* + ********************************************************************************* + ** + ** Name : iep_lite_hardware.c + ** Author : Imagination Technologies + ** + ** Copyright : 2008 by Imagination Technologies Limited. All rights reserved + ** : No part of this software, either material or conceptual + ** : may be copied or distributed, transmitted, transcribed, + ** : stored in a retrieval system or translated into any + ** : human or computer language in any form by any means, + ** : electronic, mechanical, manual or other-wise, or + ** : disclosed to third parties without the express written + ** : permission of Imagination Technologies Limited, Unit 8, + ** : HomePark Industrial Estate, King's Langley, Hertfordshire, + ** : WD4 8LZ, U.K. + ** + ** Description : This module contains hardware specific data for the + ** IEP LITE module. + ** + ********************************************************************************* + *********************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +/*-------------------------------------------------------------------------------*/ + +/* + Includes +*/ + +#include "img_iep_defs.h" +#include "csc2.h" + +#define EXTERNAL +#include "iep_lite_api.h" +#include "iep_lite_utils.h" +#undef EXTERNAL + +/*-------------------------------------------------------------------------------*/ + +/* + Data +*/ + +const IEP_LITE_sBLEModeSpecificSettings asBLEBlackModes [ IEP_LITE_BLE_NO_OF_MODES ] = +{ + /* Safety check D Slope */ + { IEP_LITE_BLE_OFF, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (1.0 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Off */ + + { IEP_LITE_BLE_LOW, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.9 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Low */ + { IEP_LITE_BLE_MEDIUM, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.6 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Medium */ + { IEP_LITE_BLE_HIGH, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.4 * (1ul << IEP_LITE_BLE_RES_PAR)) } /* High */ +}; + +const IEP_LITE_sBLEModeSpecificSettings asBLEWhiteModes [ IEP_LITE_BLE_NO_OF_MODES ] = +{ + /* Safety check D Slope */ + { IEP_LITE_BLE_OFF, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (1.0 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Off */ + + { IEP_LITE_BLE_LOW, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.9 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Low */ + { IEP_LITE_BLE_MEDIUM, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.6 * (1ul << IEP_LITE_BLE_RES_PAR)) }, /* Medium */ + { IEP_LITE_BLE_HIGH, (img_uint32) (0.3f * (1ul << (IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR))), (img_uint32) (0.4 * (1ul << IEP_LITE_BLE_RES_PAR)) } /* High */ +}; + +/*--------------------------- End of File --------------------------------*/ diff --git a/src/powervr_iep_lite/iep_lite/iep_lite_reg_defs.h b/src/powervr_iep_lite/iep_lite/iep_lite_reg_defs.h index 75c11e1..a6e0117 100644 --- a/src/powervr_iep_lite/iep_lite/iep_lite_reg_defs.h +++ b/src/powervr_iep_lite/iep_lite/iep_lite_reg_defs.h @@ -1,1168 +1,1168 @@ -/*! -****************************************************************************** -@file : out_reg_io.h - -@brief - -@Author - - Copyright 2008 by Imagination Technologies Limited. - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - -Description:\n - This file contains the IEP lite Defintions. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#if !defined (__IEP_LITE_REG_DEFS_H__) -#define __IEP_LITE_REG_DEFS_H__ - -/* This line just means we can write C here and C++ elsewhere when it -** picks up the header file will know that all these functions are -** mangled up C wise instead of C++ wise. See also the } way below. -*/ -#ifdef __cplusplus -extern "C" { -#endif - - -/* Hardware register definitions */ - -/* -------------------- Register DEBUGMODE -------------------- */ - -#define IEP_LITE_DEBUGMODE_OFFSET 0x7000 - -/* Field IEP_LITE_DEBUGMODE */ -#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_OFFSET IEP_LITE_DEBUGMODE_OFFSET -#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_SHIFT 0 -#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_MASK 0x00000001 -#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_FLAGS REG_VOL -#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_DEBUGMODE_REG_OFFSET IEP_LITE_DEBUGMODE_OFFSET -#define IEP_LITE_DEBUGMODE_REG_SHIFT 0 -#define IEP_LITE_DEBUGMODE_REG_MASK 0xFFFFFFFF -#define IEP_LITE_DEBUGMODE_REG_FLAGS REG_VOL -#define IEP_LITE_DEBUGMODE_REG_LENGTH 32 - - -/* -------------------- Register DINBSY_DIN -------------------- */ - -#define IEP_LITE_DINBSY_DIN_OFFSET 0x7004 - -/* Field IEP_LITE_DEBUG_DIN */ -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_OFFSET IEP_LITE_DINBSY_DIN_OFFSET -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_SHIFT 0 -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_MASK 0x3FFFFFFF -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_FLAGS REG_VOL -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_LENGTH 30 - -/* Field IEP_LITE_DINBSY */ -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_OFFSET IEP_LITE_DINBSY_DIN_OFFSET -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_SHIFT 31 -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_MASK 0x80000000 -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_FLAGS REG_VOL -#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_DINBSY_DIN_REG_OFFSET IEP_LITE_DINBSY_DIN_OFFSET -#define IEP_LITE_DINBSY_DIN_REG_SHIFT 0 -#define IEP_LITE_DINBSY_DIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_DINBSY_DIN_REG_FLAGS REG_VOL -#define IEP_LITE_DINBSY_DIN_REG_LENGTH 32 - - -/* -------------------- Register SIDEIN -------------------- */ - -#define IEP_LITE_SIDEIN_OFFSET 0x7008 - -/* Field IEP_LITE_SIDEIN */ -#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_OFFSET IEP_LITE_SIDEIN_OFFSET -#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_SHIFT 0 -#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_MASK 0x00000007 -#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_FLAGS REG_VOL -#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_LENGTH 3 - -/* Complete Register Definition */ -#define IEP_LITE_SIDEIN_REG_OFFSET IEP_LITE_SIDEIN_OFFSET -#define IEP_LITE_SIDEIN_REG_SHIFT 0 -#define IEP_LITE_SIDEIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_SIDEIN_REG_FLAGS REG_VOL -#define IEP_LITE_SIDEIN_REG_LENGTH 32 - - -/* -------------------- Register DOUTVLD_DOUT -------------------- */ - -#define IEP_LITE_DOUTVLD_DOUT_OFFSET 0x700C - -/* Field IEP_LITE_DEBUG_DOUT */ -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_SHIFT 0 -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_MASK 0x3FFFFFFF -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_FLAGS REG_VOL -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_LENGTH 30 - -/* Field IEP_LITE_DEBUG_DOUTVLD */ -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_SHIFT 31 -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_MASK 0x80000000 -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_FLAGS REG_VOL -#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_DOUTVLD_DOUT_REG_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET -#define IEP_LITE_DOUTVLD_DOUT_REG_SHIFT 0 -#define IEP_LITE_DOUTVLD_DOUT_REG_MASK 0xFFFFFFFF -#define IEP_LITE_DOUTVLD_DOUT_REG_FLAGS REG_VOL -#define IEP_LITE_DOUTVLD_DOUT_REG_LENGTH 32 - - -/* -------------------- Register SIDEOUT -------------------- */ - -#define IEP_LITE_SIDEOUT_OFFSET 0x7010 - -/* Field IEP_LITE_SIDEOUT */ -#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_OFFSET IEP_LITE_SIDEOUT_OFFSET -#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_SHIFT 0 -#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_MASK 0x00000007 -#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_FLAGS REG_VOL -#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_LENGTH 3 - -/* Complete Register Definition */ -#define IEP_LITE_SIDEOUT_REG_OFFSET IEP_LITE_SIDEOUT_OFFSET -#define IEP_LITE_SIDEOUT_REG_SHIFT 0 -#define IEP_LITE_SIDEOUT_REG_MASK 0xFFFFFFFF -#define IEP_LITE_SIDEOUT_REG_FLAGS REG_VOL -#define IEP_LITE_SIDEOUT_REG_LENGTH 32 - - -/* -------------------- Register CORE_ID -------------------- */ - -#define IEP_LITE_CORE_ID_OFFSET 0x7014 - -/* Field CONFIG_ID */ -#define IEP_LITE_CORE_ID_CONFIG_ID_OFFSET IEP_LITE_CORE_ID_OFFSET -#define IEP_LITE_CORE_ID_CONFIG_ID_SHIFT 0 -#define IEP_LITE_CORE_ID_CONFIG_ID_MASK 0x0000FFFF -#define IEP_LITE_CORE_ID_CONFIG_ID_FLAGS REG_VOL -#define IEP_LITE_CORE_ID_CONFIG_ID_LENGTH 16 - -/* Field CORE_ID */ -#define IEP_LITE_CORE_ID_CORE_ID_OFFSET IEP_LITE_CORE_ID_OFFSET -#define IEP_LITE_CORE_ID_CORE_ID_SHIFT 16 -#define IEP_LITE_CORE_ID_CORE_ID_MASK 0x00FF0000 -#define IEP_LITE_CORE_ID_CORE_ID_FLAGS REG_VOL -#define IEP_LITE_CORE_ID_CORE_ID_LENGTH 8 - -/* Field GROUP_ID */ -#define IEP_LITE_CORE_ID_GROUP_ID_OFFSET IEP_LITE_CORE_ID_OFFSET -#define IEP_LITE_CORE_ID_GROUP_ID_SHIFT 24 -#define IEP_LITE_CORE_ID_GROUP_ID_MASK 0xFF000000 -#define IEP_LITE_CORE_ID_GROUP_ID_FLAGS REG_VOL -#define IEP_LITE_CORE_ID_GROUP_ID_LENGTH 8 - -/* Complete Register Definition */ -#define IEP_LITE_CORE_ID_REG_OFFSET IEP_LITE_CORE_ID_OFFSET -#define IEP_LITE_CORE_ID_REG_SHIFT 0 -#define IEP_LITE_CORE_ID_REG_MASK 0xFFFFFFFF -#define IEP_LITE_CORE_ID_REG_FLAGS REG_VOL -#define IEP_LITE_CORE_ID_REG_LENGTH 32 - - -/* -------------------- Register CORE_REV -------------------- */ - -#define IEP_LITE_CORE_REV_OFFSET 0x7018 - -/* Field MAINT_REV */ -#define IEP_LITE_CORE_REV_MAINT_REV_OFFSET IEP_LITE_CORE_REV_OFFSET -#define IEP_LITE_CORE_REV_MAINT_REV_SHIFT 0 -#define IEP_LITE_CORE_REV_MAINT_REV_MASK 0x000000FF -#define IEP_LITE_CORE_REV_MAINT_REV_FLAGS REG_VOL -#define IEP_LITE_CORE_REV_MAINT_REV_LENGTH 8 - -/* Field MINOR_REV */ -#define IEP_LITE_CORE_REV_MINOR_REV_OFFSET IEP_LITE_CORE_REV_OFFSET -#define IEP_LITE_CORE_REV_MINOR_REV_SHIFT 8 -#define IEP_LITE_CORE_REV_MINOR_REV_MASK 0x0000FF00 -#define IEP_LITE_CORE_REV_MINOR_REV_FLAGS REG_VOL -#define IEP_LITE_CORE_REV_MINOR_REV_LENGTH 8 - -/* Field MAJOR_REV */ -#define IEP_LITE_CORE_REV_MAJOR_REV_OFFSET IEP_LITE_CORE_REV_OFFSET -#define IEP_LITE_CORE_REV_MAJOR_REV_SHIFT 16 -#define IEP_LITE_CORE_REV_MAJOR_REV_MASK 0x00FF0000 -#define IEP_LITE_CORE_REV_MAJOR_REV_FLAGS REG_VOL -#define IEP_LITE_CORE_REV_MAJOR_REV_LENGTH 8 - -/* Complete Register Definition */ -#define IEP_LITE_CORE_REV_REG_OFFSET IEP_LITE_CORE_REV_OFFSET -#define IEP_LITE_CORE_REV_REG_SHIFT 0 -#define IEP_LITE_CORE_REV_REG_MASK 0xFFFFFFFF -#define IEP_LITE_CORE_REV_REG_FLAGS REG_VOL -#define IEP_LITE_CORE_REV_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_0 -------------------- */ - -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET 0x457C - -/* Field H_DSL_COEFF_0 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_MASK 0x0000FFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_LENGTH 16 - -/* Field H_DSL_COEFF_1 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_SHIFT 16 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_MASK 0xFFFF0000 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_LENGTH 16 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_1 -------------------- */ - -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET 0x4580 - -/* Field H_DSL_COEFF_2 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_MASK 0x0000FFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_LENGTH 16 - -/* Field H_DSL_COEFF_3 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_SHIFT 16 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_MASK 0xFFFF0000 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_LENGTH 16 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_2 -------------------- */ - -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET 0x4584 - -/* Field H_DSL_COEFF_4 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_MASK 0x0000FFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_LENGTH 16 - -/* Field H_DSL_COEFF_5 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_SHIFT 16 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_MASK 0xFFFF0000 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_LENGTH 16 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_3 -------------------- */ - -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET 0x4588 - -/* Field H_DSL_COEFF_6 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_MASK 0x0000FFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_LENGTH 16 - -/* Field H_DSL_COEFF_7 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_SHIFT 16 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_MASK 0xFFFF0000 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_LENGTH 16 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_4 -------------------- */ - -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET 0x458C - -/* Field H_DSL_COEFF_8 */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_MASK 0x0000FFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_LENGTH 16 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_SHIFT 0 -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_CHROMA_LPF -------------------- */ - -#define IEP_LITE_EE_TI_CHROMA_LPF_OFFSET 0x45B4 - -/* Field NUMTAPS */ -#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_OFFSET IEP_LITE_EE_TI_CHROMA_LPF_OFFSET -#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_MASK 0x0000000F -#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_LENGTH 4 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_CHROMA_LPF_REG_OFFSET IEP_LITE_EE_TI_CHROMA_LPF_OFFSET -#define IEP_LITE_EE_TI_CHROMA_LPF_REG_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_LPF_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_CHROMA_LPF_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_LPF_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_HORIZONTAL_GAIN -------------------- */ - -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET 0x45B8 - -/* Field HCGAIN */ -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_SHIFT 0 -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_MASK 0x000003FF -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_LENGTH 10 - -/* Field HLGAIN */ -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_SHIFT 10 -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_MASK 0x000FFC00 -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_SHIFT 0 -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_VERTICAL_GAIN -------------------- */ - -#define IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET 0x45BC - -/* Field VLGAIN */ -#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_OFFSET IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET -#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_SHIFT 10 -#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_MASK 0x000FFC00 -#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_OFFSET IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET -#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_SHIFT 0 -#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_OUTPUT -------------------- */ - -#define IEP_LITE_EE_TI_OUTPUT_OFFSET 0x45C0 - -/* Field COVERSHOOT */ -#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET -#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_SHIFT 0 -#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_MASK 0x000003FF -#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_LENGTH 10 - -/* Field LOVERSHOOT */ -#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET -#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_SHIFT 10 -#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_MASK 0x000FFC00 -#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_LENGTH 10 - -/* Field OVERSHOOT_CLAMP */ -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_SHIFT 24 -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_MASK 0x01000000 -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_FLAGS REG_VOL -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_LENGTH 1 - -/* Field OVERSHOOT_WINDOW */ -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_SHIFT 28 -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_MASK 0x10000000 -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_FLAGS REG_VOL -#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_OUTPUT_REG_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET -#define IEP_LITE_EE_TI_OUTPUT_REG_SHIFT 0 -#define IEP_LITE_EE_TI_OUTPUT_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_OUTPUT_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_OUTPUT_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_CONFIG -------------------- */ - -#define IEP_LITE_EE_TI_CONFIG_OFFSET 0x45C4 - -/* Field EE_TI_EN */ -#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_OFFSET IEP_LITE_EE_TI_CONFIG_OFFSET -#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_SHIFT 0 -#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_MASK 0x00000001 -#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_CONFIG_REG_OFFSET IEP_LITE_EE_TI_CONFIG_OFFSET -#define IEP_LITE_EE_TI_CONFIG_REG_SHIFT 0 -#define IEP_LITE_EE_TI_CONFIG_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_CONFIG_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CONFIG_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_LUMA_UNDERSHOOT_COMPRESSION -------------------- */ - -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET 0x45C8 - -/* Field LU_US_START */ -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_MASK 0x000003FF -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_LENGTH 10 - -/* Field LU_US_GRADIENT */ -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_SHIFT 16 -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_MASK 0x3FFF0000 -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_LUMA_OVERSHOOT_COMPRESSION -------------------- */ - -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET 0x45CC - -/* Field LU_OS_START */ -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_MASK 0x000003FF -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_LENGTH 10 - -/* Field LU_OS_GRADIENT */ -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_SHIFT 16 -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_MASK 0x3FFF0000 -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_CHROMA_UNDERSHOOT_COMPRESSION -------------------- */ - -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET 0x45D0 - -/* Field CR_US_START */ -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_MASK 0x000003FF -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_LENGTH 10 - -/* Field CR_US_GRADIENT */ -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_SHIFT 16 -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_MASK 0x3FFF0000 -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_CHROMA_OVERSHOOT_COMPRESSION -------------------- */ - -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET 0x45D4 - -/* Field CR_OS_START */ -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_MASK 0x000003FF -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_LENGTH 10 - -/* Field CR_OS_GRADIENT */ -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_SHIFT 16 -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_MASK 0x3FFF0000 -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_SHIFT 0 -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN -------------------- */ - -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET 0x45D8 - -/* Field LU_H_ADPT_GAIN */ -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_SHIFT 0 -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_MASK 0x00003FFF -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_OFFSET IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_SHIFT 0 -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN -------------------- */ - -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET 0x45DC - -/* Field LU_V_ADPT_GAIN */ -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_OFFSET IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_SHIFT 0 -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_MASK 0x00003FFF -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_FLAGS REG_VOL -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_LENGTH 14 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_OFFSET IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_SHIFT 0 -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_END_OF_FRAME -------------------- */ - -#define IEP_LITE_EE_TI_END_OF_FRAME_OFFSET 0x45E0 - -/* Field EOF */ -#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_OFFSET IEP_LITE_EE_TI_END_OF_FRAME_OFFSET -#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_SHIFT 0 -#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_MASK 0x00000001 -#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_FLAGS REG_VOL -#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_END_OF_FRAME_REG_OFFSET IEP_LITE_EE_TI_END_OF_FRAME_OFFSET -#define IEP_LITE_EE_TI_END_OF_FRAME_REG_SHIFT 0 -#define IEP_LITE_EE_TI_END_OF_FRAME_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_END_OF_FRAME_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_END_OF_FRAME_REG_LENGTH 32 - - -/* -------------------- Register EE_TI_LUMA_FD_CORING_THRESHOLD -------------------- */ - -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET 0x4604 - -/* Field LU_FD_CORE_THRESH */ -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_OFFSET IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_MASK 0x0000000F -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_LENGTH 4 - -/* Complete Register Definition */ -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_OFFSET IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_SHIFT 0 -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_MASK 0xFFFFFFFF -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_FLAGS REG_VOL -#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_LENGTH 32 - - -/* -------------------- Register HS_C11C12 -------------------- */ - -#define IEP_LITE_HS_C11C12_OFFSET 0x2000 - -/* Field HS_C11 */ -#define IEP_LITE_HS_C11C12_HS_C11_OFFSET IEP_LITE_HS_C11C12_OFFSET -#define IEP_LITE_HS_C11C12_HS_C11_SHIFT 0 -#define IEP_LITE_HS_C11C12_HS_C11_MASK 0x000007FF -#define IEP_LITE_HS_C11C12_HS_C11_FLAGS REG_VOL -#define IEP_LITE_HS_C11C12_HS_C11_LENGTH 11 - -/* Field HS_C12 */ -#define IEP_LITE_HS_C11C12_HS_C12_OFFSET IEP_LITE_HS_C11C12_OFFSET -#define IEP_LITE_HS_C11C12_HS_C12_SHIFT 16 -#define IEP_LITE_HS_C11C12_HS_C12_MASK 0x07FF0000 -#define IEP_LITE_HS_C11C12_HS_C12_FLAGS REG_VOL -#define IEP_LITE_HS_C11C12_HS_C12_LENGTH 11 - -/* Complete Register Definition */ -#define IEP_LITE_HS_C11C12_REG_OFFSET IEP_LITE_HS_C11C12_OFFSET -#define IEP_LITE_HS_C11C12_REG_SHIFT 0 -#define IEP_LITE_HS_C11C12_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_C11C12_REG_FLAGS REG_VOL -#define IEP_LITE_HS_C11C12_REG_LENGTH 32 - - -/* -------------------- Register HS_C13C21 -------------------- */ - -#define IEP_LITE_HS_C13C21_OFFSET 0x2004 - -/* Field HS_C13 */ -#define IEP_LITE_HS_C13C21_HS_C13_OFFSET IEP_LITE_HS_C13C21_OFFSET -#define IEP_LITE_HS_C13C21_HS_C13_SHIFT 0 -#define IEP_LITE_HS_C13C21_HS_C13_MASK 0x000007FF -#define IEP_LITE_HS_C13C21_HS_C13_FLAGS REG_VOL -#define IEP_LITE_HS_C13C21_HS_C13_LENGTH 11 - -/* Field HS_C21 */ -#define IEP_LITE_HS_C13C21_HS_C21_OFFSET IEP_LITE_HS_C13C21_OFFSET -#define IEP_LITE_HS_C13C21_HS_C21_SHIFT 16 -#define IEP_LITE_HS_C13C21_HS_C21_MASK 0x07FF0000 -#define IEP_LITE_HS_C13C21_HS_C21_FLAGS REG_VOL -#define IEP_LITE_HS_C13C21_HS_C21_LENGTH 11 - -/* Complete Register Definition */ -#define IEP_LITE_HS_C13C21_REG_OFFSET IEP_LITE_HS_C13C21_OFFSET -#define IEP_LITE_HS_C13C21_REG_SHIFT 0 -#define IEP_LITE_HS_C13C21_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_C13C21_REG_FLAGS REG_VOL -#define IEP_LITE_HS_C13C21_REG_LENGTH 32 - - -/* -------------------- Register HS_C22C23 -------------------- */ - -#define IEP_LITE_HS_C22C23_OFFSET 0x2008 - -/* Field HS_C22 */ -#define IEP_LITE_HS_C22C23_HS_C22_OFFSET IEP_LITE_HS_C22C23_OFFSET -#define IEP_LITE_HS_C22C23_HS_C22_SHIFT 0 -#define IEP_LITE_HS_C22C23_HS_C22_MASK 0x000007FF -#define IEP_LITE_HS_C22C23_HS_C22_FLAGS REG_VOL -#define IEP_LITE_HS_C22C23_HS_C22_LENGTH 11 - -/* Field HS_C23 */ -#define IEP_LITE_HS_C22C23_HS_C23_OFFSET IEP_LITE_HS_C22C23_OFFSET -#define IEP_LITE_HS_C22C23_HS_C23_SHIFT 16 -#define IEP_LITE_HS_C22C23_HS_C23_MASK 0x07FF0000 -#define IEP_LITE_HS_C22C23_HS_C23_FLAGS REG_VOL -#define IEP_LITE_HS_C22C23_HS_C23_LENGTH 11 - -/* Complete Register Definition */ -#define IEP_LITE_HS_C22C23_REG_OFFSET IEP_LITE_HS_C22C23_OFFSET -#define IEP_LITE_HS_C22C23_REG_SHIFT 0 -#define IEP_LITE_HS_C22C23_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_C22C23_REG_FLAGS REG_VOL -#define IEP_LITE_HS_C22C23_REG_LENGTH 32 - - -/* -------------------- Register HS_C31C32 -------------------- */ - -#define IEP_LITE_HS_C31C32_OFFSET 0x200C - -/* Field HS_C31 */ -#define IEP_LITE_HS_C31C32_HS_C31_OFFSET IEP_LITE_HS_C31C32_OFFSET -#define IEP_LITE_HS_C31C32_HS_C31_SHIFT 0 -#define IEP_LITE_HS_C31C32_HS_C31_MASK 0x000007FF -#define IEP_LITE_HS_C31C32_HS_C31_FLAGS REG_VOL -#define IEP_LITE_HS_C31C32_HS_C31_LENGTH 11 - -/* Field HS_C32 */ -#define IEP_LITE_HS_C31C32_HS_C32_OFFSET IEP_LITE_HS_C31C32_OFFSET -#define IEP_LITE_HS_C31C32_HS_C32_SHIFT 16 -#define IEP_LITE_HS_C31C32_HS_C32_MASK 0x07FF0000 -#define IEP_LITE_HS_C31C32_HS_C32_FLAGS REG_VOL -#define IEP_LITE_HS_C31C32_HS_C32_LENGTH 11 - -/* Complete Register Definition */ -#define IEP_LITE_HS_C31C32_REG_OFFSET IEP_LITE_HS_C31C32_OFFSET -#define IEP_LITE_HS_C31C32_REG_SHIFT 0 -#define IEP_LITE_HS_C31C32_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_C31C32_REG_FLAGS REG_VOL -#define IEP_LITE_HS_C31C32_REG_LENGTH 32 - - -/* -------------------- Register HS_C33 -------------------- */ - -#define IEP_LITE_HS_C33_OFFSET 0x2010 - -/* Field HS_C33 */ -#define IEP_LITE_HS_C33_HS_C33_OFFSET IEP_LITE_HS_C33_OFFSET -#define IEP_LITE_HS_C33_HS_C33_SHIFT 0 -#define IEP_LITE_HS_C33_HS_C33_MASK 0x000007FF -#define IEP_LITE_HS_C33_HS_C33_FLAGS REG_VOL -#define IEP_LITE_HS_C33_HS_C33_LENGTH 11 - -/* Complete Register Definition */ -#define IEP_LITE_HS_C33_REG_OFFSET IEP_LITE_HS_C33_OFFSET -#define IEP_LITE_HS_C33_REG_SHIFT 0 -#define IEP_LITE_HS_C33_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_C33_REG_FLAGS REG_VOL -#define IEP_LITE_HS_C33_REG_LENGTH 32 - - -/* -------------------- Register HS_CBOCRO -------------------- */ - -#define IEP_LITE_HS_CBOCRO_OFFSET 0x2014 - -/* Field HS_CRO */ -#define IEP_LITE_HS_CBOCRO_HS_CRO_OFFSET IEP_LITE_HS_CBOCRO_OFFSET -#define IEP_LITE_HS_CBOCRO_HS_CRO_SHIFT 0 -#define IEP_LITE_HS_CBOCRO_HS_CRO_MASK 0x000003FF -#define IEP_LITE_HS_CBOCRO_HS_CRO_FLAGS REG_VOL -#define IEP_LITE_HS_CBOCRO_HS_CRO_LENGTH 10 - -/* Field HS_CBO */ -#define IEP_LITE_HS_CBOCRO_HS_CBO_OFFSET IEP_LITE_HS_CBOCRO_OFFSET -#define IEP_LITE_HS_CBOCRO_HS_CBO_SHIFT 16 -#define IEP_LITE_HS_CBOCRO_HS_CBO_MASK 0x03FF0000 -#define IEP_LITE_HS_CBOCRO_HS_CBO_FLAGS REG_VOL -#define IEP_LITE_HS_CBOCRO_HS_CBO_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_HS_CBOCRO_REG_OFFSET IEP_LITE_HS_CBOCRO_OFFSET -#define IEP_LITE_HS_CBOCRO_REG_SHIFT 0 -#define IEP_LITE_HS_CBOCRO_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_CBOCRO_REG_FLAGS REG_VOL -#define IEP_LITE_HS_CBOCRO_REG_LENGTH 32 - - -/* -------------------- Register HS_YO -------------------- */ - -#define IEP_LITE_HS_YO_OFFSET 0x2018 - -/* Field HS_YO */ -#define IEP_LITE_HS_YO_HS_YO_OFFSET IEP_LITE_HS_YO_OFFSET -#define IEP_LITE_HS_YO_HS_YO_SHIFT 0 -#define IEP_LITE_HS_YO_HS_YO_MASK 0x000003FF -#define IEP_LITE_HS_YO_HS_YO_FLAGS REG_VOL -#define IEP_LITE_HS_YO_HS_YO_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_HS_YO_REG_OFFSET IEP_LITE_HS_YO_OFFSET -#define IEP_LITE_HS_YO_REG_SHIFT 0 -#define IEP_LITE_HS_YO_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_YO_REG_FLAGS REG_VOL -#define IEP_LITE_HS_YO_REG_LENGTH 32 - - -/* -------------------- Register HS_ROGO -------------------- */ - -#define IEP_LITE_HS_ROGO_OFFSET 0x201C - -/* Field HS_RO */ -#define IEP_LITE_HS_ROGO_HS_RO_OFFSET IEP_LITE_HS_ROGO_OFFSET -#define IEP_LITE_HS_ROGO_HS_RO_SHIFT 0 -#define IEP_LITE_HS_ROGO_HS_RO_MASK 0x000003FF -#define IEP_LITE_HS_ROGO_HS_RO_FLAGS REG_VOL -#define IEP_LITE_HS_ROGO_HS_RO_LENGTH 10 - -/* Field HS_GO */ -#define IEP_LITE_HS_ROGO_HS_GO_OFFSET IEP_LITE_HS_ROGO_OFFSET -#define IEP_LITE_HS_ROGO_HS_GO_SHIFT 16 -#define IEP_LITE_HS_ROGO_HS_GO_MASK 0x03FF0000 -#define IEP_LITE_HS_ROGO_HS_GO_FLAGS REG_VOL -#define IEP_LITE_HS_ROGO_HS_GO_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_HS_ROGO_REG_OFFSET IEP_LITE_HS_ROGO_OFFSET -#define IEP_LITE_HS_ROGO_REG_SHIFT 0 -#define IEP_LITE_HS_ROGO_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_ROGO_REG_FLAGS REG_VOL -#define IEP_LITE_HS_ROGO_REG_LENGTH 32 - - -/* -------------------- Register HS_BO -------------------- */ - -#define IEP_LITE_HS_BO_OFFSET 0x2020 - -/* Field HS_BO */ -#define IEP_LITE_HS_BO_HS_BO_OFFSET IEP_LITE_HS_BO_OFFSET -#define IEP_LITE_HS_BO_HS_BO_SHIFT 0 -#define IEP_LITE_HS_BO_HS_BO_MASK 0x000003FF -#define IEP_LITE_HS_BO_HS_BO_FLAGS REG_VOL -#define IEP_LITE_HS_BO_HS_BO_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_HS_BO_REG_OFFSET IEP_LITE_HS_BO_OFFSET -#define IEP_LITE_HS_BO_REG_SHIFT 0 -#define IEP_LITE_HS_BO_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_BO_REG_FLAGS REG_VOL -#define IEP_LITE_HS_BO_REG_LENGTH 32 - - -/* -------------------- Register HS_CONF_STATUS -------------------- */ - -#define IEP_LITE_HS_CONF_STATUS_OFFSET 0x2024 - -/* Field HS_EN */ -#define IEP_LITE_HS_CONF_STATUS_HS_EN_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET -#define IEP_LITE_HS_CONF_STATUS_HS_EN_SHIFT 0 -#define IEP_LITE_HS_CONF_STATUS_HS_EN_MASK 0x00000001 -#define IEP_LITE_HS_CONF_STATUS_HS_EN_FLAGS REG_VOL -#define IEP_LITE_HS_CONF_STATUS_HS_EN_LENGTH 1 - -/* Field HS_RWND */ -#define IEP_LITE_HS_CONF_STATUS_HS_RWND_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET -#define IEP_LITE_HS_CONF_STATUS_HS_RWND_SHIFT 1 -#define IEP_LITE_HS_CONF_STATUS_HS_RWND_MASK 0x00000002 -#define IEP_LITE_HS_CONF_STATUS_HS_RWND_FLAGS REG_VOL -#define IEP_LITE_HS_CONF_STATUS_HS_RWND_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_HS_CONF_STATUS_REG_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET -#define IEP_LITE_HS_CONF_STATUS_REG_SHIFT 0 -#define IEP_LITE_HS_CONF_STATUS_REG_MASK 0xFFFFFFFF -#define IEP_LITE_HS_CONF_STATUS_REG_FLAGS REG_VOL -#define IEP_LITE_HS_CONF_STATUS_REG_LENGTH 32 - - -/* -------------------- Register BSSCC_CTRL -------------------- */ - -#define IEP_LITE_BSSCC_CTRL_OFFSET 0x1000 - -/* Field BS_EN */ -#define IEP_LITE_BSSCC_CTRL_BS_EN_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET -#define IEP_LITE_BSSCC_CTRL_BS_EN_SHIFT 0 -#define IEP_LITE_BSSCC_CTRL_BS_EN_MASK 0x00000001 -#define IEP_LITE_BSSCC_CTRL_BS_EN_FLAGS REG_VOL -#define IEP_LITE_BSSCC_CTRL_BS_EN_LENGTH 1 - -/* Field SCC_EN */ -#define IEP_LITE_BSSCC_CTRL_SCC_EN_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET -#define IEP_LITE_BSSCC_CTRL_SCC_EN_SHIFT 1 -#define IEP_LITE_BSSCC_CTRL_SCC_EN_MASK 0x00000002 -#define IEP_LITE_BSSCC_CTRL_SCC_EN_FLAGS REG_VOL -#define IEP_LITE_BSSCC_CTRL_SCC_EN_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_BSSCC_CTRL_REG_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET -#define IEP_LITE_BSSCC_CTRL_REG_SHIFT 0 -#define IEP_LITE_BSSCC_CTRL_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BSSCC_CTRL_REG_FLAGS REG_VOL -#define IEP_LITE_BSSCC_CTRL_REG_LENGTH 32 - - -/* -------------------- Register BS_CHROMA_RADIUS -------------------- */ - -#define IEP_LITE_BS_CHROMA_RADIUS_OFFSET 0x1004 - -/* Field R3 */ -#define IEP_LITE_BS_CHROMA_RADIUS_R3_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET -#define IEP_LITE_BS_CHROMA_RADIUS_R3_SHIFT 0 -#define IEP_LITE_BS_CHROMA_RADIUS_R3_MASK 0x000003FF -#define IEP_LITE_BS_CHROMA_RADIUS_R3_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_RADIUS_R3_LENGTH 10 - -/* Field R4 */ -#define IEP_LITE_BS_CHROMA_RADIUS_R4_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET -#define IEP_LITE_BS_CHROMA_RADIUS_R4_SHIFT 16 -#define IEP_LITE_BS_CHROMA_RADIUS_R4_MASK 0x03FF0000 -#define IEP_LITE_BS_CHROMA_RADIUS_R4_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_RADIUS_R4_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BS_CHROMA_RADIUS_REG_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET -#define IEP_LITE_BS_CHROMA_RADIUS_REG_SHIFT 0 -#define IEP_LITE_BS_CHROMA_RADIUS_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BS_CHROMA_RADIUS_REG_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_RADIUS_REG_LENGTH 32 - - -/* -------------------- Register BS_CHROMA_ANGLE -------------------- */ - -#define IEP_LITE_BS_CHROMA_ANGLE_OFFSET 0x1008 - -/* Field THETA3 */ -#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET -#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_SHIFT 0 -#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_MASK 0x000003FF -#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_LENGTH 10 - -/* Field THETA4 */ -#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET -#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_SHIFT 16 -#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_MASK 0x03FF0000 -#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BS_CHROMA_ANGLE_REG_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET -#define IEP_LITE_BS_CHROMA_ANGLE_REG_SHIFT 0 -#define IEP_LITE_BS_CHROMA_ANGLE_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BS_CHROMA_ANGLE_REG_FLAGS REG_VOL -#define IEP_LITE_BS_CHROMA_ANGLE_REG_LENGTH 32 - - -/* -------------------- Register BS_LUMA -------------------- */ - -#define IEP_LITE_BS_LUMA_OFFSET 0x100C - -/* Field YMIN */ -#define IEP_LITE_BS_LUMA_YMIN_OFFSET IEP_LITE_BS_LUMA_OFFSET -#define IEP_LITE_BS_LUMA_YMIN_SHIFT 0 -#define IEP_LITE_BS_LUMA_YMIN_MASK 0x000003FF -#define IEP_LITE_BS_LUMA_YMIN_FLAGS REG_VOL -#define IEP_LITE_BS_LUMA_YMIN_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BS_LUMA_REG_OFFSET IEP_LITE_BS_LUMA_OFFSET -#define IEP_LITE_BS_LUMA_REG_SHIFT 0 -#define IEP_LITE_BS_LUMA_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BS_LUMA_REG_FLAGS REG_VOL -#define IEP_LITE_BS_LUMA_REG_LENGTH 32 - - -/* -------------------- Register BS_CORR -------------------- */ - -#define IEP_LITE_BS_CORR_OFFSET 0x1010 - -/* Field OFFSET */ -#define IEP_LITE_BS_CORR_OFFST_OFFSET IEP_LITE_BS_CORR_OFFSET -#define IEP_LITE_BS_CORR_OFFST_SHIFT 0 -#define IEP_LITE_BS_CORR_OFFST_MASK 0x000003FF -#define IEP_LITE_BS_CORR_OFFST_FLAGS REG_VOL -#define IEP_LITE_BS_CORR_OFFST_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BS_CORR_REG_OFFSET IEP_LITE_BS_CORR_OFFSET -#define IEP_LITE_BS_CORR_REG_SHIFT 0 -#define IEP_LITE_BS_CORR_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BS_CORR_REG_FLAGS REG_VOL -#define IEP_LITE_BS_CORR_REG_LENGTH 32 - - -/* -------------------- Register SCC_RADIUS -------------------- */ - -#define IEP_LITE_SCC_RADIUS_OFFSET 0x1014 - -/* Field R1 */ -#define IEP_LITE_SCC_RADIUS_R1_OFFSET IEP_LITE_SCC_RADIUS_OFFSET -#define IEP_LITE_SCC_RADIUS_R1_SHIFT 0 -#define IEP_LITE_SCC_RADIUS_R1_MASK 0x000003FF -#define IEP_LITE_SCC_RADIUS_R1_FLAGS REG_VOL -#define IEP_LITE_SCC_RADIUS_R1_LENGTH 10 - -/* Field R2 */ -#define IEP_LITE_SCC_RADIUS_R2_OFFSET IEP_LITE_SCC_RADIUS_OFFSET -#define IEP_LITE_SCC_RADIUS_R2_SHIFT 16 -#define IEP_LITE_SCC_RADIUS_R2_MASK 0x03FF0000 -#define IEP_LITE_SCC_RADIUS_R2_FLAGS REG_VOL -#define IEP_LITE_SCC_RADIUS_R2_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_SCC_RADIUS_REG_OFFSET IEP_LITE_SCC_RADIUS_OFFSET -#define IEP_LITE_SCC_RADIUS_REG_SHIFT 0 -#define IEP_LITE_SCC_RADIUS_REG_MASK 0xFFFFFFFF -#define IEP_LITE_SCC_RADIUS_REG_FLAGS REG_VOL -#define IEP_LITE_SCC_RADIUS_REG_LENGTH 32 - - -/* -------------------- Register SCC_ANGLE -------------------- */ - -#define IEP_LITE_SCC_ANGLE_OFFSET 0x1018 - -/* Field THETA1 */ -#define IEP_LITE_SCC_ANGLE_THETA1_OFFSET IEP_LITE_SCC_ANGLE_OFFSET -#define IEP_LITE_SCC_ANGLE_THETA1_SHIFT 0 -#define IEP_LITE_SCC_ANGLE_THETA1_MASK 0x000003FF -#define IEP_LITE_SCC_ANGLE_THETA1_FLAGS REG_VOL -#define IEP_LITE_SCC_ANGLE_THETA1_LENGTH 10 - -/* Field THETA2 */ -#define IEP_LITE_SCC_ANGLE_THETA2_OFFSET IEP_LITE_SCC_ANGLE_OFFSET -#define IEP_LITE_SCC_ANGLE_THETA2_SHIFT 16 -#define IEP_LITE_SCC_ANGLE_THETA2_MASK 0x03FF0000 -#define IEP_LITE_SCC_ANGLE_THETA2_FLAGS REG_VOL -#define IEP_LITE_SCC_ANGLE_THETA2_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_SCC_ANGLE_REG_OFFSET IEP_LITE_SCC_ANGLE_OFFSET -#define IEP_LITE_SCC_ANGLE_REG_SHIFT 0 -#define IEP_LITE_SCC_ANGLE_REG_MASK 0xFFFFFFFF -#define IEP_LITE_SCC_ANGLE_REG_FLAGS REG_VOL -#define IEP_LITE_SCC_ANGLE_REG_LENGTH 32 - - -/* -------------------- Register SCC_CORR -------------------- */ - -#define IEP_LITE_SCC_CORR_OFFSET 0x101C - -/* Field GAIN */ -#define IEP_LITE_SCC_CORR_GAIN_OFFSET IEP_LITE_SCC_CORR_OFFSET -#define IEP_LITE_SCC_CORR_GAIN_SHIFT 0 -#define IEP_LITE_SCC_CORR_GAIN_MASK 0x000003FF -#define IEP_LITE_SCC_CORR_GAIN_FLAGS REG_VOL -#define IEP_LITE_SCC_CORR_GAIN_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_SCC_CORR_REG_OFFSET IEP_LITE_SCC_CORR_OFFSET -#define IEP_LITE_SCC_CORR_REG_SHIFT 0 -#define IEP_LITE_SCC_CORR_REG_MASK 0xFFFFFFFF -#define IEP_LITE_SCC_CORR_REG_FLAGS REG_VOL -#define IEP_LITE_SCC_CORR_REG_LENGTH 32 - - -/* -------------------- Register BLE_LUT_TABLE -------------------- */ - -#define IEP_LITE_BLE_LUT_TABLE_OFFSET 0x0000 - -/* Field ble_lut(2*n) */ -#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET -#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_SHIFT 0 -#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_MASK 0x000003FF -#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_FLAGS REG_VOL -#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_LENGTH 10 - -/* Field ble_lut(2*n+1) */ -#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET -#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_SHIFT 16 -#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_MASK 0x03FF0000 -#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_FLAGS REG_VOL -#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BLE_LUT_REG_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET -#define IEP_LITE_BLE_LUT_REG_SHIFT 0 -#define IEP_LITE_BLE_LUT_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BLE_LUT_REG_FLAGS REG_VOL -#define IEP_LITE_BLE_LUT_REG_LENGTH 32 - - -/* -------------------- Register BLE_CONF_STATUS -------------------- */ - -#define IEP_LITE_BLE_CONF_STATUS_OFFSET 0x0800 - -/* Field BLE_EN */ -#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET -#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_SHIFT 0 -#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_MASK 0x00000001 -#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_FLAGS REG_VOL -#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_LENGTH 1 - -/* Field BLE_RWND */ -#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET -#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_SHIFT 1 -#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_MASK 0x00000002 -#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_FLAGS REG_VOL -#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_LENGTH 1 - -/* Complete Register Definition */ -#define IEP_LITE_BLE_CONF_STATUS_REG_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET -#define IEP_LITE_BLE_CONF_STATUS_REG_SHIFT 0 -#define IEP_LITE_BLE_CONF_STATUS_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BLE_CONF_STATUS_REG_FLAGS REG_VOL -#define IEP_LITE_BLE_CONF_STATUS_REG_LENGTH 32 - - -/* -------------------- Register BLE_MAV -------------------- */ - -#define IEP_LITE_BLE_MAV_OFFSET 0x0804 - -/* Field BLE_MAVMIN */ -#define IEP_LITE_BLE_MAV_BLE_MAVMIN_OFFSET IEP_LITE_BLE_MAV_OFFSET -#define IEP_LITE_BLE_MAV_BLE_MAVMIN_SHIFT 0 -#define IEP_LITE_BLE_MAV_BLE_MAVMIN_MASK 0x000003FF -#define IEP_LITE_BLE_MAV_BLE_MAVMIN_FLAGS REG_VOL -#define IEP_LITE_BLE_MAV_BLE_MAVMIN_LENGTH 10 - -/* Field BLE_MAVMAX */ -#define IEP_LITE_BLE_MAV_BLE_MAVMAX_OFFSET IEP_LITE_BLE_MAV_OFFSET -#define IEP_LITE_BLE_MAV_BLE_MAVMAX_SHIFT 16 -#define IEP_LITE_BLE_MAV_BLE_MAVMAX_MASK 0x03FF0000 -#define IEP_LITE_BLE_MAV_BLE_MAVMAX_FLAGS REG_VOL -#define IEP_LITE_BLE_MAV_BLE_MAVMAX_LENGTH 10 - -/* Complete Register Definition */ -#define IEP_LITE_BLE_MAV_REG_OFFSET IEP_LITE_BLE_MAV_OFFSET -#define IEP_LITE_BLE_MAV_REG_SHIFT 0 -#define IEP_LITE_BLE_MAV_REG_MASK 0xFFFFFFFF -#define IEP_LITE_BLE_MAV_REG_FLAGS REG_VOL -#define IEP_LITE_BLE_MAV_REG_LENGTH 32 - -/* ------------------------ End of register definitions ------------------------ */ - -/* -// NUMREG defines the extent of register address space. -*/ - -#define IEP_LITE_NUMREG ((0x0804 >> 2)+1) - -/*-------------------------------------------------------------------------------*/ - -#ifdef __cplusplus -} -#endif - -#endif /* __IEP_LITE_REG_DEFS_H__ */ +/*! +****************************************************************************** +@file : out_reg_io.h + +@brief + +@Author + + Copyright 2008 by Imagination Technologies Limited. + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + +Description:\n + This file contains the IEP lite Defintions. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__IEP_LITE_REG_DEFS_H__) +#define __IEP_LITE_REG_DEFS_H__ + +/* This line just means we can write C here and C++ elsewhere when it +** picks up the header file will know that all these functions are +** mangled up C wise instead of C++ wise. See also the } way below. +*/ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Hardware register definitions */ + +/* -------------------- Register DEBUGMODE -------------------- */ + +#define IEP_LITE_DEBUGMODE_OFFSET 0x7000 + +/* Field IEP_LITE_DEBUGMODE */ +#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_OFFSET IEP_LITE_DEBUGMODE_OFFSET +#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_SHIFT 0 +#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_MASK 0x00000001 +#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_FLAGS REG_VOL +#define IEP_LITE_DEBUGMODE_IEP_LITE_DEBUGMODE_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_DEBUGMODE_REG_OFFSET IEP_LITE_DEBUGMODE_OFFSET +#define IEP_LITE_DEBUGMODE_REG_SHIFT 0 +#define IEP_LITE_DEBUGMODE_REG_MASK 0xFFFFFFFF +#define IEP_LITE_DEBUGMODE_REG_FLAGS REG_VOL +#define IEP_LITE_DEBUGMODE_REG_LENGTH 32 + + +/* -------------------- Register DINBSY_DIN -------------------- */ + +#define IEP_LITE_DINBSY_DIN_OFFSET 0x7004 + +/* Field IEP_LITE_DEBUG_DIN */ +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_OFFSET IEP_LITE_DINBSY_DIN_OFFSET +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_SHIFT 0 +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_MASK 0x3FFFFFFF +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_FLAGS REG_VOL +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DEBUG_DIN_LENGTH 30 + +/* Field IEP_LITE_DINBSY */ +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_OFFSET IEP_LITE_DINBSY_DIN_OFFSET +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_SHIFT 31 +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_MASK 0x80000000 +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_FLAGS REG_VOL +#define IEP_LITE_DINBSY_DIN_IEP_LITE_DINBSY_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_DINBSY_DIN_REG_OFFSET IEP_LITE_DINBSY_DIN_OFFSET +#define IEP_LITE_DINBSY_DIN_REG_SHIFT 0 +#define IEP_LITE_DINBSY_DIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_DINBSY_DIN_REG_FLAGS REG_VOL +#define IEP_LITE_DINBSY_DIN_REG_LENGTH 32 + + +/* -------------------- Register SIDEIN -------------------- */ + +#define IEP_LITE_SIDEIN_OFFSET 0x7008 + +/* Field IEP_LITE_SIDEIN */ +#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_OFFSET IEP_LITE_SIDEIN_OFFSET +#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_SHIFT 0 +#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_MASK 0x00000007 +#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_FLAGS REG_VOL +#define IEP_LITE_SIDEIN_IEP_LITE_SIDEIN_LENGTH 3 + +/* Complete Register Definition */ +#define IEP_LITE_SIDEIN_REG_OFFSET IEP_LITE_SIDEIN_OFFSET +#define IEP_LITE_SIDEIN_REG_SHIFT 0 +#define IEP_LITE_SIDEIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_SIDEIN_REG_FLAGS REG_VOL +#define IEP_LITE_SIDEIN_REG_LENGTH 32 + + +/* -------------------- Register DOUTVLD_DOUT -------------------- */ + +#define IEP_LITE_DOUTVLD_DOUT_OFFSET 0x700C + +/* Field IEP_LITE_DEBUG_DOUT */ +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_SHIFT 0 +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_MASK 0x3FFFFFFF +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_FLAGS REG_VOL +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUT_LENGTH 30 + +/* Field IEP_LITE_DEBUG_DOUTVLD */ +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_SHIFT 31 +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_MASK 0x80000000 +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_FLAGS REG_VOL +#define IEP_LITE_DOUTVLD_DOUT_IEP_LITE_DEBUG_DOUTVLD_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_DOUTVLD_DOUT_REG_OFFSET IEP_LITE_DOUTVLD_DOUT_OFFSET +#define IEP_LITE_DOUTVLD_DOUT_REG_SHIFT 0 +#define IEP_LITE_DOUTVLD_DOUT_REG_MASK 0xFFFFFFFF +#define IEP_LITE_DOUTVLD_DOUT_REG_FLAGS REG_VOL +#define IEP_LITE_DOUTVLD_DOUT_REG_LENGTH 32 + + +/* -------------------- Register SIDEOUT -------------------- */ + +#define IEP_LITE_SIDEOUT_OFFSET 0x7010 + +/* Field IEP_LITE_SIDEOUT */ +#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_OFFSET IEP_LITE_SIDEOUT_OFFSET +#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_SHIFT 0 +#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_MASK 0x00000007 +#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_FLAGS REG_VOL +#define IEP_LITE_SIDEOUT_IEP_LITE_SIDEOUT_LENGTH 3 + +/* Complete Register Definition */ +#define IEP_LITE_SIDEOUT_REG_OFFSET IEP_LITE_SIDEOUT_OFFSET +#define IEP_LITE_SIDEOUT_REG_SHIFT 0 +#define IEP_LITE_SIDEOUT_REG_MASK 0xFFFFFFFF +#define IEP_LITE_SIDEOUT_REG_FLAGS REG_VOL +#define IEP_LITE_SIDEOUT_REG_LENGTH 32 + + +/* -------------------- Register CORE_ID -------------------- */ + +#define IEP_LITE_CORE_ID_OFFSET 0x7014 + +/* Field CONFIG_ID */ +#define IEP_LITE_CORE_ID_CONFIG_ID_OFFSET IEP_LITE_CORE_ID_OFFSET +#define IEP_LITE_CORE_ID_CONFIG_ID_SHIFT 0 +#define IEP_LITE_CORE_ID_CONFIG_ID_MASK 0x0000FFFF +#define IEP_LITE_CORE_ID_CONFIG_ID_FLAGS REG_VOL +#define IEP_LITE_CORE_ID_CONFIG_ID_LENGTH 16 + +/* Field CORE_ID */ +#define IEP_LITE_CORE_ID_CORE_ID_OFFSET IEP_LITE_CORE_ID_OFFSET +#define IEP_LITE_CORE_ID_CORE_ID_SHIFT 16 +#define IEP_LITE_CORE_ID_CORE_ID_MASK 0x00FF0000 +#define IEP_LITE_CORE_ID_CORE_ID_FLAGS REG_VOL +#define IEP_LITE_CORE_ID_CORE_ID_LENGTH 8 + +/* Field GROUP_ID */ +#define IEP_LITE_CORE_ID_GROUP_ID_OFFSET IEP_LITE_CORE_ID_OFFSET +#define IEP_LITE_CORE_ID_GROUP_ID_SHIFT 24 +#define IEP_LITE_CORE_ID_GROUP_ID_MASK 0xFF000000 +#define IEP_LITE_CORE_ID_GROUP_ID_FLAGS REG_VOL +#define IEP_LITE_CORE_ID_GROUP_ID_LENGTH 8 + +/* Complete Register Definition */ +#define IEP_LITE_CORE_ID_REG_OFFSET IEP_LITE_CORE_ID_OFFSET +#define IEP_LITE_CORE_ID_REG_SHIFT 0 +#define IEP_LITE_CORE_ID_REG_MASK 0xFFFFFFFF +#define IEP_LITE_CORE_ID_REG_FLAGS REG_VOL +#define IEP_LITE_CORE_ID_REG_LENGTH 32 + + +/* -------------------- Register CORE_REV -------------------- */ + +#define IEP_LITE_CORE_REV_OFFSET 0x7018 + +/* Field MAINT_REV */ +#define IEP_LITE_CORE_REV_MAINT_REV_OFFSET IEP_LITE_CORE_REV_OFFSET +#define IEP_LITE_CORE_REV_MAINT_REV_SHIFT 0 +#define IEP_LITE_CORE_REV_MAINT_REV_MASK 0x000000FF +#define IEP_LITE_CORE_REV_MAINT_REV_FLAGS REG_VOL +#define IEP_LITE_CORE_REV_MAINT_REV_LENGTH 8 + +/* Field MINOR_REV */ +#define IEP_LITE_CORE_REV_MINOR_REV_OFFSET IEP_LITE_CORE_REV_OFFSET +#define IEP_LITE_CORE_REV_MINOR_REV_SHIFT 8 +#define IEP_LITE_CORE_REV_MINOR_REV_MASK 0x0000FF00 +#define IEP_LITE_CORE_REV_MINOR_REV_FLAGS REG_VOL +#define IEP_LITE_CORE_REV_MINOR_REV_LENGTH 8 + +/* Field MAJOR_REV */ +#define IEP_LITE_CORE_REV_MAJOR_REV_OFFSET IEP_LITE_CORE_REV_OFFSET +#define IEP_LITE_CORE_REV_MAJOR_REV_SHIFT 16 +#define IEP_LITE_CORE_REV_MAJOR_REV_MASK 0x00FF0000 +#define IEP_LITE_CORE_REV_MAJOR_REV_FLAGS REG_VOL +#define IEP_LITE_CORE_REV_MAJOR_REV_LENGTH 8 + +/* Complete Register Definition */ +#define IEP_LITE_CORE_REV_REG_OFFSET IEP_LITE_CORE_REV_OFFSET +#define IEP_LITE_CORE_REV_REG_SHIFT 0 +#define IEP_LITE_CORE_REV_REG_MASK 0xFFFFFFFF +#define IEP_LITE_CORE_REV_REG_FLAGS REG_VOL +#define IEP_LITE_CORE_REV_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_0 -------------------- */ + +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET 0x457C + +/* Field H_DSL_COEFF_0 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_MASK 0x0000FFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_0_LENGTH 16 + +/* Field H_DSL_COEFF_1 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_SHIFT 16 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_MASK 0xFFFF0000 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_H_DSL_COEFF_1_LENGTH 16 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_0_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_1 -------------------- */ + +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET 0x4580 + +/* Field H_DSL_COEFF_2 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_MASK 0x0000FFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_2_LENGTH 16 + +/* Field H_DSL_COEFF_3 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_SHIFT 16 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_MASK 0xFFFF0000 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_H_DSL_COEFF_3_LENGTH 16 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_1_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_2 -------------------- */ + +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET 0x4584 + +/* Field H_DSL_COEFF_4 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_MASK 0x0000FFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_4_LENGTH 16 + +/* Field H_DSL_COEFF_5 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_SHIFT 16 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_MASK 0xFFFF0000 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_H_DSL_COEFF_5_LENGTH 16 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_2_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_3 -------------------- */ + +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET 0x4588 + +/* Field H_DSL_COEFF_6 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_MASK 0x0000FFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_6_LENGTH 16 + +/* Field H_DSL_COEFF_7 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_SHIFT 16 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_MASK 0xFFFF0000 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_H_DSL_COEFF_7_LENGTH 16 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_3_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_H_DOWNSAMPLE_LUMA_4 -------------------- */ + +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET 0x458C + +/* Field H_DSL_COEFF_8 */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_MASK 0x0000FFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_H_DSL_COEFF_8_LENGTH 16 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_OFFSET IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_OFFSET +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_SHIFT 0 +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_H_DOWNSAMPLE_LUMA_4_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_CHROMA_LPF -------------------- */ + +#define IEP_LITE_EE_TI_CHROMA_LPF_OFFSET 0x45B4 + +/* Field NUMTAPS */ +#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_OFFSET IEP_LITE_EE_TI_CHROMA_LPF_OFFSET +#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_MASK 0x0000000F +#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_LPF_NUMTAPS_LENGTH 4 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_CHROMA_LPF_REG_OFFSET IEP_LITE_EE_TI_CHROMA_LPF_OFFSET +#define IEP_LITE_EE_TI_CHROMA_LPF_REG_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_LPF_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_CHROMA_LPF_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_LPF_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_HORIZONTAL_GAIN -------------------- */ + +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET 0x45B8 + +/* Field HCGAIN */ +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_SHIFT 0 +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_MASK 0x000003FF +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HCGAIN_LENGTH 10 + +/* Field HLGAIN */ +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_SHIFT 10 +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_MASK 0x000FFC00 +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_HLGAIN_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_OFFSET IEP_LITE_EE_TI_HORIZONTAL_GAIN_OFFSET +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_SHIFT 0 +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_HORIZONTAL_GAIN_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_VERTICAL_GAIN -------------------- */ + +#define IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET 0x45BC + +/* Field VLGAIN */ +#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_OFFSET IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET +#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_SHIFT 10 +#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_MASK 0x000FFC00 +#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_VERTICAL_GAIN_VLGAIN_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_OFFSET IEP_LITE_EE_TI_VERTICAL_GAIN_OFFSET +#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_SHIFT 0 +#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_VERTICAL_GAIN_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_OUTPUT -------------------- */ + +#define IEP_LITE_EE_TI_OUTPUT_OFFSET 0x45C0 + +/* Field COVERSHOOT */ +#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET +#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_SHIFT 0 +#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_MASK 0x000003FF +#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_OUTPUT_COVERSHOOT_LENGTH 10 + +/* Field LOVERSHOOT */ +#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET +#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_SHIFT 10 +#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_MASK 0x000FFC00 +#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_OUTPUT_LOVERSHOOT_LENGTH 10 + +/* Field OVERSHOOT_CLAMP */ +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_SHIFT 24 +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_MASK 0x01000000 +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_FLAGS REG_VOL +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_CLAMP_LENGTH 1 + +/* Field OVERSHOOT_WINDOW */ +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_SHIFT 28 +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_MASK 0x10000000 +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_FLAGS REG_VOL +#define IEP_LITE_EE_TI_OUTPUT_OVERSHOOT_WINDOW_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_OUTPUT_REG_OFFSET IEP_LITE_EE_TI_OUTPUT_OFFSET +#define IEP_LITE_EE_TI_OUTPUT_REG_SHIFT 0 +#define IEP_LITE_EE_TI_OUTPUT_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_OUTPUT_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_OUTPUT_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_CONFIG -------------------- */ + +#define IEP_LITE_EE_TI_CONFIG_OFFSET 0x45C4 + +/* Field EE_TI_EN */ +#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_OFFSET IEP_LITE_EE_TI_CONFIG_OFFSET +#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_SHIFT 0 +#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_MASK 0x00000001 +#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CONFIG_EE_TI_EN_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_CONFIG_REG_OFFSET IEP_LITE_EE_TI_CONFIG_OFFSET +#define IEP_LITE_EE_TI_CONFIG_REG_SHIFT 0 +#define IEP_LITE_EE_TI_CONFIG_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_CONFIG_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CONFIG_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_LUMA_UNDERSHOOT_COMPRESSION -------------------- */ + +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET 0x45C8 + +/* Field LU_US_START */ +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_MASK 0x000003FF +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_START_LENGTH 10 + +/* Field LU_US_GRADIENT */ +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_SHIFT 16 +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_MASK 0x3FFF0000 +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_LU_US_GRADIENT_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_UNDERSHOOT_COMPRESSION_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_LUMA_OVERSHOOT_COMPRESSION -------------------- */ + +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET 0x45CC + +/* Field LU_OS_START */ +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_MASK 0x000003FF +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_START_LENGTH 10 + +/* Field LU_OS_GRADIENT */ +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_SHIFT 16 +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_MASK 0x3FFF0000 +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_LU_OS_GRADIENT_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_OVERSHOOT_COMPRESSION_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_CHROMA_UNDERSHOOT_COMPRESSION -------------------- */ + +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET 0x45D0 + +/* Field CR_US_START */ +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_MASK 0x000003FF +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_START_LENGTH 10 + +/* Field CR_US_GRADIENT */ +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_SHIFT 16 +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_MASK 0x3FFF0000 +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_CR_US_GRADIENT_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_UNDERSHOOT_COMPRESSION_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_CHROMA_OVERSHOOT_COMPRESSION -------------------- */ + +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET 0x45D4 + +/* Field CR_OS_START */ +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_MASK 0x000003FF +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_START_LENGTH 10 + +/* Field CR_OS_GRADIENT */ +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_SHIFT 16 +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_MASK 0x3FFF0000 +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_CR_OS_GRADIENT_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_OFFSET IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_OFFSET +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_SHIFT 0 +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_CHROMA_OVERSHOOT_COMPRESSION_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN -------------------- */ + +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET 0x45D8 + +/* Field LU_H_ADPT_GAIN */ +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_OFFSET IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_SHIFT 0 +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_MASK 0x00003FFF +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_LU_H_ADPT_GAIN_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_OFFSET IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_OFFSET +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_SHIFT 0 +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_HORIZONTAL_LUMA_ADAPTIVE_GAIN_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN -------------------- */ + +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET 0x45DC + +/* Field LU_V_ADPT_GAIN */ +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_OFFSET IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_SHIFT 0 +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_MASK 0x00003FFF +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_FLAGS REG_VOL +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_LU_V_ADPT_GAIN_LENGTH 14 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_OFFSET IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_OFFSET +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_SHIFT 0 +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_VERTICAL_LUMA_ADAPTIVE_GAIN_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_END_OF_FRAME -------------------- */ + +#define IEP_LITE_EE_TI_END_OF_FRAME_OFFSET 0x45E0 + +/* Field EOF */ +#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_OFFSET IEP_LITE_EE_TI_END_OF_FRAME_OFFSET +#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_SHIFT 0 +#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_MASK 0x00000001 +#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_FLAGS REG_VOL +#define IEP_LITE_EE_TI_END_OF_FRAME_EOF_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_END_OF_FRAME_REG_OFFSET IEP_LITE_EE_TI_END_OF_FRAME_OFFSET +#define IEP_LITE_EE_TI_END_OF_FRAME_REG_SHIFT 0 +#define IEP_LITE_EE_TI_END_OF_FRAME_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_END_OF_FRAME_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_END_OF_FRAME_REG_LENGTH 32 + + +/* -------------------- Register EE_TI_LUMA_FD_CORING_THRESHOLD -------------------- */ + +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET 0x4604 + +/* Field LU_FD_CORE_THRESH */ +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_OFFSET IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_MASK 0x0000000F +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_LU_FD_CORE_THRESH_LENGTH 4 + +/* Complete Register Definition */ +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_OFFSET IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_OFFSET +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_SHIFT 0 +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_MASK 0xFFFFFFFF +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_FLAGS REG_VOL +#define IEP_LITE_EE_TI_LUMA_FD_CORING_THRESHOLD_REG_LENGTH 32 + + +/* -------------------- Register HS_C11C12 -------------------- */ + +#define IEP_LITE_HS_C11C12_OFFSET 0x2000 + +/* Field HS_C11 */ +#define IEP_LITE_HS_C11C12_HS_C11_OFFSET IEP_LITE_HS_C11C12_OFFSET +#define IEP_LITE_HS_C11C12_HS_C11_SHIFT 0 +#define IEP_LITE_HS_C11C12_HS_C11_MASK 0x000007FF +#define IEP_LITE_HS_C11C12_HS_C11_FLAGS REG_VOL +#define IEP_LITE_HS_C11C12_HS_C11_LENGTH 11 + +/* Field HS_C12 */ +#define IEP_LITE_HS_C11C12_HS_C12_OFFSET IEP_LITE_HS_C11C12_OFFSET +#define IEP_LITE_HS_C11C12_HS_C12_SHIFT 16 +#define IEP_LITE_HS_C11C12_HS_C12_MASK 0x07FF0000 +#define IEP_LITE_HS_C11C12_HS_C12_FLAGS REG_VOL +#define IEP_LITE_HS_C11C12_HS_C12_LENGTH 11 + +/* Complete Register Definition */ +#define IEP_LITE_HS_C11C12_REG_OFFSET IEP_LITE_HS_C11C12_OFFSET +#define IEP_LITE_HS_C11C12_REG_SHIFT 0 +#define IEP_LITE_HS_C11C12_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_C11C12_REG_FLAGS REG_VOL +#define IEP_LITE_HS_C11C12_REG_LENGTH 32 + + +/* -------------------- Register HS_C13C21 -------------------- */ + +#define IEP_LITE_HS_C13C21_OFFSET 0x2004 + +/* Field HS_C13 */ +#define IEP_LITE_HS_C13C21_HS_C13_OFFSET IEP_LITE_HS_C13C21_OFFSET +#define IEP_LITE_HS_C13C21_HS_C13_SHIFT 0 +#define IEP_LITE_HS_C13C21_HS_C13_MASK 0x000007FF +#define IEP_LITE_HS_C13C21_HS_C13_FLAGS REG_VOL +#define IEP_LITE_HS_C13C21_HS_C13_LENGTH 11 + +/* Field HS_C21 */ +#define IEP_LITE_HS_C13C21_HS_C21_OFFSET IEP_LITE_HS_C13C21_OFFSET +#define IEP_LITE_HS_C13C21_HS_C21_SHIFT 16 +#define IEP_LITE_HS_C13C21_HS_C21_MASK 0x07FF0000 +#define IEP_LITE_HS_C13C21_HS_C21_FLAGS REG_VOL +#define IEP_LITE_HS_C13C21_HS_C21_LENGTH 11 + +/* Complete Register Definition */ +#define IEP_LITE_HS_C13C21_REG_OFFSET IEP_LITE_HS_C13C21_OFFSET +#define IEP_LITE_HS_C13C21_REG_SHIFT 0 +#define IEP_LITE_HS_C13C21_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_C13C21_REG_FLAGS REG_VOL +#define IEP_LITE_HS_C13C21_REG_LENGTH 32 + + +/* -------------------- Register HS_C22C23 -------------------- */ + +#define IEP_LITE_HS_C22C23_OFFSET 0x2008 + +/* Field HS_C22 */ +#define IEP_LITE_HS_C22C23_HS_C22_OFFSET IEP_LITE_HS_C22C23_OFFSET +#define IEP_LITE_HS_C22C23_HS_C22_SHIFT 0 +#define IEP_LITE_HS_C22C23_HS_C22_MASK 0x000007FF +#define IEP_LITE_HS_C22C23_HS_C22_FLAGS REG_VOL +#define IEP_LITE_HS_C22C23_HS_C22_LENGTH 11 + +/* Field HS_C23 */ +#define IEP_LITE_HS_C22C23_HS_C23_OFFSET IEP_LITE_HS_C22C23_OFFSET +#define IEP_LITE_HS_C22C23_HS_C23_SHIFT 16 +#define IEP_LITE_HS_C22C23_HS_C23_MASK 0x07FF0000 +#define IEP_LITE_HS_C22C23_HS_C23_FLAGS REG_VOL +#define IEP_LITE_HS_C22C23_HS_C23_LENGTH 11 + +/* Complete Register Definition */ +#define IEP_LITE_HS_C22C23_REG_OFFSET IEP_LITE_HS_C22C23_OFFSET +#define IEP_LITE_HS_C22C23_REG_SHIFT 0 +#define IEP_LITE_HS_C22C23_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_C22C23_REG_FLAGS REG_VOL +#define IEP_LITE_HS_C22C23_REG_LENGTH 32 + + +/* -------------------- Register HS_C31C32 -------------------- */ + +#define IEP_LITE_HS_C31C32_OFFSET 0x200C + +/* Field HS_C31 */ +#define IEP_LITE_HS_C31C32_HS_C31_OFFSET IEP_LITE_HS_C31C32_OFFSET +#define IEP_LITE_HS_C31C32_HS_C31_SHIFT 0 +#define IEP_LITE_HS_C31C32_HS_C31_MASK 0x000007FF +#define IEP_LITE_HS_C31C32_HS_C31_FLAGS REG_VOL +#define IEP_LITE_HS_C31C32_HS_C31_LENGTH 11 + +/* Field HS_C32 */ +#define IEP_LITE_HS_C31C32_HS_C32_OFFSET IEP_LITE_HS_C31C32_OFFSET +#define IEP_LITE_HS_C31C32_HS_C32_SHIFT 16 +#define IEP_LITE_HS_C31C32_HS_C32_MASK 0x07FF0000 +#define IEP_LITE_HS_C31C32_HS_C32_FLAGS REG_VOL +#define IEP_LITE_HS_C31C32_HS_C32_LENGTH 11 + +/* Complete Register Definition */ +#define IEP_LITE_HS_C31C32_REG_OFFSET IEP_LITE_HS_C31C32_OFFSET +#define IEP_LITE_HS_C31C32_REG_SHIFT 0 +#define IEP_LITE_HS_C31C32_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_C31C32_REG_FLAGS REG_VOL +#define IEP_LITE_HS_C31C32_REG_LENGTH 32 + + +/* -------------------- Register HS_C33 -------------------- */ + +#define IEP_LITE_HS_C33_OFFSET 0x2010 + +/* Field HS_C33 */ +#define IEP_LITE_HS_C33_HS_C33_OFFSET IEP_LITE_HS_C33_OFFSET +#define IEP_LITE_HS_C33_HS_C33_SHIFT 0 +#define IEP_LITE_HS_C33_HS_C33_MASK 0x000007FF +#define IEP_LITE_HS_C33_HS_C33_FLAGS REG_VOL +#define IEP_LITE_HS_C33_HS_C33_LENGTH 11 + +/* Complete Register Definition */ +#define IEP_LITE_HS_C33_REG_OFFSET IEP_LITE_HS_C33_OFFSET +#define IEP_LITE_HS_C33_REG_SHIFT 0 +#define IEP_LITE_HS_C33_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_C33_REG_FLAGS REG_VOL +#define IEP_LITE_HS_C33_REG_LENGTH 32 + + +/* -------------------- Register HS_CBOCRO -------------------- */ + +#define IEP_LITE_HS_CBOCRO_OFFSET 0x2014 + +/* Field HS_CRO */ +#define IEP_LITE_HS_CBOCRO_HS_CRO_OFFSET IEP_LITE_HS_CBOCRO_OFFSET +#define IEP_LITE_HS_CBOCRO_HS_CRO_SHIFT 0 +#define IEP_LITE_HS_CBOCRO_HS_CRO_MASK 0x000003FF +#define IEP_LITE_HS_CBOCRO_HS_CRO_FLAGS REG_VOL +#define IEP_LITE_HS_CBOCRO_HS_CRO_LENGTH 10 + +/* Field HS_CBO */ +#define IEP_LITE_HS_CBOCRO_HS_CBO_OFFSET IEP_LITE_HS_CBOCRO_OFFSET +#define IEP_LITE_HS_CBOCRO_HS_CBO_SHIFT 16 +#define IEP_LITE_HS_CBOCRO_HS_CBO_MASK 0x03FF0000 +#define IEP_LITE_HS_CBOCRO_HS_CBO_FLAGS REG_VOL +#define IEP_LITE_HS_CBOCRO_HS_CBO_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_HS_CBOCRO_REG_OFFSET IEP_LITE_HS_CBOCRO_OFFSET +#define IEP_LITE_HS_CBOCRO_REG_SHIFT 0 +#define IEP_LITE_HS_CBOCRO_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_CBOCRO_REG_FLAGS REG_VOL +#define IEP_LITE_HS_CBOCRO_REG_LENGTH 32 + + +/* -------------------- Register HS_YO -------------------- */ + +#define IEP_LITE_HS_YO_OFFSET 0x2018 + +/* Field HS_YO */ +#define IEP_LITE_HS_YO_HS_YO_OFFSET IEP_LITE_HS_YO_OFFSET +#define IEP_LITE_HS_YO_HS_YO_SHIFT 0 +#define IEP_LITE_HS_YO_HS_YO_MASK 0x000003FF +#define IEP_LITE_HS_YO_HS_YO_FLAGS REG_VOL +#define IEP_LITE_HS_YO_HS_YO_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_HS_YO_REG_OFFSET IEP_LITE_HS_YO_OFFSET +#define IEP_LITE_HS_YO_REG_SHIFT 0 +#define IEP_LITE_HS_YO_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_YO_REG_FLAGS REG_VOL +#define IEP_LITE_HS_YO_REG_LENGTH 32 + + +/* -------------------- Register HS_ROGO -------------------- */ + +#define IEP_LITE_HS_ROGO_OFFSET 0x201C + +/* Field HS_RO */ +#define IEP_LITE_HS_ROGO_HS_RO_OFFSET IEP_LITE_HS_ROGO_OFFSET +#define IEP_LITE_HS_ROGO_HS_RO_SHIFT 0 +#define IEP_LITE_HS_ROGO_HS_RO_MASK 0x000003FF +#define IEP_LITE_HS_ROGO_HS_RO_FLAGS REG_VOL +#define IEP_LITE_HS_ROGO_HS_RO_LENGTH 10 + +/* Field HS_GO */ +#define IEP_LITE_HS_ROGO_HS_GO_OFFSET IEP_LITE_HS_ROGO_OFFSET +#define IEP_LITE_HS_ROGO_HS_GO_SHIFT 16 +#define IEP_LITE_HS_ROGO_HS_GO_MASK 0x03FF0000 +#define IEP_LITE_HS_ROGO_HS_GO_FLAGS REG_VOL +#define IEP_LITE_HS_ROGO_HS_GO_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_HS_ROGO_REG_OFFSET IEP_LITE_HS_ROGO_OFFSET +#define IEP_LITE_HS_ROGO_REG_SHIFT 0 +#define IEP_LITE_HS_ROGO_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_ROGO_REG_FLAGS REG_VOL +#define IEP_LITE_HS_ROGO_REG_LENGTH 32 + + +/* -------------------- Register HS_BO -------------------- */ + +#define IEP_LITE_HS_BO_OFFSET 0x2020 + +/* Field HS_BO */ +#define IEP_LITE_HS_BO_HS_BO_OFFSET IEP_LITE_HS_BO_OFFSET +#define IEP_LITE_HS_BO_HS_BO_SHIFT 0 +#define IEP_LITE_HS_BO_HS_BO_MASK 0x000003FF +#define IEP_LITE_HS_BO_HS_BO_FLAGS REG_VOL +#define IEP_LITE_HS_BO_HS_BO_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_HS_BO_REG_OFFSET IEP_LITE_HS_BO_OFFSET +#define IEP_LITE_HS_BO_REG_SHIFT 0 +#define IEP_LITE_HS_BO_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_BO_REG_FLAGS REG_VOL +#define IEP_LITE_HS_BO_REG_LENGTH 32 + + +/* -------------------- Register HS_CONF_STATUS -------------------- */ + +#define IEP_LITE_HS_CONF_STATUS_OFFSET 0x2024 + +/* Field HS_EN */ +#define IEP_LITE_HS_CONF_STATUS_HS_EN_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET +#define IEP_LITE_HS_CONF_STATUS_HS_EN_SHIFT 0 +#define IEP_LITE_HS_CONF_STATUS_HS_EN_MASK 0x00000001 +#define IEP_LITE_HS_CONF_STATUS_HS_EN_FLAGS REG_VOL +#define IEP_LITE_HS_CONF_STATUS_HS_EN_LENGTH 1 + +/* Field HS_RWND */ +#define IEP_LITE_HS_CONF_STATUS_HS_RWND_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET +#define IEP_LITE_HS_CONF_STATUS_HS_RWND_SHIFT 1 +#define IEP_LITE_HS_CONF_STATUS_HS_RWND_MASK 0x00000002 +#define IEP_LITE_HS_CONF_STATUS_HS_RWND_FLAGS REG_VOL +#define IEP_LITE_HS_CONF_STATUS_HS_RWND_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_HS_CONF_STATUS_REG_OFFSET IEP_LITE_HS_CONF_STATUS_OFFSET +#define IEP_LITE_HS_CONF_STATUS_REG_SHIFT 0 +#define IEP_LITE_HS_CONF_STATUS_REG_MASK 0xFFFFFFFF +#define IEP_LITE_HS_CONF_STATUS_REG_FLAGS REG_VOL +#define IEP_LITE_HS_CONF_STATUS_REG_LENGTH 32 + + +/* -------------------- Register BSSCC_CTRL -------------------- */ + +#define IEP_LITE_BSSCC_CTRL_OFFSET 0x1000 + +/* Field BS_EN */ +#define IEP_LITE_BSSCC_CTRL_BS_EN_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET +#define IEP_LITE_BSSCC_CTRL_BS_EN_SHIFT 0 +#define IEP_LITE_BSSCC_CTRL_BS_EN_MASK 0x00000001 +#define IEP_LITE_BSSCC_CTRL_BS_EN_FLAGS REG_VOL +#define IEP_LITE_BSSCC_CTRL_BS_EN_LENGTH 1 + +/* Field SCC_EN */ +#define IEP_LITE_BSSCC_CTRL_SCC_EN_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET +#define IEP_LITE_BSSCC_CTRL_SCC_EN_SHIFT 1 +#define IEP_LITE_BSSCC_CTRL_SCC_EN_MASK 0x00000002 +#define IEP_LITE_BSSCC_CTRL_SCC_EN_FLAGS REG_VOL +#define IEP_LITE_BSSCC_CTRL_SCC_EN_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_BSSCC_CTRL_REG_OFFSET IEP_LITE_BSSCC_CTRL_OFFSET +#define IEP_LITE_BSSCC_CTRL_REG_SHIFT 0 +#define IEP_LITE_BSSCC_CTRL_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BSSCC_CTRL_REG_FLAGS REG_VOL +#define IEP_LITE_BSSCC_CTRL_REG_LENGTH 32 + + +/* -------------------- Register BS_CHROMA_RADIUS -------------------- */ + +#define IEP_LITE_BS_CHROMA_RADIUS_OFFSET 0x1004 + +/* Field R3 */ +#define IEP_LITE_BS_CHROMA_RADIUS_R3_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET +#define IEP_LITE_BS_CHROMA_RADIUS_R3_SHIFT 0 +#define IEP_LITE_BS_CHROMA_RADIUS_R3_MASK 0x000003FF +#define IEP_LITE_BS_CHROMA_RADIUS_R3_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_RADIUS_R3_LENGTH 10 + +/* Field R4 */ +#define IEP_LITE_BS_CHROMA_RADIUS_R4_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET +#define IEP_LITE_BS_CHROMA_RADIUS_R4_SHIFT 16 +#define IEP_LITE_BS_CHROMA_RADIUS_R4_MASK 0x03FF0000 +#define IEP_LITE_BS_CHROMA_RADIUS_R4_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_RADIUS_R4_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BS_CHROMA_RADIUS_REG_OFFSET IEP_LITE_BS_CHROMA_RADIUS_OFFSET +#define IEP_LITE_BS_CHROMA_RADIUS_REG_SHIFT 0 +#define IEP_LITE_BS_CHROMA_RADIUS_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BS_CHROMA_RADIUS_REG_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_RADIUS_REG_LENGTH 32 + + +/* -------------------- Register BS_CHROMA_ANGLE -------------------- */ + +#define IEP_LITE_BS_CHROMA_ANGLE_OFFSET 0x1008 + +/* Field THETA3 */ +#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET +#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_SHIFT 0 +#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_MASK 0x000003FF +#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_ANGLE_THETA3_LENGTH 10 + +/* Field THETA4 */ +#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET +#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_SHIFT 16 +#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_MASK 0x03FF0000 +#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_ANGLE_THETA4_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BS_CHROMA_ANGLE_REG_OFFSET IEP_LITE_BS_CHROMA_ANGLE_OFFSET +#define IEP_LITE_BS_CHROMA_ANGLE_REG_SHIFT 0 +#define IEP_LITE_BS_CHROMA_ANGLE_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BS_CHROMA_ANGLE_REG_FLAGS REG_VOL +#define IEP_LITE_BS_CHROMA_ANGLE_REG_LENGTH 32 + + +/* -------------------- Register BS_LUMA -------------------- */ + +#define IEP_LITE_BS_LUMA_OFFSET 0x100C + +/* Field YMIN */ +#define IEP_LITE_BS_LUMA_YMIN_OFFSET IEP_LITE_BS_LUMA_OFFSET +#define IEP_LITE_BS_LUMA_YMIN_SHIFT 0 +#define IEP_LITE_BS_LUMA_YMIN_MASK 0x000003FF +#define IEP_LITE_BS_LUMA_YMIN_FLAGS REG_VOL +#define IEP_LITE_BS_LUMA_YMIN_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BS_LUMA_REG_OFFSET IEP_LITE_BS_LUMA_OFFSET +#define IEP_LITE_BS_LUMA_REG_SHIFT 0 +#define IEP_LITE_BS_LUMA_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BS_LUMA_REG_FLAGS REG_VOL +#define IEP_LITE_BS_LUMA_REG_LENGTH 32 + + +/* -------------------- Register BS_CORR -------------------- */ + +#define IEP_LITE_BS_CORR_OFFSET 0x1010 + +/* Field OFFSET */ +#define IEP_LITE_BS_CORR_OFFST_OFFSET IEP_LITE_BS_CORR_OFFSET +#define IEP_LITE_BS_CORR_OFFST_SHIFT 0 +#define IEP_LITE_BS_CORR_OFFST_MASK 0x000003FF +#define IEP_LITE_BS_CORR_OFFST_FLAGS REG_VOL +#define IEP_LITE_BS_CORR_OFFST_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BS_CORR_REG_OFFSET IEP_LITE_BS_CORR_OFFSET +#define IEP_LITE_BS_CORR_REG_SHIFT 0 +#define IEP_LITE_BS_CORR_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BS_CORR_REG_FLAGS REG_VOL +#define IEP_LITE_BS_CORR_REG_LENGTH 32 + + +/* -------------------- Register SCC_RADIUS -------------------- */ + +#define IEP_LITE_SCC_RADIUS_OFFSET 0x1014 + +/* Field R1 */ +#define IEP_LITE_SCC_RADIUS_R1_OFFSET IEP_LITE_SCC_RADIUS_OFFSET +#define IEP_LITE_SCC_RADIUS_R1_SHIFT 0 +#define IEP_LITE_SCC_RADIUS_R1_MASK 0x000003FF +#define IEP_LITE_SCC_RADIUS_R1_FLAGS REG_VOL +#define IEP_LITE_SCC_RADIUS_R1_LENGTH 10 + +/* Field R2 */ +#define IEP_LITE_SCC_RADIUS_R2_OFFSET IEP_LITE_SCC_RADIUS_OFFSET +#define IEP_LITE_SCC_RADIUS_R2_SHIFT 16 +#define IEP_LITE_SCC_RADIUS_R2_MASK 0x03FF0000 +#define IEP_LITE_SCC_RADIUS_R2_FLAGS REG_VOL +#define IEP_LITE_SCC_RADIUS_R2_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_SCC_RADIUS_REG_OFFSET IEP_LITE_SCC_RADIUS_OFFSET +#define IEP_LITE_SCC_RADIUS_REG_SHIFT 0 +#define IEP_LITE_SCC_RADIUS_REG_MASK 0xFFFFFFFF +#define IEP_LITE_SCC_RADIUS_REG_FLAGS REG_VOL +#define IEP_LITE_SCC_RADIUS_REG_LENGTH 32 + + +/* -------------------- Register SCC_ANGLE -------------------- */ + +#define IEP_LITE_SCC_ANGLE_OFFSET 0x1018 + +/* Field THETA1 */ +#define IEP_LITE_SCC_ANGLE_THETA1_OFFSET IEP_LITE_SCC_ANGLE_OFFSET +#define IEP_LITE_SCC_ANGLE_THETA1_SHIFT 0 +#define IEP_LITE_SCC_ANGLE_THETA1_MASK 0x000003FF +#define IEP_LITE_SCC_ANGLE_THETA1_FLAGS REG_VOL +#define IEP_LITE_SCC_ANGLE_THETA1_LENGTH 10 + +/* Field THETA2 */ +#define IEP_LITE_SCC_ANGLE_THETA2_OFFSET IEP_LITE_SCC_ANGLE_OFFSET +#define IEP_LITE_SCC_ANGLE_THETA2_SHIFT 16 +#define IEP_LITE_SCC_ANGLE_THETA2_MASK 0x03FF0000 +#define IEP_LITE_SCC_ANGLE_THETA2_FLAGS REG_VOL +#define IEP_LITE_SCC_ANGLE_THETA2_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_SCC_ANGLE_REG_OFFSET IEP_LITE_SCC_ANGLE_OFFSET +#define IEP_LITE_SCC_ANGLE_REG_SHIFT 0 +#define IEP_LITE_SCC_ANGLE_REG_MASK 0xFFFFFFFF +#define IEP_LITE_SCC_ANGLE_REG_FLAGS REG_VOL +#define IEP_LITE_SCC_ANGLE_REG_LENGTH 32 + + +/* -------------------- Register SCC_CORR -------------------- */ + +#define IEP_LITE_SCC_CORR_OFFSET 0x101C + +/* Field GAIN */ +#define IEP_LITE_SCC_CORR_GAIN_OFFSET IEP_LITE_SCC_CORR_OFFSET +#define IEP_LITE_SCC_CORR_GAIN_SHIFT 0 +#define IEP_LITE_SCC_CORR_GAIN_MASK 0x000003FF +#define IEP_LITE_SCC_CORR_GAIN_FLAGS REG_VOL +#define IEP_LITE_SCC_CORR_GAIN_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_SCC_CORR_REG_OFFSET IEP_LITE_SCC_CORR_OFFSET +#define IEP_LITE_SCC_CORR_REG_SHIFT 0 +#define IEP_LITE_SCC_CORR_REG_MASK 0xFFFFFFFF +#define IEP_LITE_SCC_CORR_REG_FLAGS REG_VOL +#define IEP_LITE_SCC_CORR_REG_LENGTH 32 + + +/* -------------------- Register BLE_LUT_TABLE -------------------- */ + +#define IEP_LITE_BLE_LUT_TABLE_OFFSET 0x0000 + +/* Field ble_lut(2*n) */ +#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET +#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_SHIFT 0 +#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_MASK 0x000003FF +#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_FLAGS REG_VOL +#define IEP_LITE_BLE_LUT_TABLE_LOW_ENTRY_LENGTH 10 + +/* Field ble_lut(2*n+1) */ +#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET +#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_SHIFT 16 +#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_MASK 0x03FF0000 +#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_FLAGS REG_VOL +#define IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BLE_LUT_REG_OFFSET IEP_LITE_BLE_LUT_TABLE_OFFSET +#define IEP_LITE_BLE_LUT_REG_SHIFT 0 +#define IEP_LITE_BLE_LUT_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BLE_LUT_REG_FLAGS REG_VOL +#define IEP_LITE_BLE_LUT_REG_LENGTH 32 + + +/* -------------------- Register BLE_CONF_STATUS -------------------- */ + +#define IEP_LITE_BLE_CONF_STATUS_OFFSET 0x0800 + +/* Field BLE_EN */ +#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET +#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_SHIFT 0 +#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_MASK 0x00000001 +#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_FLAGS REG_VOL +#define IEP_LITE_BLE_CONF_STATUS_BLE_EN_LENGTH 1 + +/* Field BLE_RWND */ +#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET +#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_SHIFT 1 +#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_MASK 0x00000002 +#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_FLAGS REG_VOL +#define IEP_LITE_BLE_CONF_STATUS_BLE_RWND_LENGTH 1 + +/* Complete Register Definition */ +#define IEP_LITE_BLE_CONF_STATUS_REG_OFFSET IEP_LITE_BLE_CONF_STATUS_OFFSET +#define IEP_LITE_BLE_CONF_STATUS_REG_SHIFT 0 +#define IEP_LITE_BLE_CONF_STATUS_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BLE_CONF_STATUS_REG_FLAGS REG_VOL +#define IEP_LITE_BLE_CONF_STATUS_REG_LENGTH 32 + + +/* -------------------- Register BLE_MAV -------------------- */ + +#define IEP_LITE_BLE_MAV_OFFSET 0x0804 + +/* Field BLE_MAVMIN */ +#define IEP_LITE_BLE_MAV_BLE_MAVMIN_OFFSET IEP_LITE_BLE_MAV_OFFSET +#define IEP_LITE_BLE_MAV_BLE_MAVMIN_SHIFT 0 +#define IEP_LITE_BLE_MAV_BLE_MAVMIN_MASK 0x000003FF +#define IEP_LITE_BLE_MAV_BLE_MAVMIN_FLAGS REG_VOL +#define IEP_LITE_BLE_MAV_BLE_MAVMIN_LENGTH 10 + +/* Field BLE_MAVMAX */ +#define IEP_LITE_BLE_MAV_BLE_MAVMAX_OFFSET IEP_LITE_BLE_MAV_OFFSET +#define IEP_LITE_BLE_MAV_BLE_MAVMAX_SHIFT 16 +#define IEP_LITE_BLE_MAV_BLE_MAVMAX_MASK 0x03FF0000 +#define IEP_LITE_BLE_MAV_BLE_MAVMAX_FLAGS REG_VOL +#define IEP_LITE_BLE_MAV_BLE_MAVMAX_LENGTH 10 + +/* Complete Register Definition */ +#define IEP_LITE_BLE_MAV_REG_OFFSET IEP_LITE_BLE_MAV_OFFSET +#define IEP_LITE_BLE_MAV_REG_SHIFT 0 +#define IEP_LITE_BLE_MAV_REG_MASK 0xFFFFFFFF +#define IEP_LITE_BLE_MAV_REG_FLAGS REG_VOL +#define IEP_LITE_BLE_MAV_REG_LENGTH 32 + +/* ------------------------ End of register definitions ------------------------ */ + +/* +// NUMREG defines the extent of register address space. +*/ + +#define IEP_LITE_NUMREG ((0x0804 >> 2)+1) + +/*-------------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __IEP_LITE_REG_DEFS_H__ */ diff --git a/src/powervr_iep_lite/iep_lite/iep_lite_utils.c b/src/powervr_iep_lite/iep_lite/iep_lite_utils.c index 50879c7..7bcd605 100644 --- a/src/powervr_iep_lite/iep_lite/iep_lite_utils.c +++ b/src/powervr_iep_lite/iep_lite/iep_lite_utils.c @@ -1,333 +1,333 @@ -/********************************************************************************* - ********************************************************************************* - ** - ** Name : iep_lite_utils.c - ** Author : Imagination Technologies - ** - ** Copyright : 2008 by Imagination Technologies Limited. All rights reserved - ** : No part of this software, either material or conceptual - ** : may be copied or distributed, transmitted, transcribed, - ** : stored in a retrieval system or translated into any - ** : human or computer language in any form by any means, - ** : electronic, mechanical, manual or other-wise, or - ** : disclosed to third parties without the express written - ** : permission of Imagination Technologies Limited, Unit 8, - ** : HomePark Industrial Estate, King's Langley, Hertfordshire, - ** : WD4 8LZ, U.K. - ** - ** Description : Contains all general utility functions for iep lite api. - ** - ********************************************************************************* - *********************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -/*-------------------------------------------------------------------------------*/ - -/* - Includes -*/ - -#include -#include -#include - -#include "img_iep_defs.h" -#include "csc2.h" - -#define EXTERNAL -#include "iep_lite_api.h" -#include "iep_lite_reg_defs.h" -#undef EXTERNAL - -#include "iep_lite_utils.h" - -inline void READ_REGISTER(void * p_iep_lite_context,unsigned int reg,unsigned int * pval) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - *pval = *(img_uint32 *)(sIEP_LITE_Context->ui32RegBaseAddr + (img_uint32)reg); - /*fprintf ( stderr, "Reading reg at addr %08x val %08x \n", reg, *pval );*/ -} - -/*! -****************************************************************************** - - @Function iep_lite_RenderCompleteCallback - -******************************************************************************/ - -img_void iep_lite_RenderCompleteCallback (void * p_iep_lite_context) -{ - IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; - img_uint32 ui32MyReg; - - DEBUG_PRINT ( "Entering iep_lite_RenderCompleteCallback\n" ); - if (NULL == sIEP_LITE_Context) - { - return IMG_FAILED; - } - - if (( sIEP_LITE_Context->eBLEBlackMode != IEP_LITE_BLE_OFF ) || - ( sIEP_LITE_Context->eBLEWhiteMode != IEP_LITE_BLE_OFF )) - { - if ( sIEP_LITE_Context->bFirstLUTValuesWritten == IMG_FALSE ) - { - /* The first table must be calculated using fixed values for YMinIn and YMaxIn. */ - /* This is because the BLE hardware will not return meaningful values for these */ - /* until it has been turned on and we can't turn it on without a valid table. */ - /* As such, we use fixed values to approximate a table for the first frame. */ - sIEP_LITE_Context->i32YMinIn = IEP_LITE_BLE_INITIAL_MAVMIN_VALUE; - sIEP_LITE_Context->i32YMaxIn = IEP_LITE_BLE_INITIAL_MAVMAX_VALUE; - } - else - { - /* Back at start of "read vals / calc table / write table" cycle */ - READ_REGISTER ( sIEP_LITE_Context, - IEP_LITE_BLE_MAV_OFFSET, - &ui32MyReg ); - - sIEP_LITE_Context->i32YMinIn = READ_BITFIELD ( IEP_LITE_BLE_MAV_BLE_MAVMIN, ui32MyReg ); - sIEP_LITE_Context->i32YMaxIn = READ_BITFIELD ( IEP_LITE_BLE_MAV_BLE_MAVMAX, ui32MyReg ); - } - - /* The hardware can return unusable values for MinIn and MaxIn for two reasons : */ - /* 1. The read has been performed while the hardware is calculating new values */ - /* (i.e.: mid frame). In this case, both readback values will be zero. */ - /* 2. The read has been performed during the first frame after the hardware has */ - /* been turned on, but before the first readback values have been calculated. */ - /* In this case, the value for MinIn will be greater than the value for MaxIn. */ - /* */ - /* In both cases, we just ignore the read and try again next time. */ - if ( - (( sIEP_LITE_Context->i32YMinIn == 0 ) && - ( sIEP_LITE_Context->i32YMaxIn == 0 )) - || - (( sIEP_LITE_Context->i32YMinIn > sIEP_LITE_Context->i32YMaxIn )) - ) - { - /* Discard values */ - } - else - { - iep_lite_CalculateBLELookUpTable ( sIEP_LITE_Context, - sIEP_LITE_Context->i32YMinIn, - sIEP_LITE_Context->i32YMaxIn ); - - /* All ready for writing to hardware */ - iep_lite_WriteBLELUTToHardware (sIEP_LITE_Context); - } - } - - DEBUG_PRINT ( "Leaving iep_lite_RenderCompleteCallback\n" ); - - return; -} - -/****************************************************************************** - * Function Name: iep_lite_CalculateBLELookUpTable - *****************************************************************************/ -img_void iep_lite_CalculateBLELookUpTable ( IEP_LITE_sContext * sIEP_LITE_Context, - img_int32 i32YMinIn, - img_int32 i32YMaxIn ) -{ - img_uint32 ui32x1; - img_uint32 ui32x2; - img_uint32 ui32x3; - img_uint32 ui32x4; - img_uint32 ui32y1; - img_uint32 ui32y2; - img_uint32 ui32y3; - img_uint32 ui32y4; - img_uint32 ui32lum0; - img_uint32 ui32lum1; - img_uint32 ui32i; - img_uint32 ui32DR; - img_uint32 ui32DB; - img_uint32 ui32DW; - img_uint32 ui32BlackSlope; - img_uint32 ui32WhiteSlope; - img_uint32 ui32CompositeWord = 0; - - img_uint32 ui32resolution = (IEP_LITE_DATA_SIZE_10_BITS + 1); - img_uint32 ui32col_res = IEP_LITE_DATA_SIZE_10_BITS; - - DEBUG_PRINT ( "Entering iep_lite_CalculateBLELookUpTable\n" ); - - ui32DB = asBLEBlackModes [ sIEP_LITE_Context->eBLEBlackMode ].ui32D; - ui32DW = asBLEWhiteModes [ sIEP_LITE_Context->eBLEWhiteMode ].ui32D; - ui32BlackSlope = asBLEBlackModes [ sIEP_LITE_Context->eBLEBlackMode ].ui32Slope; - ui32WhiteSlope = asBLEWhiteModes [ sIEP_LITE_Context->eBLEWhiteMode ].ui32Slope; - - ui32DR = i32YMaxIn - i32YMinIn; - - ui32lum0 = i32YMinIn + ((ui32DB * ui32DR)>>(IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR)); - ui32lum1 = i32YMaxIn - ((ui32DW * ui32DR)>>(IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR)); - - ui32x1 = (ui32lum0 - (ui32lum0 * ui32BlackSlope>>IEP_LITE_BLE_RES_PAR)); - ui32y1 = 0; - ui32x2 = ui32lum0; - ui32y2 = ui32lum0; - ui32x3 = ui32lum1; - ui32y3 = ui32lum1; - ui32x4 = (ui32lum1 + ((ui32col_res - ui32lum1) * ui32WhiteSlope>>IEP_LITE_BLE_RES_PAR)); - ui32y4 = ui32col_res; - - /* initialization (we see black pixels if the resolution is not dense enough) */ - IMG_MEMSET (sIEP_LITE_Context->aui32BLELUT, 0, sizeof(img_uint32)*(ui32resolution)); - /*----------------------------------------------------------------------------*/ - for(ui32i = ui32x4; ui32i < ui32resolution; ui32i++) - { - sIEP_LITE_Context->aui32BLELUT [ui32i] = IEP_LITE_DATA_SIZE_10_BITS; - } - - sIEP_LITE_Context->aui32BLELUT [ui32x1] = ui32y1; - sIEP_LITE_Context->aui32BLELUT [ui32x2] = ui32y2; - sIEP_LITE_Context->aui32BLELUT [ui32x3] = ui32y3; - sIEP_LITE_Context->aui32BLELUT [ui32x4] = ui32y4; - - iep_lite_BLERecursiveLUTCalculation ( sIEP_LITE_Context, - ui32x1, - sIEP_LITE_Context->aui32BLELUT[ui32x1], - ui32x2, - sIEP_LITE_Context->aui32BLELUT[ui32x2], - ui32x3, - sIEP_LITE_Context->aui32BLELUT[ui32x3], - ui32x4, - sIEP_LITE_Context->aui32BLELUT[ui32x4] ); - - /* Compress table */ - for(ui32i=0; ui32iaui32BLELUT [ ui32i ], - ui32CompositeWord ); - - WRITE_BITFIELD ( IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY, - sIEP_LITE_Context->aui32BLELUT [ (ui32i+1) ], - ui32CompositeWord ); - - sIEP_LITE_Context->aui32BLELUT [ ui32i ] = ui32CompositeWord; - } - - DEBUG_PRINT ( "Leaving iep_lite_CalculateBLELookUpTable\n" ); -} - -/****************************************************************************** - * Function Name: iep_lite_BLERecursiveLUTCalculation - *****************************************************************************/ -img_void iep_lite_BLERecursiveLUTCalculation ( IEP_LITE_sContext * sIEP_LITE_Context, img_int32 i32x1, img_int32 i32y1, img_int32 i32x2, img_int32 i32y2, img_int32 i32x3, img_int32 i32y3, img_int32 i32x4, img_int32 i32y4 ) -{ - img_uint32 ui32id1; - img_uint32 ui32id2; - img_uint32 ui32id3; - img_uint32 ui32id4; - img_uint32 ui32id5; - img_uint32 ui32id6; - img_uint32 ui32id7; - img_uint32 ui32id8; - - DEBUG_PRINT ( "Entering iep_lite_BLERecursiveLUTCalculation\n" ); - - if( - i32x2 - i32x1 <= 1 && - i32x3 - i32x2 <= 1 && - i32x4 - i32x3 <= 1 - ) - { - return; - } - else - { - ui32id1 = i32x1; - ui32id2 = (i32x1 + i32x2) >> 1; - ui32id3 = (ui32id2 >> 1) + ((i32x2 + i32x3) >> 2); - ui32id7 = (i32x3 + i32x4) >> 1; - ui32id8 = i32x4; - ui32id6 = ((i32x2 + i32x3) >> 2) + (ui32id7 >> 1); - ui32id4 = ui32id5 = ((ui32id3 + ui32id6) >> 1); - - sIEP_LITE_Context->aui32BLELUT[ui32id1] = i32y1; - sIEP_LITE_Context->aui32BLELUT[ui32id2] = (i32y1 + i32y2) >> 1; - sIEP_LITE_Context->aui32BLELUT[ui32id3] = (sIEP_LITE_Context->aui32BLELUT[ui32id2] >> 1) + ((i32y2 + i32y3) >> 2); - sIEP_LITE_Context->aui32BLELUT[ui32id7] = (i32y3 + i32y4) >> 1; - sIEP_LITE_Context->aui32BLELUT[ui32id8] = i32y4; - sIEP_LITE_Context->aui32BLELUT[ui32id6] = ((i32y2 + i32y3) >> 2) + (sIEP_LITE_Context->aui32BLELUT[ui32id7] >> 1); - sIEP_LITE_Context->aui32BLELUT[ui32id4] = sIEP_LITE_Context->aui32BLELUT[ui32id5] = ((sIEP_LITE_Context->aui32BLELUT[ui32id3] + sIEP_LITE_Context->aui32BLELUT[ui32id6]) >> 1); - - iep_lite_BLERecursiveLUTCalculation (sIEP_LITE_Context, ui32id1, sIEP_LITE_Context->aui32BLELUT[ui32id1], ui32id2, sIEP_LITE_Context->aui32BLELUT[ui32id2], ui32id3, sIEP_LITE_Context->aui32BLELUT[ui32id3], ui32id4, sIEP_LITE_Context->aui32BLELUT[ui32id4]); - iep_lite_BLERecursiveLUTCalculation (sIEP_LITE_Context, ui32id5, sIEP_LITE_Context->aui32BLELUT[ui32id5], ui32id6, sIEP_LITE_Context->aui32BLELUT[ui32id6], ui32id7, sIEP_LITE_Context->aui32BLELUT[ui32id7], ui32id8, sIEP_LITE_Context->aui32BLELUT[ui32id8]); - } - - DEBUG_PRINT ( "Leaving iep_lite_BLERecursiveLUTCalculation\n" ); -} - - -/****************************************************************************** - * Function Name: iep_lite_WriteBLELUTToHardware - *****************************************************************************/ - -img_void iep_lite_WriteBLELUTToHardware (IEP_LITE_sContext * sIEP_LITE_Context ) -{ - img_uint32 i; - - DEBUG_PRINT ( "Entering iep_lite_WriteBLELUTToHardware\n" ); - - for(i=0; iaui32BLELUT [ i ] ); - } - - if ( sIEP_LITE_Context->bFirstLUTValuesWritten == IMG_FALSE ) - { - /* Turn BLE on */ - WRITE_REGISTER ( IEP_LITE_BLE_CONF_STATUS_OFFSET, - IEP_LITE_BLE_CONF_STATUS_BLE_EN_MASK ); - - sIEP_LITE_Context->bFirstLUTValuesWritten = IMG_TRUE; - } - - DEBUG_PRINT ( "Leaving iep_lite_WriteBLELUTToHardware\n" ); -} - -/*! -****************************************************************************** - - @Function iep_lite_StaticDataSafetyCheck - -******************************************************************************/ - -img_void iep_lite_StaticDataSafetyCheck ( img_void ) -{ - img_uint32 ui32i; - - DEBUG_PRINT ( "Entering iep_lite_StaticDataSafetyCheck\n" ); - - /* asBLEBlackModes */ - for ( ui32i=0; ui32i +#include +#include + +#include "img_iep_defs.h" +#include "csc2.h" + +#define EXTERNAL +#include "iep_lite_api.h" +#include "iep_lite_reg_defs.h" +#undef EXTERNAL + +#include "iep_lite_utils.h" + +inline void READ_REGISTER(void * p_iep_lite_context,unsigned int reg,unsigned int * pval) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + *pval = *(img_uint32 *)(sIEP_LITE_Context->ui32RegBaseAddr + (img_uint32)reg); + /*fprintf ( stderr, "Reading reg at addr %08x val %08x \n", reg, *pval );*/ +} + +/*! +****************************************************************************** + + @Function iep_lite_RenderCompleteCallback + +******************************************************************************/ + +img_void iep_lite_RenderCompleteCallback (void * p_iep_lite_context) +{ + IEP_LITE_sContext * sIEP_LITE_Context = p_iep_lite_context; + img_uint32 ui32MyReg; + + DEBUG_PRINT ( "Entering iep_lite_RenderCompleteCallback\n" ); + if (NULL == sIEP_LITE_Context) + { + return; + } + + if (( sIEP_LITE_Context->eBLEBlackMode != IEP_LITE_BLE_OFF ) || + ( sIEP_LITE_Context->eBLEWhiteMode != IEP_LITE_BLE_OFF )) + { + if ( sIEP_LITE_Context->bFirstLUTValuesWritten == IMG_FALSE ) + { + /* The first table must be calculated using fixed values for YMinIn and YMaxIn. */ + /* This is because the BLE hardware will not return meaningful values for these */ + /* until it has been turned on and we can't turn it on without a valid table. */ + /* As such, we use fixed values to approximate a table for the first frame. */ + sIEP_LITE_Context->i32YMinIn = IEP_LITE_BLE_INITIAL_MAVMIN_VALUE; + sIEP_LITE_Context->i32YMaxIn = IEP_LITE_BLE_INITIAL_MAVMAX_VALUE; + } + else + { + /* Back at start of "read vals / calc table / write table" cycle */ + READ_REGISTER ( sIEP_LITE_Context, + IEP_LITE_BLE_MAV_OFFSET, + &ui32MyReg ); + + sIEP_LITE_Context->i32YMinIn = READ_BITFIELD ( IEP_LITE_BLE_MAV_BLE_MAVMIN, ui32MyReg ); + sIEP_LITE_Context->i32YMaxIn = READ_BITFIELD ( IEP_LITE_BLE_MAV_BLE_MAVMAX, ui32MyReg ); + } + + /* The hardware can return unusable values for MinIn and MaxIn for two reasons : */ + /* 1. The read has been performed while the hardware is calculating new values */ + /* (i.e.: mid frame). In this case, both readback values will be zero. */ + /* 2. The read has been performed during the first frame after the hardware has */ + /* been turned on, but before the first readback values have been calculated. */ + /* In this case, the value for MinIn will be greater than the value for MaxIn. */ + /* */ + /* In both cases, we just ignore the read and try again next time. */ + if ( + (( sIEP_LITE_Context->i32YMinIn == 0 ) && + ( sIEP_LITE_Context->i32YMaxIn == 0 )) + || + (( sIEP_LITE_Context->i32YMinIn > sIEP_LITE_Context->i32YMaxIn )) + ) + { + /* Discard values */ + } + else + { + iep_lite_CalculateBLELookUpTable ( sIEP_LITE_Context, + sIEP_LITE_Context->i32YMinIn, + sIEP_LITE_Context->i32YMaxIn ); + + /* All ready for writing to hardware */ + iep_lite_WriteBLELUTToHardware (sIEP_LITE_Context); + } + } + + DEBUG_PRINT ( "Leaving iep_lite_RenderCompleteCallback\n" ); + + return; +} + +/****************************************************************************** + * Function Name: iep_lite_CalculateBLELookUpTable + *****************************************************************************/ +img_void iep_lite_CalculateBLELookUpTable ( IEP_LITE_sContext * sIEP_LITE_Context, + img_int32 i32YMinIn, + img_int32 i32YMaxIn ) +{ + img_uint32 ui32x1; + img_uint32 ui32x2; + img_uint32 ui32x3; + img_uint32 ui32x4; + img_uint32 ui32y1; + img_uint32 ui32y2; + img_uint32 ui32y3; + img_uint32 ui32y4; + img_uint32 ui32lum0; + img_uint32 ui32lum1; + img_uint32 ui32i; + img_uint32 ui32DR; + img_uint32 ui32DB; + img_uint32 ui32DW; + img_uint32 ui32BlackSlope; + img_uint32 ui32WhiteSlope; + img_uint32 ui32CompositeWord = 0; + + img_uint32 ui32resolution = (IEP_LITE_DATA_SIZE_10_BITS + 1); + img_uint32 ui32col_res = IEP_LITE_DATA_SIZE_10_BITS; + + DEBUG_PRINT ( "Entering iep_lite_CalculateBLELookUpTable\n" ); + + ui32DB = asBLEBlackModes [ sIEP_LITE_Context->eBLEBlackMode ].ui32D; + ui32DW = asBLEWhiteModes [ sIEP_LITE_Context->eBLEWhiteMode ].ui32D; + ui32BlackSlope = asBLEBlackModes [ sIEP_LITE_Context->eBLEBlackMode ].ui32Slope; + ui32WhiteSlope = asBLEWhiteModes [ sIEP_LITE_Context->eBLEWhiteMode ].ui32Slope; + + ui32DR = i32YMaxIn - i32YMinIn; + + ui32lum0 = i32YMinIn + ((ui32DB * ui32DR)>>(IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR)); + ui32lum1 = i32YMaxIn - ((ui32DW * ui32DR)>>(IEP_LITE_BLE_RES_PAR + IEP_LITE_BLE_RES_PAR_CORR)); + + ui32x1 = (ui32lum0 - (ui32lum0 * ui32BlackSlope>>IEP_LITE_BLE_RES_PAR)); + ui32y1 = 0; + ui32x2 = ui32lum0; + ui32y2 = ui32lum0; + ui32x3 = ui32lum1; + ui32y3 = ui32lum1; + ui32x4 = (ui32lum1 + ((ui32col_res - ui32lum1) * ui32WhiteSlope>>IEP_LITE_BLE_RES_PAR)); + ui32y4 = ui32col_res; + + /* initialization (we see black pixels if the resolution is not dense enough) */ + IMG_MEMSET (sIEP_LITE_Context->aui32BLELUT, 0, sizeof(img_uint32)*(ui32resolution)); + /*----------------------------------------------------------------------------*/ + for(ui32i = ui32x4; ui32i < ui32resolution; ui32i++) + { + sIEP_LITE_Context->aui32BLELUT [ui32i] = IEP_LITE_DATA_SIZE_10_BITS; + } + + sIEP_LITE_Context->aui32BLELUT [ui32x1] = ui32y1; + sIEP_LITE_Context->aui32BLELUT [ui32x2] = ui32y2; + sIEP_LITE_Context->aui32BLELUT [ui32x3] = ui32y3; + sIEP_LITE_Context->aui32BLELUT [ui32x4] = ui32y4; + + iep_lite_BLERecursiveLUTCalculation ( sIEP_LITE_Context, + ui32x1, + sIEP_LITE_Context->aui32BLELUT[ui32x1], + ui32x2, + sIEP_LITE_Context->aui32BLELUT[ui32x2], + ui32x3, + sIEP_LITE_Context->aui32BLELUT[ui32x3], + ui32x4, + sIEP_LITE_Context->aui32BLELUT[ui32x4] ); + + /* Compress table */ + for(ui32i=0; ui32iaui32BLELUT [ ui32i ], + ui32CompositeWord ); + + WRITE_BITFIELD ( IEP_LITE_BLE_LUT_TABLE_HIGH_ENTRY, + sIEP_LITE_Context->aui32BLELUT [ (ui32i+1) ], + ui32CompositeWord ); + + sIEP_LITE_Context->aui32BLELUT [ ui32i ] = ui32CompositeWord; + } + + DEBUG_PRINT ( "Leaving iep_lite_CalculateBLELookUpTable\n" ); +} + +/****************************************************************************** + * Function Name: iep_lite_BLERecursiveLUTCalculation + *****************************************************************************/ +img_void iep_lite_BLERecursiveLUTCalculation ( IEP_LITE_sContext * sIEP_LITE_Context, img_int32 i32x1, img_int32 i32y1, img_int32 i32x2, img_int32 i32y2, img_int32 i32x3, img_int32 i32y3, img_int32 i32x4, img_int32 i32y4 ) +{ + img_uint32 ui32id1; + img_uint32 ui32id2; + img_uint32 ui32id3; + img_uint32 ui32id4; + img_uint32 ui32id5; + img_uint32 ui32id6; + img_uint32 ui32id7; + img_uint32 ui32id8; + + DEBUG_PRINT ( "Entering iep_lite_BLERecursiveLUTCalculation\n" ); + + if( + i32x2 - i32x1 <= 1 && + i32x3 - i32x2 <= 1 && + i32x4 - i32x3 <= 1 + ) + { + return; + } + else + { + ui32id1 = i32x1; + ui32id2 = (i32x1 + i32x2) >> 1; + ui32id3 = (ui32id2 >> 1) + ((i32x2 + i32x3) >> 2); + ui32id7 = (i32x3 + i32x4) >> 1; + ui32id8 = i32x4; + ui32id6 = ((i32x2 + i32x3) >> 2) + (ui32id7 >> 1); + ui32id4 = ui32id5 = ((ui32id3 + ui32id6) >> 1); + + sIEP_LITE_Context->aui32BLELUT[ui32id1] = i32y1; + sIEP_LITE_Context->aui32BLELUT[ui32id2] = (i32y1 + i32y2) >> 1; + sIEP_LITE_Context->aui32BLELUT[ui32id3] = (sIEP_LITE_Context->aui32BLELUT[ui32id2] >> 1) + ((i32y2 + i32y3) >> 2); + sIEP_LITE_Context->aui32BLELUT[ui32id7] = (i32y3 + i32y4) >> 1; + sIEP_LITE_Context->aui32BLELUT[ui32id8] = i32y4; + sIEP_LITE_Context->aui32BLELUT[ui32id6] = ((i32y2 + i32y3) >> 2) + (sIEP_LITE_Context->aui32BLELUT[ui32id7] >> 1); + sIEP_LITE_Context->aui32BLELUT[ui32id4] = sIEP_LITE_Context->aui32BLELUT[ui32id5] = ((sIEP_LITE_Context->aui32BLELUT[ui32id3] + sIEP_LITE_Context->aui32BLELUT[ui32id6]) >> 1); + + iep_lite_BLERecursiveLUTCalculation (sIEP_LITE_Context, ui32id1, sIEP_LITE_Context->aui32BLELUT[ui32id1], ui32id2, sIEP_LITE_Context->aui32BLELUT[ui32id2], ui32id3, sIEP_LITE_Context->aui32BLELUT[ui32id3], ui32id4, sIEP_LITE_Context->aui32BLELUT[ui32id4]); + iep_lite_BLERecursiveLUTCalculation (sIEP_LITE_Context, ui32id5, sIEP_LITE_Context->aui32BLELUT[ui32id5], ui32id6, sIEP_LITE_Context->aui32BLELUT[ui32id6], ui32id7, sIEP_LITE_Context->aui32BLELUT[ui32id7], ui32id8, sIEP_LITE_Context->aui32BLELUT[ui32id8]); + } + + DEBUG_PRINT ( "Leaving iep_lite_BLERecursiveLUTCalculation\n" ); +} + + +/****************************************************************************** + * Function Name: iep_lite_WriteBLELUTToHardware + *****************************************************************************/ + +img_void iep_lite_WriteBLELUTToHardware (IEP_LITE_sContext * sIEP_LITE_Context ) +{ + img_uint32 i; + + DEBUG_PRINT ( "Entering iep_lite_WriteBLELUTToHardware\n" ); + + for(i=0; iaui32BLELUT [ i ] ); + } + + if ( sIEP_LITE_Context->bFirstLUTValuesWritten == IMG_FALSE ) + { + /* Turn BLE on */ + WRITE_REGISTER ( IEP_LITE_BLE_CONF_STATUS_OFFSET, + IEP_LITE_BLE_CONF_STATUS_BLE_EN_MASK ); + + sIEP_LITE_Context->bFirstLUTValuesWritten = IMG_TRUE; + } + + DEBUG_PRINT ( "Leaving iep_lite_WriteBLELUTToHardware\n" ); +} + +/*! +****************************************************************************** + + @Function iep_lite_StaticDataSafetyCheck + +******************************************************************************/ + +img_void iep_lite_StaticDataSafetyCheck ( img_void ) +{ + img_uint32 ui32i; + + DEBUG_PRINT ( "Entering iep_lite_StaticDataSafetyCheck\n" ); + + /* asBLEBlackModes */ + for ( ui32i=0; ui32iui32RegBaseAddr + (img_uint32)reg) = val; \ -} - -inline void READ_REGISTER(void * p_iep_lite_context, unsigned int reg,unsigned int * pval); -/************************************************************************************************************/ - -#define READ_BITFIELD(field,regval) \ - ((regval & field##_MASK) >> field##_SHIFT) - -#define WRITE_BITFIELD(field,val,reg) \ -{ \ - (reg) = \ - ((reg) & ~(field##_MASK)) | \ - (((IMG_UINT32) (val) << (field##_SHIFT)) & (field##_MASK)); \ -} - -#define IEP_LITE_DATA_SIZE_10_BITS 0x000003FF -#define IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES 1024 -#define IEP_LITE_BLE_RES_PAR 10 -#define IEP_LITE_BLE_RES_PAR_CORR 3 -#define IEP_LITE_BLE_INITIAL_MAVMIN_VALUE 0 -#define IEP_LITE_BLE_INITIAL_MAVMAX_VALUE ((1 << IEP_LITE_BLE_MAV_BLE_MAVMAX_LENGTH) - 1) - -#define IEP_LITE_BS_R4_DEFAULT_VALUE 0 /* 0 -> 1024 */ -#define IEP_LITE_BS_R3_DEFAULT_VALUE 150 /* 0 -> 1024 */ -#define IEP_LITE_BS_THETA4_DEFAULT_VALUE 25 /* 0 -> 360 */ -#define IEP_LITE_BS_THETA3_DEFAULT_VALUE 170 /* 0 -> 360 */ -#define IEP_LITE_BS_YMIN_DEFAULT_VALUE 0x2D0 /* 0 -> 1024 */ - -#define IEP_LITE_BS_OFFSET_MAX_VALUE ((img_uint32) (0.8f * (1 << 23))) /* 0.23 fixed point format - max val 0.99999 */ - -#define IEP_LITE_SCC_R2_DEFAULT_VALUE 0 /* 0 -> 1024 */ -#define IEP_LITE_SCC_R1_DEFAULT_VALUE 0x3E8 /* 0 -> 1024 */ -#define IEP_LITE_SCC_THETA2_DEFAULT_VALUE 28 /* 0 -> 360 */ -#define IEP_LITE_SCC_THETA1_DEFAULT_VALUE 112 /* 0 -> 360 */ - -#define IEP_LITE_SCC_OFFSET_MAX_VALUE ((img_uint32) (0.5f * (1 << 23))) /* 0.23 fixed point format - max val 0.99999 */ - -#define IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS 7 -#define IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS 1 - -/*-------------------------------------------------------------------------------*/ - -/* - Typedefs -*/ - -typedef struct -{ - IEP_LITE_eBLEMode eSafetyCheck; - - img_uint32 ui32D; - img_uint32 ui32Slope; - -} IEP_LITE_sBLEModeSpecificSettings; - -typedef struct -{ - /************************************************************************************************/ - /* Initialised and configured flags MUST come first in the structure as it is the only part */ - /* of the structure which is initialised statically. */ - img_bool bInitialised; - /************************************************************************************************/ - - /* Blue stretch */ - img_uint8 ui8BSGain; - - /* Skin colour conversion */ - img_uint8 ui8SCCGain; - - /* Black level expander */ - img_bool bFirstLUTValuesWritten; - img_int32 i32YMinIn; - img_int32 i32YMaxIn; - - IEP_LITE_eBLEMode eBLEBlackMode; - IEP_LITE_eBLEMode eBLEWhiteMode; - img_uint32 ui32RegBaseAddr; - img_uint32 aui32BLELUT [ IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES ]; -} IEP_LITE_sContext; -/*-------------------------------------------------------------------------------*/ - -/* - Externs -*/ -#define EXTERNAL -#if defined EXTERNAL -#define EXTERN extern -#define INITIALISE 0 -#else -#define EXTERN -#define INITIALISE 1 -#endif - -#if INITIALISE - IEP_LITE_sContext sIEP_LITE_Context = { IMG_FALSE }; -#else - EXTERN IEP_LITE_sContext sIEP_LITE_Context; -#endif - -/* Non pre-initialised declarations -EXTERN img_uint32 aui32BLELUT [ IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES ]; -*/ -extern const IEP_LITE_sBLEModeSpecificSettings asBLEBlackModes [ IEP_LITE_BLE_NO_OF_MODES ]; -extern const IEP_LITE_sBLEModeSpecificSettings asBLEWhiteModes [ IEP_LITE_BLE_NO_OF_MODES ]; - -#undef EXTERN -#undef INITIALISE - -/*-------------------------------------------------------------------------------*/ - -/* - Function prototypes -*/ - -img_void iep_lite_CalculateBLELookUpTable ( IEP_LITE_sContext * sIEP_LITE_Context, - img_int32 i32YMinIn, - img_int32 i32YMaxIn ); -img_void iep_lite_BLERecursiveLUTCalculation ( IEP_LITE_sContext * sIEP_LITE_Context, - img_int32 i32x1, - img_int32 i32y1, - img_int32 i32x2, - img_int32 i32y2, - img_int32 i32x3, - img_int32 i32y3, - img_int32 i32x4, - img_int32 i32y4 ); -img_void iep_lite_WriteBLELUTToHardware ( IEP_LITE_sContext * sIEP_LITE_Context ); -img_void iep_lite_StaticDataSafetyCheck ( img_void ); - -#endif /* __IEP_LITE_UTILS_H__ */ - -/*--------------------------- End of File --------------------------------*/ +/********************************************************************************* + ********************************************************************************* + ** + ** Author : Imagination Technologies + ** + ** Copyright : 2008 by Imagination Technologies Limited. All rights reserved + ** : No part of this software, either material or conceptual + ** : may be copied or distributed, transmitted, transcribed, + ** : stored in a retrieval system or translated into any + ** : human or computer language in any form by any means, + ** : electronic, mechanical, manual or other-wise, or + ** : disclosed to third parties without the express written + ** : permission of Imagination Technologies Limited, Unit 8, + ** : HomePark Industrial Estate, King's Langley, Hertfordshire, + ** : WD4 8LZ, U.K. + ** + ** Description : This header file contains internal definitions required + ** by the IEP lite API. + ** + ********************************************************************************* + *********************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__IEP_LITE_UTILS_H__) +#define __IEP_LITE_UTILS_H__ + +/************************************************************************************************************/ +/* The following defines should be replaced with real system equivalent - these are placeholders only, and */ +/* provide no actual functionality. */ +#define RENDER_COMPLETE 0 +#define REGISTER_CALLBACK(event_type,pfnCallbackFunction) + +#define WRITE_REGISTER(reg,val) \ +{ \ + /*fprintf ( stderr, "Writing reg at addr %08x : %08x\n", reg, val );*/ \ + *(img_uint32 *)(sIEP_LITE_Context->ui32RegBaseAddr + (img_uint32)reg) = val; \ +} + +inline void READ_REGISTER(void * p_iep_lite_context, unsigned int reg,unsigned int * pval); +/************************************************************************************************************/ + +#define READ_BITFIELD(field,regval) \ + ((regval & field##_MASK) >> field##_SHIFT) + +#define WRITE_BITFIELD(field,val,reg) \ +{ \ + (reg) = \ + ((reg) & ~(field##_MASK)) | \ + (((IMG_UINT32) (val) << (field##_SHIFT)) & (field##_MASK)); \ +} + +#define IEP_LITE_DATA_SIZE_10_BITS 0x000003FF +#define IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES 1024 +#define IEP_LITE_BLE_RES_PAR 10 +#define IEP_LITE_BLE_RES_PAR_CORR 3 +#define IEP_LITE_BLE_INITIAL_MAVMIN_VALUE 0 +#define IEP_LITE_BLE_INITIAL_MAVMAX_VALUE ((1 << IEP_LITE_BLE_MAV_BLE_MAVMAX_LENGTH) - 1) + +#define IEP_LITE_BS_R4_DEFAULT_VALUE 0 /* 0 -> 1024 */ +#define IEP_LITE_BS_R3_DEFAULT_VALUE 150 /* 0 -> 1024 */ +#define IEP_LITE_BS_THETA4_DEFAULT_VALUE 25 /* 0 -> 360 */ +#define IEP_LITE_BS_THETA3_DEFAULT_VALUE 170 /* 0 -> 360 */ +#define IEP_LITE_BS_YMIN_DEFAULT_VALUE 0x2D0 /* 0 -> 1024 */ + +#define IEP_LITE_BS_OFFSET_MAX_VALUE ((img_uint32) (0.8f * (1 << 23))) /* 0.23 fixed point format - max val 0.99999 */ + +#define IEP_LITE_SCC_R2_DEFAULT_VALUE 0 /* 0 -> 1024 */ +#define IEP_LITE_SCC_R1_DEFAULT_VALUE 0x3E8 /* 0 -> 1024 */ +#define IEP_LITE_SCC_THETA2_DEFAULT_VALUE 28 /* 0 -> 360 */ +#define IEP_LITE_SCC_THETA1_DEFAULT_VALUE 112 /* 0 -> 360 */ + +#define IEP_LITE_SCC_OFFSET_MAX_VALUE ((img_uint32) (0.5f * (1 << 23))) /* 0.23 fixed point format - max val 0.99999 */ + +#define IEP_LITE_CSC_FRACTIONAL_BITS_IN_COEFFICIENTS 7 +#define IEP_LITE_CSC_FRACTIONAL_BITS_IN_OUTPUT_OFFSETS 1 + +/*-------------------------------------------------------------------------------*/ + +/* + Typedefs +*/ + +typedef struct +{ + IEP_LITE_eBLEMode eSafetyCheck; + + img_uint32 ui32D; + img_uint32 ui32Slope; + +} IEP_LITE_sBLEModeSpecificSettings; + +typedef struct +{ + /************************************************************************************************/ + /* Initialised and configured flags MUST come first in the structure as it is the only part */ + /* of the structure which is initialised statically. */ + img_bool bInitialised; + /************************************************************************************************/ + + /* Blue stretch */ + img_uint8 ui8BSGain; + + /* Skin colour conversion */ + img_uint8 ui8SCCGain; + + /* Black level expander */ + img_bool bFirstLUTValuesWritten; + img_int32 i32YMinIn; + img_int32 i32YMaxIn; + + IEP_LITE_eBLEMode eBLEBlackMode; + IEP_LITE_eBLEMode eBLEWhiteMode; + img_uint32 ui32RegBaseAddr; + img_uint32 aui32BLELUT [ IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES ]; +} IEP_LITE_sContext; +/*-------------------------------------------------------------------------------*/ + +/* + Externs +*/ +#define EXTERNAL +#if defined EXTERNAL +#define EXTERN extern +#define INITIALISE 0 +#else +#define EXTERN +#define INITIALISE 1 +#endif + +#if INITIALISE + IEP_LITE_sContext sIEP_LITE_Context = { IMG_FALSE }; +#else + EXTERN IEP_LITE_sContext sIEP_LITE_Context; +#endif + +/* Non pre-initialised declarations +EXTERN img_uint32 aui32BLELUT [ IEP_LITE_BLE_LUT_TABLE_SIZE_IN_ENTRIES ]; +*/ +extern const IEP_LITE_sBLEModeSpecificSettings asBLEBlackModes [ IEP_LITE_BLE_NO_OF_MODES ]; +extern const IEP_LITE_sBLEModeSpecificSettings asBLEWhiteModes [ IEP_LITE_BLE_NO_OF_MODES ]; + +#undef EXTERN +#undef INITIALISE + +/*-------------------------------------------------------------------------------*/ + +/* + Function prototypes +*/ + +img_void iep_lite_CalculateBLELookUpTable ( IEP_LITE_sContext * sIEP_LITE_Context, + img_int32 i32YMinIn, + img_int32 i32YMaxIn ); +img_void iep_lite_BLERecursiveLUTCalculation ( IEP_LITE_sContext * sIEP_LITE_Context, + img_int32 i32x1, + img_int32 i32y1, + img_int32 i32x2, + img_int32 i32y2, + img_int32 i32x3, + img_int32 i32y3, + img_int32 i32x4, + img_int32 i32y4 ); +img_void iep_lite_WriteBLELUTToHardware ( IEP_LITE_sContext * sIEP_LITE_Context ); +img_void iep_lite_StaticDataSafetyCheck ( img_void ); + +#endif /* __IEP_LITE_UTILS_H__ */ + +/*--------------------------- End of File --------------------------------*/ diff --git a/src/powervr_iep_lite/iep_lite_demo/iep_lite_demo.c b/src/powervr_iep_lite/iep_lite_demo/iep_lite_demo.c index e9030df..8101937 100644 --- a/src/powervr_iep_lite/iep_lite_demo/iep_lite_demo.c +++ b/src/powervr_iep_lite/iep_lite_demo/iep_lite_demo.c @@ -1,59 +1,59 @@ -#include - -#include "img_defs.h" -#include "csc2.h" -#include "iep_lite_api.h" - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -img_void iep_lite_RenderCompleteCallback ( img_void ); - -int main ( void ) -{ - CSC_sHSBCSettings sHSBCSettings; - - DEBUG_PRINT ( "IEP Lite demo\n" ); - - /* Initialise API */ - IEP_LITE_Initialise (); - - /* Configure BLE module */ - IEP_LITE_BlackLevelExpanderConfigure ( IEP_LITE_BLE_LOW, IEP_LITE_BLE_HIGH ); - - /* Configure blue stretch module */ - IEP_LITE_BlueStretchConfigure ( 200 ); - - /* Configure skin colour correction module */ - IEP_LITE_SkinColourCorrectionConfigure ( 100 ); - - /* Configure colour space converter */ - sHSBCSettings.i32Hue = (img_int32) (5.25f * (1<<25)); - sHSBCSettings.i32Saturation = (img_int32) (1.07f * (1<<25)); - sHSBCSettings.i32Brightness = (img_int32) (-10.1f * (1<<10)); - sHSBCSettings.i32Contrast = (img_int32) (0.99f * (1<<25)); - - IEP_LITE_CSCConfigure ( CSC_COLOURSPACE_YCC_BT601, - CSC_COLOURSPACE_RGB, - &sHSBCSettings ); - - /* The h/w would now be kicked (not shown here) */ - - /* Once the render has completed, the render callback will be invoked */ - /* Simulate this */ - iep_lite_RenderCompleteCallback (); - - DEBUG_PRINT ( "End of demo\n" ); - - fclose ( pfDebugOutput ); - - return 0; +#include + +#include "img_defs.h" +#include "csc2.h" +#include "iep_lite_api.h" + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +img_void iep_lite_RenderCompleteCallback ( img_void ); + +int main ( void ) +{ + CSC_sHSBCSettings sHSBCSettings; + + DEBUG_PRINT ( "IEP Lite demo\n" ); + + /* Initialise API */ + IEP_LITE_Initialise (); + + /* Configure BLE module */ + IEP_LITE_BlackLevelExpanderConfigure ( IEP_LITE_BLE_LOW, IEP_LITE_BLE_HIGH ); + + /* Configure blue stretch module */ + IEP_LITE_BlueStretchConfigure ( 200 ); + + /* Configure skin colour correction module */ + IEP_LITE_SkinColourCorrectionConfigure ( 100 ); + + /* Configure colour space converter */ + sHSBCSettings.i32Hue = (img_int32) (5.25f * (1<<25)); + sHSBCSettings.i32Saturation = (img_int32) (1.07f * (1<<25)); + sHSBCSettings.i32Brightness = (img_int32) (-10.1f * (1<<10)); + sHSBCSettings.i32Contrast = (img_int32) (0.99f * (1<<25)); + + IEP_LITE_CSCConfigure ( CSC_COLOURSPACE_YCC_BT601, + CSC_COLOURSPACE_RGB, + &sHSBCSettings ); + + /* The h/w would now be kicked (not shown here) */ + + /* Once the render has completed, the render callback will be invoked */ + /* Simulate this */ + iep_lite_RenderCompleteCallback (); + + DEBUG_PRINT ( "End of demo\n" ); + + fclose ( pfDebugOutput ); + + return 0; } \ No newline at end of file diff --git a/src/powervr_iep_lite/include/csc2.h b/src/powervr_iep_lite/include/csc2.h index a7a213c..91c06d7 100644 --- a/src/powervr_iep_lite/include/csc2.h +++ b/src/powervr_iep_lite/include/csc2.h @@ -1,118 +1,118 @@ -/*! -****************************************************************************** - @file : csc2.h - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - - -#if !defined (__CSC2_H__) -#define __CSC2_H__ -#if (__cplusplus) -extern "C" { +/*! +****************************************************************************** + @file : csc2.h + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + + +#if !defined (__CSC2_H__) +#define __CSC2_H__ +#if (__cplusplus) +extern "C" { +#endif + +#define CSC_FRACTIONAL_BITS (32-5) /* Final outputs must fit into 4.10, plus we need one bit for sign */ +#define CSC_HSC_FRACTIONAL_BITS 25 /* Bits of fractional data in user specified values for Hue, Saturation and Contrast */ +#define CSC_OUTPUT_OFFSET_FRACTIONAL_BITS 10 /* Bits of fractional data in user specified value for Brightness */ + +/* This enumeration lists all colour spaces supported by the CSC API */ +typedef enum +{ + CSC_COLOURSPACE_YCC_BT601 = 0x00, + CSC_COLOURSPACE_YCC_BT709, + CSC_COLOURSPACE_YCC_SMPTE_240, + CSC_COLOURSPACE_RGB, + + /* Placeholder - do not remove */ + /* Note: This is not a valid colourspace */ + CSC_NO_OF_COLOURSPACES + +} CSC_eColourSpace; + +/* This enumeration lists all supported input and output ranges */ +typedef enum +{ + CSC_RANGE_0_255 = 0x00, + CSC_RANGE_16_235, + CSC_RANGE_48_208, + + /* Placeholder - do not remove */ + /* Note: This is not a valid range */ + CSC_NO_OF_RANGES + +} CSC_eRange; + +/* This enumeration lists all supported colour primaries */ +typedef enum +{ + CSC_COLOUR_PRIMARY_BT709 = 0x00, + CSC_COLOUR_PRIMARY_BT601, + CSC_COLOUR_PRIMARY_BT470_2_SYSBG, + CSC_COLOUR_PRIMARY_BT470_2_SYSM, + + /* Placeholder - do not remove */ + /* Note: This is not a valid colour primary */ + CSC_NO_OF_COLOUR_PRIMARIES + +} CSC_eColourPrimary; + +/* This structure contains settings for Hue, Saturation, Brightness and Contrast (HSBC) */ +typedef struct +{ + img_int32 i32Hue; /* Between -30 and +30 degrees (specified in x.25 signed fixed point format) */ + img_int32 i32Saturation; /* Between 0 and 2 (specified in x.25 signed fixed point format) */ + img_int32 i32Brightness; /* Between -50 and 50 (specified in x.10 signed fixed point format) */ + img_int32 i32Contrast; /* Between 0 and 2 (specified in x.25 signed fixed point format) */ + +} CSC_sHSBCSettings, * CSC_psHSBCSettings; + +typedef struct +{ + img_int32 ai32Coefficients [3][3]; /* Indices are [row][column] */ + +} CSC_s3x3Matrix, * CSC_ps3x3Matrix; + +typedef struct +{ + CSC_s3x3Matrix sCoefficients; + + img_int32 ai32InputOffsets [3]; + img_int32 ai32OutputOffsets [3]; + +} CSC_sConfiguration, * CSC_psConfiguration; + +img_result CSC_GenerateMatrix ( CSC_eColourSpace eInputColourSpace, + CSC_eColourSpace eOutputColourSpace, + CSC_eRange eInputRange, + CSC_eRange eOutputRange, + CSC_eColourPrimary eInputPrimary, + CSC_eColourPrimary eOutputPrimary, + CSC_psHSBCSettings psHSBCSettings, + CSC_psConfiguration psResultantConfigurationData ); + +#if (__cplusplus) +} #endif - -#define CSC_FRACTIONAL_BITS (32-5) /* Final outputs must fit into 4.10, plus we need one bit for sign */ -#define CSC_HSC_FRACTIONAL_BITS 25 /* Bits of fractional data in user specified values for Hue, Saturation and Contrast */ -#define CSC_OUTPUT_OFFSET_FRACTIONAL_BITS 10 /* Bits of fractional data in user specified value for Brightness */ - -/* This enumeration lists all colour spaces supported by the CSC API */ -typedef enum -{ - CSC_COLOURSPACE_YCC_BT601 = 0x00, - CSC_COLOURSPACE_YCC_BT709, - CSC_COLOURSPACE_YCC_SMPTE_240, - CSC_COLOURSPACE_RGB, - - /* Placeholder - do not remove */ - /* Note: This is not a valid colourspace */ - CSC_NO_OF_COLOURSPACES - -} CSC_eColourSpace; - -/* This enumeration lists all supported input and output ranges */ -typedef enum -{ - CSC_RANGE_0_255 = 0x00, - CSC_RANGE_16_235, - CSC_RANGE_48_208, - - /* Placeholder - do not remove */ - /* Note: This is not a valid range */ - CSC_NO_OF_RANGES - -} CSC_eRange; - -/* This enumeration lists all supported colour primaries */ -typedef enum -{ - CSC_COLOUR_PRIMARY_BT709 = 0x00, - CSC_COLOUR_PRIMARY_BT601, - CSC_COLOUR_PRIMARY_BT470_2_SYSBG, - CSC_COLOUR_PRIMARY_BT470_2_SYSM, - - /* Placeholder - do not remove */ - /* Note: This is not a valid colour primary */ - CSC_NO_OF_COLOUR_PRIMARIES - -} CSC_eColourPrimary; - -/* This structure contains settings for Hue, Saturation, Brightness and Contrast (HSBC) */ -typedef struct -{ - img_int32 i32Hue; /* Between -30 and +30 degrees (specified in x.25 signed fixed point format) */ - img_int32 i32Saturation; /* Between 0 and 2 (specified in x.25 signed fixed point format) */ - img_int32 i32Brightness; /* Between -50 and 50 (specified in x.10 signed fixed point format) */ - img_int32 i32Contrast; /* Between 0 and 2 (specified in x.25 signed fixed point format) */ - -} CSC_sHSBCSettings, * CSC_psHSBCSettings; - -typedef struct -{ - img_int32 ai32Coefficients [3][3]; /* Indices are [row][column] */ - -} CSC_s3x3Matrix, * CSC_ps3x3Matrix; - -typedef struct -{ - CSC_s3x3Matrix sCoefficients; - - img_int32 ai32InputOffsets [3]; - img_int32 ai32OutputOffsets [3]; - -} CSC_sConfiguration, * CSC_psConfiguration; - -img_result CSC_GenerateMatrix ( CSC_eColourSpace eInputColourSpace, - CSC_eColourSpace eOutputColourSpace, - CSC_eRange eInputRange, - CSC_eRange eOutputRange, - CSC_eColourPrimary eInputPrimary, - CSC_eColourPrimary eOutputPrimary, - CSC_psHSBCSettings psHSBCSettings, - CSC_psConfiguration psResultantConfigurationData ); - -#if (__cplusplus) -} -#endif -#endif /* __CSC2_H__ */ +#endif /* __CSC2_H__ */ diff --git a/src/powervr_iep_lite/include/fixedpointmaths.h b/src/powervr_iep_lite/include/fixedpointmaths.h index 976d64e..9f2c12f 100644 --- a/src/powervr_iep_lite/include/fixedpointmaths.h +++ b/src/powervr_iep_lite/include/fixedpointmaths.h @@ -1,398 +1,398 @@ -/*! -****************************************************************************** - @file : fixedpointmaths.h - - @brief - - @Author Tom Whalley - - @date 07/01/2005 - - Copyright 2003 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - Fixed point maths utility functions header file - - Platform:\n - Platform Independent - - @Version - - 1.0 1st Release - -******************************************************************************/ - -/* -****************************************************************************** - Modifications :- - - $Log: fixedpointmaths.h,v $ - Revision 1.9 2007/12/13 11:23:40 thw - Added macro 'FIXEDPT_CONVERT_FLOAT_TO_FIXED'. - - Revision 1.8 2007/12/11 15:44:08 thw - Added definition 'FIXEDPT_ONE_DEGREE_IN_RADIANS'. - - Revision 1.7 2007/12/11 14:43:37 thw - Removed hard coded references to number of fractional bits used. - Added 'convert no of fractional bits' macros. - - Revision 1.6 2007/12/10 18:17:58 thw - Added prototype for 'FIXEDPT_Cosine'. - - Revision 1.5 2007/12/10 10:56:36 thw - - Changed name of downshift variable in 'FIXEDPT_64BitDivide' from 'ui32NumIntBitsInResult' to 'ui32PostShiftResult'. - - Added prototype for function 'FIXEDPT_64BitDivide_Signed'. - - Changed prototype for function 'FIXEDPT_ScalarMatrixMultiply' to reflect new operation - now multiplies two matrices (scalar multiply) rather than a single matrix by a single value. - - Revision 1.4 2007/12/06 16:38:36 thw - Added header for new function 'FIXEDPT_ScalarMatrixMultiply'. - - Revision 1.3 2007/12/06 15:55:46 thw - Added headers for new functions 'FIXEDPT_64BitMultiply_Signed' and 'FIXEDPT_MatrixMultiply'. - - Revision 1.2 2007/07/04 10:45:13 thw - Fixed Linux warning. - - Revision 1.1 2005/01/07 11:11:44 thw - New addition - fixed point maths utilities header file - - -******************************************************************************/ - -#if !defined (__FIXEDPOINTMATHS_H__) -#define __FIXEDPOINTMATHS_H__ - -#if (__cplusplus) -extern "C" { -#endif - -/* Macros */ -#define FIXEDPT_CONVERT_FRACTIONAL_BITS(number,from,to) (((from)>(to))?(((number)+((1<<((from)-(to)))>>1))>>((from)-(to))):((number)<<((to)-(from)))) -#define FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(number,from,to) (((from)>(to))?(((number))>>((from)-(to))):((number)<<((to)-(from)))) -#define FIXEDPT_CONVERT_FLOAT_TO_FIXED(float_num,fractional_bits) (((img_float)(float_num)) * (1<<(fractional_bits))) - -/* Constants */ -#define FIXEDPT_SINE_TABLE_FRACTION_SIZE 8 /* Sine table represents values 0->PI/2 in 1.x format */ -#define FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS 29 -#define FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS 30 - -#define FIXEDPT_PI (img_uint32) ((img_float) (3.1415927f) * (1 << FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS)) /* 2.18 fixed point format */ -#define FIXEDPT_NO_OF_SINE_TABLE_ENTRIES (sizeof(FIXEDPT_aui32FixedPointSineTable)/sizeof(img_uint32)) -#define FIXEDPT_DIVISION_PER_SINE_TABLE_ENTRY (FIXEDPT_PI/FIXEDPT_NO_OF_SINE_TABLE_ENTRIES) -#define FIXEDPT_ONE_DEGREE_IN_RADIANS (FIXEDPT_PI/180) - -/* Function prototypes */ - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitMultiply - - @Description This function takes two unsigned 32 bit inputs and - multiplies them together to give a 64 bit result. - It then shifts the result down by a user specified - amount in order to return a 32 bit value. - - @Input ui32X : The first of two unsigned 32 bit values to multiply - together. - - @Input ui32Y : The second of two unsigned 32 bit values to multiply - together. - - @Input ui32PostShiftResult : - The number of bits to right shift the 64 bit result of - the multiplication in order to achieve a 32 bit result. - Note : If the post shift result is not sufficient to - ensure that no data remains in the upper 32 bit word of - the 64 bit result, the function will cause an assert to - indicate that data is being lost. - - @Return img_uint32 : This function returns an unsigned 32 bit value, - which is the downshifted 64 bit result of the - multiplication. - -******************************************************************************/ -/*INLINE*/ img_uint32 FIXEDPT_64BitMultiply ( img_uint32 ui32X, - img_uint32 ui32Y, - img_uint32 ui32PostShiftResult ); - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitDivide - - @Description This function takes two unsigned 32 bit inputs: a - numerator and a denominator. The numerator is promoted - to a 64 bit value before being divided by the - denominator. The result of the division is then - shifted down according to the 'ui32PostShiftResult' - parameter. - - @Input ui32Numerator : - The 32 bit numerator. - - @Input ui32Denominator : - The 32 bit denominator. - - @Input ui32PostShiftResult : - The number of bits to right shift the 64 bit result of - the division in order to achieve a 32 bit result. - Note : If the post shift result is not sufficient to - ensure that no data remains in the upper 32 bit word of - the 64 bit result, the function will cause an assert to - indicate that data is being lost. - - @Return img_uint32 : This function returns an unsigned 32 bit value, - which is the downshifted 64 bit result of the - division. - -******************************************************************************/ -/*INLINE*/ img_uint32 FIXEDPT_64BitDivide ( img_uint32 ui32Numerator, - img_uint32 ui32Denominator, - img_uint32 ui32PostShiftResult ); - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitMultiply_Signed - - @Description This function takes two signed 32 bit inputs and - multiplies them together to give a 64 bit result. - It then shifts the result down by a user specified - amount in order to return a 32 bit value. - - @Input ui32X : The first of two signed 32 bit values to multiply - together. - - @Input ui32Y : The second of two signed 32 bit values to multiply - together. - - @Input ui32PostShiftResult : - The number of bits to right shift the 64 bit result of - the multiplication in order to achieve a 32 bit result. - Note : If the post shift result is not sufficient to - ensure that no data remains in the upper 32 bit word of - the 64 bit result, the function will cause an assert to - indicate that data is being lost. - - @Return img_uint32 : This function returns a signed 32 bit value, - which is the downshifted 64 bit result of the - multiplication. - -******************************************************************************/ -img_int32 FIXEDPT_64BitMultiply_Signed ( img_int32 i32X, - img_int32 i32Y, - img_uint32 ui32PostShiftResult ); - -/*! -****************************************************************************** - - @Function FIXEDPT_64BitDivide_Signed - - @Description This function takes two signed 32 bit inputs: a - numerator and a denominator. The numerator is promoted - to a 64 bit value before being divided by the - denominator. The result of the division is then - shifted down according to the 'ui32PostShiftResult' - parameter. - - @Input i32Numerator : - The 32 bit numerator. - - @Input i32Denominator : - The 32 bit denominator. - - @Input ui32PostShiftResult : - The number of bits to right shift the 64 bit result of - the division in order to achieve a 32 bit result. - Note : If the post shift result is not sufficient to - ensure that no data remains in the upper 32 bit word of - the 64 bit result, the function will cause an assert to - indicate that data is being lost. - - @Return img_int32 : This function returns a signed 32 bit value, - which is the downshifted 64 bit result of the - division. - -******************************************************************************/ - -img_int32 FIXEDPT_64BitDivide_Signed ( img_int32 ui32Numerator, - img_int32 ui32Denominator, - img_uint32 ui32PostShiftResult ); - -/*! -****************************************************************************** - - @Function FIXEDPT_Sine - - @Description This function calculates Sine(Theta) where - both Theta and the result of the Sine function are - specified in fixed point format. - - @Input ui32Theta : The value of Theta for which Sine(Theta) is to be - established. Theta is specified in 3.29 unsigned fixed - point format and must fall in the range 0 -> 2*PI - radians. The number of fractional bits used in the - input to this function (29) is defined by the constant - 'FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS'. - - @Return img_int32 : This function returns a signed 32 bit value, in signed - 1.30 bit fixed point format. The value will be in the - range -1 -> 1. The number of fractional bits used in - the output from this function (30) is defined by the - constant 'FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS'. - -******************************************************************************/ -img_int32 FIXEDPT_Sine ( img_uint32 ui32Theta ); - - -/*! -****************************************************************************** - - @Function FIXEDPT_Cosine - - @Description This function calculates Cosine(Theta) where - both Theta and the result of the Cosine function are - specified in fixed point format. - - @Input ui32Theta : The value of Theta for which Cosine(Theta) is to be - established. Theta is specified in 3.29 unsigned fixed - point format and must fall in the range 0 -> 2*PI - radians. The number of fractional bits used in the - input to this function (29) is defined by the constant - 'FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS'. - - @Return img_int32 : This function returns a signed 32 bit value, in signed - 1.30 bit fixed point format. The value will be in the - range -1 -> 1. The number of fractional bits used in - the output from this function (30) is defined by the - constant 'FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS'. - -******************************************************************************/ -img_int32 FIXEDPT_Cosine ( img_uint32 ui32Theta ); - - -/*! -****************************************************************************** - - @Function FIXEDPT_MatrixMultiply - - @Description This function multiplies two matrices, A and B,to - produce a third matrix; - - @Input ui32MatrixARows : - The number of rows in the first matrix (A) - - @Input ui32MatrixAColumns : - The number of columns in the first matrix (A) - - @Input ui32MatrixBRows : - The number of rows in the second matrix (B) - - @Input ui32MatrixBColumns : - The number of columns in the second matrix (B) - - @Input ui32ui32ResultRows : - The number of rows in the resultant matrix. This - value is provided as a safety check, and must match - the value expected by the function. - - @Input ui32ui32ResultColumns : - The number of columns in the resultant matrix. This - value is provided as a safety check, and must match - the value expected by the function. - - @Input pai32MatrixA : - A pointer to the first matrix, comprising - (Rows(A) x Columns(A)) signed 32 bit values. - - @Input pai32MatrixB : - A pointer to the second matrix, comprising - (Rows(B) x Columns(C)) signed 32 bit values. - - @Input pai32ResultMatrix : - A pointer to the resultant matrix, comprising - (Rows(result) x Columns(result)) signed 32 bit values. - This matrix is overwritten by the function. - - @Input ui32PostShiftResults : - The number of bits to postshift the result of each - multiplication by. This must be set such that the - results do not overflow 32 bits. The function will - assert in the case of an overflow. - - @Return img_void : This function does not return a value - -******************************************************************************/ -img_void FIXEDPT_MatrixMultiply ( img_uint32 ui32MatrixARows, - img_uint32 ui32MatrixAColumns, - img_uint32 ui32MatrixBRows, - img_uint32 ui32MatrixBColumns, - img_uint32 ui32ResultRows, - img_uint32 ui32ResultColumns, - img_int32 * pai32MatrixA, - img_int32 * pai32MatrixB, - img_int32 * pai32ResultMatrix, - img_uint32 ui32PostShiftResults ); - -/*! -****************************************************************************** - - @Function FIXEDPT_ScalarMatrixMultiply - - @Description This function multiplies each value in a matrix, A, by - the corresponding value in a second matrix, B, placing - the results in a third matrix. This is a scalar - multiplication - NOT a matrix multiplication. All - three matrices must be of identical dimensions. - - @Input ui32MatrixRows : - The number of rows in the matrix - - @Input ui32MatrixColumns : - The number of columns in the matrix - - @Input pai32MatrixA : - A pointer to the first matrix, comprising - (Rows x Columns) signed 32 bit values. - - @Input pai32MatrixB : - A pointer to the second matrix, comprising - (Rows x Columns) signed 32 bit values. - - @Input pai32ResultantMatrix : - A pointer to the resultant matrix - this matrix must - occupy a separate area of memory from MatrixA and - MatrixB - it is not valid to use a single matrix - as both input and output from this function. - - @Input ui32PostShiftResults : - The number of bits to postshift the result of each - multiplication by. This must be set such that the - results do not overflow 32 bits. The function will - assert in the case of an overflow. - - @Return img_void : This function does not return a value - -******************************************************************************/ -img_void FIXEDPT_ScalarMatrixMultiply ( img_uint32 ui32MatrixRows, - img_uint32 ui32MatrixColumns, - img_int32 * pai32MatrixA, - img_int32 * pai32MatrixB, - img_int32 * pai32ResultantMatrix, - img_uint32 ui32PostShiftResults ); - -#if (__cplusplus) -} -#endif - -#endif /* __FIXEDPOINTMATHS_H__ */ +/*! +****************************************************************************** + @file : fixedpointmaths.h + + @brief + + @Author Tom Whalley + + @date 07/01/2005 + + Copyright 2003 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + Fixed point maths utility functions header file + + Platform:\n + Platform Independent + + @Version + - 1.0 1st Release + +******************************************************************************/ + +/* +****************************************************************************** + Modifications :- + + $Log: fixedpointmaths.h,v $ + Revision 1.9 2007/12/13 11:23:40 thw + Added macro 'FIXEDPT_CONVERT_FLOAT_TO_FIXED'. + + Revision 1.8 2007/12/11 15:44:08 thw + Added definition 'FIXEDPT_ONE_DEGREE_IN_RADIANS'. + + Revision 1.7 2007/12/11 14:43:37 thw + Removed hard coded references to number of fractional bits used. + Added 'convert no of fractional bits' macros. + + Revision 1.6 2007/12/10 18:17:58 thw + Added prototype for 'FIXEDPT_Cosine'. + + Revision 1.5 2007/12/10 10:56:36 thw + - Changed name of downshift variable in 'FIXEDPT_64BitDivide' from 'ui32NumIntBitsInResult' to 'ui32PostShiftResult'. + - Added prototype for function 'FIXEDPT_64BitDivide_Signed'. + - Changed prototype for function 'FIXEDPT_ScalarMatrixMultiply' to reflect new operation - now multiplies two matrices (scalar multiply) rather than a single matrix by a single value. + + Revision 1.4 2007/12/06 16:38:36 thw + Added header for new function 'FIXEDPT_ScalarMatrixMultiply'. + + Revision 1.3 2007/12/06 15:55:46 thw + Added headers for new functions 'FIXEDPT_64BitMultiply_Signed' and 'FIXEDPT_MatrixMultiply'. + + Revision 1.2 2007/07/04 10:45:13 thw + Fixed Linux warning. + + Revision 1.1 2005/01/07 11:11:44 thw + New addition - fixed point maths utilities header file + + +******************************************************************************/ + +#if !defined (__FIXEDPOINTMATHS_H__) +#define __FIXEDPOINTMATHS_H__ + +#if (__cplusplus) +extern "C" { +#endif + +/* Macros */ +#define FIXEDPT_CONVERT_FRACTIONAL_BITS(number,from,to) (((from)>(to))?(((number)+((1<<((from)-(to)))>>1))>>((from)-(to))):((number)<<((to)-(from)))) +#define FIXEDPT_CONVERT_FRACTIONAL_BITS_NO_ROUNDING(number,from,to) (((from)>(to))?(((number))>>((from)-(to))):((number)<<((to)-(from)))) +#define FIXEDPT_CONVERT_FLOAT_TO_FIXED(float_num,fractional_bits) (((img_float)(float_num)) * (1<<(fractional_bits))) + +/* Constants */ +#define FIXEDPT_SINE_TABLE_FRACTION_SIZE 8 /* Sine table represents values 0->PI/2 in 1.x format */ +#define FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS 29 +#define FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS 30 + +#define FIXEDPT_PI (img_uint32) ((img_float) (3.1415927f) * (1 << FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS)) /* 2.18 fixed point format */ +#define FIXEDPT_NO_OF_SINE_TABLE_ENTRIES (sizeof(FIXEDPT_aui32FixedPointSineTable)/sizeof(img_uint32)) +#define FIXEDPT_DIVISION_PER_SINE_TABLE_ENTRY (FIXEDPT_PI/FIXEDPT_NO_OF_SINE_TABLE_ENTRIES) +#define FIXEDPT_ONE_DEGREE_IN_RADIANS (FIXEDPT_PI/180) + +/* Function prototypes */ + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitMultiply + + @Description This function takes two unsigned 32 bit inputs and + multiplies them together to give a 64 bit result. + It then shifts the result down by a user specified + amount in order to return a 32 bit value. + + @Input ui32X : The first of two unsigned 32 bit values to multiply + together. + + @Input ui32Y : The second of two unsigned 32 bit values to multiply + together. + + @Input ui32PostShiftResult : + The number of bits to right shift the 64 bit result of + the multiplication in order to achieve a 32 bit result. + Note : If the post shift result is not sufficient to + ensure that no data remains in the upper 32 bit word of + the 64 bit result, the function will cause an assert to + indicate that data is being lost. + + @Return img_uint32 : This function returns an unsigned 32 bit value, + which is the downshifted 64 bit result of the + multiplication. + +******************************************************************************/ +/*INLINE*/ img_uint32 FIXEDPT_64BitMultiply ( img_uint32 ui32X, + img_uint32 ui32Y, + img_uint32 ui32PostShiftResult ); + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitDivide + + @Description This function takes two unsigned 32 bit inputs: a + numerator and a denominator. The numerator is promoted + to a 64 bit value before being divided by the + denominator. The result of the division is then + shifted down according to the 'ui32PostShiftResult' + parameter. + + @Input ui32Numerator : + The 32 bit numerator. + + @Input ui32Denominator : + The 32 bit denominator. + + @Input ui32PostShiftResult : + The number of bits to right shift the 64 bit result of + the division in order to achieve a 32 bit result. + Note : If the post shift result is not sufficient to + ensure that no data remains in the upper 32 bit word of + the 64 bit result, the function will cause an assert to + indicate that data is being lost. + + @Return img_uint32 : This function returns an unsigned 32 bit value, + which is the downshifted 64 bit result of the + division. + +******************************************************************************/ +/*INLINE*/ img_uint32 FIXEDPT_64BitDivide ( img_uint32 ui32Numerator, + img_uint32 ui32Denominator, + img_uint32 ui32PostShiftResult ); + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitMultiply_Signed + + @Description This function takes two signed 32 bit inputs and + multiplies them together to give a 64 bit result. + It then shifts the result down by a user specified + amount in order to return a 32 bit value. + + @Input ui32X : The first of two signed 32 bit values to multiply + together. + + @Input ui32Y : The second of two signed 32 bit values to multiply + together. + + @Input ui32PostShiftResult : + The number of bits to right shift the 64 bit result of + the multiplication in order to achieve a 32 bit result. + Note : If the post shift result is not sufficient to + ensure that no data remains in the upper 32 bit word of + the 64 bit result, the function will cause an assert to + indicate that data is being lost. + + @Return img_uint32 : This function returns a signed 32 bit value, + which is the downshifted 64 bit result of the + multiplication. + +******************************************************************************/ +img_int32 FIXEDPT_64BitMultiply_Signed ( img_int32 i32X, + img_int32 i32Y, + img_uint32 ui32PostShiftResult ); + +/*! +****************************************************************************** + + @Function FIXEDPT_64BitDivide_Signed + + @Description This function takes two signed 32 bit inputs: a + numerator and a denominator. The numerator is promoted + to a 64 bit value before being divided by the + denominator. The result of the division is then + shifted down according to the 'ui32PostShiftResult' + parameter. + + @Input i32Numerator : + The 32 bit numerator. + + @Input i32Denominator : + The 32 bit denominator. + + @Input ui32PostShiftResult : + The number of bits to right shift the 64 bit result of + the division in order to achieve a 32 bit result. + Note : If the post shift result is not sufficient to + ensure that no data remains in the upper 32 bit word of + the 64 bit result, the function will cause an assert to + indicate that data is being lost. + + @Return img_int32 : This function returns a signed 32 bit value, + which is the downshifted 64 bit result of the + division. + +******************************************************************************/ + +img_int32 FIXEDPT_64BitDivide_Signed ( img_int32 ui32Numerator, + img_int32 ui32Denominator, + img_uint32 ui32PostShiftResult ); + +/*! +****************************************************************************** + + @Function FIXEDPT_Sine + + @Description This function calculates Sine(Theta) where + both Theta and the result of the Sine function are + specified in fixed point format. + + @Input ui32Theta : The value of Theta for which Sine(Theta) is to be + established. Theta is specified in 3.29 unsigned fixed + point format and must fall in the range 0 -> 2*PI + radians. The number of fractional bits used in the + input to this function (29) is defined by the constant + 'FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS'. + + @Return img_int32 : This function returns a signed 32 bit value, in signed + 1.30 bit fixed point format. The value will be in the + range -1 -> 1. The number of fractional bits used in + the output from this function (30) is defined by the + constant 'FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS'. + +******************************************************************************/ +img_int32 FIXEDPT_Sine ( img_uint32 ui32Theta ); + + +/*! +****************************************************************************** + + @Function FIXEDPT_Cosine + + @Description This function calculates Cosine(Theta) where + both Theta and the result of the Cosine function are + specified in fixed point format. + + @Input ui32Theta : The value of Theta for which Cosine(Theta) is to be + established. Theta is specified in 3.29 unsigned fixed + point format and must fall in the range 0 -> 2*PI + radians. The number of fractional bits used in the + input to this function (29) is defined by the constant + 'FIXEDPT_TRIG_INPUT_FRACTIONAL_BITS'. + + @Return img_int32 : This function returns a signed 32 bit value, in signed + 1.30 bit fixed point format. The value will be in the + range -1 -> 1. The number of fractional bits used in + the output from this function (30) is defined by the + constant 'FIXEDPT_TRIG_OUTPUT_FRACTIONAL_BITS'. + +******************************************************************************/ +img_int32 FIXEDPT_Cosine ( img_uint32 ui32Theta ); + + +/*! +****************************************************************************** + + @Function FIXEDPT_MatrixMultiply + + @Description This function multiplies two matrices, A and B,to + produce a third matrix; + + @Input ui32MatrixARows : + The number of rows in the first matrix (A) + + @Input ui32MatrixAColumns : + The number of columns in the first matrix (A) + + @Input ui32MatrixBRows : + The number of rows in the second matrix (B) + + @Input ui32MatrixBColumns : + The number of columns in the second matrix (B) + + @Input ui32ui32ResultRows : + The number of rows in the resultant matrix. This + value is provided as a safety check, and must match + the value expected by the function. + + @Input ui32ui32ResultColumns : + The number of columns in the resultant matrix. This + value is provided as a safety check, and must match + the value expected by the function. + + @Input pai32MatrixA : + A pointer to the first matrix, comprising + (Rows(A) x Columns(A)) signed 32 bit values. + + @Input pai32MatrixB : + A pointer to the second matrix, comprising + (Rows(B) x Columns(C)) signed 32 bit values. + + @Input pai32ResultMatrix : + A pointer to the resultant matrix, comprising + (Rows(result) x Columns(result)) signed 32 bit values. + This matrix is overwritten by the function. + + @Input ui32PostShiftResults : + The number of bits to postshift the result of each + multiplication by. This must be set such that the + results do not overflow 32 bits. The function will + assert in the case of an overflow. + + @Return img_void : This function does not return a value + +******************************************************************************/ +img_void FIXEDPT_MatrixMultiply ( img_uint32 ui32MatrixARows, + img_uint32 ui32MatrixAColumns, + img_uint32 ui32MatrixBRows, + img_uint32 ui32MatrixBColumns, + img_uint32 ui32ResultRows, + img_uint32 ui32ResultColumns, + img_int32 * pai32MatrixA, + img_int32 * pai32MatrixB, + img_int32 * pai32ResultMatrix, + img_uint32 ui32PostShiftResults ); + +/*! +****************************************************************************** + + @Function FIXEDPT_ScalarMatrixMultiply + + @Description This function multiplies each value in a matrix, A, by + the corresponding value in a second matrix, B, placing + the results in a third matrix. This is a scalar + multiplication - NOT a matrix multiplication. All + three matrices must be of identical dimensions. + + @Input ui32MatrixRows : + The number of rows in the matrix + + @Input ui32MatrixColumns : + The number of columns in the matrix + + @Input pai32MatrixA : + A pointer to the first matrix, comprising + (Rows x Columns) signed 32 bit values. + + @Input pai32MatrixB : + A pointer to the second matrix, comprising + (Rows x Columns) signed 32 bit values. + + @Input pai32ResultantMatrix : + A pointer to the resultant matrix - this matrix must + occupy a separate area of memory from MatrixA and + MatrixB - it is not valid to use a single matrix + as both input and output from this function. + + @Input ui32PostShiftResults : + The number of bits to postshift the result of each + multiplication by. This must be set such that the + results do not overflow 32 bits. The function will + assert in the case of an overflow. + + @Return img_void : This function does not return a value + +******************************************************************************/ +img_void FIXEDPT_ScalarMatrixMultiply ( img_uint32 ui32MatrixRows, + img_uint32 ui32MatrixColumns, + img_int32 * pai32MatrixA, + img_int32 * pai32MatrixB, + img_int32 * pai32ResultantMatrix, + img_uint32 ui32PostShiftResults ); + +#if (__cplusplus) +} +#endif + +#endif /* __FIXEDPOINTMATHS_H__ */ diff --git a/src/powervr_iep_lite/include/win32/img_iep_defs.h b/src/powervr_iep_lite/include/win32/img_iep_defs.h index 96a53ea..afa24b5 100644 --- a/src/powervr_iep_lite/include/win32/img_iep_defs.h +++ b/src/powervr_iep_lite/include/win32/img_iep_defs.h @@ -1,214 +1,214 @@ -/*! -****************************************************************************** - @file : img_iep_defs.h - - @brief - - @Author Various - - Copyright 2008 by Imagination Technologies Limited.\n - All rights reserved. No part of this software, either - material or conceptual may be copied or distributed, - transmitted, transcribed, stored in a retrieval system - or translated into any human or computer language in any - form by any means, electronic, mechanical, manual or - other-wise, or disclosed to third parties without the - express written permission of Imagination Technologies - Limited, Unit 8, HomePark Industrial Estate, - King's Langley, Hertfordshire, WD4 8LZ, U.K. - - Description:\n - This header file contains the Imagination Technologies platform - specific defintions. - - Platform:\n - Win32. - -******************************************************************************/ - -/******************************************************************** - DISCLAIMER: - This code is provided for demonstration purposes only. It has - been ported from other projects and has not been tested with - real hardware. It is not provided in a state that can be run - with real hardware - this is not intended as the basis for a - production driver. This code should only be used as an example - of the algorithms to be used for setting up the IEP lite - hardware. - ********************************************************************/ - -#if !defined (__IMG_IEP_DEFS_H__) -#define __IMG_IEP_DEFS_H__ - -#include - -#include -#include -#include "img_defs.h" - -#if (__cplusplus) -extern "C" { -#endif - -typedef IMG_INT32 img_int32, * img_pint32; -typedef int img_result, * img_presult; -typedef unsigned int img_uint32, * img_puint32; -typedef void img_void, * img_pvoid; -typedef void* img_handle, * img_phandle; -typedef void** img_hvoid, * img_phvoid; -typedef int img_bool, * img_pbool; -typedef unsigned char img_uint8, * img_puint8; -typedef float img_float, * img_pfloat; -typedef char img_int8, * img_pint8; -typedef char img_char, * img_pchar; -typedef unsigned char img_byte, * img_pbyte; -typedef unsigned short img_uint16, * img_puint16; -typedef short img_int16, * img_pint16; -#if 0 -typedef unsigned __int64 img_uint64, * img_puint64; -typedef __int64 img_int64, * img_pint64; -#else -typedef unsigned long long img_uint64, * img_puint64; -typedef long long img_int64, * img_pint64; -#endif -typedef unsigned long img_uintptr_t; - - -//#define IMG_SUCCESS (0) -#define IMG_TIMEOUT (1) -#define IMG_MALLOC_FAILED (2) -#define IMG_FATAL_ERROR (3) - -#if 0 -typedef enum img_tag_TriStateSwitch -{ - IMG_ON = 0x00, - IMG_OFF, - IMG_IGNORE - -} img_TriStateSwitch, * img_pTriStateSwitch; -#endif - -#define IMG_NULL 0 -#define IMG_TRUE 1 -#define IMG_FALSE 0 - -/* Maths functions - platform dependant */ -#define IMG_COS cos -#define IMG_SIN sin -#define IMG_POW(A, B) pow (A,B) -#define IMG_SQRT(A) sqrt (A) -#define IMG_FABS(A) fabs (A) -#define IMG_EXP(A) exp (A) - -/* General functions */ -#define IMG_MEMCPY(A,B,C) memcpy (A,B,C) -#define IMG_MEMSET(A,B,C) memset (A,B,C) -#define IMG_MEMCMP(A,B,C) memcmp (A,B,C) -#define IMG_MEMMOVE(A,B,C) memmove (A,B,C) - -#ifndef EXIT_ON_ASSERT -/*FIXME: not use _flushall() -#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), _flushall(), assert(exp), 0) ) -*/ -#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), assert(exp), 0) ) -//#define IMG_ASSERT(A) assert (A) -#else -//FIXME: not use _flushall() -//#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), _flushall(), exit(-1), 0) ) -#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), exit(-1), 0) ) -#endif - -#define IMG_ASSERT_LIVE // Defined when IMG_ASSERT() does something. - -/* Takes any two signed values - return 'IMG_TRUE' if they have the same polarity */ -#define IMG_SAMESIGN(A,B) (((((img_int32)A)^((img_int32)B))&0x80000000)==0) - -#if defined (NO_INLINE_FUNCS) - #define INLINE - #define FORCE_INLINE -#else -#if defined(_UITRON_) - #define INLINE - #define FORCE_INLINE - #define INLINE_IS_PRAGMA -#else -#if defined (__cplusplus) - #define INLINE inline - #define FORCE_INLINE inline -#else - #define INLINE __inline -#if defined(UNDER_CE) || defined(UNDER_XP) || defined(UNDER_VISTA) - #define FORCE_INLINE __forceinline -#else - #define FORCE_INLINE static __inline -#endif -#endif -#endif -#endif - -/* Use this in any file, or use attributes under GCC - see below */ -#ifndef PVR_UNREFERENCED_PARAMETER -#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) -#endif - -/* The best way to supress unused parameter warnings using GCC is to use a - * variable attribute. Place the unref__ between the type and name of an - * unused parameter in a function parameter list, eg `int unref__ var'. This - * should only be used in GCC build environments, for example, in files that - * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */ -#ifdef __GNUC__ -#define unref__ __attribute__ ((unused)) -#else -#define unref__ -#endif - -#if 0 -/* - Wide character definitions -*/ -#if defined(UNICODE) -typedef unsigned short TCHAR, *PTCHAR, *PTSTR; -#else /* #if defined(UNICODE) */ -typedef char TCHAR, *PTCHAR, *PTSTR; -#endif /* #if defined(UNICODE) */ -#endif - -//#define IMG_CALLCONV __stdcall -//#define IMG_INTERNAL -//#define IMG_EXPORT __declspec(dllexport) - -/* IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations match. - * Some compilers require the header to be declared IMPORT, while the implementation is declared EXPORT - */ -//#define IMG_IMPORT IMG_EXPORT - -#define IMG_MALLOC(A) malloc (A) -#define IMG_FREE(A) free (A) - -#define IMG_ALIGN(byte) -#define IMG_NORETURN - -#if defined (__cplusplus) - #define INLINE inline -#else -#if !defined(INLINE) - #define INLINE __inline -#endif -#endif - -#define __TBILogF consolePrintf - -#define IMG_NORETURN - -#if (__cplusplus) -} -#endif - -#if !defined (__IMG_IEP_TYPES_H__) -#include "img_types.h" -#endif - -#endif // IMG_IEP_DEFS_H - - +/*! +****************************************************************************** + @file : img_iep_defs.h + + @brief + + @Author Various + + Copyright 2008 by Imagination Technologies Limited.\n + All rights reserved. No part of this software, either + material or conceptual may be copied or distributed, + transmitted, transcribed, stored in a retrieval system + or translated into any human or computer language in any + form by any means, electronic, mechanical, manual or + other-wise, or disclosed to third parties without the + express written permission of Imagination Technologies + Limited, Unit 8, HomePark Industrial Estate, + King's Langley, Hertfordshire, WD4 8LZ, U.K. + + Description:\n + This header file contains the Imagination Technologies platform + specific defintions. + + Platform:\n + Win32. + +******************************************************************************/ + +/******************************************************************** + DISCLAIMER: + This code is provided for demonstration purposes only. It has + been ported from other projects and has not been tested with + real hardware. It is not provided in a state that can be run + with real hardware - this is not intended as the basis for a + production driver. This code should only be used as an example + of the algorithms to be used for setting up the IEP lite + hardware. + ********************************************************************/ + +#if !defined (__IMG_IEP_DEFS_H__) +#define __IMG_IEP_DEFS_H__ + +#include + +#include +#include +#include "img_defs.h" + +#if (__cplusplus) +extern "C" { +#endif + +typedef IMG_INT32 img_int32, * img_pint32; +typedef int img_result, * img_presult; +typedef unsigned int img_uint32, * img_puint32; +typedef void img_void, * img_pvoid; +typedef void* img_handle, * img_phandle; +typedef void** img_hvoid, * img_phvoid; +typedef int img_bool, * img_pbool; +typedef unsigned char img_uint8, * img_puint8; +typedef float img_float, * img_pfloat; +typedef char img_int8, * img_pint8; +typedef char img_char, * img_pchar; +typedef unsigned char img_byte, * img_pbyte; +typedef unsigned short img_uint16, * img_puint16; +typedef short img_int16, * img_pint16; +#if 0 +typedef unsigned __int64 img_uint64, * img_puint64; +typedef __int64 img_int64, * img_pint64; +#else +typedef unsigned long long img_uint64, * img_puint64; +typedef long long img_int64, * img_pint64; +#endif +typedef unsigned long img_uintptr_t; + + +//#define IMG_SUCCESS (0) +#define IMG_TIMEOUT (1) +#define IMG_MALLOC_FAILED (2) +#define IMG_FATAL_ERROR (3) + +#if 0 +typedef enum img_tag_TriStateSwitch +{ + IMG_ON = 0x00, + IMG_OFF, + IMG_IGNORE + +} img_TriStateSwitch, * img_pTriStateSwitch; +#endif + +#define IMG_NULL 0 +#define IMG_TRUE 1 +#define IMG_FALSE 0 + +/* Maths functions - platform dependant */ +#define IMG_COS cos +#define IMG_SIN sin +#define IMG_POW(A, B) pow (A,B) +#define IMG_SQRT(A) sqrt (A) +#define IMG_FABS(A) fabs (A) +#define IMG_EXP(A) exp (A) + +/* General functions */ +#define IMG_MEMCPY(A,B,C) memcpy (A,B,C) +#define IMG_MEMSET(A,B,C) memset (A,B,C) +#define IMG_MEMCMP(A,B,C) memcmp (A,B,C) +#define IMG_MEMMOVE(A,B,C) memmove (A,B,C) + +#ifndef EXIT_ON_ASSERT +/*FIXME: not use _flushall() +#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), _flushall(), assert(exp), 0) ) +*/ +#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), assert(exp), 0) ) +//#define IMG_ASSERT(A) assert (A) +#else +//FIXME: not use _flushall() +//#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), _flushall(), exit(-1), 0) ) +#define IMG_ASSERT(exp) (void)( (exp) || (fprintf(stderr, "ERROR: Assert %s; File %s; Line %d\n", #exp, __FILE__, __LINE__), exit(-1), 0) ) +#endif + +#define IMG_ASSERT_LIVE // Defined when IMG_ASSERT() does something. + +/* Takes any two signed values - return 'IMG_TRUE' if they have the same polarity */ +#define IMG_SAMESIGN(A,B) (((((img_int32)A)^((img_int32)B))&0x80000000)==0) + +#if defined (NO_INLINE_FUNCS) + #define INLINE + #define FORCE_INLINE +#else +#if defined(_UITRON_) + #define INLINE + #define FORCE_INLINE + #define INLINE_IS_PRAGMA +#else +#if defined (__cplusplus) + #define INLINE inline + #define FORCE_INLINE inline +#else + #define INLINE __inline +#if defined(UNDER_CE) || defined(UNDER_XP) || defined(UNDER_VISTA) + #define FORCE_INLINE __forceinline +#else + #define FORCE_INLINE static __inline +#endif +#endif +#endif +#endif + +/* Use this in any file, or use attributes under GCC - see below */ +#ifndef PVR_UNREFERENCED_PARAMETER +#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) +#endif + +/* The best way to supress unused parameter warnings using GCC is to use a + * variable attribute. Place the unref__ between the type and name of an + * unused parameter in a function parameter list, eg `int unref__ var'. This + * should only be used in GCC build environments, for example, in files that + * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */ +#ifdef __GNUC__ +#define unref__ __attribute__ ((unused)) +#else +#define unref__ +#endif + +#if 0 +/* + Wide character definitions +*/ +#if defined(UNICODE) +typedef unsigned short TCHAR, *PTCHAR, *PTSTR; +#else /* #if defined(UNICODE) */ +typedef char TCHAR, *PTCHAR, *PTSTR; +#endif /* #if defined(UNICODE) */ +#endif + +//#define IMG_CALLCONV __stdcall +//#define IMG_INTERNAL +//#define IMG_EXPORT __declspec(dllexport) + +/* IMG_IMPORT is defined as IMG_EXPORT so that headers and implementations match. + * Some compilers require the header to be declared IMPORT, while the implementation is declared EXPORT + */ +//#define IMG_IMPORT IMG_EXPORT + +#define IMG_MALLOC(A) malloc (A) +#define IMG_FREE(A) free (A) + +#define IMG_ALIGN(byte) +#define IMG_NORETURN + +#if defined (__cplusplus) + #define INLINE inline +#else +#if !defined(INLINE) + #define INLINE __inline +#endif +#endif + +#define __TBILogF consolePrintf + +#define IMG_NORETURN + +#if (__cplusplus) +} +#endif + +#if !defined (__IMG_IEP_TYPES_H__) +#include "img_types.h" +#endif + +#endif // IMG_IEP_DEFS_H + + diff --git a/src/psb_H264.c b/src/psb_H264.c index 1955f6a..24f0260 100644 --- a/src/psb_H264.c +++ b/src/psb_H264.c @@ -1105,7 +1105,7 @@ static void psb__H264_setup_alternative_frame( context_H264_p ctx ) if(rotate_surface->extra_info[5] != obj_context->rotate) psb__error_message("Display rotate mode does not match surface rotate mode!\n"); - + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); @@ -1416,7 +1416,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu /* If this a two pass mode deblock, then we will perform the rotation as part of the * 2nd pass deblock procedure */ - if(!ctx->two_pass_mode && ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not */ + if(/*!ctx->two_pass_mode &&*/ ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not issue */ psb__H264_setup_alternative_frame(ctx); /* CHUNK: SEQ Commands 1 */ @@ -1921,7 +1921,7 @@ static VAStatus psb_H264_EndPicture( return VA_STATUS_ERROR_UNKNOWN; } - if (ctx->two_pass_mode) + if (ctx->two_pass_mode && (ctx->obj_context->rotate == VA_ROTATION_NONE)) { void *pMbData = NULL; diff --git a/src/psb_VC1.c b/src/psb_VC1.c index 7f3ee6d..9314ac5 100644 --- a/src/psb_VC1.c +++ b/src/psb_VC1.c @@ -1984,6 +1984,39 @@ static void psb__VC1_write_kick(context_VC1_p ctx, VASliceParameterBufferVC1 *sl *cmdbuf->cmd_idx++ = CMD_COMPLETION; } +/* Programme the Alt output if there is a rotation*/ +static void psb__VC1_setup_alternative_frame( context_VC1_p ctx ) +{ + uint32_t cmd; + psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; + psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; + object_context_p obj_context = ctx->obj_context; + + if(rotate_surface->extra_info[5] != obj_context->rotate) + psb__error_message("Display rotate mode does not match surface rotate mode!\n"); + + + /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ + psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); + + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); + psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); + + psb_cmdbuf_rendec_end_chunk( cmdbuf ); + + /* Set the rotation registers */ + psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION) ); + cmd = 0; + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 ); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]); + + psb_cmdbuf_rendec_write( cmdbuf, cmd ); + + psb_cmdbuf_rendec_end_chunk( cmdbuf ); +} + static void psb__VC1_send_rendec_params(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) { VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; @@ -2126,6 +2159,9 @@ static void psb__VC1_send_rendec_params(context_VC1_p ctx, VASliceParameterBuffe psb_cmdbuf_rendec_start_block( cmdbuf ); + if(ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not issue */ + psb__VC1_setup_alternative_frame(ctx); + /* CHUNK: 1 - VC1SEQUENCE00 */ psb_cmdbuf_rendec_start_chunk( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) ); diff --git a/src/psb_buffer.c b/src/psb_buffer.c index eab7fc6..8d09c07 100644 --- a/src/psb_buffer.c +++ b/src/psb_buffer.c @@ -33,6 +33,7 @@ #include #include "pnw_jpeg.h" +#include "pnw_H264ES.h" #include "lnc_H264ES.h" /* @@ -365,6 +366,11 @@ int psb_codedbuf_map_mangle( return vaStatus; } + if ( VAProfileJPEGBaseline != obj_config->profile && *((unsigned long *) raw_codedbuf + 1) != 0) + { + /*Set frame skip flag*/ + pnw_set_frame_skip_flag(obj_context); + } switch (obj_config->profile) { case VAProfileMPEG4Simple: case VAProfileMPEG4AdvancedSimple: diff --git a/src/psb_cmdbuf.c b/src/psb_cmdbuf.c index 856a449..0e5e72f 100644 --- a/src/psb_cmdbuf.c +++ b/src/psb_cmdbuf.c @@ -483,6 +483,7 @@ psbDRMCmdBuf(int fd, int ioctl_offset, psb_buffer_p *buffer_list,int buffer_coun req->presumed_gpu_offset = (uint64_t)wsbmBOOffsetHint(buffer_list[i]->drm_buf); req->presumed_flags = PSB_USE_PRESUMED; + req->pad64 = (uint32_t)buffer_list[i]->pl_flags; } arg_list[buffer_count-1].d.req.next = 0; @@ -972,6 +973,61 @@ int psb_context_submit_deblock( object_context_p obj_context ) return 0; } +/* Issue deblock cmd, HW will do deblock instead of host */ +int psb_context_submit_hw_deblock(object_context_p obj_context, + psb_buffer_p buf_a, + psb_buffer_p buf_b, + psb_buffer_p colocate_buffer, + uint32_t picture_widht_mb, + uint32_t frame_height_mb, + uint32_t rotation_flags, + uint32_t field_type, + uint32_t ext_stride_a, + uint32_t chroma_offset_a, + uint32_t chroma_offset_b, + uint32_t is_oold) +{ + psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; + psb_driver_data_p driver_data = obj_context->driver_data; + uint32_t msg_size = FW_DEVA_DEBLOCK_SIZE; + unsigned int item_size; /* Size of a render/deocde msg */ + FW_VA_DEBLOCK_MSG *deblock_msg; + + if(IS_MFLD(driver_data)) + item_size = FW_DEVA_DECODE_SIZE; + else + item_size = FW_DXVA_RENDER_SIZE; + + uint32_t *msg = cmdbuf->MTX_msg + item_size * cmdbuf->cmd_count; + + memset(msg, 0, sizeof(FW_VA_DEBLOCK_MSG)); + deblock_msg = (FW_VA_DEBLOCK_MSG *)msg; + + deblock_msg->header.bits.msg_size = msg_size; + if(is_oold) + deblock_msg->header.bits.msg_type = VA_MSGID_OOLD_MFLD; + else + deblock_msg->header.bits.msg_type = VA_MSGID_DEBLOCK_MFLD; + deblock_msg->flags.bits.flags = FW_DXVA_RENDER_HOST_INT | FW_DXVA_RENDER_IS_LAST_SLICE; + deblock_msg->flags.bits.slice_type = field_type; + deblock_msg->operating_mode = obj_context->operating_mode; + deblock_msg->mmu_context.bits.context = (uint8_t)(obj_context->msvdx_context >> 16); + deblock_msg->pic_size.bits.frame_height_mb = (uint16_t)frame_height_mb; + deblock_msg->pic_size.bits.pic_width_mb = (uint16_t)picture_widht_mb; + deblock_msg->ext_stride_a = ext_stride_a; + deblock_msg->rotation_flags = rotation_flags; + + RELOC_MSG(deblock_msg->address_a0, buf_a->buffer_ofs, buf_a); + RELOC_MSG(deblock_msg->address_a1, buf_a->buffer_ofs + chroma_offset_a, buf_a); + if(buf_b) { + RELOC_MSG(deblock_msg->address_b0, buf_b->buffer_ofs, buf_b); + RELOC_MSG(deblock_msg->address_b1, buf_b->buffer_ofs + chroma_offset_b, buf_b); + } + + RELOC_MSG(deblock_msg->mb_param_address, colocate_buffer->buffer_ofs, colocate_buffer); + cmdbuf->deblock_count++; + return 0; +} int psb_context_submit_oold( object_context_p obj_context, psb_buffer_p src_buf, @@ -1028,7 +1084,15 @@ int psb_context_submit_oold( object_context_p obj_context, int psb_context_submit_cmdbuf( object_context_p obj_context ) { psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; - uint32_t cmdbuffer_size = (void *) cmdbuf->cmd_idx - cmdbuf->cmd_start; // In bytes + psb_driver_data_p driver_data = obj_context->driver_data; + unsigned int item_size; /* Size of a render/deocde msg */ + + if(IS_MFLD(driver_data)) + item_size = FW_DEVA_DECODE_SIZE; + else + item_size = FW_DXVA_RENDER_SIZE; + + uint32_t cmdbuffer_size = (void *) cmdbuf->cmd_idx - cmdbuf->cmd_start; // In bytes if (cmdbuf->last_next_segment_cmd) { @@ -1036,8 +1100,8 @@ int psb_context_submit_cmdbuf( object_context_p obj_context ) psb_cmdbuf_close_segment( cmdbuf ); } - uint32_t msg_size = FW_DXVA_RENDER_SIZE; - uint32_t *msg = cmdbuf->MTX_msg + cmdbuf->cmd_count * FW_DXVA_RENDER_SIZE; + uint32_t msg_size = item_size; + uint32_t *msg = cmdbuf->MTX_msg + cmdbuf->cmd_count * msg_size; #ifdef DEBUG_TRACE debug_cmd_start[cmdbuf->cmd_count] = cmdbuf->cmd_start - cmdbuf->cmd_base; @@ -1045,6 +1109,20 @@ int psb_context_submit_cmdbuf( object_context_p obj_context ) debug_cmd_count = cmdbuf->cmd_count+1; #endif +#define DUMP_CMDBUF 0 + +#if DUMP_CMDBUF + static int c = 0; + static char pFileName[30]; + + + sprintf( pFileName , "cmdbuf%i.txt", c++); + FILE* pF = fopen(pFileName,"w"); + + fwrite(cmdbuf->cmd_start, 1, cmdbuffer_size, pF); + fclose(pF); +#endif + cmdbuf->cmd_count++; memset(msg, 0, msg_size); @@ -1052,27 +1130,48 @@ int psb_context_submit_cmdbuf( object_context_p obj_context ) ASSERT(cmdbuffer_size < CMD_SIZE); ASSERT((void *) cmdbuf->cmd_idx < CMD_END(cmdbuf)); - MEMIO_WRITE_FIELD(msg, FWRK_GENMSG_SIZE, FW_DXVA_RENDER_SIZE); + MEMIO_WRITE_FIELD(msg, FWRK_GENMSG_SIZE, msg_size); MEMIO_WRITE_FIELD(msg, FWRK_GENMSG_ID, DXVA_MSGID_RENDER); - /* TODO: Need to make context more unique */ - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_CONTEXT, obj_context->msvdx_context ); - /* Point to CMDBUFFER */ - uint32_t lldma_record_offset = psb_cmdbuf_lldma_create(cmdbuf, - &(cmdbuf->buf), (cmdbuf->cmd_start - cmdbuf->cmd_base) /* offset */, - cmdbuffer_size, - 0 /* destination offset */, - (obj_context->video_op == psb_video_vld) ? LLDMA_TYPE_RENDER_BUFF_VLD : LLDMA_TYPE_RENDER_BUFF_MC); - /* This is the last relocation */ - RELOC_MSG( *(msg + (FW_DXVA_RENDER_LLDMA_ADDRESS_OFFSET/sizeof(uint32_t))), + if(!IS_MFLD(driver_data)) + { + /* TODO: Need to make context more unique */ + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_CONTEXT, obj_context->msvdx_context ); + + /* Point to CMDBUFFER */ + uint32_t lldma_record_offset = psb_cmdbuf_lldma_create(cmdbuf, + &(cmdbuf->buf), (cmdbuf->cmd_start - cmdbuf->cmd_base) /* offset */, + cmdbuffer_size, + 0 /* destination offset */, + (obj_context->video_op == psb_video_vld) ? LLDMA_TYPE_RENDER_BUFF_VLD : LLDMA_TYPE_RENDER_BUFF_MC); + /* This is the last relocation */ + RELOC_MSG( *(msg + (FW_DXVA_RENDER_LLDMA_ADDRESS_OFFSET/sizeof(uint32_t))), lldma_record_offset, &(cmdbuf->buf)); - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE, cmdbuffer_size); // In bytes - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE, obj_context->operating_mode); - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME, obj_context->last_mb); - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE, obj_context->first_mb); - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FLAGS, obj_context->flags); - + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE, cmdbuffer_size); // In bytes + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE, obj_context->operating_mode); + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME, obj_context->last_mb); + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE, obj_context->first_mb); + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FLAGS, obj_context->flags); + } + else + { + MEMIO_WRITE_FIELD(msg, FW_DEVA_DECODE_CONTEXT, (obj_context->msvdx_context >> 16) );/* context is 8 bits */ + + /* Point to CMDBUFFER */ + uint32_t lldma_record_offset = psb_cmdbuf_lldma_create(cmdbuf, + &(cmdbuf->buf), (cmdbuf->cmd_start - cmdbuf->cmd_base) /* offset */, + cmdbuffer_size, + 0 /* destination offset */, + (obj_context->video_op == psb_video_vld) ? LLDMA_TYPE_RENDER_BUFF_VLD : LLDMA_TYPE_RENDER_BUFF_MC); + /* This is the last relocation */ + RELOC_MSG( *(msg + (FW_DEVA_DECODE_LLDMA_ADDRESS_OFFSET/sizeof(uint32_t))), + lldma_record_offset, &(cmdbuf->buf)); + + MEMIO_WRITE_FIELD(msg, FW_DEVA_DECODE_BUFFER_SIZE, cmdbuffer_size / 4); // In dwords + MEMIO_WRITE_FIELD(msg, FW_DEVA_DECODE_OPERATING_MODE, obj_context->operating_mode); + MEMIO_WRITE_FIELD(msg, FW_DEVA_DECODE_FLAGS, obj_context->flags); + } #ifdef DEBUG_TRACE debug_lldma_count = (cmdbuf->lldma_idx - cmdbuf->lldma_base) / sizeof(DMA_sLinkedList); debug_lldma_start = cmdbuf->lldma_base - cmdbuf->cmd_base; @@ -1110,6 +1209,12 @@ int psb_context_flush_cmdbuf( object_context_p obj_context ) unsigned int reloc_offset; unsigned int num_relocs; int ret; + unsigned int item_size; /* Size of a render/deocde msg */ + + if(IS_MFLD(driver_data)) + item_size = FW_DEVA_DECODE_SIZE; + else + item_size = FW_DXVA_RENDER_SIZE; if ((NULL == cmdbuf) || ((0 == cmdbuf->cmd_count) && (0 == cmdbuf->deblock_count))) { @@ -1131,10 +1236,15 @@ int psb_context_flush_cmdbuf( object_context_p obj_context ) for(i = 1; i <= cmdbuf->cmd_count; i++) { - uint32_t flags = MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS); + uint32_t flags; + if(IS_MFLD(driver_data)) + flags = MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_FLAGS); + else + flags = MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS); + /* Update flags */ - int bBatchEnd = (i == cmdbuf->cmd_count + cmdbuf->deblock_count + cmdbuf->oold_count); + int bBatchEnd = (i == (cmdbuf->cmd_count + cmdbuf->deblock_count + cmdbuf->oold_count)); flags |= (bBatchEnd ? (FW_DXVA_RENDER_HOST_INT | FW_DXVA_LAST_SLICE_OF_EXT_DMA) : FW_DXVA_RENDER_NO_RESPONCE_MSG) | @@ -1144,33 +1254,58 @@ int psb_context_flush_cmdbuf( object_context_p obj_context ) flags |= FW_DXVA_LAST_SLICE_OF_EXT_DMA; /* VXD385 DDK406 not use FW_DXVA_LAST_SLICE_OF_EXT_DMA, this flags should be cleaned later */ - if(IS_MFLD(driver_data)) + if(IS_MFLD(driver_data)) + { flags &= ~FW_DXVA_LAST_SLICE_OF_EXT_DMA; - - MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FLAGS, flags); + flags &= ~FW_DXVA_RENDER_IS_VLD_NOT_MC; + MEMIO_WRITE_FIELD(msg, FW_DEVA_DECODE_FLAGS, flags); + } + else { + MEMIO_WRITE_FIELD(msg, FW_DXVA_RENDER_FLAGS, flags); + } #ifdef DEBUG_TRACE -psb__trace_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE) ); -psb__trace_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE) ); -psb__trace_message("MSG LAST_MB_IN_FRAME = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME) ); -psb__trace_message("MSG FIRST_MB_IN_SLICE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE) ); -psb__trace_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS) ); - -psb__information_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE) ); -psb__information_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE) ); -psb__information_message("MSG LAST_MB_IN_FRAME = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME) ); -psb__information_message("MSG FIRST_MB_IN_SLICE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE) ); -psb__information_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS) ); + if(!IS_MFLD(driver_data)) + { + psb__trace_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE) ); + psb__trace_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE) ); + psb__trace_message("MSG LAST_MB_IN_FRAME = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME) ); + psb__trace_message("MSG FIRST_MB_IN_SLICE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE) ); + psb__trace_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS) ); + + psb__information_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_BUFFER_SIZE) ); + psb__information_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_OPERATING_MODE) ); + psb__information_message("MSG LAST_MB_IN_FRAME = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_LAST_MB_IN_FRAME) ); + psb__information_message("MSG FIRST_MB_IN_SLICE = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FIRST_MB_IN_SLICE) ); + psb__information_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DXVA_RENDER_FLAGS) ); + } + else + { + psb__trace_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_BUFFER_SIZE) ); + psb__trace_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_OPERATING_MODE) ); + psb__trace_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_FLAGS) ); + + psb__information_message("MSG BUFFER_SIZE = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_BUFFER_SIZE) ); + psb__information_message("MSG OPERATING_MODE = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_OPERATING_MODE) ); + psb__information_message("MSG FLAGS = %08x\n", MEMIO_READ_FIELD(msg, FW_DEVA_DECODE_FLAGS) ); + } #endif - msg += FW_DXVA_RENDER_SIZE / sizeof(uint32_t); - msg_size += FW_DXVA_RENDER_SIZE; +#if 0 /* todo */ + /* Update SAREA */ + driver_data->psb_sarea->msvdx_context = obj_context->msvdx_context; +#endif + msg += item_size / sizeof(uint32_t); + msg_size += item_size; } /* Assume deblock message is following render messages and no more render message behand deblock message */ for(i = 1; i <= cmdbuf->deblock_count; i++) { - msg_size += FW_DXVA_DEBLOCK_SIZE; + if(!IS_MFLD(driver_data)) + msg_size += FW_DXVA_DEBLOCK_SIZE; + else + msg_size += FW_DEVA_DEBLOCK_SIZE; } for(i = 1; i <= cmdbuf->oold_count; i++) @@ -1294,12 +1429,12 @@ static int error_count = 0; debug_cmd_count, wsbmBOOffsetHint(cmdbuf->buf.drm_buf)); for(i = 0; i < debug_cmd_count; i++) { - uint32_t *msg = cmdbuf->MTX_msg + i * FW_DXVA_RENDER_SIZE; + uint32_t *msg = cmdbuf->MTX_msg + i * item_size; int j; psb__information_message("start = %08x size = %08x\n", debug_cmd_start[i], debug_cmd_size[i]); debug_dump_cmdbuf( (uint32_t *) (cmdbuf->cmd_base + debug_cmd_start[i]), debug_cmd_size[i] ); - for (j=0; jbuf ); @@ -1376,7 +1511,7 @@ static const DMA_DETAIL_LOOKUP DmaDetailLookUp[] = IMG_FALSE, MMU_GROUP1, HOST_TO_MSVDX, - DMA_BURST_2 + DMA_BURST_4 }, /*LLDMA_TYPE_RENDER_BUFF_MC*/{ @@ -1445,7 +1580,7 @@ static const DMA_DETAIL_LOOKUP DmaDetailLookUp[] = DMA_PERIPH_INCR_1, DMA_PERIPH_INCR_OFF, IMG_TRUE, /* na */ - MMU_GROUP1, + MMU_GROUP0, MSXDX_TO_HOST, DMA_BURST_1 //2 /* From MTX */ }, @@ -1455,7 +1590,7 @@ static const DMA_DETAIL_LOOKUP DmaDetailLookUp[] = DMA_PERIPH_INCR_1, DMA_PERIPH_INCR_OFF, IMG_TRUE, /* na */ - MMU_GROUP1, + MMU_GROUP0, HOST_TO_MSVDX, DMA_BURST_1 /* Into MTX */ }, @@ -1682,6 +1817,15 @@ void psb_cmdbuf_reg_start_block( psb_cmdbuf_p cmdbuf ) ASSERT(NULL == cmdbuf->rendec_block_start); /* Can't have both */ cmdbuf->reg_start = cmdbuf->cmd_idx++; + *cmdbuf->reg_start = 0; +} + +void psb_cmdbuf_reg_start_block_flag( psb_cmdbuf_p cmdbuf, uint32_t flags ) +{ + ASSERT(NULL == cmdbuf->rendec_block_start); /* Can't have both */ + + cmdbuf->reg_start = cmdbuf->cmd_idx++; + *cmdbuf->reg_start = flags; } void psb_cmdbuf_reg_set_address( psb_cmdbuf_p cmdbuf, @@ -1700,7 +1844,7 @@ void psb_cmdbuf_reg_end_block( psb_cmdbuf_p cmdbuf ) { uint32_t reg_count = ((cmdbuf->cmd_idx - cmdbuf->reg_start) - 1) / 2; - *cmdbuf->reg_start = CMD_REGVALPAIR_WRITE | reg_count; + *cmdbuf->reg_start |= CMD_REGVALPAIR_WRITE | reg_count; cmdbuf->reg_start = NULL; } @@ -1743,6 +1887,17 @@ void psb_cmdbuf_rendec_start_chunk( psb_cmdbuf_p cmdbuf, uint32_t dest_address ) REGIO_WRITE_FIELD_LITE(*cmdbuf->rendec_chunk_start, RENDEC_SLICE_INFO, CK_HDR, CK_START_ADDRESS, ( dest_address >> 2)); } +/* + * Start a new rendec block of another format + */ +void psb_cmdbuf_rendec_start( psb_cmdbuf_p cmdbuf, uint32_t dest_address ) +{ + ASSERT( ((dest_address>>2)& ~0xfff) == 0 ); + cmdbuf->rendec_chunk_start = cmdbuf->cmd_idx++; + + *cmdbuf->rendec_chunk_start = CMD_RENDEC_BLOCK | ((dest_address>>2) <<4 ); +} + void psb_cmdbuf_rendec_write_block( psb_cmdbuf_p cmdbuf, unsigned char *block, uint32_t size ) @@ -1781,6 +1936,20 @@ void psb_cmdbuf_rendec_end_chunk( psb_cmdbuf_p cmdbuf ) cmdbuf->rendec_chunk_start = NULL; } +/* + * Finish a RENDEC block + */ +void psb_cmdbuf_rendec_end( psb_cmdbuf_p cmdbuf ) +{ + ASSERT(NULL != cmdbuf->rendec_chunk_start); /* Must have an open RENDEC chunk */ + uint32_t dword_count = cmdbuf->cmd_idx - cmdbuf->rendec_chunk_start; + + ASSERT( (dword_count-1) <= 0xff ); + + *cmdbuf->rendec_chunk_start += ((dword_count - 1) << 16); + cmdbuf->rendec_chunk_start = NULL; +} + /* * Finish a RENDEC block */ diff --git a/src/psb_cmdbuf.h b/src/psb_cmdbuf.h index 8845565..3f6f75b 100644 --- a/src/psb_cmdbuf.h +++ b/src/psb_cmdbuf.h @@ -160,6 +160,20 @@ int psb_context_submit_oold( object_context_p obj_context, uint32_t frame_height_in_mb, uint32_t field_type, uint32_t chroma_offset ); + +int psb_context_submit_hw_deblock(object_context_p obj_context, + psb_buffer_p buf_a, + psb_buffer_p buf_b, + psb_buffer_p colocate_buffer, + uint32_t picture_widht_mb, + uint32_t frame_height_mb, + uint32_t rotation_flags, + uint32_t field_type, + uint32_t ext_stride_a, + uint32_t chroma_offset_a, + uint32_t chroma_offset_b, + uint32_t is_oold); + /* * Submits the current cmdbuf * @@ -216,6 +230,11 @@ uint32_t psb_cmdbuf_lldma_create( psb_cmdbuf_p cmdbuf, */ void psb_cmdbuf_reg_start_block( psb_cmdbuf_p cmdbuf ); +/* + * Create a command to set registers + */ +void psb_cmdbuf_reg_start_block_flag( psb_cmdbuf_p cmdbuf, uint32_t flags ); + #define psb_cmdbuf_reg_set( cmdbuf, reg, val ) \ do { *cmdbuf->cmd_idx++ = reg; *cmdbuf->cmd_idx++ = val; } while (0) @@ -237,6 +256,10 @@ void psb_cmdbuf_reg_end_block( psb_cmdbuf_p cmdbuf ); */ void psb_cmdbuf_rendec_start_block( psb_cmdbuf_p cmdbuf ); +/* + * Create a RENDEC command block + */ +void psb_cmdbuf_rendec_start( psb_cmdbuf_p cmdbuf, uint32_t dest_address ); /* * Start a new chunk in a RENDEC command block */ @@ -288,6 +311,10 @@ void psb_cmdbuf_skip_start_block( psb_cmdbuf_p cmdbuf, uint32_t skip_condition ) */ void psb_cmdbuf_skip_end_block( psb_cmdbuf_p cmdbuf ); +/* + * Terminate a conditional SKIP block + */ +void psb_cmdbuf_rendec_end( psb_cmdbuf_p cmdbuf ); /* * Write RegIO record into buffer */ diff --git a/src/psb_drv_video.c b/src/psb_drv_video.c index 4c7d329..b283d43 100644 --- a/src/psb_drv_video.c +++ b/src/psb_drv_video.c @@ -36,6 +36,7 @@ #include "pnw_MPEG2.h" #include "pnw_MPEG4.h" #include "pnw_H264.h" +#include "pnw_VC1.h" #include "lnc_MPEG4ES.h" #include "lnc_H264ES.h" #include "lnc_H263ES.h" @@ -70,7 +71,7 @@ #endif #define PSB_DRV_VERSION PSB_PACKAGE_VERSION -#define PSB_CHG_REVISION "(0X00000035)" +#define PSB_CHG_REVISION "(0X0000003C)" #define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION #define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION @@ -102,21 +103,23 @@ static int psb_get_device_info( VADriverContextP ctx ); -int psb_parse_config(char *env_from_file, char *env_value) +/* + * read a config "env" for libva.conf or from environment setting + * liva.conf has higher priority + * return 0: the "env" is set, and the value is copied into env_value + * 1: the env is not set + */ +int psb_parse_config(char *env, char *env_value) { char *token, *value, *saveptr; char oneline[1024]; FILE *fp=NULL; - - if (env_from_file == NULL) + if (env_value == NULL) return 1; fp = fopen("/etc/psbvideo.conf", "r"); - if (fp == NULL) - return 1; - - while (fgets(oneline, 1024, fp) != NULL) { + while (fp && (fgets(oneline, 1024, fp) != NULL)) { if (strlen(oneline) == 1) continue; token = strtok_r(oneline, "=\n", &saveptr); @@ -125,7 +128,7 @@ int psb_parse_config(char *env_from_file, char *env_value) if (NULL == token || NULL == value) continue; - if (strcmp(token, env_from_file) == 0) { + if (strcmp(token, env) == 0) { if (env_value) strcpy(env_value,value); @@ -134,8 +137,15 @@ int psb_parse_config(char *env_from_file, char *env_value) return 0; } } + if (fp) + fclose(fp); - fclose(fp); + if (getenv(env)) { + if (env_value) + strncpy(env_value, getenv(env), 1024); + + return 0; + } return 1; } @@ -152,14 +162,11 @@ static void psb__open_log(void) sprintf(log_fn+strlen(log_fn), ".%d", suffix); psb_video_debug_fp = fopen(log_fn, "w"); } - - if (getenv("PSB_VIDEO_DEBUG") != NULL) - psb_video_debug_fp = stderr; } static void psb__close_log(void) { - if ((psb_video_debug_fp != NULL) && (psb_video_debug_fp != stderr)) + if (psb_video_debug_fp != NULL) fclose(psb_video_debug_fp); } @@ -404,7 +411,9 @@ VAStatus psb_GetConfigAttributes( switch (attrib_list[i].type) { case VAConfigAttribRTFormat: - attrib_list[i].value = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422; + attrib_list[i].value = VA_RT_FORMAT_YUV420; + if (entrypoint == VAEntrypointEncPicture) + attrib_list[i].value |= VA_RT_FORMAT_YUV422; break; default: @@ -451,9 +460,9 @@ static VAStatus psb__validate_config(object_config_p obj_config) switch (obj_config->attrib_list[i].type) { case VAConfigAttribRTFormat: - if (obj_config->attrib_list[i].value != VA_RT_FORMAT_YUV420 - && (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 && - obj_config->entrypoint != VAEntrypointEncPicture)) + if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420 + || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 && + obj_config->entrypoint == VAEntrypointEncPicture))) { return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; } @@ -740,6 +749,7 @@ VAStatus psb_CreateSurfaces( obj_surface->height = height; obj_surface->width_r = width; obj_surface->height_r = height; + obj_surface->height_origin = height_origin; psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); if (NULL == psb_surface) @@ -791,9 +801,9 @@ VAStatus psb_CreateSurfaces( psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); if (NULL == psb_surface) { - object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface); - obj_surface->surface_id = VA_INVALID_SURFACE; psb_surface_destroy(obj_surface->psb_surface); + obj_surface->surface_id = VA_INVALID_SURFACE; + /* object_heap_free( &driver_data->surface_heap, (object_base_p) obj_surface); */ vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; @@ -1291,11 +1301,14 @@ VAStatus psb_CreateContext( lnc_ospm_start(driver_data, encode); #ifdef ANDROID - if ((obj_config->entrypoint != VAEntrypointEncSlice) && (obj_config->entrypoint != VAEntrypointEncPicture)) { - int buffer_width, buffer_height; - buffer_width = picture_width; - buffer_height = (picture_height + 0x1f) & ~0x1f; - vaStatus = psb_register_video_bcd(ctx, buffer_width, buffer_height, buffer_stride, num_render_targets, render_targets); + if (driver_data->output_method == PSB_PUTSURFACE_TEXSTREAMING || + driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXSTREAMING) { + if ((obj_config->entrypoint != VAEntrypointEncSlice) && (obj_config->entrypoint != VAEntrypointEncPicture)) { + int buffer_width, buffer_height; + buffer_width = picture_width; + buffer_height = (picture_height + 0x1f) & ~0x1f; + vaStatus = psb_register_video_bcd(ctx, buffer_width, buffer_height, buffer_stride, num_render_targets, render_targets); + } } #endif @@ -1579,7 +1592,7 @@ VAStatus psb_DestroyContext( #endif psb__destroy_context(driver_data, obj_context); - + return vaStatus; } @@ -1966,6 +1979,55 @@ VAStatus psb_DestroyBuffer( return vaStatus; } +static VAStatus psb__create_surface_rotation(VADriverContextP ctx, object_surface_p obj_surface, int protected) +{ + INIT_DRIVER_DATA + int width, height; + psb_surface_p psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); + VAStatus vaStatus = VA_STATUS_SUCCESS; + + psb__information_message("Try to allocate surface for alternative rotate output\n"); + + if (NULL == psb_surface) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + return vaStatus; + } + + width = obj_surface->width; + height = obj_surface->height; + + if(driver_data->rotate == VA_ROTATION_180) + { + vaStatus = psb_surface_create( driver_data, width, height, VA_FOURCC_NV12, + protected, psb_surface); + obj_surface->width_r = width; + obj_surface->height_r = height; + } + else + { + vaStatus = psb_surface_create( driver_data, obj_surface->height_origin, ((width + 0x1f) & ~0x1f), VA_FOURCC_NV12, + protected, psb_surface + ); + obj_surface->width_r = obj_surface->height_origin; + obj_surface->height_r = ((width + 0x1f) & ~0x1f); + } + if ( VA_STATUS_SUCCESS != vaStatus ) + { + free(psb_surface); + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + return vaStatus; + } + /* by default, surface fourcc is NV12 */ + memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info)); + psb_surface->extra_info[4] = VA_FOURCC_NV12; + psb_surface->extra_info[5] = driver_data->rotate; + + obj_surface->psb_surface_rotate = psb_surface; + return vaStatus; +} VAStatus psb_BeginPicture( VADriverContextP ctx, @@ -2013,6 +2075,59 @@ VAStatus psb_BeginPicture( vaStatus = obj_context->format_vtable->beginPicture(obj_context); } + /* Create surface for rotation if needed */ + if(driver_data->rotate == VA_ROTATION_NONE && obj_surface->psb_surface_rotate) + { + psb_surface_destroy(obj_surface->psb_surface_rotate); + obj_surface->psb_surface_rotate = NULL; + obj_surface->width_r = obj_surface->width; + obj_surface->height_r = obj_surface->height; + obj_context->rotate = driver_data->rotate; + } + else if(driver_data->rotate != VA_ROTATION_NONE && + (!obj_surface->psb_surface_rotate ? 1 : (obj_surface->psb_surface_rotate->extra_info[5] != driver_data->rotate))) + { + if(!obj_surface->psb_surface_rotate) + { + psb__create_surface_rotation(ctx, obj_surface, obj_surface->psb_surface->buf.type == psb_bt_rar_surface); + } + else + { + psb_surface_destroy(obj_surface->psb_surface_rotate); + free(obj_surface->psb_surface_rotate); + psb__create_surface_rotation(ctx, obj_surface, obj_surface->psb_surface->buf.type == psb_bt_rar_surface); + } + obj_context->rotate = driver_data->rotate; + } + + if(driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) + { + psb_surface_p psb_surface = obj_surface->psb_surface; + + psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s)); + if (NULL == psb_surface->in_loop_buf) + { + vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; + DEBUG_FAILURE; + return vaStatus; + } + + /* FIXME: For RAR surface, need allocate RAR buffer */ + vaStatus = psb_buffer_create( obj_context->driver_data, + psb_surface->size, + psb_bt_surface, + psb_surface->in_loop_buf ); + } + else if(!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) + { + psb_surface_p psb_surface = obj_surface->psb_surface; + + psb_buffer_destroy(psb_surface->in_loop_buf); + free(psb_surface->in_loop_buf); + psb_surface->in_loop_buf = NULL; + } + obj_context->is_oold = driver_data->is_oold; + psb__information_message("---BeginPicture 0x%08x for frame %d --\n", render_target, obj_context->frame_count); #ifdef DEBUG_TRACE @@ -2142,6 +2257,55 @@ VAStatus psb_EndPicture( } +static void psb__surface_usage( + psb_driver_data_p driver_data, + object_surface_p obj_surface, + int *decode, int *encode, int *rc_enable +) +{ + object_context_p obj_context; + object_config_p obj_config; + VAEntrypoint tmp; + unsigned int eRCmode; + int i; + + + *decode = 0; + *encode = 0; + *rc_enable = 0; + + obj_context = CONTEXT(obj_surface->context_id); + if (NULL == obj_context) /* not associate with a context */ + return; + + obj_config = CONFIG(obj_context->config_id); + if (NULL == obj_config) /* not have a validate context */ + return; + + tmp = obj_config->entrypoint; + + *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture); + *decode = (VAEntrypointVLD <= tmp) && (tmp <=VAEntrypointDeblocking); + + if (*encode) { + for(i = 0; i < obj_config->attrib_count; i++) { + if(obj_config->attrib_list[i].type == VAConfigAttribRateControl) + break; + } + + if(i >= obj_config->attrib_count) + eRCmode = VA_RC_NONE; + else + eRCmode = obj_config->attrib_list[i].value; + + if (eRCmode == VA_RC_NONE) + *rc_enable = 0; + else + *rc_enable = 1; + } +} + + VAStatus psb_SyncSurface( VADriverContextP ctx, @@ -2151,6 +2315,7 @@ VAStatus psb_SyncSurface( INIT_DRIVER_DATA VAStatus vaStatus = VA_STATUS_SUCCESS; object_surface_p obj_surface; + int decode = 0, encode = 0, rc_enable=0; obj_surface = SURFACE(render_target); if (NULL == obj_surface) @@ -2187,6 +2352,21 @@ VAStatus psb_SyncSurface( if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) vaStatus = psb_surface_sync(obj_surface->psb_surface); + /* report any error of decode for Android */ + psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable); + if (decode && IS_MRST(driver_data)) { + struct drm_lnc_video_getparam_arg arg; + uint32_t ret, fw_status = 0; + + arg.key = IMG_VIDEO_DECODE_STATUS; + arg.value = (uint64_t)((unsigned long) fw_status); + ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, + &arg, sizeof(arg)); + + if ((ret == 0) && (fw_status != 0)) + vaStatus = VA_STATUS_ERROR_DECODING_ERROR; + } + DEBUG_FAILURE; return vaStatus; } @@ -2201,10 +2381,8 @@ VAStatus psb_QuerySurfaceStatus( INIT_DRIVER_DATA VAStatus vaStatus = VA_STATUS_SUCCESS; object_surface_p obj_surface; - object_context_p obj_context; - object_config_p obj_config; VASurfaceStatus surface_status; - int frame_skip = 0; + int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0; obj_surface = SURFACE(render_target); if (NULL == obj_surface) @@ -2245,27 +2423,18 @@ VAStatus psb_QuerySurfaceStatus( } pthread_mutex_unlock(&driver_data->output_mutex); - /* try to get frameskip flag */ - obj_context = CONTEXT(obj_surface->context_id); - if (NULL == obj_context) /* not associate with a context */ - goto out_done; - - obj_config = CONFIG(obj_context->config_id); - if (NULL == obj_config) /* not have a validate context */ - goto out_done; - - if (obj_config->entrypoint != VAEntrypointEncSlice) - goto out_done; /* not encode context */ - - if (IS_MRST(obj_context->driver_data)) - lnc_surface_get_frameskip(obj_context, obj_surface->psb_surface, &frame_skip); - else - pnw_surface_get_frameskip(obj_context, obj_surface->psb_surface, &frame_skip); - - if (frame_skip == 1) - surface_status = surface_status | VASurfaceSkipped; + /* try to get frameskip flag for encode */ + psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable); + if (encode && rc_enable) { + if (IS_MRST(driver_data)) + lnc_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); + else + pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); -out_done: + if (frame_skip == 1) + surface_status = surface_status | VASurfaceSkipped; + } + *status = surface_status; return vaStatus; @@ -2307,8 +2476,7 @@ VAStatus psb_LockSurface( if (buffer) { /* map the surface buffer */ uint32_t srf_buf_ofs = 0; ret = psb_buffer_map(&psb_surface->buf, &surface_data); - if (ret) - { + if (ret) { *buffer = NULL; vaStatus = VA_STATUS_ERROR_UNKNOWN; DEBUG_FAILURE; @@ -2318,20 +2486,6 @@ VAStatus psb_LockSurface( *buffer = surface_data + srf_buf_ofs; } - if (buffer) { /* map the surface buffer */ - uint32_t srf_buf_ofs = 0; - ret = psb_buffer_map(&psb_surface->buf, &surface_data); - if (ret) - { - *buffer = NULL; - vaStatus = VA_STATUS_ERROR_UNKNOWN; - DEBUG_FAILURE; - return vaStatus; - } - srf_buf_ofs = psb_surface->buf.buffer_ofs; - *buffer = surface_data + srf_buf_ofs; - } - *fourcc = VA_FOURCC_NV12; *luma_stride = psb_surface->stride; *chroma_u_stride = psb_surface->stride; @@ -2591,8 +2745,13 @@ static VAStatus psb__initTTM( VADriverContextP ctx ) /* FIXME: should check dri enabled? * it seems not init dri here at all */ + + LOGE("%s:%s:%d :%x:%x", __FILE__, __func__, __LINE__, driver_data->drm_fd, DRM_PSB_EXTENSION); + ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &arg, sizeof(arg)); + + LOGE("%s:%s:%d :%s:%x:%x", __FILE__, __func__, __LINE__, arg.extension, arg.rep.exists, ret); if (ret != 0 || !arg.rep.exists) { psb__error_message("failed to detect DRM extension \"%s\".\n", drm_ext); @@ -2636,6 +2795,7 @@ static VAStatus psb__initDRM( VADriverContextP ctx ) vaStatus = psb__initDRI(ctx); + LOGE("%s:%s:%d:%d", __FILE__, __func__, __LINE__, vaStatus); if (vaStatus == VA_STATUS_SUCCESS) return psb__initTTM(ctx); else @@ -2847,7 +3007,7 @@ EXPORT VAStatus __vaDriverInit_0_31( VADriverContextP ctx ) free(ctx->vtable_tpi); return VA_STATUS_ERROR_ALLOCATION_FAILED; } - + LOGE("%s:%s:%d", __FILE__, __func__, __LINE__); if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) { free(ctx->pDriverData); @@ -2855,6 +3015,7 @@ EXPORT VAStatus __vaDriverInit_0_31( VADriverContextP ctx ) return VA_STATUS_ERROR_UNKNOWN; } + LOGE("%s:%s:%d", __FILE__, __func__, __LINE__); pthread_mutex_init(&driver_data->drm_mutex, NULL); /* @@ -2938,7 +3099,7 @@ EXPORT VAStatus __vaDriverInit_0_31( VADriverContextP ctx ) driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable; -/* + driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable; driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable; @@ -2951,7 +3112,7 @@ EXPORT VAStatus __vaDriverInit_0_31( VADriverContextP ctx ) driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable; driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable; driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable; -*/ + } else if (IS_MRST(driver_data) && driver_data->encode_supported) { driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &lnc_H263ES_vtable; @@ -2982,6 +3143,10 @@ EXPORT VAStatus __vaDriverInit_0_31( VADriverContextP ctx ) driver_data->cur_displaying_surface = VA_INVALID_SURFACE; driver_data->last_displaying_surface = VA_INVALID_SURFACE; + driver_data->clear_color = 0; + driver_data->blend_color = 0; + driver_data->blend_mode = 0; + if (IS_MFLD(driver_data)) ctx->str_vendor = PSB_STR_VENDOR_MFLD; else diff --git a/src/psb_drv_video.h b/src/psb_drv_video.h index 59631d1..e00e38d 100644 --- a/src/psb_drv_video.h +++ b/src/psb_drv_video.h @@ -193,6 +193,10 @@ struct psb_driver_data_s { int dummy_putsurface; int fixed_fps; unsigned int frame_count; + + uint32_t blend_mode; + uint32_t blend_color; + uint32_t color_key; }; #define IS_MRST(driver_data) ((driver_data->dev_id & 0xFFFC) == 0x4100) @@ -269,6 +273,7 @@ struct object_surface_s { VAContextID context_id; int width; int height; + int height_origin; int width_r; int height_r; struct psb_surface_s *psb_surface; diff --git a/src/psb_output.c b/src/psb_output.c index 15ed437..b8071c1 100644 --- a/src/psb_output.c +++ b/src/psb_output.c @@ -113,6 +113,7 @@ VAStatus psb_initOutput(VADriverContextP ctx) #endif driver_data->ws_priv = ws_priv; +#ifndef ANDROID /* use client overlay */ if (driver_data->coverlay == 1) psb_coverlay_init(ctx); @@ -120,6 +121,7 @@ VAStatus psb_initOutput(VADriverContextP ctx) //use client textureblit if (driver_data->ctexture == 1) psb_ctexture_init(ctx); +#endif /* //use texture streaming @@ -135,13 +137,20 @@ VAStatus psb_deinitOutput( ) { INIT_DRIVER_DATA; - + + struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; + +#ifndef ANDROID if (driver_data->coverlay == 1) psb_coverlay_deinit(ctx); //use client textureblit - if (driver_data->ctexture == 1) + if (driver_data->ctexture == 1) { psb_ctexture_deinit(ctx); + if (texture_priv->extend_dri_init_flag) + psb_extend_ctexture_deinit(ctx); + } +#endif #ifdef ANDROID psb_android_output_deinit(ctx); @@ -1873,6 +1882,9 @@ VAStatus psb_GetDisplayAttributes ( case VADisplayAttribBackgroundColor: p->value = driver_data->clear_color; break; + case VADisplayAttribBlendColor: + p->value = driver_data->blend_color; + break; default: break; } @@ -1957,7 +1969,10 @@ VAStatus psb_SetDisplayAttributes ( driver_data->rotate = p->value; if(driver_data->rotate == 4) driver_data->rotate = 3; /* Match with hw definition */ - + break; + case VADisplayAttribBlendColor: + driver_data->blend_color = p->value; + break; default: break; } diff --git a/src/psb_overlay.c b/src/psb_overlay.c index 467b247..a97c71a 100644 --- a/src/psb_overlay.c +++ b/src/psb_overlay.c @@ -59,13 +59,18 @@ * write to OVADD. **********************************************************************************************/ static void -I830ResetVideo(PsbPortPrivPtr pPriv) +I830ResetVideo(VADriverContextP ctx, PsbPortPrivPtr pPriv) { + INIT_DRIVER_DATA; I830OverlayRegPtr overlayA = (I830OverlayRegPtr)(pPriv->regmap[0]); I830OverlayRegPtr overlayC = (I830OverlayRegPtr)(pPriv->regmap[1]); + long offsetA = wsbmBOOffsetHint(pPriv->wsbo[0]) & 0x0FFFFFFF; + long offsetC = wsbmBOOffsetHint(pPriv->wsbo[1]) & 0x0FFFFFFF; + struct drm_psb_register_rw_arg regs; memset(overlayA, 0, sizeof(*overlayA)); memset(overlayC, 0, sizeof(*overlayC)); + memset(®s, 0, sizeof(regs)); overlayA->OCLRC0 = (pPriv->contrast.Value << 18) | (pPriv->brightness.Value & 0xff); overlayA->OCLRC1 = pPriv->saturation.Value; @@ -75,11 +80,11 @@ I830ResetVideo(PsbPortPrivPtr pPriv) #if USE_DCLRK /* case bit depth 16 */ - overlayA->DCLRKV = RGB16ToColorKey(pPriv->colorKey); + overlayA->DCLRKV = pPriv->colorKey; overlayA->DCLRKM |= DEST_KEY_ENABLE; overlayA->DCLRKM &= ~CONST_ALPHA_ENABLE; - overlayC->DCLRKV = RGB16ToColorKey(pPriv->colorKey); + overlayC->DCLRKV = pPriv->colorKey; overlayC->DCLRKM |= DEST_KEY_ENABLE; overlayC->DCLRKM &= ~CONST_ALPHA_ENABLE; #else @@ -91,6 +96,24 @@ I830ResetVideo(PsbPortPrivPtr pPriv) overlayC->DWINSZ = 0x00000000; overlayC->OCONFIG = CC_OUT_8BIT; + regs.overlay_read_mask = OVC_REGRWBITS_OVADD; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + regs.overlay_read_mask = 0; + regs.overlay_write_mask = OVC_REGRWBITS_OVADD; + regs.overlay.OVADD &= ~(0xffff << 16); + regs.overlay.OVADD |= offsetC; + regs.overlay.b_wait_vblank = 1; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + + memset(®s, 0, sizeof(regs)); + regs.overlay_read_mask = OV_REGRWBITS_OVADD; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + regs.overlay_read_mask = 0; + regs.overlay_write_mask = OV_REGRWBITS_OVADD; + regs.overlay.OVADD &= ~(0xffff << 16); + regs.overlay.OVADD |= offsetA; + regs.overlay.b_wait_vblank = 1; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); } static uint32_t I830BoundGammaElt (uint32_t elt, uint32_t eltPrev) @@ -149,15 +172,14 @@ static void I830StopVideo(VADriverContextP ctx) INIT_DRIVER_DATA; PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); long offsetA = wsbmBOOffsetHint(pPriv->wsbo[0]) & 0x0FFFFFFF; - long offsetC = wsbmBOOffsetHint(pPriv->wsbo[1]) & 0x0FFFFFFF; + I830OverlayRegPtr overlayA = (I830OverlayRegPtr)(pPriv->regmap[0]); + I830OverlayRegPtr overlayC = (I830OverlayRegPtr)(pPriv->regmap[1]); struct drm_psb_register_rw_arg regs; #if 0 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); #endif - I830ResetVideo(pPriv); - memset(®s, 0, sizeof(regs)); if (pPriv->subpicture_enabled ) { regs.subpicture_disable_mask = pPriv->subpicture_enable_mask; @@ -169,16 +191,26 @@ static void I830StopVideo(VADriverContextP ctx) if (pPriv->is_mfld && psb_xrandr_single_mode() == 0) { if (pPriv->overlayC_enabled) { + regs.overlay_read_mask = OVC_REGRWBITS_OVADD; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + + overlayC->OCMD &= ~OVERLAY_ENABLE; + regs.overlay_read_mask = 0; regs.overlay_write_mask = OVC_REGRWBITS_OVADD; - regs.overlay.OVADD = offsetC; - pPriv->overlayC_enabled = 0; drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + + memset(®s, 0, sizeof(regs)); + pPriv->overlayC_enabled = 0; } if (pPriv->overlayA_enabled) { - regs.overlay_write_mask = OV_REGRWBITS_OVADD; - regs.overlay.OVADD = offsetA; - pPriv->overlayA_enabled = 0; + regs.overlay_read_mask = OV_REGRWBITS_OVADD; drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + + overlayA->OCMD &= ~OVERLAY_ENABLE; + regs.overlay_read_mask = 0; + regs.overlay_write_mask = OV_REGRWBITS_OVADD; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + pPriv->overlayA_enabled = 0; } } else { regs.overlay_write_mask = OV_REGRWBITS_OVADD; @@ -188,6 +220,54 @@ static void I830StopVideo(VADriverContextP ctx) } } +static void I830SwitchPipe(VADriverContextP ctx , int overlayId, int pipeId) +{ + INIT_DRIVER_DATA; + PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); + I830OverlayRegPtr overlay = (I830OverlayRegPtr)(pPriv->regmap[overlayId]); + struct drm_psb_register_rw_arg regs; + uint32_t overlay_mask; + + if ((overlayId == OVERLAY_A) && pPriv->overlayA_enabled) + overlay_mask = OV_REGRWBITS_OVADD; + else if ((overlayId == OVERLAY_C) && pPriv->overlayC_enabled) + overlay_mask = OVC_REGRWBITS_OVADD; + else + return; /*No overlay enabled, do nothing.*/ + + printf("Overlay %d switch to pipe %d\n", overlayId, pipeId); + memset(®s, 0, sizeof(regs)); + memset(overlay, 0, sizeof(*overlay)); + overlay->OCLRC0 = (pPriv->contrast.Value << 18) | (pPriv->brightness.Value & 0xff); + overlay->OCLRC1 = pPriv->saturation.Value; + + /* case bit depth 16 */ + overlay->DCLRKV = pPriv->colorKey; + overlay->DCLRKM |= DEST_KEY_ENABLE; + overlay->DCLRKM &= ~CONST_ALPHA_ENABLE; + overlay->DWINSZ = 0x00000000; + overlay->OCONFIG = CC_OUT_8BIT; + + regs.overlay_read_mask = overlay_mask; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + + switch(pipeId) { + case PIPEA: + overlay->OCONFIG |= OVERLAY_C_PIPE_A; + break; + case PIPEB: + overlay->OCONFIG |= OVERLAY_C_PIPE_B; + break; + case PIPEC: + overlay->OCONFIG |= OVERLAY_C_PIPE_C; + break; + } + regs.overlay_read_mask = 0; + regs.overlay_write_mask = overlay_mask; + regs.overlay.b_wait_vblank = 1; + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); +} + static int i830_swidth (unsigned int offset, unsigned int width, unsigned int mask, int shift) { @@ -368,8 +448,7 @@ i830_display_video( else overlay->DCLRKM |= DEST_KEY_ENABLE; - overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); - + overlay->DCLRKV = pPriv->colorKey; #if USE_ROTATION_FUNC switch (pPriv->rotation) { case RR_Rotate_0: @@ -622,7 +701,7 @@ i830_display_video( } } } - + OCMD = OVERLAY_ENABLE; switch (id) { @@ -724,11 +803,11 @@ i830_display_video( driver_data->ble_white_mode.value); iep_lite_RenderCompleteCallback (pPriv->p_iep_lite_context); - #if 0 +#if 0 printf("bs gain %d, scc gain %d\n", - driver_data->blueStretch_gain.value, - driver_data->skinColorCorrection_gain.value); - #endif + driver_data->blueStretch_gain.value, + driver_data->skinColorCorrection_gain.value); +#endif IEP_LITE_BlueStretchConfigure(pPriv->p_iep_lite_context, driver_data->blueStretch_gain.value); IEP_LITE_SkinColourCorrectionConfigure(pPriv->p_iep_lite_context, @@ -786,7 +865,6 @@ i830_display_video( regs.overlay.OVADD |= 0x40; break; } - overlay->OCONFIG |= IEP_LITE_BYPASS; /* By pass IEP functionality */ overlay->OCONFIG |= ZORDER_TOP; } else @@ -855,6 +933,62 @@ static int I830PutImage( else psb_surface = obj_surface->psb_surface_rotate; + if(!psb_surface) + psb_surface = obj_surface->psb_surface; +#if 0 + if(pipeId == 5) + { + psb_buffer_p buf = &psb_surface->buf; + unsigned char *data, *chroma, *buffer, *header; + static FILE *pf = NULL; + int ret, i; + if(pf == NULL) + if((pf = fopen("/home/1080p.yuv", "w+")) == NULL) + printf("Open yuv file fails\n"); + + ret = psb_buffer_map(buf, &data); + + if(ret) + printf("Map buffer fail\n"); + + for(i = 0; i < obj_surface->height_r; i++) + { + fwrite(data, 1, obj_surface->width_r, pf); + data += psb_surface->stride; + } + + buffer = malloc(obj_surface->height_r * obj_surface->width_r); + if(!buffer) + printf("Alloc chroma buffer fail\n"); + + header = buffer; + chroma = data; + for(i = 0; i < obj_surface->height_r/2; i++) + { + int j; + for(j = 0; j < obj_surface->width_r/2; j++) + { + *buffer++ = data[j*2]; + } + data += psb_surface->stride; + } + + data = chroma; + for(i = 0; i < obj_surface->height_r/2; i++) + { + int j; + for(j = 0; j < obj_surface->width_r/2; j++) + { + *buffer++ = data[j*2 + 1]; + } + data += psb_surface->stride; + } + + fwrite(header, obj_surface->height_r/2, obj_surface->width_r, pf); + free(header); + psb_buffer_unmap(buf); + } +#endif pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); switch (fourcc) { @@ -1038,6 +1172,8 @@ static void psbPortPrivCreate(PsbPortPrivPtr pPriv) pPriv->subpicture_enable_mask = 0; pPriv->overlayA_enabled = 0; pPriv->overlayC_enabled = 0; + pPriv->overlayA_pipeId = PIPEA; + pPriv->overlayC_pipeId = PIPEB; /* FIXME: is this right? set up to current screen size */ #if 1 @@ -1049,6 +1185,8 @@ static void psbPortPrivCreate(PsbPortPrivPtr pPriv) static void psbPortPrivDestroy(VADriverContextP ctx, PsbPortPrivPtr pPriv) { + psb_subpictureKeyPtr head_key = pPriv->subpicture_key; + psb_subpictureKeyPtr tail_key = NULL; if (pPriv->overlayA_enabled) I830StopVideo(ctx); @@ -1061,6 +1199,12 @@ psbPortPrivDestroy(VADriverContextP ctx, PsbPortPrivPtr pPriv) free(pPriv->p_iep_lite_context); } pPriv->p_iep_lite_context = NULL; + + while (head_key != NULL) { + tail_key = head_key->next; + free(head_key); + head_key = tail_key; + } } static PsbPortPrivPtr @@ -1074,8 +1218,7 @@ psbSetupImageVideoOverlay(VADriverContextP ctx, PsbPortPrivPtr pPriv) /* use green as color key by default for android media player */ - pPriv->colorKey = 0 /*0x0440*/; - + pPriv->colorKey = driver_data->color_key/*0x0440*/; pPriv->brightness.Value = -19; /* (255/219) * -16 */ pPriv->contrast.Value = 75; /* 255/219 * 64 */ pPriv->saturation.Value = 146; /* 128/112 * 128 */ @@ -1167,10 +1310,11 @@ int psb_coverlay_init(VADriverContextP ctx) INIT_DRIVER_DATA; PsbPortPrivPtr pPriv = &driver_data->coverlay_priv; + memset(pPriv, 0, sizeof(PsbPortPrivRec)); pPriv->is_mfld = IS_MFLD(driver_data); psbSetupImageVideoOverlay(ctx, pPriv); - I830ResetVideo(pPriv); + I830ResetVideo(ctx, pPriv); I830UpdateGamma(ctx, pPriv); return 0; @@ -1210,7 +1354,18 @@ VAStatus psb_putsurface_overlay( { INIT_DRIVER_DATA; object_surface_p obj_surface = SURFACE(surface); + PsbPortPrivPtr pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); + if ((overlayId == OVERLAY_A) && (pPriv->overlayA_pipeId != pipeId)) { + pPriv->overlayA_pipeId = pipeId; + I830SwitchPipe(ctx, OVERLAY_A, pipeId); + psb__information_message("OverlayA switch pipe to %d, stop overlayA first.\n", pipeId); + } + else if ((overlayId == OVERLAY_C) && (pPriv->overlayC_pipeId != pipeId)) { + pPriv->overlayC_pipeId = pipeId; + I830SwitchPipe(ctx, OVERLAY_C, pipeId); + psb__information_message("OverlayC switch pipe to %d, stop overlayC first.\n", pipeId); + } I830PutImage(ctx, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, VA_FOURCC_NV12, flags, overlayId, pipeId); diff --git a/src/psb_overlay.h b/src/psb_overlay.h index 6eda82a..db56ae4 100644 --- a/src/psb_overlay.h +++ b/src/psb_overlay.h @@ -23,6 +23,7 @@ #ifndef _PSB_OVERLAY_H_ #define _PSB_OVERLAY_H_ +#include #define USE_OVERLAY 1 #define USE_DISPLAY_C_SPRITE 0 @@ -243,14 +244,38 @@ typedef struct _ov_psb_fixed32 { }; } ov_psb_fixed32; +typedef struct _psb_subpictureKeyRec { + struct _psb_subpictureKeyRec *next; + unsigned int subpic_id; + + int subpic_dstx; + int subpic_dsty; + int subpic_dstw; + int subpic_dsth; +} psb_subpictureKeyRec, *psb_subpictureKeyPtr; + typedef struct _PsbPortPrivRec { int curBuf; int is_mfld; + /*subpicture*/ int subpicture_enabled; unsigned int subpicture_enable_mask; + psb_subpictureKeyPtr subpicture_key; + + /*overlay status*/ + int overlayA_pipeId; + int overlayC_pipeId; int overlayA_enabled; int overlayC_enabled; + /*window attribute*/ + int last_num_clipbox; + VARectangle last_clipbox[16]; + int x11_window_width; + int x11_window_height; + int create_window_flag; + int adjust_window_flag; + /* used to check downscale*/ short width_save; short height_save; diff --git a/src/psb_surface.c b/src/psb_surface.c index c3d650f..188e8d1 100644 --- a/src/psb_surface.c +++ b/src/psb_surface.c @@ -79,7 +79,7 @@ VAStatus psb_surface_create( psb_driver_data_p driver_data, psb_surface->stride_mode = STRIDE_NA; psb_surface->stride = (width + 0x1f) & ~0x1f; } - + psb_surface->luma_offset = 0; psb_surface->chroma_offset = psb_surface->stride * height; psb_surface->size = (psb_surface->stride * height * 3) / 2; diff --git a/src/psb_texture.c b/src/psb_texture.c index dd5f672..62ef5f9 100644 --- a/src/psb_texture.c +++ b/src/psb_texture.c @@ -26,12 +26,14 @@ #include #include +#include #include #ifndef ANDROID #include #include "x11/psb_xrandr.h" +#include "x11/psb_x11.h" #endif #include "pvr2d.h" @@ -42,8 +44,8 @@ #include "psb_texture.h" - #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; +#define INIT_OUTPUT_PRIV psb_x11_output_p output = (psb_x11_output_p)(((psb_driver_data_p)ctx->pDriverData)->ws_priv) #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) #define Degree (2*PI / 360.0) @@ -166,7 +168,6 @@ static int pvr_context_create(void **pvr_ctx) ret = PVR2DEnumerateDevices(pvr_devs); if (ret != PVR2D_OK) { - free(pvr_devs); psb__error_message("%s(): PVR2DEnumerateDevices() failed(%d)", __func__, ret); goto out; @@ -190,6 +191,8 @@ static int pvr_context_create(void **pvr_ctx) void psb_ctexture_init(VADriverContextP ctx) { INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; + struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; int ret; @@ -223,28 +226,62 @@ void psb_ctexture_init(VADriverContextP ctx) texture_priv->gamma0 = 0x080808; #ifndef ANDROID texture_priv->dri_init_flag = 0; + texture_priv->drawable_update_flag = 0; + texture_priv->extend_dri_init_flag = 0; texture_priv->current_blt_buffer = 0; texture_priv->extend_current_blt_buffer = 0; -#ifdef SUBPIC + texture_priv->adjust_window_flag = 0; + texture_priv->destw_save = 0; + texture_priv->desth_save = 0; + output->output_drawable = 0; + output->extend_drawable = 0; + int i; for (i = 0; i < 6; i++) texture_priv->pal_meminfo[i] = NULL; #endif - XWindowAttributes attr; - XGetWindowAttributes(ctx->native_dpy, DefaultRootWindow(ctx->native_dpy), &attr); - texture_priv->rootwin_width = attr.width; - texture_priv->rootwin_height = attr.height; -#endif psb_setup_coeffs(texture_priv); } +void psb_extend_ctexture_deinit(VADriverContextP ctx) +{ + INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; + PVR2DERROR ePVR2DStatus; + int i; + + struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; +#ifndef ANDROID + for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { + ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->extend_blt_meminfo[i]); + if (ePVR2DStatus!= PVR2D_OK) + psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); + } + XDestroyWindow(ctx->native_dpy, output->extend_drawable); + for (i = 0; i < 6; i++) { + if (texture_priv->pal_meminfo[i]) { + ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->pal_meminfo[i]); + if (ePVR2DStatus!= PVR2D_OK) + psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); + } + } +#endif +} + void psb_ctexture_deinit(VADriverContextP ctx) { INIT_DRIVER_DATA; + PVR2DERROR ePVR2DStatus; int i; struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; #ifndef ANDROID + if (!texture_priv->dri_drawable->is_window) { + ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->blt_meminfo_pixmap); + if (ePVR2DStatus!= PVR2D_OK) + psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); + } + if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->blt_meminfo[i]); @@ -257,21 +294,6 @@ void psb_ctexture_deinit(VADriverContextP ctx) if (ePVR2DStatus!= PVR2D_OK) psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); } - - if (driver_data->xrandr_thread_id) { - if (psb_xrandr_extvideo_mode()) - for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { - ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->extend_blt_meminfo[i]); - if (ePVR2DStatus!= PVR2D_OK) - psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); - } - } - - texture_priv->dri_init_flag = 0; - texture_priv->current_blt_buffer = 0; - texture_priv->extend_current_blt_buffer = 0; - texture_priv->rootwin_width = texture_priv->rootwin_height = 0; -#ifdef SUBPIC for (i = 0; i < 6; i++) { if (texture_priv->pal_meminfo[i]) { ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, texture_priv->pal_meminfo[i]); @@ -279,17 +301,16 @@ void psb_ctexture_deinit(VADriverContextP ctx) psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); } } -#endif #endif (void)texture_priv; - + } #ifndef ANDROID void psb_putsurface_textureblit( VADriverContextP ctx, PPVR2DMEMINFO pDstMeminfo, VASurfaceID surface, int src_x, int src_y, int src_w, - int src_h, int dst_x, int dst_y, int dst_w, int dst_h, + int src_h, int dst_x, int dst_y, int dst_w, int dst_h, unsigned int subtitle, int width, int height, int src_pitch, struct _WsbmBufferObject * src_buf, unsigned int placement) @@ -304,25 +325,28 @@ void psb_putsurface_textureblit( { #ifndef ANDROID INIT_DRIVER_DATA; - int i, j = 0, update_coeffs = 0; + int i, j, update_coeffs = 0; unsigned char tmp; - unsigned char * tmp_buffer; - unsigned char * tmp_subpic_buffer; - unsigned char temp; + unsigned char *tmp_buffer, *tmp_palette; struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; - object_surface_p obj_surface = SURFACE(surface); - PsbVASurfaceRec *surface_subpic; - surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; + object_surface_p obj_surface; + PsbVASurfaceRec *surface_subpic = NULL; + obj_surface = SURFACE(surface); PVR2D_VPBLT sBltVP; PVR2DERROR ePVR2DStatus; PPVR2DMEMINFO pVaVideoMemInfo; -#ifdef SUBPIC PPVR2DMEMINFO pVaVideoSubpicMemInfo[6]; -#endif + unsigned char * tmp_subpic_buffer; src_pitch = (src_pitch + 0x3) & ~0x3; + if (NULL == obj_surface) + { + psb__error_message("%s: Invalid surface ID 0x%08x!\n", __func__, surface); + return; + } + surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; /* check whether we need to update coeffs */ if ((height > 576) && (texture_priv->video_transfermatrix != PSB_VideoTransferMatrix_BT709)) { @@ -340,7 +364,7 @@ void psb_putsurface_textureblit( psb_setup_coeffs(texture_priv); sBltVP.psYUVCoeffs = (PPVR2D_YUVCOEFFS) &texture_priv->coeffs; /* FIXME: is it right? */ - sBltVP.bCoeffsGiven = 1; + sBltVP.bCoeffsGiven = 1; } /* now wrap the source wsbmBO */ @@ -383,7 +407,7 @@ void psb_putsurface_textureblit( #ifndef ANDROID if (IS_MFLD(driver_data)) //FIXME: zhaohan, mdfld gfx driver requires 8 bits aligned in the future, use 32 bits temporary - sBltVP.sDst.Stride = PVRCalculateStride(dst_w, 32, 32); + sBltVP.sDst.Stride = PVRCalculateStride(dst_w, 32, 8); if (IS_MRST(driver_data)) sBltVP.sDst.Stride = PVRCalculateStride(dst_w, 32, 32); sBltVP.sDst.Format = PVR2D_ARGB8888; @@ -420,62 +444,82 @@ void psb_putsurface_textureblit( sBltVP.rcSource->right = src_x + src_w; sBltVP.rcSource->top = src_y; sBltVP.rcSource->bottom = src_y + src_h; -#ifdef SUBPIC - for (i = 0; i < obj_surface->subpic_count; i++) { - tmp_subpic_buffer = NULL; - tmp_subpic_buffer = wsbmBOMap (surface_subpic->bo, WSBM_ACCESS_READ | WSBM_ACCESS_WRITE); - for (i = 0; i < surface_subpic->stride * surface_subpic->subpic_srch * 4; i = i + 4096) { - tmp = *(tmp_subpic_buffer + i); - if (tmp == 0) - *(tmp_subpic_buffer + i) = 0; - } - ePVR2DStatus = PVR2DMemWrap(texture_priv->hPVR2DContext, - tmp_subpic_buffer, - 0, - (surface_subpic->subpic_srcw * surface_subpic->subpic_srch * 4), - NULL, - &pVaVideoSubpicMemInfo[j]); - if (ePVR2DStatus!= PVR2D_OK) - { - psb__error_message("%s: PVR2DMemWrap subpic error %d\n", __FUNCTION__, ePVR2DStatus); - } + if (subtitle == 0 && obj_surface->subpic_count) { + for (i = 0; i < obj_surface->subpic_count; i++) { + tmp_subpic_buffer = NULL; + tmp_subpic_buffer = wsbmBOMap (surface_subpic->bo, WSBM_ACCESS_READ | WSBM_ACCESS_WRITE); + for (j = 0; j < surface_subpic->stride * surface_subpic->subpic_srch * 4; j = j + 4096) { + tmp = *(tmp_subpic_buffer + j); + if (tmp == 0) + *(tmp_subpic_buffer + j) = 0; + } - sBltVP.uiNumLayers += 1; - - sBltVP.sSrcSubpic[j].pSurfMemInfo = pVaVideoSubpicMemInfo[j]; - sBltVP.sSrcSubpic[j].SurfOffset = 0; - sBltVP.sSrcSubpic[j].Stride = surface_subpic->stride; - sBltVP.sSrcSubpic[j].Format = surface_subpic->fourcc; - sBltVP.sSrcSubpic[j].SurfWidth = surface_subpic->subpic_srcw; - sBltVP.sSrcSubpic[j].SurfHeight = surface_subpic->subpic_srch; - - sBltVP.rcSubPicSource[j].left = surface_subpic->subpic_srcx; - sBltVP.rcSubpicSource[j].right = surface_subpic->subpic_srcx + surface_subpic->subpic_srcw; - sBltVP.rcSubpicSource[j].top = surface_subpic->subpic_srcy; - sBltVP.rcSubpicSource[j].bottom = surface_subpic->subpic_srcy + surface_subpic->subpic_srch; - - sBltVP.rcSubpicDest[j].left = surface_subpic->subpic_dstx; - sBltVP.rcSubpicDest[j].right = surface_subpic->subpic_dstx + surface_subpic->subpic_dstw; - sBltVP.rcSubpicDest[j].top = surface_subpic->subpic_dsty; - sBltVP.rcSubpicDest[j].bottom = surface_subpic->subpic_dsty + surface_subpic->subpic_desth; - - //only allocate memory once for palette - if ((surface_subpic->fourcc == MAKEFOURCC('A', 'I' , '4', '4')) && !texture_priv->pal_meminfo[j]) { - ePVR2DStatus = PVR2DMemAlloc(texture_priv->hPVR2DContext, 16 * sizeof(unsigned int), &texture_priv->pal_meminfo[j]); - if (ePVR2DStatus!= PVR2D_OK) { - psb__error_message("%s: PVR2DMemAlloc error %d\n", __FUNCTION__, ePVR2DStatus); - return; + ePVR2DStatus = PVR2DMemWrap(texture_priv->hPVR2DContext, + tmp_subpic_buffer, + 0, + (surface_subpic->subpic_srcw * surface_subpic->subpic_srch * 4), + NULL, + &pVaVideoSubpicMemInfo[i]); + if (ePVR2DStatus!= PVR2D_OK) + psb__error_message("%s: PVR2DMemWrap subpic error %d\n", __FUNCTION__, ePVR2DStatus); + + sBltVP.uiNumLayers += 1; + + float h_ratio, v_ratio; + if (src_w > dst_w) { + h_ratio = (float)src_w / dst_w; + surface_subpic->subpic_dstx /= h_ratio; + surface_subpic->subpic_dstw /= h_ratio; + } else if (src_w < dst_w) { + h_ratio = (float)dst_w / src_w; + surface_subpic->subpic_dstx *= h_ratio; + surface_subpic->subpic_dstw *= h_ratio; + } + + if (src_h > dst_h) { + v_ratio = (float)src_h / dst_h; + surface_subpic->subpic_dsty /= v_ratio; + surface_subpic->subpic_dsth /= v_ratio; + } else if (src_h < dst_h) { + v_ratio = (float)dst_h / src_h; + surface_subpic->subpic_dsty *= v_ratio; + surface_subpic->subpic_dsth *= v_ratio; } - sBltVP.pPalMemInfo[j] = texture_priv->pal_meminfo[j]; - tmp = sBltVP.pPalMemInfo[j]->pBase; - memcpy(tmp, surface_subpic->palette_ptr, 16 * sizeof(unsigned int)); - sBltVP.PalOffset[j] = 0; + sBltVP.sSrcSubpic[i].pSurfMemInfo = pVaVideoSubpicMemInfo[i]; + sBltVP.sSrcSubpic[i].SurfOffset = 0; + sBltVP.sSrcSubpic[i].Stride = surface_subpic->stride; + sBltVP.sSrcSubpic[i].Format = surface_subpic->fourcc; + sBltVP.sSrcSubpic[i].SurfWidth = surface_subpic->subpic_srcw; + sBltVP.sSrcSubpic[i].SurfHeight = surface_subpic->subpic_srch; + + sBltVP.rcSubpicSource[i].left = surface_subpic->subpic_srcx; + sBltVP.rcSubpicSource[i].right = surface_subpic->subpic_srcx + surface_subpic->subpic_srcw; + sBltVP.rcSubpicSource[i].top = surface_subpic->subpic_srcy; + sBltVP.rcSubpicSource[i].bottom = surface_subpic->subpic_srcy + surface_subpic->subpic_srch; + + sBltVP.rcSubpicDest[i].left = surface_subpic->subpic_dstx; + sBltVP.rcSubpicDest[i].right = surface_subpic->subpic_dstx + surface_subpic->subpic_dstw; + sBltVP.rcSubpicDest[i].top = surface_subpic->subpic_dsty; + sBltVP.rcSubpicDest[i].bottom = surface_subpic->subpic_dsty + surface_subpic->subpic_dsth; + + //only allocate memory once for palette + if ((surface_subpic->fourcc == MAKEFOURCC('A', 'I' , '4', '4')) && !texture_priv->pal_meminfo[i]) { + ePVR2DStatus = PVR2DMemAlloc(texture_priv->hPVR2DContext, 16 * sizeof(unsigned int), 0, 0, &texture_priv->pal_meminfo[i]); + if (ePVR2DStatus!= PVR2D_OK) { + psb__error_message("%s: PVR2DMemAlloc error %d\n", __FUNCTION__, ePVR2DStatus); + return; + } + + sBltVP.pPalMemInfo[i] = texture_priv->pal_meminfo[i]; + tmp_palette = sBltVP.pPalMemInfo[i]->pBase; + memcpy(tmp_palette, surface_subpic->palette_ptr, 16 * sizeof(unsigned int)); + sBltVP.PalOffset[i] = 0; + } + surface_subpic = surface_subpic->next; } - surface_subpic = surface_subpic->next; } -#endif ePVR2DStatus = PVR2DBltVideo(texture_priv->hPVR2DContext, &sBltVP); if (ePVR2DStatus != PVR2D_OK) @@ -495,14 +539,17 @@ void psb_putsurface_textureblit( { psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); } -#ifdef SUBPIC + + surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; for (i = 0; i < obj_surface->subpic_count; i++) { - ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, pVaVideoSubpicMemInfo[j]); + ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, pVaVideoSubpicMemInfo[i]); if (ePVR2DStatus!= PVR2D_OK) psb__error_message("%s: PVR2DMemFree error %d\n", __FUNCTION__, ePVR2DStatus); + + wsbmBOUnmap(surface_subpic->bo); + surface_subpic = surface_subpic->next; } - wsbmBOUnmap(surface_subpic->bo); -#endif + #ifdef ANDROID ePVR2DStatus = PVR2DMemFree(texture_priv->hPVR2DContext, pDstMeminfo); if (ePVR2DStatus!= PVR2D_OK) diff --git a/src/psb_texture.h b/src/psb_texture.h index 0a94c20..1f9f7b6 100644 --- a/src/psb_texture.h +++ b/src/psb_texture.h @@ -101,12 +101,16 @@ struct psb_texture_s { struct dri_drawable *extend_dri_drawable; struct dri_drawable *dri_drawable; uint32_t dri_init_flag; + uint32_t extend_dri_init_flag; + uint32_t adjust_window_flag; uint32_t current_blt_buffer; uint32_t extend_current_blt_buffer; - uint32_t rootwin_width; - uint32_t rootwin_height; + uint32_t destw_save; + uint32_t desth_save; + uint32_t drawable_update_flag; /* drawable resize or switch between window <==> pixmap */ + PVR2DMEMINFO *blt_meminfo_pixmap; PVR2DMEMINFO *blt_meminfo[DRI2_BLIT_BUFFERS_NUM]; PVR2DMEMINFO *flip_meminfo[DRI2_FLIP_BUFFERS_NUM]; PVR2DMEMINFO *extend_blt_meminfo[DRI2_BLIT_BUFFERS_NUM]; @@ -117,6 +121,7 @@ struct psb_texture_s { void psb_ctexture_init(VADriverContextP ctx); void psb_ctexture_deinit(VADriverContextP ctx); +void psb_extend_ctexture_deinit(VADriverContextP ctx); void blit_texture_to_buf(VADriverContextP ctx, unsigned char * data, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, @@ -125,7 +130,7 @@ void blit_texture_to_buf(VADriverContextP ctx, unsigned char * data, int src_x, #ifndef ANDROID void psb_putsurface_textureblit( VADriverContextP ctx, PPVR2DMEMINFO pDstMeminfo, VASurfaceID surface, int src_x, int src_y, int src_w, - int src_h, int dst_x, int dst_y, int dst_w, int dst_h, + int src_h, int dst_x, int dst_y, int dst_w, int dst_h, unsigned int subtitle, int width, int height, int src_pitch, struct _WsbmBufferObject * src_buf, unsigned int placement); diff --git a/src/psb_ws_driver.c b/src/psb_ws_driver.c index 9eae860..a63facc 100644 --- a/src/psb_ws_driver.c +++ b/src/psb_ws_driver.c @@ -19,34 +19,6 @@ * otherwise. Any license under such intellectual property rights must be * express and approved by Intel in writing. */ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ #include "psb_def.h" diff --git a/src/psb_ws_driver.h b/src/psb_ws_driver.h index b2925fc..8178839 100644 --- a/src/psb_ws_driver.h +++ b/src/psb_ws_driver.h @@ -19,34 +19,6 @@ * otherwise. Any license under such intellectual property rights must be * express and approved by Intel in writing. */ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * Copyright 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ #ifndef _PSB_WS_DRIVER_H_ #define _PSB_WS_DRIVER_H_ diff --git a/src/pvr2d.h b/src/pvr2d.h index 20f063b..ef6e5eb 100644 --- a/src/pvr2d.h +++ b/src/pvr2d.h @@ -51,11 +51,6 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/****************************************************************************** -Modifications :- -$Log: pvr2d.h $ -******************************************************************************/ - #ifndef _PVR2D_H_ #define _PVR2D_H_ @@ -64,12 +59,17 @@ extern "C" { #endif /* PVR2D Platform-specific definitions */ +#if defined (__linux__) +#define PVR2D_EXPORT __attribute__((visibility("default"))) +#define PVR2D_IMPORT +#else #define PVR2D_EXPORT #define PVR2D_IMPORT +#endif /* PVR2D header revision */ #define PVR2D_REV_MAJOR 3 -#define PVR2D_REV_MINOR 2 +#define PVR2D_REV_MINOR 5 /* Basic types */ typedef enum @@ -138,17 +138,27 @@ typedef unsigned long PVR2DFORMAT; #define PVR2D_64BPP_RAW 0x1DUL // 64 bit raw #define PVR2D_128BPP_RAW 0x1EUL // 128 bit raw #define PVR2D_RGBA8888 0x1FUL // Common rgba 888 format -#define PVR2D_NV12_U8V8 0x20UL // NV12 Plane U8V8 +#define PVR2D_NV12_U8V8 0x20UL // NV12 Plane U8V8 #define PVR2D_NO_OF_FORMATS 0x21UL -/* Format modifier bit fields */ -#define PVR2D_FORMAT_MASK 0x0000FFFFUL // Format field -#define PVR2D_FORMAT_LAYOUT_MASK 0x00FF0000UL // Format layout (strided / twiddled / tiled) -#define PVR2D_FORMAT_LAYOUT_SHIFT 16UL -#define PVR2D_FORMAT_LAYOUT_STRIDED (0x00UL) -#define PVR2D_FORMAT_LAYOUT_TILED (0x01UL<<(PVR2D_FORMAT_LAYOUT_SHIFT)) -#define PVR2D_FORMAT_LAYOUT_TWIDDLED (0x02UL<<(PVR2D_FORMAT_LAYOUT_SHIFT)) +/* Format modifier bit field (DstFormat and SrcFormat bits 16..23) */ +#define PVR2D_FORMAT_MASK 0x0000FFFFUL // PVR2D Format bits +#define PVR2D_FORMAT_LAYOUT_MASK 0x000F0000UL // Format layout (strided / twiddled / tiled) +#define PVR2D_FORMAT_FLAGS_MASK 0x0FF00000UL // Surface Flags mask + +/* Layout */ +#define PVR2D_FORMAT_LAYOUT_SHIFT 16 +#define PVR2D_FORMAT_LAYOUT_STRIDED 0x00000000UL +#define PVR2D_FORMAT_LAYOUT_TILED 0x00010000UL +#define PVR2D_FORMAT_LAYOUT_TWIDDLED 0x00020000UL + +/* + PVR2D_SURFACE_PDUMP + This flag requests a surface pdump, to capture the pixel state after host writes. + Not needed if the surface state has resulted from previous SGX 2D/3D core writes. +*/ +#define PVR2D_SURFACE_PDUMP 0x00100000UL // calls PVRSRVPDumpMem to capture the surface (pdump builds only) /* Low level 3D format extension - for blts via the 3D core only. @@ -175,22 +185,29 @@ typedef enum /* flags for control information of additional blits */ typedef enum { - PVR2D_BLIT_DISABLE_ALL = 0x0000, /* disable all additional controls */ - PVR2D_BLIT_CK_ENABLE = 0x0001, /* enable colour key */ - PVR2D_BLIT_GLOBAL_ALPHA_ENABLE = 0x0002, /* enable standard global alpha */ - PVR2D_BLIT_PERPIXEL_ALPHABLEND_ENABLE = 0x0004, /* enable per-pixel alpha bleding */ - PVR2D_BLIT_PAT_SURFACE_ENABLE = 0x0008, /* enable pattern surf (disable fill) */ - PVR2D_BLIT_FULLY_SPECIFIED_ALPHA_ENABLE = 0x0010, /* enable fully specified alpha */ - PVR2D_BLIT_ROT_90 = 0x0020, /* apply 90 degree rotation to the blt */ - PVR2D_BLIT_ROT_180 = 0x0040, /* apply 180 degree rotation to the blt */ - PVR2D_BLIT_ROT_270 = 0x0080, /* apply 270 degree rotation to the blt */ - PVR2D_BLIT_COPYORDER_TL2BR = 0x0100, /* copy order overrides */ - PVR2D_BLIT_COPYORDER_BR2TL = 0x0200, - PVR2D_BLIT_COPYORDER_TR2BL = 0x0400, - PVR2D_BLIT_COPYORDER_BL2TR = 0x0800, - PVR2D_BLIT_COLKEY_SOURCE = 0x1000, /* Key colour is on the source surface */ - PVR2D_BLIT_COLKEY_DEST = 0x2000, /* Key colour is on the destination surface */ - PVR2D_BLIT_NO_SRC_SYNC_INFO = 0x4000 /* Dont send a source sync info*/ + PVR2D_BLIT_DISABLE_ALL = 0x00000000, /* disable all additional controls */ + PVR2D_BLIT_CK_ENABLE = 0x00000001, /* enable colour key */ + PVR2D_BLIT_GLOBAL_ALPHA_ENABLE = 0x00000002, /* enable standard global alpha */ + PVR2D_BLIT_PERPIXEL_ALPHABLEND_ENABLE = 0x00000004, /* enable per-pixel alpha bleding */ + PVR2D_BLIT_PAT_SURFACE_ENABLE = 0x00000008, /* enable pattern surf (disable fill) */ + PVR2D_BLIT_FULLY_SPECIFIED_ALPHA_ENABLE = 0x00000010, /* enable fully specified alpha */ + PVR2D_BLIT_ROT_90 = 0x00000020, /* apply 90 degree rotation to the blt */ + PVR2D_BLIT_ROT_180 = 0x00000040, /* apply 180 degree rotation to the blt */ + PVR2D_BLIT_ROT_270 = 0x00000080, /* apply 270 degree rotation to the blt */ + PVR2D_BLIT_COPYORDER_TL2BR = 0x00000100, /* copy order overrides */ + PVR2D_BLIT_COPYORDER_BR2TL = 0x00000200, + PVR2D_BLIT_COPYORDER_TR2BL = 0x00000400, + PVR2D_BLIT_COPYORDER_BL2TR = 0x00000800, + PVR2D_BLIT_COLKEY_SOURCE = 0x00001000, /* Key colour is on the source surface */ + PVR2D_BLIT_COLKEY_DEST = 0x00002000, /* Key colour is on the destination surface */ + PVR2D_BLIT_COLKEY_MASKED = 0x00004000, /* Mask enabled for colour key */ + PVR2D_BLIT_COLKEY_OP_PASS = 0x00008000, /* Colour key op = pass */ + PVR2D_BLIT_COLKEY_OP_REJECT = 0x00010000, /* Colour key op = reject */ + PVR2D_BLIT_PATH_2DCORE = 0x00100000, /* Blt via dedicated 2D Core or PTLA */ + PVR2D_BLIT_PATH_3DCORE = 0x00200000, /* Blt via 3D Core */ + PVR2D_BLIT_PATH_SWBLT = 0x00400000, /* Blt via host software */ + PVR2D_BLIT_NO_SRC_SYNC_INFO = 0x00800000, /* Dont send a source sync info*/ + PVR2D_BLIT_ISSUE_STATUS_UPDATES = 0x01000000, /* Issue status updates */ } PVR2DBLITFLAGS; @@ -201,7 +218,7 @@ typedef enum PVR2D_ALPHA_OP_SRCP_DSTINV = 2 /* premultiplied source alpha : Cdst = Csrc + Cdst*(1-Asrc) */ } PVR2D_ALPHABLENDFUNC; -/* blend ops for fully specified alpha */ +/* blend ops for fully specified alpha (SGX 2D Core only) */ typedef enum { PVR2D_BLEND_OP_ZERO = 0, @@ -213,7 +230,7 @@ typedef enum PVR2D_BLEND_OP_DST_PLUS_GLOBAL = 6 }PVR2D_BLEND_OP; -/* 2D Core Fully specified alpha blend : pAlpha field of PVR2DBLTINFO structure */ +/* SGX 2D Core Fully specified alpha blend : pAlpha field of PVR2DBLTINFO structure */ /* a fully specified Alpha Blend operation is defined as */ /* DST (ALPHA) = (ALPHA_1 * SRC (ALPHA)) + (ALPHA_3 * DST (ALPHA)) */ /* DST (RGB) = (ALPHA_2 * SRC (RGB)) + (ALPHA_4 * DST (RGB)) */ @@ -279,6 +296,7 @@ typedef struct _PVR2DISPLAYINFO }PVR2DDISPLAYINFO; + typedef struct _PVR2MISCDISPLAYINFO { PVR2D_ULONG ulPhysicalWidthmm; @@ -355,11 +373,13 @@ typedef struct _PVR2DBLTINFO PVR2D_ULONG MaskSurfHeight; /* size of mask surface in pixels */ PPVR2D_ALPHABLT pAlpha; /* fully specified alpha blend (2DCore only) */ - + PVR2D_ULONG uSrcChromaPlane1; /* mem offset from start of source alloc to chroma plane 1 */ PVR2D_ULONG uSrcChromaPlane2; /* mem offset from start of source alloc to chroma plane 2 */ PVR2D_ULONG uDstChromaPlane1; /* mem offset from start of dest alloc to chroma plane 1 */ PVR2D_ULONG uDstChromaPlane2; /* mem offset from start of dest alloc to chroma plane 2 */ + + PVR2D_ULONG ColourKeyMask; /* 32 bit colour key mask, only valid when PVR2D_BLIT_COLKEY_MASKED is set */ }PVR2DBLTINFO, *PPVR2DBLTINFO; @@ -371,15 +391,23 @@ typedef struct _PVR2DRECT typedef struct { - PVR2DMEMINFO *pSurfMemInfo; /* surface memory */ + PVR2DMEMINFO *pSurfMemInfo; /* surface memory */ PVR2D_ULONG SurfOffset; /* byte offset from start of allocation to destination surface pixel 0,0 */ PVR2D_LONG Stride; /* signed stride */ - PVR2DFORMAT Format; /* PVR2D_3DFORMAT implies a 3D-only format in Format3D field */ - PVR2D_ULONG SurfWidth; /* surface size in pixels */ - PVR2D_ULONG SurfHeight; + PVR2DFORMAT Format; /* format */ + PVR2D_ULONG SurfWidth; /* surface width in pixels */ + PVR2D_ULONG SurfHeight; /* surface height in pixels */ } PVR2D_SURFACE, *PPVR2D_SURFACE; +typedef struct +{ + PVR2D_ULONG uChromaPlane1; /* YUV multiplane - byte offset from start of alloc to chroma plane 1 */ + PVR2D_ULONG uChromaPlane2; /* YUV multiplane - byte offset from start of alloc to chroma plane 2 */ + PVR2D_LONG Reserved[2]; /* Reserved, must be zero */ + +} PVR2D_SURFACE_EXT, *PPVR2D_SURFACE_EXT; + typedef struct { PVR2D_ULONG *pUseCode; /* USSE code */ @@ -391,27 +419,30 @@ typedef struct { PVR2D_SURFACE sDst; /* destination surface */ PVR2D_SURFACE sSrc; /* source surface */ - PVR2DRECT rcDest; /* destination rectangle */ - PVR2DRECT rcSource; /* source rectangle */ + PVR2DRECT rcDest; /* destination rectangle */ + PVR2DRECT rcSource; /* source rectangle */ PVR2D_HANDLE hUseCode; /* custom USE code (NULL implies source copy) */ PVR2D_ULONG UseParams[2]; /* per-blt params for use code */ - PVR2D_UCHAR RotationValue; /* Rotation setting */ + PVR2D_UCHAR RotationValue; /* Rotation setting */ } PVR2D_3DBLT, *PPVR2D_3DBLT; typedef struct { PVR2D_SURFACE sDst; /* destination surface */ - PVR2DRECT rcDest; /* destination rectangle; scaling is supported */ + PVR2DRECT rcDest; /* destination rectangle; scaling is supported */ PVR2D_SURFACE sSrc; /* source surface */ - PVR2DRECT rcSource; /* source rectangle; scaling is supported */ + PVR2DRECT rcSource; /* source rectangle; scaling is supported */ PPVR2D_SURFACE pSrc2; /* optional second source surface (NULL if not required) */ - PVR2DRECT* prcSource2; /* optional pSrc2 rectangle */ + PVR2DRECT* prcSource2; /* optional pSrc2 rectangle */ PVR2D_HANDLE hUseCode; /* custom USSE shader code (NULL implies default source copy) */ PVR2D_ULONG UseParams[2]; /* per-blt params for usse code */ - PVR2D_UINT uiNumTemporaryRegisters; /* no. of temporary registers used in custom shader code */ - PVR2D_BOOL bDisableDestInput; /* set true if the destination is output only */ -} PVR2D_3DBLT_EXT, *PPVR2D_3DBLT_EXT; + PVR2D_ULONG uiNumTemporaryRegisters; /* no. of temporary registers used in custom shader code */ + PVR2D_BOOL bDisableDestInput; /* set true if the destination is output only */ + PPVR2D_SURFACE_EXT pDstExt; /* Extended format params for dest */ + PPVR2D_SURFACE_EXT pSrcExt[2]; /* Extended format params for source 1 and 2 */ + PVR2D_LONG Reserved[4]; /* Reserved, must be zero */ +} PVR2D_3DBLT_EXT, *PPVR2D_3DBLT_EXT; typedef struct { @@ -425,8 +456,20 @@ typedef struct PPVR2D_YUVCOEFFS psYUVCoeffs; /* YUV Coeffs needed for RGB conversion */ PVR2D_UINT uiNumLayers; /* no. of YUV planes */ PVR2D_UCHAR RotationValue; /* Rotation setting */ + PVR2D_SURFACE sSrcSubpic[6]; /* subpic source surfaces */ + PVR2DRECT rcSubpicSource[6]; /* source rectangle */ + PVR2DRECT rcSubpicDest[6]; /* subpicture destination rectangle */ + PVR2DMEMINFO *pPalMemInfo[6]; /* source/pattern palette memory containing argb8888 colour table */ + PVR2D_ULONG PalOffset[6]; /* byte offset from start of allocation to start of palette */ } PVR2D_VPBLT, *PPVR2D_VPBLT; + typedef struct + { + PVR2D_SURFACE sDst; /* destination surface */ + PVR2DRECT rcDest; /* destination rectangle */ + PVR2DRECT rcSource; /* source rectangle */ + } PVR2D_WIDIBLT, *PPVR2D_WIDIBLT; + #define MAKE_COPY_BLIT(src,soff,dest,doff,sx,sy,dx,dy,sz) typedef void* PVR2DCONTEXTHANDLE; @@ -504,27 +547,38 @@ typedef void* PVR2DFLIPCHAINHANDLE; #define PVR2D_PRESENT_PROPERTY_CLIPRECTS (1UL << 3) #define PVR2D_PRESENT_PROPERTY_INTERVAL (1UL << 4) - #define PVR2D_CREATE_FLIPCHAIN_SHARED (1UL << 0) #define PVR2D_CREATE_FLIPCHAIN_QUERY (1UL << 1) -#define PVR2D_CREATE_FLIPCHAIN_OEMOVERLAY (1UL << 2) -#define PVR2D_CREATE_FLIPCHAIN_AS_BLITCHAIN (1UL << 3) +#define PVR2D_CREATE_FLIPCHAIN_OEMOVERLAY (1UL << 2) +#define PVR2D_CREATE_FLIPCHAIN_AS_BLITCHAIN (1UL << 3) -/* Colour-key colours must be translated into argb8888 format */ +/* Colour-key colour must be translated into argb8888 format */ #define CKEY_8888(P) (P) #define CKEY_4444(P) (((P&0xF000UL)<<16) | ((P&0x0F00UL)<<12) | ((P&0x00F0UL)<<8) | ((P&0x000FUL)<<4)) #define CKEY_1555(P) (((P&0x8000UL)<<16) | ((P&0x7C00UL)<<9) | ((P&0x3E0UL)<<6) | ((P&0x1FUL)<<3)) #define CKEY_565(P) (((P&0xF800UL)<<8) | ((P&0x7E0UL)<<5) | ((P&0x1FUL)<<3)) #define CKEY_MASK_8888 0x00FFFFFFUL #define CKEY_MASK_4444 0x00F0F0F0UL -#define CKEY_MASK_1555 0x00F8F8F8UL +#define CKEY_MASK_1555 0x00F8F8F8UL /* Alpha is not normally included in the key test */ #define CKEY_MASK_565 0x00F8FCF8UL +/* Fill colours must be translated into argb8888 format */ +#define CFILL_4444(P) (((P&0xF000UL)<<16) | ((P&0x0F00UL)<<12) | ((P&0x00F0UL)<<8) | ((P&0x000FUL)<<4)) +#define CFILL_1555(P) (((P&0x8000UL)<<16) | ((P&0x7C00UL)<<9) | ((P&0x3E0UL)<<6) | ((P&0x1FUL)<<3)) +#define CFILL_565(P) (((P&0xF800UL)<<8) | ((P&0x7E0UL)<<5) | ((P&0x1FUL)<<3)) + +/* PVR2DCreateDeviceContext flags */ +#define PVR2D_XSERVER_PROC 0x00000001UL /*!< Set for the Xserver connection */ + +/* PVR2DMemAlloc flags */ +#define PVR2D_MEM_UNCACHED 0x00000000UL /* Default */ +#define PVR2D_MEM_CACHED 0x00000001UL /* Caller must flush and sync when necessary */ +#define PVR2D_MEM_WRITECOMBINE 0x00000002UL /* Functions that the library exports */ PVR2D_IMPORT -PVR2D_INT PVR2DEnumerateDevices(PVR2DDEVICEINFO *pDevInfo); +int PVR2DEnumerateDevices(PVR2DDEVICEINFO *pDevInfo); PVR2D_IMPORT PVR2DERROR PVR2DCreateDeviceContext(PVR2D_ULONG ulDevID, @@ -676,6 +730,20 @@ PVR2DERROR PVR2DBlt3DExt (const PVR2DCONTEXTHANDLE hContext, const PPVR2D_3DBLT_ PVR2D_IMPORT PVR2DERROR PVR2DBltVideo (const PVR2DCONTEXTHANDLE hContext, const PPVR2D_VPBLT pBltVP); + +PVR2D_IMPORT +PVR2DERROR PVR2DScaleBltEx (const PVR2DCONTEXTHANDLE hContext, const PPVR2D_3DBLT pBlt3D, + const PVR2D_ULONG color, const PVR2D_INT isFixedSize, const PVR2DRECT *pFillRect); + +PVR2D_EXPORT +PVR2DERROR PVR2D_GetSrcRect(PVR2DRECT *pSrc, PVR2DRECT *pDest, + PVR2D_INT tgtXOffset, PVR2D_INT tgtYOffset, + PVR2D_UINT tgtWidth, PVR2D_UINT tgtHeight, + PVR2D_UINT winWidth, PVR2D_UINT winHeight); + +PVR2D_IMPORT +PVR2DERROR PVR2DBltWidi (const PVR2DCONTEXTHANDLE hContext, const PPVR2D_WIDIBLT pBltWidi); + #ifdef __cplusplus } #endif diff --git a/src/vc1_header.h b/src/vc1_header.h index f37ebcf..533bd2f 100644 --- a/src/vc1_header.h +++ b/src/vc1_header.h @@ -296,13 +296,43 @@ struct context_VC1_s { /* Aux MSB buffer */ struct psb_buffer_s aux_msb_buffer; psb_buffer_p bitplane_buffer; + struct psb_buffer_s bitplane_hw_buffer; /* For hw parase */ uint32_t *p_range_mapping_base; /* pointer to ui32RangeMappingBase in CMD_HEADER_VC1 */ + uint32_t *p_range_mapping_base1; uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER_VC1 */ + uint32_t *slice_first_pic_last; + uint32_t *alt_output_flags; }; typedef struct context_VC1_s *context_VC1_p; +/* VC1 Sequence Header Data Bit Positions Within 32 bit Command Word */ +#define VC1_SEQHDR_EXTENDED_DMV 0 +#define VC1_SEQHDR_PSF 1 +#define VC1_SEQHDR_SECONDFIELD 2 +#define VC1_SEQHDR_FINTERPFLAG 3 +#define VC1_SEQHDR_TFCNTRFLAG 4 +#define VC1_SEQHDR_INTERLACE 5 +#define VC1_SEQHDR_PULLDOWN 6 +#define VC1_SEQHDR_POSTPROCFLAG 7 +#define VC1_SEQHDR_VSTRANSFORM 8 +#define VC1_SEQHDR_DQUANT 9 +#define VC1_SEQHDR_EXTENDED_MV 11 +#define VC1_SEQHDR_FASTUVMC 12 +#define VC1_SEQHDR_LOOPFILTER 13 +#define VC1_SEQHDR_REFDIST_FLAG 14 +#define VC1_SEQHDR_PANSCAN_FLAG 15 +#define VC1_SEQHDR_MAXBFRAMES 16 +#define VC1_SEQHDR_RANGERED 19 +#define VC1_SEQHDR_SYNCMARKER 20 +#define VC1_SEQHDR_MULTIRES 21 +#define VC1_SEQHDR_QUANTIZER 22 +#define VC1_SEQHDR_OVERLAP 24 +#define VC1_SEQHDR_PROFILE 25 +#define VC1_SEQHDR_PICTYPE 27 +#define VC1_SEQHDR_ICFLAG 29 +#define VC1_SEQHDR_FCM_CURRPIC 30 #if 0 diff --git a/src/vc1_idx.c b/src/vc1_idx.c index d9b4535..0966845 100644 --- a/src/vc1_idx.c +++ b/src/vc1_idx.c @@ -112,6 +112,7 @@ IMG_UINT16 gaui16vc1VlcIndexData[83][3] = { {0, 4, 6869}, /* vc1DEC_Two_Field_Ref_Ilace_MV_7.out */ }; + const IMG_UINT8 gui8vc1VlcIndexSize = 83; /* EOF */ diff --git a/src/vc1_vlc.c b/src/vc1_vlc.c index e588bfa..259b1f4 100644 --- a/src/vc1_vlc.c +++ b/src/vc1_vlc.c @@ -7158,7 +7158,5 @@ IMG_UINT16 gaui16vc1VlcTableData[] = { 4, 2, 28, }; -IMG_UINT32 gaui32vc1VlcPackedTableData[7045]; +//IMG_UINT32 gaui32vc1VlcPackedTableData[7045]; const IMG_UINT16 gui16vc1VlcTableSize = 7045; - -/* EOF */ diff --git a/src/x11/psb_coverlay.c b/src/x11/psb_coverlay.c index 1afb70f..e7476fa 100644 --- a/src/x11/psb_coverlay.c +++ b/src/x11/psb_coverlay.c @@ -55,6 +55,19 @@ typedef struct x11_rect_list { struct x11_rect_list * next; } psb_x11_clip_list_t; +typedef struct { + /*src coordinate*/ + short srcx; + short srcy; + unsigned short sWidth; + unsigned short sHeight; + /*dest coordinate*/ + short destx; + short desty; + unsigned short dWidth; + unsigned short dHeight; +} psb_overlay_rect_t, *psb_overlay_rect_p; + static int psb_x11_getWindowCoordinate(Display * display, Window x11_window_id, @@ -386,18 +399,41 @@ psb_x11_createWindowClipBoxList(Display * display, return 0; } +static int psb_cleardrawable_stopoverlay( + VADriverContextP ctx, + Drawable draw, /* X Drawable */ + short destx, + short desty, + unsigned short destw, + unsigned short desth +) +{ + INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; + + XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, destx, desty, destw, desth); + XSync((Display *)ctx->native_dpy, False); + + driver_data->cur_displaying_surface = VA_INVALID_SURFACE; + driver_data->last_displaying_surface = VA_INVALID_SURFACE; + + return 0; +} + static VAStatus psb_DisplayRGBASubpicture( PsbVASurfaceRec *subpicture, VADriverContextP ctx, - GC gc, - Drawable draw, /* X Drawable */ - int win_width, - int win_height, - int surface_x, - int surface_y + int win_width, + int win_height, + int surface_x, + int surface_y, + int surface_w, + int surface_h, + psb_extvideo_subtitle subtitle ) { INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; XImage *ximg = NULL; Visual *visual; PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); @@ -405,145 +441,483 @@ static VAStatus psb_DisplayRGBASubpicture( int image_width, image_height, width, height, size; int srcx, srcy, srcw, srch; int destx, desty, destw, desth; - int depth; + int depth, i; if (subpicture->fourcc != VA_FOURCC_RGBA){ psb__error_message("%s: Invalid image format, ONLY support RGBA subpicture now.\n", __func__); return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; } - /*clear frame buffer*/ - XSetForeground((Display *)ctx->native_dpy, gc, 0); - XFillRectangle((Display *)ctx->native_dpy, draw, gc, 0, 0, win_width, win_height); - XSync((Display *)ctx->native_dpy, False); - srcx = subpicture->subpic_srcx; - srcy = subpicture->subpic_srcy; - srcw = subpicture->subpic_srcw; - srch = subpicture->subpic_srch; + for (i = 0; subpicture != NULL; subpicture = subpicture->next, i++) { + srcx = subpicture->subpic_srcx; + srcy = subpicture->subpic_srcy; + srcw = subpicture->subpic_srcw; + srch = subpicture->subpic_srch; + + destx = subpicture->subpic_dstx + surface_x; + desty = subpicture->subpic_dsty + surface_y; + destw = subpicture->subpic_dstw; + desth = subpicture->subpic_dsth; + + image_width = subpicture->width; + image_height = subpicture->height; + size = subpicture->size; + + //clip in image region + if (srcx < 0) { + srcw += srcx; + srcx = 0; + } - destx = subpicture->subpic_dstx + surface_x; - desty = subpicture->subpic_dsty + surface_y; - destw = subpicture->subpic_dstw; - desth = subpicture->subpic_dsth; - - image_width = subpicture->width; - image_height = subpicture->height; - size = subpicture->size; - - //clip in image region - if (srcx < 0) { - srcw += srcx; - srcx = 0; - } - - if (srcy < 0) { - srch += srcy; - srcy = 0; - } + if (srcy < 0) { + srch += srcy; + srcy = 0; + } - if ((srcx + srcw) > image_width) - srcw = image_width - srcx; - if ((srcy + srch) > image_height) - srch = image_height -srcy; + if ((srcx + srcw) > image_width) + srcw = image_width - srcx; + if ((srcy + srch) > image_height) + srch = image_height -srcy; - //clip in drawable region - if (destx < 0) { - destw += destx; - destx = 0; - } - - if (desty < 0) { - desth += desty; - desty = 0; + //clip in drawable region + if (destx < 0) { + destw += destx; + destx = 0; + } + + if (desty < 0) { + desth += desty; + desty = 0; + } + + if ((destx + destw) > surface_w) + destw = surface_w - destx; + if ((desty + desth) > surface_h) + desth = surface_h - desty; + + if (srcw <= destw) + width = srcw; + else + width = destw; + + if (srch <= desth) + height = srch; + else + height = desth; + + visual = DefaultVisual(ctx->native_dpy, 0); + depth = DefaultDepth(ctx->native_dpy, 0); + + ximg = XCreateImage(ctx->native_dpy, visual, depth, ZPixmap, 0, NULL, image_width, image_height, 32, 0 ); + + if (NULL == ximg) + { + psb__error_message("%s: XCreateImage failed! at L%d\n", __func__, __LINE__); + return VA_STATUS_ERROR_UNKNOWN; + } + + ximg->data = wsbmBOMap( bo, WSBM_ACCESS_READ); + if (NULL == ximg->data) { + psb__error_message("%s: Failed to map to ximg->data.\n", __func__); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + + pPriv->clear_key[i].subpic_dstx = destx; + pPriv->clear_key[i].subpic_dsty = desty; + pPriv->clear_key[i].subpic_dstw = destw; + pPriv->clear_key[i].subpic_dsth = desth; + if (psb_xrandr_extvideo_mode()) { + /*It is a HACK: Adjust subtitle to proper position.*/ + float xScale, yScale; + + xScale = win_width * 1.0 / surface_w; + yScale = win_height * 1.0 / surface_h; + destx = subpicture->subpic_dstx * xScale; + desty = subpicture->subpic_dsty * yScale; + } + XPutImage(ctx->native_dpy, output->output_drawable, output->gc, ximg, srcx, srcy, destx, desty, width, height); + XSync((Display *)ctx->native_dpy, False); + + if (psb_xrandr_extvideo_mode() && + (subtitle == ONLY_HDMI || subtitle == BOTH)) { + float xScale, yScale; + + xScale = pPriv->extend_display_width * 1.0 / surface_w; + yScale = pPriv->extend_display_height * 1.0 / surface_h; + + destx = subpicture->subpic_dstx * xScale; + desty = subpicture->subpic_dsty * yScale; + + XPutImage(ctx->native_dpy, output->extend_drawable, output->extend_gc, ximg, + srcx, srcy, destx, desty, destw, desth); + XSync((Display *)ctx->native_dpy, False); + } + + pPriv->subpic_clear_flag = 0; + ximg->data = NULL; + wsbmBOUnmap(bo); + if (NULL != ximg) + XDestroyImage(ximg); } - /*Temporary handle for testsuite subpicture destx/desty exceeding window width/height.*/ - if (destx > win_width) - destx %= win_width; - if (desty > win_height) - desty %= win_height; - /*****************/ - - if ((destx + destw) > win_width) - destw = win_width - destx; - if ((desty + desth) > win_height) - desth = win_height - desty; - - if (srcw <= destw) - width = srcw; - else - width = destw; + return VA_STATUS_SUCCESS; +} - if (srch <= desth) - height = srch; - else - height = desth; +static VAStatus psb_repaint_colorkey( + VADriverContextP ctx, + Drawable draw, /* X Drawable */ + VASurfaceID surface, + int x11_window_width, + int x11_window_height +) +{ + INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; + psb_x11_clip_list_t *pClipBoxList = NULL, *pClipNext = NULL; + unsigned int ui32NumClipBoxList = 0; + VARectangle *pVaWindowClipRects = NULL; + object_surface_p obj_surface = SURFACE(surface); + PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); + int i, ret; - visual = DefaultVisual(ctx->native_dpy, 0); - depth = DefaultDepth(ctx->native_dpy, 0); + /* get window clipbox */ + ret = psb_x11_createWindowClipBoxList(ctx->native_dpy, draw, &pClipBoxList, &ui32NumClipBoxList); + if(ret != 0) { + psb__error_message("%s: get window clip boxes error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } - ximg = XCreateImage(ctx->native_dpy, visual, depth, ZPixmap, 0, NULL, image_width, image_height, 32, 0 ); - - ximg->data = wsbmBOMap( bo, WSBM_ACCESS_READ); - if (NULL == ximg->data) { - psb__error_message("%s: Failed to map to ximg->data.\n", __func__); + pVaWindowClipRects = (VARectangle *)calloc(1, sizeof(VARectangle)*ui32NumClipBoxList); + if (!pVaWindowClipRects) { + psb_x11_freeWindowClipBoxList(pClipBoxList); return VA_STATUS_ERROR_ALLOCATION_FAILED; } - - XPutImage(ctx->native_dpy, draw, gc, ximg, srcx, srcy, destx, desty, width, height); - XSync((Display *)ctx->native_dpy, False); - - ximg->data = NULL; - wsbmBOUnmap(bo); - if (NULL != ximg) - XDestroyImage(ximg); + + memset(pVaWindowClipRects, 0, sizeof(VARectangle)*ui32NumClipBoxList); + pClipNext = pClipBoxList; +#ifdef CLIP_DEBUG + psb__error_message("%s: Total %d clip boxes\n", __func__, ui32NumClipBoxList); +#endif + for (i = 0; i < ui32NumClipBoxList; i++) + { + pVaWindowClipRects[i].x = pClipNext->rect.i32Left; + pVaWindowClipRects[i].y = pClipNext->rect.i32Top; + pVaWindowClipRects[i].width = pClipNext->rect.i32Right - pClipNext->rect.i32Left; + pVaWindowClipRects[i].height = pClipNext->rect.i32Bottom - pClipNext->rect.i32Top; +#ifdef CLIP_DEBUG + psb__error_message("%s: clip boxes Left Top (%d, %d) Right Bottom (%d, %d) width %d height %d\n", __func__, + pClipNext->rect.i32Left, pClipNext->rect.i32Top, + pClipNext->rect.i32Right, pClipNext->rect.i32Bottom, + pVaWindowClipRects[i].width, pVaWindowClipRects[i].height); +#endif + pClipNext = pClipNext->next; + } + + /* repaint the color key when window size changed*/ + if (!obj_surface->subpictures && + ((pPriv->x11_window_width != x11_window_width) || + (pPriv->x11_window_height != x11_window_height))) { + pPriv->x11_window_width = x11_window_width; + pPriv->x11_window_height = x11_window_height; + XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); + XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); + XSync((Display *)ctx->native_dpy, False); + } + + + if ((!obj_surface->subpictures) && + ((ui32NumClipBoxList != pPriv->last_num_clipbox) || + (memcmp(&pVaWindowClipRects[0], &(pPriv->last_clipbox[0]), (ui32NumClipBoxList > 16 ? 16: ui32NumClipBoxList)*sizeof(VARectangle))!=0))) { + pPriv->last_num_clipbox = ui32NumClipBoxList; + memcpy(&pPriv->last_clipbox[0], &pVaWindowClipRects[0],(ui32NumClipBoxList > 16 ? 16 : ui32NumClipBoxList)*sizeof(VARectangle)); + XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); + XSync((Display *)ctx->native_dpy, False); + } + free(pVaWindowClipRects); + psb_x11_freeWindowClipBoxList(pClipBoxList); + + return VA_STATUS_SUCCESS; +} + +static VAStatus psb_extendMode_getCoordinate( + PsbPortPrivPtr pPriv, + psb_xrandr_location extend_location, + short destx, + short desty, + short srcx, + short srcy, + float xScaleFactor, + float yScaleFactor, + int *x11_window_width, + int *x11_window_height, + psb_overlay_rect_p local_rect, + psb_overlay_rect_p extend_rect, + enum overlay_id_t *extend_overlay +) +{ + switch (extend_location) { + case LEFT_OF: + if ((destx + *x11_window_width) > (pPriv->display_width + pPriv->extend_display_width)) { + *x11_window_width = pPriv->display_width + pPriv->extend_display_width - destx; + } + if (((desty + *x11_window_height) < pPriv->display_height) && + ((desty + *x11_window_height) < pPriv->extend_display_height)) + local_rect->dHeight = extend_rect->dHeight = *x11_window_height; + else if (pPriv->display_height < pPriv->extend_display_height) { + local_rect->dHeight = pPriv->display_height - desty; + if ((desty + *x11_window_height) > pPriv->extend_display_height) + extend_rect->dHeight = *x11_window_height = pPriv->extend_display_height - desty; + else + extend_rect->dHeight = *x11_window_height; + } else { + extend_rect->dHeight = pPriv->extend_display_height - desty; + if ((desty + *x11_window_height) > pPriv->display_height) + local_rect->dHeight = *x11_window_height = pPriv->display_height - desty; + else + local_rect->dHeight = *x11_window_height; + } + + if ((destx < pPriv->extend_display_width) && ((destx + *x11_window_width) < pPriv->extend_display_width)) { + local_rect->dWidth = 0; + extend_rect->dWidth = *x11_window_width; + *extend_overlay = OVERLAY_A; + local_rect->destx = 0; + } + else if ((destx < pPriv->extend_display_width) && ((destx + *x11_window_width) >= pPriv->extend_display_width)) { + extend_rect->dWidth = pPriv->extend_display_width - destx; + local_rect->dWidth = *x11_window_width - extend_rect->dWidth; + local_rect->destx = 0; + } + else { + local_rect->dWidth = *x11_window_width; + extend_rect->dWidth = 0; + local_rect->destx = destx - pPriv->extend_display_width; + } + local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); + local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); + extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); + extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); + + local_rect->srcx = srcx + extend_rect->sWidth; + extend_rect->srcx = srcx; + local_rect->srcy = extend_rect->srcy = srcy; + + extend_rect->destx = destx; + local_rect->desty = extend_rect->desty = desty; + break; + case RIGHT_OF: + if ((destx + *x11_window_width) > (pPriv->display_width + pPriv->extend_display_width)) { + *x11_window_width = pPriv->display_width + pPriv->extend_display_width - destx; + } + if (((desty + *x11_window_height) < pPriv->display_height) && + ((desty + *x11_window_height) < pPriv->extend_display_height)) + local_rect->dHeight = extend_rect->dHeight = *x11_window_height; + else if (pPriv->display_height < pPriv->extend_display_height) { + local_rect->dHeight = pPriv->display_height - desty; + if ((desty + *x11_window_height) > pPriv->extend_display_height) + extend_rect->dHeight = *x11_window_height = pPriv->extend_display_height - desty; + else + extend_rect->dHeight = *x11_window_height; + } else { + extend_rect->dHeight = pPriv->extend_display_height - desty; + if ((desty + *x11_window_height) > pPriv->display_height) + local_rect->dHeight = *x11_window_height = pPriv->display_height - desty; + else + local_rect->dHeight = *x11_window_height; + } + + if ((destx < pPriv->display_width) && ((destx + *x11_window_width) < pPriv->display_width)) { + local_rect->dWidth = *x11_window_width; + extend_rect->dWidth = 0; + extend_rect->destx = 0; + } + else if ((destx < pPriv->display_width) && ((destx + *x11_window_width) >= pPriv->display_width)) { + local_rect->dWidth = pPriv->display_width - destx; + extend_rect->dWidth = *x11_window_width - local_rect->dWidth; + extend_rect->destx = 0; + } + else { + local_rect->dWidth = 0; + extend_rect->dWidth = *x11_window_width; + *extend_overlay = OVERLAY_A; + extend_rect->destx = destx - pPriv->display_width; + } + local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); + local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); + extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); + extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); + + local_rect->srcx = srcx; + extend_rect->srcx = srcx + local_rect->sWidth; + local_rect->srcy = extend_rect->srcy = srcy; + + local_rect->destx = destx; + local_rect->desty = extend_rect->desty = desty; + break; + case ABOVE: + if (((destx + *x11_window_width) < pPriv->display_width) && + ((destx + *x11_window_width) < pPriv->extend_display_width)) + local_rect->dWidth = extend_rect->dWidth = *x11_window_width; + else if (pPriv->display_width < pPriv->extend_display_width) { + local_rect->dWidth = pPriv->display_width - destx; + if ((destx + *x11_window_width) > pPriv->extend_display_width) + extend_rect->dWidth = *x11_window_width = pPriv->extend_display_width - destx; + else + extend_rect->dWidth = *x11_window_width; + } else { + extend_rect->dWidth = pPriv->extend_display_width - destx; + if ((destx + *x11_window_width) > pPriv->display_width) + local_rect->dWidth = *x11_window_width = pPriv->display_width - destx; + else + local_rect->dWidth = *x11_window_width; + } + + if ((desty + *x11_window_height) > (pPriv->display_height + pPriv->extend_display_height)) { + *x11_window_height = pPriv->display_height + pPriv->extend_display_height - desty; + } + + if ((desty < pPriv->extend_display_height) && ((desty + *x11_window_height) < pPriv->extend_display_height)) { + local_rect->dHeight = 0; + extend_rect->dHeight = *x11_window_height; + *extend_overlay = OVERLAY_A; + local_rect->desty = 0; + } + else if ((desty < pPriv->extend_display_height) && ((desty + *x11_window_height) >= pPriv->extend_display_height)) { + extend_rect->dHeight = pPriv->extend_display_height - desty; + local_rect->dHeight = *x11_window_height - extend_rect->dHeight; + local_rect->desty = 0; + } + else { + local_rect->dHeight = *x11_window_height; + extend_rect->dHeight = 0; + local_rect->desty = desty - pPriv->extend_display_height; + } + local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); + local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); + extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); + extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); + + local_rect->srcy = srcy + extend_rect->sHeight; + extend_rect->srcy = srcy; + local_rect->srcx = extend_rect->srcx = srcx; + + extend_rect->desty = desty; + local_rect->destx = extend_rect->destx = destx; + break; + case BELOW: + if (((destx + *x11_window_width) < pPriv->display_width) && + ((destx + *x11_window_width) < pPriv->extend_display_width)) + local_rect->dWidth = extend_rect->dWidth = *x11_window_width; + else if (pPriv->display_width < pPriv->extend_display_width) { + local_rect->dWidth = pPriv->display_width - destx; + if ((destx + *x11_window_width) > pPriv->extend_display_width) + extend_rect->dWidth = *x11_window_width = pPriv->extend_display_width - destx; + else + extend_rect->dWidth = *x11_window_width; + } else { + extend_rect->dWidth = pPriv->extend_display_width - destx; + if ((destx + *x11_window_width) > pPriv->display_width) + local_rect->dWidth = *x11_window_width = pPriv->display_width - destx; + else + local_rect->dWidth = *x11_window_width; + } + + if ((desty + *x11_window_height) > (pPriv->display_height + pPriv->extend_display_height)) { + *x11_window_height = pPriv->display_height + pPriv->extend_display_height - desty; + } + + if ((desty < pPriv->display_height) && ((desty + *x11_window_height) < pPriv->display_height)) { + local_rect->dHeight = *x11_window_height; + extend_rect->dHeight = 0; + extend_rect->desty = 0; + } + else if ((desty < pPriv->display_height) && ((desty + *x11_window_height) >= pPriv->display_height)) { + local_rect->dHeight = pPriv->display_height - desty; + extend_rect->dHeight = *x11_window_height - local_rect->dHeight; + extend_rect->desty = 0; + } + else { + local_rect->dHeight = 0; + extend_rect->dHeight = *x11_window_height; + *extend_overlay = OVERLAY_A; + extend_rect->desty = desty - pPriv->display_height; + } + local_rect->sWidth = (unsigned short)(local_rect->dWidth * xScaleFactor); + local_rect->sHeight = (unsigned short)(local_rect->dHeight * yScaleFactor); + extend_rect->sWidth = (unsigned short)(extend_rect->dWidth * xScaleFactor); + extend_rect->sHeight = (unsigned short)(extend_rect->dHeight * yScaleFactor); + + local_rect->srcy = srcy; + extend_rect->srcy = srcy + local_rect->sHeight; + local_rect->srcx = extend_rect->srcx = srcx; + + local_rect->desty = desty; + local_rect->destx = extend_rect->destx = destx; + break; + case NORMAL: + default: + break; + } + return VA_STATUS_SUCCESS; +} + +static void psb_init_subpicture(VADriverContextP ctx, PsbPortPrivPtr pPriv) +{ + INIT_DRIVER_DATA; + struct drm_psb_register_rw_arg regs; + unsigned int subpicture_enable_mask = REGRWBITS_DSPACNTR; + if ( !pPriv->subpicture_enabled ) { - struct drm_psb_register_rw_arg regs; - unsigned int subpicture_enable_mask = REGRWBITS_DSPACNTR; - - if (psb_xrandr_hdmi_connected()) + if (psb_xrandr_hdmi_enabled()) subpicture_enable_mask |= REGRWBITS_DSPBCNTR; - if (psb_xrandr_mipi1_connected()) - subpicture_enable_mask |= REGRWBITS_DSPCCNTR; - + if (psb_xrandr_mipi1_enabled()) + subpicture_enable_mask |= REGRWBITS_DSPCCNTR; + memset(®s, 0, sizeof(regs)); - regs.subpicture_enable_mask = subpicture_enable_mask; - pPriv->subpicture_enable_mask = subpicture_enable_mask; + regs.subpicture_enable_mask = subpicture_enable_mask; + pPriv->subpicture_enable_mask = subpicture_enable_mask; pPriv->subpicture_enabled = 1; - drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); + drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_REGISTER_RW, ®s, sizeof(regs)); } - return VA_STATUS_SUCCESS; } - -static int psb_cleardrawable_stopoverlay( +static void psb_clear_subpictures( VADriverContextP ctx, - Drawable draw, /* X Drawable */ - short destx, - short desty, - unsigned short destw, - unsigned short desth + PsbPortPrivPtr pPriv, + int win_width, + int win_height, + object_surface_p obj_surface ) { - INIT_DRIVER_DATA; INIT_OUTPUT_PRIV; - - XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, destx, desty, destw, desth); - XSync((Display *)ctx->native_dpy, False); - - psb_coverlay_stop(ctx); + PsbVASurfaceRec *subpicture = (PsbVASurfaceRec *)obj_surface->subpictures; + int i; - driver_data->cur_displaying_surface = VA_INVALID_SURFACE; - driver_data->last_displaying_surface = VA_INVALID_SURFACE; + if (subpicture == NULL) { + psb__information_message("Surface has no subpicture to render.\n"); + return; + } - return 0; + for (i = 0; subpicture != NULL; subpicture = subpicture->next, i++) { + if ((subpicture->subpic_dstx != pPriv->clear_key[i].subpic_dstx) || + (subpicture->subpic_dsty != pPriv->clear_key[i].subpic_dsty) || + (subpicture->subpic_dstw != pPriv->clear_key[i].subpic_dstw) || + (subpicture->subpic_dsth != pPriv->clear_key[i].subpic_dsth)) { + XSetForeground((Display *)ctx->native_dpy, output->gc, 0); + XFillRectangle((Display *)ctx->native_dpy, output->output_drawable, output->gc, 0, 0, win_width, win_height); + XSync((Display *)ctx->native_dpy, False); + if (psb_xrandr_extvideo_mode()) { + XSetForeground((Display *)ctx->native_dpy, output->extend_gc, 0); + XFillRectangle((Display *)ctx->native_dpy, output->extend_drawable, output->extend_gc, + 0, 0, pPriv->extend_display_width, pPriv->extend_display_height); + XSync((Display *)ctx->native_dpy, False); + } + pPriv->subpic_clear_flag = 1; + } + } + return; } -static int last_num_clipbox = 0; -static VARectangle last_clipbox[16]; -static unsigned int last_x11_window_width = 0, last_x11_window_height = 0; -static unsigned int show_extend_window = 0,show_local_window = 0; - VAStatus psb_putsurface_coverlay( VADriverContextP ctx, VASurfaceID surface, @@ -563,28 +937,20 @@ VAStatus psb_putsurface_coverlay( { INIT_DRIVER_DATA; INIT_OUTPUT_PRIV; - int i32GrabXorgRet = 0; int bIsVisible = 0; psb_x11_win_t winRect; - int i, ret; - psb_x11_clip_list_t * pClipBoxList = NULL, * pClipNext = NULL; - unsigned int ui32NumClipBoxList = 0; - VARectangle * pVaWindowClipRects = NULL; + int ret; int x11_window_width = destw, x11_window_height = desth; psb_xrandr_location extend_location; object_surface_p obj_surface = SURFACE(surface); PsbPortPrivRec *pPriv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); - short sWidth = (short)obj_surface->width, sHeight = (short)obj_surface->height; - int display_width, display_height, extend_display_width = 0, extend_display_height = 0; - unsigned short local_sWidth, local_sHeight, extend_sWidth, extend_sHeight; - short local_srcx, local_srcy, extend_srcx, extend_srcy; - short local_destx, local_desty, extend_destx, extend_desty; - unsigned short local_window_width = 0, local_window_height = 0; - unsigned short extend_window_width = 0, extend_window_height = 0; int primary_crtc_x, primary_crtc_y, extend_crtc_x, extend_crtc_y; - enum overlay_id_t local_overlay = OVERLAY_A, extend_overlay = OVERLAY_C; - enum pipe_id_t local_pipe = PIPEA, extend_pipe = PIPEA; + enum pipe_id_t local_pipe = PIPEA, extend_pipe = PIPEB; int surfacex = destx, surfacey = desty; + float xScaleFactor, yScaleFactor; + Rotation rotation = RR_Rotate_0; + psb_output_device local_device, extend_device; + psb_extvideo_subtitle subtitle; if (flags & VA_CLEAR_DRAWABLE) { psb__information_message("Clean draw with color 0x%08x\n",driver_data->clear_color); @@ -594,92 +960,75 @@ VAStatus psb_putsurface_coverlay( } /* get window screen coordination */ - i32GrabXorgRet = XGrabServer(ctx->native_dpy); ret = psb_x11_getWindowCoordinate(ctx->native_dpy, draw, &winRect, &bIsVisible); if (ret != 0) { - if (i32GrabXorgRet != 0) { - psb__error_message("%s: Failed to get X11 window coordinates error # %d\n", __func__, ret); - XUngrabServer(ctx->native_dpy); - } + psb__error_message("%s: Failed to get X11 window coordinates error # %d\n", __func__, ret); return VA_STATUS_ERROR_UNKNOWN; } if (!bIsVisible) { - if (i32GrabXorgRet != 0) - XUngrabServer(ctx->native_dpy); return VA_STATUS_SUCCESS; } + if (NULL == obj_surface) + { + psb__error_message("%s: Invalid surface id 0x%08x.\n", __func__, surface); + return VA_STATUS_ERROR_INVALID_SURFACE; + } + /* re-paint the color key if necessary */ if (output->output_drawable != draw) { - Window extend_win; - - ret = psb_xrandr_init(ctx); - if ( ret != 0) { - psb__error_message("%s: Failed to initialize psb xrandr error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; - } - - if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) { - ret = psb_xrandr_thread_create(ctx); - if ( ret != 0) { - psb__error_message("%s: Failed to create psb xrandr thread error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; - } - } - output->output_drawable = draw; - if (output->gc) XFreeGC((Display *)ctx->native_dpy, output->gc); output->gc = XCreateGC ((Display *)ctx->native_dpy, draw, 0, NULL); - /* paint the color key */ if (!obj_surface->subpictures) { XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); XSync((Display *)ctx->native_dpy, False); } - - if (psb_xrandr_extvideo_mode()) { - extend_win = psb_xrandr_create_full_screen_window(); - if (output->extend_drawable != extend_win) { - output->extend_drawable = extend_win; - if (output->extend_gc) - XFreeGC((Display *)ctx->native_dpy, output->extend_gc); - output->extend_gc = XCreateGC ((Display *)ctx->native_dpy, extend_win, 0, NULL); - - /* paint the color key */ - if (!obj_surface->subpictures) { - XSetForeground((Display *)ctx->native_dpy, output->extend_gc, pPriv->colorKey); - XFillRectangle((Display *)ctx->native_dpy, extend_win, output->extend_gc, 0, 0, extend_display_width, extend_display_height); - XSync((Display *)ctx->native_dpy, False); - } - } - } } - if (pPriv->is_mfld && psb_xrandr_outputchanged()) - psb_coverlay_stop(ctx); - - ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height); - if (ret != 0) { + ret = psb_xrandr_local_crtc_coordinate(&local_device, &primary_crtc_x, &primary_crtc_y, &pPriv->display_width, &pPriv->display_height, &rotation); + if (ret != VA_STATUS_SUCCESS) { psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); return VA_STATUS_ERROR_UNKNOWN; } - - if (psb_xrandr_single_mode() == 0) { - if (psb_xrandr_hdmi_connected()) - extend_pipe = PIPEB; - else if (psb_xrandr_mipi1_connected()) - extend_pipe = PIPEC; - - ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, - &extend_display_width, &extend_display_height, &extend_location); - if (ret != 0) { + switch (local_device) { + case LVDS0: + case MIPI0: + local_pipe = PIPEA; + break; + /* single HDMI */ + case HDMI: + local_pipe = PIPEB; + break; + case MIPI1: + local_pipe = PIPEC; + break; + } + + if (!psb_xrandr_single_mode()) { + + ret = psb_xrandr_extend_crtc_coordinate(&extend_device, &extend_crtc_x, &extend_crtc_y, + &pPriv->extend_display_width, &pPriv->extend_display_height, &extend_location, &rotation); + if (ret != VA_STATUS_SUCCESS) { psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); return VA_STATUS_ERROR_UNKNOWN; } + + switch (extend_device) { + case HDMI: + extend_pipe = PIPEB; + break; + case MIPI1: + extend_pipe = PIPEC; + break; + default: + psb__error_message("%s: Failed to get extend pipe\n", __func__); + break; + } } /*clip in the window area*/ @@ -703,12 +1052,6 @@ VAStatus psb_putsurface_coverlay( srcy = 0; } - if ((srcx + srcw) > sWidth) - srcw = sWidth - srcx; - - if ((srcy + srch) > sHeight) - srch = sHeight - srcy; - if ((destx + x11_window_width) > winRect.ui32Width) x11_window_width = winRect.ui32Width - destx; @@ -720,352 +1063,235 @@ VAStatus psb_putsurface_coverlay( desty += winRect.i32Top; /*clip in the screen area*/ + xScaleFactor = srcw * 1.0/x11_window_width; + yScaleFactor = srch * 1.0/x11_window_height; + if (destx < 0) { x11_window_width += destx; + srcx = (short)((-destx) * xScaleFactor); destx = 0; } if (desty < 0) { x11_window_height += desty; + srcy = (short)((-desty) * yScaleFactor); desty = 0; } - - if (psb_xrandr_clone_mode()) { - int min_display_width, min_display_height; - min_display_width = (display_width > extend_display_width) ? extend_display_width : display_width; - min_display_height = (display_height > extend_display_height) ? extend_display_height : display_height; - if ((destx + x11_window_width) > min_display_width) { - x11_window_width = min_display_width - destx; + + /* display by overlay */ + if (psb_xrandr_single_mode() || IS_MRST(driver_data)) { + if ((destx + x11_window_width) > pPriv->display_width) { + x11_window_width = pPriv->display_width - destx; + srcw = (unsigned short)(x11_window_width * xScaleFactor); } - if ((desty + x11_window_height) > min_display_height) { - x11_window_height = min_display_height - desty; + if ((desty + x11_window_height) > pPriv->display_height) { + x11_window_height = pPriv->display_height - desty; + srch = (unsigned short)(x11_window_height *yScaleFactor); } - local_sWidth = local_sHeight = extend_sWidth = extend_sHeight = 0; - local_srcx = local_srcy = extend_srcx = extend_srcy = 0; - local_destx = local_desty = extend_destx = extend_desty = 0; - } - else if (psb_xrandr_extend_mode()) { - float xScaleFactor, yScaleFactor; - int min_display_width, min_display_height; - min_display_width = (display_width > extend_display_width) ? extend_display_width : display_width; - min_display_height = (display_height > extend_display_height) ? extend_display_height : display_height; - - switch (extend_location) { - case LEFT_OF: - if ((destx + x11_window_width) > (display_width + extend_display_width)) { - x11_window_width = display_width + extend_display_width - destx; - } - if ((desty + x11_window_height) > min_display_height) { - x11_window_height = min_display_height - desty; - } - - if ((destx < extend_display_width) && ((destx + x11_window_width) < extend_display_width)) { - local_window_width = 0; - extend_window_width = x11_window_width; - extend_overlay = OVERLAY_A; - } - else if ((destx < extend_display_width) && ((destx + x11_window_width) >= extend_display_width)) { - extend_window_width = extend_display_width - destx; - local_window_width = x11_window_width - extend_window_width; - } - else { - local_window_width = x11_window_width; - extend_window_width = 0; - } - local_window_height = extend_window_height = x11_window_height; - - xScaleFactor = srcw * 1.0/x11_window_width; - extend_sWidth = (unsigned short)(extend_window_width * xScaleFactor); - local_sWidth = srcw - extend_sWidth; - local_sHeight = extend_sHeight = srch; - - local_srcx = srcx + extend_sWidth; - extend_srcx = srcx; - local_srcy = extend_srcy = srcy; - - local_destx = 0; - extend_destx = destx; - local_desty = extend_desty = desty; - break; - case RIGHT_OF: - if ((destx + x11_window_width) > (display_width + extend_display_width)) { - x11_window_width = display_width + extend_display_width - destx; - } - if ((desty + x11_window_height) > min_display_height) { - x11_window_height = min_display_height - desty; - } - - if ((destx < display_width) && ((destx + x11_window_width) < display_width)) { - local_window_width = x11_window_width; - extend_window_width = 0; - } - else if ((destx < display_width) && ((destx + x11_window_width) >= display_width)) { - local_window_width = display_width - destx; - extend_window_width = x11_window_width - local_window_width; - } - else { - local_window_width = 0; - extend_window_width = x11_window_width; - extend_overlay = OVERLAY_A; - } - local_window_height = extend_window_height = x11_window_height; - - xScaleFactor = srcw * 1.0/x11_window_width; - local_sWidth = (unsigned short)(local_window_width * xScaleFactor); - extend_sWidth = srcw - local_sWidth; - local_sHeight = extend_sHeight = srch; - - local_srcx = srcx; - extend_srcx = srcx + local_sWidth; - local_srcy = extend_srcy = srcy; - - local_destx = destx; - extend_destx = 0; - local_desty = extend_desty = desty; - break; - case ABOVE: - if ((destx + x11_window_width) > min_display_width) { - x11_window_width = min_display_width - destx; - } - if ((desty + x11_window_height) > (display_height + extend_display_height)) { - x11_window_height = display_height + extend_display_height - desty; - } - - if ((desty < extend_display_height) && ((desty + x11_window_height) < extend_display_height)) { - local_window_height = 0; - extend_window_height = x11_window_height; - extend_overlay = OVERLAY_A; - } - else if ((desty < extend_display_height) && ((desty + x11_window_height) >= extend_display_height)) { - extend_window_height = extend_display_height - desty; - local_window_height = x11_window_height - extend_window_height; - } - else { - local_window_height = x11_window_height; - extend_window_height = 0; - } - local_window_width = extend_window_width = x11_window_width; - - yScaleFactor = srch * 1.0/x11_window_height; - extend_sHeight = (unsigned short)(extend_window_height * yScaleFactor); - local_sHeight = srch - extend_sHeight; - local_sWidth = extend_sWidth = srcw; - - local_srcy = srcy + extend_sHeight; - extend_srcy = srcy; - local_srcx = extend_srcx = srcx; - - local_desty = 0; - extend_desty = desty; - local_destx = extend_destx = destx; - break; - case BELOW: - if ((destx + x11_window_width) > min_display_width) { - x11_window_width = min_display_width - destx; - } - if ((desty + x11_window_height) > (display_height + extend_display_height)) { - x11_window_height = display_height + extend_display_height - desty; - } - - if ((desty < display_height) && ((desty + x11_window_height) < display_height)) { - local_window_height = x11_window_height; - extend_window_height = 0; - } - else if ((desty < display_height) && ((desty + x11_window_height) >= display_height)) { - local_window_height = display_height - desty; - extend_window_height = x11_window_height - local_window_height; - } - else { - local_window_height = 0; - extend_window_height = x11_window_height; - extend_overlay = OVERLAY_A; - } - local_window_width = extend_window_width = x11_window_width; - - yScaleFactor = srch * 1.0/x11_window_height; - local_sHeight = (unsigned short)(local_window_height * yScaleFactor); - extend_sHeight = srch - local_sHeight; - local_sWidth = extend_sWidth = srcw; - - local_srcy = srcy; - extend_srcy = srcy + local_sHeight; - local_srcx = extend_srcx = srcx; - - local_desty = desty; - extend_desty = 0; - local_destx = extend_destx = destx; - break; - case NORMAL: - default: - local_sWidth = local_sHeight = extend_sWidth = extend_sHeight = 0; - local_srcx = local_srcy = extend_srcx = extend_srcy = 0; - local_destx = local_desty = extend_destx = extend_desty = 0; - break; + + ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); + if (ret != 0) { + psb__error_message("%s: Failed to repaint color key error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; } - } else { - if ((destx + x11_window_width) > display_width) { - x11_window_width = display_width - destx; - } - if ((desty + x11_window_height) > display_height) { - x11_window_height = display_height - desty; - } - local_sWidth = local_sHeight = extend_sWidth = extend_sHeight = 0; - local_srcx = local_srcy = extend_srcx = extend_srcy = 0; - local_destx = local_desty = extend_destx = extend_desty = 0; - } - /* get window clipbox */ - ret = psb_x11_createWindowClipBoxList(ctx->native_dpy, draw, &pClipBoxList, &ui32NumClipBoxList); - if(ret != 0) { - if (i32GrabXorgRet != 0) { - psb__error_message("%s: get window clip boxes error # %d\n", __func__, ret); - XUngrabServer(ctx->native_dpy); + psb_putsurface_overlay( + ctx, surface, srcx, srcy, srcw, srch, + /* screen coordinate */ + destx, desty, x11_window_width, x11_window_height, + flags, OVERLAY_A, local_pipe); + } else if (psb_xrandr_clone_mode()) { + psb_overlay_rect_t local_rect, extend_rect; + + if (output->extend_drawable) { + XDestroyWindow(ctx->native_dpy, output->extend_drawable); + output->extend_drawable = 0; + XFreeGC((Display *)ctx->native_dpy, output->extend_gc); + } + + if (((destx + x11_window_width) < pPriv->display_width) && + ((destx + x11_window_width) < pPriv->extend_display_width)) + local_rect.dWidth = extend_rect.dWidth = x11_window_width; + else if (pPriv->display_width < pPriv->extend_display_width) { + local_rect.dWidth = pPriv->display_width - destx; + if ((destx + x11_window_width) > pPriv->extend_display_width) + extend_rect.dWidth = x11_window_width = pPriv->extend_display_width - destx; + else + extend_rect.dWidth = x11_window_width; + } else { + extend_rect.dWidth = pPriv->extend_display_width - destx; + if ((destx + x11_window_width) > pPriv->display_width) + local_rect.dWidth = x11_window_width = pPriv->display_width - destx; + else + local_rect.dWidth = x11_window_width; } - return VA_STATUS_ERROR_UNKNOWN; - } - pVaWindowClipRects = (VARectangle *)calloc(1, sizeof(VARectangle)*ui32NumClipBoxList); - if (!pVaWindowClipRects) { - psb_x11_freeWindowClipBoxList(pClipBoxList); - return VA_STATUS_ERROR_ALLOCATION_FAILED; - } + if (((desty + x11_window_height) < pPriv->display_height) && + ((desty + x11_window_height) < pPriv->extend_display_height)) + local_rect.dHeight = extend_rect.dHeight = x11_window_height; + else if (pPriv->display_height < pPriv->extend_display_height) { + local_rect.dHeight = pPriv->display_height - desty; + if ((desty + x11_window_height) > pPriv->extend_display_height) + extend_rect.dHeight = x11_window_height = pPriv->extend_display_height - desty; + else + extend_rect.dHeight = x11_window_height; + } else { + extend_rect.dHeight = pPriv->extend_display_height - desty; + if ((desty + x11_window_height) > pPriv->display_height) + local_rect.dHeight = x11_window_height = pPriv->display_height - desty; + else + local_rect.dHeight = x11_window_height; + } + if ((driver_data->mipi0_rotation != VA_ROTATION_NONE) || + (driver_data->hdmi_rotation != VA_ROTATION_NONE)) { + local_rect.sWidth = srcw; + local_rect.sHeight = srch; + extend_rect.sWidth = srcw; + extend_rect.sHeight = srch; + } else { + local_rect.sWidth = (unsigned short)(local_rect.dWidth * xScaleFactor); + local_rect.sHeight = (unsigned short)(local_rect.dHeight * yScaleFactor); + extend_rect.sWidth = (unsigned short)(extend_rect.dWidth * xScaleFactor); + extend_rect.sHeight = (unsigned short)(extend_rect.dHeight * yScaleFactor); + } + ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); + if (ret != 0) { + psb__error_message("%s: Failed to repaint color key error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + psb_putsurface_overlay( + ctx, surface, srcx, srcy, extend_rect.sWidth, extend_rect.sHeight, + /* screen coordinate */ + destx, desty, extend_rect.dWidth, extend_rect.dHeight, + flags, OVERLAY_C, extend_pipe); + psb_putsurface_overlay( + ctx, surface, srcx, srcy, local_rect.sWidth, local_rect.sHeight, + /* screen coordinate */ + destx, desty, local_rect.dWidth, local_rect.dHeight, + flags, OVERLAY_A, local_pipe); + } else if (psb_xrandr_extend_mode()) { + psb_overlay_rect_t local_rect, extend_rect; + enum overlay_id_t extend_overlay = OVERLAY_C; + + if (output->extend_drawable) { + XDestroyWindow(ctx->native_dpy, output->extend_drawable); + output->extend_drawable = 0; + XFreeGC((Display *)ctx->native_dpy, output->extend_gc); + } + memset(&local_rect, 0, sizeof(psb_overlay_rect_t)); + memset(&extend_rect, 0, sizeof(psb_overlay_rect_t)); + psb_extendMode_getCoordinate(pPriv, extend_location, destx, desty, srcx, srcy, + xScaleFactor, yScaleFactor, &x11_window_width, &x11_window_height, + &local_rect, &extend_rect, &extend_overlay); + + ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); + if (ret != 0) { + psb__error_message("%s: Failed to repaint color key error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + + if ((extend_rect.dWidth > 0) && (extend_rect.dHeight > 0)) { + psb_putsurface_overlay( + ctx, surface, + extend_rect.srcx, extend_rect.srcy, extend_rect.sWidth, extend_rect.sHeight, + extend_rect.destx, extend_rect.desty, extend_rect.dWidth, extend_rect.dHeight, + flags, extend_overlay, extend_pipe); + } + if ((local_rect.dWidth > 0) && (local_rect.dHeight > 0)) { + psb_putsurface_overlay( + ctx, surface, + local_rect.srcx, local_rect.srcy, local_rect.sWidth, local_rect.sHeight, + local_rect.destx, local_rect.desty, local_rect.dWidth, local_rect.dHeight, + flags, OVERLAY_A, local_pipe); + } + } else if (psb_xrandr_extvideo_mode()) { + unsigned int xres, yres, xoffset, yoffset, overscanmode, pannelfitting; + psb_extvideo_center center; - memset(pVaWindowClipRects, 0, sizeof(VARectangle)*ui32NumClipBoxList); - pClipNext = pClipBoxList; -#ifdef CLIP_DEBUG - psb__error_message("%s: Total %d clip boxes\n", __func__, ui32NumClipBoxList); -#endif - for (i = 0; i < ui32NumClipBoxList; i++) - { - pVaWindowClipRects[i].x = pClipNext->rect.i32Left; - pVaWindowClipRects[i].y = pClipNext->rect.i32Top; - pVaWindowClipRects[i].width = pClipNext->rect.i32Right - pClipNext->rect.i32Left; - pVaWindowClipRects[i].height = pClipNext->rect.i32Bottom - pClipNext->rect.i32Top; -#ifdef CLIP_DEBUG - psb__error_message("%s: clip boxes Left Top (%d, %d) Right Bottom (%d, %d) width %d height %d\n", __func__, - pClipNext->rect.i32Left, pClipNext->rect.i32Top, - pClipNext->rect.i32Right, pClipNext->rect.i32Bottom, - pVaWindowClipRects[i].width, pVaWindowClipRects[i].height); -#endif - pClipNext = pClipNext->next; - } -#ifdef CLIP_DEBUG - psb__error_message("%s: dst (%d, %d) (%d, %d) width %d, height %d\n", __func__, - winRect.i32Left, winRect.i32Top, - winRect.i32Right, winRect.i32Bottom, - winRect.ui32Width, winRect.ui32Height); -#endif + switch(extend_location) { + case RIGHT_OF: + case BELOW: + case NORMAL: + break; + case LEFT_OF: + if (!pPriv->adjust_window_flag) { + destx = pPriv->extend_display_width + 1; + XMoveResizeWindow(ctx->native_dpy, output->output_drawable, destx, desty, x11_window_width, x11_window_height); + XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); + XFlush(ctx->native_dpy); + pPriv->adjust_window_flag = 1; + } + destx = destx - pPriv->extend_display_width; + break; + case ABOVE: + if (!pPriv->adjust_window_flag) { + desty = pPriv->extend_display_height + 1; + XMoveResizeWindow(ctx->native_dpy, output->output_drawable, destx, desty, x11_window_width, x11_window_height); + XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); + XFlush(ctx->native_dpy); + pPriv->adjust_window_flag = 1; + } + desty = desty - pPriv->extend_display_height; + break; + } + if ((destx + x11_window_width) > pPriv->display_width) + x11_window_width = pPriv->display_width - destx; + if ((desty + x11_window_height) > pPriv->display_height) + x11_window_height = pPriv->display_height - desty; - /* repaint the color key when window size changed*/ - if (!obj_surface->subpictures && - ((last_x11_window_width != x11_window_width) || - (last_x11_window_height != x11_window_height))) { - last_x11_window_width = x11_window_width; - last_x11_window_height = x11_window_height; - XSetForeground((Display *)ctx->native_dpy, output->gc, pPriv->colorKey); - XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); - XSync((Display *)ctx->native_dpy, False); - } - + psb_xrandr_extvideo_prop(&xres, &yres, &xoffset, &yoffset, ¢er, &subtitle, &overscanmode, &pannelfitting); - if ((!obj_surface->subpictures) && - ((ui32NumClipBoxList != last_num_clipbox) || - (memcmp(&pVaWindowClipRects[0], &last_clipbox[0], (ui32NumClipBoxList > 16 ? 16: ui32NumClipBoxList)*sizeof(VARectangle))!=0))) { - last_num_clipbox = ui32NumClipBoxList; - memcpy(&last_clipbox[0], &pVaWindowClipRects[0],(ui32NumClipBoxList > 16 ? 16 : ui32NumClipBoxList)*sizeof(VARectangle)); + if(!pPriv->create_window_flag) { + Window extend_win; + extend_win = psb_xrandr_create_full_screen_window(xoffset, yoffset, xres, yres); + if (output->extend_drawable != extend_win) { + output->extend_drawable = extend_win; + if (output->extend_gc) + XFreeGC((Display *)ctx->native_dpy, output->extend_gc); + output->extend_gc = XCreateGC ((Display *)ctx->native_dpy, extend_win, 0, NULL); - if (ui32NumClipBoxList <= 1) { - XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, 0, 0, x11_window_width, x11_window_height); - } else { - for (i = 0; i < ui32NumClipBoxList; i++) { - psb__error_message("cliprect # %d @(%d, %d) width %d height %d\n", i, - last_clipbox[i].x, last_clipbox[i].y, - last_clipbox[i].width, last_clipbox[i].height); - XFillRectangle((Display *)ctx->native_dpy, draw, output->gc, - last_clipbox[i].x - destx, last_clipbox[i].y - desty, - last_clipbox[i].width, last_clipbox[i].height); + /* paint the color key */ + if (!obj_surface->subpictures) { + XSetForeground((Display *)ctx->native_dpy, output->extend_gc, pPriv->colorKey); + XFillRectangle((Display *)ctx->native_dpy, extend_win, output->extend_gc, 0, 0, xres, yres); + XSync((Display *)ctx->native_dpy, False); + } } + pPriv->create_window_flag = 1; } - - XSync((Display *)ctx->native_dpy, False); - } - - if (pPriv->is_mfld && obj_surface->subpictures/*place holder for psb_subtitile_enable()*/) { - psb_DisplayRGBASubpicture((PsbVASurfaceRec *)obj_surface->subpictures, ctx, output->gc, draw, winRect.ui32Width, winRect.ui32Height, surfacex, surfacey); - } + ret = psb_repaint_colorkey(ctx, draw, surface, x11_window_width, x11_window_height); + if (ret != 0) { + psb__error_message("%s: Failed to repaint color key error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } - /* display by overlay */ - if (psb_xrandr_single_mode() || IS_MRST(driver_data)) { psb_putsurface_overlay( ctx, surface, srcx, srcy, srcw, srch, /* screen coordinate */ - destx, desty, - x11_window_width, x11_window_height, - flags, local_overlay, local_pipe); - } else if (psb_xrandr_clone_mode()) { - psb_putsurface_overlay( - ctx, surface, srcx, srcy, srcw, srch, - /* screen coordinate */ - destx, desty, - x11_window_width, x11_window_height, - flags, extend_overlay, extend_pipe); + xoffset, yoffset, xres, yres, + flags, OVERLAY_C, PIPEB); psb_putsurface_overlay( - ctx, surface, srcx, srcy, srcw, srch, + ctx, surface, srcx, srcy, srcw, srch, /* screen coordinate */ destx, desty, x11_window_width, x11_window_height, - flags, local_overlay, local_pipe); - } else if (psb_xrandr_extend_mode()) { - if ((extend_window_width > 0) && (extend_window_height > 0)) { - show_extend_window = 1; - psb_putsurface_overlay( - ctx, surface, - extend_srcx, extend_srcy, - extend_sWidth, extend_sHeight, - /* screen coordinate */ - extend_destx, extend_desty, - extend_window_width, extend_window_height, - flags, extend_overlay, extend_pipe); - } else if (show_extend_window) { - show_extend_window = 0; - psb_coverlay_stop(ctx); - } - if ((local_window_width > 0) && (local_window_height > 0)) { - show_local_window = 1; - psb_putsurface_overlay( - ctx, surface, - local_srcx, local_srcy, - local_sWidth, local_sHeight, - /* screen coordinate */ - local_destx, local_desty, - local_window_width, local_window_height, - flags, local_overlay, local_pipe); - } else if (show_local_window) { - show_local_window = 0; - psb_coverlay_stop(ctx); + flags, OVERLAY_A, local_pipe); + } + + /*Init Overlay subpicuture blending and make proper clear.*/ + if (pPriv->is_mfld && obj_surface->subpictures) { + PsbVASurfaceRec *subpicture = (PsbVASurfaceRec *)obj_surface->subpictures; + + psb_init_subpicture(ctx, pPriv); + /*clear changed subpicture zones in drawable.*/ + psb_clear_subpictures(ctx, pPriv, x11_window_width, x11_window_height, obj_surface); + if (pPriv->subpic_clear_flag) { + psb_DisplayRGBASubpicture(subpicture, ctx, x11_window_width, x11_window_height, + surfacex, surfacey, obj_surface->width, obj_surface->height, subtitle); } - } else if (psb_xrandr_extvideo_mode()) { - psb_putsurface_overlay( - ctx, surface, srcx, srcy, srcw, srch, - /* screen coordinate */ - 0, 0, - extend_display_width, extend_display_height, - flags, extend_overlay, extend_pipe); - psb_putsurface_overlay( - ctx, surface, srcx, srcy, srcw, srch, - /* screen coordinate */ - destx, desty, - x11_window_width, x11_window_height, - flags, local_overlay, local_pipe); } - - if (i32GrabXorgRet != 0) - XUngrabServer(ctx->native_dpy); - - free(pVaWindowClipRects); - psb_x11_freeWindowClipBoxList(pClipBoxList); return VA_STATUS_SUCCESS; } diff --git a/src/x11/psb_ctexture.c b/src/x11/psb_ctexture.c index 4315d87..df77569 100644 --- a/src/x11/psb_ctexture.c +++ b/src/x11/psb_ctexture.c @@ -49,52 +49,65 @@ #define SUBPIC(id) ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id )) #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) -static VAStatus psb_dri_init(VADriverContextP ctx, VASurfaceID surface, Drawable draw) +static VAStatus psb_extend_dri_init(VADriverContextP ctx, unsigned int destx, unsigned desty, unsigned destw, unsigned desth) { INIT_DRIVER_DATA; INIT_OUTPUT_PRIV; - int i, ret; - union dri_buffer *dri_buffer; + int i, ret; union dri_buffer *extend_dri_buffer; - PPVR2DMEMINFO dri2_bb_export_meminfo; struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; - if (psb_xrandr_extvideo_mode()) { + output->extend_drawable = (Window)psb_xrandr_create_full_screen_window(destx, desty, destw, desth); + if (!output->extend_drawable) { + psb__error_message("%s: Failed to create drawable for extend display # %d\n", __func__); + } + texture_priv->extend_dri_drawable = dri_get_drawable(ctx, output->extend_drawable); + if (!texture_priv->extend_dri_drawable) { + psb__error_message("%s(): Failed to get extend_dri_drawable\n", __func__); + return VA_STATUS_ERROR_UNKNOWN; + } - output->extend_drawable = (Window)psb_xrandr_create_full_screen_window(); + extend_dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->extend_dri_drawable); + if (!extend_dri_buffer) { + psb__error_message("%s(): Failed to get extend_dri_buffer\n", __func__); + return VA_STATUS_ERROR_UNKNOWN; + } - texture_priv->extend_dri_drawable = dri_get_drawable(ctx, output->extend_drawable); - if (!texture_priv->extend_dri_drawable) { - psb__error_message("%s(): Failed to get extend_dri_drawable\n", __func__); - return VA_STATUS_ERROR_UNKNOWN; - } + ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)extend_dri_buffer->dri2.name, &dri2_bb_export_meminfo); + if (ret != PVR2D_OK) { + psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } - extend_dri_buffer = dri_get_rendering_buffer(ctx, texture_priv->extend_dri_drawable); - if (!extend_dri_buffer) { - psb__error_message("%s(): Failed to get extend_dri_buffer\n", __func__); - return VA_STATUS_ERROR_UNKNOWN; - } + memcpy(&texture_priv->extend_dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport)); - ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)extend_dri_buffer->dri2.name, &dri2_bb_export_meminfo); + for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { + ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->extend_dri2_bb_export.hBuffers[i], &texture_priv->extend_blt_meminfo[i]); if (ret != PVR2D_OK) { - psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret); + psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); return VA_STATUS_ERROR_UNKNOWN; } + } - memcpy(&texture_priv->extend_dri2_bb_export, dri2_bb_export_meminfo->pBase, sizeof(PVRDRI2BackBuffersExport)); + texture_priv->extend_dri_init_flag = 1; - //must be Flip-Chain mode - for(i = 0; i < DRI2_BLIT_BUFFERS_NUM; i++) { - ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, texture_priv->extend_dri2_bb_export.hBuffers[i], &texture_priv->extend_blt_meminfo[i]); - if (ret != PVR2D_OK) { - psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); - return VA_STATUS_ERROR_UNKNOWN; - } - } - } + return VA_STATUS_SUCCESS; +} + +static VAStatus psb_dri_init(VADriverContextP ctx, Drawable draw) +{ + INIT_DRIVER_DATA; + INIT_OUTPUT_PRIV; + int i, ret; + + union dri_buffer *dri_buffer; + + PPVR2DMEMINFO dri2_bb_export_meminfo; + + struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; texture_priv->dri_drawable = dri_get_drawable(ctx, output->output_drawable); if (!texture_priv->dri_drawable) { @@ -108,7 +121,19 @@ static VAStatus psb_dri_init(VADriverContextP ctx, VASurfaceID surface, Drawable return VA_STATUS_ERROR_UNKNOWN; } - ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)dri_buffer->dri2.name, &dri2_bb_export_meminfo); + /* pixmap */ + if (!texture_priv->dri_drawable->is_window) { + ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)(dri_buffer->dri2.name & 0x00FFFFFF), &texture_priv->blt_meminfo_pixmap); + if (ret != PVR2D_OK) { + psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", ret); + return VA_STATUS_ERROR_UNKNOWN; + } + + texture_priv->dri_init_flag = 1; + return VA_STATUS_SUCCESS; + } + + ret = PVR2DMemMap(texture_priv->hPVR2DContext, 0, (PVR2D_HANDLE)(dri_buffer->dri2.name & 0x00FFFFFF), &dri2_bb_export_meminfo); if (ret != PVR2D_OK) { psb__error_message("%s(): PVR2DMemMap failed, ret = %d\n", __func__, ret); return VA_STATUS_ERROR_UNKNOWN; @@ -162,59 +187,129 @@ VAStatus psb_putsurface_ctexture( INIT_DRIVER_DATA; INIT_OUTPUT_PRIV; int ret; - int primary_crtc_x, primary_crtc_y, extend_crtc_x, extend_crtc_y; - int display_width, display_height, extend_display_width, extend_display_height; - psb_xrandr_location extend_location; + int local_crtc_x, local_crtc_y, extend_crtc_x, extend_crtc_y; + int display_width = 0, display_height = 0, extend_display_width = 0, extend_display_height = 0; + int surface_width, surface_height; + psb_xrandr_location extend_location = NORMAL; + psb_extvideo_subtitle subtitle = NOSUBTITLE; object_surface_p obj_surface = SURFACE(surface); psb_surface_p psb_surface; - + Rotation local_rotation, extend_rotation; + psb_output_device local_device, extend_device; + unsigned short tmp; struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; + obj_surface = SURFACE(surface); - psb_surface = obj_surface->psb_surface; + if (NULL == obj_surface) + { + psb__error_message("%s: Invalid surface ID 0x%08x.\n", __func__, surface); + return VA_STATUS_ERROR_INVALID_SURFACE; + } - if (output->output_drawable != draw) { - output->output_drawable = draw; - ret = psb_xrandr_init(ctx); - if ( ret != 0) { - psb__error_message("%s: Failed to initialize psb xrandr error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; + if(driver_data->video_rotate == VA_ROTATION_NONE) { + psb_surface = obj_surface->psb_surface; + surface_width = obj_surface->width; + surface_height = obj_surface->height; + } else { + psb_surface = obj_surface->psb_surface_rotate; + if (driver_data->video_rotate != VA_ROTATION_180) { + tmp = srcw; + srcw = srch; + srch = tmp; } + surface_width = obj_surface->width_r; + surface_height = obj_surface->height_r; } - if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) { - ret = psb_xrandr_thread_create(ctx); - if ( ret != 0) { - psb__error_message("%s: Failed to create psb xrandr thread error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; - } + if(!psb_surface) + psb_surface = obj_surface->psb_surface; + + if (output->output_drawable != draw) { + output->output_drawable = draw; + if (texture_priv->dri_init_flag) + texture_priv->drawable_update_flag = 1; } if (!texture_priv->dri_init_flag) { - ret = psb_dri_init(ctx, surface, draw); - if (ret != VA_STATUS_SUCCESS) - return VA_STATUS_ERROR_UNKNOWN; + texture_priv->destw_save = destw; + texture_priv->desth_save = desth; + } else { + if (texture_priv->destw_save != destw || texture_priv->desth_save != desth) { + texture_priv->destw_save = destw; + texture_priv->desth_save = desth; + texture_priv->drawable_update_flag = 1; + } } - if (psb_xrandr_clone_mode()) { - psb__information_message("psb_putsurface_ctexture: current mode is Clone\n"); - } else if (psb_xrandr_extend_mode()) { - ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height); - if (ret != 0) { - psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; - } - display_width += 1; - display_height += 1; + /* MRST */ + if (IS_MRST(driver_data)) { + ret = psb_xrandr_local_crtc_coordinate(&local_device, &local_crtc_x, &local_crtc_y, &display_width, &display_height, &local_rotation); + } else if (IS_MFLD(driver_data)) { + /* MDFLD */ + ret = psb_xrandr_local_crtc_coordinate(&local_device, &local_crtc_x, &local_crtc_y, &display_width, &display_height, &local_rotation); + } else { + psb__error_message("%s: unknown platform\n"); + return VA_STATUS_ERROR_UNKNOWN; + } - ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location); - if (ret != 0) { + if (ret != VA_STATUS_SUCCESS) { + psb__error_message("%s: Failed to get local crtc coordinates error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + + if (!psb_xrandr_single_mode() && IS_MFLD(driver_data)) { + ret = psb_xrandr_extend_crtc_coordinate(&extend_device, &extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location, &extend_rotation); + if (ret != VA_STATUS_SUCCESS) { psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); return VA_STATUS_ERROR_UNKNOWN; } - extend_display_width += 1; - extend_display_height += 1; + } + + //Reinit DRI if screen rotates + if (texture_priv->local_rotation_save != local_rotation) { + texture_priv->local_rotation_save = local_rotation; + texture_priv->dri_init_flag = 0; + } + if (texture_priv->extend_rotation_save != extend_rotation) { + texture_priv->extend_rotation_save = extend_rotation; + texture_priv->extend_dri_init_flag = 0; + } + + if (!psb_xrandr_extvideo_mode()) { + if (!texture_priv->dri_init_flag || texture_priv->drawable_update_flag) { + if (texture_priv->drawable_update_flag) { + psb__information_message("Drawable update, reinit ctexture and dri\n"); + psb_ctexture_deinit(ctx); + texture_priv->drawable_update_flag = 0; + } + + ret = psb_dri_init(ctx, output->output_drawable); + if (ret != VA_STATUS_SUCCESS) + return VA_STATUS_ERROR_UNKNOWN; + } + } + + /* Extend video */ + if (psb_xrandr_clone_mode() && local_rotation == extend_rotation) { + if (output->extend_drawable) { + XDestroyWindow(ctx->native_dpy, output->extend_drawable); + output->extend_drawable = 0; + texture_priv->extend_dri_init_flag = 0; + } + + psb__information_message("psb_putsurface_ctexture: Clone Mode\n"); + if (destw > display_width) + destw = display_width; + if (desth > display_height) + desth = display_height; + } else if (psb_xrandr_extend_mode()) { + if (output->extend_drawable) { + XDestroyWindow(ctx->native_dpy, output->extend_drawable); + output->extend_drawable = 0; + texture_priv->extend_dri_init_flag = 0; + } switch (extend_location) { case LEFT_OF: display_height = display_height > extend_display_height ? display_height : extend_display_height; @@ -248,62 +343,136 @@ VAStatus psb_putsurface_ctexture( default: break; } - psb__information_message("psb_putsurface_ctexture: current mode is Extend, Location: %08x\n", extend_location); + + psb__information_message("psb_putsurface_ctexture: Extend Mode, Location: %08x\n", extend_location); } else if (psb_xrandr_extvideo_mode()) { - psb__information_message("psb_putsurface_ctexture: current mode is ExtVideo, Location: %08x\n", extend_location); - ret = psb_xrandr_primary_crtc_coordinate(&primary_crtc_x, &primary_crtc_y, &display_width, &display_height); - if (ret != 0) { - psb__error_message("%s: Failed to get primary crtc coordinates error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; - } - display_width += 1; - display_height += 1; + unsigned int xres, yres, xoffset, yoffset, overscanmode, pannelfitting; + psb_extvideo_center center; - ret = psb_xrandr_extend_crtc_coordinate(&extend_crtc_x, &extend_crtc_y, &extend_display_width, &extend_display_height, &extend_location); - if (ret != 0) { - psb__error_message("%s: Failed to get extend crtc coordinates error # %d\n", __func__, ret); - return VA_STATUS_ERROR_UNKNOWN; + psb_xrandr_extvideo_prop(&xres, &yres, &xoffset, &yoffset, ¢er, &subtitle, &overscanmode, &pannelfitting); + + xres = extend_display_width - xoffset; + yres = extend_display_height - yoffset; + //Init DRI for extend display + if (!texture_priv->extend_dri_init_flag) { + ret = psb_extend_dri_init(ctx, xoffset, yoffset, xres, yres); + if (ret != VA_STATUS_SUCCESS) + return VA_STATUS_ERROR_UNKNOWN; } - extend_display_width += 1; - extend_display_height += 1; - psb__information_message("psb_putsurface_ctexture: ExtVideo coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", - srcx, srcy, srcw, srch, destx, desty, extend_display_width, extend_display_height, texture_priv->current_blt_buffer); + psb__information_message("psb_putsurface_ctexture: ExtendVideo Mode, Location: %08x\n", extend_location); + psb__information_message("psb_putsurface_ctexture: ExtVideo coordinate srcx= %d, srcy=%d, \ + srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", + srcx, srcy, srcw, srch, xoffset, yoffset, xres, yres, texture_priv->extend_current_blt_buffer); - psb_putsurface_textureblit(ctx, texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, extend_crtc_x, extend_crtc_y, - extend_display_width, extend_display_height, - obj_surface->width, obj_surface->height, + if (subtitle == BOTH || subtitle == ONLY_HDMI) + psb_putsurface_textureblit(ctx, texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, 0, 0, + xres, yres, 1, + surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); + else + psb_putsurface_textureblit(ctx, texture_priv->extend_blt_meminfo[texture_priv->extend_current_blt_buffer], surface, srcx, srcy, srcw, srch, 0, 0, + xres, yres, 0, + surface_width, surface_height, psb_surface->stride, psb_surface->buf.drm_buf, psb_surface->buf.pl_flags); dri_swap_buffer(ctx, texture_priv->extend_dri_drawable); texture_priv->extend_current_blt_buffer = (texture_priv->extend_current_blt_buffer + 1) & 0x01; - } + /* int this mode, destination retangle may be larger than MIPI resolution, if so setting it to MIPI resolution */ + if (destw > display_width) + destw = display_width; + if (desth > display_height) + desth = display_height; + + /* adjust local window on MIPI, make sure it is not covered by HDMI image */ + if (!texture_priv->adjust_window_flag) { + switch (extend_location) { + case ABOVE: + XMoveResizeWindow(ctx->native_dpy, output->output_drawable, 0, extend_display_height, destw, desth); + break; + case LEFT_OF: + XMoveResizeWindow(ctx->native_dpy, output->output_drawable, extend_display_width, 0, destw, desth); + break; + case BELOW: + case RIGHT_OF: + case NORMAL: + default: + break; + } + XFlush(ctx->native_dpy); + texture_priv->adjust_window_flag = 1; + } + + if (!texture_priv->dri_init_flag || texture_priv->drawable_update_flag) { + if (texture_priv->drawable_update_flag) { + psb__information_message("Drawable update, reinit ctexture and dri\n"); + psb_ctexture_deinit(ctx); + texture_priv->drawable_update_flag = 0; + } + + ret = psb_dri_init(ctx, output->output_drawable); + if (ret != VA_STATUS_SUCCESS) + return VA_STATUS_ERROR_UNKNOWN; + + } + } + + /* Main Video for pixmap*/ + if (!texture_priv->dri_drawable->is_window) { + psb__information_message("psb_putsurface_ctexture: Main video Pixmap, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", + srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer); + if (subtitle == BOTH) + psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo_pixmap, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, + surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); + else + psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo_pixmap, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 0, + surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); + + dri_swap_buffer(ctx, texture_priv->dri_drawable); + return VA_STATUS_SUCCESS; + } + + /* Main Video for window*/ if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_BUFFERS) { - psb__information_message("psb_putsurface_ctexture: SWAP BUFFER, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", + psb__information_message("psb_putsurface_ctexture: Main video, swap buffer, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", srcx, srcy, srcw, srch, destx, desty, destw, desth, texture_priv->current_blt_buffer); - //FIXME: Currently using Extend Mode to simulate ExtVideo mode. - //When resolution >= 864x480, Extend video has a white line on top. - //When resolution >= 864x480, testsuite should create a window with maximum resolution of 864x480, but now it creates window based on the virtual frame buffer resolution. - //When ExtVideo driver is ready, double check the above 2 issue. - psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, - obj_surface->width, obj_surface->height, - psb_surface->stride, psb_surface->buf.drm_buf, - psb_surface->buf.pl_flags); + + if (subtitle == BOTH) + psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, + surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); + else + psb_putsurface_textureblit(ctx, texture_priv->blt_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 0, + surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); dri_swap_buffer(ctx, texture_priv->dri_drawable); texture_priv->current_blt_buffer = (texture_priv->current_blt_buffer + 1) & 0x01; } else if (texture_priv->dri2_bb_export.ui32Type == DRI2_BACK_BUFFER_EXPORT_TYPE_SWAPCHAIN) { - psb__information_message("psb_putsurface_ctexture: FLIP CHAIN, Video coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", - srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height, texture_priv->current_blt_buffer); - - psb_putsurface_textureblit(ctx, texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, texture_priv->rootwin_width, texture_priv->rootwin_height, - obj_surface->width, obj_surface->height, - psb_surface->stride, psb_surface->buf.drm_buf, - psb_surface->buf.pl_flags); + psb__information_message("psb_putsurface_ctexture: Main video, flip chain, coordinate: srcx= %d, srcy=%d, srcw=%d, srch=%d, destx=%d, desty=%d, destw=%d, desth=%d, cur_buffer=%d\n", + srcx, srcy, srcw, srch, destx, desty, display_width, display_height, texture_priv->current_blt_buffer); + + if (subtitle == BOTH) + psb_putsurface_textureblit(ctx, texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, + display_width, display_height, 1, surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); + else + psb_putsurface_textureblit(ctx, texture_priv->flip_meminfo[texture_priv->current_blt_buffer], surface, srcx, srcy, srcw, srch, destx, desty, + display_width, display_height, 0, surface_width, surface_height, + psb_surface->stride, psb_surface->buf.drm_buf, + psb_surface->buf.pl_flags); dri_swap_buffer(ctx, texture_priv->dri_drawable); texture_priv->current_blt_buffer++; diff --git a/src/x11/psb_x11.c b/src/x11/psb_x11.c index 37118ac..bd4353d 100644 --- a/src/x11/psb_x11.c +++ b/src/x11/psb_x11.c @@ -46,34 +46,37 @@ #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) -static struct timeval tftarget = {0}; +//X error trap +static int x11_error_code = 0; +static int (*old_error_handler)(Display *, XErrorEvent *); + +static struct timeval inter_period = {0}; static void psb_doframerate(int fps) { - struct timeval tfdiff; + struct timeval time_deta; + + inter_period.tv_usec += 1000000 / fps; - tftarget.tv_usec += 1000000 / fps; - /* this is where we should be */ - if (tftarget.tv_usec >= 1000000) { - tftarget.tv_usec -= 1000000; - tftarget.tv_sec++; + /*recording how long it passed*/ + if (inter_period.tv_usec >= 1000000) { + inter_period.tv_usec -= 1000000; + inter_period.tv_sec++; } - /* this is where we are */ - gettimeofday(&tfdiff,(struct timezone *)NULL); + gettimeofday(&time_deta,(struct timezone *)NULL); + + time_deta.tv_usec = inter_period.tv_usec - time_deta.tv_usec; + time_deta.tv_sec = inter_period.tv_sec - time_deta.tv_sec; - tfdiff.tv_usec = tftarget.tv_usec - tfdiff.tv_usec; - tfdiff.tv_sec = tftarget.tv_sec - tfdiff.tv_sec; - if (tfdiff.tv_usec < 0) { - tfdiff.tv_usec += 1000000; - tfdiff.tv_sec--; + if (time_deta.tv_usec < 0) { + time_deta.tv_usec += 1000000; + time_deta.tv_sec--; } - /* See if we are already lagging behind */ - if (tfdiff.tv_sec < 0 || (tfdiff.tv_sec == 0 && tfdiff.tv_usec <= 0)) + if (time_deta.tv_sec < 0 || (time_deta.tv_sec == 0 && time_deta.tv_usec <= 0)) return; - /* Spin for awhile */ - select(0,NULL,NULL,NULL,&tfdiff); + select(0,NULL,NULL,NULL,&time_deta); } static uint32_t mask2shift(uint32_t mask) @@ -250,8 +253,6 @@ void yuv2pixel(uint32_t *pixel, int y, int u, int v) return vaStatus; } - - void *psb_x11_output_init(VADriverContextP ctx) { INIT_DRIVER_DATA; @@ -271,6 +272,7 @@ void *psb_x11_output_init(VADriverContextP ctx) psb_init_xvideo(ctx, output); + driver_data->color_key = 0x11; if (IS_MFLD(driver_data)) { /* force MFLD to use COVERLAY */ psb__information_message("Use client overlay mode for post-processing\n"); @@ -288,13 +290,25 @@ void *psb_x11_output_init(VADriverContextP ctx) driver_data->output_method = PSB_PUTSURFACE_FORCE_OVERLAY; } - if (getenv("PSB_VIDEO_CTEXTURE")) { + if (getenv("PSB_VIDEO_CTEXTURE") || + (driver_data->mipi1_rotation != VA_ROTATION_NONE) || + ((driver_data->mipi0_rotation != VA_ROTATION_NONE) && + (driver_data->hdmi_rotation != VA_ROTATION_NONE) && + (driver_data->mipi0_rotation != driver_data->hdmi_rotation)) + ) { psb__information_message("Putsurface force to use Client Texture\n"); driver_data->ctexture = 1; driver_data->output_method = PSB_PUTSURFACE_FORCE_CTEXTURE; + } else if (driver_data->mipi0_rotation != VA_ROTATION_NONE) { + driver_data->rotate = driver_data->mipi0_rotation; + } else if (driver_data->hdmi_rotation != VA_ROTATION_NONE) { + driver_data->rotate = driver_data->hdmi_rotation; } + if (driver_data->rotate == 4) + driver_data->rotate = 3; + if (getenv("PSB_VIDEO_COVERLAY")) { psb__information_message("Putsurface force to use Client Overlay\n"); @@ -305,14 +319,46 @@ void *psb_x11_output_init(VADriverContextP ctx) return output; } +static int +error_handler(Display *dpy, XErrorEvent *error) +{ + x11_error_code = error->error_code; + return 0; +} + void psb_x11_output_deinit(VADriverContextP ctx) { psb_deinit_xvideo(ctx); } -static int pnw_check_output_method(VADriverContextP ctx, int width, int height) +static void +x11_trap_errors(void) +{ + x11_error_code = 0; + old_error_handler = XSetErrorHandler(error_handler); +} + +static int +x11_untrap_errors(void) +{ + XSetErrorHandler(old_error_handler); + return x11_error_code; +} + +static int +is_window(Display *dpy, Drawable drawable) +{ + XWindowAttributes wattr; + + x11_trap_errors(); + XGetWindowAttributes(dpy, drawable, &wattr); + return x11_untrap_errors() == 0; +} + +static int pnw_check_output_method(VADriverContextP ctx, object_surface_p obj_surface, int width, int height, int destw, int desth, Drawable draw) { INIT_DRIVER_DATA; + if (driver_data->output_method == PSB_PUTSURFACE_FORCE_TEXTURE || driver_data->output_method == PSB_PUTSURFACE_FORCE_OVERLAY || driver_data->output_method == PSB_PUTSURFACE_FORCE_CTEXTURE || @@ -321,14 +367,15 @@ static int pnw_check_output_method(VADriverContextP ctx, int width, int height) return 0; } - if (width >= 2048 || height >= 2048) { - - psb__information_message("Clip resolution %dx%d, Putsurface fall back to use Client Texture\n", width, height); + if (!is_window(ctx->native_dpy, draw) || (IS_MRST(driver_data) && obj_surface->subpic_count > 0) || width >= 2048 || height >= 2048 || + /*FIXME: overlay path can't handle subpicture scaling. when surface size > dest box, fallback to texblit.*/ + (IS_MFLD(driver_data) && obj_surface->subpic_count && ((width > destw) || (height > desth)))) { + psb__information_message("Putsurface fall back to use Client Texture\n"); - driver_data->ctexture = 1; - driver_data->output_method = PSB_PUTSURFACE_FORCE_CTEXTURE; + driver_data->ctexture = 1; + driver_data->output_method = PSB_PUTSURFACE_FORCE_CTEXTURE; - psb_ctexture_init(ctx); + psb_ctexture_init(ctx); } return 0; @@ -375,14 +422,13 @@ VAStatus psb_PutSurface( } if (driver_data->fixed_fps > 0) { - if ((tftarget.tv_sec == 0) && (tftarget.tv_usec == 0)) - gettimeofday(&tftarget,(struct timezone *)NULL); + if ((inter_period.tv_sec == 0) && (inter_period.tv_usec == 0)) + gettimeofday(&inter_period,(struct timezone *)NULL); psb_doframerate(driver_data->fixed_fps); } - if (IS_MFLD(driver_data)) - pnw_check_output_method(ctx, srcw, srch); + pnw_check_output_method(ctx, obj_surface, srcw, srch, destw, desth, draw); pthread_mutex_lock(&driver_data->output_mutex); diff --git a/src/x11/psb_xrandr.c b/src/x11/psb_xrandr.c index 4ac557d..611c2dd 100644 --- a/src/x11/psb_xrandr.c +++ b/src/x11/psb_xrandr.c @@ -1,13 +1,10 @@ #include "psb_xrandr.h" #include "psb_x11.h" +/* Global variable for xrandr */ psb_xrandr_info_p psb_xrandr_info; -static psb_xrandr_crtc_p crtc_head, crtc_tail; -static psb_xrandr_output_p output_head, output_tail; -static pthread_mutex_t psb_extvideo_mutex; -static XRRScreenResources *res; -Display *dpy; -Window root; + +#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData #define MWM_HINTS_DECORATIONS (1L << 1) typedef struct @@ -41,165 +38,289 @@ char* location2string(psb_xrandr_location location) } } -static psb_xrandr_output_p get_output_by_id(RROutput output_id) +static int RRrotation2VArotation(Rotation rotation) { - psb_xrandr_output_p p_output; - for (p_output = output_head; p_output; p_output = p_output->next) { - if (p_output->output_id == output_id) - return p_output; + switch (rotation) { + case RR_Rotate_0: + return VA_ROTATION_NONE; + case RR_Rotate_90: + return VA_ROTATION_270; + case RR_Rotate_180: + return VA_ROTATION_180; + case RR_Rotate_270: + return VA_ROTATION_90; } - return NULL; } - static psb_xrandr_crtc_p get_crtc_by_id(RRCrtc crtc_id) { psb_xrandr_crtc_p p_crtc; - for (p_crtc = crtc_head; p_crtc; p_crtc = p_crtc->next) + for (p_crtc = psb_xrandr_info->crtc_head; p_crtc; p_crtc = p_crtc->next) if (p_crtc->crtc_id == crtc_id) return p_crtc; return NULL; } -static void psb_extvideo_prop() +static void psb_xrandr_hdmi_property() { - psb_xrandr_crtc_p p_crtc; - psb_xrandr_output_p p_output; -#if 0 - int i, j, nprop, actual_format; - unsigned long nitems, bytes_after; Atom *props; Atom actual_type; + XRRPropertyInfo *propinfo; + int i, nprop, actual_format; + unsigned long nitems, bytes_after; + char* prop_name; unsigned char* prop; - unsigned char* prop_name; -#endif - psb_xrandr_info->output_changed = 1; - if (psb_xrandr_info->nconnected_output == 1) - { - for (p_output = output_head; p_output; p_output = p_output->next) - if (p_output->connection == RR_Connected) - psb_xrandr_info->primary_output = p_output; - for (p_crtc = crtc_head; p_crtc; p_crtc = p_crtc->next) - { - if (p_crtc->noutput == 0) - continue; - else - psb_xrandr_info->primary_crtc = p_crtc; + /* Check HDMI properties */ + props = XRRListOutputProperties(psb_xrandr_info->dpy, psb_xrandr_info->extend_output->output_id, &nprop); + if (!props) { + psb__error_message("Xrandr: XRRListOutputProperties failed\n", psb_xrandr_info->extend_output->output_id); + return; } - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode = SINGLE; - } - else if (psb_xrandr_info->nconnected_output >= 2) - { - for (p_output = output_head; p_output; p_output = p_output->next) - { - if (p_output->connection != RR_Connected) - continue; + psb__information_message("Xrandr: extend output %08x has %d properties\n", psb_xrandr_info->extend_output->output_id, nprop); - if (!strcmp(p_output->name, "MIPI0")) - { - psb_xrandr_info->primary_output = p_output; - psb_xrandr_info->primary_crtc = p_output->crtc; - } - else if (!strcmp(p_output->name, "MIPI1")) - { - psb_xrandr_info->mipi1_connected = 1; - psb_xrandr_info->extend_output = p_output; - psb_xrandr_info->extend_crtc = p_output->crtc; + for (i = 0; i < nprop; i++) { + XRRGetOutputProperty(psb_xrandr_info->dpy, psb_xrandr_info->extend_output->output_id, props[i], + 0, 100, False, False, AnyPropertyType, &actual_type, &actual_format, + &nitems, &bytes_after, &prop); + + propinfo = XRRQueryOutputProperty(psb_xrandr_info->dpy, psb_xrandr_info->extend_output->output_id, props[i]); + if (!propinfo) { + psb__error_message("Xrandr: get output %08x prop %08x failed\n", psb_xrandr_info->extend_output->output_id, props[i]); + return; } - else if (!strcmp(p_output->name, "TMDS0-1")) - { - psb_xrandr_info->hdmi_connected = 1; - psb_xrandr_info->extend_output = p_output; - psb_xrandr_info->extend_crtc = p_output->crtc; + + prop_name = XGetAtomName(psb_xrandr_info->dpy, props[i]); + + /* Currently all properties are XA_INTEGER, 32 */ + if (!strcmp(prop_name, "ExtVideoMode")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode); + } else if (!strcmp(prop_name, "ExtVideoMode_Xres")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_XRes = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_XRes (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_XRes); + } else if (!strcmp(prop_name, "ExtVideoMode_Yres")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_YRes = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_YRes (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_YRes); + } else if (!strcmp(prop_name, "ExtVideoMode_X_Offset")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_X_Offset = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_X_Offset (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_X_Offset); + } else if (!strcmp(prop_name, "ExtVideoMode_Y_Offset")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Y_Offset = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_Y_Offset (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Y_Offset); + } else if (!strcmp(prop_name, "ExtVideoMode_Center")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Center = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_Center (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Center); + } else if (!strcmp(prop_name, "ExtVideoMode_SubTitle")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_SubTitle = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtVideoMode_SubTitle (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_SubTitle); + } else if (!strcmp(prop_name, "ExtDesktopMode")) { + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: ExtDesktopMode (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode); + } else if (!strcmp(prop_name, "OverscanMode")) { + psb_xrandr_info->hdmi_extvideo_prop->OverscanMode = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: OverscanMode (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->OverscanMode); + } else if (!strcmp(prop_name, "PANELFITTING")) { + psb_xrandr_info->hdmi_extvideo_prop->PANELFITTING = (int)((INT32*)prop)[0]; + psb__information_message("Xrandr: PANELFITTING (%08x)\n", psb_xrandr_info->hdmi_extvideo_prop->PANELFITTING); } } +} - if (!psb_xrandr_info->primary_crtc || !psb_xrandr_info->extend_crtc || !psb_xrandr_info->primary_output || !psb_xrandr_info->extend_output) - { - psb__error_message("Xrandr: failed to get primary/extend crtc/output\n"); +static void psb_xrandr_mipi_location_init(psb_output_device_mode output_device_mode) +{ + psb_xrandr_crtc_p local_crtc, extend_crtc; + + switch (output_device_mode) { + case SINGLE_MIPI0: + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = SINGLE; + psb_xrandr_info->local_crtc[0]->location = NORMAL; return; - } + case SINGLE_MIPI1: + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = SINGLE; + psb_xrandr_info->local_crtc[1]->location = NORMAL; + return; + case MIPI0_MIPI1: + local_crtc = psb_xrandr_info->local_crtc[0]; + extend_crtc = psb_xrandr_info->local_crtc[1]; + break; + default: + break; + } - if (psb_xrandr_info->primary_crtc->x == 0 && psb_xrandr_info->primary_crtc->y == 0 \ - && psb_xrandr_info->extend_crtc->x == 0 && psb_xrandr_info->extend_crtc->y == 0) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode = CLONE; - else { - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode = EXTENDED; - - if (psb_xrandr_info->primary_crtc->y == psb_xrandr_info->extend_crtc->height) - psb_xrandr_info->extend_crtc->location = ABOVE; - else if (psb_xrandr_info->extend_crtc->y == psb_xrandr_info->primary_crtc->height) - psb_xrandr_info->extend_crtc->location = BELOW; - else if (psb_xrandr_info->primary_crtc->x == psb_xrandr_info->extend_crtc->width) - psb_xrandr_info->extend_crtc->location = LEFT_OF; - else if (psb_xrandr_info->extend_crtc->x == psb_xrandr_info->primary_crtc->width) - psb_xrandr_info->extend_crtc->location = RIGHT_OF; - } -#if 0 - props = XRRListOutputProperties(dpy, psb_xrandr_info->extend_output->output_id, &nprop); - for (i = 0; i < nprop; i++) { - XRRGetOutputProperty(dpy, psb_xrandr_info->extend_output->output_id, props[i], - 0, 100, False, False, AnyPropertyType, &actual_type, &actual_format, - &nitems, &bytes_after, &prop); + if (!local_crtc || !extend_crtc) { + psb__error_message("Failed to get crtc info\n"); + return; + } - XRRQueryOutputProperty(dpy, psb_xrandr_info->extend_output->output_id, props[i]); - prop_name = XGetAtomName(dpy, props[i]); - - if (!strcmp(prop_name, "ExtVideoMode")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_XRes")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_XRes = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_YRes")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_YRes = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_X_Offset")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_X_Offset = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_Y_Offset")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Y_Offset = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_Center")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Center = (int)((INT32*)prop)[j]; - else if (!strcmp(prop_name, "ExtVideoMode_SubTitle")) - for (j = 0; j < nitems; j++) - psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_SubTitle = (int)((INT32*)prop)[j]; - } + /* MIPI1 clone MIPI0 */ + if (local_crtc->x == 0 && local_crtc->y == 0 && + extend_crtc->x == 0 && extend_crtc->y == 0) { + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = CLONE; + extend_crtc->location = NORMAL; + } else { + /* MIPI1 entend MIPI0 */ + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = EXTENDED; + if (local_crtc->y == extend_crtc->height) + extend_crtc->location = ABOVE; + else if (extend_crtc->y == local_crtc->height) + extend_crtc->location = BELOW; + else if (local_crtc->x == extend_crtc->width) + extend_crtc->location = LEFT_OF; + else if (extend_crtc->x == local_crtc->width) + extend_crtc->location = RIGHT_OF; + } +} + +static void psb_xrandr_hdmi_location_init(psb_output_device_mode output_device_mode) +{ + psb_xrandr_crtc_p local_crtc, extend_crtc; - if (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == CLONE) + switch (output_device_mode) { + case SINGLE_HDMI: + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = SINGLE; psb_xrandr_info->extend_crtc->location = NORMAL; - else if (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == EXTENDED) { - if (psb_xrandr_info->primary_crtc->y == psb_xrandr_info->extend_crtc->height) - psb_xrandr_info->extend_crtc->location = ABOVE; - else if (psb_xrandr_info->extend_crtc->y == psb_xrandr_info->primary_crtc->height) - psb_xrandr_info->extend_crtc->location = BELOW; - else if (psb_xrandr_info->primary_crtc->x == psb_xrandr_info->extend_crtc->width) - psb_xrandr_info->extend_crtc->location = LEFT_OF; - else if (psb_xrandr_info->extend_crtc->x == psb_xrandr_info->primary_crtc->width) - psb_xrandr_info->extend_crtc->location = RIGHT_OF; + return; + case MIPI0_HDMI: + case MIPI0_MIPI1_HDMI: + local_crtc = psb_xrandr_info->local_crtc[0]; + extend_crtc = psb_xrandr_info->extend_crtc; + break; + case MIPI1_HDMI: + local_crtc = psb_xrandr_info->local_crtc[1]; + extend_crtc = psb_xrandr_info->extend_crtc; + break; + default: + break; + } + + if (!local_crtc || !extend_crtc) { + psb__error_message("Failed to get crtc info\n"); + return; + } + + if (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == CLONE) + psb_xrandr_info->extend_crtc->location = NORMAL; + + if (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == EXTENDED + || psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == EXTENDEDVIDEO) { + if (local_crtc->y == extend_crtc->height) + psb_xrandr_info->extend_crtc->location = ABOVE; + else if (extend_crtc->y == local_crtc->height) + psb_xrandr_info->extend_crtc->location = BELOW; + else if (local_crtc->x == extend_crtc->width) + psb_xrandr_info->extend_crtc->location = LEFT_OF; + else if (extend_crtc->x == local_crtc->width) + psb_xrandr_info->extend_crtc->location = RIGHT_OF; + } +} + +static void psb_xrandr_coordinate_init(VADriverContextP ctx) +{ + INIT_DRIVER_DATA; + psb_xrandr_output_p p_output; + + psb_xrandr_info->output_changed = 1; + + for (p_output = psb_xrandr_info->output_head; p_output; p_output = p_output->next) { + if (p_output->connection == RR_Connected) { + if (!strcmp(p_output->name, "MIPI0")) { + if (p_output->crtc) { + psb_xrandr_info->mipi0_enabled = 1; + psb_xrandr_info->local_output[0] = p_output; + psb_xrandr_info->local_crtc[0] = p_output->crtc; + psb_xrandr_info->mipi0_rotation = p_output->crtc->rotation; + } else { + psb_xrandr_info->mipi0_enabled = 0; + psb_xrandr_info->local_output[0] = NULL; + psb_xrandr_info->local_crtc[0] = NULL; + } + } else if (!strcmp(p_output->name, "MIPI1")) { + if (p_output->crtc) { + psb_xrandr_info->mipi1_enabled = 1; + psb_xrandr_info->local_output[1] = p_output; + psb_xrandr_info->local_crtc[1] = p_output->crtc; + psb_xrandr_info->mipi1_rotation = p_output->crtc->rotation; + } else { + psb_xrandr_info->mipi1_enabled = 0; + psb_xrandr_info->local_output[1] = NULL; + psb_xrandr_info->local_crtc[1] = NULL; + } + } else if (!strcmp(p_output->name, "TMDS0-1")) { + if (p_output->crtc) { + psb_xrandr_info->hdmi_enabled = 1; + psb_xrandr_info->extend_output = p_output; + psb_xrandr_info->extend_crtc = p_output->crtc; + psb_xrandr_info->hdmi_rotation = p_output->crtc->rotation; + } else { + psb_xrandr_info->hdmi_enabled = 0; + psb_xrandr_info->extend_output = NULL; + psb_xrandr_info->extend_crtc = NULL; + } + } else if (!strcmp(p_output->name, "LVDS0") && IS_MRST(driver_data)) { + if (p_output->crtc) { + psb_xrandr_info->lvds0_enabled = 1; + psb_xrandr_info->local_output[0] = p_output; + psb_xrandr_info->local_crtc[0] = p_output->crtc; + } else { + psb_xrandr_info->lvds0_enabled = 0; + psb_xrandr_info->local_output[0] = NULL; + psb_xrandr_info->local_crtc[0] = NULL; + } + } } -#if 0 - else if (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == EXTENDEDVIDEO) { - if (psb_xrandr_info->primary_crtc->y == psb_xrandr_info->extend_crtc->height) - psb_xrandr_info->extend_crtc->location = ABOVE; - else if (psb_xrandr_info->extend_crtc->y == psb_xrandr_info->primary_crtc->height) - psb_xrandr_info->extend_crtc->location = BELOW; - else if (psb_xrandr_info->primary_crtc->x == psb_xrandr_info->extend_crtc->width) - psb_xrandr_info->extend_crtc->location = LEFT_OF; - else if (psb_xrandr_info->extend_crtc->x == psb_xrandr_info->primary_crtc->width) - psb_xrandr_info->extend_crtc->location = RIGHT_OF; + } + + /* for MRST */ + if (IS_MRST(driver_data) && psb_xrandr_info->lvds0_enabled) { + psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode = SINGLE; + psb_xrandr_info->output_device_mode = SINGLE_LVDS0; + psb_xrandr_info->local_crtc[0]->location = NORMAL; + return; + } + + /* HDMI + either MIPI0 or MIPI1 */ + if (psb_xrandr_info->hdmi_enabled) { + + /* Get HDMI properties if it is enabled*/ + psb_xrandr_hdmi_property(); + + /* Only HDMI */ + if (!psb_xrandr_info->mipi0_enabled && !psb_xrandr_info->mipi1_enabled) + psb_xrandr_info->output_device_mode = SINGLE_HDMI; + + /* HDMI + MIPI0 */ + if (psb_xrandr_info->mipi0_enabled && !psb_xrandr_info->mipi1_enabled) + psb_xrandr_info->output_device_mode = MIPI0_HDMI; + + /* HDMI + MIPI1 */ + if (!psb_xrandr_info->mipi0_enabled && psb_xrandr_info->mipi1_enabled) + psb_xrandr_info->output_device_mode = MIPI1_HDMI; + + /* HDMI + MIPI0 + MIPI1 */ + if (psb_xrandr_info->mipi0_enabled && psb_xrandr_info->mipi1_enabled) + psb_xrandr_info->output_device_mode = MIPI0_MIPI1_HDMI; + + psb_xrandr_hdmi_location_init(psb_xrandr_info->output_device_mode); + } else { + /* MIPI0 + MIPI1 */ + if (psb_xrandr_info->mipi0_enabled && psb_xrandr_info->mipi1_enabled) { + psb_xrandr_info->output_device_mode = MIPI0_MIPI1; + } else { + /* MIPI0/MIPI1 */ + if (psb_xrandr_info->mipi0_enabled) + psb_xrandr_info->output_device_mode = SINGLE_MIPI0; + else if (psb_xrandr_info->mipi1_enabled) + psb_xrandr_info->output_device_mode = SINGLE_MIPI1; } -#endif -#endif + + psb_xrandr_mipi_location_init(psb_xrandr_info->output_device_mode); } } -void psb_xrandr_refresh() +void psb_xrandr_refresh(VADriverContextP ctx) { - int i, j; + int i; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; @@ -207,105 +328,107 @@ void psb_xrandr_refresh() psb_xrandr_crtc_p p_crtc; psb_xrandr_output_p p_output; - pthread_mutex_lock(&psb_extvideo_mutex); - - if (psb_xrandr_info) - { - if (psb_xrandr_info->hdmi_extvideo_prop) - free(psb_xrandr_info->hdmi_extvideo_prop); - - free(psb_xrandr_info); - - psb_xrandr_info = NULL; - } - - psb_xrandr_info = (psb_xrandr_info_p)calloc(1, sizeof(psb_xrandr_info_s)); - memset(psb_xrandr_info, 0, sizeof(psb_xrandr_info_s)); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); psb_xrandr_info->hdmi_extvideo_prop = (psb_extvideo_prop_p)calloc(1, sizeof(psb_extvideo_prop_s)); + if (!psb_xrandr_info->hdmi_extvideo_prop) { + psb__error_message("output of memory\n"); + return; + } memset(psb_xrandr_info->hdmi_extvideo_prop, 0, sizeof(psb_extvideo_prop_s)); //deinit crtc - if (crtc_head) + if (psb_xrandr_info->crtc_head) { - while (crtc_head) + while (psb_xrandr_info->crtc_head) { - crtc_tail = crtc_head->next; + psb_xrandr_info->crtc_tail = psb_xrandr_info->crtc_head->next; - free(crtc_head->output); - free(crtc_head); + free(psb_xrandr_info->crtc_head); - crtc_head = crtc_tail; + psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail; } - crtc_head = crtc_tail = NULL; + psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = NULL; } - for (i = 0; i < res->ncrtc; i++) + for (i = 0; i < psb_xrandr_info->res->ncrtc; i++) { - crtc_info = XRRGetCrtcInfo (dpy, res, res->crtcs[i]); + crtc_info = XRRGetCrtcInfo (psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->crtcs[i]); if (crtc_info) { p_crtc = (psb_xrandr_crtc_p)calloc(1, sizeof(psb_xrandr_crtc_s)); - if (!p_crtc) + if (!p_crtc) { psb__error_message("output of memory\n"); + return; + } if (i == 0) - crtc_head = crtc_tail = p_crtc; + psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = p_crtc; - p_crtc->crtc_id = res->crtcs[i]; + p_crtc->crtc_id = psb_xrandr_info->res->crtcs[i]; p_crtc->x = crtc_info->x; p_crtc->y = crtc_info->y; p_crtc->width = crtc_info->width; p_crtc->height = crtc_info->height; p_crtc->crtc_mode = crtc_info->mode; p_crtc->noutput = crtc_info->noutput; + p_crtc->rotation = crtc_info->rotation; - crtc_tail->next = p_crtc; + psb_xrandr_info->crtc_tail->next = p_crtc; p_crtc->next = NULL; - crtc_tail = p_crtc; + psb_xrandr_info->crtc_tail = p_crtc; } else{ psb__error_message("failed to get crtc_info\n"); - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return; } } //deinit output - if (output_head) + if (psb_xrandr_info->output_head) { - while (output_head) + while (psb_xrandr_info->output_head) { - output_tail = output_head->next; + psb_xrandr_info->output_tail = psb_xrandr_info->output_head->next; - free(output_head); + free(psb_xrandr_info->output_head); - output_head = output_tail; + psb_xrandr_info->output_head = psb_xrandr_info->output_tail; } - output_head = output_tail = NULL; + psb_xrandr_info->output_head = psb_xrandr_info->output_tail = NULL; } - - for (i = 0; i < res->noutput; i++) +#if 0 + //destroy the full-screen window + //FIXME: commited out for X Error message: BadDrawable, need more investigation + if (va_output) { + if (va_output->extend_drawable) { + XDestroyWindow(ctx->native_dpy, va_output->extend_drawable); + va_output->extend_drawable = 0; + texture_priv->extend_dri_init_flag = 0; + } + } +#endif + for (i = 0; i < psb_xrandr_info->res->noutput; i++) { - output_info = XRRGetOutputInfo(dpy, res, res->outputs[i]); + output_info = XRRGetOutputInfo(psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->outputs[i]); if (output_info) { p_output = (psb_xrandr_output_p)calloc(1, sizeof(psb_xrandr_output_s)); - if (!output_info) + if (!p_output) { psb__error_message("output of memory\n"); + return; + } if (i == 0) - output_head = output_tail = p_output; + psb_xrandr_info->output_head = psb_xrandr_info->output_tail = p_output; - p_output->output_id = res->outputs[i]; + p_output->output_id = psb_xrandr_info->res->outputs[i]; p_output->connection = output_info->connection; if (p_output->connection == RR_Connected) psb_xrandr_info->nconnected_output++; - p_output->mm_width = output_info->mm_width; - p_output->mm_height = output_info->mm_height; - strcpy(p_output->name, output_info->name); if (output_info->crtc) @@ -313,56 +436,40 @@ void psb_xrandr_refresh() else p_output->crtc = NULL; - - output_tail->next = p_output; + psb_xrandr_info->output_tail->next = p_output; p_output->next = NULL; - output_tail = p_output; + psb_xrandr_info->output_tail = p_output; } else { psb__error_message("failed to get output_info\n"); - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return; } } - for (p_crtc = crtc_head; p_crtc; p_crtc = p_crtc->next) - { - crtc_info = XRRGetCrtcInfo (dpy, res, p_crtc->crtc_id); - - p_crtc->output = (struct _psb_xrandr_output_s**)calloc(p_crtc->noutput, sizeof(psb_xrandr_output_s)); - - for (j = 0; j < crtc_info->noutput; j++) - { - p_output = get_output_by_id(crtc_info->outputs[j]); - if (p_output) - p_crtc->output[j] = p_output; - else - p_crtc->output[j] = NULL; - } - } - - psb_extvideo_prop(); - pthread_mutex_unlock(&psb_extvideo_mutex); + psb_xrandr_coordinate_init(ctx); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); } -void psb_xrandr_thread() +void psb_xrandr_thread(void* arg) { + VADriverContextP ctx = (VADriverContextP)arg; int event_base, error_base; XEvent event; - XRRQueryExtension(dpy, &event_base, &error_base); - XRRSelectInput(dpy, root, RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask); + XRRQueryExtension(psb_xrandr_info->dpy, &event_base, &error_base); + XRRSelectInput(psb_xrandr_info->dpy, psb_xrandr_info->root, RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask); psb__information_message("Xrandr: psb xrandr thread start\n"); while (1) { - XNextEvent(dpy, (XEvent *)&event); + XNextEvent(psb_xrandr_info->dpy, (XEvent *)&event); if (event.type == ClientMessage) { psb__information_message("Xrandr: receive ClientMessage event, thread should exit\n"); XClientMessageEvent *evt; evt = (XClientMessageEvent*)&event; - if (evt->message_type == psb_exit_atom) { + if (evt->message_type == psb_xrandr_info->psb_exit_atom) { psb__information_message("Xrandr: xrandr thread exit safely\n"); pthread_exit(NULL); } @@ -371,7 +478,7 @@ void psb_xrandr_thread() case RRNotify_OutputChange: XRRUpdateConfiguration (&event); psb__information_message("Xrandr: receive RRNotify_OutputChange event, refresh output/crtc info\n"); - psb_xrandr_refresh(); + psb_xrandr_refresh(ctx); break; default: break; @@ -379,7 +486,7 @@ void psb_xrandr_thread() } } -Window psb_xrandr_create_full_screen_window() +Window psb_xrandr_create_full_screen_window(unsigned int destx, unsigned int desty, unsigned int destw, unsigned int desth) { int x, y, width, height; Window win; @@ -389,198 +496,116 @@ Window psb_xrandr_create_full_screen_window() width = psb_xrandr_info->extend_crtc->width; height = psb_xrandr_info->extend_crtc->height; - win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), x, y, width, height, 0, 0, 0); + if (destw == 0 || desth == 0) { + destw = width; + desth = height; + } + win = XCreateSimpleWindow(psb_xrandr_info->dpy, DefaultRootWindow(psb_xrandr_info->dpy), destx, desty, destw, desth, 0, 0, 0); MWMHints mwmhints; Atom MOTIF_WM_HINTS; mwmhints.flags = MWM_HINTS_DECORATIONS; mwmhints.decorations = 0; /* MWM_DECOR_BORDER */ - MOTIF_WM_HINTS = XInternAtom(dpy, "_MOTIF_WM_HINTS", False); - XChangeProperty(dpy, win, MOTIF_WM_HINTS, MOTIF_WM_HINTS, sizeof(long)*8, + MOTIF_WM_HINTS = XInternAtom(psb_xrandr_info->dpy, "_MOTIF_WM_HINTS", False); + XChangeProperty(psb_xrandr_info->dpy, win, MOTIF_WM_HINTS, MOTIF_WM_HINTS, sizeof(long)*8, PropModeReplace, (unsigned char*) &mwmhints, sizeof(mwmhints)/sizeof(long)); XSetWindowAttributes attributes; attributes.override_redirect = 1; unsigned long valuemask; valuemask = CWOverrideRedirect ; - XChangeWindowAttributes(dpy, win, valuemask, &attributes); + XChangeWindowAttributes(psb_xrandr_info->dpy, win, valuemask, &attributes); - XMapWindow(dpy, win); - XFlush(dpy); + XMapWindow(psb_xrandr_info->dpy, win); + XFlush(psb_xrandr_info->dpy); return win; } -#if 0 -void show_current() +int psb_xrandr_hdmi_enabled() { - int i, ret; - int x, y, widht, height; - psb_xrandr_location location; - - ret = pthread_mutex_trylock(&psb_extvideo_mutex); - if (ret != 0) - { - printf("mutex busy, should not read\n"); - return; - } - - if (psb_xrandr_single_mode()) - { - printf("single mode\n"); - printf("primary crtc info:\n"); - - ret = psb_xrandr_primary_crtc_coordinate(&x, &y, &widht, &height); - - if (!ret) - printf("failed to get primary crtc info\n"); - else - { - printf("\tx = %d, y = %d, widht = %d, height = %d\n", x, y, widht, height); - printf("\tcrtc id: %08x, crtc mode: %08x, ", psb_xrandr_info->primary_crtc->crtc_id, psb_xrandr_info->primary_crtc->crtc_mode); - for (i = 0; i < psb_xrandr_info->primary_crtc->noutput; i++) - printf("output: %08x\n", psb_xrandr_info->primary_crtc->output[i]->output_id); - } - } - else if (psb_xrandr_clone_mode()) - { - printf("clone mode\n"); - - ret = psb_xrandr_primary_crtc_coordinate(&x, &y, &widht, &height); - - if (!ret) - printf("failed to get primary crtc info\n"); - else - { - printf("primary crtc info:\n"); - printf("\tx = %d, y = %d, widht = %d, height = %d\n", x, y, widht, height); - printf("\tcrtc id: %08x, crtc mode: %08x, ", psb_xrandr_info->primary_crtc->crtc_id, psb_xrandr_info->primary_crtc->crtc_mode); - for (i = 0; i < psb_xrandr_info->primary_crtc->noutput; i++) - printf("output: %08x\n", psb_xrandr_info->primary_crtc->output[i]->output_id); - } - - ret = psb_xrandr_extend_crtc_coordinate(&x, &y, &widht, &height, &location); - - if (!ret) - printf("failed to get clone crtc info\n"); - else - { - printf("clone crtc info:\n"); - printf("\tx = %d, y = %d, widht = %d, height = %d, location = %s\n", x, y, widht, height, location2string(location)); - printf("\tcrtc id: %08x, crtc mode: %08x, ", psb_xrandr_info->extend_crtc->crtc_id, psb_xrandr_info->extend_crtc->crtc_mode); - for (i = 0; i < psb_xrandr_info->extend_crtc->noutput; i++) - printf("output: %08x\n", psb_xrandr_info->extend_crtc->output[i]->output_id); - } - } - else if (psb_xrandr_extend_mode()) - { - printf("extend mode\n"); - ret = psb_xrandr_primary_crtc_coordinate(&x, &y, &widht, &height); - - if (!ret) - printf("failed to get primary crtc info\n"); - else - { - printf("primary crtc info:\n"); - printf("\tx = %d, y = %d, widht = %d, height = %d\n", x, y, widht, height); - printf("\tcrtc id: %08x, crtc mode: %08x, ", psb_xrandr_info->primary_crtc->crtc_id, psb_xrandr_info->primary_crtc->crtc_mode); - for (i = 0; i < psb_xrandr_info->primary_crtc->noutput; i++) - printf("output: %08x\n", psb_xrandr_info->primary_crtc->output[i]->output_id); - } - - ret = psb_xrandr_extend_crtc_coordinate(&x, &y, &widht, &height, &location); - - if (!ret) - printf("failed to get extend crtc info\n"); - else - { - printf("extend crtc info:\n"); - printf("\tx = %d, y = %d, widht = %d, height = %d, location = %s\n", x, y, widht, height, location2string(location)); - printf("\tcrtc id: %08x, crtc mode: %08x, ", psb_xrandr_info->extend_crtc->crtc_id, psb_xrandr_info->extend_crtc->crtc_mode); - for (i = 0; i < psb_xrandr_info->extend_crtc->noutput; i++) - printf("output: %08x\n", psb_xrandr_info->extend_crtc->output[i]->output_id); - } - } - else if (psb_xrandr_extvideo_mode()) - printf("extvideo mode\n"); - - pthread_mutex_unlock(&psb_extvideo_mutex); + int ret; + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = psb_xrandr_info->hdmi_enabled; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return ret; } -#endif -int psb_xrandr_hdmi_connected() + +int psb_xrandr_mipi0_enabled() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = psb_xrandr_info->hdmi_connected; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = psb_xrandr_info->mipi0_enabled; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } -int psb_xrandr_mipi1_connected() +int psb_xrandr_mipi1_enabled() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = psb_xrandr_info->mipi1_connected; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = psb_xrandr_info->mipi1_enabled; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } int psb_xrandr_single_mode() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == SINGLE) ? 1 : 0; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == SINGLE) ? 1 : 0; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } int psb_xrandr_clone_mode() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == CLONE) ? 1 : 0; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == CLONE) ? 1 : 0; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } int psb_xrandr_extend_mode() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == EXTENDED) ? 1 : 0; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == EXTENDED) ? 1 : 0; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } int psb_xrandr_extvideo_mode() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); - ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode == EXTENDEDVIDEO) ? 1 : 0; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + ret = (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode == EXTENDEDVIDEO) ? 1 : 0; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } int psb_xrandr_outputchanged() { int ret; - pthread_mutex_lock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); if (psb_xrandr_info->output_changed){ psb_xrandr_info->output_changed = 0; ret = 1; } else ret = 0; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return ret; } -VAStatus psb_xrandr_extvideo_mode_prop(unsigned int *xres, unsigned int *yres, unsigned int *xoffset, - unsigned int *yoffset, psb_extvideo_center *center, psb_extvideo_subtitle *subtitle) +VAStatus psb_xrandr_extvideo_prop(unsigned int *xres, unsigned int *yres, unsigned int *xoffset, + unsigned int *yoffset, psb_extvideo_center *center, psb_extvideo_subtitle *subtitle, + unsigned int *overscanmode, unsigned int *pannelfitting) { - pthread_mutex_lock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); - if (psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode != EXTENDEDVIDEO){ - pthread_mutex_unlock(&psb_extvideo_mutex); + if (psb_xrandr_info->hdmi_extvideo_prop->ExtDesktopMode != EXTENDEDVIDEO){ + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return VA_STATUS_ERROR_UNKNOWN; } @@ -590,61 +615,133 @@ VAStatus psb_xrandr_extvideo_mode_prop(unsigned int *xres, unsigned int *yres, u *yoffset = psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Y_Offset; *center = psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_Center; *subtitle = psb_xrandr_info->hdmi_extvideo_prop->ExtVideoMode_SubTitle; + *pannelfitting = psb_xrandr_info->hdmi_extvideo_prop->PANELFITTING; + *overscanmode = psb_xrandr_info->hdmi_extvideo_prop->OverscanMode; - pthread_mutex_unlock(&psb_extvideo_mutex); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return VA_STATUS_SUCCESS; } -VAStatus psb_xrandr_primary_crtc_coordinate(int *x, int *y, int *width, int *height) +VAStatus psb_xrandr_local_crtc_coordinate(psb_output_device *local_device_enabled, int *x, int *y, int *width, int *height, Rotation *rotation) { - pthread_mutex_lock(&psb_extvideo_mutex); - psb_xrandr_crtc_p crtc = psb_xrandr_info->primary_crtc;; - if (crtc) { - *x = crtc->x; - *y = crtc->y; - *width = crtc->width - 1; - *height = crtc->height - 1; - pthread_mutex_unlock(&psb_extvideo_mutex); - psb__information_message("Xrandr: crtc %08x coordinate: x = %d, y = %d, widht = %d, height = %d\n", - psb_xrandr_info->primary_crtc->crtc_id, *x, *y, *width + 1, *height + 1); + psb_xrandr_crtc_p p_crtc; + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + + switch (psb_xrandr_info->output_device_mode) { + case SINGLE_LVDS0: + *local_device_enabled = LVDS0; + p_crtc = psb_xrandr_info->local_crtc[0]; + break; + case SINGLE_MIPI0: + case MIPI0_MIPI1: + case MIPI0_HDMI: + case MIPI0_MIPI1_HDMI: + *local_device_enabled = MIPI0; + p_crtc = psb_xrandr_info->local_crtc[0]; + break; + case SINGLE_MIPI1: + case MIPI1_HDMI: + *local_device_enabled = MIPI1; + p_crtc = psb_xrandr_info->local_crtc[1]; + break; + case SINGLE_HDMI: + *local_device_enabled = HDMI; + p_crtc = psb_xrandr_info->extend_crtc; + break; + default: + psb__error_message("Xrandr: Unknown statue\n"); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return VA_STATUS_ERROR_UNKNOWN; + break; + } + + if (p_crtc) { + *x = p_crtc->x; + *y = p_crtc->y; + *width = p_crtc->width; + *height = p_crtc->height; + *rotation = p_crtc->rotation; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + psb__information_message("Xrandr: device %08x enabled, crtc %08x coordinate: x = %d, y = %d, widht = %d, height = %d, rotate = %08x\n", + *local_device_enabled, p_crtc->crtc_id, *x, *y, *width + 1, *height + 1, *rotation); return VA_STATUS_SUCCESS; + } else { + psb__error_message("Xrandr: local device is not available\n"); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return VA_STATUS_ERROR_UNKNOWN; } - pthread_mutex_unlock(&psb_extvideo_mutex); - return VA_STATUS_ERROR_UNKNOWN; } -VAStatus psb_xrandr_extend_crtc_coordinate(int *x, int *y, int *width, int *height, psb_xrandr_location *location) +VAStatus psb_xrandr_extend_crtc_coordinate(psb_output_device *extend_device_enabled, int *x, int *y, int *width, int *height, psb_xrandr_location *location, Rotation *rotation) { - pthread_mutex_lock(&psb_extvideo_mutex); + psb_xrandr_crtc_p p_crtc; - if (psb_xrandr_info->nconnected_output == 1 || !psb_xrandr_info->extend_crtc){ - pthread_mutex_unlock(&psb_extvideo_mutex); - return VA_STATUS_ERROR_UNKNOWN; + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + + switch (psb_xrandr_info->output_device_mode) { + case MIPI0_MIPI1: + *extend_device_enabled = MIPI1; + p_crtc = psb_xrandr_info->local_crtc[1]; + break; + case MIPI0_HDMI: + case MIPI0_MIPI1_HDMI: + case MIPI1_HDMI: + *extend_device_enabled = HDMI; + p_crtc = psb_xrandr_info->extend_crtc; + break; + default: + psb__error_message("Xrandr: Unknown status, may be extend device is not available\n"); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return VA_STATUS_ERROR_UNKNOWN; + break; } - *x = psb_xrandr_info->extend_crtc->x; - *y = psb_xrandr_info->extend_crtc->y; - *width = psb_xrandr_info->extend_crtc->width - 1; - *height = psb_xrandr_info->extend_crtc->height - 1; - *location = psb_xrandr_info->extend_crtc->location; + if (p_crtc) { + *x = p_crtc->x; + *y = p_crtc->y; + *width = p_crtc->width; + *height = p_crtc->height; + *location = p_crtc->location; + *rotation = p_crtc->rotation; + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + psb__information_message("Xrandr: extend device %08x enabled, crtc %08x coordinate: x = %d, y = %d, widht = %d, height = %d, location = %s, rotation = %08x\n", + *extend_device_enabled, p_crtc->crtc_id, *x, *y, *width + 1, *height + 1, location2string(p_crtc->location), *rotation); + } else { + psb__error_message("Xrandr: extend device is not available\n"); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return VA_STATUS_ERROR_UNKNOWN; + } - pthread_mutex_unlock(&psb_extvideo_mutex); - psb__information_message("Xrandr: crtc %08x coordinate: x = %d, y = %d, widht = %d, height = %d, location = %s\n", - psb_xrandr_info->extend_crtc->crtc_id, *x, *y, *width + 1, *height + 1, location2string(psb_xrandr_info->extend_crtc->location)); + return VA_STATUS_SUCCESS; +} + +VAStatus psb_xrandr_get_output_rotation(int *mipi0_rotation, int *mipi1_rotation, int *hdmi_rotation) +{ + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); + if (psb_xrandr_info) { + *mipi0_rotation = RRrotation2VArotation(psb_xrandr_info->mipi0_rotation); + *mipi1_rotation = RRrotation2VArotation(psb_xrandr_info->mipi1_rotation); + *hdmi_rotation = RRrotation2VArotation(psb_xrandr_info->hdmi_rotation); + } else { + psb__error_message("Xrandr: can't get output rotation.\n"); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + return VA_STATUS_ERROR_UNKNOWN; + } + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return VA_STATUS_SUCCESS; } VAStatus psb_xrandr_thread_exit(Drawable draw) { int ret; - XSelectInput(dpy, draw, StructureNotifyMask); + XSelectInput(psb_xrandr_info->dpy, draw, StructureNotifyMask); XClientMessageEvent xevent; xevent.type = ClientMessage; - xevent.message_type = psb_exit_atom; + xevent.message_type = psb_xrandr_info->psb_exit_atom; xevent.window = draw; xevent.format = 32; - ret = XSendEvent(dpy, draw, 0, 0, (XEvent*)&xevent); - XFlush(dpy); + ret = XSendEvent(psb_xrandr_info->dpy, draw, 0, 0, (XEvent*)&xevent); + XFlush(psb_xrandr_info->dpy); if (!ret) { psb__information_message("Xrandr: send thread exit event to drawable: %08x failed\n", draw); return VA_STATUS_ERROR_UNKNOWN; @@ -657,53 +754,53 @@ VAStatus psb_xrandr_thread_exit(Drawable draw) VAStatus psb_xrandr_thread_create(VADriverContextP ctx) { - psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; pthread_t id; + INIT_DRIVER_DATA; - pthread_create(&id, NULL, (void*)psb_xrandr_thread, NULL); + psb_xrandr_info->psb_exit_atom = XInternAtom(psb_xrandr_info->dpy, "psb_exit_atom", 0); + pthread_create(&id, NULL, (void*)psb_xrandr_thread, ctx); driver_data->xrandr_thread_id = id; return VA_STATUS_SUCCESS; } VAStatus psb_xrandr_deinit() { - pthread_mutex_lock(&psb_extvideo_mutex); + pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); //free crtc - if (crtc_head) + if (psb_xrandr_info->crtc_head) { - while (crtc_head) + while (psb_xrandr_info->crtc_head) { - crtc_tail = crtc_head->next; + psb_xrandr_info->crtc_tail = psb_xrandr_info->crtc_head->next; - free(crtc_head); + free(psb_xrandr_info->crtc_head); - crtc_head = crtc_tail; + psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail; } - crtc_head = crtc_tail = NULL; + psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = NULL; } //free output - if (output_head) + if (psb_xrandr_info->output_head) { - while (output_head) + while (psb_xrandr_info->output_head) { - output_tail = output_head->next; + psb_xrandr_info->output_tail = psb_xrandr_info->output_head->next; - free(output_head); + free(psb_xrandr_info->output_head); - output_head = output_tail; + psb_xrandr_info->output_head = psb_xrandr_info->output_tail; } - output_head = output_tail = NULL; + psb_xrandr_info->output_head = psb_xrandr_info->output_tail = NULL; } - if (psb_xrandr_info->hdmi_extvideo_prop) + if (psb_xrandr_info->hdmi_extvideo_prop) { free(psb_xrandr_info->hdmi_extvideo_prop); - - if (psb_xrandr_info) free(psb_xrandr_info); + } - pthread_mutex_unlock(&psb_extvideo_mutex); - pthread_mutex_destroy(&psb_extvideo_mutex); + pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); + pthread_mutex_destroy(&psb_xrandr_info->psb_extvideo_mutex); return VA_STATUS_SUCCESS; } @@ -713,35 +810,37 @@ VAStatus psb_xrandr_init (VADriverContextP ctx) int major, minor; int screen; - dpy = (Display *)ctx->native_dpy; - screen = DefaultScreen (dpy); - psb_exit_atom = XInternAtom(dpy, "psb_exit_atom", 0); + psb_xrandr_info = (psb_xrandr_info_p)calloc(1, sizeof(psb_xrandr_info_s)); + if (!psb_xrandr_info) { + psb__error_message("output of memory\n"); + return VA_STATUS_ERROR_UNKNOWN; + } + memset(psb_xrandr_info, 0, sizeof(psb_xrandr_info_s)); + + psb_xrandr_info->dpy = (Display *)ctx->native_dpy; + screen = DefaultScreen (psb_xrandr_info->dpy); - if (screen >= ScreenCount (dpy)) { + if (screen >= ScreenCount (psb_xrandr_info->dpy)) { psb__error_message("Xrandr: Invalid screen number %d (display has %d)\n", - screen, ScreenCount (dpy)); + screen, ScreenCount (psb_xrandr_info->dpy)); return VA_STATUS_ERROR_UNKNOWN; } - root = RootWindow (dpy, screen); + psb_xrandr_info->root = RootWindow (psb_xrandr_info->dpy, screen); - if (!XRRQueryVersion (dpy, &major, &minor)) + if (!XRRQueryVersion (psb_xrandr_info->dpy, &major, &minor)) { psb__error_message("Xrandr: RandR extension missing\n"); return VA_STATUS_ERROR_UNKNOWN; } - res = XRRGetScreenResources (dpy, root); - if (!res) + psb_xrandr_info->res = XRRGetScreenResources (psb_xrandr_info->dpy, psb_xrandr_info->root); + if (!psb_xrandr_info->res) psb__error_message("Xrandr: failed to get screen resources\n"); - pthread_mutex_init(&psb_extvideo_mutex, NULL); + pthread_mutex_init(&psb_xrandr_info->psb_extvideo_mutex, NULL); - psb_xrandr_refresh(); + psb_xrandr_refresh(ctx); - /*while(1) { sleep(1); - show_current(); - }*/ - - return 0; + return VA_STATUS_SUCCESS; } diff --git a/src/x11/psb_xrandr.h b/src/x11/psb_xrandr.h index 7a80e1c..c04c8d2 100644 --- a/src/x11/psb_xrandr.h +++ b/src/x11/psb_xrandr.h @@ -1,128 +1,164 @@ -#ifndef _PSB_XRANDR_H_ -#define _PSB_XRANDR_H_ -#include -#include -#include -#include -#include -#include -#include /* we share subpixel information */ -#include -#include -#include -#include -#include -#include - -typedef enum _psb_hdmi_mode { - CLONE, - EXTENDED, - EXTENDEDVIDEO, - SINGLE, - UNKNOWNVIDEOMODE, -} psb_hdmi_mode; - -typedef enum _psb_extvideo_center { - NOCENTER, - CENTER, - UNKNOWNCENTER, -} psb_extvideo_center; - -typedef enum _psb_extvideo_subtitle { - BOTH, - HDMI, - NOSUBTITLE, -} psb_extvideo_subtitle; - -typedef enum _psb_xrandr_location -{ - NORMAL, ABOVE, BELOW, LEFT_OF, RIGHT_OF, -} psb_xrandr_location; - -typedef struct _psb_extvideo_prop_s { - psb_hdmi_mode ExtVideoMode; - - unsigned int ExtVideoMode_XRes; - unsigned int ExtVideoMode_YRes; - unsigned int ExtVideoMode_X_Offset; - unsigned int ExtVideoMode_Y_Offset; - - psb_extvideo_center ExtVideoMode_Center; - psb_extvideo_subtitle ExtVideoMode_SubTitle; - -} psb_extvideo_prop_s, *psb_extvideo_prop_p; - -typedef struct _psb_xrandr_crtc_s { - struct _psb_xrandr_crtc_s *next; - - RRCrtc crtc_id; - RRMode crtc_mode; - - unsigned int width; - unsigned int height; - unsigned int x; - unsigned int y; - - psb_xrandr_location location; - - int noutput; - - struct _psb_xrandr_output_s **output; - -} psb_xrandr_crtc_s, *psb_xrandr_crtc_p; - -typedef struct _psb_xrandr_output_s -{ - RROutput output_id; - char name[10]; - struct _psb_xrandr_output_s *next; - - Connection connection; - - unsigned long mm_width; - unsigned long mm_height; - - psb_xrandr_crtc_p crtc; - -} psb_xrandr_output_s, *psb_xrandr_output_p; - -typedef struct _psb_xrandr_info_s -{ - psb_xrandr_crtc_p primary_crtc; - psb_xrandr_crtc_p extend_crtc; - - psb_xrandr_output_p primary_output; - psb_xrandr_output_p extend_output; - - unsigned int nconnected_output; - - psb_extvideo_prop_p hdmi_extvideo_prop; - int hdmi_connected; - int mipi1_connected; - int output_changed; -} psb_xrandr_info_s, *psb_xrandr_info_p; - - -Atom psb_exit_atom; -int psb_xrandr_hdmi_connected(); -int psb_xrandr_mipi1_connected(); -int psb_xrandr_single_mode(); -int psb_xrandr_clone_mode(); -int psb_xrandr_extend_mode(); -int psb_xrandr_extvideo_mode(); -int psb_xrandr_outputchanged(); - -Window psb_xrandr_create_full_screen_window(); -VAStatus psb_xrandr_extvideo_mode_prop(unsigned int *xres, unsigned int *yres, unsigned int *xoffset, unsigned int *yoffset, - psb_extvideo_center *center, psb_extvideo_subtitle *subtitle); -VAStatus psb_xrandr_primary_crtc_coordinate(int *x, int *y, int *width, int *height); -VAStatus psb_xrandr_extend_crtc_coordinate(int *x, int *y, int *width, int *height, psb_xrandr_location *location); - -void psb_xrandr_refresh(); -void psb_xrandr_thread(); -VAStatus psb_xrandr_thread_create(VADriverContextP ctx); -VAStatus psb_xrandr_thread_exit(Drawable draw); -VAStatus psb_xrandr_init (VADriverContextP ctx); -VAStatus psb_xrandr_deinit(); - -#endif /* _PSB_XRANDR_H_ */ +#ifndef _PSB_XRANDR_H_ +#define _PSB_XRANDR_H_ +#include +#include +#include +#include +#include +#include +#include /* we share subpixel information */ +#include +#include +#include +#include +#include +#include + +typedef enum _psb_output_device { + MIPI0, + MIPI1, + LVDS0, + HDMI, +} psb_output_device; + +typedef enum _psb_output_device_mode { + SINGLE_MIPI0, + SINGLE_MIPI1, + SINGLE_HDMI, + SINGLE_LVDS0, + MIPI0_MIPI1, + MIPI0_HDMI, + MIPI0_MIPI1_HDMI, + MIPI1_HDMI, +} psb_output_device_mode; + +typedef enum _psb_hdmi_mode { + CLONE, + EXTENDED, + EXTENDEDVIDEO, + SINGLE, + UNKNOWNVIDEOMODE, +} psb_hdmi_mode; + +typedef enum _psb_extvideo_center { + NOCENTER, + CENTER, + UNKNOWNCENTER, +} psb_extvideo_center; + +typedef enum _psb_extvideo_subtitle { + BOTH, + ONLY_HDMI, + NOSUBTITLE, +} psb_extvideo_subtitle; + +typedef enum _psb_xrandr_location +{ + NORMAL, ABOVE, BELOW, LEFT_OF, RIGHT_OF, +} psb_xrandr_location; + +typedef struct _psb_extvideo_prop_s { + psb_hdmi_mode ExtVideoMode; + psb_hdmi_mode ExtDesktopMode; + + unsigned int ExtVideoMode_XRes; + unsigned int ExtVideoMode_YRes; + unsigned int ExtVideoMode_X_Offset; + unsigned int ExtVideoMode_Y_Offset; + unsigned int OverscanMode; + unsigned int PANELFITTING; + + psb_extvideo_center ExtVideoMode_Center; + psb_extvideo_subtitle ExtVideoMode_SubTitle; + +} psb_extvideo_prop_s, *psb_extvideo_prop_p; + +typedef struct _psb_xrandr_crtc_s { + struct _psb_xrandr_crtc_s *next; + + RRCrtc crtc_id; + RRMode crtc_mode; + + unsigned int width; + unsigned int height; + unsigned int x; + unsigned int y; + + Rotation rotation; + psb_xrandr_location location; + + int noutput; + +} psb_xrandr_crtc_s, *psb_xrandr_crtc_p; + +typedef struct _psb_xrandr_output_s +{ + RROutput output_id; + char name[10]; + struct _psb_xrandr_output_s *next; + + Connection connection; + + psb_xrandr_crtc_p crtc; + +} psb_xrandr_output_s, *psb_xrandr_output_p; + +typedef struct _psb_xrandr_info_s +{ + psb_xrandr_crtc_p local_crtc[2]; + psb_xrandr_crtc_p extend_crtc; + + psb_xrandr_output_p local_output[2]; + psb_xrandr_output_p extend_output; + + unsigned int nconnected_output; + + psb_extvideo_prop_p hdmi_extvideo_prop; + + int lvds0_enabled; + int mipi0_enabled; + int mipi1_enabled; + int hdmi_enabled; + + Rotation mipi0_rotation; + Rotation mipi1_rotation; + Rotation hdmi_rotation; + + int output_changed; + psb_output_device_mode output_device_mode; + + psb_xrandr_crtc_p crtc_head, crtc_tail; + psb_xrandr_output_p output_head, output_tail; + + pthread_mutex_t psb_extvideo_mutex; + XRRScreenResources *res; + Display *dpy; + Window root; + Atom psb_exit_atom; +} psb_xrandr_info_s, *psb_xrandr_info_p; + + +int psb_xrandr_hdmi_enabled(); +int psb_xrandr_mipi1_enabled(); +int psb_xrandr_single_mode(); +int psb_xrandr_clone_mode(); +int psb_xrandr_extend_mode(); +int psb_xrandr_extvideo_mode(); +int psb_xrandr_outputchanged(); + +Window psb_xrandr_create_full_screen_window(unsigned int destx, unsigned int desty, unsigned int destw, unsigned int desth); +VAStatus psb_xrandr_extvideo_prop(unsigned int *xres, unsigned int *yres, unsigned int *xoffset, + unsigned int *yoffset, psb_extvideo_center *center, psb_extvideo_subtitle *subtitle, + unsigned int *overscanmode, unsigned int *pannelfitting); +VAStatus psb_xrandr_local_crtc_coordinate(psb_output_device *local_device_enabled, int *x, int *y, int *width, int *height, Rotation *rotation); +VAStatus psb_xrandr_extend_crtc_coordinate(psb_output_device *extend_device_enabled, int *x, int *y, int *width, int *height, psb_xrandr_location *location, Rotation *rotation); +VAStatus psb_xrandr_get_output_rotation(int *mipi0_rotation, int *mipi1_rotation, int *hdmi_rotation); + +void psb_xrandr_refresh(VADriverContextP ctx); +void psb_xrandr_thread(); +VAStatus psb_xrandr_thread_create(VADriverContextP ctx); +VAStatus psb_xrandr_thread_exit(Drawable draw); +VAStatus psb_xrandr_init (VADriverContextP ctx); +VAStatus psb_xrandr_deinit(); + +#endif /* _PSB_XRANDR_H_ */ diff --git a/src/x11/psb_xvva.c b/src/x11/psb_xvva.c index 1b03bd3..4346cb6 100644 --- a/src/x11/psb_xvva.c +++ b/src/x11/psb_xvva.c @@ -108,7 +108,7 @@ static int GetPortId(VADriverContextP ctx, psb_x11_output_p output) VAStatus psb_init_xvideo(VADriverContextP ctx, psb_x11_output_p output) { INIT_DRIVER_DATA; - int dummy; + int dummy, ret; output->textured_portID = output->overlay_portID = 0; if (GetPortId(ctx, output)) { @@ -151,6 +151,28 @@ VAStatus psb_init_xvideo(VADriverContextP ctx, psb_x11_output_p output) if (output->overlay_portID) driver_data->output_method = PSB_PUTSURFACE_OVERLAY; + ret = psb_xrandr_init(ctx); + if ( ret != 0) { + psb__error_message("%s: Failed to initialize psb xrandr error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + + ret = psb_xrandr_get_output_rotation(&driver_data->mipi0_rotation, &driver_data->mipi1_rotation, &driver_data->hdmi_rotation); + driver_data->local_rotation = driver_data->mipi0_rotation; + driver_data->extend_rotation = driver_data->hdmi_rotation; + if ( ret != 0) { + psb__error_message("%s: Failed to get xrandr output rotation info error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + + if (driver_data->use_xrandr_thread && !driver_data->xrandr_thread_id) { + ret = psb_xrandr_thread_create(ctx); + if ( ret != 0) { + psb__error_message("%s: Failed to create psb xrandr thread error # %d\n", __func__, ret); + return VA_STATUS_ERROR_UNKNOWN; + } + } + return VA_STATUS_SUCCESS; } @@ -206,14 +228,13 @@ VAStatus psb_deinit_xvideo(VADriverContextP ctx) output->overlay_portID = 0; } - if (output->output_drawable) { - if (driver_data->use_xrandr_thread && driver_data->xrandr_thread_id) { - psb_xrandr_thread_exit(output->output_drawable); - pthread_join(driver_data->xrandr_thread_id, NULL); - driver_data->xrandr_thread_id = 0; - } - psb_xrandr_deinit(); + if (driver_data->use_xrandr_thread && driver_data->xrandr_thread_id) { + psb_xrandr_thread_exit(output->output_drawable); + pthread_join(driver_data->xrandr_thread_id, NULL); + driver_data->xrandr_thread_id = 0; } + psb_xrandr_deinit(); + output->using_port = 0; output->output_drawable = 0; output->extend_drawable = 0; -- cgit v1.2.3