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  * This class simulates a hardware JPEG compressor.  It receives image buffers
19  * in RGBA_8888 format, processes them in a worker thread, and then pushes them
20  * out to their destination stream.
21  */
22 
23 #ifndef HW_EMULATOR_CAMERA2_JPEG_H
24 #define HW_EMULATOR_CAMERA2_JPEG_H
25 
26 #include "utils/Mutex.h"
27 #include "utils/Thread.h"
28 #include "utils/Timers.h"
29 
30 #include "Base.h"
31 
32 #include <stdio.h>
33 
34 extern "C" {
35 #include <jpeglib.h>
36 }
37 
38 namespace android {
39 
40 class JpegCompressor : private Thread, public virtual RefBase {
41  public:
42   JpegCompressor();
43   ~JpegCompressor();
44 
45   struct JpegListener {
46     // Called when JPEG compression has finished, or encountered an error
47     virtual void onJpegDone(const StreamBuffer &jpegBuffer, bool success) = 0;
48     // Called when the input buffer for JPEG is not needed any more,
49     // if the buffer came from the framework.
50     virtual void onJpegInputDone(const StreamBuffer &inputBuffer) = 0;
51     virtual ~JpegListener();
52   };
53 
54   // Start compressing COMPRESSED format buffers; JpegCompressor takes
55   // ownership of the Buffers vector.
56   // Reserve() must be called first.
57   status_t start(Buffers *buffers, JpegListener *listener);
58 
59   // Compress and block until buffer is complete.
60   status_t compressSynchronous(Buffers *buffers);
61 
62   status_t cancel();
63 
64   bool isBusy();
65   bool isStreamInUse(uint32_t id);
66 
67   bool waitForDone(nsecs_t timeout);
68 
69   // Reserve the compressor for a later start() call.
70   status_t reserve();
71 
72   // TODO: Measure this
73   static const size_t kMaxJpegSize = 300000;
74 
75  private:
76   Mutex mBusyMutex;
77   bool mIsBusy;
78   Condition mDone;
79   bool mSynchronous;
80 
81   Mutex mMutex;
82 
83   Buffers *mBuffers;
84   JpegListener *mListener;
85 
86   StreamBuffer mJpegBuffer, mAuxBuffer;
87   bool mFoundJpeg, mFoundAux;
88 
89   jpeg_compress_struct mCInfo;
90 
91   struct JpegError : public jpeg_error_mgr {
92     JpegCompressor *parent;
93   };
94   j_common_ptr mJpegErrorInfo;
95 
96   struct JpegDestination : public jpeg_destination_mgr {
97     JpegCompressor *parent;
98   };
99 
100   static void jpegErrorHandler(j_common_ptr cinfo);
101 
102   static void jpegInitDestination(j_compress_ptr cinfo);
103   static boolean jpegEmptyOutputBuffer(j_compress_ptr cinfo);
104   static void jpegTermDestination(j_compress_ptr cinfo);
105 
106   bool checkError(const char *msg);
107   status_t compress();
108 
109   void cleanUp();
110 
111   /**
112    * Inherited Thread virtual overrides
113    */
114  private:
115   virtual status_t readyToRun();
116   virtual bool threadLoop();
117 };
118 
119 }  // namespace android
120 
121 #endif
122