diff --git a/common.mk b/common.mk index abd17e4..ba6575e 100644 --- a/common.mk +++ b/common.mk @@ -44,7 +44,11 @@ PRODUCT_PACKAGES := \ gps.smdkv310 \ sensors.smdkv310 \ lights.smdkv310 \ - mediaserver.smdkv310 + mediaserver.smdkv310 \ + overlay.smdkv310 \ + libstagefrighthw \ + libexifa \ + libjpega # These are the hardware-specific configuration files PRODUCT_COPY_FILES := \ @@ -130,8 +134,15 @@ PRODUCT_COPY_FILES += \ # configuration files PRODUCT_COPY_FILES += \ - device/samsung/c1-common/etc/media_profiles.xml:system/etc/media_profiles.xml - - + device/samsung/c1-common/etc/media_profiles.xml:system/etc/media_profiles.xml \ + device/samsung/c1-common/sec_mm/sec_omx/sec_omx_core/secomxregistry:system/etc/secomxregistry \ + +# These are the OpenMAX IL modules +PRODUCT_PACKAGES += \ + libSEC_OMX_Core.smdkv310 \ + libOMX.SEC.AVC.Decoder.smdkv310 \ + libOMX.SEC.M4V.Decoder.smdkv310 \ + libOMX.SEC.M4V.Encoder.smdkv310 \ + libOMX.SEC.AVC.Encoder.smdkv310 diff --git a/include/s3c_bc.h b/include/s3c_bc.h new file mode 100755 index 0000000..e8ea490 --- /dev/null +++ b/include/s3c_bc.h @@ -0,0 +1,63 @@ +/*!**************************************************************************** +@File s3c_bc.h + +@Title s3c_bc kernel driver parameters + +@Author Imagination Technologies + Samsung Electronics Co. LTD + +@Date 03/03/2010 + +@Copyright Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +@Platform Generic + +@Description s3c_bc kernel driver parameters + +@DoxygenVer + +******************************************************************************/ + +/****************************************************************************** +Modifications :- +$Log: s3c_bc.h $ +******************************************************************************/ +#ifndef __S3C_BC_H__ +#define __S3C_BC_H__ + +#include + +#define S3C_BC_DEVICE_NAME "s3c_bc" + +#define S3C_BC_DEVICE_ID 0 +#define S3C_BC_DEVICE_BUFFER_COUNT 4 /* TODO: Modify this accordingly. */ + +#define S3C_BC_DEVICE_PHYS_PAGE_SIZE 0x1000 /* 4KB */ + +typedef struct S3C_BC_ioctl_package_TAG +{ + int inputparam; + int outputparam; +} S3C_BC_ioctl_package, *PS3C_BC_ioctl_package; + +/*!< Nov 2006: according to ioctl-number.txt 'g' wasn't in use. */ +#define S3C_BC_IOC_GID 'g' + +#define S3C_BC_IOWR(INDEX) _IOWR(S3C_BC_IOC_GID, INDEX, S3C_BC_ioctl_package) + +#define S3C_BC_ioctl_get_physical_base_address S3C_BC_IOWR(0) + +#endif /* __S3C_BC__H__ */ +/****************************************************************************** + End of file (s3c_bc.h) +******************************************************************************/ diff --git a/include/s3c_mem.h b/include/s3c_mem.h new file mode 100755 index 0000000..d51398a --- /dev/null +++ b/include/s3c_mem.h @@ -0,0 +1,56 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _S3C_MEM_COMMON_H_ +#define _S3C_MEM_COMMON_H_ + +#define MEM_IOCTL_MAGIC 'M' + +#define S3C_MEM_ALLOC _IOWR(MEM_IOCTL_MAGIC, 310, struct s3c_mem_alloc) +#define S3C_MEM_FREE _IOWR(MEM_IOCTL_MAGIC, 311, struct s3c_mem_alloc) + +#define S3C_MEM_SHARE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 314, struct s3c_mem_alloc) +#define S3C_MEM_SHARE_FREE _IOWR(MEM_IOCTL_MAGIC, 315, struct s3c_mem_alloc) + +#define S3C_MEM_CACHEABLE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 316, struct s3c_mem_alloc) +#define S3C_MEM_CACHEABLE_SHARE_ALLOC _IOWR(MEM_IOCTL_MAGIC, 317, struct s3c_mem_alloc) + +#define S3C_MEM_DMA_COPY _IOWR(MEM_IOCTL_MAGIC, 318, struct s3c_mem_dma_param) +#define S3C_MEM_DMA_SET _IOWR(MEM_IOCTL_MAGIC, 319, struct s3c_mem_dma_param) + +#define S3C_MEM_CACHE_INV _IOWR(MEM_IOCTL_MAGIC, 330, struct s3c_mem_dma_param) + + +struct s3c_mem_alloc { + int size; + unsigned int vir_addr; + unsigned int phy_addr; +}; + +struct s3c_mem_dma_param { + int size; + unsigned int src_addr; + unsigned int dst_addr; + int cfg; +}; + +#if 0 +typedef struct _s3c_mem_t{ + int dev_fd; + struct s3c_mem_alloc mem_alloc_info; +}s3c_mem_t; +#endif +#endif // _S3C_MEM_COMMON_H_ diff --git a/include/s5p_fimc.h b/include/s5p_fimc.h new file mode 100755 index 0000000..d2c760c --- /dev/null +++ b/include/s5p_fimc.h @@ -0,0 +1,153 @@ +/* + * Copyright@ Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef _S5P_FIMC_H_ +#define _S5P_FIMC_H_ + +#include + +/* + * G E N E R A L S + * +*/ +#define MIN(x, y) ((x < y) ? x : y) + +/* + * P I X E L F O R M A T G U I D E + * + * The 'x' means 'DO NOT CARE' + * The '*' means 'FIMC SPECIFIC' + * For some fimc formats, we couldn't find equivalent format in the V4L2 FOURCC. + * + * FIMC TYPE PLANES ORDER V4L2_PIX_FMT + * --------------------------------------------------------- + * RGB565 x x V4L2_PIX_FMT_RGB565 + * RGB888 x x V4L2_PIX_FMT_RGB24 + * YUV420 2 LSB_CBCR V4L2_PIX_FMT_NV12 + * YUV420 2 LSB_CRCB V4L2_PIX_FMT_NV21 + * YUV420 2 MSB_CBCR V4L2_PIX_FMT_NV21X* + * YUV420 2 MSB_CRCB V4L2_PIX_FMT_NV12X* + * YUV420 3 x V4L2_PIX_FMT_YUV420 + * YUV422 1 YCBYCR V4L2_PIX_FMT_YUYV + * YUV422 1 YCRYCB V4L2_PIX_FMT_YVYU + * YUV422 1 CBYCRY V4L2_PIX_FMT_UYVY + * YUV422 1 CRYCBY V4L2_PIX_FMT_VYUY* + * YUV422 2 LSB_CBCR V4L2_PIX_FMT_NV16* + * YUV422 2 LSB_CRCB V4L2_PIX_FMT_NV61* + * YUV422 2 MSB_CBCR V4L2_PIX_FMT_NV16X* + * YUV422 2 MSB_CRCB V4L2_PIX_FMT_NV61X* + * YUV422 3 x V4L2_PIX_FMT_YUV422P + * +*/ + +/* + * V 4 L 2 F I M C E X T E N S I O N S + * +*/ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') + +/* FOURCC for FIMC specific */ +#define V4L2_PIX_FMT_NV12X v4l2_fourcc('N', '1', '2', 'X') +#define V4L2_PIX_FMT_NV21X v4l2_fourcc('N', '2', '1', 'X') +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#define V4L2_PIX_FMT_NV16X v4l2_fourcc('N', '1', '6', 'X') +#define V4L2_PIX_FMT_NV61X v4l2_fourcc('N', '6', '1', 'X') + +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) +/* + * U S E R D E F I N E D T Y P E S + * +*/ + +typedef unsigned int dma_addr_t; + +struct fimc_buf { + dma_addr_t base[3]; + size_t length[3]; +}; + +struct fimc_buffer { + void *virt_addr; + void *phys_addr; + size_t length; +}; + +struct yuv_fmt_list { + const char *name; + const char *desc; + unsigned int fmt; + int bpp; + int planes; +}; + +struct img_offset { + int y_h; + int y_v; + int cb_h; + int cb_v; + int cr_h; + int cr_v; +}; + +//------------ STRUCT ---------------------------------------------------------// + +typedef struct +{ + unsigned int full_width; // Source Image Full Width (Virtual screen size) + unsigned int full_height; // Source Image Full Height (Virtual screen size) + unsigned int start_x; // Source Image Start width offset + unsigned int start_y; // Source Image Start height offset + unsigned int width; // Source Image Width + unsigned int height; // Source Image Height + unsigned int buf_addr_phy_rgb_y; // Base Address of the Source Image (RGB or Y): Physical Address + unsigned int buf_addr_phy_cb; // Base Address of the Source Image (CB Component) : Physical Address + unsigned int buf_addr_phy_cr; // Base Address of the Source Image (CR Component) : Physical Address + unsigned int color_space; // Color Space of the Source Image +} s5p_fimc_img_info; + +typedef struct +{ + s5p_fimc_img_info src; + s5p_fimc_img_info dst; +} s5p_fimc_params_t; + +typedef struct _s5p_fimc_t { + int dev_fd; + struct fimc_buffer out_buf; + + s5p_fimc_params_t params; + + int use_ext_out_mem; + unsigned int hw_ver; +}s5p_fimc_t; + +//------------------------ functions for v4l2 ------------------------------// +int fimc_v4l2_set_src(int fd, unsigned int hw_ver, s5p_fimc_img_info *src); +int fimc_v4l2_set_dst(int fd, s5p_fimc_img_info *dst, int rotation, unsigned int addr); +int fimc_v4l2_stream_on(int fd, enum v4l2_buf_type type); +int fimc_v4l2_queue(int fd, struct fimc_buf *fimc_buf); +int fimc_v4l2_dequeue(int fd); +int fimc_v4l2_stream_off(int fd); +int fimc_v4l2_clr_buf(int fd); +int fimc_handle_oneshot(int fd, struct fimc_buf *fimc_buf); +#endif diff --git a/include/videodev2_samsung.h b/include/videodev2_samsung.h new file mode 100755 index 0000000..0a7d7c3 --- /dev/null +++ b/include/videodev2_samsung.h @@ -0,0 +1,633 @@ +/* + * Video for Linux Two header file for samsung + * + * Copyright (C) 2009, Samsung Electronics + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until bein accepted, will be used restrictly in Samsung's + * camera interface driver FIMC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Alternatively, Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LINUX_VIDEODEV2_SAMSUNG_H +#define __LINUX_VIDEODEV2_SAMSUNG_H + +/* Values for 'capabilities' field */ +/* Object detection device */ +#define V4L2_CAP_OBJ_RECOGNITION 0x10000000 +/* strobe control */ +#define V4L2_CAP_STROBE 0x20000000 + +#define V4L2_CID_FOCUS_MODE (V4L2_CID_CAMERA_CLASS_BASE + 17) +/* Focus Methods */ +enum v4l2_focus_mode { + V4L2_FOCUS_MODE_AUTO = 0, + V4L2_FOCUS_MODE_MACRO = 1, + V4L2_FOCUS_MODE_MANUAL = 2, + V4L2_FOCUS_MODE_LASTP = 2, +}; + +#define V4L2_CID_ZOOM_MODE (V4L2_CID_CAMERA_CLASS_BASE + 18) +/* Zoom Methods */ +enum v4l2_zoom_mode { + V4L2_ZOOM_MODE_CONTINUOUS = 0, + V4L2_ZOOM_MODE_OPTICAL = 1, + V4L2_ZOOM_MODE_DIGITAL = 2, + V4L2_ZOOM_MODE_LASTP = 2, +}; + +/* Exposure Methods */ +#define V4L2_CID_PHOTOMETRY (V4L2_CID_CAMERA_CLASS_BASE + 19) +enum v4l2_photometry_mode { + V4L2_PHOTOMETRY_MULTISEG = 0, /*Multi Segment */ + V4L2_PHOTOMETRY_CWA = 1, /*Centre Weighted Average */ + V4L2_PHOTOMETRY_SPOT = 2, + V4L2_PHOTOMETRY_AFSPOT = 3, /*Spot metering on focused point */ + V4L2_PHOTOMETRY_LASTP = V4L2_PHOTOMETRY_AFSPOT, +}; + +/* Manual exposure control items menu type: iris, shutter, iso */ +#define V4L2_CID_CAM_APERTURE (V4L2_CID_CAMERA_CLASS_BASE + 20) +#define V4L2_CID_CAM_SHUTTER (V4L2_CID_CAMERA_CLASS_BASE + 21) +#define V4L2_CID_CAM_ISO (V4L2_CID_CAMERA_CLASS_BASE + 22) + +/* Following CIDs are menu type */ +#define V4L2_CID_SCENEMODE (V4L2_CID_CAMERA_CLASS_BASE + 23) +#define V4L2_CID_CAM_STABILIZE (V4L2_CID_CAMERA_CLASS_BASE + 24) +#define V4L2_CID_CAM_MULTISHOT (V4L2_CID_CAMERA_CLASS_BASE + 25) + +/* Control dynamic range */ +#define V4L2_CID_CAM_DR (V4L2_CID_CAMERA_CLASS_BASE + 26) + +/* White balance preset control */ +#define V4L2_CID_WHITE_BALANCE_PRESET (V4L2_CID_CAMERA_CLASS_BASE + 27) + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5) +#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_DST_INFO (V4L2_CID_PRIVATE_BASE + 10) +#define V4L2_CID_IMAGE_EFFECT_FN (V4L2_CID_PRIVATE_BASE + 16) +#define V4L2_CID_IMAGE_EFFECT_APPLY (V4L2_CID_PRIVATE_BASE + 17) +#define V4L2_CID_IMAGE_EFFECT_CB (V4L2_CID_PRIVATE_BASE + 18) +#define V4L2_CID_IMAGE_EFFECT_CR (V4L2_CID_PRIVATE_BASE + 19) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) + +/* CID Extensions for camera sensor operations */ +#define V4L2_CID_CAM_PREVIEW_ONOFF (V4L2_CID_PRIVATE_BASE + 64) +#define V4L2_CID_CAM_CAPTURE (V4L2_CID_PRIVATE_BASE + 65) +#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_PRIVATE_BASE + 66) + +#define V4L2_CID_CAM_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 14) +#define V4L2_CID_CAM_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 15) +#define V4L2_CID_CAM_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 22) +#define V4L2_CID_CAM_SENSOR_VER (V4L2_CID_PRIVATE_BASE + 23) +#define V4L2_CID_CAM_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 24) +#define V4L2_CID_CAM_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 25) +#define V4L2_CID_CAM_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 26) +#define V4L2_CID_CAM_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 27) +#define V4L2_CID_CAM_FW_VER (V4L2_CID_PRIVATE_BASE + 28) +#define V4L2_CID_CAM_SET_FW_ADDR (V4L2_CID_PRIVATE_BASE + 29) +#define V4L2_CID_CAM_SET_FW_SIZE (V4L2_CID_PRIVATE_BASE + 30) +#define V4L2_CID_CAM_UPDATE_FW (V4L2_CID_PRIVATE_BASE + 31) +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) +#define V4L2_CID_CAM_SENSOR_MAKER (V4L2_CID_PRIVATE_BASE + 38) +#define V4L2_CID_CAM_SENSOR_OPTICAL (V4L2_CID_PRIVATE_BASE + 39) +#define V4L2_CID_CAM_AF_VER_LOW (V4L2_CID_PRIVATE_BASE + 40) +#define V4L2_CID_CAM_AF_VER_HIGH (V4L2_CID_PRIVATE_BASE + 41) +#define V4L2_CID_CAM_GAMMA_RG_LOW (V4L2_CID_PRIVATE_BASE + 42) +#define V4L2_CID_CAM_GAMMA_RG_HIGH (V4L2_CID_PRIVATE_BASE + 43) +#define V4L2_CID_CAM_GAMMA_BG_LOW (V4L2_CID_PRIVATE_BASE + 44) +#define V4L2_CID_CAM_GAMMA_BG_HIGH (V4L2_CID_PRIVATE_BASE + 45) +#define V4L2_CID_CAM_DUMP_FW (V4L2_CID_PRIVATE_BASE + 46) +#define V4L2_CID_CAM_GET_DUMP_SIZE (V4L2_CID_PRIVATE_BASE + 47) +#define V4L2_CID_CAMERA_VT_MODE (V4L2_CID_PRIVATE_BASE + 48) +#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49) +#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50) + +#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54) +#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55) +#define V4L2_CID_MAIN_SW_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 56) +#define V4L2_CID_MAIN_SW_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 57) +#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58) +#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59) +#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60) + +enum v4l2_blur { + BLUR_LEVEL_0 = 0, + BLUR_LEVEL_1, + BLUR_LEVEL_2, + BLUR_LEVEL_3, + BLUR_LEVEL_MAX, +}; + +#define V4L2_CID_CAMERA_SCENE_MODE (V4L2_CID_PRIVATE_BASE + 70) +enum v4l2_scene_mode { + SCENE_MODE_BASE, + SCENE_MODE_NONE, + SCENE_MODE_PORTRAIT, + SCENE_MODE_NIGHTSHOT, + SCENE_MODE_BACK_LIGHT, + SCENE_MODE_LANDSCAPE, + SCENE_MODE_SPORTS, + SCENE_MODE_PARTY_INDOOR, + SCENE_MODE_BEACH_SNOW, + SCENE_MODE_SUNSET, + SCENE_MODE_DUST_DAWN, + SCENE_MODE_FALL_COLOR, + SCENE_MODE_FIREWORKS, + SCENE_MODE_TEXT, + SCENE_MODE_CANDLE_LIGHT, + SCENE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_FLASH_MODE (V4L2_CID_PRIVATE_BASE + 71) +enum v4l2_flash_mode { + FLASH_MODE_BASE, + FLASH_MODE_OFF, + FLASH_MODE_AUTO, + FLASH_MODE_ON, + FLASH_MODE_TORCH, + FLASH_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRIGHTNESS (V4L2_CID_PRIVATE_BASE + 72) +enum v4l2_ev_mode { + EV_MINUS_4 = 0, + EV_MINUS_3, + EV_MINUS_2, + EV_MINUS_1, + EV_DEFAULT, + EV_PLUS_1, + EV_PLUS_2, + EV_PLUS_3, + EV_PLUS_4, + EV_MAX, +}; + +#define V4L2_CID_CAMERA_WHITE_BALANCE (V4L2_CID_PRIVATE_BASE + 73) +enum v4l2_wb_mode { + WHITE_BALANCE_BASE = 0, + WHITE_BALANCE_AUTO, + WHITE_BALANCE_SUNNY, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_TUNGSTEN, + WHITE_BALANCE_FLUORESCENT, + WHITE_BALANCE_MAX, +}; + +#define V4L2_CID_CAMERA_EFFECT (V4L2_CID_PRIVATE_BASE + 74) +enum v4l2_effect_mode { + IMAGE_EFFECT_BASE = 0, + IMAGE_EFFECT_NONE, + IMAGE_EFFECT_BNW, + IMAGE_EFFECT_SEPIA, + IMAGE_EFFECT_AQUA, + IMAGE_EFFECT_ANTIQUE, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_SHARPEN, + IMAGE_EFFECT_MAX, +}; + +#define V4L2_CID_CAMERA_ISO (V4L2_CID_PRIVATE_BASE + 75) +enum v4l2_iso_mode { + ISO_AUTO = 0, + ISO_50, + ISO_100, + ISO_200, + ISO_400, + ISO_800, + ISO_1600, + ISO_SPORTS, + ISO_NIGHT, + ISO_MOVIE, + ISO_MAX, +}; + +#define V4L2_CID_CAMERA_METERING (V4L2_CID_PRIVATE_BASE + 76) +enum v4l2_metering_mode { + METERING_BASE = 0, + METERING_MATRIX, + METERING_CENTER, + METERING_SPOT, + METERING_MAX, +}; + +#define V4L2_CID_CAMERA_CONTRAST (V4L2_CID_PRIVATE_BASE + 77) +enum v4l2_contrast_mode { + CONTRAST_MINUS_2 = 0, + CONTRAST_MINUS_1, + CONTRAST_DEFAULT, + CONTRAST_PLUS_1, + CONTRAST_PLUS_2, + CONTRAST_MAX, +}; + +#define V4L2_CID_CAMERA_SATURATION (V4L2_CID_PRIVATE_BASE + 78) +enum v4l2_saturation_mode { + SATURATION_MINUS_2 = 0, + SATURATION_MINUS_1, + SATURATION_DEFAULT, + SATURATION_PLUS_1, + SATURATION_PLUS_2, + SATURATION_MAX, +}; + +#define V4L2_CID_CAMERA_SHARPNESS (V4L2_CID_PRIVATE_BASE + 79) +enum v4l2_sharpness_mode { + SHARPNESS_MINUS_2 = 0, + SHARPNESS_MINUS_1, + SHARPNESS_DEFAULT, + SHARPNESS_PLUS_1, + SHARPNESS_PLUS_2, + SHARPNESS_MAX, +}; + +#define V4L2_CID_CAMERA_WDR (V4L2_CID_PRIVATE_BASE + 80) +enum v4l2_wdr_mode { + WDR_OFF, + WDR_ON, + WDR_MAX, +}; + +#define V4L2_CID_CAMERA_ANTI_SHAKE (V4L2_CID_PRIVATE_BASE + 81) +enum v4l2_anti_shake_mode { + ANTI_SHAKE_OFF, + ANTI_SHAKE_STILL_ON, + ANTI_SHAKE_MOVIE_ON, + ANTI_SHAKE_MAX, +}; + +#define V4L2_CID_CAMERA_TOUCH_AF_START_STOP (V4L2_CID_PRIVATE_BASE + 82) +enum v4l2_touch_af { + TOUCH_AF_STOP = 0, + TOUCH_AF_START, + TOUCH_AF_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO (V4L2_CID_PRIVATE_BASE + 83) +enum v4l2_smart_auto { + SMART_AUTO_OFF = 0, + SMART_AUTO_ON, + SMART_AUTO_MAX, +}; + +#define V4L2_CID_CAMERA_VINTAGE_MODE (V4L2_CID_PRIVATE_BASE + 84) +enum v4l2_vintage_mode { + VINTAGE_MODE_BASE, + VINTAGE_MODE_OFF, + VINTAGE_MODE_NORMAL, + VINTAGE_MODE_WARM, + VINTAGE_MODE_COOL, + VINTAGE_MODE_BNW, + VINTAGE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 85) +#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE + 30) +#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31) +#define V4L2_CID_CAMERA_GPS_TIMESTAMP (V4L2_CID_CAMERA_CLASS_BASE + 32) +#define V4L2_CID_CAMERA_GPS_ALTITUDE (V4L2_CID_CAMERA_CLASS_BASE + 33) +#define V4L2_CID_CAMERA_EXIF_TIME_INFO (V4L2_CID_CAMERA_CLASS_BASE + 34) +#define V4L2_CID_CAMERA_ZOOM (V4L2_CID_PRIVATE_BASE + 90) +enum v4l2_zoom_level { + ZOOM_LEVEL_0 = 0, + ZOOM_LEVEL_1, + ZOOM_LEVEL_2, + ZOOM_LEVEL_3, + ZOOM_LEVEL_4, + ZOOM_LEVEL_5, + ZOOM_LEVEL_6, + ZOOM_LEVEL_7, + ZOOM_LEVEL_8, + ZOOM_LEVEL_9, + ZOOM_LEVEL_10, + ZOOM_LEVEL_11, + ZOOM_LEVEL_12, + ZOOM_LEVEL_MAX, +}; + +#define V4L2_CID_CAMERA_FACE_DETECTION (V4L2_CID_PRIVATE_BASE + 91) +enum v4l2_face_detection { + FACE_DETECTION_OFF = 0, + FACE_DETECTION_ON, + FACE_DETECTION_NOLINE, + FACE_DETECTION_ON_BEAUTY, + FACE_DETECTION_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO_STATUS (V4L2_CID_PRIVATE_BASE + 92) +enum v4l2_smart_auto_status { + SMART_AUTO_STATUS_AUTO = 0, + SMART_AUTO_STATUS_LANDSCAPE, + SMART_AUTO_STATUS_PORTRAIT, + SMART_AUTO_STATUS_MACRO, + SMART_AUTO_STATUS_NIGHT, + SMART_AUTO_STATUS_PORTRAIT_NIGHT, + SMART_AUTO_STATUS_BACKLIT, + SMART_AUTO_STATUS_PORTRAIT_BACKLIT, + SMART_AUTO_STATUS_ANTISHAKE, + SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE, + SMART_AUTO_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_SET_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE + 93) +enum v4l2_auto_focus { + AUTO_FOCUS_OFF = 0, + AUTO_FOCUS_ON, + AUTO_FOCUS_MAX, +}; + +#define V4L2_CID_CAMERA_BEAUTY_SHOT (V4L2_CID_PRIVATE_BASE + 94) +enum v4l2_beauty_shot { + BEAUTY_SHOT_OFF = 0, + BEAUTY_SHOT_ON, + BEAUTY_SHOT_MAX, +}; + +#define V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 95) +enum v4l2_ae_awb_lockunlock { + AE_UNLOCK_AWB_UNLOCK = 0, + AE_LOCK_AWB_UNLOCK, + AE_UNLOCK_AWB_LOCK, + AE_LOCK_AWB_LOCK, + AE_AWB_MAX +}; + +#define V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK (V4L2_CID_PRIVATE_BASE + 96) +enum v4l2_face_lock { + FACE_LOCK_OFF = 0, + FACE_LOCK_ON, + FIRST_FACE_TRACKING, + FACE_LOCK_MAX, +}; + +#define V4L2_CID_CAMERA_OBJECT_POSITION_X (V4L2_CID_PRIVATE_BASE + 97) +#define V4L2_CID_CAMERA_OBJECT_POSITION_Y (V4L2_CID_PRIVATE_BASE + 98) +#define V4L2_CID_CAMERA_FOCUS_MODE (V4L2_CID_PRIVATE_BASE + 99) +enum v4l2_focusmode { + FOCUS_MODE_AUTO = 0, + FOCUS_MODE_MACRO, + FOCUS_MODE_FACEDETECT, + FOCUS_MODE_AUTO_DEFAULT, + FOCUS_MODE_MACRO_DEFAULT, + FOCUS_MODE_FACEDETECT_DEFAULT, + FOCUS_MODE_INFINITY, + FOCUS_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE + 100) +enum v4l2_obj_tracking_status { + OBJECT_TRACKING_STATUS_BASE, + OBJECT_TRACKING_STATUS_PROGRESSING, + OBJECT_TRACKING_STATUS_SUCCESS, + OBJECT_TRACKING_STATUS_FAIL, + OBJECT_TRACKING_STATUS_MISSING, + OBJECT_TRACKING_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP (V4L2_CID_PRIVATE_BASE + 101) +enum v4l2_ot_start_stop { + OT_STOP = 0, + OT_START, + OT_MAX, +}; + +#define V4L2_CID_CAMERA_CAF_START_STOP (V4L2_CID_PRIVATE_BASE + 102) +enum v4l2_caf_start_stop { + CAF_STOP = 0, + CAF_START, + CAF_MAX, +}; + +#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT (V4L2_CID_PRIVATE_BASE + 103) +#define V4L2_CID_CAMERA_FRAME_RATE (V4L2_CID_PRIVATE_BASE + 104) +enum v4l2_frame_rate { + FRAME_RATE_AUTO = 0, + FRAME_RATE_7 = 7, + FRAME_RATE_15 = 15, + FRAME_RATE_30 = 30, + FRAME_RATE_60 = 60, + FRAME_RATE_120 = 120, + FRAME_RATE_MAX +}; + +#define V4L2_CID_CAMERA_ANTI_BANDING (V4L2_CID_PRIVATE_BASE + 105) +enum v4l2_anti_banding { + ANTI_BANDING_AUTO = 0, + ANTI_BANDING_50HZ = 1, + ANTI_BANDING_60HZ = 2, + ANTI_BANDING_OFF = 3, +}; + +#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE + 106) +enum v4l2_gamma_mode { + GAMMA_OFF = 0, + GAMMA_ON = 1, + GAMMA_MAX, +}; + +#define V4L2_CID_CAMERA_SET_SLOW_AE (V4L2_CID_PRIVATE_BASE + 107) +enum v4l2_slow_ae_mode { + SLOW_AE_OFF, + SLOW_AE_ON, + SLOW_AE_MAX, +}; + +#define V4L2_CID_CAMERA_BATCH_REFLECTION (V4L2_CID_PRIVATE_BASE + 108) +#define V4L2_CID_CAMERA_EXIF_ORIENTATION (V4L2_CID_PRIVATE_BASE + 109) + +#define V4L2_CID_CAMERA_RESET (V4L2_CID_PRIVATE_BASE + 111) +#define V4L2_CID_CAMERA_CHECK_DATALINE (V4L2_CID_PRIVATE_BASE + 112) +#define V4L2_CID_CAMERA_CHECK_DATALINE_STOP (V4L2_CID_PRIVATE_BASE + 113) +#define V4L2_CID_CAMERA_GET_ISO (V4L2_CID_PRIVATE_BASE + 114) +#define V4L2_CID_CAMERA_GET_SHT_TIME (V4L2_CID_PRIVATE_BASE + 115) +#define V4L2_CID_CAMERA_SENSOR_MODE (V4L2_CID_PRIVATE_BASE + 116) +#define V4L2_CID_ESD_INT (V4L2_CID_PRIVATE_BASE + 117) +#define V4L2_CID_CAMERA_GET_FLASH_ONOFF (V4L2_CID_PRIVATE_BASE + 118) +#define V4L2_CID_CAMERA_RETURN_FOCUS (V4L2_CID_PRIVATE_BASE + 119) + +/* Pixel format FOURCC depth Description */ +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') + +/* + * * V4L2 extention for digital camera + * */ +/* Strobe flash light */ +enum v4l2_strobe_control { + /* turn off the flash light */ + V4L2_STROBE_CONTROL_OFF = 0, + /* turn on the flash light */ + V4L2_STROBE_CONTROL_ON = 1, + /* act guide light before splash */ + V4L2_STROBE_CONTROL_AFGUIDE = 2, + /* charge the flash light */ + V4L2_STROBE_CONTROL_CHARGE = 3, +}; + +enum v4l2_strobe_conf { + V4L2_STROBE_OFF = 0, /* Always off */ + V4L2_STROBE_ON = 1, /* Always splashes */ + /* Auto control presets */ + V4L2_STROBE_AUTO = 2, + V4L2_STROBE_REDEYE_REDUCTION = 3, + V4L2_STROBE_SLOW_SYNC = 4, + V4L2_STROBE_FRONT_CURTAIN = 5, + V4L2_STROBE_REAR_CURTAIN = 6, + /* Extra manual control presets */ + /* keep turned on until turning off */ + V4L2_STROBE_PERMANENT = 7, + V4L2_STROBE_EXTERNAL = 8, +}; + +enum v4l2_strobe_status { + V4L2_STROBE_STATUS_OFF = 0, + /* while processing configurations */ + V4L2_STROBE_STATUS_BUSY = 1, + V4L2_STROBE_STATUS_ERR = 2, + V4L2_STROBE_STATUS_CHARGING = 3, + V4L2_STROBE_STATUS_CHARGED = 4, +}; + +/* capabilities field */ +/* No strobe supported */ +#define V4L2_STROBE_CAP_NONE 0x0000 +/* Always flash off mode */ +#define V4L2_STROBE_CAP_OFF 0x0001 +/* Always use flash light mode */ +#define V4L2_STROBE_CAP_ON 0x0002 +/* Flashlight works automatic */ +#define V4L2_STROBE_CAP_AUTO 0x0004 +/* Red-eye reduction */ +#define V4L2_STROBE_CAP_REDEYE 0x0008 +/* Slow sync */ +#define V4L2_STROBE_CAP_SLOWSYNC 0x0010 +/* Front curtain */ +#define V4L2_STROBE_CAP_FRONT_CURTAIN 0x0020 +/* Rear curtain */ +#define V4L2_STROBE_CAP_REAR_CURTAIN 0x0040 +/* keep turned on until turning off */ +#define V4L2_STROBE_CAP_PERMANENT 0x0080 +/* use external strobe */ +#define V4L2_STROBE_CAP_EXTERNAL 0x0100 + +/* Set mode and Get status */ +struct v4l2_strobe { + /* off/on/charge:0/1/2 */ + enum v4l2_strobe_control control; + /* supported strobe capabilities */ + __u32 capabilities; + enum v4l2_strobe_conf mode; + enum v4l2_strobe_status status; /* read only */ + /* default is 0 and range of value varies from each models */ + __u32 flash_ev; + __u32 reserved[4]; +}; + +#define VIDIOC_S_STROBE _IOWR('V', 83, struct v4l2_strobe) +#define VIDIOC_G_STROBE _IOR('V', 84, struct v4l2_strobe) + +/* Object recognition and collateral actions */ +enum v4l2_recog_mode { + V4L2_RECOGNITION_MODE_OFF = 0, + V4L2_RECOGNITION_MODE_ON = 1, + V4L2_RECOGNITION_MODE_LOCK = 2, +}; + +enum v4l2_recog_action { + V4L2_RECOGNITION_ACTION_NONE = 0, /* only recognition */ + V4L2_RECOGNITION_ACTION_BLINK = 1, /* Capture on blinking */ + V4L2_RECOGNITION_ACTION_SMILE = 2, /* Capture on smiling */ +}; + +enum v4l2_recog_pattern { + V4L2_RECOG_PATTERN_FACE = 0, /* Face */ + V4L2_RECOG_PATTERN_HUMAN = 1, /* Human */ + V4L2_RECOG_PATTERN_CHAR = 2, /* Character */ +}; + +struct v4l2_recog_rect { + enum v4l2_recog_pattern p; /* detected pattern */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recog_data { + __u8 detect_cnt; /* detected object counter */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recognition { + enum v4l2_recog_mode mode; + + /* Which pattern to detect */ + enum v4l2_recog_pattern pattern; + + /* How many object to detect */ + __u8 obj_num; + + /* select detected object */ + __u32 detect_idx; + + /* read only :Get object coordination */ + struct v4l2_recog_data data; + + enum v4l2_recog_action action; + __u32 reserved[4]; +}; + +#define VIDIOC_S_RECOGNITION _IOWR('V', 85, struct v4l2_recognition) +#define VIDIOC_G_RECOGNITION _IOR('V', 86, struct v4l2_recognition) + +/* We use this struct as the v4l2_streamparm raw_data for + * VIDIOC_G_PARM and VIDIOC_S_PARM + */ +struct sec_cam_parm { + struct v4l2_captureparm capture; + int contrast; + int effects; + int brightness; + int flash_mode; + int focus_mode; + int iso; + int metering; + int saturation; + int scene_mode; + int sharpness; + int white_balance; +}; + +#endif /* __LINUX_VIDEODEV2_SAMSUNG_H */ diff --git a/libexifa/Android.mk b/libexifa/Android.mk new file mode 100755 index 0000000..e27ee2e --- /dev/null +++ b/libexifa/Android.mk @@ -0,0 +1,46 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRELINK_MODULE:=false + +LOCAL_C_INCLUDES += $(LOCAL_PATH)\ + $(LOCAL_PATH)/libexif/\ + $(LOCAL_PATH)/libexif/canon/\ + $(LOCAL_PATH)/libexif/fuji/\ + $(LOCAL_PATH)/libexif/olympus/\ + $(LOCAL_PATH)/libexif/pentax/ + +LOCAL_SRC_FILES:=\ + canon/exif-mnote-data-canon.c\ + canon/mnote-canon-tag.c\ + canon/mnote-canon-entry.c\ + pentax/mnote-pentax-tag.c\ + pentax/mnote-pentax-entry.c\ + pentax/exif-mnote-data-pentax.c\ + exif-loader.c\ + exif-byte-order.c\ + exif-content.c\ + exif-log.c\ + exif-mem.c\ + olympus/mnote-olympus-tag.c\ + olympus/mnote-olympus-entry.c\ + olympus/exif-mnote-data-olympus.c\ + exif-format.c\ + exif-utils.c\ + exif-entry.c\ + exif-ifd.c\ + exif-data.c\ + exif-tag.c\ + fuji/mnote-fuji-tag.c\ + fuji/mnote-fuji-entry.c\ + fuji/exif-mnote-data-fuji.c\ + exif-mnote-data.c + +#LOCAL_CFLAGS:=-O2 -g +#LOCAL_CFLAGS+=-DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -Dlinux -D__GLIBC__ -D_GNU_SOURCE + +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE:= libexifa + +include $(BUILD_SHARED_LIBRARY) diff --git a/libexifa/MODULE_LICENSE_LGPL b/libexifa/MODULE_LICENSE_LGPL new file mode 100755 index 0000000..e69de29 diff --git a/libexifa/NOTICE b/libexifa/NOTICE new file mode 100755 index 0000000..b1e3f5a --- /dev/null +++ b/libexifa/NOTICE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libexifa/canon/exif-mnote-data-canon.c b/libexifa/canon/exif-mnote-data-canon.c new file mode 100755 index 0000000..eb53598 --- /dev/null +++ b/libexifa/canon/exif-mnote-data-canon.c @@ -0,0 +1,389 @@ +/* exif-mnote-data-canon.c + * + * Copyright (c) 2002, 2003 Lutz Mueller + * Copyright (c) 2003 Matthieu Castet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "exif-mnote-data-canon.h" + +#include +#include +#include + +#include +#include +#include + +#define DEBUG + +static void +exif_mnote_data_canon_clear (ExifMnoteDataCanon *n) +{ + ExifMnoteData *d = (ExifMnoteData *) n; + unsigned int i; + + if (!n) return; + + if (n->entries) { + for (i = 0; i < n->count; i++) + if (n->entries[i].data) { + exif_mem_free (d->mem, n->entries[i].data); + n->entries[i].data = NULL; + } + exif_mem_free (d->mem, n->entries); + n->entries = NULL; + n->count = 0; + } +} + +static void +exif_mnote_data_canon_free (ExifMnoteData *n) +{ + if (!n) return; + + exif_mnote_data_canon_clear ((ExifMnoteDataCanon *) n); +} + +static void +exif_mnote_data_canon_get_tags (ExifMnoteDataCanon *dc, unsigned int n, + unsigned int *m, unsigned int *s) +{ + unsigned int from = 0, to; + + if (!dc || !m) return; + for (*m = 0; *m < dc->count; (*m)++) { + to = from + mnote_canon_entry_count_values (&dc->entries[*m]); + if (to > n) { + if (s) *s = n - from; + break; + } + from = to; + } +} + +static char * +exif_mnote_data_canon_get_value (ExifMnoteData *note, unsigned int n, char *val, unsigned int maxlen) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note; + unsigned int m, s; + + if (!dc) return NULL; + exif_mnote_data_canon_get_tags (dc, n, &m, &s); + if (m >= dc->count) return NULL; + return mnote_canon_entry_get_value (&dc->entries[m], s, val, maxlen); +} + +static void +exif_mnote_data_canon_set_byte_order (ExifMnoteData *d, ExifByteOrder o) +{ + ExifByteOrder o_orig; + ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) d; + unsigned int i; + + if (!n) return; + + o_orig = n->order; + n->order = o; + for (i = 0; i < n->count; i++) { + n->entries[i].order = o; + exif_array_set_byte_order (n->entries[i].format, n->entries[i].data, + n->entries[i].components, o_orig, o); + } +} + +static void +exif_mnote_data_canon_set_offset (ExifMnoteData *n, unsigned int o) +{ + if (n) ((ExifMnoteDataCanon *) n)->offset = o; +} + +static void +exif_mnote_data_canon_save (ExifMnoteData *ne, + unsigned char **buf, unsigned int *buf_size) +{ + ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne; + size_t i, o, s, doff; + unsigned char *t; + size_t ts; + + if (!n || !buf || !buf_size) return; + + /* + * Allocate enough memory for all entries and the number + * of entries. + */ + *buf_size = 2 + n->count * 12 + 4; + *buf = exif_mem_alloc (ne->mem, sizeof (char) * *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", *buf_size); + return; + } + + /* Save the number of entries */ + exif_set_short (*buf, n->order, (ExifShort) n->count); + + /* Save each entry */ + for (i = 0; i < n->count; i++) { + o = 2 + i * 12; + exif_set_short (*buf + o + 0, n->order, (ExifShort) n->entries[i].tag); + exif_set_short (*buf + o + 2, n->order, (ExifShort) n->entries[i].format); + exif_set_long (*buf + o + 4, n->order, + n->entries[i].components); + o += 8; + s = exif_format_get_size (n->entries[i].format) * + n->entries[i].components; + if (s > 65536) { + /* Corrupt data: EXIF data size is limited to the + * maximum size of a JPEG segment (64 kb). + */ + continue; + } + if (s > 4) { + ts = *buf_size + s; + + /* Ensure even offsets. Set padding bytes to 0. */ + if (s & 1) ts += 1; + t = exif_mem_realloc (ne->mem, *buf, + sizeof (char) * ts); + if (!t) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", ts); + return; + } + *buf = t; + *buf_size = ts; + doff = *buf_size - s; + if (s & 1) { doff--; *(*buf + *buf_size - 1) = '\0'; } + exif_set_long (*buf + o, n->order, n->offset + doff); + } else + doff = o; + + /* + * Write the data. Fill unneeded bytes with 0. Do not + * crash if data is NULL. + */ + if (!n->entries[i].data) memset (*buf + doff, 0, s); + else memcpy (*buf + doff, n->entries[i].data, s); + if (s < 4) memset (*buf + doff + s, 0, (4 - s)); + } +} + +/* XXX + * FIXME: exif_mnote_data_canon_load() may fail and there is no + * semantics to express that. + * See bug #1054323 for details, especially the comment by liblit + * after it has supposedly been fixed: + * + * https://sourceforge.net/tracker/?func=detail&aid=1054323&group_id=12272&atid=112272 + * Unfortunately, the "return" statements aren't commented at + * all, so it isn't trivial to find out what is a normal + * return, and what is a reaction to an error condition. + */ + +static void +exif_mnote_data_canon_load (ExifMnoteData *ne, + const unsigned char *buf, unsigned int buf_size) +{ + ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne; + ExifShort c; + size_t i, tcount, o, datao; + + if (!n || !buf || !buf_size) { + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteCanon", "Short MakerNote"); + return; + } + datao = 6 + n->offset; + if ((datao + 2 < datao) || (datao + 2 < 2) || (datao + 2 > buf_size)) { + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteCanon", "Short MakerNote"); + return; + } + + /* Read the number of tags */ + c = exif_get_short (buf + datao, n->order); + datao += 2; + + /* Remove any old entries */ + exif_mnote_data_canon_clear (n); + + /* Reserve enough space for all the possible MakerNote tags */ + n->entries = exif_mem_alloc (ne->mem, sizeof (MnoteCanonEntry) * c); + if (!n->entries) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", sizeof (MnoteCanonEntry) * c); + return; + } + + /* Parse the entries */ + tcount = 0; + for (i = c, o = datao; i; --i, o += 12) { + size_t s; + if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteCanon", "Short MakerNote"); + break; + } + + n->entries[tcount].tag = exif_get_short (buf + o, n->order); + n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); + n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); + n->entries[tcount].order = n->order; + + exif_log (ne->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteCanon", + "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, + mnote_canon_tag_get_name (n->entries[tcount].tag)); + + /* + * Size? If bigger than 4 bytes, the actual data is not + * in the entry but somewhere else (offset). + */ + s = exif_format_get_size (n->entries[tcount].format) * + n->entries[tcount].components; + n->entries[tcount].size = s; + if (!s) { + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteCanon", + "Invalid zero-length tag size"); + continue; + + } else { + size_t dataofs = o + 8; + if (s > 4) dataofs = exif_get_long (buf + dataofs, n->order) + 6; + if ((dataofs + s < s) || (dataofs + s < dataofs) || (dataofs + s > buf_size)) { + exif_log (ne->log, EXIF_LOG_CODE_DEBUG, + "ExifMnoteCanon", + "Tag data past end of buffer (%u > %u)", + dataofs + s, buf_size); + continue; + } + + n->entries[tcount].data = exif_mem_alloc (ne->mem, s); + if (!n->entries[tcount].data) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteCanon", s); + continue; + } + memcpy (n->entries[tcount].data, buf + dataofs, s); + } + + /* Tag was successfully parsed */ + ++tcount; + } + /* Store the count of successfully parsed tags */ + n->count = tcount; +} + +static unsigned int +exif_mnote_data_canon_count (ExifMnoteData *n) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) n; + unsigned int i, c; + + for (i = c = 0; dc && (i < dc->count); i++) + c += mnote_canon_entry_count_values (&dc->entries[i]); + return c; +} + +static unsigned int +exif_mnote_data_canon_get_id (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) d; + unsigned int m; + + if (!dc) return 0; + exif_mnote_data_canon_get_tags (dc, i, &m, NULL); + if (m >= dc->count) return 0; + return dc->entries[m].tag; +} + +static const char * +exif_mnote_data_canon_get_name (ExifMnoteData *note, unsigned int i) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note; + unsigned int m, s; + + if (!dc) return NULL; + exif_mnote_data_canon_get_tags (dc, i, &m, &s); + if (m >= dc->count) return NULL; + return mnote_canon_tag_get_name_sub (dc->entries[m].tag, s, dc->options); +} + +static const char * +exif_mnote_data_canon_get_title (ExifMnoteData *note, unsigned int i) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note; + unsigned int m, s; + + if (!dc) return NULL; + exif_mnote_data_canon_get_tags (dc, i, &m, &s); + if (m >= dc->count) return NULL; + return mnote_canon_tag_get_title_sub (dc->entries[m].tag, s, dc->options); +} + +static const char * +exif_mnote_data_canon_get_description (ExifMnoteData *note, unsigned int i) +{ + ExifMnoteDataCanon *dc = (ExifMnoteDataCanon *) note; + unsigned int m; + + if (!dc) return NULL; + exif_mnote_data_canon_get_tags (dc, i, &m, NULL); + if (m >= dc->count) return NULL; + return mnote_canon_tag_get_description (dc->entries[m].tag); +} + +int +exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e) +{ + char value[8]; + ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE); + if (!em) + return 0; + return !strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon"); +} + +ExifMnoteData * +exif_mnote_data_canon_new (ExifMem *mem, ExifDataOption o) +{ + ExifMnoteData *d; + ExifMnoteDataCanon *dc; + + if (!mem) return NULL; + + d = exif_mem_alloc (mem, sizeof (ExifMnoteDataCanon)); + if (!d) + return NULL; + + exif_mnote_data_construct (d, mem); + + /* Set up function pointers */ + d->methods.free = exif_mnote_data_canon_free; + d->methods.set_byte_order = exif_mnote_data_canon_set_byte_order; + d->methods.set_offset = exif_mnote_data_canon_set_offset; + d->methods.load = exif_mnote_data_canon_load; + d->methods.save = exif_mnote_data_canon_save; + d->methods.count = exif_mnote_data_canon_count; + d->methods.get_id = exif_mnote_data_canon_get_id; + d->methods.get_name = exif_mnote_data_canon_get_name; + d->methods.get_title = exif_mnote_data_canon_get_title; + d->methods.get_description = exif_mnote_data_canon_get_description; + d->methods.get_value = exif_mnote_data_canon_get_value; + + dc = (ExifMnoteDataCanon*)d; + dc->options = o; + return d; +} diff --git a/libexifa/canon/mnote-canon-entry.c b/libexifa/canon/mnote-canon-entry.c new file mode 100755 index 0000000..6e3be19 --- /dev/null +++ b/libexifa/canon/mnote-canon-entry.c @@ -0,0 +1,759 @@ +/* mnote-canon-entry.c + * + * Copyright (c) 2002 Lutz Mueller + * Copyright (c) 2003 Matthieu Castet + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "mnote-canon-entry.h" + +#include +#include +#include +#include + +#include +#include +#include + +/* #define DEBUG */ + +#define CF(format,target,v,maxlen) \ +{ \ + if (format != target) { \ + snprintf (v, maxlen, \ + _("Invalid format '%s', " \ + "expected '%s'."), \ + exif_format_get_name (format), \ + exif_format_get_name (target)); \ + break; \ + } \ +} + +#define CC(number,target,v,maxlen) \ +{ \ + if (number != target) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i)."), (int) number, (int) target); \ + break; \ + } \ +} +#define CC2(number,t1,t2,v,maxlen) \ +{ \ + if ((number != t1) && (number != t2)) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i or %i)."), (int) number, \ + (int) t1, (int) t2); \ + break; \ + } \ +} + +#define UNDEFINED 0xFF + +static const struct canon_entry_table_t { + unsigned int subtag; + ExifShort value; + const char *name; +} entries_settings_1 [] = { +#ifndef NO_VERBOSE_TAG_DATA + { 0, 1, N_("Macro")}, + { 0, 2, N_("Normal")}, + { 2, 1, N_("Economy")}, + { 2, 2, N_("Normal")}, + { 2, 3, N_("Fine")}, + { 2, 4, N_("RAW")}, + { 2, 5, N_("Superfine")}, + { 3, 0, N_("Off")}, + { 3, 1, N_("Auto")}, + { 3, 2, N_("On")}, + { 3, 3, N_("Red-eye reduction")}, + { 3, 4, N_("Slow synchro")}, + { 3, 5, N_("Auto, red-eye reduction")}, + { 3, 6, N_("On, red-eye reduction")}, + { 3, 16, N_("External flash")}, + { 4, 0, N_("Single")}, + { 4, 1, N_("Continuous")}, + { 4, 2, N_("Movie")}, + { 4, 3, N_("Continuous, speed priority")}, + { 4, 4, N_("Continuous, low")}, + { 4, 5, N_("Continuous, high")}, + { 6, 0, N_("One-shot AF")}, + { 6, 1, N_("AI servo AF")}, + { 6, 2, N_("AI focus AF")}, + { 6, 3, N_("Manual focus")}, + { 6, 4, N_("Single")}, + { 6, 5, N_("Continuous")}, + { 6, 6, N_("Manual focus")}, + { 6, 16, N_("Pan focus")}, + { 8, 1, N_("JPEG")}, + { 8, 2, N_("CRW+THM")}, + { 8, 3, N_("AVI+THM")}, + { 8, 4, N_("TIF")}, + { 8, 5, N_("TIF+JPEG")}, + { 8, 6, N_("CR2")}, + { 8, 7, N_("CR2+JPEG")}, + { 9, 0, N_("Large")}, + { 9, 1, N_("Medium")}, + { 9, 2, N_("Small")}, + { 9, 5, N_("Medium 1")}, + { 9, 6, N_("Medium 2")}, + { 9, 7, N_("Medium 3")}, + { 9, 8, N_("Postcard")}, + { 9, 9, N_("Widescreen")}, + {10, 0, N_("Full auto")}, + {10, 1, N_("Manual")}, + {10, 2, N_("Landscape")}, + {10, 3, N_("Fast shutter")}, + {10, 4, N_("Slow shutter")}, + {10, 5, N_("Night")}, + {10, 6, N_("Grayscale")}, + {10, 7, N_("Sepia")}, + {10, 8, N_("Portrait")}, + {10, 9, N_("Sports")}, + {10, 10, N_("Macro")}, + {10, 11, N_("Black & white")}, + {10, 12, N_("Pan focus")}, + {10, 13, N_("Vivid")}, + {10, 14, N_("Neutral")}, + {10, 15, N_("Flash off")}, + {10, 16, N_("Long shutter")}, + {10, 17, N_("Super macro")}, + {10, 18, N_("Foliage")}, + {10, 19, N_("Indoor")}, + {10, 20, N_("Fireworks")}, + {10, 21, N_("Beach")}, + {10, 22, N_("Underwater")}, + {10, 23, N_("Snow")}, + {10, 24, N_("Kids & pets")}, + {10, 25, N_("Night snapshot")}, + {10, 26, N_("Digital macro")}, + {10, 27, N_("My colors")}, + {10, 28, N_("Still image")}, + {10, 30, N_("Color accent")}, + {10, 31, N_("Color swap")}, + {10, 32, N_("Aquarium")}, + {10, 33, N_("ISO 3200")}, + {11, 0, N_("None")}, + {11, 1, N_("2x")}, + {11, 2, N_("4x")}, + {11, 3, N_("Other")}, + {12, 0x0000, N_("Normal")}, + {12, 0x0001, N_("High")}, + {12, 0xffff, N_("Low")}, + {13, 0x0000, N_("Normal")}, + {13, 0x0001, N_("High")}, + {13, 0xffff, N_("Low")}, + {14, 0x0000, N_("Normal")}, + {14, 0x0001, N_("High")}, + {14, 0xffff, N_("Low")}, + {15, 14, N_("Auto high")}, + {15, 15, N_("Auto")}, + {15, 16, N_("50")}, + {15, 17, N_("100")}, + {15, 18, N_("200")}, + {15, 19, N_("400")}, + {15, 20, N_("800")}, + {16, 0, N_("Default")}, + {16, 1, N_("Spot")}, + {16, 2, N_("Average")}, + {16, 3, N_("Evaluative")}, + {16, 4, N_("Partial")}, + {16, 5, N_("Center-weighted average")}, + {17, 0, N_("Manual")}, + {17, 1, N_("Auto")}, + {17, 2, N_("Not known")}, + {17, 3, N_("Macro")}, + {17, 4, N_("Very close")}, + {17, 5, N_("Close")}, + {17, 6, N_("Middle range")}, + {17, 7, N_("Far range")}, + {17, 8, N_("Pan focus")}, + {17, 9, N_("Super macro")}, + {17, 10, N_("Infinity")}, + {18, 0x2005, N_("Manual AF point selection")}, + {18, 0x3000, N_("None (MF)")}, + {18, 0x3001, N_("Auto-selected")}, + {18, 0x3002, N_("Right")}, + {18, 0x3003, N_("Center")}, + {18, 0x3004, N_("Left")}, + {18, 0x4001, N_("Auto AF point selection")}, + {19, 0, N_("Easy shooting")}, + {19, 1, N_("Program")}, + {19, 2, N_("Tv-priority")}, + {19, 3, N_("Av-priority")}, + {19, 4, N_("Manual")}, + {19, 5, N_("A-DEP")}, + {19, 6, N_("M-DEP")}, + {21, 1, N_("Canon EF 50mm f/1.8")}, + {21, 2, N_("Canon EF 28mm f/2.8")}, + {21, 4, N_("Sigma UC Zoom 35-135mm f/4-5.6")}, + {21, 6, N_("Tokina AF193-2 19-35mm f/3.5-4.5")}, + {21, 7, N_("Canon EF 100-300mm F5.6L")}, + {21, 10, N_("Sigma 50mm f/2.8 EX or 28mm f/1.8")}, + {21, 11, N_("Canon EF 35mm f/2")}, + {21, 13, N_("Canon EF 15mm f/2.8")}, + {21, 21, N_("Canon EF 80-200mm f/2.8L")}, + {21, 22, N_("Tokina AT-X280AF PRO 28-80mm F2.8 Aspherical")}, + {21, 26, N_("Cosina 100mm f/3.5 Macro AF")}, + {21, 28, N_("Tamron AF Aspherical 28-200mm f/3.8-5.6")}, + {21, 29, N_("Canon EF 50mm f/1.8 MkII")}, + {21, 31, N_("Tamron SP AF 300mm f/2.8 LD IF")}, + {21, 32, N_("Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye")}, + {21, 39, N_("Canon EF 75-300mm f/4-5.6")}, + {21, 40, N_("Canon EF 28-80mm f/3.5-5.6")}, + {21, 43, N_("Canon EF 28-105mm f/4-5.6")}, + {21, 45, N_("Canon EF-S 18-55mm f/3.5-5.6")}, + {21, 124, N_("Canon MP-E 65mm f/2.8 1-5x Macro Photo")}, + {21, 125, N_("Canon TS-E 24mm f/3.5L")}, + {21, 126, N_("Canon TS-E 45mm f/2.8")}, + {21, 127, N_("Canon TS-E 90mm f/2.8")}, + {21, 130, N_("Canon EF 50mm f/1.0L")}, + {21, 131, N_("Sigma 17-35mm f2.8-4 EX Aspherical HSM")}, + {21, 134, N_("Canon EF 600mm f/4L IS")}, + {21, 135, N_("Canon EF 200mm f/1.8L")}, + {21, 136, N_("Canon EF 300mm f/2.8L")}, + {21, 137, N_("Canon EF 85mm f/1.2L")}, + {21, 139, N_("Canon EF 400mm f/2.8L")}, + {21, 141, N_("Canon EF 500mm f/4.5L")}, + {21, 142, N_("Canon EF 300mm f/2.8L IS")}, + {21, 143, N_("Canon EF 500mm f/4L IS")}, + {21, 149, N_("Canon EF 100mm f/2")}, + {21, 150, N_("Sigma 20mm EX f/1.8")}, + {21, 151, N_("Canon EF 200mm f/2.8L")}, + {21, 152, N_("Sigma 10-20mm F4-5.6 or 12-24mm f/4.5-5.6 or 14mm f/2.8")}, + {21, 153, N_("Canon EF 35-350mm f/3.5-5.6L")}, + {21, 155, N_("Canon EF 85mm f/1.8 USM")}, + {21, 156, N_("Canon EF 28-105mm f/3.5-4.5 USM")}, + {21, 160, N_("Canon EF 20-35mm f/3.5-4.5 USM")}, + {21, 161, N_("Canon EF 28-70mm f/2.8L or Sigma 24-70mm EX f/2.8")}, + {21, 165, N_("Canon EF 70-200mm f/2.8 L")}, + {21, 166, N_("Canon EF 70-200mm f/2.8 L + x1.4")}, + {21, 167, N_("Canon EF 70-200mm f/2.8 L + x2")}, + {21, 168, N_("Canon EF 28mm f/1.8 USM")}, + {21, 169, N_("Sigma 15-30mm f/3.5-4.5 EX DG Aspherical")}, + {21, 170, N_("Canon EF 200mm f/2.8L II")}, + {21, 173, N_("Canon EF 180mm Macro f/3.5L or Sigma 180mm EX HSM Macro f/3.5")}, + {21, 174, N_("Canon EF 135mm f/2L")}, + {21, 176, N_("Canon EF 24-85mm f/3.5-4.5 USM")}, + {21, 177, N_("Canon EF 300mm f/4L IS")}, + {21, 178, N_("Canon EF 28-135mm f/3.5-5.6 IS")}, + {21, 180, N_("Canon EF 35mm f/1.4L")}, + {21, 181, N_("Canon EF 100-400mm f/4.5-5.6L IS + x1.4")}, + {21, 182, N_("Canon EF 100-400mm f/4.5-5.6L IS + x2")}, + {21, 183, N_("Canon EF 100-400mm f/4.5-5.6L IS")}, + {21, 184, N_("Canon EF 400mm f/2.8L + x2")}, + {21, 186, N_("Canon EF 70-200mm f/4L")}, + {21, 190, N_("Canon EF 100mm f/2.8 Macro")}, + {21, 191, N_("Canon EF 400mm f/4 DO IS")}, + {21, 197, N_("Canon EF 75-300mm f/4-5.6 IS")}, + {21, 198, N_("Canon EF 50mm f/1.4")}, + {21, 202, N_("Canon EF 28-80 f/3.5-5.6 USM IV")}, + {21, 211, N_("Canon EF 28-200mm f/3.5-5.6")}, + {21, 213, N_("Canon EF 90-300mm f/4.5-5.6")}, + {21, 214, N_("Canon EF-S 18-55mm f/3.5-4.5 USM")}, + {21, 224, N_("Canon EF 70-200mm f/2.8L IS USM")}, + {21, 225, N_("Canon EF 70-200mm f/2.8L IS USM + x1.4")}, + {21, 226, N_("Canon EF 70-200mm f/2.8L IS USM + x2")}, + {21, 229, N_("Canon EF 16-35mm f/2.8L")}, + {21, 230, N_("Canon EF 24-70mm f/2.8L")}, + {21, 231, N_("Canon EF 17-40mm f/4L")}, + {21, 232, N_("Canon EF 70-300mm f/4.5-5.6 DO IS USM")}, + {21, 234, N_("Canon EF-S 17-85mm f4-5.6 IS USM")}, + {21, 235, N_("Canon EF-S10-22mm F3.5-4.5 USM")}, + {21, 236, N_("Canon EF-S60mm F2.8 Macro USM")}, + {21, 237, N_("Canon EF 24-105mm f/4L IS")}, + {21, 238, N_("Canon EF 70-300mm F4-5.6 IS USM")}, + {21, 241, N_("Canon EF 50mm F1.2L USM")}, + {21, 242, N_("Canon EF 70-200mm f/4L IS USM")}, + {28, 0, N_("Manual")}, + {28, 1, N_("TTL")}, + {28, 2, N_("A-TTL")}, + {28, 3, N_("E-TTL")}, + {28, 4, N_("FP sync enabled")}, + {28, 7, N_("2nd-curtain sync used")}, + {28, 11, N_("FP sync used")}, + {28, 13, N_("Internal")}, + {28, 14, N_("External")}, + {31, 0, N_("Single")}, + {31, 1, N_("Continuous")}, + {32, 0, N_("Normal AE")}, + {32, 1, N_("Exposure compensation")}, + {32, 2, N_("AE lock")}, + {32, 3, N_("AE lock + exposure compensation")}, + {32, 4, N_("No AE")}, + {33, 0, N_("Off")}, + {33, 1, N_("On")}, + {33, 2, N_("On, shot only")}, + {39, 0, N_("Off")}, + {39, 1, N_("Vivid")}, + {39, 2, N_("Neutral")}, + {39, 3, N_("Smooth")}, + {39, 4, N_("Sepia")}, + {39, 5, N_("Black & white")}, + {39, 6, N_("Custom")}, + {39, 100, N_("My color data")}, + {40, 0, N_("Off")}, + {40, 0x0500, N_("Full")}, + {40, 0x0502, N_("2/3")}, + {40, 0x0504, N_("1/3")}, +#endif + { 0, 0, NULL} +}, +entries_focal_length [] = { +#ifndef NO_VERBOSE_TAG_DATA + {0, 1, N_("Fixed")}, + {0, 2, N_("Zoom")}, +#endif + {0, 0, NULL} +}, +entries_settings_2 [] = { +#ifndef NO_VERBOSE_TAG_DATA + { 6, 0, N_("Auto")}, + { 6, 1, N_("Sunny")}, + { 6, 2, N_("Cloudy")}, + { 6, 3, N_("Tungsten")}, + { 6, 4, N_("Fluorescent")}, + { 6, 5, N_("Flash")}, + { 6, 6, N_("Custom")}, + { 6, 7, N_("Black & white")}, + { 6, 8, N_("Shade")}, + { 6, 9, N_("Manual temperature (Kelvin)")}, + { 6, 10, N_("PC set 1")}, + { 6, 11, N_("PC set 2")}, + { 6, 12, N_("PC set 3")}, + { 6, 14, N_("Daylight fluorescent")}, + { 6, 15, N_("Custom 1")}, + { 6, 16, N_("Custom 2")}, + { 6, 17, N_("Underwater")}, + { 7, 0, N_("Off")}, + { 7, 1, N_("Night scene")}, + { 7, 2, N_("On")}, + { 7, 3, N_("None")}, + { 13, 0x3000, N_("None (MF)")}, + { 13, 0x3001, N_("Right")}, + { 13, 0x3002, N_("Center")}, + { 13, 0x3003, N_("Center-right")}, + { 13, 0x3004, N_("Left")}, + { 13, 0x3005, N_("Left-right")}, + { 13, 0x3006, N_("Left-center")}, + { 13, 0x3007, N_("All")}, + { 15, 0, N_("Off")}, + { 15, 1, N_("On (shot 1)")}, + { 15, 2, N_("On (shot 2)")}, + { 15, 3, N_("On (shot 3)")}, + { 15, 0xffff, N_("On")}, + { 25, 248, N_("EOS high-end")}, + { 25, 250, N_("Compact")}, + { 25, 252, N_("EOS mid-range")}, + { 26, 0, N_("None")}, + { 26, 1, N_("Rotate 90 CW")}, + { 26, 2, N_("Rotate 180")}, + { 26, 3, N_("Rotate 270 CW")}, + { 26, 0xffff, N_("Rotated by software")}, + { 27, 0, N_("Off")}, + { 27, 1, N_("On")}, + { 32, 0, N_("Off")}, + { 32, 0x0014, N_("1/3")}, + { 32, 0x008c, N_("2/3")}, + { 32, 0x07d0, N_("Full")}, +#endif + {0, 0, NULL} +}, +entries_panorama [] = { +#ifndef NO_VERBOSE_TAG_DATA + {0, 0, N_("Left to right")}, + {0, 1, N_("Right to left")}, + {0, 2, N_("Bottom to top")}, + {0, 3, N_("Top to bottom")}, + {0, 4, N_("2x2 matrix (clockwise)")}, +#endif + {0, 0, NULL} +}, +color_information [] = { +#ifndef NO_VERBOSE_TAG_DATA + {0, 0, N_("Standard")}, + {0, 1, N_("Manual")}, + {0, 2, N_("Custom")}, + {2, 0, N_("N/A")}, + {2, 1, N_("Lowest")}, + {2, 2, N_("Low")}, + {2, 3, N_("Standard")}, + {2, 4, N_("High")}, + {2, 5, N_("Highest")}, + {7, 0, N_("Auto")}, + {7, 1, N_("Daylight")}, + {7, 2, N_("Cloudy")}, + {7, 3, N_("Tungsten")}, + {7, 4, N_("Fluorescent")}, + {7, 5, N_("Flash")}, + {7, 6, N_("Custom")}, + {7, 7, N_("Black & white")}, + {7, 8, N_("Shade")}, + {7, 9, N_("Manual temperature (Kelvin)")}, + {7, 10, N_("PC set 1")}, + {7, 11, N_("PC set 2")}, + {7, 12, N_("PC set 3")}, + {7, 14, N_("Daylight fluorescent")}, + {7, 15, N_("Custom 1")}, + {7, 16, N_("Custom 2")}, + {7, 17, N_("Underwater")}, + {9, 0x00, N_("None")}, + {9, 0x01, N_("Standard")}, + {9, 0x02, N_("Set 1")}, + {9, 0x03, N_("Set 2")}, + {9, 0x04, N_("Set 3")}, + {9, 0x21, N_("User def. 1")}, + {9, 0x22, N_("User def. 2")}, + {9, 0x23, N_("User def. 3")}, + {9, 0x41, N_("External 1")}, + {9, 0x42, N_("External 2")}, + {9, 0x43, N_("External 3")}, + {9, 0x81, N_("Standard")}, + {9, 0x82, N_("Portrait")}, + {9, 0x83, N_("Landscape")}, + {9, 0x84, N_("Neutral")}, + {9, 0x85, N_("Faithful")}, + {9, 0x86, N_("Monochrome")}, +#endif + {0, 0, NULL} +}; + +static void +canon_search_table_value (const struct canon_entry_table_t table[], + unsigned int t, ExifShort vs, char *val, unsigned int maxlen) +{ + unsigned int j; + + /* Search the table for the first matching subtag and value. */ + for (j = 0; table[j].name && ((table[j].subtag < t) || + ((table[j].subtag == t) && table[j].value <= vs)); j++) { + if ((table[j].subtag == t) && (table[j].value == vs)) { + break; + } + } + if ((table[j].subtag == t) && (table[j].value == vs) && table[j].name) { + /* Matching subtag and value found. */ + strncpy (val, _(table[j].name), maxlen); + } else { + /* No matching subtag and/or value found. */ + snprintf (val, maxlen, "0x%04x", vs); + } +} + +static void +canon_search_table_bitfield (const struct canon_entry_table_t table[], + unsigned int t, ExifShort vs, char *val, unsigned int maxlen) +{ + unsigned int j; + + /* Search the table for the first matching subtag. */ + for (j = 0; table[j].name && (table[j].subtag <= t); j++) { + if (table[j].subtag == t) { + break; + } + } + if ((table[j].subtag == t) && table[j].name) { + unsigned int i, bit, lastbit = 0; + + /* + * Search the table for the last matching bit, because + * that one needs no additional comma appended. + */ + for (i = j; table[i].name && (table[i].subtag == t); i++) { + bit = table[i].value; + if ((vs >> bit) & 1) { + lastbit = bit; + } + } + /* Search the table for all matching bits. */ + for (i = j; table[i].name && (table[i].subtag == t); i++) { + bit = table[i].value; + if ((vs >> bit) & 1) { + strncat(val, _(table[i].name), maxlen - strlen (val)); + if (bit != lastbit) + strncat (val, _(", "), maxlen - strlen (val)); + } + } + } else { + /* No matching subtag found. */ + snprintf (val, maxlen, "0x%04x", vs); + } +} + +unsigned int +mnote_canon_entry_count_values (const MnoteCanonEntry *entry) +{ + unsigned int val; + + if (!entry) return 0; + + switch (entry->tag) { + case MNOTE_CANON_TAG_FOCAL_LENGTH: + case MNOTE_CANON_TAG_PANORAMA: + return entry->components; + case MNOTE_CANON_TAG_SETTINGS_1: + case MNOTE_CANON_TAG_SETTINGS_2: + case MNOTE_CANON_TAG_CUSTOM_FUNCS: + case MNOTE_CANON_TAG_COLOR_INFORMATION: + if (entry->format != EXIF_FORMAT_SHORT) return 0; + + val = exif_get_short (entry->data, entry->order); + /* val is buffer size, i.e. # of values plus 1 */ + return MIN (entry->size - 2, val) / 2; + default: + return 1; + } +} + +/* + * For reference, see Exif 2.1 specification (Appendix C), + * or http://en.wikipedia.org/wiki/APEX_system + */ +static double +apex_value_to_aperture (double x) +{ + return pow (2, x / 2.); +} + +static double +apex_value_to_shutter_speed(double x) +{ + return 1.0 / pow (2, x); +} + +static double +apex_value_to_iso_speed (double x) +{ + return 3.125 * pow (2, x); +} + +char * +mnote_canon_entry_get_value (const MnoteCanonEntry *entry, unsigned int t, char *val, unsigned int maxlen) +{ + char buf[128]; + ExifLong vl; + ExifShort vs, n; + unsigned char *data; + double d; + + if (!entry) + return NULL; + + data = entry->data; + + memset (val, 0, maxlen); + maxlen--; + + switch (entry->tag) { + case MNOTE_CANON_TAG_SETTINGS_1: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + n = exif_get_short (data, entry->order) / 2; + if (t >= n) return NULL; + CC (entry->components, n, val, maxlen); + vs = exif_get_short (data + 2 + t * 2, entry->order); + switch (t) { + case 1: + if (!vs) { + strncpy(val, _("Off"), maxlen); + break; + } + snprintf (val, maxlen, _("%i (ms)"), vs * 100); + break; + case 15: + if (((vs & 0xC000) == 0x4000) && (vs != 0x7FFF)) { + /* Canon S3 IS - directly specified value */ + snprintf (val, maxlen, "%i", vs & ~0x4000); + } else { + /* Standard Canon - index into lookup table */ + canon_search_table_value (entries_settings_1, t, vs, val, maxlen); + } + break; + case 22: + case 23: + case 24: + snprintf (val, maxlen, "%u", vs); + break; + case 25: + case 26: + snprintf (val, maxlen, "%.2f", apex_value_to_aperture (vs / 32.0)); + break; + case 28: + canon_search_table_bitfield(entries_settings_1, t, vs, val, maxlen); + break; + case 34: + snprintf (val, maxlen, "%.2f", vs / 10.0); + break; + case 35: + case 36: + snprintf (val, maxlen, "%u", vs); + break; + default: + canon_search_table_value (entries_settings_1, t, vs, val, maxlen); + } + break; + + case MNOTE_CANON_TAG_FOCAL_LENGTH: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + vs = exif_get_short (data + t * 2, entry->order); + switch (t) { + case 1: + snprintf (val, maxlen, "%u", vs); + break; + case 2: + case 3: + snprintf (val, maxlen, _("%.2f mm"), vs * 25.4 / 1000); + break; + default: + canon_search_table_value (entries_focal_length, t, vs, val, maxlen); + } + break; + + case MNOTE_CANON_TAG_SETTINGS_2: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + n = exif_get_short (data, entry->order) / 2; + if (t >= n) return NULL; + CC (entry->components, n, val, maxlen); + vs = exif_get_short (data + 2 + t * 2, entry->order); + switch (t) { + case 0: + snprintf (val, maxlen, "%.3f", pow (2, (ExifSShort)vs / 32.0)); + break; + case 1: + snprintf (val, maxlen, "%.0f", apex_value_to_iso_speed ((ExifSShort)vs / 32.0)); + break; + case 2: + case 5: + case 14: + case 16: + snprintf (val, maxlen, _("%.2f EV"), (ExifSShort)vs / 32.0); + break; + case 3: + case 20: + snprintf (val, maxlen, "%.2f", apex_value_to_aperture (vs / 32.0)); + break; + case 4: + case 21: + d = apex_value_to_shutter_speed ((ExifSShort)vs / 32.0); + if (d < 1) + snprintf (val, maxlen, _("1/%i"),(int)(1.0 / d)); + else + snprintf (val, maxlen, "%i", (int) d); + break; + case 8: + snprintf (val, maxlen, "%u", vs); + break; + case 12: + snprintf (val, maxlen, "%.2f", vs / 32.0); + break; + case 18: + case 19: + snprintf (val, maxlen, _("%u mm"), vs); + break; + case 28: + if ((ExifSShort)vs <= 0) { + strncpy(val, _("Off"), maxlen); + break; + } + snprintf (val, maxlen, _("%i (ms)"), vs * 100); + break; + default: + canon_search_table_value (entries_settings_2, t, vs, val, maxlen); + } + break; + + case MNOTE_CANON_TAG_PANORAMA: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + vs = exif_get_short (data + t * 2, entry->order); + canon_search_table_value (entries_panorama, t, vs, val, maxlen); + break; + + case MNOTE_CANON_TAG_OWNER: + CC (entry->components, 32, val, maxlen); + /* Fall through; ImageType can have many sizes */ + case MNOTE_CANON_TAG_IMAGE_TYPE: + CF (entry->format, EXIF_FORMAT_ASCII, val, maxlen); + strncpy (val, (char *)data, MIN (entry->size, maxlen)); + break; + + case MNOTE_CANON_TAG_FIRMWARE: + CF (entry->format, EXIF_FORMAT_ASCII, val, maxlen); +/* CC2 (entry->components, 24, 32, val, maxlen); Can also be 22 */ + strncpy (val, (char *)data, MIN (entry->size, maxlen)); + break; + + case MNOTE_CANON_TAG_IMAGE_NUMBER: + CF (entry->format, EXIF_FORMAT_LONG, val, maxlen); + CC (entry->components, 1, val, maxlen); + vl = exif_get_long (data, entry->order); + snprintf (val, maxlen, "%03lu-%04lu", + (unsigned long) vl/10000, + (unsigned long) vl%10000); + break; + + case MNOTE_CANON_TAG_SERIAL_NUMBER: + CF (entry->format, EXIF_FORMAT_LONG, val, maxlen); + CC (entry->components, 1, val, maxlen); + vl = exif_get_long (data, entry->order); + snprintf (val, maxlen, "%04X-%05d", (int)vl>>16,(int)vl&0xffff); + break; + + case MNOTE_CANON_TAG_CUSTOM_FUNCS: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + n = exif_get_short (data, entry->order) / 2; + if (t >= n) return NULL; + CC (entry->components, n, val, maxlen); + vs = exif_get_short (data + 2 + t * 2, entry->order); + snprintf (buf, sizeof (buf), "%u", vs); + strncat (val, buf, maxlen - strlen (val)); + break; + + case MNOTE_CANON_TAG_COLOR_INFORMATION: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + n = exif_get_short (data, entry->order) / 2; + if (t >= n) return NULL; + CC (entry->components, n, val, maxlen); + vs = exif_get_short (data + 2 + t * 2, entry->order); + canon_search_table_value (color_information, t, vs, val, maxlen); + break; + + default: +#ifdef DEBUG + { + int i; + if (entry->format == EXIF_FORMAT_SHORT) + for(i=0;icomponents;i++) { + vs = exif_get_short (data, entry->order); + data+=2; + printf ("Value%d=%d\n", i, vs); + } + else if (entry->format == EXIF_FORMAT_LONG) + for(i=0;icomponents;i++) { + vl = exif_get_long (data, entry->order); + data+=4; + printf ("Value%d=%d\n", i, vs); + } + else if (entry->format == EXIF_FORMAT_ASCII) + strncpy (val, data, MIN (entry->size, maxlen)); + } +#endif + break; + } + return val; +} diff --git a/libexifa/canon/mnote-canon-tag.c b/libexifa/canon/mnote-canon-tag.c new file mode 100755 index 0000000..6ef73a4 --- /dev/null +++ b/libexifa/canon/mnote-canon-tag.c @@ -0,0 +1,201 @@ +/* mnote-canon-tag.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "mnote-canon-tag.h" + +#include + +#include + +static const struct { + MnoteCanonTag tag; + const char *name; + const char *title; + const char *description; +} table[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + {MNOTE_CANON_TAG_SETTINGS_1, "Settings1", N_("Settings (First Part)"), ""}, + {MNOTE_CANON_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length"), ""}, + {MNOTE_CANON_TAG_SETTINGS_2, "Settings2", N_("Settings (Second Part)"), ""}, + {MNOTE_CANON_TAG_PANORAMA, "Panorama", N_("Panorama"), ""}, + {MNOTE_CANON_TAG_IMAGE_TYPE, "ImageType", N_("Image Type"), ""}, + {MNOTE_CANON_TAG_FIRMWARE, "FirmwareVersion", N_("Firmware Version"), ""}, + {MNOTE_CANON_TAG_IMAGE_NUMBER, "ImageNumber", N_("Image Number"), ""}, + {MNOTE_CANON_TAG_OWNER, "OwnerName", N_("Owner Name"), ""}, + {MNOTE_CANON_TAG_COLOR_INFORMATION, "ColorInformation", N_("Color Information"), ""}, + {MNOTE_CANON_TAG_SERIAL_NUMBER, "SerialNumber", N_("Serial Number"), ""}, + {MNOTE_CANON_TAG_CUSTOM_FUNCS, "CustomFunctions", N_("Custom Functions"), ""}, +#endif + {0, NULL, NULL, NULL} +}; + +static const struct { + MnoteCanonTag tag; + unsigned int subtag; + const char *name; +} table_sub[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + {MNOTE_CANON_TAG_SETTINGS_1, 0, N_("Macro Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 1, N_("Self-timer")}, + {MNOTE_CANON_TAG_SETTINGS_1, 2, N_("Quality")}, + {MNOTE_CANON_TAG_SETTINGS_1, 3, N_("Flash Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 4, N_("Drive Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 6, N_("Focus Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 8, N_("Record Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 9, N_("Image Size")}, + {MNOTE_CANON_TAG_SETTINGS_1, 10, N_("Easy Shooting Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 11, N_("Digital Zoom")}, + {MNOTE_CANON_TAG_SETTINGS_1, 12, N_("Contrast")}, + {MNOTE_CANON_TAG_SETTINGS_1, 13, N_("Saturation")}, + {MNOTE_CANON_TAG_SETTINGS_1, 14, N_("Sharpness")}, + {MNOTE_CANON_TAG_SETTINGS_1, 15, N_("ISO")}, + {MNOTE_CANON_TAG_SETTINGS_1, 16, N_("Metering Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 17, N_("Focus Range")}, + {MNOTE_CANON_TAG_SETTINGS_1, 18, N_("AF Point")}, + {MNOTE_CANON_TAG_SETTINGS_1, 19, N_("Exposure Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 21, N_("Lens Type")}, + {MNOTE_CANON_TAG_SETTINGS_1, 22, N_("Long Focal Length of Lens")}, + {MNOTE_CANON_TAG_SETTINGS_1, 23, N_("Short Focal Length of Lens")}, + {MNOTE_CANON_TAG_SETTINGS_1, 24, N_("Focal Units per mm")}, + {MNOTE_CANON_TAG_SETTINGS_1, 25, N_("Maximal Aperture")}, + {MNOTE_CANON_TAG_SETTINGS_1, 26, N_("Minimal Aperture")}, + {MNOTE_CANON_TAG_SETTINGS_1, 27, N_("Flash Activity")}, + {MNOTE_CANON_TAG_SETTINGS_1, 28, N_("Flash Details")}, + {MNOTE_CANON_TAG_SETTINGS_1, 31, N_("Focus Mode")}, + {MNOTE_CANON_TAG_SETTINGS_1, 32, N_("AE Setting")}, + {MNOTE_CANON_TAG_SETTINGS_1, 33, N_("Image Stabilization")}, + {MNOTE_CANON_TAG_SETTINGS_1, 34, N_("Display Aperture")}, + {MNOTE_CANON_TAG_SETTINGS_1, 35, N_("Zoom Source Width")}, + {MNOTE_CANON_TAG_SETTINGS_1, 36, N_("Zoom Target Width")}, + {MNOTE_CANON_TAG_SETTINGS_1, 39, N_("Photo Effect")}, + {MNOTE_CANON_TAG_SETTINGS_1, 40, N_("Manual Flash Output")}, + {MNOTE_CANON_TAG_SETTINGS_1, 41, N_("Color Tone")}, + {MNOTE_CANON_TAG_FOCAL_LENGTH, 0, N_("Focal Type")}, + {MNOTE_CANON_TAG_FOCAL_LENGTH, 1, N_("Focal Length")}, + {MNOTE_CANON_TAG_FOCAL_LENGTH, 2, N_("Focal Plane X Size")}, + {MNOTE_CANON_TAG_FOCAL_LENGTH, 3, N_("Focal Plane Y Size")}, + {MNOTE_CANON_TAG_SETTINGS_2, 0, N_("Auto ISO")}, + {MNOTE_CANON_TAG_SETTINGS_2, 1, N_("Shot ISO")}, + {MNOTE_CANON_TAG_SETTINGS_2, 2, N_("Measured EV")}, + {MNOTE_CANON_TAG_SETTINGS_2, 3, N_("Target Aperture")}, + {MNOTE_CANON_TAG_SETTINGS_2, 4, N_("Target Exposure Time")}, + {MNOTE_CANON_TAG_SETTINGS_2, 5, N_("Exposure Compensation")}, + {MNOTE_CANON_TAG_SETTINGS_2, 6, N_("White Balance")}, + {MNOTE_CANON_TAG_SETTINGS_2, 7, N_("Slow Shutter")}, + {MNOTE_CANON_TAG_SETTINGS_2, 8, N_("Sequence Number")}, + {MNOTE_CANON_TAG_SETTINGS_2, 12, N_("Flash Guide Number")}, + {MNOTE_CANON_TAG_SETTINGS_2, 13, N_("AF Point")}, + {MNOTE_CANON_TAG_SETTINGS_2, 14, N_("Flash Exposure Compensation")}, + {MNOTE_CANON_TAG_SETTINGS_2, 15, N_("AE Bracketing")}, + {MNOTE_CANON_TAG_SETTINGS_2, 16, N_("AE Bracket Value")}, + {MNOTE_CANON_TAG_SETTINGS_2, 18, N_("Focus Distance Upper")}, + {MNOTE_CANON_TAG_SETTINGS_2, 19, N_("Focus Distance Lower")}, + {MNOTE_CANON_TAG_SETTINGS_2, 20, N_("FNumber")}, + {MNOTE_CANON_TAG_SETTINGS_2, 21, N_("Exposure Time")}, + {MNOTE_CANON_TAG_SETTINGS_2, 23, N_("Bulb Duration")}, + {MNOTE_CANON_TAG_SETTINGS_2, 25, N_("Camera Type")}, + {MNOTE_CANON_TAG_SETTINGS_2, 26, N_("Auto Rotate")}, + {MNOTE_CANON_TAG_SETTINGS_2, 27, N_("ND Filter")}, + {MNOTE_CANON_TAG_SETTINGS_2, 28, N_("Self-timer")}, + {MNOTE_CANON_TAG_SETTINGS_2, 32, N_("Manual Flash Output")}, + {MNOTE_CANON_TAG_PANORAMA, 2, N_("Panorama Frame")}, + {MNOTE_CANON_TAG_PANORAMA, 5, N_("Panorama Direction")}, + {MNOTE_CANON_TAG_COLOR_INFORMATION, 0, N_("Tone Curve")}, + {MNOTE_CANON_TAG_COLOR_INFORMATION, 2, N_("Sharpness Frequency")}, + {MNOTE_CANON_TAG_COLOR_INFORMATION, 7, N_("White Balance")}, + {MNOTE_CANON_TAG_COLOR_INFORMATION, 9, N_("Picture Style")}, +#endif + {0, 0, NULL} +}; + +const char * +mnote_canon_tag_get_name (MnoteCanonTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return table[i].name; /* do not translate */ + return NULL; +} + +const char * +mnote_canon_tag_get_name_sub (MnoteCanonTag t, unsigned int s, ExifDataOption o) +{ + unsigned int i; + int tag_found = 0; + + for (i = 0; i < sizeof (table_sub) / sizeof (table_sub[0]); i++) { + if (table_sub[i].tag == t) { + if (table_sub[i].subtag == s) + return table_sub[i].name; + tag_found = 1; + } + } + if (!tag_found || !(o & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS)) + return mnote_canon_tag_get_name (t); + else + return NULL; +} + +const char * +mnote_canon_tag_get_title (MnoteCanonTag t) +{ + unsigned int i; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (_(table[i].title)); + return NULL; +} + +const char * +mnote_canon_tag_get_title_sub (MnoteCanonTag t, unsigned int s, ExifDataOption o) +{ + unsigned int i; + int tag_found = 0; + + for (i = 0; i < sizeof (table_sub) / sizeof (table_sub[0]); i++) { + if (table_sub[i].tag == t) { + if (table_sub[i].subtag == s) + return _(table_sub[i].name); + tag_found = 1; + } + } + if (!tag_found || !(o & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS)) + return mnote_canon_tag_get_title (t); + else + return NULL; +} + +const char * +mnote_canon_tag_get_description (MnoteCanonTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) { + if (!*table[i].description) + return ""; + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(table[i].description); + } + return NULL; +} diff --git a/libexifa/exif-byte-order.c b/libexifa/exif-byte-order.c new file mode 100755 index 0000000..05164e0 --- /dev/null +++ b/libexifa/exif-byte-order.c @@ -0,0 +1,39 @@ +/* exif-byte-order.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include + +const char * +exif_byte_order_get_name (ExifByteOrder order) +{ + switch (order) { + case EXIF_BYTE_ORDER_MOTOROLA: + return (_("Motorola")); + case EXIF_BYTE_ORDER_INTEL: + return (_("Intel")); + default: + return NULL; + } +} diff --git a/libexifa/exif-content.c b/libexifa/exif-content.c new file mode 100755 index 0000000..6d6c589 --- /dev/null +++ b/libexifa/exif-content.c @@ -0,0 +1,327 @@ +/* exif-content.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include +#include +#include + +/* unused constant + * static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + */ + +struct _ExifContentPrivate +{ + unsigned int ref_count; + + ExifMem *mem; + ExifLog *log; +}; + +ExifContent * +exif_content_new (void) +{ + ExifMem *mem = exif_mem_new_default (); + ExifContent *content = exif_content_new_mem (mem); + + exif_mem_unref (mem); + + return content; +} + +ExifContent * +exif_content_new_mem (ExifMem *mem) +{ + ExifContent *content; + + if (!mem) return NULL; + + content = exif_mem_alloc (mem, (ExifLong) sizeof (ExifContent)); + if (!content) + return NULL; + content->priv = exif_mem_alloc (mem, + (ExifLong) sizeof (ExifContentPrivate)); + if (!content->priv) { + exif_mem_free (mem, content); + return NULL; + } + + content->priv->ref_count = 1; + + content->priv->mem = mem; + exif_mem_ref (mem); + + return content; +} + +void +exif_content_ref (ExifContent *content) +{ + content->priv->ref_count++; +} + +void +exif_content_unref (ExifContent *content) +{ + content->priv->ref_count--; + if (!content->priv->ref_count) + exif_content_free (content); +} + +void +exif_content_free (ExifContent *content) +{ + ExifMem *mem = (content && content->priv) ? content->priv->mem : NULL; + unsigned int i; + + if (!content) return; + + for (i = 0; i < content->count; i++) + exif_entry_unref (content->entries[i]); + exif_mem_free (mem, content->entries); + + if (content->priv) { + exif_log_unref (content->priv->log); + } + + exif_mem_free (mem, content->priv); + exif_mem_free (mem, content); + exif_mem_unref (mem); +} + +void +exif_content_dump (ExifContent *content, unsigned int indent) +{ + char buf[1024]; + unsigned int i; + + for (i = 0; i < 2 * indent; i++) + buf[i] = ' '; + buf[i] = '\0'; + + if (!content) + return; + + printf ("%sDumping exif content (%u entries)...\n", buf, + content->count); + for (i = 0; i < content->count; i++) + exif_entry_dump (content->entries[i], indent + 1); +} + +void +exif_content_add_entry (ExifContent *c, ExifEntry *entry) +{ + ExifEntry **entries; + if (!c || !c->priv || !entry || entry->parent) return; + + /* One tag can only be added once to an IFD. */ + if (exif_content_get_entry (c, entry->tag)) { + exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "ExifContent", + "An attempt has been made to add " + "the tag '%s' twice to an IFD. This is against " + "specification.", exif_tag_get_name (entry->tag)); + return; + } + + entries = exif_mem_realloc (c->priv->mem, + c->entries, sizeof (ExifEntry*) * (c->count + 1)); + if (!entries) return; + entry->parent = c; + entries[c->count++] = entry; + c->entries = entries; + exif_entry_ref (entry); +} + +void +exif_content_remove_entry (ExifContent *c, ExifEntry *e) +{ + unsigned int i; + ExifEntry **t, *temp; + + if (!c || !c->priv || !e || (e->parent != c)) return; + + /* Search the entry */ + for (i = 0; i < c->count; i++) + if (c->entries[i] == e) + break; + + if (i == c->count) + return; + + /* Remove the entry */ + temp = c->entries[c->count-1]; + if (c->count > 1) { + t = exif_mem_realloc (c->priv->mem, c->entries, + sizeof(ExifEntry*) * (c->count - 1)); + if (!t) { + return; + } + c->entries = t; + c->count--; + if (i != c->count) { /* we deallocated the last slot already */ + memmove (&t[i], &t[i + 1], sizeof (ExifEntry*) * (c->count - i - 1)); + t[c->count-1] = temp; + } + } else { + exif_mem_free (c->priv->mem, c->entries); + c->entries = NULL; + c->count = 0; + } + e->parent = NULL; + exif_entry_unref (e); +} + +ExifEntry * +exif_content_get_entry (ExifContent *content, ExifTag tag) +{ + unsigned int i; + + if (!content) + return (NULL); + + for (i = 0; i < content->count; i++) + if (content->entries[i]->tag == tag) + return (content->entries[i]); + return (NULL); +} + +void +exif_content_foreach_entry (ExifContent *content, + ExifContentForeachEntryFunc func, void *data) +{ + unsigned int i; + + if (!content || !func) + return; + + for (i = 0; i < content->count; i++) + func (content->entries[i], data); +} + +void +exif_content_log (ExifContent *content, ExifLog *log) +{ + if (!content || !content->priv || !log || content->priv->log == log) + return; + + if (content->priv->log) exif_log_unref (content->priv->log); + content->priv->log = log; + exif_log_ref (log); +} + +ExifIfd +exif_content_get_ifd (ExifContent *c) +{ + if (!c || !c->parent) return EXIF_IFD_COUNT; + + return + ((c)->parent->ifd[EXIF_IFD_EXIF] == (c)) ? EXIF_IFD_EXIF : + ((c)->parent->ifd[EXIF_IFD_0] == (c)) ? EXIF_IFD_0 : + ((c)->parent->ifd[EXIF_IFD_1] == (c)) ? EXIF_IFD_1 : + ((c)->parent->ifd[EXIF_IFD_GPS] == (c)) ? EXIF_IFD_GPS : + ((c)->parent->ifd[EXIF_IFD_INTEROPERABILITY] == (c)) ? EXIF_IFD_INTEROPERABILITY : + EXIF_IFD_COUNT; +} + +static void +fix_func (ExifEntry *e, void *UNUSED(data)) +{ + exif_entry_fix (e); +} + +/*! + * Check if this entry is unknown and if so, delete it. + * \note Be careful calling this function in a loop. Deleting an entry from + * an ExifContent changes the index of subsequent entries, as well as the + * total size of the entries array. + */ +static void +remove_not_recorded (ExifEntry *e, void *UNUSED(data)) +{ + ExifIfd ifd = exif_entry_get_ifd(e) ; + ExifContent *c = e->parent; + ExifDataType dt = exif_data_get_data_type (c->parent); + ExifTag t = e->tag; + + if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == + EXIF_SUPPORT_LEVEL_NOT_RECORDED) { + exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", + "Tag 0x%04x is not recorded in IFD '%s' and has therefore been " + "removed.", t, exif_ifd_get_name (ifd)); + exif_content_remove_entry (c, e); + } + +} + +void +exif_content_fix (ExifContent *c) +{ + ExifIfd ifd = exif_content_get_ifd (c); + ExifDataType dt; + ExifEntry *e; + unsigned int i, num; + + if (!c) + return; + + dt = exif_data_get_data_type (c->parent); + + /* + * First of all, fix all existing entries. + */ + exif_content_foreach_entry (c, fix_func, NULL); + + /* + * Go through each tag and if it's not recorded, remove it. If one + * is removed, exif_content_foreach_entry() will skip the next entry, + * so if this happens do the loop again from the beginning to ensure + * they're all checked. This could be avoided if we stop relying on + * exif_content_foreach_entry but loop intelligently here. + */ + do { + num = c->count; + exif_content_foreach_entry (c, remove_not_recorded, NULL); + } while (num != c->count); + + /* + * Then check for non-existing mandatory tags and create them if needed + */ + num = exif_tag_table_count(); + for (i = 0; i < num; ++i) { + const ExifTag t = exif_tag_table_get_tag (i); + if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == + EXIF_SUPPORT_LEVEL_MANDATORY) { + if (exif_content_get_entry (c, t)) + /* This tag already exists */ + continue; + exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", + "Tag '%s' is mandatory in IFD '%s' and has therefore been added.", + exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd)); + e = exif_entry_new (); + exif_content_add_entry (c, e); + exif_entry_initialize (e, t); + exif_entry_unref (e); + } + } +} diff --git a/libexifa/exif-data.c b/libexifa/exif-data.c new file mode 100755 index 0000000..80533b6 --- /dev/null +++ b/libexifa/exif-data.c @@ -0,0 +1,1266 @@ +/* exif-data.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#undef JPEG_MARKER_SOI +#define JPEG_MARKER_SOI 0xd8 +#undef JPEG_MARKER_APP0 +#define JPEG_MARKER_APP0 0xe0 +#undef JPEG_MARKER_APP1 +#define JPEG_MARKER_APP1 0xe1 + +static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + +struct _ExifDataPrivate +{ + ExifByteOrder order; + + ExifMnoteData *md; + + ExifLog *log; + ExifMem *mem; + + unsigned int ref_count; + + /* Temporarily used while loading data */ + unsigned int offset_mnote; + + ExifDataOption options; + ExifDataType data_type; +}; + +static void * +exif_data_alloc (ExifData *data, unsigned int i) +{ + void *d; + + if (!data || !i) + return NULL; + + d = exif_mem_alloc (data->priv->mem, i); + if (d) + return d; + + EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", i); + return NULL; +} + +ExifMnoteData * +exif_data_get_mnote_data (ExifData *d) +{ + return (d && d->priv) ? d->priv->md : NULL; +} + +ExifData * +exif_data_new (void) +{ + ExifMem *mem = exif_mem_new_default (); + ExifData *d = exif_data_new_mem (mem); + + exif_mem_unref (mem); + + return d; +} + +ExifData * +exif_data_new_mem (ExifMem *mem) +{ + ExifData *data; + unsigned int i; + + if (!mem) + return NULL; + + data = exif_mem_alloc (mem, sizeof (ExifData)); + if (!data) + return (NULL); + data->priv = exif_mem_alloc (mem, sizeof (ExifDataPrivate)); + if (!data->priv) { + exif_mem_free (mem, data); + return (NULL); + } + data->priv->ref_count = 1; + + data->priv->mem = mem; + exif_mem_ref (mem); + + for (i = 0; i < EXIF_IFD_COUNT; i++) { + data->ifd[i] = exif_content_new_mem (data->priv->mem); + if (!data->ifd[i]) { + exif_data_free (data); + return (NULL); + } + data->ifd[i]->parent = data; + } + + /* Default options */ +#ifndef NO_VERBOSE_TAG_STRINGS + /* + * When the tag list is compiled away, setting this option prevents + * any tags from being loaded + */ + exif_data_set_option (data, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS); +#endif + exif_data_set_option (data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); + + /* Default data type: none */ + exif_data_set_data_type (data, EXIF_DATA_TYPE_COUNT); + + return (data); +} + +ExifData * +exif_data_new_from_data (const unsigned char *data, unsigned int size) +{ + ExifData *edata; + + edata = exif_data_new (); + exif_data_load_data (edata, data, size); + return (edata); +} + +static int +exif_data_load_data_entry (ExifData *data, ExifEntry *entry, + const unsigned char *d, + unsigned int size, unsigned int offset) +{ + unsigned int s, doff; + + entry->tag = exif_get_short (d + offset + 0, data->priv->order); + entry->format = exif_get_short (d + offset + 2, data->priv->order); + entry->components = exif_get_long (d + offset + 4, data->priv->order); + + /* FIXME: should use exif_tag_get_name_in_ifd here but entry->parent + * has not been set yet + */ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Loading entry 0x%x ('%s')...", entry->tag, + exif_tag_get_name (entry->tag)); + + /* {0,1,2,4,8} x { 0x00000000 .. 0xffffffff } + * -> { 0x000000000 .. 0x7fffffff8 } */ + s = exif_format_get_size(entry->format) * entry->components; + if ((s < entry->components) || (s == 0)){ + return 0; + } + + /* + * Size? If bigger than 4 bytes, the actual data is not + * in the entry but somewhere else (offset). + */ + if (s > 4) + doff = exif_get_long (d + offset + 8, data->priv->order); + else + doff = offset + 8; + + /* Sanity checks */ + if ((doff + s < doff) || (doff + s < s) || (doff + s > size)) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Tag data past end of buffer (%u > %u)", doff+s, size); + return 0; + } + + entry->data = exif_data_alloc (data, s); + if (entry->data) { + entry->size = s; + memcpy (entry->data, d + doff, s); + } else { + /* FIXME: What do our callers do if (entry->data == NULL)? */ + EXIF_LOG_NO_MEMORY(data->priv->log, "ExifData", s); + } + + /* If this is the MakerNote, remember the offset */ + if (entry->tag == EXIF_TAG_MAKER_NOTE) { + if (!entry->data) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "MakerNote found with empty data"); + } else if (entry->size > 6) { + exif_log (data->priv->log, + EXIF_LOG_CODE_DEBUG, "ExifData", + "MakerNote found (%02x %02x %02x %02x " + "%02x %02x %02x...).", + entry->data[0], entry->data[1], entry->data[2], + entry->data[3], entry->data[4], entry->data[5], + entry->data[6]); + } + data->priv->offset_mnote = doff; + } + return 1; +} + +static void +exif_data_save_data_entry (ExifData *data, ExifEntry *e, + unsigned char **d, unsigned int *ds, + unsigned int offset) +{ + unsigned int doff, s; + unsigned int ts; + + if (!data || !data->priv) + return; + + /* + * Each entry is 12 bytes long. The memory for the entry has + * already been allocated. + */ + exif_set_short (*d + 6 + offset + 0, + data->priv->order, (ExifShort) e->tag); + exif_set_short (*d + 6 + offset + 2, + data->priv->order, (ExifShort) e->format); + + if (!(data->priv->options & EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE)) { + /* If this is the maker note tag, update it. */ + if ((e->tag == EXIF_TAG_MAKER_NOTE) && data->priv->md) { + /* TODO: this is using the wrong ExifMem to free e->data */ + exif_mem_free (data->priv->mem, e->data); + e->data = NULL; + e->size = 0; + exif_mnote_data_set_offset (data->priv->md, *ds - 6); + exif_mnote_data_save (data->priv->md, &e->data, &e->size); + e->components = e->size; + } + } + + exif_set_long (*d + 6 + offset + 4, + data->priv->order, e->components); + + /* + * Size? If bigger than 4 bytes, the actual data is not in + * the entry but somewhere else. + */ + s = exif_format_get_size (e->format) * e->components; + if (s > 4) { + unsigned char *t; + doff = *ds - 6; + ts = *ds + s; + + /* + * According to the TIFF specification, + * the offset must be an even number. If we need to introduce + * a padding byte, we set it to 0. + */ + if (s & 1) + ts++; + t = exif_mem_realloc (data->priv->mem, *d, ts); + if (!t) { + EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts); + return; + } + *d = t; + *ds = ts; + exif_set_long (*d + 6 + offset + 8, data->priv->order, doff); + if (s & 1) + *(*d + *ds - 1) = '\0'; + + } else + doff = offset + 8; + + /* Write the data. Fill unneeded bytes with 0. Do not crash with + * e->data is NULL */ + if (e->data) { + memcpy (*d + 6 + doff, e->data, s); + } else { + memset (*d + 6 + doff, 0, s); + } + if (s < 4) + memset (*d + 6 + doff + s, 0, (4 - s)); +} + +static void +exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d, + unsigned int ds, ExifLong o, ExifLong s) +{ + /* Sanity checks */ + if ((o + s < o) || (o + s < s) || (o + s > ds) || (o > ds)) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Bogus thumbnail offset (%u) or size (%u).", + o, s); + return; + } + + if (data->data) + exif_mem_free (data->priv->mem, data->data); + if (!(data->data = exif_data_alloc (data, s))) { + EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", s); + data->size = 0; + return; + } + data->size = s; + memcpy (data->data, d + o, s); +} + +#undef CHECK_REC +#define CHECK_REC(i) \ +if ((i) == ifd) { \ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \ + "ExifData", "Recursive entry in IFD " \ + "'%s' detected. Skipping...", \ + exif_ifd_get_name (i)); \ + break; \ +} \ +if (data->ifd[(i)]->count) { \ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, \ + "ExifData", "Attempt to load IFD " \ + "'%s' multiple times detected. " \ + "Skipping...", \ + exif_ifd_get_name (i)); \ + break; \ +} + +/*! Load data for an IFD. + * + * \param[in,out] data #ExifData + * \param[in] ifd IFD to load + * \param[in] d pointer to buffer containing raw IFD data + * \param[in] ds size of raw data in buffer at \c d + * \param[in] offset offset into buffer at \c d at which IFD starts + * \param[in] recursion_depth number of times this function has been + * recursively called without returning + */ +static void +exif_data_load_data_content (ExifData *data, ExifIfd ifd, + const unsigned char *d, + unsigned int ds, unsigned int offset, unsigned int recursion_depth) +{ + ExifLong o, thumbnail_offset = 0, thumbnail_length = 0; + ExifShort n; + ExifEntry *entry; + unsigned int i; + ExifTag tag; + + if (!data || !data->priv) + return; + + /* check for valid ExifIfd enum range */ + if ((((int)ifd) < 0) || ( ((int)ifd) >= EXIF_IFD_COUNT)) + return; + + if (recursion_depth > 30) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", + "Deep recursion detected!"); + return; + } + + /* Read the number of entries */ + if ((offset + 2 < offset) || (offset + 2 < 2) || (offset + 2 > ds)) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", + "Tag data past end of buffer (%u > %u)", offset+2, ds); + return; + } + n = exif_get_short (d + offset, data->priv->order); + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Loading %hu entries...", n); + offset += 2; + + /* Check if we have enough data. */ + if (offset + 12 * n > ds) { + n = (ds - offset) / 12; + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Short data; only loading %hu entries...", n); + } + + for (i = 0; i < n; i++) { + + tag = exif_get_short (d + offset + 12 * i, data->priv->order); + switch (tag) { + case EXIF_TAG_EXIF_IFD_POINTER: + case EXIF_TAG_GPS_INFO_IFD_POINTER: + case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: + o = exif_get_long (d + offset + 12 * i + 8, + data->priv->order); + /* FIXME: IFD_POINTER tags aren't marked as being in a + * specific IFD, so exif_tag_get_name_in_ifd won't work + */ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Sub-IFD entry 0x%x ('%s') at %u.", tag, + exif_tag_get_name(tag), o); + switch (tag) { + case EXIF_TAG_EXIF_IFD_POINTER: + CHECK_REC (EXIF_IFD_EXIF); + exif_data_load_data_content (data, EXIF_IFD_EXIF, d, ds, o, recursion_depth + 1); + break; + case EXIF_TAG_GPS_INFO_IFD_POINTER: + CHECK_REC (EXIF_IFD_GPS); + exif_data_load_data_content (data, EXIF_IFD_GPS, d, ds, o, recursion_depth + 1); + break; + case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: + CHECK_REC (EXIF_IFD_INTEROPERABILITY); + exif_data_load_data_content (data, EXIF_IFD_INTEROPERABILITY, d, ds, o, recursion_depth + 1); + break; + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: + thumbnail_offset = o; + if (thumbnail_offset && thumbnail_length) + exif_data_load_data_thumbnail (data, d, + ds, thumbnail_offset, + thumbnail_length); + break; + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: + thumbnail_length = o; + if (thumbnail_offset && thumbnail_length) + exif_data_load_data_thumbnail (data, d, + ds, thumbnail_offset, + thumbnail_length); + break; + default: + return; + } + break; + default: + + /* + * If we don't know the tag, don't fail. It could be that new + * versions of the standard have defined additional tags. Note that + * 0 is a valid tag in the GPS IFD. + */ + if (!exif_tag_get_name_in_ifd (tag, ifd)) { + + /* + * Special case: Tag and format 0. That's against specification + * (at least up to 2.2). But Photoshop writes it anyways. + */ + if (!memcmp (d + offset + 12 * i, "\0\0\0\0", 4)) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Skipping empty entry at position %u in '%s'.", i, + exif_ifd_get_name (ifd)); + break; + } + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Unknown tag 0x%04x (entry %u in '%s'). Please report this tag " + "to .", tag, i, + exif_ifd_get_name (ifd)); + if (data->priv->options & EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS) + break; + } + entry = exif_entry_new_mem (data->priv->mem); + if (exif_data_load_data_entry (data, entry, d, ds, + offset + 12 * i)) + exif_content_add_entry (data->ifd[ifd], entry); + exif_entry_unref (entry); + break; + } + } +} + +static int +cmp_func (const unsigned char *p1, const unsigned char *p2, ExifByteOrder o) +{ + ExifShort tag1 = exif_get_short (p1, o); + ExifShort tag2 = exif_get_short (p2, o); + + return (tag1 < tag2) ? -1 : (tag1 > tag2) ? 1 : 0; +} + +static int +cmp_func_intel (const void *elem1, const void *elem2) +{ + return cmp_func ((const unsigned char *) elem1, + (const unsigned char *) elem2, EXIF_BYTE_ORDER_INTEL); +} + +static int +cmp_func_motorola (const void *elem1, const void *elem2) +{ + return cmp_func ((const unsigned char *) elem1, + (const unsigned char *) elem2, EXIF_BYTE_ORDER_MOTOROLA); +} + +static void +exif_data_save_data_content (ExifData *data, ExifContent *ifd, + unsigned char **d, unsigned int *ds, + unsigned int offset) +{ + unsigned int j, n_ptr = 0, n_thumb = 0; + ExifIfd i; + unsigned char *t; + unsigned int ts; + + if (!data || !data->priv || !ifd || !d || !ds) + return; + + for (i = 0; i < EXIF_IFD_COUNT; i++) + if (ifd == data->ifd[i]) + break; + if (i == EXIF_IFD_COUNT) + return; /* error */ + + /* + * Check if we need some extra entries for pointers or the thumbnail. + */ + switch (i) { + case EXIF_IFD_0: + + /* + * The pointer to IFD_EXIF is in IFD_0. The pointer to + * IFD_INTEROPERABILITY is in IFD_EXIF. + */ + if (data->ifd[EXIF_IFD_EXIF]->count || + data->ifd[EXIF_IFD_INTEROPERABILITY]->count) + n_ptr++; + + /* The pointer to IFD_GPS is in IFD_0. */ + if (data->ifd[EXIF_IFD_GPS]->count) + n_ptr++; + + break; + case EXIF_IFD_1: + if (data->size) + n_thumb = 2; + break; + case EXIF_IFD_EXIF: + if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) + n_ptr++; + default: + break; + } + + /* + * Allocate enough memory for all entries + * and the number of entries. + */ + ts = *ds + (2 + (ifd->count + n_ptr + n_thumb) * 12 + 4); + t = exif_mem_realloc (data->priv->mem, *d, ts); + if (!t) { + EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", ts); + return; + } + *d = t; + *ds = ts; + + /* Save the number of entries */ + exif_set_short (*d + 6 + offset, data->priv->order, + (ExifShort) (ifd->count + n_ptr + n_thumb)); + offset += 2; + + /* + * Save each entry. Make sure that no memcpys from NULL pointers are + * performed + */ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Saving %i entries (IFD '%s', offset: %i)...", + ifd->count, exif_ifd_get_name (i), offset); + for (j = 0; j < ifd->count; j++) { + if (ifd->entries[j]) { + exif_data_save_data_entry (data, ifd->entries[j], d, ds, + offset + 12 * j); + } + } + + offset += 12 * ifd->count; + + /* Now save special entries. */ + switch (i) { + case EXIF_IFD_0: + + /* + * The pointer to IFD_EXIF is in IFD_0. + * However, the pointer to IFD_INTEROPERABILITY is in IFD_EXIF, + * therefore, if IFD_INTEROPERABILITY is not empty, we need + * IFD_EXIF even if latter is empty. + */ + if (data->ifd[EXIF_IFD_EXIF]->count || + data->ifd[EXIF_IFD_INTEROPERABILITY]->count) { + exif_set_short (*d + 6 + offset + 0, data->priv->order, + EXIF_TAG_EXIF_IFD_POINTER); + exif_set_short (*d + 6 + offset + 2, data->priv->order, + EXIF_FORMAT_LONG); + exif_set_long (*d + 6 + offset + 4, data->priv->order, + 1); + exif_set_long (*d + 6 + offset + 8, data->priv->order, + *ds - 6); + exif_data_save_data_content (data, + data->ifd[EXIF_IFD_EXIF], d, ds, *ds - 6); + offset += 12; + } + + /* The pointer to IFD_GPS is in IFD_0, too. */ + if (data->ifd[EXIF_IFD_GPS]->count) { + exif_set_short (*d + 6 + offset + 0, data->priv->order, + EXIF_TAG_GPS_INFO_IFD_POINTER); + exif_set_short (*d + 6 + offset + 2, data->priv->order, + EXIF_FORMAT_LONG); + exif_set_long (*d + 6 + offset + 4, data->priv->order, + 1); + exif_set_long (*d + 6 + offset + 8, data->priv->order, + *ds - 6); + exif_data_save_data_content (data, + data->ifd[EXIF_IFD_GPS], d, ds, *ds - 6); + offset += 12; + } + + break; + case EXIF_IFD_EXIF: + + /* + * The pointer to IFD_INTEROPERABILITY is in IFD_EXIF. + * See note above. + */ + if (data->ifd[EXIF_IFD_INTEROPERABILITY]->count) { + exif_set_short (*d + 6 + offset + 0, data->priv->order, + EXIF_TAG_INTEROPERABILITY_IFD_POINTER); + exif_set_short (*d + 6 + offset + 2, data->priv->order, + EXIF_FORMAT_LONG); + exif_set_long (*d + 6 + offset + 4, data->priv->order, + 1); + exif_set_long (*d + 6 + offset + 8, data->priv->order, + *ds - 6); + exif_data_save_data_content (data, + data->ifd[EXIF_IFD_INTEROPERABILITY], d, ds, + *ds - 6); + offset += 12; + } + + break; + case EXIF_IFD_1: + + /* + * Information about the thumbnail (if any) is saved in + * IFD_1. + */ + if (data->size) { + + /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT */ + exif_set_short (*d + 6 + offset + 0, data->priv->order, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT); + exif_set_short (*d + 6 + offset + 2, data->priv->order, + EXIF_FORMAT_LONG); + exif_set_long (*d + 6 + offset + 4, data->priv->order, + 1); + exif_set_long (*d + 6 + offset + 8, data->priv->order, + *ds - 6); + ts = *ds + data->size; + t = exif_mem_realloc (data->priv->mem, *d, ts); + if (!t) { + EXIF_LOG_NO_MEMORY (data->priv->log, "ExifData", + ts); + return; + } + *d = t; + *ds = ts; + memcpy (*d + *ds - data->size, data->data, data->size); + offset += 12; + + /* EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH */ + exif_set_short (*d + 6 + offset + 0, data->priv->order, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); + exif_set_short (*d + 6 + offset + 2, data->priv->order, + EXIF_FORMAT_LONG); + exif_set_long (*d + 6 + offset + 4, data->priv->order, + 1); + exif_set_long (*d + 6 + offset + 8, data->priv->order, + data->size); + offset += 12; + } + + break; + default: + break; + } + + /* Sort the directory according to TIFF specification */ + qsort (*d + 6 + offset - (ifd->count + n_ptr + n_thumb) * 12, + (ifd->count + n_ptr + n_thumb), 12, + (data->priv->order == EXIF_BYTE_ORDER_INTEL) ? cmp_func_intel : cmp_func_motorola); + + /* Correctly terminate the directory */ + if (i == EXIF_IFD_0 && (data->ifd[EXIF_IFD_1]->count || + data->size)) { + + /* + * We are saving IFD 0. Tell where IFD 1 starts and save + * IFD 1. + */ + exif_set_long (*d + 6 + offset, data->priv->order, *ds - 6); + exif_data_save_data_content (data, data->ifd[EXIF_IFD_1], d, ds, + *ds - 6); + } else + exif_set_long (*d + 6 + offset, data->priv->order, 0); +} + +typedef enum { + EXIF_DATA_TYPE_MAKER_NOTE_NONE = 0, + EXIF_DATA_TYPE_MAKER_NOTE_CANON = 1, + EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS = 2, + EXIF_DATA_TYPE_MAKER_NOTE_PENTAX = 3, + EXIF_DATA_TYPE_MAKER_NOTE_NIKON = 4, + EXIF_DATA_TYPE_MAKER_NOTE_CASIO = 5, + EXIF_DATA_TYPE_MAKER_NOTE_FUJI = 6 +} ExifDataTypeMakerNote; + +/*! If MakerNote is recognized, load it. + * + * \param[in,out] data #ExifData + * \param[in] d pointer to raw EXIF data + * \param[in] ds length of data at d + */ +static void +interpret_maker_note(ExifData *data, const unsigned char *d, unsigned int ds) +{ + int mnoteid; + ExifEntry* e = exif_data_get_entry (data, EXIF_TAG_MAKER_NOTE); + if (!e) + return; + + if ((mnoteid = exif_mnote_data_olympus_identify (data, e)) != 0) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, + "ExifData", "Olympus MakerNote variant type %d", mnoteid); + data->priv->md = exif_mnote_data_olympus_new (data->priv->mem); + + } else if ((mnoteid = exif_mnote_data_canon_identify (data, e)) != 0) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, + "ExifData", "Canon MakerNote variant type %d", mnoteid); + data->priv->md = exif_mnote_data_canon_new (data->priv->mem, data->priv->options); + + } else if ((mnoteid = exif_mnote_data_fuji_identify (data, e)) != 0) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, + "ExifData", "Fuji MakerNote variant type %d", mnoteid); + data->priv->md = exif_mnote_data_fuji_new (data->priv->mem); + + /* NOTE: Must do Pentax detection last because some of the + * heuristics are pretty general. */ + } else if ((mnoteid = exif_mnote_data_pentax_identify (data, e)) != 0) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, + "ExifData", "Pentax MakerNote variant type %d", mnoteid); + data->priv->md = exif_mnote_data_pentax_new (data->priv->mem); + } + + /* + * If we are able to interpret the maker note, do so. + */ + if (data->priv->md) { + exif_mnote_data_log (data->priv->md, data->priv->log); + exif_mnote_data_set_byte_order (data->priv->md, + data->priv->order); + exif_mnote_data_set_offset (data->priv->md, + data->priv->offset_mnote); + exif_mnote_data_load (data->priv->md, d, ds); + } +} + +#define LOG_TOO_SMALL \ +exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData", \ + _("Size of data too small to allow for EXIF data.")); + +void +exif_data_load_data (ExifData *data, const unsigned char *d_orig, + unsigned int ds_orig) +{ + unsigned int l; + ExifLong offset; + ExifShort n; + const unsigned char *d = d_orig; + unsigned int ds = ds_orig, len; + + if (!data || !data->priv || !d || !ds) + return; + + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Parsing %i byte(s) EXIF data...\n", ds); + + /* + * It can be that the data starts with the EXIF header. If it does + * not, search the EXIF marker. + */ + if (ds < 6) { + LOG_TOO_SMALL; + return; + } + if (!memcmp (d, ExifHeader, 6)) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Found EXIF header."); + } else { + while (1) { + while ((d[0] == 0xff) && ds) { + d++; + ds--; + } + + /* JPEG_MARKER_SOI */ + if (d[0] == JPEG_MARKER_SOI) { + d++; + ds--; + continue; + } + + /* JPEG_MARKER_APP0 */ + if (d[0] == JPEG_MARKER_APP0) { + d++; + ds--; + l = (d[0] << 8) | d[1]; + if (l > ds) + return; + d += l; + ds -= l; + continue; + } + + /* JPEG_MARKER_APP1 */ + if (d[0] == JPEG_MARKER_APP1) + break; + + /* Unknown marker or data. Give up. */ + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifData", _("EXIF marker not found.")); + return; + } + d++; + ds--; + if (ds < 2) { + LOG_TOO_SMALL; + return; + } + len = (d[0] << 8) | d[1]; + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "We have to deal with %i byte(s) of EXIF data.", + len); + d += 2; + ds -= 2; + } + + /* + * Verify the exif header + * (offset 2, length 6). + */ + if (ds < 6) { + LOG_TOO_SMALL; + return; + } + if (memcmp (d, ExifHeader, 6)) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifData", _("EXIF header not found.")); + return; + } + + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Found EXIF header."); + + /* Byte order (offset 6, length 2) */ + if (ds < 14) + return; + if (!memcmp (d + 6, "II", 2)) + data->priv->order = EXIF_BYTE_ORDER_INTEL; + else if (!memcmp (d + 6, "MM", 2)) + data->priv->order = EXIF_BYTE_ORDER_MOTOROLA; + else { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifData", _("Unknown encoding.")); + return; + } + + /* Fixed value */ + if (exif_get_short (d + 8, data->priv->order) != 0x002a) + return; + + /* IFD 0 offset */ + offset = exif_get_long (d + 10, data->priv->order); + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "IFD 0 at %i.", (int) offset); + + /* Parse the actual exif data (usually offset 14 from start) */ + exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0); + + /* IFD 1 offset */ + if (offset + 6 + 2 > ds) { + return; + } + n = exif_get_short (d + 6 + offset, data->priv->order); + if (offset + 6 + 2 + 12 * n + 4 > ds) { + return; + } + offset = exif_get_long (d + 6 + offset + 2 + 12 * n, data->priv->order); + if (offset) { + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "IFD 1 at %i.", (int) offset); + + /* Sanity check. */ + if (offset > ds - 6) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifData", "Bogus offset of IFD1."); + } else { + exif_data_load_data_content (data, EXIF_IFD_1, d + 6, ds - 6, offset, 0); + } + } + + /* + * If we got an EXIF_TAG_MAKER_NOTE, try to interpret it. Some + * cameras use pointers in the maker note tag that point to the + * space between IFDs. Here is the only place where we have access + * to that data. + */ + interpret_maker_note(data, d, ds); + + /* Fixup tags if requested */ + if (data->priv->options & EXIF_DATA_OPTION_FOLLOW_SPECIFICATION) + exif_data_fix (data); +} + +void +exif_data_save_data (ExifData *data, unsigned char **d, unsigned int *ds) +{ + if (ds) + *ds = 0; /* This means something went wrong */ + + if (!data || !d || !ds) + return; + + /* Header */ + *ds = 14; + *d = exif_data_alloc (data, *ds); + if (!*d) { + *ds = 0; + return; + } + memcpy (*d, ExifHeader, 6); + + /* Order (offset 6) */ + if (data->priv->order == EXIF_BYTE_ORDER_INTEL) { + memcpy (*d + 6, "II", 2); + } else { + memcpy (*d + 6, "MM", 2); + } + + /* Fixed value (2 bytes, offset 8) */ + exif_set_short (*d + 8, data->priv->order, 0x002a); + + /* + * IFD 0 offset (4 bytes, offset 10). + * We will start 8 bytes after the + * EXIF header (2 bytes for order, another 2 for the test, and + * 4 bytes for the IFD 0 offset make 8 bytes together). + */ + exif_set_long (*d + 10, data->priv->order, 8); + + /* Now save IFD 0. IFD 1 will be saved automatically. */ + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Saving IFDs..."); + exif_data_save_data_content (data, data->ifd[EXIF_IFD_0], d, ds, + *ds - 6); + exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", + "Saved %i byte(s) EXIF data.", *ds); +} + +ExifData * +exif_data_new_from_file (const char *path) +{ + ExifData *edata; + ExifLoader *loader; + + loader = exif_loader_new (); + exif_loader_write_file (loader, path); + edata = exif_loader_get_data (loader); + exif_loader_unref (loader); + + return (edata); +} + +void +exif_data_ref (ExifData *data) +{ + if (!data) + return; + + data->priv->ref_count++; +} + +void +exif_data_unref (ExifData *data) +{ + if (!data) + return; + + data->priv->ref_count--; + if (!data->priv->ref_count) + exif_data_free (data); +} + +void +exif_data_free (ExifData *data) +{ + unsigned int i; + ExifMem *mem = (data && data->priv) ? data->priv->mem : NULL; + + if (!data) + return; + + for (i = 0; i < EXIF_IFD_COUNT; i++) { + if (data->ifd[i]) { + exif_content_unref (data->ifd[i]); + data->ifd[i] = NULL; + } + } + + if (data->data) { + exif_mem_free (mem, data->data); + data->data = NULL; + } + + if (data->priv) { + if (data->priv->log) { + exif_log_unref (data->priv->log); + data->priv->log = NULL; + } + if (data->priv->md) { + exif_mnote_data_unref (data->priv->md); + data->priv->md = NULL; + } + exif_mem_free (mem, data->priv); + exif_mem_free (mem, data); + } + + exif_mem_unref (mem); +} + +void +exif_data_dump (ExifData *data) +{ + unsigned int i; + + if (!data) + return; + + for (i = 0; i < EXIF_IFD_COUNT; i++) { + if (data->ifd[i] && data->ifd[i]->count) { + printf ("Dumping IFD '%s'...\n", + exif_ifd_get_name (i)); + exif_content_dump (data->ifd[i], 0); + } + } + + if (data->data) { + printf ("%i byte(s) thumbnail data available.", data->size); + if (data->size >= 4) { + printf ("0x%02x 0x%02x ... 0x%02x 0x%02x\n", + data->data[0], data->data[1], + data->data[data->size - 2], + data->data[data->size - 1]); + } + } +} + +ExifByteOrder +exif_data_get_byte_order (ExifData *data) +{ + if (!data) + return (0); + + return (data->priv->order); +} + +void +exif_data_foreach_content (ExifData *data, ExifDataForeachContentFunc func, + void *user_data) +{ + unsigned int i; + + if (!data || !func) + return; + + for (i = 0; i < EXIF_IFD_COUNT; i++) + func (data->ifd[i], user_data); +} + +typedef struct _ByteOrderChangeData ByteOrderChangeData; +struct _ByteOrderChangeData { + ExifByteOrder old, new; +}; + +static void +entry_set_byte_order (ExifEntry *e, void *data) +{ + ByteOrderChangeData *d = data; + + if (!e) + return; + + exif_array_set_byte_order (e->format, e->data, e->components, d->old, d->new); +} + +static void +content_set_byte_order (ExifContent *content, void *data) +{ + exif_content_foreach_entry (content, entry_set_byte_order, data); +} + +void +exif_data_set_byte_order (ExifData *data, ExifByteOrder order) +{ + ByteOrderChangeData d; + + if (!data || (order == data->priv->order)) + return; + + d.old = data->priv->order; + d.new = order; + exif_data_foreach_content (data, content_set_byte_order, &d); + data->priv->order = order; + if (data->priv->md) + exif_mnote_data_set_byte_order (data->priv->md, order); +} + +void +exif_data_log (ExifData *data, ExifLog *log) +{ + unsigned int i; + + if (!data || !data->priv) + return; + exif_log_unref (data->priv->log); + data->priv->log = log; + exif_log_ref (log); + + for (i = 0; i < EXIF_IFD_COUNT; i++) + exif_content_log (data->ifd[i], log); +} + +/* Used internally within libexif */ +ExifLog *exif_data_get_log (ExifData *); +ExifLog * +exif_data_get_log (ExifData *data) +{ + if (!data || !data->priv) + return NULL; + return data->priv->log; +} + +static const struct { + ExifDataOption option; + const char *name; + const char *description; +} exif_data_option[] = { + {EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS, N_("Ignore unknown tags"), + N_("Ignore unknown tags when loading EXIF data.")}, + {EXIF_DATA_OPTION_FOLLOW_SPECIFICATION, N_("Follow specification"), + N_("Add, correct and remove entries to get EXIF data that follows " + "the specification.")}, + {EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE, N_("Do not change maker note"), + N_("When loading and resaving Exif data, save the maker note unmodified." + " Be aware that the maker note can get corrupted.")}, + {0, NULL, NULL} +}; + +const char * +exif_data_option_get_name (ExifDataOption o) +{ + unsigned int i; + + for (i = 0; exif_data_option[i].name; i++) + if (exif_data_option[i].option == o) + break; + return _(exif_data_option[i].name); +} + +const char * +exif_data_option_get_description (ExifDataOption o) +{ + unsigned int i; + + for (i = 0; exif_data_option[i].description; i++) + if (exif_data_option[i].option == o) + break; + return _(exif_data_option[i].description); +} + +void +exif_data_set_option (ExifData *d, ExifDataOption o) +{ + if (!d) + return; + + d->priv->options |= o; +} + +void +exif_data_unset_option (ExifData *d, ExifDataOption o) +{ + if (!d) + return; + + d->priv->options &= ~o; +} + +static void +fix_func (ExifContent *c, void *UNUSED(data)) +{ + switch (exif_content_get_ifd (c)) { + case EXIF_IFD_1: + if (c->parent->data) + exif_content_fix (c); + else if (c->count) { + exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data", + "No thumbnail but entries on thumbnail. These entries have been " + "removed."); + while (c->count) { + unsigned int cnt = c->count; + exif_content_remove_entry (c, c->entries[c->count - 1]); + if (cnt == c->count) { + /* safety net */ + exif_log (c->parent->priv->log, EXIF_LOG_CODE_DEBUG, "exif-data", + "failed to remove last entry from entries."); + c->count--; + } + } + } + break; + default: + exif_content_fix (c); + } +} + +void +exif_data_fix (ExifData *d) +{ + exif_data_foreach_content (d, fix_func, NULL); +} + +void +exif_data_set_data_type (ExifData *d, ExifDataType dt) +{ + if (!d || !d->priv) + return; + + d->priv->data_type = dt; +} + +ExifDataType +exif_data_get_data_type (ExifData *d) +{ + return (d && d->priv) ? d->priv->data_type : EXIF_DATA_TYPE_UNKNOWN; +} diff --git a/libexifa/exif-entry.c b/libexifa/exif-entry.c new file mode 100755 index 0000000..a7edf7a --- /dev/null +++ b/libexifa/exif-entry.c @@ -0,0 +1,1710 @@ +/* exif-entry.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +struct _ExifEntryPrivate +{ + unsigned int ref_count; + + ExifMem *mem; +}; + +/* This function is hidden in exif-data.c */ +ExifLog *exif_data_get_log (ExifData *); + +#ifndef NO_VERBOSE_TAG_STRINGS +static void +exif_entry_log (ExifEntry *e, ExifLogCode code, const char *format, ...) +{ + va_list args; + ExifLog *l = NULL; + + if (e && e->parent && e->parent->parent) + l = exif_data_get_log (e->parent->parent); + va_start (args, format); + exif_logv (l, code, "ExifEntry", format, args); + va_end (args); +} +#else +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define exif_entry_log(...) do { } while (0) +#elif defined(__GNUC__) +#define exif_entry_log(x...) do { } while (0) +#else +#define exif_entry_log (void) +#endif +#endif + +static void * +exif_entry_alloc (ExifEntry *e, unsigned int i) +{ + void *d; + ExifLog *l = NULL; + + if (!e || !e->priv || !i) return NULL; + + d = exif_mem_alloc (e->priv->mem, i); + if (d) return d; + + if (e->parent && e->parent->parent) + l = exif_data_get_log (e->parent->parent); + EXIF_LOG_NO_MEMORY (l, "ExifEntry", i); + return NULL; +} + +static void * +exif_entry_realloc (ExifEntry *e, void *d_orig, unsigned int i) +{ + void *d; + ExifLog *l = NULL; + + if (!e || !e->priv) return NULL; + + if (!i) { exif_mem_free (e->priv->mem, d_orig); return NULL; } + + d = exif_mem_realloc (e->priv->mem, d_orig, i); + if (d) return d; + + if (e->parent && e->parent->parent) + l = exif_data_get_log (e->parent->parent); + EXIF_LOG_NO_MEMORY (l, "ExifEntry", i); + return NULL; +} + +ExifEntry * +exif_entry_new (void) +{ + ExifMem *mem = exif_mem_new_default (); + ExifEntry *e = exif_entry_new_mem (mem); + + exif_mem_unref (mem); + + return e; +} + +ExifEntry * +exif_entry_new_mem (ExifMem *mem) +{ + ExifEntry *e = NULL; + + e = exif_mem_alloc (mem, sizeof (ExifEntry)); + if (!e) return NULL; + e->priv = exif_mem_alloc (mem, sizeof (ExifEntryPrivate)); + if (!e->priv) { exif_mem_free (mem, e); return NULL; } + e->priv->ref_count = 1; + + e->priv->mem = mem; + exif_mem_ref (mem); + + return e; +} + +void +exif_entry_ref (ExifEntry *e) +{ + if (!e) return; + + e->priv->ref_count++; +} + +void +exif_entry_unref (ExifEntry *e) +{ + if (!e) return; + + e->priv->ref_count--; + if (!e->priv->ref_count) + exif_entry_free (e); +} + +void +exif_entry_free (ExifEntry *e) +{ + if (!e) return; + + if (e->priv) { + ExifMem *mem = e->priv->mem; + if (e->data) + exif_mem_free (mem, e->data); + exif_mem_free (mem, e->priv); + exif_mem_free (mem, e); + exif_mem_unref (mem); + } +} + +/*! Get a value and convert it to an ExifShort. + * \bug Not all types are converted that could be converted and no indication + * is made when that occurs + */ +static inline ExifShort +exif_get_short_convert (const unsigned char *buf, ExifFormat format, + ExifByteOrder order) +{ + switch (format) { + case EXIF_FORMAT_LONG: + return (ExifShort) exif_get_long (buf, order); + case EXIF_FORMAT_SLONG: + return (ExifShort) exif_get_slong (buf, order); + case EXIF_FORMAT_SHORT: + return (ExifShort) exif_get_short (buf, order); + case EXIF_FORMAT_SSHORT: + return (ExifShort) exif_get_sshort (buf, order); + case EXIF_FORMAT_BYTE: + case EXIF_FORMAT_SBYTE: + return (ExifShort) buf[0]; + default: + /* Unsupported type */ + return (ExifShort) 0; + } +} + +void +exif_entry_fix (ExifEntry *e) +{ + unsigned int i, newsize; + unsigned char *newdata; + ExifByteOrder o; + ExifRational r; + ExifSRational sr; + + if (!e || !e->priv) return; + + switch (e->tag) { + + /* These tags all need to be of format SHORT. */ + case EXIF_TAG_YCBCR_SUB_SAMPLING: + case EXIF_TAG_SUBJECT_AREA: + case EXIF_TAG_COLOR_SPACE: + case EXIF_TAG_PLANAR_CONFIGURATION: + case EXIF_TAG_SENSING_METHOD: + case EXIF_TAG_ORIENTATION: + case EXIF_TAG_YCBCR_POSITIONING: + case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: + case EXIF_TAG_CUSTOM_RENDERED: + case EXIF_TAG_EXPOSURE_MODE: + case EXIF_TAG_WHITE_BALANCE: + case EXIF_TAG_SCENE_CAPTURE_TYPE: + case EXIF_TAG_GAIN_CONTROL: + case EXIF_TAG_SATURATION: + case EXIF_TAG_CONTRAST: + case EXIF_TAG_SHARPNESS: + case EXIF_TAG_ISO_SPEED_RATINGS: + switch (e->format) { + case EXIF_FORMAT_LONG: + case EXIF_FORMAT_SLONG: + case EXIF_FORMAT_BYTE: + case EXIF_FORMAT_SBYTE: + case EXIF_FORMAT_SSHORT: + if (!e->parent || !e->parent->parent) break; + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag '%s' was of format '%s' (which is " + "against specification) and has been " + "changed to format '%s'."), + exif_tag_get_name_in_ifd(e->tag, + exif_entry_get_ifd(e)), + exif_format_get_name (e->format), + exif_format_get_name (EXIF_FORMAT_SHORT)); + + o = exif_data_get_byte_order (e->parent->parent); + newsize = e->components * exif_format_get_size (EXIF_FORMAT_SHORT); + newdata = exif_entry_alloc (e, newsize); + if (!newdata) { + exif_entry_log (e, EXIF_LOG_CODE_NO_MEMORY, + "Could not allocate %lu byte(s).", (unsigned long)newsize); + break; + } + + for (i = 0; i < e->components; i++) + exif_set_short ( + newdata + i * + exif_format_get_size ( + EXIF_FORMAT_SHORT), o, + exif_get_short_convert ( + e->data + i * + exif_format_get_size (e->format), + e->format, o)); + + exif_mem_free (e->priv->mem, e->data); + e->data = newdata; + e->size = newsize; + e->format = EXIF_FORMAT_SHORT; + break; + case EXIF_FORMAT_SHORT: + /* No conversion necessary */ + break; + default: + exif_entry_log (e, EXIF_LOG_CODE_CORRUPT_DATA, + _("Tag '%s' is of format '%s' (which is " + "against specification) but cannot be changed " + "to format '%s'."), + exif_tag_get_name_in_ifd(e->tag, + exif_entry_get_ifd(e)), + exif_format_get_name (e->format), + exif_format_get_name (EXIF_FORMAT_SHORT)); + break; + } + break; + + /* All these tags need to be of format 'Rational'. */ + case EXIF_TAG_FNUMBER: + case EXIF_TAG_APERTURE_VALUE: + case EXIF_TAG_EXPOSURE_TIME: + case EXIF_TAG_FOCAL_LENGTH: + switch (e->format) { + case EXIF_FORMAT_SRATIONAL: + if (!e->parent || !e->parent->parent) break; + o = exif_data_get_byte_order (e->parent->parent); + for (i = 0; i < e->components; i++) { + sr = exif_get_srational (e->data + i * + exif_format_get_size ( + EXIF_FORMAT_SRATIONAL), o); + r.numerator = (ExifLong) sr.numerator; + r.denominator = (ExifLong) sr.denominator; + exif_set_rational (e->data + i * + exif_format_get_size ( + EXIF_FORMAT_RATIONAL), o, r); + } + e->format = EXIF_FORMAT_RATIONAL; + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag '%s' was of format '%s' (which is " + "against specification) and has been " + "changed to format '%s'."), + exif_tag_get_name_in_ifd(e->tag, + exif_entry_get_ifd(e)), + exif_format_get_name (EXIF_FORMAT_SRATIONAL), + exif_format_get_name (EXIF_FORMAT_RATIONAL)); + break; + default: + break; + } + break; + + /* All these tags need to be of format 'SRational'. */ + case EXIF_TAG_EXPOSURE_BIAS_VALUE: + case EXIF_TAG_BRIGHTNESS_VALUE: + case EXIF_TAG_SHUTTER_SPEED_VALUE: + switch (e->format) { + case EXIF_FORMAT_RATIONAL: + if (!e->parent || !e->parent->parent) break; + o = exif_data_get_byte_order (e->parent->parent); + for (i = 0; i < e->components; i++) { + r = exif_get_rational (e->data + i * + exif_format_get_size ( + EXIF_FORMAT_RATIONAL), o); + sr.numerator = (ExifLong) r.numerator; + sr.denominator = (ExifLong) r.denominator; + exif_set_srational (e->data + i * + exif_format_get_size ( + EXIF_FORMAT_SRATIONAL), o, sr); + } + e->format = EXIF_FORMAT_SRATIONAL; + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag '%s' was of format '%s' (which is " + "against specification) and has been " + "changed to format '%s'."), + exif_tag_get_name_in_ifd(e->tag, + exif_entry_get_ifd(e)), + exif_format_get_name (EXIF_FORMAT_RATIONAL), + exif_format_get_name (EXIF_FORMAT_SRATIONAL)); + break; + default: + break; + } + break; + + case EXIF_TAG_USER_COMMENT: + + /* Format needs to be UNDEFINED. */ + if (e->format != EXIF_FORMAT_UNDEFINED) { + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag 'UserComment' had invalid format '%s'. " + "Format has been set to 'undefined'."), + exif_format_get_name (e->format)); + e->format = EXIF_FORMAT_UNDEFINED; + } + + /* Some packages like Canon ZoomBrowser EX 4.5 store + only one zero byte followed by 7 bytes of rubbish */ + if ((e->size >= 8) && (e->data[0] == 0)) { + memcpy(e->data, "\0\0\0\0\0\0\0\0", 8); + } + + /* There need to be at least 8 bytes. */ + if (e->size < 8) { + e->data = exif_entry_realloc (e, e->data, 8 + e->size); + if (!e->data) { + e->size = 0; + e->components = 0; + return; + } + + /* Assume ASCII */ + memmove (e->data + 8, e->data, e->size); + memcpy (e->data, "ASCII\0\0\0", 8); + e->size += 8; + e->components += 8; + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag 'UserComment' has been expanded to at " + "least 8 bytes in order to follow the " + "specification.")); + break; + } + + /* + * If the first 8 bytes are empty and real data starts + * afterwards, let's assume ASCII and claim the 8 first + * bytes for the format specifyer. + */ + for (i = 0; (i < e->size) && !e->data[i]; i++); + if (!i) for ( ; (i < e->size) && (e->data[i] == ' '); i++); + if ((i >= 8) && (i < e->size)) { + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag 'UserComment' is not empty but does not " + "start with a format identifier. " + "This has been fixed.")); + memcpy (e->data, "ASCII\0\0\0", 8); + break; + } + + /* + * First 8 bytes need to follow the specification. If they don't, + * assume ASCII. + */ + if (memcmp (e->data, "ASCII\0\0\0" , 8) && + memcmp (e->data, "UNICODE\0" , 8) && + memcmp (e->data, "JIS\0\0\0\0\0" , 8) && + memcmp (e->data, "\0\0\0\0\0\0\0\0", 8)) { + e->data = exif_entry_realloc (e, e->data, 8 + e->size); + if (!e->data) { + e->size = 0; + e->components = 0; + break; + } + + /* Assume ASCII */ + memmove (e->data + 8, e->data, e->size); + memcpy (e->data, "ASCII\0\0\0", 8); + e->size += 8; + e->components += 8; + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag 'UserComment' did not start with a " + "format identifier. This has been fixed.")); + break; + } + + break; + default: + break; + } +} + +/*! Format the value of an ExifEntry for human display in a generic way. + * The output is localized. The formatting is independent of the tag number. + * \pre The buffer at val is entirely cleared to 0. This guarantees that the + * resulting string will be NUL terminated. + * \pre The ExifEntry is already a member of an ExifData. + * \param[in] e EXIF entry + * \param[out] val buffer in which to store value + * \param[in] maxlen one less than the length of the buffer val + */ +static void +exif_entry_format_value(ExifEntry *e, char *val, size_t maxlen) +{ + ExifByte v_byte; + ExifShort v_short; + ExifSShort v_sshort; + ExifLong v_long; + ExifRational v_rat; + ExifSRational v_srat; + ExifSLong v_slong; + char b[64]; + unsigned int i; + const ExifByteOrder o = exif_data_get_byte_order (e->parent->parent); + + if (!e->size) + return; + switch (e->format) { + case EXIF_FORMAT_UNDEFINED: + snprintf (val, maxlen, _("%i bytes undefined data"), e->size); + break; + case EXIF_FORMAT_BYTE: + case EXIF_FORMAT_SBYTE: + v_byte = e->data[0]; + snprintf (val, maxlen, "0x%02x", v_byte); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_byte = e->data[i]; + snprintf (b, sizeof (b), ", 0x%02x", v_byte); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_FORMAT_SHORT: + v_short = exif_get_short (e->data, o); + snprintf (val, maxlen, "%u", v_short); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_short = exif_get_short (e->data + + exif_format_get_size (e->format) * i, o); + snprintf (b, sizeof (b), ", %u", v_short); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_FORMAT_SSHORT: + v_sshort = exif_get_sshort (e->data, o); + snprintf (val, maxlen, "%i", v_sshort); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_sshort = exif_get_short (e->data + + exif_format_get_size (e->format) * + i, o); + snprintf (b, sizeof (b), ", %i", v_sshort); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_FORMAT_LONG: + v_long = exif_get_long (e->data, o); + snprintf (val, maxlen, "%lu", (unsigned long) v_long); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_long = exif_get_long (e->data + + exif_format_get_size (e->format) * + i, o); + snprintf (b, sizeof (b), ", %lu", (unsigned long) v_long); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_FORMAT_SLONG: + v_slong = exif_get_slong (e->data, o); + snprintf (val, maxlen, "%li", (long) v_slong); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_slong = exif_get_slong (e->data + + exif_format_get_size (e->format) * i, o); + snprintf (b, sizeof (b), ", %li", (long) v_slong); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_FORMAT_ASCII: + strncpy (val, (char *) e->data, MIN (maxlen, e->size)); + break; + case EXIF_FORMAT_RATIONAL: + for (i = 0; i < e->components; i++) { + if (i > 0) { + strncat (val, ", ", maxlen); + maxlen -= 2; + } + v_rat = exif_get_rational ( + e->data + 8 * i, o); + if (v_rat.denominator) { + /* + * Choose the number of significant digits to + * display based on the size of the denominator. + * It is scaled so that denominators within the + * range 13..120 will show 2 decimal points. + */ + int decimals = (int)(log10(v_rat.denominator)-0.08+1.0); + snprintf (b, sizeof (b), "%2.*f", + decimals, + (double) v_rat.numerator / + (double) v_rat.denominator); + } else + snprintf (b, sizeof (b), "%lu/%lu", + (unsigned long) v_rat.numerator, + (unsigned long) v_rat.denominator); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed) maxlen <= 0) break; + } + break; + case EXIF_FORMAT_SRATIONAL: + for (i = 0; i < e->components; i++) { + if (i > 0) { + strncat (val, ", ", maxlen); + maxlen -= 2; + } + v_srat = exif_get_srational ( + e->data + 8 * i, o); + if (v_srat.denominator) { + int decimals = (int)(log10(fabs(v_srat.denominator))-0.08+1.0); + snprintf (b, sizeof (b), "%2.*f", + decimals, + (double) v_srat.numerator / + (double) v_srat.denominator); + } else + snprintf (b, sizeof (b), "%li/%li", + (long) v_srat.numerator, + (long) v_srat.denominator); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed) maxlen <= 0) break; + } + break; + case EXIF_FORMAT_DOUBLE: + case EXIF_FORMAT_FLOAT: + default: + snprintf (val, maxlen, _("%i bytes unsupported data type"), + e->size); + break; + } +} + +void +exif_entry_dump (ExifEntry *e, unsigned int indent) +{ + char buf[1024]; + char value[1024]; + unsigned int i; + + for (i = 0; i < 2 * indent; i++) + buf[i] = ' '; + buf[i] = '\0'; + + if (!e) + return; + + printf ("%sTag: 0x%x ('%s')\n", buf, e->tag, + exif_tag_get_name_in_ifd (e->tag, exif_entry_get_ifd(e))); + printf ("%s Format: %i ('%s')\n", buf, e->format, + exif_format_get_name (e->format)); + printf ("%s Components: %i\n", buf, (int) e->components); + printf ("%s Size: %i\n", buf, e->size); + printf ("%s Value: %s\n", buf, exif_entry_get_value (e, value, sizeof(value))); +} + +#define CF(entry,target,v,maxlen) \ +{ \ + if (entry->format != target) { \ + exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \ + _("The tag '%s' contains data of an invalid " \ + "format ('%s', expected '%s')."), \ + exif_tag_get_name (entry->tag), \ + exif_format_get_name (entry->format), \ + exif_format_get_name (target)); \ + break; \ + } \ +} + +#define CC(entry,target,v,maxlen) \ +{ \ + if (entry->components != target) { \ + exif_entry_log (entry, EXIF_LOG_CODE_CORRUPT_DATA, \ + _("The tag '%s' contains an invalid number of " \ + "components (%i, expected %i)."), \ + exif_tag_get_name (entry->tag), \ + (int) entry->components, (int) target); \ + break; \ + } \ +} + +static const struct { + ExifTag tag; + const char *strings[10]; +} list[] = { +#ifndef NO_VERBOSE_TAG_DATA + { EXIF_TAG_PLANAR_CONFIGURATION, + { N_("Chunky format"), N_("Planar format"), NULL}}, + { EXIF_TAG_SENSING_METHOD, + { "", N_("Not defined"), N_("One-chip color area sensor"), + N_("Two-chip color area sensor"), N_("Three-chip color area sensor"), + N_("Color sequential area sensor"), "", N_("Trilinear sensor"), + N_("Color sequential linear sensor"), NULL}}, + { EXIF_TAG_ORIENTATION, + { "", N_("Top-left"), N_("Top-right"), N_("Bottom-right"), + N_("Bottom-left"), N_("Left-top"), N_("Right-top"), + N_("Right-bottom"), N_("Left-bottom"), NULL}}, + { EXIF_TAG_YCBCR_POSITIONING, + { "", N_("Centered"), N_("Co-sited"), NULL}}, + { EXIF_TAG_PHOTOMETRIC_INTERPRETATION, + { N_("Reversed mono"), N_("Normal mono"), N_("RGB"), N_("Palette"), "", + N_("CMYK"), N_("YCbCr"), "", N_("CieLAB"), NULL}}, + { EXIF_TAG_CUSTOM_RENDERED, + { N_("Normal process"), N_("Custom process"), NULL}}, + { EXIF_TAG_EXPOSURE_MODE, + { N_("Auto exposure"), N_("Manual exposure"), N_("Auto bracket"), NULL}}, + { EXIF_TAG_WHITE_BALANCE, + { N_("Auto white balance"), N_("Manual white balance"), NULL}}, + { EXIF_TAG_SCENE_CAPTURE_TYPE, + { N_("Standard"), N_("Landscape"), N_("Portrait"), + N_("Night scene"), NULL}}, + { EXIF_TAG_GAIN_CONTROL, + { N_("Normal"), N_("Low gain up"), N_("High gain up"), + N_("Low gain down"), N_("High gain down"), NULL}}, + { EXIF_TAG_SATURATION, + { N_("Normal"), N_("Low saturation"), N_("High saturation"), NULL}}, + { EXIF_TAG_CONTRAST , {N_("Normal"), N_("Soft"), N_("Hard"), NULL}}, + { EXIF_TAG_SHARPNESS, {N_("Normal"), N_("Soft"), N_("Hard"), NULL}}, +#endif + { 0, {NULL}} +}; + +static const struct { + ExifTag tag; + struct { + int index; + const char *values[4]; /*!< list of progressively shorter string + descriptions; the longest one that fits will be + selected */ + } elem[25]; +} list2[] = { +#ifndef NO_VERBOSE_TAG_DATA + { EXIF_TAG_METERING_MODE, + { { 0, {N_("Unknown"), NULL}}, + { 1, {N_("Average"), N_("Avg"), NULL}}, + { 2, {N_("Center-weighted average"), N_("Center-weight"), NULL}}, + { 3, {N_("Spot"), NULL}}, + { 4, {N_("Multi spot"), NULL}}, + { 5, {N_("Pattern"), NULL}}, + { 6, {N_("Partial"), NULL}}, + {255, {N_("Other"), NULL}}, + { 0, {NULL}}}}, + { EXIF_TAG_COMPRESSION, + { {1, {N_("Uncompressed"), NULL}}, + {5, {N_("LZW compression"), NULL}}, + {6, {N_("JPEG compression"), NULL}}, + {7, {N_("JPEG compression"), NULL}}, + {8, {N_("Deflate/ZIP compression"), NULL}}, + {32773, {N_("PackBits compression"), NULL}}, + {0, {NULL}}}}, + { EXIF_TAG_LIGHT_SOURCE, + { { 0, {N_("Unknown"), NULL}}, + { 1, {N_("Daylight"), NULL}}, + { 2, {N_("Fluorescent"), NULL}}, + { 3, {N_("Tungsten incandescent light"), N_("Tungsten"), NULL}}, + { 4, {N_("Flash"), NULL}}, + { 9, {N_("Fine weather"), NULL}}, + { 10, {N_("Cloudy weather"), N_("Cloudy"), NULL}}, + { 11, {N_("Shade"), NULL}}, + { 12, {N_("Daylight fluorescent"), NULL}}, + { 13, {N_("Day white fluorescent"), NULL}}, + { 14, {N_("Cool white fluorescent"), NULL}}, + { 15, {N_("White fluorescent"), NULL}}, + { 17, {N_("Standard light A"), NULL}}, + { 18, {N_("Standard light B"), NULL}}, + { 19, {N_("Standard light C"), NULL}}, + { 20, {N_("D55"), NULL}}, + { 21, {N_("D65"), NULL}}, + { 22, {N_("D75"), NULL}}, + { 24, {N_("ISO studio tungsten"),NULL}}, + {255, {N_("Other"), NULL}}, + { 0, {NULL}}}}, + { EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, + { {2, {N_("Inch"), N_("in"), NULL}}, + {3, {N_("Centimeter"), N_("cm"), NULL}}, + {0, {NULL}}}}, + { EXIF_TAG_RESOLUTION_UNIT, + { {2, {N_("Inch"), N_("in"), NULL}}, + {3, {N_("Centimeter"), N_("cm"), NULL}}, + {0, {NULL}}}}, + { EXIF_TAG_EXPOSURE_PROGRAM, + { {0, {N_("Not defined"), NULL}}, + {1, {N_("Manual"), NULL}}, + {2, {N_("Normal program"), N_("Normal"), NULL}}, + {3, {N_("Aperture priority"), N_("Aperture"), NULL}}, + {4, {N_("Shutter priority"),N_("Shutter"), NULL}}, + {5, {N_("Creative program (biased toward depth of field)"), + N_("Creative"), NULL}}, + {6, {N_("Creative program (biased toward fast shutter speed)"), + N_("Action"), NULL}}, + {7, {N_("Portrait mode (for closeup photos with the background out " + "of focus)"), N_("Portrait"), NULL}}, + {8, {N_("Landscape mode (for landscape photos with the background " + "in focus)"), N_("Landscape"), NULL}}, + {0, {NULL}}}}, + { EXIF_TAG_FLASH, + { {0x0000, {N_("Flash did not fire"), N_("No flash"), NULL}}, + {0x0001, {N_("Flash fired"), N_("Flash"), N_("Yes"), NULL}}, + {0x0005, {N_("Strobe return light not detected"), N_("Without strobe"), + NULL}}, + {0x0007, {N_("Strobe return light detected"), N_("With strobe"), NULL}}, + {0x0008, {N_("Flash did not fire"), NULL}}, /* Olympus E-330 */ + {0x0009, {N_("Flash fired, compulsory flash mode"), NULL}}, + {0x000d, {N_("Flash fired, compulsory flash mode, return light " + "not detected"), NULL}}, + {0x000f, {N_("Flash fired, compulsory flash mode, return light " + "detected"), NULL}}, + {0x0010, {N_("Flash did not fire, compulsory flash mode"), NULL}}, + {0x0018, {N_("Flash did not fire, auto mode"), NULL}}, + {0x0019, {N_("Flash fired, auto mode"), NULL}}, + {0x001d, {N_("Flash fired, auto mode, return light not detected"), + NULL}}, + {0x001f, {N_("Flash fired, auto mode, return light detected"), NULL}}, + {0x0020, {N_("No flash function"),NULL}}, + {0x0041, {N_("Flash fired, red-eye reduction mode"), NULL}}, + {0x0045, {N_("Flash fired, red-eye reduction mode, return light " + "not detected"), NULL}}, + {0x0047, {N_("Flash fired, red-eye reduction mode, return light " + "detected"), NULL}}, + {0x0049, {N_("Flash fired, compulsory flash mode, red-eye reduction " + "mode"), NULL}}, + {0x004d, {N_("Flash fired, compulsory flash mode, red-eye reduction " + "mode, return light not detected"), NULL}}, + {0x004f, {N_("Flash fired, compulsory flash mode, red-eye reduction mode, " + "return light detected"), NULL}}, + {0x0058, {N_("Flash did not fire, auto mode, red-eye reduction mode"), NULL}}, + {0x0059, {N_("Flash fired, auto mode, red-eye reduction mode"), NULL}}, + {0x005d, {N_("Flash fired, auto mode, return light not detected, " + "red-eye reduction mode"), NULL}}, + {0x005f, {N_("Flash fired, auto mode, return light detected, " + "red-eye reduction mode"), NULL}}, + {0x0000, {NULL}}}}, + { EXIF_TAG_SUBJECT_DISTANCE_RANGE, + { {0, {N_("Unknown"), N_("?"), NULL}}, + {1, {N_("Macro"), NULL}}, + {2, {N_("Close view"), N_("Close"), NULL}}, + {3, {N_("Distant view"), N_("Distant"), NULL}}, + {0, {NULL}}}}, + { EXIF_TAG_COLOR_SPACE, + { {1, {N_("sRGB"), NULL}}, + {2, {N_("Adobe RGB"), NULL}}, + {0xffff, {N_("Uncalibrated"), NULL}}, + {0x0000, {NULL}}}}, +#endif + {0, { { 0, {NULL}}} } +}; + +const char * +exif_entry_get_value (ExifEntry *e, char *val, unsigned int maxlen) +{ + unsigned int i, j, k; + const unsigned char *t; + ExifShort v_short, v_short2, v_short3, v_short4; + ExifByte v_byte; + ExifRational v_rat; + ExifSRational v_srat; + char b[64]; + const char *c; + ExifByteOrder o; + double d; + ExifEntry *entry; + static const struct { + char label[5]; + char major, minor; + } versions[] = { + {"0110", 1, 1}, + {"0120", 1, 2}, + {"0200", 2, 0}, + {"0210", 2, 1}, + {"0220", 2, 2}, + {"0221", 2, 21}, + {"" , 0, 0} + }; + + /* FIXME: This belongs to somewhere else. */ + /* libexif should use the default system locale. + * If an application specifically requires UTF-8, then we + * must give the application a way to tell libexif that. + * + * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + */ + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + + /* make sure the returned string is zero terminated */ + memset (val, 0, maxlen); + maxlen--; + memset (b, 0, sizeof (b)); + + /* We need the byte order */ + if (!e || !e->parent || !e->parent->parent) + return val; + o = exif_data_get_byte_order (e->parent->parent); + + /* Sanity check */ + if (e->size != e->components * exif_format_get_size (e->format)) { + snprintf (val, maxlen, _("Invalid size of entry (%i, " + "expected %li x %i)."), e->size, e->components, + exif_format_get_size (e->format)); + return val; + } + + switch (e->tag) { + case EXIF_TAG_USER_COMMENT: + + /* + * The specification says UNDEFINED, but some + * manufacturers don't care and use ASCII. If this is the + * case here, only refuse to read it if there is no chance + * of finding readable data. + */ + if ((e->format != EXIF_FORMAT_ASCII) || + (e->size <= 8) || + ( memcmp (e->data, "ASCII\0\0\0" , 8) && + memcmp (e->data, "UNICODE\0" , 8) && + memcmp (e->data, "JIS\0\0\0\0\0", 8) && + memcmp (e->data, "\0\0\0\0\0\0\0\0", 8))) + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + + /* + * Note that, according to the specification (V2.1, p 40), + * the user comment field does not have to be + * NULL terminated. + */ + if ((e->size >= 8) && !memcmp (e->data, "ASCII\0\0\0", 8)) { + strncpy (val, (char *) e->data + 8, MIN (e->size - 8, maxlen)); + break; + } + if ((e->size >= 8) && !memcmp (e->data, "UNICODE\0", 8)) { + strncpy (val, _("Unsupported UNICODE string"), maxlen); + /* FIXME: use iconv to convert into the locale encoding. + * EXIF 2.2 implies (but does not say) that this encoding is + * UCS-2. + */ + break; + } + if ((e->size >= 8) && !memcmp (e->data, "JIS\0\0\0\0\0", 8)) { + strncpy (val, _("Unsupported JIS string"), maxlen); + /* FIXME: use iconv to convert into the locale encoding */ + break; + } + + /* Check if there is really some information in the tag. */ + for (i = 0; (i < e->size) && + (!e->data[i] || (e->data[i] == ' ')); i++); + if (i == e->size) break; + + /* + * If we reach this point, the tag does not + * comply with the standard and seems to contain data. + * Print as much as possible. + */ + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Tag UserComment does not comply " + "with standard but contains data.")); + for (; (i < e->size) && (strlen (val) < maxlen - 1); i++) { + exif_entry_log (e, EXIF_LOG_CODE_DEBUG, + _("Byte at position %i: 0x%02x"), i, e->data[i]); + val[strlen (val)] = + isprint (e->data[i]) ? e->data[i] : '.'; + } + break; + + case EXIF_TAG_EXIF_VERSION: + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (e, 4, val, maxlen); + strncpy (val, _("Unknown Exif Version"), maxlen); + for (i = 0; *versions[i].label; i++) { + if (!memcmp (e->data, versions[i].label, 4)) { + snprintf (val, maxlen, + _("Exif Version %d.%d"), + versions[i].major, + versions[i].minor); + break; + } + } + break; + case EXIF_TAG_FLASH_PIX_VERSION: + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (e, 4, val, maxlen); + if (!memcmp (e->data, "0100", 4)) + strncpy (val, _("FlashPix Version 1.0"), maxlen); + else if (!memcmp (e->data, "0101", 4)) + strncpy (val, _("FlashPix Version 1.01"), maxlen); + else + strncpy (val, _("Unknown FlashPix Version"), maxlen); + break; + case EXIF_TAG_COPYRIGHT: + CF (e, EXIF_FORMAT_ASCII, val, maxlen); + + /* + * First part: Photographer. + * Some cameras store a string like " " here. Ignore it. + */ + if (e->size && e->data && + (strspn ((char *)e->data, " ") != strlen ((char *) e->data))) + strncpy (val, (char *) e->data, MIN (maxlen, e->size)); + else + strncpy (val, _("[None]"), maxlen); + strncat (val, " ", maxlen - strlen (val)); + strncat (val, _("(Photographer)"), maxlen - strlen (val)); + + /* Second part: Editor. */ + strncat (val, " - ", maxlen - strlen (val)); + if (e->size && e->data) { + size_t ts; + t = e->data + strlen ((char *) e->data) + 1; + ts = e->data + e->size - t; + if ((ts > 0) && (strspn ((char *)t, " ") != ts)) + strncat (val, (char *)t, MIN (maxlen - strlen (val), ts)); + } else { + strncat (val, _("[None]"), maxlen - strlen (val)); + } + strncat (val, " ", maxlen - strlen (val)); + strncat (val, _("(Editor)"), maxlen - strlen (val)); + + break; + case EXIF_TAG_FNUMBER: + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, "f/%.01f", d); + break; + case EXIF_TAG_APERTURE_VALUE: + case EXIF_TAG_MAX_APERTURE_VALUE: + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator || (0x80000000 == v_rat.numerator)) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + snprintf (b, sizeof (b), _(" (f/%.01f)"), pow (2, d / 2.)); + if (maxlen > strlen (val) + strlen (b)) + strncat (val, b, maxlen - strlen (val)); + break; + case EXIF_TAG_FOCAL_LENGTH: + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + + /* + * For calculation of the 35mm equivalent, + * Minolta cameras need a multiplier that depends on the + * camera model. + */ + d = 0.; + entry = exif_content_get_entry ( + e->parent->parent->ifd[EXIF_IFD_0], EXIF_TAG_MAKE); + if (entry && entry->data && + !strncmp ((char *)entry->data, "Minolta", 7)) { + entry = exif_content_get_entry ( + e->parent->parent->ifd[EXIF_IFD_0], + EXIF_TAG_MODEL); + if (entry && entry->data) { + if (!strncmp ((char *)entry->data, "DiMAGE 7", 8)) + d = 3.9; + else if (!strncmp ((char *)entry->data, "DiMAGE 5", 8)) + d = 4.9; + } + } + if (d) + snprintf (b, sizeof (b), _(" (35 equivalent: %d mm)"), + (int) (d * (double) v_rat.numerator / + (double) v_rat.denominator)); + + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, "%.1f mm", d); + if (maxlen > strlen (val) + strlen (b)) + strncat (val, b, maxlen - strlen (val)); + break; + case EXIF_TAG_SUBJECT_DISTANCE: + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, "%.1f m", d); + break; + case EXIF_TAG_EXPOSURE_TIME: + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_rat.numerator / (double) v_rat.denominator; + if (d < 1) + snprintf (val, maxlen, _("1/%i"), (int) (0.5 + 1. / d)); + else + snprintf (val, maxlen, "%i", (int) d); + if (maxlen > strlen (val) + strlen (_(" sec."))) + strncat (val, _(" sec."), maxlen - strlen (val)); + break; + case EXIF_TAG_SHUTTER_SPEED_VALUE: + CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_srat = exif_get_srational (e->data, o); + if (!v_srat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + d = 1. / pow (2, d); + if (d < 1) + snprintf (b, sizeof (b), _(" (1/%d sec.)"), (int) (1. / d)); + else + snprintf (b, sizeof (b), _(" (%d sec.)"), (int) d); + strncat (val, b, maxlen - strlen (val)); + break; + case EXIF_TAG_BRIGHTNESS_VALUE: + CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_srat = exif_get_srational (e->data, o); + if (!v_srat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + snprintf (b, sizeof (b), _(" (%.02f cd/m^2)"), + 1. / (M_PI * 0.3048 * 0.3048) * pow (2, d)); + if (maxlen > strlen (val) + strlen (b)) + strncat (val, b, maxlen - strlen (val)); + break; + case EXIF_TAG_FILE_SOURCE: + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (e, 1, val, maxlen); + v_byte = e->data[0]; + if (v_byte == 3) + strncpy (val, _("DSC"), maxlen); + else + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_byte); + break; + case EXIF_TAG_COMPONENTS_CONFIGURATION: + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (e, 4, val, maxlen); + for (i = 0; i < 4; i++) { + switch (e->data[i]) { + case 0: c = _("-"); break; + case 1: c = _("Y"); break; + case 2: c = _("Cb"); break; + case 3: c = _("Cr"); break; + case 4: c = _("R"); break; + case 5: c = _("G"); break; + case 6: c = _("B"); break; + default: c = _("Reserved"); break; + } + strncat (val, c, maxlen - strlen (val)); + if (i < 3) + strncat (val, " ", maxlen - strlen (val)); + } + break; + case EXIF_TAG_EXPOSURE_BIAS_VALUE: + CF (e, EXIF_FORMAT_SRATIONAL, val, maxlen); + CC (e, 1, val, maxlen); + v_srat = exif_get_srational (e->data, o); + if (!v_srat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_srat.numerator / (double) v_srat.denominator; + snprintf (val, maxlen, _("%.02f EV"), d); + break; + case EXIF_TAG_SCENE_TYPE: + CF (e, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (e, 1, val, maxlen); + v_byte = e->data[0]; + if (v_byte == 1) + strncpy (val, _("Directly photographed"), maxlen); + else + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_byte); + break; + case EXIF_TAG_YCBCR_SUB_SAMPLING: + CF (e, EXIF_FORMAT_SHORT, val, maxlen); + CC (e, 2, val, maxlen); + v_short = exif_get_short (e->data, o); + v_short2 = exif_get_short ( + e->data + exif_format_get_size (e->format), + o); + if ((v_short == 2) && (v_short2 == 1)) + strncpy (val, _("YCbCr4:2:2"), maxlen); + else if ((v_short == 2) && (v_short2 == 2)) + strncpy (val, _("YCbCr4:2:0"), maxlen); + else + snprintf (val, maxlen, "%u, %u", v_short, v_short2); + break; + case EXIF_TAG_SUBJECT_AREA: + CF (e, EXIF_FORMAT_SHORT, val, maxlen); + switch (e->components) { + case 2: + v_short = exif_get_short (e->data, o); + v_short2 = exif_get_short (e->data + 2, o); + snprintf (val, maxlen, "(x,y) = (%i,%i)", + v_short, v_short2); + break; + case 3: + v_short = exif_get_short (e->data, o); + v_short2 = exif_get_short (e->data + 2, o); + v_short3 = exif_get_short (e->data + 4, o); + snprintf (val, maxlen, _("Within distance %i of " + "(x,y) = (%i,%i)"), v_short3, v_short, + v_short2); + break; + case 4: + v_short = exif_get_short (e->data, o); + v_short2 = exif_get_short (e->data + 2, o); + v_short3 = exif_get_short (e->data + 4, o); + v_short4 = exif_get_short (e->data + 6, o); + snprintf (val, maxlen, _("Within rectangle " + "(width %i, height %i) around " + "(x,y) = (%i,%i)"), v_short3, v_short4, + v_short, v_short2); + break; + default: + snprintf (val, maxlen, _("Unexpected number " + "of components (%li, expected 2, 3, or 4)."), + e->components); + } + break; + case EXIF_TAG_GPS_VERSION_ID: + /* This is only valid in the GPS IFD */ + CF (e, EXIF_FORMAT_BYTE, val, maxlen); + CC (e, 4, val, maxlen); + v_byte = e->data[0]; + snprintf (val, maxlen, "%u", v_byte); + maxlen -= strlen (val); + for (i = 1; i < e->components; i++) { + v_byte = e->data[i]; + snprintf (b, sizeof (b), ".%u", v_byte); + strncat (val, b, maxlen); + maxlen -= strlen (b); + if ((signed)maxlen <= 0) break; + } + break; + case EXIF_TAG_INTEROPERABILITY_VERSION: + /* a.k.a. case EXIF_TAG_GPS_LATITUDE: */ + /* This tag occurs in EXIF_IFD_INTEROPERABILITY */ + if (e->format == EXIF_FORMAT_UNDEFINED) { + strncpy (val, (char *) e->data, MIN (maxlen, e->size)); + break; + } + /* EXIF_TAG_GPS_LATITUDE is the same numerically as + * EXIF_TAG_INTEROPERABILITY_VERSION but in EXIF_IFD_GPS + */ + exif_entry_format_value(e, val, maxlen); + break; + case EXIF_TAG_GPS_ALTITUDE_REF: + /* This is only valid in the GPS IFD */ + CF (e, EXIF_FORMAT_BYTE, val, maxlen); + CC (e, 1, val, maxlen); + v_byte = e->data[0]; + if (v_byte == 0) + strncpy (val, _("Sea level"), maxlen); + else if (v_byte == 1) + strncpy (val, _("Sea level reference"), maxlen); + else + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_byte); + break; + case EXIF_TAG_GPS_TIME_STAMP: + /* This is only valid in the GPS IFD */ + CF (e, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (e, 3, val, maxlen); + + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + i = v_rat.numerator / v_rat.denominator; + + v_rat = exif_get_rational (e->data + + exif_format_get_size (e->format), + o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + j = v_rat.numerator / v_rat.denominator; + + v_rat = exif_get_rational (e->data + + 2*exif_format_get_size (e->format), + o); + if (!v_rat.denominator) { + exif_entry_format_value(e, val, maxlen); + break; + } + d = (double) v_rat.numerator / (double) v_rat.denominator; + snprintf (val, maxlen, "%02u:%02u:%05.2f", i, j, d); + break; + + case EXIF_TAG_METERING_MODE: + case EXIF_TAG_COMPRESSION: + case EXIF_TAG_LIGHT_SOURCE: + case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT: + case EXIF_TAG_RESOLUTION_UNIT: + case EXIF_TAG_EXPOSURE_PROGRAM: + case EXIF_TAG_FLASH: + case EXIF_TAG_SUBJECT_DISTANCE_RANGE: + case EXIF_TAG_COLOR_SPACE: + CF (e,EXIF_FORMAT_SHORT, val, maxlen); + CC (e, 1, val, maxlen); + v_short = exif_get_short (e->data, o); + + /* Search the tag */ + for (i = 0; list2[i].tag && (list2[i].tag != e->tag); i++); + if (!list2[i].tag) { + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_short); + break; + } + + /* Find the value */ + for (j = 0; list2[i].elem[j].values[0] && + (list2[i].elem[j].index < v_short); j++); + if (list2[i].elem[j].index != v_short) { + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_short); + break; + } + + /* Find a short enough value */ + memset (val, 0, maxlen); + for (k = 0; list2[i].elem[j].values[k]; k++) { + size_t l = strlen (_(list2[i].elem[j].values[k])); + if ((maxlen > l) && (strlen (val) < l)) + strncpy (val, _(list2[i].elem[j].values[k]), maxlen); + } + if (!val[0]) snprintf (val, maxlen, "%i", v_short); + + break; + + case EXIF_TAG_PLANAR_CONFIGURATION: + case EXIF_TAG_SENSING_METHOD: + case EXIF_TAG_ORIENTATION: + case EXIF_TAG_YCBCR_POSITIONING: + case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: + case EXIF_TAG_CUSTOM_RENDERED: + case EXIF_TAG_EXPOSURE_MODE: + case EXIF_TAG_WHITE_BALANCE: + case EXIF_TAG_SCENE_CAPTURE_TYPE: + case EXIF_TAG_GAIN_CONTROL: + case EXIF_TAG_SATURATION: + case EXIF_TAG_CONTRAST: + case EXIF_TAG_SHARPNESS: + CF (e, EXIF_FORMAT_SHORT, val, maxlen); + CC (e, 1, val, maxlen); + v_short = exif_get_short (e->data, o); + + /* Search the tag */ + for (i = 0; list[i].tag && (list[i].tag != e->tag); i++); + if (!list[i].tag) { + snprintf (val, maxlen, _("Internal error (unknown " + "value %i)"), v_short); + break; + } + + /* Find the value */ + for (j = 0; list[i].strings[j] && (j < v_short); j++); + if (!list[i].strings[j]) + snprintf (val, maxlen, "%i", v_short); + else if (!*list[i].strings[j]) + snprintf (val, maxlen, _("Unknown value %i"), v_short); + else + strncpy (val, _(list[i].strings[j]), maxlen); + break; + + case EXIF_TAG_XP_TITLE: + case EXIF_TAG_XP_COMMENT: + case EXIF_TAG_XP_AUTHOR: + case EXIF_TAG_XP_KEYWORDS: + case EXIF_TAG_XP_SUBJECT: + /* Warning! The texts are converted from UTF16 to UTF8 */ + /* FIXME: use iconv to convert into the locale encoding */ + exif_convert_utf16_to_utf8(val, (unsigned short*)e->data, MIN(maxlen, e->size)); + break; + + default: + /* Use a generic value formatting */ + exif_entry_format_value(e, val, maxlen); + } + + return val; +} + + +/*! + * \bug Log and report failed exif_mem_malloc() calls. + */ +void +exif_entry_initialize (ExifEntry *e, ExifTag tag) +{ + ExifRational r; + ExifByteOrder o; + + /* We need the byte order */ + if (!e || !e->parent || e->data || !e->parent->parent) + return; + o = exif_data_get_byte_order (e->parent->parent); + + e->tag = tag; + switch (tag) { + + /* LONG, 1 component, no default */ + case EXIF_TAG_PIXEL_X_DIMENSION: + case EXIF_TAG_PIXEL_Y_DIMENSION: + case EXIF_TAG_EXIF_IFD_POINTER: + case EXIF_TAG_GPS_INFO_IFD_POINTER: + case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH: + case EXIF_TAG_JPEG_INTERCHANGE_FORMAT: + e->components = 1; + e->format = EXIF_FORMAT_LONG; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + break; + + /* SHORT, 1 component, no default */ + case EXIF_TAG_SUBJECT_LOCATION: + case EXIF_TAG_SENSING_METHOD: + case EXIF_TAG_PHOTOMETRIC_INTERPRETATION: + case EXIF_TAG_COMPRESSION: + case EXIF_TAG_EXPOSURE_MODE: + case EXIF_TAG_WHITE_BALANCE: + case EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM: + case EXIF_TAG_GAIN_CONTROL: + case EXIF_TAG_SUBJECT_DISTANCE_RANGE: + case EXIF_TAG_FLASH: + case EXIF_TAG_ISO_SPEED_RATINGS: + + /* SHORT, 1 component, default 0 */ + case EXIF_TAG_IMAGE_WIDTH: + case EXIF_TAG_IMAGE_LENGTH: + case EXIF_TAG_EXPOSURE_PROGRAM: + case EXIF_TAG_LIGHT_SOURCE: + case EXIF_TAG_METERING_MODE: + case EXIF_TAG_CUSTOM_RENDERED: + case EXIF_TAG_SCENE_CAPTURE_TYPE: + case EXIF_TAG_CONTRAST: + case EXIF_TAG_SATURATION: + case EXIF_TAG_SHARPNESS: + e->components = 1; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 0); + break; + + /* SHORT, 1 component, default 1 */ + case EXIF_TAG_ORIENTATION: + case EXIF_TAG_PLANAR_CONFIGURATION: + case EXIF_TAG_YCBCR_POSITIONING: + e->components = 1; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 1); + break; + + /* SHORT, 1 component, default 2 */ + case EXIF_TAG_RESOLUTION_UNIT: + case EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT: + e->components = 1; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 2); + break; + + /* SHORT, 1 component, default 3 */ + case EXIF_TAG_SAMPLES_PER_PIXEL: + e->components = 1; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 3); + break; + + /* SHORT, 1 component, default 0xffff */ + case EXIF_TAG_COLOR_SPACE: + e->components = 1; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 0xffff); + break; + + /* SHORT, 3 components, default 8 8 8 */ + case EXIF_TAG_BITS_PER_SAMPLE: + e->components = 3; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 8); + exif_set_short ( + e->data + exif_format_get_size (e->format), + o, 8); + exif_set_short ( + e->data + 2 * exif_format_get_size (e->format), + o, 8); + break; + + /* SHORT, 2 components, default 2 1 */ + case EXIF_TAG_YCBCR_SUB_SAMPLING: + e->components = 2; + e->format = EXIF_FORMAT_SHORT; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + exif_set_short (e->data, o, 2); + exif_set_short ( + e->data + exif_format_get_size (e->format), + o, 1); + break; + + /* SRATIONAL, 1 component, no default */ + case EXIF_TAG_EXPOSURE_BIAS_VALUE: + case EXIF_TAG_BRIGHTNESS_VALUE: + case EXIF_TAG_SHUTTER_SPEED_VALUE: + e->components = 1; + e->format = EXIF_FORMAT_SRATIONAL; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + break; + + /* RATIONAL, 1 component, no default */ + case EXIF_TAG_EXPOSURE_TIME: + case EXIF_TAG_FOCAL_PLANE_X_RESOLUTION: + case EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION: + case EXIF_TAG_EXPOSURE_INDEX: + case EXIF_TAG_FLASH_ENERGY: + case EXIF_TAG_FNUMBER: + case EXIF_TAG_FOCAL_LENGTH: + case EXIF_TAG_SUBJECT_DISTANCE: + case EXIF_TAG_MAX_APERTURE_VALUE: + case EXIF_TAG_APERTURE_VALUE: + case EXIF_TAG_COMPRESSED_BITS_PER_PIXEL: + case EXIF_TAG_PRIMARY_CHROMATICITIES: + case EXIF_TAG_DIGITAL_ZOOM_RATIO: + e->components = 1; + e->format = EXIF_FORMAT_RATIONAL; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + break; + + /* RATIONAL, 1 component, default 72/1 */ + case EXIF_TAG_X_RESOLUTION: + case EXIF_TAG_Y_RESOLUTION: + e->components = 1; + e->format = EXIF_FORMAT_RATIONAL; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + r.numerator = 72; + r.denominator = 1; + exif_set_rational (e->data, o, r); + break; + + /* RATIONAL, 2 components, no default */ + case EXIF_TAG_WHITE_POINT: + e->components = 2; + e->format = EXIF_FORMAT_RATIONAL; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + break; + + /* RATIONAL, 6 components */ + case EXIF_TAG_REFERENCE_BLACK_WHITE: + e->components = 6; + e->format = EXIF_FORMAT_RATIONAL; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + r.denominator = 1; + r.numerator = 0; + exif_set_rational (e->data, o, r); + r.numerator = 255; + exif_set_rational ( + e->data + exif_format_get_size (e->format), o, r); + r.numerator = 0; + exif_set_rational ( + e->data + 2 * exif_format_get_size (e->format), o, r); + r.numerator = 255; + exif_set_rational ( + e->data + 3 * exif_format_get_size (e->format), o, r); + r.numerator = 0; + exif_set_rational ( + e->data + 4 * exif_format_get_size (e->format), o, r); + r.numerator = 255; + exif_set_rational ( + e->data + 5 * exif_format_get_size (e->format), o, r); + break; + + /* ASCII, 20 components */ + case EXIF_TAG_DATE_TIME: + case EXIF_TAG_DATE_TIME_ORIGINAL: + case EXIF_TAG_DATE_TIME_DIGITIZED: + { + time_t t; +#ifdef HAVE_LOCALTIME_R + struct tm tms; +#endif + struct tm *tm; + + t = time (NULL); +#ifdef HAVE_LOCALTIME_R + tm = localtime_r (&t, &tms); +#else + tm = localtime (&t); +#endif + e->components = 20; + e->format = EXIF_FORMAT_ASCII; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + snprintf ((char *) e->data, e->size, + "%04i:%02i:%02i %02i:%02i:%02i", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + break; + } + + /* ASCII, no default */ + case EXIF_TAG_SUB_SEC_TIME: + case EXIF_TAG_SUB_SEC_TIME_ORIGINAL: + case EXIF_TAG_SUB_SEC_TIME_DIGITIZED: + e->components = 0; + e->format = EXIF_FORMAT_ASCII; + e->size = 0; + e->data = NULL; + break; + + /* ASCII, default "[None]" */ + case EXIF_TAG_IMAGE_DESCRIPTION: + case EXIF_TAG_MAKE: + case EXIF_TAG_MODEL: + case EXIF_TAG_SOFTWARE: + case EXIF_TAG_ARTIST: + e->components = strlen (_("[None]")) + 1; + e->format = EXIF_FORMAT_ASCII; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + strncpy ((char *)e->data, _("[None]"), e->size); + break; + /* ASCII, default "[None]\0[None]\0" */ + case EXIF_TAG_COPYRIGHT: + e->components = (strlen (_("[None]")) + 1) * 2; + e->format = EXIF_FORMAT_ASCII; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + strcpy (((char *)e->data) + 0, _("[None]")); + strcpy (((char *)e->data) + strlen (_("[None]")) + 1, _("[None]")); + break; + + /* UNDEFINED, 1 component, default 1 */ + case EXIF_TAG_SCENE_TYPE: + e->components = 1; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + e->data[0] = 0x01; + break; + + /* UNDEFINED, 1 component, default 3 */ + case EXIF_TAG_FILE_SOURCE: + e->components = 1; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + e->data[0] = 0x03; + break; + + /* UNDEFINED, 4 components, default 48 49 48 48 */ + case EXIF_TAG_FLASH_PIX_VERSION: + e->components = 4; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + memcpy (e->data, "0100", 4); + break; + + /* UNDEFINED, 4 components, default 48 50 49 48 */ + case EXIF_TAG_EXIF_VERSION: + e->components = 4; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + memcpy (e->data, "0210", 4); + break; + + /* UNDEFINED, 4 components, default 1 2 3 0 */ + case EXIF_TAG_COMPONENTS_CONFIGURATION: + e->components = 4; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = exif_format_get_size (e->format) * e->components; + e->data = exif_entry_alloc (e, e->size); + if (!e->data) break; + e->data[0] = 1; + e->data[1] = 2; + e->data[2] = 3; + e->data[3] = 0; + break; + + /* UNDEFINED, no components, no default */ + /* Use this if the tag is otherwise unsupported */ + case EXIF_TAG_MAKER_NOTE: + case EXIF_TAG_USER_COMMENT: + default: + e->components = 0; + e->format = EXIF_FORMAT_UNDEFINED; + e->size = 0; + e->data = NULL; + break; + } +} diff --git a/libexifa/exif-format.c b/libexifa/exif-format.c new file mode 100755 index 0000000..2c63c33 --- /dev/null +++ b/libexifa/exif-format.c @@ -0,0 +1,81 @@ +/* exif-format.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include + +/*! Table of data format types, descriptions and sizes. + * This table should be sorted in decreasing order of popularity in order + * to decrease the total average lookup time. + */ +static const struct { + ExifFormat format; + const char *name; + unsigned char size; +} ExifFormatTable[] = { + {EXIF_FORMAT_SHORT, N_("Short"), 2}, + {EXIF_FORMAT_RATIONAL, N_("Rational"), 8}, + {EXIF_FORMAT_SRATIONAL, N_("SRational"), 8}, + {EXIF_FORMAT_UNDEFINED, N_("Undefined"), 1}, + {EXIF_FORMAT_ASCII, N_("ASCII"), 1}, + {EXIF_FORMAT_LONG, N_("Long"), 4}, + {EXIF_FORMAT_BYTE, N_("Byte"), 1}, + {EXIF_FORMAT_SBYTE, N_("SByte"), 1}, + {EXIF_FORMAT_SSHORT, N_("SShort"), 2}, + {EXIF_FORMAT_SLONG, N_("SLong"), 4}, + {EXIF_FORMAT_FLOAT, N_("Float"), 4}, + {EXIF_FORMAT_DOUBLE, N_("Double"), 8}, + {0, NULL, 0} +}; + +const char * +exif_format_get_name (ExifFormat format) +{ + unsigned int i; + + /* FIXME: This belongs to somewhere else. */ + /* libexif should use the default system locale. + * If an application specifically requires UTF-8, then we + * must give the application a way to tell libexif that. + * + * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + */ + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + + for (i = 0; ExifFormatTable[i].name; i++) + if (ExifFormatTable[i].format == format) + return _(ExifFormatTable[i].name); + return NULL; +} + +unsigned char +exif_format_get_size (ExifFormat format) +{ + unsigned int i; + + for (i = 0; ExifFormatTable[i].size; i++) + if (ExifFormatTable[i].format == format) + return ExifFormatTable[i].size; + return 0; +} diff --git a/libexifa/exif-ifd.c b/libexifa/exif-ifd.c new file mode 100755 index 0000000..f0f8816 --- /dev/null +++ b/libexifa/exif-ifd.c @@ -0,0 +1,49 @@ +/* exif-ifd.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include + +#include + +static const struct { + ExifIfd ifd; + const char *name; +} ExifIfdTable[] = { + {EXIF_IFD_0, "0"}, + {EXIF_IFD_1, "1"}, + {EXIF_IFD_EXIF, "EXIF"}, + {EXIF_IFD_GPS, "GPS"}, + {EXIF_IFD_INTEROPERABILITY, "Interoperability"}, + {0, NULL} +}; + +const char * +exif_ifd_get_name (ExifIfd ifd) +{ + unsigned int i; + + for (i = 0; ExifIfdTable[i].name; i++) + if (ExifIfdTable[i].ifd == ifd) + break; + + return (ExifIfdTable[i].name); +} diff --git a/libexifa/exif-loader.c b/libexifa/exif-loader.c new file mode 100755 index 0000000..317b86b --- /dev/null +++ b/libexifa/exif-loader.c @@ -0,0 +1,434 @@ +/* exif-loader.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#undef JPEG_MARKER_DHT +#define JPEG_MARKER_DHT 0xc4 +#undef JPEG_MARKER_SOI +#define JPEG_MARKER_SOI 0xd8 +#undef JPEG_MARKER_DQT +#define JPEG_MARKER_DQT 0xdb +#undef JPEG_MARKER_APP0 +#define JPEG_MARKER_APP0 0xe0 +#undef JPEG_MARKER_APP1 +#define JPEG_MARKER_APP1 0xe1 +#undef JPEG_MARKER_APP2 +#define JPEG_MARKER_APP2 0xe2 +#undef JPEG_MARKER_APP13 +#define JPEG_MARKER_APP13 0xed +#undef JPEG_MARKER_COM +#define JPEG_MARKER_COM 0xfe + +typedef enum { + EL_READ = 0, + EL_READ_SIZE_BYTE_24, + EL_READ_SIZE_BYTE_16, + EL_READ_SIZE_BYTE_08, + EL_READ_SIZE_BYTE_00, + EL_SKIP_BYTES, + EL_EXIF_FOUND, +} ExifLoaderState; + +typedef enum { + EL_DATA_FORMAT_UNKNOWN, + EL_DATA_FORMAT_EXIF, + EL_DATA_FORMAT_JPEG, + EL_DATA_FORMAT_FUJI_RAW +} ExifLoaderDataFormat; + +/*! \internal */ +struct _ExifLoader { + ExifLoaderState state; + ExifLoaderDataFormat data_format; + + /*! Small buffer used for detection of format */ + unsigned char b[12]; + + /*! Number of bytes in the small buffer \c b */ + unsigned char b_len; + + unsigned int size; + unsigned char *buf; + unsigned int bytes_read; + + unsigned int ref_count; + + ExifLog *log; + ExifMem *mem; +}; + +/*! Magic number for EXIF header */ +static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; + +static void * +exif_loader_alloc (ExifLoader *l, unsigned int i) +{ + void *d; + + if (!l || !i) + return NULL; + + d = exif_mem_alloc (l->mem, i); + if (d) + return d; + + EXIF_LOG_NO_MEMORY (l->log, "ExifLog", i); + return NULL; +} + +void +exif_loader_write_file (ExifLoader *l, const char *path) +{ + FILE *f; + int size; + unsigned char data[1024]; + + if (!l) + return; + + f = fopen (path, "rb"); + if (!f) { + exif_log (l->log, EXIF_LOG_CODE_NONE, "ExifLoader", + _("The file '%s' could not be opened."), path); + return; + } + while (1) { + size = fread (data, 1, sizeof (data), f); + if (size <= 0) + break; + if (!exif_loader_write (l, data, size)) + break; + } + fclose (f); +} + +static unsigned int +exif_loader_copy (ExifLoader *eld, unsigned char *buf, unsigned int len) +{ + if (!eld || (len && !buf) || (eld->bytes_read >= eld->size)) + return 0; + + /* If needed, allocate the buffer. */ + if (!eld->buf) + eld->buf = exif_loader_alloc (eld, eld->size); + if (!eld->buf) + return 0; + + /* Copy memory */ + len = MIN (len, eld->size - eld->bytes_read); + memcpy (eld->buf + eld->bytes_read, buf, len); + eld->bytes_read += len; + + return (eld->bytes_read >= eld->size) ? 0 : 1; +} + +unsigned char +exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) +{ + unsigned int i; + + if (!eld || (len && !buf)) + return 0; + + switch (eld->state) { + case EL_EXIF_FOUND: + return exif_loader_copy (eld, buf, len); + case EL_SKIP_BYTES: + if (eld->size > len) { + eld->size -= len; + return 1; + } + len -= eld->size; + buf += eld->size; + eld->size = 0; + eld->b_len = 0; + switch (eld->data_format) { + case EL_DATA_FORMAT_FUJI_RAW: + eld->state = EL_READ_SIZE_BYTE_24; + break; + default: + eld->state = EL_READ; + break; + } + break; + + case EL_READ: + default: + break; + } + + if (!len) + return 1; + exif_log (eld->log, EXIF_LOG_CODE_DEBUG, "ExifLoader", + "Scanning %i byte(s) of data...", len); + + /* + * First fill the small buffer. Only continue if the buffer + * is filled. Note that EXIF data contains at least 12 bytes. + */ + i = MIN (len, sizeof (eld->b) - eld->b_len); + if (i) { + memcpy (&eld->b[eld->b_len], buf, i); + eld->b_len += i; + if (eld->b_len < sizeof (eld->b)) + return 1; + buf += i; + len -= i; + } + + switch (eld->data_format) { + case EL_DATA_FORMAT_UNKNOWN: + + /* Check the small buffer against known formats. */ + if (!memcmp (eld->b, "FUJIFILM", 8)) { + + /* Skip to byte 84. There is another offset there. */ + eld->data_format = EL_DATA_FORMAT_FUJI_RAW; + eld->size = 84; + eld->state = EL_SKIP_BYTES; + eld->size = 84; + + } else if (!memcmp (eld->b + 2, ExifHeader, sizeof (ExifHeader))) { + + /* Read the size (2 bytes). */ + eld->data_format = EL_DATA_FORMAT_EXIF; + eld->state = EL_READ_SIZE_BYTE_08; + } + default: + break; + } + + for (i = 0; i < sizeof (eld->b); i++) + switch (eld->state) { + case EL_EXIF_FOUND: + if (!exif_loader_copy (eld, eld->b + i, + sizeof (eld->b) - i)) + return 0; + return exif_loader_copy (eld, buf, len); + case EL_SKIP_BYTES: + eld->size--; + if (!eld->size) + eld->state = EL_READ; + break; + + case EL_READ_SIZE_BYTE_24: + eld->size |= eld->b[i] << 24; + eld->state = EL_READ_SIZE_BYTE_16; + break; + case EL_READ_SIZE_BYTE_16: + eld->size |= eld->b[i] << 16; + eld->state = EL_READ_SIZE_BYTE_08; + break; + case EL_READ_SIZE_BYTE_08: + eld->size |= eld->b[i] << 8; + eld->state = EL_READ_SIZE_BYTE_00; + break; + case EL_READ_SIZE_BYTE_00: + eld->size |= eld->b[i] << 0; + switch (eld->data_format) { + case EL_DATA_FORMAT_JPEG: + eld->state = EL_SKIP_BYTES; + eld->size -= 2; + break; + case EL_DATA_FORMAT_FUJI_RAW: + eld->data_format = EL_DATA_FORMAT_EXIF; + eld->state = EL_SKIP_BYTES; + eld->size -= 86; + break; + case EL_DATA_FORMAT_EXIF: + eld->state = EL_EXIF_FOUND; + break; + default: + break; + } + break; + + default: + switch (eld->b[i]) { + case JPEG_MARKER_APP1: + if (!memcmp (eld->b + i + 3, ExifHeader, MIN((ssize_t)(sizeof(ExifHeader)), MAX(0, ((ssize_t)(sizeof(eld->b))) - ((ssize_t)i) - 3)))) { + eld->data_format = EL_DATA_FORMAT_EXIF; + } else { + eld->data_format = EL_DATA_FORMAT_JPEG; /* Probably JFIF - keep searching for APP1 EXIF*/ + } + eld->size = 0; + eld->state = EL_READ_SIZE_BYTE_08; + break; + case JPEG_MARKER_DHT: + case JPEG_MARKER_DQT: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP2: + case JPEG_MARKER_APP13: + case JPEG_MARKER_COM: + eld->data_format = EL_DATA_FORMAT_JPEG; + eld->size = 0; + eld->state = EL_READ_SIZE_BYTE_08; + break; + case 0xff: + case JPEG_MARKER_SOI: + break; + default: + exif_log (eld->log, + EXIF_LOG_CODE_CORRUPT_DATA, + "ExifLoader", _("The data supplied " + "does not seem to contain " + "EXIF data.")); + exif_loader_reset (eld); + return 0; + } + } + + /* + * If we reach this point, the buffer has not been big enough + * to read all data we need. Fill it with new data. + */ + eld->b_len = 0; + return exif_loader_write (eld, buf, len); +} + +ExifLoader * +exif_loader_new (void) +{ + ExifMem *mem = exif_mem_new_default (); + ExifLoader *l = exif_loader_new_mem (mem); + + exif_mem_unref (mem); + + return l; +} + +ExifLoader * +exif_loader_new_mem (ExifMem *mem) +{ + ExifLoader *loader; + + if (!mem) + return NULL; + + loader = exif_mem_alloc (mem, sizeof (ExifLoader)); + if (!loader) + return NULL; + loader->ref_count = 1; + + loader->mem = mem; + exif_mem_ref (mem); + + return loader; +} + +void +exif_loader_ref (ExifLoader *loader) +{ + if (loader) + loader->ref_count++; +} + +static void +exif_loader_free (ExifLoader *loader) +{ + ExifMem *mem; + + if (!loader) + return; + + mem = loader->mem; + exif_loader_reset (loader); + exif_log_unref (loader->log); + exif_mem_free (mem, loader); + exif_mem_unref (mem); +} + +void +exif_loader_unref (ExifLoader *loader) +{ + if (!loader) + return; + if (!--loader->ref_count) + exif_loader_free (loader); +} + +void +exif_loader_reset (ExifLoader *loader) +{ + if (!loader) + return; + exif_mem_free (loader->mem, loader->buf); loader->buf = NULL; + loader->size = 0; + loader->bytes_read = 0; + loader->state = 0; + loader->b_len = 0; + loader->data_format = EL_DATA_FORMAT_UNKNOWN; +} + +ExifData * +exif_loader_get_data (ExifLoader *loader) +{ + ExifData *ed; + + if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN) || + !loader->bytes_read) + return NULL; + + ed = exif_data_new_mem (loader->mem); + exif_data_log (ed, loader->log); + exif_data_load_data (ed, loader->buf, loader->bytes_read); + + return ed; +} + +void +exif_loader_get_buf (ExifLoader *loader, const unsigned char **buf, + unsigned int *buf_size) +{ + const unsigned char* b = NULL; + unsigned int s = 0; + + if (!loader || (loader->data_format == EL_DATA_FORMAT_UNKNOWN)) { + exif_log (loader->log, EXIF_LOG_CODE_DEBUG, "ExifLoader", + "Loader format unknown"); + } else { + b = loader->buf; + s = loader->bytes_read; + } + if (buf) + *buf = b; + if (buf_size) + *buf_size = s; +} + +void +exif_loader_log (ExifLoader *loader, ExifLog *log) +{ + if (!loader) + return; + exif_log_unref (loader->log); + loader->log = log; + exif_log_ref (log); +} diff --git a/libexifa/exif-log.c b/libexifa/exif-log.c new file mode 100755 index 0000000..2db18e3 --- /dev/null +++ b/libexifa/exif-log.c @@ -0,0 +1,152 @@ +/* exif-log.c + * + * Copyright (c) 2004 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include +#include + +struct _ExifLog { + unsigned int ref_count; + + ExifLogFunc func; + void *data; + + ExifMem *mem; +}; + +static const struct { + ExifLogCode code; + const char *title; + const char *message; +} codes[] = { + { EXIF_LOG_CODE_DEBUG, N_("Debugging information"), + N_("Debugging information is available.") }, + { EXIF_LOG_CODE_NO_MEMORY, N_("Not enough memory"), + N_("The system cannot provide enough memory.") }, + { EXIF_LOG_CODE_CORRUPT_DATA, N_("Corrupt data"), + N_("The data provided does not follow the specification.") }, + { 0, NULL, NULL } +}; + +const char * +exif_log_code_get_title (ExifLogCode code) +{ + unsigned int i; + + for (i = 0; codes[i].title; i++) if (codes[i].code == code) break; + return _(codes[i].title); +} + +const char * +exif_log_code_get_message (ExifLogCode code) +{ + unsigned int i; + + for (i = 0; codes[i].message; i++) if (codes[i].code == code) break; + return _(codes[i].message); +} + +ExifLog * +exif_log_new_mem (ExifMem *mem) +{ + ExifLog *log; + + log = exif_mem_alloc (mem, sizeof (ExifLog)); + if (!log) return NULL; + log->ref_count = 1; + + log->mem = mem; + exif_mem_ref (mem); + + return log; +} + +ExifLog * +exif_log_new (void) +{ + ExifMem *mem = exif_mem_new_default (); + ExifLog *log = exif_log_new_mem (mem); + + exif_mem_unref (mem); + + return log; +} + +void +exif_log_ref (ExifLog *log) +{ + if (!log) return; + log->ref_count++; +} + +void +exif_log_unref (ExifLog *log) +{ + if (!log) return; + if (log->ref_count > 0) log->ref_count--; + if (!log->ref_count) exif_log_free (log); +} + +void +exif_log_free (ExifLog *log) +{ + ExifMem *mem = log ? log->mem : NULL; + + if (!log) return; + + exif_mem_free (mem, log); + exif_mem_unref (mem); +} + +void +exif_log_set_func (ExifLog *log, ExifLogFunc func, void *data) +{ + if (!log) return; + log->func = func; + log->data = data; +} + +#ifdef NO_VERBOSE_TAG_STRINGS +/* exif_log forms part of the API and can't be commented away */ +#undef exif_log +#endif +void +exif_log (ExifLog *log, ExifLogCode code, const char *domain, + const char *format, ...) +{ + va_list args; + + va_start (args, format); + exif_logv (log, code, domain, format, args); + va_end (args); +} + +void +exif_logv (ExifLog *log, ExifLogCode code, const char *domain, + const char *format, va_list args) +{ + if (!log) return; + if (!log->func) return; + log->func (log, code, domain, format, args, log->data); +} diff --git a/libexifa/exif-mem.c b/libexifa/exif-mem.c new file mode 100755 index 0000000..b4d7ece --- /dev/null +++ b/libexifa/exif-mem.c @@ -0,0 +1,99 @@ +#include + +#include + +struct _ExifMem { + unsigned int ref_count; + ExifMemAllocFunc alloc_func; + ExifMemReallocFunc realloc_func; + ExifMemFreeFunc free_func; +}; + +/*! Default memory allocation function. */ +static void * +exif_mem_alloc_func (ExifLong ds) +{ + return calloc ((size_t) ds, 1); +} + +/*! Default memory reallocation function. */ +static void * +exif_mem_realloc_func (void *d, ExifLong ds) +{ + return realloc (d, (size_t) ds); +} + +/*! Default memory free function. */ +static void +exif_mem_free_func (void *d) +{ + free (d); +} + +ExifMem * +exif_mem_new (ExifMemAllocFunc alloc_func, ExifMemReallocFunc realloc_func, + ExifMemFreeFunc free_func) +{ + ExifMem *mem; + + if (!alloc_func && !realloc_func) + return NULL; + mem = alloc_func ? alloc_func (sizeof (ExifMem)) : + realloc_func (NULL, sizeof (ExifMem)); + if (!mem) return NULL; + mem->ref_count = 1; + + mem->alloc_func = alloc_func; + mem->realloc_func = realloc_func; + mem->free_func = free_func; + + return mem; +} + +void +exif_mem_ref (ExifMem *mem) +{ + if (!mem) return; + mem->ref_count++; +} + +void +exif_mem_unref (ExifMem *mem) +{ + if (!mem) return; + if (!--mem->ref_count) + exif_mem_free (mem, mem); +} + +void +exif_mem_free (ExifMem *mem, void *d) +{ + if (!mem) return; + if (mem->free_func) { + mem->free_func (d); + return; + } +} + +void * +exif_mem_alloc (ExifMem *mem, ExifLong ds) +{ + if (!mem) return NULL; + if (mem->alloc_func || mem->realloc_func) + return mem->alloc_func ? mem->alloc_func (ds) : + mem->realloc_func (NULL, ds); + return NULL; +} + +void * +exif_mem_realloc (ExifMem *mem, void *d, ExifLong ds) +{ + return (mem && mem->realloc_func) ? mem->realloc_func (d, ds) : NULL; +} + +ExifMem * +exif_mem_new_default (void) +{ + return exif_mem_new (exif_mem_alloc_func, exif_mem_realloc_func, + exif_mem_free_func); +} diff --git a/libexifa/exif-mnote-data.c b/libexifa/exif-mnote-data.c new file mode 100755 index 0000000..248056e --- /dev/null +++ b/libexifa/exif-mnote-data.c @@ -0,0 +1,158 @@ +/* exif-mnote-data.c + * + * Copyright (C) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include +#include + +struct _ExifMnoteDataPriv +{ + unsigned int ref_count; +}; + +void +exif_mnote_data_construct (ExifMnoteData *d, ExifMem *mem) +{ + if (!d || !mem) return; + if (d->priv) return; + d->priv = exif_mem_alloc (mem, sizeof (ExifMnoteDataPriv)); + if (!d->priv) return; + + d->priv->ref_count = 1; + + d->mem = mem; + exif_mem_ref (mem); +} + +void +exif_mnote_data_ref (ExifMnoteData *d) +{ + if (d && d->priv) d->priv->ref_count++; +} + +static void +exif_mnote_data_free (ExifMnoteData *d) +{ + ExifMem *mem = d ? d->mem : NULL; + + if (!d) return; + if (d->priv) { + if (d->methods.free) d->methods.free (d); + exif_mem_free (mem, d->priv); + d->priv = NULL; + } + exif_log_unref (d->log); + exif_mem_free (mem, d); + exif_mem_unref (mem); +} + +void +exif_mnote_data_unref (ExifMnoteData *d) +{ + if (!d || !d->priv) return; + if (d->priv->ref_count > 0) d->priv->ref_count--; + if (!d->priv->ref_count) + exif_mnote_data_free (d); +} + +void +exif_mnote_data_load (ExifMnoteData *d, const unsigned char *buf, + unsigned int buf_size) +{ + if (!d || !d->methods.load) return; + d->methods.load (d, buf, buf_size); +} + +void +exif_mnote_data_save (ExifMnoteData *d, unsigned char **buf, + unsigned int *buf_size) +{ + if (!d || !d->methods.save) return; + d->methods.save (d, buf, buf_size); +} + +void +exif_mnote_data_set_byte_order (ExifMnoteData *d, ExifByteOrder o) +{ + if (!d || !d->methods.set_byte_order) return; + d->methods.set_byte_order (d, o); +} + +void +exif_mnote_data_set_offset (ExifMnoteData *d, unsigned int o) +{ + if (!d || !d->methods.set_offset) return; + d->methods.set_offset (d, o); +} + +unsigned int +exif_mnote_data_count (ExifMnoteData *d) +{ + if (!d || !d->methods.count) return 0; + return d->methods.count (d); +} + +unsigned int +exif_mnote_data_get_id (ExifMnoteData *d, unsigned int n) +{ + if (!d || !d->methods.get_id) return 0; + return d->methods.get_id (d, n); +} + +const char * +exif_mnote_data_get_name (ExifMnoteData *d, unsigned int n) +{ + if (!d || !d->methods.get_name) return NULL; + return d->methods.get_name (d, n); +} + +const char * +exif_mnote_data_get_title (ExifMnoteData *d, unsigned int n) +{ + if (!d || !d->methods.get_title) return NULL; + return d->methods.get_title (d, n); +} + +const char * +exif_mnote_data_get_description (ExifMnoteData *d, unsigned int n) +{ + if (!d || !d->methods.get_description) return NULL; + return d->methods.get_description (d, n); +} + +char * +exif_mnote_data_get_value (ExifMnoteData *d, unsigned int n, char *val, unsigned int maxlen) +{ + if (!d || !d->methods.get_value) return NULL; + return d->methods.get_value (d, n, val, maxlen); +} + +void +exif_mnote_data_log (ExifMnoteData *d, ExifLog *log) +{ + if (!d) return; + exif_log_unref (d->log); + d->log = log; + exif_log_ref (log); +} diff --git a/libexifa/exif-tag.c b/libexifa/exif-tag.c new file mode 100755 index 0000000..9e38849 --- /dev/null +++ b/libexifa/exif-tag.c @@ -0,0 +1,1180 @@ +/* exif-tag.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include +#include + +#define ESL_NNNN { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED } +#define ESL_OOOO { EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_OPTIONAL } +#define ESL_MMMN { EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_NOT_RECORDED } +#define ESL_MMMM { EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY } +#define ESL_OMON { EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_NOT_RECORDED } +#define ESL_NNOO { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_OPTIONAL, EXIF_SUPPORT_LEVEL_OPTIONAL } +#define ESL_NNMN { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_NOT_RECORDED } +#define ESL_NNMM { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_MANDATORY, EXIF_SUPPORT_LEVEL_MANDATORY } +#define ESL_NNNM { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_MANDATORY } +#define ESL_NNNO { EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_NOT_RECORDED, EXIF_SUPPORT_LEVEL_OPTIONAL } +#define ESL_GPS { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN } + +/*! + * Table giving information about each EXIF tag. + * There may be more than one entry with the same tag value because some tags + * have different meanings depending on the IFD in which they appear. + * When there are such duplicate entries, there must be no overlap in their + * support levels. + * The entries MUST be sorted in tag order. + * The name and title are mandatory, but the description may be an empty + * string. None of the entries may be NULL except the final array terminator. + */ +static const struct TagEntry { + /*! Tag ID. There may be duplicate tags when the same number is used for + * different meanings in different IFDs. */ + ExifTag tag; + const char *name; + const char *title; + const char *description; + /*! indexed by the types [ExifIfd][ExifDataType] */ + ExifSupportLevel esl[EXIF_IFD_COUNT][EXIF_DATA_TYPE_COUNT]; +} ExifTagTable[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", N_("GPS Tag Version"), + N_("Indicates the version of . The version is given " + "as 2.0.0.0. This tag is mandatory when tag is " + "present. (Note: The tag is given in bytes, " + "unlike the tag. When the version is " + "2.0.0.0, the tag value is 02000000.H)."), ESL_GPS}, + {EXIF_TAG_INTEROPERABILITY_INDEX, "InteroperabilityIndex", + N_("Interoperability Index"), + N_("Indicates the identification of the Interoperability rule. " + "Use \"R98\" for stating ExifR98 Rules. Four bytes used " + "including the termination code (NULL). see the separate " + "volume of Recommended Exif Interoperability Rules (ExifR98) " + "for other tags used for ExifR98."), + { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO } }, + {EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef", N_("North or South Latitude"), + N_("Indicates whether the latitude is north or south latitude. The " + "ASCII value 'N' indicates north latitude, and 'S' is south " + "latitude."), ESL_GPS}, + {EXIF_TAG_INTEROPERABILITY_VERSION, "InteroperabilityVersion", + N_("Interoperability Version"), "", + { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_OOOO } }, + {EXIF_TAG_GPS_LATITUDE, "GPSLatitude", N_("Latitude"), + N_("Indicates the latitude. The latitude is expressed as three " + "RATIONAL values giving the degrees, minutes, and seconds, " + "respectively. When degrees, minutes and seconds are expressed, " + "the format is dd/1,mm/1,ss/1. When degrees and minutes are used " + "and, for example, fractions of minutes are given up to two " + "decimal places, the format is dd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", N_("East or West Longitude"), + N_("Indicates whether the longitude is east or west longitude. " + "ASCII 'E' indicates east longitude, and 'W' is west " + "longitude."), ESL_GPS}, + {EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", N_("Longitude"), + N_("Indicates the longitude. The longitude is expressed as three " + "RATIONAL values giving the degrees, minutes, and seconds, " + "respectively. When degrees, minutes and seconds are expressed, " + "the format is ddd/1,mm/1,ss/1. When degrees and minutes are " + "used and, for example, fractions of minutes are given up to " + "two decimal places, the format is ddd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", N_("Altitude Reference"), + N_("Indicates the altitude used as the reference altitude. If the " + "reference is sea level and the altitude is above sea level, 0 " + "is given. If the altitude is below sea level, a value of 1 is given " + "and the altitude is indicated as an absolute value in the " + "GSPAltitude tag. The reference unit is meters. Note that this tag " + "is BYTE type, unlike other reference tags."), ESL_GPS}, + {EXIF_TAG_GPS_ALTITUDE, "GPSAltitude", N_("Altitude"), + N_("Indicates the altitude based on the reference in GPSAltitudeRef. " + "Altitude is expressed as one RATIONAL value. The reference unit " + "is meters."), ESL_GPS}, + {EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", N_("GPS Time (Atomic Clock)"), + N_("Indicates the time as UTC (Coordinated Universal Time). " + "TimeStamp is expressed as three RATIONAL values giving " + "the hour, minute, and second."), ESL_GPS}, + {EXIF_TAG_GPS_SATELLITES, "GPSSatellites", N_("GPS Satellites"), + N_("Indicates the GPS satellites used for measurements. This " + "tag can be used to describe the number of satellites, their ID " + "number, angle of elevation, azimuth, SNR and other information " + "in ASCII notation. The format is not specified. If the GPS " + "receiver is incapable of taking measurements, value of the tag " + "shall be set to NULL."), ESL_GPS}, + {EXIF_TAG_GPS_STATUS, "GPSStatus", N_("GPS Receiver Status"), + N_("Indicates the status of the GPS receiver when the image is " + "recorded. 'A' means measurement is in progress, and 'V' means " + "the measurement is Interoperability."), ESL_GPS}, + {EXIF_TAG_GPS_MEASURE_MODE, "GPSMeasureMode", N_("GPS Measurement Mode"), + N_("Indicates the GPS measurement mode. '2' means " + "two-dimensional measurement and '3' means three-dimensional " + "measurement is in progress."), ESL_GPS}, + {EXIF_TAG_GPS_DOP, "GPSDOP", N_("Measurement Precision"), + N_("Indicates the GPS DOP (data degree of precision). An HDOP " + "value is written during two-dimensional measurement, and PDOP " + "during three-dimensional measurement."), ESL_GPS}, + {EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", N_("Speed Unit"), + N_("Indicates the unit used to express the GPS receiver speed " + "of movement. 'K', 'M' and 'N' represent kilometers per hour, " + "miles per hour, and knots."), ESL_GPS}, + {EXIF_TAG_GPS_SPEED, "GPSSpeed", N_("Speed of GPS Receiver"), + N_("Indicates the speed of GPS receiver movement."), ESL_GPS}, + {EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", N_("Reference for direction of movement"), + N_("Indicates the reference for giving the direction of GPS " + "receiver movement. 'T' denotes true direction and 'M' is " + "magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_TRACK, "GPSTrack", N_("Direction of Movement"), + N_("Indicates the direction of GPS receiver movement. The range " + "of values is from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", N_("GPS Image Direction Reference"), + N_("Indicates the reference for giving the direction of the image when it is captured. " + "'T' denotes true direction and 'M' is magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", N_("GPS Image Direction"), + N_("Indicates the direction of the image when it was captured. The range of values is " + "from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", N_("Geodetic Survey Data Used"), + N_("Indicates the geodetic survey data used by the GPS " + "receiver. If the survey data is restricted to Japan, the value " + "of this tag is 'TOKYO' or 'WGS-84'. If a GPS Info tag is " + "recorded, it is strongly recommended that this tag be recorded."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", N_("Reference For Latitude of Destination"), + N_("Indicates whether the latitude of the destination point is " + "north or south latitude. The ASCII value 'N' indicates north " + "latitude, and 'S' is south latitude."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", N_("Latitude of Destination"), + N_("Indicates the latitude of the destination point. The " + "latitude is expressed as three RATIONAL values giving the " + "degrees, minutes, and seconds, respectively. If latitude is " + "expressed as degrees, minutes and seconds, a typical format " + "would be dd/1,mm/1,ss/1. When degrees and minutes are used and, " + "for example, fractions of minutes are given up to two decimal " + "places, the format would be dd/1,mmmm/100,0/1."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", N_("Reference for Longitude of Destination"), + N_("Indicates whether the longitude of the destination point is " + "east or west longitude. ASCII 'E' indicates east longitude, and " + "'W' is west longitude."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", N_("Longitude of Destination"), + N_("Indicates the longitude of the destination point. The " + "longitude is expressed as three RATIONAL values giving the " + "degrees, minutes, and seconds, respectively. If longitude is " + "expressed as degrees, minutes and seconds, a typical format " + "would be ddd/1,mm/1,ss/1. When degrees and minutes are used " + "and, for example, fractions of minutes are given up to two " + "decimal places, the format would be ddd/1,mmmm/100,0/1."), + ESL_GPS}, + {EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", N_("Reference for Bearing of Destination"), + N_("Indicates the reference used for giving the bearing to " + "the destination point. 'T' denotes true direction and 'M' is " + "magnetic direction."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", N_("Bearing of Destination"), + N_("Indicates the bearing to the destination point. The range " + "of values is from 0.00 to 359.99."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", N_("Reference for Distance to Destination"), + N_("Indicates the unit used to express the distance to the " + "destination point. 'K', 'M' and 'N' represent kilometers, miles " + "and knots."), ESL_GPS}, + {EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", N_("Distance to Destination"), + N_("Indicates the distance to the destination point."), ESL_GPS}, + {EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", N_("Name of GPS Processing Method"), + N_("A character string recording the name of the method used " + "for location finding. The first byte indicates the character " + "code used, and this is followed by the name " + "of the method. Since the Type is not ASCII, NULL termination is " + "not necessary."), ESL_GPS}, + {EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", N_("Name of GPS Area"), + N_("A character string recording the name of the GPS area. The " + "first byte indicates the character code used, " + "and this is followed by the name of the GPS area. Since " + "the Type is not ASCII, NULL termination is not necessary."), ESL_GPS}, + {EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", N_("GPS Date"), + N_("A character string recording date and time information " + "relative to UTC (Coordinated Universal Time). The format is " + "\"YYYY:MM:DD\". The length of the string is 11 bytes including " + "NULL."), ESL_GPS}, + {EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", N_("GPS Differential Correction"), + N_("Indicates whether differential correction is applied to the " + "GPS receiver."), ESL_GPS}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_NEW_SUBFILE_TYPE, "NewSubfileType", + N_("New Subfile Type"), N_("A general indication of the kind of data " + "contained in this subfile.")}, + {EXIF_TAG_IMAGE_WIDTH, "ImageWidth", N_("Image Width"), + N_("The number of columns of image data, equal to the number of " + "pixels per row. In JPEG compressed data a JPEG marker is " + "used instead of this tag."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_IMAGE_LENGTH, "ImageLength", N_("Image Length"), + N_("The number of rows of image data. In JPEG compressed data a " + "JPEG marker is used instead of this tag."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_BITS_PER_SAMPLE, "BitsPerSample", N_("Bits per Sample"), + N_("The number of bits per image component. In this standard each " + "component of the image is 8 bits, so the value for this " + "tag is 8. See also . In JPEG compressed data " + "a JPEG marker is used instead of this tag."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_COMPRESSION, "Compression", N_("Compression"), + N_("The compression scheme used for the image data. When a " + "primary image is JPEG compressed, this designation is " + "not necessary and is omitted. When thumbnails use JPEG " + "compression, this tag value is set to 6."), + { ESL_MMMN, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation", + N_("Photometric Interpretation"), + N_("The pixel composition. In JPEG compressed data a JPEG " + "marker is used instead of this tag."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_FILL_ORDER, "FillOrder", N_("Fill Order"), ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_DOCUMENT_NAME, "DocumentName", N_("Document Name"), ""}, + {EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription", + N_("Image Description"), + N_("A character string giving the title of the image. It may be " + "a comment such as \"1988 company picnic\" or " + "the like. Two-bytes character codes cannot be used. " + "When a 2-bytes code is necessary, the Exif Private tag " + " is to be used."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_MAKE, "Make", N_("Manufacturer"), + N_("The manufacturer of the recording " + "equipment. This is the manufacturer of the DSC, scanner, " + "video digitizer or other equipment that generated the " + "image. When the field is left blank, it is treated as " + "unknown."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_MODEL, "Model", N_("Model"), + N_("The model name or model number of the equipment. This is the " + "model name or number of the DSC, scanner, video digitizer " + "or other equipment that generated the image. When the field " + "is left blank, it is treated as unknown."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_STRIP_OFFSETS, "StripOffsets", N_("Strip Offsets"), + N_("For each strip, the byte offset of that strip. It is " + "recommended that this be selected so the number of strip " + "bytes does not exceed 64 Kbytes. With JPEG compressed " + "data this designation is not needed and is omitted. See also " + " and ."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_ORIENTATION, "Orientation", N_("Orientation"), + N_("The image orientation viewed in terms of rows and columns."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SAMPLES_PER_PIXEL, "SamplesPerPixel", + N_("Samples per Pixel"), + N_("The number of components per pixel. Since this standard applies " + "to RGB and YCbCr images, the value set for this tag is 3. " + "In JPEG compressed data a JPEG marker is used instead of this " + "tag."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_ROWS_PER_STRIP, "RowsPerStrip", N_("Rows per Strip"), + N_("The number of rows per strip. This is the number of rows " + "in the image of one strip when an image is divided into " + "strips. With JPEG compressed data this designation is not " + "needed and is omitted. See also and " + "."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_STRIP_BYTE_COUNTS, "StripByteCounts", N_("Strip Byte Count"), + N_("The total number of bytes in each strip. With JPEG compressed " + "data this designation is not needed and is omitted."), + { ESL_MMMN, ESL_MMMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_X_RESOLUTION, "XResolution", N_("X-Resolution"), + N_("The number of pixels per in the " + "direction. When the image resolution is unknown, 72 [dpi] " + "is designated."), + { ESL_MMMM, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_Y_RESOLUTION, "YResolution", N_("Y-Resolution"), + N_("The number of pixels per in the " + "direction. The same value as is designated."), + { ESL_MMMM, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_PLANAR_CONFIGURATION, "PlanarConfiguration", + N_("Planar Configuration"), + N_("Indicates whether pixel components are recorded in a chunky " + "or planar format. In JPEG compressed files a JPEG marker " + "is used instead of this tag. If this field does not exist, " + "the TIFF default of 1 (chunky) is assumed."), + { ESL_OMON, ESL_OMON, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_RESOLUTION_UNIT, "ResolutionUnit", N_("Resolution Unit"), + N_("The unit for measuring and . The same " + "unit is used for both and . If " + "the image resolution is unknown, 2 (inches) is designated."), + { ESL_MMMM, ESL_MMMM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_TRANSFER_FUNCTION, "TransferFunction", + N_("Transfer Function"), + N_("A transfer function for the image, described in tabular style. " + "Normally this tag is not necessary, since color space is " + "specified in the color space information tag ()."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SOFTWARE, "Software", N_("Software"), + N_("This tag records the name and version of the software or " + "firmware of the camera or image input device used to " + "generate the image. The detailed format is not specified, but " + "it is recommended that the example shown below be " + "followed. When the field is left blank, it is treated as " + "unknown."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_DATE_TIME, "DateTime", N_("Date and Time"), + N_("The date and time of image creation. In this standard " + "(EXIF-2.1) it is the date and time the file was changed."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_ARTIST, "Artist", N_("Artist"), + N_("This tag records the name of the camera owner, photographer or " + "image creator. The detailed format is not specified, but it is " + "recommended that the information be written as in the example " + "below for ease of Interoperability. When the field is " + "left blank, it is treated as unknown."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_WHITE_POINT, "WhitePoint", N_("White Point"), + N_("The chromaticity of the white point of the image. Normally " + "this tag is not necessary, since color space is specified " + "in the color space information tag ()."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_PRIMARY_CHROMATICITIES, "PrimaryChromaticities", + N_("Primary Chromaticities"), + N_("The chromaticity of the three primary colors of the image. " + "Normally this tag is not necessary, since color space is " + "specified in the color space information tag ()."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_SUB_IFDS, "SubIFDs", "SubIFD Offsets", N_("Defined by Adobe Corporation " + "to enable TIFF Trees within a TIFF file.")}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_TRANSFER_RANGE, "TransferRange", N_("Transfer Range"), ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_JPEG_PROC, "JPEGProc", "JPEGProc", ""}, + {EXIF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEGInterchangeFormat", + N_("JPEG Interchange Format"), + N_("The offset to the start byte (SOI) of JPEG compressed " + "thumbnail data. This is not used for primary image " + "JPEG data."), + { ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, + "JPEGInterchangeFormatLength", N_("JPEG Interchange Format Length"), + N_("The number of bytes of JPEG compressed thumbnail data. This " + "is not used for primary image JPEG data. JPEG thumbnails " + "are not divided but are recorded as a continuous JPEG " + "bitstream from SOI to EOI. Appn and COM markers should " + "not be recorded. Compressed thumbnails must be recorded in no " + "more than 64 Kbytes, including all other data to be " + "recorded in APP1."), + { ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_YCBCR_COEFFICIENTS, "YCbCrCoefficients", + N_("YCbCr Coefficients"), + N_("The matrix coefficients for transformation from RGB to YCbCr " + "image data. No default is given in TIFF; but here the " + "value given in \"Color Space Guidelines\", is used " + "as the default. The color space is declared in a " + "color space information tag, with the default being the value " + "that gives the optimal image characteristics " + "Interoperability this condition."), + { ESL_NNOO, ESL_NNOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_YCBCR_SUB_SAMPLING, "YCbCrSubSampling", + N_("YCbCr Sub-Sampling"), + N_("The sampling ratio of chrominance components in relation to the " + "luminance component. In JPEG compressed data a JPEG marker " + "is used instead of this tag."), + { ESL_NNMN, ESL_NNMN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_YCBCR_POSITIONING, "YCbCrPositioning", + N_("YCbCr Positioning"), + N_("The position of chrominance components in relation to the " + "luminance component. This field is designated only for " + "JPEG compressed data or uncompressed YCbCr data. The TIFF " + "default is 1 (centered); but when Y:Cb:Cr = 4:2:2 it is " + "recommended in this standard that 2 (co-sited) be used to " + "record data, in order to improve the image quality when viewed " + "on TV systems. When this field does not exist, the reader shall " + "assume the TIFF default. In the case of Y:Cb:Cr = 4:2:0, the " + "TIFF default (centered) is recommended. If the reader " + "does not have the capability of supporting both kinds of " + ", it shall follow the TIFF default regardless " + "of the value in this field. It is preferable that readers " + "be able to support both centered and co-sited positioning."), + { ESL_NNMM, ESL_NNOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_REFERENCE_BLACK_WHITE, "ReferenceBlackWhite", + N_("Reference Black/White"), + N_("The reference black point value and reference white point " + "value. No defaults are given in TIFF, but the values " + "below are given as defaults here. The color space is declared " + "in a color space information tag, with the default " + "being the value that gives the optimal image characteristics " + "Interoperability these conditions."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_XML_PACKET, "XMLPacket", N_("XML Packet"), N_("XMP Metadata")}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_RELATED_IMAGE_FILE_FORMAT, "RelatedImageFileFormat", + "RelatedImageFileFormat", ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_RELATED_IMAGE_WIDTH, "RelatedImageWidth", + "RelatedImageWidth", ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_RELATED_IMAGE_LENGTH, "RelatedImageLength", + "RelatedImageLength", ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_CFA_REPEAT_PATTERN_DIM, "CFARepeatPatternDim", + "CFARepeatPatternDim", ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_CFA_PATTERN, "CFAPattern", + N_("CFA Pattern"), + N_("Indicates the color filter array (CFA) geometric pattern of the " + "image sensor when a one-chip color area sensor is used. " + "It does not apply to all sensing methods.")}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", N_("Battery Level"), ""}, + {EXIF_TAG_COPYRIGHT, "Copyright", N_("Copyright"), + N_("Copyright information. In this standard the tag is used to " + "indicate both the photographer and editor copyrights. It is " + "the copyright notice of the person or organization claiming " + "rights to the image. The Interoperability copyright " + "statement including date and rights should be written in this " + "field; e.g., \"Copyright, John Smith, 19xx. All rights " + "reserved.\". In this standard the field records both the " + "photographer and editor copyrights, with each recorded in a " + "separate part of the statement. When there is a clear " + "distinction between the photographer and editor copyrights, " + "these are to be written in the order of photographer followed " + "by editor copyright, separated by NULL (in this case, " + "since the statement also ends with a NULL, there are two NULL " + "codes) (see example 1). When only the photographer is given, " + "it is terminated by one NULL code (see example 2). When only " + "the editor copyright is given, " + "the photographer copyright part consists of one space followed " + "by a terminating NULL code, then the editor copyright is given " + "(see example 3). When the field is left blank, it is treated " + "as unknown."), + { ESL_OOOO, ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_EXPOSURE_TIME, "ExposureTime", N_("Exposure Time"), + N_("Exposure time, given in seconds (sec)."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FNUMBER, "FNumber", N_("F-Number"), + N_("The F number."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_IPTC_NAA, "IPTC/NAA", "IPTC/NAA", ""}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_IMAGE_RESOURCES, "ImageResources", N_("Image Resources Block"), ""}, + {EXIF_TAG_EXIF_IFD_POINTER, "ExifIfdPointer", "ExifIFDPointer", + N_("A pointer to the Exif IFD. Interoperability, Exif IFD has the " + "same structure as that of the IFD specified in TIFF. " + "ordinarily, however, it does not contain image data as in " + "the case of TIFF."), + { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile", + "InterColorProfile", ""}, + {EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", N_("Exposure Program"), + N_("The class of the program used by the camera to set exposure " + "when the picture is taken."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SPECTRAL_SENSITIVITY, "SpectralSensitivity", + N_("Spectral Sensitivity"), + N_("Indicates the spectral sensitivity of each channel of the " + "camera used. The tag value is an ASCII string compatible " + "with the standard developed by the ASTM Technical Committee."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer", + N_("GPS Info IFD Pointer"), + N_("A pointer to the GPS Info IFD. The " + "Interoperability structure of the GPS Info IFD, like that of " + "Exif IFD, has no image data."), + { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + + {EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings", + N_("ISO Speed Ratings"), + N_("Indicates the ISO Speed and ISO Latitude of the camera or " + "input device as specified in ISO 12232."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_OECF, "OECF", N_("Opto-Electronic Conversion Function"), + N_("Indicates the Opto-Electronic Conversion Function (OECF) " + "specified in ISO 14524. is the relationship between " + "the camera optical input and the image values."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_TIME_ZONE_OFFSET, "TimeZoneOffset", N_("Time Zone Offset"), + N_("Encodes time zone of camera clock relative to GMT.")}, + {EXIF_TAG_EXIF_VERSION, "ExifVersion", N_("Exif Version"), + N_("The version of this standard supported. Nonexistence of this " + "field is taken to mean nonconformance to the standard."), + { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_DATE_TIME_ORIGINAL, "DateTimeOriginal", + N_("Date and Time (Original)"), + N_("The date and time when the original image data was generated. " + "For a digital still camera " + "the date and time the picture was taken are recorded."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_DATE_TIME_DIGITIZED, "DateTimeDigitized", + N_("Date and Time (Digitized)"), + N_("The date and time when the image was stored as digital data."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_COMPONENTS_CONFIGURATION, "ComponentsConfiguration", + N_("Components Configuration"), + N_("Information specific to compressed data. The channels of " + "each component are arranged in order from the 1st " + "component to the 4th. For uncompressed data the data " + "arrangement is given in the tag. " + "However, since can only " + "express the order of Y, Cb and Cr, this tag is provided " + "for cases when compressed data uses components other than " + "Y, Cb, and Cr and to enable support of other sequences."), + { ESL_NNNN, ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, "CompressedBitsPerPixel", + N_("Compressed Bits per Pixel"), + N_("Information specific to compressed data. The compression mode " + "used for a compressed image is indicated in unit bits " + "per pixel."), + { ESL_NNNN, ESL_NNNN, ESL_NNNO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue", N_("Shutter Speed"), + N_("Shutter speed. The unit is the APEX (Additive System of " + "Photographic Exposure) setting."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_APERTURE_VALUE, "ApertureValue", N_("Aperture"), + N_("The lens aperture. The unit is the APEX value."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_BRIGHTNESS_VALUE, "BrightnessValue", N_("Brightness"), + N_("The value of brightness. The unit is the APEX value. " + "Ordinarily it is given in the range of -99.99 to 99.99."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_EXPOSURE_BIAS_VALUE, "ExposureBiasValue", + N_("Exposure Bias"), + N_("The exposure bias. The units is the APEX value. Ordinarily " + "it is given in the range of -99.99 to 99.99."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", N_("Maximum Aperture Value"), + N_("The smallest F number of the lens. The unit is the APEX value. " + "Ordinarily it is given in the range of 00.00 to 99.99, " + "but it is not limited to this range."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUBJECT_DISTANCE, "SubjectDistance", + N_("Subject Distance"), + N_("The distance to the subject, given in meters."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_METERING_MODE, "MeteringMode", N_("Metering Mode"), + N_("The metering mode."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_LIGHT_SOURCE, "LightSource", N_("Light Source"), + N_("The kind of light source."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FLASH, "Flash", N_("Flash"), + N_("This tag is recorded when an image is taken using a strobe " + "light (flash)."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length"), + N_("The actual focal length of the lens, in mm. Conversion is not " + "made to the focal length of a 35 mm film camera."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUBJECT_AREA, "SubjectArea", N_("Subject Area"), + N_("This tag indicates the location and area of the main subject " + "in the overall scene."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_TIFF_EP_STANDARD_ID, "TIFF/EPStandardID", N_("TIFF/EP Standard ID"), ""}, + {EXIF_TAG_MAKER_NOTE, "MakerNote", N_("Maker Note"), + N_("A tag for manufacturers of Exif writers to record any desired " + "information. The contents are up to the manufacturer."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_USER_COMMENT, "UserComment", N_("User Comment"), + N_("A tag for Exif users to write keywords or comments on the image " + "besides those in , and without the " + "character code limitations of the tag. The " + "character code used in the tag is identified " + "based on an ID code in a fixed 8-byte area at the start of " + "the tag data area. The unused portion of the area is padded " + "with NULL (\"00.h\"). ID codes are assigned by means of " + "registration. The designation method and references for each " + "character code are defined in the specification. The value of " + "CountN is determined based on the 8 bytes in the character code " + "area and the number of bytes in the user comment part. Since " + "the TYPE is not ASCII, NULL termination is not necessary. " + "The ID code for the area may be a Defined code " + "such as JIS or ASCII, or may be Undefined. The Undefined name " + "is UndefinedText, and the ID code is filled with 8 bytes of all " + "\"NULL\" (\"00.H\"). An Exif reader that reads the " + " tag must have a function for determining the " + "ID code. This function is not required in Exif readers that " + "do not use the tag. " + "When a area is set aside, it is recommended that " + "the ID code be ASCII and that the following user comment " + "part be filled with blank characters [20.H]."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUB_SEC_TIME, "SubsecTime", N_("Sub-second Time"), + N_("A tag used to record fractions of seconds for the " + " tag."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "SubSecTimeOriginal", + N_("Sub-second Time (Original)"), + N_("A tag used to record fractions of seconds for the " + " tag."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "SubSecTimeDigitized", + N_("Sub-second Time (Digitized)"), + N_("A tag used to record fractions of seconds for the " + " tag."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_TITLE, "XPTitle", N_("XP Title"), + N_("A character string giving the title of the image, encoded in " + "UTF-16LE."), + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_COMMENT, "XPComment", N_("XP Comment"), + N_("A character string containing a comment about the image, encoded " + "in UTF-16LE."), + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_AUTHOR, "XPAuthor", N_("XP Author"), + N_("A character string containing the name of the image creator, " + "encoded in UTF-16LE."), + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_KEYWORDS, "XPKeywords", N_("XP Keywords"), + N_("A character string containing key words describing the image, " + "encoded in UTF-16LE."), + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 (Microsoft extension) */ + {EXIF_TAG_XP_SUBJECT, "XPSubject", N_("XP Subject"), + N_("A character string giving the image subject, encoded in " + "UTF-16LE."), + { ESL_OOOO, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FLASH_PIX_VERSION, "FlashPixVersion", "FlashPixVersion", + N_("The FlashPix format version supported by a FPXR file."), + { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_COLOR_SPACE, "ColorSpace", N_("Color Space"), + N_("The color space information tag is always " + "recorded as the color space specifier. Normally sRGB (=1) " + "is used to define the color space based on the PC monitor " + "conditions and environment. If a color space other than " + "sRGB is used, Uncalibrated (=FFFF.H) is set. Image data " + "recorded as Uncalibrated can be treated as sRGB when it is " + "converted to FlashPix."), + { ESL_NNNN, ESL_NNNN, ESL_MMMM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", N_("Pixel X Dimension"), + N_("Information specific to compressed data. When a " + "compressed file is recorded, the valid width of the " + "meaningful image must be recorded in this tag, whether or " + "not there is padding data or a restart marker. This tag " + "should not exist in an uncompressed file."), + { ESL_NNNN, ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", N_("Pixel Y Dimension"), + N_("Information specific to compressed data. When a compressed " + "file is recorded, the valid height of the meaningful image " + "must be recorded in this tag, whether or not there is padding " + "data or a restart marker. This tag should not exist in an " + "uncompressed file. " + "Since data padding is unnecessary in the vertical direction, " + "the number of lines recorded in this valid image height tag " + "will in fact be the same as that recorded in the SOF."), + { ESL_NNNN, ESL_NNNN, ESL_NNNM, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_RELATED_SOUND_FILE, "RelatedSoundFile", + N_("Related Sound File"), + N_("This tag is used to record the name of an audio file related " + "to the image data. The only relational information " + "recorded here is the Exif audio file name and extension (an " + "ASCII string consisting of 8 characters + '.' + 3 " + "characters). The path is not recorded. Stipulations on audio " + "and file naming conventions are defined in the specification. " + "When using this tag, audio files must be recorded in " + "conformance to the Exif audio format. Writers are also allowed " + "to store the data such as Audio within APP2 as FlashPix " + "extension stream data. " + "The mapping of Exif image files and audio files is done " + "in any of three ways, [1], [2] and [3]. If multiple files " + "are mapped to one file as in [2] or [3], the above " + "format is used to record just one audio file name. If " + "there are multiple audio files, the first recorded file is " + "given. In the case of [3], for example, for the " + "Exif image file \"DSC00001.JPG\" only \"SND00001.WAV\" is " + "given as the related Exif audio file. When there are three " + "Exif audio files \"SND00001.WAV\", \"SND00002.WAV\" and " + "\"SND00003.WAV\", the Exif image file name for each of them, " + "\"DSC00001.JPG\", is indicated. By combining multiple " + "relational information, a variety of playback possibilities " + "can be supported. The method of using relational information " + "is left to the implementation on the playback side. Since this " + "information is an ASCII character string, it is terminated by " + "NULL. When this tag is used to map audio files, the relation " + "of the audio file to image data must also be indicated on the " + "audio file end."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer", + N_("Interoperability IFD Pointer"), + N_("Interoperability IFD is composed of tags which stores the " + "information to ensure the Interoperability and pointed " + "by the following tag located in Exif IFD. " + "The Interoperability structure of Interoperability IFD is " + "the same as TIFF defined IFD structure " + "but does not contain the " + "image data characteristically compared with normal TIFF " + "IFD."), + { ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FLASH_ENERGY, "FlashEnergy", N_("Flash Energy"), + N_("Indicates the strobe energy at the time the image is " + "captured, as measured in Beam Candle Power Seconds (BCPS)."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE, "SpatialFrequencyResponse", + N_("Spatial Frequency Response"), + N_("This tag records the camera or input device spatial frequency " + "table and SFR values in the direction of image width, " + "image height, and diagonal direction, as specified in ISO " + "12233."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, "FocalPlaneXResolution", + N_("Focal Plane X-Resolution"), + N_("Indicates the number of pixels in the image width (X) direction " + "per on the camera focal plane."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, "FocalPlaneYResolution", + N_("Focal Plane Y-Resolution"), + N_("Indicates the number of pixels in the image height (V) direction " + "per on the camera focal plane."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, "FocalPlaneResolutionUnit", + N_("Focal Plane Resolution Unit"), + N_("Indicates the unit for measuring and " + ". This value is the same as the " + "."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUBJECT_LOCATION, "SubjectLocation", + N_("Subject Location"), + N_("Indicates the location of the main subject in the scene. The " + "value of this tag represents the pixel at the center of the " + "main subject relative to the left edge, prior to rotation " + "processing as per the tag. The first value " + "indicates the X column number and the second indicates " + "the Y row number."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_EXPOSURE_INDEX, "ExposureIndex", N_("Exposure Index"), + N_("Indicates the exposure index selected on the camera or " + "input device at the time the image is captured."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SENSING_METHOD, "SensingMethod", N_("Sensing Method"), + N_("Indicates the image sensor type on the camera or input " + "device."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FILE_SOURCE, "FileSource", N_("File Source"), + N_("Indicates the image source. If a DSC recorded the image, " + "the tag value of this tag always be set to 3, indicating " + "that the image was recorded on a DSC."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SCENE_TYPE, "SceneType", N_("Scene Type"), + N_("Indicates the type of scene. If a DSC recorded the image, " + "this tag value must always be set to 1, indicating that the " + "image was directly photographed."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_NEW_CFA_PATTERN, "CFAPattern", + N_("CFA Pattern"), + N_("Indicates the color filter array (CFA) geometric pattern of the " + "image sensor when a one-chip color area sensor is used. " + "It does not apply to all sensing methods."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_CUSTOM_RENDERED, "CustomRendered", N_("Custom Rendered"), + N_("This tag indicates the use of special processing on image " + "data, such as rendering geared to output. When special " + "processing is performed, the reader is expected to disable " + "or minimize any further processing."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_EXPOSURE_MODE, "ExposureMode", N_("Exposure Mode"), + N_("This tag indicates the exposure mode set when the image was " + "shot. In auto-bracketing mode, the camera shoots a series of " + "frames of the same scene at different exposure settings."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), + N_("This tag indicates the white balance mode set when the image " + "was shot."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_DIGITAL_ZOOM_RATIO, "DigitalZoomRatio", + N_("Digital Zoom Ratio"), + N_("This tag indicates the digital zoom ratio when the image was " + "shot. If the numerator of the recorded value is 0, this " + "indicates that digital zoom was not used."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm", + N_("Focal Length in 35mm Film"), + N_("This tag indicates the equivalent focal length assuming a " + "35mm film camera, in mm. A value of 0 means the focal " + "length is unknown. Note that this tag differs from the " + "FocalLength tag."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SCENE_CAPTURE_TYPE, "SceneCaptureType", + N_("Scene Capture Type"), + N_("This tag indicates the type of scene that was shot. It can " + "also be used to record the mode in which the image was " + "shot. Note that this differs from the scene type " + " tag."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_GAIN_CONTROL, "GainControl", N_("Gain Control"), + N_("This tag indicates the degree of overall image gain " + "adjustment."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_CONTRAST, "Contrast", N_("Contrast"), + N_("This tag indicates the direction of contrast processing " + "applied by the camera when the image was shot."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SATURATION, "Saturation", N_("Saturation"), + N_("This tag indicates the direction of saturation processing " + "applied by the camera when the image was shot."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), + N_("This tag indicates the direction of sharpness processing " + "applied by the camera when the image was shot."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_DEVICE_SETTING_DESCRIPTION, "DeviceSettingDescription", + N_("Device Setting Description"), + N_("This tag indicates information on the picture-taking " + "conditions of a particular camera model. The tag is used " + "only to indicate the picture-taking conditions in the " + "reader."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_SUBJECT_DISTANCE_RANGE, "SubjectDistanceRange", + N_("Subject Distance Range"), + N_("This tag indicates the distance to the subject."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + {EXIF_TAG_IMAGE_UNIQUE_ID, "ImageUniqueID", N_("Image Unique ID"), + N_("This tag indicates an identifier assigned uniquely to " + "each image. It is recorded as an ASCII string equivalent " + "to hexadecimal notation and 128-bit fixed length."), + { ESL_NNNN, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, + /* Not in EXIF 2.2 */ + {EXIF_TAG_GAMMA, "Gamma", N_("Gamma"), + N_("Indicates the value of coefficient gamma.")}, + /* Not in EXIF 2.2 */ + {EXIF_TAG_PRINT_IMAGE_MATCHING, "PrintImageMatching", N_("PRINT Image Matching"), + N_("Related to Epson's PRINT Image Matching technology")}, + /* Not in EXIF 2.2 (from the Microsoft HD Photo specification) */ + {EXIF_TAG_PADDING, "Padding", N_("Padding"), + N_("This tag reserves space that can be reclaimed later when " + "additional metadata are added. New metadata can be written " + "in place by replacing this tag with a smaller data element " + "and using the reclaimed space to store the new or expanded " + "metadata tags."), + { ESL_OOOO, ESL_NNNN, ESL_OOOO, ESL_NNNN, ESL_NNNN } }, +#endif + {0, NULL, NULL, NULL} +}; + +/* For now, do not use these functions. */ + +/*! + * Return the number of entries in the EXIF tag table, including the + * terminating NULL entry. + */ +inline unsigned int +exif_tag_table_count (void) +{ + return sizeof (ExifTagTable) / sizeof (ExifTagTable[0]); +} + + +ExifTag +exif_tag_table_get_tag (unsigned int n) +{ + return (n < exif_tag_table_count ()) ? ExifTagTable[n].tag : 0; +} + +const char * +exif_tag_table_get_name (unsigned int n) +{ + return (n < exif_tag_table_count ()) ? ExifTagTable[n].name : NULL; +} + +/*! + * Compares the tag with that in entry. + * \param[in] tag pointer to integer tag value + * \param[in] entry pointer to a struct TagEntry + * \return 0 if tags are equal, <0 if tag < entry, >0 if tag > entry + */ +static int +match_tag(const void *tag, const void *entry) +{ + return *(int*)tag - ((struct TagEntry *)entry)->tag; +} + + +/*! + * Finds the first entry in the EXIF tag table with the given tag number + * using a binary search. + * \param[in] tag to find + * \return index into table, or -1 if not found + */ +static int +exif_tag_table_first(ExifTag tag) +{ + int i; + struct TagEntry *entry = bsearch(&tag, ExifTagTable, + exif_tag_table_count()-1, sizeof(struct TagEntry), match_tag); + if (!entry) + return -1; /* Not found */ + + /* Calculate index of found entry */ + i = entry - ExifTagTable; + + /* There may be other entries with the same tag number, so search + * backwards to find the first + */ + while ((i > 0) && (ExifTagTable[i-1].tag == tag)) { + --i; + } + return i; +} + +#define RECORDED \ +((ExifTagTable[i].esl[ifd][EXIF_DATA_TYPE_UNCOMPRESSED_CHUNKY] != EXIF_SUPPORT_LEVEL_NOT_RECORDED) || \ + (ExifTagTable[i].esl[ifd][EXIF_DATA_TYPE_UNCOMPRESSED_PLANAR] != EXIF_SUPPORT_LEVEL_NOT_RECORDED) || \ + (ExifTagTable[i].esl[ifd][EXIF_DATA_TYPE_UNCOMPRESSED_YCC] != EXIF_SUPPORT_LEVEL_NOT_RECORDED) || \ + (ExifTagTable[i].esl[ifd][EXIF_DATA_TYPE_COMPRESSED] != EXIF_SUPPORT_LEVEL_NOT_RECORDED)) + +const char * +exif_tag_get_name_in_ifd (ExifTag tag, ExifIfd ifd) +{ + unsigned int i; + int first; + + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } + return ExifTagTable[i].name; +} + +const char * +exif_tag_get_title_in_ifd (ExifTag tag, ExifIfd ifd) +{ + unsigned int i; + int first; + + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } + /* FIXME: This belongs to somewhere else. */ + /* libexif should use the default system locale. + * If an application specifically requires UTF-8, then we + * must give the application a way to tell libexif that. + * + * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + */ + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(ExifTagTable[i].title); +} + +const char * +exif_tag_get_description_in_ifd (ExifTag tag, ExifIfd ifd) +{ + unsigned int i; + int first; + + if (ifd >= EXIF_IFD_COUNT) + return NULL; + first = exif_tag_table_first(tag); + if (first < 0) + return NULL; + + for (i = first; ExifTagTable[i].name; i++) { + if (ExifTagTable[i].tag == tag) { + if (RECORDED) + break; + } else + return NULL; /* Recorded tag not found in the table */ + } + + /* GNU gettext acts strangely when given an empty string */ + if (!ExifTagTable[i].description || !*ExifTagTable[i].description) + return ""; + + /* libexif should use the default system locale. + * If an application specifically requires UTF-8, then we + * must give the application a way to tell libexif that. + * + * bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + */ + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(ExifTagTable[i].description); +} + + +/********************************************************************** + * convenience functions + **********************************************************************/ + +/* generic part: iterate through IFD list and return first result */ +typedef const char * (*get_stuff_func) (ExifTag tag, ExifIfd ifd); + +static const char * +exif_tag_get_stuff (ExifTag tag, get_stuff_func func) +{ + /* Search IFDs in this order, in decreasing order of number of valid tags */ + static const ExifIfd ifds[EXIF_IFD_COUNT] = { + EXIF_IFD_EXIF, + EXIF_IFD_0, + EXIF_IFD_1, + EXIF_IFD_INTEROPERABILITY, + EXIF_IFD_GPS + }; + int i; + for (i=0; i= EXIF_IFD_COUNT) + return EXIF_SUPPORT_LEVEL_UNKNOWN; + + if (t >= EXIF_DATA_TYPE_COUNT) + return get_support_level_any_type (tag, ifd); + + return get_support_level_in_ifd (tag, ifd, t); +} diff --git a/libexifa/exif-utils.c b/libexifa/exif-utils.c new file mode 100755 index 0000000..22ee29f --- /dev/null +++ b/libexifa/exif-utils.c @@ -0,0 +1,253 @@ +/* exif-utils.c + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include + +void +exif_array_set_byte_order (ExifFormat f, unsigned char *b, unsigned int n, + ExifByteOrder o_orig, ExifByteOrder o_new) +{ + unsigned int j; + unsigned int fs = exif_format_get_size (f); + ExifShort s; + ExifSShort ss; + ExifLong l; + ExifSLong sl; + ExifRational r; + ExifSRational sr; + + if (!b || !n || !fs) return; + + switch (f) { + case EXIF_FORMAT_SHORT: + for (j = 0; j < n; j++) { + s = exif_get_short (b + j * fs, o_orig); + exif_set_short (b + j * fs, o_new, s); + } + break; + case EXIF_FORMAT_SSHORT: + for (j = 0; j < n; j++) { + ss = exif_get_sshort (b + j * fs, o_orig); + exif_set_sshort (b + j * fs, o_new, ss); + } + break; + case EXIF_FORMAT_LONG: + for (j = 0; j < n; j++) { + l = exif_get_long (b + j * fs, o_orig); + exif_set_long (b + j * fs, o_new, l); + } + break; + case EXIF_FORMAT_RATIONAL: + for (j = 0; j < n; j++) { + r = exif_get_rational (b + j * fs, o_orig); + exif_set_rational (b + j * fs, o_new, r); + } + break; + case EXIF_FORMAT_SLONG: + for (j = 0; j < n; j++) { + sl = exif_get_slong (b + j * fs, o_orig); + exif_set_slong (b + j * fs, o_new, sl); + } + break; + case EXIF_FORMAT_SRATIONAL: + for (j = 0; j < n; j++) { + sr = exif_get_srational (b + j * fs, o_orig); + exif_set_srational (b + j * fs, o_new, sr); + } + break; + case EXIF_FORMAT_UNDEFINED: + case EXIF_FORMAT_BYTE: + case EXIF_FORMAT_ASCII: + default: + /* Nothing here. */ + break; + } +} + +ExifSShort +exif_get_sshort (const unsigned char *buf, ExifByteOrder order) +{ + if (!buf) return 0; + switch (order) { + case EXIF_BYTE_ORDER_MOTOROLA: + return ((buf[0] << 8) | buf[1]); + case EXIF_BYTE_ORDER_INTEL: + return ((buf[1] << 8) | buf[0]); + } + + /* Won't be reached */ + return (0); +} + +ExifShort +exif_get_short (const unsigned char *buf, ExifByteOrder order) +{ + return (exif_get_sshort (buf, order) & 0xffff); +} + +void +exif_set_sshort (unsigned char *b, ExifByteOrder order, ExifSShort value) +{ + if (!b) return; + switch (order) { + case EXIF_BYTE_ORDER_MOTOROLA: + b[0] = (unsigned char) (value >> 8); + b[1] = (unsigned char) value; + break; + case EXIF_BYTE_ORDER_INTEL: + b[0] = (unsigned char) value; + b[1] = (unsigned char) (value >> 8); + break; + } +} + +void +exif_set_short (unsigned char *b, ExifByteOrder order, ExifShort value) +{ + exif_set_sshort (b, order, value); +} + +ExifSLong +exif_get_slong (const unsigned char *b, ExifByteOrder order) +{ + if (!b) return 0; + switch (order) { + case EXIF_BYTE_ORDER_MOTOROLA: + return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); + case EXIF_BYTE_ORDER_INTEL: + return ((b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]); + } + + /* Won't be reached */ + return (0); +} + +void +exif_set_slong (unsigned char *b, ExifByteOrder order, ExifSLong value) +{ + if (!b) return; + switch (order) { + case EXIF_BYTE_ORDER_MOTOROLA: + b[0] = (unsigned char) (value >> 24); + b[1] = (unsigned char) (value >> 16); + b[2] = (unsigned char) (value >> 8); + b[3] = (unsigned char) value; + break; + case EXIF_BYTE_ORDER_INTEL: + b[3] = (unsigned char) (value >> 24); + b[2] = (unsigned char) (value >> 16); + b[1] = (unsigned char) (value >> 8); + b[0] = (unsigned char) value; + break; + } +} + +ExifLong +exif_get_long (const unsigned char *buf, ExifByteOrder order) +{ + return (exif_get_slong (buf, order) & 0xffffffff); +} + +void +exif_set_long (unsigned char *b, ExifByteOrder order, ExifLong value) +{ + exif_set_slong (b, order, value); +} + +ExifSRational +exif_get_srational (const unsigned char *buf, ExifByteOrder order) +{ + ExifSRational r; + + r.numerator = buf ? exif_get_slong (buf, order) : 0; + r.denominator = buf ? exif_get_slong (buf + 4, order) : 0; + + return (r); +} + +ExifRational +exif_get_rational (const unsigned char *buf, ExifByteOrder order) +{ + ExifRational r; + + r.numerator = buf ? exif_get_long (buf, order) : 0; + r.denominator = buf ? exif_get_long (buf + 4, order) : 0; + + return (r); +} + +void +exif_set_rational (unsigned char *buf, ExifByteOrder order, + ExifRational value) +{ + if (!buf) return; + exif_set_long (buf, order, value.numerator); + exif_set_long (buf + 4, order, value.denominator); +} + +void +exif_set_srational (unsigned char *buf, ExifByteOrder order, + ExifSRational value) +{ + if (!buf) return; + exif_set_slong (buf, order, value.numerator); + exif_set_slong (buf + 4, order, value.denominator); +} + +/*! This function converts rather UCS-2LE than UTF-16 to UTF-8. + * It should really be replaced by iconv(). + */ +void +exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen) +{ + if (maxlen <= 0) { + return; + } + while (*in) { + if (*in < 0x80) { + if (maxlen > 1) { + *out++ = (char)*in++; + maxlen--; + } else { + break; + } + } else if (*in < 0x800) { + if (maxlen > 2) { + *out++ = ((*in >> 6) & 0x1F) | 0xC0; + *out++ = (*in++ & 0x3F) | 0x80; + maxlen -= 2; + } else { + break; + } + } else { + if (maxlen > 2) { + *out++ = ((*in >> 12) & 0x0F) | 0xE0; + *out++ = ((*in >> 6) & 0x3F) | 0x80; + *out++ = (*in++ & 0x3F) | 0x80; + maxlen -= 3; + } else { + break; + } + } + } + *out = 0; +} diff --git a/libexifa/fuji/exif-mnote-data-fuji.c b/libexifa/fuji/exif-mnote-data-fuji.c new file mode 100755 index 0000000..9514654 --- /dev/null +++ b/libexifa/fuji/exif-mnote-data-fuji.c @@ -0,0 +1,349 @@ +/* exif-mnote-data-fuji.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include + + +#include +#include +#include + +#include "exif-mnote-data-fuji.h" + +struct _MNoteFujiDataPrivate { + ExifByteOrder order; +}; + +static void +exif_mnote_data_fuji_clear (ExifMnoteDataFuji *n) +{ + ExifMnoteData *d = (ExifMnoteData *) n; + unsigned int i; + + if (!n) return; + + if (n->entries) { + for (i = 0; i < n->count; i++) + if (n->entries[i].data) { + exif_mem_free (d->mem, n->entries[i].data); + n->entries[i].data = NULL; + } + exif_mem_free (d->mem, n->entries); + n->entries = NULL; + n->count = 0; + } +} + +static void +exif_mnote_data_fuji_free (ExifMnoteData *n) +{ + if (!n) return; + + exif_mnote_data_fuji_clear ((ExifMnoteDataFuji *) n); +} + +static char * +exif_mnote_data_fuji_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d; + + if (!d || !val) return NULL; + if (i > n->count -1) return NULL; +/* + exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataFuji", + "Querying value for tag '%s'...", + mnote_fuji_tag_get_name (n->entries[i].tag)); +*/ + return mnote_fuji_entry_get_value (&n->entries[i], val, maxlen); +} + +static void +exif_mnote_data_fuji_save (ExifMnoteData *ne, unsigned char **buf, + unsigned int *buf_size) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) ne; + size_t i, o, s, doff; + unsigned char *t; + size_t ts; + + if (!n || !buf || !buf_size) return; + + /* + * Allocate enough memory for all entries and the number + * of entries. + */ + *buf_size = 8 + 4 + 2 + n->count * 12 + 4; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + *buf_size = 0; + return; + } + + /* + * Header: "FUJIFILM" and 4 bytes offset to the first entry. + * As the first entry will start right thereafter, the offset is 12. + */ + memcpy (*buf, "FUJIFILM", 8); + exif_set_long (*buf + 8, n->order, 12); + + /* Save the number of entries */ + exif_set_short (*buf + 8 + 4, n->order, (ExifShort) n->count); + + /* Save each entry */ + for (i = 0; i < n->count; i++) { + o = 8 + 4 + 2 + i * 12; + exif_set_short (*buf + o + 0, n->order, (ExifShort) n->entries[i].tag); + exif_set_short (*buf + o + 2, n->order, (ExifShort) n->entries[i].format); + exif_set_long (*buf + o + 4, n->order, n->entries[i].components); + o += 8; + s = exif_format_get_size (n->entries[i].format) * + n->entries[i].components; + if (s > 65536) { + /* Corrupt data: EXIF data size is limited to the + * maximum size of a JPEG segment (64 kb). + */ + continue; + } + if (s > 4) { + ts = *buf_size + s; + + /* Ensure even offsets. Set padding bytes to 0. */ + if (s & 1) ts += 1; + t = exif_mem_realloc (ne->mem, *buf, ts); + if (!t) { + return; + } + *buf = t; + *buf_size = ts; + doff = *buf_size - s; + if (s & 1) { doff--; *(*buf + *buf_size - 1) = '\0'; } + exif_set_long (*buf + o, n->order, doff); + } else + doff = o; + + /* + * Write the data. Fill unneeded bytes with 0. Do not + * crash if data is NULL. + */ + if (!n->entries[i].data) memset (*buf + doff, 0, s); + else memcpy (*buf + doff, n->entries[i].data, s); + } +} + +static void +exif_mnote_data_fuji_load (ExifMnoteData *en, + const unsigned char *buf, unsigned int buf_size) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji*) en; + ExifLong c; + size_t i, tcount, o, datao; + + if (!n || !buf || !buf_size) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataFuji", "Short MakerNote"); + return; + } + datao = 6 + n->offset; + if ((datao + 12 < datao) || (datao + 12 < 12) || (datao + 12 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataFuji", "Short MakerNote"); + return; + } + + n->order = EXIF_BYTE_ORDER_INTEL; + datao += exif_get_long (buf + datao + 8, EXIF_BYTE_ORDER_INTEL); + if ((datao + 2 < datao) || (datao + 2 < 2) || + (datao + 2 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataFuji", "Short MakerNote"); + return; + } + + /* Read the number of tags */ + c = exif_get_short (buf + datao, EXIF_BYTE_ORDER_INTEL); + datao += 2; + + /* Remove any old entries */ + exif_mnote_data_fuji_clear (n); + + /* Reserve enough space for all the possible MakerNote tags */ + n->entries = exif_mem_alloc (en->mem, sizeof (MnoteFujiEntry) * c); + if (!n->entries) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", sizeof (MnoteFujiEntry) * c); + return; + } + + /* Parse all c entries, storing ones that are successfully parsed */ + tcount = 0; + for (i = c, o = datao; i; --i, o += 12) { + size_t s; + if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataFuji", "Short MakerNote"); + break; + } + + n->entries[tcount].tag = exif_get_short (buf + o, n->order); + n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); + n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); + n->entries[tcount].order = n->order; + + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataFuji", + "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, + mnote_fuji_tag_get_name (n->entries[tcount].tag)); + + /* + * Size? If bigger than 4 bytes, the actual data is not + * in the entry but somewhere else (offset). + */ + s = exif_format_get_size (n->entries[tcount].format) * n->entries[tcount].components; + n->entries[tcount].size = s; + if (s) { + size_t dataofs = o + 8; + if (s > 4) + /* The data in this case is merely a pointer */ + dataofs = exif_get_long (buf + dataofs, n->order) + 6 + n->offset; + if ((dataofs + s < dataofs) || (dataofs + s < s) || + (dataofs + s >= buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataFuji", "Tag data past end of " + "buffer (%u >= %u)", dataofs + s, buf_size); + continue; + } + + n->entries[tcount].data = exif_mem_alloc (en->mem, s); + if (!n->entries[tcount].data) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataFuji", s); + continue; + } + memcpy (n->entries[tcount].data, buf + dataofs, s); + } + + /* Tag was successfully parsed */ + ++tcount; + } + /* Store the count of successfully parsed tags */ + n->count = tcount; +} + +static unsigned int +exif_mnote_data_fuji_count (ExifMnoteData *n) +{ + return n ? ((ExifMnoteDataFuji *) n)->count : 0; +} + +static unsigned int +exif_mnote_data_fuji_get_id (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataFuji *note = (ExifMnoteDataFuji *) d; + + if (!note) return 0; + if (note->count <= n) return 0; + return note->entries[n].tag; +} + +static const char * +exif_mnote_data_fuji_get_name (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_fuji_tag_get_name (n->entries[i].tag); +} + +static const char * +exif_mnote_data_fuji_get_title (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_fuji_tag_get_title (n->entries[i].tag); +} + +static const char * +exif_mnote_data_fuji_get_description (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_fuji_tag_get_description (n->entries[i].tag); +} + +static void +exif_mnote_data_fuji_set_byte_order (ExifMnoteData *d, ExifByteOrder o) +{ + ExifByteOrder o_orig; + ExifMnoteDataFuji *n = (ExifMnoteDataFuji *) d; + unsigned int i; + + if (!n) return; + + o_orig = n->order; + n->order = o; + for (i = 0; i < n->count; i++) { + n->entries[i].order = o; + exif_array_set_byte_order (n->entries[i].format, n->entries[i].data, + n->entries[i].components, o_orig, o); + } +} + +static void +exif_mnote_data_fuji_set_offset (ExifMnoteData *n, unsigned int o) +{ + if (n) ((ExifMnoteDataFuji *) n)->offset = o; +} + +int +exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e) +{ + return ((e->size >= 12) && !memcmp (e->data, "FUJIFILM", 8)); +} + +ExifMnoteData * +exif_mnote_data_fuji_new (ExifMem *mem) +{ + ExifMnoteData *d; + + if (!mem) return NULL; + + d = exif_mem_alloc (mem, sizeof (ExifMnoteDataFuji)); + if (!d) return NULL; + + exif_mnote_data_construct (d, mem); + + /* Set up function pointers */ + d->methods.free = exif_mnote_data_fuji_free; + d->methods.set_byte_order = exif_mnote_data_fuji_set_byte_order; + d->methods.set_offset = exif_mnote_data_fuji_set_offset; + d->methods.load = exif_mnote_data_fuji_load; + d->methods.save = exif_mnote_data_fuji_save; + d->methods.count = exif_mnote_data_fuji_count; + d->methods.get_id = exif_mnote_data_fuji_get_id; + d->methods.get_name = exif_mnote_data_fuji_get_name; + d->methods.get_title = exif_mnote_data_fuji_get_title; + d->methods.get_description = exif_mnote_data_fuji_get_description; + d->methods.get_value = exif_mnote_data_fuji_get_value; + + return d; +} diff --git a/libexifa/fuji/mnote-fuji-entry.c b/libexifa/fuji/mnote-fuji-entry.c new file mode 100755 index 0000000..0ca1634 --- /dev/null +++ b/libexifa/fuji/mnote-fuji-entry.c @@ -0,0 +1,306 @@ +/* mnote-fuji-entry.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include + +#include + +#include "mnote-fuji-entry.h" + +#define CF(format,target,v,maxlen) \ +{ \ + if (format != target) { \ + snprintf (v, maxlen, \ + _("Invalid format '%s', " \ + "expected '%s'."), \ + exif_format_get_name (format), \ + exif_format_get_name (target)); \ + break; \ + } \ +} + +#define CC(number,target,v,maxlen) \ +{ \ + if (number != target) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i)."), (int) number, (int) target); \ + break; \ + } \ +} + +static const struct { + ExifTag tag; + struct { + int index; + const char *string; + } elem[22]; +} items[] = { +#ifndef NO_VERBOSE_TAG_DATA + { MNOTE_FUJI_TAG_SHARPNESS, + { {1, N_("Softest")}, + {2, N_("Soft")}, + {3, N_("Normal")}, + {4, N_("Hard")}, + {5, N_("Hardest")}, + {0x0082, N_("Medium soft")}, + {0x0084, N_("Medium hard")}, + {0x8000, N_("Film simulation mode")}, + {0xFFFF, N_("Off")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_WHITE_BALANCE, + { {0, N_("Auto")}, + {0x100, N_("Daylight")}, + {0x200, N_("Cloudy")}, + {0x300, N_("Daylight fluorescent")}, + {0x301, N_("Day white fluorescent")}, + {0x302, N_("White fluorescent")}, + {0x400, N_("Incandescent")}, + {0x500, N_("Flash")}, + {0xF00, N_("Custom")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_COLOR, + { {0, N_("Standard")}, + {0x0080, N_("Medium high")}, + {0x0100, N_("High")}, + {0x0180, N_("Medium low")}, + {0x0200, N_("Original")}, + {0x0300, N_("Black & white")}, + {0x8000, N_("Film simulation mode")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_TONE, + { {0, N_("Standard")}, + {0x0080, N_("Medium hard")}, + {0x0100, N_("Hard")}, + {0x0180, N_("Medium soft")}, + {0x0200, N_("Original")}, + {0x8000, N_("Film simulation mode")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_FLASH_MODE, + { {0, N_("Auto")}, + {1, N_("On")}, + {2, N_("Off")}, + {3, N_("Red-eye reduction")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_MACRO, + { {0, N_("Off")}, + {1, N_("On")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_FOCUS_MODE, + { {0, N_("Auto")}, + {1, N_("Manual")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_SLOW_SYNC, + { {0, N_("Off")}, + {1, N_("On")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_PICTURE_MODE, + { {0, N_("Auto")}, + {1, N_("Portrait")}, + {2, N_("Landscape")}, + {4, N_("Sports")}, + {5, N_("Night")}, + {6, N_("Program AE")}, + {7, N_("Natural photo")}, + {8, N_("Vibration reduction")}, + {0x000A, N_("Sunset")}, + {0x000B, N_("Museum")}, + {0x000C, N_("Party")}, + {0x000D, N_("Flower")}, + {0x000E, N_("Text")}, + {0x000F, N_("NP & flash")}, + {0x0010, N_("Beach")}, + {0x0011, N_("Snow")}, + {0x0012, N_("Fireworks")}, + {0x0013, N_("Underwater")}, + {0x0100, N_("Aperture priority AE")}, + {0x0200, N_("Shutter priority AE")}, + {0x0300, N_("Manual exposure")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_CONT_TAKING, + { {0, N_("Off")}, + {1, N_("On")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_FINEPIX_COLOR, + { {0x00, N_("F-Standard")}, + {0x10, N_("F-Chrome")}, + {0x30, N_("F-B&W")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_BLUR_CHECK, + { {0, N_("No blur")}, + {1, N_("Blur warning")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_FOCUS_CHECK, + { {0, N_("Focus good")}, + {1, N_("Out of focus")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK, + { {0, N_("AE good")}, + {1, N_("Over exposed")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_DYNAMIC_RANGE, + { {1, N_("Standard")}, + {3, N_("Wide")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_FILM_MODE, + { {0, N_("F0/Standard")}, + {0x0100, N_("F1/Studio portrait")}, + {0x0110, N_("F1a/Professional portrait")}, + {0x0120, N_("F1b/Professional portrait")}, + {0x0130, N_("F1c/Professional portrait")}, + {0x0200, N_("F2/Fujichrome")}, + {0x0300, N_("F3/Studio portrait Ex")}, + {0x0400, N_("F4/Velvia")}, + {0, NULL}}}, + { MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING, + { {0, N_("Auto (100-400%)")}, + {1, N_("RAW")}, + {0x0100, N_("Standard (100%)")}, + {0x0200, N_("Wide1 (230%)")}, + {0x0201, N_("Wide2 (400%)")}, + {0x8000, N_("Film simulation mode")}, + {0, NULL}}}, +#endif + {0, {{0, NULL}}} +}; + + +char * +mnote_fuji_entry_get_value (MnoteFujiEntry *entry, + char *val, unsigned int maxlen) +{ + ExifLong vl; + ExifSLong vsl; + ExifShort vs, vs2; + ExifRational vr; + ExifSRational vsr; + int i, j; + + if (!entry) return (NULL); + + memset (val, 0, maxlen); + maxlen--; + + switch (entry->tag) { + case MNOTE_FUJI_TAG_VERSION: + CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (entry->components, 4, val, maxlen); + memcpy (val, entry->data, MIN(maxlen, entry->size)); + break; + case MNOTE_FUJI_TAG_SHARPNESS: + case MNOTE_FUJI_TAG_WHITE_BALANCE: + case MNOTE_FUJI_TAG_COLOR: + case MNOTE_FUJI_TAG_TONE: + case MNOTE_FUJI_TAG_FLASH_MODE: + case MNOTE_FUJI_TAG_MACRO: + case MNOTE_FUJI_TAG_FOCUS_MODE: + case MNOTE_FUJI_TAG_SLOW_SYNC: + case MNOTE_FUJI_TAG_PICTURE_MODE: + case MNOTE_FUJI_TAG_CONT_TAKING: + case MNOTE_FUJI_TAG_FINEPIX_COLOR: + case MNOTE_FUJI_TAG_BLUR_CHECK: + case MNOTE_FUJI_TAG_FOCUS_CHECK: + case MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK: + case MNOTE_FUJI_TAG_DYNAMIC_RANGE: + case MNOTE_FUJI_TAG_FILM_MODE: + case MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + CC (entry->components, 1, val, maxlen); + vs = exif_get_short (entry->data, entry->order); + + /* search the tag */ + for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++); + if (!items[i].tag) { + snprintf (val, maxlen, + _("Internal error (unknown value %i)"), vs); + break; + } + + /* find the value */ + for (j = 0; items[i].elem[j].string && + (items[i].elem[j].index < vs); j++); + if (items[i].elem[j].index != vs) { + snprintf (val, maxlen, + _("Internal error (unknown value %i)"), vs); + break; + } + strncpy (val, _(items[i].elem[j].string), maxlen); + break; + case MNOTE_FUJI_TAG_FOCUS_POINT: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + CC (entry->components, 2, val, maxlen); + vs = exif_get_short (entry->data, entry->order); + vs2 = exif_get_short (entry->data+2, entry->order); + snprintf (val, maxlen, "%i, %i", vs, vs2); + break; + case MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH: + case MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH: + CF (entry->format, EXIF_FORMAT_RATIONAL, val, maxlen); + CC (entry->components, 1, val, maxlen); + vr = exif_get_rational (entry->data, entry->order); + if (!vr.denominator) break; + snprintf (val, maxlen, _("%2.2f mm"), (double) vr.numerator / + vr.denominator); + break; + + default: + switch (entry->format) { + case EXIF_FORMAT_ASCII: + strncpy (val, (char *)entry->data, MIN(maxlen, entry->size)); + break; + case EXIF_FORMAT_SHORT: + vs = exif_get_short (entry->data, entry->order); + snprintf (val, maxlen, "%i", vs); + break; + case EXIF_FORMAT_LONG: + vl = exif_get_long (entry->data, entry->order); + snprintf (val, maxlen, "%lu", (long unsigned) vl); + break; + case EXIF_FORMAT_SLONG: + vsl = exif_get_slong (entry->data, entry->order); + snprintf (val, maxlen, "%li", (long int) vsl); + break; + case EXIF_FORMAT_RATIONAL: + vr = exif_get_rational (entry->data, entry->order); + if (!vr.denominator) break; + snprintf (val, maxlen, "%2.4f", (double) vr.numerator / + vr.denominator); + break; + case EXIF_FORMAT_SRATIONAL: + vsr = exif_get_srational (entry->data, entry->order); + if (!vsr.denominator) break; + snprintf (val, maxlen, "%2.4f", (double) vsr.numerator / + vsr.denominator); + break; + case EXIF_FORMAT_UNDEFINED: + default: + snprintf (val, maxlen, _("%i bytes unknown data"), + entry->size); + break; + } + break; + } + + return (val); +} diff --git a/libexifa/fuji/mnote-fuji-tag.c b/libexifa/fuji/mnote-fuji-tag.c new file mode 100755 index 0000000..3200eb6 --- /dev/null +++ b/libexifa/fuji/mnote-fuji-tag.c @@ -0,0 +1,105 @@ +/* mnote-fuji-tag.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#include "mnote-fuji-tag.h" + + +static const struct { + MnoteFujiTag tag; + const char *name; + const char *title; + const char *description; +} table[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + {MNOTE_FUJI_TAG_VERSION, "Version", N_("Maker Note Version"), ""}, + {MNOTE_FUJI_TAG_SERIAL_NUMBER, "SerialNumber", N_("Serial Number"), N_("This number is unique and based on the date of manufacture.")}, + {MNOTE_FUJI_TAG_QUALITY, "Quality", N_("Quality"), ""}, + {MNOTE_FUJI_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""}, + {MNOTE_FUJI_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_FUJI_TAG_COLOR, "ChromaticitySaturation", N_("Chromaticity Saturation"), ""}, + {MNOTE_FUJI_TAG_TONE, "Contrast", N_("Contrast"), ""}, + {MNOTE_FUJI_TAG_FLASH_MODE, "FlashMode", N_("Flash Mode"), ""}, + {MNOTE_FUJI_TAG_FLASH_STRENGTH, "FlashStrength", N_("Flash Firing Strength Compensation"), ""}, + {MNOTE_FUJI_TAG_MACRO, "MacroMode", N_("Macro Mode"), ""}, + {MNOTE_FUJI_TAG_FOCUS_MODE, "FocusingMode", N_("Focusing Mode"), ""}, + {MNOTE_FUJI_TAG_FOCUS_POINT, "FocusPoint", N_("Focus Point"), ""}, + {MNOTE_FUJI_TAG_SLOW_SYNC, "SlowSynchro", N_("Slow Synchro Mode"), ""}, + {MNOTE_FUJI_TAG_PICTURE_MODE, "PictureMode", N_("Picture Mode"), ""}, + {MNOTE_FUJI_TAG_CONT_TAKING, "ContinuousTaking", N_("Continuous Taking"), ""}, + {MNOTE_FUJI_TAG_SEQUENCE_NUMBER, "ContinuousSequence", N_("Continuous Sequence Number"), ""}, + {MNOTE_FUJI_TAG_FINEPIX_COLOR, "FinePixColor", N_("FinePix Color"), ""}, + {MNOTE_FUJI_TAG_BLUR_CHECK, "BlurCheck", N_("Blur Check"), ""}, + {MNOTE_FUJI_TAG_FOCUS_CHECK, "AutoFocusCheck", N_("Auto Focus Check"), ""}, + {MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK, "AutoExposureCheck", N_("Auto Exposure Check"), ""}, + {MNOTE_FUJI_TAG_DYNAMIC_RANGE, "DynamicRange", N_("Dynamic Range"), ""}, + {MNOTE_FUJI_TAG_FILM_MODE, "FilmMode", N_("Film Simulation Mode"), ""}, + {MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING, "DRangeMode", N_("Dynamic Range Wide Mode"), ""}, + {MNOTE_FUJI_TAG_DEV_DYNAMIC_RANGE_SETTING, "DevDRangeMode", N_("Development Dynamic Range Wide Mode"), ""}, + {MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH, "MinFocalLen", N_("Minimum Focal Length"), ""}, + {MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH, "MaxFocalLen", N_("Maximum Focal Length"), ""}, + {MNOTE_FUJI_TAG_MAX_APERT_AT_MIN_FOC, "MaxApertAtMinFoc", N_("Maximum Aperture at Minimum Focal"), ""}, + {MNOTE_FUJI_TAG_MAX_APERT_AT_MAX_FOC, "MaxApertAtMaxFoc", N_("Maximum Aperture at Maximum Focal"), ""}, + {MNOTE_FUJI_TAG_FILE_SOURCE, "FileSource", N_("File Source"), ""}, + {MNOTE_FUJI_TAG_ORDER_NUMBER, "OrderNumber", N_("Order Number"), ""}, + {MNOTE_FUJI_TAG_FRAME_NUMBER, "FrameNumber", N_("Frame Number"), ""}, +#endif + {0, NULL, NULL, NULL} +}; + +const char * +mnote_fuji_tag_get_name (MnoteFujiTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (table[i].name); + return NULL; +} + +const char * +mnote_fuji_tag_get_title (MnoteFujiTag t) +{ + unsigned int i; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (_(table[i].title)); + return NULL; +} + +const char * +mnote_fuji_tag_get_description (MnoteFujiTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) { + if (!*table[i].description) + return ""; + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(table[i].description); + } + return NULL; +} diff --git a/libexifa/libexif/_stdint.h b/libexifa/libexif/_stdint.h new file mode 100755 index 0000000..80ecf41 --- /dev/null +++ b/libexifa/libexif/_stdint.h @@ -0,0 +1,2 @@ +/* This file is generated automatically by configure */ +#include diff --git a/libexifa/libexif/canon/exif-mnote-data-canon.h b/libexifa/libexif/canon/exif-mnote-data-canon.h new file mode 100755 index 0000000..2a1cc87 --- /dev/null +++ b/libexifa/libexif/canon/exif-mnote-data-canon.h @@ -0,0 +1,58 @@ +/* exif-mnote-data-canon.h + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_CANON_H__ +#define __EXIF_MNOTE_DATA_CANON_H__ + +#include +#include +#include +#include +#include + +typedef struct _ExifMnoteDataCanon ExifMnoteDataCanon; + +#include + +struct _ExifMnoteDataCanon { + ExifMnoteData parent; + + MnoteCanonEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + + ExifDataOption options; +}; + +/*! Detect if MakerNote is recognized as one handled by the Canon module. + * + * \param[in] ed image #ExifData to identify as as a Canon type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_canon_new (ExifMem *mem, ExifDataOption o); + +#endif /* __EXIF_MNOTE_DATA_CANON_H__ */ diff --git a/libexifa/libexif/canon/mnote-canon-entry.h b/libexifa/libexif/canon/mnote-canon-entry.h new file mode 100755 index 0000000..a4d4499 --- /dev/null +++ b/libexifa/libexif/canon/mnote-canon-entry.h @@ -0,0 +1,44 @@ +/* mnote-canon-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_CANON_ENTRY_H__ +#define __MNOTE_CANON_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnoteCanonEntry MnoteCanonEntry; + +struct _MnoteCanonEntry { + MnoteCanonTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +unsigned int mnote_canon_entry_count_values (const MnoteCanonEntry *); +char *mnote_canon_entry_get_value (const MnoteCanonEntry *, unsigned int t, char *val, unsigned int maxlen); + +#endif /* __MNOTE_CANON_ENTRY_H__ */ diff --git a/libexifa/libexif/canon/mnote-canon-tag.h b/libexifa/libexif/canon/mnote-canon-tag.h new file mode 100755 index 0000000..0c7d9aa --- /dev/null +++ b/libexifa/libexif/canon/mnote-canon-tag.h @@ -0,0 +1,59 @@ +/* mnote-canon-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_CANON_TAG_H__ +#define __MNOTE_CANON_TAG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum _MnoteCanonTag { + MNOTE_CANON_TAG_UNKNOWN_0 = 0x0, + MNOTE_CANON_TAG_SETTINGS_1 = 0x1, + MNOTE_CANON_TAG_FOCAL_LENGTH = 0x2, + MNOTE_CANON_TAG_UNKNOWN_3 = 0x3, + MNOTE_CANON_TAG_SETTINGS_2 = 0x4, + MNOTE_CANON_TAG_PANORAMA = 0x5, + MNOTE_CANON_TAG_IMAGE_TYPE = 0x6, + MNOTE_CANON_TAG_FIRMWARE = 0x7, + MNOTE_CANON_TAG_IMAGE_NUMBER = 0x8, + MNOTE_CANON_TAG_OWNER = 0x9, + MNOTE_CANON_TAG_UNKNOWN_10 = 0xa, + MNOTE_CANON_TAG_SERIAL_NUMBER = 0xc, + MNOTE_CANON_TAG_UNKNOWN_13 = 0xd, + MNOTE_CANON_TAG_CUSTOM_FUNCS = 0xf, + MNOTE_CANON_TAG_COLOR_INFORMATION = 0xa0 +}; +typedef enum _MnoteCanonTag MnoteCanonTag; + +const char *mnote_canon_tag_get_name (MnoteCanonTag); +const char *mnote_canon_tag_get_name_sub (MnoteCanonTag, unsigned int, ExifDataOption); +const char *mnote_canon_tag_get_title (MnoteCanonTag); +const char *mnote_canon_tag_get_title_sub (MnoteCanonTag, unsigned int, ExifDataOption); +const char *mnote_canon_tag_get_description (MnoteCanonTag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_CANON_TAG_H__ */ diff --git a/libexifa/libexif/config.h b/libexifa/libexif/config.h new file mode 100755 index 0000000..27a0dfc --- /dev/null +++ b/libexifa/libexif/config.h @@ -0,0 +1,92 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +/* #undef ENABLE_NLS */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +/* #undef HAVE_DCGETTEXT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +/* #undef HAVE_GETTEXT */ + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef ICONV_CONST */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libexif" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libexif-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "EXIF library" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "EXIF library 0.6.20" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libexif" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.6.20" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.6.20" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/libexifa/libexif/exif-byte-order.h b/libexifa/libexif/exif-byte-order.h new file mode 100755 index 0000000..ab5c9ad --- /dev/null +++ b/libexifa/libexif/exif-byte-order.h @@ -0,0 +1,46 @@ +/* exif-byte-order.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_BYTE_ORDER_H__ +#define __EXIF_BYTE_ORDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Which byte order to use */ +typedef enum { + /*! Big-endian byte order */ + EXIF_BYTE_ORDER_MOTOROLA, + /*! Little-endian byte order */ + EXIF_BYTE_ORDER_INTEL +} ExifByteOrder; + +/*! Return a short, localized, textual name for the given byte order. + * \param[in] order byte order + * \return localized textual name of the byte order + */ +const char *exif_byte_order_get_name (ExifByteOrder order); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_BYTE_ORDER_H__ */ diff --git a/libexifa/libexif/exif-content.h b/libexifa/libexif/exif-content.h new file mode 100755 index 0000000..d912ccf --- /dev/null +++ b/libexifa/libexif/exif-content.h @@ -0,0 +1,145 @@ +/*! \file exif-content.h + * \brief Handling EXIF IFDs + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_CONTENT_H__ +#define __EXIF_CONTENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Holds all EXIF tags in a single IFD */ +typedef struct _ExifContent ExifContent; +typedef struct _ExifContentPrivate ExifContentPrivate; + +#include +#include +#include +#include +#include + +struct _ExifContent +{ + ExifEntry **entries; + unsigned int count; + + /*! Data containing this content */ + ExifData *parent; + + ExifContentPrivate *priv; +}; + +/* Lifecycle */ +ExifContent *exif_content_new (void); +ExifContent *exif_content_new_mem (ExifMem *); +void exif_content_ref (ExifContent *content); +void exif_content_unref (ExifContent *content); +void exif_content_free (ExifContent *content); + +/*! Add an EXIF tag to an IFD. + * If this tag already exists in the IFD, this function does nothing. + * \pre The "tag" member of the entry must be set on entry. + * + * \param[out] c IFD + * \param[in] entry EXIF entry to add + */ +void exif_content_add_entry (ExifContent *c, ExifEntry *entry); + +/*! Remove an EXIF tag from an IFD. + * If this tag does not exist in the IFD, this function does nothing. + * + * \param[out] c IFD + * \param[in] e EXIF entry to remove + */ +void exif_content_remove_entry (ExifContent *c, ExifEntry *e); + +/*! Return the #ExifEntry in this IFD corresponding to the given tag. + * This is a pointer into a member of the #ExifContent array and must NOT be + * freed or unrefed by the caller. + * + * \param[in] content EXIF content for an IFD + * \param[in] tag EXIF tag to return + * \return #ExifEntry of the tag, or NULL on error + */ +ExifEntry *exif_content_get_entry (ExifContent *content, ExifTag tag); + +/*! Fix the IFD to bring it into specification. Call #exif_entry_fix on + * each entry in this IFD to fix existing entries, create any new entries + * that are mandatory in this IFD but do not yet exist, and remove any + * entries that are not allowed in this IFD. + * + * \param[in,out] c EXIF content for an IFD + */ +void exif_content_fix (ExifContent *c); + +typedef void (* ExifContentForeachEntryFunc) (ExifEntry *, void *user_data); + +/*! Executes function on each EXIF tag in this IFD in turn. + * The tags will not necessarily be visited in numerical order. + * + * \param[in,out] content IFD over which to iterate + * \param[in] func function to call for each entry + * \param[in] user_data data to pass into func on each call + */ +void exif_content_foreach_entry (ExifContent *content, + ExifContentForeachEntryFunc func, + void *user_data); + +/*! Return the IFD number in which the given #ExifContent is found. + * + * \param[in] c an #ExifContent* + * \return IFD number, or #EXIF_IFD_COUNT on error + */ +ExifIfd exif_content_get_ifd (ExifContent *c); + +/*! Return a textual representation of the EXIF data for a tag. + * + * \param[in] c #ExifContent* for an IFD + * \param[in] t #ExifTag to return + * \param[out] v char* buffer in which to store value + * \param[in] m unsigned int length of the buffer v + * \return the v pointer, or NULL on error + */ +#define exif_content_get_value(c,t,v,m) \ + (exif_content_get_entry (c,t) ? \ + exif_entry_get_value (exif_content_get_entry (c,t),v,m) : NULL) + +/*! Dump contents of the IFD to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] content IFD data + * \param[in] indent how many levels deep to indent the data + */ +void exif_content_dump (ExifContent *content, unsigned int indent); + +/*! Set the log message object for this IFD. + * + * \param[in] content IFD + * \param[in] log #ExifLog* + */ +void exif_content_log (ExifContent *content, ExifLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_CONTENT_H__ */ diff --git a/libexifa/libexif/exif-data-type.h b/libexifa/libexif/exif-data-type.h new file mode 100755 index 0000000..05d4f95 --- /dev/null +++ b/libexifa/libexif/exif-data-type.h @@ -0,0 +1,46 @@ +/* exif-data-tag.h + * + * Copyright (c) 2005 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_DATA_TYPE_H__ +#define __EXIF_DATA_TYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Represents the type of image data to which the EXIF data applies. + * The EXIF tags have different constraints depending on the type of + * image data. + */ +typedef enum { + EXIF_DATA_TYPE_UNCOMPRESSED_CHUNKY = 0, + EXIF_DATA_TYPE_UNCOMPRESSED_PLANAR, + EXIF_DATA_TYPE_UNCOMPRESSED_YCC, + EXIF_DATA_TYPE_COMPRESSED, + EXIF_DATA_TYPE_COUNT, + + EXIF_DATA_TYPE_UNKNOWN = EXIF_DATA_TYPE_COUNT +} ExifDataType; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_TAG_H__ */ diff --git a/libexifa/libexif/exif-data.h b/libexifa/libexif/exif-data.h new file mode 100755 index 0000000..1bcc4e5 --- /dev/null +++ b/libexifa/libexif/exif-data.h @@ -0,0 +1,264 @@ +/*! \file exif-data.h + * \brief Defines the ExifData type and the associated functions. + */ +/* + * \author Lutz Mueller + * \date 2001-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_DATA_H__ +#define __EXIF_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include +#include +#include + +/*! Represents the entire EXIF data found in an image */ +typedef struct _ExifData ExifData; +typedef struct _ExifDataPrivate ExifDataPrivate; + +#include +#include +#include + +/*! Represents the entire EXIF data found in an image */ +struct _ExifData +{ + /*! Data for each IFD */ + ExifContent *ifd[EXIF_IFD_COUNT]; + + /*! Pointer to thumbnail image, or NULL if not available */ + unsigned char *data; + + /*! Number of bytes in thumbnail image at \c data */ + unsigned int size; + + ExifDataPrivate *priv; +}; + +/*! Allocate a new #ExifData. The #ExifData contains an empty + * #ExifContent for each IFD and the default set of options, + * which has #EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS + * and #EXIF_DATA_OPTION_FOLLOW_SPECIFICATION set. + * + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new (void); + +/*! Allocate a new #ExifData using the given memory allocator. + * The #ExifData contains an empty #ExifContent for each IFD and the default + * set of options, which has #EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS and + * #EXIF_DATA_OPTION_FOLLOW_SPECIFICATION set. + * + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_mem (ExifMem *); + +/*! Allocate a new #ExifData and load EXIF data from a JPEG file. + * Uses an #ExifLoader internally to do the loading. + * + * \param[in] path filename including path + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_from_file (const char *path); + +/*! Allocate a new #ExifData and load EXIF data from a memory buffer. + * + * \param[in] data pointer to raw JPEG or EXIF data + * \param[in] size number of bytes of data at data + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_from_data (const unsigned char *data, + unsigned int size); + +/*! Load the #ExifData structure from the raw JPEG or EXIF data in the given + * memory buffer. If the EXIF data contains a recognized MakerNote, it is + * loaded and stored as well for later retrieval by #exif_data_get_mnote_data. + * If the EXIF_DATA_OPTION_FOLLOW_SPECIFICATION has been set on this #ExifData, + * then the tags are fixed after loading. + * + * \param[in,out] data EXIF data + * \param[in] d pointer to raw JPEG or EXIF data + * \param[in] size number of bytes of data at d + */ +void exif_data_load_data (ExifData *data, const unsigned char *d, + unsigned int size); + +/*! Store raw EXIF data representing the #ExifData structure into a memory + * buffer. The buffer is allocated by this function and must subsequently be + * freed by the caller using the matching free function as used by the #ExifMem + * in use by this #ExifData. + * + * \param[in] data EXIF data + * \param[out] d pointer to buffer pointer containing raw EXIF data on return + * \param[out] ds pointer to variable to hold the number of bytes of + * data at d, or set to 0 on error + */ +void exif_data_save_data (ExifData *data, unsigned char **d, + unsigned int *ds); + +void exif_data_ref (ExifData *data); +void exif_data_unref (ExifData *data); +void exif_data_free (ExifData *data); + +/*! Return the byte order in use by this EXIF structure. + * + * \param[in] data EXIF data + * \return byte order + */ +ExifByteOrder exif_data_get_byte_order (ExifData *data); + +/*! Set the byte order to use for this EXIF data. If any tags already exist + * (including MakerNote tags) they are are converted to the specified byte + * order. + * + * \param[in,out] data EXIF data + * \param[in] order byte order + */ +void exif_data_set_byte_order (ExifData *data, ExifByteOrder order); + +/*! Return the MakerNote data out of the EXIF data. Only certain + * MakerNote formats that are recognized by libexif are supported. + * The pointer references a member of the #ExifData structure and must NOT be + * freed by the caller. + * + * \param[in] d EXIF data + * \return MakerNote data, or NULL if not found or not supported + */ +ExifMnoteData *exif_data_get_mnote_data (ExifData *d); + +/*! Fix the EXIF data to bring it into specification. Call #exif_content_fix + * on each IFD to fix existing entries, create any new entries that are + * mandatory but do not yet exist, and remove any entries that are not + * allowed. + * + * \param[in,out] d EXIF data + */ +void exif_data_fix (ExifData *d); + +typedef void (* ExifDataForeachContentFunc) (ExifContent *, void *user_data); + +/*! Execute a function on each IFD in turn. + * + * \param[in] data EXIF data over which to iterate + * \param[in] func function to call for each entry + * \param[in] user_data data to pass into func on each call + */ +void exif_data_foreach_content (ExifData *data, + ExifDataForeachContentFunc func, + void *user_data); + +/*! Options to configure the behaviour of #ExifData */ +typedef enum { + /*! Act as though unknown tags are not present */ + EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS = 1 << 0, + + /*! Fix the EXIF tags to follow the spec */ + EXIF_DATA_OPTION_FOLLOW_SPECIFICATION = 1 << 1, + + /*! Leave the MakerNote alone, which could cause it to be corrupted */ + EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE = 1 << 2 +} ExifDataOption; + +/*! Return a short textual description of the given #ExifDataOption. + * + * \param[in] o option + * \return localized textual description of the option + */ +const char *exif_data_option_get_name (ExifDataOption o); + +/*! Return a verbose textual description of the given #ExifDataOption. + * + * \param[in] o option + * \return verbose localized textual description of the option + */ +const char *exif_data_option_get_description (ExifDataOption o); + +/*! Set the given option on the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] o option + */ +void exif_data_set_option (ExifData *d, ExifDataOption o); + +/*! Clear the given option on the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] o option + */ +void exif_data_unset_option (ExifData *d, ExifDataOption o); + +/*! Set the data type for the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] dt data type + */ +void exif_data_set_data_type (ExifData *d, ExifDataType dt); + +/*! Return the data type for the given #ExifData. + * + * \param[in] d EXIF data + * \return data type, or #EXIF_DATA_TYPE_UNKNOWN on error + */ +ExifDataType exif_data_get_data_type (ExifData *d); + +/*! Dump all EXIF data to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] data EXIF data + */ +void exif_data_dump (ExifData *data); + +/*! Set the log message object for all IFDs. + * + * \param[in] data EXIF data + * \param[in] log #ExifLog + */ +void exif_data_log (ExifData *data, ExifLog *log); + +/*! Return an #ExifEntry for the given tag if found in any IFD. + * Each IFD is searched in turn and the first containing a tag with + * this number is returned. + * + * \param[in] d #ExifData + * \param[in] t #ExifTag + * \return #ExifEntry* if found, else NULL if not found + */ +#define exif_data_get_entry(d,t) \ + (exif_content_get_entry(d->ifd[EXIF_IFD_0],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_0],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_1],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_1],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) : NULL) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_DATA_H__ */ diff --git a/libexifa/libexif/exif-entry.h b/libexifa/libexif/exif-entry.h new file mode 100755 index 0000000..22f5d5a --- /dev/null +++ b/libexifa/libexif/exif-entry.h @@ -0,0 +1,188 @@ +/*! \file exif-entry.h + * \brief Handling EXIF entries + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_ENTRY_H__ +#define __EXIF_ENTRY_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Data found in one EXIF tag. + * The #exif_entry_get_value function can provide access to the + * formatted contents, or the struct members can be used directly to + * access the raw contents. + */ +typedef struct _ExifEntry ExifEntry; +typedef struct _ExifEntryPrivate ExifEntryPrivate; + +#include +#include +#include +#include + +/*! Data found in one EXIF tag */ +struct _ExifEntry { + /*! EXIF tag for this entry */ + /* ExifTag had been changed to ExifShort to enable writing of the GPS related tags. + 2011.03.01 - Samsung Electronics */ + ExifShort tag; + + /*! Type of data in this entry */ + ExifFormat format; + + /*! Number of elements in the array, if this is an array entry. + * Contains 1 for non-array data types. */ + unsigned long components; + + /*! Pointer to the raw EXIF data for this entry. It is allocated + * by #exif_entry_initialize and is NULL beforehand. Data contained + * here may be manipulated using the functions in exif-utils.h */ + unsigned char *data; + + /*! Number of bytes in the buffer at \c data. This must be no less + * than exif_format_get_size(format)*components */ + unsigned int size; + + /*! #ExifContent containing this entry. + * \see exif_entry_get_ifd */ + ExifContent *parent; + + /*! Internal data to be used by libexif itself */ + ExifEntryPrivate *priv; +}; + +/* Lifecycle */ + +/*! Reserve memory for and initialize a new #ExifEntry. + * No memory is allocated for the \c data element of the returned #ExifEntry. + * + * \return new allocated #ExifEntry, or NULL on error + * + * \see exif_entry_new_mem, exif_entry_unref + */ +ExifEntry *exif_entry_new (void); + +/*! Reserve memory for and initialize new #ExifEntry using the specified + * memory allocator. + * No memory is allocated for the \c data element of the returned #ExifEntry. + * + * \return new allocated #ExifEntry, or NULL on error + * + * \see exif_entry_new, exif_entry_unref + */ +ExifEntry *exif_entry_new_mem (ExifMem *); + +/*! Increase reference counter for #ExifEntry. + * + * \param[in] entry #ExifEntry + * + * \see exif_entry_unref + */ +void exif_entry_ref (ExifEntry *entry); + +/*! Decrease reference counter for #ExifEntry. + * When the reference count drops to zero, free the entry. + * + * \param[in] entry #ExifEntry + */ +void exif_entry_unref (ExifEntry *entry); + +/*! Actually free the #ExifEntry. + * + * \deprecated Should not be called directly. Use #exif_entry_ref and + * #exif_entry_unref instead. + * + * \param[in] entry EXIF entry + */ +void exif_entry_free (ExifEntry *entry); + +/*! Initialize an empty #ExifEntry with default data in the correct format + * for the given tag. If the entry is already initialized, this function + * does nothing. + * This call allocates memory for the \c data element of the given #ExifEntry. + * That memory is freed at the same time as the #ExifEntry. + * + * \param[out] e entry to initialize + * \param[in] tag tag number to initialize as + */ +void exif_entry_initialize (ExifEntry *e, ExifTag tag); + +/*! Fix the type or format of the given EXIF entry to bring it into spec. + * If the data for this EXIF tag is in of the wrong type or is in an invalid + * format according to the EXIF specification, then it is converted to make it + * valid. This may involve, for example, converting an EXIF_FORMAT_LONG into a + * EXIF_FORMAT_SHORT. If the tag is unknown, its value is untouched. + * + * \note Unfortunately, some conversions are to a type with a more restricted + * range, which could have the side effect that the converted data becomes + * invalid. This is unlikely as the range of each tag in the standard is + * designed to encompass all likely data. + * + * \param[in,out] entry EXIF entry + */ +void exif_entry_fix (ExifEntry *entry); + + +/* For your convenience */ + +/*! Return a localized textual representation of the value of the EXIF entry. + * This is meant for display to the user. The format of each tag is subject + * to change between locales and in newer versions of libexif. Users who + * require the tag data in an unambiguous form should access the data members + * of the #ExifEntry structure directly. + * + * \warning The character set of the returned string may be in + * the encoding of the current locale or the native encoding + * of the camera. + * \bug The EXIF_TAG_XP_* tags are currently always returned in UTF-8, + * regardless of locale, and code points above U+FFFF are not + * supported. + * + * \param[in] entry EXIF entry + * \param[out] val buffer in which to store value + * \param[in] maxlen length of the buffer val + * \return val pointer + */ +const char *exif_entry_get_value (ExifEntry *entry, char *val, + unsigned int maxlen); + +/*! Dump text representation of #ExifEntry to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] entry EXIF tag data + * \param[in] indent how many levels deep to indent the data + */ +void exif_entry_dump (ExifEntry *entry, unsigned int indent); + +/*! Return the IFD number of the given #ExifEntry + * + * \param[in] e an #ExifEntry* + * \return #ExifIfd, or #EXIF_IFD_COUNT on error + */ +#define exif_entry_get_ifd(e) ((e)?exif_content_get_ifd((e)->parent):EXIF_IFD_COUNT) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_ENTRY_H__ */ diff --git a/libexifa/libexif/exif-format.h b/libexifa/libexif/exif-format.h new file mode 100755 index 0000000..b7a79a4 --- /dev/null +++ b/libexifa/libexif/exif-format.h @@ -0,0 +1,65 @@ +/*! \file exif-format.h + * \brief Handling native EXIF data types + */ +/* + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_FORMAT_H__ +#define __EXIF_FORMAT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! EXIF tag data formats */ +typedef enum { + EXIF_FORMAT_BYTE = 1, + EXIF_FORMAT_ASCII = 2, + EXIF_FORMAT_SHORT = 3, + EXIF_FORMAT_LONG = 4, + EXIF_FORMAT_RATIONAL = 5, + EXIF_FORMAT_SBYTE = 6, + EXIF_FORMAT_UNDEFINED = 7, + EXIF_FORMAT_SSHORT = 8, + EXIF_FORMAT_SLONG = 9, + EXIF_FORMAT_SRATIONAL = 10, + EXIF_FORMAT_FLOAT = 11, + EXIF_FORMAT_DOUBLE = 12 +} ExifFormat; + +/*! Return a textual representation of the given EXIF data type. + * + * \param[in] format EXIF data format + * \return localized textual name + */ +const char *exif_format_get_name (ExifFormat format); + +/*! Return the raw size of the given EXIF data type. + * + * \param[in] format EXIF data format + * \return size in bytes + */ +unsigned char exif_format_get_size (ExifFormat format); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_FORMAT_H__ */ diff --git a/libexifa/libexif/exif-ifd.h b/libexifa/libexif/exif-ifd.h new file mode 100755 index 0000000..26c4053 --- /dev/null +++ b/libexifa/libexif/exif-ifd.h @@ -0,0 +1,43 @@ +/* exif-ifd.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_IFD_H__ +#define __EXIF_IFD_H__ + +/*! Possible EXIF Image File Directories */ +typedef enum { + EXIF_IFD_0 = 0, /*!< */ + EXIF_IFD_1, /*!< */ + EXIF_IFD_EXIF, /*!< */ + EXIF_IFD_GPS, /*!< */ + EXIF_IFD_INTEROPERABILITY, /*!< */ + EXIF_IFD_COUNT /*!< Not a real value, just (max_value + 1). */ +} ExifIfd; + +/*! Return a textual name of the given IFD. The name is a short, unique, + * non-localized text string containing only US-ASCII alphanumeric + * characters. + * + * \param[in] ifd IFD + * \return textual name of the IFD + */ +const char *exif_ifd_get_name (ExifIfd ifd); + +#endif /* __EXIF_IFD_H__ */ diff --git a/libexifa/libexif/exif-loader.h b/libexifa/libexif/exif-loader.h new file mode 100755 index 0000000..62ee87c --- /dev/null +++ b/libexifa/libexif/exif-loader.h @@ -0,0 +1,128 @@ +/*! \file exif-loader.h + * \brief Defines the ExifLoader type + */ +/* + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_LOADER_H__ +#define __EXIF_LOADER_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Data used by the loader interface */ +typedef struct _ExifLoader ExifLoader; + +/*! Allocate a new #ExifLoader. + * + * \return allocated ExifLoader + */ +ExifLoader *exif_loader_new (void); + +/*! Allocate a new #ExifLoader using the specified memory allocator. + * + * \param[in] mem the ExifMem + * \return allocated ExifLoader + */ +ExifLoader *exif_loader_new_mem (ExifMem *mem); + +/*! Increase the refcount of the #ExifLoader. + * + * \param[in] loader the ExifLoader to increase the refcount of. + */ +void exif_loader_ref (ExifLoader *loader); + +/*! Decrease the refcount of the #ExifLoader. + * If the refcount reaches 0, the loader is freed. + * + * \param[in] loader ExifLoader for which to decrease the refcount + */ +void exif_loader_unref (ExifLoader *loader); + +/*! Load a file into the given #ExifLoader from the filesystem. + * The relevant data is copied in raw form into the #ExifLoader. + * + * \param[in] loader loader to write to + * \param[in] fname path to the file to read + */ +void exif_loader_write_file (ExifLoader *loader, const char *fname); + +/*! Load a buffer into the #ExifLoader from a memory buffer. + * The relevant data is copied in raw form into the #ExifLoader. + * + * \param[in] loader loader to write to + * \param[in] buf buffer to read from + * \param[in] sz size of the buffer + * \return 1 while EXIF data is read (or while there is still hope that + * there will be EXIF data later on), 0 otherwise. + */ +unsigned char exif_loader_write (ExifLoader *loader, unsigned char *buf, unsigned int sz); + +/*! Free any data previously loaded and reset the #ExifLoader to its + * newly-initialized state. + * + * \param[in] loader the loader + */ +void exif_loader_reset (ExifLoader *loader); + +/*! Create an #ExifData from the data in the loader. The loader must + * already contain data from a previous call to #exif_loader_write_file + * or #exif_loader_write. + * + * \note The #ExifData returned is created using its default options, which + * may take effect before the data is returned. If other options are desired, + * an #ExifData must be created explicitly and data extracted from the loader + * using #exif_loader_get_buf instead. + * + * \param[in] loader the loader + * \return allocated ExifData + * + * \see exif_loader_get_buf + */ +ExifData *exif_loader_get_data (ExifLoader *loader); + +/*! Return the raw data read by the loader. The returned pointer is only + * guaranteed to be valid until the next call to a function modifying + * this #ExifLoader. Either or both of buf and buf_size may be NULL on + * entry, in which case that value is not returned. + * + * \param[in] loader the loader + * \param[out] buf read-only pointer to the data read by the loader, or NULL + * in case of error + * \param[out] buf_size size of the data at buf, or 0 in case of error + */ +void exif_loader_get_buf (ExifLoader *loader, const unsigned char **buf, + unsigned int *buf_size); + +/*! Set the log message object used by this #ExifLoader. + * \param[in] loader the loader + * \param[in] log #ExifLog + */ +void exif_loader_log (ExifLoader *loader, ExifLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_LOADER_H__ */ diff --git a/libexifa/libexif/exif-log.h b/libexifa/libexif/exif-log.h new file mode 100755 index 0000000..9e71ad6 --- /dev/null +++ b/libexifa/libexif/exif-log.h @@ -0,0 +1,116 @@ +/*! \file exif-log.h + * \brief Log message infrastructure + */ +/* + * Copyright (c) 2004 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_LOG_H__ +#define __EXIF_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +/*! State maintained by the logging interface */ +typedef struct _ExifLog ExifLog; + +/*! Create a new logging instance. + * \see exif_log_free + * + * \return new instance of #ExifLog + */ +ExifLog *exif_log_new (void); +ExifLog *exif_log_new_mem (ExifMem *); +void exif_log_ref (ExifLog *log); +void exif_log_unref (ExifLog *log); + +/*! Delete instance of #ExifLog. + * \see exif_log_new + * + * \param[in] log #ExifLog + * \return new instance of #ExifLog + */ +void exif_log_free (ExifLog *log); + +typedef enum { + EXIF_LOG_CODE_NONE, + EXIF_LOG_CODE_DEBUG, + EXIF_LOG_CODE_NO_MEMORY, + EXIF_LOG_CODE_CORRUPT_DATA +} ExifLogCode; + +/*! Return a textual description of the given class of error log. + * + * \param[in] code logging message class + * \return textual description of the log class + */ +const char *exif_log_code_get_title (ExifLogCode code); + +/*! Return a verbose description of the given class of error log. + * + * \param[in] code logging message class + * \return verbose description of the log class + */ +const char *exif_log_code_get_message (ExifLogCode code); + +/*! Log callback function prototype. + */ +typedef void (* ExifLogFunc) (ExifLog *log, ExifLogCode, const char *domain, + const char *format, va_list args, void *data); + +/*! Register log callback function. + * Calls to the log callback function are purely for diagnostic purposes. + * + * \param[in] log logging state variable + * \param[in] func callback function to set + * \param[in] data data to pass into callback function + */ +void exif_log_set_func (ExifLog *log, ExifLogFunc func, void *data); + +#ifndef NO_VERBOSE_TAG_STRINGS +void exif_log (ExifLog *log, ExifLogCode, const char *domain, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,4,5))) +#endif +; +#else +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define exif_log(...) do { } while (0) +#elif defined(__GNUC__) +#define exif_log(x...) do { } while (0) +#else +#define exif_log (void) +#endif +#endif + +void exif_logv (ExifLog *log, ExifLogCode, const char *domain, + const char *format, va_list args); + +/* For your convenience */ +#define EXIF_LOG_NO_MEMORY(l,d,s) exif_log ((l), EXIF_LOG_CODE_NO_MEMORY, (d), "Could not allocate %lu byte(s).", (unsigned long)(s)) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_LOG_H__ */ diff --git a/libexifa/libexif/exif-mem.h b/libexifa/libexif/exif-mem.h new file mode 100755 index 0000000..fd8f2fa --- /dev/null +++ b/libexifa/libexif/exif-mem.h @@ -0,0 +1,90 @@ +/*! \file exif-mem.h + * \brief Define the ExifMem data type and the associated functions. + * ExifMem defines the memory management functions used within libexif. + */ +/* exif-mem.h + * + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MEM_H__ +#define __EXIF_MEM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Should work like calloc() + * + * \param[in] s the size of the block to allocate. + * \return the allocated memory and initialized. + */ +typedef void * (* ExifMemAllocFunc) (ExifLong s); + +/*! Should work like realloc() + * + * \param[in] p the pointer to reallocate + * \param[in] s the size of the reallocated block + * \return allocated memory + */ +typedef void * (* ExifMemReallocFunc) (void *p, ExifLong s); + +/*! Free method for ExifMem + * + * \param[in] p the pointer to free + * \return the freed pointer + */ +typedef void (* ExifMemFreeFunc) (void *p); + +/*! ExifMem define a memory allocator */ +typedef struct _ExifMem ExifMem; + +/*! Create a new ExifMem + * + * \param[in] a the allocator function + * \param[in] r the reallocator function + * \param[in] f the free function + */ +ExifMem *exif_mem_new (ExifMemAllocFunc a, ExifMemReallocFunc r, + ExifMemFreeFunc f); +/*! Refcount an ExifMem + */ +void exif_mem_ref (ExifMem *); + +/*! Unrefcount an ExifMem. + * If the refcount reaches 0, the ExifMem is freed + */ +void exif_mem_unref (ExifMem *); + +void *exif_mem_alloc (ExifMem *m, ExifLong s); +void *exif_mem_realloc (ExifMem *m, void *p, ExifLong s); +void exif_mem_free (ExifMem *m, void *p); + +/*! Create a new ExifMem with default values for your convenience + * + * \return return a new default ExifMem + */ +ExifMem *exif_mem_new_default (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MEM_H__ */ diff --git a/libexifa/libexif/exif-mnote-data-priv.h b/libexifa/libexif/exif-mnote-data-priv.h new file mode 100755 index 0000000..7462c97 --- /dev/null +++ b/libexifa/libexif/exif-mnote-data-priv.h @@ -0,0 +1,86 @@ +/* exif-mnote-data-priv.h + * + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_PRIV_H__ +#define __EXIF_MNOTE_DATA_PRIV_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + +/*! \internal */ +typedef struct _ExifMnoteDataMethods ExifMnoteDataMethods; + +/*! \internal */ +struct _ExifMnoteDataMethods { + + /* Life cycle */ + void (* free) (ExifMnoteData *); + + /* Modification */ + void (* save) (ExifMnoteData *, unsigned char **, unsigned int *); + void (* load) (ExifMnoteData *, const unsigned char *, unsigned int); + void (* set_offset) (ExifMnoteData *, unsigned int); + void (* set_byte_order) (ExifMnoteData *, ExifByteOrder); + + /* Query */ + unsigned int (* count) (ExifMnoteData *); + unsigned int (* get_id) (ExifMnoteData *, unsigned int); + const char * (* get_name) (ExifMnoteData *, unsigned int); + const char * (* get_title) (ExifMnoteData *, unsigned int); + const char * (* get_description) (ExifMnoteData *, unsigned int); + char * (* get_value) (ExifMnoteData *, unsigned int, char *val, unsigned int maxlen); +}; + +/*! \internal */ +typedef struct _ExifMnoteDataPriv ExifMnoteDataPriv; + +/*! \internal */ +struct _ExifMnoteData +{ + ExifMnoteDataPriv *priv; + + ExifMnoteDataMethods methods; + + /* Logging */ + ExifLog *log; + + /* Memory management */ + ExifMem *mem; +}; + +/*! \internal */ +void exif_mnote_data_construct (ExifMnoteData *, ExifMem *mem); + +/*! \internal */ +void exif_mnote_data_set_byte_order (ExifMnoteData *, ExifByteOrder); + +/*! \internal */ +void exif_mnote_data_set_offset (ExifMnoteData *, unsigned int); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MNOTE_PRIV_H__ */ diff --git a/libexifa/libexif/exif-mnote-data.h b/libexifa/libexif/exif-mnote-data.h new file mode 100755 index 0000000..19e1de5 --- /dev/null +++ b/libexifa/libexif/exif-mnote-data.h @@ -0,0 +1,122 @@ +/*! \file exif-mnote-data.h + * \brief Handling EXIF MakerNote tags + */ +/* + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_H__ +#define __EXIF_MNOTE_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +/*! Data found in the MakerNote tag */ +typedef struct _ExifMnoteData ExifMnoteData; + +void exif_mnote_data_ref (ExifMnoteData *); +void exif_mnote_data_unref (ExifMnoteData *); + +/*! Load the MakerNote data from a memory buffer. + * + * \param[in] d MakerNote data + * \param[in] buf pointer to raw MakerNote tag data + * \param[in] buf_siz number of bytes of data at buf + */ +void exif_mnote_data_load (ExifMnoteData *d, const unsigned char *buf, + unsigned int buf_siz); + +/*! + * Save the raw MakerNote data into a memory buffer. The buffer is + * allocated by this function and must subsequently be freed by the + * caller. + * + * \param[in,out] d extract the data from this structure + * \param[out] buf pointer to buffer pointer containing MakerNote data on return + * \param[out] buf_siz pointer to the size of the buffer + */ +void exif_mnote_data_save (ExifMnoteData *d, unsigned char **buf, + unsigned int *buf_siz); + +/*! Return the number of tags in the MakerNote. + * + * \param[in] d MakerNote data + * \return number of tags, or 0 if no MakerNote or the type is not supported + */ +unsigned int exif_mnote_data_count (ExifMnoteData *d); + +/*! Return the MakerNote tag number for the tag at the specified index within + * the MakerNote. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return MakerNote tag number + */ +unsigned int exif_mnote_data_get_id (ExifMnoteData *d, unsigned int n); + +/*! Returns textual name of the given MakerNote tag. The name is a short, + * unique (within this type of MakerNote), non-localized text string + * containing only US-ASCII alphanumeric characters. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual name of the tag + */ +const char *exif_mnote_data_get_name (ExifMnoteData *d, unsigned int n); + +/*! Returns textual title of the given MakerNote tag. + * The title is a short, localized textual description of the tag. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual name of the tag + */ +const char *exif_mnote_data_get_title (ExifMnoteData *d, unsigned int n); + +/*! Returns verbose textual description of the given MakerNote tag. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual description of the tag + */ +const char *exif_mnote_data_get_description (ExifMnoteData *d, unsigned int n); + +/*! Return a textual representation of the value of the MakerNote entry. + * + * \warning The character set of the returned string may be in + * the encoding of the current locale or the native encoding + * of the camera. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \param[out] val buffer in which to store value + * \param[in] maxlen length of the buffer val + * \return val pointer, or NULL on error + */ +char *exif_mnote_data_get_value (ExifMnoteData *d, unsigned int n, char *val, unsigned int maxlen); + +void exif_mnote_data_log (ExifMnoteData *, ExifLog *); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MNOTE_DATA_H__ */ diff --git a/libexifa/libexif/exif-system.h b/libexifa/libexif/exif-system.h new file mode 100755 index 0000000..81fa703 --- /dev/null +++ b/libexifa/libexif/exif-system.h @@ -0,0 +1,32 @@ +/*! \file exif-system.h + * \brief System specific definitions, not for installation! + */ +/* + * Copyright (c) 2007 Hans Ulrich Niedermann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef EXIF_SYSTEM_H +#define EXIF_SYSTEM_H + +#if defined(__GNUC__) && (__GNUC__ >= 2) +# define UNUSED(param) UNUSED_PARAM_##param __attribute__((unused)) +#else +# define UNUSED(param) param +#endif + +#endif /* !defined(EXIF_SYSTEM_H) */ diff --git a/libexifa/libexif/exif-tag.h b/libexifa/libexif/exif-tag.h new file mode 100755 index 0000000..d8b8657 --- /dev/null +++ b/libexifa/libexif/exif-tag.h @@ -0,0 +1,287 @@ +/*! \file exif-tag.h + * \brief Handling EXIF tags + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_TAG_H__ +#define __EXIF_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +/*! EXIF tags */ +typedef enum { + EXIF_TAG_INTEROPERABILITY_INDEX = 0x0001, + EXIF_TAG_INTEROPERABILITY_VERSION = 0x0002, + EXIF_TAG_NEW_SUBFILE_TYPE = 0x00fe, + EXIF_TAG_IMAGE_WIDTH = 0x0100, + EXIF_TAG_IMAGE_LENGTH = 0x0101, + EXIF_TAG_BITS_PER_SAMPLE = 0x0102, + EXIF_TAG_COMPRESSION = 0x0103, + EXIF_TAG_PHOTOMETRIC_INTERPRETATION = 0x0106, + EXIF_TAG_FILL_ORDER = 0x010a, + EXIF_TAG_DOCUMENT_NAME = 0x010d, + EXIF_TAG_IMAGE_DESCRIPTION = 0x010e, + EXIF_TAG_MAKE = 0x010f, + EXIF_TAG_MODEL = 0x0110, + EXIF_TAG_STRIP_OFFSETS = 0x0111, + EXIF_TAG_ORIENTATION = 0x0112, + EXIF_TAG_SAMPLES_PER_PIXEL = 0x0115, + EXIF_TAG_ROWS_PER_STRIP = 0x0116, + EXIF_TAG_STRIP_BYTE_COUNTS = 0x0117, + EXIF_TAG_X_RESOLUTION = 0x011a, + EXIF_TAG_Y_RESOLUTION = 0x011b, + EXIF_TAG_PLANAR_CONFIGURATION = 0x011c, + EXIF_TAG_RESOLUTION_UNIT = 0x0128, + EXIF_TAG_TRANSFER_FUNCTION = 0x012d, + EXIF_TAG_SOFTWARE = 0x0131, + EXIF_TAG_DATE_TIME = 0x0132, + EXIF_TAG_ARTIST = 0x013b, + EXIF_TAG_WHITE_POINT = 0x013e, + EXIF_TAG_PRIMARY_CHROMATICITIES = 0x013f, + EXIF_TAG_SUB_IFDS = 0x014a, + EXIF_TAG_TRANSFER_RANGE = 0x0156, + EXIF_TAG_JPEG_PROC = 0x0200, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT = 0x0201, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = 0x0202, + EXIF_TAG_YCBCR_COEFFICIENTS = 0x0211, + EXIF_TAG_YCBCR_SUB_SAMPLING = 0x0212, + EXIF_TAG_YCBCR_POSITIONING = 0x0213, + EXIF_TAG_REFERENCE_BLACK_WHITE = 0x0214, + EXIF_TAG_XML_PACKET = 0x02bc, + EXIF_TAG_RELATED_IMAGE_FILE_FORMAT = 0x1000, + EXIF_TAG_RELATED_IMAGE_WIDTH = 0x1001, + EXIF_TAG_RELATED_IMAGE_LENGTH = 0x1002, + EXIF_TAG_CFA_REPEAT_PATTERN_DIM = 0x828d, + EXIF_TAG_CFA_PATTERN = 0x828e, + EXIF_TAG_BATTERY_LEVEL = 0x828f, + EXIF_TAG_COPYRIGHT = 0x8298, + EXIF_TAG_EXPOSURE_TIME = 0x829a, + EXIF_TAG_FNUMBER = 0x829d, + EXIF_TAG_IPTC_NAA = 0x83bb, + EXIF_TAG_IMAGE_RESOURCES = 0x8649, + EXIF_TAG_EXIF_IFD_POINTER = 0x8769, + EXIF_TAG_INTER_COLOR_PROFILE = 0x8773, + EXIF_TAG_EXPOSURE_PROGRAM = 0x8822, + EXIF_TAG_SPECTRAL_SENSITIVITY = 0x8824, + EXIF_TAG_GPS_INFO_IFD_POINTER = 0x8825, + EXIF_TAG_ISO_SPEED_RATINGS = 0x8827, + EXIF_TAG_OECF = 0x8828, + EXIF_TAG_TIME_ZONE_OFFSET = 0x882a, + EXIF_TAG_EXIF_VERSION = 0x9000, + EXIF_TAG_DATE_TIME_ORIGINAL = 0x9003, + EXIF_TAG_DATE_TIME_DIGITIZED = 0x9004, + EXIF_TAG_COMPONENTS_CONFIGURATION = 0x9101, + EXIF_TAG_COMPRESSED_BITS_PER_PIXEL = 0x9102, + EXIF_TAG_SHUTTER_SPEED_VALUE = 0x9201, + EXIF_TAG_APERTURE_VALUE = 0x9202, + EXIF_TAG_BRIGHTNESS_VALUE = 0x9203, + EXIF_TAG_EXPOSURE_BIAS_VALUE = 0x9204, + EXIF_TAG_MAX_APERTURE_VALUE = 0x9205, + EXIF_TAG_SUBJECT_DISTANCE = 0x9206, + EXIF_TAG_METERING_MODE = 0x9207, + EXIF_TAG_LIGHT_SOURCE = 0x9208, + EXIF_TAG_FLASH = 0x9209, + EXIF_TAG_FOCAL_LENGTH = 0x920a, + EXIF_TAG_SUBJECT_AREA = 0x9214, + EXIF_TAG_TIFF_EP_STANDARD_ID = 0x9216, + EXIF_TAG_MAKER_NOTE = 0x927c, + EXIF_TAG_USER_COMMENT = 0x9286, + EXIF_TAG_SUB_SEC_TIME = 0x9290, + EXIF_TAG_SUB_SEC_TIME_ORIGINAL = 0x9291, + EXIF_TAG_SUB_SEC_TIME_DIGITIZED = 0x9292, + EXIF_TAG_XP_TITLE = 0x9c9b, + EXIF_TAG_XP_COMMENT = 0x9c9c, + EXIF_TAG_XP_AUTHOR = 0x9c9d, + EXIF_TAG_XP_KEYWORDS = 0x9c9e, + EXIF_TAG_XP_SUBJECT = 0x9c9f, + EXIF_TAG_FLASH_PIX_VERSION = 0xa000, + EXIF_TAG_COLOR_SPACE = 0xa001, + EXIF_TAG_PIXEL_X_DIMENSION = 0xa002, + EXIF_TAG_PIXEL_Y_DIMENSION = 0xa003, + EXIF_TAG_RELATED_SOUND_FILE = 0xa004, + EXIF_TAG_INTEROPERABILITY_IFD_POINTER = 0xa005, + EXIF_TAG_FLASH_ENERGY = 0xa20b, + EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE = 0xa20c, + EXIF_TAG_FOCAL_PLANE_X_RESOLUTION = 0xa20e, + EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION = 0xa20f, + EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT = 0xa210, + EXIF_TAG_SUBJECT_LOCATION = 0xa214, + EXIF_TAG_EXPOSURE_INDEX = 0xa215, + EXIF_TAG_SENSING_METHOD = 0xa217, + EXIF_TAG_FILE_SOURCE = 0xa300, + EXIF_TAG_SCENE_TYPE = 0xa301, + EXIF_TAG_NEW_CFA_PATTERN = 0xa302, + EXIF_TAG_CUSTOM_RENDERED = 0xa401, + EXIF_TAG_EXPOSURE_MODE = 0xa402, + EXIF_TAG_WHITE_BALANCE = 0xa403, + EXIF_TAG_DIGITAL_ZOOM_RATIO = 0xa404, + EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM = 0xa405, + EXIF_TAG_SCENE_CAPTURE_TYPE = 0xa406, + EXIF_TAG_GAIN_CONTROL = 0xa407, + EXIF_TAG_CONTRAST = 0xa408, + EXIF_TAG_SATURATION = 0xa409, + EXIF_TAG_SHARPNESS = 0xa40a, + EXIF_TAG_DEVICE_SETTING_DESCRIPTION = 0xa40b, + EXIF_TAG_SUBJECT_DISTANCE_RANGE = 0xa40c, + EXIF_TAG_IMAGE_UNIQUE_ID = 0xa420, + EXIF_TAG_GAMMA = 0xa500, + EXIF_TAG_PRINT_IMAGE_MATCHING = 0xc4a5, + EXIF_TAG_PADDING = 0xea1c +} ExifTag; + +/* GPS tags overlap with above ones. */ +#define EXIF_TAG_GPS_VERSION_ID 0x0000 +#define EXIF_TAG_GPS_LATITUDE_REF 0x0001 /* INTEROPERABILITY_INDEX */ +#define EXIF_TAG_GPS_LATITUDE 0x0002 /* INTEROPERABILITY_VERSION */ +#define EXIF_TAG_GPS_LONGITUDE_REF 0x0003 +#define EXIF_TAG_GPS_LONGITUDE 0x0004 +#define EXIF_TAG_GPS_ALTITUDE_REF 0x0005 +#define EXIF_TAG_GPS_ALTITUDE 0x0006 +#define EXIF_TAG_GPS_TIME_STAMP 0x0007 +#define EXIF_TAG_GPS_SATELLITES 0x0008 +#define EXIF_TAG_GPS_STATUS 0x0009 +#define EXIF_TAG_GPS_MEASURE_MODE 0x000a +#define EXIF_TAG_GPS_DOP 0x000b +#define EXIF_TAG_GPS_SPEED_REF 0x000c +#define EXIF_TAG_GPS_SPEED 0x000d +#define EXIF_TAG_GPS_TRACK_REF 0x000e +#define EXIF_TAG_GPS_TRACK 0x000f +#define EXIF_TAG_GPS_IMG_DIRECTION_REF 0x0010 +#define EXIF_TAG_GPS_IMG_DIRECTION 0x0011 +#define EXIF_TAG_GPS_MAP_DATUM 0x0012 +#define EXIF_TAG_GPS_DEST_LATITUDE_REF 0x0013 +#define EXIF_TAG_GPS_DEST_LATITUDE 0x0014 +#define EXIF_TAG_GPS_DEST_LONGITUDE_REF 0x0015 +#define EXIF_TAG_GPS_DEST_LONGITUDE 0x0016 +#define EXIF_TAG_GPS_DEST_BEARING_REF 0x0017 +#define EXIF_TAG_GPS_DEST_BEARING 0x0018 +#define EXIF_TAG_GPS_DEST_DISTANCE_REF 0x0019 +#define EXIF_TAG_GPS_DEST_DISTANCE 0x001a +#define EXIF_TAG_GPS_PROCESSING_METHOD 0x001b +#define EXIF_TAG_GPS_AREA_INFORMATION 0x001c +#define EXIF_TAG_GPS_DATE_STAMP 0x001d +#define EXIF_TAG_GPS_DIFFERENTIAL 0x001e + +/*! What level of support a tag enjoys in the EXIF standard */ +typedef enum { + /*! The meaning of this tag is unknown */ + EXIF_SUPPORT_LEVEL_UNKNOWN = 0, + + /*! This tag is not allowed in the given IFD */ + EXIF_SUPPORT_LEVEL_NOT_RECORDED, + + /*! This tag is mandatory in the given IFD */ + EXIF_SUPPORT_LEVEL_MANDATORY, + + /*! This tag is optional in the given IFD */ + EXIF_SUPPORT_LEVEL_OPTIONAL +} ExifSupportLevel; + +/*! Return the tag ID given its unique textual name. + * + * \param[in] name tag name + * \return tag ID, or 0 if tag not found + * \note The tag not found value cannot be distinguished from a legitimate + * tag number 0. + */ +ExifTag exif_tag_from_name (const char *name); + +/*! Return a textual name of the given tag when found in the given IFD. The + * name is a short, unique, non-localized text string containing only + * US-ASCII alphanumeric characters. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual name of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_name_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return a textual title of the given tag when found in the given IFD. + * The title is a short, localized description of the tag. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual title of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_title_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return a verbose textual description of the given tag when found in the + * given IFD. The description is a verbose, localized description of the tag. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual description of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_description_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return whether the given tag is mandatory or not in the given IFD and + * data type according to the EXIF specification. If the IFD given is + * EXIF_IFD_COUNT, the result is EXIF_SUPPORT_LEVEL_UNKNOWN. If the data + * type is EXIF_DATA_TYPE_UNKNOWN, the result is + * EXIF_SUPPORT_LEVEL_UNKNOWN unless the support level is the same for + * all data types. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD or EXIF_IFD_COUNT + * \param[in] t data type or EXIF_DATA_TYPE_UNKNOWN + * \return the level of support for this tag + */ +ExifSupportLevel exif_tag_get_support_level_in_ifd (ExifTag tag, ExifIfd ifd, + ExifDataType t); + +/* Don't use these functions. They are here for compatibility only. */ + +/*! \deprecated Use #exif_tag_get_name_in_ifd instead */ +const char *exif_tag_get_name (ExifTag tag); + +/*! \deprecated Use #exif_tag_get_title_in_ifd instead */ +const char *exif_tag_get_title (ExifTag tag); + +/*! \deprecated Use #exif_tag_get_description_in_ifd instead */ +const char *exif_tag_get_description (ExifTag tag); + + +/* For now, do not use these functions. */ + +/*! \internal */ +ExifTag exif_tag_table_get_tag (unsigned int n); + +/*! \internal */ +const char *exif_tag_table_get_name (unsigned int n); + +/*! \internal */ +unsigned int exif_tag_table_count (void); + + +/* Don't use these definitions. They are here for compatibility only. */ + +/*! \deprecated Use EXIF_TAG_PRINT_IMAGE_MATCHING instead. */ +#define EXIF_TAG_UNKNOWN_C4A5 EXIF_TAG_PRINT_IMAGE_MATCHING + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_TAG_H__ */ diff --git a/libexifa/libexif/exif-utils.h b/libexifa/libexif/exif-utils.h new file mode 100755 index 0000000..7861564 --- /dev/null +++ b/libexifa/libexif/exif-utils.h @@ -0,0 +1,194 @@ +/*! \file exif-utils.h + * \brief EXIF data manipulation functions and types + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_UTILS_H__ +#define __EXIF_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + + +/* If these definitions don't work for you, please let us fix the + * macro generating _stdint.h */ + +/*! EXIF Unsigned Byte data type */ +typedef unsigned char ExifByte; /* 1 byte */ + +/*! EXIF Signed Byte data type */ +typedef signed char ExifSByte; /* 1 byte */ + +/*! EXIF Text String data type */ +typedef char * ExifAscii; + +/*! EXIF Unsigned Short data type */ +typedef uint16_t ExifShort; /* 2 bytes */ + +/*! EXIF Signed Short data type */ +typedef int16_t ExifSShort; /* 2 bytes */ + +/*! EXIF Unsigned Long data type */ +typedef uint32_t ExifLong; /* 4 bytes */ + +/*! EXIF Signed Long data type */ +typedef int32_t ExifSLong; /* 4 bytes */ + +/*! EXIF Unsigned Rational data type */ +typedef struct {ExifLong numerator; ExifLong denominator;} ExifRational; + +typedef char ExifUndefined; /* 1 byte */ + +/*! EXIF Signed Rational data type */ +typedef struct {ExifSLong numerator; ExifSLong denominator;} ExifSRational; + + +/*! Retrieve an #ExifShort value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifShort exif_get_short (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSShort value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSShort exif_get_sshort (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifLong value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifLong exif_get_long (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSLong value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSLong exif_get_slong (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifRational value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifRational exif_get_rational (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSRational value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSRational exif_get_srational (const unsigned char *b, ExifByteOrder order); + +/*! Store an ExifShort value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_short (unsigned char *b, ExifByteOrder order, + ExifShort value); + +/*! Store an ExifSShort value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_sshort (unsigned char *b, ExifByteOrder order, + ExifSShort value); + +/*! Store an ExifLong value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_long (unsigned char *b, ExifByteOrder order, + ExifLong value); + +/*! Store an ExifSLong value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_slong (unsigned char *b, ExifByteOrder order, + ExifSLong value); + +/*! Store an ExifRational value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_rational (unsigned char *b, ExifByteOrder order, + ExifRational value); + +/*! Store an ExifSRational value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_srational (unsigned char *b, ExifByteOrder order, + ExifSRational value); + +/*! \internal */ +void exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen); + +/* Please do not use this function outside of the library. */ + +/*! \internal */ +void exif_array_set_byte_order (ExifFormat, unsigned char *, unsigned int, + ExifByteOrder o_orig, ExifByteOrder o_new); + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/* For compatibility with older versions */ + +/*! \deprecated Use EXIF_TAG_SUB_SEC_TIME instead. */ +#define EXIF_TAG_SUBSEC_TIME EXIF_TAG_SUB_SEC_TIME + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_UTILS_H__ */ diff --git a/libexifa/libexif/exif.h b/libexifa/libexif/exif.h new file mode 100755 index 0000000..1c8e0f6 --- /dev/null +++ b/libexifa/libexif/exif.h @@ -0,0 +1,87 @@ +/*! \file exif.h exif/exif.h + * \brief Dummy header file for documentation purposes + * \date 2007 + * \author Hans Ulrich Niedermann, et. al. + * + * \mainpage The libexif library + * + * \section general_notes General Notes + * + * This documentation is work in progress, as is the code itself. + * + * \section using_libexif Using libexif + * + * \#include + * + * libexif provides a libexif.pc file for use with pkgconfig on the + * libexif installation. If you are using libtool to build your + * package, you can also make use of libexif-uninstalled.pc. + * + * An application using libexif would typically first create an #ExifLoader to + * load EXIF data into memory. From there, it would extract that data as + * an #ExifData to start manipulating it. Each IFD is represented by its own + * #ExifContent within that #ExifData, which contains all the tag data in + * #ExifEntry form. If the MakerNote data is required, an #ExifMnoteData + * can be extracted from the #ExifData and manipulated with the MakerNote + * functions. + * + * libexif is written in C using an object-based style that defines + * sets of functions that operate on each data structure. + * + * \section data_structures Primary Data Structures + * + * #ExifLoader + * State maintained by the loader interface while importing EXIF data + * from an external file or memory + * + * #ExifData + * The entirety of EXIF data found in an image + * + * #ExifContent + * All EXIF tags in a single IFD + * + * #ExifEntry + * Data found in a single EXIF tag + * + * #ExifMnoteData + * All data found in the MakerNote tag + * + * #ExifLog + * State maintained by the logging interface + * + * \section string_conventions String Conventions + * + * Strings are 8 bit characters ("char*"). When libexif is compiled with + * NLS, character set and encoding are as set in the current locale, + * except for strings that come directly from the data in EXIF + * tags which are generally returned in raw form. Most EXIF strings are + * defined to be plain 7-bit ASCII so this raw form should be acceptable in + * any UNIX locale, but some software ignores the specification and + * writes 8-bit characters. It is up to the application to detect this + * and deal with it intelligently. + * + * \section memory_management Memory Management Patterns + * + * For pointers to data objects, libexif uses reference counting. The + * pattern is to use the foo_new() function to create a data object, + * foo_ref() to increase the reference counter, and foo_unref() to + * decrease the reference counter and possibly free(3)ing the memory. + * + * Libexif by default relies on the calloc(3), realloc(3), and free(3) + * functions, but the libexif user can tell libexif to use their + * special memory management functions at runtime. + * + * \section thread_safety Thread Safety + * + * libexif is thread safe when the underlying C library is also thread safe. + * Some C libraries may require defining a special macro (like _REENTRANT) + * to ensure this, or may require linking to a special thread-safe version of + * the library. + * + * The programmer must ensure that each object allocated by libexif is only + * used in a single thread at once. For example, an ExifData* allocated + * in one thread can't be used in a second thread if there is any chance + * that the first thread could use it at the same time. Multiple threads + * can use libexif without issues if they never share handles. + * + */ diff --git a/libexifa/libexif/fuji/exif-mnote-data-fuji.h b/libexifa/libexif/fuji/exif-mnote-data-fuji.h new file mode 100755 index 0000000..2a7cd3e --- /dev/null +++ b/libexifa/libexif/fuji/exif-mnote-data-fuji.h @@ -0,0 +1,53 @@ +/* exif-mnote-data-fuji.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_CONTENT_H__ +#define __MNOTE_FUJI_CONTENT_H__ + +#include +#include +#include +#include + +typedef struct _ExifMnoteDataFuji ExifMnoteDataFuji; + +struct _ExifMnoteDataFuji { + ExifMnoteData parent; + + MnoteFujiEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; +}; + +/*! Detect if MakerNote is recognized as one handled by the Fuji module. + * + * \param[in] ed image #ExifData to identify as as a Fuji type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_fuji_new (ExifMem *); + +#endif /* __MNOTE_FUJI_CONTENT_H__ */ diff --git a/libexifa/libexif/fuji/mnote-fuji-entry.h b/libexifa/libexif/fuji/mnote-fuji-entry.h new file mode 100755 index 0000000..a8395c5 --- /dev/null +++ b/libexifa/libexif/fuji/mnote-fuji-entry.h @@ -0,0 +1,45 @@ +/* mnote-fuji-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_ENTRY_H__ +#define __MNOTE_FUJI_ENTRY_H__ + +#include +#include + +typedef struct _MnoteFujiEntry MnoteFujiEntry; +typedef struct _MnoteFujiEntryPrivate MnoteFujiEntryPrivate; + +#include + +struct _MnoteFujiEntry { + MnoteFujiTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_fuji_entry_get_value (MnoteFujiEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_FUJI_ENTRY_H__ */ diff --git a/libexifa/libexif/fuji/mnote-fuji-tag.h b/libexifa/libexif/fuji/mnote-fuji-tag.h new file mode 100755 index 0000000..1d250e4 --- /dev/null +++ b/libexifa/libexif/fuji/mnote-fuji-tag.h @@ -0,0 +1,92 @@ +/* mnote-fuji-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_TAG_H__ +#define __MNOTE_FUJI_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +enum _MnoteFujiTag { + MNOTE_FUJI_TAG_VERSION = 0x0000, + MNOTE_FUJI_TAG_SERIAL_NUMBER = 0x0010, + MNOTE_FUJI_TAG_QUALITY = 0x1000, + MNOTE_FUJI_TAG_SHARPNESS = 0x1001, + MNOTE_FUJI_TAG_WHITE_BALANCE = 0x1002, + MNOTE_FUJI_TAG_COLOR = 0x1003, + MNOTE_FUJI_TAG_TONE = 0x1004, + MNOTE_FUJI_TAG_UNKNOWN_1006 = 0x1006, + MNOTE_FUJI_TAG_UNKNOWN_1007 = 0x1007, + MNOTE_FUJI_TAG_UNKNOWN_1008 = 0x1008, + MNOTE_FUJI_TAG_UNKNOWN_1009 = 0x1009, + MNOTE_FUJI_TAG_UNKNOWN_100A = 0x100A, + MNOTE_FUJI_TAG_UNKNOWN_100B = 0x100B, + MNOTE_FUJI_TAG_FLASH_MODE = 0x1010, + MNOTE_FUJI_TAG_FLASH_STRENGTH = 0x1011, + MNOTE_FUJI_TAG_MACRO = 0x1020, + MNOTE_FUJI_TAG_FOCUS_MODE = 0x1021, + MNOTE_FUJI_TAG_UNKNOWN_1022 = 0x1022, + MNOTE_FUJI_TAG_FOCUS_POINT = 0x1023, + MNOTE_FUJI_TAG_UNKNOWN_1024 = 0x1024, + MNOTE_FUJI_TAG_UNKNOWN_1025 = 0x1025, + MNOTE_FUJI_TAG_SLOW_SYNC = 0x1030, + MNOTE_FUJI_TAG_PICTURE_MODE = 0x1031, + MNOTE_FUJI_TAG_UNKNOWN_1032 = 0x1032, + MNOTE_FUJI_TAG_CONT_TAKING = 0x1100, + MNOTE_FUJI_TAG_SEQUENCE_NUMBER = 0x1101, + MNOTE_FUJI_TAG_UNKNOWN_1200 = 0x1200, + MNOTE_FUJI_TAG_FINEPIX_COLOR = 0x1210, + MNOTE_FUJI_TAG_BLUR_CHECK = 0x1300, + MNOTE_FUJI_TAG_FOCUS_CHECK = 0x1301, + MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK = 0x1302, + MNOTE_FUJI_TAG_UNKNOWN_1303 = 0x1303, + MNOTE_FUJI_TAG_DYNAMIC_RANGE = 0x1400, + MNOTE_FUJI_TAG_FILM_MODE = 0x1401, + MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING = 0x1402, + MNOTE_FUJI_TAG_DEV_DYNAMIC_RANGE_SETTING= 0x1403, + MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH = 0x1404, + MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH = 0x1405, + MNOTE_FUJI_TAG_MAX_APERT_AT_MIN_FOC = 0x1406, + MNOTE_FUJI_TAG_MAX_APERT_AT_MAX_FOC = 0x1407, + MNOTE_FUJI_TAG_UNKNOWN_1408 = 0x1408, + MNOTE_FUJI_TAG_UNKNOWN_1409 = 0x1409, + MNOTE_FUJI_TAG_UNKNOWN_140A = 0x140A, + MNOTE_FUJI_TAG_UNKNOWN_1410 = 0x1410, + MNOTE_FUJI_TAG_UNKNOWN_1421 = 0x1421, + MNOTE_FUJI_TAG_UNKNOWN_4100 = 0x4100, + MNOTE_FUJI_TAG_UNKNOWN_4800 = 0x4800, + MNOTE_FUJI_TAG_FILE_SOURCE = 0x8000, + MNOTE_FUJI_TAG_ORDER_NUMBER = 0x8002, + MNOTE_FUJI_TAG_FRAME_NUMBER = 0x8003, +}; +typedef enum _MnoteFujiTag MnoteFujiTag; + +const char *mnote_fuji_tag_get_name (MnoteFujiTag tag); +const char *mnote_fuji_tag_get_title (MnoteFujiTag tag); +const char *mnote_fuji_tag_get_description (MnoteFujiTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_FUJI_TAG_H__ */ diff --git a/libexifa/libexif/i18n.h b/libexifa/libexif/i18n.h new file mode 100755 index 0000000..4b4b908 --- /dev/null +++ b/libexifa/libexif/i18n.h @@ -0,0 +1,52 @@ +/* i18n.h + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __I18N_H__ +#define __I18N_H__ + +#include "config.h" + +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define ngettext(String1,String2,Count) (Count==1?String1:String2) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +#ifdef __WATCOMC__ +# define bind_textdomain_codeset(Domain,Codeset) +# define bindtextdomain(Domain,Directory) +#else +# define bind_textdomain_codeset(Domain,Codeset) +# define bindtextdomain(Domain,Directory) +#endif +# define _(String) (String) +# define N_(String) (String) +#endif + +#endif /* __I18N_H__ */ diff --git a/libexifa/libexif/olympus/exif-mnote-data-olympus.h b/libexifa/libexif/olympus/exif-mnote-data-olympus.h new file mode 100755 index 0000000..d08b0f4 --- /dev/null +++ b/libexifa/libexif/olympus/exif-mnote-data-olympus.h @@ -0,0 +1,67 @@ +/* mnote-olympus-data.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_CONTENT_H__ +#define __MNOTE_OLYMPUS_CONTENT_H__ + +#include +#include +#include +#include +#include + +enum OlympusVersion { + unrecognized = 0, + nikonV1 = 1, + nikonV2 = 2, + olympusV1 = 3, + olympusV2 = 4, + sanyoV1 = 5, + epsonV1 = 6, + nikonV0 = 7 +}; + + +typedef struct _ExifMnoteDataOlympus ExifMnoteDataOlympus; + +struct _ExifMnoteDataOlympus { + ExifMnoteData parent; + + MnoteOlympusEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + enum OlympusVersion version; +}; + +/*! Detect if MakerNote is recognized as one handled by the Olympus module. + * + * \param[in] ed image #ExifData to identify as as an Olympus type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_olympus_new (ExifMem *); + +#endif /* __MNOTE_OLYMPUS_CONTENT_H__ */ diff --git a/libexifa/libexif/olympus/mnote-olympus-entry.h b/libexifa/libexif/olympus/mnote-olympus-entry.h new file mode 100755 index 0000000..f1b0a98 --- /dev/null +++ b/libexifa/libexif/olympus/mnote-olympus-entry.h @@ -0,0 +1,43 @@ +/* mnote-olympus-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_ENTRY_H__ +#define __MNOTE_OLYMPUS_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnoteOlympusEntry MnoteOlympusEntry; + +struct _MnoteOlympusEntry { + MnoteOlympusTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_OLYMPUS_ENTRY_H__ */ diff --git a/libexifa/libexif/olympus/mnote-olympus-tag.h b/libexifa/libexif/olympus/mnote-olympus-tag.h new file mode 100755 index 0000000..2c3de82 --- /dev/null +++ b/libexifa/libexif/olympus/mnote-olympus-tag.h @@ -0,0 +1,229 @@ +/* mnote-olympus-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_TAG_H__ +#define __MNOTE_OLYMPUS_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum _MnoteOlympusTag { + + /* Nikon v.2 */ + MNOTE_NIKON_TAG_FIRMWARE = 0x0001, + MNOTE_NIKON_TAG_ISO = 0x0002, + MNOTE_NIKON_TAG_COLORMODE1 = 0x0003, + MNOTE_NIKON_TAG_QUALITY = 0x0004, + MNOTE_NIKON_TAG_WHITEBALANCE = 0x0005, + MNOTE_NIKON_TAG_SHARPENING = 0x0006, + MNOTE_NIKON_TAG_FOCUSMODE = 0x0007, + MNOTE_NIKON_TAG_FLASHSETTING = 0x0008, + MNOTE_NIKON_TAG_FLASHMODE = 0x0009, + MNOTE_NIKON_TAG_WHITEBALANCEFINE = 0x000b, + MNOTE_NIKON_TAG_WHITEBALANCERB = 0x000c, + MNOTE_NIKON_TAG_UNKNOWN_0X000D = 0x000d, + MNOTE_NIKON_TAG_EXPOSUREDIFF = 0x000e, + MNOTE_NIKON_TAG_ISOSELECTION = 0x000f, + MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER= 0x0011, + MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION = 0x0012, + MNOTE_NIKON_TAG_ISO2 = 0x0013, + MNOTE_NIKON_TAG_IMAGEBOUNDARY = 0x0016, + MNOTE_NIKON_TAG_UNKNOWN_0X0017 = 0x0017, + MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL = 0x0018, + MNOTE_NIKON_TAG_EXPOSUREBRACKETVAL = 0x0019, + MNOTE_NIKON_TAG_IMAGEADJUSTMENT = 0x0080, + MNOTE_NIKON_TAG_TONECOMPENSATION = 0x0081, + MNOTE_NIKON_TAG_ADAPTER = 0x0082, + MNOTE_NIKON_TAG_LENSTYPE = 0x0083, + MNOTE_NIKON_TAG_LENS = 0x0084, + MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE = 0x0085, + MNOTE_NIKON_TAG_DIGITALZOOM = 0x0086, + MNOTE_NIKON_TAG_FLASHUSED = 0x0087, + MNOTE_NIKON_TAG_AFFOCUSPOSITION = 0x0088, + MNOTE_NIKON_TAG_BRACKETING = 0x0089, + MNOTE_NIKON_TAG_UNKNOWN_0X008A = 0x008a, + MNOTE_NIKON_TAG_LENS_FSTOPS = 0x008b, + MNOTE_NIKON_TAG_CURVE = 0x008c, + MNOTE_NIKON_TAG_COLORMODE = 0x008d, + MNOTE_NIKON_TAG_LIGHTTYPE = 0x0090, + MNOTE_NIKON_TAG_UNKNOWN_0X0091 = 0x0091, + MNOTE_NIKON_TAG_HUE = 0x0092, + MNOTE_NIKON_TAG_SATURATION = 0x0094, + MNOTE_NIKON_TAG_NOISEREDUCTION = 0x0095, + MNOTE_NIKON_TAG_UNKNOWN_0X0097 = 0x0097, + MNOTE_NIKON_TAG_UNKNOWN_0X0098 = 0x0098, + MNOTE_NIKON_TAG_SENSORPIXELSIZE = 0x009a, + MNOTE_NIKON_TAG_UNKNOWN_0X009B = 0x009b, + MNOTE_NIKON_TAG_SERIALNUMBER = 0x00a0, + MNOTE_NIKON_TAG_IMAGE_DATASIZE = 0x00a2, + MNOTE_NIKON_TAG_UNKNOWN_0X00A3 = 0x00a3, + MNOTE_NIKON_TAG_TOTALPICTURES = 0x00a7, + MNOTE_NIKON_TAG_UNKNOWN_0X00A8 = 0x00a8, + MNOTE_NIKON_TAG_OPTIMIZATION = 0x00a9, + MNOTE_NIKON_TAG_SATURATION2 = 0x00aa, + MNOTE_NIKON_TAG_VARIPROGRAM = 0x00ab, + MNOTE_NIKON_TAG_CAPTUREEDITORDATA = 0x0e01, + MNOTE_NIKON_TAG_CAPTUREEDITORVER = 0x0e09, + MNOTE_NIKON_TAG_UNKNOWN_0X0E0E = 0x0e0e, + MNOTE_NIKON_TAG_UNKNOWN_0X0E10 = 0x0e10, + + /* Nikon v1: real values + our proprietary base to distinguish from v2 */ + MNOTE_NIKON1_TAG_BASE = 0x8000, + MNOTE_NIKON1_TAG_UNKNOWN_0X0002 = 0x0002 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_QUALITY = 0x0003 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_COLORMODE = 0x0004 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_IMAGEADJUSTMENT = 0x0005 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_CCDSENSITIVITY = 0x0006 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_WHITEBALANCE = 0x0007 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_FOCUS = 0x0008 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_UNKNOWN_0X0009 = 0x0009 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_DIGITALZOOM = 0x000a + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_CONVERTER = 0x000b + MNOTE_NIKON1_TAG_BASE, + + /* Olympus and some Sanyo */ + MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE = 0x0100, + MNOTE_OLYMPUS_TAG_MODE = 0x0200, + MNOTE_OLYMPUS_TAG_QUALITY = 0x0201, + MNOTE_OLYMPUS_TAG_MACRO = 0x0202, + MNOTE_OLYMPUS_TAG_BWMODE = 0x0203, + MNOTE_OLYMPUS_TAG_DIGIZOOM = 0x0204, + MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL = 0x0205, + MNOTE_OLYMPUS_TAG_LENSDISTORTION = 0x0206, + MNOTE_OLYMPUS_TAG_VERSION = 0x0207, + MNOTE_OLYMPUS_TAG_INFO = 0x0208, + MNOTE_OLYMPUS_TAG_ID = 0x0209, + MNOTE_OLYMPUS_TAG_PRECAPTUREFRAMES = 0x0300, + MNOTE_OLYMPUS_TAG_WHITEBOARD = 0x0301, + MNOTE_OLYMPUS_TAG_ONETOUCHWB = 0x0302, + MNOTE_OLYMPUS_TAG_WHITEBALANCEBRACKET = 0x0303, + MNOTE_OLYMPUS_TAG_WHITEBALANCEBIAS = 0x0304, + MNOTE_OLYMPUS_TAG_DATADUMP = 0x0f00, + MNOTE_OLYMPUS_TAG_UNKNOWN_4 = 0x0f04, + MNOTE_OLYMPUS_TAG_SHUTTERSPEED = 0x1000, + MNOTE_OLYMPUS_TAG_ISOVALUE = 0x1001, + MNOTE_OLYMPUS_TAG_APERTUREVALUE = 0x1002, + MNOTE_OLYMPUS_TAG_BRIGHTNESSVALUE = 0x1003, + MNOTE_OLYMPUS_TAG_FLASHMODE = 0x1004, + MNOTE_OLYMPUS_TAG_FLASHDEVICE = 0x1005, + MNOTE_OLYMPUS_TAG_EXPOSURECOMP = 0x1006, + MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE = 0x1007, + MNOTE_OLYMPUS_TAG_LENSTEMPERATURE = 0x1008, + MNOTE_OLYMPUS_TAG_LIGHTCONDITION = 0x1009, + MNOTE_OLYMPUS_TAG_FOCUSRANGE = 0x100a, + MNOTE_OLYMPUS_TAG_MANFOCUS = 0x100b, + MNOTE_OLYMPUS_TAG_FOCUSDIST = 0x100c, + MNOTE_OLYMPUS_TAG_ZOOMSTEPCOUNT = 0x100d, + MNOTE_OLYMPUS_TAG_FOCUSSTEPCOUNT = 0x100e, + MNOTE_OLYMPUS_TAG_SHARPNESS = 0x100f, + MNOTE_OLYMPUS_TAG_FLASHCHARGELEVEL = 0x1010, + MNOTE_OLYMPUS_TAG_COLORMATRIX = 0x1011, + MNOTE_OLYMPUS_TAG_BLACKLEVEL = 0x1012, + MNOTE_OLYMPUS_TAG_WBALANCE = 0x1015, + MNOTE_OLYMPUS_TAG_REDBALANCE = 0x1017, + MNOTE_OLYMPUS_TAG_BLUEBALANCE = 0x1018, + MNOTE_OLYMPUS_TAG_COLORMATRIXNUMBER = 0x1019, + MNOTE_OLYMPUS_TAG_SERIALNUMBER2 = 0x101a, + MNOTE_OLYMPUS_TAG_FLASHEXPOSURECOMP = 0x1023, + MNOTE_OLYMPUS_TAG_INTERNALFLASHTABLE = 0x1024, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHGVALUE = 0x1025, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE = 0x1026, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHZOOM = 0x1027, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHMODE = 0x1028, + MNOTE_OLYMPUS_TAG_CONTRAST = 0x1029, + MNOTE_OLYMPUS_TAG_SHARPNESSFACTOR = 0x102a, + MNOTE_OLYMPUS_TAG_COLORCONTROL = 0x102b, + MNOTE_OLYMPUS_TAG_IMAGEWIDTH = 0x102e, + MNOTE_OLYMPUS_TAG_IMAGEHEIGHT = 0x102f, + MNOTE_OLYMPUS_TAG_SCENEDETECT = 0x1030, + MNOTE_OLYMPUS_TAG_COMPRESSIONRATIO = 0x1034, + MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID = 0x1035, + MNOTE_OLYMPUS_TAG_AFRESULT = 0x1038, + MNOTE_OLYMPUS_TAG_CCDSCANMODE = 0x1039, + MNOTE_OLYMPUS_TAG_NOISEREDUCTION = 0x103a, + MNOTE_OLYMPUS_TAG_INFINITYLENSSTEP = 0x103b, + MNOTE_OLYMPUS_TAG_NEARLENSSTEP = 0x103c, + MNOTE_OLYMPUS_TAG_LIGHTVALUECENTER = 0x103d, + MNOTE_OLYMPUS_TAG_LIGHTVALUEPERIPHERY = 0x103e, + + /* Epson */ + MNOTE_EPSON_TAG_IMAGE_WIDTH = 0x020b, + MNOTE_EPSON_TAG_IMAGE_HEIGHT = 0x020c, + MNOTE_EPSON_TAG_SOFTWARE = 0x020d, + + /* Sanyo */ + MNOTE_SANYO_TAG_SEQUENTIALSHOT = 0x020e, + MNOTE_SANYO_TAG_WIDERANGE = 0x020f, + MNOTE_SANYO_TAG_COLORADJUSTMENTMODE = 0x0210, + MNOTE_SANYO_TAG_FOCUSMODE = 0x0212, + MNOTE_SANYO_TAG_QUICKSHOT = 0x0213, + MNOTE_SANYO_TAG_SELFTIMER = 0x0214, + MNOTE_SANYO_TAG_VOICEMEMO = 0x0216, + MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE = 0x0217, + MNOTE_SANYO_TAG_FLICKERREDUCE = 0x0218, + MNOTE_SANYO_TAG_OPTICALZOOM = 0x0219, + MNOTE_SANYO_TAG_CCDSENSITIVITY = 0x021a, + MNOTE_SANYO_TAG_DIGITALZOOM = 0x021b, + MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL = 0x021d, + MNOTE_SANYO_TAG_RESAVED = 0x021e, + MNOTE_SANYO_TAG_SCENESELECT = 0x021f, + MNOTE_SANYO_TAG_MANUALFOCUSDISTANCE = 0x0223, + MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL = 0x0224, +}; +typedef enum _MnoteOlympusTag MnoteOlympusTag; + +/* Don't use these definitions. They are here for compatibility only. */ +#define MNOTE_OLYMPUS_TAG_UNKNOWN_1 MNOTE_OLYMPUS_TAG_BWMODE +#define MNOTE_OLYMPUS_TAG_UNKNOWN_2 MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL +#define MNOTE_OLYMPUS_TAG_UNKNOWN_3 MNOTE_OLYMPUS_TAG_LENSDISTORTION +#define MNOTE_OLYMPUS_TAG_UNKNOWN_5 MNOTE_OLYMPUS_TAG_DATADUMP +#define MNOTE_NIKON_TAG_PREVIEWIMAGE MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER + +/*! Return a textual name of the given tag within the Olympus-style MakerNote. + * The name is a short, unique, non-localized text string containing only + * US-ASCII alphanumeric characters. + * + * \param[in] tag Olympus-style MakerNote tag + * \return textual name of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_name (MnoteOlympusTag tag); + +/*! Return a textual title of the given tag within the Olympus-style MakerNote. + * The title is a short, localized description of the tag. + * + * \param[in] tag Olympus-style MakerNote tag + * \return textual title of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_title (MnoteOlympusTag tag); + +/*! Return a verbose textual description of the given tag within the + * Olympus-style MakerNote. + * The description is a verbose, localized description of the tag. + * + * \param[in] tag EXIF tag + * \return textual description of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_description (MnoteOlympusTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_OLYMPUS_TAG_H__ */ diff --git a/libexifa/libexif/pentax/exif-mnote-data-pentax.h b/libexifa/libexif/pentax/exif-mnote-data-pentax.h new file mode 100755 index 0000000..da9f79a --- /dev/null +++ b/libexifa/libexif/pentax/exif-mnote-data-pentax.h @@ -0,0 +1,59 @@ +/* exif-mnote-data-pentax.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_PENTAX_H__ +#define __EXIF_MNOTE_DATA_PENTAX_H__ + +#include +#include +#include +#include +#include +#include + +enum PentaxVersion {pentaxV1 = 1, pentaxV2 = 2, pentaxV3 = 3, casioV2 = 4 }; + +typedef struct _ExifMnoteDataPentax ExifMnoteDataPentax; + +struct _ExifMnoteDataPentax { + ExifMnoteData parent; + + MnotePentaxEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + + enum PentaxVersion version; +}; + +/*! Detect if MakerNote is recognized as one handled by the Pentax module. + * + * \param[in] ed image #ExifData to identify as as a Pentax type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_pentax_new (ExifMem *); + +#endif /* __EXIF_MNOTE_DATA_PENTAX_H__ */ diff --git a/libexifa/libexif/pentax/mnote-pentax-entry.h b/libexifa/libexif/pentax/mnote-pentax-entry.h new file mode 100755 index 0000000..4547ec3 --- /dev/null +++ b/libexifa/libexif/pentax/mnote-pentax-entry.h @@ -0,0 +1,43 @@ +/* mnote-pentax-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_ENTRY_H__ +#define __MNOTE_PENTAX_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnotePentaxEntry MnotePentaxEntry; + +struct _MnotePentaxEntry { + MnotePentaxTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_pentax_entry_get_value (MnotePentaxEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_PENTAX_ENTRY_H__ */ diff --git a/libexifa/libexif/pentax/mnote-pentax-tag.h b/libexifa/libexif/pentax/mnote-pentax-tag.h new file mode 100755 index 0000000..51b2aec --- /dev/null +++ b/libexifa/libexif/pentax/mnote-pentax-tag.h @@ -0,0 +1,153 @@ +/* mnote-pentax-tag.h + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_TAG_H__ +#define __MNOTE_PENTAX_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Missing features which are probably in the unknowns somewhere ... + * 1/ AF Area (Wide, Spot, Free) + * 2/ AE Metering (Multi segment, Centre-weighted, Spot) + * 3/ + */ + +enum _MnotePentaxTag { + MNOTE_PENTAX_TAG_MODE = 0x0001, + MNOTE_PENTAX_TAG_QUALITY = 0x0002, + MNOTE_PENTAX_TAG_FOCUS = 0x0003, + MNOTE_PENTAX_TAG_FLASH = 0x0004, + MNOTE_PENTAX_TAG_UNKNOWN_05 = 0x0005, + MNOTE_PENTAX_TAG_UNKNOWN_06 = 0x0006, + MNOTE_PENTAX_TAG_WHITE_BALANCE = 0x0007, + MNOTE_PENTAX_TAG_UNKNOWN_08 = 0x0008, + MNOTE_PENTAX_TAG_UNKNOWN_09 = 0x0009, + MNOTE_PENTAX_TAG_ZOOM = 0x000a, + MNOTE_PENTAX_TAG_SHARPNESS = 0x000b, + MNOTE_PENTAX_TAG_CONTRAST = 0x000c, + MNOTE_PENTAX_TAG_SATURATION = 0x000d, + MNOTE_PENTAX_TAG_UNKNOWN_14 = 0x000e, + MNOTE_PENTAX_TAG_UNKNOWN_15 = 0x000f, + MNOTE_PENTAX_TAG_UNKNOWN_16 = 0x0010, + MNOTE_PENTAX_TAG_UNKNOWN_17 = 0x0011, + MNOTE_PENTAX_TAG_UNKNOWN_18 = 0x0012, + MNOTE_PENTAX_TAG_UNKNOWN_19 = 0x0013, + MNOTE_PENTAX_TAG_ISO_SPEED = 0x0014, + MNOTE_PENTAX_TAG_UNKNOWN_21 = 0x0015, + MNOTE_PENTAX_TAG_COLOR = 0x0017, + MNOTE_PENTAX_TAG_UNKNOWN_24 = 0x0018, + MNOTE_PENTAX_TAG_UNKNOWN_25 = 0x0019, + MNOTE_PENTAX_TAG_PRINTIM = 0x0e00, + MNOTE_PENTAX_TAG_TZ_CITY = 0x1000, + MNOTE_PENTAX_TAG_TZ_DST = 0x1001, + + /* Pentax v2, v3: real values + our proprietary base to distinguish from v1 */ + MNOTE_PENTAX2_TAG_BASE = 0x4000, + MNOTE_PENTAX2_TAG_MODE = 0x0001 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_SIZE = 0x0002 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_LENGTH = 0x0003 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_START = 0x0004 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_MODEL_ID = 0x0005 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DATE = 0x0006 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_TIME = 0x0007 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_QUALITY = 0x0008 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_SIZE = 0x0009 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE = 0x000b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_MODE = 0x000c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_MODE = 0x000d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINT_SELECTED = 0x000e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_AFPOINT = 0x000f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_POSITION = 0x0010 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_TIME = 0x0012 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FNUMBER = 0x0013 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_ISO = 0x0014 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION = 0x0016 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_METERING_MODE = 0x0017 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_BRACKETING = 0x0018 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE = 0x0019 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE= 0x001a + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLUE_BALANCE = 0x001b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RED_BALANCE = 0x001c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCAL_LENGTH = 0x001d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DIGITAL_ZOOM = 0x001e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SATURATION = 0x001f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CONTRAST = 0x0020 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHARPNESS = 0x0021 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION = 0x0022 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY = 0x0023 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY = 0x0024 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_DST = 0x0025 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_DST = 0x0026 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FRAME_NUMBER = 0x0029 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_PROCESSING = 0x0032 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE2 = 0x0033 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DRIVE_MODE = 0x0034 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_COLOR_SPACE = 0x0037 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET = 0x0038 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE = 0x0039 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINTS_USED = 0x003c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_TYPE = 0x003f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE = 0x0047 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_NOISE_REDUCTION = 0x0049 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP = 0x004d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_TONE = 0x004f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO = 0x005c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLACK_POINT = 0x0200 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_POINT = 0x0201 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AE_INFO = 0x0206 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_INFO = 0x0207 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_INFO = 0x0208 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_INFO = 0x0215 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BATTERY_INFO = 0x0216 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE = 0x1000 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE = 0x1001 + MNOTE_PENTAX2_TAG_BASE, + + /* Casio v2: some Casio v2 tags match Pentax v2 tags */ + MNOTE_CASIO2_TAG_BASE = MNOTE_PENTAX2_TAG_BASE, + MNOTE_CASIO2_TAG_PREVIEW_START = 0x2000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS = 0x2011 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE = 0x2012 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_OBJECT_DISTANCE = 0x2022 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FLASH_DISTANCE = 0x2034 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_RECORD_MODE = 0x3000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_SELF_TIMER = 0x3001 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_QUALITY = 0x3002 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FOCUS_MODE = 0x3003 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_TIME_ZONE = 0x3006 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_BESTSHOT_MODE = 0x3007 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY = 0x3014 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_COLOR_MODE = 0x3015 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_ENHANCEMENT = 0x3016 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FINER = 0x3017 + MNOTE_CASIO2_TAG_BASE +}; +typedef enum _MnotePentaxTag MnotePentaxTag; + +const char *mnote_pentax_tag_get_name (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_title (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_description (MnotePentaxTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_PENTAX_TAG_H__ */ diff --git a/libexifa/olympus/exif-mnote-data-olympus.c b/libexifa/olympus/exif-mnote-data-olympus.c new file mode 100755 index 0000000..099671d --- /dev/null +++ b/libexifa/olympus/exif-mnote-data-olympus.c @@ -0,0 +1,659 @@ +/* exif-mnote-data-olympus.c + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "exif-mnote-data-olympus.h" + +#include +#include +#include + +#include +#include + +#define DEBUG + +/* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best + * not to in most cases because it seems to only affect the thumbnail tag + * which is duplicated in IFD 1, and fixing the offset could actually cause + * problems with other software that expects the broken form. + */ +/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */ + +static enum OlympusVersion +exif_mnote_data_olympus_identify_variant (const unsigned char *buf, + unsigned int buf_size); + + +static void +exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n) +{ + ExifMnoteData *d = (ExifMnoteData *) n; + unsigned int i; + + if (!n) return; + + if (n->entries) { + for (i = 0; i < n->count; i++) + if (n->entries[i].data) { + exif_mem_free (d->mem, n->entries[i].data); + n->entries[i].data = NULL; + } + exif_mem_free (d->mem, n->entries); + n->entries = NULL; + n->count = 0; + } +} + +static void +exif_mnote_data_olympus_free (ExifMnoteData *n) +{ + if (!n) return; + + exif_mnote_data_olympus_clear ((ExifMnoteDataOlympus *) n); +} + +static char * +exif_mnote_data_olympus_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; + + if (!d || !val) return NULL; + if (i > n->count -1) return NULL; +/* + exif_log (d->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Querying value for tag '%s'...", + mnote_olympus_tag_get_name (n->entries[i].tag)); +*/ + return mnote_olympus_entry_get_value (&n->entries[i], val, maxlen); +} + + + + +/** + * @brief save the MnoteData from ne to buf + * + * @param ne extract the data from this structure + * @param *buf write the mnoteData to this buffer (buffer will be allocated) + * @param buf_size the size of the buffer + */ +static void +exif_mnote_data_olympus_save (ExifMnoteData *ne, + unsigned char **buf, unsigned int *buf_size) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) ne; + size_t i, o, s, doff, base = 0, o2 = 6 + 2; + size_t datao = 0; + unsigned char *t; + size_t ts; + + if (!n || !buf || !buf_size) return; + + /* + * Allocate enough memory for all entries and the number of entries. + */ + *buf_size = 6 + 2 + 2 + n->count * 12; + switch (n->version) { + case olympusV1: + case sanyoV1: + case epsonV1: + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); + return; + } + + /* Write the header and the number of entries. */ + strcpy ((char *)*buf, n->version==sanyoV1?"SANYO": + (n->version==epsonV1?"EPSON":"OLYMP")); + exif_set_short (*buf + 6, n->order, (ExifShort) 1); + datao = n->offset; + break; + + case olympusV2: + *buf_size += 8-6 + 4; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); + return; + } + + /* Write the header and the number of entries. */ + strcpy ((char *)*buf, "OLYMPUS"); + exif_set_short (*buf + 8, n->order, (ExifShort) ( + (n->order == EXIF_BYTE_ORDER_INTEL) ? + ('I' << 8) | 'I' : + ('M' << 8) | 'M')); + exif_set_short (*buf + 10, n->order, (ExifShort) 3); + o2 += 4; + break; + + case nikonV1: + base = MNOTE_NIKON1_TAG_BASE; + + /* v1 has offsets based to main IFD, not makernote IFD */ + datao += n->offset + 10; + /* subtract the size here, so the increment in the next case will not harm us */ + *buf_size -= 8 + 2; + /* Fall through to nikonV2 handler */ + case nikonV2: + /* Write out V0 files in V2 format */ + case nikonV0: + *buf_size += 8 + 2; + *buf_size += 4; /* Next IFD pointer */ + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", *buf_size); + return; + } + + /* Write the header and the number of entries. */ + strcpy ((char *)*buf, "Nikon"); + (*buf)[6] = n->version; + + if (n->version != nikonV1) { + exif_set_short (*buf + 10, n->order, (ExifShort) ( + (n->order == EXIF_BYTE_ORDER_INTEL) ? + ('I' << 8) | 'I' : + ('M' << 8) | 'M')); + exif_set_short (*buf + 12, n->order, (ExifShort) 0x2A); + exif_set_long (*buf + 14, n->order, (ExifShort) 8); + o2 += 2 + 8; + } + datao -= 10; + /* Reset next IFD pointer */ + exif_set_long (*buf + o2 + 2 + n->count * 12, n->order, 0); + break; + + default: + return; + } + + exif_set_short (*buf + o2, n->order, (ExifShort) n->count); + o2 += 2; + + /* Save each entry */ + for (i = 0; i < n->count; i++) { + o = o2 + i * 12; + exif_set_short (*buf + o + 0, n->order, + (ExifShort) (n->entries[i].tag - base)); + exif_set_short (*buf + o + 2, n->order, + (ExifShort) n->entries[i].format); + exif_set_long (*buf + o + 4, n->order, + n->entries[i].components); + o += 8; + s = exif_format_get_size (n->entries[i].format) * + n->entries[i].components; + if (s > 65536) { + /* Corrupt data: EXIF data size is limited to the + * maximum size of a JPEG segment (64 kb). + */ + continue; + } + if (s > 4) { + doff = *buf_size; + ts = *buf_size + s; + t = exif_mem_realloc (ne->mem, *buf, + sizeof (char) * ts); + if (!t) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataOlympus", ts); + return; + } + *buf = t; + *buf_size = ts; + exif_set_long (*buf + o, n->order, datao + doff); + } else + doff = o; + + /* Write the data. */ + if (n->entries[i].data) { + memcpy (*buf + doff, n->entries[i].data, s); + } else { + /* Most certainly damaged input file */ + memset (*buf + doff, 0, s); + } + } +} + +static void +exif_mnote_data_olympus_load (ExifMnoteData *en, + const unsigned char *buf, unsigned int buf_size) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en; + ExifShort c; + size_t i, tcount, o, o2, datao = 6, base = 0; + + if (!n || !buf || !buf_size) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataOlympus", "Short MakerNote"); + return; + } + o2 = 6 + n->offset; /* Start of interesting data */ + if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataOlympus", "Short MakerNote"); + return; + } + + /* + * Olympus headers start with "OLYMP" and need to have at least + * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the + * number of entries, and 12 for one entry. + * + * Sanyo format is identical and uses identical tags except that + * header starts with "SANYO". + * + * Epson format is identical and uses identical tags except that + * header starts with "EPSON". + * + * Nikon headers start with "Nikon" (6 bytes including '\0'), + * version number (1 or 2). + * + * Version 1 continues with 0, 1, 0, number_of_tags, + * or just with number_of_tags (models D1H, D1X...). + * + * Version 2 continues with an unknown byte (0 or 10), + * two unknown bytes (0), "MM" or "II", another byte 0 and + * lastly 0x2A. + */ + n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2); + switch (n->version) { + case olympusV1: + case sanyoV1: + case epsonV1: + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Parsing Olympus/Sanyo/Epson maker note v1..."); + + /* The number of entries is at position 8. */ + if (buf[o2 + 6] == 1) + n->order = EXIF_BYTE_ORDER_INTEL; + else if (buf[o2 + 6 + 1] == 1) + n->order = EXIF_BYTE_ORDER_MOTOROLA; + o2 += 8; + if (o2 + 2 > buf_size) return; + c = exif_get_short (buf + o2, n->order); + if ((!(c & 0xFF)) && (c > 0x500)) { + if (n->order == EXIF_BYTE_ORDER_INTEL) { + n->order = EXIF_BYTE_ORDER_MOTOROLA; + } else { + n->order = EXIF_BYTE_ORDER_INTEL; + } + } + break; + + case olympusV2: + /* Olympus S760, S770 */ + datao = o2; + o2 += 8; + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...", + buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]); + + if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I')) + n->order = EXIF_BYTE_ORDER_INTEL; + else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M')) + n->order = EXIF_BYTE_ORDER_MOTOROLA; + + /* The number of entries is at position 8+4. */ + o2 += 4; + break; + + case nikonV1: + o2 += 6; + if (o2 >= buf_size) return; + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, " + "%02x, %02x, %02x, %02x, %02x)...", + buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], + buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); + + /* Skip version number */ + o2 += 1; + + /* Skip an unknown byte (00 or 0A). */ + o2 += 1; + + base = MNOTE_NIKON1_TAG_BASE; + /* Fix endianness, if needed */ + if (o2 + 2 > buf_size) return; + c = exif_get_short (buf + o2, n->order); + if ((!(c & 0xFF)) && (c > 0x500)) { + if (n->order == EXIF_BYTE_ORDER_INTEL) { + n->order = EXIF_BYTE_ORDER_MOTOROLA; + } else { + n->order = EXIF_BYTE_ORDER_INTEL; + } + } + break; + + case nikonV2: + o2 += 6; + if (o2 >= buf_size) return; + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, " + "%02x, %02x, %02x, %02x, %02x)...", + buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], + buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); + + /* Skip version number */ + o2 += 1; + + /* Skip an unknown byte (00 or 0A). */ + o2 += 1; + + /* Skip 2 unknown bytes (00 00). */ + o2 += 2; + + /* + * Byte order. From here the data offset + * gets calculated. + */ + datao = o2; + if (o2 >= buf_size) return; + if (!strncmp ((char *)&buf[o2], "II", 2)) + n->order = EXIF_BYTE_ORDER_INTEL; + else if (!strncmp ((char *)&buf[o2], "MM", 2)) + n->order = EXIF_BYTE_ORDER_MOTOROLA; + else { + exif_log (en->log, EXIF_LOG_CODE_DEBUG, + "ExifMnoteDataOlympus", "Unknown " + "byte order '%c%c'", buf[o2], + buf[o2 + 1]); + return; + } + o2 += 2; + + /* Skip 2 unknown bytes (00 2A). */ + o2 += 2; + + /* Go to where the number of entries is. */ + if (o2 + 4 > buf_size) return; + o2 = datao + exif_get_long (buf + o2, n->order); + break; + + case nikonV0: + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, " + "%02x, %02x, %02x, %02x, %02x)...", + buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], + buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); + /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */ + n->order = EXIF_BYTE_ORDER_MOTOROLA; + break; + + default: + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", + "Unknown Olympus variant %i.", n->version); + return; + } + + /* Sanity check the offset */ + if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteOlympus", "Short MakerNote"); + return; + } + + /* Read the number of tags */ + c = exif_get_short (buf + o2, n->order); + o2 += 2; + + /* Remove any old entries */ + exif_mnote_data_olympus_clear (n); + + /* Reserve enough space for all the possible MakerNote tags */ + n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c); + if (!n->entries) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c); + return; + } + + /* Parse all c entries, storing ones that are successfully parsed */ + tcount = 0; + for (i = c, o = o2; i; --i, o += 12) { + size_t s; + if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteOlympus", "Short MakerNote"); + break; + } + + n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base; + n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); + n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); + n->entries[tcount].order = n->order; + + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", + "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, + mnote_olympus_tag_get_name (n->entries[tcount].tag)); +/* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", + "0x%x %d %ld*(%d)", + n->entries[tcount].tag, + n->entries[tcount].format, + n->entries[tcount].components, + (int)exif_format_get_size(n->entries[tcount].format)); */ + + /* + * Size? If bigger than 4 bytes, the actual data is not + * in the entry but somewhere else (offset). + */ + s = exif_format_get_size (n->entries[tcount].format) * + n->entries[tcount].components; + n->entries[tcount].size = s; + if (s) { + size_t dataofs = o + 8; + if (s > 4) { + /* The data in this case is merely a pointer */ + dataofs = exif_get_long (buf + dataofs, n->order) + datao; +#ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG + /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when + * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE + * tag in its MakerNote. The offset is actually the absolute + * position in the file instead of the position within the IFD. + */ + if (dataofs + s > buf_size && n->version == sanyoV1) { + /* fix pointer */ + dataofs -= datao + 6; + exif_log (en->log, EXIF_LOG_CODE_DEBUG, + "ExifMnoteOlympus", + "Inconsistent thumbnail tag offset; attempting to recover"); + } +#endif + } + if ((dataofs + s < dataofs) || (dataofs + s < s) || + (dataofs + s > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_DEBUG, + "ExifMnoteOlympus", + "Tag data past end of buffer (%u > %u)", + dataofs + s, buf_size); + continue; + } + + n->entries[tcount].data = exif_mem_alloc (en->mem, s); + if (!n->entries[tcount].data) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s); + continue; + } + memcpy (n->entries[tcount].data, buf + dataofs, s); + } + + /* Tag was successfully parsed */ + ++tcount; + } + /* Store the count of successfully parsed tags */ + n->count = tcount; +} + +static unsigned int +exif_mnote_data_olympus_count (ExifMnoteData *n) +{ + return n ? ((ExifMnoteDataOlympus *) n)->count : 0; +} + +static unsigned int +exif_mnote_data_olympus_get_id (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataOlympus *note = (ExifMnoteDataOlympus *) d; + + if (!note) return 0; + if (note->count <= n) return 0; + return note->entries[n].tag; +} + +static const char * +exif_mnote_data_olympus_get_name (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_olympus_tag_get_name (n->entries[i].tag); +} + +static const char * +exif_mnote_data_olympus_get_title (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_olympus_tag_get_title (n->entries[i].tag); +} + +static const char * +exif_mnote_data_olympus_get_description (ExifMnoteData *d, unsigned int i) +{ + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; + + if (!n) return NULL; + if (i >= n->count) return NULL; + return mnote_olympus_tag_get_description (n->entries[i].tag); +} + +static void +exif_mnote_data_olympus_set_byte_order (ExifMnoteData *d, ExifByteOrder o) +{ + ExifByteOrder o_orig; + ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) d; + unsigned int i; + + if (!n) return; + + o_orig = n->order; + n->order = o; + for (i = 0; i < n->count; i++) { + n->entries[i].order = o; + exif_array_set_byte_order (n->entries[i].format, n->entries[i].data, + n->entries[i].components, o_orig, o); + } +} + +static void +exif_mnote_data_olympus_set_offset (ExifMnoteData *n, unsigned int o) +{ + if (n) ((ExifMnoteDataOlympus *) n)->offset = o; +} + +static enum OlympusVersion +exif_mnote_data_olympus_identify_variant (const unsigned char *buf, + unsigned int buf_size) +{ + /* Olympus, Nikon, Sanyo, Epson */ + if (buf_size >= 8) { + /* Match the terminating NUL character, too */ + if (!memcmp (buf, "OLYMPUS", 8)) + return olympusV2; + else if (!memcmp (buf, "OLYMP", 6)) + return olympusV1; + else if (!memcmp (buf, "SANYO", 6)) + return sanyoV1; + else if (!memcmp (buf, "EPSON", 6)) + return epsonV1; + else if (!memcmp (buf, "Nikon", 6)) { + switch (buf[6]) { + case 1: return nikonV1; + case 2: return nikonV2; + default: return 0; /* Unrecognized Nikon variant */ + } + } + } + + /* Another variant of Nikon */ + if ((buf_size >= 2) && (buf[0] == 0x00) && (buf[1] == 0x1b)) { + return nikonV0; + } + + return unrecognized; +} + +int +exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e) +{ + int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size); + + if (variant == nikonV0) { + /* This variant needs some extra checking with the Make */ + char value[5]; + ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE); + variant = unrecognized; + + if (em) { + const char *v = exif_entry_get_value (em, value, sizeof(value)); + if (v && (!strncmp (v, "Nikon", sizeof(value)) || + !strncmp (v, "NIKON", sizeof(value)) )) + /* When saved, this variant will be written out like the + * alternative nikonV2 form above instead + */ + variant = nikonV0; + } + } + + return variant; +} + + +ExifMnoteData * +exif_mnote_data_olympus_new (ExifMem *mem) +{ + ExifMnoteData *d; + + if (!mem) return NULL; + + d = exif_mem_alloc (mem, sizeof (ExifMnoteDataOlympus)); + if (!d) return NULL; + + exif_mnote_data_construct (d, mem); + + /* Set up function pointers */ + d->methods.free = exif_mnote_data_olympus_free; + d->methods.set_byte_order = exif_mnote_data_olympus_set_byte_order; + d->methods.set_offset = exif_mnote_data_olympus_set_offset; + d->methods.load = exif_mnote_data_olympus_load; + d->methods.save = exif_mnote_data_olympus_save; + d->methods.count = exif_mnote_data_olympus_count; + d->methods.get_id = exif_mnote_data_olympus_get_id; + d->methods.get_name = exif_mnote_data_olympus_get_name; + d->methods.get_title = exif_mnote_data_olympus_get_title; + d->methods.get_description = exif_mnote_data_olympus_get_description; + d->methods.get_value = exif_mnote_data_olympus_get_value; + + return d; +} diff --git a/libexifa/olympus/mnote-olympus-entry.c b/libexifa/olympus/mnote-olympus-entry.c new file mode 100755 index 0000000..9db5224 --- /dev/null +++ b/libexifa/olympus/mnote-olympus-entry.c @@ -0,0 +1,821 @@ +/* mnote-olympus-entry.c + * + * Copyright (c) 2002-2009 Lutz Mueller et. al. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "mnote-olympus-entry.h" + +#include +#include +#include + +#include +#include +#include +#include + +#define CF(format,target,v,maxlen) \ +{ \ + if (format != target) { \ + snprintf (v, maxlen, \ + _("Invalid format '%s', " \ + "expected '%s'."), \ + exif_format_get_name (format), \ + exif_format_get_name (target)); \ + break; \ + } \ +} + +#define CF2(format,target1,target2,v,maxlen) \ +{ \ + if ((format != target1) && (format != target2)) { \ + snprintf (v, maxlen, \ + _("Invalid format '%s', " \ + "expected '%s' or '%s'."), \ + exif_format_get_name (format), \ + exif_format_get_name (target1), \ + exif_format_get_name (target2)); \ + break; \ + } \ +} + +#define CC(number,target,v,maxlen) \ +{ \ + if (number != target) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i)."), (int) number, (int) target); \ + break; \ + } \ +} + +#define CC2(number,t1,t2,v,maxlen) \ +{ \ + if ((number < t1) || (number > t2)) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i or %i)."), (int) number, \ + (int) t1, (int) t2); \ + break; \ + } \ +} + +static const struct { + ExifTag tag; + ExifFormat fmt; + struct { + int index; + const char *string; + } elem[24]; +} items[] = { +#ifndef NO_VERBOSE_TAG_DATA + { MNOTE_NIKON_TAG_LENSTYPE, EXIF_FORMAT_BYTE, + { {0, N_("AF non D lens")}, + {1, N_("Manual")}, + {2, N_("AF-D or AF-S lens")}, + {6, N_("AF-D G lens")}, + {10, N_("AF-D VR lens")}, + {14, N_("AF-D G VR lens")}, + {0, NULL}}}, + { MNOTE_NIKON_TAG_FLASHUSED, EXIF_FORMAT_BYTE, + { {0, N_("Flash did not fire")}, + {4, N_("Flash unit unknown")}, + {7, N_("Flash is external")}, + {9, N_("Flash is on camera")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_QUALITY, EXIF_FORMAT_SHORT, + { {1, N_("VGA basic")}, + {2, N_("VGA normal")}, + {3, N_("VGA fine")}, + {4, N_("SXGA basic")}, + {5, N_("SXGA normal")}, + {6, N_("SXGA fine")}, + {10, N_("2 Mpixel basic")}, + {11, N_("2 Mpixel normal")}, + {12, N_("2 Mpixel fine")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_COLORMODE, EXIF_FORMAT_SHORT, + { {1, N_("Color")}, + {2, N_("Monochrome")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, EXIF_FORMAT_SHORT, + { {0, N_("Normal")}, + {1, N_("Bright+")}, + {2, N_("Bright-")}, + {3, N_("Contrast+")}, + {4, N_("Contrast-")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT, + { {0, N_("ISO 80")}, + {2, N_("ISO 160")}, + {4, N_("ISO 320")}, + {5, N_("ISO 100")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_WHITEBALANCE, EXIF_FORMAT_SHORT, + { {0, N_("Auto")}, + {1, N_("Preset")}, + {2, N_("Daylight")}, + {3, N_("Incandescence")}, + {4, N_("Fluorescence")}, + {5, N_("Cloudy")}, + {6, N_("SpeedLight")}, + {0, NULL}}}, + { MNOTE_NIKON1_TAG_CONVERTER, EXIF_FORMAT_SHORT, + { {0, N_("No fisheye")}, + {1, N_("Fisheye on")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_QUALITY, EXIF_FORMAT_SHORT, + { {1, N_("Normal, SQ")}, + {2, N_("Normal, HQ")}, + {3, N_("Normal, SHQ")}, + {4, N_("Normal, RAW")}, + {5, N_("Normal, SQ1")}, + {6, N_("Normal, SQ2")}, + {7, N_("Normal, super high")}, + {17, N_("Normal, standard")}, + {0x101, N_("Fine, SQ")}, + {0x102, N_("Fine, HQ")}, + {0x103, N_("Fine, SHQ")}, + {0x104, N_("Fine, RAW")}, + {0x105, N_("Fine, SQ1")}, + {0x106, N_("Fine, SQ2")}, + {0x107, N_("Fine, super high")}, + {0x201, N_("Super fine, SQ")}, + {0x202, N_("Super fine, HQ")}, + {0x203, N_("Super fine, SHQ")}, + {0x204, N_("Super fine, RAW")}, + {0x205, N_("Super fine, SQ1")}, + {0x206, N_("Super fine, SQ2")}, + {0x207, N_("Super fine, super high")}, + {0x211, N_("Super fine, high")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_MACRO, EXIF_FORMAT_SHORT, + { {0, N_("No")}, + {1, N_("Yes")}, + {2, N_("Super macro")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_BWMODE, EXIF_FORMAT_SHORT, + { {0, N_("No")}, + {1, N_("Yes")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_ONETOUCHWB, EXIF_FORMAT_SHORT, + { {0, N_("Off")}, + {1, N_("On")}, + {2, N_("On (Preset)")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_FLASHMODE, EXIF_FORMAT_SHORT, + { {0, N_("Auto")}, + {1, N_("Red-eye reduction")}, + {2, N_("Fill")}, + {3, N_("Off")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_FLASHDEVICE, EXIF_FORMAT_SHORT, + { {0, N_("None")}, + {1, N_("Internal")}, + {4, N_("External")}, + {5, N_("Internal + external")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_FOCUSRANGE, EXIF_FORMAT_SHORT, + { {0, N_("Normal")}, + {1, N_("Macro")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_MANFOCUS, EXIF_FORMAT_SHORT, + { {0, N_("Auto")}, + {1, N_("Manual")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_SHARPNESS, EXIF_FORMAT_SHORT, + { {0, N_("Normal")}, + {1, N_("Hard")}, + {2, N_("Soft")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, EXIF_FORMAT_SHORT, + { {0, N_("No")}, + {1, N_("Yes")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_CONTRAST, EXIF_FORMAT_SHORT, + { {0, N_("Hard")}, + {1, N_("Normal")}, + {2, N_("Soft")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, EXIF_FORMAT_LONG, + { {0, N_("No")}, + {1, N_("Yes")}, + {0, NULL}}}, + { MNOTE_OLYMPUS_TAG_CCDSCANMODE, EXIF_FORMAT_SHORT, + { {0, N_("Interlaced")}, + {1, N_("Progressive")}, + {0, NULL}}}, + + { MNOTE_SANYO_TAG_SEQUENTIALSHOT, EXIF_FORMAT_SHORT, + { {0, N_("None")}, + {1, N_("Standard")}, + {2, N_("Best")}, + {3, N_("Adjust exposure")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_FOCUSMODE, EXIF_FORMAT_SHORT, + { {1, N_("Spot focus")}, + {2, N_("Normal focus")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, EXIF_FORMAT_SHORT, + { {0, N_("Record while down")}, + {1, N_("Press start, press stop")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_RESAVED, EXIF_FORMAT_SHORT, + { {0, N_("No")}, + {1, N_("Yes")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_CCDSENSITIVITY, EXIF_FORMAT_SHORT, + { {0, N_("Auto")}, + {1, N_("ISO 50")}, + {3, N_("ISO 100")}, + {4, N_("ISO 200")}, + {5, N_("ISO 400")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_SCENESELECT, EXIF_FORMAT_SHORT, + { {0, N_("Off")}, + {1, N_("Sport")}, + {2, N_("TV")}, + {3, N_("Night")}, + {4, N_("User 1")}, + {5, N_("User 2")}, + {6, N_("Lamp")}, + {0, NULL}}}, + { MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, EXIF_FORMAT_SHORT, + { {0, N_("5 frames/sec")}, + {1, N_("10 frames/sec")}, + {2, N_("15 frames/sec")}, + {3, N_("20 frames/sec")}, + {0, NULL}}}, +#endif + { 0, 0, { { 0, NULL } } } +}; + +char * +mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *v, unsigned int maxlen) +{ + char buf[30]; + ExifLong vl; + ExifShort vs = 0; + ExifSShort vss = 0; + ExifRational vr, vr2; + ExifSRational vsr; + int i, j; + double r, b; + + if (!entry) + return (NULL); + + memset (v, 0, maxlen); + maxlen--; + + if ((!entry->data) && (entry->components > 0)) + return (v); + + switch (entry->tag) { + + /* Nikon */ + case MNOTE_NIKON_TAG_FIRMWARE: + CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); + CC (entry->components, 4, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + if ((vl & 0xF0F0F0F0) == 0x30303030) { + memcpy (v, entry->data, MIN (maxlen, 4)); + } else { + snprintf (v, maxlen, "%04lx", (long unsigned int) vl); + } + break; + case MNOTE_NIKON_TAG_ISO: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 2, v, maxlen); + /*vs = exif_get_short (entry->data, entry->order);*/ + vs = exif_get_short (entry->data + 2, entry->order); + snprintf (v, maxlen, "ISO %hd", vs); + break; + case MNOTE_NIKON_TAG_ISO2: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 2, v, maxlen); + /*vs = exif_get_short (entry->data, entry->order);*/ + vs = exif_get_short (entry->data + 2, entry->order); + snprintf (v, maxlen, "ISO2 %hd", vs); + break; + case MNOTE_NIKON_TAG_QUALITY: + case MNOTE_NIKON_TAG_COLORMODE: + case MNOTE_NIKON_TAG_COLORMODE1: + case MNOTE_NIKON_TAG_WHITEBALANCE: + case MNOTE_NIKON_TAG_SHARPENING: + case MNOTE_NIKON_TAG_FOCUSMODE: + case MNOTE_NIKON_TAG_FLASHSETTING: + case MNOTE_NIKON_TAG_ISOSELECTION: + case MNOTE_NIKON_TAG_FLASHMODE: + case MNOTE_NIKON_TAG_IMAGEADJUSTMENT: + case MNOTE_NIKON_TAG_ADAPTER: + case MNOTE_NIKON_TAG_SATURATION2: + case MNOTE_EPSON_TAG_SOFTWARE: + CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); + memcpy(v, entry->data, MIN (maxlen, entry->size)); + break; + case MNOTE_NIKON_TAG_TOTALPICTURES: + case MNOTE_EPSON_TAG_IMAGE_WIDTH: + case MNOTE_EPSON_TAG_IMAGE_HEIGHT: + CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); + CC (entry->components, 1, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + snprintf (v, maxlen, "%lu", (long unsigned int) vl ); + break; + case MNOTE_NIKON_TAG_LENS_FSTOPS: + case MNOTE_NIKON_TAG_EXPOSUREDIFF: { + unsigned char a,b,c,d; + CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); + CC (entry->components, 4, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + a = (vl>>24)&0xff; b = (vl>>16)&0xff; c = (vl>>8)&0xff; d = (vl)&0xff; + snprintf (v, maxlen, "%.1f", c?(float)a*((float)b/(float)c):0 ); + break; + } + case MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION: + case MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL: + CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); + CC (entry->components, 4, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + snprintf (v, maxlen, "%.1f", ((long unsigned int) vl>>24)/6.0 ); + break; + case MNOTE_NIKON_TAG_SATURATION: + case MNOTE_NIKON_TAG_WHITEBALANCEFINE: + case MNOTE_NIKON_TAG_HUE: + case MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE: + case MNOTE_OLYMPUS_TAG_LENSTEMPERATURE: + CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen); + CC (entry->components, 1, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + snprintf (v, maxlen, "%hd", vs); + break; + case MNOTE_NIKON_TAG_WHITEBALANCERB: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + CC (entry->components, 4, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + r = (double)vr.numerator / vr.denominator; + vr = exif_get_rational (entry->data+8, entry->order); + b = (double)vr.numerator / vr.denominator; + snprintf (v, maxlen, _("Red Correction %f, blue Correction %f"), r,b); + break; + case MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + CC (entry->components, 1, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + if (vr.numerator) { + r = (double)vr.numerator / vr.denominator; + snprintf (v, maxlen, _("%2.2f meters"), r); + } else { + strncpy (v, _("No manual focus selection"), maxlen); + } + break; + case MNOTE_NIKON_TAG_SENSORPIXELSIZE: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + CC (entry->components, 2, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + vr2 = exif_get_rational (entry->data+8, entry->order); + r = (double)vr.numerator / vr.denominator; + b = (double)vr2.numerator / vr2.denominator; + snprintf (v, maxlen, "%2.2f x %2.2f um", r, b); + break; + case MNOTE_NIKON_TAG_BRACKETING: + CF2 (entry->format, EXIF_FORMAT_BYTE, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 1, v, maxlen); + if (EXIF_FORMAT_SHORT == entry->format) { + vs = exif_get_short (entry->data, entry->order); + } else { + vs = entry->data[0]; + } + snprintf (v, maxlen, "%hd", vs); + break; + case MNOTE_NIKON_TAG_AFFOCUSPOSITION: + CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); + CC (entry->components, 4, v, maxlen); + switch ( *( entry->data+1) ) { + case 0: strncpy (v, _("AF position: center"), maxlen); break; + case 1: strncpy (v, _("AF position: top"), maxlen); break; + case 2: strncpy (v, _("AF position: bottom"), maxlen); break; + case 3: strncpy (v, _("AF position: left"), maxlen); break; + case 4: strncpy (v, _("AF position: right"), maxlen); break; + case 5: strncpy (v, _("AF position: upper-left"), maxlen); break; + case 6: strncpy (v, _("AF position: upper-right"), maxlen); break; + case 7: strncpy (v, _("AF position: lower-left"), maxlen); break; + case 8: strncpy (v, _("AF position: lower-right"), maxlen); break; + case 9: strncpy (v, _("AF position: far left"), maxlen); break; + case 10: strncpy (v, _("AF position: far right"), maxlen); break; + default: strncpy (v, _("Unknown AF position"), maxlen); + } + break; + case MNOTE_OLYMPUS_TAG_FLASHDEVICE: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 2, v, maxlen); + vs = exif_get_short(entry->data, entry->order); + /* search for the tag */ + for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++) + ; + if (!items[i].tag) { + snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs); + break; + } + CF (entry->format, items[i].fmt, v, maxlen); + /* find the value */ + for (j = 0; items[i].elem[j].string && + (items[i].elem[j].index < vs); j++); + if (items[i].elem[j].index != vs) { + snprintf (v, maxlen, _("Unknown value %hi"), vs); + break; + } + strncpy (v, _(items[i].elem[j].string), maxlen); + break; + case MNOTE_OLYMPUS_TAG_DIGIZOOM: + if (entry->format == EXIF_FORMAT_RATIONAL) { + CC (entry->components, 1, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + if (!vr.numerator) { + strncpy (v, _("None"), maxlen); + } else { + r = (double)vr.numerator / vr.denominator; + snprintf (v, maxlen, "%2.2f", r); + } + break; + } + /* fall through to handle SHORT version of this tag */ + case MNOTE_NIKON_TAG_LENSTYPE: + case MNOTE_NIKON_TAG_FLASHUSED: + case MNOTE_NIKON1_TAG_QUALITY: + case MNOTE_NIKON1_TAG_COLORMODE: + case MNOTE_NIKON1_TAG_IMAGEADJUSTMENT: + case MNOTE_NIKON1_TAG_CCDSENSITIVITY: + case MNOTE_NIKON1_TAG_WHITEBALANCE: + case MNOTE_NIKON1_TAG_CONVERTER: + case MNOTE_OLYMPUS_TAG_QUALITY: + case MNOTE_OLYMPUS_TAG_MACRO: + case MNOTE_OLYMPUS_TAG_BWMODE: + case MNOTE_OLYMPUS_TAG_ONETOUCHWB: + case MNOTE_OLYMPUS_TAG_FLASHMODE: + case MNOTE_OLYMPUS_TAG_FOCUSRANGE: + case MNOTE_OLYMPUS_TAG_MANFOCUS: + case MNOTE_OLYMPUS_TAG_SHARPNESS: + case MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE: + case MNOTE_OLYMPUS_TAG_CONTRAST: + case MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID: + case MNOTE_OLYMPUS_TAG_CCDSCANMODE: + case MNOTE_SANYO_TAG_SEQUENTIALSHOT: + case MNOTE_SANYO_TAG_FOCUSMODE: + case MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE: + case MNOTE_SANYO_TAG_RESAVED: + case MNOTE_SANYO_TAG_CCDSENSITIVITY: + case MNOTE_SANYO_TAG_SCENESELECT: + case MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL: + CC (entry->components, 1, v, maxlen); + switch (entry->format) { + case EXIF_FORMAT_BYTE: + case EXIF_FORMAT_UNDEFINED: + vs = entry->data[0]; + break; + case EXIF_FORMAT_SHORT: + vs = exif_get_short(entry->data, entry->order); + break; + default: + vs = 0; + break; + } + /* search for the tag */ + for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++) + ; + if (!items[i].tag) { + snprintf (v, maxlen, _("Internal error (unknown value %hi)"), vs); + break; + } + CF (entry->format, items[i].fmt, v, maxlen); + /* find the value */ + for (j = 0; items[i].elem[j].string && + (items[i].elem[j].index < vs); j++); + if (items[i].elem[j].index != vs) { + snprintf (v, maxlen, _("Unknown value %hi"), vs); + break; + } + strncpy (v, _(items[i].elem[j].string), maxlen); + break; + case MNOTE_OLYMPUS_TAG_NOISEREDUCTION: + case MNOTE_SANYO_TAG_WIDERANGE: + case MNOTE_SANYO_TAG_COLORADJUSTMENTMODE: + case MNOTE_SANYO_TAG_QUICKSHOT: + case MNOTE_SANYO_TAG_VOICEMEMO: + case MNOTE_SANYO_TAG_FLICKERREDUCE: + case MNOTE_SANYO_TAG_OPTICALZOOM: + case MNOTE_SANYO_TAG_DIGITALZOOM: + case MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 1, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + switch (vs) { + case 0: + strncpy (v, _("Off"), maxlen); + break; + case 1: + strncpy (v, _("On"), maxlen); + break; + default: + sprintf (buf, _("Unknown %hu"), vs); + strncat (v, buf, maxlen - strlen (v)); + break; + } + break; + case MNOTE_SANYO_TAG_SELFTIMER: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 1, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + switch (vs) { + case 0: + strncpy (v, _("Off"), maxlen); + break; + case 1: + strncpy (v, _("On"), maxlen); + break; + case 2: + strncpy (v, _("2 sec."), maxlen); + break; + default: + sprintf (buf, _("Unknown %hu"), vs); + strncat (v, buf, maxlen - strlen (v)); + break; + } + break; + case MNOTE_NIKON_TAG_LENS: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + CC (entry->components, 4, v, maxlen); + { + double c,d; + unsigned long a,b; + vr = exif_get_rational (entry->data, entry->order); + a = vr.numerator / vr.denominator; + vr = exif_get_rational (entry->data+8, entry->order); + b = vr.numerator / vr.denominator; + vr = exif_get_rational (entry->data+16, entry->order); + c = (double)vr.numerator / vr.denominator; + vr = exif_get_rational (entry->data+24, entry->order); + d = (double)vr.numerator / vr.denominator; + snprintf (v, maxlen, "%ld-%ldmm 1:%3.1f - %3.1f",a,b,c,d); + } + break; + + /* Olympus */ + case MNOTE_OLYMPUS_TAG_MODE: + CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); + CC (entry->components, 3, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + switch (vl) { + case 0: + strncpy (v, _("Normal"), maxlen); + break; + case 1: + strncpy (v, _("Unknown"), maxlen); + break; + case 2: + strncpy (v, _("Fast"), maxlen); + break; + case 3: + strncpy (v, _("Panorama"), maxlen); + break; + default: + snprintf (v, maxlen, "%li", (long int) vl); + } + vl = exif_get_long (entry->data + 4, entry->order); + snprintf (buf, sizeof (buf), "/%li/", (long int) vl); + strncat (v, buf, maxlen - strlen (v)); + vl = exif_get_long (entry->data + 8, entry->order); + switch (vl) { + case 1: + strncat (v, _("Left to right"), maxlen - strlen (v)); + break; + case 2: + strncat (v, _("Right to left"), maxlen - strlen (v)); + break; + case 3: + strncat (v, _("Bottom to top"), maxlen - strlen (v)); + break; + case 4: + strncat (v, _("Top to bottom"), maxlen - strlen (v)); + break; + default: + snprintf (buf, sizeof (buf), "%li", + (long int) vl); + strncat (v, buf, maxlen - strlen (v)); + } + break; + case MNOTE_OLYMPUS_TAG_LENSDISTORTION: + if (entry->format == EXIF_FORMAT_SHORT) { + /* Epson uses a single SHORT here */ + CC (entry->components, 1, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + sprintf (buf, "%hu", vs); + strncat (v, buf, maxlen - strlen (v)); + } else { + /* Others use an array of SSHORT here */ + CC (entry->components, 6, v, maxlen); + CF (entry->format, EXIF_FORMAT_SSHORT, v, maxlen); + for (i=0; i < (int)entry->components; ++i) { + vss = exif_get_sshort (entry->data+2*i, entry->order); + sprintf (buf, "%hd ", vss); + strncat (v, buf, maxlen - strlen (v)); + } + } + break; + case MNOTE_OLYMPUS_TAG_COLORCONTROL: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 6, v, maxlen); + for (i=0; i < (int)entry->components; ++i) { + vs = exif_get_short (entry->data+2*i, entry->order); + sprintf (buf, "%hu ", vs); + strncat (v, buf, maxlen - strlen (v)); + } + break; + case MNOTE_OLYMPUS_TAG_VERSION: + CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); + CC2 (entry->components, 5, 8, v, maxlen); + strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); + break; + case MNOTE_OLYMPUS_TAG_SERIALNUMBER2: + CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); + strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); + break; + case MNOTE_OLYMPUS_TAG_INFO: + CF (entry->format, EXIF_FORMAT_ASCII, v, maxlen); + CC2 (entry->components, 52, 60, v, maxlen); + strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); + break; + case MNOTE_OLYMPUS_TAG_ID: + CF (entry->format, EXIF_FORMAT_UNDEFINED, v, maxlen); + CC (entry->components, 32, v, maxlen); + strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); + break; + case MNOTE_OLYMPUS_TAG_UNKNOWN_4: + CF (entry->format, EXIF_FORMAT_LONG, v, maxlen); + CC (entry->components, 30, v, maxlen); + for (i=0; i < (int)entry->components; ++i) { + vl = exif_get_long (entry->data+4*i, entry->order); + sprintf (buf, "%lu ", (unsigned long)vl); + strncat (v, buf, maxlen - strlen (v)); + } + break; + case MNOTE_OLYMPUS_TAG_FOCUSDIST: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + CC (entry->components, 1, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + if (vr.numerator == 0) { + strncpy (v, _("Unknown"), maxlen); + } + else { + unsigned long tmp = vr.numerator / vr.denominator; + snprintf (v, maxlen, "%li mm", tmp); + } + break; + case MNOTE_OLYMPUS_TAG_WBALANCE: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 2, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + switch (vs) { + case 1: + strncpy (v, _("Automatic"), maxlen); + break; + case 2: + { + ExifShort v2 = exif_get_short (entry->data + 2, entry->order); + unsigned long colorTemp = 0; + switch (v2) { + case 2: + colorTemp = 3000; + break; + case 3: + colorTemp = 3700; + break; + case 4: + colorTemp = 4000; + break; + case 5: + colorTemp = 4500; + break; + case 6: + colorTemp = 5500; + break; + case 7: + colorTemp = 6500; + break; + case 9: + colorTemp = 7500; + break; + } + if (colorTemp) { + snprintf (v, maxlen, _("Manual: %liK"), colorTemp); + } + else { + strncpy (v, _("Manual: unknown"), maxlen); + } + + } + break; + case 3: + strncpy (v, _("One-touch"), maxlen); + break; + default: + strncpy (v, _("Unknown"), maxlen); + break; + } + break; + case MNOTE_OLYMPUS_TAG_REDBALANCE: + case MNOTE_OLYMPUS_TAG_BLUEBALANCE: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + CC (entry->components, 2, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + snprintf (v, maxlen, "%hu ", vs); + vs = exif_get_short (entry->data + 2, entry->order); + sprintf (buf, "%hu", vs); + strncat (v, buf, maxlen - strlen (v)); + break; + case MNOTE_OLYMPUS_TAG_BLACKLEVEL: + case MNOTE_NIKON_TAG_IMAGEBOUNDARY: + CC (entry->components, 4, v, maxlen); + /* Fall through to COLORMATRIX */ + case MNOTE_OLYMPUS_TAG_COLORMATRIX: + CF (entry->format, EXIF_FORMAT_SHORT, v, maxlen); + if (entry->tag == MNOTE_OLYMPUS_TAG_COLORMATRIX) + CC (entry->components, 9, v, maxlen); + for (i=0; i < (int)entry->components; ++i) { + vs = exif_get_short (entry->data+2*i, entry->order); + sprintf (buf, "%hu ", vs); + strncat (v, buf, maxlen - strlen (v)); + } + break; + case MNOTE_NIKON1_TAG_FOCUS: + case MNOTE_NIKON_TAG_DIGITALZOOM: + case MNOTE_NIKON1_TAG_DIGITALZOOM: + case MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL: + CF (entry->format, EXIF_FORMAT_RATIONAL, v, maxlen); + /* Fall through to default handler for display */ + default: + switch (entry->format) { + case EXIF_FORMAT_ASCII: + strncpy (v, (char *)entry->data, MIN (maxlen, entry->size)); + break; + case EXIF_FORMAT_SHORT: + CC (entry->components, 1, v, maxlen); + vs = exif_get_short (entry->data, entry->order); + snprintf (v, maxlen, "%hu", vs); + break; + case EXIF_FORMAT_LONG: + CC (entry->components, 1, v, maxlen); + vl = exif_get_long (entry->data, entry->order); + snprintf (v, maxlen, "%li", (long int) vl); + break; + case EXIF_FORMAT_RATIONAL: + CC (entry->components, 1, v, maxlen); + vr = exif_get_rational (entry->data, entry->order); + if (!vr.denominator) { + strncpy (v, _("Infinite"), maxlen); + } else { + r = (double)vr.numerator / vr.denominator; + snprintf (v, maxlen, "%2.3f", r); + } + break; + case EXIF_FORMAT_SRATIONAL: + CC (entry->components, 1, v, maxlen); + vsr = exif_get_srational (entry->data, entry->order); + if (!vsr.denominator) { + strncpy (v, _("Infinite"), maxlen); + } else { + r = (double)vsr.numerator / vsr.denominator; + snprintf (v, maxlen, "%2.3f", r); + } + break; + case EXIF_FORMAT_UNDEFINED: + default: + snprintf (v, maxlen, _("%i bytes unknown data: "), + entry->size); + for (i = 0; i < (int)entry->size; i++) { + sprintf (buf, "%02x", entry->data[i]); + strncat (v, buf, maxlen - strlen (v)); + } + break; + } + break; + } + + return (v); +} diff --git a/libexifa/olympus/mnote-olympus-tag.c b/libexifa/olympus/mnote-olympus-tag.c new file mode 100755 index 0000000..3810352 --- /dev/null +++ b/libexifa/olympus/mnote-olympus-tag.c @@ -0,0 +1,230 @@ +/* mnote-olympus-tag.c: + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "mnote-olympus-tag.h" + +#include +#include + +#include + +static const struct { + MnoteOlympusTag tag; + const char *name; + const char *title; + const char *description; +} table[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + /* Nikon v2 */ + {MNOTE_NIKON_TAG_FIRMWARE, "Firmware", N_("Firmware Version"), ""}, + {MNOTE_NIKON_TAG_ISO, "ISO", N_("ISO Setting"), ""}, + {MNOTE_NIKON_TAG_COLORMODE1, "ColorMode1", N_("Color Mode (?)"), ""}, + {MNOTE_NIKON_TAG_QUALITY, "Quality", N_("Quality"), ""}, + {MNOTE_NIKON_TAG_WHITEBALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_NIKON_TAG_SHARPENING, "Sharpening", N_("Image Sharpening"), ""}, + {MNOTE_NIKON_TAG_FOCUSMODE, "FocusMode", N_("Focus Mode"), ""}, + {MNOTE_NIKON_TAG_FLASHSETTING, "FlashSetting", N_("Flash Setting"), ""}, + {MNOTE_NIKON_TAG_FLASHMODE, "FlashMode", N_("Flash Mode"), ""}, + {MNOTE_NIKON_TAG_WHITEBALANCEFINE,"WhiteBalanceFine",N_("White Balance Fine Adjustment"), ""}, + {MNOTE_NIKON_TAG_WHITEBALANCERB, "WhiteBalanceRB", N_("White Balance RB"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X000D, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_ISOSELECTION, "ISOSelection", N_("ISO Selection"), ""}, + {MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER, "PreviewImage", N_("Preview Image IFD"), N_("Offset of the preview image directory (IFD) inside the file.")}, + {MNOTE_NIKON_TAG_EXPOSUREDIFF, "ExposureDiff", N_("Exposurediff ?"), ""}, + {MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION, "FlashExpCompensation", N_("Flash Exposure Compensation"), ""}, + {MNOTE_NIKON_TAG_ISO2, "ISO", N_("ISO Setting"), ""}, + {MNOTE_NIKON_TAG_IMAGEBOUNDARY, "ImageBoundary", N_("Image Boundary"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0017, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL, "FlashExposureBracketVal", N_("Flash Exposure Bracket Value"), ""}, + {MNOTE_NIKON_TAG_EXPOSUREBRACKETVAL, "ExposureBracketVal", N_("Exposure Bracket Value"), ""}, + {MNOTE_NIKON_TAG_IMAGEADJUSTMENT, "ImageAdjustment", N_("Image Adjustment"), ""}, + {MNOTE_NIKON_TAG_TONECOMPENSATION, "ToneCompensation", N_("Tone Compensation"), ""}, + {MNOTE_NIKON_TAG_ADAPTER, "Adapter", N_("Adapter"), ""}, + {MNOTE_NIKON_TAG_LENSTYPE, "LensType", N_("Lens Type"), ""}, + {MNOTE_NIKON_TAG_LENS, "Lens", N_("Lens"), ""}, + {MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE, "ManualFocusDistance", N_("Manual Focus Distance"), ""}, + {MNOTE_NIKON_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""}, + {MNOTE_NIKON_TAG_FLASHUSED, "FlashUsed", N_("Flash Used"), ""}, + {MNOTE_NIKON_TAG_AFFOCUSPOSITION, "AFFocusPosition", N_("AF Focus Position"), ""}, + {MNOTE_NIKON_TAG_BRACKETING, "Bracketing", N_("Bracketing"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X008A, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_LENS_FSTOPS, "LensFStops", N_("Lens F Stops"), ""}, + {MNOTE_NIKON_TAG_CURVE, "Curve,", N_("Contrast Curve"), ""}, + {MNOTE_NIKON_TAG_COLORMODE, "ColorMode,", N_("Color Mode"), ""}, + {MNOTE_NIKON_TAG_LIGHTTYPE, "LightType,", N_("Light Type"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0091, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_HUE, "Hue", N_("Hue Adjustment"), ""}, + {MNOTE_NIKON_TAG_SATURATION, "Saturation", N_("Saturation"), ""}, + {MNOTE_NIKON_TAG_NOISEREDUCTION, "NoiseReduction,", N_("Noise Reduction"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0097, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0098, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_SENSORPIXELSIZE, "SensorPixelSize", N_("Sensor Pixel Size"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X009B, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_SERIALNUMBER, "SerialNumber", N_("Serial Number"), ""}, + {MNOTE_NIKON_TAG_IMAGE_DATASIZE, "ImageDataSize", N_("Image Data Size"), N_("Size of compressed image data in bytes.")}, + {MNOTE_NIKON_TAG_UNKNOWN_0X00A3, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_TOTALPICTURES, "TotalPictures,", N_("Total Number of Pictures Taken"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X00A8, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_OPTIMIZATION, "Optimization,", N_("Optimize Image"), ""}, + {MNOTE_NIKON_TAG_SATURATION, "Saturation", N_("Saturation"), ""}, + {MNOTE_NIKON_TAG_VARIPROGRAM, "VariProgram", N_("Vari Program"), ""}, + {MNOTE_NIKON_TAG_CAPTUREEDITORDATA, "CaptureEditorData", N_("Capture Editor Data"), ""}, + {MNOTE_NIKON_TAG_CAPTUREEDITORVER, "CaptureEditorVer", N_("Capture Editor Version"), ""}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0E0E, NULL, NULL, NULL}, + {MNOTE_NIKON_TAG_UNKNOWN_0X0E10, NULL, NULL, NULL}, + {MNOTE_NIKON1_TAG_UNKNOWN_0X0002, NULL, NULL, NULL}, + {MNOTE_NIKON1_TAG_QUALITY, "Quality", N_("Quality"), ""}, + {MNOTE_NIKON1_TAG_COLORMODE, "ColorMode,", N_("Color Mode"), ""}, + {MNOTE_NIKON1_TAG_IMAGEADJUSTMENT, "ImageAdjustment", N_("Image Adjustment"), ""}, + {MNOTE_NIKON1_TAG_CCDSENSITIVITY, "CCDSensitivity", N_("CCD Sensitivity"), ""}, + {MNOTE_NIKON1_TAG_WHITEBALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_NIKON1_TAG_FOCUS, "Focus", N_("Focus"), ""}, + {MNOTE_NIKON1_TAG_UNKNOWN_0X0009, NULL, NULL, NULL}, + {MNOTE_NIKON1_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""}, + {MNOTE_NIKON1_TAG_CONVERTER, "Converter", N_("Converter"), ""}, + + /* Olympus & some Sanyo */ + {MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE, "ThumbnailImage", N_("Thumbnail Image"), ""}, + {MNOTE_OLYMPUS_TAG_MODE, "Mode", N_("Speed/Sequence/Panorama Direction"), ""}, + {MNOTE_OLYMPUS_TAG_QUALITY, "Quality", N_("Quality"), ""}, + {MNOTE_OLYMPUS_TAG_MACRO, "Macro", N_("Macro"), ""}, + {MNOTE_OLYMPUS_TAG_BWMODE, "BWMode", N_("Black & White Mode"), ""}, + {MNOTE_OLYMPUS_TAG_DIGIZOOM, "DigiZoom", N_("Digital Zoom"), ""}, + {MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL, "FocalPlaneDiagonal", N_("Focal Plane Diagonal"), ""}, + {MNOTE_OLYMPUS_TAG_LENSDISTORTION, "LensDistortionParams", N_("Lens Distortion Parameters"), ""}, + {MNOTE_OLYMPUS_TAG_VERSION, "FirmwareVersion", N_("Firmware Version"), ""}, + {MNOTE_OLYMPUS_TAG_INFO, "Info", N_("Info"), ""}, + {MNOTE_OLYMPUS_TAG_ID, "CameraID", N_("Camera ID"), ""}, + {MNOTE_OLYMPUS_TAG_PRECAPTUREFRAMES, "PreCaptureFrames", N_("Precapture Frames"), ""}, + {MNOTE_OLYMPUS_TAG_WHITEBOARD, "WhiteBoard", N_("White Board"), ""}, + {MNOTE_OLYMPUS_TAG_ONETOUCHWB, "OneTouchWB", N_("One Touch White Balance"), ""}, + {MNOTE_OLYMPUS_TAG_WHITEBALANCEBRACKET, "WhiteBalanceBracket", N_("White Balance Bracket"), ""}, + {MNOTE_OLYMPUS_TAG_WHITEBALANCEBIAS, "WhiteBalanceBias", N_("White Balance Bias"), ""}, + {MNOTE_OLYMPUS_TAG_DATADUMP, "DataDump", N_("Data Dump"), NULL}, + {MNOTE_OLYMPUS_TAG_UNKNOWN_4, NULL, NULL, NULL}, + {MNOTE_OLYMPUS_TAG_SHUTTERSPEED, "ShutterSpeed", N_("Shutter Speed"), ""}, + {MNOTE_OLYMPUS_TAG_ISOVALUE, "ISOValue", N_("ISO Value"), ""}, + {MNOTE_OLYMPUS_TAG_APERTUREVALUE, "ApertureValue", N_("Aperture Value"), ""}, + {MNOTE_OLYMPUS_TAG_BRIGHTNESSVALUE, "BrightnessValue", N_("Brightness Value"), ""}, + {MNOTE_OLYMPUS_TAG_FLASHMODE, "FlashMode", N_("Flash Mode"), ""}, + {MNOTE_OLYMPUS_TAG_FLASHDEVICE, "FlashDevice", N_("Flash Device"), ""}, + {MNOTE_OLYMPUS_TAG_EXPOSURECOMP, "ExposureCompensation", N_("Exposure Compensation"), ""}, + {MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE, "SensorTemperature", N_("Sensor Temperature"), ""}, + {MNOTE_OLYMPUS_TAG_LENSTEMPERATURE, "LensTemperature", N_("Lens Temperature"), ""}, + {MNOTE_OLYMPUS_TAG_LIGHTCONDITION, "LightCondition", N_("Light Condition"), ""}, + {MNOTE_OLYMPUS_TAG_FOCUSRANGE, "FocusRange", N_("Focus Range"), ""}, + {MNOTE_OLYMPUS_TAG_MANFOCUS, "FocusMode", N_("Focus Mode"), "Automatic or manual focusing mode"}, + {MNOTE_OLYMPUS_TAG_FOCUSDIST, "ManualFocusDistance", N_("Manual Focus Distance"), ""}, + {MNOTE_OLYMPUS_TAG_ZOOMSTEPCOUNT, "ZoomStepCount", N_("Zoom Step Count"), ""}, + {MNOTE_OLYMPUS_TAG_FOCUSSTEPCOUNT, "FocusStepCount", N_("Focus Step Count"), ""}, + {MNOTE_OLYMPUS_TAG_SHARPNESS, "Sharpness", N_("Sharpness Setting"), ""}, + {MNOTE_OLYMPUS_TAG_FLASHCHARGELEVEL, "FlashChargeLevel", N_("Flash Charge Level"), ""}, + {MNOTE_OLYMPUS_TAG_COLORMATRIX, "ColorMatrix", N_("Color Matrix"), ""}, + {MNOTE_OLYMPUS_TAG_BLACKLEVEL, "BlackLevel", N_("Black Level"), ""}, + {MNOTE_OLYMPUS_TAG_WBALANCE, "WhiteBalance", N_("White Balance Setting"), ""}, + {MNOTE_OLYMPUS_TAG_REDBALANCE, "RedBalance", N_("Red Balance"), ""}, + {MNOTE_OLYMPUS_TAG_BLUEBALANCE, "BlueBalance", N_("Blue Balance"), ""}, + {MNOTE_OLYMPUS_TAG_COLORMATRIXNUMBER, "ColorMatrixNumber", N_("Color Matrix Number"), ""}, + {MNOTE_OLYMPUS_TAG_SERIALNUMBER2, "SerialNumber", N_("Serial Number"), ""}, + {MNOTE_OLYMPUS_TAG_FLASHEXPOSURECOMP, "FlashExposureComp", N_("Flash Exposure Comp"), ""}, + {MNOTE_OLYMPUS_TAG_INTERNALFLASHTABLE, "InternalFlashTable", N_("Internal Flash Table"), ""}, + {MNOTE_OLYMPUS_TAG_EXTERNALFLASHGVALUE, "ExternalFlashGValue", N_("External Flash G Value"), ""}, + {MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE, "ExternalFlashBounce", N_("External Flash Bounce"), ""}, + {MNOTE_OLYMPUS_TAG_EXTERNALFLASHZOOM, "ExternalFlashZoom", N_("External Flash Zoom"), ""}, + {MNOTE_OLYMPUS_TAG_EXTERNALFLASHMODE, "ExternalFlashMode", N_("External Flash Mode"), ""}, + {MNOTE_OLYMPUS_TAG_CONTRAST, "Contrast", N_("Contrast Setting"), ""}, + {MNOTE_OLYMPUS_TAG_SHARPNESSFACTOR, "SharpnessFactor", N_("Sharpness Factor"), ""}, + {MNOTE_OLYMPUS_TAG_COLORCONTROL, "ColorControl", N_("Color Control"), ""}, + {MNOTE_OLYMPUS_TAG_IMAGEWIDTH, "OlympusImageWidth", N_("Olympus Image Width"), ""}, + {MNOTE_OLYMPUS_TAG_IMAGEHEIGHT, "OlympusImageHeight", N_("Olympus Image Height"), ""}, + {MNOTE_OLYMPUS_TAG_SCENEDETECT, "SceneDetect", N_("Scene Detect"), ""}, + {MNOTE_OLYMPUS_TAG_COMPRESSIONRATIO, "CompressionRatio", N_("Compression Ratio"), ""}, + {MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID, "PreviewImageValid", N_("Preview Image Valid"), ""}, + {MNOTE_OLYMPUS_TAG_AFRESULT, "AFResult", N_("AF Result"), ""}, + {MNOTE_OLYMPUS_TAG_CCDSCANMODE, "CCDScanMode", N_("CCD Scan Mode"), ""}, + {MNOTE_OLYMPUS_TAG_NOISEREDUCTION, "NoiseReduction", N_("Noise Reduction"), ""}, + {MNOTE_OLYMPUS_TAG_INFINITYLENSSTEP, "InfinityLensStep", N_("Infinity Lens Step"), ""}, + {MNOTE_OLYMPUS_TAG_NEARLENSSTEP, "NearLensStep", N_("Near Lens Step"), ""}, + {MNOTE_OLYMPUS_TAG_LIGHTVALUECENTER, "LightValueCenter", N_("Light Value Center"), ""}, + {MNOTE_OLYMPUS_TAG_LIGHTVALUEPERIPHERY, "LightValuePeriphery", N_("Light Value Periphery"), ""}, + + /* Sanyo */ + {MNOTE_SANYO_TAG_SEQUENTIALSHOT, "SequentialShot", N_("Sequential Shot"), ""}, + {MNOTE_SANYO_TAG_WIDERANGE, "WideRange", N_("Wide Range"), ""}, + {MNOTE_SANYO_TAG_COLORADJUSTMENTMODE, "ColorAdjustmentMode", N_("Color Adjustment Mode"), ""}, + {MNOTE_SANYO_TAG_FOCUSMODE, "FocusMode", N_("Focus Mode"), ""}, + {MNOTE_SANYO_TAG_QUICKSHOT, "QuickShot", N_("Quick Shot"), ""}, + {MNOTE_SANYO_TAG_SELFTIMER, "SelfTimer", N_("Self-timer"), ""}, + {MNOTE_SANYO_TAG_VOICEMEMO, "VoiceMemo", N_("Voice Memo"), ""}, + {MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE, "RecordShutterRelease", N_("Record Shutter Release"), ""}, + {MNOTE_SANYO_TAG_FLICKERREDUCE, "FlickerReduce", N_("Flicker Reduce"), ""}, + {MNOTE_SANYO_TAG_OPTICALZOOM, "OpticalZoom", N_("Optical Zoom"), ""}, + {MNOTE_SANYO_TAG_DIGITALZOOM, "DigitalZoom", N_("Digital Zoom"), ""}, + {MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL, "LightSourceSpecial", N_("Light Source Special"), ""}, + {MNOTE_SANYO_TAG_RESAVED, "Resaved", N_("Resaved"), ""}, + {MNOTE_SANYO_TAG_CCDSENSITIVITY, "CCDSensitivity", N_("CCD Sensitivity"), ""}, + {MNOTE_SANYO_TAG_SCENESELECT, "SceneSelect", N_("Scene Select"), ""}, + {MNOTE_SANYO_TAG_MANUALFOCUSDISTANCE, "ManualFocusDistance", N_("Manual Focus Distance"), ""}, + {MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL, "SequenceShotInterval", N_("Sequence Shot Interval"), ""}, + + /* Epson */ + {MNOTE_EPSON_TAG_IMAGE_WIDTH, "EpsonImageWidth", N_("Epson Image Width"), ""}, + {MNOTE_EPSON_TAG_IMAGE_HEIGHT, "EpsonImageHeight", N_("Epson Image Height"), ""}, + {MNOTE_EPSON_TAG_SOFTWARE, "EpsonSoftware", N_("Epson Software Version"), ""}, +#endif + {0, NULL, NULL, NULL} +}; + +const char * +mnote_olympus_tag_get_name (MnoteOlympusTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (table[i].name); + return NULL; +} + +const char * +mnote_olympus_tag_get_title (MnoteOlympusTag t) +{ + unsigned int i; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (_(table[i].title)); + return NULL; +} + +const char * +mnote_olympus_tag_get_description (MnoteOlympusTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) { + if (!table[i].description || !*table[i].description) + return ""; + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(table[i].description); + } + return NULL; +} diff --git a/libexifa/pentax/exif-mnote-data-pentax.c b/libexifa/pentax/exif-mnote-data-pentax.c new file mode 100755 index 0000000..757bb72 --- /dev/null +++ b/libexifa/pentax/exif-mnote-data-pentax.c @@ -0,0 +1,449 @@ +/* exif-mnote-data-pentax.c + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "exif-mnote-data-pentax.h" + +#include +#include +#include + +#include +#include + +static void +exif_mnote_data_pentax_clear (ExifMnoteDataPentax *n) +{ + ExifMnoteData *d = (ExifMnoteData *) n; + unsigned int i; + + if (!n) return; + + if (n->entries) { + for (i = 0; i < n->count; i++) + if (n->entries[i].data) { + exif_mem_free (d->mem, n->entries[i].data); + n->entries[i].data = NULL; + } + exif_mem_free (d->mem, n->entries); + n->entries = NULL; + n->count = 0; + } +} + +static void +exif_mnote_data_pentax_free (ExifMnoteData *n) +{ + if (!n) return; + + exif_mnote_data_pentax_clear ((ExifMnoteDataPentax *) n); +} + +static char * +exif_mnote_data_pentax_get_value (ExifMnoteData *d, unsigned int i, char *val, unsigned int maxlen) +{ + ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d; + + if (!n) return NULL; + if (n->count <= i) return NULL; + return mnote_pentax_entry_get_value (&n->entries[i], val, maxlen); +} + +/** + * @brief save the MnoteData from ne to buf + * + * @param ne extract the data from this structure + * @param *buf write the mnoteData to this buffer (buffer will be allocated) + * @param buf_size the final size of the buffer + */ +static void +exif_mnote_data_pentax_save (ExifMnoteData *ne, + unsigned char **buf, unsigned int *buf_size) +{ + ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) ne; + size_t i, + base = 0, /* internal MakerNote tag number offset */ + o2 = 4 + 2; /* offset to first tag entry, past header */ + size_t datao = n->offset; /* this MakerNote style uses offsets + based on main IFD, not makernote IFD */ + + if (!n || !buf || !buf_size) return; + + /* + * Allocate enough memory for header, the number of entries, entries, + * and next IFD pointer + */ + *buf_size = o2 + 2 + n->count * 12 + 4; + switch (n->version) { + case casioV2: + base = MNOTE_PENTAX2_TAG_BASE; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size); + return; + } + /* Write the magic header */ + strcpy ((char *)*buf, "QVC"); + exif_set_short (*buf + 4, n->order, (ExifShort) 0); + + break; + + case pentaxV3: + base = MNOTE_PENTAX2_TAG_BASE; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size); + return; + } + + /* Write the magic header */ + strcpy ((char *)*buf, "AOC"); + exif_set_short (*buf + 4, n->order, (ExifShort) ( + (n->order == EXIF_BYTE_ORDER_INTEL) ? + ('I' << 8) | 'I' : + ('M' << 8) | 'M')); + break; + + case pentaxV2: + base = MNOTE_PENTAX2_TAG_BASE; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size); + return; + } + + /* Write the magic header */ + strcpy ((char *)*buf, "AOC"); + exif_set_short (*buf + 4, n->order, (ExifShort) 0); + break; + + case pentaxV1: + /* It looks like this format doesn't have a magic header as + * such, just has a fixed number of entries equal to 0x001b */ + *buf_size -= 6; + o2 -= 6; + *buf = exif_mem_alloc (ne->mem, *buf_size); + if (!*buf) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", *buf_size); + return; + } + break; + + default: + /* internal error */ + return; + } + + /* Write the number of entries. */ + exif_set_short (*buf + o2, n->order, (ExifShort) n->count); + o2 += 2; + + /* Save each entry */ + for (i = 0; i < n->count; i++) { + size_t doff; /* offset to current data portion of tag */ + size_t s; + unsigned char *t; + size_t o = o2 + i * 12; /* current offset into output buffer */ + exif_set_short (*buf + o + 0, n->order, + (ExifShort) (n->entries[i].tag - base)); + exif_set_short (*buf + o + 2, n->order, + (ExifShort) n->entries[i].format); + exif_set_long (*buf + o + 4, n->order, + n->entries[i].components); + o += 8; + s = exif_format_get_size (n->entries[i].format) * + n->entries[i].components; + if (s > 65536) { + /* Corrupt data: EXIF data size is limited to the + * maximum size of a JPEG segment (64 kb). + */ + continue; + } + if (s > 4) { + size_t ts = *buf_size + s; + doff = *buf_size; + t = exif_mem_realloc (ne->mem, *buf, + sizeof (char) * ts); + if (!t) { + EXIF_LOG_NO_MEMORY(ne->log, "ExifMnoteDataPentax", ts); + return; + } + *buf = t; + *buf_size = ts; + exif_set_long (*buf + o, n->order, datao + doff); + } else + doff = o; + + /* Write the data. */ + if (n->entries[i].data) { + memcpy (*buf + doff, n->entries[i].data, s); + } else { + /* Most certainly damaged input file */ + memset (*buf + doff, 0, s); + } + } + + /* Sanity check the buffer size */ + if (*buf_size < (o2 + n->count * 12 + 4)) { + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteDataPentax", + "Buffer overflow"); + } + + /* Reset next IFD pointer */ + exif_set_long (*buf + o2 + n->count * 12, n->order, 0); +} + +static void +exif_mnote_data_pentax_load (ExifMnoteData *en, + const unsigned char *buf, unsigned int buf_size) +{ + ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) en; + size_t i, tcount, o, datao, base = 0; + ExifShort c; + + if (!n || !buf || !buf_size) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataPentax", "Short MakerNote"); + return; + } + datao = 6 + n->offset; + if ((datao + 8 < datao) || (datao + 8 < 8) || (datao + 8 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataPentax", "Short MakerNote"); + return; + } + + /* Detect variant of Pentax/Casio MakerNote found */ + if (!memcmp(buf + datao, "AOC", 4)) { + if ((buf[datao + 4] == 'I') && (buf[datao + 5] == 'I')) { + n->version = pentaxV3; + n->order = EXIF_BYTE_ORDER_INTEL; + } else if ((buf[datao + 4] == 'M') && (buf[datao + 5] == 'M')) { + n->version = pentaxV3; + n->order = EXIF_BYTE_ORDER_MOTOROLA; + } else { + /* Uses Casio v2 tags */ + n->version = pentaxV2; + } + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax", + "Parsing Pentax maker note v%d...", (int)n->version); + datao += 4 + 2; + base = MNOTE_PENTAX2_TAG_BASE; + } else if (!memcmp(buf + datao, "QVC", 4)) { + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax", + "Parsing Casio maker note v2..."); + n->version = casioV2; + base = MNOTE_CASIO2_TAG_BASE; + datao += 4 + 2; + } else { + /* probably assert(!memcmp(buf + datao, "\x00\x1b", 2)) */ + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataPentax", + "Parsing Pentax maker note v1..."); + n->version = pentaxV1; + } + + /* Read the number of tags */ + c = exif_get_short (buf + datao, n->order); + datao += 2; + + /* Remove any old entries */ + exif_mnote_data_pentax_clear (n); + + /* Reserve enough space for all the possible MakerNote tags */ + n->entries = exif_mem_alloc (en->mem, sizeof (MnotePentaxEntry) * c); + if (!n->entries) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", sizeof (MnotePentaxEntry) * c); + return; + } + + /* Parse all c entries, storing ones that are successfully parsed */ + tcount = 0; + for (i = c, o = datao; i; --i, o += 12) { + size_t s; + if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, + "ExifMnoteDataPentax", "Short MakerNote"); + break; + } + + n->entries[tcount].tag = exif_get_short (buf + o + 0, n->order) + base; + n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); + n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); + n->entries[tcount].order = n->order; + + exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnotePentax", + "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, + mnote_pentax_tag_get_name (n->entries[tcount].tag)); + + /* + * Size? If bigger than 4 bytes, the actual data is not + * in the entry but somewhere else (offset). + */ + s = exif_format_get_size (n->entries[tcount].format) * + n->entries[tcount].components; + n->entries[tcount].size = s; + if (s) { + size_t dataofs = o + 8; + if (s > 4) + /* The data in this case is merely a pointer */ + dataofs = exif_get_long (buf + dataofs, n->order) + 6; + if ((dataofs + s < dataofs) || (dataofs + s < s) || + (dataofs + s > buf_size)) { + exif_log (en->log, EXIF_LOG_CODE_DEBUG, + "ExifMnoteDataPentax", "Tag data past end " + "of buffer (%u > %u)", dataofs + s, buf_size); + continue; + } + + n->entries[tcount].data = exif_mem_alloc (en->mem, s); + if (!n->entries[tcount].data) { + EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteDataPentax", s); + continue; + } + memcpy (n->entries[tcount].data, buf + dataofs, s); + } + + /* Tag was successfully parsed */ + ++tcount; + } + /* Store the count of successfully parsed tags */ + n->count = tcount; +} + +static unsigned int +exif_mnote_data_pentax_count (ExifMnoteData *n) +{ + return n ? ((ExifMnoteDataPentax *) n)->count : 0; +} + +static unsigned int +exif_mnote_data_pentax_get_id (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d; + + if (!note) return 0; + if (note->count <= n) return 0; + return note->entries[n].tag; +} + +static const char * +exif_mnote_data_pentax_get_name (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d; + + if (!note) return NULL; + if (note->count <= n) return NULL; + return mnote_pentax_tag_get_name (note->entries[n].tag); +} + +static const char * +exif_mnote_data_pentax_get_title (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d; + + if (!note) return NULL; + if (note->count <= n) return NULL; + return mnote_pentax_tag_get_title (note->entries[n].tag); +} + +static const char * +exif_mnote_data_pentax_get_description (ExifMnoteData *d, unsigned int n) +{ + ExifMnoteDataPentax *note = (ExifMnoteDataPentax *) d; + + if (!note) return NULL; + if (note->count <= n) return NULL; + return mnote_pentax_tag_get_description (note->entries[n].tag); +} + +static void +exif_mnote_data_pentax_set_offset (ExifMnoteData *d, unsigned int o) +{ + if (d) ((ExifMnoteDataPentax *) d)->offset = o; +} + +static void +exif_mnote_data_pentax_set_byte_order (ExifMnoteData *d, ExifByteOrder o) +{ + ExifByteOrder o_orig; + ExifMnoteDataPentax *n = (ExifMnoteDataPentax *) d; + unsigned int i; + + if (!n) return; + + o_orig = n->order; + n->order = o; + for (i = 0; i < n->count; i++) { + n->entries[i].order = o; + exif_array_set_byte_order (n->entries[i].format, n->entries[i].data, + n->entries[i].components, o_orig, o); + } +} + +int +exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e) +{ + if ((e->size >= 8) && !memcmp (e->data, "AOC", 4)) { + if (((e->data[4] == 'I') && (e->data[5] == 'I')) || + ((e->data[4] == 'M') && (e->data[5] == 'M'))) + return pentaxV3; + else + /* Uses Casio v2 tags */ + return pentaxV2; + } + + if ((e->size >= 8) && !memcmp (e->data, "QVC", 4)) + return casioV2; + + /* This isn't a very robust test, so make sure it's done last */ + /* Maybe we should additionally check for a make of Asahi or Pentax */ + if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b)) + return pentaxV1; + + return 0; +} + +ExifMnoteData * +exif_mnote_data_pentax_new (ExifMem *mem) +{ + ExifMnoteData *d; + + if (!mem) return NULL; + + d = exif_mem_alloc (mem, sizeof (ExifMnoteDataPentax)); + if (!d) return NULL; + + exif_mnote_data_construct (d, mem); + + /* Set up function pointers */ + d->methods.free = exif_mnote_data_pentax_free; + d->methods.set_byte_order = exif_mnote_data_pentax_set_byte_order; + d->methods.set_offset = exif_mnote_data_pentax_set_offset; + d->methods.load = exif_mnote_data_pentax_load; + d->methods.save = exif_mnote_data_pentax_save; + d->methods.count = exif_mnote_data_pentax_count; + d->methods.get_id = exif_mnote_data_pentax_get_id; + d->methods.get_name = exif_mnote_data_pentax_get_name; + d->methods.get_title = exif_mnote_data_pentax_get_title; + d->methods.get_description = exif_mnote_data_pentax_get_description; + d->methods.get_value = exif_mnote_data_pentax_get_value; + + return d; +} diff --git a/libexifa/pentax/exif-mnote-data-pentax.h b/libexifa/pentax/exif-mnote-data-pentax.h new file mode 100755 index 0000000..da9f79a --- /dev/null +++ b/libexifa/pentax/exif-mnote-data-pentax.h @@ -0,0 +1,59 @@ +/* exif-mnote-data-pentax.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_PENTAX_H__ +#define __EXIF_MNOTE_DATA_PENTAX_H__ + +#include +#include +#include +#include +#include +#include + +enum PentaxVersion {pentaxV1 = 1, pentaxV2 = 2, pentaxV3 = 3, casioV2 = 4 }; + +typedef struct _ExifMnoteDataPentax ExifMnoteDataPentax; + +struct _ExifMnoteDataPentax { + ExifMnoteData parent; + + MnotePentaxEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + + enum PentaxVersion version; +}; + +/*! Detect if MakerNote is recognized as one handled by the Pentax module. + * + * \param[in] ed image #ExifData to identify as as a Pentax type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_pentax_new (ExifMem *); + +#endif /* __EXIF_MNOTE_DATA_PENTAX_H__ */ diff --git a/libexifa/pentax/mnote-pentax-entry.c b/libexifa/pentax/mnote-pentax-entry.c new file mode 100755 index 0000000..7e97c2c --- /dev/null +++ b/libexifa/pentax/mnote-pentax-entry.c @@ -0,0 +1,459 @@ +/* mnote-pentax-entry.c + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "mnote-pentax-entry.h" + +#include + +#include +#include +#include + +#include +#include +#include + + +#define CF(format,target,v,maxlen) \ +{ \ + if (format != target) { \ + snprintf (v, maxlen, \ + _("Invalid format '%s', " \ + "expected '%s'."), \ + exif_format_get_name (format), \ + exif_format_get_name (target)); \ + break; \ + } \ +} + +#define CC(number,target,v,maxlen) \ +{ \ + if (number != target) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i)."), (int) number, (int) target); \ + break; \ + } \ +} + +#define CC2(number,t1,t2,v,maxlen) \ +{ \ + if ((number != t1) && (number != t2)) { \ + snprintf (v, maxlen, \ + _("Invalid number of components (%i, " \ + "expected %i or %i)."), (int) number, \ + (int) t1, (int) t2); \ + break; \ + } \ +} + +static const struct { + ExifTag tag; + struct { + int index; + const char *string; + } elem[33]; +} items[] = { +#ifndef NO_VERBOSE_TAG_DATA + { MNOTE_PENTAX_TAG_MODE, + { {0, N_("Auto")}, + {1, N_("Night scene")}, + {2, N_("Manual")}, + {4, N_("Multi-exposure")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_QUALITY, + { {0, N_("Good")}, + {1, N_("Better")}, + {2, N_("Best")},{0,NULL}}}, + { MNOTE_PENTAX_TAG_FOCUS, + { {2, N_("Custom")}, + {3, N_("Auto")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_FLASH, + { {1, N_("Auto")}, + {2, N_("Flash on")}, + {4, N_("Flash off")}, + {6, N_("Red-eye reduction")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_WHITE_BALANCE, + { {0, N_("Auto")}, + {1, N_("Daylight")}, + {2, N_("Shade")}, + {3, N_("Tungsten")}, + {4, N_("Fluorescent")}, + {5, N_("Manual")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_SHARPNESS, + { {0, N_("Normal")}, + {1, N_("Soft")}, + {2, N_("Hard")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_CONTRAST, + { {0, N_("Normal")}, + {1, N_("Low")}, + {2, N_("High")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_SATURATION, + { {0, N_("Normal")}, + {1, N_("Low")}, + {2, N_("High")}, + {0, NULL}}}, + { MNOTE_PENTAX_TAG_ISO_SPEED, + { {10, N_("100")}, + {16, N_("200")}, + {100, N_("100")}, + {200, N_("200")}, + { 0, NULL}}}, + { MNOTE_PENTAX_TAG_COLOR, + { {1, N_("Full")}, + {2, N_("Black & white")}, + {3, N_("Sepia")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_MODE, + { {0, N_("Auto")}, + {1, N_("Night scene")}, + {2, N_("Manual")}, + {4, N_("Multi-exposure")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_QUALITY, + { {0, N_("Good")}, + {1, N_("Better")}, + {2, N_("Best")}, + {3, N_("TIFF")}, + {4, N_("RAW")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_IMAGE_SIZE, + { {0, "640x480"}, + {1, N_("Full")}, + {2, "1024x768"}, + {3, "1280x960"}, + {4, "1600x1200"}, + {5, "2048x1536"}, + {8, N_("2560x1920 or 2304x1728")}, + {9, "3072x2304"}, + {10, "3264x2448"}, + {19, "320x240"}, + {20, "2288x1712"}, + {21, "2592x1944"}, + {22, N_("2304x1728 or 2592x1944")}, + {23, "3056x2296"}, + {25, N_("2816x2212 or 2816x2112")}, + {27, "3648x2736"}, + {36, "3008x2008"}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_PICTURE_MODE, + { {0, N_("Program")}, + {2, N_("Program AE")}, + {3, N_("Manual")}, + {5, N_("Portrait")}, + {6, N_("Landscape")}, + {8, N_("Sport")}, + {9, N_("Night scene")}, + {11, N_("Soft")}, + {12, N_("Surf & snow")}, + {13, N_("Sunset or candlelight")}, + {14, N_("Autumn")}, + {15, N_("Macro")}, + {17, N_("Fireworks")}, + {18, N_("Text")}, + {19, N_("Panorama")}, + {30, N_("Self portrait")}, + {31, N_("Illustrations")}, + {33, N_("Digital filter")}, + {37, N_("Museum")}, + {38, N_("Food")}, + {40, N_("Green mode")}, + {49, N_("Light pet")}, + {50, N_("Dark pet")}, + {51, N_("Medium pet")}, + {53, N_("Underwater")}, + {54, N_("Candlelight")}, + {55, N_("Natural skin tone")}, + {56, N_("Synchro sound record")}, + {58, N_("Frame composite")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_FLASH_MODE, + { {0x0000, N_("Auto, did not fire")}, + {0x0001, N_("Off")}, + {0x0003, N_("Auto, did not fire, red-eye reduction")}, + {0x0100, N_("Auto, fired")}, + {0x0102, N_("On")}, + {0x0103, N_("Auto, fired, red-eye reduction")}, + {0x0104, N_("On, red-eye reduction")}, + {0x0105, N_("On, wireless")}, + {0x0108, N_("On, soft")}, + {0x0109, N_("On, slow-sync")}, + {0x010a, N_("On, slow-sync, red-eye reduction")}, + {0x010b, N_("On, trailing-curtain sync")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_FOCUS_MODE, + { {0, N_("Normal")}, + {1, N_("Macro")}, + {2, N_("Infinity")}, + {3, N_("Manual")}, + {5, N_("Pan focus")}, + {16, N_("AF-S")}, + {17, N_("AF-C")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_AFPOINT_SELECTED, + { {1, N_("Upper-left")}, + {2, N_("Top")}, + {3, N_("Upper-right")}, + {4, N_("Left")}, + {5, N_("Mid-left")}, + {6, N_("Center")}, + {7, N_("Mid-right")}, + {8, N_("Right")}, + {9, N_("Lower-left")}, + {10, N_("Bottom")}, + {11, N_("Lower-right")}, + {0xfffe, N_("Fixed center")}, + {0xffff, N_("Auto")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_AUTO_AFPOINT, + { {0, N_("Multiple")}, + {1, N_("Top-left")}, + {2, N_("Top-center")}, + {3, N_("Top-right")}, + {4, N_("Left")}, + {5, N_("Center")}, + {6, N_("Right")}, + {7, N_("Bottom-left")}, + {8, N_("Bottom-center")}, + {9, N_("Bottom-right")}, + {0xffff, N_("None")}, + {0, NULL}}}, + { MNOTE_PENTAX2_TAG_WHITE_BALANCE, + { {0, N_("Auto")}, + {1, N_("Daylight")}, + {2, N_("Shade")}, + {3, N_("Fluorescent")}, + {4, N_("Tungsten")}, + {5, N_("Manual")}, + {6, N_("Daylight fluorescent")}, + {7, N_("Day white fluorescent")}, + {8, N_("White fluorescent")}, + {9, N_("Flash")}, + {10, N_("Cloudy")}, + {0xfffe, N_("Unknown")}, + {0xffff, N_("User selected")}, + {0, NULL}}}, + {MNOTE_CASIO2_TAG_BESTSHOT_MODE, + { {0, N_("Off")}, + {1, N_("On")}, + {0, NULL}}}, +#endif + {0, {{0, NULL}}} +}; + +/* Two-component values */ +static const struct { + ExifTag tag; + struct { + int index1, index2; + const char *string; + } elem[39]; +} items2[] = { +#ifndef NO_VERBOSE_TAG_DATA + { MNOTE_PENTAX2_TAG_IMAGE_SIZE, + { {0, 0, "2304x1728"}, + {4, 0, "1600x1200"}, + {5, 0, "2048x1536"}, + {8, 0, "2560x1920"}, + {34, 0, "1536x1024"}, + {36, 0, N_("3008x2008 or 3040x2024")}, + {37, 0, "3008x2000"}, + {35, 1, "2400x1600"}, + {32, 2, "960x480"}, + {33, 2, "1152x768"}, + {34, 2, "1536x1024"}, + {0, 0, NULL}}}, + { MNOTE_PENTAX2_TAG_PICTURE_MODE, + { {0, 0, N_("Auto")}, + {5, 0, N_("Portrait")}, + {53, 0, N_("Underwater")}, + {255, 0, N_("Digital filter?")}, + {5, 1, N_("Portrait")}, + {9, 1, N_("Night scene")}, + {13, 1, N_("Candlelight")}, + {15, 1, N_("Macro")}, + {53, 1, N_("Underwater")}, + {0, 2, N_("Program AE")}, + {5, 2, N_("Portrait")}, + {6, 2, N_("Landscape")}, + {0, 0, NULL}}}, +#endif + {0, {{0, 0, NULL}}} +}; + +char * +mnote_pentax_entry_get_value (MnotePentaxEntry *entry, + char *val, unsigned int maxlen) +{ + ExifLong vl; + ExifShort vs, vs2; + int i = 0, j = 0; + + if (!entry) return (NULL); + + memset (val, 0, maxlen); + maxlen--; + + switch (entry->tag) { + case MNOTE_PENTAX_TAG_MODE: + case MNOTE_PENTAX_TAG_QUALITY: + case MNOTE_PENTAX_TAG_FOCUS: + case MNOTE_PENTAX_TAG_FLASH: + case MNOTE_PENTAX_TAG_WHITE_BALANCE: + case MNOTE_PENTAX_TAG_SHARPNESS: + case MNOTE_PENTAX_TAG_CONTRAST: + case MNOTE_PENTAX_TAG_SATURATION: + case MNOTE_PENTAX_TAG_ISO_SPEED: + case MNOTE_PENTAX_TAG_COLOR: + case MNOTE_PENTAX2_TAG_MODE: + case MNOTE_PENTAX2_TAG_QUALITY: + case MNOTE_PENTAX2_TAG_FLASH_MODE: + case MNOTE_PENTAX2_TAG_FOCUS_MODE: + case MNOTE_PENTAX2_TAG_AFPOINT_SELECTED: + case MNOTE_PENTAX2_TAG_AUTO_AFPOINT: + case MNOTE_PENTAX2_TAG_WHITE_BALANCE: + case MNOTE_PENTAX2_TAG_PICTURE_MODE: + case MNOTE_PENTAX2_TAG_IMAGE_SIZE: + case MNOTE_CASIO2_TAG_BESTSHOT_MODE: + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + CC2 (entry->components, 1, 2, val, maxlen); + if (entry->components == 1) { + vs = exif_get_short (entry->data, entry->order); + + /* search the tag */ + for (i = 0; (items[i].tag && items[i].tag != entry->tag); i++); + if (!items[i].tag) { + snprintf (val, maxlen, + _("Internal error (unknown value %i)"), vs); + break; + } + + /* find the value */ + for (j = 0; items[i].elem[j].string && + (items[i].elem[j].index < vs); j++); + if (items[i].elem[j].index != vs) { + snprintf (val, maxlen, + _("Internal error (unknown value %i)"), vs); + break; + } + strncpy (val, _(items[i].elem[j].string), maxlen); + } else { + /* Two-component values */ + CF (entry->format, EXIF_FORMAT_SHORT, val, maxlen); + CC2 (entry->components, 1, 2, val, maxlen); + vs = exif_get_short (entry->data, entry->order); + vs2 = exif_get_short (entry->data+2, entry->order) << 16; + + /* search the tag */ + for (i = 0; (items2[i].tag && items2[i].tag != entry->tag); i++); + if (!items2[i].tag) { + snprintf (val, maxlen, + _("Internal error (unknown value %i %i)"), vs, vs2); + break; + } + + /* find the value */ + for (j = 0; items2[i].elem[j].string && ((items2[i].elem[j].index2 < vs2) + || ((items2[i].elem[j].index2 == vs2) && (items2[i].elem[j].index1 < vs))); j++); + if ((items2[i].elem[j].index1 != vs) || (items2[i].elem[j].index2 != vs2)) { + snprintf (val, maxlen, + _("Internal error (unknown value %i %i)"), vs, vs2); + break; + } + strncpy (val, _(items2[i].elem[j].string), maxlen); + } + break; + + case MNOTE_PENTAX_TAG_ZOOM: + CF (entry->format, EXIF_FORMAT_LONG, val, maxlen); + CC (entry->components, 1, val, maxlen); + vl = exif_get_long (entry->data, entry->order); + snprintf (val, maxlen, "%li", (long int) vl); + break; + case MNOTE_PENTAX_TAG_PRINTIM: + CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (entry->components, 124, val, maxlen); + snprintf (val, maxlen, _("%i bytes unknown data"), + entry->size); + break; + case MNOTE_PENTAX_TAG_TZ_CITY: + case MNOTE_PENTAX_TAG_TZ_DST: + CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (entry->components, 4, val, maxlen); + strncpy (val, (char*)entry->data, MIN(maxlen, entry->size)); + break; + case MNOTE_PENTAX2_TAG_DATE: + CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC (entry->components, 4, val, maxlen); + /* Note: format is UNDEFINED, not SHORT -> order is fixed: MOTOROLA */ + vs = exif_get_short (entry->data, EXIF_BYTE_ORDER_MOTOROLA); + snprintf (val, maxlen, "%i:%02i:%02i", vs, entry->data[2], entry->data[3]); + break; + case MNOTE_PENTAX2_TAG_TIME: + CF (entry->format, EXIF_FORMAT_UNDEFINED, val, maxlen); + CC2 (entry->components, 3, 4, val, maxlen); + snprintf (val, maxlen, "%02i:%02i:%02i", entry->data[0], entry->data[1], entry->data[2]); + break; + default: + switch (entry->format) { + case EXIF_FORMAT_ASCII: + strncpy (val, (char *)entry->data, MIN(maxlen, entry->size)); + break; + case EXIF_FORMAT_SHORT: + { + const unsigned char *data = entry->data; + size_t k, len = strlen(val); + for(k=0; kcomponents; k++) { + vs = exif_get_short (data, entry->order); + snprintf (val+len, maxlen-len, "%i ", vs); + len = strlen(val); + data += 2; + } + } + break; + case EXIF_FORMAT_LONG: + { + const unsigned char *data = entry->data; + size_t k, len = strlen(val); + for(k=0; kcomponents; k++) { + vl = exif_get_long (data, entry->order); + snprintf (val+len, maxlen-len, "%li", (long int) vl); + len = strlen(val); + data += 4; + } + } + break; + case EXIF_FORMAT_UNDEFINED: + default: + snprintf (val, maxlen, _("%i bytes unknown data"), + entry->size); + break; + } + break; + } + + return (val); +} diff --git a/libexifa/pentax/mnote-pentax-entry.h b/libexifa/pentax/mnote-pentax-entry.h new file mode 100755 index 0000000..4547ec3 --- /dev/null +++ b/libexifa/pentax/mnote-pentax-entry.h @@ -0,0 +1,43 @@ +/* mnote-pentax-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_ENTRY_H__ +#define __MNOTE_PENTAX_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnotePentaxEntry MnotePentaxEntry; + +struct _MnotePentaxEntry { + MnotePentaxTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_pentax_entry_get_value (MnotePentaxEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_PENTAX_ENTRY_H__ */ diff --git a/libexifa/pentax/mnote-pentax-tag.c b/libexifa/pentax/mnote-pentax-tag.c new file mode 100755 index 0000000..740f135 --- /dev/null +++ b/libexifa/pentax/mnote-pentax-tag.c @@ -0,0 +1,175 @@ +/* mnote-pentax-tag.c: + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include +#include "mnote-pentax-tag.h" + +#include + +#include + +static const struct { + MnotePentaxTag tag; + const char *name; + const char *title; + const char *description; +} table[] = { +#ifndef NO_VERBOSE_TAG_STRINGS + {MNOTE_PENTAX_TAG_MODE, "Mode", N_("Capture Mode"), ""}, + {MNOTE_PENTAX_TAG_QUALITY, "Quality", N_("Quality Level"), ""}, + {MNOTE_PENTAX_TAG_FOCUS, "Focus", N_("Focus Mode"), ""}, + {MNOTE_PENTAX_TAG_FLASH, "Flash", N_("Flash Mode"), ""}, + {MNOTE_PENTAX_TAG_UNKNOWN_05, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_06, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_PENTAX_TAG_UNKNOWN_08, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_09, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_ZOOM, "Zoom", N_("Zoom"), NULL}, + {MNOTE_PENTAX_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""}, + {MNOTE_PENTAX_TAG_CONTRAST, "Contrast", N_("Contrast"), ""}, + {MNOTE_PENTAX_TAG_SATURATION, "Saturation", N_("Saturation"), ""}, + {MNOTE_PENTAX_TAG_UNKNOWN_14, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_15, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_16, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_17, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_18, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_19, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_ISO_SPEED, "ISOSpeed", N_("ISO Speed"), ""}, + {MNOTE_PENTAX_TAG_UNKNOWN_21, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_COLOR, "Color", N_("Colors"), ""}, + {MNOTE_PENTAX_TAG_UNKNOWN_24, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_UNKNOWN_25, NULL, NULL, NULL}, + {MNOTE_PENTAX_TAG_PRINTIM, "PrintIM", N_("PrintIM Settings"), ""}, + {MNOTE_PENTAX_TAG_TZ_CITY, "TimeZone", N_("Time Zone"), ""}, + {MNOTE_PENTAX_TAG_TZ_DST, "DaylightSavings", N_("Daylight Savings"), ""}, + + {MNOTE_PENTAX2_TAG_MODE, "Mode", N_("Capture Mode"), ""}, + {MNOTE_PENTAX2_TAG_PREVIEW_SIZE, "PentaxPreviewSize", N_("Preview Size"), ""}, + {MNOTE_PENTAX2_TAG_PREVIEW_LENGTH, "PentaxPreviewLength", N_("Preview Length"), ""}, + {MNOTE_PENTAX2_TAG_PREVIEW_START, "PentaxPreviewStart", N_("Preview Start"), ""}, + {MNOTE_PENTAX2_TAG_MODEL_ID, "ModelID", N_("Model Identification"), ""}, + {MNOTE_PENTAX2_TAG_DATE, "Date", N_("Date"), ""}, + {MNOTE_PENTAX2_TAG_TIME, "Time", N_("Time"), ""}, + {MNOTE_PENTAX2_TAG_QUALITY, "Quality", N_("Quality Level"), ""}, + {MNOTE_PENTAX2_TAG_IMAGE_SIZE, "ImageSize", N_("Image Size"), ""}, + {MNOTE_PENTAX2_TAG_PICTURE_MODE, "PictureMode", N_("Picture Mode"), ""}, + {MNOTE_PENTAX2_TAG_FLASH_MODE, "FlashMode", N_("Flash Mode"), ""}, + {MNOTE_PENTAX2_TAG_FOCUS_MODE, "FocusMode", N_("Focus Mode"), ""}, + {MNOTE_PENTAX2_TAG_AFPOINT_SELECTED, "AFPointSelected", N_("AF Point Selected"), ""}, + {MNOTE_PENTAX2_TAG_AUTO_AFPOINT, "AutoAFPoint", N_("Auto AF Point"), ""}, + {MNOTE_PENTAX2_TAG_FOCUS_POSITION, "FocusPosition", N_("Focus Position"), ""}, + {MNOTE_PENTAX2_TAG_EXPOSURE_TIME, "ExposureTime", N_("Exposure Time"), ""}, + {MNOTE_PENTAX2_TAG_FNUMBER, "FNumber", N_("F-Number"), ""}, + {MNOTE_PENTAX2_TAG_ISO, "ISO", N_("ISO Number"), ""}, + {MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION, "ExposureCompensation", N_("Exposure Compensation"), ""}, + {MNOTE_PENTAX2_TAG_METERING_MODE, "MeteringMode", N_("Metering Mode"), ""}, + {MNOTE_PENTAX2_TAG_AUTO_BRACKETING, "AutoBracketing", N_("Auto Bracketing"), ""}, + {MNOTE_PENTAX2_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE, "WhiteBalanceMode", N_("White Balance Mode"), ""}, + {MNOTE_PENTAX2_TAG_BLUE_BALANCE, "BlueBalance", N_("Blue Balance"), ""}, + {MNOTE_PENTAX2_TAG_RED_BALANCE, "RedBalance", N_("Red Balance"), ""}, + {MNOTE_PENTAX2_TAG_FOCAL_LENGTH, "FocalLength", N_("Focal Length"), ""}, + {MNOTE_PENTAX2_TAG_DIGITAL_ZOOM, "DigitalZoom", N_("Digital Zoom"), ""}, + {MNOTE_PENTAX2_TAG_SATURATION, "Saturation", N_("Saturation"), ""}, + {MNOTE_PENTAX2_TAG_CONTRAST, "Contrast", N_("Contrast"), ""}, + {MNOTE_PENTAX2_TAG_SHARPNESS, "Sharpness", N_("Sharpness"), ""}, + {MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION, "WorldTimeLocation", N_("World Time Location"), ""}, + {MNOTE_PENTAX2_TAG_HOMETOWN_CITY, "HometownCity", N_("Hometown City"), ""}, + {MNOTE_PENTAX2_TAG_DESTINATION_CITY, "DestinationCity", N_("Destination City"), ""}, + {MNOTE_PENTAX2_TAG_HOMETOWN_DST, "HometownDST,", N_("Hometown DST"), N_("Home Daylight Savings Time")}, + {MNOTE_PENTAX2_TAG_DESTINATION_DST, "DestinationDST", N_("Destination DST"), N_("Destination Daylight Savings Time")}, + {MNOTE_PENTAX2_TAG_FRAME_NUMBER, "FrameNumber", N_("Frame Number"), ""}, + {MNOTE_PENTAX2_TAG_IMAGE_PROCESSING, "ImageProcessing", N_("Image Processing"), ""}, + {MNOTE_PENTAX2_TAG_PICTURE_MODE2, "PictureMode2", N_("Picture Mode (2)"), ""}, + {MNOTE_PENTAX2_TAG_DRIVE_MODE, "DriveMode", N_("Drive Mode"), ""}, + {MNOTE_PENTAX2_TAG_COLOR_SPACE, "ColorSpace", N_("Color Space"), ""}, + {MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET, "ImageAreaOffset", N_("Image Area Offset"), ""}, + {MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE, "RawImageSize", N_("Raw Image Size"), ""}, + {MNOTE_PENTAX2_TAG_AFPOINTS_USED, "AfPointsUsed,", N_("Autofocus Points Used"), ""}, + {MNOTE_PENTAX2_TAG_LENS_TYPE, "LensType", N_("Lens Type"), ""}, + {MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE, "CameraTemperature", N_("Camera Temperature"), ""}, + {MNOTE_PENTAX2_TAG_NOISE_REDUCTION, "NoiseReduction", N_("Noise Reduction"), ""}, + {MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP, "FlashExposureComp", N_("Flash Exposure Compensation"), ""}, + {MNOTE_PENTAX2_TAG_IMAGE_TONE, "ImageTone", N_("Image Tone"), ""}, + {MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO, "ShakeReductionInfo,", N_("Shake Reduction Info"), ""}, + {MNOTE_PENTAX2_TAG_BLACK_POINT, "BlackPoint", N_("Black Point"), ""}, + {MNOTE_PENTAX2_TAG_WHITE_POINT, "WhitePoint", N_("White Point"), ""}, + {MNOTE_PENTAX2_TAG_AE_INFO, "AEInfo", N_("AE Info"), ""}, + {MNOTE_PENTAX2_TAG_LENS_INFO, "LensInfo", N_("Lens Info"), ""}, + {MNOTE_PENTAX2_TAG_FLASH_INFO, "FlashInfo", N_("Flash Info"), ""}, + {MNOTE_PENTAX2_TAG_CAMERA_INFO, "CameraInfo", N_("Camera Info"), ""}, + {MNOTE_PENTAX2_TAG_BATTERY_INFO, "BatteryInfo", N_("Battery Info"), ""}, + {MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE, "HometownCityCode", N_("Hometown City Code"), ""}, + {MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE, "DestinationCityCode", N_("Destination City Code"), ""}, + + {MNOTE_CASIO2_TAG_PREVIEW_START, "CasioPreviewStart", N_("Preview Start"), ""}, + {MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS, "WhiteBalanceBias", N_("White Balance Bias"), ""}, + {MNOTE_CASIO2_TAG_WHITE_BALANCE, "WhiteBalance", N_("White Balance"), ""}, + {MNOTE_CASIO2_TAG_OBJECT_DISTANCE, "ObjectDistance", N_("Object Distance"), N_("Distance of photographed object in millimeters.")}, + {MNOTE_CASIO2_TAG_FLASH_DISTANCE, "FlashDistance", N_("Flash Distance"), ""}, + {MNOTE_CASIO2_TAG_RECORD_MODE, "RecordMode", N_("Record Mode"), ""}, + {MNOTE_CASIO2_TAG_SELF_TIMER, "SelfTimer", N_("Self-timer"), ""}, + {MNOTE_CASIO2_TAG_QUALITY, "CasioQuality", N_("Quality Level"), ""}, + {MNOTE_CASIO2_TAG_FOCUS_MODE, "CasioFocusMode", N_("Focus Mode"), ""}, + {MNOTE_CASIO2_TAG_TIME_ZONE, "TimeZone", N_("Time Zone"), ""}, + {MNOTE_CASIO2_TAG_BESTSHOT_MODE, "BestshotMode", N_("Bestshot Mode"), ""}, + {MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY, "CCSISOSensitivity", N_("CCS ISO Sensitivity"), ""}, + {MNOTE_CASIO2_TAG_COLOR_MODE, "ColorMode", N_("Color Mode"), ""}, + {MNOTE_CASIO2_TAG_ENHANCEMENT, "Enhancement", N_("Enhancement"), ""}, + {MNOTE_CASIO2_TAG_FINER, "Finer", N_("Finer"), ""}, +#endif + {0, NULL, NULL, NULL} +}; + +const char * +mnote_pentax_tag_get_name (MnotePentaxTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (table[i].name); + return NULL; +} + +const char * +mnote_pentax_tag_get_title (MnotePentaxTag t) +{ + unsigned int i; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) return (_(table[i].title)); + return NULL; +} + +const char * +mnote_pentax_tag_get_description (MnotePentaxTag t) +{ + unsigned int i; + + for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) + if (table[i].tag == t) { + if (!table[i].description || !*table[i].description) + return ""; + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + return _(table[i].description); + } + return NULL; +} diff --git a/libexifa/pentax/mnote-pentax-tag.h b/libexifa/pentax/mnote-pentax-tag.h new file mode 100755 index 0000000..51b2aec --- /dev/null +++ b/libexifa/pentax/mnote-pentax-tag.h @@ -0,0 +1,153 @@ +/* mnote-pentax-tag.h + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_TAG_H__ +#define __MNOTE_PENTAX_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Missing features which are probably in the unknowns somewhere ... + * 1/ AF Area (Wide, Spot, Free) + * 2/ AE Metering (Multi segment, Centre-weighted, Spot) + * 3/ + */ + +enum _MnotePentaxTag { + MNOTE_PENTAX_TAG_MODE = 0x0001, + MNOTE_PENTAX_TAG_QUALITY = 0x0002, + MNOTE_PENTAX_TAG_FOCUS = 0x0003, + MNOTE_PENTAX_TAG_FLASH = 0x0004, + MNOTE_PENTAX_TAG_UNKNOWN_05 = 0x0005, + MNOTE_PENTAX_TAG_UNKNOWN_06 = 0x0006, + MNOTE_PENTAX_TAG_WHITE_BALANCE = 0x0007, + MNOTE_PENTAX_TAG_UNKNOWN_08 = 0x0008, + MNOTE_PENTAX_TAG_UNKNOWN_09 = 0x0009, + MNOTE_PENTAX_TAG_ZOOM = 0x000a, + MNOTE_PENTAX_TAG_SHARPNESS = 0x000b, + MNOTE_PENTAX_TAG_CONTRAST = 0x000c, + MNOTE_PENTAX_TAG_SATURATION = 0x000d, + MNOTE_PENTAX_TAG_UNKNOWN_14 = 0x000e, + MNOTE_PENTAX_TAG_UNKNOWN_15 = 0x000f, + MNOTE_PENTAX_TAG_UNKNOWN_16 = 0x0010, + MNOTE_PENTAX_TAG_UNKNOWN_17 = 0x0011, + MNOTE_PENTAX_TAG_UNKNOWN_18 = 0x0012, + MNOTE_PENTAX_TAG_UNKNOWN_19 = 0x0013, + MNOTE_PENTAX_TAG_ISO_SPEED = 0x0014, + MNOTE_PENTAX_TAG_UNKNOWN_21 = 0x0015, + MNOTE_PENTAX_TAG_COLOR = 0x0017, + MNOTE_PENTAX_TAG_UNKNOWN_24 = 0x0018, + MNOTE_PENTAX_TAG_UNKNOWN_25 = 0x0019, + MNOTE_PENTAX_TAG_PRINTIM = 0x0e00, + MNOTE_PENTAX_TAG_TZ_CITY = 0x1000, + MNOTE_PENTAX_TAG_TZ_DST = 0x1001, + + /* Pentax v2, v3: real values + our proprietary base to distinguish from v1 */ + MNOTE_PENTAX2_TAG_BASE = 0x4000, + MNOTE_PENTAX2_TAG_MODE = 0x0001 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_SIZE = 0x0002 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_LENGTH = 0x0003 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_START = 0x0004 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_MODEL_ID = 0x0005 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DATE = 0x0006 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_TIME = 0x0007 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_QUALITY = 0x0008 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_SIZE = 0x0009 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE = 0x000b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_MODE = 0x000c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_MODE = 0x000d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINT_SELECTED = 0x000e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_AFPOINT = 0x000f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_POSITION = 0x0010 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_TIME = 0x0012 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FNUMBER = 0x0013 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_ISO = 0x0014 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION = 0x0016 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_METERING_MODE = 0x0017 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_BRACKETING = 0x0018 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE = 0x0019 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE= 0x001a + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLUE_BALANCE = 0x001b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RED_BALANCE = 0x001c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCAL_LENGTH = 0x001d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DIGITAL_ZOOM = 0x001e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SATURATION = 0x001f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CONTRAST = 0x0020 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHARPNESS = 0x0021 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION = 0x0022 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY = 0x0023 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY = 0x0024 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_DST = 0x0025 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_DST = 0x0026 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FRAME_NUMBER = 0x0029 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_PROCESSING = 0x0032 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE2 = 0x0033 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DRIVE_MODE = 0x0034 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_COLOR_SPACE = 0x0037 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET = 0x0038 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE = 0x0039 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINTS_USED = 0x003c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_TYPE = 0x003f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE = 0x0047 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_NOISE_REDUCTION = 0x0049 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP = 0x004d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_TONE = 0x004f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO = 0x005c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLACK_POINT = 0x0200 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_POINT = 0x0201 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AE_INFO = 0x0206 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_INFO = 0x0207 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_INFO = 0x0208 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_INFO = 0x0215 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BATTERY_INFO = 0x0216 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE = 0x1000 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE = 0x1001 + MNOTE_PENTAX2_TAG_BASE, + + /* Casio v2: some Casio v2 tags match Pentax v2 tags */ + MNOTE_CASIO2_TAG_BASE = MNOTE_PENTAX2_TAG_BASE, + MNOTE_CASIO2_TAG_PREVIEW_START = 0x2000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS = 0x2011 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE = 0x2012 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_OBJECT_DISTANCE = 0x2022 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FLASH_DISTANCE = 0x2034 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_RECORD_MODE = 0x3000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_SELF_TIMER = 0x3001 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_QUALITY = 0x3002 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FOCUS_MODE = 0x3003 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_TIME_ZONE = 0x3006 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_BESTSHOT_MODE = 0x3007 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY = 0x3014 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_COLOR_MODE = 0x3015 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_ENHANCEMENT = 0x3016 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FINER = 0x3017 + MNOTE_CASIO2_TAG_BASE +}; +typedef enum _MnotePentaxTag MnotePentaxTag; + +const char *mnote_pentax_tag_get_name (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_title (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_description (MnotePentaxTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_PENTAX_TAG_H__ */ diff --git a/libjpega/Android.mk b/libjpega/Android.mk new file mode 100755 index 0000000..a638281 --- /dev/null +++ b/libjpega/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRELINK_MODULE:=false + +LOCAL_C_INCLUDES += $(LOCAL_PATH)\ + $(LOCAL_PATH)/libjpeg/\ + $(LOCAL_PATH)/libexif/\ + $(LOCAL_PATH)/libexif/canon/\ + $(LOCAL_PATH)/libexif/fuji/\ + $(LOCAL_PATH)/libexif/olympus/\ + $(LOCAL_PATH)/libexif/pentax/ + +LOCAL_SHARED_LIBRARIES:= \ + libexifa + +LOCAL_SRC_FILES:=\ + jpeg-data.c\ + jpeg-marker.c\ + exif-i18n + +#LOCAL_CFLAGS:=-O2 -g +#LOCAL_CFLAGS+=-DHAVE_CONFIG_H -D_U_="__attribute__((unused))" -Dlinux -D__GLIBC__ -D_GNU_SOURCE + +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE:= libjpega + +include $(BUILD_SHARED_LIBRARY) diff --git a/libjpega/MODULE_LICENSE_LGPL b/libjpega/MODULE_LICENSE_LGPL new file mode 100755 index 0000000..e69de29 diff --git a/libjpega/NOTICE b/libjpega/NOTICE new file mode 100755 index 0000000..b1e3f5a --- /dev/null +++ b/libjpega/NOTICE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/libjpega/exif-i18n.c b/libjpega/exif-i18n.c new file mode 100755 index 0000000..9f32ff8 --- /dev/null +++ b/libjpega/exif-i18n.c @@ -0,0 +1,42 @@ +#include +#include "exif-i18n.h" + +#ifdef HAVE_ICONV +# include +# include +#endif + +#include +#include + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +const char * +exif_i18n_convert_utf8_to_locale (const char *in) +{ +#if defined(ENABLE_GETTEXT_ICONV) && defined(HAVE_ICONV) + /* If gettext() doesn't convert the message texts into the proper + * encoding for the current locale, then it's broken (because there's + * no way for the app to know the encoding of the translated text). + * In this case, assume the translated text is in UTF-8 (which could + * be wrong) and use iconv to convert to the proper encoding. + * This is only an issue with really old gettext versions (< 0.10.36) + */ + static iconv_t tr = 0; + size_t t = (in ? strlen (in) : 0); + static char buf[2048]; + size_t buf_size = sizeof (buf); + char *out = buf; + + if (!in) return ""; + + memset (buf, 0, sizeof (buf)); + if (!tr) tr = iconv_open (nl_langinfo (CODESET), "UTF-8"); + iconv (tr, (char **) &in, &t, (char **) &out, &buf_size); + return buf; +#else + if (!in) return ""; + return in; +#endif +} diff --git a/libjpega/jpeg-data.c b/libjpega/jpeg-data.c new file mode 100755 index 0000000..47b2fa1 --- /dev/null +++ b/libjpega/jpeg-data.c @@ -0,0 +1,537 @@ +/* jpeg-data.c + * + * Copyright ?2001 Lutz M?ler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "jpeg-data.h" + +#include +#include +#include + +/* This refers to the exif-i18n.h file from the "exif" package and is + * NOT to be confused with the libexif/i18n.h file. + */ +#include "exif-i18n.h" + +/* realloc that cleans up on memory failure and returns to caller */ +#define CLEANUP_REALLOC(p,s) { \ + unsigned char *cleanup_ptr = realloc((p),(s)); \ + if (!cleanup_ptr) { free(p); (p) = NULL; return; } \ + (p) = cleanup_ptr; \ +} + +struct _JPEGDataPrivate +{ + unsigned int ref_count; + + ExifLog *log; +}; + +JPEGData * +jpeg_data_new (void) +{ + JPEGData *data; + + data = malloc (sizeof (JPEGData)); + if (!data) + return (NULL); + memset (data, 0, sizeof (JPEGData)); + data->priv = malloc (sizeof (JPEGDataPrivate)); + if (!data->priv) { + free (data); + return (NULL); + } + memset (data->priv, 0, sizeof (JPEGDataPrivate)); + data->priv->ref_count = 1; + + return (data); +} + +void +jpeg_data_append_section (JPEGData *data) +{ + JPEGSection *s; + + if (!data) return; + + if (!data->count) + s = malloc (sizeof (JPEGSection)); + else + s = realloc (data->sections, + sizeof (JPEGSection) * (data->count + 1)); + if (!s) { + EXIF_LOG_NO_MEMORY (data->priv->log, "jpeg-data", + sizeof (JPEGSection) * (data->count + 1)); + return; + } + memset(s + data->count, 0, sizeof (JPEGSection)); + data->sections = s; + data->count++; +} + +/*! jpeg_data_save_file returns 1 on success, 0 on failure */ +int +jpeg_data_save_file (JPEGData *data, const char *path) +{ + FILE *f; + unsigned char *d = NULL; + unsigned int size = 0, written; + + jpeg_data_save_data (data, &d, &size); + if (!d) + return 0; + + remove (path); + f = fopen (path, "wb"); + if (!f) { + free (d); + return 0; + } + written = fwrite (d, 1, size, f); + fclose (f); + free (d); + if (written == size) { + return 1; + } + remove(path); + return 0; +} + +void +jpeg_data_save_data (JPEGData *data, unsigned char **d, unsigned int *ds) +{ + unsigned int i, eds = 0; + JPEGSection s; + unsigned char *ed = NULL; + + if (!data) + return; + if (!d) + return; + if (!ds) + return; + + for (*ds = i = 0; i < data->count; i++) { + s = data->sections[i]; + + /* Write the marker */ + CLEANUP_REALLOC (*d, sizeof (char) * (*ds + 2)); + (*d)[*ds + 0] = 0xff; + (*d)[*ds + 1] = s.marker; + *ds += 2; + + switch (s.marker) { + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + break; + case JPEG_MARKER_APP1: + exif_data_save_data (s.content.app1, &ed, &eds); + if (!ed) break; + CLEANUP_REALLOC (*d, sizeof (char) * (*ds + 2)); + (*d)[*ds + 0] = (eds + 2) >> 8; + (*d)[*ds + 1] = (eds + 2) >> 0; + *ds += 2; + CLEANUP_REALLOC (*d, sizeof (char) * (*ds + eds)); + memcpy (*d + *ds, ed, eds); + *ds += eds; + free (ed); + break; + default: + CLEANUP_REALLOC (*d, sizeof (char) * + (*ds + s.content.generic.size + 2)); + (*d)[*ds + 0] = (s.content.generic.size + 2) >> 8; + (*d)[*ds + 1] = (s.content.generic.size + 2) >> 0; + *ds += 2; + memcpy (*d + *ds, s.content.generic.data, + s.content.generic.size); + *ds += s.content.generic.size; + + /* In case of SOS, we need to write the data. */ + if (s.marker == JPEG_MARKER_SOS) { + CLEANUP_REALLOC (*d, *ds + data->size); + memcpy (*d + *ds, data->data, data->size); + *ds += data->size; + } + break; + } + } +} + +void jpeg_data_save_data_no_copy(JPEGData *data, unsigned char *d, unsigned int *ds) +{ + unsigned int i, eds = 0; + JPEGSection s; + unsigned char *ed = NULL; + + if (!data) + return; + if (!d) + return; + if (!ds) + return; + + for (*ds = i = 0; i < data->count; i++) { + s = data->sections[i]; + + /* Write the marker */ + //CLEANUP_REALLOC (*d, sizeof (char) * (*ds + 2)); + d[*ds + 0] = 0xff; + d[*ds + 1] = s.marker; + *ds += 2; + + switch (s.marker) { + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + break; + case JPEG_MARKER_APP1: + exif_data_save_data (s.content.app1, &ed, &eds); + if (!ed) break; + //CLEANUP_REALLOC (*d, sizeof (char) * (*ds + 2)); + d[*ds + 0] = (eds + 2) >> 8; + d[*ds + 1] = (eds + 2) >> 0; + *ds += 2; + //CLEANUP_REALLOC (*d, sizeof (char) * (*ds + eds)); + memcpy (d + *ds, ed, eds); + *ds += eds; + free (ed); + break; + default: + /*CLEANUP_REALLOC (*d, sizeof (char) * + (*ds + s.content.generic.size + 2));*/ + d[*ds + 0] = (s.content.generic.size + 2) >> 8; + d[*ds + 1] = (s.content.generic.size + 2) >> 0; + *ds += 2; + memcpy (d + *ds, s.content.generic.data, + s.content.generic.size); + *ds += s.content.generic.size; + + /* In case of SOS, we need to write the data. */ + if (s.marker == JPEG_MARKER_SOS) { + //CLEANUP_REALLOC (*d, *ds + data->size); + memcpy (d + *ds, data->data, data->size); + *ds += data->size; + } + break; + } + } +} + +JPEGData * +jpeg_data_new_from_data (const unsigned char *d, + unsigned int size) +{ + JPEGData *data; + + data = jpeg_data_new (); + jpeg_data_load_data (data, d, size); + return (data); +} + +void +jpeg_data_load_data (JPEGData *data, const unsigned char *d, + unsigned int size) +{ + unsigned int i, o, len; + JPEGSection *s; + JPEGMarker marker; + + if (!data) return; + if (!d) return; + + for (o = 0; o < size;) { + + /* + * JPEG sections start with 0xff. The first byte that is + * not 0xff is a marker (hopefully). + */ + for (i = 0; i < MIN(7, size - o); i++) + if (d[o + i] != 0xff) + break; + if (!JPEG_IS_MARKER (d[o + i])) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "jpeg-data", + _("Data does not follow JPEG specification.")); + return; + } + marker = d[o + i]; + + /* Append this section */ + jpeg_data_append_section (data); + if (!data->count) return; + s = &data->sections[data->count - 1]; + s->marker = marker; + o += i + 1; + + switch (s->marker) { + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + break; + default: + + /* Read the length of the section */ + len = ((d[o] << 8) | d[o + 1]) - 2; + if (len > size) { o = size; break; } + o += 2; + if (o + len > size) { o = size; break; } + + switch (s->marker) { + case JPEG_MARKER_APP1: + s->content.app1 = exif_data_new_from_data ( + d + o - 4, len + 4); + break; + default: + s->content.generic.data = + malloc (sizeof (char) * len); + if (!s->content.generic.data) return; + s->content.generic.size = len; + memcpy (s->content.generic.data, &d[o], len); + + /* In case of SOS, image data will follow. */ + if (s->marker == JPEG_MARKER_SOS) { + /* -2 means 'take all but the last 2 bytes which are hoped to be JPEG_MARKER_EOI */ + data->size = size - 2 - o - len; + if (d[o + len + data->size] != 0xFF) { + /* A truncated file (i.e. w/o JPEG_MARKER_EOI at the end). + Instead of trying to use the last two bytes as marker, + touching memory beyond allocated memory and posssibly saving + back screwed file, we rather take the rest of the file. */ + data->size += 2; + } + data->data = malloc ( + sizeof (char) * data->size); + if (!data->data) return; + memcpy (data->data, d + o + len, + data->size); + o += data->size; + } + break; + } + o += len; + break; + } + } +} + +JPEGData * +jpeg_data_new_from_file (const char *path) +{ + JPEGData *data; + + data = jpeg_data_new (); + jpeg_data_load_file (data, path); + return (data); +} + +void +jpeg_data_load_file (JPEGData *data, const char *path) +{ + FILE *f; + unsigned char *d; + unsigned int size; + + if (!data) return; + if (!path) return; + + f = fopen (path, "rb"); + if (!f) { + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "jpeg-data", + _("Path '%s' invalid."), path); + return; + } + + /* For now, we read the data into memory. Patches welcome... */ + fseek (f, 0, SEEK_END); + size = ftell (f); + fseek (f, 0, SEEK_SET); + d = malloc (size); + if (!d) { + EXIF_LOG_NO_MEMORY (data->priv->log, "jpeg-data", size); + fclose (f); + return; + } + if (fread (d, 1, size, f) != size) { + free (d); + fclose (f); + exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "jpeg-data", + _("Could not read '%s'."), path); + return; + } + fclose (f); + + jpeg_data_load_data (data, d, size); + free (d); +} + +void +jpeg_data_ref (JPEGData *data) +{ + if (!data) + return; + + data->priv->ref_count++; +} + +void +jpeg_data_unref (JPEGData *data) +{ + if (!data) + return; + + if (data->priv) { + data->priv->ref_count--; + if (!data->priv->ref_count) + jpeg_data_free (data); + } +} + +void +jpeg_data_free (JPEGData *data) +{ + unsigned int i; + JPEGSection s; + + if (!data) + return; + + if (data->count) { + for (i = 0; i < data->count; i++) { + s = data->sections[i]; + switch (s.marker) { + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + break; + case JPEG_MARKER_APP1: + exif_data_unref (s.content.app1); + break; + default: + free (s.content.generic.data); + break; + } + } + free (data->sections); + } + + if (data->data) + free (data->data); + + if (data->priv) { + if (data->priv->log) { + exif_log_unref (data->priv->log); + data->priv->log = NULL; + } + free (data->priv); + } + + free (data); +} + +void +jpeg_data_dump (JPEGData *data) +{ + unsigned int i; + JPEGContent content; + JPEGMarker marker; + + if (!data) + return; + + printf ("Dumping JPEG data (%i bytes of data)...\n", data->size); + for (i = 0; i < data->count; i++) { + marker = data->sections[i].marker; + content = data->sections[i].content; + printf ("Section %i (marker 0x%x - %s):\n", i, marker, + jpeg_marker_get_name (marker)); + printf (" Description: %s\n", + jpeg_marker_get_description (marker)); + switch (marker) { + case JPEG_MARKER_SOI: + case JPEG_MARKER_EOI: + break; + case JPEG_MARKER_APP1: + exif_data_dump (content.app1); + break; + default: + printf (" Size: %i\n", content.generic.size); + printf (" Unknown content.\n"); + break; + } + } +} + +static JPEGSection * +jpeg_data_get_section (JPEGData *data, JPEGMarker marker) +{ + unsigned int i; + + if (!data) + return (NULL); + + for (i = 0; i < data->count; i++) + if (data->sections[i].marker == marker) + return (&data->sections[i]); + return (NULL); +} + +ExifData * +jpeg_data_get_exif_data (JPEGData *data) +{ + JPEGSection *section; + + if (!data) + return NULL; + + section = jpeg_data_get_section (data, JPEG_MARKER_APP1); + if (section) { + exif_data_ref (section->content.app1); + return (section->content.app1); + } + + return (NULL); +} + +void +jpeg_data_set_exif_data (JPEGData *data, ExifData *exif_data) +{ + JPEGSection *section; + + if (!data) return; + + section = jpeg_data_get_section (data, JPEG_MARKER_APP1); + if (!section) { + jpeg_data_append_section (data); + if (data->count < 2) return; + memmove (&data->sections[2], &data->sections[1], + sizeof (JPEGSection) * (data->count - 2)); + section = &data->sections[1]; + } else { + exif_data_unref (section->content.app1); + } + section->marker = JPEG_MARKER_APP1; + section->content.app1 = exif_data; + exif_data_ref (exif_data); +} + +void +jpeg_data_log (JPEGData *data, ExifLog *log) +{ + if (!data || !data->priv) return; + if (data->priv->log) exif_log_unref (data->priv->log); + data->priv->log = log; + exif_log_ref (log); +} diff --git a/libjpega/jpeg-marker.c b/libjpega/jpeg-marker.c new file mode 100755 index 0000000..10824d2 --- /dev/null +++ b/libjpega/jpeg-marker.c @@ -0,0 +1,122 @@ +/* jpeg-marker.c + * + * Copyright © 2001-2008 Lutz Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ +#include "config.h" +#include "jpeg-marker.h" + +#include + +static const struct { + JPEGMarker marker; + const char *name; + const char *description; +} JPEGMarkerTable[] = { + {JPEG_MARKER_SOF0, "SOF0", "Encoding (baseline)"}, + {JPEG_MARKER_SOF1, "SOF1", "Encoding (extended sequential)"}, + {JPEG_MARKER_SOF2, "SOF2", "Encoding (progressive)"}, + {JPEG_MARKER_SOF3, "SOF3", "Encoding (lossless)"}, + {JPEG_MARKER_SOF5, "SOF5", "Encoding (differential sequential)"}, + {JPEG_MARKER_SOF6, "SOF6", "Encoding (differential progressive)"}, + {JPEG_MARKER_SOF7, "SOF7", "Encoding (differential lossless)"}, + {JPEG_MARKER_SOF9, "SOF9", + "Encoding (extended sequential, arithmetic)"}, + {JPEG_MARKER_SOF10, "SOF10", "Encoding (progressive, arithmetic)"}, + {JPEG_MARKER_SOF11, "SOF11", "Encoding (lossless, arithmetic)"}, + {JPEG_MARKER_SOF13, "SOF13", + "Encoding (differential sequential, arithmetic)"}, + {JPEG_MARKER_SOF14, "SOF14", + "Encoding (differential progressive, arithmetic)"}, + {JPEG_MARKER_SOF15, "SOF15", + "Encoding (differential lossless, arithmetic)"}, + {JPEG_MARKER_SOI, "SOI", "Start of image"}, + {JPEG_MARKER_EOI, "EOI", "End of image"}, + {JPEG_MARKER_SOS, "SOS", "Start of scan"}, + {JPEG_MARKER_COM, "COM", "Comment"}, + {JPEG_MARKER_DHT, "DHT", "Define Huffman table"}, + {JPEG_MARKER_JPG, "JPG", "Extension"}, + {JPEG_MARKER_DAC, "DAC", "Define arithmetic coding conditioning"}, + {JPEG_MARKER_RST1, "RST1", "Restart 1"}, + {JPEG_MARKER_RST2, "RST2", "Restart 2"}, + {JPEG_MARKER_RST3, "RST3", "Restart 3"}, + {JPEG_MARKER_RST4, "RST4", "Restart 4"}, + {JPEG_MARKER_RST5, "RST5", "Restart 5"}, + {JPEG_MARKER_RST6, "RST6", "Restart 6"}, + {JPEG_MARKER_RST7, "RST7", "Restart 7"}, + {JPEG_MARKER_DQT, "DQT", "Define quantization table"}, + {JPEG_MARKER_DNL, "DNL", "Define number of lines"}, + {JPEG_MARKER_DRI, "DRI", "Define restart interval"}, + {JPEG_MARKER_DHP, "DHP", "Define hierarchical progression"}, + {JPEG_MARKER_EXP, "EXP", "Expand reference component"}, + {JPEG_MARKER_APP0, "APP0", "Application segment 0"}, + {JPEG_MARKER_APP1, "APP1", "Application segment 1"}, + {JPEG_MARKER_APP2, "APP2", "Application segment 2"}, + {JPEG_MARKER_APP3, "APP3", "Application segment 3"}, + {JPEG_MARKER_APP4, "APP4", "Application segment 4"}, + {JPEG_MARKER_APP5, "APP5", "Application segment 5"}, + {JPEG_MARKER_APP6, "APP6", "Application segment 6"}, + {JPEG_MARKER_APP7, "APP7", "Application segment 7"}, + {JPEG_MARKER_APP8, "APP8", "Application segment 8"}, + {JPEG_MARKER_APP9, "APP9", "Application segment 9"}, + {JPEG_MARKER_APP10, "APP10", "Application segment 10"}, + {JPEG_MARKER_APP11, "APP11", "Application segment 11"}, + {JPEG_MARKER_APP12, "APP12", "Application segment 12"}, + {JPEG_MARKER_APP13, "APP13", "Application segment 13"}, + {JPEG_MARKER_APP14, "APP14", "Application segment 14"}, + {JPEG_MARKER_APP15, "APP15", "Application segment 15"}, + {JPEG_MARKER_JPG0, "JPG0", "Extension 0"}, + {JPEG_MARKER_JPG1, "JPG1", "Extension 1"}, + {JPEG_MARKER_JPG2, "JPG2", "Extension 2"}, + {JPEG_MARKER_JPG3, "JPG3", "Extension 3"}, + {JPEG_MARKER_JPG4, "JPG4", "Extension 4"}, + {JPEG_MARKER_JPG5, "JPG5", "Extension 5"}, + {JPEG_MARKER_JPG6, "JPG6", "Extension 6"}, + {JPEG_MARKER_JPG7, "JPG7", "Extension 7"}, + {JPEG_MARKER_JPG8, "JPG8", "Extension 8"}, + {JPEG_MARKER_JPG9, "JPG9", "Extension 9"}, + {JPEG_MARKER_JPG10, "JPG10", "Extension 10"}, + {JPEG_MARKER_JPG11, "JPG11", "Extension 11"}, + {JPEG_MARKER_JPG12, "JPG12", "Extension 12"}, + {JPEG_MARKER_JPG13, "JPG13", "Extension 13"}, + {0, NULL, NULL} +}; + +const char * +jpeg_marker_get_name (JPEGMarker marker) +{ + unsigned int i; + + for (i = 0; JPEGMarkerTable[i].name; i++) + if (JPEGMarkerTable[i].marker == marker) + break; + + return (JPEGMarkerTable[i].name); +} + +const char * +jpeg_marker_get_description (JPEGMarker marker) +{ + unsigned int i; + + for (i = 0; JPEGMarkerTable[i].description; i++) + if (JPEGMarkerTable[i].marker == marker) + break; + + return (JPEGMarkerTable[i].description); +} + diff --git a/libjpega/libexif/_stdint.h b/libjpega/libexif/_stdint.h new file mode 100755 index 0000000..80ecf41 --- /dev/null +++ b/libjpega/libexif/_stdint.h @@ -0,0 +1,2 @@ +/* This file is generated automatically by configure */ +#include diff --git a/libjpega/libexif/canon/exif-mnote-data-canon.h b/libjpega/libexif/canon/exif-mnote-data-canon.h new file mode 100755 index 0000000..2a1cc87 --- /dev/null +++ b/libjpega/libexif/canon/exif-mnote-data-canon.h @@ -0,0 +1,58 @@ +/* exif-mnote-data-canon.h + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_CANON_H__ +#define __EXIF_MNOTE_DATA_CANON_H__ + +#include +#include +#include +#include +#include + +typedef struct _ExifMnoteDataCanon ExifMnoteDataCanon; + +#include + +struct _ExifMnoteDataCanon { + ExifMnoteData parent; + + MnoteCanonEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + + ExifDataOption options; +}; + +/*! Detect if MakerNote is recognized as one handled by the Canon module. + * + * \param[in] ed image #ExifData to identify as as a Canon type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_canon_new (ExifMem *mem, ExifDataOption o); + +#endif /* __EXIF_MNOTE_DATA_CANON_H__ */ diff --git a/libjpega/libexif/canon/mnote-canon-entry.h b/libjpega/libexif/canon/mnote-canon-entry.h new file mode 100755 index 0000000..a4d4499 --- /dev/null +++ b/libjpega/libexif/canon/mnote-canon-entry.h @@ -0,0 +1,44 @@ +/* mnote-canon-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_CANON_ENTRY_H__ +#define __MNOTE_CANON_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnoteCanonEntry MnoteCanonEntry; + +struct _MnoteCanonEntry { + MnoteCanonTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +unsigned int mnote_canon_entry_count_values (const MnoteCanonEntry *); +char *mnote_canon_entry_get_value (const MnoteCanonEntry *, unsigned int t, char *val, unsigned int maxlen); + +#endif /* __MNOTE_CANON_ENTRY_H__ */ diff --git a/libjpega/libexif/canon/mnote-canon-tag.h b/libjpega/libexif/canon/mnote-canon-tag.h new file mode 100755 index 0000000..0c7d9aa --- /dev/null +++ b/libjpega/libexif/canon/mnote-canon-tag.h @@ -0,0 +1,59 @@ +/* mnote-canon-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_CANON_TAG_H__ +#define __MNOTE_CANON_TAG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum _MnoteCanonTag { + MNOTE_CANON_TAG_UNKNOWN_0 = 0x0, + MNOTE_CANON_TAG_SETTINGS_1 = 0x1, + MNOTE_CANON_TAG_FOCAL_LENGTH = 0x2, + MNOTE_CANON_TAG_UNKNOWN_3 = 0x3, + MNOTE_CANON_TAG_SETTINGS_2 = 0x4, + MNOTE_CANON_TAG_PANORAMA = 0x5, + MNOTE_CANON_TAG_IMAGE_TYPE = 0x6, + MNOTE_CANON_TAG_FIRMWARE = 0x7, + MNOTE_CANON_TAG_IMAGE_NUMBER = 0x8, + MNOTE_CANON_TAG_OWNER = 0x9, + MNOTE_CANON_TAG_UNKNOWN_10 = 0xa, + MNOTE_CANON_TAG_SERIAL_NUMBER = 0xc, + MNOTE_CANON_TAG_UNKNOWN_13 = 0xd, + MNOTE_CANON_TAG_CUSTOM_FUNCS = 0xf, + MNOTE_CANON_TAG_COLOR_INFORMATION = 0xa0 +}; +typedef enum _MnoteCanonTag MnoteCanonTag; + +const char *mnote_canon_tag_get_name (MnoteCanonTag); +const char *mnote_canon_tag_get_name_sub (MnoteCanonTag, unsigned int, ExifDataOption); +const char *mnote_canon_tag_get_title (MnoteCanonTag); +const char *mnote_canon_tag_get_title_sub (MnoteCanonTag, unsigned int, ExifDataOption); +const char *mnote_canon_tag_get_description (MnoteCanonTag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_CANON_TAG_H__ */ diff --git a/libjpega/libexif/config.h b/libjpega/libexif/config.h new file mode 100755 index 0000000..27a0dfc --- /dev/null +++ b/libjpega/libexif/config.h @@ -0,0 +1,92 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +/* #undef ENABLE_NLS */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +/* #undef HAVE_DCGETTEXT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +/* #undef HAVE_GETTEXT */ + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef ICONV_CONST */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libexif" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libexif-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "EXIF library" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "EXIF library 0.6.20" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libexif" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.6.20" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.6.20" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/libjpega/libexif/exif-byte-order.h b/libjpega/libexif/exif-byte-order.h new file mode 100755 index 0000000..ab5c9ad --- /dev/null +++ b/libjpega/libexif/exif-byte-order.h @@ -0,0 +1,46 @@ +/* exif-byte-order.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_BYTE_ORDER_H__ +#define __EXIF_BYTE_ORDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Which byte order to use */ +typedef enum { + /*! Big-endian byte order */ + EXIF_BYTE_ORDER_MOTOROLA, + /*! Little-endian byte order */ + EXIF_BYTE_ORDER_INTEL +} ExifByteOrder; + +/*! Return a short, localized, textual name for the given byte order. + * \param[in] order byte order + * \return localized textual name of the byte order + */ +const char *exif_byte_order_get_name (ExifByteOrder order); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_BYTE_ORDER_H__ */ diff --git a/libjpega/libexif/exif-content.h b/libjpega/libexif/exif-content.h new file mode 100755 index 0000000..d912ccf --- /dev/null +++ b/libjpega/libexif/exif-content.h @@ -0,0 +1,145 @@ +/*! \file exif-content.h + * \brief Handling EXIF IFDs + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_CONTENT_H__ +#define __EXIF_CONTENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Holds all EXIF tags in a single IFD */ +typedef struct _ExifContent ExifContent; +typedef struct _ExifContentPrivate ExifContentPrivate; + +#include +#include +#include +#include +#include + +struct _ExifContent +{ + ExifEntry **entries; + unsigned int count; + + /*! Data containing this content */ + ExifData *parent; + + ExifContentPrivate *priv; +}; + +/* Lifecycle */ +ExifContent *exif_content_new (void); +ExifContent *exif_content_new_mem (ExifMem *); +void exif_content_ref (ExifContent *content); +void exif_content_unref (ExifContent *content); +void exif_content_free (ExifContent *content); + +/*! Add an EXIF tag to an IFD. + * If this tag already exists in the IFD, this function does nothing. + * \pre The "tag" member of the entry must be set on entry. + * + * \param[out] c IFD + * \param[in] entry EXIF entry to add + */ +void exif_content_add_entry (ExifContent *c, ExifEntry *entry); + +/*! Remove an EXIF tag from an IFD. + * If this tag does not exist in the IFD, this function does nothing. + * + * \param[out] c IFD + * \param[in] e EXIF entry to remove + */ +void exif_content_remove_entry (ExifContent *c, ExifEntry *e); + +/*! Return the #ExifEntry in this IFD corresponding to the given tag. + * This is a pointer into a member of the #ExifContent array and must NOT be + * freed or unrefed by the caller. + * + * \param[in] content EXIF content for an IFD + * \param[in] tag EXIF tag to return + * \return #ExifEntry of the tag, or NULL on error + */ +ExifEntry *exif_content_get_entry (ExifContent *content, ExifTag tag); + +/*! Fix the IFD to bring it into specification. Call #exif_entry_fix on + * each entry in this IFD to fix existing entries, create any new entries + * that are mandatory in this IFD but do not yet exist, and remove any + * entries that are not allowed in this IFD. + * + * \param[in,out] c EXIF content for an IFD + */ +void exif_content_fix (ExifContent *c); + +typedef void (* ExifContentForeachEntryFunc) (ExifEntry *, void *user_data); + +/*! Executes function on each EXIF tag in this IFD in turn. + * The tags will not necessarily be visited in numerical order. + * + * \param[in,out] content IFD over which to iterate + * \param[in] func function to call for each entry + * \param[in] user_data data to pass into func on each call + */ +void exif_content_foreach_entry (ExifContent *content, + ExifContentForeachEntryFunc func, + void *user_data); + +/*! Return the IFD number in which the given #ExifContent is found. + * + * \param[in] c an #ExifContent* + * \return IFD number, or #EXIF_IFD_COUNT on error + */ +ExifIfd exif_content_get_ifd (ExifContent *c); + +/*! Return a textual representation of the EXIF data for a tag. + * + * \param[in] c #ExifContent* for an IFD + * \param[in] t #ExifTag to return + * \param[out] v char* buffer in which to store value + * \param[in] m unsigned int length of the buffer v + * \return the v pointer, or NULL on error + */ +#define exif_content_get_value(c,t,v,m) \ + (exif_content_get_entry (c,t) ? \ + exif_entry_get_value (exif_content_get_entry (c,t),v,m) : NULL) + +/*! Dump contents of the IFD to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] content IFD data + * \param[in] indent how many levels deep to indent the data + */ +void exif_content_dump (ExifContent *content, unsigned int indent); + +/*! Set the log message object for this IFD. + * + * \param[in] content IFD + * \param[in] log #ExifLog* + */ +void exif_content_log (ExifContent *content, ExifLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_CONTENT_H__ */ diff --git a/libjpega/libexif/exif-data-type.h b/libjpega/libexif/exif-data-type.h new file mode 100755 index 0000000..05d4f95 --- /dev/null +++ b/libjpega/libexif/exif-data-type.h @@ -0,0 +1,46 @@ +/* exif-data-tag.h + * + * Copyright (c) 2005 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_DATA_TYPE_H__ +#define __EXIF_DATA_TYPE_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Represents the type of image data to which the EXIF data applies. + * The EXIF tags have different constraints depending on the type of + * image data. + */ +typedef enum { + EXIF_DATA_TYPE_UNCOMPRESSED_CHUNKY = 0, + EXIF_DATA_TYPE_UNCOMPRESSED_PLANAR, + EXIF_DATA_TYPE_UNCOMPRESSED_YCC, + EXIF_DATA_TYPE_COMPRESSED, + EXIF_DATA_TYPE_COUNT, + + EXIF_DATA_TYPE_UNKNOWN = EXIF_DATA_TYPE_COUNT +} ExifDataType; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_TAG_H__ */ diff --git a/libjpega/libexif/exif-data.h b/libjpega/libexif/exif-data.h new file mode 100755 index 0000000..1bcc4e5 --- /dev/null +++ b/libjpega/libexif/exif-data.h @@ -0,0 +1,264 @@ +/*! \file exif-data.h + * \brief Defines the ExifData type and the associated functions. + */ +/* + * \author Lutz Mueller + * \date 2001-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_DATA_H__ +#define __EXIF_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include +#include +#include + +/*! Represents the entire EXIF data found in an image */ +typedef struct _ExifData ExifData; +typedef struct _ExifDataPrivate ExifDataPrivate; + +#include +#include +#include + +/*! Represents the entire EXIF data found in an image */ +struct _ExifData +{ + /*! Data for each IFD */ + ExifContent *ifd[EXIF_IFD_COUNT]; + + /*! Pointer to thumbnail image, or NULL if not available */ + unsigned char *data; + + /*! Number of bytes in thumbnail image at \c data */ + unsigned int size; + + ExifDataPrivate *priv; +}; + +/*! Allocate a new #ExifData. The #ExifData contains an empty + * #ExifContent for each IFD and the default set of options, + * which has #EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS + * and #EXIF_DATA_OPTION_FOLLOW_SPECIFICATION set. + * + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new (void); + +/*! Allocate a new #ExifData using the given memory allocator. + * The #ExifData contains an empty #ExifContent for each IFD and the default + * set of options, which has #EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS and + * #EXIF_DATA_OPTION_FOLLOW_SPECIFICATION set. + * + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_mem (ExifMem *); + +/*! Allocate a new #ExifData and load EXIF data from a JPEG file. + * Uses an #ExifLoader internally to do the loading. + * + * \param[in] path filename including path + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_from_file (const char *path); + +/*! Allocate a new #ExifData and load EXIF data from a memory buffer. + * + * \param[in] data pointer to raw JPEG or EXIF data + * \param[in] size number of bytes of data at data + * \return allocated #ExifData, or NULL on error + */ +ExifData *exif_data_new_from_data (const unsigned char *data, + unsigned int size); + +/*! Load the #ExifData structure from the raw JPEG or EXIF data in the given + * memory buffer. If the EXIF data contains a recognized MakerNote, it is + * loaded and stored as well for later retrieval by #exif_data_get_mnote_data. + * If the EXIF_DATA_OPTION_FOLLOW_SPECIFICATION has been set on this #ExifData, + * then the tags are fixed after loading. + * + * \param[in,out] data EXIF data + * \param[in] d pointer to raw JPEG or EXIF data + * \param[in] size number of bytes of data at d + */ +void exif_data_load_data (ExifData *data, const unsigned char *d, + unsigned int size); + +/*! Store raw EXIF data representing the #ExifData structure into a memory + * buffer. The buffer is allocated by this function and must subsequently be + * freed by the caller using the matching free function as used by the #ExifMem + * in use by this #ExifData. + * + * \param[in] data EXIF data + * \param[out] d pointer to buffer pointer containing raw EXIF data on return + * \param[out] ds pointer to variable to hold the number of bytes of + * data at d, or set to 0 on error + */ +void exif_data_save_data (ExifData *data, unsigned char **d, + unsigned int *ds); + +void exif_data_ref (ExifData *data); +void exif_data_unref (ExifData *data); +void exif_data_free (ExifData *data); + +/*! Return the byte order in use by this EXIF structure. + * + * \param[in] data EXIF data + * \return byte order + */ +ExifByteOrder exif_data_get_byte_order (ExifData *data); + +/*! Set the byte order to use for this EXIF data. If any tags already exist + * (including MakerNote tags) they are are converted to the specified byte + * order. + * + * \param[in,out] data EXIF data + * \param[in] order byte order + */ +void exif_data_set_byte_order (ExifData *data, ExifByteOrder order); + +/*! Return the MakerNote data out of the EXIF data. Only certain + * MakerNote formats that are recognized by libexif are supported. + * The pointer references a member of the #ExifData structure and must NOT be + * freed by the caller. + * + * \param[in] d EXIF data + * \return MakerNote data, or NULL if not found or not supported + */ +ExifMnoteData *exif_data_get_mnote_data (ExifData *d); + +/*! Fix the EXIF data to bring it into specification. Call #exif_content_fix + * on each IFD to fix existing entries, create any new entries that are + * mandatory but do not yet exist, and remove any entries that are not + * allowed. + * + * \param[in,out] d EXIF data + */ +void exif_data_fix (ExifData *d); + +typedef void (* ExifDataForeachContentFunc) (ExifContent *, void *user_data); + +/*! Execute a function on each IFD in turn. + * + * \param[in] data EXIF data over which to iterate + * \param[in] func function to call for each entry + * \param[in] user_data data to pass into func on each call + */ +void exif_data_foreach_content (ExifData *data, + ExifDataForeachContentFunc func, + void *user_data); + +/*! Options to configure the behaviour of #ExifData */ +typedef enum { + /*! Act as though unknown tags are not present */ + EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS = 1 << 0, + + /*! Fix the EXIF tags to follow the spec */ + EXIF_DATA_OPTION_FOLLOW_SPECIFICATION = 1 << 1, + + /*! Leave the MakerNote alone, which could cause it to be corrupted */ + EXIF_DATA_OPTION_DONT_CHANGE_MAKER_NOTE = 1 << 2 +} ExifDataOption; + +/*! Return a short textual description of the given #ExifDataOption. + * + * \param[in] o option + * \return localized textual description of the option + */ +const char *exif_data_option_get_name (ExifDataOption o); + +/*! Return a verbose textual description of the given #ExifDataOption. + * + * \param[in] o option + * \return verbose localized textual description of the option + */ +const char *exif_data_option_get_description (ExifDataOption o); + +/*! Set the given option on the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] o option + */ +void exif_data_set_option (ExifData *d, ExifDataOption o); + +/*! Clear the given option on the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] o option + */ +void exif_data_unset_option (ExifData *d, ExifDataOption o); + +/*! Set the data type for the given #ExifData. + * + * \param[in] d EXIF data + * \param[in] dt data type + */ +void exif_data_set_data_type (ExifData *d, ExifDataType dt); + +/*! Return the data type for the given #ExifData. + * + * \param[in] d EXIF data + * \return data type, or #EXIF_DATA_TYPE_UNKNOWN on error + */ +ExifDataType exif_data_get_data_type (ExifData *d); + +/*! Dump all EXIF data to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] data EXIF data + */ +void exif_data_dump (ExifData *data); + +/*! Set the log message object for all IFDs. + * + * \param[in] data EXIF data + * \param[in] log #ExifLog + */ +void exif_data_log (ExifData *data, ExifLog *log); + +/*! Return an #ExifEntry for the given tag if found in any IFD. + * Each IFD is searched in turn and the first containing a tag with + * this number is returned. + * + * \param[in] d #ExifData + * \param[in] t #ExifTag + * \return #ExifEntry* if found, else NULL if not found + */ +#define exif_data_get_entry(d,t) \ + (exif_content_get_entry(d->ifd[EXIF_IFD_0],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_0],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_1],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_1],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_EXIF],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_GPS],t) : \ + exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) ? \ + exif_content_get_entry(d->ifd[EXIF_IFD_INTEROPERABILITY],t) : NULL) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_DATA_H__ */ diff --git a/libjpega/libexif/exif-entry.h b/libjpega/libexif/exif-entry.h new file mode 100755 index 0000000..22f5d5a --- /dev/null +++ b/libjpega/libexif/exif-entry.h @@ -0,0 +1,188 @@ +/*! \file exif-entry.h + * \brief Handling EXIF entries + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_ENTRY_H__ +#define __EXIF_ENTRY_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Data found in one EXIF tag. + * The #exif_entry_get_value function can provide access to the + * formatted contents, or the struct members can be used directly to + * access the raw contents. + */ +typedef struct _ExifEntry ExifEntry; +typedef struct _ExifEntryPrivate ExifEntryPrivate; + +#include +#include +#include +#include + +/*! Data found in one EXIF tag */ +struct _ExifEntry { + /*! EXIF tag for this entry */ + /* ExifTag had been changed to ExifShort to enable writing of the GPS related tags. + 2011.03.01 - Samsung Electronics */ + ExifShort tag; + + /*! Type of data in this entry */ + ExifFormat format; + + /*! Number of elements in the array, if this is an array entry. + * Contains 1 for non-array data types. */ + unsigned long components; + + /*! Pointer to the raw EXIF data for this entry. It is allocated + * by #exif_entry_initialize and is NULL beforehand. Data contained + * here may be manipulated using the functions in exif-utils.h */ + unsigned char *data; + + /*! Number of bytes in the buffer at \c data. This must be no less + * than exif_format_get_size(format)*components */ + unsigned int size; + + /*! #ExifContent containing this entry. + * \see exif_entry_get_ifd */ + ExifContent *parent; + + /*! Internal data to be used by libexif itself */ + ExifEntryPrivate *priv; +}; + +/* Lifecycle */ + +/*! Reserve memory for and initialize a new #ExifEntry. + * No memory is allocated for the \c data element of the returned #ExifEntry. + * + * \return new allocated #ExifEntry, or NULL on error + * + * \see exif_entry_new_mem, exif_entry_unref + */ +ExifEntry *exif_entry_new (void); + +/*! Reserve memory for and initialize new #ExifEntry using the specified + * memory allocator. + * No memory is allocated for the \c data element of the returned #ExifEntry. + * + * \return new allocated #ExifEntry, or NULL on error + * + * \see exif_entry_new, exif_entry_unref + */ +ExifEntry *exif_entry_new_mem (ExifMem *); + +/*! Increase reference counter for #ExifEntry. + * + * \param[in] entry #ExifEntry + * + * \see exif_entry_unref + */ +void exif_entry_ref (ExifEntry *entry); + +/*! Decrease reference counter for #ExifEntry. + * When the reference count drops to zero, free the entry. + * + * \param[in] entry #ExifEntry + */ +void exif_entry_unref (ExifEntry *entry); + +/*! Actually free the #ExifEntry. + * + * \deprecated Should not be called directly. Use #exif_entry_ref and + * #exif_entry_unref instead. + * + * \param[in] entry EXIF entry + */ +void exif_entry_free (ExifEntry *entry); + +/*! Initialize an empty #ExifEntry with default data in the correct format + * for the given tag. If the entry is already initialized, this function + * does nothing. + * This call allocates memory for the \c data element of the given #ExifEntry. + * That memory is freed at the same time as the #ExifEntry. + * + * \param[out] e entry to initialize + * \param[in] tag tag number to initialize as + */ +void exif_entry_initialize (ExifEntry *e, ExifTag tag); + +/*! Fix the type or format of the given EXIF entry to bring it into spec. + * If the data for this EXIF tag is in of the wrong type or is in an invalid + * format according to the EXIF specification, then it is converted to make it + * valid. This may involve, for example, converting an EXIF_FORMAT_LONG into a + * EXIF_FORMAT_SHORT. If the tag is unknown, its value is untouched. + * + * \note Unfortunately, some conversions are to a type with a more restricted + * range, which could have the side effect that the converted data becomes + * invalid. This is unlikely as the range of each tag in the standard is + * designed to encompass all likely data. + * + * \param[in,out] entry EXIF entry + */ +void exif_entry_fix (ExifEntry *entry); + + +/* For your convenience */ + +/*! Return a localized textual representation of the value of the EXIF entry. + * This is meant for display to the user. The format of each tag is subject + * to change between locales and in newer versions of libexif. Users who + * require the tag data in an unambiguous form should access the data members + * of the #ExifEntry structure directly. + * + * \warning The character set of the returned string may be in + * the encoding of the current locale or the native encoding + * of the camera. + * \bug The EXIF_TAG_XP_* tags are currently always returned in UTF-8, + * regardless of locale, and code points above U+FFFF are not + * supported. + * + * \param[in] entry EXIF entry + * \param[out] val buffer in which to store value + * \param[in] maxlen length of the buffer val + * \return val pointer + */ +const char *exif_entry_get_value (ExifEntry *entry, char *val, + unsigned int maxlen); + +/*! Dump text representation of #ExifEntry to stdout. + * This is intended for diagnostic purposes only. + * + * \param[in] entry EXIF tag data + * \param[in] indent how many levels deep to indent the data + */ +void exif_entry_dump (ExifEntry *entry, unsigned int indent); + +/*! Return the IFD number of the given #ExifEntry + * + * \param[in] e an #ExifEntry* + * \return #ExifIfd, or #EXIF_IFD_COUNT on error + */ +#define exif_entry_get_ifd(e) ((e)?exif_content_get_ifd((e)->parent):EXIF_IFD_COUNT) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_ENTRY_H__ */ diff --git a/libjpega/libexif/exif-format.h b/libjpega/libexif/exif-format.h new file mode 100755 index 0000000..b7a79a4 --- /dev/null +++ b/libjpega/libexif/exif-format.h @@ -0,0 +1,65 @@ +/*! \file exif-format.h + * \brief Handling native EXIF data types + */ +/* + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_FORMAT_H__ +#define __EXIF_FORMAT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! EXIF tag data formats */ +typedef enum { + EXIF_FORMAT_BYTE = 1, + EXIF_FORMAT_ASCII = 2, + EXIF_FORMAT_SHORT = 3, + EXIF_FORMAT_LONG = 4, + EXIF_FORMAT_RATIONAL = 5, + EXIF_FORMAT_SBYTE = 6, + EXIF_FORMAT_UNDEFINED = 7, + EXIF_FORMAT_SSHORT = 8, + EXIF_FORMAT_SLONG = 9, + EXIF_FORMAT_SRATIONAL = 10, + EXIF_FORMAT_FLOAT = 11, + EXIF_FORMAT_DOUBLE = 12 +} ExifFormat; + +/*! Return a textual representation of the given EXIF data type. + * + * \param[in] format EXIF data format + * \return localized textual name + */ +const char *exif_format_get_name (ExifFormat format); + +/*! Return the raw size of the given EXIF data type. + * + * \param[in] format EXIF data format + * \return size in bytes + */ +unsigned char exif_format_get_size (ExifFormat format); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_FORMAT_H__ */ diff --git a/libjpega/libexif/exif-ifd.h b/libjpega/libexif/exif-ifd.h new file mode 100755 index 0000000..26c4053 --- /dev/null +++ b/libjpega/libexif/exif-ifd.h @@ -0,0 +1,43 @@ +/* exif-ifd.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_IFD_H__ +#define __EXIF_IFD_H__ + +/*! Possible EXIF Image File Directories */ +typedef enum { + EXIF_IFD_0 = 0, /*!< */ + EXIF_IFD_1, /*!< */ + EXIF_IFD_EXIF, /*!< */ + EXIF_IFD_GPS, /*!< */ + EXIF_IFD_INTEROPERABILITY, /*!< */ + EXIF_IFD_COUNT /*!< Not a real value, just (max_value + 1). */ +} ExifIfd; + +/*! Return a textual name of the given IFD. The name is a short, unique, + * non-localized text string containing only US-ASCII alphanumeric + * characters. + * + * \param[in] ifd IFD + * \return textual name of the IFD + */ +const char *exif_ifd_get_name (ExifIfd ifd); + +#endif /* __EXIF_IFD_H__ */ diff --git a/libjpega/libexif/exif-loader.h b/libjpega/libexif/exif-loader.h new file mode 100755 index 0000000..62ee87c --- /dev/null +++ b/libjpega/libexif/exif-loader.h @@ -0,0 +1,128 @@ +/*! \file exif-loader.h + * \brief Defines the ExifLoader type + */ +/* + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_LOADER_H__ +#define __EXIF_LOADER_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Data used by the loader interface */ +typedef struct _ExifLoader ExifLoader; + +/*! Allocate a new #ExifLoader. + * + * \return allocated ExifLoader + */ +ExifLoader *exif_loader_new (void); + +/*! Allocate a new #ExifLoader using the specified memory allocator. + * + * \param[in] mem the ExifMem + * \return allocated ExifLoader + */ +ExifLoader *exif_loader_new_mem (ExifMem *mem); + +/*! Increase the refcount of the #ExifLoader. + * + * \param[in] loader the ExifLoader to increase the refcount of. + */ +void exif_loader_ref (ExifLoader *loader); + +/*! Decrease the refcount of the #ExifLoader. + * If the refcount reaches 0, the loader is freed. + * + * \param[in] loader ExifLoader for which to decrease the refcount + */ +void exif_loader_unref (ExifLoader *loader); + +/*! Load a file into the given #ExifLoader from the filesystem. + * The relevant data is copied in raw form into the #ExifLoader. + * + * \param[in] loader loader to write to + * \param[in] fname path to the file to read + */ +void exif_loader_write_file (ExifLoader *loader, const char *fname); + +/*! Load a buffer into the #ExifLoader from a memory buffer. + * The relevant data is copied in raw form into the #ExifLoader. + * + * \param[in] loader loader to write to + * \param[in] buf buffer to read from + * \param[in] sz size of the buffer + * \return 1 while EXIF data is read (or while there is still hope that + * there will be EXIF data later on), 0 otherwise. + */ +unsigned char exif_loader_write (ExifLoader *loader, unsigned char *buf, unsigned int sz); + +/*! Free any data previously loaded and reset the #ExifLoader to its + * newly-initialized state. + * + * \param[in] loader the loader + */ +void exif_loader_reset (ExifLoader *loader); + +/*! Create an #ExifData from the data in the loader. The loader must + * already contain data from a previous call to #exif_loader_write_file + * or #exif_loader_write. + * + * \note The #ExifData returned is created using its default options, which + * may take effect before the data is returned. If other options are desired, + * an #ExifData must be created explicitly and data extracted from the loader + * using #exif_loader_get_buf instead. + * + * \param[in] loader the loader + * \return allocated ExifData + * + * \see exif_loader_get_buf + */ +ExifData *exif_loader_get_data (ExifLoader *loader); + +/*! Return the raw data read by the loader. The returned pointer is only + * guaranteed to be valid until the next call to a function modifying + * this #ExifLoader. Either or both of buf and buf_size may be NULL on + * entry, in which case that value is not returned. + * + * \param[in] loader the loader + * \param[out] buf read-only pointer to the data read by the loader, or NULL + * in case of error + * \param[out] buf_size size of the data at buf, or 0 in case of error + */ +void exif_loader_get_buf (ExifLoader *loader, const unsigned char **buf, + unsigned int *buf_size); + +/*! Set the log message object used by this #ExifLoader. + * \param[in] loader the loader + * \param[in] log #ExifLog + */ +void exif_loader_log (ExifLoader *loader, ExifLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_LOADER_H__ */ diff --git a/libjpega/libexif/exif-log.h b/libjpega/libexif/exif-log.h new file mode 100755 index 0000000..9e71ad6 --- /dev/null +++ b/libjpega/libexif/exif-log.h @@ -0,0 +1,116 @@ +/*! \file exif-log.h + * \brief Log message infrastructure + */ +/* + * Copyright (c) 2004 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_LOG_H__ +#define __EXIF_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +/*! State maintained by the logging interface */ +typedef struct _ExifLog ExifLog; + +/*! Create a new logging instance. + * \see exif_log_free + * + * \return new instance of #ExifLog + */ +ExifLog *exif_log_new (void); +ExifLog *exif_log_new_mem (ExifMem *); +void exif_log_ref (ExifLog *log); +void exif_log_unref (ExifLog *log); + +/*! Delete instance of #ExifLog. + * \see exif_log_new + * + * \param[in] log #ExifLog + * \return new instance of #ExifLog + */ +void exif_log_free (ExifLog *log); + +typedef enum { + EXIF_LOG_CODE_NONE, + EXIF_LOG_CODE_DEBUG, + EXIF_LOG_CODE_NO_MEMORY, + EXIF_LOG_CODE_CORRUPT_DATA +} ExifLogCode; + +/*! Return a textual description of the given class of error log. + * + * \param[in] code logging message class + * \return textual description of the log class + */ +const char *exif_log_code_get_title (ExifLogCode code); + +/*! Return a verbose description of the given class of error log. + * + * \param[in] code logging message class + * \return verbose description of the log class + */ +const char *exif_log_code_get_message (ExifLogCode code); + +/*! Log callback function prototype. + */ +typedef void (* ExifLogFunc) (ExifLog *log, ExifLogCode, const char *domain, + const char *format, va_list args, void *data); + +/*! Register log callback function. + * Calls to the log callback function are purely for diagnostic purposes. + * + * \param[in] log logging state variable + * \param[in] func callback function to set + * \param[in] data data to pass into callback function + */ +void exif_log_set_func (ExifLog *log, ExifLogFunc func, void *data); + +#ifndef NO_VERBOSE_TAG_STRINGS +void exif_log (ExifLog *log, ExifLogCode, const char *domain, + const char *format, ...) +#ifdef __GNUC__ + __attribute__((__format__(printf,4,5))) +#endif +; +#else +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define exif_log(...) do { } while (0) +#elif defined(__GNUC__) +#define exif_log(x...) do { } while (0) +#else +#define exif_log (void) +#endif +#endif + +void exif_logv (ExifLog *log, ExifLogCode, const char *domain, + const char *format, va_list args); + +/* For your convenience */ +#define EXIF_LOG_NO_MEMORY(l,d,s) exif_log ((l), EXIF_LOG_CODE_NO_MEMORY, (d), "Could not allocate %lu byte(s).", (unsigned long)(s)) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_LOG_H__ */ diff --git a/libjpega/libexif/exif-mem.h b/libjpega/libexif/exif-mem.h new file mode 100755 index 0000000..fd8f2fa --- /dev/null +++ b/libjpega/libexif/exif-mem.h @@ -0,0 +1,90 @@ +/*! \file exif-mem.h + * \brief Define the ExifMem data type and the associated functions. + * ExifMem defines the memory management functions used within libexif. + */ +/* exif-mem.h + * + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MEM_H__ +#define __EXIF_MEM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! Should work like calloc() + * + * \param[in] s the size of the block to allocate. + * \return the allocated memory and initialized. + */ +typedef void * (* ExifMemAllocFunc) (ExifLong s); + +/*! Should work like realloc() + * + * \param[in] p the pointer to reallocate + * \param[in] s the size of the reallocated block + * \return allocated memory + */ +typedef void * (* ExifMemReallocFunc) (void *p, ExifLong s); + +/*! Free method for ExifMem + * + * \param[in] p the pointer to free + * \return the freed pointer + */ +typedef void (* ExifMemFreeFunc) (void *p); + +/*! ExifMem define a memory allocator */ +typedef struct _ExifMem ExifMem; + +/*! Create a new ExifMem + * + * \param[in] a the allocator function + * \param[in] r the reallocator function + * \param[in] f the free function + */ +ExifMem *exif_mem_new (ExifMemAllocFunc a, ExifMemReallocFunc r, + ExifMemFreeFunc f); +/*! Refcount an ExifMem + */ +void exif_mem_ref (ExifMem *); + +/*! Unrefcount an ExifMem. + * If the refcount reaches 0, the ExifMem is freed + */ +void exif_mem_unref (ExifMem *); + +void *exif_mem_alloc (ExifMem *m, ExifLong s); +void *exif_mem_realloc (ExifMem *m, void *p, ExifLong s); +void exif_mem_free (ExifMem *m, void *p); + +/*! Create a new ExifMem with default values for your convenience + * + * \return return a new default ExifMem + */ +ExifMem *exif_mem_new_default (void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MEM_H__ */ diff --git a/libjpega/libexif/exif-mnote-data-priv.h b/libjpega/libexif/exif-mnote-data-priv.h new file mode 100755 index 0000000..7462c97 --- /dev/null +++ b/libjpega/libexif/exif-mnote-data-priv.h @@ -0,0 +1,86 @@ +/* exif-mnote-data-priv.h + * + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_PRIV_H__ +#define __EXIF_MNOTE_DATA_PRIV_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + +/*! \internal */ +typedef struct _ExifMnoteDataMethods ExifMnoteDataMethods; + +/*! \internal */ +struct _ExifMnoteDataMethods { + + /* Life cycle */ + void (* free) (ExifMnoteData *); + + /* Modification */ + void (* save) (ExifMnoteData *, unsigned char **, unsigned int *); + void (* load) (ExifMnoteData *, const unsigned char *, unsigned int); + void (* set_offset) (ExifMnoteData *, unsigned int); + void (* set_byte_order) (ExifMnoteData *, ExifByteOrder); + + /* Query */ + unsigned int (* count) (ExifMnoteData *); + unsigned int (* get_id) (ExifMnoteData *, unsigned int); + const char * (* get_name) (ExifMnoteData *, unsigned int); + const char * (* get_title) (ExifMnoteData *, unsigned int); + const char * (* get_description) (ExifMnoteData *, unsigned int); + char * (* get_value) (ExifMnoteData *, unsigned int, char *val, unsigned int maxlen); +}; + +/*! \internal */ +typedef struct _ExifMnoteDataPriv ExifMnoteDataPriv; + +/*! \internal */ +struct _ExifMnoteData +{ + ExifMnoteDataPriv *priv; + + ExifMnoteDataMethods methods; + + /* Logging */ + ExifLog *log; + + /* Memory management */ + ExifMem *mem; +}; + +/*! \internal */ +void exif_mnote_data_construct (ExifMnoteData *, ExifMem *mem); + +/*! \internal */ +void exif_mnote_data_set_byte_order (ExifMnoteData *, ExifByteOrder); + +/*! \internal */ +void exif_mnote_data_set_offset (ExifMnoteData *, unsigned int); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MNOTE_PRIV_H__ */ diff --git a/libjpega/libexif/exif-mnote-data.h b/libjpega/libexif/exif-mnote-data.h new file mode 100755 index 0000000..19e1de5 --- /dev/null +++ b/libjpega/libexif/exif-mnote-data.h @@ -0,0 +1,122 @@ +/*! \file exif-mnote-data.h + * \brief Handling EXIF MakerNote tags + */ +/* + * Copyright (c) 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_H__ +#define __EXIF_MNOTE_DATA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +/*! Data found in the MakerNote tag */ +typedef struct _ExifMnoteData ExifMnoteData; + +void exif_mnote_data_ref (ExifMnoteData *); +void exif_mnote_data_unref (ExifMnoteData *); + +/*! Load the MakerNote data from a memory buffer. + * + * \param[in] d MakerNote data + * \param[in] buf pointer to raw MakerNote tag data + * \param[in] buf_siz number of bytes of data at buf + */ +void exif_mnote_data_load (ExifMnoteData *d, const unsigned char *buf, + unsigned int buf_siz); + +/*! + * Save the raw MakerNote data into a memory buffer. The buffer is + * allocated by this function and must subsequently be freed by the + * caller. + * + * \param[in,out] d extract the data from this structure + * \param[out] buf pointer to buffer pointer containing MakerNote data on return + * \param[out] buf_siz pointer to the size of the buffer + */ +void exif_mnote_data_save (ExifMnoteData *d, unsigned char **buf, + unsigned int *buf_siz); + +/*! Return the number of tags in the MakerNote. + * + * \param[in] d MakerNote data + * \return number of tags, or 0 if no MakerNote or the type is not supported + */ +unsigned int exif_mnote_data_count (ExifMnoteData *d); + +/*! Return the MakerNote tag number for the tag at the specified index within + * the MakerNote. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return MakerNote tag number + */ +unsigned int exif_mnote_data_get_id (ExifMnoteData *d, unsigned int n); + +/*! Returns textual name of the given MakerNote tag. The name is a short, + * unique (within this type of MakerNote), non-localized text string + * containing only US-ASCII alphanumeric characters. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual name of the tag + */ +const char *exif_mnote_data_get_name (ExifMnoteData *d, unsigned int n); + +/*! Returns textual title of the given MakerNote tag. + * The title is a short, localized textual description of the tag. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual name of the tag + */ +const char *exif_mnote_data_get_title (ExifMnoteData *d, unsigned int n); + +/*! Returns verbose textual description of the given MakerNote tag. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \return textual description of the tag + */ +const char *exif_mnote_data_get_description (ExifMnoteData *d, unsigned int n); + +/*! Return a textual representation of the value of the MakerNote entry. + * + * \warning The character set of the returned string may be in + * the encoding of the current locale or the native encoding + * of the camera. + * + * \param[in] d MakerNote data + * \param[in] n index of the entry within the MakerNote data + * \param[out] val buffer in which to store value + * \param[in] maxlen length of the buffer val + * \return val pointer, or NULL on error + */ +char *exif_mnote_data_get_value (ExifMnoteData *d, unsigned int n, char *val, unsigned int maxlen); + +void exif_mnote_data_log (ExifMnoteData *, ExifLog *); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_MNOTE_DATA_H__ */ diff --git a/libjpega/libexif/exif-system.h b/libjpega/libexif/exif-system.h new file mode 100755 index 0000000..81fa703 --- /dev/null +++ b/libjpega/libexif/exif-system.h @@ -0,0 +1,32 @@ +/*! \file exif-system.h + * \brief System specific definitions, not for installation! + */ +/* + * Copyright (c) 2007 Hans Ulrich Niedermann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef EXIF_SYSTEM_H +#define EXIF_SYSTEM_H + +#if defined(__GNUC__) && (__GNUC__ >= 2) +# define UNUSED(param) UNUSED_PARAM_##param __attribute__((unused)) +#else +# define UNUSED(param) param +#endif + +#endif /* !defined(EXIF_SYSTEM_H) */ diff --git a/libjpega/libexif/exif-tag.h b/libjpega/libexif/exif-tag.h new file mode 100755 index 0000000..d8b8657 --- /dev/null +++ b/libjpega/libexif/exif-tag.h @@ -0,0 +1,287 @@ +/*! \file exif-tag.h + * \brief Handling EXIF tags + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_TAG_H__ +#define __EXIF_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +/*! EXIF tags */ +typedef enum { + EXIF_TAG_INTEROPERABILITY_INDEX = 0x0001, + EXIF_TAG_INTEROPERABILITY_VERSION = 0x0002, + EXIF_TAG_NEW_SUBFILE_TYPE = 0x00fe, + EXIF_TAG_IMAGE_WIDTH = 0x0100, + EXIF_TAG_IMAGE_LENGTH = 0x0101, + EXIF_TAG_BITS_PER_SAMPLE = 0x0102, + EXIF_TAG_COMPRESSION = 0x0103, + EXIF_TAG_PHOTOMETRIC_INTERPRETATION = 0x0106, + EXIF_TAG_FILL_ORDER = 0x010a, + EXIF_TAG_DOCUMENT_NAME = 0x010d, + EXIF_TAG_IMAGE_DESCRIPTION = 0x010e, + EXIF_TAG_MAKE = 0x010f, + EXIF_TAG_MODEL = 0x0110, + EXIF_TAG_STRIP_OFFSETS = 0x0111, + EXIF_TAG_ORIENTATION = 0x0112, + EXIF_TAG_SAMPLES_PER_PIXEL = 0x0115, + EXIF_TAG_ROWS_PER_STRIP = 0x0116, + EXIF_TAG_STRIP_BYTE_COUNTS = 0x0117, + EXIF_TAG_X_RESOLUTION = 0x011a, + EXIF_TAG_Y_RESOLUTION = 0x011b, + EXIF_TAG_PLANAR_CONFIGURATION = 0x011c, + EXIF_TAG_RESOLUTION_UNIT = 0x0128, + EXIF_TAG_TRANSFER_FUNCTION = 0x012d, + EXIF_TAG_SOFTWARE = 0x0131, + EXIF_TAG_DATE_TIME = 0x0132, + EXIF_TAG_ARTIST = 0x013b, + EXIF_TAG_WHITE_POINT = 0x013e, + EXIF_TAG_PRIMARY_CHROMATICITIES = 0x013f, + EXIF_TAG_SUB_IFDS = 0x014a, + EXIF_TAG_TRANSFER_RANGE = 0x0156, + EXIF_TAG_JPEG_PROC = 0x0200, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT = 0x0201, + EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = 0x0202, + EXIF_TAG_YCBCR_COEFFICIENTS = 0x0211, + EXIF_TAG_YCBCR_SUB_SAMPLING = 0x0212, + EXIF_TAG_YCBCR_POSITIONING = 0x0213, + EXIF_TAG_REFERENCE_BLACK_WHITE = 0x0214, + EXIF_TAG_XML_PACKET = 0x02bc, + EXIF_TAG_RELATED_IMAGE_FILE_FORMAT = 0x1000, + EXIF_TAG_RELATED_IMAGE_WIDTH = 0x1001, + EXIF_TAG_RELATED_IMAGE_LENGTH = 0x1002, + EXIF_TAG_CFA_REPEAT_PATTERN_DIM = 0x828d, + EXIF_TAG_CFA_PATTERN = 0x828e, + EXIF_TAG_BATTERY_LEVEL = 0x828f, + EXIF_TAG_COPYRIGHT = 0x8298, + EXIF_TAG_EXPOSURE_TIME = 0x829a, + EXIF_TAG_FNUMBER = 0x829d, + EXIF_TAG_IPTC_NAA = 0x83bb, + EXIF_TAG_IMAGE_RESOURCES = 0x8649, + EXIF_TAG_EXIF_IFD_POINTER = 0x8769, + EXIF_TAG_INTER_COLOR_PROFILE = 0x8773, + EXIF_TAG_EXPOSURE_PROGRAM = 0x8822, + EXIF_TAG_SPECTRAL_SENSITIVITY = 0x8824, + EXIF_TAG_GPS_INFO_IFD_POINTER = 0x8825, + EXIF_TAG_ISO_SPEED_RATINGS = 0x8827, + EXIF_TAG_OECF = 0x8828, + EXIF_TAG_TIME_ZONE_OFFSET = 0x882a, + EXIF_TAG_EXIF_VERSION = 0x9000, + EXIF_TAG_DATE_TIME_ORIGINAL = 0x9003, + EXIF_TAG_DATE_TIME_DIGITIZED = 0x9004, + EXIF_TAG_COMPONENTS_CONFIGURATION = 0x9101, + EXIF_TAG_COMPRESSED_BITS_PER_PIXEL = 0x9102, + EXIF_TAG_SHUTTER_SPEED_VALUE = 0x9201, + EXIF_TAG_APERTURE_VALUE = 0x9202, + EXIF_TAG_BRIGHTNESS_VALUE = 0x9203, + EXIF_TAG_EXPOSURE_BIAS_VALUE = 0x9204, + EXIF_TAG_MAX_APERTURE_VALUE = 0x9205, + EXIF_TAG_SUBJECT_DISTANCE = 0x9206, + EXIF_TAG_METERING_MODE = 0x9207, + EXIF_TAG_LIGHT_SOURCE = 0x9208, + EXIF_TAG_FLASH = 0x9209, + EXIF_TAG_FOCAL_LENGTH = 0x920a, + EXIF_TAG_SUBJECT_AREA = 0x9214, + EXIF_TAG_TIFF_EP_STANDARD_ID = 0x9216, + EXIF_TAG_MAKER_NOTE = 0x927c, + EXIF_TAG_USER_COMMENT = 0x9286, + EXIF_TAG_SUB_SEC_TIME = 0x9290, + EXIF_TAG_SUB_SEC_TIME_ORIGINAL = 0x9291, + EXIF_TAG_SUB_SEC_TIME_DIGITIZED = 0x9292, + EXIF_TAG_XP_TITLE = 0x9c9b, + EXIF_TAG_XP_COMMENT = 0x9c9c, + EXIF_TAG_XP_AUTHOR = 0x9c9d, + EXIF_TAG_XP_KEYWORDS = 0x9c9e, + EXIF_TAG_XP_SUBJECT = 0x9c9f, + EXIF_TAG_FLASH_PIX_VERSION = 0xa000, + EXIF_TAG_COLOR_SPACE = 0xa001, + EXIF_TAG_PIXEL_X_DIMENSION = 0xa002, + EXIF_TAG_PIXEL_Y_DIMENSION = 0xa003, + EXIF_TAG_RELATED_SOUND_FILE = 0xa004, + EXIF_TAG_INTEROPERABILITY_IFD_POINTER = 0xa005, + EXIF_TAG_FLASH_ENERGY = 0xa20b, + EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE = 0xa20c, + EXIF_TAG_FOCAL_PLANE_X_RESOLUTION = 0xa20e, + EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION = 0xa20f, + EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT = 0xa210, + EXIF_TAG_SUBJECT_LOCATION = 0xa214, + EXIF_TAG_EXPOSURE_INDEX = 0xa215, + EXIF_TAG_SENSING_METHOD = 0xa217, + EXIF_TAG_FILE_SOURCE = 0xa300, + EXIF_TAG_SCENE_TYPE = 0xa301, + EXIF_TAG_NEW_CFA_PATTERN = 0xa302, + EXIF_TAG_CUSTOM_RENDERED = 0xa401, + EXIF_TAG_EXPOSURE_MODE = 0xa402, + EXIF_TAG_WHITE_BALANCE = 0xa403, + EXIF_TAG_DIGITAL_ZOOM_RATIO = 0xa404, + EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM = 0xa405, + EXIF_TAG_SCENE_CAPTURE_TYPE = 0xa406, + EXIF_TAG_GAIN_CONTROL = 0xa407, + EXIF_TAG_CONTRAST = 0xa408, + EXIF_TAG_SATURATION = 0xa409, + EXIF_TAG_SHARPNESS = 0xa40a, + EXIF_TAG_DEVICE_SETTING_DESCRIPTION = 0xa40b, + EXIF_TAG_SUBJECT_DISTANCE_RANGE = 0xa40c, + EXIF_TAG_IMAGE_UNIQUE_ID = 0xa420, + EXIF_TAG_GAMMA = 0xa500, + EXIF_TAG_PRINT_IMAGE_MATCHING = 0xc4a5, + EXIF_TAG_PADDING = 0xea1c +} ExifTag; + +/* GPS tags overlap with above ones. */ +#define EXIF_TAG_GPS_VERSION_ID 0x0000 +#define EXIF_TAG_GPS_LATITUDE_REF 0x0001 /* INTEROPERABILITY_INDEX */ +#define EXIF_TAG_GPS_LATITUDE 0x0002 /* INTEROPERABILITY_VERSION */ +#define EXIF_TAG_GPS_LONGITUDE_REF 0x0003 +#define EXIF_TAG_GPS_LONGITUDE 0x0004 +#define EXIF_TAG_GPS_ALTITUDE_REF 0x0005 +#define EXIF_TAG_GPS_ALTITUDE 0x0006 +#define EXIF_TAG_GPS_TIME_STAMP 0x0007 +#define EXIF_TAG_GPS_SATELLITES 0x0008 +#define EXIF_TAG_GPS_STATUS 0x0009 +#define EXIF_TAG_GPS_MEASURE_MODE 0x000a +#define EXIF_TAG_GPS_DOP 0x000b +#define EXIF_TAG_GPS_SPEED_REF 0x000c +#define EXIF_TAG_GPS_SPEED 0x000d +#define EXIF_TAG_GPS_TRACK_REF 0x000e +#define EXIF_TAG_GPS_TRACK 0x000f +#define EXIF_TAG_GPS_IMG_DIRECTION_REF 0x0010 +#define EXIF_TAG_GPS_IMG_DIRECTION 0x0011 +#define EXIF_TAG_GPS_MAP_DATUM 0x0012 +#define EXIF_TAG_GPS_DEST_LATITUDE_REF 0x0013 +#define EXIF_TAG_GPS_DEST_LATITUDE 0x0014 +#define EXIF_TAG_GPS_DEST_LONGITUDE_REF 0x0015 +#define EXIF_TAG_GPS_DEST_LONGITUDE 0x0016 +#define EXIF_TAG_GPS_DEST_BEARING_REF 0x0017 +#define EXIF_TAG_GPS_DEST_BEARING 0x0018 +#define EXIF_TAG_GPS_DEST_DISTANCE_REF 0x0019 +#define EXIF_TAG_GPS_DEST_DISTANCE 0x001a +#define EXIF_TAG_GPS_PROCESSING_METHOD 0x001b +#define EXIF_TAG_GPS_AREA_INFORMATION 0x001c +#define EXIF_TAG_GPS_DATE_STAMP 0x001d +#define EXIF_TAG_GPS_DIFFERENTIAL 0x001e + +/*! What level of support a tag enjoys in the EXIF standard */ +typedef enum { + /*! The meaning of this tag is unknown */ + EXIF_SUPPORT_LEVEL_UNKNOWN = 0, + + /*! This tag is not allowed in the given IFD */ + EXIF_SUPPORT_LEVEL_NOT_RECORDED, + + /*! This tag is mandatory in the given IFD */ + EXIF_SUPPORT_LEVEL_MANDATORY, + + /*! This tag is optional in the given IFD */ + EXIF_SUPPORT_LEVEL_OPTIONAL +} ExifSupportLevel; + +/*! Return the tag ID given its unique textual name. + * + * \param[in] name tag name + * \return tag ID, or 0 if tag not found + * \note The tag not found value cannot be distinguished from a legitimate + * tag number 0. + */ +ExifTag exif_tag_from_name (const char *name); + +/*! Return a textual name of the given tag when found in the given IFD. The + * name is a short, unique, non-localized text string containing only + * US-ASCII alphanumeric characters. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual name of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_name_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return a textual title of the given tag when found in the given IFD. + * The title is a short, localized description of the tag. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual title of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_title_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return a verbose textual description of the given tag when found in the + * given IFD. The description is a verbose, localized description of the tag. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD + * \return textual description of the tag, or NULL if the tag is unknown + */ +const char *exif_tag_get_description_in_ifd (ExifTag tag, ExifIfd ifd); + +/*! Return whether the given tag is mandatory or not in the given IFD and + * data type according to the EXIF specification. If the IFD given is + * EXIF_IFD_COUNT, the result is EXIF_SUPPORT_LEVEL_UNKNOWN. If the data + * type is EXIF_DATA_TYPE_UNKNOWN, the result is + * EXIF_SUPPORT_LEVEL_UNKNOWN unless the support level is the same for + * all data types. + * + * \param[in] tag EXIF tag + * \param[in] ifd IFD or EXIF_IFD_COUNT + * \param[in] t data type or EXIF_DATA_TYPE_UNKNOWN + * \return the level of support for this tag + */ +ExifSupportLevel exif_tag_get_support_level_in_ifd (ExifTag tag, ExifIfd ifd, + ExifDataType t); + +/* Don't use these functions. They are here for compatibility only. */ + +/*! \deprecated Use #exif_tag_get_name_in_ifd instead */ +const char *exif_tag_get_name (ExifTag tag); + +/*! \deprecated Use #exif_tag_get_title_in_ifd instead */ +const char *exif_tag_get_title (ExifTag tag); + +/*! \deprecated Use #exif_tag_get_description_in_ifd instead */ +const char *exif_tag_get_description (ExifTag tag); + + +/* For now, do not use these functions. */ + +/*! \internal */ +ExifTag exif_tag_table_get_tag (unsigned int n); + +/*! \internal */ +const char *exif_tag_table_get_name (unsigned int n); + +/*! \internal */ +unsigned int exif_tag_table_count (void); + + +/* Don't use these definitions. They are here for compatibility only. */ + +/*! \deprecated Use EXIF_TAG_PRINT_IMAGE_MATCHING instead. */ +#define EXIF_TAG_UNKNOWN_C4A5 EXIF_TAG_PRINT_IMAGE_MATCHING + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_TAG_H__ */ diff --git a/libjpega/libexif/exif-utils.h b/libjpega/libexif/exif-utils.h new file mode 100755 index 0000000..7861564 --- /dev/null +++ b/libjpega/libexif/exif-utils.h @@ -0,0 +1,194 @@ +/*! \file exif-utils.h + * \brief EXIF data manipulation functions and types + */ +/* + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_UTILS_H__ +#define __EXIF_UTILS_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + + +/* If these definitions don't work for you, please let us fix the + * macro generating _stdint.h */ + +/*! EXIF Unsigned Byte data type */ +typedef unsigned char ExifByte; /* 1 byte */ + +/*! EXIF Signed Byte data type */ +typedef signed char ExifSByte; /* 1 byte */ + +/*! EXIF Text String data type */ +typedef char * ExifAscii; + +/*! EXIF Unsigned Short data type */ +typedef uint16_t ExifShort; /* 2 bytes */ + +/*! EXIF Signed Short data type */ +typedef int16_t ExifSShort; /* 2 bytes */ + +/*! EXIF Unsigned Long data type */ +typedef uint32_t ExifLong; /* 4 bytes */ + +/*! EXIF Signed Long data type */ +typedef int32_t ExifSLong; /* 4 bytes */ + +/*! EXIF Unsigned Rational data type */ +typedef struct {ExifLong numerator; ExifLong denominator;} ExifRational; + +typedef char ExifUndefined; /* 1 byte */ + +/*! EXIF Signed Rational data type */ +typedef struct {ExifSLong numerator; ExifSLong denominator;} ExifSRational; + + +/*! Retrieve an #ExifShort value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifShort exif_get_short (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSShort value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSShort exif_get_sshort (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifLong value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifLong exif_get_long (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSLong value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSLong exif_get_slong (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifRational value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifRational exif_get_rational (const unsigned char *b, ExifByteOrder order); + +/*! Retrieve an #ExifSRational value from memory. + * + * \param[in] b pointer to raw EXIF value in memory + * \param[in] order byte order of raw value + * \return value + */ +ExifSRational exif_get_srational (const unsigned char *b, ExifByteOrder order); + +/*! Store an ExifShort value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_short (unsigned char *b, ExifByteOrder order, + ExifShort value); + +/*! Store an ExifSShort value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_sshort (unsigned char *b, ExifByteOrder order, + ExifSShort value); + +/*! Store an ExifLong value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_long (unsigned char *b, ExifByteOrder order, + ExifLong value); + +/*! Store an ExifSLong value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_slong (unsigned char *b, ExifByteOrder order, + ExifSLong value); + +/*! Store an ExifRational value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_rational (unsigned char *b, ExifByteOrder order, + ExifRational value); + +/*! Store an ExifSRational value into memory in EXIF format. + * + * \param[out] b buffer in which to write raw value + * \param[in] order byte order to use + * \param[in] value data value to store + */ +void exif_set_srational (unsigned char *b, ExifByteOrder order, + ExifSRational value); + +/*! \internal */ +void exif_convert_utf16_to_utf8 (char *out, const unsigned short *in, int maxlen); + +/* Please do not use this function outside of the library. */ + +/*! \internal */ +void exif_array_set_byte_order (ExifFormat, unsigned char *, unsigned int, + ExifByteOrder o_orig, ExifByteOrder o_new); + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/* For compatibility with older versions */ + +/*! \deprecated Use EXIF_TAG_SUB_SEC_TIME instead. */ +#define EXIF_TAG_SUBSEC_TIME EXIF_TAG_SUB_SEC_TIME + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXIF_UTILS_H__ */ diff --git a/libjpega/libexif/exif.h b/libjpega/libexif/exif.h new file mode 100755 index 0000000..1c8e0f6 --- /dev/null +++ b/libjpega/libexif/exif.h @@ -0,0 +1,87 @@ +/*! \file exif.h exif/exif.h + * \brief Dummy header file for documentation purposes + * \date 2007 + * \author Hans Ulrich Niedermann, et. al. + * + * \mainpage The libexif library + * + * \section general_notes General Notes + * + * This documentation is work in progress, as is the code itself. + * + * \section using_libexif Using libexif + * + * \#include + * + * libexif provides a libexif.pc file for use with pkgconfig on the + * libexif installation. If you are using libtool to build your + * package, you can also make use of libexif-uninstalled.pc. + * + * An application using libexif would typically first create an #ExifLoader to + * load EXIF data into memory. From there, it would extract that data as + * an #ExifData to start manipulating it. Each IFD is represented by its own + * #ExifContent within that #ExifData, which contains all the tag data in + * #ExifEntry form. If the MakerNote data is required, an #ExifMnoteData + * can be extracted from the #ExifData and manipulated with the MakerNote + * functions. + * + * libexif is written in C using an object-based style that defines + * sets of functions that operate on each data structure. + * + * \section data_structures Primary Data Structures + * + * #ExifLoader + * State maintained by the loader interface while importing EXIF data + * from an external file or memory + * + * #ExifData + * The entirety of EXIF data found in an image + * + * #ExifContent + * All EXIF tags in a single IFD + * + * #ExifEntry + * Data found in a single EXIF tag + * + * #ExifMnoteData + * All data found in the MakerNote tag + * + * #ExifLog + * State maintained by the logging interface + * + * \section string_conventions String Conventions + * + * Strings are 8 bit characters ("char*"). When libexif is compiled with + * NLS, character set and encoding are as set in the current locale, + * except for strings that come directly from the data in EXIF + * tags which are generally returned in raw form. Most EXIF strings are + * defined to be plain 7-bit ASCII so this raw form should be acceptable in + * any UNIX locale, but some software ignores the specification and + * writes 8-bit characters. It is up to the application to detect this + * and deal with it intelligently. + * + * \section memory_management Memory Management Patterns + * + * For pointers to data objects, libexif uses reference counting. The + * pattern is to use the foo_new() function to create a data object, + * foo_ref() to increase the reference counter, and foo_unref() to + * decrease the reference counter and possibly free(3)ing the memory. + * + * Libexif by default relies on the calloc(3), realloc(3), and free(3) + * functions, but the libexif user can tell libexif to use their + * special memory management functions at runtime. + * + * \section thread_safety Thread Safety + * + * libexif is thread safe when the underlying C library is also thread safe. + * Some C libraries may require defining a special macro (like _REENTRANT) + * to ensure this, or may require linking to a special thread-safe version of + * the library. + * + * The programmer must ensure that each object allocated by libexif is only + * used in a single thread at once. For example, an ExifData* allocated + * in one thread can't be used in a second thread if there is any chance + * that the first thread could use it at the same time. Multiple threads + * can use libexif without issues if they never share handles. + * + */ diff --git a/libjpega/libexif/fuji/exif-mnote-data-fuji.h b/libjpega/libexif/fuji/exif-mnote-data-fuji.h new file mode 100755 index 0000000..2a7cd3e --- /dev/null +++ b/libjpega/libexif/fuji/exif-mnote-data-fuji.h @@ -0,0 +1,53 @@ +/* exif-mnote-data-fuji.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_CONTENT_H__ +#define __MNOTE_FUJI_CONTENT_H__ + +#include +#include +#include +#include + +typedef struct _ExifMnoteDataFuji ExifMnoteDataFuji; + +struct _ExifMnoteDataFuji { + ExifMnoteData parent; + + MnoteFujiEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; +}; + +/*! Detect if MakerNote is recognized as one handled by the Fuji module. + * + * \param[in] ed image #ExifData to identify as as a Fuji type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_fuji_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_fuji_new (ExifMem *); + +#endif /* __MNOTE_FUJI_CONTENT_H__ */ diff --git a/libjpega/libexif/fuji/mnote-fuji-entry.h b/libjpega/libexif/fuji/mnote-fuji-entry.h new file mode 100755 index 0000000..a8395c5 --- /dev/null +++ b/libjpega/libexif/fuji/mnote-fuji-entry.h @@ -0,0 +1,45 @@ +/* mnote-fuji-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_ENTRY_H__ +#define __MNOTE_FUJI_ENTRY_H__ + +#include +#include + +typedef struct _MnoteFujiEntry MnoteFujiEntry; +typedef struct _MnoteFujiEntryPrivate MnoteFujiEntryPrivate; + +#include + +struct _MnoteFujiEntry { + MnoteFujiTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_fuji_entry_get_value (MnoteFujiEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_FUJI_ENTRY_H__ */ diff --git a/libjpega/libexif/fuji/mnote-fuji-tag.h b/libjpega/libexif/fuji/mnote-fuji-tag.h new file mode 100755 index 0000000..1d250e4 --- /dev/null +++ b/libjpega/libexif/fuji/mnote-fuji-tag.h @@ -0,0 +1,92 @@ +/* mnote-fuji-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_FUJI_TAG_H__ +#define __MNOTE_FUJI_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +enum _MnoteFujiTag { + MNOTE_FUJI_TAG_VERSION = 0x0000, + MNOTE_FUJI_TAG_SERIAL_NUMBER = 0x0010, + MNOTE_FUJI_TAG_QUALITY = 0x1000, + MNOTE_FUJI_TAG_SHARPNESS = 0x1001, + MNOTE_FUJI_TAG_WHITE_BALANCE = 0x1002, + MNOTE_FUJI_TAG_COLOR = 0x1003, + MNOTE_FUJI_TAG_TONE = 0x1004, + MNOTE_FUJI_TAG_UNKNOWN_1006 = 0x1006, + MNOTE_FUJI_TAG_UNKNOWN_1007 = 0x1007, + MNOTE_FUJI_TAG_UNKNOWN_1008 = 0x1008, + MNOTE_FUJI_TAG_UNKNOWN_1009 = 0x1009, + MNOTE_FUJI_TAG_UNKNOWN_100A = 0x100A, + MNOTE_FUJI_TAG_UNKNOWN_100B = 0x100B, + MNOTE_FUJI_TAG_FLASH_MODE = 0x1010, + MNOTE_FUJI_TAG_FLASH_STRENGTH = 0x1011, + MNOTE_FUJI_TAG_MACRO = 0x1020, + MNOTE_FUJI_TAG_FOCUS_MODE = 0x1021, + MNOTE_FUJI_TAG_UNKNOWN_1022 = 0x1022, + MNOTE_FUJI_TAG_FOCUS_POINT = 0x1023, + MNOTE_FUJI_TAG_UNKNOWN_1024 = 0x1024, + MNOTE_FUJI_TAG_UNKNOWN_1025 = 0x1025, + MNOTE_FUJI_TAG_SLOW_SYNC = 0x1030, + MNOTE_FUJI_TAG_PICTURE_MODE = 0x1031, + MNOTE_FUJI_TAG_UNKNOWN_1032 = 0x1032, + MNOTE_FUJI_TAG_CONT_TAKING = 0x1100, + MNOTE_FUJI_TAG_SEQUENCE_NUMBER = 0x1101, + MNOTE_FUJI_TAG_UNKNOWN_1200 = 0x1200, + MNOTE_FUJI_TAG_FINEPIX_COLOR = 0x1210, + MNOTE_FUJI_TAG_BLUR_CHECK = 0x1300, + MNOTE_FUJI_TAG_FOCUS_CHECK = 0x1301, + MNOTE_FUJI_TAG_AUTO_EXPOSURE_CHECK = 0x1302, + MNOTE_FUJI_TAG_UNKNOWN_1303 = 0x1303, + MNOTE_FUJI_TAG_DYNAMIC_RANGE = 0x1400, + MNOTE_FUJI_TAG_FILM_MODE = 0x1401, + MNOTE_FUJI_TAG_DYNAMIC_RANGE_SETTING = 0x1402, + MNOTE_FUJI_TAG_DEV_DYNAMIC_RANGE_SETTING= 0x1403, + MNOTE_FUJI_TAG_MIN_FOCAL_LENGTH = 0x1404, + MNOTE_FUJI_TAG_MAX_FOCAL_LENGTH = 0x1405, + MNOTE_FUJI_TAG_MAX_APERT_AT_MIN_FOC = 0x1406, + MNOTE_FUJI_TAG_MAX_APERT_AT_MAX_FOC = 0x1407, + MNOTE_FUJI_TAG_UNKNOWN_1408 = 0x1408, + MNOTE_FUJI_TAG_UNKNOWN_1409 = 0x1409, + MNOTE_FUJI_TAG_UNKNOWN_140A = 0x140A, + MNOTE_FUJI_TAG_UNKNOWN_1410 = 0x1410, + MNOTE_FUJI_TAG_UNKNOWN_1421 = 0x1421, + MNOTE_FUJI_TAG_UNKNOWN_4100 = 0x4100, + MNOTE_FUJI_TAG_UNKNOWN_4800 = 0x4800, + MNOTE_FUJI_TAG_FILE_SOURCE = 0x8000, + MNOTE_FUJI_TAG_ORDER_NUMBER = 0x8002, + MNOTE_FUJI_TAG_FRAME_NUMBER = 0x8003, +}; +typedef enum _MnoteFujiTag MnoteFujiTag; + +const char *mnote_fuji_tag_get_name (MnoteFujiTag tag); +const char *mnote_fuji_tag_get_title (MnoteFujiTag tag); +const char *mnote_fuji_tag_get_description (MnoteFujiTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_FUJI_TAG_H__ */ diff --git a/libjpega/libexif/i18n.h b/libjpega/libexif/i18n.h new file mode 100755 index 0000000..4b4b908 --- /dev/null +++ b/libjpega/libexif/i18n.h @@ -0,0 +1,52 @@ +/* i18n.h + * + * Copyright (c) 2001 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __I18N_H__ +#define __I18N_H__ + +#include "config.h" + +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define ngettext(String1,String2,Count) (Count==1?String1:String2) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +#ifdef __WATCOMC__ +# define bind_textdomain_codeset(Domain,Codeset) +# define bindtextdomain(Domain,Directory) +#else +# define bind_textdomain_codeset(Domain,Codeset) +# define bindtextdomain(Domain,Directory) +#endif +# define _(String) (String) +# define N_(String) (String) +#endif + +#endif /* __I18N_H__ */ diff --git a/libjpega/libexif/olympus/exif-mnote-data-olympus.h b/libjpega/libexif/olympus/exif-mnote-data-olympus.h new file mode 100755 index 0000000..d08b0f4 --- /dev/null +++ b/libjpega/libexif/olympus/exif-mnote-data-olympus.h @@ -0,0 +1,67 @@ +/* mnote-olympus-data.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_CONTENT_H__ +#define __MNOTE_OLYMPUS_CONTENT_H__ + +#include +#include +#include +#include +#include + +enum OlympusVersion { + unrecognized = 0, + nikonV1 = 1, + nikonV2 = 2, + olympusV1 = 3, + olympusV2 = 4, + sanyoV1 = 5, + epsonV1 = 6, + nikonV0 = 7 +}; + + +typedef struct _ExifMnoteDataOlympus ExifMnoteDataOlympus; + +struct _ExifMnoteDataOlympus { + ExifMnoteData parent; + + MnoteOlympusEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + enum OlympusVersion version; +}; + +/*! Detect if MakerNote is recognized as one handled by the Olympus module. + * + * \param[in] ed image #ExifData to identify as as an Olympus type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_olympus_new (ExifMem *); + +#endif /* __MNOTE_OLYMPUS_CONTENT_H__ */ diff --git a/libjpega/libexif/olympus/mnote-olympus-entry.h b/libjpega/libexif/olympus/mnote-olympus-entry.h new file mode 100755 index 0000000..f1b0a98 --- /dev/null +++ b/libjpega/libexif/olympus/mnote-olympus-entry.h @@ -0,0 +1,43 @@ +/* mnote-olympus-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_ENTRY_H__ +#define __MNOTE_OLYMPUS_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnoteOlympusEntry MnoteOlympusEntry; + +struct _MnoteOlympusEntry { + MnoteOlympusTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_olympus_entry_get_value (MnoteOlympusEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_OLYMPUS_ENTRY_H__ */ diff --git a/libjpega/libexif/olympus/mnote-olympus-tag.h b/libjpega/libexif/olympus/mnote-olympus-tag.h new file mode 100755 index 0000000..2c3de82 --- /dev/null +++ b/libjpega/libexif/olympus/mnote-olympus-tag.h @@ -0,0 +1,229 @@ +/* mnote-olympus-tag.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_OLYMPUS_TAG_H__ +#define __MNOTE_OLYMPUS_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +enum _MnoteOlympusTag { + + /* Nikon v.2 */ + MNOTE_NIKON_TAG_FIRMWARE = 0x0001, + MNOTE_NIKON_TAG_ISO = 0x0002, + MNOTE_NIKON_TAG_COLORMODE1 = 0x0003, + MNOTE_NIKON_TAG_QUALITY = 0x0004, + MNOTE_NIKON_TAG_WHITEBALANCE = 0x0005, + MNOTE_NIKON_TAG_SHARPENING = 0x0006, + MNOTE_NIKON_TAG_FOCUSMODE = 0x0007, + MNOTE_NIKON_TAG_FLASHSETTING = 0x0008, + MNOTE_NIKON_TAG_FLASHMODE = 0x0009, + MNOTE_NIKON_TAG_WHITEBALANCEFINE = 0x000b, + MNOTE_NIKON_TAG_WHITEBALANCERB = 0x000c, + MNOTE_NIKON_TAG_UNKNOWN_0X000D = 0x000d, + MNOTE_NIKON_TAG_EXPOSUREDIFF = 0x000e, + MNOTE_NIKON_TAG_ISOSELECTION = 0x000f, + MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER= 0x0011, + MNOTE_NIKON_TAG_FLASHEXPCOMPENSATION = 0x0012, + MNOTE_NIKON_TAG_ISO2 = 0x0013, + MNOTE_NIKON_TAG_IMAGEBOUNDARY = 0x0016, + MNOTE_NIKON_TAG_UNKNOWN_0X0017 = 0x0017, + MNOTE_NIKON_TAG_FLASHEXPOSUREBRACKETVAL = 0x0018, + MNOTE_NIKON_TAG_EXPOSUREBRACKETVAL = 0x0019, + MNOTE_NIKON_TAG_IMAGEADJUSTMENT = 0x0080, + MNOTE_NIKON_TAG_TONECOMPENSATION = 0x0081, + MNOTE_NIKON_TAG_ADAPTER = 0x0082, + MNOTE_NIKON_TAG_LENSTYPE = 0x0083, + MNOTE_NIKON_TAG_LENS = 0x0084, + MNOTE_NIKON_TAG_MANUALFOCUSDISTANCE = 0x0085, + MNOTE_NIKON_TAG_DIGITALZOOM = 0x0086, + MNOTE_NIKON_TAG_FLASHUSED = 0x0087, + MNOTE_NIKON_TAG_AFFOCUSPOSITION = 0x0088, + MNOTE_NIKON_TAG_BRACKETING = 0x0089, + MNOTE_NIKON_TAG_UNKNOWN_0X008A = 0x008a, + MNOTE_NIKON_TAG_LENS_FSTOPS = 0x008b, + MNOTE_NIKON_TAG_CURVE = 0x008c, + MNOTE_NIKON_TAG_COLORMODE = 0x008d, + MNOTE_NIKON_TAG_LIGHTTYPE = 0x0090, + MNOTE_NIKON_TAG_UNKNOWN_0X0091 = 0x0091, + MNOTE_NIKON_TAG_HUE = 0x0092, + MNOTE_NIKON_TAG_SATURATION = 0x0094, + MNOTE_NIKON_TAG_NOISEREDUCTION = 0x0095, + MNOTE_NIKON_TAG_UNKNOWN_0X0097 = 0x0097, + MNOTE_NIKON_TAG_UNKNOWN_0X0098 = 0x0098, + MNOTE_NIKON_TAG_SENSORPIXELSIZE = 0x009a, + MNOTE_NIKON_TAG_UNKNOWN_0X009B = 0x009b, + MNOTE_NIKON_TAG_SERIALNUMBER = 0x00a0, + MNOTE_NIKON_TAG_IMAGE_DATASIZE = 0x00a2, + MNOTE_NIKON_TAG_UNKNOWN_0X00A3 = 0x00a3, + MNOTE_NIKON_TAG_TOTALPICTURES = 0x00a7, + MNOTE_NIKON_TAG_UNKNOWN_0X00A8 = 0x00a8, + MNOTE_NIKON_TAG_OPTIMIZATION = 0x00a9, + MNOTE_NIKON_TAG_SATURATION2 = 0x00aa, + MNOTE_NIKON_TAG_VARIPROGRAM = 0x00ab, + MNOTE_NIKON_TAG_CAPTUREEDITORDATA = 0x0e01, + MNOTE_NIKON_TAG_CAPTUREEDITORVER = 0x0e09, + MNOTE_NIKON_TAG_UNKNOWN_0X0E0E = 0x0e0e, + MNOTE_NIKON_TAG_UNKNOWN_0X0E10 = 0x0e10, + + /* Nikon v1: real values + our proprietary base to distinguish from v2 */ + MNOTE_NIKON1_TAG_BASE = 0x8000, + MNOTE_NIKON1_TAG_UNKNOWN_0X0002 = 0x0002 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_QUALITY = 0x0003 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_COLORMODE = 0x0004 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_IMAGEADJUSTMENT = 0x0005 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_CCDSENSITIVITY = 0x0006 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_WHITEBALANCE = 0x0007 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_FOCUS = 0x0008 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_UNKNOWN_0X0009 = 0x0009 + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_DIGITALZOOM = 0x000a + MNOTE_NIKON1_TAG_BASE, + MNOTE_NIKON1_TAG_CONVERTER = 0x000b + MNOTE_NIKON1_TAG_BASE, + + /* Olympus and some Sanyo */ + MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE = 0x0100, + MNOTE_OLYMPUS_TAG_MODE = 0x0200, + MNOTE_OLYMPUS_TAG_QUALITY = 0x0201, + MNOTE_OLYMPUS_TAG_MACRO = 0x0202, + MNOTE_OLYMPUS_TAG_BWMODE = 0x0203, + MNOTE_OLYMPUS_TAG_DIGIZOOM = 0x0204, + MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL = 0x0205, + MNOTE_OLYMPUS_TAG_LENSDISTORTION = 0x0206, + MNOTE_OLYMPUS_TAG_VERSION = 0x0207, + MNOTE_OLYMPUS_TAG_INFO = 0x0208, + MNOTE_OLYMPUS_TAG_ID = 0x0209, + MNOTE_OLYMPUS_TAG_PRECAPTUREFRAMES = 0x0300, + MNOTE_OLYMPUS_TAG_WHITEBOARD = 0x0301, + MNOTE_OLYMPUS_TAG_ONETOUCHWB = 0x0302, + MNOTE_OLYMPUS_TAG_WHITEBALANCEBRACKET = 0x0303, + MNOTE_OLYMPUS_TAG_WHITEBALANCEBIAS = 0x0304, + MNOTE_OLYMPUS_TAG_DATADUMP = 0x0f00, + MNOTE_OLYMPUS_TAG_UNKNOWN_4 = 0x0f04, + MNOTE_OLYMPUS_TAG_SHUTTERSPEED = 0x1000, + MNOTE_OLYMPUS_TAG_ISOVALUE = 0x1001, + MNOTE_OLYMPUS_TAG_APERTUREVALUE = 0x1002, + MNOTE_OLYMPUS_TAG_BRIGHTNESSVALUE = 0x1003, + MNOTE_OLYMPUS_TAG_FLASHMODE = 0x1004, + MNOTE_OLYMPUS_TAG_FLASHDEVICE = 0x1005, + MNOTE_OLYMPUS_TAG_EXPOSURECOMP = 0x1006, + MNOTE_OLYMPUS_TAG_SENSORTEMPERATURE = 0x1007, + MNOTE_OLYMPUS_TAG_LENSTEMPERATURE = 0x1008, + MNOTE_OLYMPUS_TAG_LIGHTCONDITION = 0x1009, + MNOTE_OLYMPUS_TAG_FOCUSRANGE = 0x100a, + MNOTE_OLYMPUS_TAG_MANFOCUS = 0x100b, + MNOTE_OLYMPUS_TAG_FOCUSDIST = 0x100c, + MNOTE_OLYMPUS_TAG_ZOOMSTEPCOUNT = 0x100d, + MNOTE_OLYMPUS_TAG_FOCUSSTEPCOUNT = 0x100e, + MNOTE_OLYMPUS_TAG_SHARPNESS = 0x100f, + MNOTE_OLYMPUS_TAG_FLASHCHARGELEVEL = 0x1010, + MNOTE_OLYMPUS_TAG_COLORMATRIX = 0x1011, + MNOTE_OLYMPUS_TAG_BLACKLEVEL = 0x1012, + MNOTE_OLYMPUS_TAG_WBALANCE = 0x1015, + MNOTE_OLYMPUS_TAG_REDBALANCE = 0x1017, + MNOTE_OLYMPUS_TAG_BLUEBALANCE = 0x1018, + MNOTE_OLYMPUS_TAG_COLORMATRIXNUMBER = 0x1019, + MNOTE_OLYMPUS_TAG_SERIALNUMBER2 = 0x101a, + MNOTE_OLYMPUS_TAG_FLASHEXPOSURECOMP = 0x1023, + MNOTE_OLYMPUS_TAG_INTERNALFLASHTABLE = 0x1024, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHGVALUE = 0x1025, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHBOUNCE = 0x1026, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHZOOM = 0x1027, + MNOTE_OLYMPUS_TAG_EXTERNALFLASHMODE = 0x1028, + MNOTE_OLYMPUS_TAG_CONTRAST = 0x1029, + MNOTE_OLYMPUS_TAG_SHARPNESSFACTOR = 0x102a, + MNOTE_OLYMPUS_TAG_COLORCONTROL = 0x102b, + MNOTE_OLYMPUS_TAG_IMAGEWIDTH = 0x102e, + MNOTE_OLYMPUS_TAG_IMAGEHEIGHT = 0x102f, + MNOTE_OLYMPUS_TAG_SCENEDETECT = 0x1030, + MNOTE_OLYMPUS_TAG_COMPRESSIONRATIO = 0x1034, + MNOTE_OLYMPUS_TAG_PREVIEWIMAGEVALID = 0x1035, + MNOTE_OLYMPUS_TAG_AFRESULT = 0x1038, + MNOTE_OLYMPUS_TAG_CCDSCANMODE = 0x1039, + MNOTE_OLYMPUS_TAG_NOISEREDUCTION = 0x103a, + MNOTE_OLYMPUS_TAG_INFINITYLENSSTEP = 0x103b, + MNOTE_OLYMPUS_TAG_NEARLENSSTEP = 0x103c, + MNOTE_OLYMPUS_TAG_LIGHTVALUECENTER = 0x103d, + MNOTE_OLYMPUS_TAG_LIGHTVALUEPERIPHERY = 0x103e, + + /* Epson */ + MNOTE_EPSON_TAG_IMAGE_WIDTH = 0x020b, + MNOTE_EPSON_TAG_IMAGE_HEIGHT = 0x020c, + MNOTE_EPSON_TAG_SOFTWARE = 0x020d, + + /* Sanyo */ + MNOTE_SANYO_TAG_SEQUENTIALSHOT = 0x020e, + MNOTE_SANYO_TAG_WIDERANGE = 0x020f, + MNOTE_SANYO_TAG_COLORADJUSTMENTMODE = 0x0210, + MNOTE_SANYO_TAG_FOCUSMODE = 0x0212, + MNOTE_SANYO_TAG_QUICKSHOT = 0x0213, + MNOTE_SANYO_TAG_SELFTIMER = 0x0214, + MNOTE_SANYO_TAG_VOICEMEMO = 0x0216, + MNOTE_SANYO_TAG_RECORDSHUTTERRELEASE = 0x0217, + MNOTE_SANYO_TAG_FLICKERREDUCE = 0x0218, + MNOTE_SANYO_TAG_OPTICALZOOM = 0x0219, + MNOTE_SANYO_TAG_CCDSENSITIVITY = 0x021a, + MNOTE_SANYO_TAG_DIGITALZOOM = 0x021b, + MNOTE_SANYO_TAG_LIGHTSOURCESPECIAL = 0x021d, + MNOTE_SANYO_TAG_RESAVED = 0x021e, + MNOTE_SANYO_TAG_SCENESELECT = 0x021f, + MNOTE_SANYO_TAG_MANUALFOCUSDISTANCE = 0x0223, + MNOTE_SANYO_TAG_SEQUENCESHOTINTERVAL = 0x0224, +}; +typedef enum _MnoteOlympusTag MnoteOlympusTag; + +/* Don't use these definitions. They are here for compatibility only. */ +#define MNOTE_OLYMPUS_TAG_UNKNOWN_1 MNOTE_OLYMPUS_TAG_BWMODE +#define MNOTE_OLYMPUS_TAG_UNKNOWN_2 MNOTE_OLYMPUS_TAG_FOCALPLANEDIAGONAL +#define MNOTE_OLYMPUS_TAG_UNKNOWN_3 MNOTE_OLYMPUS_TAG_LENSDISTORTION +#define MNOTE_OLYMPUS_TAG_UNKNOWN_5 MNOTE_OLYMPUS_TAG_DATADUMP +#define MNOTE_NIKON_TAG_PREVIEWIMAGE MNOTE_NIKON_TAG_PREVIEWIMAGE_IFD_POINTER + +/*! Return a textual name of the given tag within the Olympus-style MakerNote. + * The name is a short, unique, non-localized text string containing only + * US-ASCII alphanumeric characters. + * + * \param[in] tag Olympus-style MakerNote tag + * \return textual name of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_name (MnoteOlympusTag tag); + +/*! Return a textual title of the given tag within the Olympus-style MakerNote. + * The title is a short, localized description of the tag. + * + * \param[in] tag Olympus-style MakerNote tag + * \return textual title of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_title (MnoteOlympusTag tag); + +/*! Return a verbose textual description of the given tag within the + * Olympus-style MakerNote. + * The description is a verbose, localized description of the tag. + * + * \param[in] tag EXIF tag + * \return textual description of the tag, or NULL if the tag is unknown + */ +const char *mnote_olympus_tag_get_description (MnoteOlympusTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_OLYMPUS_TAG_H__ */ diff --git a/libjpega/libexif/pentax/exif-mnote-data-pentax.h b/libjpega/libexif/pentax/exif-mnote-data-pentax.h new file mode 100755 index 0000000..da9f79a --- /dev/null +++ b/libjpega/libexif/pentax/exif-mnote-data-pentax.h @@ -0,0 +1,59 @@ +/* exif-mnote-data-pentax.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __EXIF_MNOTE_DATA_PENTAX_H__ +#define __EXIF_MNOTE_DATA_PENTAX_H__ + +#include +#include +#include +#include +#include +#include + +enum PentaxVersion {pentaxV1 = 1, pentaxV2 = 2, pentaxV3 = 3, casioV2 = 4 }; + +typedef struct _ExifMnoteDataPentax ExifMnoteDataPentax; + +struct _ExifMnoteDataPentax { + ExifMnoteData parent; + + MnotePentaxEntry *entries; + unsigned int count; + + ExifByteOrder order; + unsigned int offset; + + enum PentaxVersion version; +}; + +/*! Detect if MakerNote is recognized as one handled by the Pentax module. + * + * \param[in] ed image #ExifData to identify as as a Pentax type + * \param[in] e #ExifEntry for EXIF_TAG_MAKER_NOTE, from within ed but + * duplicated here for convenience + * \return 0 if not recognized, nonzero if recognized. The specific nonzero + * value returned may identify a subtype unique within this module. + */ +int exif_mnote_data_pentax_identify (const ExifData *ed, const ExifEntry *e); + +ExifMnoteData *exif_mnote_data_pentax_new (ExifMem *); + +#endif /* __EXIF_MNOTE_DATA_PENTAX_H__ */ diff --git a/libjpega/libexif/pentax/mnote-pentax-entry.h b/libjpega/libexif/pentax/mnote-pentax-entry.h new file mode 100755 index 0000000..4547ec3 --- /dev/null +++ b/libjpega/libexif/pentax/mnote-pentax-entry.h @@ -0,0 +1,43 @@ +/* mnote-pentax-entry.h + * + * Copyright (c) 2002 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_ENTRY_H__ +#define __MNOTE_PENTAX_ENTRY_H__ + +#include +#include +#include + +typedef struct _MnotePentaxEntry MnotePentaxEntry; + +struct _MnotePentaxEntry { + MnotePentaxTag tag; + ExifFormat format; + unsigned long components; + + unsigned char *data; + unsigned int size; + + ExifByteOrder order; +}; + +char *mnote_pentax_entry_get_value (MnotePentaxEntry *entry, char *val, unsigned int maxlen); + +#endif /* __MNOTE_PENTAX_ENTRY_H__ */ diff --git a/libjpega/libexif/pentax/mnote-pentax-tag.h b/libjpega/libexif/pentax/mnote-pentax-tag.h new file mode 100755 index 0000000..51b2aec --- /dev/null +++ b/libjpega/libexif/pentax/mnote-pentax-tag.h @@ -0,0 +1,153 @@ +/* mnote-pentax-tag.h + * + * Copyright (c) 2002, 2003 Lutz Mueller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __MNOTE_PENTAX_TAG_H__ +#define __MNOTE_PENTAX_TAG_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * Missing features which are probably in the unknowns somewhere ... + * 1/ AF Area (Wide, Spot, Free) + * 2/ AE Metering (Multi segment, Centre-weighted, Spot) + * 3/ + */ + +enum _MnotePentaxTag { + MNOTE_PENTAX_TAG_MODE = 0x0001, + MNOTE_PENTAX_TAG_QUALITY = 0x0002, + MNOTE_PENTAX_TAG_FOCUS = 0x0003, + MNOTE_PENTAX_TAG_FLASH = 0x0004, + MNOTE_PENTAX_TAG_UNKNOWN_05 = 0x0005, + MNOTE_PENTAX_TAG_UNKNOWN_06 = 0x0006, + MNOTE_PENTAX_TAG_WHITE_BALANCE = 0x0007, + MNOTE_PENTAX_TAG_UNKNOWN_08 = 0x0008, + MNOTE_PENTAX_TAG_UNKNOWN_09 = 0x0009, + MNOTE_PENTAX_TAG_ZOOM = 0x000a, + MNOTE_PENTAX_TAG_SHARPNESS = 0x000b, + MNOTE_PENTAX_TAG_CONTRAST = 0x000c, + MNOTE_PENTAX_TAG_SATURATION = 0x000d, + MNOTE_PENTAX_TAG_UNKNOWN_14 = 0x000e, + MNOTE_PENTAX_TAG_UNKNOWN_15 = 0x000f, + MNOTE_PENTAX_TAG_UNKNOWN_16 = 0x0010, + MNOTE_PENTAX_TAG_UNKNOWN_17 = 0x0011, + MNOTE_PENTAX_TAG_UNKNOWN_18 = 0x0012, + MNOTE_PENTAX_TAG_UNKNOWN_19 = 0x0013, + MNOTE_PENTAX_TAG_ISO_SPEED = 0x0014, + MNOTE_PENTAX_TAG_UNKNOWN_21 = 0x0015, + MNOTE_PENTAX_TAG_COLOR = 0x0017, + MNOTE_PENTAX_TAG_UNKNOWN_24 = 0x0018, + MNOTE_PENTAX_TAG_UNKNOWN_25 = 0x0019, + MNOTE_PENTAX_TAG_PRINTIM = 0x0e00, + MNOTE_PENTAX_TAG_TZ_CITY = 0x1000, + MNOTE_PENTAX_TAG_TZ_DST = 0x1001, + + /* Pentax v2, v3: real values + our proprietary base to distinguish from v1 */ + MNOTE_PENTAX2_TAG_BASE = 0x4000, + MNOTE_PENTAX2_TAG_MODE = 0x0001 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_SIZE = 0x0002 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_LENGTH = 0x0003 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PREVIEW_START = 0x0004 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_MODEL_ID = 0x0005 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DATE = 0x0006 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_TIME = 0x0007 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_QUALITY = 0x0008 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_SIZE = 0x0009 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE = 0x000b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_MODE = 0x000c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_MODE = 0x000d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINT_SELECTED = 0x000e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_AFPOINT = 0x000f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCUS_POSITION = 0x0010 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_TIME = 0x0012 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FNUMBER = 0x0013 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_ISO = 0x0014 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_EXPOSURE_COMPENSATION = 0x0016 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_METERING_MODE = 0x0017 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AUTO_BRACKETING = 0x0018 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE = 0x0019 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_BALANCE_MODE= 0x001a + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLUE_BALANCE = 0x001b + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RED_BALANCE = 0x001c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FOCAL_LENGTH = 0x001d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DIGITAL_ZOOM = 0x001e + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SATURATION = 0x001f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CONTRAST = 0x0020 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHARPNESS = 0x0021 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WORLDTIME_LOCATION = 0x0022 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY = 0x0023 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY = 0x0024 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_DST = 0x0025 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_DST = 0x0026 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FRAME_NUMBER = 0x0029 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_PROCESSING = 0x0032 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_PICTURE_MODE2 = 0x0033 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DRIVE_MODE = 0x0034 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_COLOR_SPACE = 0x0037 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_AREA_OFFSET = 0x0038 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_RAW_IMAGE_SIZE = 0x0039 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AFPOINTS_USED = 0x003c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_TYPE = 0x003f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_TEMPERATURE = 0x0047 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_NOISE_REDUCTION = 0x0049 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_EXPOSURE_COMP = 0x004d + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_IMAGE_TONE = 0x004f + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_SHAKE_REDUCTION_INFO = 0x005c + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BLACK_POINT = 0x0200 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_WHITE_POINT = 0x0201 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_AE_INFO = 0x0206 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_LENS_INFO = 0x0207 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_FLASH_INFO = 0x0208 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_CAMERA_INFO = 0x0215 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_BATTERY_INFO = 0x0216 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_HOMETOWN_CITY_CODE = 0x1000 + MNOTE_PENTAX2_TAG_BASE, + MNOTE_PENTAX2_TAG_DESTINATION_CITY_CODE = 0x1001 + MNOTE_PENTAX2_TAG_BASE, + + /* Casio v2: some Casio v2 tags match Pentax v2 tags */ + MNOTE_CASIO2_TAG_BASE = MNOTE_PENTAX2_TAG_BASE, + MNOTE_CASIO2_TAG_PREVIEW_START = 0x2000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE_BIAS = 0x2011 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_WHITE_BALANCE = 0x2012 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_OBJECT_DISTANCE = 0x2022 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FLASH_DISTANCE = 0x2034 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_RECORD_MODE = 0x3000 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_SELF_TIMER = 0x3001 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_QUALITY = 0x3002 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FOCUS_MODE = 0x3003 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_TIME_ZONE = 0x3006 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_BESTSHOT_MODE = 0x3007 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_CCS_ISO_SENSITIVITY = 0x3014 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_COLOR_MODE = 0x3015 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_ENHANCEMENT = 0x3016 + MNOTE_CASIO2_TAG_BASE, + MNOTE_CASIO2_TAG_FINER = 0x3017 + MNOTE_CASIO2_TAG_BASE +}; +typedef enum _MnotePentaxTag MnotePentaxTag; + +const char *mnote_pentax_tag_get_name (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_title (MnotePentaxTag tag); +const char *mnote_pentax_tag_get_description (MnotePentaxTag tag); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MNOTE_PENTAX_TAG_H__ */ diff --git a/libjpega/libjpeg/config.h b/libjpega/libjpeg/config.h new file mode 100755 index 0000000..27a0dfc --- /dev/null +++ b/libjpega/libjpeg/config.h @@ -0,0 +1,92 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +/* #undef ENABLE_NLS */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +/* #undef HAVE_DCGETTEXT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +/* #undef HAVE_GETTEXT */ + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define as const if the declaration of iconv() needs const. */ +/* #undef ICONV_CONST */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libexif" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libexif-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "EXIF library" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "EXIF library 0.6.20" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libexif" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.6.20" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.6.20" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/libjpega/libjpeg/exif-i18n.h b/libjpega/libjpeg/exif-i18n.h new file mode 100755 index 0000000..09321ff --- /dev/null +++ b/libjpega/libjpeg/exif-i18n.h @@ -0,0 +1,56 @@ +/* i18n.h + * + * Copyright © 2001 Lutz Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __I18N_H__ +#define __I18N_H__ + +#ifdef ENABLE_NLS +# include +# undef _ +# define _(String) dgettext (GETTEXT_PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define ngettext(String1,String2,Count) ((Count)==1?(String1):(String2)) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bind_textdomain_codeset(Domain,Codeset) (Codeset) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + + +/*! Convert a string from UTF-8 into one appropriate for the current locale + * if gettext doesn't doesn't do the conversion itself. + * If given a NULL pointer, returns a pointer to an empty string. + * \param[in] in the string to convert + * \returns pointer to converted string, which may be in a static buffer + */ +const char *exif_i18n_convert_utf8_to_locale (const char *); +#define C(s) (exif_i18n_convert_utf8_to_locale(s)) + + +#endif /* __I18N_H__ */ diff --git a/libjpega/libjpeg/jpeg-data.h b/libjpega/libjpeg/jpeg-data.h new file mode 100755 index 0000000..e9468ba --- /dev/null +++ b/libjpega/libjpeg/jpeg-data.h @@ -0,0 +1,102 @@ +/* jpeg-data.h + * + * Copyright © 2001 Lutz Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ + +#ifndef __JPEG_DATA_H__ +#define __JPEG_DATA_H__ + +#include "jpeg-marker.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef ExifData * JPEGContentAPP1; + +typedef struct _JPEGContentGeneric JPEGContentGeneric; +struct _JPEGContentGeneric +{ + unsigned char *data; + unsigned int size; +}; + +typedef union _JPEGContent JPEGContent; +union _JPEGContent +{ + JPEGContentGeneric generic; + JPEGContentAPP1 app1; +}; + +typedef struct _JPEGSection JPEGSection; +struct _JPEGSection +{ + JPEGMarker marker; + JPEGContent content; +}; + +typedef struct _JPEGData JPEGData; +typedef struct _JPEGDataPrivate JPEGDataPrivate; + +struct _JPEGData +{ + JPEGSection *sections; + unsigned int count; + + unsigned char *data; + unsigned int size; + + JPEGDataPrivate *priv; +}; + +JPEGData *jpeg_data_new (void); +JPEGData *jpeg_data_new_from_file (const char *path); +JPEGData *jpeg_data_new_from_data (const unsigned char *data, + unsigned int size); + +void jpeg_data_ref (JPEGData *data); +void jpeg_data_unref (JPEGData *data); +void jpeg_data_free (JPEGData *data); + +void jpeg_data_load_data (JPEGData *data, const unsigned char *d, + unsigned int size); +void jpeg_data_save_data (JPEGData *data, unsigned char **d, + unsigned int *size); +void jpeg_data_save_data_no_copy (JPEGData *data, unsigned char *d, + unsigned int *size); + +void jpeg_data_load_file (JPEGData *data, const char *path); +int jpeg_data_save_file (JPEGData *data, const char *path); + +void jpeg_data_set_exif_data (JPEGData *data, ExifData *exif_data); +ExifData *jpeg_data_get_exif_data (JPEGData *data); + +void jpeg_data_dump (JPEGData *data); + +void jpeg_data_append_section (JPEGData *data); + +void jpeg_data_log (JPEGData *data, ExifLog *log); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __JPEG_DATA_H__ */ diff --git a/libjpega/libjpeg/jpeg-marker.h b/libjpega/libjpeg/jpeg-marker.h new file mode 100755 index 0000000..88bfe48 --- /dev/null +++ b/libjpega/libjpeg/jpeg-marker.h @@ -0,0 +1,103 @@ +/* jpeg-marker.h + * + * Copyright © 2001 Lutz Müller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + */ +#ifndef __JPEG_MARKER_H__ +#define __JPEG_MARKER_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum { + JPEG_MARKER_SOF0 = 0xc0, + JPEG_MARKER_SOF1 = 0xc1, + JPEG_MARKER_SOF2 = 0xc2, + JPEG_MARKER_SOF3 = 0xc3, + JPEG_MARKER_DHT = 0xc4, + JPEG_MARKER_SOF5 = 0xc5, + JPEG_MARKER_SOF6 = 0xc6, + JPEG_MARKER_SOF7 = 0xc7, + JPEG_MARKER_JPG = 0xc8, + JPEG_MARKER_SOF9 = 0xc9, + JPEG_MARKER_SOF10 = 0xca, + JPEG_MARKER_SOF11 = 0xcb, + JPEG_MARKER_DAC = 0xcc, + JPEG_MARKER_SOF13 = 0xcd, + JPEG_MARKER_SOF14 = 0xce, + JPEG_MARKER_SOF15 = 0xcf, + JPEG_MARKER_RST0 = 0xd0, + JPEG_MARKER_RST1 = 0xd1, + JPEG_MARKER_RST2 = 0xd2, + JPEG_MARKER_RST3 = 0xd3, + JPEG_MARKER_RST4 = 0xd4, + JPEG_MARKER_RST5 = 0xd5, + JPEG_MARKER_RST6 = 0xd6, + JPEG_MARKER_RST7 = 0xd7, + JPEG_MARKER_SOI = 0xd8, + JPEG_MARKER_EOI = 0xd9, + JPEG_MARKER_SOS = 0xda, + JPEG_MARKER_DQT = 0xdb, + JPEG_MARKER_DNL = 0xdc, + JPEG_MARKER_DRI = 0xdd, + JPEG_MARKER_DHP = 0xde, + JPEG_MARKER_EXP = 0xdf, + JPEG_MARKER_APP0 = 0xe0, + JPEG_MARKER_APP1 = 0xe1, + JPEG_MARKER_APP2 = 0xe2, + JPEG_MARKER_APP3 = 0xe3, + JPEG_MARKER_APP4 = 0xe4, + JPEG_MARKER_APP5 = 0xe5, + JPEG_MARKER_APP6 = 0xe6, + JPEG_MARKER_APP7 = 0xe7, + JPEG_MARKER_APP8 = 0xe8, + JPEG_MARKER_APP9 = 0xe9, + JPEG_MARKER_APP10 = 0xea, + JPEG_MARKER_APP11 = 0xeb, + JPEG_MARKER_APP12 = 0xec, + JPEG_MARKER_APP13 = 0xed, + JPEG_MARKER_APP14 = 0xee, + JPEG_MARKER_APP15 = 0xef, + JPEG_MARKER_JPG0 = 0xf0, + JPEG_MARKER_JPG1 = 0xf1, + JPEG_MARKER_JPG2 = 0xf2, + JPEG_MARKER_JPG3 = 0xf3, + JPEG_MARKER_JPG4 = 0xf4, + JPEG_MARKER_JPG5 = 0xf5, + JPEG_MARKER_JPG6 = 0xf6, + JPEG_MARKER_JPG7 = 0xf7, + JPEG_MARKER_JPG8 = 0xf8, + JPEG_MARKER_JPG9 = 0xf9, + JPEG_MARKER_JPG10 = 0xfa, + JPEG_MARKER_JPG11 = 0xfb, + JPEG_MARKER_JPG12 = 0xfc, + JPEG_MARKER_JPG13 = 0xfd, + JPEG_MARKER_COM = 0xfe +} JPEGMarker; + +#define JPEG_IS_MARKER(m) (((m) >= JPEG_MARKER_SOF0) && \ + ((m) <= JPEG_MARKER_COM)) + +const char *jpeg_marker_get_name (JPEGMarker marker); +const char *jpeg_marker_get_description (JPEGMarker marker); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __JPEG_MARKER_H__ */ diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk new file mode 100644 index 0000000..1114496 --- /dev/null +++ b/liboverlay/Android.mk @@ -0,0 +1,35 @@ +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) +# HAL module implemenation, not prelinked and stored in +# hw/..so + +include $(CLEAR_VARS) +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SHARED_LIBRARIES := liblog libcutils + +ifdef BOARD_V4L2_DEVICE + LOCAL_CFLAGS += -DV4L2_DEVICE=\"$(BOARD_V4L2_DEVICE)\" +endif + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/../include + +LOCAL_SRC_FILES := v4l2_utils.c overlay.cpp + +LOCAL_MODULE := overlay.smdkc210 +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp new file mode 100644 index 0000000..d0a4289 --- /dev/null +++ b/liboverlay/overlay.cpp @@ -0,0 +1,1490 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*#define LOG_NDEBUG 0*/ +#define LOG_TAG "SEC_Overlay" + +#include +#include + +extern "C" { +#include "v4l2_utils.h" +} + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "linux/fb.h" + +/*****************************************************************************/ + +#define LOG_FUNCTION_NAME LOGV(" %s %s", __FILE__, __func__) + +#define NUM_OVERLAY_BUFFERS_REQUESTED (3) +/* OVRLYSHM on phone keypad*/ +#define SHARED_DATA_MARKER (0x68759746) + +/* These values should come from Surface Flinger */ +unsigned int g_lcd_width = 480; +unsigned int g_lcd_height = 800; +unsigned int g_lcd_bpp = 32; + +#define CACHEABLE_BUFFERS 0x1 + +/* shared with Camera/Video Playback HAL */ +#define ALL_BUFFERS_FLUSHED -66 + +uint32_t phyAddr; +s5p_fimc_t g_s5p_fimc; + +typedef struct +{ + uint32_t posX; + uint32_t posY; + uint32_t posW; + uint32_t posH; + uint32_t rotation; + uint32_t flip; + + uint32_t posX_org; + uint32_t posY_org; + uint32_t posW_org; + uint32_t posH_org; + +} overlay_ctrl_t; + +typedef struct +{ + uint32_t cropX; + uint32_t cropY; + uint32_t cropW; + uint32_t cropH; +} overlay_data_t; + +typedef struct +{ + uint32_t marker; + uint32_t size; + + volatile int32_t refCnt; + + uint32_t controlReady; /* Only updated by the control side */ + uint32_t dataReady; /* Only updated by the data side */ + + pthread_mutex_t lock; + pthread_mutexattr_t attr; + + uint32_t streamEn; + uint32_t streamingReset; + + uint32_t dispW; + uint32_t dispH; + +} overlay_shared_t; + +/* Only one instance is created per platform */ +struct overlay_control_context_t { + struct overlay_control_device_t device; + /* our private state goes below here */ + struct overlay_t* overlay_video1; + struct overlay_t* overlay_video2; +}; + +/* A separate instance is created per overlay data side user*/ +struct overlay_data_context_t { + struct overlay_data_device_t device; + /* our private state goes below here */ + int ctl_fd; + int shared_fd; + int shared_size; + int width; + int height; + int format; + int num_buffers; + size_t *buffers_len; + void **buffers; + + overlay_data_t data; + overlay_shared_t *shared; + struct mapping_data *mapping_data; + /* Need to count Qd buffers + to be sure we don't block DQ'ing when exiting */ + int qd_buf_count; + int cacheable_buffers; + + bool zerocopy; +}; + +static int create_shared_data(overlay_shared_t **shared); +static void destroy_shared_data(int shared_fd, overlay_shared_t *shared, + bool closefd); +static int open_shared_data(overlay_data_context_t *ctx); +static void close_shared_data(overlay_data_context_t *ctx); +enum { LOCK_REQUIRED = 1, NO_LOCK_NEEDED = 0 }; +static int enable_streaming(overlay_shared_t *shared, int ovly_fd, + int lock_required ); + +static int overlay_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device); + +static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc, + unsigned int rotation); +static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc); + +static struct hw_module_methods_t overlay_module_methods = { +open: overlay_device_open +}; + +struct overlay_module_t HAL_MODULE_INFO_SYM = { +common: { +tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: OVERLAY_HARDWARE_MODULE_ID, + name: "SEC Overlay module", + author: "The Android Open Source Project", + methods: &overlay_module_methods, + } +}; + +/*****************************************************************************/ + +/* + * This is the overlay_t object, it is returned to the user and represents + * an overlay. here we use a subclass, where we can store our own state. + * This handles will be passed across processes and possibly given to other + * HAL modules (for instance video decode modules). + */ +struct handle_t : public native_handle { + /* add the data fields we need here, for instance: */ + int ctl_fd; + int shared_fd; + int width; + int height; + int format; + int num_buffers; + int shared_size; +}; + +static int handle_format(const overlay_handle_t overlay) { + return static_cast(overlay)->format; +} + +static int handle_ctl_fd(const overlay_handle_t overlay) { + return static_cast(overlay)->ctl_fd; +} + +static int handle_shared_fd(const overlay_handle_t overlay) { + return static_cast(overlay)->shared_fd; +} + +static int handle_num_buffers(const overlay_handle_t overlay) { + return static_cast(overlay)->num_buffers; +} + +static int handle_width(const overlay_handle_t overlay) { + return static_cast(overlay)->width; +} + +static int handle_height(const overlay_handle_t overlay) { + return static_cast(overlay)->height; +} + +static int handle_shared_size(const overlay_handle_t overlay) { + return static_cast(overlay)->shared_size; +} + +/* A separate instance of this class is created per overlay */ +class overlay_object : public overlay_t +{ + handle_t mHandle; + + overlay_ctrl_t mCtl; + overlay_ctrl_t mCtlStage; + overlay_shared_t *mShared; + + static overlay_handle_t getHandleRef(struct overlay_t* overlay) { + /* returns a reference to the handle, caller doesn't take ownership */ + return &(static_cast(overlay)->mHandle); + } + + public: + overlay_object(int ctl_fd, int shared_fd, int shared_size, int w, int h, + int format, int num_buffers) { + this->overlay_t::getHandleRef = getHandleRef; + mHandle.version = sizeof(native_handle); + mHandle.numFds = 2; + mHandle.numInts = 5; /* extra ints we have in our handle */ + mHandle.ctl_fd = ctl_fd; + mHandle.shared_fd = shared_fd; + mHandle.width = w; + mHandle.height = h; + mHandle.format = format; + mHandle.num_buffers = num_buffers; + mHandle.shared_size = shared_size; + this->w = w; + this->h = h; + this->format = format; + + memset( &mCtl, 0, sizeof( mCtl ) ); + memset( &mCtlStage, 0, sizeof( mCtlStage ) ); + } + + int ctl_fd() { return mHandle.ctl_fd; } + int shared_fd() { return mHandle.shared_fd; } + overlay_ctrl_t* data() { return &mCtl; } + overlay_ctrl_t* staging() { return &mCtlStage; } + overlay_shared_t* getShared() { return mShared; } + void setShared( overlay_shared_t *p ) { mShared = p; } +}; + +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +static int create_shared_data(overlay_shared_t **shared) +{ + int fd; + /* assuming sizeof(overlay_shared_t) < a single page */ + int size = getpagesize(); + overlay_shared_t *p; + + if ((fd = ashmem_create_region("overlay_data", size)) < 0) { + LOGE("Failed to Create Overlay Shared Data!\n"); + return fd; + } + + p = (overlay_shared_t*)mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) { + LOGE("Failed to Map Overlay Shared Data!\n"); + close(fd); + return -1; + } + + memset(p, 0, size); + p->marker = SHARED_DATA_MARKER; + p->size = size; + p->refCnt = 1; + if (pthread_mutexattr_init(&p->attr) != 0) { + LOGE("Failed to initialize overlay mutex attr"); + goto MutexAttrErr; + } + if (pthread_mutexattr_setpshared(&p->attr, PTHREAD_PROCESS_SHARED) != 0) { + LOGE("Failed to set the overlay mutex attr to be shared across-processes"); + goto MutexAttrSetErr; + } + if (pthread_mutex_init(&p->lock, &p->attr) != 0) { + LOGE("Failed to initialize overlay mutex\n"); + goto MutexErr; + } + + *shared = p; + return fd; + +MutexErr: +MutexAttrSetErr: + pthread_mutexattr_destroy(&p->attr); +MutexAttrErr: + munmap(p, size); + close(fd); + return -1; +} + +static void destroy_shared_data(int shared_fd, overlay_shared_t *shared, + bool closefd ) +{ + if (shared == NULL) + return; + + /* Last side deallocated releases the mutex, otherwise the remaining */ + /* side will deadlock trying to use an already released mutex */ + if (android_atomic_dec(&shared->refCnt) == 1) { + if (pthread_mutex_destroy(&shared->lock)) { + LOGE("Failed to uninitialize overlay mutex!\n"); + } + + if (pthread_mutexattr_destroy(&shared->attr)) { + LOGE("Failed to uninitialize the overlay mutex attr!\n"); + } + shared->marker = 0; + } + + if (munmap(shared, shared->size)) { + LOGE("Failed to Unmap Overlay Shared Data!\n"); + } + + if (closefd && close(shared_fd)) { + LOGE("Failed to Close Overlay Shared Data!\n"); + } +} + +static int open_shared_data( overlay_data_context_t *ctx ) +{ + int rc = -1; + int mode = PROT_READ | PROT_WRITE; + int fd = ctx->shared_fd; + int size = ctx->shared_size; + + if (ctx->shared != NULL) { + /* Already open, return success */ + LOGI("Overlay Shared Data Already Open\n"); + return 0; + } + ctx->shared = (overlay_shared_t*)mmap(0, size, mode, MAP_SHARED, fd, 0); + + if (ctx->shared == MAP_FAILED) { + LOGE("Failed to Map Overlay Shared Data!\n"); + } else if ( ctx->shared->marker != SHARED_DATA_MARKER ) { + LOGE("Invalid Overlay Shared Marker!\n"); + munmap( ctx->shared, size); + } else if ( (int)ctx->shared->size != size ) { + LOGE("Invalid Overlay Shared Size!\n"); + munmap(ctx->shared, size); + } else { + android_atomic_inc(&ctx->shared->refCnt); + rc = 0; + } + + return rc; +} + +static void close_shared_data(overlay_data_context_t *ctx) +{ + destroy_shared_data(ctx->shared_fd, ctx->shared, false); + ctx->shared = NULL; +} + +static int enable_streaming_locked(overlay_shared_t *shared, int ovly_fd) +{ + int rc = 0; + + if (!shared->controlReady || !shared->dataReady) { + LOGI("Postponing Stream Enable/%d/%d\n", shared->controlReady, + shared->dataReady); + } else { + shared->streamEn = 1; + rc = v4l2_overlay_stream_on(ovly_fd); + if (rc) { + LOGE("Stream Enable Failed!/%d\n", rc); + shared->streamEn = 0; + } + } + + return rc; +} + +static int enable_streaming(overlay_shared_t *shared, int ovly_fd) +{ + int ret; + + pthread_mutex_lock(&shared->lock); + ret = enable_streaming_locked(shared, ovly_fd); + pthread_mutex_unlock(&shared->lock); + return ret; +} + +static int disable_streaming_locked(overlay_shared_t *shared, int ovly_fd) +{ + int ret = 0; + + if (shared->streamEn) { + ret = v4l2_overlay_stream_off( ovly_fd ); + if (ret) { + LOGE("Stream Off Failed!/%d\n", ret); + } else { + shared->streamingReset = 1; + shared->streamEn = 0; + } + } + + return ret; +} + +static void set_color_space(unsigned int overlay_color_format, unsigned int *v4l2_color_format) +{ + switch (overlay_color_format) { + case OVERLAY_FORMAT_RGB_565: + *v4l2_color_format = V4L2_PIX_FMT_RGB565; + break; + + case OVERLAY_FORMAT_YCbYCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + *v4l2_color_format = V4L2_PIX_FMT_YUYV; + break; + + case OVERLAY_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + *v4l2_color_format = V4L2_PIX_FMT_UYVY; + break; + + case HAL_PIXEL_FORMAT_YCbCr_420_P: + *v4l2_color_format = V4L2_PIX_FMT_YUV420; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + *v4l2_color_format = V4L2_PIX_FMT_NV12T; + break; + + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + *v4l2_color_format = V4L2_PIX_FMT_NV21; + break; + + default : + LOGE("unsupported pixel format (0x%x)", overlay_color_format); + *v4l2_color_format = -1; + } +} + +/**************************************************************************** + * Control module + *****************************************************************************/ + +static int overlay_get(struct overlay_control_device_t *dev, int name) +{ + int result = -1; + + switch (name) { + /* 0 = no limit */ + case OVERLAY_MINIFICATION_LIMIT: result = 0; break; + /* 0 = no limit */ + case OVERLAY_MAGNIFICATION_LIMIT: result = 0; break; + /* 0 = infinite */ + case OVERLAY_SCALING_FRAC_BITS: result = 0; break; + /* 90 rotation steps (for instance) */ + case OVERLAY_ROTATION_STEP_DEG: result = 90; break; + /* 1-pixel alignment */ + case OVERLAY_HORIZONTAL_ALIGNMENT: result = 1; break; + /* 1-pixel alignment */ + case OVERLAY_VERTICAL_ALIGNMENT: result = 1; break; + /* 1-pixel alignment */ + case OVERLAY_WIDTH_ALIGNMENT: result = 1; break; + case OVERLAY_HEIGHT_ALIGNMENT: break; + } + + return result; +} + +static int get_fb_var_screeninfo( struct fb_var_screeninfo *info ) +{ + int fd = -1; + int i=0; + char name[64]; + int ret = 0; + + char const * const device_template[] = { + "/dev/graphics/fb%u", + "/dev/fb%u", + 0 }; + + while ((fd==-1) && device_template[i]) { + snprintf(name, 64, device_template[i], 0); + fd = open(name, O_RDWR, 0); + i++; + } + + if (fd < 0) + ret = -EINVAL; + + if (ioctl(fd, FBIOGET_VSCREENINFO, info) == -1) + ret = -EINVAL; + + if (fd > 0) + close(fd); + + return 0; +} +static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev, + uint32_t w, uint32_t h, int32_t format) +{ + LOGD("overlay_createOverlay:IN w=%d h=%d format=%d\n", w, h, format); + LOG_FUNCTION_NAME; + + overlay_object *overlay; + overlay_control_context_t *ctx = (overlay_control_context_t *)dev; + overlay_shared_t *shared; + + int ret; + uint32_t num = NUM_OVERLAY_BUFFERS_REQUESTED; + int fd; + int shared_fd; + struct fb_var_screeninfo info; + bool zerocopy = false; + + phyAddr = 0; + + if (format == OVERLAY_FORMAT_DEFAULT) { + LOGD("format == OVERLAY_FORMAT_DEFAULT\n"); + LOGD("set to HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP\n"); + format = HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP; + } + + if (ctx->overlay_video1) { + LOGE("Error - overlays already in use\n"); + return NULL; + } + + shared_fd = create_shared_data(&shared); + if (shared_fd < 0) { + LOGE("Failed to create shared data"); + return NULL; + } + + fd = v4l2_overlay_open(V4L2_OVERLAY_PLANE_VIDEO1); + if (fd < 0) { + LOGE("Failed to open overlay device : %s\n", strerror(errno)); + goto error; + } + + g_s5p_fimc.params.src.full_width = w; + g_s5p_fimc.params.src.full_height = h; + g_s5p_fimc.params.src.width = w; + g_s5p_fimc.params.src.height = h; + set_color_space(format, &g_s5p_fimc.params.src.color_space); + ret = check_fimc_src_constraints(&g_s5p_fimc); + if(ret != 0) { + if(ret < 0) { + LOGE("Not supported source image size"); + goto error1; + } else { + LOGD("src width, height are changed [w= %d, h= %d]->[w=%d, h= %d]" + , w, h, g_s5p_fimc.params.src.width + , g_s5p_fimc.params.src.height); + w = g_s5p_fimc.params.src.width; + h = g_s5p_fimc.params.src.height; + } + } + + if (v4l2_overlay_init(fd, w, h, format, phyAddr)) { + LOGE("Failed initializing overlays\n"); + goto error1; + } + + if (v4l2_overlay_set_crop(fd, 0, 0, w, h)) { + LOGE("Failed defaulting crop window\n"); + goto error1; + } + + if (v4l2_overlay_set_flip(fd, 0)) { + LOGE("Failed defaulting flip\n"); + goto error1; + } + + if (v4l2_overlay_set_rotation(fd, 0, 0)) { + LOGE("Failed defaulting rotation\n"); + goto error1; + } + + if (format >= HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP + && format < HAL_PIXEL_FORMAT_CUSTOM_MAX) + zerocopy = true; + + if (v4l2_overlay_req_buf(fd, &num, 0, (int)zerocopy)) { + LOGE("Failed requesting buffers\n"); + goto error1; + } + + v4l2_overlay_init_fimc(fd, &g_s5p_fimc); + + overlay = new overlay_object(fd, shared_fd, shared->size, + w, h, format, num); + if (overlay == NULL) { + LOGE("Failed to create overlay object\n"); + goto error1; + } + ctx->overlay_video1 = overlay; + + overlay->setShared(shared); + + shared->controlReady = 0; + shared->streamEn = 0; + shared->streamingReset = 0; + + /* get lcd size from kernel framebuffer */ + if(get_fb_var_screeninfo(&info) == 0) { + shared->dispW = info.xres; + shared->dispH = info.yres; + g_lcd_width = info.xres; + g_lcd_height = info.yres; + g_lcd_bpp = info.bits_per_pixel; + } else { + shared->dispW = g_lcd_width; /* Need to determine this properly */ + shared->dispH = g_lcd_height; /* Need to determine this properly */ + } + + LOGI("Opened video1/fd=%d/obj=%08lx/shm=%d/size=%d", fd, + (unsigned long)overlay, shared_fd, shared->size); + + return overlay; + +error1: + close(fd); +error: + destroy_shared_data(shared_fd, shared, true); + return NULL; +} + +static void overlay_destroyOverlay(struct overlay_control_device_t *dev, + overlay_t* overlay) +{ + LOGD("overlay_destroyOverlay:IN dev (%p) and overlay (%p)", dev, overlay); + LOG_FUNCTION_NAME; + + overlay_control_context_t *ctx = (overlay_control_context_t *)dev; + overlay_object *obj = static_cast(overlay); + + int rc; + int fd = obj->ctl_fd(); + uint32_t num = 0; + + overlay_shared_t *shared = obj->getShared(); + + if (shared == NULL) { + LOGE("Overlay was already destroyed - nothing needs to be done\n"); + return; + } + + pthread_mutex_lock(&shared->lock); + + disable_streaming_locked(shared, fd); + + pthread_mutex_unlock(&shared->lock); + + destroy_shared_data(obj->shared_fd(), shared, true); + obj->setShared(NULL); + + if (v4l2_overlay_req_buf(fd, &num, 0, 0)) { + LOGE("Failed requesting buffers\n"); + } + + LOGI("Destroying overlay/fd=%d/obj=%08lx", fd, (unsigned long)overlay); + + if (close(fd)) { + LOGE( "Error closing overly fd/%d\n", errno); + } + + if (overlay) { + if (ctx->overlay_video1 == overlay) + ctx->overlay_video1 = NULL; + delete overlay; + overlay = NULL; + } + LOGD("overlay_destroyOverlay:OUT"); +} + +static int overlay_setPosition(struct overlay_control_device_t *dev, + overlay_t* overlay, int x, int y, uint32_t w, + uint32_t h) +{ + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast(overlay); + + overlay_ctrl_t *stage = obj->staging(); + overlay_shared_t *shared = obj->getShared(); + + int rc = 0; + int temp_x = x, temp_y = y, temp_w = w, temp_h = h; + + /* + * This logic here is to return an error if the rectangle is not fully + * within the display, unless we have not received a valid position yet, + * in which case we will do our best to adjust the rectangle to be within + * the display. + */ + + /* Require a minimum size */ + if (temp_w < 16) + temp_w = 16; + if (temp_h < 8) + temp_h = 8; + + if (!shared->controlReady) { + if ( temp_x < 0 ) temp_x = 0; + if ( temp_y < 0 ) temp_y = 0; + if ( temp_w > shared->dispW ) temp_w = shared->dispW; + if ( temp_h > shared->dispH ) temp_h = shared->dispH; + if ( (temp_x + temp_w) > shared->dispW ) temp_w = shared->dispW - temp_x; + if ( (temp_y + temp_h) > shared->dispH ) temp_h = shared->dispH - temp_y; + } else if (temp_x < 0 || temp_y < 0 || (temp_x + temp_w) > shared->dispW || + (temp_y + temp_h) > shared->dispH) { + /* Return an error */ + rc = -1; + } + + if (rc == 0) { + stage->posX = temp_x; + stage->posY = temp_y; + stage->posW = temp_w; + stage->posH = temp_h; + + stage->posX_org = x; + stage->posY_org = y; + stage->posW_org = w; + stage->posH_org = h; + } + + return rc; +} + +static int overlay_getPosition(struct overlay_control_device_t *dev, + overlay_t* overlay, int* x, int* y, uint32_t* w, + uint32_t* h) +{ + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast(overlay); + overlay_ctrl_t *stage = obj->staging(); + + *x = stage->posX_org; + *y = stage->posY_org; + *w = stage->posW_org; + *h = stage->posH_org; + + return 0; +} + +static int overlay_setParameter(struct overlay_control_device_t *dev, + overlay_t* overlay, int param, int value) +{ + LOG_FUNCTION_NAME; + + overlay_ctrl_t *stage = static_cast(overlay)->staging(); + int rc = 0; + + switch (param) { + case OVERLAY_DITHER: + break; + + case OVERLAY_TRANSFORM: + switch ( value ) + { + case 0: + stage->rotation = 0; + stage->flip = 0; + break; + case OVERLAY_TRANSFORM_ROT_90: + stage->rotation = 90; + stage->flip = 0; + break; + case OVERLAY_TRANSFORM_ROT_180: + stage->rotation = 180; + stage->flip = 0; + break; + case OVERLAY_TRANSFORM_ROT_270: + stage->rotation = 270; + stage->flip = 0; + break; + // FIMC VFLIP = android overlay FLIP_H. + case OVERLAY_TRANSFORM_FLIP_H: + stage->rotation = 0; + stage->flip = V4L2_CID_VFLIP; + break; + case OVERLAY_TRANSFORM_FLIP_V: + stage->rotation = 0; + stage->flip = V4L2_CID_HFLIP; + break; + // FIMC rotates first but android flips first. + case OVERLAY_TRANSFORM_ROT_90+OVERLAY_TRANSFORM_FLIP_H: + stage->rotation = 90; + stage->flip = V4L2_CID_HFLIP; + break; + case OVERLAY_TRANSFORM_ROT_90+OVERLAY_TRANSFORM_FLIP_V: + stage->rotation = 90; + stage->flip = V4L2_CID_VFLIP; + break; + + default: + rc = -EINVAL; + break; + } + break; + } + + return rc; +} + +static int overlay_stage(struct overlay_control_device_t *dev, + overlay_t* overlay) { + return 0; +} + +static int overlay_commit(struct overlay_control_device_t *dev, + overlay_t* overlay) { + LOG_FUNCTION_NAME; + + overlay_object *obj = static_cast(overlay); + + overlay_ctrl_t *data = obj->data(); + overlay_ctrl_t *stage = obj->staging(); + overlay_shared_t *shared = obj->getShared(); + + int ret = 0; + int fd = obj->ctl_fd(); + + if (shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + pthread_mutex_lock(&shared->lock); + + if (!shared->controlReady) { + shared->controlReady = 1; + } + + g_s5p_fimc.params.dst.full_width = g_lcd_width; + g_s5p_fimc.params.dst.full_height = g_lcd_height; + g_s5p_fimc.params.dst.width = stage->posW; + g_s5p_fimc.params.dst.height = stage->posH; + if (g_lcd_bpp == 32) + g_s5p_fimc.params.dst.color_space = V4L2_PIX_FMT_RGB32; + else + g_s5p_fimc.params.dst.color_space = V4L2_PIX_FMT_RGB565; + ret = check_fimc_dst_constraints(&g_s5p_fimc, stage->rotation); + if (ret != 0) { + if (ret < 0) { + LOGE("Unsupported destination image size"); + goto end; + } else { + LOGD("dst width, height have changed [w= %d, h= %d] -> [w=%d, h= %d]", + stage->posW, stage->posH, g_s5p_fimc.params.dst.width, + g_s5p_fimc.params.dst.height); + stage->posW = g_s5p_fimc.params.dst.width; + stage->posH = g_s5p_fimc.params.dst.height; + } + } + + if (data->posX == stage->posX && data->posY == stage->posY && + data->posW == stage->posW && data->posH == stage->posH && + data->rotation == stage->rotation && + data->flip == stage->flip) { + LOGI("Nothing to do!\n"); + goto end; + } + + LOGD("Position/X%d/Y%d/W%d/H%d\n", data->posX, data->posY, data->posW, + data->posH); + LOGD("Adjusted Position/X%d/Y%d/W%d/H%d\n", stage->posX, stage->posY, + stage->posW, stage->posH); + LOGD("Rotation/%d\n", stage->rotation ); + + if ((ret = disable_streaming_locked(shared, fd))) + goto end; + + if (stage->flip != data->flip) { + ret = v4l2_overlay_set_flip(fd, stage->flip); + if (ret) { + LOGE("Set Flip Failed!/%d\n", ret); + goto end; + } + } + + if (stage->rotation != data->rotation) { + ret = v4l2_overlay_set_rotation(fd, stage->rotation, 0); + if (ret) { + LOGE("Set Rotation Failed!/%d\n", ret); + goto end; + } + v4l2_overlay_s_fbuf(fd, stage->rotation); + } + + ret = v4l2_overlay_set_position(fd, stage->posX, stage->posY, + stage->posW, stage->posH, stage->rotation); + if (ret) { + LOGE("Set Position Failed!/%d\n", ret); + goto end; + } + + data->posX = stage->posX; + data->posY = stage->posY; + data->posW = stage->posW; + data->posH = stage->posH; + data->rotation = stage->rotation; + data->flip = stage->flip; + + ret = enable_streaming_locked(shared, fd); + +end: + pthread_mutex_unlock(&shared->lock); + + return ret; +} + +static int overlay_control_close(struct hw_device_t *dev) +{ + LOG_FUNCTION_NAME; + + struct overlay_control_context_t* ctx = + (struct overlay_control_context_t*)dev; + overlay_object *overlay_v1; + + if (ctx) { + overlay_v1 = static_cast(ctx->overlay_video1); + + overlay_destroyOverlay((struct overlay_control_device_t *)ctx, + overlay_v1); + + free(ctx); + } + return 0; +} + +static int get_pixel_format_type(unsigned int pixelformat) +{ + switch(pixelformat) { + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_RGB565: + return PFT_RGB; + + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_YUV420: + return PFT_YUV420; + + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_YUV422P: + return PFT_YUV422; + + default: + return PFT_YUV444; + } +} + +/* check the constraints of destination image size */ +static int check_fimc_dst_constraints(s5p_fimc_t *s5p_fimc, + unsigned int rotation) +{ + int tmp = 0; + + if((s5p_fimc->params.dst.height > 0) && (s5p_fimc->params.dst.height < 16)) + s5p_fimc->params.dst.height = 16; + + if(s5p_fimc->params.dst.width%8 != 0) { + tmp = s5p_fimc->params.dst.width - (s5p_fimc->params.dst.width%8); + if(tmp <= 0) + return -1; + else + s5p_fimc->params.dst.width = tmp; + } + + return 1; +} +/* check the constraints of source image size */ +static int check_fimc_src_constraints(s5p_fimc_t *s5p_fimc) +{ + int format_type = 0; + + if(s5p_fimc->params.src.full_width < 16 || + s5p_fimc->params.src.full_height < 8 ) + return -1; + + if(s5p_fimc->hw_ver == 0x50) { + format_type = get_pixel_format_type(s5p_fimc->params.src.color_space); + switch (format_type) { + case PFT_YUV420: + if (s5p_fimc->params.src.height%2 != 0) + s5p_fimc->params.src.height = s5p_fimc->params.src.height + - (s5p_fimc->params.src.height)%2; + + if (s5p_fimc->params.src.width%2 != 0) + s5p_fimc->params.src.width = s5p_fimc->params.src.width + - (s5p_fimc->params.src.width)%2; + break; + + case PFT_YUV422: + if (s5p_fimc->params.src.width%2 != 0) + s5p_fimc->params.src.width = s5p_fimc->params.src.width + - (s5p_fimc->params.src.width)%2; + } + } else { + if (s5p_fimc->params.src.height < 8) { + s5p_fimc->params.src.height = 8; + } + + if (s5p_fimc->params.src.width%16 != 0) { + s5p_fimc->params.src.width = s5p_fimc->params.src.width + - (s5p_fimc->params.src.width)%16; + } + } + + return 1; +} + +/**************************************************************************** + * Data module + *****************************************************************************/ + +int overlay_initialize(struct overlay_data_device_t *dev, + overlay_handle_t handle) +{ + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + struct stat stat; + + int i; + int rc = -1; + + ctx->num_buffers = handle_num_buffers(handle); + ctx->width = handle_width(handle); + ctx->height = handle_height(handle); + ctx->format = handle_format(handle); + ctx->ctl_fd = handle_ctl_fd(handle); + ctx->shared_fd = handle_shared_fd(handle); + ctx->shared_size = handle_shared_size(handle); + ctx->shared = NULL; + ctx->qd_buf_count = 0; + ctx->cacheable_buffers = 0; + + if (ctx->format >= HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP + && ctx->format < HAL_PIXEL_FORMAT_CUSTOM_MAX) + ctx->zerocopy = true; + else + ctx->zerocopy = false; + + if (fstat(ctx->ctl_fd, &stat)) { + LOGE("Error = %s from %s\n", strerror(errno), "overlay initialize"); + return -1; + } + + if (open_shared_data(ctx)) { + return -1; + } + + ctx->shared->dataReady = 0; + + ctx->mapping_data = new struct mapping_data; + ctx->buffers = new void* [ctx->num_buffers]; + ctx->buffers_len = new size_t[ctx->num_buffers]; + + if (!ctx->buffers || !ctx->buffers_len || !ctx->mapping_data) { + LOGE("Failed alloc'ing buffer arrays\n"); + goto error; + } else { + + /* + * in the zero copy case, + * don't need to mmap buffer for source + */ + if (ctx->zerocopy) + rc = 0; + else { + for (i = 0; i < ctx->num_buffers; i++) { + rc = v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i], + &ctx->buffers_len[i]); + if (rc) { + LOGE("Failed mapping buffers\n"); + goto error; + } + } + } + } + + v4l2_overlay_init_fimc(ctx->ctl_fd, &g_s5p_fimc); + + return ( rc ); + +error: + + if(ctx->mapping_data) + delete (ctx->mapping_data); + if(ctx->buffers) + delete [] ctx->buffers; + if(ctx->buffers_len) + delete [] ctx->buffers_len; + + close_shared_data( ctx ); + + return -1; +} + +static int overlay_resizeInput(struct overlay_data_device_t *dev, uint32_t w, + uint32_t h) +{ + int rc = -1; + int ret = 0; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if ((ctx->width == (int)w) && (ctx->width == (int)h)) { + LOGV("same as current width and height. so do nothing"); + return 0; + } + + if (!ctx->shared) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + if (ctx->shared->dataReady) { + LOGV("Either setCrop() or queueBuffer() was called prior to this!" + "Therefore failing this call.\n"); + return -1; + } + + pthread_mutex_lock(&ctx->shared->lock); + + if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd))) + goto end; + + if (!ctx->zerocopy) { + for (int i = 0; i < ctx->num_buffers; i++) { + v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]); + } + } + + g_s5p_fimc.params.src.full_width = w; + g_s5p_fimc.params.src.full_height = h; + g_s5p_fimc.params.src.width = w; + g_s5p_fimc.params.src.height = h; + set_color_space(ctx->format, &g_s5p_fimc.params.src.color_space); + ret = check_fimc_src_constraints(&g_s5p_fimc); + + if(ret != 0) { + if(ret < 0) { + LOGE("Not supported source image size"); + goto end; + } else { + LOGD("src width, height are changed [w= %d, h= %d] -> [w=%d, h= %d]" + , w, h, g_s5p_fimc.params.src.width + , g_s5p_fimc.params.src.height); + w = g_s5p_fimc.params.src.width; + h = g_s5p_fimc.params.src.height; + } + } + + rc = v4l2_overlay_init(ctx->ctl_fd, w, h, ctx->format, phyAddr); + if (rc) { + LOGE("Error initializing overlay"); + goto end; + } + rc = v4l2_overlay_set_crop(ctx->ctl_fd, 0, 0, w, h); + if (rc) { + LOGE("Error setting crop window\n"); + goto end; + } + rc = v4l2_overlay_req_buf(ctx->ctl_fd, (uint32_t *)(&ctx->num_buffers), + ctx->cacheable_buffers, (int)ctx->zerocopy); + if (rc) { + LOGE("Error creating buffers"); + goto end; + } + + if (!ctx->zerocopy) { + for (int i = 0; i < ctx->num_buffers; i++) + v4l2_overlay_map_buf(ctx->ctl_fd, i, &ctx->buffers[i], + &ctx->buffers_len[i]); + } + + rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd); + +end: + pthread_mutex_unlock(&ctx->shared->lock); + + return rc; +} + + +static int overlay_data_setParameter(struct overlay_data_device_t *dev, + int param, int value) +{ + int ret = 0; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if (ctx->shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + if (ctx->shared->dataReady) { + LOGI("Too late. Cant set it now!\n"); + return -1; + } + + if (param == CACHEABLE_BUFFERS) + ctx->cacheable_buffers = value; + + return ( ret ); +} + + +static int overlay_setCrop(struct overlay_data_device_t *dev, uint32_t x, + uint32_t y, uint32_t w, uint32_t h) { + LOG_FUNCTION_NAME; + + int rc = 0; + int cnt = 0; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if (ctx->shared == NULL) { + LOGI("Shared Data Not Init'd!\n"); + return -1; + } + + pthread_mutex_lock(&ctx->shared->lock); + + ctx->shared->dataReady = 1; + + if (ctx->data.cropX == x && ctx->data.cropY == y && ctx->data.cropW == w + && ctx->data.cropH == h) { + goto end; + } + + ctx->data.cropX = x; + ctx->data.cropY = y; + ctx->data.cropW = w; + ctx->data.cropH = h; + + LOGD("Crop Win/X%d/Y%d/W%d/H%d\n", x, y, w, h ); + + if ((rc = disable_streaming_locked(ctx->shared, ctx->ctl_fd))) + goto end; + + rc = v4l2_overlay_set_crop(ctx->ctl_fd, x, y, w, h); + if (rc) { + LOGE("Set Crop Window Failed!/%d\n", rc); + } + + rc = enable_streaming_locked(ctx->shared, ctx->ctl_fd); + +end: + pthread_mutex_unlock(&ctx->shared->lock); + return rc; +} + +static int overlay_getCrop(struct overlay_data_device_t *dev , uint32_t* x, + uint32_t* y, uint32_t* w, uint32_t* h) { + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + return v4l2_overlay_get_crop(ctx->ctl_fd, x, y, w, h); +} + +int overlay_dequeueBuffer(struct overlay_data_device_t *dev, + overlay_buffer_t *buffer) { + /* blocks until a buffer is available and return an opaque structure + * representing this buffer. + */ + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + int rc=0; + int i = -1; + uint32_t num = 0; + int cnt = 0; + + pthread_mutex_lock(&ctx->shared->lock); + if ( ctx->shared->streamingReset ) { + ctx->shared->streamingReset = 0; + pthread_mutex_unlock(&ctx->shared->lock); + return ALL_BUFFERS_FLUSHED; + } + pthread_mutex_unlock(&ctx->shared->lock); + + /* If we are not streaming dequeue will fail, + skip to prevent error printouts */ + if (ctx->shared->streamEn && ctx->qd_buf_count) { + if ((rc = v4l2_overlay_dq_buf( ctx->ctl_fd, &i ,ctx->zerocopy)) != 0) { + LOGE("Failed to DQ/%d\n", rc); + } + else if (i < 0 || i > ctx->num_buffers) { + rc = -EINVAL; + } else { + *((int *)buffer) = i; + ctx->qd_buf_count --; + } + } else { + rc = -1; + } + + return rc; +} + +int overlay_queueBuffer(struct overlay_data_device_t *dev, + overlay_buffer_t buffer) { + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + int cnt = 0; + + pthread_mutex_lock(&ctx->shared->lock); + if ( ctx->shared->streamingReset ) { + ctx->shared->streamingReset = 0; + pthread_mutex_unlock(&ctx->shared->lock); + return ALL_BUFFERS_FLUSHED; + } + pthread_mutex_unlock(&ctx->shared->lock); + + /* Catch the case where the data side had no need to set the crop window */ + if (!ctx->shared->dataReady) { + ctx->shared->dataReady = 1; + enable_streaming(ctx->shared, ctx->ctl_fd); + } + + if (!ctx->shared->controlReady) return -1; + int rc = v4l2_overlay_q_buf( ctx->ctl_fd, (int)buffer, (int) ctx->zerocopy ); + if (rc == 0 && ctx->qd_buf_count < ctx->num_buffers) { + ctx->qd_buf_count ++; + } + + return rc; +} + +void *overlay_getBufferAddress(struct overlay_data_device_t *dev, + overlay_buffer_t buffer) +{ + LOG_FUNCTION_NAME; + + /* this may fail (NULL) if this feature is not supported. In that case, + * presumably, there is some other HAL module that can fill the buffer, + * using a DSP for instance + */ + int ret; + struct v4l2_buffer buf; + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + if (ctx->zerocopy) + return NULL; + + if ((int)buffer >= 0 && (int)buffer < ctx->num_buffers) + return (void*) ctx->buffers[(int)buffer]; + else + return NULL; +} + +int overlay_getBufferCount(struct overlay_data_device_t *dev) +{ + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + + return (ctx->num_buffers); +} + +static int overlay_data_close(struct hw_device_t *dev) { + + LOG_FUNCTION_NAME; + + struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev; + int rc; + + if (ctx) { + overlay_data_device_t *overlay_dev = &ctx->device; + int buf; + int i; + + pthread_mutex_lock(&ctx->shared->lock); + + if (!ctx->zerocopy) + for (i = 0; i < ctx->num_buffers; i++) { + LOGV("Unmap Buffer/%d/%08lx/%d", i, (unsigned long)ctx->buffers[i], + ctx->buffers_len[i] ); + rc = v4l2_overlay_unmap_buf(ctx->buffers[i], ctx->buffers_len[i]); + if (rc != 0) { + LOGE("Error unmapping the buffer/%d/%d", i, rc); + } + } + + delete (ctx->mapping_data); + delete [] ctx->buffers; + delete [] ctx->buffers_len; + + pthread_mutex_unlock(&ctx->shared->lock); + + ctx->shared->dataReady = 0; + close_shared_data( ctx ); + + free(ctx); + } + + return 0; +} + +/*****************************************************************************/ + +static int overlay_device_open(const struct hw_module_t* module, + const char* name, struct hw_device_t** device) +{ + LOG_FUNCTION_NAME; + int status = -EINVAL; + + if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) { + struct overlay_control_context_t *dev; + dev = (overlay_control_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = overlay_control_close; + + dev->device.get = overlay_get; + dev->device.createOverlay = overlay_createOverlay; + dev->device.destroyOverlay = overlay_destroyOverlay; + dev->device.setPosition = overlay_setPosition; + dev->device.getPosition = overlay_getPosition; + dev->device.setParameter = overlay_setParameter; + dev->device.stage = overlay_stage; + dev->device.commit = overlay_commit; + + *device = &dev->device.common; + status = 0; + } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) { + struct overlay_data_context_t *dev; + dev = (overlay_data_context_t*)malloc(sizeof(*dev)); + + /* initialize our state here */ + memset(dev, 0, sizeof(*dev)); + + /* initialize the procs */ + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast(module); + dev->device.common.close = overlay_data_close; + + dev->device.initialize = overlay_initialize; + dev->device.resizeInput = overlay_resizeInput; + dev->device.setCrop = overlay_setCrop; + dev->device.getCrop = overlay_getCrop; + dev->device.setParameter = overlay_data_setParameter; + dev->device.dequeueBuffer = overlay_dequeueBuffer; + dev->device.queueBuffer = overlay_queueBuffer; + dev->device.getBufferAddress = overlay_getBufferAddress; + dev->device.getBufferCount = overlay_getBufferCount; + + *device = &dev->device.common; + status = 0; + } + return status; +} diff --git a/liboverlay/v4l2_utils.c b/liboverlay/v4l2_utils.c new file mode 100644 index 0000000..f3ebbc2 --- /dev/null +++ b/liboverlay/v4l2_utils.c @@ -0,0 +1,788 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* #define OVERLAY_DEBUG 1 */ +#define LOG_TAG "v4l2_utils" + +#include +#include +#include +#include +#include +#include +#include +#include "v4l2_utils.h" + +#ifndef V4L2_DEVICE +#define V4L2_DEVICE "/dev/video1" +#endif + + + +#define LOG_FUNCTION_NAME LOGV("%s: %s", __FILE__, __func__); + +#define V4L2_CID_PRIV_OFFSET 0x0 +#define V4L2_CID_PRIV_ROTATION (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 0) +#define V4L2_CID_PRIV_COLORKEY (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 1) +#define V4L2_CID_PRIV_COLORKEY_EN (V4L2_CID_PRIVATE_BASE \ + + V4L2_CID_PRIV_OFFSET + 2) + +extern unsigned int g_lcd_width; +extern unsigned int g_lcd_height; +extern unsigned int g_lcd_bpp; + +int v4l2_overlay_get(int name) +{ + int result = -1; + switch (name) { + case OVERLAY_MINIFICATION_LIMIT: + result = 4; /* 0 = no limit */ + break; + case OVERLAY_MAGNIFICATION_LIMIT: + result = 2; /* 0 = no limit */ + break; + case OVERLAY_SCALING_FRAC_BITS: + result = 0; /* 0 = infinite */ + break; + case OVERLAY_ROTATION_STEP_DEG: + result = 90; /* 90 rotation steps (for instance) */ + break; + case OVERLAY_HORIZONTAL_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_VERTICAL_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_WIDTH_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + case OVERLAY_HEIGHT_ALIGNMENT: + result = 1; /* 1-pixel alignment */ + break; + } + return result; +} + +int v4l2_overlay_open(int id) +{ + LOG_FUNCTION_NAME + return open(V4L2_DEVICE, O_RDWR); +} + +int v4l2_overlay_init_fimc(int fd, s5p_fimc_t *s5p_fimc) +{ + int ret; + struct v4l2_control vc; + + if (fd < 0) + return -1; + + vc.id = V4L2_CID_FIMC_VERSION; + vc.value = 0; + + s5p_fimc->dev_fd = fd; + + ret = ioctl(s5p_fimc->dev_fd, VIDIOC_G_CTRL, &vc); + if (ret < 0) { + LOGE("Error in video VIDIOC_G_CTRL - V4L2_CID_FIMC_VERSION (%d)", ret); + LOGE("FIMC version is set with default"); + vc.value = 0x43; + } + s5p_fimc->hw_ver = vc.value; + return 0; +} + +void dump_pixfmt(struct v4l2_pix_format *pix) +{ + LOGV("w: %d\n", pix->width); + LOGV("h: %d\n", pix->height); + LOGV("color: %x\n", pix->colorspace); + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + LOGV("YUYV\n"); + break; + case V4L2_PIX_FMT_UYVY: + LOGV("UYVY\n"); + break; + case V4L2_PIX_FMT_RGB565: + LOGV("RGB565\n"); + break; + case V4L2_PIX_FMT_RGB565X: + LOGV("RGB565X\n"); + break; + default: + LOGV("not supported\n"); + } +} + +void dump_crop(struct v4l2_crop *crop) +{ + LOGV("crop l: %d ", crop->c.left); + LOGV("crop t: %d ", crop->c.top); + LOGV("crop w: %d ", crop->c.width); + LOGV("crop h: %d\n", crop->c.height); +} + +void dump_window(struct v4l2_window *win) +{ + LOGV("window l: %d ", win->w.left); + LOGV("window t: %d ", win->w.top); + LOGV("window w: %d ", win->w.width); + LOGV("window h: %d\n", win->w.height); +} + +void v4l2_overlay_dump_state(int fd) +{ + struct v4l2_format format; + struct v4l2_crop crop; + int ret; + + LOGV("dumping driver state:"); + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(fd, VIDIOC_G_FMT, &format); + if (ret < 0) + return; + LOGV("output pixfmt:\n"); + dump_pixfmt(&format.fmt.pix); + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = ioctl(fd, VIDIOC_G_FMT, &format); + if (ret < 0) + return; + LOGV("v4l2_overlay window:\n"); + dump_window(&format.fmt.win); + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = ioctl(fd, VIDIOC_G_CROP, &crop); + if (ret < 0) + return; + LOGV("output crop:\n"); + dump_crop(&crop); +} + +static void error(int fd, const char *msg) +{ + LOGE("Error = %s from %s", strerror(errno), msg); +#ifdef OVERLAY_DEBUG + v4l2_overlay_dump_state(fd); +#endif +} + +static int v4l2_overlay_ioctl(int fd, int req, void *arg, const char* msg) +{ + int ret; + ret = ioctl(fd, req, arg); + if (ret < 0) { + error(fd, msg); + return -1; + } + return 0; +} + +#define v4l2_fourcc(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \ + ((__u32)(c) << 16) | ((__u32)(d) << 24)) +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') + +int configure_pixfmt(struct v4l2_pix_format *pix, int32_t fmt, + uint32_t w, uint32_t h) +{ + LOG_FUNCTION_NAME + int fd; + + switch (fmt) { + case OVERLAY_FORMAT_RGBA_8888: + return -1; + case OVERLAY_FORMAT_RGB_565: + pix->pixelformat = V4L2_PIX_FMT_RGB565; + break; + case OVERLAY_FORMAT_BGRA_8888: + return -1; + case OVERLAY_FORMAT_YCbYCr_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: + pix->pixelformat = V4L2_PIX_FMT_YUYV; + break; + case OVERLAY_FORMAT_CbYCrY_422_I: + case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: + pix->pixelformat = V4L2_PIX_FMT_UYVY; + break; + case HAL_PIXEL_FORMAT_YCbCr_420_P: + pix->pixelformat = V4L2_PIX_FMT_YUV420; + break; + case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: + pix->pixelformat = V4L2_PIX_FMT_NV12T; + break; + case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: + pix->pixelformat = V4L2_PIX_FMT_NV21; + break; + default: + return -1; + } + pix->width = w; + pix->height = h; + return 0; +} + +static void configure_window(struct v4l2_window *win, int32_t w, + int32_t h, int32_t x, int32_t y) +{ + LOG_FUNCTION_NAME + + win->w.left = x; + win->w.top = y; + win->w.width = w; + win->w.height = h; +} + +void get_window(struct v4l2_format *format, int32_t *x, + int32_t *y, int32_t *w, int32_t *h) +{ + LOG_FUNCTION_NAME + + *x = format->fmt.win.w.left; + *y = format->fmt.win.w.top; + *w = format->fmt.win.w.width; + *h = format->fmt.win.w.height; +} + +int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt, + uint32_t addr) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + struct v4l2_framebuffer fbuf; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); + if (ret) + return ret; + LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, + format.fmt.pix.height); + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + configure_pixfmt(&format.fmt.pix, fmt, w, h); + LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, + format.fmt.pix.height); + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format"); + if (ret) + return ret; + + ret = v4l2_overlay_s_fbuf(fd, 0); + if (ret) + return ret; + + return ret; +} + +int v4l2_overlay_s_fbuf(int fd, int rotation) +{ + struct v4l2_framebuffer fbuf; + int ret; + + /* configure the v4l2_overlay framebuffer */ + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get fbuf"); + if (ret) + return ret; + + /* if fbuf.base value is set by 0, using local DMA. */ + fbuf.base = (void *)0; + if (rotation == 0 || rotation == 180) { + fbuf.fmt.width = g_lcd_width; + fbuf.fmt.height = g_lcd_height; + } else { + fbuf.fmt.width = g_lcd_height; + fbuf.fmt.height = g_lcd_width; + } + + if (g_lcd_bpp == 32) + fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB32; + else + fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "set fbuf"); + if (ret) + return ret; + + return ret; +} + +int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h + , uint32_t *fmt) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format"); + *w = format.fmt.pix.width; + *h = format.fmt.pix.height; + if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) + *fmt = OVERLAY_FORMAT_CbYCrY_422_I; + else + return -EINVAL; + return ret; +} + +int v4l2_overlay_set_position(int fd, int32_t x, int32_t y + , int32_t w, int32_t h, int rotation) +{ + LOG_FUNCTION_NAME + + struct v4l2_format format; + int ret; + int rot_x = 0, rot_y = 0 , rot_w = 0, rot_h = 0; + + /* configure the src format pix */ + /* configure the dst v4l2_overlay window */ + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, + "get v4l2_overlay format"); + if (ret) + return ret; + LOGV("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width + , format.fmt.win.w.height); + + if (rotation == 0) { + rot_x = x; + rot_y = y; + rot_w = w; + rot_h = h; + } else if (rotation == 90) { + rot_x = y; + rot_y = g_lcd_width - (x + w); + rot_w = h; + rot_h = w; + } else if (rotation == 180) { + rot_x = g_lcd_width - (x + w); + rot_y = g_lcd_height - (y + h); + rot_w = w; + rot_h = h; + } else if (rotation == 270) { + rot_x = g_lcd_height - (y + h); + rot_y = x; + rot_w = h; + rot_h = w; + } + + configure_window(&format.fmt.win, rot_w, rot_h, rot_x, rot_y); + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, + "set v4l2_overlay format"); + + LOGV("v4l2_overlay_set_position:: w=%d h=%d rotation=%d" + , format.fmt.win.w.width, format.fmt.win.w.height, rotation); + + if (ret) + return ret; + v4l2_overlay_dump_state(fd); + + return 0; +} + +int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, + int32_t *h) +{ + struct v4l2_format format; + int ret; + + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, + "get v4l2_overlay format"); + + if (ret) + return ret; + + get_window(&format, x, y, w, h); + + return 0; +} + +int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, + uint32_t h) +{ + LOG_FUNCTION_NAME + + struct v4l2_crop crop; + int ret; + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); + crop.c.left = x; + crop.c.top = y; + crop.c.width = w; + crop.c.height = h; + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + LOGV("%s:crop.c.left = %d\n", __func__, crop.c.left); + LOGV("%s:crop.c.top = %d\n", __func__, crop.c.top); + LOGV("%s:crop.c.width = %d\n", __func__, crop.c.width); + LOGV("%s:crop.c.height = %d\n", __func__, crop.c.height); + LOGV("%s:crop.type = 0x%x\n", __func__, crop.type); + + return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop"); +} + +int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, + uint32_t *h) +{ + LOG_FUNCTION_NAME + + struct v4l2_crop crop; + int ret; + + crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop"); + *x = crop.c.left; + *y = crop.c.top; + *w = crop.c.width; + *h = crop.c.height; + return ret; +} + +int v4l2_overlay_set_flip(int fd, int flip) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_control ctrl_v; + struct v4l2_control ctrl_h; + + switch (flip) { + case 0: + ctrl_v.value = 0; + ctrl_h.value = 0; + break; + case V4L2_CID_HFLIP: + ctrl_v.value = 0; + ctrl_h.value = 1; + break; + case V4L2_CID_VFLIP: + ctrl_v.value = 1; + ctrl_h.value = 0; + break; + default: + return -1; + } + + ctrl_v.id = V4L2_CID_VFLIP; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl_v, "set vflip"); + if (ret) return ret; + + ctrl_h.id = V4L2_CID_HFLIP; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl_h, "set hflip"); + return ret; +} + +int v4l2_overlay_set_rotation(int fd, int degree, int step) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_control ctrl; + + ctrl.id = V4L2_CID_PRIV_ROTATION; + ctrl.value = degree; + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation"); + + return ret; +} + +int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + memset(&fbuf, 0, sizeof(fbuf)); + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, + "get transparency enables"); + + if (ret) + return ret; + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey"); + + if (ret) + return ret; + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey"); + + if (ret) + return ret; + + fmt.fmt.win.chromakey = colorkey & 0xFFFFFF; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey"); + } + + return ret; +} + +int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha) +{ + LOG_FUNCTION_NAME + + int ret; + struct v4l2_framebuffer fbuf; + struct v4l2_format fmt; + + memset(&fbuf, 0, sizeof(fbuf)); + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, + "get transparency enables"); + + if (ret) + return ret; + + if (enable) + fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + else + fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha"); + + if (ret) + return ret; + + if (enable) { + memset(&fmt, 0, sizeof(fmt)); + fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha"); + + if (ret) + return ret; + + fmt.fmt.win.global_alpha = alpha & 0xFF; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha"); + } + + return ret; +} + +int v4l2_overlay_set_local_alpha(int fd, int enable) +{ + int ret; + struct v4l2_framebuffer fbuf; + + ret = 0; + + return ret; +} + +int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers, int zerocopy) +{ + struct v4l2_requestbuffers reqbuf; + int ret, i; + + reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + if (zerocopy) + reqbuf.memory = V4L2_MEMORY_USERPTR; + else + reqbuf.memory = V4L2_MEMORY_MMAP; + reqbuf.count = *num_bufs; + + ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf); + if (ret < 0) { + error(fd, "reqbuf ioctl"); + return ret; + } + + if (reqbuf.count > *num_bufs) { + error(fd, "Not enough buffer structs passed to get_buffers"); + return -ENOMEM; + } + *num_bufs = reqbuf.count; + + return 0; +} + +static int is_mmaped(struct v4l2_buffer *buf) +{ + return buf->flags == V4L2_BUF_FLAG_MAPPED; +} + +static int is_queued(struct v4l2_buffer *buf) +{ + /* is either on the input or output queue in the kernel */ + return (buf->flags & V4L2_BUF_FLAG_QUEUED) || + (buf->flags & V4L2_BUF_FLAG_DONE); +} + +static int is_dequeued(struct v4l2_buffer *buf) +{ + /* is on neither input or output queue in kernel */ + return !(buf->flags & V4L2_BUF_FLAG_QUEUED) && + !(buf->flags & V4L2_BUF_FLAG_DONE); +} + +int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf) +{ + LOG_FUNCTION_NAME + + memset(buf, 0, sizeof(struct v4l2_buffer)); + + buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf->memory = V4L2_MEMORY_MMAP; + buf->index = index; + LOGV("query buffer, mem=%u type=%u index=%u\n", + buf->memory, buf->type, buf->index); + return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl"); +} + +int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len) +{ + LOG_FUNCTION_NAME + + struct v4l2_buffer buf; + int ret; + + ret = v4l2_overlay_query_buffer(fd, index, &buf); + if (ret) + return ret; + + if (is_mmaped(&buf)) { + LOGE("Trying to mmap buffers that are already mapped!\n"); + return -EINVAL; + } + + *len = buf.length; + *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, buf.m.offset); + if (*start == MAP_FAILED) { + LOGE("map failed, length=%u offset=%u\n", buf.length, buf.m.offset); + return -EINVAL; + } + return 0; +} + +int v4l2_overlay_unmap_buf(void *start, size_t len) +{ + LOG_FUNCTION_NAME + return munmap(start, len); +} + + +int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps) +{ + return v4l2_overlay_ioctl(fd, VIDIOC_QUERYCAP, caps, "query cap"); +} + +int v4l2_overlay_stream_on(int fd) +{ + int ret; + uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + ret = v4l2_overlay_set_local_alpha(fd, 1); + if (ret) + return ret; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on"); + + return ret; +} + +int v4l2_overlay_stream_off(int fd) +{ + int ret; + uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + ret = v4l2_overlay_set_local_alpha(fd, 0); + if (ret) + return ret; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMOFF, &type, "stream off"); + + return ret; +} + +int v4l2_overlay_q_buf(int fd, int buffer, int zerocopy) +{ + struct v4l2_buffer buf; + int ret; + + if (zerocopy) { + uint8_t *pPhyYAddr; + uint8_t *pPhyCAddr; + struct fimc_buf fimc_src_buf; + uint8_t index; + + memcpy(&pPhyYAddr, (void *) buffer, sizeof(pPhyYAddr)); + memcpy(&pPhyCAddr, (void *) (buffer + sizeof(pPhyYAddr)), + sizeof(pPhyCAddr)); + memcpy(&index, + (void *) (buffer + sizeof(pPhyYAddr) + sizeof(pPhyCAddr)), + sizeof(index)); + + fimc_src_buf.base[0] = (dma_addr_t) pPhyYAddr; + fimc_src_buf.base[1] = (dma_addr_t) pPhyCAddr; + fimc_src_buf.base[2] = + (dma_addr_t) (pPhyCAddr + (pPhyCAddr - pPhyYAddr)/4); + + buf.index = index; + buf.memory = V4L2_MEMORY_USERPTR; + buf.m.userptr = (unsigned long)&fimc_src_buf; + buf.length = 0; + } else { + buf.index = buffer; + buf.memory = V4L2_MEMORY_MMAP; + } + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + buf.field = V4L2_FIELD_NONE; + buf.timestamp.tv_sec = 0; + buf.timestamp.tv_usec = 0; + buf.flags = 0; + + return v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf"); +} + +int v4l2_overlay_dq_buf(int fd, int *index, int zerocopy) +{ + struct v4l2_buffer buf; + int ret; + + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + if (zerocopy) + buf.memory = V4L2_MEMORY_USERPTR; + else + buf.memory = V4L2_MEMORY_MMAP; + + ret = v4l2_overlay_ioctl(fd, VIDIOC_DQBUF, &buf, "dqbuf"); + if (ret) + return ret; + *index = buf.index; + return 0; +} diff --git a/liboverlay/v4l2_utils.h b/liboverlay/v4l2_utils.h new file mode 100644 index 0000000..02797c3 --- /dev/null +++ b/liboverlay/v4l2_utils.h @@ -0,0 +1,75 @@ +/* + * Copyright 2009 Google Inc. All Rights Reserved. + * Author: rschultz@google.com (Rebecca Schultz Zavin) + */ + +#ifndef ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_ +#define ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_ + +#include "s5p_fimc.h" + +int v4l2_overlay_open(int id); +int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps); +int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers, + int zerocopy); +int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf); +int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len); +int v4l2_overlay_unmap_buf(void *start, size_t len); +int v4l2_overlay_stream_on(int fd); +int v4l2_overlay_stream_off(int fd); +int v4l2_overlay_q_buf(int fd, int index, int zerocopy); +int v4l2_overlay_dq_buf(int fd, int *index, int zerocopy); +int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt, + uint32_t addr); +int v4l2_overlay_get_input_size(int fd, uint32_t *w, uint32_t *h, + uint32_t *fmt); +int v4l2_overlay_set_position(int fd, int32_t x, int32_t y, int32_t w, + int32_t h, int rotation); +int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, + int32_t *h); +int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, + uint32_t h); +int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, + uint32_t *h); +int v4l2_overlay_set_flip(int fd, int degree); +int v4l2_overlay_set_rotation(int fd, int degree, int step); +int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey); +int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha); +int v4l2_overlay_set_local_alpha(int fd, int enable); +int v4l2_overlay_init_fimc(int fd, s5p_fimc_t *s5p_fimc); +int v4l2_overlay_s_fbuf(int fd, int rotation); + +enum { + V4L2_OVERLAY_PLANE_GRAPHICS, + V4L2_OVERLAY_PLANE_VIDEO1, + V4L2_OVERLAY_PLANE_VIDEO2, +}; + +enum { + /* support customed format for zero copy */ + HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x21, + HAL_PIXEL_FORMAT_YCbCr_420_P = 0x13, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP = 0x100, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I = 0x101, + HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I = 0x102, + HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP = 0x103, + HAL_PIXEL_FORMAT_CUSTOM_MAX +}; + +enum { + PFT_RGB, + PFT_YUV420, + PFT_YUV422, + PFT_YUV444, +}; + +struct mapping_data { + int fd; + size_t length; + uint32_t offset; + void *ptr; +}; + +#define ALL_BUFFERS_FLUSHED -66 + +#endif /* ANDROID_ZOOM_REPO_HARDWARE_SEC_LIBOVERLAY_V4L2_UTILS_H_*/ diff --git a/libstagefrighthw/Android.mk b/libstagefrighthw/Android.mk new file mode 100644 index 0000000..7716541 --- /dev/null +++ b/libstagefrighthw/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + stagefright_overlay_output.cpp \ + SecHardwareRenderer.cpp \ + SEC_OMX_Plugin.cpp + +LOCAL_CFLAGS += $(PV_CFLAGS_MINUS_VISIBILITY) + +LOCAL_C_INCLUDES:= \ + $(TOP)/frameworks/base/include/media/stagefright/openmax \ + $(LOCAL_PATH)/../include \ + $(LOCAL_PATH)/../liboverlay + +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + libutils \ + libcutils \ + libui \ + libdl \ + libsurfaceflinger_client + +LOCAL_MODULE := libstagefrighthw + +LOCAL_MODULE_TAGS := optional +include $(BUILD_SHARED_LIBRARY) diff --git a/libstagefrighthw/SEC_OMX_Plugin.cpp b/libstagefrighthw/SEC_OMX_Plugin.cpp new file mode 100644 index 0000000..e6022b3 --- /dev/null +++ b/libstagefrighthw/SEC_OMX_Plugin.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SEC_OMX_Plugin.h" + +#include + +#include +#include + +namespace android { + +OMXPluginBase *createOMXPlugin() { + return new SECOMXPlugin; +} + +SECOMXPlugin::SECOMXPlugin() + : mLibHandle(dlopen("libSEC_OMX_Core.smdkc210.so", RTLD_NOW)), + mInit(NULL), + mDeinit(NULL), + mComponentNameEnum(NULL), + mGetHandle(NULL), + mFreeHandle(NULL), + mGetRolesOfComponentHandle(NULL) { + if (mLibHandle != NULL) { + mInit = (InitFunc)dlsym(mLibHandle, "SEC_OMX_Init"); + mDeinit = (DeinitFunc)dlsym(mLibHandle, "SEC_OMX_DeInit"); + + mComponentNameEnum = + (ComponentNameEnumFunc)dlsym(mLibHandle, "SEC_OMX_ComponentNameEnum"); + + mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "SEC_OMX_GetHandle"); + mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "SEC_OMX_FreeHandle"); + + mGetRolesOfComponentHandle = + (GetRolesOfComponentFunc)dlsym( + mLibHandle, "SEC_OMX_GetRolesOfComponent"); + + (*mInit)(); + + } +} + +SECOMXPlugin::~SECOMXPlugin() { + if (mLibHandle != NULL) { + (*mDeinit)(); + + dlclose(mLibHandle); + mLibHandle = NULL; + } +} + +OMX_ERRORTYPE SECOMXPlugin::makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mGetHandle)( + reinterpret_cast(component), + const_cast(name), + appData, const_cast(callbacks)); +} + +OMX_ERRORTYPE SECOMXPlugin::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mFreeHandle)(reinterpret_cast(component)); +} + +OMX_ERRORTYPE SECOMXPlugin::enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index) { + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + return (*mComponentNameEnum)(name, size, index); +} + +OMX_ERRORTYPE SECOMXPlugin::getRolesOfComponent( + const char *name, + Vector *roles) { + roles->clear(); + + if (mLibHandle == NULL) { + return OMX_ErrorUndefined; + } + + OMX_U32 numRoles; + OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)( + const_cast(name), &numRoles, NULL); + + if (err != OMX_ErrorNone) { + return err; + } + + if (numRoles > 0) { + OMX_U8 **array = new OMX_U8 *[numRoles]; + for (OMX_U32 i = 0; i < numRoles; ++i) { + array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE]; + } + + OMX_U32 numRoles2; + err = (*mGetRolesOfComponentHandle)( + const_cast(name), &numRoles2, array); + + CHECK_EQ(err, OMX_ErrorNone); + CHECK_EQ(numRoles, numRoles2); + + for (OMX_U32 i = 0; i < numRoles; ++i) { + String8 s((const char *)array[i]); + roles->push(s); + + delete[] array[i]; + array[i] = NULL; + } + + delete[] array; + array = NULL; + } + + return OMX_ErrorNone; +} + +} // namespace android + diff --git a/libstagefrighthw/SEC_OMX_Plugin.h b/libstagefrighthw/SEC_OMX_Plugin.h new file mode 100644 index 0000000..6df2d31 --- /dev/null +++ b/libstagefrighthw/SEC_OMX_Plugin.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SEC_OMX_PLUGIN + +#define SEC_OMX_PLUGIN + +#include + +namespace android { + +struct SECOMXPlugin : public OMXPluginBase { + SECOMXPlugin(); + virtual ~SECOMXPlugin(); + + virtual OMX_ERRORTYPE makeComponentInstance( + const char *name, + const OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData, + OMX_COMPONENTTYPE **component); + + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component); + + virtual OMX_ERRORTYPE enumerateComponents( + OMX_STRING name, + size_t size, + OMX_U32 index); + + virtual OMX_ERRORTYPE getRolesOfComponent( + const char *name, + Vector *roles); + +private: + void *mLibHandle; + + typedef OMX_ERRORTYPE (*InitFunc)(); + typedef OMX_ERRORTYPE (*DeinitFunc)(); + typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)( + OMX_STRING, OMX_U32, OMX_U32); + + typedef OMX_ERRORTYPE (*GetHandleFunc)( + OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *); + + typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *); + + typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)( + OMX_STRING, OMX_U32 *, OMX_U8 **); + + InitFunc mInit; + DeinitFunc mDeinit; + ComponentNameEnumFunc mComponentNameEnum; + GetHandleFunc mGetHandle; + FreeHandleFunc mFreeHandle; + GetRolesOfComponentFunc mGetRolesOfComponentHandle; + + SECOMXPlugin(const SECOMXPlugin &); + SECOMXPlugin &operator=(const SECOMXPlugin &); +}; + +} // namespace android + +#endif // SEC_OMX_PLUGIN diff --git a/libstagefrighthw/SecHardwareRenderer.cpp b/libstagefrighthw/SecHardwareRenderer.cpp new file mode 100644 index 0000000..cb9e8e8 --- /dev/null +++ b/libstagefrighthw/SecHardwareRenderer.cpp @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SecHardwareRenderer" +#define LOG_NDEBUG 0 +#include + +#include "SecHardwareRenderer.h" + +#include +#include +#include + +#include + +#include "v4l2_utils.h" +#include "utils/Timers.h" + +#define CACHEABLE_BUFFERS 0x1 + +#define USE_ZERO_COPY +//#define SEC_DEBUG + +namespace android { + +//////////////////////////////////////////////////////////////////////////////// + +SecHardwareRenderer::SecHardwareRenderer( + const sp &surface, + size_t displayWidth, size_t displayHeight, + size_t decodedWidth, size_t decodedHeight, + OMX_COLOR_FORMATTYPE colorFormat, + int32_t rotationDegrees, + bool fromHardwareDecoder) + : mISurface(surface), + mDisplayWidth(displayWidth), + mDisplayHeight(displayHeight), + mDecodedWidth(decodedWidth), + mDecodedHeight(decodedHeight), + mColorFormat(colorFormat), + mInitCheck(NO_INIT), + mFrameSize(mDecodedWidth * mDecodedHeight * 2), + mIsFirstFrame(true), + mCustomFormat(false), + mIndex(0) { + + CHECK(mISurface.get() != NULL); + CHECK(mDecodedWidth > 0); + CHECK(mDecodedHeight > 0); + + if (colorFormat != OMX_COLOR_FormatCbYCrY + && colorFormat != OMX_COLOR_FormatYUV420Planar + && colorFormat != OMX_COLOR_FormatYUV420SemiPlanar) { + LOGE("Invalid colorFormat (0x%x)", colorFormat); + return; + } + + uint32_t orientation; + switch (rotationDegrees) { + case 0: orientation = ISurface::BufferHeap::ROT_0; break; + case 90: orientation = ISurface::BufferHeap::ROT_90; break; + case 180: orientation = ISurface::BufferHeap::ROT_180; break; + case 270: orientation = ISurface::BufferHeap::ROT_270; break; + default: orientation = ISurface::BufferHeap::ROT_0; break; + } + + sp ref; + +#if defined (USE_ZERO_COPY) + if (fromHardwareDecoder) { + ref = mISurface->createOverlay( + mDecodedWidth, mDecodedHeight, + HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP, orientation); + mCustomFormat = true; + } +#else + else + { + ref = mISurface->createOverlay( + mDecodedWidth, mDecodedHeight, HAL_PIXEL_FORMAT_YCbCr_420_P, + orientation); + } +#endif + + if (ref.get() == NULL) { + LOGE("Unable to create the overlay!"); + return; + } + + mOverlay = new Overlay(ref); + mOverlay->setParameter(CACHEABLE_BUFFERS, 0); + + mNumBuf = mOverlay->getBufferCount(); + + if (mCustomFormat) { + mFrameSize = 32; + mMemoryHeap = new MemoryHeapBase(mNumBuf * mFrameSize); + } else { + for (size_t i = 0; i < (size_t)mNumBuf; ++i) { + void *addr = mOverlay->getBufferAddress((void *)i); + mOverlayAddresses.push(addr); + } + } + + mInitCheck = OK; +} + +SecHardwareRenderer::~SecHardwareRenderer() { + + if(mMemoryHeap != NULL) + mMemoryHeap.clear(); + + if (mOverlay.get() != NULL) { + mOverlay->destroy(); + mOverlay.clear(); + } +} + +void SecHardwareRenderer::handleYUV420Planar( + const void *data, size_t size) { + + int FrameSize; + uint8_t* pPhyYAddr; + uint8_t* pPhyCAddr; + int AddrSize; + size_t offset; + + CHECK(size >= (mDecodedWidth * mDecodedHeight * 3) / 2); + + offset = mIndex * mFrameSize; + void *dst = (uint8_t *)mMemoryHeap->getBase() + offset; + + AddrSize = sizeof(void *); + memcpy(&FrameSize, data, sizeof(FrameSize)); + memcpy(&pPhyYAddr, data + sizeof(FrameSize), sizeof(pPhyYAddr)); + memcpy(&pPhyCAddr, data + sizeof(FrameSize) + (AddrSize * 1), sizeof(pPhyCAddr)); + + memcpy(dst , &pPhyYAddr, sizeof(pPhyYAddr)); + memcpy(dst + sizeof(pPhyYAddr) , &pPhyCAddr, sizeof(pPhyCAddr)); + memcpy(dst + sizeof(pPhyYAddr) + sizeof(pPhyCAddr), &mIndex, sizeof(mIndex)); +} + +void SecHardwareRenderer::render( + const void *data, size_t size, void *platformPrivate) { + + if (mOverlay.get() == NULL) { + return; + } + + if (mCustomFormat) { + /* zero copy solution case */ + + overlay_buffer_t dst = (uint8_t *)mMemoryHeap->getBase() + mIndex*mFrameSize; + + if (mColorFormat == OMX_COLOR_FormatYUV420Planar || + mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { + handleYUV420Planar(data, size); + } + + if (mOverlay->queueBuffer(dst) == ALL_BUFFERS_FLUSHED) { + mIsFirstFrame = true; + if (mOverlay->queueBuffer((void *)dst) != 0) { + return; + } + } + + if (++mIndex == mNumBuf) { + mIndex = 0; + } + + overlay_buffer_t overlay_buffer; + if (!mIsFirstFrame) { + status_t err = mOverlay->dequeueBuffer(&overlay_buffer); + if (err == ALL_BUFFERS_FLUSHED) { + mIsFirstFrame = true; + } else { + return; + } + } else { + mIsFirstFrame = false; + } + } else { + /* normal frame case */ + if (mColorFormat == OMX_COLOR_FormatYUV420Planar) { + memcpy(mOverlayAddresses[mIndex], data, size); + } + + if (mOverlay->queueBuffer((void *)mIndex) == ALL_BUFFERS_FLUSHED) { + mIsFirstFrame = true; + if (mOverlay->queueBuffer((void *)mIndex) != 0) { + return; + } + } + + if (++mIndex == mNumBuf) { + mIndex = 0; + } + + overlay_buffer_t overlay_buffer; + if (!mIsFirstFrame) { + status_t err = mOverlay->dequeueBuffer(&overlay_buffer); + + if (err == ALL_BUFFERS_FLUSHED) { + mIsFirstFrame = true; + } else { + return; + } + } else { + mIsFirstFrame = false; + } + } +} + +} // namespace android + diff --git a/libstagefrighthw/SecHardwareRenderer.h b/libstagefrighthw/SecHardwareRenderer.h new file mode 100644 index 0000000..3fad243 --- /dev/null +++ b/libstagefrighthw/SecHardwareRenderer.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SEC_HARDWARE_RENDERER_H_ + +#define SEC_HARDWARE_RENDERER_H_ + +#include +#include +#include + +#include + +#include +#include + +namespace android { + +class ISurface; +class Overlay; + +class SecHardwareRenderer : public VideoRenderer { +public: + SecHardwareRenderer( + const sp &surface, + size_t displayWidth, size_t displayHeight, + size_t decodedWidth, size_t decodedHeight, + OMX_COLOR_FORMATTYPE colorFormat, + int32_t rotationDegrees, + bool fromHardwareDecoder); + + virtual ~SecHardwareRenderer(); + + status_t initCheck() const { return mInitCheck; } + + virtual void render( + const void *data, size_t size, void *platformPrivate); + + +private: + sp mISurface; + size_t mDisplayWidth, mDisplayHeight; + size_t mDecodedWidth, mDecodedHeight; + OMX_COLOR_FORMATTYPE mColorFormat; + status_t mInitCheck; + size_t mFrameSize; + sp mOverlay; + sp mMemoryHeap; + Vector mOverlayAddresses; + bool mIsFirstFrame; + int mNumBuf; + size_t mIndex; + bool mCustomFormat; + + + SecHardwareRenderer(const SecHardwareRenderer &); + SecHardwareRenderer &operator=(const SecHardwareRenderer &); + + void handleYUV420Planar(const void *, size_t); +}; + +} // namespace android + +#endif // SEC_HARDWARE_RENDERER_H_ + diff --git a/libstagefrighthw/stagefright_overlay_output.cpp b/libstagefrighthw/stagefright_overlay_output.cpp new file mode 100644 index 0000000..fce1d7e --- /dev/null +++ b/libstagefrighthw/stagefright_overlay_output.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SecHardwareRenderer.h" + +#include + +using android::sp; +using android::ISurface; +using android::VideoRenderer; + +VideoRenderer *createRendererWithRotation( + const sp &surface, + const char *componentName, + OMX_COLOR_FORMATTYPE colorFormat, + size_t displayWidth, size_t displayHeight, + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) { + using android::SecHardwareRenderer; + + bool fromHardwareDecoder = !strncmp(componentName, "OMX.SEC.", 8); + + SecHardwareRenderer *renderer = + new SecHardwareRenderer( + surface, displayWidth, displayHeight, + decodedWidth, decodedHeight, + colorFormat, + rotationDegrees, + fromHardwareDecoder); + + if (renderer->initCheck() != android::OK) { + delete renderer; + renderer = NULL; + } + + return renderer; +} + diff --git a/sec_mm/Android.mk b/sec_mm/Android.mk new file mode 100644 index 0000000..6571161 --- /dev/null +++ b/sec_mm/Android.mk @@ -0,0 +1 @@ +include $(all-subdir-makefiles) diff --git a/sec_mm/sec_omx/Android.mk b/sec_mm/sec_omx/Android.mk new file mode 100644 index 0000000..cbae428 --- /dev/null +++ b/sec_mm/sec_omx/Android.mk @@ -0,0 +1,22 @@ + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +SEC_OMX_TOP := $(LOCAL_PATH) +SEC_CODECS := $(SEC_OMX_TOP)/sec_codecs/ + +SEC_OMX_INC := $(SEC_OMX_TOP)/sec_omx_include/ +SEC_OMX_COMPONENT := $(SEC_OMX_TOP)/sec_omx_component + +include $(SEC_OMX_TOP)/sec_osal/Android.mk +include $(SEC_OMX_TOP)/sec_omx_core/Android.mk + +include $(SEC_CODECS)/Android.mk +include $(SEC_OMX_COMPONENT)/common/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/h264dec/Android.mk +include $(SEC_OMX_COMPONENT)/video/dec/mpeg4dec/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/h264enc/Android.mk +include $(SEC_OMX_COMPONENT)/video/enc/mpeg4enc/Android.mk diff --git a/sec_mm/sec_omx/sec_codecs/Android.mk b/sec_mm/sec_omx/sec_codecs/Android.mk new file mode 100644 index 0000000..a51a075 --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +include $(SEC_CODECS)/video/mfc_c110/dec/Android.mk +include $(SEC_CODECS)/video/mfc_c110/enc/Android.mk + diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/Android.mk b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/Android.mk new file mode 100644 index 0000000..7d2b304 --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/Android.mk @@ -0,0 +1,26 @@ + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + src/SsbSipMfcDecAPI.c + +LOCAL_MODULE := libsecmfcdecapi.smdkc210 + +LOCAL_PRELINK_MODULE := false + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := liblog + +LOCAL_C_INCLUDES := \ + $(SEC_CODECS)/video/mfc_c110/include + +include $(BUILD_STATIC_LIBRARY) + diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c new file mode 100644 index 0000000..508f290 --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/dec/src/SsbSipMfcDecAPI.c @@ -0,0 +1,675 @@ +/* + * Copyright 2010 Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mfc_interface.h" +#include "SsbSipMfcApi.h" + +#define _MFCLIB_MAGIC_NUMBER 0x92241000 + +#define USR_DATA_START_CODE (0x000001B2) +#define VOP_START_CODE (0x000001B6) +#define MP4_START_CODE (0x000001) + +static void getAByte(char *buff, int *code) +{ + int byte; + + *code = (*code << 8); + byte = (int)*buff; + byte &= 0xFF; + *code |= byte; +} + +static mfc_packed_mode isPBPacked(_MFCLIB *pCtx, int length) +{ + char *strmBuffer = NULL; + char *strmBufferEnd = NULL; + int startCode = 0xFFFFFFFF; + + strmBuffer = (char *)pCtx->virStrmBuf; + strmBufferEnd = (char *)pCtx->virStrmBuf + length; + + while (1) { + while (startCode != USR_DATA_START_CODE) { + if (startCode == VOP_START_CODE) { + LOGV("isPBPacked: VOP START Found !!.....return\n"); + LOGV("isPBPacked: Non Packed PB\n"); + return MFC_UNPACKED_PB; + } + getAByte(strmBuffer, &startCode); + strmBuffer++; + if (strmBuffer >= strmBufferEnd) + goto out; + } + LOGV("isPBPacked: User Data Found !!\n"); + + do { + if (*strmBuffer == 'p') { + LOGI("isPBPacked: Packed PB\n"); + return MFC_PACKED_PB; + } + getAByte(strmBuffer, &startCode); + strmBuffer++; + if (strmBuffer >= strmBufferEnd) + goto out; + } while ((startCode >> 8) != MP4_START_CODE); + } + +out: + LOGV("isPBPacked: Non Packed PB\n"); + return MFC_UNPACKED_PB; +} + +void *SsbSipMfcDecOpen(void) +{ + int hMFCOpen; + unsigned int mapped_addr; + _MFCLIB *pCTX; + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcDecOpen: malloc failed.\n"); + return NULL; + } + memset(pCTX, 0, sizeof(_MFCLIB)); + + hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcDecOpen: MFC Open failure\n"); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcDecOpen: FIMV5.0 driver address mapping failed\n"); + return NULL; + } + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng) +{ + int ret_code; + int packedPB = MFC_UNPACKED_PB; + mfc_common_args DecArg; + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + if ((codec_type != MPEG4_DEC) && + (codec_type != H264_DEC) && + (codec_type != H263_DEC) && + (codec_type != MPEG1_DEC) && + (codec_type != MPEG2_DEC) && + (codec_type != FIMV1_DEC) && + (codec_type != FIMV2_DEC) && + (codec_type != FIMV3_DEC) && + (codec_type != FIMV4_DEC) && + (codec_type != XVID_DEC) && + (codec_type != VC1RCV_DEC) && + (codec_type != VC1_DEC)) { + LOGE("SsbSipMfcDecOpen: Undefined codec type.\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX->codec_type = codec_type; + + if ((pCTX->codec_type == MPEG4_DEC) || + (pCTX->codec_type == FIMV1_DEC) || + (pCTX->codec_type == FIMV2_DEC) || + (pCTX->codec_type == FIMV3_DEC) || + (pCTX->codec_type == FIMV4_DEC) || + (pCTX->codec_type == XVID_DEC)) + packedPB = isPBPacked(pCTX, Frameleng); + + /* init args */ + DecArg.args.dec_init.in_codec_type = pCTX->codec_type; + DecArg.args.dec_init.in_strm_size = Frameleng; + DecArg.args.dec_init.in_strm_buf = pCTX->phyStrmBuf; + DecArg.args.dec_init.in_packed_PB = packedPB; + + /* mem alloc args */ + DecArg.args.dec_init.in_mapped_addr = pCTX->mapped_addr; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_INIT, &DecArg); + if (DecArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecInit: IOCTL_MFC_DEC_INIT (%d) failed\n", DecArg.ret_code); + return MFC_RET_DEC_INIT_FAIL; + } + + pCTX->decOutInfo.img_width = DecArg.args.dec_init.out_img_width; + pCTX->decOutInfo.img_height = DecArg.args.dec_init.out_img_height; + pCTX->decOutInfo.buf_width = DecArg.args.dec_init.out_buf_width; + pCTX->decOutInfo.buf_height = DecArg.args.dec_init.out_buf_height; + + /* by RainAde : crop information */ + pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_init.out_crop_top_offset; + pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_init.out_crop_bottom_offset; + pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_init.out_crop_left_offset; + pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_init.out_crop_right_offset; + + pCTX->virFrmBuf.luma = DecArg.args.dec_init.out_u_addr.luma; + pCTX->virFrmBuf.chroma = DecArg.args.dec_init.out_u_addr.chroma; + + pCTX->phyFrmBuf.luma = DecArg.args.dec_init.out_p_addr.luma; + pCTX->phyFrmBuf.chroma = DecArg.args.dec_init.out_p_addr.chroma; + pCTX->sizeFrmBuf.luma = DecArg.args.dec_init.out_frame_buf_size.luma; + pCTX->sizeFrmBuf.chroma = DecArg.args.dec_init.out_frame_buf_size.chroma; + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill) +{ + int ret_code; + int Yoffset; + int Coffset; + _MFCLIB *pCTX; + mfc_common_args DecArg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecExe: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + if ((lengthBufFill < 0) || (lengthBufFill > MAX_DECODER_INPUT_BUFFER_SIZE)) { + LOGE("SsbSipMfcDecExe: lengthBufFill is invalid. (lengthBufFill=%d)\n", lengthBufFill); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + DecArg.args.dec_exe.in_codec_type = pCTX->codec_type; + DecArg.args.dec_exe.in_strm_buf = pCTX->phyStrmBuf; + DecArg.args.dec_exe.in_strm_size = lengthBufFill; + DecArg.args.dec_exe.in_frm_buf.luma = pCTX->phyFrmBuf.luma; + DecArg.args.dec_exe.in_frm_buf.chroma = pCTX->phyFrmBuf.chroma; + DecArg.args.dec_exe.in_frm_size.luma = pCTX->sizeFrmBuf.luma; + DecArg.args.dec_exe.in_frm_size.chroma = pCTX->sizeFrmBuf.chroma; + DecArg.args.dec_exe.in_frametag = pCTX->in_frametag; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_DEC_EXE, &DecArg); + if (DecArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecExe: IOCTL_MFC_DEC_EXE failed(ret : %d)\n", DecArg.ret_code); + return MFC_RET_DEC_EXE_ERR; + } + + Yoffset = DecArg.args.dec_exe.out_display_Y_addr - DecArg.args.dec_exe.in_frm_buf.luma; + Coffset = DecArg.args.dec_exe.out_display_C_addr - DecArg.args.dec_exe.in_frm_buf.chroma; + + pCTX->decOutInfo.YPhyAddr = (void *)(DecArg.args.dec_exe.out_display_Y_addr); + pCTX->decOutInfo.CPhyAddr = (void *)(DecArg.args.dec_exe.out_display_C_addr); + pCTX->decOutInfo.YVirAddr = (void *)(pCTX->virFrmBuf.luma + Yoffset); + pCTX->decOutInfo.CVirAddr = (void *)(pCTX->virFrmBuf.chroma + Coffset); + pCTX->decOutInfo.timestamp_top = DecArg.args.dec_exe.out_timestamp_top; + pCTX->decOutInfo.timestamp_bottom = DecArg.args.dec_exe.out_timestamp_bottom; + pCTX->decOutInfo.consumedByte = DecArg.args.dec_exe.out_consume_bytes; + pCTX->decOutInfo.res_change = DecArg.args.dec_exe.out_res_change; + pCTX->decOutInfo.crop_top_offset = DecArg.args.dec_exe.out_crop_top_offset; + pCTX->decOutInfo.crop_bottom_offset = DecArg.args.dec_exe.out_crop_bottom_offset; + pCTX->decOutInfo.crop_left_offset = DecArg.args.dec_exe.out_crop_left_offset; + pCTX->decOutInfo.crop_right_offset = DecArg.args.dec_exe.out_crop_right_offset; + pCTX->out_frametag_top = DecArg.args.dec_exe.out_frametag_top; + pCTX->out_frametag_bottom = DecArg.args.dec_exe.out_frametag_bottom; + pCTX->displayStatus = DecArg.args.dec_exe.out_display_status; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args free_arg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecClose: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.chroma; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + free_arg.args.mem_free.u_addr = pCTX->virStrmBuf; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + pCTX->inter_buff_status = MFC_USE_NONE; + + munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP); + close(pCTX->hMFC); + free(pCTX); + + return MFC_RET_OK; +} + +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args user_addr_arg, phys_addr_arg; + + if (inputBufferSize < 0) { + LOGE("SsbSipMfcDecGetInBuf: inputBufferSize = %d is invalid\n", inputBufferSize); + return NULL; + } + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetInBuf: openHandle is NULL\n"); + return NULL; + } + + pCTX = (_MFCLIB *)openHandle; + + user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; + user_addr_arg.args.mem_alloc.buff_size = inputBufferSize; + user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcDecGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n"); + return NULL; + } + pCTX->virStrmBuf = user_addr_arg.args.mem_alloc.out_uaddr; + pCTX->phyStrmBuf = user_addr_arg.args.mem_alloc.out_paddr; + pCTX->sizeStrmBuf = inputBufferSize; + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + *phyInBuf = (void *)pCTX->phyStrmBuf; + + return (void *)pCTX->virStrmBuf; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int inputBufferSize) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecSetInBuf: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + pCTX->phyStrmBuf = (int)phyInBuf; + pCTX->virStrmBuf = (int)virInBuf; + pCTX->sizeStrmBuf = inputBufferSize; + return MFC_RET_OK; +} + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetOutBuf: openHandle is NULL\n"); + return MFC_GETOUTBUF_DISPLAY_END; + } + + pCTX = (_MFCLIB *)openHandle; + + output_info->YPhyAddr = pCTX->decOutInfo.YPhyAddr; + output_info->CPhyAddr = pCTX->decOutInfo.CPhyAddr; + + output_info->YVirAddr = pCTX->decOutInfo.YVirAddr; + output_info->CVirAddr = pCTX->decOutInfo.CVirAddr; + + output_info->img_width = pCTX->decOutInfo.img_width; + output_info->img_height= pCTX->decOutInfo.img_height; + + output_info->buf_width = pCTX->decOutInfo.buf_width; + output_info->buf_height= pCTX->decOutInfo.buf_height; + + /* by RainAde : for crop information */ + output_info->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + output_info->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset; + output_info->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + output_info->crop_right_offset= pCTX->decOutInfo.crop_right_offset; + + if (pCTX->displayStatus == 0) + return MFC_GETOUTBUF_DISPLAY_END; + else if (pCTX->displayStatus == 1) + return MFC_GETOUTBUF_DISPLAY_DECODING; + else if (pCTX->displayStatus == 2) + return MFC_GETOUTBUF_DISPLAY_ONLY; + else + return MFC_GETOUTBUF_DECODING_ONLY; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args DecArg; + SSBSIP_MFC_IMG_RESOLUTION *img_resolution; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecSetConfig: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("SsbSipMfcDecSetConfig: value is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + switch (conf_type) { + case MFC_DEC_SETCONF_POST_ENABLE: + case MFC_DEC_SETCONF_EXTRA_BUFFER_NUM: + case MFC_DEC_SETCONF_DISPLAY_DELAY: + case MFC_DEC_SETCONF_IS_LAST_FRAME: + case MFC_DEC_SETCONF_SLICE_ENABLE: + case MFC_DEC_SETCONF_CRC_ENABLE: + DecArg.args.set_config.in_config_param = conf_type; + DecArg.args.set_config.in_config_value[0] = *((unsigned int *)value); + DecArg.args.set_config.in_config_value[1] = 0; + break; + + case MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT: + img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; + DecArg.args.set_config.in_config_param = conf_type; + DecArg.args.set_config.in_config_value[0] = img_resolution->width; + DecArg.args.set_config.in_config_value[1] = img_resolution->height; + break; + + case MFC_DEC_SETCONF_FRAME_TAG: + pCTX->in_frametag = *((int *)value); + return MFC_RET_OK; + + default: + LOGE("SsbSipMfcDecSetConfig: No such conf_type is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &DecArg); + if (DecArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type); + return MFC_RET_DEC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args DecArg; + + SSBSIP_MFC_IMG_RESOLUTION *img_resolution; + SSBSIP_MFC_CROP_INFORMATION *crop_information; + MFC_CRC_DATA *crc_data; + + if (openHandle == NULL) { + LOGE("SsbSipMfcDecGetConfig: openHandle is NULL\n"); + return MFC_RET_FAIL; + } + + if (value == NULL) { + LOGE("SsbSipMfcDecGetConfig: value is NULL\n"); + return MFC_RET_FAIL; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&DecArg, 0x00, sizeof(DecArg)); + + switch (conf_type) { + case MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT: + img_resolution = (SSBSIP_MFC_IMG_RESOLUTION *)value; + img_resolution->width = pCTX->decOutInfo.img_width; + img_resolution->height = pCTX->decOutInfo.img_height; + img_resolution->buf_width = pCTX->decOutInfo.buf_width; + img_resolution->buf_height = pCTX->decOutInfo.buf_height; + break; + + /* Added by RainAde */ + case MFC_DEC_GETCONF_CROP_INFO: + crop_information = (SSBSIP_MFC_CROP_INFORMATION*)value; + crop_information->crop_top_offset = pCTX->decOutInfo.crop_top_offset; + crop_information->crop_bottom_offset= pCTX->decOutInfo.crop_bottom_offset; + crop_information->crop_left_offset = pCTX->decOutInfo.crop_left_offset; + crop_information->crop_right_offset= pCTX->decOutInfo.crop_right_offset; + break; + + case MFC_DEC_GETCONF_CRC_DATA: + crc_data = (MFC_CRC_DATA *)value; + + DecArg.args.get_config.in_config_param = conf_type; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_CONFIG, &DecArg); + if (DecArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecGetConfig: IOCTL_MFC_GET_CONFIG failed(ret : %d, conf_type: %d)\n", DecArg.ret_code, conf_type); + return MFC_RET_DEC_GET_CONF_FAIL; + } + crc_data->luma0 = DecArg.args.get_config.out_config_value[0]; + crc_data->chroma0 = DecArg.args.get_config.out_config_value[1]; + break; + + case MFC_DEC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->out_frametag_top; + break; + + default: + LOGE("SsbSipMfcDecGetConfig: No such conf_type is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} + +int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos) +{ + int pixel_x_m1, pixel_y_m1; + int roundup_x, roundup_y; + int linear_addr0, linear_addr1, bank_addr ; + int x_addr; + int trans_addr; + + pixel_x_m1 = x_size -1; + pixel_y_m1 = y_size -1; + + roundup_x = ((pixel_x_m1 >> 7) + 1); + roundup_y = ((pixel_x_m1 >> 6) + 1); + + x_addr = x_pos >> 2; + + if ((y_size <= y_pos+32) && ( y_pos < y_size) && + (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) { + linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } else { + linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf)); + linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f)); + + if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1)) + bank_addr = ((x_addr >> 4) & 0x1); + else + bank_addr = 0x2 | ((x_addr >> 4) & 0x1); + } + + linear_addr0 = linear_addr0 << 2; + trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0; + + return trans_addr; +} + +void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) +{ + int trans_addr; + unsigned int i, j, k, index; + unsigned char data8[4]; + unsigned int max_index = x_size * y_size; + + for (i = 0; i < y_size; i = i + 16) { + for (j = 0; j < x_size; j = j + 16) { + trans_addr = tile_4x2_read(x_size, y_size, j, i); + for (k = 0; k < 16; k++) { + /* limit check - prohibit segmentation fault */ + index = (i * x_size) + (x_size * k) + j; + /* remove equal condition to solve thumbnail bug */ + if (index + 16 > max_index) { + continue; + } + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; + + p_linear_addr[index] = data8[0]; + p_linear_addr[index + 1] = data8[1]; + p_linear_addr[index + 2] = data8[2]; + p_linear_addr[index + 3] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; + + p_linear_addr[index + 4] = data8[0]; + p_linear_addr[index + 5] = data8[1]; + p_linear_addr[index + 6] = data8[2]; + p_linear_addr[index + 7] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; + + p_linear_addr[index + 8] = data8[0]; + p_linear_addr[index + 9] = data8[1]; + p_linear_addr[index + 10] = data8[2]; + p_linear_addr[index + 11] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; + + p_linear_addr[index + 12] = data8[0]; + p_linear_addr[index + 13] = data8[1]; + p_linear_addr[index + 14] = data8[2]; + p_linear_addr[index + 15] = data8[3]; + } + } + } +} + +void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) +{ + int trans_addr; + unsigned int i, j, k, index; + unsigned char data8[4]; + unsigned int half_y_size = y_size / 2; + unsigned int max_index = x_size * half_y_size; + unsigned char *pUVAddr[2]; + + pUVAddr[0] = p_linear_addr; + pUVAddr[1] = p_linear_addr + ((x_size * half_y_size) / 2); + + for (i = 0; i < half_y_size; i = i + 16) { + for (j = 0; j < x_size; j = j + 16) { + trans_addr = tile_4x2_read(x_size, half_y_size, j, i); + for (k = 0; k < 16; k++) { + /* limit check - prohibit segmentation fault */ + index = (i * x_size) + (x_size * k) + j; + /* remove equal condition to solve thumbnail bug */ + if (index + 16 > max_index) { + continue; + } + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 0]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 1]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 2]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 3]; + + pUVAddr[index%2][index/2] = data8[0]; + pUVAddr[(index+1)%2][(index+1)/2] = data8[1]; + pUVAddr[(index+2)%2][(index+2)/2] = data8[2]; + pUVAddr[(index+3)%2][(index+3)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 4]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 5]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 6]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 7]; + + pUVAddr[(index+4)%2][(index+4)/2] = data8[0]; + pUVAddr[(index+5)%2][(index+5)/2] = data8[1]; + pUVAddr[(index+6)%2][(index+6)/2] = data8[2]; + pUVAddr[(index+7)%2][(index+7)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 8]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 9]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 10]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 11]; + + pUVAddr[(index+8)%2][(index+8)/2] = data8[0]; + pUVAddr[(index+9)%2][(index+9)/2] = data8[1]; + pUVAddr[(index+10)%2][(index+10)/2] = data8[2]; + pUVAddr[(index+11)%2][(index+11)/2] = data8[3]; + + data8[0] = p_tiled_addr[trans_addr + 64 * k + 12]; + data8[1] = p_tiled_addr[trans_addr + 64 * k + 13]; + data8[2] = p_tiled_addr[trans_addr + 64 * k + 14]; + data8[3] = p_tiled_addr[trans_addr + 64 * k + 15]; + + pUVAddr[(index+12)%2][(index+12)/2] = data8[0]; + pUVAddr[(index+13)%2][(index+13)/2] = data8[1]; + pUVAddr[(index+14)%2][(index+14)/2] = data8[2]; + pUVAddr[(index+15)%2][(index+15)/2] = data8[3]; + } + } + } +} diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/Android.mk b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/Android.mk new file mode 100644 index 0000000..97bb12c --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/Android.mk @@ -0,0 +1,26 @@ + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + src/SsbSipMfcEncAPI.c + +LOCAL_MODULE := libsecmfcencapi.smdkc210 + +LOCAL_PRELINK_MODULE := false + +LOCAL_CFLAGS := -DUSE_FIMC_FRAME_BUFFER + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := + +LOCAL_SHARED_LIBRARIES := liblog + +LOCAL_C_INCLUDES := \ + $(SEC_CODECS)/video/mfc_c110/include + +include $(BUILD_STATIC_LIBRARY) + diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c new file mode 100644 index 0000000..2c33c5b --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/enc/src/SsbSipMfcEncAPI.c @@ -0,0 +1,630 @@ +/* + * Copyright 2010 Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "SsbSipMfcApi.h" +#include "mfc_interface.h" + +#define _MFCLIB_MAGIC_NUMBER 0x92241001 + +void *SsbSipMfcEncOpen(void) +{ + int hMFCOpen; + _MFCLIB *pCTX; + unsigned int mapped_addr; + + hMFCOpen = open(S5PC110_MFC_DEV_NAME, O_RDWR | O_NDELAY); + if (hMFCOpen < 0) { + LOGE("SsbSipMfcEncOpen: MFC Open failure\n"); + return NULL; + } + + pCTX = (_MFCLIB *)malloc(sizeof(_MFCLIB)); + if (pCTX == NULL) { + LOGE("SsbSipMfcEncOpen: malloc failed.\n"); + close(hMFCOpen); + return NULL; + } + + mapped_addr = (unsigned int)mmap(0, MMAP_BUFFER_SIZE_MMAP, PROT_READ | PROT_WRITE, MAP_SHARED, hMFCOpen, 0); + if (!mapped_addr) { + LOGE("SsbSipMfcEncOpen: FIMV5.0 driver address mapping failed\n"); + return NULL; + } + + memset(pCTX, 0, sizeof(_MFCLIB)); + + pCTX->magic = _MFCLIB_MAGIC_NUMBER; + pCTX->hMFC = hMFCOpen; + pCTX->mapped_addr = mapped_addr; + pCTX->inter_buff_status = MFC_USE_NONE; + + return (void *)pCTX; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param) +{ + int ret_code; + int dpbBufSize; + + _MFCLIB *pCTX; + mfc_common_args EncArg; + mfc_common_args user_addr_arg, phys_addr_arg; + SSBSIP_MFC_ENC_H264_PARAM *h264_arg; + SSBSIP_MFC_ENC_MPEG4_PARAM *mpeg4_arg; + SSBSIP_MFC_ENC_H263_PARAM *h263_arg; + SSBSIP_MFC_CODEC_TYPE codec_type; + + pCTX = (_MFCLIB *)openHandle; + memset(&EncArg, 0, sizeof(mfc_common_args)); + + LOGV("SsbSipMfcEncInit: Encode Init start\n"); + + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; + codec_type = mpeg4_arg->codecType; + + if ((codec_type != MPEG4_ENC) && + (codec_type != H264_ENC) && + (codec_type != H263_ENC)) { + LOGE("SsbSipMfcEncOpen: Undefined codec type.\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX->codec_type = codec_type; + + switch (pCTX->codec_type) { + case MPEG4_ENC: + LOGV("SsbSipMfcEncInit: MPEG4 Encode\n"); + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM *)param; + + pCTX->width = mpeg4_arg->SourceWidth; + pCTX->height = mpeg4_arg->SourceHeight; + break; + + case H263_ENC: + LOGV("SsbSipMfcEncInit: H263 Encode\n"); + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; + + pCTX->width = h263_arg->SourceWidth; + pCTX->height = h263_arg->SourceHeight; + break; + + case H264_ENC: + LOGV("SsbSipMfcEncInit: H264 Encode\n"); + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; + + pCTX->width = h264_arg->SourceWidth; + pCTX->height = h264_arg->SourceHeight; + break; + + default: + break; + } + + switch (pCTX->codec_type) { + case MPEG4_ENC: + mpeg4_arg = (SSBSIP_MFC_ENC_MPEG4_PARAM*)param; + + EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type; + EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(mpeg4_arg->ProfileIDC, mpeg4_arg->LevelIDC); + + EncArg.args.enc_init_mpeg4.in_width = mpeg4_arg->SourceWidth; + EncArg.args.enc_init_mpeg4.in_height = mpeg4_arg->SourceHeight; + EncArg.args.enc_init_mpeg4.in_gop_num = mpeg4_arg->IDRPeriod; + if (mpeg4_arg->DisableQpelME) + EncArg.args.enc_init_mpeg4.in_qpelME_enable = 0; + else + EncArg.args.enc_init_mpeg4.in_qpelME_enable = 1; + + EncArg.args.enc_init_mpeg4.in_MS_mode = mpeg4_arg->SliceMode; + EncArg.args.enc_init_mpeg4.in_MS_size = mpeg4_arg->SliceArgument; + + if (mpeg4_arg->NumberBFrames > 2) { + LOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_BframeNum = mpeg4_arg->NumberBFrames; + EncArg.args.enc_init_mpeg4.in_mb_refresh = mpeg4_arg->RandomIntraMBRefresh; + + /* rate control*/ + EncArg.args.enc_init_mpeg4.in_RC_frm_enable = mpeg4_arg->EnableFRMRateControl; + if ((mpeg4_arg->QSCodeMin > 51) || (mpeg4_arg->QSCodeMax > 51)) { + LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(mpeg4_arg->QSCodeMin, mpeg4_arg->QSCodeMax); + EncArg.args.enc_init_mpeg4.in_RC_rpara = mpeg4_arg->CBRPeriodRf; + + /* pad control */ + EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = mpeg4_arg->PadControlOn; + if ((mpeg4_arg->LumaPadVal > 255) || (mpeg4_arg->CbPadVal > 255) || (mpeg4_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_luma_pad_val = mpeg4_arg->LumaPadVal; + EncArg.args.enc_init_mpeg4.in_cb_pad_val = mpeg4_arg->CbPadVal; + EncArg.args.enc_init_mpeg4.in_cr_pad_val = mpeg4_arg->CrPadVal; + + EncArg.args.enc_init_mpeg4.in_time_increament_res = mpeg4_arg->TimeIncreamentRes; + EncArg.args.enc_init_mpeg4.in_time_vop_time_increament = mpeg4_arg->VopTimeIncreament; + EncArg.args.enc_init_mpeg4.in_RC_framerate = (mpeg4_arg->TimeIncreamentRes / mpeg4_arg->VopTimeIncreament); + EncArg.args.enc_init_mpeg4.in_RC_bitrate = mpeg4_arg->Bitrate; + if ((mpeg4_arg->FrameQp > 51) || (mpeg4_arg->FrameQp_P) > 51 || (mpeg4_arg->FrameQp_B > 51)) { + LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_frame_qp = mpeg4_arg->FrameQp; + if (mpeg4_arg->FrameQp_P) + EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp_P; + else + EncArg.args.enc_init_mpeg4.in_frame_P_qp = mpeg4_arg->FrameQp; + if (mpeg4_arg->FrameQp_B) + EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp_B; + else + EncArg.args.enc_init_mpeg4.in_frame_B_qp = mpeg4_arg->FrameQp; + + break; + + case H263_ENC: + h263_arg = (SSBSIP_MFC_ENC_H263_PARAM *)param; + + EncArg.args.enc_init_mpeg4.in_codec_type = pCTX->codec_type; + EncArg.args.enc_init_mpeg4.in_profile_level = ENC_PROFILE_LEVEL(66, 40); + EncArg.args.enc_init_mpeg4.in_width = h263_arg->SourceWidth; + EncArg.args.enc_init_mpeg4.in_height = h263_arg->SourceHeight; + EncArg.args.enc_init_mpeg4.in_gop_num = h263_arg->IDRPeriod; + EncArg.args.enc_init_mpeg4.in_mb_refresh = h263_arg->RandomIntraMBRefresh; + EncArg.args.enc_init_mpeg4.in_MS_mode = h263_arg->SliceMode; + EncArg.args.enc_init_mpeg4.in_MS_size = 0; + + /* rate control*/ + EncArg.args.enc_init_mpeg4.in_RC_frm_enable = h263_arg->EnableFRMRateControl; + if ((h263_arg->QSCodeMin > 51) || (h263_arg->QSCodeMax > 51)) { + LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_RC_qbound = ENC_RC_QBOUND(h263_arg->QSCodeMin, h263_arg->QSCodeMax); + EncArg.args.enc_init_mpeg4.in_RC_rpara = h263_arg->CBRPeriodRf; + + /* pad control */ + EncArg.args.enc_init_mpeg4.in_pad_ctrl_on = h263_arg->PadControlOn; + if ((h263_arg->LumaPadVal > 255) || (h263_arg->CbPadVal > 255) || (h263_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_luma_pad_val = h263_arg->LumaPadVal; + EncArg.args.enc_init_mpeg4.in_cb_pad_val = h263_arg->CbPadVal; + EncArg.args.enc_init_mpeg4.in_cr_pad_val = h263_arg->CrPadVal; + + EncArg.args.enc_init_mpeg4.in_RC_framerate = h263_arg->FrameRate; + EncArg.args.enc_init_mpeg4.in_RC_bitrate = h263_arg->Bitrate; + if (h263_arg->FrameQp > 51) { + LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_mpeg4.in_frame_qp = h263_arg->FrameQp; + if (h263_arg->FrameQp_P) + EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp_P; + else + EncArg.args.enc_init_mpeg4.in_frame_P_qp = h263_arg->FrameQp; + + break; + + case H264_ENC: + h264_arg = (SSBSIP_MFC_ENC_H264_PARAM *)param; + + EncArg.args.enc_init_h264.in_codec_type = H264_ENC; + EncArg.args.enc_init_h264.in_profile_level = ENC_PROFILE_LEVEL(h264_arg->ProfileIDC, h264_arg->LevelIDC); + + EncArg.args.enc_init_h264.in_width = h264_arg->SourceWidth; + EncArg.args.enc_init_h264.in_height = h264_arg->SourceHeight; + EncArg.args.enc_init_h264.in_gop_num = h264_arg->IDRPeriod; + + if ((h264_arg->NumberRefForPframes > 2) || (h264_arg->NumberReferenceFrames > 2)) { + LOGE("SsbSipMfcEncInit: No such ref Num is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_reference_num = h264_arg->NumberReferenceFrames; + EncArg.args.enc_init_h264.in_ref_num_p = h264_arg->NumberRefForPframes; + + if ((h264_arg->SliceMode == 0) || (h264_arg->SliceMode == 1) || + (h264_arg->SliceMode == 2) || (h264_arg->SliceMode == 4)) { + EncArg.args.enc_init_h264.in_MS_mode = h264_arg->SliceMode; + } else { + LOGE("SsbSipMfcEncInit: No such slice mode is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_MS_size = h264_arg->SliceArgument; + + if (h264_arg->NumberBFrames > 2) { + LOGE("SsbSipMfcEncInit: No such BframeNum is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_BframeNum = h264_arg->NumberBFrames; + + EncArg.args.enc_init_h264.in_deblock_filt = h264_arg->LoopFilterDisable; + if ((abs(h264_arg->LoopFilterAlphaC0Offset) > 6) || (abs(h264_arg->LoopFilterBetaOffset) > 6)) { + LOGE("SsbSipMfcEncInit: No such AlphaC0Offset or BetaOffset is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_deblock_alpha_C0 = h264_arg->LoopFilterAlphaC0Offset; + EncArg.args.enc_init_h264.in_deblock_beta = h264_arg->LoopFilterBetaOffset; + + EncArg.args.enc_init_h264.in_symbolmode = h264_arg->SymbolMode; + EncArg.args.enc_init_h264.in_interlace_mode = h264_arg->PictureInterlace; + EncArg.args.enc_init_h264.in_transform8x8_mode = h264_arg->Transform8x8Mode; + + EncArg.args.enc_init_h264.in_mb_refresh = h264_arg->RandomIntraMBRefresh; + + /* pad control */ + EncArg.args.enc_init_h264.in_pad_ctrl_on = h264_arg->PadControlOn; + if ((h264_arg->LumaPadVal > 255) || (h264_arg->CbPadVal > 255) || (h264_arg->CrPadVal > 255)) { + LOGE("SsbSipMfcEncInit: No such Pad value is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_luma_pad_val = h264_arg->LumaPadVal; + EncArg.args.enc_init_h264.in_cb_pad_val = h264_arg->CbPadVal; + EncArg.args.enc_init_h264.in_cr_pad_val = h264_arg->CrPadVal; + + /* rate control*/ + EncArg.args.enc_init_h264.in_RC_frm_enable = h264_arg->EnableFRMRateControl; + EncArg.args.enc_init_h264.in_RC_mb_enable = h264_arg->EnableMBRateControl; + EncArg.args.enc_init_h264.in_RC_framerate = h264_arg->FrameRate; + EncArg.args.enc_init_h264.in_RC_bitrate = h264_arg->Bitrate; + if (h264_arg->FrameQp > 51) { + LOGE("SsbSipMfcEncInit: No such FrameQp is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_frame_qp = h264_arg->FrameQp; + if (h264_arg->FrameQp_P) + EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp_P; + else + EncArg.args.enc_init_h264.in_frame_P_qp = h264_arg->FrameQp; + if (h264_arg->FrameQp_B) + EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp_B; + else + EncArg.args.enc_init_h264.in_frame_B_qp = h264_arg->FrameQp; + + if ((h264_arg->QSCodeMin > 51) || (h264_arg->QSCodeMax > 51)) { + LOGE("SsbSipMfcEncInit: No such Min/Max QP is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + EncArg.args.enc_init_h264.in_RC_qbound = ENC_RC_QBOUND(h264_arg->QSCodeMin, h264_arg->QSCodeMax); + EncArg.args.enc_init_h264.in_RC_rpara = h264_arg->CBRPeriodRf; + EncArg.args.enc_init_h264.in_RC_mb_dark_disable = h264_arg->DarkDisable; + EncArg.args.enc_init_h264.in_RC_mb_smooth_disable = h264_arg->SmoothDisable; + EncArg.args.enc_init_h264.in_RC_mb_static_disable = h264_arg->StaticDisable; + EncArg.args.enc_init_h264.in_RC_mb_activity_disable = h264_arg->ActivityDisable; + + /* default setting */ + EncArg.args.enc_init_h264.in_md_interweight_pps = 0; + EncArg.args.enc_init_h264.in_md_intraweight_pps = 0; + break; + + default: + break; + } + + EncArg.args.enc_init_mpeg4.in_mapped_addr = pCTX->mapped_addr; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_INIT, &EncArg); + if (EncArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcEncInit: IOCTL_MFC_ENC_INIT (%d) failed\n", EncArg.ret_code); + return MFC_RET_ENC_INIT_FAIL; + } + + pCTX->virStrmBuf = EncArg.args.enc_init_mpeg4.out_u_addr.strm_ref_y; + pCTX->phyStrmBuf = EncArg.args.enc_init_mpeg4.out_p_addr.strm_ref_y; + pCTX->sizeStrmBuf = MAX_ENCODER_OUTPUT_BUFFER_SIZE; + pCTX->encodedHeaderSize = EncArg.args.enc_init_mpeg4.out_header_size; + + pCTX->virMvRefYC = EncArg.args.enc_init_mpeg4.out_u_addr.mv_ref_yc; + + pCTX->inter_buff_status |= MFC_USE_STRM_BUFF; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args EncArg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncExe: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + memset(&EncArg, 0x00, sizeof(mfc_common_args)); + + EncArg.args.enc_exe.in_codec_type = pCTX->codec_type; + EncArg.args.enc_exe.in_Y_addr = (unsigned int)pCTX->phyFrmBuf.luma; + EncArg.args.enc_exe.in_CbCr_addr = (unsigned int)pCTX->phyFrmBuf.chroma; + EncArg.args.enc_exe.in_Y_addr_vir = (unsigned int)pCTX->virFrmBuf.luma; + EncArg.args.enc_exe.in_CbCr_addr_vir = (unsigned int)pCTX->virFrmBuf.chroma; + EncArg.args.enc_exe.in_strm_st = (unsigned int)pCTX->phyStrmBuf; + EncArg.args.enc_exe.in_strm_end = (unsigned int)pCTX->phyStrmBuf + pCTX->sizeStrmBuf; + EncArg.args.enc_exe.in_frametag = pCTX->in_frametag; + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_ENC_EXE, &EncArg); + if (EncArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcDecExe: IOCTL_MFC_ENC_EXE failed(ret : %d)\n", EncArg.ret_code); + return MFC_RET_ENC_EXE_ERR; + } + + pCTX->encodedDataSize = EncArg.args.enc_exe.out_encoded_size; + pCTX->encodedframeType = EncArg.args.enc_exe.out_frame_type; + pCTX->encoded_Y_paddr = EncArg.args.enc_exe.out_encoded_Y_paddr; + pCTX->encoded_C_paddr = EncArg.args.enc_exe.out_encoded_C_paddr; + pCTX->out_frametag_top = EncArg.args.enc_exe.out_frametag_top; + pCTX->out_frametag_bottom = EncArg.args.enc_exe.out_frametag_bottom; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args free_arg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncClose: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + if (pCTX->inter_buff_status & MFC_USE_YUV_BUFF) { + free_arg.args.mem_free.u_addr = pCTX->virFrmBuf.luma; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + if (pCTX->inter_buff_status & MFC_USE_STRM_BUFF) { + free_arg.args.mem_free.u_addr = pCTX->virStrmBuf; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + free_arg.args.mem_free.u_addr = pCTX->virMvRefYC; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_FREE_BUF, &free_arg); + } + + pCTX->inter_buff_status = MFC_USE_NONE; + + munmap((void *)pCTX->mapped_addr, MMAP_BUFFER_SIZE_MMAP); + close(pCTX->hMFC); + free(pCTX); + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args user_addr_arg, phys_addr_arg; + int y_size, c_size; + int aligned_y_size, aligned_c_size; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetInBuf: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + user_addr_arg.args.mem_alloc.codec_type = pCTX->codec_type; + + y_size = pCTX->width * pCTX->height; + c_size = (pCTX->width * pCTX->height) >> 1; + + aligned_y_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height)); + aligned_c_size = ALIGN_TO_8KB(ALIGN_TO_128B(pCTX->width) * ALIGN_TO_32B(pCTX->height/2)); + + /* Allocate luma & chroma buf */ + user_addr_arg.args.mem_alloc.buff_size = aligned_y_size + aligned_c_size; + user_addr_arg.args.mem_alloc.mapped_addr = pCTX->mapped_addr; + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_GET_IN_BUF, &user_addr_arg); + if (ret_code < 0) { + LOGE("SsbSipMfcEncGetInBuf: IOCTL_MFC_GET_IN_BUF failed\n"); + return MFC_RET_ENC_GET_INBUF_FAIL; + } + pCTX->virFrmBuf.luma = user_addr_arg.args.mem_alloc.out_uaddr; + pCTX->virFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_uaddr + (unsigned int)aligned_y_size; + pCTX->phyFrmBuf.luma = user_addr_arg.args.mem_alloc.out_paddr; + pCTX->phyFrmBuf.chroma = user_addr_arg.args.mem_alloc.out_paddr + (unsigned int)aligned_y_size; + + pCTX->sizeFrmBuf.luma = (unsigned int)y_size; + pCTX->sizeFrmBuf.chroma = (unsigned int)c_size; + pCTX->inter_buff_status |= MFC_USE_YUV_BUFF; + + input_info->YPhyAddr = (void*)pCTX->phyFrmBuf.luma; + input_info->CPhyAddr = (void*)pCTX->phyFrmBuf.chroma; + input_info->YVirAddr = (void*)pCTX->virFrmBuf.luma; + input_info->CVirAddr = (void*)pCTX->virFrmBuf.chroma; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetInBuf: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + LOGV("SsbSipMfcEncSetInBuf: input_info->YPhyAddr & input_info->CPhyAddr should be 64KB aligned\n"); + + pCTX = (_MFCLIB *)openHandle; + + pCTX->phyFrmBuf.luma = (unsigned int)input_info->YPhyAddr; + pCTX->phyFrmBuf.chroma = (unsigned int)input_info->CPhyAddr; + pCTX->virFrmBuf.luma = (unsigned int)input_info->YVirAddr; + pCTX->virFrmBuf.chroma = (unsigned int)input_info->CVirAddr; + + pCTX->sizeFrmBuf.luma = (unsigned int)input_info->YSize; + pCTX->sizeFrmBuf.chroma = (unsigned int)input_info->CSize; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetOutBuf: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + output_info->headerSize = pCTX->encodedHeaderSize; + output_info->dataSize = pCTX->encodedDataSize; + output_info->StrmPhyAddr = (void *)pCTX->phyStrmBuf; + output_info->StrmVirAddr = (void *)pCTX->virStrmBuf; + + if (pCTX->encodedframeType == 0) + output_info->frameType = MFC_FRAME_TYPE_NOT_CODED; + else if (pCTX->encodedframeType == 1) + output_info->frameType = MFC_FRAME_TYPE_I_FRAME; + else if (pCTX->encodedframeType == 2) + output_info->frameType = MFC_FRAME_TYPE_P_FRAME; + else if (pCTX->encodedframeType == 3) + output_info->frameType = MFC_FRAME_TYPE_B_FRAME; + else if (pCTX->encodedframeType == 4) + output_info->frameType = MFC_FRAME_TYPE_OTHERS; + else { + LOGE("Strange encoded frame type = %d\n", pCTX->encodedframeType); + return MFC_RET_INVALID_PARAM; + } + + output_info->encodedYPhyAddr = (void *)pCTX->encoded_Y_paddr; + output_info->encodedCPhyAddr = (void *)pCTX->encoded_C_paddr; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf(void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize) +{ + _MFCLIB *pCTX; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetOutBuf: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + + pCTX->phyStrmBuf = (int)phyOutbuf; + pCTX->virStrmBuf = (int)virOutbuf; + pCTX->sizeStrmBuf = outputBufferSize; + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args EncArg; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncSetConfig: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + if (value == NULL) { + LOGE("SsbSipMfcEncSetConfig: value is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&EncArg, 0x00, sizeof(mfc_common_args)); + + switch (conf_type) { + case MFC_ENC_SETCONF_FRAME_TYPE: + case MFC_ENC_SETCONF_CHANGE_FRAME_RATE: + case MFC_ENC_SETCONF_CHANGE_BIT_RATE: + case MFC_ENC_SETCONF_ALLOW_FRAME_SKIP: + EncArg.args.set_config.in_config_param = conf_type; + EncArg.args.set_config.in_config_value[0] = *((unsigned int *) value); + EncArg.args.set_config.in_config_value[1] = 0; + break; + + case MFC_ENC_SETCONF_FRAME_TAG: + pCTX->in_frametag = *((int *)value); + return MFC_RET_OK; + + default: + LOGE("SsbSipMfcEncSetConfig: No such conf_type is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + + ret_code = ioctl(pCTX->hMFC, IOCTL_MFC_SET_CONFIG, &EncArg); + if (EncArg.ret_code != MFC_RET_OK) { + LOGE("SsbSipMfcEncSetConfig: IOCTL_MFC_SET_CONFIG failed(ret : %d)\n", EncArg.ret_code); + return MFC_RET_ENC_SET_CONF_FAIL; + } + + return MFC_RET_OK; +} + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value) +{ + int ret_code; + _MFCLIB *pCTX; + mfc_common_args EncArg; + + pCTX = (_MFCLIB *)openHandle; + + if (openHandle == NULL) { + LOGE("SsbSipMfcEncGetConfig: openHandle is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + if (value == NULL) { + LOGE("SsbSipMfcEncGetConfig: value is NULL\n"); + return MFC_RET_INVALID_PARAM; + } + + pCTX = (_MFCLIB *)openHandle; + memset(&EncArg, 0x00, sizeof(mfc_common_args)); + + switch (conf_type) { + case MFC_ENC_GETCONF_FRAME_TAG: + *((unsigned int *)value) = pCTX->out_frametag_top; + break; + + default: + LOGE("SsbSipMfcEncGetConfig: No such conf_type is supported.\n"); + return MFC_RET_INVALID_PARAM; + } + + return MFC_RET_OK; +} diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h new file mode 100644 index 0000000..e083998 --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/SsbSipMfcApi.h @@ -0,0 +1,330 @@ +/* + * Copyright 2010 Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SSBSIP_MFC_API_H_ +#define _SSBSIP_MFC_API_H_ + +/*--------------------------------------------------------------------------------*/ +/* Definition */ +/*--------------------------------------------------------------------------------*/ +#define MAX_DECODER_INPUT_BUFFER_SIZE (1024 * 3072) +#define MAX_ENCODER_OUTPUT_BUFFER_SIZE (1024 * 3072) + +#define SUPPORT_1080P 1 + +#if SUPPORT_1080P +#define MMAP_BUFFER_SIZE_MMAP (63*1024*1024) +#else +#define MMAP_BUFFER_SIZE_MMAP (49*1024*1024) +#endif + +#define S5PC110_MFC_DEV_NAME "/dev/s3c-mfc" + +/*--------------------------------------------------------------------------------*/ +/* Structure and Type */ +/*--------------------------------------------------------------------------------*/ +typedef enum { + H264_DEC, + VC1_DEC, /* VC1 advaced Profile decoding */ + MPEG4_DEC, + XVID_DEC, + MPEG1_DEC, + MPEG2_DEC, + H263_DEC, + VC1RCV_DEC, /* VC1 simple/main profile decoding */ + FIMV1_DEC, + FIMV2_DEC, + FIMV3_DEC, + FIMV4_DEC, + H264_ENC, + MPEG4_ENC, + H263_ENC, + UNKNOWN_TYPE +} SSBSIP_MFC_CODEC_TYPE; + +typedef enum { + DONT_CARE = 0, + I_FRAME = 1, + NOT_CODED = 2 +} SSBSIP_MFC_FORCE_SET_FRAME_TYPE; + +typedef enum { + MFC_DEC_SETCONF_POST_ENABLE = 1, + MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, + MFC_DEC_SETCONF_DISPLAY_DELAY, + MFC_DEC_SETCONF_IS_LAST_FRAME, + MFC_DEC_SETCONF_SLICE_ENABLE, + MFC_DEC_SETCONF_CRC_ENABLE, + MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, + MFC_DEC_SETCONF_FRAME_TAG, + MFC_DEC_GETCONF_CRC_DATA, + MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, + MFC_DEC_GETCONF_CROP_INFO, + MFC_DEC_GETCONF_FRAME_TAG +} SSBSIP_MFC_DEC_CONF; + +typedef enum { + MFC_ENC_SETCONF_FRAME_TYPE = 100, + MFC_ENC_SETCONF_CHANGE_FRAME_RATE, + MFC_ENC_SETCONF_CHANGE_BIT_RATE, + MFC_ENC_SETCONF_FRAME_TAG, + MFC_ENC_SETCONF_ALLOW_FRAME_SKIP, + MFC_ENC_GETCONF_FRAME_TAG +} SSBSIP_MFC_ENC_CONF; + +typedef enum { + MFC_GETOUTBUF_STATUS_NULL = 0, + MFC_GETOUTBUF_DECODING_ONLY = 1, + MFC_GETOUTBUF_DISPLAY_DECODING, + MFC_GETOUTBUF_DISPLAY_ONLY, + MFC_GETOUTBUF_DISPLAY_END +} SSBSIP_MFC_DEC_OUTBUF_STATUS; + +typedef enum { + MFC_FRAME_TYPE_NOT_CODED, + MFC_FRAME_TYPE_I_FRAME, + MFC_FRAME_TYPE_P_FRAME, + MFC_FRAME_TYPE_B_FRAME, + MFC_FRAME_TYPE_OTHERS +} SSBSIP_MFC_FRAME_TYPE; + +typedef enum { + MFC_RET_OK = 1, + MFC_RET_FAIL = -1000, + MFC_RET_OPEN_FAIL = -1001, + MFC_RET_CLOSE_FAIL = -1002, + + MFC_RET_DEC_INIT_FAIL = -2000, + MFC_RET_DEC_EXE_TIME_OUT = -2001, + MFC_RET_DEC_EXE_ERR = -2002, + MFC_RET_DEC_GET_INBUF_FAIL = -2003, + MFC_RET_DEC_SET_INBUF_FAIL = -2004, + MFC_RET_DEC_GET_OUTBUF_FAIL = -2005, + MFC_RET_DEC_GET_CONF_FAIL = -2006, + MFC_RET_DEC_SET_CONF_FAIL = -2007, + + MFC_RET_ENC_INIT_FAIL = -3000, + MFC_RET_ENC_EXE_TIME_OUT = -3001, + MFC_RET_ENC_EXE_ERR = -3002, + MFC_RET_ENC_GET_INBUF_FAIL = -3003, + MFC_RET_ENC_SET_INBUF_FAIL = -3004, + MFC_RET_ENC_GET_OUTBUF_FAIL = -3005, + MFC_RET_ENC_SET_OUTBUF_FAIL = -3006, + MFC_RET_ENC_GET_CONF_FAIL = -3007, + MFC_RET_ENC_SET_CONF_FAIL = -3008, + + MFC_RET_INVALID_PARAM = -4000 +} SSBSIP_MFC_ERROR_CODE; + +typedef struct { + void *YPhyAddr; // [OUT] physical address of Y + void *CPhyAddr; // [OUT] physical address of CbCr + void *YVirAddr; // [OUT] virtual address of Y + void *CVirAddr; // [OUT] virtual address of CbCr + + int img_width; // [OUT] width of real image + int img_height; // [OUT] height of real image + int buf_width; // [OUT] width aligned to 16 + int buf_height; // [OUT] height alighed to 16 + + int timestamp_top; // [OUT] timestamp of top filed(This is used for interlaced stream) + int timestamp_bottom; // [OUT] timestamp of bottom filed(This is used for interlaced stream) + int consumedByte; // [OUT] the number of byte consumed during decoding + int res_change; // [OUT] whether resolution is changed or not. 0: not change, 1: increased, 2: decreased + int crop_top_offset; // [OUT] crop information, top_offset + int crop_bottom_offset; // [OUT] crop information, bottom_offset + int crop_left_offset; // [OUT] crop information, left_offset + int crop_right_offset; // [OUT] crop information, right_offset +} SSBSIP_MFC_DEC_OUTPUT_INFO; + +typedef struct { + void *YPhyAddr; // [IN/OUT] physical address of Y + void *CPhyAddr; // [IN/OUT] physical address of CbCr + void *YVirAddr; // [IN/OUT] virtual address of Y + void *CVirAddr; // [IN/OUT] virtual address of CbCr + int YSize; // [IN/OUT] input size of Y data + int CSize; // [IN/OUT] input size of CbCr data +} SSBSIP_MFC_ENC_INPUT_INFO; + +typedef struct { + unsigned int dataSize; // [OUT] encoded data size(without header) + unsigned int headerSize; // [OUT] encoded header size + unsigned int frameType; // [OUT] frame type of encoded stream + void *StrmPhyAddr; // [OUT] physical address of Y + void *StrmVirAddr; // [OUT] virtual address of Y + void *encodedYPhyAddr; // [OUT] physical address of Y which is flushed + void *encodedCPhyAddr; // [OUT] physical address of C which is flushed +} SSBSIP_MFC_ENC_OUTPUT_INFO; + +typedef struct { + // common parameters + SSBSIP_MFC_CODEC_TYPE codecType; // [IN] codec type + int SourceWidth; // [IN] width of video to be encoded + int SourceHeight; // [IN] height of video to be encoded + int IDRPeriod; // [IN] GOP number(interval of I-frame) + int SliceMode; // [IN] Multi slice mode + int RandomIntraMBRefresh; // [IN] cyclic intra refresh + int EnableFRMRateControl; // [IN] frame based rate control enable + int Bitrate; // [IN] rate control parameter(bit rate) + int FrameQp; // [IN] The quantization parameter of the frame + int FrameQp_P; // [IN] The quantization parameter of the P frame + int QSCodeMax; // [IN] Maximum Quantization value + int QSCodeMin; // [IN] Minimum Quantization value + int CBRPeriodRf; // [IN] Reaction coefficient parameter for rate control + int PadControlOn; // [IN] Enable padding control + int LumaPadVal; // [IN] Luma pel value used to fill padding area + int CbPadVal; // [IN] CB pel value used to fill padding area + int CrPadVal; // [IN] CR pel value used to fill padding area + + // H.264 specific parameters + int ProfileIDC; // [IN] profile + int LevelIDC; // [IN] level + int FrameQp_B; // [IN] The quantization parameter of the B frame + int FrameRate; // [IN] rate control parameter(frame rate) + int SliceArgument; // [IN] MB number or byte number + int NumberBFrames; // [IN] The number of consecutive B frame inserted + int NumberReferenceFrames; // [IN] The number of reference pictures used + int NumberRefForPframes; // [IN] The number of reference pictures used for encoding P pictures + int LoopFilterDisable; // [IN] disable the loop filter + int LoopFilterAlphaC0Offset; // [IN] Alpha & C0 offset for H.264 loop filter + int LoopFilterBetaOffset; // [IN] Beta offset for H.264 loop filter + int SymbolMode; // [IN] The mode of entropy coding(CABAC, CAVLC) + int PictureInterlace; // [IN] Enables the interlace mode + int Transform8x8Mode; // [IN] Allow 8x8 transform(This is allowed only for high profile) + int EnableMBRateControl; // [IN] Enable macroblock-level rate control + int DarkDisable; // [IN] Disable adaptive rate control on dark region + int SmoothDisable; // [IN] Disable adaptive rate control on smooth region + int StaticDisable; // [IN] Disable adaptive rate control on static region + int ActivityDisable; // [IN] Disable adaptive rate control on high activity region +} SSBSIP_MFC_ENC_H264_PARAM; + +typedef struct { + // common parameters + SSBSIP_MFC_CODEC_TYPE codecType; // [IN] codec type + int SourceWidth; // [IN] width of video to be encoded + int SourceHeight; // [IN] height of video to be encoded + int IDRPeriod; // [IN] GOP number(interval of I-frame) + int SliceMode; // [IN] Multi slice mode + int RandomIntraMBRefresh; // [IN] cyclic intra refresh + int EnableFRMRateControl; // [IN] frame based rate control enable + int Bitrate; // [IN] rate control parameter(bit rate) + int FrameQp; // [IN] The quantization parameter of the frame + int FrameQp_P; // [IN] The quantization parameter of the P frame + int QSCodeMax; // [IN] Maximum Quantization value + int QSCodeMin; // [IN] Minimum Quantization value + int CBRPeriodRf; // [IN] Reaction coefficient parameter for rate control + int PadControlOn; // [IN] Enable padding control + int LumaPadVal; // [IN] Luma pel value used to fill padding area + int CbPadVal; // [IN] CB pel value used to fill padding area + int CrPadVal; // [IN] CR pel value used to fill padding area + + // MPEG4 specific parameters + int ProfileIDC; // [IN] profile + int LevelIDC; // [IN] level + int FrameQp_B; // [IN] The quantization parameter of the B frame + int TimeIncreamentRes; // [IN] frame rate + int VopTimeIncreament; // [IN] frame rate + int SliceArgument; // [IN] MB number or byte number + int NumberBFrames; // [IN] The number of consecutive B frame inserted + int DisableQpelME; // [IN] disable quarter-pixel motion estimation +} SSBSIP_MFC_ENC_MPEG4_PARAM; + +typedef struct { + // common parameters + SSBSIP_MFC_CODEC_TYPE codecType; // [IN] codec type + int SourceWidth; // [IN] width of video to be encoded + int SourceHeight; // [IN] height of video to be encoded + int IDRPeriod; // [IN] GOP number(interval of I-frame) + int SliceMode; // [IN] Multi slice mode + int RandomIntraMBRefresh; // [IN] cyclic intra refresh + int EnableFRMRateControl; // [IN] frame based rate control enable + int Bitrate; // [IN] rate control parameter(bit rate) + int FrameQp; // [IN] The quantization parameter of the frame + int FrameQp_P; // [IN] The quantization parameter of the P frame + int QSCodeMax; // [IN] Maximum Quantization value + int QSCodeMin; // [IN] Minimum Quantization value + int CBRPeriodRf; // [IN] Reaction coefficient parameter for rate control + int PadControlOn; // [IN] Enable padding control + int LumaPadVal; // [IN] Luma pel value used to fill padding area + int CbPadVal; // [IN] CB pel value used to fill padding area + int CrPadVal; // [IN] CR pel value used to fill padding area + + // H.263 specific parameters + int FrameRate; // [IN] rate control parameter(frame rate) +} SSBSIP_MFC_ENC_H263_PARAM; + +typedef struct { + int width; + int height; + int buf_width; + int buf_height; +} SSBSIP_MFC_IMG_RESOLUTION; + +typedef struct { + int crop_top_offset; + int crop_bottom_offset; + int crop_left_offset; + int crop_right_offset; +} SSBSIP_MFC_CROP_INFORMATION; + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------------*/ +/* Format Conversion API */ +/*--------------------------------------------------------------------------------*/ +void Y_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size); +void CbCr_tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size); + +/*--------------------------------------------------------------------------------*/ +/* Decoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcDecOpen(void); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecInit(void *openHandle, SSBSIP_MFC_CODEC_TYPE codec_type, int Frameleng); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecExe(void *openHandle, int lengthBufFill); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecClose(void *openHandle); + +void *SsbSipMfcDecGetInBuf(void *openHandle, void **phyInBuf, int inputBufferSize); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetInBuf(void *openHandle, void *phyInBuf, void *virInBuf, int inputBufferSize); + +SSBSIP_MFC_DEC_OUTBUF_STATUS SsbSipMfcDecGetOutBuf(void *openHandle, SSBSIP_MFC_DEC_OUTPUT_INFO *output_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecSetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcDecGetConfig(void *openHandle, SSBSIP_MFC_DEC_CONF conf_type, void *value); + +/*--------------------------------------------------------------------------------*/ +/* Encoding APIs */ +/*--------------------------------------------------------------------------------*/ +void *SsbSipMfcEncOpen(void); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncInit(void *openHandle, void *param); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncExe(void *openHandle); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncClose(void *openHandle); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetInBuf(void *openHandle, SSBSIP_MFC_ENC_INPUT_INFO *input_info); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetOutBuf(void *openHandle, SSBSIP_MFC_ENC_OUTPUT_INFO *output_info); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetOutBuf (void *openHandle, void *phyOutbuf, void *virOutbuf, int outputBufferSize); + +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncSetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); +SSBSIP_MFC_ERROR_CODE SsbSipMfcEncGetConfig(void *openHandle, SSBSIP_MFC_ENC_CONF conf_type, void *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _SSBSIP_MFC_API_H_ */ diff --git a/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h new file mode 100644 index 0000000..e7e23c3 --- /dev/null +++ b/sec_mm/sec_omx/sec_codecs/video/mfc_c110/include/mfc_interface.h @@ -0,0 +1,333 @@ +/* + * Copyright 2010 Samsung Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MFC_INTERFACE_H_ +#define _MFC_INTERFACE_H_ + +#include "SsbSipMfcApi.h" + +#define IOCTL_MFC_DEC_INIT 0x00800001 +#define IOCTL_MFC_ENC_INIT 0x00800002 +#define IOCTL_MFC_DEC_EXE 0x00800003 +#define IOCTL_MFC_ENC_EXE 0x00800004 + +#define IOCTL_MFC_GET_IN_BUF 0x00800010 +#define IOCTL_MFC_FREE_BUF 0x00800011 +#define IOCTL_MFC_GET_PHYS_ADDR 0x00800012 + +#define IOCTL_MFC_SET_CONFIG 0x00800101 +#define IOCTL_MFC_GET_CONFIG 0x00800102 + +/* MFC H/W support maximum 32 extra DPB */ +#define MFC_MAX_EXTRA_DPB 5 + +#define ENC_PROFILE_LEVEL(profile, level) ((profile) | ((level) << 8)) + +#define ENC_PROFILE_MPEG4_SP 0 +#define ENC_PROFILE_MPEG4_ASP 1 +#define ENC_PROFILE_H264_BP 0 +#define ENC_PROFILE_H264_MAIN 1 +#define ENC_PROFILE_H264_HIGH 2 + +#define ENC_RC_DISABLE 0 +#define ENC_RC_ENABLE_MACROBLOCK 1 +#define ENC_RC_ENABLE_FRAME 2 + +#define ENC_RC_QBOUND(min_qp, max_qp) ((min_qp) | ((max_qp) << 8)) +#define ENC_RC_MB_CTRL_DARK_DISABLE (1 << 3) +#define ENC_RC_MB_CTRL_SMOOTH_DISABLE (1 << 2) +#define ENC_RC_MB_CTRL_STATIC_DISABLE (1 << 1) +#define ENC_RC_MB_CTRL_ACTIVITY_DISABLE (1 << 0) + +#define ALIGN_TO_16B(x) ((((x) + (1 << 4) - 1) >> 4) << 4) +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_64B(x) ((((x) + (1 << 6) - 1) >> 6) << 6) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_2KB(x) ((((x) + (1 << 11) - 1) >> 11) << 11) +#define ALIGN_TO_4KB(x) ((((x) + (1 << 12) - 1) >> 12) << 12) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) +#define ALIGN_TO_64KB(x) ((((x) + (1 << 16) - 1) >> 16) << 16) +#define ALIGN_TO_128KB(x) ((((x) + (1 << 17) - 1) >> 17) << 17) + +typedef struct { + int luma0; // per frame (or top field) + int chroma0; // per frame (or top field) + int luma1; // per frame (or bottom field) + int chroma1; // per frame (or bottom field) +} MFC_CRC_DATA; + +typedef enum { + MFC_USE_NONE = 0x00, + MFC_USE_YUV_BUFF = 0x01, + MFC_USE_STRM_BUFF = 0x10 +} mfc_interbuff_status; + +typedef enum { + MFC_UNPACKED_PB = 0, + MFC_PACKED_PB = 1 +} mfc_packed_mode; + +typedef struct tag_strm_ref_buf_arg { + unsigned int strm_ref_y; + unsigned int mv_ref_yc; +} mfc_strm_ref_buf_arg_t; + +typedef struct tag_frame_buf_arg { + unsigned int luma; + unsigned int chroma; +} mfc_frame_buf_arg_t; + +typedef struct { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_width; /* [IN] width of YUV420 frame to be encoded */ + int in_height; /* [IN] height of YUV420 frame to be encoded */ + int in_profile_level; /* [IN] profile & level */ + int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ + int in_frame_qp; /* [IN] the quantization parameter of the frame */ + int in_frame_P_qp; /* [IN] the quantization parameter of the P frame */ + int in_frame_B_qp; /* [IN] the quantization parameter of the B frame */ + + int in_RC_frm_enable; /* [IN] RC enable (0:disable, 1:frame level RC) */ + int in_RC_framerate; /* [IN] RC parameter (framerate) */ + int in_RC_bitrate; /* [IN] RC parameter (bitrate in kbps) */ + int in_RC_qbound; /* [IN] RC parameter (Q bound) */ + int in_RC_rpara; /* [IN] RC parameter (Reaction Coefficient) */ + + int in_MS_mode; /* [IN] Multi-slice mode (0:single, 1:multiple) */ + int in_MS_size; /* [IN] Multi-slice size (in num. of mb or byte) */ + int in_mb_refresh; /* [IN] Macroblock refresh */ + int in_interlace_mode; /* [IN] interlace mode(0:progressive, 1:interlace) */ + int in_BframeNum; /* [IN] B frame number */ + + int in_pad_ctrl_on; /* [IN] Enable (1) / Disable (0) padding */ + int in_luma_pad_val; /* [IN] pad value if pad_ctrl_on is Enable */ + int in_cb_pad_val; + int in_cr_pad_val; + + unsigned int in_mapped_addr; + mfc_strm_ref_buf_arg_t out_u_addr; + mfc_strm_ref_buf_arg_t out_p_addr; + mfc_strm_ref_buf_arg_t out_buf_size; + unsigned int out_header_size; + + /* MPEG4 Only */ + int in_qpelME_enable; /* [IN] Quarter-pel MC enable(1:enable, 0:disable) */ + int in_time_increament_res; /* [IN] time increment resolution */ + int in_time_vop_time_increament; /* [IN] time increment */ +} mfc_enc_init_mpeg4_arg_t; + +typedef mfc_enc_init_mpeg4_arg_t mfc_enc_init_h263_arg_t; + +typedef struct { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + int in_width; /* [IN] width of YUV420 frame to be encoded */ + int in_height; /* [IN] height of YUV420 frame to be encoded */ + int in_profile_level; /* [IN] profile & level */ + int in_gop_num; /* [IN] GOP Number (interval of I-frame) */ + int in_frame_qp; /* [IN] the quantization parameter of the frame */ + int in_frame_P_qp; /* [IN] the quantization parameter of the P frame */ + int in_frame_B_qp; /* [IN] the quantization parameter of the B frame */ + + int in_RC_frm_enable; /* [IN] RC enable (0:disable, 1:frame level RC) */ + int in_RC_framerate; /* [IN] RC parameter (framerate) */ + int in_RC_bitrate; /* [IN] RC parameter (bitrate in kbps) */ + int in_RC_qbound; /* [IN] RC parameter (Q bound) */ + int in_RC_rpara; /* [IN] RC parameter (Reaction Coefficient) */ + + int in_MS_mode; /* [IN] Multi-slice mode (0:single, 1:multiple) */ + int in_MS_size; /* [IN] Multi-slice size (in num. of mb or byte) */ + int in_mb_refresh; /* [IN] Macroblock refresh */ + int in_interlace_mode; /* [IN] interlace mode(0:progressive, 1:interlace) */ + int in_BframeNum; + + int in_pad_ctrl_on; /* [IN] Enable padding control */ + int in_luma_pad_val; /* [IN] Luma pel value used to fill padding area */ + int in_cb_pad_val; /* [IN] CB pel value used to fill padding area */ + int in_cr_pad_val; /* [IN] CR pel value used to fill padding area */ + + unsigned int in_mapped_addr; + mfc_strm_ref_buf_arg_t out_u_addr; + mfc_strm_ref_buf_arg_t out_p_addr; + mfc_strm_ref_buf_arg_t out_buf_size; + unsigned int out_header_size; + + /* H264 Only */ + int in_RC_mb_enable; /* [IN] RC enable (0:disable, 1:MB level RC) */ + int in_reference_num; /* [IN] The number of reference pictures used */ + int in_ref_num_p; /* [IN] The number of reference pictures used for P pictures */ + int in_RC_mb_dark_disable; /* [IN] Disable adaptive rate control on dark region */ + int in_RC_mb_smooth_disable; /* [IN] Disable adaptive rate control on smooth region */ + int in_RC_mb_static_disable; /* [IN] Disable adaptive rate control on static region */ + int in_RC_mb_activity_disable; /* [IN] Disable adaptive rate control on static region */ + int in_deblock_filt; /* [IN] disable the loop filter */ + int in_deblock_alpha_C0; /* [IN] Alpha & C0 offset for H.264 loop filter */ + int in_deblock_beta; /* [IN] Beta offset for H.264 loop filter */ + int in_symbolmode; /* [IN] The mode of entropy coding(CABAC, CAVLC) */ + int in_transform8x8_mode; /* [IN] Allow 8x8 transform(only for high profile) */ + int in_md_interweight_pps; /* [IN] Inter weighted parameter for mode decision */ + int in_md_intraweight_pps; /* [IN] Intra weighted parameter for mode decision */ +} mfc_enc_init_h264_arg_t; + +typedef struct { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_Y_addr; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_Y_addr_vir; /* [IN] In-buffer addr of Y component */ + unsigned int in_CbCr_addr_vir; /* [IN] In-buffer addr of CbCr component */ + unsigned int in_strm_st; /* [IN] Out-buffer start addr of encoded strm */ + unsigned int in_strm_end; /* [IN] Out-buffer end addr of encoded strm */ + int in_frametag; /* [IN] unique frame ID */ + + unsigned int out_frame_type; /* [OUT] frame type */ + int out_encoded_size; /* [OUT] Length of Encoded video stream */ + unsigned int out_encoded_Y_paddr; /* [OUT] physical Y address which is flushed */ + unsigned int out_encoded_C_paddr; /* [OUT] physical C address which is flushed */ + int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ + int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */ +} mfc_enc_exe_arg; + +typedef struct { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_strm_buf; /* [IN] the physical address of STRM_BUF */ + int in_strm_size; /* [IN] size of video stream filled in STRM_BUF */ + int in_packed_PB; /* [IN] Is packed PB frame or not, 1: packedPB 0: unpacked */ + + int out_img_width; /* [OUT] width of YUV420 frame */ + int out_img_height; /* [OUT] height of YUV420 frame */ + int out_buf_width; /* [OUT] width of YUV420 frame */ + int out_buf_height; /* [OUT] height of YUV420 frame */ + int out_dpb_cnt; /* [OUT] the number of buffers which is nessary during decoding */ + + int out_crop_top_offset; /* [OUT] crop information, top offset */ + int out_crop_bottom_offset; /* [OUT] crop information, bottom offset */ + int out_crop_left_offset; /* [OUT] crop information, left offset */ + int out_crop_right_offset; /* [OUT] crop information, right offset */ + + mfc_frame_buf_arg_t in_frm_buf; /* [IN] the address of dpb FRAME_BUF */ + mfc_frame_buf_arg_t in_frm_size; /* [IN] size of dpb FRAME_BUF */ + unsigned int in_mapped_addr; + + mfc_frame_buf_arg_t out_u_addr; + mfc_frame_buf_arg_t out_p_addr; + mfc_frame_buf_arg_t out_frame_buf_size; +} mfc_dec_init_arg_t; + +typedef struct { + SSBSIP_MFC_CODEC_TYPE in_codec_type; /* [IN] codec type */ + unsigned int in_strm_buf; /* [IN] the physical address of STRM_BUF */ + int in_strm_size; /* [IN] Size of video stream filled in STRM_BUF */ + mfc_frame_buf_arg_t in_frm_buf; /* [IN] the address of dpb FRAME_BUF */ + mfc_frame_buf_arg_t in_frm_size; /* [IN] size of dpb FRAME_BUF */ + int in_frametag; /* [IN] unique frame ID */ + + unsigned int out_display_Y_addr; /* [OUT] the physical address of display buf */ + unsigned int out_display_C_addr; /* [OUT] the physical address of display buf */ + int out_display_status; /* [OUT] whether display frame exist or not. */ + int out_timestamp_top; /* [OUT] presentation time of an output frame or top field */ + int out_timestamp_bottom; /* [OUT] presentation time of bottom field */ + int out_consume_bytes; /* [OUT] consumed bytes when decoding finished */ + int out_frametag_top; /* [OUT] unique frame ID of an output frame or top field */ + int out_frametag_bottom; /* [OUT] unique frame ID of bottom field */ + int out_res_change; /* [OUT] whether resolution is changed or not (0, 1, 2) */ + int out_crop_top_offset; /* [OUT] crop information, top offset */ + int out_crop_bottom_offset; /* [OUT] crop information, bottom offset */ + int out_crop_left_offset; /* [OUT] crop information, left offset */ + int out_crop_right_offset; /* [OUT] crop information, right offset */ +} mfc_dec_exe_arg_t; + +typedef struct { + int in_config_param; /* [IN] Configurable parameter type */ + int out_config_value[4]; /* [IN] Values to get for the configurable parameter. */ +} mfc_get_config_arg_t; + +typedef struct { + int in_config_param; /* [IN] Configurable parameter type */ + int in_config_value[2]; /* [IN] Values to be set for the configurable parameter. */ + int out_config_value_old[2]; /* [OUT] Old values of the configurable parameters */ +} mfc_set_config_arg_t; + +typedef struct tag_get_phys_addr_arg +{ + unsigned int u_addr; + unsigned int p_addr; +} mfc_get_phys_addr_arg_t; + +typedef struct tag_mem_alloc_arg +{ + SSBSIP_MFC_CODEC_TYPE codec_type; + int buff_size; + unsigned int mapped_addr; + unsigned int out_uaddr; + unsigned int out_paddr; +} mfc_mem_alloc_arg_t; + +typedef struct tag_mem_free_arg_t +{ + unsigned int u_addr; +} mfc_mem_free_arg_t; + +typedef union { + mfc_enc_init_mpeg4_arg_t enc_init_mpeg4; + mfc_enc_init_h263_arg_t enc_init_h263; + mfc_enc_init_h264_arg_t enc_init_h264; + mfc_enc_exe_arg enc_exe; + + mfc_dec_init_arg_t dec_init; + mfc_dec_exe_arg_t dec_exe; + + mfc_get_config_arg_t get_config; + mfc_set_config_arg_t set_config; + + mfc_mem_alloc_arg_t mem_alloc; + mfc_mem_free_arg_t mem_free; + mfc_get_phys_addr_arg_t get_phys_addr; +} mfc_args; + +typedef struct tag_mfc_args { + SSBSIP_MFC_ERROR_CODE ret_code; /* [OUT] error code */ + mfc_args args; +} mfc_common_args; + +typedef struct { + int magic; + int hMFC; + int width; + int height; + int sizeStrmBuf; + mfc_frame_buf_arg_t sizeFrmBuf; + int displayStatus; + int inter_buff_status; + unsigned int virFreeStrmAddr; + unsigned int phyStrmBuf; + unsigned int virStrmBuf; + unsigned int virMvRefYC; + mfc_frame_buf_arg_t phyFrmBuf; + mfc_frame_buf_arg_t virFrmBuf; + unsigned int mapped_addr; + mfc_common_args MfcArg; + SSBSIP_MFC_CODEC_TYPE codec_type; + SSBSIP_MFC_DEC_OUTPUT_INFO decOutInfo; + unsigned int encodedHeaderSize; + int encodedDataSize; + unsigned int encodedframeType; + int in_frametag; + int out_frametag_top; + int out_frametag_bottom; + unsigned int encoded_Y_paddr; + unsigned int encoded_C_paddr; +} _MFCLIB; + +#endif /* _MFC_INTERFACE_H_ */ diff --git a/sec_mm/sec_omx/sec_omx_component/common/Android.mk b/sec_mm/sec_omx/sec_omx_component/common/Android.mk new file mode 100644 index 0000000..e28fdb4 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/Android.mk @@ -0,0 +1,24 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Basecomponent.c \ + SEC_OMX_Baseport.c \ + SEC_OMX_Resourcemanager.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libsecbasecomponent.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := libsecosal.smdkc210 +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal + +include $(BUILD_STATIC_LIBRARY) + diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.c b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.c new file mode 100644 index 0000000..d1b224f --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.c @@ -0,0 +1,1486 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Basecomponent.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OSAL_Event.h" +#include "SEC_OSAL_Thread.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Macros.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_BASE_COMP" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* Change CHECK_SIZE_VERSION Macro */ +OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + OMX_VERSIONTYPE* version = NULL; + if (header == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + version = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32)); + if (*((OMX_U32*)header) != size) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (version->s.nVersionMajor != VERSIONMAJOR_NUMBER || + version->s.nVersionMinor != VERSIONMINOR_NUMBER) { + ret = OMX_ErrorVersionMismatch; + goto EXIT; + } + ret = OMX_ErrorNone; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetComponentVersion( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE *pComponentVersion, + OMX_OUT OMX_VERSIONTYPE *pSpecVersion, + OMX_OUT OMX_UUIDTYPE *pComponentUUID) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_U32 compUUID[3]; + + FunctionIn(); + + /* check parameters */ + if (hComponent == NULL || + pComponentName == NULL || pComponentVersion == NULL || + pSpecVersion == NULL || pComponentUUID == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + SEC_OSAL_Strcpy(pComponentName, pSECComponent->componentName); + SEC_OSAL_Memcpy(pComponentVersion, &(pSECComponent->componentVersion), sizeof(OMX_VERSIONTYPE)); + SEC_OSAL_Memcpy(pSpecVersion, &(pSECComponent->specVersion), sizeof(OMX_VERSIONTYPE)); + + /* Fill UUID with handle address, PID and UID. + * This should guarantee uiniqness */ + compUUID[0] = (OMX_U32)pOMXComponent; + compUUID[1] = getpid(); + compUUID[2] = getuid(); + SEC_OSAL_Memcpy(*pComponentUUID, compUUID, 3 * sizeof(*compUUID)); + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetState ( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE *pState) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pState == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + *pState = pSECComponent->currentState; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_BufferProcessThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->sec_BufferProcess(pOMXComponent); + + SEC_OSAL_TheadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentStateSet(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 messageParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_MESSAGE *message; + OMX_STATETYPE destState = messageParam; + OMX_STATETYPE currentState = pSECComponent->currentState; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 countValue = 0; + int i = 0, j = 0; + + FunctionIn(); + + /* check parameters */ + if (currentState == destState) { + ret = OMX_ErrorSameState; + goto EXIT; + } + if (currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if ((currentState == OMX_StateLoaded) && (destState == OMX_StateIdle)) { + ret = SEC_OMX_Get_Resource(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + } + if (((currentState == OMX_StateIdle) && (destState == OMX_StateLoaded)) || + ((currentState == OMX_StateIdle) && (destState == OMX_StateInvalid)) || + ((currentState == OMX_StateExecuting) && (destState == OMX_StateInvalid)) || + ((currentState == OMX_StatePause) && (destState == OMX_StateInvalid))) { + SEC_OMX_Release_Resource(pOMXComponent); + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "destState: %d", destState); + + switch (destState) { + case OMX_StateInvalid: + switch (currentState) { + case OMX_StateIdle: + case OMX_StateExecuting: + case OMX_StatePause: + case OMX_StateLoaded: + case OMX_StateWaitForResources: + pSECComponent->currentState = OMX_StateInvalid; + if (pSECComponent->hBufferProcess) { + pSECComponent->bExitBufferProcessThread = OMX_TRUE; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); + if (countValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); + pSECComponent->hBufferProcess = NULL; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + } + if (pSECComponent->sec_mfc_componentTerminate != NULL) + pSECComponent->sec_mfc_componentTerminate(pOMXComponent); + break; + } + ret = OMX_ErrorInvalidState; + break; + case OMX_StateLoaded: + switch (currentState) { + case OMX_StateIdle: + pSECComponent->bExitBufferProcessThread = OMX_TRUE; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &countValue); + if (countValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + SEC_OSAL_ThreadTerminate(pSECComponent->hBufferProcess); + pSECComponent->hBufferProcess = NULL; + + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + + pSECComponent->sec_mfc_componentTerminate(pOMXComponent); + + for (i = 0; i < (pSECComponent->portParam.nPorts); i++) { + pSECPort = (pSECComponent->pSECPort + i); + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message != NULL) + SEC_OSAL_Free(message); + } + ret = pSECComponent->sec_FreeTunnelBuffer(pSECComponent, i); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pSECPort)) { + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + } + pSECComponent->currentState = OMX_StateLoaded; + break; + case OMX_StateWaitForResources: + ret = SEC_OMX_Out_WaitForResource(pOMXComponent); + pSECComponent->currentState = OMX_StateLoaded; + break; + case OMX_StateExecuting: + case OMX_StatePause: + default: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StateIdle: + switch (currentState) { + case OMX_StateLoaded: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = (pSECComponent->pSECPort + i); + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, i); + if (ret!=OMX_ErrorNone) + goto EXIT; + } + } else { + if (CHECK_PORT_ENABLED(pSECPort)) { + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[i].loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } + } + ret = pSECComponent->sec_mfc_componentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + goto EXIT; + } + pSECComponent->bExitBufferProcessThread = OMX_FALSE; + SEC_OSAL_SignalCreate(&pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreCreate(&pSECComponent->pSECPort[i].bufferSemID); + } + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexCreate(&pSECComponent->secDataBuffer[i].bufferMutex); + } + ret = SEC_OSAL_ThreadCreate(&pSECComponent->hBufferProcess, + SEC_OMX_BufferProcessThread, + pOMXComponent); + if (ret != OMX_ErrorNone) { + /* + * if (CHECK_PORT_TUNNELED == OMX_TRUE) thenTunnel Buffer Free + */ + + SEC_OSAL_SignalTerminate(pSECComponent->pauseEvent); + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_MutexTerminate(pSECComponent->secDataBuffer[i].bufferMutex); + pSECComponent->secDataBuffer[i].bufferMutex = NULL; + } + for (i = 0; i < ALL_PORT_NUM; i++) { + SEC_OSAL_SemaphoreTerminate(pSECComponent->pSECPort[i].bufferSemID); + pSECComponent->pSECPort[i].bufferSemID = NULL; + } + + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pSECComponent->currentState = OMX_StateIdle; + break; + case OMX_StateExecuting: + case OMX_StatePause: + SEC_OMX_BufferFlushProcessNoEvent(pOMXComponent, ALL_PORT_INDEX); + pSECComponent->currentState = OMX_StateIdle; + break; + case OMX_StateWaitForResources: + pSECComponent->currentState = OMX_StateIdle; + break; + } + break; + case OMX_StateExecuting: + switch (currentState) { + case OMX_StateLoaded: + ret = OMX_ErrorIncorrectStateTransition; + break; + case OMX_StateIdle: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { + for (j = 0; j < pSECPort->tunnelBufferNum; j++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + } + } + + pSECComponent->transientState = SEC_OMX_TransStateMax; + pSECComponent->currentState = OMX_StateExecuting; + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + break; + case OMX_StatePause: + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort) && CHECK_PORT_ENABLED(pSECPort)) { + OMX_U32 semaValue = 0, cnt = 0; + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[i].bufferSemID, &semaValue); + if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > semaValue) { + cnt = SEC_OSAL_GetElemNum(&pSECPort->bufferQ) - semaValue; + for (j = 0; j < cnt; j++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[i].bufferSemID); + } + } + } + } + + pSECComponent->currentState = OMX_StateExecuting; + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + break; + case OMX_StateWaitForResources: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StatePause: + switch (currentState) { + case OMX_StateLoaded: + ret = OMX_ErrorIncorrectStateTransition; + break; + case OMX_StateIdle: + pSECComponent->currentState = OMX_StatePause; + break; + case OMX_StateExecuting: + pSECComponent->currentState = OMX_StatePause; + break; + case OMX_StateWaitForResources: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + case OMX_StateWaitForResources: + switch (currentState) { + case OMX_StateLoaded: + ret = SEC_OMX_In_WaitForResource(pOMXComponent); + pSECComponent->currentState = OMX_StateWaitForResources; + break; + case OMX_StateIdle: + case OMX_StateExecuting: + case OMX_StatePause: + ret = OMX_ErrorIncorrectStateTransition; + break; + } + break; + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECComponent->pCallbacks != NULL) { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, OMX_CommandStateSet, + destState, NULL); + } + } else { + if (pSECComponent->pCallbacks != NULL) { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_MessageHandlerThread(OMX_PTR threadData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + OMX_U32 messageType = 0, portIndex = 0; + + FunctionIn(); + + if (threadData == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)threadData; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + while (pSECComponent->bExitMessageHandlerThread != OMX_TRUE) { + SEC_OSAL_SemaphoreWait(pSECComponent->msgSemaphoreHandle); + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECComponent->messageQ); + if (message != NULL) { + messageType = message->messageType; + switch (messageType) { + case OMX_CommandStateSet: + ret = SEC_OMX_ComponentStateSet(pOMXComponent, message->messageParam); + break; + case OMX_CommandFlush: + ret = SEC_OMX_BufferFlushProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandPortDisable: + ret = SEC_OMX_PortDisableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandPortEnable: + ret = SEC_OMX_PortEnableProcess(pOMXComponent, message->messageParam); + break; + case OMX_CommandMarkBuffer: + portIndex = message->messageParam; + pSECComponent->pSECPort[portIndex].markType.hMarkTargetComponent = ((OMX_MARKTYPE *)message->pCmdData)->hMarkTargetComponent; + pSECComponent->pSECPort[portIndex].markType.pMarkData = ((OMX_MARKTYPE *)message->pCmdData)->pMarkData; + break; + case (OMX_COMMANDTYPE)SEC_OMX_CommandComponentDeInit: + pSECComponent->bExitMessageHandlerThread = OMX_TRUE; + break; + default: + break; + } + SEC_OSAL_Free(message); + message = NULL; + } + } + + SEC_OSAL_TheadExit(NULL); + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_StateSet(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_U32 destState = nParam; + OMX_U32 i = 0; + + if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateLoaded)) { + pSECComponent->transientState = SEC_OMX_TransStateLoadedToIdle; + for(i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateIdle; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateLoaded) && (pSECComponent->currentState == OMX_StateIdle)) { + pSECComponent->transientState = SEC_OMX_TransStateIdleToLoaded; + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateLoaded; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateLoaded"); + } else if ((destState == OMX_StateIdle) && (pSECComponent->currentState == OMX_StateExecuting)) { + pSECComponent->transientState = SEC_OMX_TransStateExecutingToIdle; + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateIdle"); + } else if ((destState == OMX_StateExecuting) && (pSECComponent->currentState == OMX_StateIdle)) { + pSECComponent->transientState = SEC_OMX_TransStateIdleToExecuting; + SEC_OSAL_Log(SEC_LOG_TRACE, "to OMX_StateExecuting"); + } else if (destState == OMX_StateInvalid) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECComponent->pSECPort[i].portState = OMX_StateInvalid; + } + } + + return OMX_ErrorNone; +} + +static OMX_ERRORTYPE SEC_SetPortFlush(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0, index = 0; + + + if ((pSECComponent->currentState == OMX_StateExecuting) || + (pSECComponent->currentState == OMX_StatePause)) { + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + /********************* + * need flush event set ????? + **********************/ + cnt = (portIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + for (i = 0; i < cnt; i++) { + if (portIndex == ALL_PORT_INDEX) + index = i; + else + index = portIndex; + pSECComponent->pSECPort[index].bIsPortFlushed = OMX_TRUE; + } + } else { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +static OMX_ERRORTYPE SEC_SetPortEnable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pSECPort->portState = OMX_StateIdle; + } + } + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } else { + pSECPort->portState = OMX_StateIdle; + } + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_SetPortDisable(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + FunctionIn(); + + if ((portIndex != ALL_PORT_INDEX) && + ((OMX_S32)portIndex >= (OMX_S32)pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if (portIndex == ALL_PORT_INDEX) { + for (i = 0; i < pSECComponent->portParam.nPorts; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + if (!CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + pSECPort->portState = OMX_StateLoaded; + pSECPort->bIsPortDisabled = OMX_TRUE; + } + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portState = OMX_StateLoaded; + pSECPort->bIsPortDisabled = OMX_TRUE; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_SetMarkBuffer(SEC_OMX_BASECOMPONENT *pSECComponent, OMX_U32 nParam) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 portIndex = nParam; + OMX_U16 i = 0, cnt = 0; + + + if (nParam >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECComponent->currentState == OMX_StateExecuting) || + (pSECComponent->currentState == OMX_StatePause)) { + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorIncorrectStateOperation; + } + +EXIT: + return ret; +} + +static OMX_ERRORTYPE SEC_OMX_CommandQueue( + SEC_OMX_BASECOMPONENT *pSECComponent, + OMX_COMMANDTYPE Cmd, + OMX_U32 nParam, + OMX_PTR pCmdData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_MESSAGE *command = (SEC_OMX_MESSAGE *)SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + + if (command == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + command->messageType = (OMX_U32)Cmd; + command->messageParam = nParam; + command->pCmdData = pCmdData; + + ret = SEC_OSAL_Queue(&pSECComponent->messageQ, (void *)command); + if (ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + ret = SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SendCommand( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam, + OMX_IN OMX_PTR pCmdData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_MESSAGE *message = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (Cmd) { + case OMX_CommandStateSet : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandStateSet"); + SEC_StateSet(pSECComponent, nParam); + break; + case OMX_CommandFlush : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandFlush"); + ret = SEC_SetPortFlush(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortDisable : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortDisable"); + ret = SEC_SetPortDisable(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandPortEnable : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandPortEnable"); + ret = SEC_SetPortEnable(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; + case OMX_CommandMarkBuffer : + SEC_OSAL_Log(SEC_LOG_TRACE, "Command: OMX_CommandMarkBuffer"); + ret = SEC_SetMarkBuffer(pSECComponent, nParam); + if (ret != OMX_ErrorNone) + goto EXIT; + break; +/* + case SEC_CommandFillBuffer : + case SEC_CommandEmptyBuffer : + case SEC_CommandDeInit : +*/ + default: + break; + } + + ret = SEC_OMX_CommandQueue(pSECComponent, Cmd, nParam, pCmdData); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nParamIndex) { + case (OMX_INDEXTYPE)OMX_COMPONENT_CAPABILITY_TYPE_INDEX: + { + /* For Android PV OpenCORE */ + OMXComponentCapabilityFlagsType *capabilityFlags = (OMXComponentCapabilityFlagsType *)ComponentParameterStructure; + SEC_OSAL_Memcpy(capabilityFlags, &pSECComponent->capabilityFlags, sizeof(OMXComponentCapabilityFlagsType)); + } + break; + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + portParam->nPorts = 0; + portParam->nStartPortNumber = 0; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + SEC_OSAL_Memcpy(portDefinition, &pSECPort->portDefinition, portDefinition->nSize); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + compPriority->nGroupID = pSECComponent->compPriority.nGroupID; + compPriority->nGroupPriority = pSECComponent->compPriority.nGroupPriority; + } + break; + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if ((pSECComponent->currentState == OMX_StateLoaded) || + (pSECComponent->currentState == OMX_StateWaitForResources)) { + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + + if (pSECPort->portDefinition.eDir == OMX_DirInput) { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; + } else if (CHECK_PORT_TUNNELED(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + } else { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput; + } else if (CHECK_PORT_TUNNELED(pSECPort)) { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyInput; + } else { + bufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified; + } + } + } + else + { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + break; + default: + { + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + + ret = OMX_ErrorNone; + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamAudioInit: + case OMX_IndexParamVideoInit: + case OMX_IndexParamImageInit: + case OMX_IndexParamOtherInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && + (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + ret = OMX_ErrorUndefined; + /* SEC_OSAL_Memcpy(&pSECComponent->portParam, portParam, sizeof(OMX_PORT_PARAM_TYPE)); */ + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(portDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (portDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, portDefinition, portDefinition->nSize); + } + break; + case OMX_IndexParamPriorityMgmt: + { + OMX_PRIORITYMGMTTYPE *compPriority = (OMX_PRIORITYMGMTTYPE *)ComponentParameterStructure; + + if ((pSECComponent->currentState != OMX_StateLoaded) && + (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(compPriority, sizeof(OMX_PRIORITYMGMTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECComponent->compPriority.nGroupID = compPriority->nGroupID; + pSECComponent->compPriority.nGroupPriority = compPriority->nGroupPriority; + } + break; + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = bufferSupplier->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(bufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (CHECK_PORT_TUNNELED(pSECPort) == 0) { + ret = OMX_ErrorNone; /*OMX_ErrorNone ?????*/ + goto EXIT; + } + + if (pSECPort->portDefinition.eDir == OMX_DirInput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorNone; + } + */ + pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pSECPort->tunneledPort; + ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; + bufferSupplier->nPortIndex = pSECPort->tunneledPort; + ret = OMX_SetParameter(pSECPort->tunneledComponent, OMX_IndexParamCompBufferSupplier, bufferSupplier); + } + goto EXIT; + } + } else if (pSECPort->portDefinition.eDir == OMX_DirOutput) { + if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) { + ret = OMX_ErrorNone; + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->tunnelFlags &= ~SEC_TUNNEL_IS_SUPPLIER; + ret = OMX_ErrorNone; + } + goto EXIT; + } else if (bufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) { + /* + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorNone; + } + */ + pSECPort->tunnelFlags |= SEC_TUNNEL_IS_SUPPLIER; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + break; + default: + { + ret = OMX_ErrorUnsupportedIndex; + goto EXIT; + } + break; + } + + ret = OMX_ErrorNone; + +EXIT: + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + ret = OMX_ErrorBadParameter; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_SetCallbacks ( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pCallbacks == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + if (pSECComponent->currentState != OMX_StateLoaded) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECComponent->pCallbacks = pCallbacks; + pSECComponent->callbackData = pAppData; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_UseEGLImage( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void *eglImage) +{ + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE SEC_OMX_BaseComponent_Constructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASECOMPONENT)); + if (pSECComponent == NULL) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent, 0, sizeof(SEC_OMX_BASECOMPONENT)); + pOMXComponent->pComponentPrivate = (OMX_PTR)pSECComponent; + + ret = SEC_OSAL_SemaphoreCreate(&pSECComponent->msgSemaphoreHandle); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + ret = SEC_OSAL_MutexCreate(&pSECComponent->compMutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent->bExitMessageHandlerThread = OMX_FALSE; + SEC_OSAL_QueueCreate(&pSECComponent->messageQ); + ret = SEC_OSAL_ThreadCreate(&pSECComponent->hMessageHandler, SEC_OMX_MessageHandlerThread, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + + pOMXComponent->GetComponentVersion = &SEC_OMX_GetComponentVersion; + pOMXComponent->SendCommand = &SEC_OMX_SendCommand; + pOMXComponent->GetConfig = &SEC_OMX_GetConfig; + pOMXComponent->GetExtensionIndex = &SEC_OMX_GetExtensionIndex; + pOMXComponent->GetState = &SEC_OMX_GetState; + pOMXComponent->SetCallbacks = &SEC_OMX_SetCallbacks; + pOMXComponent->UseEGLImage = &SEC_OMX_UseEGLImage; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BaseComponent_Destructor( + OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_U32 semaValue = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OMX_CommandQueue(pSECComponent, SEC_OMX_CommandComponentDeInit, 0, NULL); + SEC_OSAL_SleepMillisec(0); + SEC_OSAL_Get_SemaphoreCount(pSECComponent->msgSemaphoreHandle, &semaValue); + if (semaValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + SEC_OSAL_SemaphorePost(pSECComponent->msgSemaphoreHandle); + + SEC_OSAL_ThreadTerminate(pSECComponent->hMessageHandler); + pSECComponent->hMessageHandler = NULL; + + SEC_OSAL_MutexTerminate(pSECComponent->compMutex); + pSECComponent->compMutex = NULL; + SEC_OSAL_SemaphoreTerminate(pSECComponent->msgSemaphoreHandle); + pSECComponent->msgSemaphoreHandle = NULL; + SEC_OSAL_QueueTerminate(&pSECComponent->messageQ); + + SEC_OSAL_Free(pSECComponent); + pSECComponent = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + + diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.h b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.h new file mode 100644 index 0000000..d413257 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Basecomponent.h @@ -0,0 +1,174 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Basecomponent.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_BASECOMP +#define SEC_OMX_BASECOMP + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" + + +typedef struct _SEC_OMX_MESSAGE +{ + OMX_U32 messageType; + OMX_U32 messageParam; + OMX_PTR pCmdData; +} SEC_OMX_MESSAGE; + +typedef struct _SEC_OMX_DATABUFFER +{ + OMX_HANDLETYPE bufferMutex; + OMX_BUFFERHEADERTYPE* bufferHeader; + OMX_BOOL dataValid; + OMX_U32 allocSize; + OMX_U32 dataLen; + OMX_U32 usedDataLen; + OMX_U32 remainDataLen; + OMX_U32 nFlags; + OMX_TICKS timeStamp; +} SEC_OMX_DATABUFFER; + +typedef struct _SEC_BUFFER_HEADER{ + void *YPhyAddr; // [IN/OUT] physical address of Y + void *CPhyAddr; // [IN/OUT] physical address of CbCr + void *YVirAddr; // [IN/OUT] virtual address of Y + void *CVirAddr; // [IN/OUT] virtual address of CbCr + int YSize; // [IN/OUT] input size of Y data + int CSize; // [IN/OUT] input size of CbCr data +} SEC_BUFFER_HEADER; + +typedef struct _SEC_OMX_DATA +{ + OMX_BYTE dataBuffer; + OMX_U32 allocSize; + OMX_U32 dataLen; + OMX_U32 usedDataLen; + OMX_U32 remainDataLen; + OMX_U32 previousDataLen; + OMX_U32 nFlags; + OMX_TICKS timeStamp; + SEC_BUFFER_HEADER specificBufferHeader; +} SEC_OMX_DATA; + +/* for Check TimeStamp after Seek */ +typedef struct _SEC_OMX_TIMESTAPM +{ + OMX_BOOL needSetStartTimeStamp; + OMX_BOOL needCheckStartTimeStamp; + OMX_TICKS startTimeStamp; + OMX_U32 nStartFlags; +} SEC_OMX_TIMESTAMP; + +typedef struct _SEC_OMX_BASECOMPONENT +{ + OMX_STRING componentName; + OMX_VERSIONTYPE componentVersion; + OMX_VERSIONTYPE specVersion; + + OMX_STATETYPE currentState; + SEC_OMX_TRANS_STATETYPE transientState; + + SEC_CODEC_TYPE codecType; + SEC_OMX_PRIORITYMGMTTYPE compPriority; + OMX_MARKTYPE propagateMarkType; + OMX_HANDLETYPE compMutex; + + OMX_HANDLETYPE hCodecHandle; + + /* Message Handler */ + OMX_BOOL bExitMessageHandlerThread; + OMX_HANDLETYPE hMessageHandler; + OMX_HANDLETYPE msgSemaphoreHandle; + SEC_QUEUE messageQ; + + /* Buffer Process */ + OMX_BOOL bExitBufferProcessThread; + OMX_HANDLETYPE hBufferProcess; + + /* Buffer */ + SEC_OMX_DATABUFFER secDataBuffer[2]; + + /* Data */ + SEC_OMX_DATA processData[2]; + + /* Port */ + OMX_PORT_PARAM_TYPE portParam; + SEC_OMX_BASEPORT *pSECPort; + + OMX_HANDLETYPE pauseEvent; + + /* Callback function */ + OMX_CALLBACKTYPE *pCallbacks; + OMX_PTR callbackData; + + /* Save Timestamp */ + OMX_TICKS timeStamp[MAX_TIMESTAMP]; + SEC_OMX_TIMESTAMP checkTimeStamp; + + /* Save Flags */ + OMX_U32 nFlags[MAX_FLAGS]; + + OMX_BOOL getAllDelayBuffer; + OMX_BOOL remainOutputData; + OMX_BOOL reInputData; + + /* Android CapabilityFlags */ + OMXComponentCapabilityFlagsType capabilityFlags; + + OMX_BOOL bUseFlagEOF; + OMX_BOOL bSaveFlagEOS; + + OMX_ERRORTYPE (*sec_mfc_componentInit)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_mfc_componentTerminate)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_mfc_bufferProcess) (OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData); + + OMX_ERRORTYPE (*sec_AllocateTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_FreeTunnelBuffer)(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_BufferProcess)(OMX_HANDLETYPE hComponent); + OMX_ERRORTYPE (*sec_BufferReset)(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex); + OMX_ERRORTYPE (*sec_InputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); + OMX_ERRORTYPE (*sec_OutputBufferReturn)(OMX_COMPONENTTYPE *pOMXComponent); + + int (*sec_checkInputFrame)(unsigned char *pInputStream, int buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame); + +} SEC_OMX_BASECOMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + OMX_ERRORTYPE SEC_OMX_Check_SizeVersion(OMX_PTR header, OMX_U32 size); + + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.c b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.c new file mode 100644 index 0000000..0e0f7ea --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.c @@ -0,0 +1,1005 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Baseport.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OSAL_Semaphore.h" +#include "SEC_OSAL_Mutex.h" + +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Basecomponent.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_BASE_PORT" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OMX_FlushPort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *bufferHeader = NULL; + SEC_OMX_MESSAGE *message = NULL; + OMX_U32 flushNum = 0; + OMX_S32 semValue = 0; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) > 0) { + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &semValue); + if (semValue == 0) + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message != NULL) { + bufferHeader = (OMX_BUFFERHEADERTYPE *)message->pCmdData; + bufferHeader->nFilledLen = 0; + + if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if (portIndex) { + OMX_EmptyThisBuffer(pSECPort->tunneledComponent, bufferHeader); + } else { + OMX_FillThisBuffer(pSECPort->tunneledComponent, bufferHeader); + } + SEC_OSAL_Free(message); + message = NULL; + } else if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + SEC_OSAL_Log(SEC_LOG_ERROR, "Tunneled mode is not working, Line:%d", __LINE__); + ret = OMX_ErrorNotImplemented; + SEC_OSAL_Queue(&pSECPort->bufferQ, pSECPort); + goto EXIT; + } else { + if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } else { + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + + SEC_OSAL_Free(message); + message = NULL; + } + } + } + + if (pSECComponent->secDataBuffer[portIndex].dataValid == OMX_TRUE) { + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + message->pCmdData = pSECComponent->secDataBuffer[portIndex].bufferHeader; + message->messageType = 0; + message->messageParam = -1; + SEC_OSAL_Queue(&pSECPort->bufferQ, message); + pSECComponent->sec_BufferReset(pOMXComponent, portIndex); + } else { + if (portIndex == INPUT_PORT_INDEX) + pSECComponent->sec_InputBufferReturn(pOMXComponent); + else if (portIndex == OUTPUT_PORT_INDEX) + pSECComponent->sec_OutputBufferReturn(pOMXComponent); + } + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) < pSECPort->assignedBufferNum) { + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + } + if (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) != pSECPort->assignedBufferNum) + SEC_OSAL_SetElemNum(&pSECPort->bufferQ, pSECPort->assignedBufferNum); + } else { + while(1) { + int cnt; + SEC_OSAL_Get_SemaphoreCount(pSECComponent->pSECPort[portIndex].bufferSemID, &cnt); + if (cnt == 0) + break; + SEC_OSAL_SemaphoreWait(pSECComponent->pSECPort[portIndex].bufferSemID); + } + SEC_OSAL_SetElemNum(&pSECPort->bufferQ, 0); + } + + pSECComponent->processData[portIndex].dataLen = 0; + pSECComponent->processData[portIndex].nFlags = 0; + pSECComponent->processData[portIndex].remainDataLen = 0; + pSECComponent->processData[portIndex].timeStamp = 0; + pSECComponent->processData[portIndex].usedDataLen = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (ret == OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_TRACE,"OMX_CommandFlush EventCmdComplete"); + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandFlush, portIndex, NULL); + } + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } else if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->remainOutputData = OMX_FALSE; + } + } + +EXIT: + if (ret != OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; + + SEC_OSAL_SignalSet(pSECComponent->pauseEvent); + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } + } + +EXIT: + if (ret != OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE SEC_OMX_EnablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = pSECComponent->sec_AllocateTunnelBuffer(pSECPort, portIndex); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + pSECPort->portDefinition.bPopulated = OMX_TRUE; + if (pSECComponent->currentState == OMX_StateExecuting) { + for (i=0; itunnelBufferNum; i++) { + SEC_OSAL_SemaphorePost(pSECComponent->pSECPort[portIndex].bufferSemID); + } + } + } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } else { + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + SEC_OSAL_SemaphoreWait(pSECPort->loadedResource); + pSECPort->portDefinition.bPopulated = OMX_TRUE; + } + } + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX) ? ALL_PORT_NUM : 1; + + for (i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = SEC_OMX_EnablePort(pOMXComponent, portIndex); + if (ret == OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortEnable, portIndex, NULL); + } + } + +EXIT: + if (ret != OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_DisablePort(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_U32 i = 0, elemNum = 0; + SEC_OMX_MESSAGE *message; + + FunctionIn(); + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if (!CHECK_PORT_ENABLED(pSECPort)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + if (pSECComponent->currentState!=OMX_StateLoaded) { + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + SEC_OSAL_Free(message); + } + ret = pSECComponent->sec_FreeTunnelBuffer(pSECPort, portIndex); + if (OMX_ErrorNone != ret) { + goto EXIT; + } + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } else if (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + pSECPort->portDefinition.bPopulated = OMX_FALSE; + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + } else { + if (CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + while (SEC_OSAL_GetElemNum(&pSECPort->bufferQ) >0 ) { + message = (SEC_OMX_MESSAGE*)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + SEC_OSAL_Free(message); + } + } + pSECPort->portDefinition.bPopulated = OMX_FALSE; + SEC_OSAL_SemaphoreWait(pSECPort->unloadedResource); + } + } + pSECPort->portDefinition.bEnabled = OMX_FALSE; + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 portIndex = 0; + OMX_U32 i = 0, cnt = 0; + SEC_OMX_DATABUFFER *flushBuffer = NULL; + + FunctionIn(); + + if (pOMXComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + cnt = (nPortIndex == ALL_PORT_INDEX ) ? ALL_PORT_NUM : 1; + + /* port flush*/ + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_TRUE; + + flushBuffer = &pSECComponent->secDataBuffer[portIndex]; + + SEC_OSAL_MutexLock(flushBuffer->bufferMutex); + ret = SEC_OMX_FlushPort(pOMXComponent, portIndex); + SEC_OSAL_MutexUnlock(flushBuffer->bufferMutex); + + pSECComponent->pSECPort[portIndex].bIsPortFlushed = OMX_FALSE; + + if (portIndex == INPUT_PORT_INDEX) { + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + } else if (portIndex == OUTPUT_PORT_INDEX) { + pSECComponent->remainOutputData = OMX_FALSE; + } + } + + for(i = 0; i < cnt; i++) { + if (nPortIndex == ALL_PORT_INDEX) + portIndex = i; + else + portIndex = nPortIndex; + + ret = SEC_OMX_DisablePort(pOMXComponent, portIndex); + pSECComponent->pSECPort[portIndex].bIsPortDisabled = OMX_FALSE; + if (ret == OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventCmdComplete, + OMX_CommandPortDisable, portIndex, NULL); + } + } + +EXIT: + if (ret != OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, + ret, 0, NULL); + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_EmptyThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + SEC_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pBuffer->nInputPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateIdle) && + (pSECComponent->currentState != OMX_StateExecuting) && + (pSECComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pSECPort)) || + ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && + (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || + ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pSECPort->bufferHeader[i]) { + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } else { + ret = OMX_ErrorNone; + } + + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + message->messageType = SEC_OMX_CommandEmptyBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); + SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FillThisBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BOOL findBuffer = OMX_FALSE; + SEC_OMX_MESSAGE *message; + OMX_U32 i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (pBuffer == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pBuffer->nOutputPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + ret = SEC_OMX_Check_SizeVersion(pBuffer, sizeof(OMX_BUFFERHEADERTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateIdle) && + (pSECComponent->currentState != OMX_StateExecuting) && + (pSECComponent->currentState != OMX_StatePause)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + if ((!CHECK_PORT_ENABLED(pSECPort)) || + ((CHECK_PORT_BEING_FLUSHED(pSECPort) || CHECK_PORT_BEING_DISABLED(pSECPort)) && + (!CHECK_PORT_TUNNELED(pSECPort) || !CHECK_PORT_BUFFER_SUPPLIER(pSECPort))) || + ((pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle) && + (CHECK_PORT_TUNNELED(pSECPort) && !CHECK_PORT_BUFFER_SUPPLIER(pSECPort)))) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pBuffer == pSECPort->bufferHeader[i]) { + findBuffer = OMX_TRUE; + break; + } + } + + if (findBuffer == OMX_FALSE) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } else { + ret = OMX_ErrorNone; + } + + message = SEC_OSAL_Malloc(sizeof(SEC_OMX_MESSAGE)); + if (message == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + message->messageType = SEC_OMX_CommandFillBuffer; + message->messageParam = (OMX_U32) i; + message->pCmdData = (OMX_PTR)pBuffer; + + SEC_OSAL_Queue(&pSECPort->bufferQ, (void *)message); + SEC_OSAL_SemaphorePost(pSECPort->bufferSemID); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Port_Constructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + INIT_SET_SIZE_VERSION(&pSECComponent->portParam, OMX_PORT_PARAM_TYPE); + pSECComponent->portParam.nPorts = ALL_PORT_NUM; + pSECComponent->portParam.nStartPortNumber = INPUT_PORT_INDEX; + + pSECPort = SEC_OSAL_Malloc(sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); + if (pSECPort == NULL) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECPort, 0, sizeof(SEC_OMX_BASEPORT) * ALL_PORT_NUM); + pSECComponent->pSECPort = pSECPort; + + /* Input Port */ + pSECInputPort = &pSECPort[INPUT_PORT_INDEX]; + + SEC_OSAL_QueueCreate(&pSECInputPort->bufferQ); + + pSECInputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + if (pSECInputPort->bufferHeader == NULL) { + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECInputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + + pSECInputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pSECInputPort->bufferStateAllocate == NULL) { + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECInputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pSECInputPort->bufferSemID = NULL; + pSECInputPort->assignedBufferNum = 0; + pSECInputPort->portState = OMX_StateMax; + pSECInputPort->bIsPortFlushed = OMX_FALSE; + pSECInputPort->bIsPortDisabled = OMX_FALSE; + pSECInputPort->tunneledComponent = NULL; + pSECInputPort->tunneledPort = 0; + pSECInputPort->tunnelBufferNum = 0; + pSECInputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pSECInputPort->tunnelFlags = 0; + pSECInputPort->eControlRate = OMX_Video_ControlRateDisable; + ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->loadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + ret = SEC_OSAL_SemaphoreCreate(&pSECInputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pSECInputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pSECInputPort->portDefinition.nPortIndex = INPUT_PORT_INDEX; + pSECInputPort->portDefinition.eDir = OMX_DirInput; + pSECInputPort->portDefinition.nBufferCountActual = 0; + pSECInputPort->portDefinition.nBufferCountMin = 0; + pSECInputPort->portDefinition.nBufferSize = 0; + pSECInputPort->portDefinition.bEnabled = OMX_FALSE; + pSECInputPort->portDefinition.bPopulated = OMX_FALSE; + pSECInputPort->portDefinition.eDomain = OMX_PortDomainMax; + pSECInputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pSECInputPort->portDefinition.nBufferAlignment = 0; + pSECInputPort->markType.hMarkTargetComponent = NULL; + pSECInputPort->markType.pMarkData = NULL; + + /* Output Port */ + pSECOutputPort = &pSECPort[OUTPUT_PORT_INDEX]; + + SEC_OSAL_QueueCreate(&pSECOutputPort->bufferQ); + + pSECOutputPort->bufferHeader = SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + if (pSECOutputPort->bufferHeader == NULL) { + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(pSECOutputPort->bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE*) * MAX_BUFFER_NUM); + + pSECOutputPort->bufferStateAllocate = SEC_OSAL_Malloc(sizeof(OMX_U32) * MAX_BUFFER_NUM); + if (pSECOutputPort->bufferStateAllocate == NULL) { + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(pSECOutputPort->bufferStateAllocate, 0, sizeof(OMX_U32) * MAX_BUFFER_NUM); + + pSECOutputPort->bufferSemID = NULL; + pSECOutputPort->assignedBufferNum = 0; + pSECOutputPort->portState = OMX_StateMax; + pSECOutputPort->bIsPortFlushed = OMX_FALSE; + pSECOutputPort->bIsPortDisabled = OMX_FALSE; + pSECOutputPort->tunneledComponent = NULL; + pSECOutputPort->tunneledPort = 0; + pSECOutputPort->tunnelBufferNum = 0; + pSECOutputPort->bufferSupplier = OMX_BufferSupplyUnspecified; + pSECOutputPort->tunnelFlags = 0; + pSECOutputPort->eControlRate = OMX_Video_ControlRateDisable; + ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->loadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); + pSECOutputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + ret = SEC_OSAL_SemaphoreCreate(&pSECOutputPort->unloadedResource); + if (ret != OMX_ErrorNone) { + SEC_OSAL_SemaphoreTerminate(pSECOutputPort->loadedResource); + pSECOutputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferStateAllocate); + pSECOutputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECOutputPort->bufferHeader); + pSECOutputPort->bufferHeader = NULL; + + SEC_OSAL_SemaphoreTerminate(pSECInputPort->unloadedResource); + pSECInputPort->unloadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECInputPort->loadedResource); + pSECInputPort->loadedResource = NULL; + SEC_OSAL_Free(pSECInputPort->bufferStateAllocate); + pSECInputPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECInputPort->bufferHeader); + pSECInputPort->bufferHeader = NULL; + SEC_OSAL_Free(pSECPort); + pSECPort = NULL; + goto EXIT; + } + + INIT_SET_SIZE_VERSION(&pSECOutputPort->portDefinition, OMX_PARAM_PORTDEFINITIONTYPE); + pSECOutputPort->portDefinition.nPortIndex = OUTPUT_PORT_INDEX; + pSECOutputPort->portDefinition.eDir = OMX_DirOutput; + pSECOutputPort->portDefinition.nBufferCountActual = 0; + pSECOutputPort->portDefinition.nBufferCountMin = 0; + pSECOutputPort->portDefinition.nBufferSize = 0; + pSECOutputPort->portDefinition.bEnabled = OMX_FALSE; + pSECOutputPort->portDefinition.bPopulated = OMX_FALSE; + pSECOutputPort->portDefinition.eDomain = OMX_PortDomainMax; + pSECOutputPort->portDefinition.bBuffersContiguous = OMX_FALSE; + pSECOutputPort->portDefinition.nBufferAlignment = 0; + pSECOutputPort->markType.hMarkTargetComponent = NULL; + pSECOutputPort->markType.pMarkData = NULL; + + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.startTimeStamp = 0; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + + pOMXComponent->EmptyThisBuffer = &SEC_OMX_EmptyThisBuffer; + pOMXComponent->FillThisBuffer = &SEC_OMX_FillThisBuffer; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Port_Destructor(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + int i = 0; + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + for (i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + + SEC_OSAL_SemaphoreTerminate(pSECPort->loadedResource); + pSECPort->loadedResource = NULL; + SEC_OSAL_SemaphoreTerminate(pSECPort->unloadedResource); + pSECPort->unloadedResource = NULL; + SEC_OSAL_Free(pSECPort->bufferStateAllocate); + pSECPort->bufferStateAllocate = NULL; + SEC_OSAL_Free(pSECPort->bufferHeader); + pSECPort->bufferHeader = NULL; + + SEC_OSAL_QueueTerminate(&pSECPort->bufferQ); + } + SEC_OSAL_Free(pSECComponent->pSECPort); + pSECComponent->pSECPort = NULL; + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.h b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.h new file mode 100644 index 0000000..f38226b --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Baseport.h @@ -0,0 +1,90 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Baseport.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_BASE_PORT +#define SEC_OMX_BASE_PORT + + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" + + +#define BUFFER_STATE_ALLOCATED (1 << 0) +#define BUFFER_STATE_ASSIGNED (1 << 1) +#define HEADER_STATE_ALLOCATED (1 << 2) +#define BUFFER_STATE_FREE 0 + +#define MAX_BUFFER_NUM 20 + +#define INPUT_PORT_INDEX 0 +#define OUTPUT_PORT_INDEX 1 +#define ALL_PORT_INDEX -1 +#define ALL_PORT_NUM 2 + +typedef struct _SEC_OMX_BASEPORT +{ + OMX_BUFFERHEADERTYPE **bufferHeader; + OMX_U32 *bufferStateAllocate; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + OMX_HANDLETYPE bufferSemID; + SEC_QUEUE bufferQ; + OMX_U32 assignedBufferNum; + OMX_STATETYPE portState; + OMX_HANDLETYPE loadedResource; + OMX_HANDLETYPE unloadedResource; + + OMX_BOOL bIsPortFlushed; + OMX_BOOL bIsPortDisabled; + OMX_MARKTYPE markType; + + /* Tunnel Info */ + OMX_HANDLETYPE tunneledComponent; + OMX_U32 tunneledPort; + OMX_U32 tunnelBufferNum; + OMX_BUFFERSUPPLIERTYPE bufferSupplier; + OMX_U32 tunnelFlags; + + OMX_VIDEO_CONTROLRATETYPE eControlRate; +} SEC_OMX_BASEPORT; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_PortEnableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_PortDisableProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_BufferFlushProcess(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_BufferFlushProcessNoEvent(OMX_COMPONENTTYPE *pOMXComponent, OMX_S32 nPortIndex); + +#ifdef __cplusplus +}; +#endif + + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.c b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.c new file mode 100644 index 0000000..41673ad --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.c @@ -0,0 +1,383 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Resourcemanager.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Resourcemanager.h" +#include "SEC_OMX_Basecomponent.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_RM" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +#define MAX_RESOURCE_VIDEO 4 + +/* Max allowable video scheduler component instance */ +static SEC_OMX_RM_COMPONENT_LIST *gpVideoRMComponentList = NULL; +static SEC_OMX_RM_COMPONENT_LIST *gpVideoRMWaitingList = NULL; +static OMX_HANDLETYPE ghVideoRMComponentListMutex = NULL; + + +OMX_ERRORTYPE addElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (*ppList != NULL) { + pTempComp = *ppList; + while (pTempComp->pNext != NULL) { + pTempComp = pTempComp->pNext; + } + pTempComp->pNext = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); + if (pTempComp->pNext == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pNext = NULL; + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->pOMXStandComp = pOMXComponent; + ((SEC_OMX_RM_COMPONENT_LIST *)(pTempComp->pNext))->groupPriority = pSECComponent->compPriority.nGroupPriority; + goto EXIT; + } else { + *ppList = (SEC_OMX_RM_COMPONENT_LIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_RM_COMPONENT_LIST)); + if (*ppList == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pTempComp = *ppList; + pTempComp->pNext = NULL; + pTempComp->pOMXStandComp = pOMXComponent; + pTempComp->groupPriority = pSECComponent->compPriority.nGroupPriority; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE removeElementList(SEC_OMX_RM_COMPONENT_LIST **ppList, OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pCurrComp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pPrevComp = NULL; + OMX_BOOL bDetectComp = OMX_FALSE; + + if (*ppList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pCurrComp = *ppList; + while (pCurrComp != NULL) { + if (pCurrComp->pOMXStandComp == pOMXComponent) { + if (*ppList == pCurrComp) { + *ppList = pCurrComp->pNext; + SEC_OSAL_Free(pCurrComp); + } else { + pPrevComp->pNext = pCurrComp->pNext; + SEC_OSAL_Free(pCurrComp); + } + bDetectComp = OMX_TRUE; + break; + } else { + pPrevComp = pCurrComp; + pCurrComp = pCurrComp->pNext; + } + } + + if (bDetectComp == OMX_FALSE) + ret = OMX_ErrorComponentNotFound; + else + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +int searchLowPriority(SEC_OMX_RM_COMPONENT_LIST *RMComp_list, int inComp_priority, SEC_OMX_RM_COMPONENT_LIST **outLowComp) +{ + int ret = 0; + SEC_OMX_RM_COMPONENT_LIST *pTempComp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pCandidateComp = NULL; + + if (RMComp_list == NULL) + ret = -1; + + pTempComp = RMComp_list; + *outLowComp = 0; + + while (pTempComp != NULL) { + if (pTempComp->groupPriority > inComp_priority) { + if (pCandidateComp != NULL) { + if (pCandidateComp->groupPriority < pTempComp->groupPriority) + pCandidateComp = pTempComp; + } else { + pCandidateComp = pTempComp; + } + } + + pTempComp = pTempComp->pNext; + } + + *outLowComp = pCandidateComp; + if (pCandidateComp == NULL) + ret = 0; + else + ret = 1; + +EXIT: + return ret; +} + +OMX_ERRORTYPE removeComponent(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateIdle) { + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, pSECComponent->callbackData, + OMX_EventError, OMX_ErrorResourcesLost, 0, NULL); + ret = OMX_SendCommand(pOMXComponent, OMX_CommandStateSet, OMX_StateLoaded, NULL); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } else if ((pSECComponent->currentState == OMX_StateExecuting) || (pSECComponent->currentState == OMX_StatePause)) { + /* Todo */ + } + + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Init() +{ + FunctionIn(); + SEC_OSAL_MutexCreate(&ghVideoRMComponentListMutex); + FunctionOut(); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit() +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_RM_COMPONENT_LIST *pCurrComponent; + SEC_OMX_RM_COMPONENT_LIST *pNextComponent; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + if (gpVideoRMComponentList) { + pCurrComponent = gpVideoRMComponentList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoRMComponentList = NULL; + } + + if (gpVideoRMWaitingList) { + pCurrComponent = gpVideoRMWaitingList; + while (pCurrComponent != NULL) { + pNextComponent = pCurrComponent->pNext; + SEC_OSAL_Free(pCurrComponent); + pCurrComponent = pNextComponent; + } + gpVideoRMWaitingList = NULL; + } + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + SEC_OSAL_MutexTerminate(ghVideoRMComponentListMutex); + ghVideoRMComponentListMutex = NULL; + + ret = OMX_ErrorNone; +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentCandidate = NULL; + int numElem = 0; + int lowCompDetect = 0; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pComponentTemp = gpVideoRMComponentList; + if (pSECComponent->codecType == HW_VIDEO_CODEC) { + if (pComponentTemp != NULL) { + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + } else { + numElem = 0; + } + if (numElem >= MAX_RESOURCE_VIDEO) { + lowCompDetect = searchLowPriority(gpVideoRMComponentList, pSECComponent->compPriority.nGroupPriority, &pComponentCandidate); + if (lowCompDetect <= 0) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeComponent(pComponentCandidate->pOMXStandComp); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } else { + ret = removeElementList(&gpVideoRMComponentList, pComponentCandidate->pOMXStandComp); + ret = addElementList(&gpVideoRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + } else { + ret = addElementList(&gpVideoRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + } + } + ret = OMX_ErrorNone; + +EXIT: + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_RM_COMPONENT_LIST *pComponentTemp = NULL; + OMX_COMPONENTTYPE *pOMXWaitComponent = NULL; + int numElem = 0; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pComponentTemp = gpVideoRMWaitingList; + if (pSECComponent->codecType == HW_VIDEO_CODEC) { + if (gpVideoRMComponentList == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = removeElementList(&gpVideoRMComponentList, pOMXComponent); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + while (pComponentTemp) { + numElem++; + pComponentTemp = pComponentTemp->pNext; + } + if (numElem > 0) { + pOMXWaitComponent = gpVideoRMWaitingList->pOMXStandComp; + removeElementList(&gpVideoRMWaitingList, pOMXWaitComponent); + ret = OMX_SendCommand(pOMXWaitComponent, OMX_CommandStateSet, OMX_StateIdle, NULL); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + } + } + +EXIT: + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->codecType == HW_VIDEO_CODEC) + ret = addElementList(&gpVideoRMWaitingList, pOMXComponent); + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + SEC_OSAL_MutexLock(ghVideoRMComponentListMutex); + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->codecType == HW_VIDEO_CODEC) + ret = removeElementList(&gpVideoRMWaitingList, pOMXComponent); + + SEC_OSAL_MutexUnlock(ghVideoRMComponentListMutex); + + FunctionOut(); + + return ret; +} + diff --git a/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.h b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.h new file mode 100644 index 0000000..b958575 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/common/SEC_OMX_Resourcemanager.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Resourcemanager.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_RESOURCEMANAGER +#define SEC_OMX_RESOURCEMANAGER + + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + + +struct SEC_OMX_RM_COMPONENT_LIST; +typedef struct _SEC_OMX_RM_COMPONENT_LIST +{ + OMX_COMPONENTTYPE *pOMXStandComp; + OMX_U32 groupPriority; + struct SEC_OMX_RM_COMPONENT_LIST *pNext; +} SEC_OMX_RM_COMPONENT_LIST; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_ResourceManager_Init(); +OMX_ERRORTYPE SEC_OMX_ResourceManager_Deinit(); +OMX_ERRORTYPE SEC_OMX_Get_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_Release_Resource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_In_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); +OMX_ERRORTYPE SEC_OMX_Out_WaitForResource(OMX_COMPONENTTYPE *pOMXComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/dec/Android.mk new file mode 100644 index 0000000..3fbc975 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Vdec.c + +LOCAL_MODULE := libSEC_OMX_Vdec.smdkc210 +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_STATIC_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.c b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.c new file mode 100644 index 0000000..48705c1 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.c @@ -0,0 +1,1355 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vdec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OMX_Vdec.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Thread.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VIDEO_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define ONE_FRAME_OUTPUT /* only one frame output for Android */ +#define S5PC110_DECODE_OUT_DATA_BUFFER /* for Android s5pc110 0copy*/ + + +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((secOutputPort->portDefinition.format.video.nFrameWidth != + secInputPort->portDefinition.format.video.nFrameWidth) || + (secOutputPort->portDefinition.format.video.nFrameHeight != + secInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + secOutputPort->portDefinition.format.video.nFrameWidth = + secInputPort->portDefinition.format.video.nFrameWidth; + secOutputPort->portDefinition.format.video.nFrameHeight = + secInputPort->portDefinition.format.video.nFrameHeight; + width = secOutputPort->portDefinition.format.video.nStride = + secInputPort->portDefinition.format.video.nStride; + height = secOutputPort->portDefinition.format.video.nSliceHeight = + secInputPort->portDefinition.format.video.nSliceHeight; + + switch(secOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + if (width && height) + secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + default: + if (width && height) + secOutputPort->portDefinition.nBufferSize = width * height * 2; + break; + } + } + + return ; +} + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if ( nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pSECPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + SEC_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = temp_buffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if ( nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { + (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, + pSECComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { + if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { + if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); + pSECPort->bufferHeader[i]->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pSECPort->assignedBufferNum--; + if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]); + pSECPort->bufferHeader[i] = NULL; + pBufferHdr = NULL; + } + pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if ( pSECPort->assignedBufferNum == 0 ) { + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT* pSECPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + if ((pSECComponent->currentState == OMX_StateExecuting) && + (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; + secOMXInputPort->markType.hMarkTargetComponent = NULL; + secOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + if (CHECK_PORT_TUNNELED(secOMXInputPort)) { + OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); + } else { + bufferHeader->nFilledLen = 0; + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE* message = NULL; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; + dataBuffer->dataValid = OMX_TRUE; + dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; + dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; + + SEC_OSAL_Free(message); + + if (dataBuffer->allocSize <= dataBuffer->dataLen) + SEC_OSAL_Log(SEC_LOG_WARNING, "Input Buffer Full, Check input buffer size! allocSize:%d, dataLen:%d", dataBuffer->allocSize, dataBuffer->dataLen); + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; + pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; + pSECComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { + OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); + } else { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + /* reset dataBuffer */ + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE *message = NULL; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid =OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ +#ifdef S5PC110_DECODE_OUT_DATA_BUFFER + pSECComponent->processData[OUTPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; + pSECComponent->processData[OUTPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; +#endif + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + + return ret; +} + +static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; + + processData->dataLen = 0; + processData->remainDataLen = 0; + processData->usedDataLen = 0; + processData->nFlags = 0; + processData->timeStamp = 0; + + return ret; +} + +OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_U32 checkedSize = 0; + OMX_BOOL flagEOF = OMX_FALSE; + OMX_BOOL previousFrameEOF = OMX_FALSE; + + FunctionIn(); + + if (inputUseBuffer->dataValid == OMX_TRUE) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + if (inputData->dataLen == 0) { + previousFrameEOF = OMX_TRUE; + } else { + previousFrameEOF = OMX_FALSE; + } + if ((pSECComponent->bUseFlagEOF == OMX_TRUE) && + !(inputUseBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) { + flagEOF = OMX_TRUE; + checkedSize = checkInputStreamLen; + } else { + pSECComponent->bUseFlagEOF = OMX_FALSE; + checkedSize = pSECComponent->sec_checkInputFrame(checkInputStream, checkInputStreamLen, inputUseBuffer->nFlags, previousFrameEOF, &flagEOF); + } + + if (flagEOF == OMX_TRUE) { + copySize = checkedSize; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); + } else { + copySize = checkInputStreamLen; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); + } + + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) + pSECComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + if (copySize > 0) + SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); + + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + inputData->dataLen += copySize; + inputData->remainDataLen += copySize; + + if (previousFrameEOF == OMX_TRUE) { + inputData->timeStamp = inputUseBuffer->timeStamp; + inputData->nFlags = inputUseBuffer->nFlags; + } + + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } else { + if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + ((inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) || + (inputData->dataLen == 0))) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) && + (!(inputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) && + (inputData->dataLen != 0)) { + inputData->nFlags = (inputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_TRUE; + } + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + + if(((inputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) && + (inputData->dataLen <= 0) && (flagEOF == OMX_TRUE)) { + inputData->dataLen = inputData->previousDataLen; + inputData->remainDataLen = inputData->previousDataLen; + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); + flagEOF = OMX_FALSE; + } + + if (inputUseBuffer->remainDataLen == 0) + SEC_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; + } + + if (flagEOF == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + } + + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + + FunctionOut(); + + return ret; +} + +OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + FunctionIn(); + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if ((pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp) && + (pSECComponent->checkTimeStamp.nStartFlags == outputData->nFlags)){ + pSECComponent->checkTimeStamp.startTimeStamp = -19761123; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + + if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = outputData->remainDataLen; +#ifndef S5PC110_DECODE_OUT_DATA_BUFFER + if (copySize > 0) + SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (outputData->dataBuffer + outputData->usedDataLen), + copySize); +#endif + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = outputData->nFlags; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_TRUE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + +#ifdef ONE_FRAME_OUTPUT /* only one frame output for Android */ + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + SEC_OutputBufferReturn(pOMXComponent); +#else + if ((outputUseBuffer->remainDataLen > 0) || + ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + SEC_OutputBufferReturn(pOMXComponent); + } else { + outputUseBuffer->dataValid = OMX_TRUE; + } +#endif + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than decoded data size Out Length"); + + copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen; + +#ifndef S5PC110_DECODE_OUT_DATA_BUFFER + SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (outputData->dataBuffer + outputData->usedDataLen), + copySize); +#endif + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = 0; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_FALSE; + + outputData->remainDataLen -= copySize; + outputData->usedDataLen += copySize; + + SEC_OutputBufferReturn(pOMXComponent); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + if (((pSECComponent->currentState == OMX_StatePause) || + (pSECComponent->currentState == OMX_StateIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + while (SEC_Check_BufferProcess_State(pSECComponent) && !pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = SEC_OutputBufferGetQueue(pSECComponent); + if ((ret == OMX_ErrorUndefined) || + (secInputPort->portState != OMX_StateIdle) || + (secOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pSECComponent->remainOutputData == OMX_FALSE) { + if (pSECComponent->reInputData == OMX_FALSE) { + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = SEC_InputBufferGetQueue(pSECComponent); + break; + } + + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataDecodeYet) + pSECComponent->reInputData = OMX_TRUE; + else + pSECComponent->reInputData = OMX_FALSE; + } + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + + if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) + pSECComponent->remainOutputData = OMX_TRUE; + else + pSECComponent->remainOutputData = OMX_FALSE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pSECComponent->portParam.nPorts; + portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; /* supportFormatNum = N-1 */ + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + + if (portIndex == INPUT_PORT_INDEX) { + supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; + portFormat->eColorFormat = portDefinition->format.video.eColorFormat; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + } else if (portIndex == OUTPUT_PORT_INDEX) { + supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + switch (index) { + case supportFormat_1: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_2: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = SEC_OMX_COLOR_FormatNV12PhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + } + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != INPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + videoRateControl->eControlRate = pSECPort->eControlRate; + videoRateControl->nTargetBitrate = portDefinition->format.video.nBitrate; + } + ret = OMX_ErrorNone; + } + break; + default: + { + ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + portDefinition->format.video.eColorFormat = portFormat->eColorFormat; + portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; + portDefinition->format.video.xFramerate = portFormat->xFramerate; + } + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != INPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + pSECPort->eControlRate = videoRateControl->eControlRate; + portDefinition->format.video.nBitrate = videoRateControl->nTargetBitrate; + } + ret = OMX_ErrorNone; + } + break; + default: + { + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = 0; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; + + pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; + pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; + pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; + pSECComponent->sec_BufferReset = &SEC_BufferReset; + pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; + pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); + pSECPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = SEC_OMX_Port_Destructor(pOMXComponent); + + ret = SEC_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h new file mode 100644 index 0000000..b7f71da --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/SEC_OMX_Vdec.h @@ -0,0 +1,107 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Vdec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_VIDEO_DECODE +#define SEC_OMX_VIDEO_DECODE + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" + +#define MAX_VIDEO_INPUTBUFFER_NUM 5 +#define MAX_VIDEO_OUTPUTBUFFER_NUM 2 + +#define DEFAULT_FRAME_WIDTH 176 +#define DEFAULT_FRAME_HEIGHT 144 + +#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT) * 2 +#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 + +#define DEFAULT_MFC_INPUT_BUFFER_SIZE 1024 * 1024 /*DEFAULT_VIDEO_INPUT_BUFFER_SIZE*/ + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 3 + + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} MFC_DEC_ADDR_INFO; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer); +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoDecodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoDecodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/Android.mk new file mode 100644 index 0000000..e5609c6 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_H264dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.AVC.Decoder.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec.smdkc210 libsecosal.smdkc210 libsecbasecomponent.smdkc210 libsecmfcdecapi.smdkc210 +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec \ + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_SHARED_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c new file mode 100644 index 0000000..5e73b7f --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.c @@ -0,0 +1,1191 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264dec.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "library_register.h" +#include "SEC_OMX_H264dec.h" +#include "SsbSipMfcApi.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_H264_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +//#define ADD_SPS_PPS_I_FRAME +//#define FULL_FRAME_SEARCH + +/* H.264 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; + + +static int Check_H264_Frame(OMX_U8 *pInputStream, int buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + OMX_U32 preFourByte = (OMX_U32)-1; + int accessUnitSize = 0; + int frameTypeBoundary = 0; + int nextNaluSize = 0; + int naluStart = 0; + + if (bPreviousFrameEOF == OMX_TRUE) + naluStart = 0; + else + naluStart = 1; + + while (1) { + int inputOneByte = 0; + + if (accessUnitSize == buffSize) + goto EXIT; + + inputOneByte = *(pInputStream++); + accessUnitSize += 1; + + if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) { + int naluType = inputOneByte & 0x1F; + + SEC_OSAL_Log(SEC_LOG_TRACE, "NaluType : %d", naluType); + if (naluStart == 0) { +#ifdef ADD_SPS_PPS_I_FRAME + if (naluType == 1 || naluType == 5) +#else + if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8) +#endif + naluStart = 1; + } else { +#ifdef OLD_DETECT + frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9) +#else + if (naluType == 9) + frameTypeBoundary = -2; +#endif + if (naluType == 1 || naluType == 5) { + if (accessUnitSize == buffSize) { + accessUnitSize--; + goto EXIT; + } + inputOneByte = *pInputStream++; + accessUnitSize += 1; + + if (inputOneByte >= 0x80) + frameTypeBoundary = -1; + } + if (frameTypeBoundary < 0) { + break; + } + } + + } + preFourByte = (preFourByte << 8) + inputOneByte; + } + + *pbEndOfFrame = OMX_TRUE; + nextNaluSize = -5; + if (frameTypeBoundary == -1) + nextNaluSize = -6; + if (preFourByte != 0x00000001) + nextNaluSize++; + return (accessUnitSize + nextNaluSize); + +EXIT: + *pbEndOfFrame = OMX_FALSE; + + return accessUnitSize; +} + +OMX_BOOL Check_H264_StartCode(OMX_U8 *pInputStream, OMX_U32 streamSize) +{ + if (streamSize < 4) { + return OMX_FALSE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x00) && + (pInputStream[3] != 0x00) && + ((pInputStream[3] >> 3) == 0x00)) { + return OMX_TRUE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] != 0x00) && + ((pInputStream[2] >> 3) == 0x00)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pProfileLevel = supportedAVCProfileLevels; + maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; + pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if(pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + width = ((pSECPort->portDefinition.format.video.nFrameWidth + 15) & (~15)); + height = ((pSECPort->portDefinition.format.video.nFrameHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) { + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + } else if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV422Planar) { + pSECOutputPort->portDefinition.nBufferSize = width * height * 2; + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) + goto EXIT; + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + + pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex]; + pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; + pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexVendorThumbnailMode: + { + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + + pH264Dec->hMFCH264Handle.bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure); + + ret = OMX_ErrorNone; + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, "OMX.SEC.index.ThumbnailMode") == 0) { + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + + +OMX_ERRORTYPE SEC_MFC_H264Dec_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_H264_DEC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + OMX_PTR hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Function Codec) decoder and CMM(Codec Memory Management) driver open */ + hMFCHandle = (OMX_PTR)SsbSipMfcDecOpen(); + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Dec->hMFCH264Handle.hMFCHandle = hMFCHandle; + + /* Allocate decoder's input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = pStreamBuffer; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = pStreamPhyBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pStreamBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Dec->hMFCH264Handle.indexTimestamp = 0; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +EXIT: + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + OMX_PTR hMFCHandle = NULL; + + FunctionIn(); + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle; + + pH264Dec->hMFCH264Handle.pMFCStreamBuffer = NULL; + pH264Dec->hMFCH264Handle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 setConfVal = 0; + OMX_S32 returnCodec = 0; + int bufWidth; + int bufHeight; + + FunctionIn(); + + if (pH264Dec->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE eCodecType = H264_DEC; + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + setConfVal = 5; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &setConfVal); + + /* Default number in the driver is optimized */ + if (pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_TRUE) { + setConfVal = 0; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } else { + setConfVal = 8; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &setConfVal); + } + + returnCodec = SsbSipMfcDecInit(pH264Dec->hMFCH264Handle.hMFCHandle, eCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + SSBSIP_MFC_CROP_INFORMATION cropInfo; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol); + SEC_OSAL_Log(SEC_LOG_TRACE, "set width height information : %d, %d", + secInputPort->portDefinition.format.video.nFrameWidth, + secInputPort->portDefinition.format.video.nFrameHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc width height information : %d, %d", + imgResol.width, imgResol.height); + + SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_CROP_INFO, &cropInfo); + SEC_OSAL_Log(SEC_LOG_TRACE, "mfc crop_top crop_bottom crop_left crop_right : %d, %d, %d, %d", + cropInfo.crop_top_offset , cropInfo.crop_bottom_offset , + cropInfo.crop_left_offset , cropInfo.crop_right_offset); + + int actualWidth = imgResol.width - cropInfo.crop_left_offset - cropInfo.crop_right_offset; + int actualHeight = imgResol.height - cropInfo.crop_top_offset - cropInfo.crop_bottom_offset; + + /** Update Frame Size **/ + if((secInputPort->portDefinition.format.video.nFrameWidth != actualWidth) || + (secInputPort->portDefinition.format.video.nFrameHeight != actualHeight)) { + SEC_OSAL_Log(SEC_LOG_TRACE, "change width height information : OMX_EventPortSettingsChanged"); + /* change width and height information */ + secInputPort->portDefinition.format.video.nFrameWidth = actualWidth; + secInputPort->portDefinition.format.video.nFrameHeight = actualHeight; + secInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + secInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /** Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, /* The command was completed */ + OMX_DirOutput, /* This is the port index */ + 0, + NULL); + } + + pH264Dec->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; +#ifdef ADD_SPS_PPS_I_FRAME + ret = OMX_ErrorInputDataDecodeYet; +#else + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; +#endif + goto EXIT; + } else { + ret = OMX_ErrorMFCInit; + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } +#endif + + pSECComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pH264Dec->hMFCH264Handle.indexTimestamp)); + pH264Dec->hMFCH264Handle.indexTimestamp++; + if (pH264Dec->hMFCH264Handle.indexTimestamp >= MAX_TIMESTAMP) + pH264Dec->hMFCH264Handle.indexTimestamp = 0; + + if (Check_H264_StartCode(pInputData->dataBuffer, pInputData->dataLen) == OMX_TRUE) { + returnCodec = SsbSipMfcDecExe(pH264Dec->hMFCH264Handle.hMFCHandle, oneFrameSize); + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(pH264Dec->hMFCH264Handle.hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + + if ((SsbSipMfcDecGetConfig(pH264Dec->hMFCH264Handle.hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; + break; + default: + pOutputData->dataLen = bufWidth * bufHeight * 2; + break; + } + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + if(status == MFC_GETOUTBUF_DECODING_ONLY) { + /* ret = OMX_ErrorInputDataDecodeYet; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; + break; + default: + pOutputData->dataLen = bufWidth * bufHeight * 2; + break; + } + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pOutputData->dataLen = 0; + } + + /* ret = OMX_ErrorUndefined; */ /* ????? */ + ret = OMX_ErrorNone; + goto EXIT; + } + + /** Fill Output Buffer **/ + if (pOutputData->dataLen > 0) + { + int frameSize = bufWidth * bufHeight; + void *pOutBuf = (void *)pOutputData->dataBuffer; + +#ifdef USE_SAMSUNG_COLORFORMAT + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress)) + +#else + if (pH264Dec->hMFCH264Handle.bThumbnailMode == OMX_FALSE) +#endif + { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutBuf, &frameSize, sizeof(frameSize)); + SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize), &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy(pOutBuf + sizeof(frameSize) + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + Y_tile_to_linear_4x2( + (unsigned char *)pOutBuf, + (unsigned char *)outputInfo.YVirAddr, + bufWidth, bufHeight); + CbCr_tile_to_linear_4x2( + ((unsigned char *)pOutBuf) + frameSize, + (unsigned char *)outputInfo.CVirAddr, + bufWidth, bufHeight); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_H264Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264DEC_HANDLE *pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL endOfFrame = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = SEC_MFC_H264_Decode(pOMXComponent, pInputData, pOutputData); + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_H264_DEC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Dec = SEC_OSAL_Malloc(sizeof(SEC_H264DEC_HANDLE)); + if (pH264Dec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pH264Dec, 0, sizeof(SEC_H264DEC_HANDLE)); + pSECComponent->hCodecHandle = (OMX_HANDLETYPE)pH264Dec; + + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_H264_DEC); + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); + pH264Dec->AVCComponent[i].nPortIndex = i; + pH264Dec->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; + pH264Dec->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel4; + } + + pOMXComponent->GetParameter = &SEC_MFC_H264Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_H264Dec_SetParameter; + pOMXComponent->SetConfig = &SEC_MFC_H264Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_H264Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Dec_bufferProcess; + pSECComponent->sec_checkInputFrame = &Check_H264_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264DEC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pH264Dec = (SEC_H264DEC_HANDLE *)pSECComponent->hCodecHandle; + if (pH264Dec != NULL) { + SEC_OSAL_Free(pH264Dec); + pH264Dec = pSECComponent->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if(ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h new file mode 100644 index 0000000..b1374fb --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/SEC_OMX_H264dec.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264dec.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_DEC_COMPONENT +#define SEC_OMX_H264_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" + + +typedef struct _SEC_MFC_H264DEC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + OMX_BOOL bThumbnailMode; +} SEC_MFC_H264DEC_HANDLE; + +typedef struct _SEC_H264DEC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_H264DEC_HANDLE hMFCH264Handle; +} SEC_H264DEC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.c b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.c new file mode 100644 index 0000000..f7bcf25 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.c @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) +{ + FunctionIn(); + + if (secComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPOMENT_H264_DEC); + SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPOMENT_H264_DEC_ROLE); + secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} + diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.h b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.h new file mode 100644 index 0000000..cdbfaa4 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/h264dec/library_register.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_REG +#define SEC_OMX_H264_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* H.264 */ +#define SEC_OMX_COMPOMENT_H264_DEC "OMX.SEC.AVC.Decoder" +#define SEC_OMX_COMPOMENT_H264_DEC_ROLE "video_decoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/Android.mk new file mode 100644 index 0000000..007ce5f --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Mpeg4dec.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.M4V.Decoder.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Vdec.smdkc210 libsecosal.smdkc210 libsecbasecomponent.smdkc210 libsecmfcdecapi.smdkc210 +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_SHARED_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c new file mode 100644 index 0000000..5074214 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.c @@ -0,0 +1,1399 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4dec.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Vdec.h" +#include "library_register.h" +#include "SEC_OMX_Mpeg4dec.h" +#include "SsbSipMfcApi.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +//#define FULL_FRAME_SEARCH + +/* MPEG4 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; + +/* H.263 Decoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { + /* Baseline (Profile 0) */ + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}, + /* Profile 1 */ + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileH320Coding, OMX_VIDEO_H263Level70}, + /* Profile 2 */ + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBackwardCompatible, OMX_VIDEO_H263Level70}, + /* Profile 3, restricted up to SD resolution */ + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileISWV2, OMX_VIDEO_H263Level70}}; + +static OMX_HANDLETYPE ghMFCHandle = NULL; +static OMX_BOOL gbFIMV1 = OMX_FALSE; + +static int Check_Mpeg4_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + int len, readStream; + unsigned startCode; + OMX_BOOL bFrameStart; + + len = 0; + bFrameStart = OMX_FALSE; + + if (flag & OMX_BUFFERFLAG_CODECCONFIG) { + if (*pInputStream == 0x03) { /* FIMV1 */ + if (ghMFCHandle != NULL) { + BitmapInfoHhr *pInfoHeader; + SSBSIP_MFC_IMG_RESOLUTION imgResolution; + + pInfoHeader = (BitmapInfoHhr *)(pInputStream + 1); + imgResolution.width = pInfoHeader->BiWidth; + imgResolution.height = pInfoHeader->BiHeight; + SsbSipMfcDecSetConfig(ghMFCHandle, MFC_DEC_SETCONF_FIMV1_WIDTH_HEIGHT, &imgResolution); + + SEC_OSAL_Log(SEC_LOG_TRACE, "width(%d), height(%d)", imgResolution.width, imgResolution.height); + gbFIMV1 = OMX_TRUE; + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + } + } + + if (gbFIMV1) { + *pbEndOfFrame = OMX_TRUE; + return buffSize; + } + + if (bPreviousFrameEOF == OMX_FALSE) + bFrameStart = OMX_TRUE; + + startCode = 0xFFFFFFFF; + if (bFrameStart == OMX_FALSE) { + /* find VOP start code */ + while(startCode != 0x1B6) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + } + + /* find next VOP start code */ + startCode = 0xFFFFFFFF; + while ((startCode != 0x1B6)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + + *pbEndOfFrame = OMX_TRUE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 4, buffSize); + + return len - 4; + +EXIT : + *pbEndOfFrame = OMX_FALSE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_Mpeg4_Frame returned EOF = %d, len = %d, buffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +static int Check_H263_Frame(OMX_U8 *pInputStream, OMX_U32 buffSize, OMX_U32 flag, OMX_BOOL bPreviousFrameEOF, OMX_BOOL *pbEndOfFrame) +{ + int len, readStream; + unsigned startCode; + OMX_BOOL bFrameStart = 0; + + len = 0; + bFrameStart = OMX_FALSE; + + if (bPreviousFrameEOF == OMX_FALSE) + bFrameStart = OMX_TRUE; + + startCode = 0xFFFFFFFF; + if (bFrameStart == OMX_FALSE) { + /* find PSC(Picture Start Code) : 0000 0000 0000 0000 1000 00 */ + while (((startCode << 8 >> 10) != 0x20)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + } + + /* find next PSC */ + startCode = 0xFFFFFFFF; + while (((startCode << 8 >> 10) != 0x20)) { + readStream = *(pInputStream + len); + startCode = (startCode << 8) | readStream; + len++; + if (len > buffSize) + goto EXIT; + } + + *pbEndOfFrame = OMX_TRUE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "1. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 3, buffSize); + + return len - 3; + +EXIT : + + *pbEndOfFrame = OMX_FALSE; + + SEC_OSAL_Log(SEC_LOG_TRACE, "2. Check_H263_Frame returned EOF = %d, len = %d, iBuffSize = %d", *pbEndOfFrame, len - 1, buffSize); + + return --len; +} + +OMX_BOOL Check_Stream_PrefixCode(OMX_U8 *pInputStream, OMX_U32 streamSize, CODEC_TYPE codecType) +{ + switch (codecType) { + case CODEC_TYPE_MPEG4: + if (gbFIMV1) { + return OMX_TRUE; + } else { + if (streamSize < 3) { + return OMX_FALSE; + } else if ((pInputStream[0] == 0x00) && + (pInputStream[1] == 0x00) && + (pInputStream[2] == 0x01)) { + return OMX_TRUE; + } else { + return OMX_FALSE; + } + } + break; + case CODEC_TYPE_H263: + if (streamSize > 0) + return OMX_TRUE; + else + return OMX_FALSE; + default: + SEC_OSAL_Log(SEC_LOG_WARNING, "%s: undefined codec type (%d)", __FUNCTION__, codecType); + return OMX_FALSE; + } +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_MPEG4_DEC_ROLE); + else + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_H263_DEC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; + } else { + pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcH263Param->eProfile; + pDstProfileLevel->eLevel = pSrcH263Param->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_MPEG4_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + //((SEC_MPEG4_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; + } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_H263_DEC_ROLE)) { + pSECComponent->pSECPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + //((SEC_MPEG4_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure; + OMX_U32 portIndex = pPortDefinition->nPortIndex; + SEC_OMX_BASEPORT *pSECPort; + OMX_U32 width, height, size; + + if (portIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + ret = SEC_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[portIndex]; + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + if (pSECPort->portDefinition.bEnabled == OMX_TRUE) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + } + if (pPortDefinition->nBufferCountActual < pSECPort->portDefinition.nBufferCountMin) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_Memcpy(&pSECPort->portDefinition, pPortDefinition, pPortDefinition->nSize); + + width = ((pSECPort->portDefinition.format.video.nFrameWidth + 15) & (~15)); + height = ((pSECPort->portDefinition.format.video.nFrameHeight + 15) & (~15)); + size = (width * height * 3) / 2; + pSECPort->portDefinition.format.video.nStride = width; + pSECPort->portDefinition.format.video.nSliceHeight = height; + pSECPort->portDefinition.nBufferSize = (size > pSECPort->portDefinition.nBufferSize) ? size : pSECPort->portDefinition.nBufferSize; + + if (portIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = pSECPort->portDefinition.format.video.nFrameWidth; + pSECOutputPort->portDefinition.format.video.nFrameHeight = pSECPort->portDefinition.format.video.nFrameHeight; + pSECOutputPort->portDefinition.format.video.nStride = width; + pSECOutputPort->portDefinition.format.video.nSliceHeight = height; + if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) { + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + } else if (pSECOutputPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV422Planar) { + pSECOutputPort->portDefinition.nBufferSize = width * height * 2; + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + /* + * To do: Check validity of profile & level parameters + */ + + pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; + } else { + /* + * To do: Check validity of profile & level parameters + */ + + pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex]; + pDstH263Param->eProfile = pSrcProfileLevel->eProfile; + pDstH263Param->eLevel = pSrcProfileLevel->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexVendorThumbnailMode: + { + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + + pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode = *((OMX_BOOL *)pComponentConfigStructure); + } + break; + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_GetExtensionIndex( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE *pIndexType) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if ((cParameterName == NULL) || (pIndexType == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + if (SEC_OSAL_Strcmp(cParameterName, "OMX.SEC.index.ThumbnailMode") == 0) { + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + + *pIndexType = OMX_IndexVendorThumbnailMode; + + ret = OMX_ErrorNone; + } else { + ret = SEC_OMX_GetExtensionIndex(hComponent, cParameterName, pIndexType); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + codecType = ((SEC_MPEG4_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_MPEG4_DEC_ROLE); + else + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_H263_DEC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + OMX_PTR pStreamBuffer = NULL; + OMX_PTR pStreamPhyBuffer = NULL; + + FunctionIn(); + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Format Codec) decoder and CMM(Codec Memory Management) driver open */ + hMFCHandle = SsbSipMfcDecOpen(); + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + ghMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; + + /* Allocate decoder's input buffer */ + pStreamBuffer = SsbSipMfcDecGetInBuf(hMFCHandle, &pStreamPhyBuffer, DEFAULT_MFC_INPUT_BUFFER_SIZE); + if (pStreamBuffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = pStreamBuffer; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = pStreamPhyBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = pStreamBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = DEFAULT_MFC_INPUT_BUFFER_SIZE; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + + FunctionIn(); + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamBuffer = NULL; + pMpeg4Dec->hMFCMpeg4Handle.pMFCStreamPhyBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = NULL; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = 0; + + if (hMFCHandle != NULL) { + SsbSipMfcDecClose(hMFCHandle); + pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Decode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle; + OMX_U32 oneFrameSize = pInputData->dataLen; + SSBSIP_MFC_DEC_OUTPUT_INFO outputInfo; + OMX_S32 configValue; + OMX_S32 returnCodec; + int bufWidth; + int bufHeight; + + FunctionIn(); + + if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + SSBSIP_MFC_CODEC_TYPE MFCCodecType; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + if (gbFIMV1) + MFCCodecType = FIMV1_DEC; + else + MFCCodecType = MPEG4_DEC; + } else { + MFCCodecType = H263_DEC; + } + + if ((oneFrameSize <= 0) && (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + goto EXIT; + } + + /* Set the number of extra buffer to prevent tearing */ + configValue = 5; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_EXTRA_BUFFER_NUM, &configValue); + + /* Set mpeg4 deblocking filter enable */ + configValue = 1; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_POST_ENABLE, &configValue); + + if (pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode == OMX_TRUE) { + configValue = 0; // the number that you want to delay + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_DISPLAY_DELAY, &configValue); + } + + returnCodec = SsbSipMfcDecInit(hMFCHandle, MFCCodecType, oneFrameSize); + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_IMG_RESOLUTION imgResol; + SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + + if (SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_BUF_WIDTH_HEIGHT, &imgResol) != MFC_RET_OK) { + ret = OMX_ErrorMFCInit; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecGetConfig failed", __FUNCTION__); + goto EXIT; + } + + /** Update Frame Size **/ + if ((pInputPort->portDefinition.format.video.nFrameWidth != imgResol.width) || + (pInputPort->portDefinition.format.video.nFrameHeight != imgResol.height)) { + /* change width and height information */ + pInputPort->portDefinition.format.video.nFrameWidth = imgResol.width; + pInputPort->portDefinition.format.video.nFrameHeight = imgResol.height; + pInputPort->portDefinition.format.video.nStride = ((imgResol.width + 15) & (~15)); + pInputPort->portDefinition.format.video.nSliceHeight = ((imgResol.height + 15) & (~15)); + + SEC_UpdateFrameSize(pOMXComponent); + + /* Send Port Settings changed call back */ + (*(pSECComponent->pCallbacks->EventHandler)) + (pOMXComponent, + pSECComponent->callbackData, + OMX_EventPortSettingsChanged, // The command was completed + OMX_DirOutput, // This is the port index + 0, + NULL); + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "nFrameWidth(%d) nFrameHeight(%d), nStride(%d), nSliceHeight(%d)", + pInputPort->portDefinition.format.video.nFrameWidth, pInputPort->portDefinition.format.video.nFrameHeight, + pInputPort->portDefinition.format.video.nStride, pInputPort->portDefinition.format.video.nSliceHeight); + + pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + ret = OMX_ErrorNone; + } else { + pOutputData->dataLen = 0; + ret = OMX_ErrorInputDataDecodeYet; + } + goto EXIT; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcDecInit failed", __FUNCTION__); + ret = OMX_ErrorMFCInit; /* OMX_ErrorUndefined */ + goto EXIT; + } + } + +#ifndef FULL_FRAME_SEARCH + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } +#endif + + pSECComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcDecSetConfig(hMFCHandle, MFC_DEC_SETCONF_FRAME_TAG, &(pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp)); + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++; + if (pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp >= MAX_TIMESTAMP) + pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0; + + if (Check_Stream_PrefixCode(pInputData->dataBuffer, pInputData->dataLen, pMpeg4Dec->hMFCMpeg4Handle.codecType) == OMX_TRUE) { + returnCodec = SsbSipMfcDecExe(hMFCHandle, oneFrameSize); + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + returnCodec = MFC_RET_OK; + goto EXIT; + } + + if (returnCodec == MFC_RET_OK) { + SSBSIP_MFC_DEC_OUTBUF_STATUS status; + OMX_S32 indexTimestamp = 0; + + status = SsbSipMfcDecGetOutBuf(hMFCHandle, &outputInfo); + bufWidth = (outputInfo.img_width + 15) & (~15); + bufHeight = (outputInfo.img_height + 15) & (~15); + + if ((SsbSipMfcDecGetConfig(hMFCHandle, MFC_DEC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if ((status == MFC_GETOUTBUF_DISPLAY_DECODING) || + (status == MFC_GETOUTBUF_DISPLAY_ONLY)) { + switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pOutputData->dataLen = (bufWidth * bufHeight * 3) /2; + break; + default: + pOutputData->dataLen = bufWidth * bufHeight * 2; + break; + } + } + if (pOutputData->nFlags & OMX_BUFFERFLAG_EOS) + pOutputData->dataLen = 0; + + if ((status == MFC_GETOUTBUF_DISPLAY_ONLY) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE)) { + ret = OMX_ErrorInputDataDecodeYet; + } + + if (status == MFC_GETOUTBUF_DECODING_ONLY) { + /* ret = OMX_ErrorInputDataDecodeYet; */ + ret = OMX_ErrorNone; + goto EXIT; + } + +#ifdef FULL_FRAME_SEARCH + if (((pInputData->nFlags & OMX_BUFFERFLAG_EOS) != OMX_BUFFERFLAG_EOS) && + (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + pInputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else +#endif + + if ((pInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pInputData->nFlags = (pOutputData->nFlags & (~OMX_BUFFERFLAG_EOS)); + pSECComponent->getAllDelayBuffer = OMX_TRUE; + ret = OMX_ErrorInputDataDecodeYet; + } else if ((pOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) { + pSECComponent->getAllDelayBuffer = OMX_FALSE; + ret = OMX_ErrorNone; + } + } else { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + switch(pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + pOutputData->dataLen = (bufWidth * bufHeight * 3) / 2; + break; + default: + pOutputData->dataLen = bufWidth * bufHeight * 2; + break; + } + + if ((pSECComponent->bSaveFlagEOS == OMX_TRUE) || + (pSECComponent->getAllDelayBuffer == OMX_TRUE) || + (pInputData->nFlags & OMX_BUFFERFLAG_EOS)) { + pOutputData->nFlags |= OMX_BUFFERFLAG_EOS; + pSECComponent->getAllDelayBuffer = OMX_FALSE; + pOutputData->dataLen = 0; + } + + /* ret = OMX_ErrorUndefined; */ /* ????? */ + ret = OMX_ErrorNone; + goto EXIT; + } + + /** Fill Output Buffer **/ + if (pOutputData->dataLen > 0) + { + int frameSize = bufWidth * bufHeight; + void *pOutputBuf = (void *)pOutputData->dataBuffer; + +#ifdef USE_SAMSUNG_COLORFORMAT + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode == OMX_FALSE) && + (pSECOutputPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress)) + +#else + if (pMpeg4Dec->hMFCMpeg4Handle.bThumbnailMode == OMX_FALSE) +#endif + { + /* if use Post copy address structure */ + SEC_OSAL_Memcpy(pOutputBuf, &frameSize, sizeof(frameSize)); + SEC_OSAL_Memcpy(pOutputBuf + sizeof(frameSize), &(outputInfo.YPhyAddr), sizeof(outputInfo.YPhyAddr)); + SEC_OSAL_Memcpy(pOutputBuf + sizeof(frameSize) + (sizeof(void *) * 1), &(outputInfo.CPhyAddr), sizeof(outputInfo.CPhyAddr)); + SEC_OSAL_Memcpy(pOutputBuf + sizeof(frameSize) + (sizeof(void *) * 2), &(outputInfo.YVirAddr), sizeof(outputInfo.YVirAddr)); + SEC_OSAL_Memcpy(pOutputBuf + sizeof(frameSize) + (sizeof(void *) * 3), &(outputInfo.CVirAddr), sizeof(outputInfo.CVirAddr)); + } else { + SEC_OSAL_Log(SEC_LOG_TRACE, "YUV420 out for ThumbnailMode"); + Y_tile_to_linear_4x2( + (unsigned char *)pOutputBuf, + (unsigned char *)outputInfo.YVirAddr, + bufWidth, bufHeight); + CbCr_tile_to_linear_4x2( + ((unsigned char *)pOutputBuf) + frameSize, + (unsigned char *)outputInfo.CVirAddr, + bufWidth, bufHeight); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Decode */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Dec_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4_HANDLE *pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL bCheckPrefix = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = SEC_MFC_Mpeg4_Decode(pOMXComponent, pInputData, pOutputData); + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataDecodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->previousDataLen = pInputData->dataLen; + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + OMX_S32 codecType = -1; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_MPEG4_DEC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_H263_DEC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoDecodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Dec = SEC_OSAL_Malloc(sizeof(SEC_MPEG4_HANDLE)); + if (pMpeg4Dec == NULL) { + SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pMpeg4Dec, 0, sizeof(SEC_MPEG4_HANDLE)); + pSECComponent->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec; + pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_MPEG4_DEC); + else + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_H263_DEC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + if (codecType == CODEC_TYPE_MPEG4) { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (codecType == CODEC_TYPE_MPEG4) { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); + pMpeg4Dec->mpeg4Component[i].nPortIndex = i; + pMpeg4Dec->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; + pMpeg4Dec->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level3; + } + } else { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); + pMpeg4Dec->h263Component[i].nPortIndex = i; + pMpeg4Dec->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2; + pMpeg4Dec->h263Component[i].eLevel = OMX_VIDEO_H263Level45; + } + } + + pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Dec_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Dec_SetParameter; + pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Dec_SetConfig; + pOMXComponent->GetExtensionIndex = &SEC_MFC_Mpeg4Dec_GetExtensionIndex; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Dec_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Dec_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Dec_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Dec_bufferProcess; + if (codecType == CODEC_TYPE_MPEG4) + pSECComponent->sec_checkInputFrame = &Check_Mpeg4_Frame; + else + pSECComponent->sec_checkInputFrame = &Check_H263_Frame; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MPEG4_HANDLE *pMpeg4Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pMpeg4Dec = (SEC_MPEG4_HANDLE *)pSECComponent->hCodecHandle; + if (pMpeg4Dec != NULL) { + SEC_OSAL_Free(pMpeg4Dec); + pSECComponent->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoDecodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h new file mode 100644 index 0000000..25170b8 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/SEC_OMX_Mpeg4dec.h @@ -0,0 +1,91 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4dec.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_DEC_COMPONENT +#define SEC_OMX_MPEG4_DEC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" + + +typedef enum _CODEC_TYPE +{ + CODEC_TYPE_H263, + CODEC_TYPE_MPEG4 +} CODEC_TYPE; + +/* + * This structure is the same as BitmapInfoHhr struct in pv_avifile_typedefs.h file + */ +typedef struct _BitmapInfoHhr +{ + OMX_U32 BiSize; + OMX_U32 BiWidth; + OMX_U32 BiHeight; + OMX_U16 BiPlanes; + OMX_U16 BiBitCount; + OMX_U32 BiCompression; + OMX_U32 BiSizeImage; + OMX_U32 BiXPelsPerMeter; + OMX_U32 BiYPelsPerMeter; + OMX_U32 BiClrUsed; + OMX_U32 BiClrImportant; +} BitmapInfoHhr; + +typedef struct _SEC_MFC_MPEG4_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + OMX_PTR pMFCStreamBuffer; + OMX_PTR pMFCStreamPhyBuffer; + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + OMX_BOOL bThumbnailMode; + CODEC_TYPE codecType; +} SEC_MFC_MPEG4_HANDLE; + +typedef struct _SEC_MPEG4_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_MPEG4_HANDLE hMFCMpeg4Handle; +} SEC_MPEG4_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.c b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.c new file mode 100644 index 0000000..89b856d --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.c @@ -0,0 +1,63 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_DEC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - video decoder MPEG4 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPOMENT_MPEG4_DEC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPOMENT_MPEG4_DEC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video decoder H.263 */ + SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPOMENT_H263_DEC); + SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPOMENT_H263_DEC_ROLE); + ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.h b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.h new file mode 100644 index 0000000..e9bcfe8 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/dec/mpeg4dec/library_register.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_DEC_REG +#define SEC_OMX_MPEG4_DEC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define SEC_OMX_COMPOMENT_MPEG4_DEC "OMX.SEC.MPEG4.Decoder" +#define SEC_OMX_COMPOMENT_MPEG4_DEC_ROLE "video_decoder.mpeg4" + +/* H.263 */ +#define SEC_OMX_COMPOMENT_H263_DEC "OMX.SEC.H263.Decoder" +#define SEC_OMX_COMPOMENT_H263_DEC_ROLE "video_decoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/enc/Android.mk new file mode 100644 index 0000000..de78419 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + SEC_OMX_Venc.c + +LOCAL_MODULE := libSEC_OMX_Venc.smdkc210 +LOCAL_ARM_MODE := arm +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/dec + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_STATIC_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.c b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.c new file mode 100644 index 0000000..eff5dec --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.c @@ -0,0 +1,1411 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Venc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include "SEC_OMX_Macros.h" +#include "SEC_OSAL_Event.h" +#include "SEC_OMX_Venc.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OSAL_Thread.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_VIDEO_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + +#define ONE_FRAME_OUTPUT /* only one frame output for Android */ +#define S5PC110_ENCODE_IN_DATA_BUFFER /* for Android s5pc110 0copy*/ + + +inline void SEC_UpdateFrameSize(OMX_COMPONENTTYPE *pOMXComponent) +{ + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + if ((secOutputPort->portDefinition.format.video.nFrameWidth != + secInputPort->portDefinition.format.video.nFrameWidth) || + (secOutputPort->portDefinition.format.video.nFrameHeight != + secInputPort->portDefinition.format.video.nFrameHeight)) { + OMX_U32 width = 0, height = 0; + + secOutputPort->portDefinition.format.video.nFrameWidth = + secInputPort->portDefinition.format.video.nFrameWidth; + secOutputPort->portDefinition.format.video.nFrameHeight = + secInputPort->portDefinition.format.video.nFrameHeight; + width = secOutputPort->portDefinition.format.video.nStride = + secInputPort->portDefinition.format.video.nStride; + height = secOutputPort->portDefinition.format.video.nSliceHeight = + secInputPort->portDefinition.format.video.nSliceHeight; + + switch(secOutputPort->portDefinition.format.video.eColorFormat) { + case OMX_COLOR_FormatYUV420Planar: + case OMX_COLOR_FormatYUV420SemiPlanar: + if (width && height) + secOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + break; + default: + if (width && height) + secOutputPort->portDefinition.nBufferSize = width * height * 2; + break; + } + } + + return ; +} + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + if (pSECPort->portState != OMX_StateIdle) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ASSIGNED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = pBuffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBufferHdr = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + if (nPortIndex >= pSECComponent->portParam.nPorts) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } +/* + if (pSECPort->portState != OMX_StateIdle ) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } +*/ + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + temp_buffer = SEC_OSAL_Malloc(sizeof(OMX_U8) * nSizeBytes); + if (temp_buffer == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + temp_bufferHeader = (OMX_BUFFERHEADERTYPE *)SEC_OSAL_Malloc(sizeof(OMX_BUFFERHEADERTYPE)); + if (temp_bufferHeader == NULL) { + SEC_OSAL_Free(temp_buffer); + temp_buffer = NULL; + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + SEC_OSAL_Memset(temp_bufferHeader, 0, sizeof(OMX_BUFFERHEADERTYPE)); + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (pSECPort->bufferStateAllocate[i] == BUFFER_STATE_FREE) { + pSECPort->bufferHeader[i] = temp_bufferHeader; + pSECPort->bufferStateAllocate[i] = (BUFFER_STATE_ALLOCATED | HEADER_STATE_ALLOCATED); + INIT_SET_SIZE_VERSION(temp_bufferHeader, OMX_BUFFERHEADERTYPE); + temp_bufferHeader->pBuffer = temp_buffer; + temp_bufferHeader->nAllocLen = nSizeBytes; + temp_bufferHeader->pAppPrivate = pAppPrivate; + if (nPortIndex == INPUT_PORT_INDEX) + temp_bufferHeader->nInputPortIndex = INPUT_PORT_INDEX; + else + temp_bufferHeader->nOutputPortIndex = OUTPUT_PORT_INDEX; + pSECPort->assignedBufferNum++; + if (pSECPort->assignedBufferNum == pSECPort->portDefinition.nBufferCountActual) { + pSECPort->portDefinition.bPopulated = OMX_TRUE; + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->loadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + } + *ppBuffer = temp_bufferHeader; + ret = OMX_ErrorNone; + goto EXIT; + } + } + ret = OMX_ErrorInsufficientResources; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECPort = &pSECComponent->pSECPort[nPortIndex]; + + if (CHECK_PORT_TUNNELED(pSECPort) && CHECK_PORT_BUFFER_SUPPLIER(pSECPort)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + if ((pSECPort->portState != OMX_StateLoaded) && (pSECPort->portState != OMX_StateInvalid)) { + (*(pSECComponent->pCallbacks->EventHandler)) (pOMXComponent, + pSECComponent->callbackData, + (OMX_U32)OMX_EventError, + (OMX_U32)OMX_ErrorPortUnpopulated, + nPortIndex, NULL); + } + + for (i = 0; i < pSECPort->portDefinition.nBufferCountActual; i++) { + if (((pSECPort->bufferStateAllocate[i] | BUFFER_STATE_FREE) != 0) && (pSECPort->bufferHeader[i] != NULL)) { + if (pSECPort->bufferHeader[i]->pBuffer == pBufferHdr->pBuffer) { + if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]->pBuffer); + pSECPort->bufferHeader[i]->pBuffer = NULL; + pBufferHdr->pBuffer = NULL; + } else if (pSECPort->bufferStateAllocate[i] & BUFFER_STATE_ASSIGNED) { + ; /* None*/ + } + pSECPort->assignedBufferNum--; + if (pSECPort->bufferStateAllocate[i] & HEADER_STATE_ALLOCATED) { + SEC_OSAL_Free(pSECPort->bufferHeader[i]); + pSECPort->bufferHeader[i] = NULL; + pBufferHdr = NULL; + } + pSECPort->bufferStateAllocate[i] = BUFFER_STATE_FREE; + ret = OMX_ErrorNone; + goto EXIT; + } + } + } + +EXIT: + if (ret == OMX_ErrorNone) { + if (pSECPort->assignedBufferNum == 0 ) { + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->unloadedResource signal set"); + /* SEC_OSAL_MutexLock(pSECComponent->compMutex); */ + SEC_OSAL_SemaphorePost(pSECPort->unloadedResource); + /* SEC_OSAL_MutexUnlock(pSECComponent->compMutex); */ + pSECPort->portDefinition.bPopulated = OMX_FALSE; + } + } + + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_BUFFERHEADERTYPE *temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer(SEC_OMX_BASEPORT *pOMXBasePort, OMX_U32 nPortIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT* pSECPort = NULL; + OMX_BUFFERHEADERTYPE* temp_bufferHeader = NULL; + OMX_U8 *temp_buffer = NULL; + OMX_U32 bufferSize = 0; + OMX_PARAM_PORTDEFINITIONTYPE portDefinition; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = OMX_ErrorTunnelingUnsupported; +EXIT: + return ret; +} + +OMX_BOOL SEC_Check_BufferProcess_State(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + if ((pSECComponent->currentState == OMX_StateExecuting) && + (pSECComponent->pSECPort[INPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portState == OMX_StateIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateExecutingToIdle) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToExecuting)) + return OMX_TRUE; + else + return OMX_FALSE; +} + +static OMX_ERRORTYPE SEC_InputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + if (secOMXInputPort->markType.hMarkTargetComponent != NULL ) { + bufferHeader->hMarkTargetComponent = secOMXInputPort->markType.hMarkTargetComponent; + bufferHeader->pMarkData = secOMXInputPort->markType.pMarkData; + secOMXInputPort->markType.hMarkTargetComponent = NULL; + secOMXInputPort->markType.pMarkData = NULL; + } + + if (bufferHeader->hMarkTargetComponent != NULL) { + if (bufferHeader->hMarkTargetComponent == pOMXComponent) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventMark, + 0, 0, bufferHeader->pMarkData); + } else { + pSECComponent->propagateMarkType.hMarkTargetComponent = bufferHeader->hMarkTargetComponent; + pSECComponent->propagateMarkType.pMarkData = bufferHeader->pMarkData; + } + } + + if (CHECK_PORT_TUNNELED(secOMXInputPort)) { + OMX_FillThisBuffer(secOMXInputPort->tunneledComponent, bufferHeader); + } else { + bufferHeader->nFilledLen = 0; + pSECComponent->pCallbacks->EmptyBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_InputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE* message = NULL; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid = OMX_TRUE; + dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; + dataBuffer->timeStamp = dataBuffer->bufferHeader->nTimeStamp; +#ifdef S5PC110_ENCODE_IN_DATA_BUFFER + pSECComponent->processData[INPUT_PORT_INDEX].dataBuffer = dataBuffer->bufferHeader->pBuffer; + pSECComponent->processData[INPUT_PORT_INDEX].allocSize = dataBuffer->bufferHeader->nAllocLen; +#endif + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; +} + +static OMX_ERRORTYPE SEC_OutputBufferReturn(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secOMXInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOMXOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; + + FunctionIn(); + + if (bufferHeader != NULL) { + bufferHeader->nFilledLen = dataBuffer->remainDataLen; + bufferHeader->nOffset = 0; + bufferHeader->nFlags = dataBuffer->nFlags; + bufferHeader->nTimeStamp = dataBuffer->timeStamp; + + if (pSECComponent->propagateMarkType.hMarkTargetComponent != NULL) { + bufferHeader->hMarkTargetComponent = pSECComponent->propagateMarkType.hMarkTargetComponent; + bufferHeader->pMarkData = pSECComponent->propagateMarkType.pMarkData; + pSECComponent->propagateMarkType.hMarkTargetComponent = NULL; + pSECComponent->propagateMarkType.pMarkData = NULL; + } + + if (bufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + pSECComponent->pCallbacks->EventHandler(pOMXComponent, + pSECComponent->callbackData, + OMX_EventBufferFlag, + OUTPUT_PORT_INDEX, + bufferHeader->nFlags, NULL); + } + + if (CHECK_PORT_TUNNELED(secOMXOutputPort)) { + OMX_EmptyThisBuffer(secOMXOutputPort->tunneledComponent, bufferHeader); + } else { + pSECComponent->pCallbacks->FillBufferDone(pOMXComponent, pSECComponent->callbackData, bufferHeader); + } + } + + if ((pSECComponent->currentState == OMX_StatePause) && + ((!CHECK_PORT_BEING_FLUSHED(secOMXInputPort) && !CHECK_PORT_BEING_FLUSHED(secOMXOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + /* reset dataBuffer */ + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OutputBufferGetQueue(SEC_OMX_BASECOMPONENT *pSECComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_OMX_DATABUFFER *dataBuffer = NULL; + SEC_OMX_MESSAGE *message = NULL; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + pSECPort= &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + dataBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + + if (pSECComponent->currentState != OMX_StateExecuting) { + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + SEC_OSAL_SemaphoreWait(pSECPort->bufferSemID); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if (dataBuffer->dataValid != OMX_TRUE) { + message = (SEC_OMX_MESSAGE *)SEC_OSAL_Dequeue(&pSECPort->bufferQ); + if (message == NULL) { + ret = OMX_ErrorUndefined; + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + goto EXIT; + } + + dataBuffer->bufferHeader = (OMX_BUFFERHEADERTYPE *)(message->pCmdData); + dataBuffer->allocSize = dataBuffer->bufferHeader->nAllocLen; + dataBuffer->dataLen = 0; //dataBuffer->bufferHeader->nFilledLen; + dataBuffer->remainDataLen = dataBuffer->dataLen; + dataBuffer->usedDataLen = 0; //dataBuffer->bufferHeader->nOffset; + dataBuffer->dataValid =OMX_TRUE; + /* dataBuffer->nFlags = dataBuffer->bufferHeader->nFlags; */ + /* dataBuffer->nTimeStamp = dataBuffer->bufferHeader->nTimeStamp; */ + SEC_OSAL_Free(message); + } + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = OMX_ErrorNone; + } +EXIT: + FunctionOut(); + + return ret; + +} + +static OMX_ERRORTYPE SEC_BufferReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + + dataBuffer->dataValid = OMX_FALSE; + dataBuffer->dataLen = 0; + dataBuffer->remainDataLen = 0; + dataBuffer->usedDataLen = 0; + dataBuffer->bufferHeader = NULL; + dataBuffer->nFlags = 0; + dataBuffer->timeStamp = 0; + + return ret; +} + +static OMX_ERRORTYPE SEC_DataReset(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 portIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + /* SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[portIndex]; */ + /* SEC_OMX_DATABUFFER *dataBuffer = &pSECComponent->secDataBuffer[portIndex]; */ + /* OMX_BUFFERHEADERTYPE *bufferHeader = dataBuffer->bufferHeader; */ + SEC_OMX_DATA *processData = &pSECComponent->processData[portIndex]; + + processData->dataLen = 0; + processData->remainDataLen = 0; + processData->usedDataLen = 0; + processData->nFlags = 0; + processData->timeStamp = 0; + + return ret; +} + +OMX_BOOL SEC_Preprocessor_InputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + OMX_BYTE checkInputStream = NULL; + OMX_U32 checkInputStreamLen = 0; + OMX_U32 checkedSize = 0; + OMX_BOOL flagEOS = OMX_FALSE; + OMX_BOOL flagEOF = OMX_FALSE; + OMX_BOOL previousFrameEOF = OMX_FALSE; + + if (inputUseBuffer->dataValid == OMX_TRUE) { + checkInputStream = inputUseBuffer->bufferHeader->pBuffer + inputUseBuffer->usedDataLen; + checkInputStreamLen = inputUseBuffer->remainDataLen; + + if ((inputUseBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } + + if (inputData->dataLen == 0) { + previousFrameEOF = OMX_TRUE; + } else { + previousFrameEOF = OMX_FALSE; + } + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + flagEOF = OMX_TRUE; + checkedSize = checkInputStreamLen; + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) { + flagEOS = OMX_TRUE; + } + } else { + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + int width = pSECPort->portDefinition.format.video.nFrameWidth; + int height = pSECPort->portDefinition.format.video.nFrameHeight; + int oneFrameSize = 0; + + if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) + oneFrameSize = (width * height * 3) / 2; + else if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) + oneFrameSize = (width * height * 3) / 2; + else if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV422Planar) + oneFrameSize = width * height * 2; + + if (previousFrameEOF == OMX_TRUE) { + if (checkInputStreamLen >= oneFrameSize) { + checkedSize = oneFrameSize; + flagEOF = OMX_TRUE; + } else { + flagEOF = OMX_FALSE; + } + } else { + if (checkInputStreamLen >= (oneFrameSize - inputData->dataLen)) { + checkedSize = oneFrameSize - inputData->dataLen; + flagEOF = OMX_TRUE; + } else { + flagEOF = OMX_FALSE; + } + } + + if ((flagEOF == OMX_FALSE) && (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) { + flagEOF = OMX_TRUE; + flagEOS = OMX_TRUE; + } + } + + if (flagEOF == OMX_TRUE) { + copySize = checkedSize; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_TRUE"); + } else { + copySize = checkInputStreamLen; + SEC_OSAL_Log(SEC_LOG_TRACE, "sec_checkInputFrame : OMX_FALSE"); + } + + if (inputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) + pSECComponent->bSaveFlagEOS = OMX_TRUE; + + if (((inputData->allocSize) - (inputData->dataLen)) >= copySize) { + SEC_OMX_BASEPORT *pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + +#ifndef S5PC110_ENCODE_IN_DATA_BUFFER + if (copySize > 0) { + SEC_OSAL_Memcpy(inputData->dataBuffer + inputData->dataLen, checkInputStream, copySize); + } +#else + if (pSECPort->portDefinition.format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) { + if (flagEOF == OMX_TRUE) { + OMX_U32 width, height; + + width = pSECPort->portDefinition.format.video.nFrameWidth; + height = pSECPort->portDefinition.format.video.nFrameHeight; + + SEC_OSAL_Log(SEC_LOG_TRACE, "inputData->specificBufferHeader.YVirAddr : 0x%x", inputData->specificBufferHeader.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "inputData->specificBufferHeader.CVirAddr : 0x%x", inputData->specificBufferHeader.CVirAddr); + + SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Ysize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Log(SEC_LOG_TRACE, "width:%d, height:%d, Csize:%d", width, height, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); + + SEC_OSAL_Memcpy(inputData->specificBufferHeader.YVirAddr, checkInputStream, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Memcpy(inputData->specificBufferHeader.CVirAddr, checkInputStream + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); + } + } +#endif + inputUseBuffer->dataLen -= copySize; + inputUseBuffer->remainDataLen -= copySize; + inputUseBuffer->usedDataLen += copySize; + + inputData->dataLen += copySize; + inputData->remainDataLen += copySize; + + if (previousFrameEOF == OMX_TRUE) { + inputData->timeStamp = inputUseBuffer->timeStamp; + inputData->nFlags = inputUseBuffer->nFlags; + } + + if (pSECComponent->bUseFlagEOF == OMX_TRUE) { + if (pSECComponent->bSaveFlagEOS == OMX_TRUE) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } + } else { + if ((checkedSize == checkInputStreamLen) && (pSECComponent->bSaveFlagEOS == OMX_TRUE)) { + inputData->nFlags |= OMX_BUFFERFLAG_EOS; + flagEOF = OMX_TRUE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + } else { + inputData->nFlags = (inputUseBuffer->nFlags & (~OMX_BUFFERFLAG_EOS)); + } + } + } else { + /*????????????????????????????????? Error ?????????????????????????????????*/ + SEC_DataReset(pOMXComponent, INPUT_PORT_INDEX); + flagEOF = OMX_FALSE; + } + + if (inputUseBuffer->remainDataLen == 0) { +#ifdef S5PC110_ENCODE_IN_DATA_BUFFER + if(flagEOF == OMX_FALSE) +#endif + SEC_InputBufferReturn(pOMXComponent); + } else { + inputUseBuffer->dataValid = OMX_TRUE; + } + } + + if (flagEOF == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_TRUE; + pSECComponent->checkTimeStamp.startTimeStamp = inputData->timeStamp; + pSECComponent->checkTimeStamp.nStartFlags = inputData->nFlags; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + } + + ret = OMX_TRUE; + } else { + ret = OMX_FALSE; + } + return ret; +} + +OMX_BOOL SEC_Postprocess_OutputData(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_BOOL ret = OMX_FALSE; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + if (outputUseBuffer->dataValid == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) { + if (pSECComponent->checkTimeStamp.startTimeStamp == outputData->timeStamp){ + pSECComponent->checkTimeStamp.startTimeStamp = -19761123; + pSECComponent->checkTimeStamp.nStartFlags = 0x0; + pSECComponent->checkTimeStamp.needSetStartTimeStamp = OMX_FALSE; + pSECComponent->checkTimeStamp.needCheckStartTimeStamp = OMX_FALSE; + } else { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + } else if (pSECComponent->checkTimeStamp.needSetStartTimeStamp == OMX_TRUE) { + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + + ret = OMX_TRUE; + goto EXIT; + } + + if (outputData->remainDataLen <= (outputUseBuffer->allocSize - outputUseBuffer->dataLen)) { + copySize = outputData->remainDataLen; + if (copySize > 0) + SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (outputData->dataBuffer + outputData->usedDataLen), + copySize); + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = outputData->nFlags; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_TRUE; + + /* reset outputData */ + SEC_DataReset(pOMXComponent, OUTPUT_PORT_INDEX); + +#ifdef ONE_FRAME_OUTPUT /* only one frame output for Android */ + if ((outputUseBuffer->remainDataLen > 0) || + (outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + SEC_OutputBufferReturn(pOMXComponent); +#else + if ((outputUseBuffer->remainDataLen > 0) || + ((outputUseBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) { + SEC_OutputBufferReturn(pOMXComponent); + } else { + outputUseBuffer->dataValid = OMX_TRUE; + } +#endif + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "output buffer is smaller than encoded data size Out Length"); + + copySize = outputUseBuffer->allocSize - outputUseBuffer->dataLen; + + SEC_OSAL_Memcpy((outputUseBuffer->bufferHeader->pBuffer + outputUseBuffer->dataLen), + (outputData->dataBuffer + outputData->usedDataLen), + copySize); + + outputUseBuffer->dataLen += copySize; + outputUseBuffer->remainDataLen += copySize; + outputUseBuffer->nFlags = 0; + outputUseBuffer->timeStamp = outputData->timeStamp; + + ret = OMX_FALSE; + + outputData->remainDataLen -= copySize; + outputData->usedDataLen += copySize; + + SEC_OutputBufferReturn(pOMXComponent); + } + } else { + ret = OMX_FALSE; + } + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *secInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *secOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *inputUseBuffer = &pSECComponent->secDataBuffer[INPUT_PORT_INDEX]; + SEC_OMX_DATABUFFER *outputUseBuffer = &pSECComponent->secDataBuffer[OUTPUT_PORT_INDEX]; + SEC_OMX_DATA *inputData = &pSECComponent->processData[INPUT_PORT_INDEX]; + SEC_OMX_DATA *outputData = &pSECComponent->processData[OUTPUT_PORT_INDEX]; + OMX_U32 copySize = 0; + + pSECComponent->remainOutputData = OMX_FALSE; + pSECComponent->reInputData = OMX_FALSE; + + FunctionIn(); + + while (!pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + if (((pSECComponent->currentState == OMX_StatePause) || + (pSECComponent->currentState == OMX_StateIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateLoadedToIdle) || + (pSECComponent->transientState == SEC_OMX_TransStateExecutingToIdle)) && + (pSECComponent->transientState != SEC_OMX_TransStateIdleToLoaded)&& + ((!CHECK_PORT_BEING_FLUSHED(secInputPort) && !CHECK_PORT_BEING_FLUSHED(secOutputPort)))) { + SEC_OSAL_SignalReset(pSECComponent->pauseEvent); + SEC_OSAL_SignalWait(pSECComponent->pauseEvent, DEF_MAX_WAIT_TIME); + } + + while (SEC_Check_BufferProcess_State(pSECComponent) && !pSECComponent->bExitBufferProcessThread) { + SEC_OSAL_SleepMillisec(0); + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + if ((outputUseBuffer->dataValid != OMX_TRUE) && + (!CHECK_PORT_BEING_FLUSHED(secOutputPort))) { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + ret = SEC_OutputBufferGetQueue(pSECComponent); + if ((ret == OMX_ErrorUndefined) || + (secInputPort->portState != OMX_StateIdle) || + (secOutputPort->portState != OMX_StateIdle)) { + break; + } + } else { + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + + if (pSECComponent->remainOutputData == OMX_FALSE) { + if (pSECComponent->reInputData == OMX_FALSE) { + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + if ((SEC_Preprocessor_InputData(pOMXComponent) == OMX_FALSE) && + (!CHECK_PORT_BEING_FLUSHED(secInputPort))) { + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + ret = SEC_InputBufferGetQueue(pSECComponent); + break; + } + + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + } + + SEC_OSAL_MutexLock(inputUseBuffer->bufferMutex); + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + ret = pSECComponent->sec_mfc_bufferProcess(pOMXComponent, inputData, outputData); +#ifdef S5PC110_ENCODE_IN_DATA_BUFFER + if (inputUseBuffer->remainDataLen == 0) + SEC_InputBufferReturn(pOMXComponent); + else + inputUseBuffer->dataValid = OMX_TRUE; +#endif + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + SEC_OSAL_MutexUnlock(inputUseBuffer->bufferMutex); + + if (ret == OMX_ErrorInputDataEncodeYet) + pSECComponent->reInputData = OMX_TRUE; + else + pSECComponent->reInputData = OMX_FALSE; + } + + SEC_OSAL_MutexLock(outputUseBuffer->bufferMutex); + + if (SEC_Postprocess_OutputData(pOMXComponent) == OMX_FALSE) + pSECComponent->remainOutputData = OMX_TRUE; + else + pSECComponent->remainOutputData = OMX_FALSE; + + SEC_OSAL_MutexUnlock(outputUseBuffer->bufferMutex); + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParam = (OMX_PORT_PARAM_TYPE *)ComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(portParam, sizeof(OMX_PORT_PARAM_TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + portParam->nPorts = pSECComponent->portParam.nPorts; + portParam->nStartPortNumber = pSECComponent->portParam.nStartPortNumber; + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + + if (portIndex == INPUT_PORT_INDEX) { + supportFormatNum = INPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + switch (index) { + case supportFormat_1: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420Planar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_2: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + case supportFormat_3: + portFormat->eCompressionFormat = OMX_VIDEO_CodingUnused; + portFormat->eColorFormat = SEC_OMX_COLOR_FormatNV12PhysicalAddress; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + break; + } + } else if (portIndex == OUTPUT_PORT_INDEX) { + supportFormatNum = OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX - 1; + if (index > supportFormatNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + portDefinition = &pSECPort->portDefinition; + + portFormat->eCompressionFormat = portDefinition->format.video.eCompressionFormat; + portFormat->eColorFormat = portDefinition->format.video.eColorFormat; + portFormat->xFramerate = portDefinition->format.video.xFramerate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + videoRateControl->eControlRate = pSECPort->eControlRate; + videoRateControl->nTargetBitrate = portDefinition->format.video.nBitrate; + } + ret = OMX_ErrorNone; + } + break; + default: + { + ret = SEC_OMX_GetParameter(hComponent, nParamIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + if (ComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure; + OMX_U32 portIndex = portFormat->nPortIndex; + OMX_U32 index = portFormat->nIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + OMX_U32 supportFormatNum = 0; + + ret = SEC_OMX_Check_SizeVersion(portFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((portIndex >= pSECComponent->portParam.nPorts)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + portDefinition->format.video.eColorFormat = portFormat->eColorFormat; + portDefinition->format.video.eCompressionFormat = portFormat->eCompressionFormat; + portDefinition->format.video.xFramerate = portFormat->xFramerate; + } + } + break; + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE *videoRateControl = (OMX_VIDEO_PARAM_BITRATETYPE *)ComponentParameterStructure; + OMX_U32 portIndex = videoRateControl->nPortIndex; + SEC_OMX_BASEPORT *pSECPort = NULL; + OMX_PARAM_PORTDEFINITIONTYPE *portDefinition = NULL; + + if ((portIndex != OUTPUT_PORT_INDEX)) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } else { + pSECPort = &pSECComponent->pSECPort[portIndex]; + portDefinition = &pSECPort->portDefinition; + + pSECPort->eControlRate = videoRateControl->eControlRate; + portDefinition->format.video.nBitrate = videoRateControl->nTargetBitrate; + } + ret = OMX_ErrorNone; + } + break; + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = + (OMX_PARAM_PORTDEFINITIONTYPE *)ComponentParameterStructure; + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pPortDefinition->nPortIndex == INPUT_PORT_INDEX) { + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + OMX_U32 width = pSECInputPort->portDefinition.format.video.nFrameWidth; + OMX_U32 height = pSECInputPort->portDefinition.format.video.nFrameHeight; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECOutputPort->portDefinition.format.video.nFrameWidth = width; + pSECOutputPort->portDefinition.format.video.nFrameHeight = height; + pSECOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2; + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECOutputPort->portDefinition.nBufferSize: %d", + pSECOutputPort->portDefinition.nBufferSize); + } + } + break; + default: + { + ret = SEC_OMX_SetParameter(hComponent, nIndex, ComponentParameterStructure); + } + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentInit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_BaseComponent_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = SEC_OMX_Port_Constructor(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OMX_BaseComponent_Destructor(pOMXComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_INPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = 0; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.nBufferCountActual = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferCountMin = MAX_VIDEO_OUTPUTBUFFER_NUM; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.eDomain = OMX_PortDomainVideo; + + pSECPort->portDefinition.format.video.cMIMEType = SEC_OSAL_Malloc(MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + pSECPort->portDefinition.format.video.nFrameWidth = 0; + pSECPort->portDefinition.format.video.nFrameHeight= 0; + pSECPort->portDefinition.format.video.nStride = 0; + pSECPort->portDefinition.format.video.nSliceHeight = 0; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate = (15 << 16); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.format.video.pNativeWindow = NULL; + + pOMXComponent->UseBuffer = &SEC_OMX_UseBuffer; + pOMXComponent->AllocateBuffer = &SEC_OMX_AllocateBuffer; + pOMXComponent->FreeBuffer = &SEC_OMX_FreeBuffer; + pOMXComponent->ComponentTunnelRequest = &SEC_OMX_ComponentTunnelRequest; + + pSECComponent->sec_AllocateTunnelBuffer = &SEC_OMX_AllocateTunnelBuffer; + pSECComponent->sec_FreeTunnelBuffer = &SEC_OMX_FreeTunnelBuffer; + pSECComponent->sec_BufferProcess = &SEC_OMX_BufferProcess; + pSECComponent->sec_BufferReset = &SEC_BufferReset; + pSECComponent->sec_InputBufferReturn = &SEC_InputBufferReturn; + pSECComponent->sec_OutputBufferReturn = &SEC_OutputBufferReturn; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + int i = 0; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + for(i = 0; i < ALL_PORT_NUM; i++) { + pSECPort = &pSECComponent->pSECPort[i]; + SEC_OSAL_Free(pSECPort->portDefinition.format.video.cMIMEType); + pSECPort->portDefinition.format.video.cMIMEType = NULL; + } + + ret = SEC_OMX_Port_Destructor(pOMXComponent); + + ret = SEC_OMX_BaseComponent_Destructor(hComponent); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h new file mode 100644 index 0000000..93d2800 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/SEC_OMX_Venc.h @@ -0,0 +1,106 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Venc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_VIDEO_ENCODE +#define SEC_OMX_VIDEO_ENCODE + +#include "OMX_Component.h" +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Queue.h" +#include "SEC_OMX_Baseport.h" + +#define MAX_VIDEO_INPUTBUFFER_NUM 5 +#define MAX_VIDEO_OUTPUTBUFFER_NUM 4 + +#define DEFAULT_FRAME_WIDTH 176 +#define DEFAULT_FRAME_HEIGHT 144 + +#define DEFAULT_VIDEO_INPUT_BUFFER_SIZE ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT)) \ + + ALIGN_TO_8KB(ALIGN_TO_128B(DEFAULT_FRAME_WIDTH) * ALIGN_TO_32B(DEFAULT_FRAME_HEIGHT / 2)) + /* (DEFAULT_FRAME_WIDTH * DEFAULT_FRAME_HEIGHT * 3) / 2 */ +#define DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE DEFAULT_VIDEO_INPUT_BUFFER_SIZE + +#define INPUT_PORT_SUPPORTFORMAT_NUM_MAX 3 +#define OUTPUT_PORT_SUPPORTFORMAT_NUM_MAX 1 + + +typedef struct +{ + void *pAddrY; + void *pAddrC; +} MFC_ENC_ADDR_INFO; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OMX_UseBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8 *pBuffer); +OMX_ERRORTYPE SEC_OMX_AllocateBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); +OMX_ERRORTYPE SEC_OMX_FreeBuffer( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE *pBufferHdr); +OMX_ERRORTYPE SEC_OMX_AllocateTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_FreeTunnelBuffer( + SEC_OMX_BASEPORT *pOMXBasePort, + OMX_U32 nPortIndex); +OMX_ERRORTYPE SEC_OMX_ComponentTunnelRequest( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE *pTunnelSetup); +OMX_ERRORTYPE SEC_OMX_BufferProcess(OMX_HANDLETYPE hComponent); +OMX_ERRORTYPE SEC_OMX_VideoEncodeGetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeSetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR ComponentParameterStructure); +OMX_ERRORTYPE SEC_OMX_VideoEncodeComponentDeinit(OMX_IN OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/Android.mk new file mode 100644 index 0000000..68819d5 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_H264enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.AVC.Encoder.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc.smdkc210 libsecosal.smdkc210 libsecbasecomponent.smdkc210 libsecmfcencapi.smdkc210 +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/enc \ + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_SHARED_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c new file mode 100644 index 0000000..239649e --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.c @@ -0,0 +1,1029 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264enc.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Venc.h" +#include "library_register.h" +#include "SEC_OMX_H264enc.h" +#include "SsbSipMfcApi.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_H264_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* H.264 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={ + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4}, + + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32}, + {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4}}; + + +OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile) +{ + OMX_U32 ret = 0; //default OMX_VIDEO_AVCProfileMain + + if (profile == OMX_VIDEO_AVCProfileMain) + ret = 0; + else if (profile == OMX_VIDEO_AVCProfileHigh) + ret = 1; + else if (profile == OMX_VIDEO_AVCProfileBaseline) + ret = 2; + + return ret; +} + +OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level) +{ + OMX_U32 ret = 40; //default OMX_VIDEO_AVCLevel4 + + if (level == OMX_VIDEO_AVCLevel1) + ret = 10; + else if (level == OMX_VIDEO_AVCLevel1b) + ret = 9; + else if (level == OMX_VIDEO_AVCLevel11) + ret = 11; + else if (level == OMX_VIDEO_AVCLevel12) + ret = 12; + else if (level == OMX_VIDEO_AVCLevel13) + ret = 13; + else if (level == OMX_VIDEO_AVCLevel2) + ret = 20; + else if (level == OMX_VIDEO_AVCLevel21) + ret = 21; + else if (level == OMX_VIDEO_AVCLevel22) + ret = 22; + else if (level == OMX_VIDEO_AVCLevel3) + ret = 30; + else if (level == OMX_VIDEO_AVCLevel31) + ret = 31; + else if (level == OMX_VIDEO_AVCLevel32) + ret = 32; + else if (level == OMX_VIDEO_AVCLevel4) + ret = 40; + + return ret; +} + +OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size) +{ + int i; + + for (i = 0; i < size - 3; i++) { + if ((pBuffer[i] == 0x00) && + (pBuffer[i+1] == 0x00) && + (pBuffer[i+2] == 0x00) && + (pBuffer[i+3] == 0x01)) + return (pBuffer + i); + } + + return NULL; +} + +void H264PrintParams(SSBSIP_MFC_ENC_H264_PARAM h264Arg) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", h264Arg.SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", h264Arg.SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", h264Arg.ProfileIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", h264Arg.LevelIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", h264Arg.IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberReferenceFrames : %d\n", h264Arg.NumberReferenceFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberRefForPframes : %d\n", h264Arg.NumberRefForPframes); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", h264Arg.SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", h264Arg.SliceArgument); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", h264Arg.NumberBFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterDisable : %d\n", h264Arg.LoopFilterDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterAlphaC0Offset : %d\n", h264Arg.LoopFilterAlphaC0Offset); + SEC_OSAL_Log(SEC_LOG_TRACE, "LoopFilterBetaOffset : %d\n", h264Arg.LoopFilterBetaOffset); + SEC_OSAL_Log(SEC_LOG_TRACE, "SymbolMode : %d\n", h264Arg.SymbolMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "PictureInterlace : %d\n", h264Arg.PictureInterlace); + SEC_OSAL_Log(SEC_LOG_TRACE, "Transform8x8Mode : %d\n", h264Arg.Transform8x8Mode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", h264Arg.RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", h264Arg.PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", h264Arg.LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", h264Arg.CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", h264Arg.CrPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", h264Arg.EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableMBRateControl : %d\n", h264Arg.EnableMBRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", h264Arg.FrameRate); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", h264Arg.Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", h264Arg.FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", h264Arg.QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", h264Arg.QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", h264Arg.CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "DarkDisable : %d\n", h264Arg.DarkDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "SmoothDisable : %d\n", h264Arg.SmoothDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "StaticDisable : %d\n", h264Arg.StaticDisable); + SEC_OSAL_Log(SEC_LOG_TRACE, "ActivityDisable : %d\n", h264Arg.ActivityDisable); +} + +void Set_H264ENC_Param(SSBSIP_MFC_ENC_H264_PARAM *pH264Arg, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pH264Arg->codecType = H264_ENC; + pH264Arg->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pH264Arg->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pH264Arg->IDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1; + pH264Arg->SliceMode = 0; + pH264Arg->RandomIntraMBRefresh = 0; + pH264Arg->EnableFRMRateControl = 1; // 0: Disable, 1: Frame level RC + pH264Arg->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pH264Arg->FrameQp = 20; + pH264Arg->FrameQp_P = 20; + pH264Arg->QSCodeMax = 30; + pH264Arg->QSCodeMin = 10; + pH264Arg->CBRPeriodRf = 100; + pH264Arg->PadControlOn = 0; // 0: disable, 1: enable + pH264Arg->LumaPadVal = 0; + pH264Arg->CbPadVal = 0; + pH264Arg->CrPadVal = 0; + + pH264Arg->ProfileIDC = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile); //0; //(OMX_VIDEO_AVCProfileMain) + pH264Arg->LevelIDC = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel); //40; //(OMX_VIDEO_AVCLevel4) + pH264Arg->FrameQp_B = 20; + pH264Arg->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + pH264Arg->SliceArgument = 0; // Slice mb/byte size number + pH264Arg->NumberBFrames = 0; // 0 ~ 2 + pH264Arg->NumberReferenceFrames = 1; + pH264Arg->NumberRefForPframes = 1; + pH264Arg->LoopFilterDisable = 1; // 1: Loop Filter Disable, 0: Filter Enable + pH264Arg->LoopFilterAlphaC0Offset = 0; + pH264Arg->LoopFilterBetaOffset = 0; + pH264Arg->SymbolMode = 0; // 0: CAVLC, 1: CABAC + pH264Arg->PictureInterlace = 0; + pH264Arg->Transform8x8Mode = 0; // 0: 4x4, 1: allow 8x8 + pH264Arg->EnableMBRateControl = 0; // 0: Disable, 1:MB level RC + pH264Arg->DarkDisable = 1; + pH264Arg->SmoothDisable = 1; + pH264Arg->StaticDisable = 1; + pH264Arg->ActivityDisable = 1; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); + switch (pSECOutputPort->eControlRate) { + case OMX_Video_ControlRateDisable: + /* TBD */ + break; + case OMX_Video_ControlRateVariable: + /* TBD */ + break; + default: + break; + } + + H264PrintParams(*pH264Arg); +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pProfileLevel = supportedAVCProfileLevels; + maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex]; + + pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile; + pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex]; + + SEC_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_H264_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + + pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex]; + pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile; + pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel; + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_SetConfig( + OMX_HANDLETYPE hComponent, + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) { + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_H264_ENC_ROLE); + ret = OMX_ErrorNone; + } else { + ret = OMX_ErrorNoMore; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + OMX_PTR hMFCHandle = NULL; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Function Codec) encoder and CMM(Codec Memory Management) driver open */ + hMFCHandle = (OMX_PTR)SsbSipMfcEncOpen(); + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pH264Enc->hMFCH264Handle.hMFCHandle = hMFCHandle; + + Set_H264ENC_Param(&(pH264Enc->hMFCH264Handle.mfcVideoAvc), pSECComponent); + + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pH264Enc->hMFCH264Handle.mfcVideoAvc)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* Allocate encoder's input buffer */ + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pH264Enc->hMFCH264Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.YVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.YVirAddr); + SEC_OSAL_Log(SEC_LOG_TRACE, "pH264Enc->hMFCH264Handle.inputInfo.CVirAddr : 0x%x", pH264Enc->hMFCH264Handle.inputInfo.CVirAddr); + + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pH264Enc->hMFCH264Handle.inputInfo.CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pH264Enc->hMFCH264Handle.inputInfo.YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pH264Enc->hMFCH264Handle.inputInfo.CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pH264Enc->hMFCH264Handle.inputInfo.YSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pH264Enc->hMFCH264Handle.inputInfo.CSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pH264Enc->hMFCH264Handle.indexTimestamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + OMX_PTR hMFCHandle = NULL; + + FunctionIn(); + + pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle; + + if (hMFCHandle != NULL) { + SsbSipMfcEncClose(hMFCHandle); + hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_H264_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &pH264Enc->hMFCH264Handle.inputInfo; + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + if (pH264Enc->hMFCH264Handle.bConfiguredMFC == OMX_FALSE) { + returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if (returnCodec != MFC_RET_OK) + { + SEC_OSAL_Log(SEC_LOG_TRACE, "%s - SsbSipMfcEncGetOutBuf Failed\n", __func__); + ret = OMX_ErrorUndefined; + goto EXIT; + } else { + char *p = NULL; + int iSpsSize = 0; + int iPpsSize = 0; + + p = FindDelimiter((OMX_U8 *)outputInfo.StrmVirAddr + 4, outputInfo.headerSize - 4); + + iSpsSize = (unsigned int)p - (unsigned int)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.pHeaderSPS = (OMX_PTR)outputInfo.StrmVirAddr; + pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize; + + iPpsSize = outputInfo.headerSize - iSpsSize; + pH264Enc->hMFCH264Handle.headerData.pHeaderPPS = outputInfo.StrmVirAddr + iSpsSize; + pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize; + } + + /* SEC_OSAL_Memcpy((void*)(pOutputData->dataBuffer), (const void*)(outputInfo.StrmVirAddr), outputInfo.headerSize); */ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pH264Enc->hMFCH264Handle.bConfiguredMFC = OMX_TRUE; + + ret = OMX_ErrorNone; + goto EXIT; + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } + + pSECComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcEncSetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pH264Enc->hMFCH264Handle.indexTimestamp)); + pH264Enc->hMFCH264Handle.indexTimestamp++; + if (pH264Enc->hMFCH264Handle.indexTimestamp >= MAX_TIMESTAMP) + pH264Enc->hMFCH264Handle.indexTimestamp = 0; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if (pSECPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress) { +#define USE_FIMC_FRAME_BUFFER +#ifdef USE_FIMC_FRAME_BUFFER + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + ret = SsbSipMfcEncSetInBuf(pH264Enc->hMFCH264Handle.hMFCHandle, pInputInfo); + if (ret != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_TRACE, "Error : SsbSipMfcEncSetInBuf() \n"); + ret = OMX_ErrorUndefined; + goto EXIT; + } +#else + OMX_U32 width, height; + + width = pSECPort->portDefinition.format.video.nFrameWidth; + height = pSECPort->portDefinition.format.video.nFrameHeight; + + SEC_OSAL_Memcpy(pInputInfo->YVirAddr, pInputData->dataBuffer, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Memcpy(pInputInfo->CVirAddr, pInputData->dataBuffer + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); +#endif + } + + returnCodec = SsbSipMfcEncExe(pH264Enc->hMFCH264Handle.hMFCHandle); + if (returnCodec == MFC_RET_OK) { + OMX_S32 indexTimestamp = 0; + + returnCodec = SsbSipMfcEncGetOutBuf(pH264Enc->hMFCH264Handle.hMFCHandle, &outputInfo); + if ((SsbSipMfcEncGetConfig(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))){ + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->usedDataLen = 0; + + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + SEC_OSAL_Log(SEC_LOG_TRACE, "MFC Encode OK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + + ret = OMX_ErrorNone; + } + } + + if (returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "In %s : SsbSipMfcEncExe OR SsbSipMfcEncGetOutBuf Failed!!!\n", __func__); + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Encode */ +OMX_ERRORTYPE SEC_MFC_H264Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_H264ENC_HANDLE *pH264Enc = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + SEC_OMX_BASEPORT *pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + OMX_BOOL endOfFrame = OMX_FALSE; + OMX_BOOL flagEOS = OMX_FALSE; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pSECInputPort)) || (!CHECK_PORT_ENABLED(pSECOutputPort)) || + (!CHECK_PORT_POPULATED(pSECInputPort)) || (!CHECK_PORT_POPULATED(pSECOutputPort))) { + ret = OMX_ErrorNone; + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + ret = OMX_ErrorNone; + goto EXIT; + } + + ret = SEC_MFC_H264_Encode(pOMXComponent, pInputData, pOutputData); + if (ret != OMX_ErrorNone) { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } else { + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + /* pOutputData->usedDataLen = 0; */ + pOutputData->remainDataLen = pOutputData->dataLen - pOutputData->usedDataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_H264ENC_HANDLE *pH264Enc = NULL; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_H264_ENC, componentName) != 0) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pH264Enc = SEC_OSAL_Malloc(sizeof(SEC_H264ENC_HANDLE)); + if (pH264Enc == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__); + goto EXIT; + } + SEC_OSAL_Memset(pH264Enc, 0, sizeof(SEC_H264ENC_HANDLE)); + pSECComponent->hCodecHandle = (OMX_HANDLETYPE)pH264Enc; + + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_H264_ENC); + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.eColorFormat = SEC_OMX_COLOR_FormatNV12PhysicalAddress; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/ + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/avc"); + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE); + pH264Enc->AVCComponent[i].nPortIndex = i; + pH264Enc->AVCComponent[i].eProfile = OMX_VIDEO_AVCProfileBaseline; + pH264Enc->AVCComponent[i].eLevel = OMX_VIDEO_AVCLevel31; + } + + pOMXComponent->GetParameter = &SEC_MFC_H264Enc_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_H264Enc_SetParameter; + pOMXComponent->SetConfig = &SEC_MFC_H264Enc_SetConfig; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_H264Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_H264Enc_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_H264Enc_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_H264Enc_bufferProcess; + pSECComponent->sec_checkInputFrame = NULL; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_H264ENC_HANDLE *pH264Dec = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pH264Dec = (SEC_H264ENC_HANDLE *)pSECComponent->hCodecHandle; + if (pH264Dec != NULL) { + SEC_OSAL_Free(pH264Dec); + pH264Dec = pSECComponent->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h new file mode 100644 index 0000000..80f6260 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/SEC_OMX_H264enc.h @@ -0,0 +1,76 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_H264enc.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_ENC_COMPONENT +#define SEC_OMX_H264_ENC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "OMX_Video.h" +#include "SsbSipMfcApi.h" + + +typedef struct _EXTRA_DATA +{ + OMX_PTR pHeaderSPS; + OMX_U32 SPSLen; + OMX_PTR pHeaderPPS; + OMX_U32 PPSLen; +} EXTRA_DATA; + +typedef struct _SEC_MFC_H264ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + SSBSIP_MFC_ENC_H264_PARAM mfcVideoAvc; + SSBSIP_MFC_ENC_INPUT_INFO inputInfo; +/* SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; */ + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + EXTRA_DATA headerData; +} SEC_MFC_H264ENC_HANDLE; + +typedef struct _SEC_H264ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_AVCTYPE AVCComponent[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_H264ENC_HANDLE hMFCH264Handle; +} SEC_H264ENC_HANDLE; + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.c b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.c new file mode 100644 index 0000000..ee1ea0a --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.c @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents) +{ + FunctionIn(); + + if (secComponents == NULL) + goto EXIT; + + /* component 1 - video decoder H.264 */ + SEC_OSAL_Strcpy(secComponents[0]->componentName, SEC_OMX_COMPOMENT_H264_ENC); + SEC_OSAL_Strcpy(secComponents[0]->roles[0], SEC_OMX_COMPOMENT_H264_ENC_ROLE); + secComponents[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + + return MAX_COMPONENT_NUM; +} + diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.h b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.h new file mode 100644 index 0000000..71397ef --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/h264enc/library_register.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_H264_REG +#define SEC_OMX_H264_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 1 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* H.264 */ +#define SEC_OMX_COMPOMENT_H264_ENC "OMX.SEC.AVC.Encoder" +#define SEC_OMX_COMPOMENT_H264_ENC_ROLE "video_encoder.avc" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **secComponents); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/Android.mk b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/Android.mk new file mode 100644 index 0000000..39baf0e --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OMX_Mpeg4enc.c \ + library_register.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libOMX.SEC.M4V.Encoder.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libSEC_OMX_Venc.smdkc210 libsecosal.smdkc210 libsecbasecomponent.smdkc210 libsecmfcencapi.smdkc210 +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_core \ + $(SEC_OMX_COMPONENT)/common \ + $(SEC_OMX_COMPONENT)/video/enc + +LOCAL_C_INCLUDES += $(SEC_OMX_TOP)/sec_codecs/video/mfc_c110/include + +include $(BUILD_SHARED_LIBRARY) diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c new file mode 100644 index 0000000..0596c25 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.c @@ -0,0 +1,1205 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4enc.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include + +#include "SEC_OMX_Macros.h" +#include "SEC_OMX_Basecomponent.h" +#include "SEC_OMX_Baseport.h" +#include "SEC_OMX_Venc.h" +#include "library_register.h" +#include "SEC_OMX_Mpeg4enc.h" +#include "SsbSipMfcApi.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +/* MPEG4 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedMPEG4ProfileLevels[] ={ + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level5}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level0b}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level1}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level2}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level3}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level4a}, + {OMX_VIDEO_MPEG4ProfileAdvancedSimple, OMX_VIDEO_MPEG4Level5}}; + +/* H.263 Encoder Supported Levels & profiles */ +SEC_OMX_VIDEO_PROFILELEVEL supportedH263ProfileLevels[] = { + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level20}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level30}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level40}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level45}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level50}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level60}, + {OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level70}}; + +OMX_U32 OMXMpeg4ProfileToMFCProfile(OMX_VIDEO_MPEG4PROFILETYPE profile) +{ + OMX_U32 ret; + + switch (profile) { + case OMX_VIDEO_MPEG4ProfileSimple: + ret = 0; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedSimple: + ret = 1; + break; + default: + ret = 0; + }; + + return ret; +} +OMX_U32 OMXMpeg4LevelToMFCLevel(OMX_VIDEO_MPEG4LEVELTYPE level) +{ + OMX_U32 ret; + + switch (level) { + case OMX_VIDEO_MPEG4Level0: + ret = 0; + break; + case OMX_VIDEO_MPEG4Level0b: + ret = 9; + break; + case OMX_VIDEO_MPEG4Level1: + ret = 1; + break; + case OMX_VIDEO_MPEG4Level2: + ret = 2; + break; + case OMX_VIDEO_MPEG4Level3: + ret = 3; + break; + case OMX_VIDEO_MPEG4Level4: + case OMX_VIDEO_MPEG4Level4a: + ret = 4; + break; + case OMX_VIDEO_MPEG4Level5: + ret = 5; + break; + default: + ret = 0; + }; + + return ret; +} + +void Mpeg4PrintParams(SSBSIP_MFC_ENC_MPEG4_PARAM mpeg4Param) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", mpeg4Param.SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", mpeg4Param.SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", mpeg4Param.IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", mpeg4Param.SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", mpeg4Param.RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", mpeg4Param.EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", mpeg4Param.Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", mpeg4Param.FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", mpeg4Param.FrameQp_P); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", mpeg4Param.QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", mpeg4Param.QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", mpeg4Param.CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", mpeg4Param.PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", mpeg4Param.LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", mpeg4Param.CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", mpeg4Param.CrPadVal); + + /* MPEG4 specific parameters */ + SEC_OSAL_Log(SEC_LOG_TRACE, "ProfileIDC : %d\n", mpeg4Param.ProfileIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "LevelIDC : %d\n", mpeg4Param.LevelIDC); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_B : %d\n", mpeg4Param.FrameQp_B); + SEC_OSAL_Log(SEC_LOG_TRACE, "TimeIncreamentRes : %d\n", mpeg4Param.TimeIncreamentRes); + SEC_OSAL_Log(SEC_LOG_TRACE, "VopTimeIncreament : %d\n", mpeg4Param.VopTimeIncreament); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceArgument : %d\n", mpeg4Param.SliceArgument); + SEC_OSAL_Log(SEC_LOG_TRACE, "NumberBFrames : %d\n", mpeg4Param.NumberBFrames); + SEC_OSAL_Log(SEC_LOG_TRACE, "DisableQpelME : %d\n", mpeg4Param.DisableQpelME); +} + +void H263PrintParams(SSBSIP_MFC_ENC_H263_PARAM h263Param) +{ + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceWidth : %d\n", h263Param.SourceWidth); + SEC_OSAL_Log(SEC_LOG_TRACE, "SourceHeight : %d\n", h263Param.SourceHeight); + SEC_OSAL_Log(SEC_LOG_TRACE, "IDRPeriod : %d\n", h263Param.IDRPeriod); + SEC_OSAL_Log(SEC_LOG_TRACE, "SliceMode : %d\n", h263Param.SliceMode); + SEC_OSAL_Log(SEC_LOG_TRACE, "RandomIntraMBRefresh : %d\n", h263Param.RandomIntraMBRefresh); + SEC_OSAL_Log(SEC_LOG_TRACE, "EnableFRMRateControl : %d\n", h263Param.EnableFRMRateControl); + SEC_OSAL_Log(SEC_LOG_TRACE, "Bitrate : %d\n", h263Param.Bitrate); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp : %d\n", h263Param.FrameQp); + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameQp_P : %d\n", h263Param.FrameQp_P); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMax : %d\n", h263Param.QSCodeMax); + SEC_OSAL_Log(SEC_LOG_TRACE, "QSCodeMin : %d\n", h263Param.QSCodeMin); + SEC_OSAL_Log(SEC_LOG_TRACE, "CBRPeriodRf : %d\n", h263Param.CBRPeriodRf); + SEC_OSAL_Log(SEC_LOG_TRACE, "PadControlOn : %d\n", h263Param.PadControlOn); + SEC_OSAL_Log(SEC_LOG_TRACE, "LumaPadVal : %d\n", h263Param.LumaPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CbPadVal : %d\n", h263Param.CbPadVal); + SEC_OSAL_Log(SEC_LOG_TRACE, "CrPadVal : %d\n", h263Param.CrPadVal); + + /* H.263 specific parameters */ + SEC_OSAL_Log(SEC_LOG_TRACE, "FrameRate : %d\n", h263Param.FrameRate); +} + +void Set_Mpeg4Enc_Param(SSBSIP_MFC_ENC_MPEG4_PARAM *pMpeg4Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pMpeg4Param->codecType = MPEG4_ENC; + pMpeg4Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pMpeg4Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pMpeg4Param->IDRPeriod = pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pMpeg4Param->SliceMode = 0; + pMpeg4Param->RandomIntraMBRefresh = 0; + pMpeg4Param->EnableFRMRateControl = 1; /* 0: disable, 1: enable */ + pMpeg4Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pMpeg4Param->FrameQp = 20; + pMpeg4Param->FrameQp_P = 20; + pMpeg4Param->QSCodeMax = 30; + pMpeg4Param->QSCodeMin = 10; + pMpeg4Param->CBRPeriodRf = 10; + pMpeg4Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pMpeg4Param->LumaPadVal = 0; + pMpeg4Param->CbPadVal = 0; + pMpeg4Param->CrPadVal = 0; + + pMpeg4Param->ProfileIDC = OMXMpeg4ProfileToMFCProfile(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eProfile); + pMpeg4Param->LevelIDC = OMXMpeg4LevelToMFCLevel(pMpeg4Enc->mpeg4Component[OUTPUT_PORT_INDEX].eLevel); + pMpeg4Param->FrameQp_B = 20; + pMpeg4Param->TimeIncreamentRes = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + pMpeg4Param->VopTimeIncreament = 1; + pMpeg4Param->SliceArgument = 0; /* MB number or byte number */ + pMpeg4Param->NumberBFrames = 0; /* 0(not used) ~ 2 */ + pMpeg4Param->DisableQpelME = 1; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); + switch (pSECOutputPort->eControlRate) { + case OMX_Video_ControlRateDisable: + /* TBD */ + break; + case OMX_Video_ControlRateVariable: + /* TBD */ + break; + default: + break; + } + + Mpeg4PrintParams(*pMpeg4Param); +} + +void Set_H263Enc_Param(SSBSIP_MFC_ENC_H263_PARAM *pH263Param, SEC_OMX_BASECOMPONENT *pSECComponent) +{ + SEC_OMX_BASEPORT *pSECInputPort = NULL; + SEC_OMX_BASEPORT *pSECOutputPort = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pSECInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + pH263Param->codecType = H263_ENC; + pH263Param->SourceWidth = pSECOutputPort->portDefinition.format.video.nFrameWidth; + pH263Param->SourceHeight = pSECOutputPort->portDefinition.format.video.nFrameHeight; + pH263Param->IDRPeriod = pMpeg4Enc->h263Component[OUTPUT_PORT_INDEX].nPFrames + 1; + pH263Param->SliceMode = 0; + pH263Param->RandomIntraMBRefresh = 0; + pH263Param->EnableFRMRateControl = 1; /* 0: disable, 1: enable */ + pH263Param->Bitrate = pSECOutputPort->portDefinition.format.video.nBitrate; + pH263Param->FrameQp = 20; + pH263Param->FrameQp_P = 20; + pH263Param->QSCodeMax = 30; + pH263Param->QSCodeMin = 10; + pH263Param->CBRPeriodRf = 10; + pH263Param->PadControlOn = 0; /* 0: Use boundary pixel, 1: Use the below setting value */ + pH263Param->LumaPadVal = 0; + pH263Param->CbPadVal = 0; + pH263Param->CrPadVal = 0; + + pH263Param->FrameRate = (pSECInputPort->portDefinition.format.video.xFramerate) >> 16; + + SEC_OSAL_Log(SEC_LOG_TRACE, "pSECPort->eControlRate: 0x%x", pSECOutputPort->eControlRate); + switch (pSECOutputPort->eControlRate) { + case OMX_Video_ControlRateDisable: + /* TBD */ + break; + case OMX_Video_ControlRateVariable: + /* TBD */ + break; + default: + break; + } + + H263PrintParams(*pH263Param); +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_GetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nParamIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcH263Param = &pMpeg4Enc->h263Component[pDstH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_S32 codecType; + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_MPEG4_ENC_ROLE); + else + SEC_OSAL_Strcpy((char *)pComponentRole->cRole, SEC_OMX_COMPOMENT_H263_ENC_ROLE); + } + break; + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + SEC_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL; + OMX_U32 maxProfileLevelNum = 0; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pProfileLevel = supportedMPEG4ProfileLevels; + maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } else { + pProfileLevel = supportedH263ProfileLevels; + maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(SEC_OMX_VIDEO_PROFILELEVEL); + } + + if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + pProfileLevel += pDstProfileLevel->nProfileIndex; + pDstProfileLevel->eProfile = pProfileLevel->profile; + pDstProfileLevel->eLevel = pProfileLevel->level; + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + pSrcMpeg4Param = &pMpeg4Enc->mpeg4Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile; + pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel; + } else { + pSrcH263Param = &pMpeg4Enc->h263Component[pDstProfileLevel->nPortIndex]; + pDstProfileLevel->eProfile = pSrcH263Param->eProfile; + pDstProfileLevel->eLevel = pSrcH263Param->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pSrcErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetParameter( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentParameterStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + switch (nIndex) { + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcMpeg4Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE)); + } + break; + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pDstH263Param = &pMpeg4Enc->h263Component[pSrcH263Param->nPortIndex]; + + SEC_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE)); + } + break; + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure; + + ret = SEC_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if ((pSECComponent->currentState != OMX_StateLoaded) && (pSECComponent->currentState != OMX_StateWaitForResources)) { + ret = OMX_ErrorIncorrectStateOperation; + goto EXIT; + } + + if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_MPEG4_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + //((SEC_MPEG4ENC_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_MPEG4; + } else if (!SEC_OSAL_Strcmp((char*)pComponentRole->cRole, SEC_OMX_COMPOMENT_H263_ENC_ROLE)) { + pSECComponent->pSECPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + //((SEC_MPEG4ENC_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL; + OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType; + + ret = SEC_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + codecType = pMpeg4Enc->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) { + /* + * To do: Check validity of profile & level parameters + */ + + pDstMpeg4Param = &pMpeg4Enc->mpeg4Component[pSrcProfileLevel->nPortIndex]; + pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile; + pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel; + } else { + /* + * To do: Check validity of profile & level parameters + */ + + pDstH263Param = &pMpeg4Enc->h263Component[pSrcProfileLevel->nPortIndex]; + pDstH263Param->eProfile = pSrcProfileLevel->eProfile; + pDstH263Param->eLevel = pSrcProfileLevel->eLevel; + } + } + break; + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + ret = SEC_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) { + ret = OMX_ErrorBadPortIndex; + goto EXIT; + } + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pDstErrorCorrectionType = &pMpeg4Enc->errorCorrectionType[OUTPUT_PORT_INDEX]; + + pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC; + pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync; + pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing; + pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning; + pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC; + } + break; + default: + ret = SEC_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure); + break; + } +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_SetConfig( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + + FunctionIn(); + + if (hComponent == NULL || pComponentConfigStructure == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid) { + ret = OMX_ErrorInvalidState; + goto EXIT; + } + + switch (nIndex) { + default: + ret = SEC_OMX_SetConfig(hComponent, nIndex, pComponentConfigStructure); + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_ComponentRoleEnum( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + OMX_S32 codecType; + + FunctionIn(); + + if ((hComponent == NULL) || (cRole == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE)); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + if (pOMXComponent->pComponentPrivate == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + if (pSECComponent->currentState == OMX_StateInvalid ) { + ret = OMX_StateInvalid; + goto EXIT; + } + + codecType = ((SEC_MPEG4ENC_HANDLE *)(pSECComponent->hCodecHandle))->hMFCMpeg4Handle.codecType; + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_MPEG4_ENC_ROLE); + else + SEC_OSAL_Strcpy((char *)cRole, SEC_OMX_COMPOMENT_H263_ENC_ROLE); + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Init */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Init(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_FALSE; + pSECComponent->bUseFlagEOF = OMX_FALSE; + pSECComponent->bSaveFlagEOS = OMX_FALSE; + + /* MFC(Multi Format Codec) encoder and CMM(Codec Memory Management) driver open */ + hMFCHandle = SsbSipMfcEncOpen(); + if (hMFCHandle == NULL) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = hMFCHandle; + + /* set MFC ENC VIDEO PARAM and initialize MFC encoder instance */ + if (pMpeg4Enc->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4) { + Set_Mpeg4Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam), pSECComponent); + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.mpeg4MFCParam)); + } else { + Set_H263Enc_Param(&(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam), pSECComponent); + returnCodec = SsbSipMfcEncInit(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.h263MFCParam)); + } + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + /* allocate encoder's input buffer */ + returnCodec = SsbSipMfcEncGetInBuf(hMFCHandle, &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo)); + if (returnCodec != MFC_RET_OK) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CPhyAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CPhyAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CVirAddr = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CVirAddr; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.YSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.YSize; + pSECComponent->processData[INPUT_PORT_INDEX].specificBufferHeader.CSize = pMpeg4Enc->hMFCMpeg4Handle.inputInfo.CSize; + + SEC_OSAL_Memset(pSECComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP); + SEC_OSAL_Memset(pSECComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS); + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Terminate */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_HANDLETYPE hMFCHandle = NULL; + + FunctionIn(); + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + + if (hMFCHandle != NULL) { + SsbSipMfcEncClose(hMFCHandle); + pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_MFC_Mpeg4_Encode(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + OMX_HANDLETYPE hMFCHandle = pMpeg4Enc->hMFCMpeg4Handle.hMFCHandle; + SSBSIP_MFC_ENC_INPUT_INFO *pInputInfo = &(pMpeg4Enc->hMFCMpeg4Handle.inputInfo); + SSBSIP_MFC_ENC_OUTPUT_INFO outputInfo; + SEC_OMX_BASEPORT *pSECPort = NULL; + MFC_ENC_ADDR_INFO addrInfo; + OMX_U32 oneFrameSize = pInputData->dataLen; + OMX_S32 returnCodec = 0; + + FunctionIn(); + + if (pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC == OMX_FALSE) { + returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + if (returnCodec != MFC_RET_OK) + { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.headerSize; + pOutputData->dataLen = outputInfo.headerSize; + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + pMpeg4Enc->hMFCMpeg4Handle.bConfiguredMFC = OMX_TRUE; + + if (pOutputData->dataLen > 0) { + ret = OMX_ErrorNone; + goto EXIT; + } else { + ret = OMX_ErrorInputDataEncodeYet; + goto EXIT; + } + } + + if ((pInputData->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && + (pSECComponent->bUseFlagEOF == OMX_FALSE)) { + pSECComponent->bUseFlagEOF = OMX_TRUE; + } + + pSECComponent->timeStamp[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->timeStamp; + pSECComponent->nFlags[pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp] = pInputData->nFlags; + SsbSipMfcEncSetConfig(hMFCHandle, MFC_ENC_SETCONF_FRAME_TAG, &(pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp)); + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp++; + if (pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp >= MAX_TIMESTAMP) + pMpeg4Enc->hMFCMpeg4Handle.indexTimestamp = 0; + + if (oneFrameSize <= 0) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + + ret = OMX_ErrorNone; + goto EXIT; + } + + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + if (pSECPort->portDefinition.format.video.eColorFormat == SEC_OMX_COLOR_FormatNV12PhysicalAddress) { + /* input data from Real camera */ +#define USE_FIMC_FRAME_BUFFER +#ifdef USE_FIMC_FRAME_BUFFER + SEC_OSAL_Memcpy(&addrInfo.pAddrY, pInputData->dataBuffer, sizeof(addrInfo.pAddrY)); + SEC_OSAL_Memcpy(&addrInfo.pAddrC, pInputData->dataBuffer + sizeof(addrInfo.pAddrY), sizeof(addrInfo.pAddrC)); + pInputInfo->YPhyAddr = addrInfo.pAddrY; + pInputInfo->CPhyAddr = addrInfo.pAddrC; + returnCodec = SsbSipMfcEncSetInBuf(hMFCHandle, pInputInfo); + if (returnCodec != MFC_RET_OK) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncSetInBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + goto EXIT; + } +#else + OMX_U32 width, height; + + width = pSECPort->portDefinition.format.video.nFrameWidth; + height = pSECPort->portDefinition.format.video.nFrameHeight; + + SEC_OSAL_Memcpy(pInputInfo->YVirAddr, pInputData->dataBuffer, ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height))); + SEC_OSAL_Memcpy(pInputInfo->CVirAddr, pInputData->dataBuffer + ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height)), ALIGN_TO_8KB(ALIGN_TO_128B(width) * ALIGN_TO_32B(height / 2))); +#endif + } + + returnCodec = SsbSipMfcEncExe(hMFCHandle); + if (returnCodec == MFC_RET_OK) { + OMX_S32 indexTimestamp = 0; + + returnCodec = SsbSipMfcEncGetOutBuf(hMFCHandle, &outputInfo); + + if ((SsbSipMfcEncGetConfig(hMFCHandle, MFC_ENC_GETCONF_FRAME_TAG, &indexTimestamp) != MFC_RET_OK) || + (((indexTimestamp < 0) || (indexTimestamp > MAX_TIMESTAMP)))) { + pOutputData->timeStamp = pInputData->timeStamp; + pOutputData->nFlags = pInputData->nFlags; + } else { + pOutputData->timeStamp = pSECComponent->timeStamp[indexTimestamp]; + pOutputData->nFlags = pSECComponent->nFlags[indexTimestamp]; + } + + if (returnCodec == MFC_RET_OK) { + /** Fill Output Buffer **/ + pOutputData->dataBuffer = outputInfo.StrmVirAddr; + pOutputData->allocSize = outputInfo.dataSize; + pOutputData->dataLen = outputInfo.dataSize; + pOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + if (outputInfo.frameType == MFC_FRAME_TYPE_I_FRAME) + pOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + ret = OMX_ErrorNone; + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncGetOutBuf failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + } + } else { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SsbSipMfcEncExe failed, ret:%d", __FUNCTION__, returnCodec); + ret = OMX_ErrorUndefined; + } + +EXIT: + FunctionOut(); + + return ret; +} + +/* MFC Encode */ +OMX_ERRORTYPE SEC_MFC_Mpeg4Enc_bufferProcess(OMX_COMPONENTTYPE *pOMXComponent, SEC_OMX_DATA *pInputData, SEC_OMX_DATA *pOutputData) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_BASECOMPONENT *pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + SEC_OMX_BASEPORT *pInputPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + SEC_OMX_BASEPORT *pOutputPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + + FunctionIn(); + + if ((!CHECK_PORT_ENABLED(pInputPort)) || (!CHECK_PORT_ENABLED(pOutputPort)) || + (!CHECK_PORT_POPULATED(pInputPort)) || (!CHECK_PORT_POPULATED(pOutputPort))) { + goto EXIT; + } + if (OMX_FALSE == SEC_Check_BufferProcess_State(pSECComponent)) { + goto EXIT; + } + + ret = SEC_MFC_Mpeg4_Encode(pOMXComponent, pInputData, pOutputData); + if (ret != OMX_ErrorNone) { + if (ret == OMX_ErrorInputDataEncodeYet) { + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } else { + pSECComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent, + pSECComponent->callbackData, + OMX_EventError, ret, 0, NULL); + } + } else { + pInputData->usedDataLen += pInputData->dataLen; + pInputData->remainDataLen = pInputData->dataLen - pInputData->usedDataLen; + pInputData->dataLen -= pInputData->usedDataLen; + pInputData->usedDataLen = 0; + + pOutputData->usedDataLen = 0; + pOutputData->remainDataLen = pOutputData->dataLen; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_OMX_BASEPORT *pSECPort = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + OMX_S32 codecType = -1; + int i = 0; + + FunctionIn(); + + if ((hComponent == NULL) || (componentName == NULL)) { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: parameters are null, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_MPEG4_ENC, componentName) == 0) { + codecType = CODEC_TYPE_MPEG4; + } else if (SEC_OSAL_Strcmp(SEC_OMX_COMPOMENT_H263_ENC, componentName) == 0) { + codecType = CODEC_TYPE_H263; + } else { + ret = OMX_ErrorBadParameter; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName(%s) error, ret: %X", __FUNCTION__, componentName, ret); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + ret = SEC_OMX_VideoEncodeComponentInit(pOMXComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_OMX_VideoDecodeComponentInit error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + pSECComponent->codecType = HW_VIDEO_CODEC; + + pSECComponent->componentName = (OMX_STRING)SEC_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE); + if (pSECComponent->componentName == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: componentName alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pSECComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE); + + pMpeg4Enc = SEC_OSAL_Malloc(sizeof(SEC_MPEG4ENC_HANDLE)); + if (pMpeg4Enc == NULL) { + SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "%s: SEC_MPEG4ENC_HANDLE alloc error, ret: %X", __FUNCTION__, ret); + goto EXIT; + } + SEC_OSAL_Memset(pMpeg4Enc, 0, sizeof(SEC_MPEG4ENC_HANDLE)); + pSECComponent->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Enc; + pMpeg4Enc->hMFCMpeg4Handle.codecType = codecType; + + if (codecType == CODEC_TYPE_MPEG4) + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_MPEG4_ENC); + else + SEC_OSAL_Strcpy(pSECComponent->componentName, SEC_OMX_COMPOMENT_H263_ENC); + + /* Set componentVersion */ + pSECComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->componentVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->componentVersion.s.nStep = STEP_NUMBER; + /* Set specVersion */ + pSECComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; + pSECComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; + pSECComponent->specVersion.s.nRevision = REVISION_NUMBER; + pSECComponent->specVersion.s.nStep = STEP_NUMBER; + + /* Android CapabilityFlags */ + pSECComponent->capabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentSupportsPartialFrames = OMX_FALSE; + pSECComponent->capabilityFlags.iOMXComponentUsesNALStartCodes = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + pSECComponent->capabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_TRUE; + + /* Input port */ + pSECPort = &pSECComponent->pSECPort[INPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate= (15 << 16); + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "raw/video"); + pSECPort->portDefinition.format.video.eColorFormat = SEC_OMX_COLOR_FormatNV12PhysicalAddress;//OMX_COLOR_FormatYUV420SemiPlanar; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + /* Output port */ + pSECPort = &pSECComponent->pSECPort[OUTPUT_PORT_INDEX]; + pSECPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH; + pSECPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT; + pSECPort->portDefinition.format.video.nBitrate = 64000; + pSECPort->portDefinition.format.video.xFramerate= (15 << 16); + if (codecType == CODEC_TYPE_MPEG4) { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/mpeg4"); + } else { + pSECPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + SEC_OSAL_Memset(pSECPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE); + SEC_OSAL_Strcpy(pSECPort->portDefinition.format.video.cMIMEType, "video/h263"); + } + pSECPort->portDefinition.format.video.pNativeRender = 0; + pSECPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE; + pSECPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused; + pSECPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE; + pSECPort->portDefinition.bEnabled = OMX_TRUE; + + if (codecType == CODEC_TYPE_MPEG4) { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Enc->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE); + pMpeg4Enc->mpeg4Component[i].nPortIndex = i; + pMpeg4Enc->mpeg4Component[i].eProfile = OMX_VIDEO_MPEG4ProfileSimple; + pMpeg4Enc->mpeg4Component[i].eLevel = OMX_VIDEO_MPEG4Level4; + + pMpeg4Enc->mpeg4Component[i].nPFrames = 10; + pMpeg4Enc->mpeg4Component[i].nBFrames = 0; /* No support for B frames */ + pMpeg4Enc->mpeg4Component[i].nMaxPacketSize = 256; /* Default value */ + pMpeg4Enc->mpeg4Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + pMpeg4Enc->mpeg4Component[i].bGov = OMX_FALSE; + + } + } else { + for(i = 0; i < ALL_PORT_NUM; i++) { + INIT_SET_SIZE_VERSION(&pMpeg4Enc->h263Component[i], OMX_VIDEO_PARAM_H263TYPE); + pMpeg4Enc->h263Component[i].nPortIndex = i; + pMpeg4Enc->h263Component[i].eProfile = OMX_VIDEO_H263ProfileBaseline; + pMpeg4Enc->h263Component[i].eLevel = OMX_VIDEO_H263Level45; + + pMpeg4Enc->h263Component[i].nPFrames = 20; + pMpeg4Enc->h263Component[i].nBFrames = 0; /* No support for B frames */ + pMpeg4Enc->h263Component[i].bPLUSPTYPEAllowed = OMX_FALSE; + pMpeg4Enc->h263Component[i].nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP; + pMpeg4Enc->h263Component[i].bForceRoundingTypeToZero = OMX_TRUE; + pMpeg4Enc->h263Component[i].nPictureHeaderRepetition = 0; + pMpeg4Enc->h263Component[i].nGOBHeaderInterval = 0; + } + } + + pOMXComponent->GetParameter = &SEC_MFC_Mpeg4Enc_GetParameter; + pOMXComponent->SetParameter = &SEC_MFC_Mpeg4Enc_SetParameter; + pOMXComponent->SetConfig = &SEC_MFC_Mpeg4Enc_SetConfig; + pOMXComponent->ComponentRoleEnum = &SEC_MFC_Mpeg4Enc_ComponentRoleEnum; + pOMXComponent->ComponentDeInit = &SEC_OMX_ComponentDeinit; + + pSECComponent->sec_mfc_componentInit = &SEC_MFC_Mpeg4Enc_Init; + pSECComponent->sec_mfc_componentTerminate = &SEC_MFC_Mpeg4Enc_Terminate; + pSECComponent->sec_mfc_bufferProcess = &SEC_MFC_Mpeg4Enc_bufferProcess; + pSECComponent->sec_checkInputFrame = NULL; + + pSECComponent->currentState = OMX_StateLoaded; + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + SEC_OMX_BASECOMPONENT *pSECComponent = NULL; + SEC_MPEG4ENC_HANDLE *pMpeg4Enc = NULL; + + FunctionIn(); + + if (hComponent == NULL) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + pOMXComponent = (OMX_COMPONENTTYPE *)hComponent; + pSECComponent = (SEC_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate; + + SEC_OSAL_Free(pSECComponent->componentName); + pSECComponent->componentName = NULL; + + pMpeg4Enc = (SEC_MPEG4ENC_HANDLE *)pSECComponent->hCodecHandle; + if (pMpeg4Enc != NULL) { + SEC_OSAL_Free(pMpeg4Enc); + pMpeg4Enc = pSECComponent->hCodecHandle = NULL; + } + + ret = SEC_OMX_VideoEncodeComponentDeinit(pOMXComponent); + if (ret != OMX_ErrorNone) { + goto EXIT; + } + + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h new file mode 100644 index 0000000..d4f9038 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/SEC_OMX_Mpeg4enc.h @@ -0,0 +1,76 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Mpeg4enc.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_ENC_COMPONENT +#define SEC_OMX_MPEG4_ENC_COMPONENT + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SsbSipMfcApi.h" + + +typedef enum _CODEC_TYPE +{ + CODEC_TYPE_H263, + CODEC_TYPE_MPEG4 +} CODEC_TYPE; + +typedef struct _SEC_MFC_MPEG4ENC_HANDLE +{ + OMX_HANDLETYPE hMFCHandle; + SSBSIP_MFC_ENC_MPEG4_PARAM mpeg4MFCParam; + SSBSIP_MFC_ENC_H263_PARAM h263MFCParam; + SSBSIP_MFC_ENC_INPUT_INFO inputInfo; + OMX_U32 indexTimestamp; + OMX_BOOL bConfiguredMFC; + CODEC_TYPE codecType; +} SEC_MFC_MPEG4ENC_HANDLE; + +typedef struct _SEC_MPEG4ENC_HANDLE +{ + /* OMX Codec specific */ + OMX_VIDEO_PARAM_H263TYPE h263Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_MPEG4TYPE mpeg4Component[ALL_PORT_NUM]; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType[ALL_PORT_NUM]; + + /* SEC MFC Codec specific */ + SEC_MFC_MPEG4ENC_HANDLE hMFCMpeg4Handle; +} SEC_MPEG4ENC_HANDLE; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OSCL_EXPORT_REF OMX_ERRORTYPE SEC_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + OMX_ERRORTYPE SEC_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.c b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.c new file mode 100644 index 0000000..20e4eb8 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.c @@ -0,0 +1,64 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "library_register.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_MPEG4_ENC" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent) +{ + FunctionIn(); + + if (ppSECComponent == NULL) + goto EXIT; + + /* component 1 - video encoder MPEG4 */ + SEC_OSAL_Strcpy(ppSECComponent[0]->componentName, SEC_OMX_COMPOMENT_MPEG4_ENC); + SEC_OSAL_Strcpy(ppSECComponent[0]->roles[0], SEC_OMX_COMPOMENT_MPEG4_ENC_ROLE); + ppSECComponent[0]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + + /* component 2 - video encoder H.263 */ + SEC_OSAL_Strcpy(ppSECComponent[1]->componentName, SEC_OMX_COMPOMENT_H263_ENC); + SEC_OSAL_Strcpy(ppSECComponent[1]->roles[0], SEC_OMX_COMPOMENT_H263_ENC_ROLE); + ppSECComponent[1]->totalRoleNum = MAX_COMPONENT_ROLE_NUM; + +EXIT: + FunctionOut(); + return MAX_COMPONENT_NUM; +} + diff --git a/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.h b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.h new file mode 100644 index 0000000..3b23011 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_component/video/enc/mpeg4enc/library_register.h @@ -0,0 +1,59 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file library_register.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MPEG4_ENC_REG +#define SEC_OMX_MPEG4_ENC_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Component.h" +#include "SEC_OMX_Component_Register.h" + + +#define OSCL_EXPORT_REF __attribute__((visibility("default"))) +#define MAX_COMPONENT_NUM 2 +#define MAX_COMPONENT_ROLE_NUM 1 + +/* MPEG4 */ +#define SEC_OMX_COMPOMENT_MPEG4_ENC "OMX.SEC.MPEG4.Encoder" +#define SEC_OMX_COMPOMENT_MPEG4_ENC_ROLE "video_encoder.mpeg4" + +/* H.263 */ +#define SEC_OMX_COMPOMENT_H263_ENC "OMX.SEC.H263.Encoder" +#define SEC_OMX_COMPOMENT_H263_ENC_ROLE "video_encoder.h263" + + +#ifdef __cplusplus +extern "C" { +#endif + +OSCL_EXPORT_REF int SEC_OMX_COMPONENT_Library_Register(SECRegisterComponentType **ppSECComponent); + +#ifdef __cplusplus +}; +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_core/Android.mk b/sec_mm/sec_omx/sec_omx_core/Android.mk new file mode 100644 index 0000000..7613c1e --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := SEC_OMX_Component_Register.c \ + SEC_OMX_Core.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libSEC_OMX_Core.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_ARM_MODE := arm + +LOCAL_STATIC_LIBRARIES := libsecosal.smdkc210 libsecbasecomponent.smdkc210 +LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal \ + $(SEC_OMX_TOP)/sec_omx_component/common + +include $(BUILD_SHARED_LIBRARY) + diff --git a/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.c b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.c new file mode 100644 index 0000000..1464397 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.c @@ -0,0 +1,269 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Component_Register.c + * @brief SEC OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OMX_Component.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" +#include "SEC_OSAL_Library.h" +#include "SEC_OMX_Component_Register.h" +#include "SEC_OMX_Macros.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_COMP_REGS" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +#define REGISTRY_FILENAME "secomxregistry" + + +OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + int componentNum = 0, roleNum = 0, totalCompNum = 0; + int read; + char *omxregistryfile = NULL; + char *line = NULL; + char *libName; + FILE *omxregistryfp; + size_t len; + OMX_HANDLETYPE soHandle; + const char *errorMsg; + int (*SEC_OMX_COMPONENT_Library_Register)(SECRegisterComponentType **secComponents); + SECRegisterComponentType **secComponentsTemp; + SEC_OMX_COMPONENT_REGLIST *componentList; + + FunctionIn(); + + omxregistryfile = SEC_OSAL_Malloc(strlen("/system/etc/") + strlen(REGISTRY_FILENAME) + 2); + SEC_OSAL_Strcpy(omxregistryfile, "/system/etc/"); + SEC_OSAL_Strcat(omxregistryfile, REGISTRY_FILENAME); + + omxregistryfp = fopen(omxregistryfile, "r"); + if (omxregistryfp == NULL) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + SEC_OSAL_Free(omxregistryfile); + + fseek(omxregistryfp, 0, 0); + componentList = (SEC_OMX_COMPONENT_REGLIST *)SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + libName = SEC_OSAL_Malloc(MAX_OMX_COMPONENT_LIBNAME_SIZE); + + while ((read = getline(&line, &len, omxregistryfp)) != -1) { + if ((*line == 'l') && (*(line + 1) == 'i') && (*(line + 2) == 'b') && + (*(line + 3) == 'O') && (*(line + 4) == 'M') && (*(line + 5) == 'X')) { + SEC_OSAL_Memset(libName, 0, MAX_OMX_COMPONENT_LIBNAME_SIZE); + SEC_OSAL_Strncpy(libName, line, SEC_OSAL_Strlen(line)-1); + SEC_OSAL_Log(SEC_LOG_TRACE, "libName : %s", libName); + + if ((soHandle = SEC_OSAL_dlopen(libName, RTLD_NOW)) != NULL) { + SEC_OSAL_dlerror(); /* clear error*/ + if ((SEC_OMX_COMPONENT_Library_Register = SEC_OSAL_dlsym(soHandle, "SEC_OMX_COMPONENT_Library_Register")) != NULL) { + int i = 0, j = 0; + + componentNum = (*SEC_OMX_COMPONENT_Library_Register)(NULL); + secComponentsTemp = (SECRegisterComponentType **)SEC_OSAL_Malloc(sizeof(SECRegisterComponentType*) * componentNum); + for (i = 0; i < componentNum; i++) { + secComponentsTemp[i] = SEC_OSAL_Malloc(sizeof(SECRegisterComponentType)); + SEC_OSAL_Memset(secComponentsTemp[i], 0, sizeof(SECRegisterComponentType)); + } + (*SEC_OMX_COMPONENT_Library_Register)(secComponentsTemp); + + for (i = 0; i < componentNum; i++) { + SEC_OSAL_Strcpy(componentList[totalCompNum].component.componentName, secComponentsTemp[i]->componentName); + for (j = 0; j < secComponentsTemp[i]->totalRoleNum; j++) + SEC_OSAL_Strcpy(componentList[totalCompNum].component.roles[j], secComponentsTemp[i]->roles[j]); + componentList[totalCompNum].component.totalRoleNum = secComponentsTemp[i]->totalRoleNum; + + SEC_OSAL_Strcpy(componentList[totalCompNum].libName, libName); + + totalCompNum++; + } + for (i = 0; i < componentNum; i++) { + SEC_OSAL_Free(secComponentsTemp[i]); + } + + SEC_OSAL_Free(secComponentsTemp); + } else { + if ((errorMsg = SEC_OSAL_dlerror()) != NULL) + SEC_OSAL_Log(SEC_LOG_WARNING, "dlsym failed: %s", errorMsg); + } + SEC_OSAL_dlclose(soHandle); + } else { + SEC_OSAL_Log(SEC_LOG_WARNING, "dlopen failed: %s", SEC_OSAL_dlerror()); + } + } else { + /* not a component name line. skip */ + continue; + } + } + + SEC_OSAL_Free(libName); + fclose(omxregistryfp); + + *compList = componentList; + *compNum = totalCompNum; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + SEC_OSAL_Memset(componentList, 0, sizeof(SEC_OMX_COMPONENT_REGLIST) * MAX_OMX_COMPONENT_NUM); + SEC_OSAL_Free(componentList); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentAPICheck(OMX_COMPONENTTYPE component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if ((NULL == component.GetComponentVersion) || + (NULL == component.SendCommand) || + (NULL == component.GetParameter) || + (NULL == component.SetParameter) || + (NULL == component.GetConfig) || + (NULL == component.SetConfig) || + (NULL == component.GetExtensionIndex) || + (NULL == component.GetState) || + (NULL == component.ComponentTunnelRequest) || + (NULL == component.UseBuffer) || + (NULL == component.AllocateBuffer) || + (NULL == component.FreeBuffer) || + (NULL == component.EmptyThisBuffer) || + (NULL == component.FillThisBuffer) || + (NULL == component.SetCallbacks) || + (NULL == component.ComponentDeInit) || + (NULL == component.UseEGLImage) || + (NULL == component.ComponentRoleEnum)) + ret = OMX_ErrorInvalidComponent; + else + ret = OMX_ErrorNone; + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_HANDLETYPE libHandle; + OMX_COMPONENTTYPE *pOMXComponent; + + FunctionIn(); + + OMX_ERRORTYPE (*SEC_OMX_ComponentInit)(OMX_HANDLETYPE hComponent, OMX_STRING componentName); + + libHandle = SEC_OSAL_dlopen(sec_component->libName, RTLD_NOW); + if (!libHandle) { + ret = OMX_ErrorInvalidComponentName; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponentName, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OMX_ComponentInit = SEC_OSAL_dlsym(libHandle, "SEC_OMX_ComponentInit"); + if (!SEC_OMX_ComponentInit) { + SEC_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + + pOMXComponent = (OMX_COMPONENTTYPE *)SEC_OSAL_Malloc(sizeof(OMX_COMPONENTTYPE)); + INIT_SET_SIZE_VERSION(pOMXComponent, OMX_COMPONENTTYPE); + ret = (*SEC_OMX_ComponentInit)((OMX_HANDLETYPE)pOMXComponent, sec_component->componentName); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(pOMXComponent); + SEC_OSAL_dlclose(libHandle); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } else { + if (SEC_OMX_ComponentAPICheck(*pOMXComponent) != OMX_ErrorNone) { + SEC_OSAL_Free(pOMXComponent); + SEC_OSAL_dlclose(libHandle); + if (NULL != pOMXComponent->ComponentDeInit) + pOMXComponent->ComponentDeInit(pOMXComponent); + ret = OMX_ErrorInvalidComponent; + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_ErrorInvalidComponent, Line:%d", __LINE__); + goto EXIT; + } + sec_component->libHandle = libHandle; + sec_component->pOMXComponent = pOMXComponent; + ret = OMX_ErrorNone; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_COMPONENTTYPE *pOMXComponent = NULL; + + FunctionIn(); + + if (!sec_component) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + pOMXComponent = sec_component->pOMXComponent; + if (pOMXComponent != NULL) { + pOMXComponent->ComponentDeInit(pOMXComponent); + SEC_OSAL_Free(pOMXComponent); + sec_component->pOMXComponent = NULL; + } + + if (sec_component->libHandle != NULL) { + SEC_OSAL_dlclose(sec_component->libHandle); + sec_component->libHandle = NULL; + } + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.h b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.h new file mode 100644 index 0000000..66580bd --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Component_Register.h @@ -0,0 +1,75 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Component_Register.h + * @brief SEC OpenMAX IL Component Register + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_COMPONENT_REG +#define SEC_OMX_COMPONENT_REG + +#include "SEC_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_Component.h" + + +typedef struct _SECRegisterComponentType +{ + OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; + OMX_U8 roles[MAX_OMX_COMPONENT_ROLE_NUM][MAX_OMX_COMPONENT_ROLE_SIZE]; + OMX_U32 totalRoleNum; +} SECRegisterComponentType; + +typedef struct _SEC_OMX_COMPONENT_REGLIST +{ + SECRegisterComponentType component; + OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; +} SEC_OMX_COMPONENT_REGLIST; + +struct SEC_OMX_COMPONENT; +typedef struct _SEC_OMX_COMPONENT +{ + OMX_U8 componentName[MAX_OMX_COMPONENT_NAME_SIZE]; + OMX_U8 libName[MAX_OMX_COMPONENT_LIBNAME_SIZE]; + OMX_HANDLETYPE libHandle; + OMX_COMPONENTTYPE *pOMXComponent; + struct SEC_OMX_COMPONENT *nextOMXComp; +} SEC_OMX_COMPONENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE SEC_OMX_Component_Register(SEC_OMX_COMPONENT_REGLIST **compList, OMX_U32 *compNum); +OMX_ERRORTYPE SEC_OMX_Component_Unregister(SEC_OMX_COMPONENT_REGLIST *componentList); +OMX_ERRORTYPE SEC_OMX_ComponentLoad(SEC_OMX_COMPONENT *sec_component); +OMX_ERRORTYPE SEC_OMX_ComponentUnload(SEC_OMX_COMPONENT *sec_component); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.c b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.c new file mode 100644 index 0000000..fe84d8d --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.c @@ -0,0 +1,354 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Core.c + * @brief SEC OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OMX_Core.h" +#include "SEC_OMX_Component_Register.h" +#include "SEC_OSAL_Memory.h" +#include "SEC_OMX_Resourcemanager.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_OMX_CORE" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +static int gInitialized = 0; +static int gComponentNum = 0; + +static SEC_OMX_COMPONENT_REGLIST *gComponentList = NULL; +static SEC_OMX_COMPONENT *gLoadComponentList = NULL; +static OMX_HANDLETYPE ghLoadComponentListMutex = NULL; + + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (gInitialized == 0) { + if (SEC_OMX_Component_Register(&gComponentList, &gComponentNum)) { + ret = OMX_ErrorInsufficientResources; + SEC_OSAL_Log(SEC_LOG_ERROR, "SEC_OMX_Init : %s", "OMX_ErrorInsufficientResources"); + goto EXIT; + } + + SEC_OMX_ResourceManager_Init(); + + SEC_OSAL_MutexCreate(&ghLoadComponentListMutex); + + gInitialized = 1; + SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_Init : %s", "OMX_ErrorNone"); + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + SEC_OSAL_MutexTerminate(ghLoadComponentListMutex); + ghLoadComponentListMutex = NULL; + + SEC_OMX_ResourceManager_Deinit(); + + if (OMX_ErrorNone != SEC_OMX_Component_Unregister(gComponentList)) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + gComponentList = NULL; + gComponentNum = 0; + gInitialized = 0; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + FunctionIn(); + + if (nIndex >= gComponentNum) { + ret = OMX_ErrorNoMore; + goto EXIT; + } + + sprintf(cComponentName, "%s", gComponentList[nIndex].component.componentName); + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE *pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE *pCallBacks) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_COMPONENT *loadComponent; + SEC_OMX_COMPONENT *currentComponent; + int i = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + if ((pHandle == NULL) || (cComponentName == NULL) || (pCallBacks == NULL)) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + SEC_OSAL_Log(SEC_LOG_TRACE, "ComponentName : %s", cComponentName); + + for (i = 0; i < gComponentNum; i++) { + if (SEC_OSAL_Strcmp(cComponentName, gComponentList[i].component.componentName) == 0) { + loadComponent = SEC_OSAL_Malloc(sizeof(SEC_OMX_COMPONENT)); + SEC_OSAL_Memset(loadComponent, 0, sizeof(SEC_OMX_COMPONENT)); + + SEC_OSAL_Strcpy(loadComponent->libName, gComponentList[i].libName); + SEC_OSAL_Strcpy(loadComponent->componentName, gComponentList[i].component.componentName); + ret = SEC_OMX_ComponentLoad(loadComponent); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(loadComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + ret = loadComponent->pOMXComponent->SetCallbacks(loadComponent->pOMXComponent, pCallBacks, pAppData); + if (ret != OMX_ErrorNone) { + SEC_OMX_ComponentUnload(loadComponent); + SEC_OSAL_Free(loadComponent); + SEC_OSAL_Log(SEC_LOG_ERROR, "OMX_Error, Line:%d", __LINE__); + goto EXIT; + } + + SEC_OSAL_MutexLock(ghLoadComponentListMutex); + if (gLoadComponentList == NULL) { + gLoadComponentList = loadComponent; + } else { + currentComponent = gLoadComponentList; + while (currentComponent->nextOMXComp != NULL) { + currentComponent = currentComponent->nextOMXComp; + } + currentComponent->nextOMXComp = loadComponent; + } + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + + *pHandle = loadComponent->pOMXComponent; + ret = OMX_ErrorNone; + SEC_OSAL_Log(SEC_LOG_TRACE, "SEC_OMX_GetHandle : %s", "OMX_ErrorNone"); + goto EXIT; + } + } + + ret = OMX_ErrorComponentNotFound; + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComponent) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_OMX_COMPONENT *currentComponent; + SEC_OMX_COMPONENT *deleteComponent; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + if (!hComponent) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + SEC_OSAL_MutexLock(ghLoadComponentListMutex); + currentComponent = gLoadComponentList; + if (gLoadComponentList->pOMXComponent == hComponent) { + deleteComponent = gLoadComponentList; + gLoadComponentList = gLoadComponentList->nextOMXComp; + } else { + while ((currentComponent != NULL) && (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent != hComponent)) + currentComponent = currentComponent->nextOMXComp; + + if (((SEC_OMX_COMPONENT *)(currentComponent->nextOMXComp))->pOMXComponent == hComponent) { + deleteComponent = currentComponent->nextOMXComp; + currentComponent->nextOMXComp = deleteComponent->nextOMXComp; + } else if (currentComponent == NULL) { + ret = OMX_ErrorComponentNotFound; + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + goto EXIT; + } + } + SEC_OSAL_MutexUnlock(ghLoadComponentListMutex); + + SEC_OMX_ComponentUnload(deleteComponent); + SEC_OSAL_Free(deleteComponent); + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput) +{ + OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; + +EXIT: + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI) +{ + OMX_ERRORTYPE ret = OMX_ErrorNotImplemented; + +EXIT: + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + int max_role_num = 0; + OMX_STRING RoleString[MAX_OMX_COMPONENT_ROLE_SIZE]; + int i = 0, j = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + *pNumComps = 0; + + for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { + max_role_num = gComponentList[i].component.totalRoleNum; + + for (j = 0; j < max_role_num; j++) { + if (SEC_OSAL_Strcmp(gComponentList[i].component.roles[j], role) == 0) { + if (compNames != NULL) { + SEC_OSAL_Strcpy((OMX_STRING)compNames[*pNumComps], gComponentList[i].component.componentName); + } + *pNumComps = (*pNumComps + 1); + } + } + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_BOOL detectComp = OMX_FALSE; + int compNum = 0, totalRoleNum = 0; + int i = 0; + + FunctionIn(); + + if (gInitialized != 1) { + ret = OMX_ErrorNotReady; + goto EXIT; + } + + for (i = 0; i < MAX_OMX_COMPONENT_NUM; i++) { + if (gComponentList != NULL) { + if (SEC_OSAL_Strcmp(gComponentList[i].component.componentName, compName) == 0) { + *pNumRoles = totalRoleNum = gComponentList[i].component.totalRoleNum; + compNum = i; + detectComp = OMX_TRUE; + break; + } + } else { + ret = OMX_ErrorUndefined; + goto EXIT; + } + } + + if (detectComp == OMX_FALSE) { + *pNumRoles = 0; + ret = OMX_ErrorComponentNotFound; + goto EXIT; + } + + if (roles != NULL) { + for (i = 0; i < totalRoleNum; i++) { + SEC_OSAL_Strcpy(roles[i], gComponentList[compNum].component.roles[i]); + } + } + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.h b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.h new file mode 100644 index 0000000..87f561c --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/SEC_OMX_Core.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Core.h + * @brief SEC OpenMAX IL Core + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * HyeYeon Chung (hyeon.chung@samsung.com) + * Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_CORE +#define SEC_OMX_CORE + +#include "SEC_OMX_Def.h" +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Init(void); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_Deinit(void); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE *pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE *pCallBacks); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE OMX_APIENTRY SEC_OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetComponentsOfRole( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); +SEC_EXPORT_REF OMX_API OMX_ERRORTYPE SEC_OMX_GetRolesOfComponent( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_core/secomxregistry b/sec_mm/sec_omx/sec_omx_core/secomxregistry new file mode 100644 index 0000000..eb79124 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_core/secomxregistry @@ -0,0 +1,4 @@ +libOMX.SEC.AVC.Decoder.smdkc210.so +libOMX.SEC.M4V.Decoder.smdkc210.so +libOMX.SEC.AVC.Encoder.smdkc210.so +libOMX.SEC.M4V.Encoder.smdkc210.so diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Audio.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Audio.h new file mode 100644 index 0000000..04f1a99 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Audio.h @@ -0,0 +1,1311 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** @file OMX_Audio.h - OpenMax IL version 1.1.2 + * The structures needed by Audio components to exchange + * parameters and configuration data with the componenmilts. + */ + +#ifndef OMX_Audio_h +#define OMX_Audio_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup midi MIDI + * @ingroup audio + */ + +/** @defgroup effects Audio effects + * @ingroup audio + */ + +/** @defgroup audio OpenMAX IL Audio Domain + * Structures for OpenMAX IL Audio domain + * @{ + */ + +/** Enumeration used to define the possible audio codings. + * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must + * be done in a vendor specific way. Since this is for an audio + * processing element this enum is relevant. However, for another + * type of component other enums would be in this area. + */ +typedef enum OMX_AUDIO_CODINGTYPE { + OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */ + OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */ + OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */ + OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */ + OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */ + OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */ + OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/ + OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */ + OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */ + OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */ + OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */ + OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */ + OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */ + OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */ + OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */ + OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */ + OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */ + OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */ + OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */ + OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */ + OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */ + OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */ + OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */ + OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */ + OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */ + OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */ + OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */ + OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */ + OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CodingMax = 0x7FFFFFFF +} OMX_AUDIO_CODINGTYPE; + + +/** The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output audio + * path. If additional information is needed to define the parameters of the + * port (such as frequency), additional structures must be sent such as the + * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port. + */ +typedef struct OMX_AUDIO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; /**< MIME type of data for the port */ + OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference + for an output device, + otherwise this field is 0 */ + OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is + supported by the OMX component */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this + port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PORTDEFINITIONTYPE; + + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */ +} OMX_AUDIO_PARAM_PORTFORMATTYPE; + + +/** PCM mode type */ +typedef enum OMX_AUDIO_PCMMODETYPE { + OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */ + OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */ + OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_PCMModeMax = 0x7FFFFFFF +} OMX_AUDIO_PCMMODETYPE; + + +typedef enum OMX_AUDIO_CHANNELTYPE { + OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */ + OMX_AUDIO_ChannelLF = 0x1, /**< Left front */ + OMX_AUDIO_ChannelRF = 0x2, /**< Right front */ + OMX_AUDIO_ChannelCF = 0x3, /**< Center front */ + OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */ + OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */ + OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */ + OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */ + OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */ + OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */ + OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELTYPE; + +#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */ +#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */ + +/** PCM format description */ +typedef struct OMX_AUDIO_PARAM_PCMMODETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */ + OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */ + OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */ + OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for + non-interleaved data (e.g. block data) */ + OMX_U32 nBitPerSample; /**< Bit per sample */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */ + OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */ + +} OMX_AUDIO_PARAM_PCMMODETYPE; + + +/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate + * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC. + */ +typedef enum OMX_AUDIO_CHANNELMODETYPE { + OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those + two channels changes accordingly to each channel information */ + OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between + 2 channels for higher compression gain */ + OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half + the bitrate of the overall bitrate */ + OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */ + OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF +} OMX_AUDIO_CHANNELMODETYPE; + + +typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE { + OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */ + OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MP3STREAMFORMATTYPE; + +/** MP3 params */ +typedef struct OMX_AUDIO_PARAM_MP3TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */ +} OMX_AUDIO_PARAM_MP3TYPE; + + +typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE { + OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */ + OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */ + OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */ + OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */ + OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */ + OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */ + OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */ + OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AACSTREAMFORMATTYPE; + + +/** AAC mode type. Note that the term profile is used with the MPEG-2 + * standard and the term object type and profile is used with MPEG-4 */ +typedef enum OMX_AUDIO_AACPROFILETYPE{ + OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */ + OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */ + OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */ + OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */ + OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */ + OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */ + OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */ + OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */ + OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */ + OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */ + OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AACObjectMax = 0x7FFFFFFF +} OMX_AUDIO_AACPROFILETYPE; + + +/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for encoder configuration and optional as decoder info output. + * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */ +#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */ +#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */ +#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */ +#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */ +#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */ +#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */ +#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/ + +/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE). + * Required for ER encoder configuration and optional as decoder info output */ +#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */ +#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */ +#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */ +#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */ +#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */ + + +/** AAC params */ +typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec. + Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD). + Use 0 to let encoder decide */ + OMX_U32 nAACtools; /**< AAC tool usage */ + OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */ + OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */ + OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ +} OMX_AUDIO_PARAM_AACPROFILETYPE; + + +/** VORBIS params */ +typedef struct OMX_AUDIO_PARAM_VORBISTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable + rate or unknown bit rates. Encoding is set to the + bitrate closest to specified value (in bps) */ + OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */ + OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */ + + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should + limit the audio signal. Use 0 to let encoder decide */ + OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high). + In the default mode of operation, teh quality level is 3. + Normal quality range is 0 - 10. */ + OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the + normal VBR encoding, but allows hard or soft bitrate + constraints to be enforced by the encoder. This mode can + be slower, and may also be lower quality. It is + primarily useful for streaming. */ + OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on + non-stereo streams). Useful for lower-bitrate encoding. */ +} OMX_AUDIO_PARAM_VORBISTYPE; + + +/** WMA Version */ +typedef enum OMX_AUDIO_WMAFORMATTYPE { + OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */ + OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */ + OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */ + OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */ + OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_WMAFORMATTYPE; + + +/** WMA Profile */ +typedef enum OMX_AUDIO_WMAPROFILETYPE { + OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */ + OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */ + OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */ + OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */ + OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF +} OMX_AUDIO_WMAPROFILETYPE; + + +/** WMA params */ +typedef struct OMX_AUDIO_PARAM_WMATYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */ + OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */ + OMX_U32 nSamplingRate; /**< Sampling rate of the source data */ + OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */ + OMX_U16 nEncodeOptions; /**< WMA Type-specific data */ + OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */ +} OMX_AUDIO_PARAM_WMATYPE; + +/** + * RealAudio format + */ +typedef enum OMX_AUDIO_RAFORMATTYPE { + OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */ + OMX_AUDIO_RA8, /**< RealAudio 8 codec */ + OMX_AUDIO_RA9, /**< RealAudio 9 codec */ + OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */ + OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */ + OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */ + OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */ + OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */ + OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RAFormatMax = 0x7FFFFFFF +} OMX_AUDIO_RAFORMATTYPE; + +/** RA (Real Audio) params */ +typedef struct OMX_AUDIO_PARAM_RATYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */ + OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */ + OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */ + OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */ + OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */ + OMX_U32 nNumRegions; /**< is the number of regions value */ + OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */ +} OMX_AUDIO_PARAM_RATYPE; + + +/** SBC Allocation Method Type */ +typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE { + OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */ + OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */ + OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF +} OMX_AUDIO_SBCALLOCMETHODTYPE; + + +/** SBC params */ +typedef struct OMX_AUDIO_PARAM_SBCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ + OMX_U32 nBlocks; /**< Number of blocks */ + OMX_U32 nSubbands; /**< Number of subbands */ + OMX_U32 nBitPool; /**< Bitpool value */ + OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */ + OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */ + OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */ +} OMX_AUDIO_PARAM_SBCTYPE; + + +/** ADPCM stream format parameters */ +typedef struct OMX_AUDIO_PARAM_ADPCMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitsPerSample; /**< Number of bits in each sample */ + OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for + variable or unknown sampling rate. */ +} OMX_AUDIO_PARAM_ADPCMTYPE; + + +/** G723 rate */ +typedef enum OMX_AUDIO_G723RATE { + OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_G723ModeLow, /**< 5300 bps */ + OMX_AUDIO_G723ModeHigh, /**< 6300 bps */ + OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G723ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G723RATE; + + +/** G723 - Sample rate must be 8 KHz */ +typedef struct OMX_AUDIO_PARAM_G723TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ + OMX_BOOL bPostFilter; /**< Enable Post Filter */ +} OMX_AUDIO_PARAM_G723TYPE; + + +/** ITU G726 (ADPCM) rate */ +typedef enum OMX_AUDIO_G726MODE { + OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */ + OMX_AUDIO_G726Mode16, /**< 16 kbps */ + OMX_AUDIO_G726Mode24, /**< 24 kbps */ + OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */ + OMX_AUDIO_G726Mode40, /**< 40 kbps */ + OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G726ModeMax = 0x7FFFFFFF +} OMX_AUDIO_G726MODE; + + +/** G.726 stream format parameters - must be at 8KHz */ +typedef struct OMX_AUDIO_PARAM_G726TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_G726MODE eG726Mode; +} OMX_AUDIO_PARAM_G726TYPE; + + +/** G729 coder type */ +typedef enum OMX_AUDIO_G729TYPE { + OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */ + OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */ + OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */ + OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */ + OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_G729Max = 0x7FFFFFFF +} OMX_AUDIO_G729TYPE; + + +/** G729 stream format parameters - fixed 6KHz sample rate */ +typedef struct OMX_AUDIO_PARAM_G729TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_AUDIO_G729TYPE eBitType; +} OMX_AUDIO_PARAM_G729TYPE; + + +/** AMR Frame format */ +typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE { + OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance + (Standard) Format */ + OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface + Format 1 */ + OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface + Format 2*/ + OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage + Format */ + OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time + Transport Protocol Payload Format */ + OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */ + OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF +} OMX_AUDIO_AMRFRAMEFORMATTYPE; + + +/** AMR band mode */ +typedef enum OMX_AUDIO_AMRBANDMODETYPE { + OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */ + OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */ + OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */ + OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */ + OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */ + OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */ + OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */ + OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */ + OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */ + OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */ + OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */ + OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */ + OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */ + OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */ + OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */ + OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */ + OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */ + OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */ + OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRBANDMODETYPE; + + +/** AMR Discontinuous Transmission mode */ +typedef enum OMX_AUDIO_AMRDTXMODETYPE { + OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */ + OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 1 (VAD1) is enabled */ + OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using + Voice Activity Detector 2 (VAD2) is enabled */ + OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between + Off, VAD1 or VAD2 modes */ + + OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */ + + OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF +} OMX_AUDIO_AMRDTXMODETYPE; + + +/** AMR params */ +typedef struct OMX_AUDIO_PARAM_AMRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels */ + OMX_U32 nBitRate; /**< Bit rate read only field */ + OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */ + OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */ + OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */ +} OMX_AUDIO_PARAM_AMRTYPE; + + +/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMFRTYPE; + + +/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMHRTYPE; + + +/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_GSMEFRTYPE; + + +/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAFRTYPE; + + +/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_TDMAEFRTYPE; + + +/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCFRTYPE; + + +/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCEFRTYPE; + +/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_PDCHRTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */ + OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */ +} OMX_AUDIO_PARAM_PDCHRTYPE; + + +/** CDMA Rate types */ +typedef enum OMX_AUDIO_CDMARATETYPE { + OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */ + OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */ + OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */ + OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */ + OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/ + OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */ + OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_CDMARateMax = 0x7FFFFFFF +} OMX_AUDIO_CDMARATETYPE; + + +/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP8TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable + rate or unknown bit rates */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP8TYPE; + + +/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_QCELP13TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ +} OMX_AUDIO_PARAM_QCELP13TYPE; + + +/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_EVRCTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */ +} OMX_AUDIO_PARAM_EVRCTYPE; + + +/** SMV ( up to 8.55kbps coder) stream format parameters */ +typedef struct OMX_AUDIO_PARAM_SMVTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannels; /**< Number of channels in the data stream (not + necessarily the same as the number of channels + to be rendered. */ + OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */ + OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */ + OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/ + OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/ + OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/ + OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */ + OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/ +} OMX_AUDIO_PARAM_SMVTYPE; + + +/** MIDI Format + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIFORMATTYPE +{ + OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */ + OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */ + OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */ + OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */ + OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */ + OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */ + OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */ + OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */ + OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIFORMATTYPE; + + +/** MIDI params + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDITYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire + MIDI file passed in, otherwise if 0x0, the MIDI data + is merged and streamed (instead of passed as an + entire MIDI file) */ + OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound + bank at initialization */ + OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */ +} OMX_AUDIO_PARAM_MIDITYPE; + + +/** Type of the MIDI sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE { + OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */ + OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */ + OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */ + OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */ + OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKTYPE; + + +/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE { + OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */ + OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */ + OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */ + OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF +} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE; + + +/** MIDI params to load/unload user soundbank + * @ingroup midi + */ +typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nDLSIndex; /**< DLS file index to be loaded */ + OMX_U32 nDLSSize; /**< Size in bytes */ + OMX_PTR pDLSData; /**< Pointer to DLS file data */ + OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */ + OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */ +} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE; + + +/** Structure for Live MIDI events and MIP messages. + * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.) + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */ + OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an + array for the MIP message buffer, where the size is + indicated by nMidiEventSize */ +} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE; + + +/** MIDI sound bank/ program pair in a given channel + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */ + OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */ + OMX_U16 nIDSoundBank; /**< Sound bank ID */ + OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks + by index if multiple banks are present */ +} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE; + + +/** MIDI control + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10 + format based on JAVA MMAPI (JSR-135) requirement */ + OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point + number based on JSR-135 requirement */ + OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10 + fixed-point number based on JSR-135 requirement */ + OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic + voices. A value of zero indicates that the default + polyphony of the device is used */ + OMX_U32 nNumRepeat; /**< Number of times to repeat playback */ + OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback + will stop automatically. Set to zero if not used */ + OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */ + OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */ + OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */ + OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */ + OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */ + +} OMX_AUDIO_CONFIG_MIDICONTROLTYPE; + + +/** MIDI Playback States + * @ingroup midi + */ +typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE { + OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to + other defined states */ + OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open. + The MIDI engine is currently processing + MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being + primed. The MIDI engine is currently + processing MIDI events. */ + OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but + not playing. The MIDI engine is currently + processing MIDI events. The transition to + this state is only possible from the + OMX_AUDIO_MIDIPlayBackStatePlaying state, + when the 'playback head' reaches the end + of media data or the playback stops due + to stop time set.*/ + OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently + playing. The MIDI engine is currently + processing MIDI events.*/ + OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS + resource constraints */ + OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and + SP-MIDI content constraints, there is + no audible MIDI content during playback + currently. The situation may change if + resources are freed later.*/ + OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF +} OMX_AUDIO_MIDIPLAYBACKSTATETYPE; + + +/** MIDI status + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field. + NOTE: May not return a meaningful value until the entire + file is parsed and buffered. */ + OMX_U32 nDuration; /**< The length of the currently open MIDI resource + in milliseconds. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nPosition; /**< Current Position of the MIDI resource being played + in milliseconds */ + OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful + value until the entire file is parsed and buffered. */ + OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently + open MIDI resource. NOTE: May not return a meaningful value + until the entire file is parsed and buffered. */ + OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing + MIDI resource. NOTE: May not return a meaningful value until + the entire file is parsed and buffered. */ + OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */ +} OMX_AUDIO_CONFIG_MIDISTATUSTYPE; + + +/** MIDI Meta Event structure one per Meta Event. + * MIDI Meta Events are like audio metadata, except that they are interspersed + * with the MIDI content throughout the file and are not localized in the header. + * As such, it is necessary to retrieve information about these Meta Events from + * the engine, as it encounters these Meta Events within the MIDI content. + * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright, + * author, default tempo, etc.) scattered throughout the file. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U32 nTrack; /**< track number for the meta event */ + OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */ +} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE; + + +/** MIDI Meta Event Data structure - one per Meta Event. + * @ingroup midi + */ +typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nIndex; /**< Index of Meta Event */ + OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */ + OMX_U8 nData[1]; /**< array of one or more bytes of meta data + as indicated by the nMetaEventSize field */ +} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE; + + +/** Audio Volume adjustment for a port */ +typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) + or logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. The values + for volume are in mB (millibels = 1/100 dB) relative + to a gain of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ +} OMX_AUDIO_CONFIG_VOLUMETYPE; + + +/** Audio Volume adjustment for a channel */ +typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's volume. Select the + output port to adjust the master + volume. */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply volume settings + to all channels */ + OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or + logarithmic scale (mB) */ + OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR + Volume logarithmic setting for this port. + The values for volume are in mB + (millibels = 1/100 dB) relative to a gain + of 1 (e.g. the output is the same as the + input level). Values are in mB from nMax + (maximum volume) to nMin mB (typically negative). + Since the volume is "voltage" + and not a "power", it takes a setting of + -600 mB to decrease the volume by 1/2. If + a component cannot accurately set the + volume to the requested value, it must + set the volume to the closest value BELOW + the requested value. When getting the + volume setting, the current actual volume + must be returned. */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE; + + +/** Audio balance setting */ +typedef struct OMX_AUDIO_CONFIG_BALANCETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's balance. Select the + output port to adjust the master + balance. */ + OMX_S32 nBalance; /**< balance setting for this port + (-100 to 100, where -100 indicates + all left, and no right */ +} OMX_AUDIO_CONFIG_BALANCETYPE; + + +/** Audio Port mute */ +typedef struct OMX_AUDIO_CONFIG_MUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port index indicating which port to + set. Select the input port to set + just that port's mute. Select the + output port to adjust the master + mute. */ + OMX_BOOL bMute; /**< Mute setting for this port */ +} OMX_AUDIO_CONFIG_MUTETYPE; + + +/** Audio Channel mute */ +typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nChannel; /**< channel to select from 0 to N-1, + using OMX_ALL to apply mute settings + to all channels */ + OMX_BOOL bMute; /**< Mute setting for this channel */ + OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel, + FALSE otherwise */ +} OMX_AUDIO_CONFIG_CHANNELMUTETYPE; + + + +/** Enable / Disable for loudness control, which boosts bass and to a + * smaller extent high end frequencies to compensate for hearing + * ability at the extreme ends of the audio spectrum + */ +typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bLoudness; /**< Enable/disable for loudness */ +} OMX_AUDIO_CONFIG_LOUDNESSTYPE; + + +/** Enable / Disable for bass, which controls low frequencies + */ +typedef struct OMX_AUDIO_CONFIG_BASSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for bass control */ + OMX_S32 nBass; /**< bass setting for the port, as a + continuous value from -100 to 100 + (0 means no change in bass level)*/ +} OMX_AUDIO_CONFIG_BASSTYPE; + + +/** Enable / Disable for treble, which controls high frequencies tones + */ +typedef struct OMX_AUDIO_CONFIG_TREBLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for treble control */ + OMX_S32 nTreble; /**< treble setting for the port, as a + continuous value from -100 to 100 + (0 means no change in treble level) */ +} OMX_AUDIO_CONFIG_TREBLETYPE; + + +/** An equalizer is typically used for two reasons: to compensate for an + * sub-optimal frequency response of a system to make it sound more natural + * or to create intentionally some unnatural coloring to the sound to create + * an effect. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for equalizer */ + OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is + N-1, where N is the number of bands, lower limit is 0 */ + OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a + read only element and is used to determine + the lower, center and upper frequency of + this band. */ + OMX_BS32 sBandLevel; /**< band level in millibels */ +} OMX_AUDIO_CONFIG_EQUALIZERTYPE; + + +/** Stereo widening mode type + * @ingroup effects + */ +typedef enum OMX_AUDIO_STEREOWIDENINGTYPE { + OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */ + OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */ + OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF +} OMX_AUDIO_STEREOWIDENINGTYPE; + + +/** Control for stereo widening, which is a special 2-channel + * case of the audio virtualizer effect. For example, for 5.1-channel + * output, it translates to virtual surround sound. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */ + OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */ + OMX_U32 nStereoWidening; /**< stereo widening setting for the port, + as a continuous value from 0 to 100 */ +} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE; + + +/** The chorus effect (or ``choralizer'') is any signal processor which makes + * one sound source (such as a voice) sound like many such sources singing + * (or playing) in unison. Since performance in unison is never exact, chorus + * effects simulate this by making independently modified copies of the input + * signal. Modifications may include (1) delay, (2) frequency shift, and + * (3) amplitude modulation. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for chorus */ + OMX_BU32 sDelay; /**< average delay in milliseconds */ + OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */ + OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of + delay (i.e. 0 to 100) */ + OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */ +} OMX_AUDIO_CONFIG_CHORUSTYPE; + + +/** Reverberation is part of the reflected sound that follows the early + * reflections. In a typical room, this consists of a dense succession of + * echoes whose energy decays exponentially. The reverberation effect structure + * as defined here includes both (early) reflections as well as (late) reverberations. + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bEnable; /**< Enable/disable for reverberation control */ + OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect + (i.e. both early reflections and late + reverberation) in millibels */ + OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies + relative to the intensity at low + frequencies in millibels */ + OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections + (relative to room value), in millibels */ + OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative + to the direct path, in milliseconds */ + OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation + relative to room level, in millibels */ + OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection + to the beginning of the late reverberation + section, in milliseconds */ + OMX_BU32 sDecayTime; /**< Late reverberation decay time at low + frequencies, in milliseconds */ + OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative + to low frequency decay time in percent */ + OMX_U32 nDensity; /**< Modal density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay, + in percent (i.e. 0 - 100) */ + OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is + the frequency used as the reference for all + the high-frequency settings above */ + +} OMX_AUDIO_CONFIG_REVERBERATIONTYPE; + + +/** Possible settings for the Echo Cancelation structure to use + * @ingroup effects + */ +typedef enum OMX_AUDIO_ECHOCANTYPE { + OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */ + OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation - + echo from plastics and face */ + OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for + Hands Free operation */ + OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for + Car Kit (longer echo) */ + OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_AUDIO_EchoCanMax = 0x7FFFFFFF +} OMX_AUDIO_ECHOCANTYPE; + + +/** Enable / Disable for echo cancelation, which removes undesired echo's + * from the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */ +} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE; + + +/** Enable / Disable for noise reduction, which undesired noise from + * the audio + * @ingroup effects + */ +typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */ +} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Component.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Component.h new file mode 100644 index 0000000..d595640 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Component.h @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** OMX_Component.h - OpenMax IL version 1.1.2 + * The OMX_Component header file contains the definitions used to define + * the public interface of a component. This header file is intended to + * be used by both the application and the component. + */ + +#ifndef OMX_Component_h +#define OMX_Component_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include +#include +#include +#include + +/** @ingroup comp */ +typedef enum OMX_PORTDOMAINTYPE { + OMX_PortDomainAudio, + OMX_PortDomainVideo, + OMX_PortDomainImage, + OMX_PortDomainOther, + OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_PortDomainMax = 0x7ffffff +} OMX_PORTDOMAINTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_PORTDEFINITIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port number the structure applies to */ + OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */ + OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */ + OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */ + OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */ + OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by + OMX_CommandPortEnable/OMX_CommandPortDisable. + When disabled a port is unpopulated. A disabled port + is not populated with buffers on a transition to IDLE. */ + OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by + nBufferCountActual. A disabled port is always unpopulated. + An enabled port is populated on a transition to OMX_StateIdle + and unpopulated on a transition to loaded. */ + OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */ + union { + OMX_AUDIO_PORTDEFINITIONTYPE audio; + OMX_VIDEO_PORTDEFINITIONTYPE video; + OMX_IMAGE_PORTDEFINITIONTYPE image; + OMX_OTHER_PORTDEFINITIONTYPE other; + } format; + OMX_BOOL bBuffersContiguous; + OMX_U32 nBufferAlignment; +} OMX_PARAM_PORTDEFINITIONTYPE; + +/** @ingroup comp */ +typedef struct OMX_PARAM_U32TYPE { + OMX_U32 nSize; /**< Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_U32 nU32; /**< U32 value */ +} OMX_PARAM_U32TYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONPOLICYTYPE { + OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */ + OMX_SuspensionEnabled, /**< Suspension allowed */ + OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspensionPolicyMax = 0x7fffffff +} OMX_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONPOLICYTYPE ePolicy; +} OMX_PARAM_SUSPENSIONPOLICYTYPE; + +/** @ingroup rpm */ +typedef enum OMX_SUSPENSIONTYPE { + OMX_NotSuspended, /**< component is not suspended */ + OMX_Suspended, /**< component is suspended */ + OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_SuspendMax = 0x7FFFFFFF +} OMX_SUSPENSIONTYPE; + +/** @ingroup rpm */ +typedef struct OMX_PARAM_SUSPENSIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_SUSPENSIONTYPE eType; +} OMX_PARAM_SUSPENSIONTYPE ; + +typedef struct OMX_CONFIG_BOOLEANTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bEnabled; +} OMX_CONFIG_BOOLEANTYPE; + +/* Parameter specifying the content uri to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTURITYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes, including + actual URI name */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 contentURI[1]; /**< The URI name */ +} OMX_PARAM_CONTENTURITYPE; + +/* Parameter specifying the pipe to use. */ +/** @ingroup cp */ +typedef struct OMX_PARAM_CONTENTPIPETYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_HANDLETYPE hPipe; /**< The pipe handle*/ +} OMX_PARAM_CONTENTPIPETYPE; + +/** @ingroup rpm */ +typedef struct OMX_RESOURCECONCEALMENTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment + methods (like degrading algorithm quality to + lower resource consumption or functional bypass) + on a component as a resolution to resource conflicts. */ +} OMX_RESOURCECONCEALMENTTYPE; + + +/** @ingroup metadata */ +typedef enum OMX_METADATACHARSETTYPE { + OMX_MetadataCharsetUnknown = 0, + OMX_MetadataCharsetASCII, + OMX_MetadataCharsetBinary, + OMX_MetadataCharsetCodePage1252, + OMX_MetadataCharsetUTF8, + OMX_MetadataCharsetJavaConformantUTF8, + OMX_MetadataCharsetUTF7, + OMX_MetadataCharsetImapUTF7, + OMX_MetadataCharsetUTF16LE, + OMX_MetadataCharsetUTF16BE, + OMX_MetadataCharsetGB12345, + OMX_MetadataCharsetHZGB2312, + OMX_MetadataCharsetGB2312, + OMX_MetadataCharsetGB18030, + OMX_MetadataCharsetGBK, + OMX_MetadataCharsetBig5, + OMX_MetadataCharsetISO88591, + OMX_MetadataCharsetISO88592, + OMX_MetadataCharsetISO88593, + OMX_MetadataCharsetISO88594, + OMX_MetadataCharsetISO88595, + OMX_MetadataCharsetISO88596, + OMX_MetadataCharsetISO88597, + OMX_MetadataCharsetISO88598, + OMX_MetadataCharsetISO88599, + OMX_MetadataCharsetISO885910, + OMX_MetadataCharsetISO885913, + OMX_MetadataCharsetISO885914, + OMX_MetadataCharsetISO885915, + OMX_MetadataCharsetShiftJIS, + OMX_MetadataCharsetISO2022JP, + OMX_MetadataCharsetISO2022JP1, + OMX_MetadataCharsetISOEUCJP, + OMX_MetadataCharsetSMS7Bit, + OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataCharsetTypeMax= 0x7FFFFFFF +} OMX_METADATACHARSETTYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASCOPETYPE +{ + OMX_MetadataScopeAllLevels, + OMX_MetadataScopeTopLevel, + OMX_MetadataScopePortLevel, + OMX_MetadataScopeNodeLevel, + OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataScopeTypeMax = 0x7fffffff +} OMX_METADATASCOPETYPE; + +/** @ingroup metadata */ +typedef enum OMX_METADATASEARCHMODETYPE +{ + OMX_MetadataSearchValueSizeByIndex, + OMX_MetadataSearchItemByIndex, + OMX_MetadataSearchNextItemByKey, + OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MetadataSearchTypeMax = 0x7fffffff +} OMX_METADATASEARCHMODETYPE; +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemCount; +} OMX_CONFIG_METADATAITEMCOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_METADATAITEMTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_METADATASCOPETYPE eScopeMode; + OMX_U32 nScopeSpecifier; + OMX_U32 nMetadataItemIndex; + OMX_METADATASEARCHMODETYPE eSearchMode; + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U8 nKeySizeUsed; + OMX_U8 nKey[128]; + OMX_METADATACHARSETTYPE eValueCharset; + OMX_STRING sLanguageCountry; + OMX_U32 nValueMaxSize; + OMX_U32 nValueSizeUsed; + OMX_U8 nValue[1]; +} OMX_CONFIG_METADATAITEMTYPE; + +/* @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNumNodes; +} OMX_CONFIG_CONTAINERNODECOUNTTYPE; + +/** @ingroup metadata */ +typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; + OMX_U32 nParentNodeID; + OMX_U32 nNodeIndex; + OMX_U32 nNodeID; + OMX_STRING cNodeName; + OMX_BOOL bIsLeafType; +} OMX_CONFIG_CONTAINERNODEIDTYPE; + +/** @ingroup metadata */ +typedef struct OMX_PARAM_METADATAFILTERTYPE +{ + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and + * the three key fields below are ignored */ + OMX_METADATACHARSETTYPE eKeyCharset; + OMX_U32 nKeySizeUsed; + OMX_U8 nKey [128]; + OMX_U32 nLanguageCountrySizeUsed; + OMX_U8 nLanguageCountry[128]; + OMX_BOOL bEnabled; /* if true then key is part of filter (e.g. + * retained for query later). If false then + * key is not part of filter */ +} OMX_PARAM_METADATAFILTERTYPE; + +/** The OMX_HANDLETYPE structure defines the component handle. The component + * handle is used to access all of the component's public methods and also + * contains pointers to the component's private data area. The component + * handle is initialized by the OMX core (with help from the component) + * during the process of loading the component. After the component is + * successfully loaded, the application can safely access any of the + * component's public functions (although some may return an error because + * the state is inappropriate for the access). + * + * @ingroup comp + */ +typedef struct OMX_COMPONENTTYPE +{ + /** The size of this structure, in bytes. It is the responsibility + of the allocator of this structure to fill in this value. Since + this structure is allocated by the GetHandle function, this + function will fill in this value. */ + OMX_U32 nSize; + + /** nVersion is the version of the OMX specification that the structure + is built against. It is the responsibility of the creator of this + structure to initialize this value and every user of this structure + should verify that it knows how to use the exact version of + this structure found herein. */ + OMX_VERSIONTYPE nVersion; + + /** pComponentPrivate is a pointer to the component private data area. + This member is allocated and initialized by the component when the + component is first loaded. The application should not access this + data area. */ + OMX_PTR pComponentPrivate; + + /** pApplicationPrivate is a pointer that is a parameter to the + OMX_GetHandle method, and contains an application private value + provided by the IL client. This application private data is + returned to the IL Client by OMX in all callbacks */ + OMX_PTR pApplicationPrivate; + + /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL + specification for details on the GetComponentVersion method. + */ + OMX_ERRORTYPE (*GetComponentVersion)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STRING pComponentName, + OMX_OUT OMX_VERSIONTYPE* pComponentVersion, + OMX_OUT OMX_VERSIONTYPE* pSpecVersion, + OMX_OUT OMX_UUIDTYPE* pComponentUUID); + + /** refer to OMX_SendCommand in OMX_core.h or the OMX IL + specification for details on the SendCommand method. + */ + OMX_ERRORTYPE (*SendCommand)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_COMMANDTYPE Cmd, + OMX_IN OMX_U32 nParam1, + OMX_IN OMX_PTR pCmdData); + + /** refer to OMX_GetParameter in OMX_core.h or the OMX IL + specification for details on the GetParameter method. + */ + OMX_ERRORTYPE (*GetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nParamIndex, + OMX_INOUT OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_SetParameter in OMX_core.h or the OMX IL + specification for details on the SetParameter method. + */ + OMX_ERRORTYPE (*SetParameter)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentParameterStructure); + + + /** refer to OMX_GetConfig in OMX_core.h or the OMX IL + specification for details on the GetConfig method. + */ + OMX_ERRORTYPE (*GetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_INOUT OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_SetConfig in OMX_core.h or the OMX IL + specification for details on the SetConfig method. + */ + OMX_ERRORTYPE (*SetConfig)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_INDEXTYPE nIndex, + OMX_IN OMX_PTR pComponentConfigStructure); + + + /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL + specification for details on the GetExtensionIndex method. + */ + OMX_ERRORTYPE (*GetExtensionIndex)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_STRING cParameterName, + OMX_OUT OMX_INDEXTYPE* pIndexType); + + + /** refer to OMX_GetState in OMX_core.h or the OMX IL + specification for details on the GetState method. + */ + OMX_ERRORTYPE (*GetState)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_STATETYPE* pState); + + + /** The ComponentTunnelRequest method will interact with another OMX + component to determine if tunneling is possible and to setup the + tunneling. The return codes for this method can be used to + determine if tunneling is not possible, or if tunneling is not + supported. + + Base profile components (i.e. non-interop) do not support this + method and should return OMX_ErrorNotImplemented + + The interop profile component MUST support tunneling to another + interop profile component with a compatible port parameters. + A component may also support proprietary communication. + + If proprietary communication is supported the negotiation of + proprietary communication is done outside of OMX in a vendor + specific way. It is only required that the proper result be + returned and the details of how the setup is done is left + to the component implementation. + + When this method is invoked when nPort in an output port, the + component will: + 1. Populate the pTunnelSetup structure with the output port's + requirements and constraints for the tunnel. + + When this method is invoked when nPort in an input port, the + component will: + 1. Query the necessary parameters from the output port to + determine if the ports are compatible for tunneling + 2. If the ports are compatible, the component should store + the tunnel step provided by the output port + 3. Determine which port (either input or output) is the buffer + supplier, and call OMX_SetParameter on the output port to + indicate this selection. + + The component will return from this call within 5 msec. + + @param [in] hComp + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle method. + @param [in] nPort + nPort is used to select the port on the component to be used + for tunneling. + @param [in] hTunneledComp + Handle of the component to tunnel with. This is the component + handle returned by the call to the OMX_GetHandle method. When + this parameter is 0x0 the component should setup the port for + communication with the application / IL Client. + @param [in] nPortOutput + nPortOutput is used indicate the port the component should + tunnel with. + @param [in] pTunnelSetup + Pointer to the tunnel setup structure. When nPort is an output port + the component should populate the fields of this structure. When + When nPort is an input port the component should review the setup + provided by the component with the output port. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup tun + */ + + OMX_ERRORTYPE (*ComponentTunnelRequest)( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 nPort, + OMX_IN OMX_HANDLETYPE hTunneledComp, + OMX_IN OMX_U32 nTunneledPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup); + + /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL + specification for details on the UseBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*UseBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes, + OMX_IN OMX_U8* pBuffer); + + /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL + specification for details on the AllocateBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*AllocateBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN OMX_U32 nSizeBytes); + + /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL + specification for details on the FreeBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FreeBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL + specification for details on the EmptyThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL + specification for details on the FillThisBuffer method. + @ingroup buf + */ + OMX_ERRORTYPE (*FillThisBuffer)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The SetCallbacks method is used by the core to specify the callback + structure from the application to the component. This is a blocking + call. The component will return from this call within 5 msec. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] pCallbacks + pointer to an OMX_CALLBACKTYPE structure used to provide the + callback information to the component + @param [in] pAppData + pointer to an application defined value. It is anticipated that + the application will pass a pointer to a data structure or a "this + pointer" in this area to allow the callback (in the application) + to determine the context of the call + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*SetCallbacks)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_CALLBACKTYPE* pCallbacks, + OMX_IN OMX_PTR pAppData); + + /** ComponentDeInit method is used to deinitialize the component + providing a means to free any resources allocated at component + initialization. NOTE: After this call the component handle is + not valid for further use. + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + */ + OMX_ERRORTYPE (*ComponentDeInit)( + OMX_IN OMX_HANDLETYPE hComponent); + + /** @ingroup buf */ + OMX_ERRORTYPE (*UseEGLImage)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr, + OMX_IN OMX_U32 nPortIndex, + OMX_IN OMX_PTR pAppPrivate, + OMX_IN void* eglImage); + + OMX_ERRORTYPE (*ComponentRoleEnum)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_OUT OMX_U8 *cRole, + OMX_IN OMX_U32 nIndex); + +} OMX_COMPONENTTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_ContentPipe.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_ContentPipe.h new file mode 100644 index 0000000..5f6310c --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_ContentPipe.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** OMX_ContentPipe.h - OpenMax IL version 1.1.2 + * The OMX_ContentPipe header file contains the definitions used to define + * the public interface for content piples. This header file is intended to + * be used by the component. + */ + +#ifndef OMX_CONTENTPIPE_H +#define OMX_CONTENTPIPE_H + +#ifndef KD_EACCES +/* OpenKODE error codes. CPResult values may be zero (indicating success + or one of the following values) */ +#define KD_EACCES (1) +#define KD_EADDRINUSE (2) +#define KD_EAGAIN (5) +#define KD_EBADF (7) +#define KD_EBUSY (8) +#define KD_ECONNREFUSED (9) +#define KD_ECONNRESET (10) +#define KD_EDEADLK (11) +#define KD_EDESTADDRREQ (12) +#define KD_ERANGE (35) +#define KD_EEXIST (13) +#define KD_EFBIG (14) +#define KD_EHOSTUNREACH (15) +#define KD_EINVAL (17) +#define KD_EIO (18) +#define KD_EISCONN (20) +#define KD_EISDIR (21) +#define KD_EMFILE (22) +#define KD_ENAMETOOLONG (23) +#define KD_ENOENT (24) +#define KD_ENOMEM (25) +#define KD_ENOSPC (26) +#define KD_ENOSYS (27) +#define KD_ENOTCONN (28) +#define KD_EPERM (33) +#define KD_ETIMEDOUT (36) +#define KD_EILSEQ (19) +#endif + +/** Map types from OMX standard types only here so interface is as generic as possible. */ +typedef OMX_U32 CPresult; +typedef char * CPstring; +typedef void * CPhandle; +typedef OMX_U32 CPuint; +typedef OMX_S32 CPint; +typedef char CPbyte; +typedef OMX_BOOL CPbool; + +/** enumeration of origin types used in the CP_PIPETYPE's Seek function + * @ingroup cp + */ +typedef enum CP_ORIGINTYPE { + CP_OriginBegin, + CP_OriginCur, + CP_OriginEnd, + CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_OriginMax = 0X7FFFFFFF +} CP_ORIGINTYPE; + +/** enumeration of contact access types used in the CP_PIPETYPE's Open function + * @ingroup cp + */ +typedef enum CP_ACCESSTYPE { + CP_AccessRead, + CP_AccessWrite, + CP_AccessReadWrite , + CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_AccessMax = 0X7FFFFFFF +} CP_ACCESSTYPE; + +/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function + * @ingroup cp + */ +typedef enum CP_CHECKBYTESRESULTTYPE +{ + CP_CheckBytesOk, /**< There are at least the request number + of bytes available */ + CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes + and presently lacks sufficient bytes. + Client will be called when they are + sufficient bytes are available. */ + CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes + but those available are less than those + requested */ + CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream + and no more bytes are available. */ + CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */ + CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_CheckBytesMax = 0X7FFFFFFF +} CP_CHECKBYTESRESULTTYPE; + +/** enumeration of content pipe events sent to the client callback. + * @ingroup cp + */ +typedef enum CP_EVENTTYPE{ + CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/ + CP_Overflow, /** enumeration of content pipe events sent to the client callback*/ + CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/ + CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + CP_EventMax = 0X7FFFFFFF +} CP_EVENTTYPE; + +/** content pipe definition + * @ingroup cp + */ +typedef struct CP_PIPETYPE +{ + /** Open a content stream for reading or writing. */ + CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess ); + + /** Close a content stream. */ + CPresult (*Close)( CPhandle hContent ); + + /** Create a content source and open it for writing. */ + CPresult (*Create)( CPhandle *hContent, CPstring szURI ); + + /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/ + CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult ); + + /** Seek to certain position in the content relative to the specified origin. */ + CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin); + + /** Retrieve the current position relative to the start of the content. */ + CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition); + + /** Retrieve data of the specified size from the content stream (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */ + CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes. + Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also + returns the size of the block actually read. Content pointer advances the by the returned size. + Note: pipe provides pointer. This function is appropriate for large reads. The client must call + ReleaseReadBuffer when done with buffer. + + In some cases the requested block may not reside in contiguous memory within the + pipe implementation. For instance if the pipe leverages a circular buffer then the requested + block may straddle the boundary of the circular buffer. By default a pipe implementation + performs a copy in this case to provide the block to the pipe client in one contiguous buffer. + If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory + boundary. Here the client may retrieve the data in segments over successive calls. */ + CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy); + + /** Release a buffer obtained by ReadBuffer back to the pipe. */ + CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer); + + /** Write data of the specified size to the content (advance content pointer by size of data). + Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */ + CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize); + + /** Retrieve a buffer allocated by the pipe used to write data to the content. + Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate + for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/ + CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize); + + /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the + the contents of the buffer to content and advance content pointer by the size of the buffer */ + CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize); + + /** Register a per-handle client callback with the content pipe. */ + CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam)); + +} CP_PIPETYPE; + +#endif + diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Core.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Core.h new file mode 100644 index 0000000..a076f2f --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Core.h @@ -0,0 +1,1431 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** OMX_Core.h - OpenMax IL version 1.1.2 + * The OMX_Core header file contains the definitions used by both the + * application and the component to access common items. + */ + +#ifndef OMX_Core_h +#define OMX_Core_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header shall include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** The OMX_COMMANDTYPE enumeration is used to specify the action in the + * OMX_SendCommand macro. + * @ingroup core + */ +typedef enum OMX_COMMANDTYPE +{ + OMX_CommandStateSet, /**< Change the component state */ + OMX_CommandFlush, /**< Flush the data queue(s) of a component */ + OMX_CommandPortDisable, /**< Disable a port on a component. */ + OMX_CommandPortEnable, /**< Enable a port on a component. */ + OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */ + OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_CommandMax = 0X7FFFFFFF +} OMX_COMMANDTYPE; + + + +/** The OMX_STATETYPE enumeration is used to indicate or change the component + * state. This enumeration reflects the current state of the component when + * used with the OMX_GetState macro or becomes the parameter in a state change + * command when used with the OMX_SendCommand macro. + * + * The component will be in the Loaded state after the component is initially + * loaded into memory. In the Loaded state, the component is not allowed to + * allocate or hold resources other than to build it's internal parameter + * and configuration tables. The application will send one or more + * SetParameters/GetParameters and SetConfig/GetConfig commands to the + * component and the component will record each of these parameter and + * configuration changes for use later. When the application sends the + * Idle command, the component will acquire the resources needed for the + * specified configuration and will transition to the idle state if the + * allocation is successful. If the component cannot successfully + * transition to the idle state for any reason, the state of the component + * shall be fully rolled back to the Loaded state (e.g. all allocated + * resources shall be released). When the component receives the command + * to go to the Executing state, it shall begin processing buffers by + * sending all input buffers it holds to the application. While + * the component is in the Idle state, the application may also send the + * Pause command. If the component receives the pause command while in the + * Idle state, the component shall send all input buffers it holds to the + * application, but shall not begin processing buffers. This will allow the + * application to prefill buffers. + * + * @ingroup comp + */ + +typedef enum OMX_STATETYPE +{ + OMX_StateInvalid, /**< component has detected that it's internal data + structures are corrupted to the point that + it cannot determine it's state properly */ + OMX_StateLoaded, /**< component has been loaded but has not completed + initialization. The OMX_SetParameter macro + and the OMX_GetParameter macro are the only + valid macros allowed to be sent to the + component in this state. */ + OMX_StateIdle, /**< component initialization has been completed + successfully and the component is ready to + to start. */ + OMX_StateExecuting, /**< component has accepted the start command and + is processing data (if data is available) */ + OMX_StatePause, /**< component has received pause command */ + OMX_StateWaitForResources, /**< component is waiting for resources, either after + preemption or before it gets the resources requested. + See specification for complete details. */ + OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_StateMax = 0X7FFFFFFF +} OMX_STATETYPE; + +/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These + * errors should cover most of the common failure cases. However, + * vendors are free to add additional error messages of their own as + * long as they follow these rules: + * 1. Vendor error messages shall be in the range of 0x90000000 to + * 0x9000FFFF. + * 2. Vendor error messages shall be defined in a header file provided + * with the component. No error messages are allowed that are + * not defined. + */ +typedef enum OMX_ERRORTYPE +{ + OMX_ErrorNone = 0, + + /** There were insufficient resources to perform the requested operation */ + OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000, + + /** There was an error, but the cause of the error could not be determined */ + OMX_ErrorUndefined = (OMX_S32) 0x80001001, + + /** The component name string was not valid */ + OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002, + + /** No component with the specified name string was found */ + OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003, + + /** The component specified did not have a "OMX_ComponentInit" or + "OMX_ComponentDeInit entry point */ + OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004, + + /** One or more parameters were not valid */ + OMX_ErrorBadParameter = (OMX_S32) 0x80001005, + + /** The requested function is not implemented */ + OMX_ErrorNotImplemented = (OMX_S32) 0x80001006, + + /** The buffer was emptied before the next buffer was ready */ + OMX_ErrorUnderflow = (OMX_S32) 0x80001007, + + /** The buffer was not available when it was needed */ + OMX_ErrorOverflow = (OMX_S32) 0x80001008, + + /** The hardware failed to respond as expected */ + OMX_ErrorHardware = (OMX_S32) 0x80001009, + + /** The component is in the state OMX_StateInvalid */ + OMX_ErrorInvalidState = (OMX_S32) 0x8000100A, + + /** Stream is found to be corrupt */ + OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B, + + /** Ports being connected are not compatible */ + OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C, + + /** Resources allocated to an idle component have been + lost resulting in the component returning to the loaded state */ + OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D, + + /** No more indicies can be enumerated */ + OMX_ErrorNoMore = (OMX_S32) 0x8000100E, + + /** The component detected a version mismatch */ + OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F, + + /** The component is not ready to return data at this time */ + OMX_ErrorNotReady = (OMX_S32) 0x80001010, + + /** There was a timeout that occurred */ + OMX_ErrorTimeout = (OMX_S32) 0x80001011, + + /** This error occurs when trying to transition into the state you are already in */ + OMX_ErrorSameState = (OMX_S32) 0x80001012, + + /** Resources allocated to an executing or paused component have been + preempted, causing the component to return to the idle state */ + OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the allocation of buffers (on a transition from the LOADED to the IDLE state or + on a port restart) when it deems that it has waited an unusually long time for the supplier + to send it an allocated buffer via a UseBuffer call. */ + OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014, + + /** A non-supplier port sends this error to the IL client (via the EventHandler callback) + during the deallocation of buffers (on a transition from the IDLE to LOADED state or + on a port stop) when it deems that it has waited an unusually long time for the supplier + to request the deallocation of a buffer header via a FreeBuffer call. */ + OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015, + + /** A supplier port sends this error to the IL client (via the EventHandler callback) + during the stopping of a port (either on a transition from the IDLE to LOADED + state or a port stop) when it deems that it has waited an unusually long time for + the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */ + OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016, + + /** Attempting a state transtion that is not allowed */ + OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017, + + /* Attempting a command that is not allowed during the present state. */ + OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018, + + /** The values encapsulated in the parameter or config structure are not supported. */ + OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019, + + /** The parameter or config indicated by the given index is not supported. */ + OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A, + + /** The port index supplied is incorrect. */ + OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B, + + /** The port has lost one or more of its buffers and it thus unpopulated. */ + OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C, + + /** Component suspended due to temporary loss of resources */ + OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D, + + /** Component suspended due to an inability to acquire dynamic resources */ + OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E, + + /** When the macroblock error reporting is enabled the component returns new error + for every frame that has errors */ + OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F, + + /** A component reports this error when it cannot parse or determine the format of an input stream. */ + OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020, + + /** The content open operation failed. */ + OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021, + + /** The content creation operation failed. */ + OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022, + + /** Separate table information is being used */ + OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023, + + /** Tunneling is unsupported by the component*/ + OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024, + + OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ErrorMax = 0x7FFFFFFF +} OMX_ERRORTYPE; + +/** @ingroup core */ +typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent); + +/** @ingroup core */ +typedef struct OMX_COMPONENTREGISTERTYPE +{ + const char * pName; /* Component name, 128 byte limit (including '\0') applies */ + OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */ +} OMX_COMPONENTREGISTERTYPE; + +/** @ingroup core */ +extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[]; + +/** @ingroup rpm */ +typedef struct OMX_PRIORITYMGMTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nGroupPriority; /**< Priority of the component group */ + OMX_U32 nGroupID; /**< ID of the component group */ +} OMX_PRIORITYMGMTTYPE; + +/* Component name and Role names are limited to 128 characters including the terminating '\0'. */ +#define OMX_MAX_STRINGNAME_SIZE 128 + +/** @ingroup comp */ +typedef struct OMX_PARAM_COMPONENTROLETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */ +} OMX_PARAM_COMPONENTROLETYPE; + +/** End of Stream Buffer Flag: + * + * A component sets EOS when it has no more data to emit on a particular + * output port. Thus an output port shall set EOS on the last buffer it + * emits. A component's determination of when an output port should + * cease sending data is implemenation specific. + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_EOS 0x00000001 + +/** Start Time Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the STARTTIME + * flag on the buffer that contains the starting timestamp for the + * stream. The starting timestamp corresponds to the first data that + * should be displayed at startup or after a seek. + * The first timestamp of the stream is not necessarily the start time. + * For instance, in the case of a seek to a particular video frame, + * the target frame may be an interframe. Thus the first buffer of + * the stream will be the intra-frame preceding the target frame and + * the starttime will occur with the target frame (with any other + * required frames required to reconstruct the target intervening). + * + * The STARTTIME flag is directly associated with the buffer's + * timestamp ' thus its association to buffer data and its + * propagation is identical to the timestamp's. + * + * When a Sync Component client receives a buffer with the + * STARTTIME flag it shall perform a SetConfig on its sync port + * using OMX_ConfigTimeClientStartTime and passing the buffer's + * timestamp. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_STARTTIME 0x00000002 + + + +/** Decode Only Buffer Flag: + * + * The source of a stream (e.g. a demux component) sets the DECODEONLY + * flag on any buffer that should shall be decoded but should not be + * displayed. This flag is used, for instance, when a source seeks to + * a target interframe that requires the decode of frames preceding the + * target to facilitate the target's reconstruction. In this case the + * source would emit the frames preceding the target downstream + * but mark them as decode only. + * + * The DECODEONLY is associated with buffer data and propagated in a + * manner identical to the buffer timestamp. + * + * A component that renders data should ignore all buffers with + * the DECODEONLY flag set. + * + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DECODEONLY 0x00000004 + + +/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt + * @ingroup buf + */ + +#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008 + +/* End of Frame: The buffer contains exactly one end of frame and no data + * occurs after the end of frame. This flag is an optional hint. The absence + * of this flag does not imply the absence of an end of frame within the buffer. + * @ingroup buf +*/ +#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010 + +/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame ' + * a frame that has no dependency on any other frame information + * @ingroup buf + */ +#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020 + +/* Extra data present flag: there is extra data appended to the data stream + * residing in the buffer + * @ingroup buf + */ +#define OMX_BUFFERFLAG_EXTRADATA 0x00000040 + +/** Codec Config Buffer Flag: +* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an +* output port when all bytes in the buffer form part or all of a set of +* codec specific configuration data. Examples include SPS/PPS nal units +* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for +* OMX_AUDIO_CodingAAC. Any component that for a given stream sets +* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes +* with frame data in the same buffer, and shall send all buffers +* containing codec configuration bytes before any buffers containing +* frame data that those configurations bytes describe. +* If the stream format for a particular codec has a frame specific +* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or +* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as +* normal without setting OMX_BUFFERFLAG_CODECCONFIG. + * @ingroup buf + */ +#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080 + + + +/** @ingroup buf */ +typedef struct OMX_BUFFERHEADERTYPE +{ + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U8* pBuffer; /**< Pointer to actual block of memory + that is acting as the buffer */ + OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */ + OMX_U32 nFilledLen; /**< number of bytes currently in the + buffer */ + OMX_U32 nOffset; /**< start offset of valid data in bytes from + the start of the buffer */ + OMX_PTR pAppPrivate; /**< pointer to any data the application + wants to associate with this buffer */ + OMX_PTR pPlatformPrivate; /**< pointer to any data the platform + wants to associate with this buffer */ + OMX_PTR pInputPortPrivate; /**< pointer to any data the input port + wants to associate with this buffer */ + OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port + wants to associate with this buffer */ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a + mark event upon processing this buffer. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ + OMX_U32 nTickCount; /**< Optional entry that the component and + application can update with a tick count + when they access the component. This + value should be in microseconds. Since + this is a value relative to an arbitrary + starting point, this value cannot be used + to determine absolute time. This is an + optional entry and not all components + will update it.*/ + OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample + starting at the first logical sample + boundary in the buffer. Timestamps of + successive samples within the buffer may + be inferred by adding the duration of the + of the preceding buffer to the timestamp + of the preceding buffer.*/ + OMX_U32 nFlags; /**< buffer specific flags */ + OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using + this buffer */ + OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using + this buffer */ +} OMX_BUFFERHEADERTYPE; + +/** The OMX_EXTRADATATYPE enumeration is used to define the + * possible extra data payload types. + * NB: this enum is binary backwards compatible with the previous + * OMX_EXTRADATA_QUANT define. This should be replaced with + * OMX_ExtraDataQuantization. + */ +typedef enum OMX_EXTRADATATYPE +{ + OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */ + OMX_ExtraDataQuantization, /**< The data payload contains quantization data */ + OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExtraDataMax = 0x7FFFFFFF +} OMX_EXTRADATATYPE; + + +typedef struct OMX_OTHER_EXTRADATATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXTRADATATYPE eType; /* Extra Data type */ + OMX_U32 nDataSize; /* Size of the supporting data to follow */ + OMX_U8 data[1]; /* Supporting data hint */ +} OMX_OTHER_EXTRADATATYPE; + +/** @ingroup comp */ +typedef struct OMX_PORT_PARAM_TYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPorts; /**< The number of ports for this component */ + OMX_U32 nStartPortNumber; /** first port number for this type of port */ +} OMX_PORT_PARAM_TYPE; + +/** @ingroup comp */ +typedef enum OMX_EVENTTYPE +{ + OMX_EventCmdComplete, /**< component has sucessfully completed a command */ + OMX_EventError, /**< component has detected an error condition */ + OMX_EventMark, /**< component has detected a buffer mark */ + OMX_EventPortSettingsChanged, /**< component is reported a port settings change */ + OMX_EventBufferFlag, /**< component has detected an EOS */ + OMX_EventResourcesAcquired, /**< component has been granted resources and is + automatically starting the state change from + OMX_StateWaitForResources to OMX_StateIdle. */ + OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */ + OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */ + OMX_EventPortFormatDetected, /**< Component has detected a supported format. */ + OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EventMax = 0x7FFFFFFF +} OMX_EVENTTYPE; + +typedef struct OMX_CALLBACKTYPE +{ + /** The EventHandler method is used to notify the application when an + event of interest occurs. Events are defined in the OMX_EVENTTYPE + enumeration. Please see that enumeration for details of what will + be returned for each type of event. Callbacks should not return + an error to the component, so if an error occurs, the application + shall handle it internally. This is a blocking call. + + The application should return from this call within 5 msec to avoid + blocking the component for an excessively long period of time. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param eEvent + Event that the component wants to notify the application about. + @param nData1 + nData will be the OMX_ERRORTYPE for an error event and will be + an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event. + @param nData2 + nData2 will hold further information related to the event. Can be OMX_STATETYPE for + a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event. + Default value is 0 if not used. ) + @param pEventData + Pointer to additional event-specific data (see spec for meaning). + */ + + OMX_ERRORTYPE (*EventHandler)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_EVENTTYPE eEvent, + OMX_IN OMX_U32 nData1, + OMX_IN OMX_U32 nData2, + OMX_IN OMX_PTR pEventData); + + /** The EmptyBufferDone method is used to return emptied buffers from an + input port back to the application for reuse. This is a blocking call + so the application should not attempt to refill the buffers during this + call, but should queue them and refill them in another thread. There + is no error return, so the application shall handle any errors generated + internally. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was emptied. + @ingroup buf + */ + OMX_ERRORTYPE (*EmptyBufferDone)( + OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); + + /** The FillBufferDone method is used to return filled buffers from an + output port back to the application for emptying and then reuse. + This is a blocking call so the application should not attempt to + empty the buffers during this call, but should queue the buffers + and empty them in another thread. There is no error return, so + the application shall handle any errors generated internally. The + application shall also update the buffer header to indicate the + number of bytes placed into the buffer. + + The application should return from this call within 5 msec. + + @param hComponent + handle of the component to access. This is the component + handle returned by the call to the GetHandle function. + @param pAppData + pointer to an application defined value that was provided in the + pAppData parameter to the OMX_GetHandle method for the component. + This application defined value is provided so that the application + can have a component specific context when receiving the callback. + @param pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer indicating the buffer that was filled. + @ingroup buf + */ + OMX_ERRORTYPE (*FillBufferDone)( + OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); + +} OMX_CALLBACKTYPE; + +/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier + preference when tunneling between two ports. + @ingroup tun buf +*/ +typedef enum OMX_BUFFERSUPPLIERTYPE +{ + OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified, + or don't care */ + OMX_BufferSupplyInput, /**< input port supplies the buffers */ + OMX_BufferSupplyOutput, /**< output port supplies the buffers */ + OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_BufferSupplyMax = 0x7FFFFFFF +} OMX_BUFFERSUPPLIERTYPE; + + +/** buffer supplier parameter + * @ingroup tun + */ +typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */ +} OMX_PARAM_BUFFERSUPPLIERTYPE; + + +/**< indicates that buffers received by an input port of a tunnel + may not modify the data in the buffers + @ingroup tun + */ +#define OMX_PORTTUNNELFLAG_READONLY 0x00000001 + + +/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output + port to an input port as part the two ComponentTunnelRequest calls + resulting from a OMX_SetupTunnel call from the IL Client. + @ingroup tun + */ +typedef struct OMX_TUNNELSETUPTYPE +{ + OMX_U32 nTunnelFlags; /**< bit flags for tunneling */ + OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */ +} OMX_TUNNELSETUPTYPE; + +/* OMX Component headers is included to enable the core to use + macros for functions into the component for OMX release 1.0. + Developers should not access any structures or data from within + the component header directly */ +/* TO BE REMOVED - #include */ + +/** GetComponentVersion will return information about the component. + This is a blocking call. This macro will go directly from the + application to the component (via a core macro). The + component will return from this call within 5 msec. + @param [in] hComponent + handle of component to execute the command + @param [out] pComponentName + pointer to an empty string of length 128 bytes. The component + will write its name into this string. The name will be + terminated by a single zero byte. The name of a component will + be 127 bytes or less to leave room for the trailing zero byte. + An example of a valid component name is "OMX.ABC.ChannelMixer\0". + @param [out] pComponentVersion + pointer to an OMX Version structure that the component will fill + in. The component will fill in a value that indicates the + component version. NOTE: the component version is NOT the same + as the OMX Specification version (found in all structures). The + component version is defined by the vendor of the component and + its value is entirely up to the component vendor. + @param [out] pSpecVersion + pointer to an OMX Version structure that the component will fill + in. The SpecVersion is the version of the specification that the + component was built against. Please note that this value may or + may not match the structure's version. For example, if the + component was built against the 2.0 specification, but the + application (which creates the structure is built against the + 1.0 specification the versions would be different. + @param [out] pComponentUUID + pointer to the UUID of the component which will be filled in by + the component. The UUID is a unique identifier that is set at + RUN time for the component and is unique to each instantion of + the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \ + hComponent, \ + pComponentName, \ + pComponentVersion, \ + pSpecVersion, \ + pComponentUUID) /* Macro End */ + + +/** Send a command to the component. This call is a non-blocking call. + The component should check the parameters and then queue the command + to the component thread to be executed. The component thread shall + send the EventHandler() callback at the conclusion of the command. + This macro will go directly from the application to the component (via + a core macro). The component will return from this call within 5 msec. + + When the command is "OMX_CommandStateSet" the component will queue a + state transition to the new state idenfied in nParam. + + When the command is "OMX_CommandFlush", to flush a port's buffer queues, + the command will force the component to return all buffers NOT CURRENTLY + BEING PROCESSED to the application, in the order in which the buffers + were received. + + When the command is "OMX_CommandPortDisable" or + "OMX_CommandPortEnable", the component's port (given by the value of + nParam) will be stopped or restarted. + + When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the + pCmdData will point to a OMX_MARKTYPE structure containing the component + handle of the component to examine the buffer chain for the mark. nParam1 + contains the index of the port on which the buffer mark is applied. + + Specification text for more details. + + @param [in] hComponent + handle of component to execute the command + @param [in] Cmd + Command for the component to execute + @param [in] nParam + Parameter for the command to be executed. When Cmd has the value + OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has + the value OMX_CommandFlush, value of nParam indicates which port(s) + to flush. -1 is used to flush all ports a single port index will + only flush that port. When Cmd has the value "OMX_CommandPortDisable" + or "OMX_CommandPortEnable", the component's port is given by + the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer" + the components pot is given by the value of nParam. + @param [in] pCmdData + Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value + "OMX_CommandMarkBuffer". + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) \ + ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \ + hComponent, \ + Cmd, \ + nParam, \ + pCmdData) /* Macro End */ + + +/** The OMX_GetParameter macro will get one of the current parameter + settings from the component. This macro cannot only be invoked when + the component is in the OMX_StateInvalid state. The nParamIndex + parameter is used to indicate which structure is being requested from + the component. The application shall allocate the correct structure + and shall fill in the structure size and version information before + invoking this macro. When the parameter applies to a port, the + caller shall fill in the appropriate nPortIndex value indicating the + port on which the parameter applies. If the component has not had + any settings changed, then the component should return a set of + valid DEFAULT parameters for the component. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nParamIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentParameterStructure + Pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_SetParameter macro will send an initialization parameter + structure to a component. Each structure shall be sent one at a time, + in a separate invocation of the macro. This macro can only be + invoked when the component is in the OMX_StateLoaded state, or the + port is disabled (when the parameter applies to a port). The + nParamIndex parameter is used to indicate which structure is being + passed to the component. The application shall allocate the + correct structure and shall fill in the structure size and version + information (as well as the actual data) before invoking this macro. + The application is free to dispose of this structure after the call + as the component is required to copy any data it shall retain. This + is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration. + @param [in] pComponentParameterStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \ + hComponent, \ + nParamIndex, \ + pComponentParameterStructure) /* Macro End */ + + +/** The OMX_GetConfig macro will get one of the configuration structures + from a component. This macro can be invoked anytime after the + component has been loaded. The nParamIndex call parameter is used to + indicate which structure is being requested from the component. The + application shall allocate the correct structure and shall fill in the + structure size and version information before invoking this macro. + If the component has not had this configuration parameter sent before, + then the component should return a set of valid DEFAULT values for the + component. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nIndex + Index of the structure to be filled. This value is from the + OMX_INDEXTYPE enumeration. + @param [in,out] pComponentConfigStructure + pointer to application allocated structure to be filled by the + component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp +*/ +#define OMX_GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_SetConfig macro will send one of the configuration + structures to a component. Each structure shall be sent one at a time, + each in a separate invocation of the macro. This macro can be invoked + anytime after the component has been loaded. The application shall + allocate the correct structure and shall fill in the structure size + and version information (as well as the actual data) before invoking + this macro. The application is free to dispose of this structure after + the call as the component is required to copy any data it shall retain. + This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nConfigIndex + Index of the structure to be sent. This value is from the + OMX_INDEXTYPE enumeration above. + @param [in] pComponentConfigStructure + pointer to application allocated structure to be used for + initialization by the component. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) \ + ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \ + hComponent, \ + nConfigIndex, \ + pComponentConfigStructure) /* Macro End */ + + +/** The OMX_GetExtensionIndex macro will invoke a component to translate + a vendor specific configuration or parameter string into an OMX + structure index. There is no requirement for the vendor to support + this command for the indexes already found in the OMX_INDEXTYPE + enumeration (this is done to save space in small components). The + component shall support all vendor supplied extension indexes not found + in the master OMX_INDEXTYPE enumeration. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @param [in] cParameterName + OMX_STRING that shall be less than 128 characters long including + the trailing null byte. This is the string that will get + translated by the component into a configuration index. + @param [out] pIndexType + a pointer to a OMX_INDEXTYPE to receive the index value. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \ + hComponent, \ + cParameterName, \ + pIndexType) /* Macro End */ + + +/** The OMX_GetState macro will invoke the component to get the current + state of the component and place the state value into the location + pointed to by pState. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] pState + pointer to the location to receive the state. The value returned + is one of the OMX_STATETYPE members + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp + */ +#define OMX_GetState( \ + hComponent, \ + pState) \ + ((OMX_COMPONENTTYPE*)hComponent)->GetState( \ + hComponent, \ + pState) /* Macro End */ + + +/** The OMX_UseBuffer macro will request that the component use + a buffer (and allocate its own buffer header) already allocated + by another component, or by the IL Client. This is a blocking + call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ + +#define OMX_UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes, \ + pBuffer) + + +/** The OMX_AllocateBuffer macro will request that the component allocate + a new buffer and buffer header. The component will allocate the + buffer and the buffer header and return a pointer to the buffer + header. This is a blocking call. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive + the pointer to the buffer header + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] nSizeBytes + size of the buffer to allocate. Used when bAllocateNew is true. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) \ + ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \ + hComponent, \ + ppBuffer, \ + nPortIndex, \ + pAppPrivate, \ + nSizeBytes) /* Macro End */ + + +/** The OMX_FreeBuffer macro will release a buffer header from the component + which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If + the component allocated the buffer (see the OMX_UseBuffer macro) then + the component shall free the buffer and buffer header. This is a + blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \ + hComponent, \ + nPortIndex, \ + pBuffer) /* Macro End */ + + +/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an + input port of a component. The buffer will be emptied by the component + and returned to the application via the EmptyBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then empty the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_StateExecuting. If nPortIndex does not specify an input + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_EmptyThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + +/** The OMX_FillThisBuffer macro will send an empty buffer to an + output port of a component. The buffer will be filled by the component + and returned to the application via the FillBufferDone call back. + This is a non-blocking call in that the component will record the buffer + and return immediately and then fill the buffer, later, at the proper + time. As expected, this macro may be invoked only while the component + is in the OMX_ExecutingState. If nPortIndex does not specify an output + port, the component shall return an error. + + The component should return from this call within 5 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [in] pBuffer + pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer + or AllocateBuffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_FillThisBuffer( \ + hComponent, \ + pBuffer) \ + ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \ + hComponent, \ + pBuffer) /* Macro End */ + + + +/** The OMX_UseEGLImage macro will request that the component use + a EGLImage provided by EGL (and allocate its own buffer header) + This is a blocking call. + + The component should return from this call within 20 msec. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the OMX_GetHandle function. + @param [out] ppBuffer + pointer to an OMX_BUFFERHEADERTYPE structure used to receive the + pointer to the buffer header. Note that the memory location used + for this buffer is NOT visible to the IL Client. + @param [in] nPortIndex + nPortIndex is used to select the port on the component the buffer will + be used with. The port can be found by using the nPortIndex + value as an index into the Port Definition array of the component. + @param [in] pAppPrivate + pAppPrivate is used to initialize the pAppPrivate member of the + buffer header structure. + @param [in] eglImage + eglImage contains the handle of the EGLImage to use as a buffer on the + specified port. The component is expected to validate properties of + the EGLImage against the configuration of the port to ensure the component + can use the EGLImage as a buffer. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup comp buf + */ +#define OMX_UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) \ + ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \ + hComponent, \ + ppBufferHdr, \ + nPortIndex, \ + pAppPrivate, \ + eglImage) + +/** The OMX_Init method is used to initialize the OMX core. It shall be the + first call made into OMX and it should only be executed one time without + an interviening OMX_Deinit call. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void); + + +/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be + the last call made into OMX. In the event that the core determines that + thare are components loaded when this call is made, the core may return + with an error rather than try to unload the components. + + The core should return from this call within 20 msec. + + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void); + + +/** The OMX_ComponentNameEnum method will enumerate through all the names of + recognised valid components in the system. This function is provided + as a means to detect all the components in the system run-time. There is + no strict ordering to the enumeration order of component names, although + each name will only be enumerated once. If the OMX core supports run-time + installation of new components, it is only requried to detect newly + installed components when the first call to enumerate component names + is made (i.e. when nIndex is 0x0). + + The core should return from this call in 20 msec. + + @param [out] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] nNameLength + number of characters in the cComponentName string. With all + component name strings restricted to less than 128 characters + (including the trailing null) it is recomended that the caller + provide a input string for the cComponentName of 128 characters. + @param [in] nIndex + number containing the enumeration index for the component. + Multiple calls to OMX_ComponentNameEnum with increasing values + of nIndex will enumerate through the component names in the + system until OMX_ErrorNoMore is returned. The value of nIndex + is 0 to (N-1), where N is the number of valid installed components + in the system. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. When the value of nIndex exceeds the number of + components in the system minus 1, OMX_ErrorNoMore will be + returned. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum( + OMX_OUT OMX_STRING cComponentName, + OMX_IN OMX_U32 nNameLength, + OMX_IN OMX_U32 nIndex); + + +/** The OMX_GetHandle method will locate the component specified by the + component name given, load that component into memory and then invoke + the component's methods to create an instance of the component. + + The core should return from this call within 20 msec. + + @param [out] pHandle + pointer to an OMX_HANDLETYPE pointer to be filled in by this method. + @param [in] cComponentName + pointer to a null terminated string with the component name. The + names of the components are strings less than 127 bytes in length + plus the trailing null for a maximum size of 128 bytes. An example + of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are + assigned by the vendor, but shall start with "OMX." and then have + the Vendor designation next. + @param [in] pAppData + pointer to an application defined value that will be returned + during callbacks so that the application can identify the source + of the callback. + @param [in] pCallBacks + pointer to a OMX_CALLBACKTYPE structure that will be passed to the + component to initialize it with. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle( + OMX_OUT OMX_HANDLETYPE* pHandle, + OMX_IN OMX_STRING cComponentName, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_CALLBACKTYPE* pCallBacks); + + +/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle + method. If the component reference count goes to zero, the component will + be unloaded from memory. + + The core should return from this call within 20 msec when the component is + in the OMX_StateLoaded state. + + @param [in] hComponent + Handle of the component to be accessed. This is the component + handle returned by the call to the GetHandle function. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle( + OMX_IN OMX_HANDLETYPE hComponent); + + + +/** The OMX_SetupTunnel method will handle the necessary calls to the components + to setup the specified tunnel the two components. NOTE: This is + an actual method (not a #define macro). This method will make calls into + the component ComponentTunnelRequest method to do the actual tunnel + connection. + + The ComponentTunnelRequest method on both components will be called. + This method shall not be called unless the component is in the + OMX_StateLoaded state except when the ports used for the tunnel are + disabled. In this case, the component may be in the OMX_StateExecuting, + OMX_StatePause, or OMX_StateIdle states. + + The core should return from this call within 20 msec. + + @param [in] hOutput + Handle of the component to be accessed. Also this is the handle + of the component whose port, specified in the nPortOutput parameter + will be used the source for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hOutput be the source for the data when + tunelling (i.e. nPortOutput is an output port). If 0x0, the component + specified in hInput will have it's port specified in nPortInput + setup for communication with the application / IL client. + @param [in] nPortOutput + nPortOutput is used to select the source port on component to be + used in the tunnel. + @param [in] hInput + This is the component to setup the tunnel with. This is the handle + of the component whose port, specified in the nPortInput parameter + will be used the destination for the tunnel. This is the component handle + returned by the call to the OMX_GetHandle function. There is a + requirement that hInput be the destination for the data when + tunelling (i.e. nPortInut is an input port). If 0x0, the component + specified in hOutput will have it's port specified in nPortPOutput + setup for communication with the application / IL client. + @param [in] nPortInput + nPortInput is used to select the destination port on component to be + used in the tunnel. + @return OMX_ERRORTYPE + If the command successfully executes, the return code will be + OMX_ErrorNone. Otherwise the appropriate OMX error will be returned. + When OMX_ErrorNotImplemented is returned, one or both components is + a non-interop component and does not support tunneling. + + On failure, the ports of both components are setup for communication + with the application / IL Client. + @ingroup core tun + */ +OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel( + OMX_IN OMX_HANDLETYPE hOutput, + OMX_IN OMX_U32 nPortOutput, + OMX_IN OMX_HANDLETYPE hInput, + OMX_IN OMX_U32 nPortInput); + +/** @ingroup cp */ +OMX_API OMX_ERRORTYPE OMX_GetContentPipe( + OMX_OUT OMX_HANDLETYPE *hPipe, + OMX_IN OMX_STRING szURI); + +/** The OMX_GetComponentsOfRole method will return the number of components that support the given + role and (if the compNames field is non-NULL) the names of those components. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the compNames field NULL to determine the number of component names + * second call this function with the compNames field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] role + This is generic standard component name consisting only of component class + name and the type within that class (e.g. 'audio_decoder.aac'). + @param [inout] pNumComps + This is used both as input and output. + + If compNames is NULL, the input is ignored and the output specifies how many components support + the given role. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of components string names listed within the compNames parameter. + @param [inout] compNames + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts + a list of the names of all physical components that implement the specified standard component name. + Each name is NULL terminated. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole ( + OMX_IN OMX_STRING role, + OMX_INOUT OMX_U32 *pNumComps, + OMX_INOUT OMX_U8 **compNames); + +/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given + component and (if the roles field is non-NULL) the names of those roles. The call will fail if + an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the + client should: + * first call this function with the roles field NULL to determine the number of role names + * second call this function with the roles field pointing to an array of names allocated + according to the number returned by the first call. + + The core should return from this call within 5 msec. + + @param [in] compName + This is the name of the component being queried about. + @param [inout] pNumRoles + This is used both as input and output. + + If roles is NULL, the input is ignored and the output specifies how many roles the component supports. + + If compNames is not NULL, on input it bounds the size of the input structure and + on output, it specifies the number of roles string names listed within the roles parameter. + @param [out] roles + If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings + which accepts a list of the names of all standard components roles implemented on the + specified component name. numComps indicates the number of names. + @ingroup core + */ +OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent ( + OMX_IN OMX_STRING compName, + OMX_INOUT OMX_U32 *pNumRoles, + OMX_OUT OMX_U8 **roles); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_IVCommon.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_IVCommon.h new file mode 100644 index 0000000..4c4995c --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_IVCommon.h @@ -0,0 +1,920 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** + * @file OMX_IVCommon.h - OpenMax IL version 1.1.2 + * The structures needed by Video and Image components to exchange + * parameters and configuration data with the components. + */ +#ifndef OMX_IVCommon_h +#define OMX_IVCommon_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Each OMX header must include all required header files to allow the header + * to compile without errors. The includes below are required for this header + * file to compile successfully + */ + +#include + +/** @defgroup iv OpenMAX IL Imaging and Video Domain + * Common structures for OpenMAX IL Imaging and Video domains + * @{ + */ + + +/** + * Enumeration defining possible uncompressed image/video formats. + * + * ENUMS: + * Unused : Placeholder value when format is N/A + * Monochrome : black and white + * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0 + * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0 + * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0 + * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0 + * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0 + * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0 + * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0 + * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0 + * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0 + * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0 + * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0 + * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0 + * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0 + * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0 + * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally + * YUV411PackedPlanar : packed per payload in planar slices + * YUV420Planar : Three arrays Y,U,V. + * YUV420PackedPlanar : packed per payload in planar slices + * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V + * YUV422Planar : Three arrays Y,U,V. + * YUV422PackedPlanar : packed per payload in planar slices + * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V + * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr) + * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb) + * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY) + * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY) + * YUV444Interleaved : Each pixel contains equal parts YUV + * RawBayer8bit : SMIA camera output format + * RawBayer10bit : SMIA camera output format + * RawBayer8bitcompressed : SMIA camera output format + */ +typedef enum OMX_COLOR_FORMATTYPE { + OMX_COLOR_FormatUnused, + OMX_COLOR_FormatMonochrome, + OMX_COLOR_Format8bitRGB332, + OMX_COLOR_Format12bitRGB444, + OMX_COLOR_Format16bitARGB4444, + OMX_COLOR_Format16bitARGB1555, + OMX_COLOR_Format16bitRGB565, + OMX_COLOR_Format16bitBGR565, + OMX_COLOR_Format18bitRGB666, + OMX_COLOR_Format18bitARGB1665, + OMX_COLOR_Format19bitARGB1666, + OMX_COLOR_Format24bitRGB888, + OMX_COLOR_Format24bitBGR888, + OMX_COLOR_Format24bitARGB1887, + OMX_COLOR_Format25bitARGB1888, + OMX_COLOR_Format32bitBGRA8888, + OMX_COLOR_Format32bitARGB8888, + OMX_COLOR_FormatYUV411Planar, + OMX_COLOR_FormatYUV411PackedPlanar, + OMX_COLOR_FormatYUV420Planar, + OMX_COLOR_FormatYUV420PackedPlanar, + OMX_COLOR_FormatYUV420SemiPlanar, + OMX_COLOR_FormatYUV422Planar, + OMX_COLOR_FormatYUV422PackedPlanar, + OMX_COLOR_FormatYUV422SemiPlanar, + OMX_COLOR_FormatYCbYCr, + OMX_COLOR_FormatYCrYCb, + OMX_COLOR_FormatCbYCrY, + OMX_COLOR_FormatCrYCbY, + OMX_COLOR_FormatYUV444Interleaved, + OMX_COLOR_FormatRawBayer8bit, + OMX_COLOR_FormatRawBayer10bit, + OMX_COLOR_FormatRawBayer8bitcompressed, + OMX_COLOR_FormatL2, + OMX_COLOR_FormatL4, + OMX_COLOR_FormatL8, + OMX_COLOR_FormatL16, + OMX_COLOR_FormatL24, + OMX_COLOR_FormatL32, + OMX_COLOR_FormatYUV420PackedSemiPlanar, + OMX_COLOR_FormatYUV422PackedSemiPlanar, + OMX_COLOR_Format18BitBGR666, + OMX_COLOR_Format24BitARGB6666, + OMX_COLOR_Format24BitABGR6666, + OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_COLOR_FormatMax = 0x7FFFFFFF +} OMX_COLOR_FORMATTYPE; + + +/** + * Defines the matrix for conversion from RGB to YUV or vice versa. + * iColorMatrix should be initialized with the fixed point values + * used in converting between formats. + */ +typedef struct OMX_CONFIG_COLORCONVERSIONTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */ + OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */ +}OMX_CONFIG_COLORCONVERSIONTYPE; + + +/** + * Structure defining percent to scale each frame dimension. For example: + * To make the width 50% larger, use fWidth = 1.5 and to make the width + * 1/2 the original size, use fWidth = 0.5 + */ +typedef struct OMX_CONFIG_SCALEFACTORTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version info */ + OMX_U32 nPortIndex; /**< Port that this struct applies to */ + OMX_S32 xWidth; /**< Fixed point value stored as Q16 */ + OMX_S32 xHeight; /**< Fixed point value stored as Q16 */ +}OMX_CONFIG_SCALEFACTORTYPE; + + +/** + * Enumeration of possible image filter types + */ +typedef enum OMX_IMAGEFILTERTYPE { + OMX_ImageFilterNone, + OMX_ImageFilterNoise, + OMX_ImageFilterEmboss, + OMX_ImageFilterNegative, + OMX_ImageFilterSketch, + OMX_ImageFilterOilPaint, + OMX_ImageFilterHatch, + OMX_ImageFilterGpen, + OMX_ImageFilterAntialias, + OMX_ImageFilterDeRing, + OMX_ImageFilterSolarize, + OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ImageFilterMax = 0x7FFFFFFF +} OMX_IMAGEFILTERTYPE; + + +/** + * Image filter configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eImageFilter : Image filter type enumeration + */ +typedef struct OMX_CONFIG_IMAGEFILTERTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGEFILTERTYPE eImageFilter; +} OMX_CONFIG_IMAGEFILTERTYPE; + + +/** + * Customized U and V for color enhancement + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bColorEnhancement : Enable/disable color enhancement + * nCustomizedU : Practical values: 16-240, range: 0-255, value set for + * U component + * nCustomizedV : Practical values: 16-240, range: 0-255, value set for + * V component + */ +typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bColorEnhancement; + OMX_U8 nCustomizedU; + OMX_U8 nCustomizedV; +} OMX_CONFIG_COLORENHANCEMENTTYPE; + + +/** + * Define color key and color key mask + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nARGBColor : 32bit Alpha, Red, Green, Blue Color + * nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels + */ +typedef struct OMX_CONFIG_COLORKEYTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nARGBColor; + OMX_U32 nARGBMask; +} OMX_CONFIG_COLORKEYTYPE; + + +/** + * List of color blend types for pre/post processing + * + * ENUMS: + * None : No color blending present + * AlphaConstant : Function is (alpha_constant * src) + + * (1 - alpha_constant) * dst) + * AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst) + * Alternate : Function is alternating pixels from src and dst + * And : Function is (src & dst) + * Or : Function is (src | dst) + * Invert : Function is ~src + */ +typedef enum OMX_COLORBLENDTYPE { + OMX_ColorBlendNone, + OMX_ColorBlendAlphaConstant, + OMX_ColorBlendAlphaPerPixel, + OMX_ColorBlendAlternate, + OMX_ColorBlendAnd, + OMX_ColorBlendOr, + OMX_ColorBlendInvert, + OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ColorBlendMax = 0x7FFFFFFF +} OMX_COLORBLENDTYPE; + + +/** + * Color blend configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nRGBAlphaConstant : Constant global alpha values when global alpha is used + * eColorBlend : Color blend type enumeration + */ +typedef struct OMX_CONFIG_COLORBLENDTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nRGBAlphaConstant; + OMX_COLORBLENDTYPE eColorBlend; +} OMX_CONFIG_COLORBLENDTYPE; + + +/** + * Hold frame dimension + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nWidth : Frame width in pixels + * nHeight : Frame height in pixels + */ +typedef struct OMX_FRAMESIZETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nWidth; + OMX_U32 nHeight; +} OMX_FRAMESIZETYPE; + + +/** + * Rotation configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nRotation : +/- integer rotation value + */ +typedef struct OMX_CONFIG_ROTATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nRotation; +} OMX_CONFIG_ROTATIONTYPE; + + +/** + * Possible mirroring directions for pre/post processing + * + * ENUMS: + * None : No mirroring + * Vertical : Vertical mirroring, flip on X axis + * Horizontal : Horizontal mirroring, flip on Y axis + * Both : Both vertical and horizontal mirroring + */ +typedef enum OMX_MIRRORTYPE { + OMX_MirrorNone = 0, + OMX_MirrorVertical, + OMX_MirrorHorizontal, + OMX_MirrorBoth, + OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_MirrorMax = 0x7FFFFFFF +} OMX_MIRRORTYPE; + + +/** + * Mirroring configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eMirror : Mirror type enumeration + */ +typedef struct OMX_CONFIG_MIRRORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_MIRRORTYPE eMirror; +} OMX_CONFIG_MIRRORTYPE; + + +/** + * Position information only + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nX : X coordinate for the point + * nY : Y coordinate for the point + */ +typedef struct OMX_CONFIG_POINTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nX; + OMX_S32 nY; +} OMX_CONFIG_POINTTYPE; + + +/** + * Frame size plus position + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nLeft : X Coordinate of the top left corner of the rectangle + * nTop : Y Coordinate of the top left corner of the rectangle + * nWidth : Width of the rectangle + * nHeight : Height of the rectangle + */ +typedef struct OMX_CONFIG_RECTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nLeft; + OMX_S32 nTop; + OMX_U32 nWidth; + OMX_U32 nHeight; +} OMX_CONFIG_RECTTYPE; + + +/** + * Deblocking state; it is required to be set up before starting the codec + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bDeblocking : Enable/disable deblocking mode + */ +typedef struct OMX_PARAM_DEBLOCKINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bDeblocking; +} OMX_PARAM_DEBLOCKINGTYPE; + + +/** + * Stabilization state + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bStab : Enable/disable frame stabilization state + */ +typedef struct OMX_CONFIG_FRAMESTABTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bStab; +} OMX_CONFIG_FRAMESTABTYPE; + + +/** + * White Balance control type + * + * STRUCT MEMBERS: + * SunLight : Referenced in JSR-234 + * Flash : Optimal for device's integrated flash + */ +typedef enum OMX_WHITEBALCONTROLTYPE { + OMX_WhiteBalControlOff = 0, + OMX_WhiteBalControlAuto, + OMX_WhiteBalControlSunLight, + OMX_WhiteBalControlCloudy, + OMX_WhiteBalControlShade, + OMX_WhiteBalControlTungsten, + OMX_WhiteBalControlFluorescent, + OMX_WhiteBalControlIncandescent, + OMX_WhiteBalControlFlash, + OMX_WhiteBalControlHorizon, + OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_WhiteBalControlMax = 0x7FFFFFFF +} OMX_WHITEBALCONTROLTYPE; + + +/** + * White Balance control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eWhiteBalControl : White balance enumeration + */ +typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_WHITEBALCONTROLTYPE eWhiteBalControl; +} OMX_CONFIG_WHITEBALCONTROLTYPE; + + +/** + * Exposure control type + */ +typedef enum OMX_EXPOSURECONTROLTYPE { + OMX_ExposureControlOff = 0, + OMX_ExposureControlAuto, + OMX_ExposureControlNight, + OMX_ExposureControlBackLight, + OMX_ExposureControlSpotLight, + OMX_ExposureControlSports, + OMX_ExposureControlSnow, + OMX_ExposureControlBeach, + OMX_ExposureControlLargeAperture, + OMX_ExposureControlSmallApperture, + OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_ExposureControlMax = 0x7FFFFFFF +} OMX_EXPOSURECONTROLTYPE; + + +/** + * White Balance control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eExposureControl : Exposure control enumeration + */ +typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_EXPOSURECONTROLTYPE eExposureControl; +} OMX_CONFIG_EXPOSURECONTROLTYPE; + + +/** + * Defines sensor supported mode. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nFrameRate : Single shot mode is indicated by a 0 + * bOneShot : Enable for single shot, disable for streaming + * sFrameSize : Framesize + */ +typedef struct OMX_PARAM_SENSORMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nFrameRate; + OMX_BOOL bOneShot; + OMX_FRAMESIZETYPE sFrameSize; +} OMX_PARAM_SENSORMODETYPE; + + +/** + * Defines contrast level + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nContrast : Values allowed for contrast -100 to 100, zero means no change + */ +typedef struct OMX_CONFIG_CONTRASTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nContrast; +} OMX_CONFIG_CONTRASTTYPE; + + +/** + * Defines brightness level + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nBrightness : 0-100% + */ +typedef struct OMX_CONFIG_BRIGHTNESSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBrightness; +} OMX_CONFIG_BRIGHTNESSTYPE; + + +/** + * Defines backlight level configuration for a video sink, e.g. LCD panel + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nBacklight : Values allowed for backlight 0-100% + * nTimeout : Number of milliseconds before backlight automatically turns + * off. A value of 0x0 disables backight timeout + */ +typedef struct OMX_CONFIG_BACKLIGHTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nBacklight; + OMX_U32 nTimeout; +} OMX_CONFIG_BACKLIGHTTYPE; + + +/** + * Defines setting for Gamma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nGamma : Values allowed for gamma -100 to 100, zero means no change + */ +typedef struct OMX_CONFIG_GAMMATYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nGamma; +} OMX_CONFIG_GAMMATYPE; + + +/** + * Define for setting saturation + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSaturation : Values allowed for saturation -100 to 100, zero means + * no change + */ +typedef struct OMX_CONFIG_SATURATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nSaturation; +} OMX_CONFIG_SATURATIONTYPE; + + +/** + * Define for setting Lightness + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nLightness : Values allowed for lightness -100 to 100, zero means no + * change + */ +typedef struct OMX_CONFIG_LIGHTNESSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_S32 nLightness; +} OMX_CONFIG_LIGHTNESSTYPE; + + +/** + * Plane blend configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Index of input port associated with the plane. + * nDepth : Depth of the plane in relation to the screen. Higher + * numbered depths are "behind" lower number depths. + * This number defaults to the Port Index number. + * nAlpha : Transparency blending component for the entire plane. + * See blending modes for more detail. + */ +typedef struct OMX_CONFIG_PLANEBLENDTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nDepth; + OMX_U32 nAlpha; +} OMX_CONFIG_PLANEBLENDTYPE; + + +/** + * Define interlace type + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnable : Enable control variable for this functionality + * (see below) + * nInterleavePortIndex : Index of input or output port associated with + * the interleaved plane. + * pPlanarPortIndexes[4] : Index of input or output planar ports. + */ +typedef struct OMX_PARAM_INTERLEAVETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnable; + OMX_U32 nInterleavePortIndex; +} OMX_PARAM_INTERLEAVETYPE; + + +/** + * Defines the picture effect used for an input picture + */ +typedef enum OMX_TRANSITIONEFFECTTYPE { + OMX_EffectNone, + OMX_EffectFadeFromBlack, + OMX_EffectFadeToBlack, + OMX_EffectUnspecifiedThroughConstantColor, + OMX_EffectDissolve, + OMX_EffectWipe, + OMX_EffectUnspecifiedMixOfTwoScenes, + OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EffectMax = 0x7FFFFFFF +} OMX_TRANSITIONEFFECTTYPE; + + +/** + * Structure used to configure current transition effect + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eEffect : Effect to enable + */ +typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_TRANSITIONEFFECTTYPE eEffect; +} OMX_CONFIG_TRANSITIONEFFECTTYPE; + + +/** + * Defines possible data unit types for encoded video data. The data unit + * types are used both for encoded video input for playback as well as + * encoded video output from recording. + */ +typedef enum OMX_DATAUNITTYPE { + OMX_DataUnitCodedPicture, + OMX_DataUnitVideoSegment, + OMX_DataUnitSeveralSegments, + OMX_DataUnitArbitraryStreamSection, + OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DataUnitMax = 0x7FFFFFFF +} OMX_DATAUNITTYPE; + + +/** + * Defines possible encapsulation types for coded video data unit. The + * encapsulation information is used both for encoded video input for + * playback as well as encoded video output from recording. + */ +typedef enum OMX_DATAUNITENCAPSULATIONTYPE { + OMX_DataEncapsulationElementaryStream, + OMX_DataEncapsulationGenericPayload, + OMX_DataEncapsulationRtpPayload, + OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DataEncapsulationMax = 0x7FFFFFFF +} OMX_DATAUNITENCAPSULATIONTYPE; + + +/** + * Structure used to configure the type of being decoded/encoded + */ +typedef struct OMX_PARAM_DATAUNITTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_DATAUNITTYPE eUnitType; + OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType; +} OMX_PARAM_DATAUNITTYPE; + + +/** + * Defines dither types + */ +typedef enum OMX_DITHERTYPE { + OMX_DitherNone, + OMX_DitherOrdered, + OMX_DitherErrorDiffusion, + OMX_DitherOther, + OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_DitherMax = 0x7FFFFFFF +} OMX_DITHERTYPE; + + +/** + * Structure used to configure current type of dithering + */ +typedef struct OMX_CONFIG_DITHERTYPE { + OMX_U32 nSize; /**< Size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_DITHERTYPE eDither; /**< Type of dithering to use */ +} OMX_CONFIG_DITHERTYPE; + +typedef struct OMX_CONFIG_CAPTUREMODETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; /**< Port that this structure applies to */ + OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture + * data as fast as possible (otherwise obey port's frame rate). */ + OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the + * specified number of frames (otherwise the port does not + * terminate the capture until instructed to do so by the client). + * Even if set, the client may manually terminate the capture prior + * to reaching the limit. */ + OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only + * valid if bFrameLimited is set). */ +} OMX_CONFIG_CAPTUREMODETYPE; + +typedef enum OMX_METERINGTYPE { + + OMX_MeteringModeAverage, /**< Center-weighted average metering. */ + OMX_MeteringModeSpot, /**< Spot (partial) metering. */ + OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */ + + OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_EVModeMax = 0x7fffffff +} OMX_METERINGTYPE; + +typedef struct OMX_CONFIG_EXPOSUREVALUETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_METERINGTYPE eMetering; + OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */ + OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */ + OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */ + OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */ + OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */ + OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */ + OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */ +} OMX_CONFIG_EXPOSUREVALUETYPE; + +/** + * Focus region configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bCenter : Use center region as focus region of interest + * bLeft : Use left region as focus region of interest + * bRight : Use right region as focus region of interest + * bTop : Use top region as focus region of interest + * bBottom : Use bottom region as focus region of interest + * bTopLeft : Use top left region as focus region of interest + * bTopRight : Use top right region as focus region of interest + * bBottomLeft : Use bottom left region as focus region of interest + * bBottomRight : Use bottom right region as focus region of interest + */ +typedef struct OMX_CONFIG_FOCUSREGIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bCenter; + OMX_BOOL bLeft; + OMX_BOOL bRight; + OMX_BOOL bTop; + OMX_BOOL bBottom; + OMX_BOOL bTopLeft; + OMX_BOOL bTopRight; + OMX_BOOL bBottomLeft; + OMX_BOOL bBottomRight; +} OMX_CONFIG_FOCUSREGIONTYPE; + +/** + * Focus Status type + */ +typedef enum OMX_FOCUSSTATUSTYPE { + OMX_FocusStatusOff = 0, + OMX_FocusStatusRequest, + OMX_FocusStatusReached, + OMX_FocusStatusUnableToReach, + OMX_FocusStatusLost, + OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_FocusStatusMax = 0x7FFFFFFF +} OMX_FOCUSSTATUSTYPE; + +/** + * Focus status configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusStatus : Specifies the focus status + * bCenterStatus : Use center region as focus region of interest + * bLeftStatus : Use left region as focus region of interest + * bRightStatus : Use right region as focus region of interest + * bTopStatus : Use top region as focus region of interest + * bBottomStatus : Use bottom region as focus region of interest + * bTopLeftStatus : Use top left region as focus region of interest + * bTopRightStatus : Use top right region as focus region of interest + * bBottomLeftStatus : Use bottom left region as focus region of interest + * bBottomRightStatus : Use bottom right region as focus region of interest + */ +typedef struct OMX_PARAM_FOCUSSTATUSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_FOCUSSTATUSTYPE eFocusStatus; + OMX_BOOL bCenterStatus; + OMX_BOOL bLeftStatus; + OMX_BOOL bRightStatus; + OMX_BOOL bTopStatus; + OMX_BOOL bBottomStatus; + OMX_BOOL bTopLeftStatus; + OMX_BOOL bTopRightStatus; + OMX_BOOL bBottomLeftStatus; + OMX_BOOL bBottomRightStatus; +} OMX_PARAM_FOCUSSTATUSTYPE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Image.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Image.h new file mode 100644 index 0000000..a6d4666 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Image.h @@ -0,0 +1,328 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/** + * @file OMX_Image.h - OpenMax IL version 1.1.2 + * The structures needed by Image components to exchange parameters and + * configuration data with the components. + */ +#ifndef OMX_Image_h +#define OMX_Image_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + +/** @defgroup imaging OpenMAX IL Imaging Domain + * @ingroup iv + * Structures for OpenMAX IL Imaging domain + * @{ + */ + +/** + * Enumeration used to define the possible image compression coding. + */ +typedef enum OMX_IMAGE_CODINGTYPE { + OMX_IMAGE_CodingUnused, /**< Value when format is N/A */ + OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */ + OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */ + OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */ + OMX_IMAGE_CodingEXIF, /**< EXIF image format */ + OMX_IMAGE_CodingTIFF, /**< TIFF image format */ + OMX_IMAGE_CodingGIF, /**< Graphics image format */ + OMX_IMAGE_CodingPNG, /**< PNG image format */ + OMX_IMAGE_CodingLZW, /**< LZW image format */ + OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */ + OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_CodingMax = 0x7FFFFFFF +} OMX_IMAGE_CODINGTYPE; + + +/** + * Data structure used to define an image path. The number of image paths + * for input and output will vary by type of the image component. + * + * Input (aka Source) : Zero Inputs, one Output, + * Splitter : One Input, 2 or more Outputs, + * Processing Element : One Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : One Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output + * image path. If additional vendor specific data is required, it should + * be transmitted to the component using the CustomCommand function. + * Compliant components will prepopulate this structure with optimal + * values during the OMX_GetParameter() command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nFrameHeight : Height of frame to be used on port if + * uncompressed format is used. Use 0 for + * unknown, don't care or variable + * nStride : Number of bytes per span of an image (i.e. + * indicates the number of bytes to get from + * span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of + * the component. When OMX_IMAGE_CodingUnused is + * specified, eColorFormat is valid + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_IMAGE_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_BOOL bFlagErrorConcealment; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_IMAGE_PORTDEFINITIONTYPE; + + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_IMAGE_CodingUnused is specified, + * eColorFormat is valid + * eColorFormat : Decompressed format used by this component + */ +typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_IMAGE_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; +} OMX_IMAGE_PARAM_PORTFORMATTYPE; + + +/** + * Flash control type + * + * ENUMS + * Torch : Flash forced constantly on + */ +typedef enum OMX_IMAGE_FLASHCONTROLTYPE { + OMX_IMAGE_FlashControlOn = 0, + OMX_IMAGE_FlashControlOff, + OMX_IMAGE_FlashControlAuto, + OMX_IMAGE_FlashControlRedEyeReduction, + OMX_IMAGE_FlashControlFillin, + OMX_IMAGE_FlashControlTorch, + OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FlashControlMax = 0x7FFFFFFF +} OMX_IMAGE_FLASHCONTROLTYPE; + + +/** + * Flash control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFlashControl : Flash control type + */ +typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FLASHCONTROLTYPE eFlashControl; +} OMX_IMAGE_PARAM_FLASHCONTROLTYPE; + + +/** + * Focus control type + */ +typedef enum OMX_IMAGE_FOCUSCONTROLTYPE { + OMX_IMAGE_FocusControlOn = 0, + OMX_IMAGE_FocusControlOff, + OMX_IMAGE_FocusControlAuto, + OMX_IMAGE_FocusControlAutoLock, + OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_FocusControlMax = 0x7FFFFFFF +} OMX_IMAGE_FOCUSCONTROLTYPE; + + +/** + * Focus control configuration + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFocusControl : Focus control + * nFocusSteps : Focus can take on values from 0 mm to infinity. + * Interest is only in number of steps over this range. + * nFocusStepIndex : Current focus step index + */ +typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl; + OMX_U32 nFocusSteps; + OMX_U32 nFocusStepIndex; +} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE; + + +/** + * Q Factor for JPEG compression, which controls the tradeoff between image + * quality and size. Q Factor provides a more simple means of controlling + * JPEG compression quality, without directly programming Quantization + * tables for chroma and luma + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1 + * produces the smallest, worst quality images, and a factor + * of 100 produces the largest, best quality images. A + * typical default is 75 for small good quality images + */ +typedef struct OMX_IMAGE_PARAM_QFACTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQFactor; +} OMX_IMAGE_PARAM_QFACTORTYPE; + +/** + * Quantization table type + */ + +typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE { + OMX_IMAGE_QuantizationTableLuma = 0, + OMX_IMAGE_QuantizationTableChroma, + OMX_IMAGE_QuantizationTableChromaCb, + OMX_IMAGE_QuantizationTableChromaCr, + OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF +} OMX_IMAGE_QUANTIZATIONTABLETYPE; + +/** + * JPEG quantization tables are used to determine DCT compression for + * YUV data, as an alternative to specifying Q factor, providing exact + * control of compression + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eQuantizationTable : Quantization table type + * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored + * in increasing columns then by rows of data (i.e. + * row 1, ... row 8). Quantization values are in + * the range 0-255 and stored in linear order + * (i.e. the component will zig-zag the + * quantization table data if required internally) + */ +typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable; + OMX_U8 nQuantizationMatrix[64]; +} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE; + + +/** + * Huffman table type, the same Huffman table is applied for chroma and + * luma component + */ +typedef enum OMX_IMAGE_HUFFMANTABLETYPE { + OMX_IMAGE_HuffmanTableAC = 0, + OMX_IMAGE_HuffmanTableDC, + OMX_IMAGE_HuffmanTableACLuma, + OMX_IMAGE_HuffmanTableACChroma, + OMX_IMAGE_HuffmanTableDCLuma, + OMX_IMAGE_HuffmanTableDCChroma, + OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF +} OMX_IMAGE_HUFFMANTABLETYPE; + +/** + * JPEG Huffman table + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eHuffmanTable : Huffman table type + * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each + * possible length + * nHuffmanTable[256] : 0-255, the size used for AC and DC + * HuffmanTable are 16 and 162 + */ +typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable; + OMX_U8 nNumberOfHuffmanCodeOfLength[16]; + OMX_U8 nHuffmanTable[256]; +}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE; + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Index.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Index.h new file mode 100644 index 0000000..44d4ea7 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Index.h @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** @file OMX_Index.h - OpenMax IL version 1.1.2 + * The OMX_Index header file contains the definitions for both applications + * and components . + */ + + +#ifndef OMX_Index_h +#define OMX_Index_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ +#include + + +/** The OMX_INDEXTYPE enumeration is used to select a structure when either + * getting or setting parameters and/or configuration data. Each entry in + * this enumeration maps to an OMX specified structure. When the + * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods + * are used, the second parameter will always be an entry from this enumeration + * and the third entry will be the structure shown in the comments for the entry. + * For example, if the application is initializing a cropping function, the + * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter + * and would send a pointer to an initialized OMX_RECTTYPE structure as the + * third parameter. + * + * The enumeration entries named with the OMX_Config prefix are sent using + * the OMX_SetConfig command and the enumeration entries named with the + * OMX_PARAM_ prefix are sent using the OMX_SetParameter command. + */ +typedef enum OMX_INDEXTYPE { + + OMX_IndexComponentStartUnused = 0x01000000, + OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */ + OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */ + OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */ + OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */ + OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */ + OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */ + OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */ + OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */ + OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */ + OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */ + OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */ + OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */ + OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */ + OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */ + OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */ + OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */ + + OMX_IndexPortStartUnused = 0x02000000, + OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */ + OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */ + OMX_IndexReservedStartUnused = 0x03000000, + + /* Audio parameters and configurations */ + OMX_IndexAudioStartUnused = 0x04000000, + OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */ + OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */ + OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */ + OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */ + OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */ + OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */ + OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */ + OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */ + OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */ + OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */ + OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */ + OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */ + OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */ + OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */ + OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */ + OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */ + OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */ + OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */ + OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */ + OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */ + OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */ + OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */ + OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */ + OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */ + OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */ + OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */ + + OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */ + OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */ + OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */ + OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */ + OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */ + OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */ + OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */ + OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */ + OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */ + OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */ + OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */ + OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */ + OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */ + OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */ + OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */ + OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */ + OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */ + OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */ + OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */ + OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */ + + /* Image specific parameters and configurations */ + OMX_IndexImageStartUnused = 0x05000000, + OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */ + OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */ + OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */ + OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */ + OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */ + OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */ + + /* Video specific parameters and configurations */ + OMX_IndexVideoStartUnused = 0x06000000, + OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */ + OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */ + OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */ + OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */ + OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */ + OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */ + OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */ + OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */ + OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */ + OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */ + OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */ + OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */ + OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */ + OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */ + OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */ + OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */ + OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */ + OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */ + OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */ + OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */ + OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */ + OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */ + OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */ + OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */ + + /* Image & Video common Configurations */ + OMX_IndexCommonStartUnused = 0x07000000, + OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */ + OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */ + OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */ + OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */ + OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */ + OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */ + OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */ + OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */ + OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */ + OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */ + OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */ + OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */ + OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */ + OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/ + OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */ + OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */ + OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */ + OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */ + OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */ + OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */ + OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */ + OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */ + OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */ + OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */ + OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */ + OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */ + OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */ + OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */ + OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */ + OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */ + OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */ + + /* Reserved Configuration range */ + OMX_IndexOtherStartUnused = 0x08000000, + OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */ + OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */ + OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */ + + + /* Reserved Time range */ + OMX_IndexTimeStartUnused = 0x09000000, + OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */ + OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */ + OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */ + OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */ + OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */ + OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */ + OMX_IndexConfigTimeClientStartTime, /** + + +/** + * Enumeration of possible data types which match to multiple domains or no + * domain at all. For types which are vendor specific, a value above + * OMX_OTHER_VENDORTSTART should be used. + */ +typedef enum OMX_OTHER_FORMATTYPE { + OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time, + time deltas, etc */ + OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power + management, setting clocks? */ + OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames + dropped, etc */ + OMX_OTHER_FormatBinary, /**< Arbitrary binary data */ + OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific + formats */ + + OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_OTHER_FormatMax = 0x7FFFFFFF +} OMX_OTHER_FORMATTYPE; + +/** + * Enumeration of seek modes. + */ +typedef enum OMX_TIME_SEEKMODETYPE { + OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation + * of the requested seek position over + * the actual seek position if it + * results in a faster seek. */ + OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek + * position over an approximation + * of the requested seek position even + * if it results in a slower seek. */ + OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_SeekModeMax = 0x7FFFFFFF +} OMX_TIME_SEEKMODETYPE; + +/* Structure representing the seekmode of the component */ +typedef struct OMX_TIME_CONFIG_SEEKMODETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */ +} OMX_TIME_CONFIG_SEEKMODETYPE; + +/** Structure representing a time stamp used with the following configs + * on the Clock Component (CC): + * + * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall + * time + * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media + * time + * OMX_IndexConfigTimeCurrentAudioReference and + * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference + * clock sending SC its reference time + * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends + * this structure to the Clock Component via a SetConfig on its + * client port when it receives a buffer with + * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp + * specified by that buffer for nStartTimestamp. + * + * It’s also used with the following config on components in general: + * + * OMX_IndexConfigTimePosition: IL client querying component position + * (GetConfig) or commanding a component to seek to the given location + * (SetConfig) + */ +typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_TICKS nTimestamp; /**< timestamp .*/ +} OMX_TIME_CONFIG_TIMESTAMPTYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_UPDATETYPE { + OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */ + OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */ + OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */ + OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_UpdateMax = 0x7FFFFFFF +} OMX_TIME_UPDATETYPE; + +/** Enumeration of possible reference clocks to the media time. */ +typedef enum OMX_TIME_REFCLOCKTYPE { + OMX_TIME_RefClockNone, /**< Use no references. */ + OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */ + OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */ + OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_RefClockMax = 0x7FFFFFFF +} OMX_TIME_REFCLOCKTYPE; + +/** Enumeration of clock states. */ +typedef enum OMX_TIME_CLOCKSTATE { + OMX_TIME_ClockStateRunning, /**< Clock running. */ + OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the + * prescribed clients emit their + * start time. */ + OMX_TIME_ClockStateStopped, /**< Clock stopped. */ + OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_TIME_ClockStateMax = 0x7FFFFFFF +} OMX_TIME_CLOCKSTATE; + +/** Structure representing a media time request to the clock component. + * + * A client component sends this structure to the Clock Component via a SetConfig + * on its client port to specify a media timestamp the Clock Component + * should emit. The Clock Component should fulfill the request by sending a + * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested + * timestamp. + * + * The client may require a media time request be fulfilled slightly + * earlier than the media time specified. In this case the client specifies + * an offset which is equal to the difference between wall time corresponding + * to the requested media time and the wall time when it will be + * fulfilled. + * + * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to + * time events according to timestamps. If a client must perform an operation O at + * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a + * media time request at T (perhaps specifying an offset to ensure the request fulfillment + * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE + * structure back to the client component, the client may perform operation O (perhaps having + * to wait a slight amount more time itself as specified by the return values). + */ + +typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< port that this structure applies to */ + OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time + * from others (e.g. the number of the frame to deliver). + * Duplicated in the media time structure that fulfills + * this request. A value of zero is reserved for time scale + * updates. */ + OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request should be fulfilled early */ +} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE; + +/**< Structure sent from the clock component client either when fulfilling + * a media time request or when the time scale has changed. + * + * In the former case the Clock Component fills this structure and times its emission + * to a client component (via the client port) according to the corresponding media + * time request sent by the client. The Clock Component should time the emission to occur + * when the requested timestamp matches the Clock Component's media time but also the + * prescribed offset early. + * + * Upon scale changes the clock component clears the nClientPrivate data, sends the current + * media time and sets the nScale to the new scale via the client port. It emits a + * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to + * alter processing to accomodate scaling. For instance a video component might skip inter-frames + * in the case of extreme fastforward. Likewise an audio component might add or remove samples + * from an audio frame to scale audio data. + * + * It is expected that some clock components may not be able to fulfill requests + * at exactly the prescribed time. This is acceptable so long as the request is + * fulfilled at least as early as described and not later. This structure provides + * fields the client may use to wait for the remaining time. + * + * The client may use either the nOffset or nWallTimeAtMedia fields to determine the + * wall time until the nMediaTimestamp actually occurs. In the latter case the + * client can get a more accurate value for offset by getting the current wall + * from the cloc component and subtracting it from nWallTimeAtMedia. + */ + +typedef struct OMX_TIME_MEDIATIMETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time + * from others. Copied from the media time request. + * A value of zero is reserved for time scale updates. */ + OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */ + OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was + * requested then this is the current media time. */ + OMX_TICKS nOffset; /**< Amount of wall clock time by which this + * request was actually fulfilled early */ + + OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp. + * A client may compare this value to current + * media time obtained from the Clock Component to determine + * the wall time until the media timestamp is really + * current. */ + OMX_S32 xScale; /**< Current media time scale in Q16 format. */ + OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/ + /**< State of the media time. */ +} OMX_TIME_MEDIATIMETYPE; + +/** Structure representing the current media time scale factor. Applicable only to clock + * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via + * the clock component client ports. Upon recieving this config the clock component changes + * the rate by which the media time increases or decreases effectively implementing trick modes. + */ +typedef struct OMX_TIME_CONFIG_SCALETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_S32 xScale; /**< This is a value in Q16 format which is used for + * scaling the media time */ +} OMX_TIME_CONFIG_SCALETYPE; + +/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */ +#define OMX_CLOCKPORT0 0x00000001 +#define OMX_CLOCKPORT1 0x00000002 +#define OMX_CLOCKPORT2 0x00000004 +#define OMX_CLOCKPORT3 0x00000008 +#define OMX_CLOCKPORT4 0x00000010 +#define OMX_CLOCKPORT5 0x00000020 +#define OMX_CLOCKPORT6 0x00000040 +#define OMX_CLOCKPORT7 0x00000080 + +/** Structure representing the current mode of the media clock. + * IL Client uses this config to change or query the mode of the + * media clock of the clock component. Applicable only to clock + * component. + * + * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time + * starts immediately at the prescribed start time. If + * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores + * the given nStartTime and waits for all clients specified in the + * nWaitMask to send starttimes (via + * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts + * the media clock using the earliest start time supplied. */ +typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version + * information */ + OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */ + OMX_TICKS nStartTime; /**< Start time of the media time. */ + OMX_TICKS nOffset; /**< Time to offset the media time by + * (e.g. preroll). Media time will be + * reported to be nOffset ticks earlier. + */ + OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */ +} OMX_TIME_CONFIG_CLOCKSTATETYPE; + +/** Structure representing the reference clock currently being used to + * compute media time. IL client uses this config to change or query the + * clock component's active reference clock */ +typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */ +} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE; + +/** Descriptor for setting specifics of power type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_POWERTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_BOOL bEnablePM; /**< Flag to enable Power Management */ +} OMX_OTHER_CONFIG_POWERTYPE; + + +/** Descriptor for setting specifics of stats type. + * Note: this structure is listed for backwards compatibility. */ +typedef struct OMX_OTHER_CONFIG_STATSTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + /* what goes here */ +} OMX_OTHER_CONFIG_STATSTYPE; + + +/** + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output other + * path. + */ +typedef struct OMX_OTHER_PORTDEFINITIONTYPE { + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PORTDEFINITIONTYPE; + +/** Port format parameter. This structure is used to enumerate + * the various data input/output format supported by the port. + */ +typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; /**< size of the structure in bytes */ + OMX_VERSIONTYPE nVersion; /**< OMX specification version information */ + OMX_U32 nPortIndex; /**< Indicates which port to set */ + OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */ + OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */ +} OMX_OTHER_PARAM_PORTFORMATTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Types.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Types.h new file mode 100644 index 0000000..31be916 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Types.h @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** OMX_Types.h - OpenMax IL version 1.1.2 + * The OMX_Types header file contains the primitive type definitions used by + * the core, the application and the component. This file may need to be + * modified to be used on systems that do not have "char" set to 8 bits, + * "short" set to 16 bits and "long" set to 32 bits. + */ + +#ifndef OMX_Types_h +#define OMX_Types_h + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** The OMX_API and OMX_APIENTRY are platform specific definitions used + * to declare OMX function prototypes. They are modified to meet the + * requirements for a particular platform */ +#ifdef __SYMBIAN32__ +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# ifdef _WIN32 +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# endif +#else +# ifdef _WIN32 +# ifdef __OMX_EXPORTS +# define OMX_API __declspec(dllexport) +# else +# define OMX_API __declspec(dllimport) +# endif +# else +# ifdef __OMX_EXPORTS +# define OMX_API +# else +# define OMX_API extern +# endif +# endif +#endif + +#ifndef OMX_APIENTRY +#define OMX_APIENTRY +#endif + +/** OMX_IN is used to identify inputs to an OMX function. This designation + will also be used in the case of a pointer that points to a parameter + that is used as an output. */ +#ifndef OMX_IN +#define OMX_IN +#endif + +/** OMX_OUT is used to identify outputs from an OMX function. This + designation will also be used in the case of a pointer that points + to a parameter that is used as an input. */ +#ifndef OMX_OUT +#define OMX_OUT +#endif + + +/** OMX_INOUT is used to identify parameters that may be either inputs or + outputs from an OMX function at the same time. This designation will + also be used in the case of a pointer that points to a parameter that + is used both as an input and an output. */ +#ifndef OMX_INOUT +#define OMX_INOUT +#endif + +/** OMX_ALL is used to as a wildcard to select all entities of the same type + * when specifying the index, or referring to a object by an index. (i.e. + * use OMX_ALL to indicate all N channels). When used as a port index + * for a config or parameter this OMX_ALL denotes that the config or + * parameter applies to the entire component not just one port. */ +#define OMX_ALL 0xFFFFFFFF + +/** In the following we define groups that help building doxygen documentation */ + +/** @defgroup core OpenMAX IL core + * Functions and structure related to the OMX IL core + */ + + /** @defgroup comp OpenMAX IL component + * Functions and structure related to the OMX IL component + */ + +/** @defgroup rpm Resource and Policy Management + * Structures for resource and policy management of components + */ + +/** @defgroup buf Buffer Management + * Buffer handling functions and structures + */ + +/** @defgroup tun Tunneling + * @ingroup core comp + * Structures and functions to manage tunnels among component ports + */ + +/** @defgroup cp Content Pipes + * @ingroup core + */ + + /** @defgroup metadata Metadata handling + * + */ + +/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */ +typedef unsigned char OMX_U8; + +/** OMX_S8 is an 8 bit signed quantity that is byte aligned */ +typedef signed char OMX_S8; + +/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */ +typedef unsigned short OMX_U16; + +/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */ +typedef signed short OMX_S16; + +/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */ +typedef unsigned long OMX_U32; + +/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */ +typedef signed long OMX_S32; + + +/* Users with compilers that cannot accept the "long long" designation should + define the OMX_SKIP64BIT macro. It should be noted that this may cause + some components to fail to compile if the component was written to require + 64 bit integral types. However, these components would NOT compile anyway + since the compiler does not support the way the component was written. +*/ +#ifndef OMX_SKIP64BIT +#ifdef __SYMBIAN32__ +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#elif defined(WIN32) + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned __int64 OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed __int64 OMX_S64; + +#else /* WIN32 */ + +/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */ +typedef unsigned long long OMX_U64; + +/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */ +typedef signed long long OMX_S64; + +#endif /* WIN32 */ +#endif + + +/** The OMX_BOOL type is intended to be used to represent a true or a false + value when passing parameters to and from the OMX core and components. The + OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary. + */ +typedef enum OMX_BOOL { + OMX_FALSE = 0, + OMX_TRUE = !OMX_FALSE, + OMX_BOOL_MAX = 0x7FFFFFFF +} OMX_BOOL; + +/** The OMX_PTR type is intended to be used to pass pointers between the OMX + applications and the OMX Core and components. This is a 32 bit pointer and + is aligned on a 32 bit boundary. + */ +typedef void* OMX_PTR; + +/** The OMX_STRING type is intended to be used to pass "C" type strings between + the application and the core and component. The OMX_STRING type is a 32 + bit pointer to a zero terminated string. The pointer is word aligned and + the string is byte aligned. + */ +typedef char* OMX_STRING; + +/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as + buffers between the application and the component and core. The OMX_BYTE + type is a 32 bit pointer to a zero terminated string. The pointer is word + aligned and the string is byte aligned. + */ +typedef unsigned char* OMX_BYTE; + +/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify + at runtime. This identifier should be generated by a component in a way + that guarantees that every instance of the identifier running on the system + is unique. */ +typedef unsigned char OMX_UUIDTYPE[128]; + +/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or + an output port. This enumeration is common across all component types. + */ +typedef enum OMX_DIRTYPE +{ + OMX_DirInput, /**< Port is an input port */ + OMX_DirOutput, /**< Port is an output port */ + OMX_DirMax = 0x7FFFFFFF +} OMX_DIRTYPE; + +/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering + for numerical data (i.e. big endian, or little endian). + */ +typedef enum OMX_ENDIANTYPE +{ + OMX_EndianBig, /**< big endian */ + OMX_EndianLittle, /**< little endian */ + OMX_EndianMax = 0x7FFFFFFF +} OMX_ENDIANTYPE; + + +/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data + is signed or unsigned + */ +typedef enum OMX_NUMERICALDATATYPE +{ + OMX_NumericalDataSigned, /**< signed data */ + OMX_NumericalDataUnsigned, /**< unsigned data */ + OMX_NumercialDataMax = 0x7FFFFFFF +} OMX_NUMERICALDATATYPE; + + +/** Unsigned bounded value type */ +typedef struct OMX_BU32 { + OMX_U32 nValue; /**< actual value */ + OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BU32; + + +/** Signed bounded value type */ +typedef struct OMX_BS32 { + OMX_S32 nValue; /**< actual value */ + OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */ + OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */ +} OMX_BS32; + + +/** Structure representing some time or duration in microseconds. This structure + * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate + * negative deltas and preroll scenarios. The quantity is represented in microseconds + * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based + * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g. + * individual audio samples delivered at 192 kHz). The quantity is 64 bit to + * accommodate a large dynamic range (signed 32 bit values would allow only for plus + * or minus 35 minutes). + * + * Implementations with limited precision may convert the signed 64 bit value to + * a signed 32 bit value internally but risk loss of precision. + */ +#ifndef OMX_SKIP64BIT +typedef OMX_S64 OMX_TICKS; +#else +typedef struct OMX_TICKS +{ + OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */ + OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */ +} OMX_TICKS; +#endif +#define OMX_TICKS_PER_SECOND 1000000 + +/** Define the public interface for the OMX Handle. The core will not use + this value internally, but the application should only use this value. + */ +typedef void* OMX_HANDLETYPE; + +typedef struct OMX_MARKTYPE +{ + OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will + generate a mark event upon + processing the mark. */ + OMX_PTR pMarkData; /**< Application specific data associated with + the mark sent on a mark event to disambiguate + this mark from others. */ +} OMX_MARKTYPE; + + +/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the display + * or can be used by a audio port for native audio rendering */ +typedef void* OMX_NATIVE_DEVICETYPE; + +/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the + * platform & operating specific object used to reference the window */ +typedef void* OMX_NATIVE_WINDOWTYPE; + +/** The OMX_VERSIONTYPE union is used to specify the version for + a structure or component. For a component, the version is entirely + specified by the component vendor. Components doing the same function + from different vendors may or may not have the same version. For + structures, the version shall be set by the entity that allocates the + structure. For structures specified in the OMX 1.1 specification, the + value of the version shall be set to 1.1.0.0 in all cases. Access to the + OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or + by accessing one of the structure elements to, for example, check only + the Major revision. + */ +typedef union OMX_VERSIONTYPE +{ + struct + { + OMX_U8 nVersionMajor; /**< Major version accessor element */ + OMX_U8 nVersionMinor; /**< Minor version accessor element */ + OMX_U8 nRevision; /**< Revision version accessor element */ + OMX_U8 nStep; /**< Step version accessor element */ + } s; + OMX_U32 nVersion; /**< 32 bit value to make accessing the + version easily done in a single word + size copy/compare operation */ +} OMX_VERSIONTYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ diff --git a/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Video.h b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Video.h new file mode 100644 index 0000000..163e450 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/khronos/OMX_Video.h @@ -0,0 +1,1060 @@ +/** + * Copyright (c) 2008 The Khronos Group Inc. + * + * 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, sublicense, 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 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + +/** + * @file OMX_Video.h - OpenMax IL version 1.1.2 + * The structures is needed by Video components to exchange parameters + * and configuration data with OMX components. + */ +#ifndef OMX_Video_h +#define OMX_Video_h + +/** @defgroup video OpenMAX IL Video Domain + * @ingroup iv + * Structures for OpenMAX IL Video domain + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Each OMX header must include all required header files to allow the + * header to compile without errors. The includes below are required + * for this header file to compile successfully + */ + +#include + + +/** + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +typedef enum OMX_VIDEO_CODINGTYPE { + OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_VIDEO_CodingH263, /**< H.263 */ + OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */ + OMX_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_VIDEO_CODINGTYPE; + + +/** + * Data structure used to define a video path. The number of Video paths for + * input and output will vary by type of the Video component. + * + * Input (aka Source) : zero Inputs, one Output, + * Splitter : one Input, 2 or more Outputs, + * Processing Element : one Input, one output, + * Mixer : 2 or more inputs, one output, + * Output (aka Sink) : one Input, zero outputs. + * + * The PortDefinition structure is used to define all of the parameters + * necessary for the compliant component to setup an input or an output video + * path. If additional vendor specific data is required, it should be + * transmitted to the component using the CustomCommand function. Compliant + * components will prepopulate this structure with optimal values during the + * GetDefaultInitParams command. + * + * STRUCT MEMBERS: + * cMIMEType : MIME type of data for the port + * pNativeRender : Platform specific reference for a display if a + * sync, otherwise this field is 0 + * nFrameWidth : Width of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nFrameHeight : Height of frame to be used on channel if + * uncompressed format is used. Use 0 for unknown, + * don't care or variable + * nStride : Number of bytes per span of an image + * (i.e. indicates the number of bytes to get + * from span N to span N+1, where negative stride + * indicates the image is bottom up + * nSliceHeight : Height used when encoding in slices + * nBitrate : Bit rate of frame to be used on channel if + * compressed format is used. Use 0 for unknown, + * don't care or variable + * xFramerate : Frame rate to be used on channel if uncompressed + * format is used. Use 0 for unknown, don't care or + * variable. Units are Q16 frames per second. + * bFlagErrorConcealment : Turns on error concealment if it is supported by + * the OMX component + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is + * specified, eColorFormat is used + * eColorFormat : Decompressed format used by this component + * pNativeWindow : Platform specific reference for a window object if a + * display sink , otherwise this field is 0x0. + */ +typedef struct OMX_VIDEO_PORTDEFINITIONTYPE { + OMX_STRING cMIMEType; + OMX_NATIVE_DEVICETYPE pNativeRender; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_S32 nStride; + OMX_U32 nSliceHeight; + OMX_U32 nBitrate; + OMX_U32 xFramerate; + OMX_BOOL bFlagErrorConcealment; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_NATIVE_WINDOWTYPE pNativeWindow; +} OMX_VIDEO_PORTDEFINITIONTYPE; + +/** + * Port format parameter. This structure is used to enumerate the various + * data input/output format supported by the port. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Indicates which port to set + * nIndex : Indicates the enumeration index for the format from + * 0x0 to N-1 + * eCompressionFormat : Compression format used in this instance of the + * component. When OMX_VIDEO_CodingUnused is specified, + * eColorFormat is used + * eColorFormat : Decompressed format used by this component + * xFrameRate : Indicates the video frame rate in Q16 format + */ +typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIndex; + OMX_VIDEO_CODINGTYPE eCompressionFormat; + OMX_COLOR_FORMATTYPE eColorFormat; + OMX_U32 xFramerate; +} OMX_VIDEO_PARAM_PORTFORMATTYPE; + + +/** + * This is a structure for configuring video compression quantization + * parameter values. Codecs may support different QP values for different + * frame types. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * nQpI : QP value to use for index frames + * nQpP : QP value to use for P frames + * nQpB : QP values to use for bidirectional frames + */ +typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nQpI; + OMX_U32 nQpP; + OMX_U32 nQpB; +} OMX_VIDEO_PARAM_QUANTIZATIONTYPE; + + +/** + * Structure for configuration of video fast update parameters. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version info + * nPortIndex : Port that this structure applies to + * bEnableVFU : Enable/Disable video fast update + * nFirstGOB : Specifies the number of the first macroblock row + * nFirstMB : specifies the first MB relative to the specified first GOB + * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB + * and nFirstMB + */ +typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableVFU; + OMX_U32 nFirstGOB; + OMX_U32 nFirstMB; + OMX_U32 nNumMBs; +} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE; + + +/** + * Enumeration of possible bitrate control types + */ +typedef enum OMX_VIDEO_CONTROLRATETYPE { + OMX_Video_ControlRateDisable, + OMX_Video_ControlRateVariable, + OMX_Video_ControlRateConstant, + OMX_Video_ControlRateVariableSkipFrames, + OMX_Video_ControlRateConstantSkipFrames, + OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_ControlRateMax = 0x7FFFFFFF +} OMX_VIDEO_CONTROLRATETYPE; + + +/** + * Structure for configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * eControlRate : Control rate type enum + * nTargetBitrate : Target bitrate to encode with + */ +typedef struct OMX_VIDEO_PARAM_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_CONTROLRATETYPE eControlRate; + OMX_U32 nTargetBitrate; +} OMX_VIDEO_PARAM_BITRATETYPE; + + +/** + * Enumeration of possible motion vector (MV) types + */ +typedef enum OMX_VIDEO_MOTIONVECTORTYPE { + OMX_Video_MotionVectorPixel, + OMX_Video_MotionVectorHalfPel, + OMX_Video_MotionVectorQuarterPel, + OMX_Video_MotionVectorEighthPel, + OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_Video_MotionVectorMax = 0x7FFFFFFF +} OMX_VIDEO_MOTIONVECTORTYPE; + + +/** + * Structure for configuring the number of motion vectors used as well + * as their accuracy. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : port that this structure applies to + * eAccuracy : Enumerated MV accuracy + * bUnrestrictedMVs : Allow unrestricted MVs + * bFourMV : Allow use of 4 MVs + * sXSearchRange : Search range in horizontal direction for MVs + * sYSearchRange : Search range in vertical direction for MVs + */ +typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_MOTIONVECTORTYPE eAccuracy; + OMX_BOOL bUnrestrictedMVs; + OMX_BOOL bFourMV; + OMX_S32 sXSearchRange; + OMX_S32 sYSearchRange; +} OMX_VIDEO_PARAM_MOTIONVECTORTYPE; + + +/** + * Enumeration of possible methods to use for Intra Refresh + */ +typedef enum OMX_VIDEO_INTRAREFRESHTYPE { + OMX_VIDEO_IntraRefreshCyclic, + OMX_VIDEO_IntraRefreshAdaptive, + OMX_VIDEO_IntraRefreshBoth, + OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF +} OMX_VIDEO_INTRAREFRESHTYPE; + + +/** + * Structure for configuring intra refresh mode + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eRefreshMode : Cyclic, Adaptive, or Both + * nAirMBs : Number of intra macroblocks to refresh in a frame when + * AIR is enabled + * nAirRef : Number of times a motion marked macroblock has to be + * intra coded + * nCirMBs : Number of consecutive macroblocks to be coded as "intra" + * when CIR is enabled + */ +typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode; + OMX_U32 nAirMBs; + OMX_U32 nAirRef; + OMX_U32 nCirMBs; +} OMX_VIDEO_PARAM_INTRAREFRESHTYPE; + + +/** + * Structure for enabling various error correction methods for video + * compression. + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * bEnableHEC : Enable/disable header extension codes (HEC) + * bEnableResync : Enable/disable resynchronization markers + * nResynchMarkerSpacing : Resynch markers interval (in bits) to be + * applied in the stream + * bEnableDataPartitioning : Enable/disable data partitioning + * bEnableRVLC : Enable/disable reversible variable length + * coding + */ +typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnableHEC; + OMX_BOOL bEnableResync; + OMX_U32 nResynchMarkerSpacing; + OMX_BOOL bEnableDataPartitioning; + OMX_BOOL bEnableRVLC; +} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE; + + +/** + * Configuration of variable block-size motion compensation (VBSMC) + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * b16x16 : Enable inter block search 16x16 + * b16x8 : Enable inter block search 16x8 + * b8x16 : Enable inter block search 8x16 + * b8x8 : Enable inter block search 8x8 + * b8x4 : Enable inter block search 8x4 + * b4x8 : Enable inter block search 4x8 + * b4x4 : Enable inter block search 4x4 + */ +typedef struct OMX_VIDEO_PARAM_VBSMCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL b16x16; + OMX_BOOL b16x8; + OMX_BOOL b8x16; + OMX_BOOL b8x8; + OMX_BOOL b8x4; + OMX_BOOL b4x8; + OMX_BOOL b4x4; +} OMX_VIDEO_PARAM_VBSMCTYPE; + + +/** + * H.263 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * Baseline : Baseline Profile: H.263 (V1), no optional modes + * H320 Coding : H.320 Coding Efficiency Backward Compatibility + * Profile: H.263+ (V2), includes annexes I, J, L.4 + * and T + * BackwardCompatible : Backward Compatibility Profile: H.263 (V1), + * includes annex F + * ISWV2 : Interactive Streaming Wireless Profile: H.263+ + * (V2), includes annexes I, J, K and T + * ISWV3 : Interactive Streaming Wireless Profile: H.263++ + * (V3), includes profile 3 and annexes V and W.6.3.8 + * HighCompression : Conversational High Compression Profile: H.263++ + * (V3), includes profiles 1 & 2 and annexes D and U + * Internet : Conversational Internet Profile: H.263++ (V3), + * includes profile 5 and annex K + * Interlace : Conversational Interlace Profile: H.263++ (V3), + * includes profile 5 and annex W.6.3.11 + * HighLatency : High Latency Profile: H.263++ (V3), includes + * profile 6 and annexes O.1 and P.5 + */ +typedef enum OMX_VIDEO_H263PROFILETYPE { + OMX_VIDEO_H263ProfileBaseline = 0x01, + OMX_VIDEO_H263ProfileH320Coding = 0x02, + OMX_VIDEO_H263ProfileBackwardCompatible = 0x04, + OMX_VIDEO_H263ProfileISWV2 = 0x08, + OMX_VIDEO_H263ProfileISWV3 = 0x10, + OMX_VIDEO_H263ProfileHighCompression = 0x20, + OMX_VIDEO_H263ProfileInternet = 0x40, + OMX_VIDEO_H263ProfileInterlace = 0x80, + OMX_VIDEO_H263ProfileHighLatency = 0x100, + OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_H263PROFILETYPE; + + +/** + * H.263 level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. + */ +typedef enum OMX_VIDEO_H263LEVELTYPE { + OMX_VIDEO_H263Level10 = 0x01, + OMX_VIDEO_H263Level20 = 0x02, + OMX_VIDEO_H263Level30 = 0x04, + OMX_VIDEO_H263Level40 = 0x08, + OMX_VIDEO_H263Level45 = 0x10, + OMX_VIDEO_H263Level50 = 0x20, + OMX_VIDEO_H263Level60 = 0x40, + OMX_VIDEO_H263Level70 = 0x80, + OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_H263LevelMax = 0x7FFFFFFF +} OMX_VIDEO_H263LEVELTYPE; + + +/** + * Specifies the picture type. These values should be OR'd to signal all + * pictures types which are allowed. + * + * ENUMS: + * Generic Picture Types: I, P and B + * H.263 Specific Picture Types: SI and SP + * H.264 Specific Picture Types: EI and EP + * MPEG-4 Specific Picture Types: S + */ +typedef enum OMX_VIDEO_PICTURETYPE { + OMX_VIDEO_PictureTypeI = 0x01, + OMX_VIDEO_PictureTypeP = 0x02, + OMX_VIDEO_PictureTypeB = 0x04, + OMX_VIDEO_PictureTypeSI = 0x08, + OMX_VIDEO_PictureTypeSP = 0x10, + OMX_VIDEO_PictureTypeEI = 0x11, + OMX_VIDEO_PictureTypeEP = 0x12, + OMX_VIDEO_PictureTypeS = 0x14, + OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF +} OMX_VIDEO_PICTURETYPE; + + +/** + * H.263 Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : H.263 profile(s) to use + * eLevel : H.263 level(s) to use + * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE + * (specified in the 1998 version of H.263) to + * indicate custom picture sizes or clock + * frequencies + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is + * not constrained. It is recommended to change + * the value of the RTYPE bit for each reference + * picture in error-free communication + * nPictureHeaderRepetition : Specifies the frequency of picture header + * repetition + * nGOBHeaderInterval : Specifies the interval of non-empty GOB + * headers in units of GOBs + */ +typedef struct OMX_VIDEO_PARAM_H263TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_H263PROFILETYPE eProfile; + OMX_VIDEO_H263LEVELTYPE eLevel; + OMX_BOOL bPLUSPTYPEAllowed; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bForceRoundingTypeToZero; + OMX_U32 nPictureHeaderRepetition; + OMX_U32 nGOBHeaderInterval; +} OMX_VIDEO_PARAM_H263TYPE; + + +/** + * MPEG-2 profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_MPEG2PROFILETYPE { + OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */ + OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */ + OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */ + OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */ + OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */ + OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */ + OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2PROFILETYPE; + + +/** + * MPEG-2 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG2LEVELTYPE { + OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */ + OMX_VIDEO_MPEG2LevelML, /**< Main Level */ + OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */ + OMX_VIDEO_MPEG2LevelHL, /**< High Level */ + OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG2LEVELTYPE; + + +/** + * MPEG-2 params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * eProfile : MPEG-2 profile(s) to use + * eLevel : MPEG-2 levels(s) to use + */ +typedef struct OMX_VIDEO_PARAM_MPEG2TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_VIDEO_MPEG2PROFILETYPE eProfile; + OMX_VIDEO_MPEG2LEVELTYPE eLevel; +} OMX_VIDEO_PARAM_MPEG2TYPE; + + +/** + * MPEG-4 profile types, each profile indicates support for various + * performance bounds and different annexes. + * + * ENUMS: + * - Simple Profile, Levels 1-3 + * - Simple Scalable Profile, Levels 1-2 + * - Core Profile, Levels 1-2 + * - Main Profile, Levels 2-4 + * - N-bit Profile, Level 2 + * - Scalable Texture Profile, Level 1 + * - Simple Face Animation Profile, Levels 1-2 + * - Simple Face and Body Animation (FBA) Profile, Levels 1-2 + * - Basic Animated Texture Profile, Levels 1-2 + * - Hybrid Profile, Levels 1-2 + * - Advanced Real Time Simple Profiles, Levels 1-4 + * - Core Scalable Profile, Levels 1-3 + * - Advanced Coding Efficiency Profile, Levels 1-4 + * - Advanced Core Profile, Levels 1-2 + * - Advanced Scalable Texture, Levels 2-3 + */ +typedef enum OMX_VIDEO_MPEG4PROFILETYPE { + OMX_VIDEO_MPEG4ProfileSimple = 0x01, + OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02, + OMX_VIDEO_MPEG4ProfileCore = 0x04, + OMX_VIDEO_MPEG4ProfileMain = 0x08, + OMX_VIDEO_MPEG4ProfileNbit = 0x10, + OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20, + OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40, + OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80, + OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100, + OMX_VIDEO_MPEG4ProfileHybrid = 0x200, + OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400, + OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800, + OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000, + OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000, + OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000, + OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000, + OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4PROFILETYPE; + + +/** + * MPEG-4 level types, each level indicates support for various frame + * sizes, bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_MPEG4LEVELTYPE { + OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */ + OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */ + OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */ + OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */ + OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */ + OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */ + OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */ + OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */ + OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF +} OMX_VIDEO_MPEG4LEVELTYPE; + + +/** + * MPEG-4 configuration. This structure handles configuration options + * which are specific to MPEG4 algorithms + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+ + * Annex K). Put zero if not used + * bSVH : Enable Short Video Header mode + * bGov : Flag to enable GOV + * nPFrames : Number of P frames between each I frame (also called + * GOV period) + * nBFrames : Number of B frames between each I frame + * nIDCVLCThreshold : Value of intra DC VLC threshold + * bACPred : Flag to use ac prediction + * nMaxPacketSize : Maximum size of packet in bytes. + * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4. + * Interpreted as described in MPEG4 standard. + * eProfile : MPEG-4 profile(s) to use. + * eLevel : MPEG-4 level(s) to use. + * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream + * nHeaderExtension : Specifies the number of consecutive video packet + * headers within a VOP + * bReversibleVLC : Specifies whether reversible variable length coding + * is in use + */ +typedef struct OMX_VIDEO_PARAM_MPEG4TYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_BOOL bSVH; + OMX_BOOL bGov; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_U32 nIDCVLCThreshold; + OMX_BOOL bACPred; + OMX_U32 nMaxPacketSize; + OMX_U32 nTimeIncRes; + OMX_VIDEO_MPEG4PROFILETYPE eProfile; + OMX_VIDEO_MPEG4LEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_U32 nHeaderExtension; + OMX_BOOL bReversibleVLC; +} OMX_VIDEO_PARAM_MPEG4TYPE; + + +/** + * WMV Versions + */ +typedef enum OMX_VIDEO_WMVFORMATTYPE { + OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */ + OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */ + OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */ + OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */ + OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_WMVFORMATTYPE; + + +/** + * WMV Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of WMV stream / data + */ +typedef struct OMX_VIDEO_PARAM_WMVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_WMVFORMATTYPE eFormat; +} OMX_VIDEO_PARAM_WMVTYPE; + + +/** + * Real Video Version + */ +typedef enum OMX_VIDEO_RVFORMATTYPE { + OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */ + OMX_VIDEO_RVFormat8, /**< Real Video format 8 */ + OMX_VIDEO_RVFormat9, /**< Real Video format 9 */ + OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */ + OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_RVFormatMax = 0x7FFFFFFF +} OMX_VIDEO_RVFORMATTYPE; + + +/** + * Real Video Params + * + * STUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * eFormat : Version of RV stream / data + * nBitsPerPixel : Bits per pixel coded in the frame + * nPaddedWidth : Padded width in pixel of a video frame + * nPaddedHeight : Padded Height in pixels of a video frame + * nFrameRate : Rate of video in frames per second + * nBitstreamFlags : Flags which internal information about the bitstream + * nBitstreamVersion : Bitstream version + * nMaxEncodeFrameSize: Max encoded frame size + * bEnablePostFilter : Turn on/off post filter + * bEnableTemporalInterpolation : Turn on/off temporal interpolation + * bEnableLatencyMode : When enabled, the decoder does not display a decoded + * frame until it has detected that no enhancement layer + * frames or dependent B frames will be coming. This + * detection usually occurs when a subsequent non-B + * frame is encountered + */ +typedef struct OMX_VIDEO_PARAM_RVTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_VIDEO_RVFORMATTYPE eFormat; + OMX_U16 nBitsPerPixel; + OMX_U16 nPaddedWidth; + OMX_U16 nPaddedHeight; + OMX_U32 nFrameRate; + OMX_U32 nBitstreamFlags; + OMX_U32 nBitstreamVersion; + OMX_U32 nMaxEncodeFrameSize; + OMX_BOOL bEnablePostFilter; + OMX_BOOL bEnableTemporalInterpolation; + OMX_BOOL bEnableLatencyMode; +} OMX_VIDEO_PARAM_RVTYPE; + + +/** + * AVC profile types, each profile indicates support for various + * performance bounds and different annexes. + */ +typedef enum OMX_VIDEO_AVCPROFILETYPE { + OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */ + OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */ + OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */ + OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */ + OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */ + OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */ + OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */ + OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF +} OMX_VIDEO_AVCPROFILETYPE; + + +/** + * AVC level types, each level indicates support for various frame sizes, + * bit rates, decoder frame rates. No need + */ +typedef enum OMX_VIDEO_AVCLEVELTYPE { + OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */ + OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */ + OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */ + OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */ + OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */ + OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */ + OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */ + OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */ + OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */ + OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */ + OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */ + OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */ + OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */ + OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */ + OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */ + OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */ + OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLEVELTYPE; + + +/** + * AVC loop filter modes + * + * OMX_VIDEO_AVCLoopFilterEnable : Enable + * OMX_VIDEO_AVCLoopFilterDisable : Disable + * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries + */ +typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE { + OMX_VIDEO_AVCLoopFilterEnable = 0, + OMX_VIDEO_AVCLoopFilterDisable, + OMX_VIDEO_AVCLoopFilterDisableSliceBoundary, + OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF +} OMX_VIDEO_AVCLOOPFILTERTYPE; + + +/** + * AVC params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nSliceHeaderSpacing : Number of macroblocks between slice header, put + * zero if not used + * nPFrames : Number of P frames between each I frame + * nBFrames : Number of B frames between each I frame + * bUseHadamard : Enable/disable Hadamard transform + * nRefFrames : Max number of reference frames to use for inter + * motion search (1-16) + * nRefIdxTrailing : Pic param set ref frame index (index into ref + * frame buffer of trailing frames list), B frame + * support + * nRefIdxForward : Pic param set ref frame index (index into ref + * frame buffer of forward frames list), B frame + * support + * bEnableUEP : Enable/disable unequal error protection. This + * is only valid of data partitioning is enabled. + * bEnableFMO : Enable/disable flexible macroblock ordering + * bEnableASO : Enable/disable arbitrary slice ordering + * bEnableRS : Enable/disable sending of redundant slices + * eProfile : AVC profile(s) to use + * eLevel : AVC level(s) to use + * nAllowedPictureTypes : Specifies the picture types allowed in the + * bitstream + * bFrameMBsOnly : specifies that every coded picture of the + * coded video sequence is a coded frame + * containing only frame macroblocks + * bMBAFF : Enable/disable switching between frame and + * field macroblocks within a picture + * bEntropyCodingCABAC : Entropy decoding method to be applied for the + * syntax elements for which two descriptors appear + * in the syntax tables + * bWeightedPPrediction : Enable/disable weighted prediction shall not + * be applied to P and SP slices + * nWeightedBipredicitonMode : Default weighted prediction is applied to B + * slices + * bconstIpred : Enable/disable intra prediction + * bDirect8x8Inference : Specifies the method used in the derivation + * process for luma motion vectors for B_Skip, + * B_Direct_16x16 and B_Direct_8x8 as specified + * in subclause 8.4.1.2 of the AVC spec + * bDirectSpatialTemporal : Flag indicating spatial or temporal direct + * mode used in B slice coding (related to + * bDirect8x8Inference) . Spatial direct mode is + * more common and should be the default. + * nCabacInitIdx : Index used to init CABAC contexts + * eLoopFilterMode : Enable/disable loop filter + */ +typedef struct OMX_VIDEO_PARAM_AVCTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nSliceHeaderSpacing; + OMX_U32 nPFrames; + OMX_U32 nBFrames; + OMX_BOOL bUseHadamard; + OMX_U32 nRefFrames; + OMX_U32 nRefIdx10ActiveMinus1; + OMX_U32 nRefIdx11ActiveMinus1; + OMX_BOOL bEnableUEP; + OMX_BOOL bEnableFMO; + OMX_BOOL bEnableASO; + OMX_BOOL bEnableRS; + OMX_VIDEO_AVCPROFILETYPE eProfile; + OMX_VIDEO_AVCLEVELTYPE eLevel; + OMX_U32 nAllowedPictureTypes; + OMX_BOOL bFrameMBsOnly; + OMX_BOOL bMBAFF; + OMX_BOOL bEntropyCodingCABAC; + OMX_BOOL bWeightedPPrediction; + OMX_U32 nWeightedBipredicitonMode; + OMX_BOOL bconstIpred ; + OMX_BOOL bDirect8x8Inference; + OMX_BOOL bDirectSpatialTemporal; + OMX_U32 nCabacInitIdc; + OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode; +} OMX_VIDEO_PARAM_AVCTYPE; + +typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE, + or OMX_VIDEO_MPEG4PROFILETYPE depending on context */ + OMX_U32 nProfileIndex; /**< Used to query for individual profile support information, + This parameter is valid only for + OMX_IndexParamVideoProfileLevelQuerySupported index, + For all other indices this parameter is to be ignored. */ +} OMX_VIDEO_PARAM_PROFILELEVELTYPE; + +/** + * Structure for dynamically configuring bitrate mode of a codec. + * + * STRUCT MEMBERS: + * nSize : Size of the struct in bytes + * nVersion : OMX spec version info + * nPortIndex : Port that this struct applies to + * nEncodeBitrate : Target average bitrate to be generated in bps + */ +typedef struct OMX_VIDEO_CONFIG_BITRATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nEncodeBitrate; +} OMX_VIDEO_CONFIG_BITRATETYPE; + +/** + * Defines Encoder Frame Rate setting + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * xEncodeFramerate : Encoding framerate represented in Q16 format + */ +typedef struct OMX_CONFIG_FRAMERATETYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 xEncodeFramerate; /* Q16 format */ +} OMX_CONFIG_FRAMERATETYPE; + +typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL IntraRefreshVOP; +} OMX_CONFIG_INTRAREFRESHVOPTYPE; + +typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */ + OMX_U8 ErrMap[1]; /* Error map hint */ +} OMX_CONFIG_MACROBLOCKERRORMAPTYPE; + +typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_BOOL bEnabled; +} OMX_CONFIG_MBERRORREPORTINGTYPE; + +typedef struct OMX_PARAM_MACROBLOCKSTYPE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nMacroblocks; +} OMX_PARAM_MACROBLOCKSTYPE; + +/** + * AVC Slice Mode modes + * + * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame + * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame + * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame + */ +typedef enum OMX_VIDEO_AVCSLICEMODETYPE { + OMX_VIDEO_SLICEMODE_AVCDefault = 0, + OMX_VIDEO_SLICEMODE_AVCMBSlice, + OMX_VIDEO_SLICEMODE_AVCByteSlice, + OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF +} OMX_VIDEO_AVCSLICEMODETYPE; + +/** + * AVC FMO Slice Mode Params + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNumSliceGroups : Specifies the number of slice groups + * nSliceGroupMapType : Specifies the type of slice groups + * eSliceMode : Specifies the type of slice + */ +typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U8 nNumSliceGroups; + OMX_U8 nSliceGroupMapType; + OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; +} OMX_VIDEO_PARAM_AVCSLICEFMO; + +/** + * AVC IDR Period Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nIDRPeriod : Specifies periodicity of IDR frames + * nPFrames : Specifies internal of coding Intra frames + */ +typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nIDRPeriod; + OMX_U32 nPFrames; +} OMX_VIDEO_CONFIG_AVCINTRAPERIOD; + +/** + * AVC NAL Size Configs + * + * STRUCT MEMBERS: + * nSize : Size of the structure in bytes + * nVersion : OMX specification version information + * nPortIndex : Port that this structure applies to + * nNaluBytes : Specifies the NAL unit size + */ +typedef struct OMX_VIDEO_CONFIG_NALSIZE { + OMX_U32 nSize; + OMX_VERSIONTYPE nVersion; + OMX_U32 nPortIndex; + OMX_U32 nNaluBytes; +} OMX_VIDEO_CONFIG_NALSIZE; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +/* File EOF */ + diff --git a/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Def.h b/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Def.h new file mode 100644 index 0000000..10dd94d --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Def.h @@ -0,0 +1,138 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Def.h + * @brief SEC_OMX specific define + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_DEF +#define SEC_OMX_DEF + +#include "OMX_Types.h" +#include "OMX_IVCommon.h" + +#define VERSIONMAJOR_NUMBER 1 +#define VERSIONMINOR_NUMBER 0 +#define REVISION_NUMBER 0 +#define STEP_NUMBER 0 + + +#define MAX_OMX_COMPONENT_NUM 20 +#define MAX_OMX_COMPONENT_ROLE_NUM 10 +#define MAX_OMX_COMPONENT_NAME_SIZE OMX_MAX_STRINGNAME_SIZE +#define MAX_OMX_COMPONENT_ROLE_SIZE OMX_MAX_STRINGNAME_SIZE +#define MAX_OMX_COMPONENT_LIBNAME_SIZE OMX_MAX_STRINGNAME_SIZE * 2 +#define MAX_OMX_MIMETYPE_SIZE OMX_MAX_STRINGNAME_SIZE + +#define MAX_TIMESTAMP 16 +#define MAX_FLAGS 16 + + +typedef enum _SEC_CODEC_TYPE +{ + SW_CODEC, + HW_VIDEO_CODEC, + HW_AUDIO_CODEC +} SEC_CODEC_TYPE; + +typedef struct _SEC_OMX_PRIORITYMGMTTYPE +{ + OMX_U32 nGroupPriority; /* the value 0 represents the highest priority */ + /* for a group of components */ + OMX_U32 nGroupID; +} SEC_OMX_PRIORITYMGMTTYPE; + +typedef enum _SEC_OMX_INDEXTYPE +{ + OMX_IndexVendorThumbnailMode = 0x7F000001, + OMX_COMPONENT_CAPABILITY_TYPE_INDEX = 0xFF7A347 /*for Android*/ +} SEC_OMX_INDEXTYPE; + +typedef enum _SEC_OMX_ERRORTYPE +{ + OMX_ErrorNoEOF = 0x90000001, + OMX_ErrorInputDataDecodeYet, + OMX_ErrorInputDataEncodeYet, + OMX_ErrorMFCInit +} SEC_OMX_ERRORTYPE; + +typedef enum _SEC_OMX_COMMANDTYPE +{ + SEC_OMX_CommandComponentDeInit = 0x7F000001, + SEC_OMX_CommandEmptyBuffer, + SEC_OMX_CommandFillBuffer +} SEC_OMX_COMMANDTYPE; + +typedef enum _SEC_OMX_TRANS_STATETYPE { + SEC_OMX_TransStateInvalid, + SEC_OMX_TransStateLoadedToIdle, + SEC_OMX_TransStateIdleToExecuting, + SEC_OMX_TransStateExecutingToIdle, + SEC_OMX_TransStateIdleToLoaded, + SEC_OMX_TransStateMax = 0X7FFFFFFF +} SEC_OMX_TRANS_STATETYPE; + +typedef enum _SEC_OMX_COLOR_FORMATTYPE { +#ifndef USE_SAMSUNG_COLORFORMAT + SEC_OMX_COLOR_FormatNV12PhysicalAddress = OMX_COLOR_FormatYUV420SemiPlanar +#else + SEC_OMX_COLOR_FormatNV12PhysicalAddress = 0x7F000001 /**< Reserved region for introducing Vendor Extensions */ +#endif +}SEC_OMX_COLOR_FORMATTYPE; + +typedef enum _SEC_OMX_SUPPORTFORMAT_TYPE +{ + supportFormat_1 = 0x00, + supportFormat_2, + supportFormat_3, + supportFormat_4 +} SEC_OMX_SUPPORTFORMAT_TYPE; + + +/* for Android */ +typedef struct _OMXComponentCapabilityFlagsType +{ + /* OMX COMPONENT CAPABILITY RELATED MEMBERS */ + OMX_BOOL iIsOMXComponentMultiThreaded; + OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; + OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; + OMX_BOOL iOMXComponentSupportsMovableInputBuffers; + OMX_BOOL iOMXComponentSupportsPartialFrames; + OMX_BOOL iOMXComponentUsesNALStartCodes; + OMX_BOOL iOMXComponentCanHandleIncompleteFrames; + OMX_BOOL iOMXComponentUsesFullAVCFrames; +} OMXComponentCapabilityFlagsType; + +typedef struct _SEC_OMX_VIDEO_PROFILELEVEL +{ + OMX_S32 profile; + OMX_S32 level; +} SEC_OMX_VIDEO_PROFILELEVEL; + + +#ifndef __OMX_EXPORTS +#define __OMX_EXPORTS +#define SEC_EXPORT_REF __attribute__((visibility("default"))) +#define SEC_IMPORT_REF __attribute__((visibility("default"))) +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Macros.h b/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Macros.h new file mode 100644 index 0000000..b3bfda6 --- /dev/null +++ b/sec_mm/sec_omx/sec_omx_include/sec/SEC_OMX_Macros.h @@ -0,0 +1,64 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OMX_Macros.h + * @brief Macros + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OMX_MACROS +#define SEC_OMX_MACROS + +#include "SEC_OMX_Def.h" +#include "SEC_OSAL_Memory.h" + + +/* + * MACROS + */ +#define ALIGN_TO_32B(x) ((((x) + (1 << 5) - 1) >> 5) << 5) +#define ALIGN_TO_128B(x) ((((x) + (1 << 7) - 1) >> 7) << 7) +#define ALIGN_TO_8KB(x) ((((x) + (1 << 13) - 1) >> 13) << 13) + +#define INIT_SET_SIZE_VERSION(_struct_, _structType_) \ + do { \ + SEC_OSAL_Memset((_struct_), 0, sizeof(_structType_)); \ + (_struct_)->nSize = sizeof(_structType_); \ + (_struct_)->nVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER; \ + (_struct_)->nVersion.s.nVersionMinor = VERSIONMINOR_NUMBER; \ + (_struct_)->nVersion.s.nRevision = REVISION_NUMBER; \ + (_struct_)->nVersion.s.nStep = STEP_NUMBER; \ + } while (0) + +/* + * Port Specific + */ +#define SEC_TUNNEL_ESTABLISHED 0x0001 +#define SEC_TUNNEL_IS_SUPPLIER 0x0002 + +#define CHECK_PORT_BEING_FLUSHED(port) (port->bIsPortFlushed == OMX_TRUE) +#define CHECK_PORT_BEING_DISABLED(port) (port->bIsPortDisabled == OMX_TRUE) +#define CHECK_PORT_ENABLED(port) (port->portDefinition.bEnabled == OMX_TRUE) +#define CHECK_PORT_POPULATED(port) (port->portDefinition.bPopulated == OMX_TRUE) +#define CHECK_PORT_TUNNELED(port) (port->tunnelFlags & SEC_TUNNEL_ESTABLISHED) +#define CHECK_PORT_BUFFER_SUPPLIER(port) (port->tunnelFlags & SEC_TUNNEL_IS_SUPPLIER) + +#endif diff --git a/sec_mm/sec_omx/sec_osal/Android.mk b/sec_mm/sec_omx/sec_osal/Android.mk new file mode 100644 index 0000000..027fc66 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := \ + SEC_OSAL_Event.c \ + SEC_OSAL_Queue.c \ + SEC_OSAL_ETC.c \ + SEC_OSAL_Mutex.c \ + SEC_OSAL_Thread.c \ + SEC_OSAL_Memory.c \ + SEC_OSAL_Semaphore.c \ + SEC_OSAL_Library.c \ + SEC_OSAL_Log.c + +LOCAL_PRELINK_MODULE := false +LOCAL_MODULE := libsecosal.smdkc210 + +LOCAL_CFLAGS := + +LOCAL_STATIC_LIBRARIES := +LOCAL_SHARED_LIBRARIES := libcutils libutils + +LOCAL_C_INCLUDES := $(SEC_OMX_INC)/khronos \ + $(SEC_OMX_INC)/sec \ + $(SEC_OMX_TOP)/sec_osal + +include $(BUILD_STATIC_LIBRARY) diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.c new file mode 100644 index 0000000..66f8355 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.c @@ -0,0 +1,144 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_ETC.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_ETC.h" + + +#ifndef HAVE_GETLINE +ssize_t getline(char **ppLine, size_t *pLen, FILE *pStream) +{ + char *pCurrentPointer = NULL; + size_t const chunk = 512; + + size_t defaultBufferSize = chunk + 1; + size_t retSize = 0; + + if (*ppLine == NULL) { + *ppLine = (char *)malloc(defaultBufferSize); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = defaultBufferSize; + } + else { + if (*pLen < defaultBufferSize) { + *ppLine = (char *)realloc(*ppLine, defaultBufferSize); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = defaultBufferSize; + } + } + + while (1) { + size_t i; + size_t j = 0; + size_t readByte = 0; + + pCurrentPointer = *ppLine + readByte; + + i = fread(pCurrentPointer, 1, chunk, pStream); + if (i < chunk && ferror(pStream)) { + retSize = -1; + goto EXIT; + } + while (j < i) { + ++j; + if (*pCurrentPointer++ == (char)'\n') { + *pCurrentPointer = '\0'; + if (j != i) { + if (fseek(pStream, j - i, SEEK_CUR)) { + retSize = -1; + goto EXIT; + } + if (feof(pStream)) + clearerr(pStream); + } + readByte += j; + retSize = readByte; + goto EXIT; + } + } + + readByte += j; + if (feof(pStream)) { + if (readByte) { + retSize = readByte; + goto EXIT; + } + if (!i) { + retSize = -1; + goto EXIT; + } + } + + i = ((readByte + (chunk * 2)) / chunk) * chunk; + if (i != *pLen) { + *ppLine = (char *)realloc(*ppLine, i); + if (*ppLine == NULL) { + retSize = -1; + goto EXIT; + } + *pLen = i; + } + } + +EXIT: + return retSize; +} +#endif /* HAVE_GETLINE */ + +OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src) +{ + return strcpy(dest, src); +} + +OMX_PTR SEC_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num) +{ + return strncpy(dest, src, num); +} + +OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2) +{ + return strcmp(str1, str2); +} + +OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src) +{ + return strcat(dest, src); +} + +size_t SEC_OSAL_Strlen(const char *str) +{ + return strlen(str); +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.h new file mode 100644 index 0000000..6c6ede7 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_ETC.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_ETC.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_ETC +#define SEC_OSAL_ETC + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR SEC_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src); +OMX_PTR SEC_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num); +OMX_S32 SEC_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2); +OMX_PTR SEC_OSAL_Strcat(OMX_PTR dest, OMX_PTR src); +size_t SEC_OSAL_Strlen(const char *str); +ssize_t getline(char **ppLine, size_t *len, FILE *stream); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.c new file mode 100644 index 0000000..51b3ca2 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.c @@ -0,0 +1,217 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* + * @file SEC_OSAL_Event.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_Event.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_OSAL_EVENT" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle) +{ + SEC_OSAL_THREADEVENT *event; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + event = (SEC_OSAL_THREADEVENT *)SEC_OSAL_Malloc(sizeof(SEC_OSAL_THREADEVENT)); + if (!event) { + ret = OMX_ErrorInsufficientResources; + goto EXIT; + } + + SEC_OSAL_Memset(event, 0, sizeof(SEC_OSAL_THREADEVENT)); + event->signal = OMX_FALSE; + + ret = SEC_OSAL_MutexCreate(&event->mutex); + if (ret != OMX_ErrorNone) { + SEC_OSAL_Free(event); + goto EXIT; + } + + if (pthread_cond_init(&event->condition, NULL)) { + SEC_OSAL_MutexTerminate(event->mutex); + SEC_OSAL_Free(event); + ret = OMX_ErrorUndefined; + goto EXIT; + } + + *eventHandle = (OMX_HANDLETYPE)event; + ret = OMX_ErrorNone; + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (pthread_cond_destroy(&event->condition)) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = SEC_OSAL_MutexUnlock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + ret = SEC_OSAL_MutexTerminate(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Free(event); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_FALSE; + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + event->signal = OMX_TRUE; + pthread_cond_signal(&event->condition); + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms) +{ + SEC_OSAL_THREADEVENT *event = (SEC_OSAL_THREADEVENT *)eventHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct timespec timeout; + struct timeval now; + int funcret = 0; + OMX_U32 tv_us; + + FunctionIn(); + + if (!event) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + gettimeofday(&now, NULL); + + tv_us = now.tv_usec + ms * 1000; + timeout.tv_sec = now.tv_sec + tv_us / 1000000; + timeout.tv_nsec = (tv_us % 1000000) * 1000; + + ret = SEC_OSAL_MutexLock(event->mutex); + if (ret != OMX_ErrorNone) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + + if (ms == 0) { + if (!event->signal) + ret = OMX_ErrorTimeout; + } else if (ms == DEF_MAX_WAIT_TIME) { + while (!event->signal) + pthread_cond_wait(&event->condition, (pthread_mutex_t *)(event->mutex)); + ret = OMX_ErrorNone; + } else { + while (!event->signal) { + funcret = pthread_cond_timedwait(&event->condition, (pthread_mutex_t *)(event->mutex), &timeout); + if ((!event->signal) && (funcret == ETIMEDOUT)) { + ret = OMX_ErrorTimeout; + break; + } + } + } + + SEC_OSAL_MutexUnlock(event->mutex); + +EXIT: + FunctionOut(); + + return ret; +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.h new file mode 100644 index 0000000..640d2cc --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Event.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Event.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_EVENT +#define SEC_OSAL_EVENT + +#include +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#define DEF_MAX_WAIT_TIME 0xFFFFFFFF + +typedef struct _SEC_OSAL_THREADEVENT +{ + OMX_BOOL signal; + OMX_HANDLETYPE mutex; + pthread_cond_t condition; +} SEC_OSAL_THREADEVENT; + + +#ifdef __cplusplus +extern "C" { +#endif + + +OMX_ERRORTYPE SEC_OSAL_SignalCreate(OMX_HANDLETYPE *eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalTerminate(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalReset(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalSet(OMX_HANDLETYPE eventHandle); +OMX_ERRORTYPE SEC_OSAL_SignalWait(OMX_HANDLETYPE eventHandle, OMX_U32 ms); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.c new file mode 100644 index 0000000..06ac712 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.c @@ -0,0 +1,54 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Library.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include +#include + +#include "SEC_OSAL_Library.h" + + +void *SEC_OSAL_dlopen(const char *filename, int flag) +{ + return dlopen(filename, flag); +} + +void *SEC_OSAL_dlsym(void *handle, const char *symbol) +{ + return dlsym(handle, symbol); +} + +int SEC_OSAL_dlclose(void *handle) +{ + return dlclose(handle); +} + +const char *SEC_OSAL_dlerror(void) +{ + return dlerror(); +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.h new file mode 100644 index 0000000..687cecd --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Library.h @@ -0,0 +1,46 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Library.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_LIBRARY +#define SEC_OSAL_LIBRARY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void *SEC_OSAL_dlopen(const char *filename, int flag); +void *SEC_OSAL_dlsym(void *handle, const char *symbol); +int SEC_OSAL_dlclose(void *handle); +const char *SEC_OSAL_dlerror(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.c new file mode 100644 index 0000000..bae4974 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Log.c + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include + +#include "SEC_OSAL_Log.h" + + +void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...) +{ + va_list argptr; + + va_start(argptr, msg); + + switch (logLevel) { + case SEC_LOG_TRACE: + __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, argptr); + break; + case SEC_LOG_WARNING: + __android_log_vprint(ANDROID_LOG_WARN, tag, msg, argptr); + break; + case SEC_LOG_ERROR: + __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, argptr); + break; + default: + __android_log_vprint(ANDROID_LOG_VERBOSE, tag, msg, argptr); + } + + va_end(argptr); +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.h new file mode 100644 index 0000000..2f8a6ce --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Log.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Log.h + * @brief + * @author Yunji Kim (yunji.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + * 2010.8.27 : Add trace function + */ + +#ifndef SEC_OSAL_LOG +#define SEC_OSAL_LOG + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SEC_LOG_OFF +#define SEC_LOG +#endif + +#ifndef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG" +#endif + +#ifdef SEC_TRACE_ON +#define SEC_TRACE +#endif + +typedef enum _LOG_LEVEL +{ + SEC_LOG_TRACE, + SEC_LOG_WARNING, + SEC_LOG_ERROR +} SEC_LOG_LEVEL; + +#ifdef SEC_LOG +#define SEC_OSAL_Log(a, ...) ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)) +#else +#define SEC_OSAL_Log(a, ...) \ + do { \ + if (a == SEC_LOG_ERROR) \ + ((void)_SEC_OSAL_Log(a, SEC_LOG_TAG, __VA_ARGS__)); \ + } while (0) +#endif + +#ifdef SEC_TRACE +#define FunctionIn() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__) +#define FunctionOut() _SEC_OSAL_Log(SEC_LOG_TRACE, SEC_LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__) +#else +#define FunctionIn() ((void *)0) +#define FunctionOut() ((void *)0) +#endif + +extern void _SEC_OSAL_Log(SEC_LOG_LEVEL logLevel, const char *tag, const char *msg, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.c new file mode 100644 index 0000000..3579d92 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.c @@ -0,0 +1,71 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Memory.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" + +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +static int mem_cnt = 0; + +OMX_PTR SEC_OSAL_Malloc(OMX_U32 size) +{ + mem_cnt++; + SEC_OSAL_Log(SEC_LOG_TRACE, "alloc count: %d", mem_cnt); + + return (OMX_PTR)malloc(size); +} + +void SEC_OSAL_Free(OMX_PTR addr) +{ + mem_cnt--; + SEC_OSAL_Log(SEC_LOG_TRACE, "free count: %d", mem_cnt); + + if (addr) + free(addr); + + return; +} + +OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n) +{ + return memset(dest, c, n); +} + +OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memcpy(dest, src, n); +} + +OMX_PTR SEC_OSAL_Memmove(OMX_PTR dest, OMX_PTR src, OMX_S32 n) +{ + return memmove(dest, src, n); +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.h new file mode 100644 index 0000000..3a12838 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Memory.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Memory.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_MEMORY +#define SEC_OSAL_MEMORY + +#include "OMX_Types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_PTR SEC_OSAL_Malloc(OMX_U32 size); +void SEC_OSAL_Free(OMX_PTR addr); +OMX_PTR SEC_OSAL_Memset(OMX_PTR dest, OMX_S32 c, OMX_S32 n); +OMX_PTR SEC_OSAL_Memcpy(OMX_PTR dest, OMX_PTR src, OMX_S32 n); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.c new file mode 100644 index 0000000..146809c --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.c @@ -0,0 +1,91 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Mutex.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" + + +OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle) +{ + pthread_mutex_t *mutex; + + mutex = (pthread_mutex_t *)SEC_OSAL_Malloc(sizeof(pthread_mutex_t)); + if (!mutex) + return OMX_ErrorInsufficientResources; + + if (pthread_mutex_init(mutex, NULL) != 0) + return OMX_ErrorUndefined; + + *mutexHandle = (OMX_HANDLETYPE)mutex; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_destroy(mutex) != 0) + return OMX_ErrorUndefined; + + SEC_OSAL_Free(mutex); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + int result; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_lock(mutex) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle) +{ + pthread_mutex_t *mutex = (pthread_mutex_t *)mutexHandle; + int result; + + if (mutex == NULL) + return OMX_ErrorBadParameter; + + if (pthread_mutex_unlock(mutex) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.h new file mode 100644 index 0000000..70dcd9d --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Mutex.h @@ -0,0 +1,47 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Mutex.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create +*/ + +#ifndef SEC_OSAL_MUTEX +#define SEC_OSAL_MUTEX + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_MutexCreate(OMX_HANDLETYPE *mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexTerminate(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexLock(OMX_HANDLETYPE mutexHandle); +OMX_ERRORTYPE SEC_OSAL_MutexUnlock(OMX_HANDLETYPE mutexHandle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.c new file mode 100644 index 0000000..7a6c024 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.c @@ -0,0 +1,174 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Queue.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + + +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Mutex.h" +#include "SEC_OSAL_Queue.h" + + +OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle) +{ + int i = 0; + SEC_QElem *newqelem = NULL; + SEC_QElem *currentqelem = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + ret = SEC_OSAL_MutexCreate(&queue->qMutex); + if (ret != OMX_ErrorNone) + return ret; + + queue->first = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); + if (queue->first == NULL) + return OMX_ErrorInsufficientResources; + + SEC_OSAL_Memset(queue->first, 0, sizeof(SEC_QElem)); + currentqelem = queue->last = queue->first; + queue->numElem = 0; + + for (i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { + newqelem = (SEC_QElem *)SEC_OSAL_Malloc(sizeof(SEC_QElem)); + if (newqelem == NULL) { + while (queue->first != NULL) { + currentqelem = queue->first->qNext; + SEC_OSAL_Free((OMX_PTR)queue->first); + queue->first = currentqelem; + } + return OMX_ErrorInsufficientResources; + } else { + SEC_OSAL_Memset(newqelem, 0, sizeof(SEC_QElem)); + currentqelem->qNext = newqelem; + currentqelem = newqelem; + } + } + + currentqelem->qNext = queue->first; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle) +{ + int i = 0; + SEC_QElem *currentqelem = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (!queue) + return OMX_ErrorBadParameter; + + for ( i = 0; i < (MAX_QUEUE_ELEMENTS - 2); i++) { + currentqelem = queue->first->qNext; + SEC_OSAL_Free(queue->first); + queue->first = currentqelem; + } + + if(queue->first) { + SEC_OSAL_Free(queue->first); + queue->first = NULL; + } + + ret = SEC_OSAL_MutexTerminate(queue->qMutex); + + return ret; +} + +int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data) +{ + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + + if ((queue->last->data != NULL) || (queue->numElem >= MAX_QUEUE_ELEMENTS)) { + SEC_OSAL_MutexUnlock(queue->qMutex); + return -1; + } + queue->last->data = data; + queue->last = queue->last->qNext; + queue->numElem++; + + SEC_OSAL_MutexUnlock(queue->qMutex); + return 0; +} + +void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle) +{ + void *data = NULL; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return NULL; + + SEC_OSAL_MutexLock(queue->qMutex); + + if ((queue->first->data == NULL) || (queue->numElem <= 0)) { + SEC_OSAL_MutexUnlock(queue->qMutex); + return NULL; + } + data = queue->first->data; + queue->first->data = NULL; + queue->first = queue->first->qNext; + queue->numElem--; + + SEC_OSAL_MutexUnlock(queue->qMutex); + return data; +} + +int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle) +{ + int ElemNum = 0; + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + ElemNum = queue->numElem; + SEC_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + +int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum) +{ + SEC_QUEUE *queue = (SEC_QUEUE *)queueHandle; + if (queue == NULL) + return -1; + + SEC_OSAL_MutexLock(queue->qMutex); + queue->numElem = ElemNum; + SEC_OSAL_MutexUnlock(queue->qMutex); + return ElemNum; +} + diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.h new file mode 100644 index 0000000..68910cc --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Queue.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Queue.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_QUEUE +#define SEC_OSAL_QUEUE + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#define MAX_QUEUE_ELEMENTS 10 + +struct SEC_QElem; +typedef struct _SEC_QElem +{ + void *data; + struct SEC_QElem *qNext; +} SEC_QElem; + +typedef struct _SEC_QUEUE +{ + SEC_QElem *first; + SEC_QElem *last; + int numElem; + OMX_HANDLETYPE qMutex; +} SEC_QUEUE; + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_QueueCreate(SEC_QUEUE *queueHandle); +OMX_ERRORTYPE SEC_OSAL_QueueTerminate(SEC_QUEUE *queueHandle); +int SEC_OSAL_Queue(SEC_QUEUE *queueHandle, void *data); +void *SEC_OSAL_Dequeue(SEC_QUEUE *queueHandle); +int SEC_OSAL_GetElemNum(SEC_QUEUE *queueHandle); +int SEC_OSAL_SetElemNum(SEC_QUEUE *queueHandle, int ElemNum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.c new file mode 100644 index 0000000..17a29a0 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.c @@ -0,0 +1,132 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Semaphore.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Semaphore.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG_SEMA" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle) +{ + sem_t *sema; + + sema = (sem_t *)SEC_OSAL_Malloc(sizeof(sema)); + if (!sema) + return OMX_ErrorInsufficientResources; + + if (sem_init(sema, 0, 0) != 0) + return OMX_ErrorUndefined; + + *semaphoreHandle = (OMX_HANDLETYPE)sema; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_destroy(sema) != 0) + return OMX_ErrorUndefined; + + SEC_OSAL_Free(sema); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + FunctionIn(); + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_wait(sema) != 0) + return OMX_ErrorUndefined; + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + FunctionIn(); + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_post(sema) != 0) + return OMX_ErrorUndefined; + + FunctionOut(); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_init(sema, 0, val) != 0) + return OMX_ErrorUndefined; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val) +{ + sem_t *sema = (sem_t *)semaphoreHandle; + OMX_U32 semaVal = 0; + + if (sema == NULL) + return OMX_ErrorBadParameter; + + if (sem_getvalue(sema, &semaVal) != 0) + return OMX_ErrorUndefined; + + *val = semaVal; + + return OMX_ErrorNone; +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.h new file mode 100644 index 0000000..f23d3d6 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Semaphore.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Semaphore.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_SEMAPHORE +#define SEC_OSAL_SEMAPHORE + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_SemaphoreCreate(OMX_HANDLETYPE *semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphoreTerminate(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphoreWait(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_SemaphorePost(OMX_HANDLETYPE semaphoreHandle); +OMX_ERRORTYPE SEC_OSAL_Set_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 val); +OMX_ERRORTYPE SEC_OSAL_Get_SemaphoreCount(OMX_HANDLETYPE semaphoreHandle, OMX_S32 *val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.c b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.c new file mode 100644 index 0000000..d488885 --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.c @@ -0,0 +1,153 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Thread.c + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#include +#include +#include +#include +#include +#include + +#include "SEC_OSAL_Memory.h" +#include "SEC_OSAL_Thread.h" + +#undef SEC_LOG_TAG +#define SEC_LOG_TAG "SEC_LOG_THREAD" +#define SEC_LOG_OFF +#include "SEC_OSAL_Log.h" + + +typedef struct _SEC_THREAD_HANDLE_TYPE +{ + pthread_t pthread; + pthread_attr_t attr; + struct sched_param schedparam; + int stack_size; +} SEC_THREAD_HANDLE_TYPE; + + +OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument) +{ + FunctionIn(); + + int result = 0; + int detach_ret = 0; + SEC_THREAD_HANDLE_TYPE *thread; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + thread = SEC_OSAL_Malloc(sizeof(SEC_THREAD_HANDLE_TYPE)); + SEC_OSAL_Memset(thread, 0, sizeof(SEC_THREAD_HANDLE_TYPE)); + + pthread_attr_init(&thread->attr); + if (thread->stack_size != 0) + pthread_attr_setstacksize(&thread->attr, thread->stack_size); + + /* set priority */ + if (thread->schedparam.sched_priority != 0) + pthread_attr_setschedparam(&thread->attr, &thread->schedparam); + + detach_ret = pthread_attr_setdetachstate(&thread->attr, PTHREAD_CREATE_JOINABLE); + if (detach_ret != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + result = pthread_create(&thread->pthread, &thread->attr, function_name, (void *)argument); + /* pthread_setschedparam(thread->pthread, SCHED_RR, &thread->schedparam); */ + + switch (result) { + case 0: + *threadHandle = (OMX_HANDLETYPE)thread; + ret = OMX_ErrorNone; + break; + case EAGAIN: + *threadHandle = NULL; + ret = OMX_ErrorInsufficientResources; + break; + default: + *threadHandle = NULL; + ret = OMX_ErrorUndefined; + break; + } + +EXIT: + FunctionOut(); + + return ret; +} + +OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle) +{ + FunctionIn(); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) { + ret = OMX_ErrorBadParameter; + goto EXIT; + } + if (pthread_join(thread->pthread, NULL) != 0) { + ret = OMX_ErrorUndefined; + goto EXIT; + } + + SEC_OSAL_Free(thread); + ret = OMX_ErrorNone; + +EXIT: + FunctionOut(); + + return ret; + +} + +OMX_ERRORTYPE SEC_OSAL_ThreadCancle(OMX_HANDLETYPE threadHandle) +{ + SEC_THREAD_HANDLE_TYPE *thread = (SEC_THREAD_HANDLE_TYPE *)threadHandle; + + if (!thread) + return OMX_ErrorBadParameter; + + /* thread_cancel(thread->pthread); */ + pthread_exit(thread->pthread); + pthread_join(thread->pthread, NULL); + + SEC_OSAL_Free(thread); + return OMX_ErrorNone; +} + +void SEC_OSAL_TheadExit(void *value_ptr) +{ + pthread_exit(value_ptr); + return; +} + +void SEC_OSAL_SleepMillisec(OMX_U32 ms) +{ + usleep(ms * 1000); + return; +} diff --git a/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.h b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.h new file mode 100644 index 0000000..b932aef --- /dev/null +++ b/sec_mm/sec_omx/sec_osal/SEC_OSAL_Thread.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2010 Samsung Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file SEC_OSAL_Thread.h + * @brief + * @author SeungBeom Kim (sbcrux.kim@samsung.com) + * @version 1.0 + * @history + * 2010.7.15 : Create + */ + +#ifndef SEC_OSAL_THREAD +#define SEC_OSAL_THREAD + +#include "OMX_Types.h" +#include "OMX_Core.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +OMX_ERRORTYPE SEC_OSAL_ThreadCreate(OMX_HANDLETYPE *threadHandle, OMX_PTR function_name, OMX_PTR argument); +OMX_ERRORTYPE SEC_OSAL_ThreadTerminate(OMX_HANDLETYPE threadHandle); +OMX_ERRORTYPE SEC_OSAL_ThreadCancle(OMX_HANDLETYPE threadHandle); +void SEC_OSAL_TheadExit(void *value_ptr); +void SEC_OSAL_SleepMillisec(OMX_U32 ms); + +#ifdef __cplusplus +} +#endif + +#endif