From c43657fcf11be71081a505b49dff907d60ac3b00 Mon Sep 17 00:00:00 2001 From: Guosong Zhou Date: Tue, 12 Sep 2017 10:40:15 +0000 Subject: camera: add camera module[1/3] PD# 146466 add android O camera hal Change-Id: Ic52852627125b8107668d5493dacc152e80b573e Signed-off-by: Guosong Zhou --- diff --git a/v3/Android.mk b/v3/Android.mk index 4f465b7..11385c3 100644 --- a/v3/Android.mk +++ b/v3/Android.mk @@ -56,7 +56,6 @@ LOCAL_SHARED_LIBRARIES:= \ libui \ libdl \ libjpeg \ - libjhead \ libexpat \ libexif @@ -124,7 +123,6 @@ LOCAL_SRC_FILES := \ EmulatedFakeCamera3Info.cpp \ fake-pipeline2/camera_hw.cpp \ VendorTags.cpp \ - LoadXml.cpp \ ifeq ($(TARGET_PRODUCT),vbox_x86) LOCAL_MODULE := camera.vbox_x86 @@ -132,6 +130,10 @@ else LOCAL_MODULE:= camera.amlogic endif +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + include $(BUILD_SHARED_LIBRARY) include $(call all-makefiles-under,$(LOCAL_PATH)) @@ -176,6 +178,10 @@ LOCAL_SRC_FILES := JpegStub.cpp LOCAL_MODULE := camera.goldfish.jpeg +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK) +LOCAL_PROPRIETARY_MODULE := true +endif + include $(BUILD_SHARED_LIBRARY) endif # !PDK diff --git a/v3/EmulatedFakeCamera3.cpp b/v3/EmulatedFakeCamera3.cpp index 41d8c0b..6e2b39f 100644 --- a/v3/EmulatedFakeCamera3.cpp +++ b/v3/EmulatedFakeCamera3.cpp @@ -194,7 +194,6 @@ EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, struct hw_module_t* modul mFlushTag = false; mPlugged = false; - gLoadXml.parseXMLFile(); } EmulatedFakeCamera3::~EmulatedFakeCamera3() { @@ -405,8 +404,6 @@ status_t EmulatedFakeCamera3::closeCamera() { status_t EmulatedFakeCamera3::getCameraInfo(struct camera_info *info) { char property[PROPERTY_VALUE_MAX]; - char* tempApkName = gLoadXml.getApkPackageName(IPCThreadState::self()->getCallingPid()); - List_Or * temp=new List_Or(); info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT; if (mSensorType == SENSOR_USB) { if (mFacingBack) { @@ -415,15 +412,6 @@ status_t EmulatedFakeCamera3::getCameraInfo(struct camera_info *info) { property_get("hw.camera.orientation.front", property, "0"); } int32_t orientation = atoi(property); - - if (gLoadXml.findApkCp(tempApkName, temp)) { - orientation = atoi(temp->pro); - } - if (temp != NULL) { - delete temp; - temp = NULL; - } - property_get("hw.camera.usb.orientation_offset", property, "0"); orientation += atoi(property); orientation %= 360; @@ -530,6 +518,18 @@ status_t EmulatedFakeCamera3::configureStreams( newStream->stream_type, newStream->max_buffers, isRestart); } + + if ((newStream->width == 0) || (newStream->width == UINT32_MAX) || + (newStream->height == 0) || (newStream->height == UINT32_MAX)) { + ALOGE("invalid width or height. \n"); + return -EINVAL; + } + + if (newStream->rotation == UINT32_MAX) { + ALOGE("invalid StreamRotation. \n"); + return -EINVAL; + } + ALOGV("%s: Stream %p (id %zu), type %d, usage 0x%x, format 0x%x", __FUNCTION__, newStream, i, newStream->stream_type, newStream->usage, @@ -562,11 +562,12 @@ status_t EmulatedFakeCamera3::configureStreams( if (!validFormat) { ALOGE("%s: Unsupported stream format 0x%x requested", __FUNCTION__, newStream->format); - return BAD_VALUE; + return -EINVAL; } status_t ret = checkValidJpegSize(newStream->width, newStream->height); if (ret != OK) { + ALOGE("Invalid Jpeg Size. \n"); return BAD_VALUE; } @@ -2013,7 +2014,7 @@ status_t EmulatedFakeCamera3::constructStaticInfo() { static const int32_t availableTargetFpsRanges[] = { - 5, 15, 15, 15, 5, 25, 25, 25, 5, 30, 30, 30, + 5, 15, 15, 15, 5, 20, 20, 20, 5, 25, 25, 25, 5, 30, 30, 30, }; info.update(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, availableTargetFpsRanges, diff --git a/v3/EmulatedFakeCamera3.h b/v3/EmulatedFakeCamera3.h index 83ea133..a4f1a3d 100644 --- a/v3/EmulatedFakeCamera3.h +++ b/v3/EmulatedFakeCamera3.h @@ -30,7 +30,7 @@ #include #include #include -#include + namespace android { @@ -215,8 +215,6 @@ private: /* Full mode (true) or limited mode (false) switch */ bool mFullMode; - LoadXml gLoadXml; - enum sensor_type_e mSensorType; /** diff --git a/v3/LoadXml.cpp b/v3/LoadXml.cpp deleted file mode 100644 index 3d7ed01..0000000 --- a/v3/LoadXml.cpp +++ b/dev/null @@ -1,208 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "LoadXml.h" -namespace android { - -char* LoadXml::getApkPackageName(int callingPid) { - cameraCallProcess[0] = 0x00; - sprintf(cameraCallProcess,"/proc/%d/cmdline",callingPid); - int id = open(cameraCallProcess, O_RDONLY); - if (id < 0) { - memset(cameraCallProcess,0x00,sizeof(cameraCallProcess)); - } else { - memset(cameraCallProcess,0x00,sizeof(cameraCallProcess)); - read(id, cameraCallProcess, 64); - close(id); - id = -1; - } - return cameraCallProcess; -} - -int LoadXml::destroyList_Open(List_Open *head) { - List_Open *p; - if (head == NULL) { - return 0; - } - while (head) { - p = head->next; - delete head; - head = NULL; - head = p; - } - return 1; -} - -int LoadXml::destroyList_Or(List_Or *head) { - List_Or *p; - if (head == NULL) { - return 0; - } - while (head) { - p = head->next; - delete head; - head = NULL; - head = p; - } - return 1; -} - -List_Or::~List_Or() { - delete apk_name; - apk_name = NULL; - delete pro; - pro = NULL; - delete capo; - capo = NULL; -} - -List_Open::~List_Open() { - delete apk_name; - apk_name = NULL; - delete camera_number; - camera_number = NULL; -} - -LoadXml::~LoadXml() { - destroyList_Open(Lo_Head); - destroyList_Or(Lr_Head); -} - -List_Open::List_Open(char const* apk,char const*camera) { - apk_name = new char[strlen(apk) + 1]; - strcpy(apk_name, apk); - camera_number = new char[strlen(camera) + 1]; - strcpy(camera_number, camera); -} - -List_Or::List_Or(char const* apk,char const* pr,char const* cap) { - apk_name=new char[strlen(apk) + 1]; - strcpy(apk_name, apk); - pro=new char[strlen(pr) + 1]; - strcpy(pro, pr); - capo=new char[strlen(cap) + 1]; - strcpy(capo, cap); -} - -List_Or::List_Or() { - apk_name = NULL; - pro = NULL; - capo = NULL; -} - -LoadXml::LoadXml() { - Lo_Head = NULL; - Lr_Head = NULL; - indent = 0; -} - -bool LoadXml::findApkOp(char * apk_name) { - List_Open* Lo_temp = Lo_Head; - while (Lo_temp != NULL) { - if (!strcmp(Lo_temp->apk_name,apk_name)) { - return true; - } - Lo_temp = Lo_temp->next; - } - return false; -} - -int LoadXml::findApkCp(char * apk_name,List_Or* temp) { - List_Or* Lr_temp = Lr_Head; - while (Lr_temp != NULL) { - if (!strcmp(Lr_temp->apk_name, apk_name)) { - temp->apk_name = new char[strlen(Lr_temp->apk_name) + 1]; - strcpy(temp->apk_name, Lr_temp->apk_name); - temp->pro = new char[strlen(Lr_temp->pro) + 1]; - strcpy(temp->pro, Lr_temp->pro); - temp->capo = new char[strlen(Lr_temp->capo) + 1]; - strcpy(temp->capo, Lr_temp->capo); - return 1; - } - Lr_temp = Lr_temp->next; - } - return 0; -} - -void LoadXml::print() { - List_Open* Lo_temp = Lo_Head; - List_Or* Lr_temp = Lr_Head; - while (Lo_temp != NULL) { - Lo_temp = Lo_temp->next; - } - while (Lr_temp != NULL) { - Lr_temp = Lr_temp->next; - } -} - -// static -void LoadXml::StartElementHandlerWrapper (void *data ,const char *name, const char **attrs) { - static_cast(data)->startElementHandler(name, attrs); -} - -// static -void LoadXml::EndElementHandlerWrapper(void *me, const char *name) { - static_cast(me)->endElementHandler(name); -} - -void LoadXml::startElementHandler(const char *name, const char **attrs) { - int i; - int j; - List_Open* q = NULL; - List_Or* l = NULL; - if (attrs[4] == NULL) { - for (i = 0; attrs[i]; i += 4) { - q = new List_Open(attrs[i + 1], attrs[i + 3]); - q->next = Lo_Head; - Lo_Head = q; - } - }else{ - for (j = 0; attrs[j]; j += 6) { - l = new List_Or(attrs[j + 1], attrs[j + 3], attrs[j + 5]); - l->next = Lr_Head; - Lr_Head = l; - } - } - ++indent; -} - -void LoadXml::endElementHandler(const char *name) { - --indent; -} - -void LoadXml::parseXMLFile() { - FILE* fp; - const int BUFF_SIZE = 1024; - const char* filename = "/etc/Third_party_apk_camera.xml"; - if ((fp = fopen(filename, "r")) == NULL) { - return ; - } - if (NULL == fp) { - return; - } - XML_Parser parser = ::XML_ParserCreate(NULL); - ::XML_SetUserData(parser, this); - ::XML_SetElementHandler(parser, StartElementHandlerWrapper, EndElementHandlerWrapper); - void *buff = ::XML_GetBuffer(parser, BUFF_SIZE); - if (buff == NULL) { - //LOG1("failed to in call to XML_GetBuffer()"); - } - int bytes_read = ::fread(buff, 1, BUFF_SIZE, fp); - if (bytes_read < 0) { - //LOG1("failed in call to read"); - } - if (::XML_ParseBuffer(parser, bytes_read, bytes_read == 0)!= XML_STATUS_OK) { - //LOG1("failed parser xml"); - } - ::XML_ParserFree(parser); - fclose(fp); - fp=NULL; -} -} - diff --git a/v3/LoadXml.h b/v3/LoadXml.h deleted file mode 100644 index c25971d..0000000 --- a/v3/LoadXml.h +++ b/dev/null @@ -1,48 +0,0 @@ -#ifndef ANDROID_SERVERS_CAMERA_FINDAPK_H -#define ANDROID_SERVERS_CAMERA_FINDAPK_H -namespace android { -class List_Open -{ -public: - List_Open(char const* apk,char const*camera); - ~List_Open(); - char* apk_name; - char* camera_number; - List_Open* next; -}; -class List_Or -{ -public: - List_Or(char const*apk,char const*pr,char const* cap); - List_Or(); - ~List_Or(); - char* apk_name; - char* pro; //preview oritation - char* capo; //capture oritation - List_Or* next; -}; -class LoadXml -{ -public: - char* getApkPackageName(int callingPid); - int findApkCp(char * apk_name, List_Or* temp); - bool findApkOp(char * apk_name); - void print(); - int destroyList_Or(List_Or *head); - int destroyList_Open(List_Open *head); - void parseXMLFile(); - static void StartElementHandlerWrapper(void *data,const char *name, const char **attrs); - static void EndElementHandlerWrapper(void *me, const char *name); - void startElementHandler(const char *name, const char **attrs); - void endElementHandler(const char *name); - LoadXml(); - ~LoadXml(); -private: - char cameraCallProcess[64]; - int callingId; - List_Open* Lo_Head; - List_Or* Lr_Head; - int indent; -}; -} -#endif diff --git a/v3/QemuClient.h b/v3/QemuClient.h index 1644321..df92180 100755..100644 --- a/v3/QemuClient.h +++ b/v3/QemuClient.h @@ -22,7 +22,7 @@ * in the emulator via qemu pipe. */ -#include +#include "qemud.h" namespace android { diff --git a/v3/fake-pipeline2/JpegCompressor.cpp b/v3/fake-pipeline2/JpegCompressor.cpp index 6a24882..2ef5c8b 100644 --- a/v3/fake-pipeline2/JpegCompressor.cpp +++ b/v3/fake-pipeline2/JpegCompressor.cpp @@ -220,54 +220,6 @@ status_t JpegCompressor::readyToRun() { return OK; } -status_t JpegCompressor::Create_Exif_Use_Libjpeg() { - ExifElementsTable* exiftable = NULL; - struct camera2_jpeg_blob blob; - int offset; - status_t res; - if (mNeedexif) { - memset(&blob,0,sizeof(struct camera2_jpeg_blob)); - exiftable = new ExifElementsTable(); - GenExif(exiftable); - } - - if (mJpegRequest.mNeedThumbnail) { - res = thumbcompress(); - } - - if (exiftable) { - uint32_t realjpegsize = 0; - Section_t* exif_section = NULL; - ExifElementsTable* exif = exiftable; - exif->insertExifToJpeg((unsigned char*)mJpegBuffer.img,mMainJpegSize); - if ((mJpegRequest.mNeedThumbnail) && (mDstThumbBuffer != NULL)) { - exif->insertExifThumbnailImage((const char*)mDstThumbBuffer,mThumbJpegSize); - } - exif_section = FindSection(M_EXIF); - if (exif_section) { - exif->saveJpeg((unsigned char*) mJpegBuffer.img, mMainJpegSize + exif_section->Size); - } - for (uint32_t size = (mMainJpegSize + exif_section->Size - 2); size > 0; size--) { - if (checkJpegEnd(mJpegBuffer.img + size)) { - realjpegsize = (size + MARKER_LENGTH); - break; - } - } - offset = mMaxbufsize-sizeof(struct camera2_jpeg_blob); - blob.jpeg_blob_id = 0x00FF; - blob.jpeg_size = realjpegsize; - memcpy(mJpegBuffer.img+offset, &blob, sizeof(struct camera2_jpeg_blob)); - } - - if (mNeedexif) { - if (exiftable != NULL) { - delete exiftable; - exiftable = NULL; - } - } - return res; -} - status_t JpegCompressor::Create_Exif_Use_Libexif() { struct camera2_jpeg_blob blob; int offset; @@ -449,11 +401,7 @@ bool JpegCompressor::threadLoop() { res = compress(); -#if PLATFORM_SDK_VERSION <= 22 - Create_Exif_Use_Libjpeg(); -#else Create_Exif_Use_Libexif(); -#endif mListener->onJpegDone(mJpegBuffer, res == OK, mJpegRequest); @@ -939,166 +887,6 @@ void JpegCompressor::SetExifInfo(struct ExifInfo info) { memcpy(&mInfo, &info, sizeof(struct ExifInfo)); } -int JpegCompressor::GenExif(ExifElementsTable* exiftable) -{ - char exifcontent[256]; - int width,height; - bool newexif = true; //add new exif tag for cts - float exposuretime = 1.0; - float ApertureValue = 1.0; - int flash = 0; - int whitebalance = 1; - int iso = 100; - char SubSecTime[10] = "63"; - char SubSecTimeOrig[10]= "63"; - char SubSecTimeDig[10]= "63"; - char property[PROPERTY_VALUE_MAX]; - - property_get("ro.product.manufacturer", property, EXIF_MAKE_DEFAULT); - exiftable->insertElement("Make",property); - property_get("ro.product.model", property, EXIF_MODEL_DEFAULT); - exiftable->insertElement("Model",property); -// int orientation = mInfo.orientation; - width = mInfo.mainwidth; - height = mInfo.mainheight; -#if 0 - if (orientation == 0) - orientation = 1; - else if (orientation == 90) - orientation = 6; - else if (orientation == 180) - orientation = 3; - else if (orientation == 270) - orientation = 8; - sprintf(exifcontent,"%d",orientation); - exiftable->insertElement("Orientation",(const char*)exifcontent); -#endif - sprintf(exifcontent,"%d",width); - exiftable->insertElement("ImageWidth",(const char*)exifcontent); - sprintf(exifcontent,"%d",height); - exiftable->insertElement("ImageLength",(const char*)exifcontent); - - sprintf(exifcontent,"%f",exposuretime); - exiftable->insertElement("ExposureTime",(const char*)exifcontent); - sprintf(exifcontent,"%f",ApertureValue); - exiftable->insertElement("ApertureValue",(const char*)exifcontent); - sprintf(exifcontent,"%d",flash); - exiftable->insertElement("Flash",(const char*)exifcontent); - sprintf(exifcontent,"%d",whitebalance); - exiftable->insertElement("WhiteBalance",(const char*)exifcontent); - sprintf(exifcontent,"%d",iso); - exiftable->insertElement("ISOSpeedRatings",(const char*)exifcontent); - if (newexif) { - time_t times; - { - time(×); - struct tm tmstruct; - tmstruct = *(localtime(×)); //convert to local time - strftime(exifcontent, 30, "%Y:%m:%d %H:%M:%S", &tmstruct); - exiftable->insertElement("DateTimeDigitized",(const char*)exifcontent); - } - { - sprintf(exifcontent, "%s", SubSecTime); - exiftable->insertElement("SubSecTime",(const char*)exifcontent); - } - { - - sprintf(exifcontent, "%s", SubSecTimeOrig); - exiftable->insertElement("SubSecTimeOriginal",(const char*)exifcontent); - } - { - - sprintf(exifcontent, "%s", SubSecTimeDig); - exiftable->insertElement("SubSecTimeDigitized",(const char*)exifcontent); - } - } - - if (mInfo.has_focallen) { - float focallen = mInfo.focallen; - if (focallen >= 0) { - int focalNum = focallen*1000; - int focalDen = 1000; - sprintf(exifcontent,"%d/%d",focalNum,focalDen); - exiftable->insertElement("FocalLength",(const char*)exifcontent); - } - } - time_t times; - { - time(×); - struct tm tmstruct; - tmstruct = *(localtime(×)); //convert to local time - strftime(exifcontent, 30, "%Y:%m:%d %H:%M:%S", &tmstruct); - exiftable->insertElement("DateTime",(const char*)exifcontent); - } - if (mInfo.has_gpsTimestamp) { - times = mInfo.gpsTimestamp; - if (times != -1) { - struct tm tmstruct; - tmstruct = *(gmtime(×));//convert to standard time - strftime(exifcontent, 20, "%Y:%m:%d", &tmstruct); - exiftable->insertElement("GPSDateStamp",(const char*)exifcontent); - sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",tmstruct.tm_hour,1,tmstruct.tm_min,1,tmstruct.tm_sec,1); - exiftable->insertElement("GPSTimeStamp",(const char*)exifcontent); - } - } - if (mInfo.has_latitude) { - int offset = 0; - float latitude = mInfo.latitude; - if (latitude < 0.0) { - offset = 1; - latitude*= (float)(-1); - } - int latitudedegree = latitude; - float latitudeminuts = (latitude-(float)latitudedegree)*60; - int latitudeminuts_int = latitudeminuts; - float latituseconds = (latitudeminuts-(float)latitudeminuts_int)*60+0.5; - int latituseconds_int = latituseconds; - sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",latitudedegree,1,latitudeminuts_int,1,latituseconds_int,1); - exiftable->insertElement("GPSLatitude",(const char*)exifcontent); - exiftable->insertElement("GPSLatitudeRef",(offset==1)?"S":"N"); - } - if (mInfo.has_longitude) { - int offset = 0; - float longitude = mInfo.longitude; - if (longitude < 0.0) { - offset = 1; - longitude*= (float)(-1); - } - int longitudedegree = longitude; - float longitudeminuts = (longitude-(float)longitudedegree)*60; - int longitudeminuts_int = longitudeminuts; - float longitudeseconds = (longitudeminuts-(float)longitudeminuts_int)*60+0.5; - int longitudeseconds_int = longitudeseconds; - sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",longitudedegree,1,longitudeminuts_int,1,longitudeseconds_int,1); - exiftable->insertElement("GPSLongitude",(const char*)exifcontent); - exiftable->insertElement("GPSLongitudeRef",(offset==1)?"S":"N"); - } - if (mInfo.has_altitude) { - int offset = 0; - float altitude = mInfo.altitude; - if (altitude < 0.0) { - offset = 1; - altitude*= (float)(-1); - } - int altitudenum = altitude*1000; - int altitudedec= 1000; - sprintf(exifcontent,"%d/%d",altitudenum,altitudedec); - exiftable->insertElement("GPSAltitude",(const char*)exifcontent); - sprintf(exifcontent,"%d",offset); - exiftable->insertElement("GPSAltitudeRef",(const char*)exifcontent); - } - if (mInfo.has_gpsProcessingMethod) { - char* processmethod = (char*)mInfo.gpsProcessingMethod; - if (processmethod != NULL) { - memset(exifcontent,0,sizeof(exifcontent)); - char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };//asicii - memcpy(exifcontent,ExifAsciiPrefix,8); - memcpy(exifcontent+8,processmethod,strlen(processmethod)); - exiftable->insertElement("GPSProcessingMethod",(const char*)exifcontent); - } - } - return 1; -} void JpegCompressor::exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s) { @@ -1567,120 +1355,4 @@ EXIT: return NULL; } -const char* ExifElementsTable::degreesToExifOrientation(const char* degrees) { - for (unsigned int i = 0; i < ARRAY_SIZE(degress_to_exif_lut); i++) { - if (!strcmp(degrees, degress_to_exif_lut[i].string1)) { - return degress_to_exif_lut[i].string2; - } - } - return NULL; -} -void ExifElementsTable::stringToRational(const char* str, unsigned int* num, unsigned int* den) { - int len; - char * tempVal = NULL; - if (str != NULL) { - len = strlen(str); - tempVal = (char*) malloc( sizeof(char) * (len + 1)); - } - if (tempVal != NULL) { - size_t den_len; - char *ctx; - unsigned int numerator = 0; - unsigned int denominator = 0; - char* temp = NULL; - memset(tempVal, '\0', len + 1); - strncpy(tempVal, str, len); - temp = strtok_r(tempVal, ".", &ctx); - if (temp != NULL) - numerator = atoi(temp); - if (!numerator) - numerator = 1; - temp = strtok_r(NULL, ".", &ctx); - if (temp != NULL) { - den_len = strlen(temp); - if(HUGE_VAL == den_len ) { - den_len = 0; - } - denominator = static_cast(pow(10, den_len)); - numerator = numerator * denominator + atoi(temp); - } else { - denominator = 1; - } - free(tempVal); - *num = numerator; - *den = denominator; - } -} -bool ExifElementsTable::isAsciiTag(const char* tag) { - return (strcmp(tag, TAG_GPS_PROCESSING_METHOD) == 0); -} -status_t ExifElementsTable::insertElement(const char* tag, const char* value) { - int value_length = 0; - status_t ret = NO_ERROR; - if (!value || !tag) { - return -EINVAL; - } - if (position >= MAX_EXIF_TAGS_SUPPORTED) { - CAMHAL_LOGEA("Max number of EXIF elements already inserted"); - return NO_MEMORY; - } - if (isAsciiTag(tag)) { - value_length = sizeof(ExifAsciiPrefix) + strlen(value + sizeof(ExifAsciiPrefix)); - } else { - value_length = strlen(value); - } - if (IsGpsTag(tag)) { - table[position].GpsTag = TRUE; - table[position].Tag = GpsTagNameToValue(tag); - gps_tag_count++; - } else { - table[position].GpsTag = FALSE; - table[position].Tag = TagNameToValue(tag); - exif_tag_count++; - } - table[position].DataLength = 0; - table[position].Value = (char*) malloc(sizeof(char) * (value_length + 1)); - if (table[position].Value) { - memcpy(table[position].Value, value, value_length + 1); - table[position].DataLength = value_length + 1; - } - position++; - return ret; -} -void ExifElementsTable::saveJpeg(unsigned char* jpeg, size_t jpeg_size) { - int ret; - if (jpeg_opened) { - ret = WriteJpegToBuffer(jpeg, jpeg_size); - ALOGD("saveJpeg :: ret =%d",ret); - DiscardData(); - jpeg_opened = false; - } -} -void ExifElementsTable::insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size) { - ReadMode_t read_mode = (ReadMode_t)(READ_METADATA | READ_IMAGE); - ResetJpgfile(); - if (ReadJpegSectionsFromBuffer(jpeg, jpeg_size, read_mode)) { - jpeg_opened = true; - create_EXIF(table, exif_tag_count, gps_tag_count,true); - } -} -status_t ExifElementsTable::insertExifThumbnailImage(const char* thumb, int len) { - status_t ret = NO_ERROR; - if ((len > 0) && jpeg_opened) { - ret = ReplaceThumbnailFromBuffer(thumb, len); - CAMHAL_LOGDB("insertExifThumbnailImage. ReplaceThumbnail(). ret=%d", ret); - } - return ret; -} -ExifElementsTable::~ExifElementsTable() { - int num_elements = gps_tag_count + exif_tag_count; - for (int i = 0; i < num_elements; i++) { - if (table[i].Value) { - free(table[i].Value); - } - } - if (jpeg_opened) { - DiscardData(); - } -} } // namespace android diff --git a/v3/fake-pipeline2/JpegCompressor.h b/v3/fake-pipeline2/JpegCompressor.h index 464af4d..d524ef3 100644 --- a/v3/fake-pipeline2/JpegCompressor.h +++ b/v3/fake-pipeline2/JpegCompressor.h @@ -40,39 +40,9 @@ extern "C" { #include -#include } namespace android { -#define MAX_EXIF_TAGS_SUPPORTED 30 -static const char TAG_MODEL[] = "Model"; -static const char TAG_MAKE[] = "Make"; -static const char TAG_FOCALLENGTH[] = "FocalLength"; -static const char TAG_DATETIME[] = "DateTime"; -static const char TAG_IMAGE_WIDTH[] = "ImageWidth"; -static const char TAG_IMAGE_LENGTH[] = "ImageLength"; -static const char TAG_GPS_LAT[] = "GPSLatitude"; -static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef"; -static const char TAG_GPS_LONG[] = "GPSLongitude"; -static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef"; -static const char TAG_GPS_ALT[] = "GPSAltitude"; -static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef"; -static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum"; -static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod"; -static const char TAG_GPS_VERSION_ID[] = "GPSVersionID"; -static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp"; -static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp"; -static const char TAG_ORIENTATION[] = "Orientation"; - -static const char TAG_EXPOSURETIME[] = "ExposureTime"; -static const char TAG_APERTURE[] = "ApertureValue"; -static const char TAG_FLASH[] = "Flash"; -static const char TAG_WHITEBALANCE[] = "WhiteBalance"; -static const char TAG_ISO_EQUIVALENT[] = "ISOSpeedRatings"; -static const char TAG_DATETIME_DIGITIZED[] = "DateTimeDigitized"; -static const char TAG_SUBSEC_TIME[] = "SubSecTime"; -static const char TAG_SUBSEC_TIME_ORIG[] = "SubSecTimeOriginal"; -static const char TAG_SUBSEC_TIME_DIG[] = "SubSecTimeDigitized"; struct CaptureRequest { uint32_t frameNumber; @@ -86,27 +56,6 @@ typedef struct _exif_buffer { unsigned int size; } exif_buffer; -class ExifElementsTable { - public: - ExifElementsTable() : - gps_tag_count(0), exif_tag_count(0), position(0), - jpeg_opened(false) { } - ~ExifElementsTable(); - status_t insertElement(const char* tag, const char* value); - void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size); - status_t insertExifThumbnailImage(const char*, int); - void saveJpeg(unsigned char* picture, size_t jpeg_size); - static const char* degreesToExifOrientation(const char*); - static void stringToRational(const char*, unsigned int*, unsigned int*); - static bool isAsciiTag(const char* tag); - private: - ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED]; - unsigned int gps_tag_count; - unsigned int exif_tag_count; - unsigned int position; - bool jpeg_opened; -}; - class JpegCompressor: private Thread, public virtual RefBase { public: @@ -141,8 +90,6 @@ class JpegCompressor: private Thread, public virtual RefBase { ssize_t GetMaxJpegBufferSize(); void SetMaxJpegBufferSize(ssize_t size); void SetExifInfo(struct ExifInfo info); - int GenExif(ExifElementsTable* exiftable); - status_t Create_Exif_Use_Libjpeg(); status_t Create_Exif_Use_Libexif(); exif_buffer *get_exif_buffer(); void exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s); diff --git a/v3/fake-pipeline2/Sensor.cpp b/v3/fake-pipeline2/Sensor.cpp index c3a45c6..e875e90 100644 --- a/v3/fake-pipeline2/Sensor.cpp +++ b/v3/fake-pipeline2/Sensor.cpp @@ -259,18 +259,18 @@ sensor_type_e Sensor::getSensorType(void) return mSensorType; } status_t Sensor::IoctlStateProbe(void) { - struct v4l2_queryctrl qc; + struct v4l2_queryctrl qc; int ret = 0; mIoctlSupport = 0; memset(&qc, 0, sizeof(struct v4l2_queryctrl)); - qc.id = V4L2_ROTATE_ID; + qc.id = V4L2_ROTATE_ID; ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc); if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_INTEGER)){ mIoctlSupport &= ~IOCTL_MASK_ROTATE; }else{ mIoctlSupport |= IOCTL_MASK_ROTATE; } - + if(mIoctlSupport & IOCTL_MASK_ROTATE){ msupportrotate = true; DBG_LOGA("camera support capture rotate"); @@ -2009,6 +2009,38 @@ void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) { ALOGE("new buffer failed!\n"); return; } +#if ANDROID_PLATFORM_SDK_VERSION > 23 + uint8_t *vBuffer = new uint8_t[width * height / 4]; + if (vBuffer == NULL) + ALOGE("alloc temperary v buffer failed\n"); + uint8_t *uBuffer = new uint8_t[width * height / 4]; + if (uBuffer == NULL) + ALOGE("alloc temperary u buffer failed\n"); + + if (ConvertToI420(src, vinfo->picture.buf.bytesused, tmp_buffer, width, uBuffer, (width + 1) / 2, + vBuffer, (width + 1) / 2, 0, 0, width, height, + width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) { + DBG_LOGA("Decode MJPEG frame failed\n"); + putback_picture_frame(vinfo); + usleep(5000); + delete vBuffer; + delete uBuffer; + } else { + + uint8_t *pUVBuffer = tmp_buffer + width * height; + for (int i = 0; i < width * height / 4; i++) { + *pUVBuffer++ = *(vBuffer + i); + *pUVBuffer++ = *(uBuffer + i); + } + + delete vBuffer; + delete uBuffer; + nv21_to_rgb24(tmp_buffer,img,width,height); + if (tmp_buffer != NULL) + delete [] tmp_buffer; + break; + } +#else if (ConvertMjpegToNV21(src, vinfo->picture.buf.bytesused, tmp_buffer, width, tmp_buffer + width * height, (width + 1) / 2, width, height, width, height, libyuv::FOURCC_MJPG) != 0) { @@ -2021,6 +2053,7 @@ void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) { delete [] tmp_buffer; break; } +#endif } else if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { if (vinfo->picture.buf.length == vinfo->picture.buf.bytesused) { yuyv422_to_rgb24(src,img,width,height); @@ -2268,6 +2301,59 @@ void Sensor::captureNV21(StreamBuffer b, uint32_t gain) { } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { uint32_t width = vinfo->preview.format.fmt.pix.width; uint32_t height = vinfo->preview.format.fmt.pix.height; +#if ANDROID_PLATFORM_SDK_VERSION > 23 + if ((width == b.width) && (height == b.height)) { + uint8_t *vBuffer = new uint8_t[width * height / 4]; + if (vBuffer == NULL) + ALOGE("alloc temperary v buffer failed\n"); + uint8_t *uBuffer = new uint8_t[width * height / 4]; + if (uBuffer == NULL) + ALOGE("alloc temperary u buffer failed\n"); + + if (ConvertToI420(src, vinfo->preview.buf.bytesused, b.img, b.stride, uBuffer, (b.stride + 1) / 2, + vBuffer, (b.stride + 1) / 2, 0, 0, width, height, + width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) { + DBG_LOGA("Decode MJPEG frame failed\n"); + putback_frame(vinfo); + ALOGE("%s , %d , Decode MJPEG frame failed \n", __FUNCTION__ , __LINE__); + continue; + } + uint8_t *pUVBuffer = b.img + b.stride * height; + for (int i = 0; i < width * height / 4; i++) { + *pUVBuffer++ = *(vBuffer + i); + *pUVBuffer++ = *(uBuffer + i); + } + delete vBuffer; + delete uBuffer; + mKernelBuffer = b.img; + } else { + memset(mTemp_buffer, 0 , width * height * 3/2); + uint8_t *vBuffer = new uint8_t[width * height / 4]; + if (vBuffer == NULL) + ALOGE("alloc temperary v buffer failed\n"); + uint8_t *uBuffer = new uint8_t[width * height / 4]; + if (uBuffer == NULL) + ALOGE("alloc temperary u buffer failed\n"); + + if (ConvertToI420(src, vinfo->preview.buf.bytesused, mTemp_buffer, width, uBuffer, (width + 1) / 2, + vBuffer, (width + 1) / 2, 0, 0, width, height, + width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) { + DBG_LOGA("Decode MJPEG frame failed\n"); + putback_frame(vinfo); + ALOGE("%s , %d , Decode MJPEG frame failed \n", __FUNCTION__ , __LINE__); + continue; + } + uint8_t *pUVBuffer = mTemp_buffer + width * height; + for (int i = 0; i < width * height / 4; i++) { + *pUVBuffer++ = *(vBuffer + i); + *pUVBuffer++ = *(uBuffer + i); + } + delete vBuffer; + delete uBuffer; + ReSizeNV21(vinfo, mTemp_buffer, b.img, b.width, b.height, b.stride); + mKernelBuffer = mTemp_buffer; + } +#else if ((width == b.width) && (height == b.height)) { if (ConvertMjpegToNV21(src, vinfo->preview.buf.bytesused, b.img, b.stride, b.img + b.stride * height, (b.stride + 1) / 2, width, @@ -2293,6 +2379,7 @@ void Sensor::captureNV21(StreamBuffer b, uint32_t gain) { ReSizeNV21(vinfo, mTemp_buffer, b.img, b.width, b.height, b.stride); mKernelBuffer = mTemp_buffer; } +#endif } mSensorWorkFlag = true; break; diff --git a/v3/inc/qemu_pipe.h b/v3/inc/qemu_pipe.h new file mode 100644 index 0000000..53aec97 --- a/dev/null +++ b/v3/inc/qemu_pipe.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2011 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 ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H +#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H + +#include +#include +#include +#include +#include /* for pthread_once() */ +#include +#include +#include +#include + +#ifndef D +# define D(...) do{}while(0) +#endif + +/* Try to open a new Qemu fast-pipe. This function returns a file descriptor + * that can be used to communicate with a named service managed by the + * emulator. + * + * This file descriptor can be used as a standard pipe/socket descriptor. + * + * 'pipeName' is the name of the emulator service you want to connect to. + * E.g. 'opengles' or 'camera'. + * + * On success, return a valid file descriptor + * Returns -1 on error, and errno gives the error code, e.g.: + * + * EINVAL -> unknown/unsupported pipeName + * ENOSYS -> fast pipes not available in this system. + * + * ENOSYS should never happen, except if you're trying to run within a + * misconfigured emulator. + * + * You should be able to open several pipes to the same pipe service, + * except for a few special cases (e.g. GSM modem), where EBUSY will be + * returned if more than one client tries to connect to it. + */ +static __inline__ int +qemu_pipe_open(const char* pipeName) +{ + char buff[256]; + int buffLen; + int fd, ret; + + if (pipeName == NULL || pipeName[0] == '\0') { + errno = EINVAL; + return -1; + } + + snprintf(buff, sizeof buff, "pipe:%s", pipeName); + + fd = open("/dev/qemu_pipe", O_RDWR); + if (fd < 0 && errno == ENOENT) + fd = open("/dev/goldfish_pipe", O_RDWR); + if (fd < 0) { + D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno)); + //errno = ENOSYS; + return -1; + } + + buffLen = strlen(buff); + + ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1)); + if (ret != buffLen+1) { + D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno)); + if (ret == 0) { + errno = ECONNRESET; + } else if (ret > 0) { + errno = EINVAL; + } + return -1; + } + + return fd; +} + +#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */ diff --git a/v3/inc/qemud.h b/v3/inc/qemud.h new file mode 100644 index 0000000..5c39f9c --- a/dev/null +++ b/v3/inc/qemud.h @@ -0,0 +1,153 @@ +/* + * 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. + */ + +#ifndef ANDROID_INCLUDE_HARDWARE_QEMUD_H +#define ANDROID_INCLUDE_HARDWARE_QEMUD_H + +#include +#include "qemu_pipe.h" + +/* the following is helper code that is used by the QEMU-specific + * hardware HAL modules to communicate with the emulator program + * through the 'qemud' multiplexing daemon, or through the qemud + * pipe. + * + * see the documentation comments for details in + * development/emulator/qemud/qemud.c + * + * all definitions here are built into the HAL module to avoid + * having to write a tiny shared library for this. + */ + +/* we expect the D macro to be defined to a function macro + * that sends its formatted string argument(s) to the log. + * If not, ignore the traces. + */ +#ifndef D +# define D(...) ((void)0) +#endif + +static __inline__ int +qemud_fd_write(int fd, const void* buff, int len) +{ + int len2; + do { + len2 = write(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static __inline__ int +qemud_fd_read(int fd, void* buff, int len) +{ + int len2; + do { + len2 = read(fd, buff, len); + } while (len2 < 0 && errno == EINTR); + return len2; +} + +static __inline__ int +qemud_channel_open(const char* name) +{ + int fd; + int namelen = strlen(name); + char answer[2]; + char pipe_name[256]; + + /* First, try to connect to the pipe. */ + snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name); + fd = qemu_pipe_open(pipe_name); + if (fd < 0) { + D("QEMUD pipe is not available for %s: %s", name, strerror(errno)); + /* If pipe is not available, connect to qemud control socket */ + fd = socket_local_client( "qemud", + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM ); + if (fd < 0) { + D("no qemud control socket: %s", strerror(errno)); + return -1; + } + + /* send service name to connect */ + if (qemud_fd_write(fd, name, namelen) != namelen) { + D("can't send service name to qemud: %s", + strerror(errno)); + close(fd); + return -1; + } + + /* read answer from daemon */ + if (qemud_fd_read(fd, answer, 2) != 2 || + answer[0] != 'O' || answer[1] != 'K') { + D("cant' connect to %s service through qemud", name); + close(fd); + return -1; + } + } + return fd; +} + +static __inline__ int +qemud_channel_send(int fd, const void* msg, int msglen) +{ + char header[5]; + + if (msglen < 0) + msglen = strlen((const char*)msg); + + if (msglen == 0) + return 0; + + snprintf(header, sizeof header, "%04x", msglen); + if (qemud_fd_write(fd, header, 4) != 4) { + D("can't write qemud frame header: %s", strerror(errno)); + return -1; + } + + if (qemud_fd_write(fd, msg, msglen) != msglen) { + D("can4t write qemud frame payload: %s", strerror(errno)); + return -1; + } + return 0; +} + +static __inline__ int +qemud_channel_recv(int fd, void* msg, int msgsize) +{ + char header[5]; + int size, avail; + + if (qemud_fd_read(fd, header, 4) != 4) { + D("can't read qemud frame header: %s", strerror(errno)); + return -1; + } + header[4] = 0; + if (sscanf(header, "%04x", &size) != 1) { + D("malformed qemud frame header: '%.*s'", 4, header); + return -1; + } + if (size > msgsize) + return -1; + + if (qemud_fd_read(fd, msg, size) != size) { + D("can't read qemud frame payload: %s", strerror(errno)); + return -1; + } + return size; +} + +#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */ -- cgit