blob: affac67259ed8d4ec70ab734bdebaf916f1fdf74
1 | /* |
2 | * Copyright (C) 2012 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | |
18 | /** |
19 | * This class simulates a hardware JPEG compressor. It receives image buffers |
20 | * in RGBA_8888 format, processes them in a worker thread, and then pushes them |
21 | * out to their destination stream. |
22 | */ |
23 | |
24 | #ifndef HW_EMULATOR_CAMERA2_JPEG_H |
25 | #define HW_EMULATOR_CAMERA2_JPEG_H |
26 | |
27 | #include "utils/Thread.h" |
28 | #include "utils/Mutex.h" |
29 | #include "utils/Timers.h" |
30 | #include "Base.h" |
31 | #include <hardware/camera3.h> |
32 | #include <utils/List.h> |
33 | #include <stdio.h> |
34 | |
35 | extern "C" { |
36 | #include <jpeglib.h> |
37 | #include <jhead.h> |
38 | } |
39 | |
40 | namespace android { |
41 | #define MAX_EXIF_TAGS_SUPPORTED 30 |
42 | static const char TAG_MODEL[] = "Model"; |
43 | static const char TAG_MAKE[] = "Make"; |
44 | static const char TAG_FOCALLENGTH[] = "FocalLength"; |
45 | static const char TAG_DATETIME[] = "DateTime"; |
46 | static const char TAG_IMAGE_WIDTH[] = "ImageWidth"; |
47 | static const char TAG_IMAGE_LENGTH[] = "ImageLength"; |
48 | static const char TAG_GPS_LAT[] = "GPSLatitude"; |
49 | static const char TAG_GPS_LAT_REF[] = "GPSLatitudeRef"; |
50 | static const char TAG_GPS_LONG[] = "GPSLongitude"; |
51 | static const char TAG_GPS_LONG_REF[] = "GPSLongitudeRef"; |
52 | static const char TAG_GPS_ALT[] = "GPSAltitude"; |
53 | static const char TAG_GPS_ALT_REF[] = "GPSAltitudeRef"; |
54 | static const char TAG_GPS_MAP_DATUM[] = "GPSMapDatum"; |
55 | static const char TAG_GPS_PROCESSING_METHOD[] = "GPSProcessingMethod"; |
56 | static const char TAG_GPS_VERSION_ID[] = "GPSVersionID"; |
57 | static const char TAG_GPS_TIMESTAMP[] = "GPSTimeStamp"; |
58 | static const char TAG_GPS_DATESTAMP[] = "GPSDateStamp"; |
59 | static const char TAG_ORIENTATION[] = "Orientation"; |
60 | |
61 | static const char TAG_EXPOSURETIME[] = "ExposureTime"; |
62 | static const char TAG_APERTURE[] = "ApertureValue"; |
63 | static const char TAG_FLASH[] = "Flash"; |
64 | static const char TAG_WHITEBALANCE[] = "WhiteBalance"; |
65 | static const char TAG_ISO_EQUIVALENT[] = "ISOSpeedRatings"; |
66 | static const char TAG_DATETIME_DIGITIZED[] = "DateTimeDigitized"; |
67 | static const char TAG_SUBSEC_TIME[] = "SubSecTime"; |
68 | static const char TAG_SUBSEC_TIME_ORIG[] = "SubSecTimeOriginal"; |
69 | static const char TAG_SUBSEC_TIME_DIG[] = "SubSecTimeDigitized"; |
70 | |
71 | struct CaptureRequest { |
72 | uint32_t frameNumber; |
73 | camera3_stream_buffer *buf; |
74 | Buffers *sensorBuffers; |
75 | bool mNeedThumbnail; |
76 | }; |
77 | |
78 | class ExifElementsTable { |
79 | public: |
80 | ExifElementsTable() : |
81 | gps_tag_count(0), exif_tag_count(0), position(0), |
82 | jpeg_opened(false) { } |
83 | ~ExifElementsTable(); |
84 | status_t insertElement(const char* tag, const char* value); |
85 | void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size); |
86 | status_t insertExifThumbnailImage(const char*, int); |
87 | void saveJpeg(unsigned char* picture, size_t jpeg_size); |
88 | static const char* degreesToExifOrientation(const char*); |
89 | static void stringToRational(const char*, unsigned int*, unsigned int*); |
90 | static bool isAsciiTag(const char* tag); |
91 | private: |
92 | ExifElement_t table[MAX_EXIF_TAGS_SUPPORTED]; |
93 | unsigned int gps_tag_count; |
94 | unsigned int exif_tag_count; |
95 | unsigned int position; |
96 | bool jpeg_opened; |
97 | }; |
98 | |
99 | class JpegCompressor: private Thread, public virtual RefBase { |
100 | public: |
101 | |
102 | JpegCompressor(); |
103 | ~JpegCompressor(); |
104 | |
105 | struct JpegListener { |
106 | // Called when JPEG compression has finished, or encountered an error |
107 | virtual void onJpegDone(const StreamBuffer &jpegBuffer, |
108 | bool success, CaptureRequest &r) = 0; |
109 | // Called when the input buffer for JPEG is not needed any more, |
110 | // if the buffer came from the framework. |
111 | virtual void onJpegInputDone(const StreamBuffer &inputBuffer) = 0; |
112 | virtual ~JpegListener(); |
113 | }; |
114 | |
115 | // Start compressing COMPRESSED format buffers; JpegCompressor takes |
116 | // ownership of the Buffers vector. |
117 | status_t start(); |
118 | status_t setlistener(JpegListener *listener); |
119 | void queueRequest(CaptureRequest &r); |
120 | |
121 | // Compress and block until buffer is complete. |
122 | status_t compressSynchronous(Buffers *buffers); |
123 | |
124 | status_t cancel(); |
125 | |
126 | bool isBusy(); |
127 | bool isStreamInUse(uint32_t id); |
128 | |
129 | bool waitForDone(nsecs_t timeout); |
130 | ssize_t GetMaxJpegBufferSize(); |
131 | void SetMaxJpegBufferSize(ssize_t size); |
132 | void SetExifInfo(struct ExifInfo info); |
133 | int GenExif(ExifElementsTable* exiftable); |
134 | |
135 | // TODO: Measure this |
136 | static const size_t kMaxJpegSize = 300000; |
137 | ssize_t mMaxbufsize; |
138 | |
139 | private: |
140 | Mutex mBusyMutex; |
141 | bool mIsBusy; |
142 | Condition mDone; |
143 | bool mSynchronous; |
144 | |
145 | Mutex mMutex; |
146 | |
147 | List<CaptureRequest*> mInJpegRequestQueue; |
148 | Condition mInJpegRequestSignal; |
149 | camera3_stream_buffer *tempHalbuffers; |
150 | Buffers *tempBuffers; |
151 | CaptureRequest mJpegRequest; |
152 | bool mExitJpegThread; |
153 | bool mNeedexif; |
154 | int mMainJpegSize, mThumbJpegSize; |
155 | uint8_t *mSrcThumbBuffer; |
156 | uint8_t *mDstThumbBuffer; |
157 | Buffers *mBuffers; |
158 | int mPendingrequest; |
159 | JpegListener *mListener; |
160 | struct ExifInfo mInfo; |
161 | StreamBuffer mJpegBuffer, mAuxBuffer; |
162 | bool mFoundJpeg, mFoundAux; |
163 | jpeg_compress_struct mCInfo; |
164 | |
165 | struct JpegError : public jpeg_error_mgr { |
166 | JpegCompressor *parent; |
167 | }; |
168 | j_common_ptr mJpegErrorInfo; |
169 | |
170 | struct JpegDestination : public jpeg_destination_mgr { |
171 | JpegCompressor *parent; |
172 | }; |
173 | |
174 | bool checkError(const char *msg); |
175 | status_t compress(); |
176 | |
177 | status_t thumbcompress(); |
178 | void cleanUp(); |
179 | |
180 | /** |
181 | * Inherited Thread virtual overrides |
182 | */ |
183 | private: |
184 | virtual status_t readyToRun(); |
185 | virtual bool threadLoop(); |
186 | }; |
187 | |
188 | } // namespace android |
189 | |
190 | #endif |
191 |