diff options
author | Brian Swetland <swetland@google.com> | 2010-09-24 20:12:54 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-09-24 20:12:54 -0700 |
commit | 1e521da356b6dff8ea870e7bfbb792256318f3a1 (patch) | |
tree | 53447543aaac48acc38f7136c6e7ad86b49868ce | |
parent | 4e3b07af1b550ba541cade2b4e4cf24d6d4c6d3d (diff) | |
parent | d7f2c96de954376e7460388c2205a7cc7775a525 (diff) | |
download | device_samsung_crespo-1e521da356b6dff8ea870e7bfbb792256318f3a1.zip device_samsung_crespo-1e521da356b6dff8ea870e7bfbb792256318f3a1.tar.gz device_samsung_crespo-1e521da356b6dff8ea870e7bfbb792256318f3a1.tar.bz2 |
Merge "libcamera: using libs3cjpeg" into gingerbread
-rw-r--r-- | libcamera/Android.mk | 3 | ||||
-rw-r--r-- | libcamera/SecCamera.cpp | 383 | ||||
-rw-r--r-- | libcamera/SecCamera.h | 40 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.cpp | 219 | ||||
-rw-r--r-- | libcamera/SecCameraHWInterface.h | 3 |
5 files changed, 557 insertions, 91 deletions
diff --git a/libcamera/Android.mk b/libcamera/Android.mk index 17b4b33..ebbd37b 100644 --- a/libcamera/Android.mk +++ b/libcamera/Android.mk @@ -19,9 +19,10 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libs3cjpeg LOCAL_SRC_FILES:= \ SecCamera.cpp \ SecCameraHWInterface.cpp - + LOCAL_SHARED_LIBRARIES:= libutils libui liblog libbinder libcutils +LOCAL_SHARED_LIBRARIES+= libs3cjpeg LOCAL_SHARED_LIBRARIES+= libcamera_client #Enable the below code to show the video output (without GUI) on TV diff --git a/libcamera/SecCamera.cpp b/libcamera/SecCamera.cpp index ad9c1c2..c83fca2 100644 --- a/libcamera/SecCamera.cpp +++ b/libcamera/SecCamera.cpp @@ -1705,9 +1705,63 @@ unsigned char* SecCamera::getJpeg(int *jpeg_size, unsigned int *phyaddr) return addr; } -int SecCamera::getExif (unsigned char *pExifDst, unsigned char *pThumbSrc) +int SecCamera::getExif(unsigned char *pExifDst, unsigned char *pThumbSrc) { - return 0; + JpegEncoder jpgEnc; +#if ADD_THUMB_IMG + int inFormat = JPG_MODESEL_YCBCR; + int outFormat = JPG_422; + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + outFormat = JPG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + outFormat = JPG_422; + break; + } + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_IN_FORMAT, inFormat) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_SAMPING_MODE, outFormat) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_QUALITY, JPG_QUALITY_LEVEL_2) != JPG_SUCCESS) + return -1; + + int thumbWidth, thumbHeight, thumbSrcSize; + getThumbnailConfig(&thumbWidth, &thumbHeight, &thumbSrcSize); + if (jpgEnc.setConfig(JPEG_SET_ENCODE_WIDTH, thumbWidth) != JPG_SUCCESS) + return -1; + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_HEIGHT, thumbHeight) != JPG_SUCCESS) + return -1; + + char *pInBuf = (char *)jpgEnc.getInBuf(thumbSrcSize); + if (pInBuf == NULL) + return -1; + memcpy(pInBuf, pThumbSrc, thumbSrcSize); + + unsigned int thumbSize; + + jpgEnc.encode(&thumbSize, NULL); + + mExifInfo.enableThumb = true; +#else + mExifInfo.enableThumb = false; +#endif + + unsigned int exifSize; + + setExifChangedAttribute(); + jpgEnc.makeExif(pExifDst, &mExifInfo, &exifSize, true); + + return exifSize; } void SecCamera::getPostViewConfig(int *width, int *height, int *size) @@ -1725,6 +1779,13 @@ void SecCamera::getPostViewConfig(int *width, int *height, int *size) m_preview_width, *width, *height, *size); } +void SecCamera::getThumbnailConfig(int *width, int *height, int *size) +{ + *width = BACK_CAMERA_THUMBNAIL_WIDTH; + *height = BACK_CAMERA_THUMBNAIL_HEIGHT; + *size = BACK_CAMERA_THUMBNAIL_WIDTH * BACK_CAMERA_THUMBNAIL_HEIGHT * BACK_CAMERA_THUMBNAIL_BPP / 8; +} + #ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA int SecCamera::getPostViewOffset(void) { @@ -1757,13 +1818,14 @@ int SecCamera::getSnapshot(unsigned char *buffer, unsigned int buffer_size) #endif -unsigned char* SecCamera::getSnapshotAndJpeg(unsigned int* output_size) +int SecCamera::getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf, + unsigned int *output_size) { LOGV("%s()", __func__); int index; //unsigned int addr; - unsigned char* addr; + unsigned char *addr; int ret = 0; LOG_TIME_DEFINE(0) @@ -1777,13 +1839,13 @@ unsigned char* SecCamera::getSnapshotAndJpeg(unsigned int* output_size) if (m_cam_fd <= 0) { LOGE("ERR(%s):Camera was closed\n", __func__); - return 0; + return -1; } if (m_flag_camera_start > 0) { - LOG_TIME_START(0) + LOG_TIME_START(0) stopPreview(); - LOG_TIME_END(0) + LOG_TIME_END(0) } memset(&m_events_c, 0, sizeof(m_events_c)); @@ -1817,27 +1879,27 @@ unsigned char* SecCamera::getSnapshotAndJpeg(unsigned int* output_size) LOGE("[zzangdol] w %d, h %d\n", m_snapshot_width, m_snapshot_height); ret = fimc_v4l2_enum_fmt(m_cam_fd,m_snapshot_v4lformat); - CHECK_PTR(ret); + CHECK(ret); ret = fimc_v4l2_s_fmt_cap(m_cam_fd, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); - CHECK_PTR(ret); + CHECK(ret); init_yuv_buffers(m_buffers_c, m_snapshot_width, m_snapshot_height, m_snapshot_v4lformat); ret = fimc_v4l2_reqbufs(m_cam_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); - CHECK_PTR(ret); + CHECK(ret); ret = fimc_v4l2_querybuf(m_cam_fd, m_buffers_c, V4L2_BUF_TYPE_VIDEO_CAPTURE, nframe); - CHECK_PTR(ret); + CHECK(ret); /* g_parm, s_parm sample */ ret = fimc_v4l2_g_parm(m_cam_fd); - CHECK_PTR(ret); + CHECK(ret); ret = fimc_v4l2_s_parm(m_cam_fd, 1, m_fps); - CHECK_PTR(ret); + CHECK(ret); ret = fimc_v4l2_qbuf(m_cam_fd, 0); - CHECK_PTR(ret); + CHECK(ret); ret = fimc_v4l2_streamon(m_cam_fd); - CHECK_PTR(ret); + CHECK(ret); LOG_TIME_END(1) LOG_TIME_START(2) // capture @@ -1852,11 +1914,7 @@ unsigned char* SecCamera::getSnapshotAndJpeg(unsigned int* output_size) #endif LOG_TIME_END(2) - //addr = getPhyAddrY(index); - addr = (unsigned char*)m_buffers_c[index].start; - if (addr == 0) { - LOGE("%s] Physical address 0"); - } + memcpy(yuv_buf, (unsigned char*)m_buffers_c[index].start, m_snapshot_width * m_snapshot_height * 2); LOG_TIME_START(5) // post fimc_v4l2_streamoff(m_cam_fd); #ifdef DUMP_YUV @@ -1867,8 +1925,62 @@ unsigned char* SecCamera::getSnapshotAndJpeg(unsigned int* output_size) LOG_CAMERA("getSnapshotAndJpeg intervals : stopPreview(%lu), prepare(%lu), " capture(%lu), memcpy(%lu), yuv2Jpeg(%lu), post(%lu) us", LOG_TIME(0), LOG_TIME(1), LOG_TIME(2), LOG_TIME(3), LOG_TIME(4), LOG_TIME(5)); + /* JPEG encoding */ + JpegEncoder jpgEnc; + int inFormat = JPG_MODESEL_YCBCR; + int outFormat = JPG_422; - return addr; + switch (m_snapshot_v4lformat) { + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV12T: + case V4L2_PIX_FMT_YUV420: + outFormat = JPG_420; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + default: + outFormat = JPG_422; + break; + } + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_IN_FORMAT, inFormat) != JPG_SUCCESS) + LOGE("[JPEG_SET_ENCODE_IN_FORMAT] Error\n"); + + if (jpgEnc.setConfig(JPEG_SET_SAMPING_MODE, outFormat) != JPG_SUCCESS) + LOGE("[JPEG_SET_SAMPING_MODE] Error\n"); + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_QUALITY, JPG_QUALITY_LEVEL_2) != JPG_SUCCESS) + LOGE("[JPEG_SET_ENCODE_QUALITY] Error\n"); + if (jpgEnc.setConfig(JPEG_SET_ENCODE_WIDTH, m_snapshot_width) != JPG_SUCCESS) + LOGE("[JPEG_SET_ENCODE_WIDTH] Error\n"); + + if (jpgEnc.setConfig(JPEG_SET_ENCODE_HEIGHT, m_snapshot_height) != JPG_SUCCESS) + LOGE("[JPEG_SET_ENCODE_HEIGHT] Error\n"); + + unsigned int snapshot_size = m_snapshot_width * m_snapshot_height * 2; + unsigned char *pInBuf = (unsigned char *)jpgEnc.getInBuf(snapshot_size); + + if (pInBuf == NULL) { + LOGE("JPEG input buffer is NULL!!\n"); + return -1; + } + memcpy(pInBuf, yuv_buf, snapshot_size); + + jpgEnc.encode(output_size, NULL); + + uint64_t outbuf_size; + unsigned char *pOutBuf = (unsigned char *)jpgEnc.getOutBuf(&outbuf_size); + + if (pOutBuf == NULL) { + LOGE("JPEG output buffer is NULL!!\n"); + return -1; + } + + memcpy(jpeg_buf, pOutBuf, outbuf_size); + + return 0; } @@ -3399,12 +3511,236 @@ int SecCamera::getJpegThumbnailSize(int *width, int *height) void SecCamera::setExifFixedAttribute() { - + //2 0th IFD TIFF Tags + //3 Maker + strcpy((char *)mExifInfo.maker, EXIF_DEF_MAKER); + //3 Model + strcpy((char *)mExifInfo.model, EXIF_DEF_MODEL); + //3 Software + property_get("ro.build.PDA", (char *)mExifInfo.software, EXIF_DEF_SOFTWARE); + //3 YCbCr Positioning + mExifInfo.ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING; + + //2 0th IFD Exif Private Tags + //3 F Number + mExifInfo.fnumber.num = EXIF_DEF_FNUMBER_NUM; + mExifInfo.fnumber.den = EXIF_DEF_FNUMBER_DEN; + //3 Exposure Program + mExifInfo.exposure_program = EXIF_DEF_EXPOSURE_PROGRAM; + //3 Exif Version + memcpy(mExifInfo.exif_version, EXIF_DEF_EXIF_VERSION, sizeof(mExifInfo.exif_version)); + //3 Aperture + uint32_t av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num/mExifInfo.fnumber.den); + mExifInfo.aperture.num = av*EXIF_DEF_APEX_DEN; + mExifInfo.aperture.den = EXIF_DEF_APEX_DEN; + //3 Maximum lens aperture + mExifInfo.max_aperture.num = mExifInfo.aperture.num; + mExifInfo.max_aperture.den = mExifInfo.aperture.den; + //3 Flash + mExifInfo.flash = EXIF_DEF_FLASH; + //3 Lens Focal Length + mExifInfo.focal_length.num = EXIF_DEF_FOCAL_LEN_NUM; + mExifInfo.focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; + //3 User Comments + strcpy((char *)mExifInfo.user_comment, EXIF_DEF_USERCOMMENTS); + //3 Color Space information + mExifInfo.color_space = EXIF_DEF_COLOR_SPACE; + //3 Exposure Mode + mExifInfo.exposure_mode = EXIF_DEF_EXPOSURE_MODE; + + //2 0th IFD GPS Info Tags + unsigned char gps_version[4] = { 0x02, 0x02, 0x00, 0x00 }; + memcpy(mExifInfo.gps_version_id, gps_version, sizeof(gps_version)); + + //2 1th IFD TIFF Tags + mExifInfo.compression_scheme = EXIF_DEF_COMPRESSION; + mExifInfo.x_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.x_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.y_resolution.num = EXIF_DEF_RESOLUTION_NUM; + mExifInfo.y_resolution.den = EXIF_DEF_RESOLUTION_DEN; + mExifInfo.resolution_unit = EXIF_DEF_RESOLUTION_UNIT; } void SecCamera::setExifChangedAttribute() { + //2 0th IFD TIFF Tags + //3 Width + mExifInfo.width = m_snapshot_width; + //3 Height + mExifInfo.height = m_snapshot_height; + //3 Orientation + switch (m_exif_orientation) { + case 0: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + case 90: + mExifInfo.orientation = EXIF_ORIENTATION_90; + break; + case 180: + mExifInfo.orientation = EXIF_ORIENTATION_180; + break; + case 270: + mExifInfo.orientation = EXIF_ORIENTATION_270; + break; + default: + mExifInfo.orientation = EXIF_ORIENTATION_UP; + break; + } + //3 Date time + time_t rawtime; + struct tm *timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + strftime((char *)mExifInfo.date_time, 20, "%Y:%m:%d %H:%M:%S", timeinfo); + + //2 0th IFD Exif Private Tags + //3 Exposure Time + int shutterSpeed = fimc_v4l2_s_ctrl(m_cam_fd, + V4L2_CID_CAMERA_GET_SHT_TIME, + 0); + mExifInfo.exposure_time.num = 1; + mExifInfo.exposure_time.den = 1000000.0 / shutterSpeed; /* us -> sec */ + + //3 ISO Speed Rating + int iso = fimc_v4l2_s_ctrl(m_cam_fd, V4L2_CID_CAMERA_GET_ISO, 0); + if (m_iso == ISO_AUTO) { + mExifInfo.iso_speed_rating = iso; + } else { + switch(m_iso) { + case ISO_50: + mExifInfo.iso_speed_rating = 50; + break; + case ISO_100: + mExifInfo.iso_speed_rating = 100; + break; + case ISO_200: + mExifInfo.iso_speed_rating = 200; + break; + case ISO_400: + mExifInfo.iso_speed_rating = 400; + break; + case ISO_800: + mExifInfo.iso_speed_rating = 800; + break; + case ISO_1600: + mExifInfo.iso_speed_rating = 1600; + break; + default: + mExifInfo.iso_speed_rating = iso; + break; + } + } + uint32_t av, tv, bv, sv, ev; + av = APEX_FNUM_TO_APERTURE((double)mExifInfo.fnumber.num / mExifInfo.fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double)mExifInfo.exposure_time.num / mExifInfo.exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(iso); + bv = av + tv - sv; + ev = av + tv; + LOGD("Shutter speed=%d us, iso=%d\n", shutterSpeed, iso); + LOGD("AV=%d, TV=%d, SV=%d\n", av, tv, sv); + + //3 Shutter Speed + mExifInfo.shutter_speed.num = tv*EXIF_DEF_APEX_DEN; + mExifInfo.shutter_speed.den = EXIF_DEF_APEX_DEN; + //3 Brightness + mExifInfo.brightness.num = bv*EXIF_DEF_APEX_DEN; + mExifInfo.brightness.den = EXIF_DEF_APEX_DEN; + //3 Exposure Bias + if (m_scene_mode == SCENE_MODE_BEACH_SNOW) { + mExifInfo.exposure_bias.num = EXIF_DEF_APEX_DEN; + mExifInfo.exposure_bias.den = EXIF_DEF_APEX_DEN; + } else { + mExifInfo.exposure_bias.num = 0; + mExifInfo.exposure_bias.den = 0; + } + //3 Metering Mode + switch (m_metering) { + case METERING_SPOT: + mExifInfo.metering_mode = EXIF_METERING_SPOT; + break; + case METERING_MATRIX: + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + case METERING_CENTER: + mExifInfo.metering_mode = EXIF_METERING_CENTER; + break; + default : + mExifInfo.metering_mode = EXIF_METERING_AVERAGE; + break; + } + //3 White Balance + if (m_white_balance == WHITE_BALANCE_AUTO) + mExifInfo.white_balance = EXIF_WB_AUTO; + else + mExifInfo.white_balance = EXIF_WB_MANUAL; + //3 Scene Capture Type + switch (m_scene_mode) { + case SCENE_MODE_PORTRAIT: + mExifInfo.scene_capture_type = EXIF_SCENE_PORTRAIT; + break; + case SCENE_MODE_LANDSCAPE: + mExifInfo.scene_capture_type = EXIF_SCENE_LANDSCAPE; + break; + case SCENE_MODE_NIGHTSHOT: + mExifInfo.scene_capture_type = EXIF_SCENE_NIGHT; + break; + default: + mExifInfo.scene_capture_type = EXIF_SCENE_STANDARD; + break; + } + + //2 0th IFD GPS Info Tags + if (m_gps_latitude != 0 && m_gps_longitude != 0) { + if (m_gps_latitude > 0) + strcpy((char *)mExifInfo.gps_latitude_ref, "N"); + else + strcpy((char *)mExifInfo.gps_latitude_ref, "S"); + + if (m_gps_longitude > 0) + strcpy((char *)mExifInfo.gps_longitude_ref, "E"); + else + strcpy((char *)mExifInfo.gps_longitude_ref, "W"); + + if (m_gps_altitude > 0) + mExifInfo.gps_altitude_ref = 0; + else + mExifInfo.gps_altitude_ref = 1; + + double latitude = fabs(m_gps_latitude / 10000.0); + double longitude = fabs(m_gps_longitude / 10000.0); + double altitude = fabs(m_gps_altitude / 100.0); + + mExifInfo.gps_latitude[0].num = (uint32_t)latitude; + mExifInfo.gps_latitude[0].den = 1; + mExifInfo.gps_latitude[1].num = (uint32_t)((latitude - mExifInfo.gps_latitude[0].num) * 60); + mExifInfo.gps_latitude[1].den = 1; + mExifInfo.gps_latitude[2].num = (uint32_t)((((latitude - mExifInfo.gps_latitude[0].num) * 60) + - mExifInfo.gps_latitude[1].num) * 60); + mExifInfo.gps_latitude[2].den = 1; + + mExifInfo.gps_longitude[0].num = (uint32_t)longitude; + mExifInfo.gps_longitude[0].den = 1; + mExifInfo.gps_longitude[1].num = (uint32_t)((longitude - mExifInfo.gps_longitude[0].num) * 60); + mExifInfo.gps_longitude[1].den = 1; + mExifInfo.gps_longitude[2].num = (uint32_t)((((longitude - mExifInfo.gps_longitude[0].num) * 60) + - mExifInfo.gps_longitude[1].num) * 60); + mExifInfo.gps_longitude[2].den = 1; + + mExifInfo.gps_altitude.num = (uint32_t)altitude; + mExifInfo.gps_altitude.den = 1; + + mExifInfo.enableGps = true; + } else { + mExifInfo.enableGps = false; + } + + //2 1th IFD TIFF Tags + int thumbWidth, thumbHeight, thumbSrcSize; + + getThumbnailConfig(&thumbWidth, &thumbHeight, &thumbSrcSize); + mExifInfo.widthThumb = thumbWidth; + mExifInfo.heightThumb = thumbHeight; } // ====================================================================== @@ -3453,4 +3789,7 @@ status_t SecCamera::dump(int fd, const Vector<String16> &args) return NO_ERROR; } +double SecCamera::jpeg_ratio = 0.7; +int SecCamera::interleaveDataSize = 4261248; + }; // namespace android diff --git a/libcamera/SecCamera.h b/libcamera/SecCamera.h index 87985d7..282eda7 100644 --- a/libcamera/SecCamera.h +++ b/libcamera/SecCamera.h @@ -37,6 +37,8 @@ #include <videodev2_samsung.h> #endif +#include "JpegEncoder.h" + #ifdef ENABLE_HDMI_DISPLAY #include "hdmi_lib.h" #endif @@ -108,6 +110,10 @@ namespace android { #define ISX006_POSTVIEW_HEIGHT 480 #define ISX006_POSTVIEW_BPP 16 +#define ISX006_THUMBNAIL_WIDTH 320 +#define ISX006_THUMBNAIL_HEIGHT 240 +#define ISX006_THUMBNAIL_BPP 16 + #define VGA_PREVIEW_WIDTH 640 #define VGA_PREVIEW_HEIGHT 480 #define VGA_SNAPSHOT_WIDTH 640 @@ -121,6 +127,9 @@ namespace android { #define BACK_CAMERA_POSTVIEW_WIDE_WIDTH JOIN(BACK_CAM,_POSTVIEW_WIDE_WIDTH) #define BACK_CAMERA_POSTVIEW_HEIGHT JOIN(BACK_CAM,_POSTVIEW_HEIGHT) #define BACK_CAMERA_POSTVIEW_BPP JOIN(BACK_CAM,_POSTVIEW_BPP) +#define BACK_CAMERA_THUMBNAIL_WIDTH JOIN(BACK_CAM,_THUMBNAIL_WIDTH) +#define BACK_CAMERA_THUMBNAIL_HEIGHT JOIN(BACK_CAM,_THUMBNAIL_HEIGHT) +#define BACK_CAMERA_THUMBNAIL_BPP JOIN(BACK_CAM,_THUMBNAIL_BPP) #define MAX_FRONT_CAMERA_PREVIEW_WIDTH JOIN(FRONT_CAM,_PREVIEW_WIDTH) #define MAX_FRONT_CAMERA_PREVIEW_HEIGHT JOIN(FRONT_CAM,_PREVIEW_HEIGHT) @@ -715,12 +724,14 @@ public: void setFrameRate(int frame_rate); // void setJpegQuality(int quality); unsigned char* getJpeg(int*, unsigned int*); - unsigned char* getSnapshotAndJpeg(unsigned int *output_size); + int getSnapshotAndJpeg(unsigned char *yuv_buf, unsigned char *jpeg_buf, + unsigned int *output_size); int getExif(unsigned char *pExifDst, unsigned char *pThumbSrc); #ifdef JPEG_FROM_SENSOR void getPostViewConfig(int*, int*, int*); #endif + void getThumbnailConfig(int *width, int *height, int *size); #ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA int getPostViewOffset(void); @@ -736,6 +747,28 @@ public: void pausePreview(); int initCamera(int index); void DeinitCamera(); + static void setJpegRatio(double ratio) + { + if((ratio < 0) || (ratio > 1)) + return; + + jpeg_ratio = ratio; + } + + static double getJpegRatio() + { + return jpeg_ratio; + } + + static void setInterleaveDataSize(int x) + { + interleaveDataSize = x; + } + + static int getInterleaveDataSize() + { + return interleaveDataSize; + } private: int m_flag_init; @@ -819,6 +852,8 @@ private: int m_postview_offset; + exif_attribute_t mExifInfo; + struct fimc_buffer m_buffers_c[MAX_BUFFERS]; struct pollfd m_events_c; @@ -827,6 +862,9 @@ private: void setExifChangedAttribute(); void setExifFixedAttribute(); void resetCamera(); + + static double jpeg_ratio; + static int interleaveDataSize; }; extern unsigned long measure_time(struct timeval *start, struct timeval *stop); diff --git a/libcamera/SecCameraHWInterface.cpp b/libcamera/SecCameraHWInterface.cpp index 98f8aee..3df798f 100644 --- a/libcamera/SecCameraHWInterface.cpp +++ b/libcamera/SecCameraHWInterface.cpp @@ -359,7 +359,7 @@ CameraHardwareSec::~CameraHardwareSec() mRecordHeap.clear(); #if defined(BOARD_USES_OVERLAY) - if(mUseOverlay) { + if (mUseOverlay) { mOverlay->destroy(); mUseOverlay = false; mOverlay = NULL; @@ -1016,6 +1016,70 @@ void CameraHardwareSec::save_postview(const char *fname, uint8_t *buf, uint32_t ::close(fd); } +bool CameraHardwareSec::scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHeight, + char *dstBuf, uint32_t dstWidth, uint32_t dstHeight) +{ + int32_t step_x, step_y; + int32_t iXsrc, iXdst; + int32_t x, y, src_y_start_pos, dst_pos, src_pos; + + if (dstWidth % 2 != 0 || dstHeight % 2 != 0){ + LOGE("scale_down_yuv422: invalid width, height for scaling"); + return false; + } + + step_x = srcWidth / dstWidth; + step_y = srcHeight / dstHeight; + + dst_pos = 0; + for (uint32_t y = 0; y < dstHeight; y++) { + src_y_start_pos = (y * step_y * (srcWidth * 2)); + + for (uint32_t x = 0; x < dstWidth; x += 2) { + src_pos = src_y_start_pos + (x * (step_x * 2)); + + dstBuf[dst_pos++] = srcBuf[src_pos ]; + dstBuf[dst_pos++] = srcBuf[src_pos + 1]; + dstBuf[dst_pos++] = srcBuf[src_pos + 2]; + dstBuf[dst_pos++] = srcBuf[src_pos + 3]; + } + } + + return true; +} + +bool CameraHardwareSec::YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight) +{ + int32_t x, y, src_y_start_pos, dst_cbcr_pos, dst_pos, src_pos; + unsigned char *srcBufPointer = (unsigned char *)srcBuf; + unsigned char *dstBufPointer = (unsigned char *)dstBuf; + + dst_pos = 0; + dst_cbcr_pos = srcWidth*srcHeight; + for (uint32_t y = 0; y < srcHeight; y++) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 2) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_pos++] = srcBufPointer[src_pos]; + } + } + for (uint32_t y = 0; y < srcHeight; y += 2) { + src_y_start_pos = (y * (srcWidth * 2)); + + for (uint32_t x = 0; x < (srcWidth * 2); x += 4) { + src_pos = src_y_start_pos + x; + + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 3]; + dstBufPointer[dst_cbcr_pos++] = srcBufPointer[src_pos + 1]; + } + } + + return true; +} + + int CameraHardwareSec::pictureThread() { LOGV("%s()", __func__); @@ -1029,16 +1093,22 @@ int CameraHardwareSec::pictureThread() //unsigned int addr; unsigned char *addr = NULL; int mPostViewWidth, mPostViewHeight, mPostViewSize; + int mThumbWidth, mThumbHeight, mThumbSize; int cap_width, cap_height, cap_frame_size; unsigned int output_size = 0; mSecCamera->getPostViewConfig(&mPostViewWidth, &mPostViewHeight, &mPostViewSize); - //*size = (BACK_CAMERA_POSTVIEW_WIDTH * BACK_CAMERA_POSTVIEW_HEIGHT * BACK_CAMERA_POSTVIEW_BPP) / 8; - int postviewHeapSize = mPostViewWidth * mPostViewHeight * 2; + mSecCamera->getThumbnailConfig(&mThumbWidth, &mThumbHeight, &mThumbSize); + int postviewHeapSize = mPostViewSize; mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); - LOGE("[kidggang]:func(%s):line(%d)&cap_width(%d), &cap_height(%d), &cap_frame_size(%d)\n", - __func__,__LINE__,cap_width, cap_height, cap_frame_size); + int mJpegHeapSize; + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) + mJpegHeapSize = cap_frame_size * mSecCamera->getJpegRatio(); + else + mJpegHeapSize = cap_frame_size; + LOGE("[kidggang]:func(%s):line(%d)&cap_width(%d), &cap_height(%d), &cap_frame_size(%d), mJpegHeapSize(%d)\n", + __func__,__LINE__,cap_width, cap_height, cap_frame_size, mJpegHeapSize); // sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, postviewHeapSize); @@ -1069,6 +1139,10 @@ int CameraHardwareSec::pictureThread() #endif }//[zzangdol]CAMERA_ID_BACK + sp<MemoryHeapBase> JpegHeap = new MemoryHeapBase(mJpegHeapSize); + sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBase(mPostViewSize); + sp<MemoryHeapBase> ThumbnailHeap = new MemoryHeapBase(mThumbSize); + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { LOG_TIME_DEFINE(1) LOG_TIME_START(1) @@ -1095,20 +1169,22 @@ int CameraHardwareSec::pictureThread() ret = UNKNOWN_ERROR; } } else { - addr = mSecCamera->getSnapshotAndJpeg(&output_size); - //LOGV("[zzangdol] getSnapshotAndJpeg\n"); + if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(), + (unsigned char*)JpegHeap->base(), &output_size) < 0) + return UNKNOWN_ERROR; + LOGE("snapshotandjpeg done\n"); } #else phyAddr = mSecCamera->getSnapshotAndJpeg(); + if (phyAddr < 0) + return UNKNOWN_ERROR; + jpeg_data = mSecCamera->yuv2Jpeg((unsigned char*)phyAddr, 0, &jpeg_size, - picture_width, picture_height, picture_format); + picture_width, picture_height, picture_format); #endif -#ifdef DIRECT_DELIVERY_OF_POSTVIEW_DATA - postview_offset = mSecCamera->getPostViewOffset(); - if (jpeg_data != NULL) - memcpy(mRawHeap->base(), jpeg_data + postview_offset, mPostViewSize); -#else +#ifndef DIRECT_DELIVERY_OF_POSTVIEW_DATA + addrs[0].addr_y = phyAddr; #endif @@ -1118,17 +1194,61 @@ int CameraHardwareSec::pictureThread() int JpegImageSize, JpegExifSize; - sp<MemoryHeapBase> PostviewHeap = new MemoryHeapBase(mPostViewSize); - sp<MemoryHeapBase> JpegHeap = new MemoryHeapBase(4300000); - decodeInterleaveData(jpeg_data, 4261248, mPostViewWidth, mPostViewHeight, - &JpegImageSize, JpegHeap->base(), PostviewHeap->base()); + if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) { + decodeInterleaveData(jpeg_data, SecCamera::getInterleaveDataSize(), mPostViewWidth, mPostViewHeight, + &JpegImageSize, JpegHeap->base(), PostviewHeap->base()); + scaleDownYuv422((char *)PostviewHeap->base(), mPostViewWidth, mPostViewHeight, + (char *)ThumbnailHeap->base(), mThumbWidth, mThumbHeight); + } + +#ifdef POSTVIEW_CALLBACK sp<MemoryBase> postview = new MemoryBase(PostviewHeap, 0, postviewHeapSize); +#endif memcpy(mRawHeap->base(),PostviewHeap->base(), postviewHeapSize); + + /* Put postview image to Overlay */ + unsigned int index = 0; + unsigned int offset = ((mPostViewWidth*mPostViewHeight*3/2) + 16) * index; + unsigned int overlay_header[4]; + buf_idx ^= 1; + overlay_header[0]= mSecCamera->getPhyAddrY(index); + overlay_header[1]= overlay_header[0] + mPostViewWidth*mPostViewHeight; + overlay_header[2]= buf_idx; + + YUY2toNV21(mRawHeap->base(), (void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + offset), + mPostViewWidth, mPostViewHeight); + + memcpy(static_cast<unsigned char*>(mPreviewHeap->base()) + offset + (mPostViewWidth*mPostViewHeight * 3 / 2), + overlay_header, 16); + + ret = mOverlay->queueBuffer((void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + offset + + (mPostViewWidth*mPostViewHeight * 3 / 2))); + + if (ret == ALL_BUFFERS_FLUSHED) { + LOGE("%s ALL_BUFFERS_FLUSHED",__func__); + goto PostviewOverlayEnd; + } else if (ret == -1) { + LOGE("ERR(%s):overlay queueBuffer fail", __func__); + goto PostviewOverlayEnd; + } + + overlay_buffer_t overlay_buffer; + ret = mOverlay->dequeueBuffer(&overlay_buffer); + + if (ret == ALL_BUFFERS_FLUSHED) { + LOGE("%s ALL_BUFFERS_FLUSHED",__func__); + goto PostviewOverlayEnd; + } else if (ret == -1) { + LOGE("ERR(%s):overlay dequeueBuffer fail", __func__); + goto PostviewOverlayEnd; + } + +PostviewOverlayEnd: if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { mDataCb(CAMERA_MSG_RAW_IMAGE, buffer, mCallbackCookie); } -#if 0//def SWP1_CAMERA_ADD_ADVANCED_FUNCTION +#ifdef POSTVIEW_CALLBACK if (mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) { int postviewHeapSize = mPostViewSize; sp<MemoryHeapBase> mPostviewHeap = new MemoryHeapBase(postviewHeapSize); @@ -1141,18 +1261,18 @@ int CameraHardwareSec::pictureThread() mDataCb(CAMERA_MSG_POSTVIEW_FRAME, postview, mCallbackCookie); } -#endif //#ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION - +#endif if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { if (mSecCamera->getCameraId() == SecCamera::CAMERA_ID_BACK) { - const int EXIF_FILE_SIZE = 28800; - const int JPG_STREAM_BUF_SIZE = 3145728; - sp<MemoryHeapBase> ExifHeap = new MemoryHeapBase(EXIF_FILE_SIZE + JPG_STREAM_BUF_SIZE); - JpegExifSize = mSecCamera->getExif ((unsigned char *)ExifHeap->base(), - (unsigned char *)PostviewHeap->base()); + JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->base(), + (unsigned char *)ThumbnailHeap->base()); LOGE("JpegExifSize=%d", JpegExifSize); + + if (JpegExifSize < 0) + return UNKNOWN_ERROR; + unsigned char *ExifStart = (unsigned char *)JpegHeap->base() + 2; unsigned char *ImageStart = ExifStart + JpegExifSize; @@ -1163,12 +1283,8 @@ int CameraHardwareSec::pictureThread() mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie); } else { LOGV("[zzangdol] COMPRESSED_IMAGE\n"); - //mSecCamera->getSnapshotSize(&cap_width, &cap_height, &cap_frame_size); - //sp<MemoryHeapBase> mHeap = new MemoryHeapBase((int)mSecCamera->getCameraFd(), (size_t)(cap_frame_size * kBufferCount), (uint32_t)0); - sp<MemoryHeapBase> mHeap = new MemoryHeapBase(2000000); - memcpy(mHeap->base(), addr, cap_frame_size); - sp<MemoryBase> mem = new MemoryBase(mHeap , 0, cap_frame_size); - //save_postview("/data/front.yuv", (uint8_t *)mHeap->base(), yuv_frame_size2); + //memcpy(JpegHeap->base(), addr, output_size); + sp<MemoryBase> mem = new MemoryBase(JpegHeap , 0, output_size); mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);//[zzangdol] } } @@ -1397,8 +1513,6 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) new_picture_format = V4L2_PIX_FMT_UYVY; else if (strcmp(new_str_picture_format, CameraParameters::PIXEL_FORMAT_JPEG) == 0) #ifdef JPEG_FROM_SENSOR - new_picture_format = V4L2_PIX_FMT_UYVY; -#else new_picture_format = V4L2_PIX_FMT_YUYV; #endif else if (strcmp(new_str_picture_format, "yuv422p") == 0) @@ -1477,30 +1591,11 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) int new_rotation = params.getInt(CameraParameters::KEY_ROTATION); int new_exif_rotation = 1; - if (new_rotation != -1) { - if (new_vtmode == SecCamera::VT_MODE_ON ) { - LOGE("ERR(%s):VT mode is on. Rotate(%d))", __func__, new_rotation); - - if (mSecCamera->SetRotate(new_rotation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __func__, new_rotation); - ret = UNKNOWN_ERROR; - } - } else { - if (mSecCamera->SetRotate(0) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->SetRotate(rotation(%d))", __func__, new_rotation); - ret = UNKNOWN_ERROR; - } - - if (new_rotation == 0) - new_exif_rotation = 1; - else if (new_rotation == 90) - new_exif_rotation = 6; - else if (new_rotation == 180) - new_exif_rotation = 3; - else if (new_rotation == 270) - new_exif_rotation = 8; - else - new_exif_rotation = 1; + if (0 <= new_rotation) { + LOGE("mingyu:set orientation:%d\n", new_rotation); + if (mSecCamera->setExifOrientationInfo(new_rotation) < 0) { + LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_rotation); + ret = UNKNOWN_ERROR; } } @@ -2215,16 +2310,6 @@ status_t CameraHardwareSec::setParameters(const CameraParameters& params) } } - //exif orientation info - int new_exif_orientation = params.getInt("exifOrientation"); - - if (0 <= new_exif_orientation) { - if (mSecCamera->setExifOrientationInfo(new_exif_orientation) < 0) { - LOGE("ERR(%s):Fail on mSecCamera->setExifOrientationInfo(%d)", __func__, new_exif_orientation); - ret = UNKNOWN_ERROR; - } - } - /*Camcorder fix fps*/ int new_sensor_mode = params.getInt("cam_mode"); diff --git a/libcamera/SecCameraHWInterface.h b/libcamera/SecCameraHWInterface.h index 3a4c509..7a151e7 100644 --- a/libcamera/SecCameraHWInterface.h +++ b/libcamera/SecCameraHWInterface.h @@ -156,6 +156,9 @@ private: int *pJpegSize, void *pJpegData, void *pYuvData); + bool YUY2toNV21(void *srcBuf, void *dstBuf, uint32_t srcWidth, uint32_t srcHeight); + bool scaleDownYuv422(char *srcBuf, uint32_t srcWidth, uint32_t srcHight, + char *dstBuf, uint32_t dstWidth, uint32_t dstHight); #ifdef SWP1_CAMERA_ADD_ADVANCED_FUNCTION static int beginObjectTrackingThread(void *cookie); |