summaryrefslogtreecommitdiff
authorGuosong Zhou <guosong.zhou@amlogic.com>2017-09-12 10:40:15 (GMT)
committer Guosong Zhou <guosong.zhou@amlogic.com>2017-09-12 11:02:21 (GMT)
commitc43657fcf11be71081a505b49dff907d60ac3b00 (patch)
tree7598679063c19acb71bd7104deb2a1d06fbbfcbf
parent34d492f5e276285ba1cd18aaa546f87dde025680 (diff)
downloadcamera-c43657fcf11be71081a505b49dff907d60ac3b00.zip
camera-c43657fcf11be71081a505b49dff907d60ac3b00.tar.gz
camera-c43657fcf11be71081a505b49dff907d60ac3b00.tar.bz2
camera: add camera module[1/3]
PD# 146466 add android O camera hal Change-Id: Ic52852627125b8107668d5493dacc152e80b573e Signed-off-by: Guosong Zhou <guosong.zhou@amlogic.com>
Diffstat
-rw-r--r--v3/Android.mk10
-rw-r--r--v3/EmulatedFakeCamera3.cpp29
-rw-r--r--v3/EmulatedFakeCamera3.h4
-rw-r--r--v3/LoadXml.cpp208
-rw-r--r--v3/LoadXml.h48
-rw-r--r--[-rwxr-xr-x]v3/QemuClient.h2
-rw-r--r--v3/fake-pipeline2/JpegCompressor.cpp328
-rw-r--r--v3/fake-pipeline2/JpegCompressor.h53
-rw-r--r--v3/fake-pipeline2/Sensor.cpp93
-rw-r--r--v3/inc/qemu_pipe.h94
-rw-r--r--v3/inc/qemud.h153
11 files changed, 362 insertions, 660 deletions
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 <camera/CameraMetadata.h>
#include <utils/List.h>
#include <utils/Mutex.h>
-#include <LoadXml.h>
+
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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <cutils/properties.h>
-#include <gui/Surface.h>
-#include <utils/Log.h>
-#include <expat.h>
-#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<LoadXml *>(data)->startElementHandler(name, attrs);
-}
-
-// static
-void LoadXml::EndElementHandlerWrapper(void *me, const char *name) {
- static_cast<LoadXml *>(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 <hardware/qemud.h>
+#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(&times);
- struct tm tmstruct;
- tmstruct = *(localtime(&times)); //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(&times);
- struct tm tmstruct;
- tmstruct = *(localtime(&times)); //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(&times));//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<unsigned int>(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 <jpeglib.h>
-#include <jhead.h>
}
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 <sys/cdefs.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <pthread.h> /* for pthread_once() */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#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 <cutils/sockets.h>
+#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 */