summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2010-09-24 20:12:54 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-09-24 20:12:54 -0700
commit1e521da356b6dff8ea870e7bfbb792256318f3a1 (patch)
tree53447543aaac48acc38f7136c6e7ad86b49868ce
parent4e3b07af1b550ba541cade2b4e4cf24d6d4c6d3d (diff)
parentd7f2c96de954376e7460388c2205a7cc7775a525 (diff)
downloaddevice_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.mk3
-rw-r--r--libcamera/SecCamera.cpp383
-rw-r--r--libcamera/SecCamera.h40
-rw-r--r--libcamera/SecCameraHWInterface.cpp219
-rw-r--r--libcamera/SecCameraHWInterface.h3
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);