blob: d524ef3437c553910004d1e415baf39f2fdf8989
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 | #include <libexif/exif-entry.h> |
36 | #include <libexif/exif-data.h> |
37 | #include <libexif/exif-ifd.h> |
38 | #include <libexif/exif-loader.h> |
39 | #include <libexif/exif-mem.h> |
40 | |
41 | extern "C" { |
42 | #include <jpeglib.h> |
43 | } |
44 | |
45 | namespace android { |
46 | |
47 | struct CaptureRequest { |
48 | uint32_t frameNumber; |
49 | camera3_stream_buffer *buf; |
50 | Buffers *sensorBuffers; |
51 | bool mNeedThumbnail; |
52 | }; |
53 | |
54 | typedef struct _exif_buffer { |
55 | unsigned char *data; |
56 | unsigned int size; |
57 | } exif_buffer; |
58 | |
59 | class JpegCompressor: private Thread, public virtual RefBase { |
60 | public: |
61 | |
62 | JpegCompressor(); |
63 | ~JpegCompressor(); |
64 | |
65 | struct JpegListener { |
66 | // Called when JPEG compression has finished, or encountered an error |
67 | virtual void onJpegDone(const StreamBuffer &jpegBuffer, |
68 | bool success, CaptureRequest &r) = 0; |
69 | // Called when the input buffer for JPEG is not needed any more, |
70 | // if the buffer came from the framework. |
71 | virtual void onJpegInputDone(const StreamBuffer &inputBuffer) = 0; |
72 | virtual ~JpegListener(); |
73 | }; |
74 | |
75 | // Start compressing COMPRESSED format buffers; JpegCompressor takes |
76 | // ownership of the Buffers vector. |
77 | status_t start(); |
78 | status_t setlistener(JpegListener *listener); |
79 | void queueRequest(CaptureRequest &r); |
80 | |
81 | // Compress and block until buffer is complete. |
82 | status_t compressSynchronous(Buffers *buffers); |
83 | |
84 | status_t cancel(); |
85 | |
86 | bool isBusy(); |
87 | bool isStreamInUse(uint32_t id); |
88 | |
89 | bool waitForDone(nsecs_t timeout); |
90 | ssize_t GetMaxJpegBufferSize(); |
91 | void SetMaxJpegBufferSize(ssize_t size); |
92 | void SetExifInfo(struct ExifInfo info); |
93 | status_t Create_Exif_Use_Libexif(); |
94 | exif_buffer *get_exif_buffer(); |
95 | void exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s); |
96 | void exif_entry_set_short (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifShort n); |
97 | void exif_entry_set_long (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifLong n); |
98 | void exif_entry_set_rational (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifRational r); |
99 | void exif_entry_set_undefined (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, exif_buffer * buf); |
100 | ExifEntry *init_tag(ExifData *exif, ExifIfd ifd, ExifTag tag); |
101 | ExifEntry *create_tag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len); |
102 | void exif_entry_set_gps_coord(ExifData * pEdata, ExifTag eEtag, |
103 | ExifRational r1, ExifRational r2, ExifRational r3); |
104 | void exif_entry_set_gps_altitude(ExifData * pEdata, ExifTag eEtag, ExifRational r1); |
105 | void exif_entry_set_gps_coord_ref(ExifData * pEdata, ExifTag eEtag, const char *s); |
106 | void exif_entry_set_gps_altitude_ref(ExifData * pEdata, ExifTag eEtag, ExifByte n); |
107 | |
108 | // TODO: Measure this |
109 | static const size_t kMaxJpegSize = 8000000; |
110 | ssize_t mMaxbufsize; |
111 | |
112 | private: |
113 | Mutex mBusyMutex; |
114 | bool mIsBusy; |
115 | Condition mDone; |
116 | bool mSynchronous; |
117 | |
118 | Mutex mMutex; |
119 | |
120 | List<CaptureRequest*> mInJpegRequestQueue; |
121 | Condition mInJpegRequestSignal; |
122 | camera3_stream_buffer *tempHalbuffers; |
123 | Buffers *tempBuffers; |
124 | CaptureRequest mJpegRequest; |
125 | bool mExitJpegThread; |
126 | bool mNeedexif; |
127 | int mMainJpegSize, mThumbJpegSize; |
128 | uint8_t *mSrcThumbBuffer; |
129 | uint8_t *mDstThumbBuffer; |
130 | Buffers *mBuffers; |
131 | int mPendingrequest; |
132 | JpegListener *mListener; |
133 | struct ExifInfo mInfo; |
134 | StreamBuffer mJpegBuffer, mAuxBuffer; |
135 | bool mFoundJpeg, mFoundAux; |
136 | jpeg_compress_struct mCInfo; |
137 | |
138 | struct JpegError : public jpeg_error_mgr { |
139 | JpegCompressor *parent; |
140 | }; |
141 | j_common_ptr mJpegErrorInfo; |
142 | |
143 | struct JpegDestination : public jpeg_destination_mgr { |
144 | JpegCompressor *parent; |
145 | }; |
146 | |
147 | bool checkError(const char *msg); |
148 | status_t compress(); |
149 | |
150 | status_t thumbcompress(); |
151 | void cleanUp(); |
152 | |
153 | /** |
154 | * Inherited Thread virtual overrides |
155 | */ |
156 | private: |
157 | virtual status_t readyToRun(); |
158 | virtual bool threadLoop(); |
159 | }; |
160 | |
161 | } // namespace android |
162 | |
163 | #endif |
164 |