1 /*
2  * Copyright (C) Texas Instruments - http://www.ti.com/
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 #ifndef BUFFER_SOURCE_ADAPTER_H
18 #define BUFFER_SOURCE_ADAPTER_H
19 
20 #ifdef OMAP_ENHANCEMENT_CPCAM
21 
22 #include "CameraHal.h"
23 #include <ui/GraphicBufferMapper.h>
24 #include <hal_public.h>
25 
26 namespace Ti {
27 namespace Camera {
28 
29 /**
30  * Handles enqueueing/dequeing buffers to tap-in/tap-out points
31  * TODO(XXX): this class implements DisplayAdapter for now
32  * but this will most likely change once tap-in/tap-out points
33  * are better defined
34  */
35 
36 class BufferSourceAdapter : public DisplayAdapter
37 {
38 // private types
39 private:
40     ///Constant declarations
41     static const int NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
42 
43 
44     // helper class to return frame in different thread context
45     class ReturnFrame : public android::Thread {
46     public:
ReturnFrame(BufferSourceAdapter * __this)47         ReturnFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
48             android::AutoMutex lock(mReturnFrameMutex);
49             mDestroying = false;
50             mFrameCount = 0;
51         }
52 
~ReturnFrame()53         ~ReturnFrame() {
54             android::AutoMutex lock(mReturnFrameMutex);
55          }
56 
signal()57         void signal() {
58             android::AutoMutex lock(mReturnFrameMutex);
59             mFrameCount++;
60             mReturnFrameCondition.signal();
61         }
62 
requestExit()63         virtual void requestExit() {
64             Thread::requestExit();
65 
66             android::AutoMutex lock(mReturnFrameMutex);
67             mDestroying = true;
68             mReturnFrameCondition.signal();
69         }
70 
threadLoop()71         virtual bool threadLoop() {
72             android::AutoMutex lock(mReturnFrameMutex);
73             if ( 0 >= mFrameCount ) {
74                 mReturnFrameCondition.wait(mReturnFrameMutex);
75             }
76             if (!mDestroying) {
77                 mBufferSourceAdapter->handleFrameReturn();
78                 mFrameCount--;
79             }
80             return true;
81         }
82 
83     private:
84         BufferSourceAdapter* mBufferSourceAdapter;
85         android::Condition mReturnFrameCondition;
86         android::Mutex mReturnFrameMutex;
87         int mFrameCount;
88         bool mDestroying;
89     };
90 
91     // helper class to queue frame in different thread context
92     class QueueFrame : public android::Thread {
93     public:
QueueFrame(BufferSourceAdapter * __this)94         QueueFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
95             mDestroying = false;
96         }
97 
~QueueFrame()98         ~QueueFrame() {
99          }
100 
addFrame(CameraFrame * frame)101         void addFrame(CameraFrame *frame) {
102             android::AutoMutex lock(mFramesMutex);
103             mFrames.add(new CameraFrame(*frame));
104             mFramesCondition.signal();
105         }
106 
requestExit()107         virtual void requestExit() {
108             Thread::requestExit();
109 
110             mDestroying = true;
111 
112             android::AutoMutex lock(mFramesMutex);
113             while (!mFrames.empty()) {
114                 CameraFrame *frame = mFrames.itemAt(0);
115                 mFrames.removeAt(0);
116                 frame->mMetaData.clear();
117                 delete frame;
118             }
119             mFramesCondition.signal();
120         }
121 
threadLoop()122         virtual bool threadLoop() {
123             CameraFrame *frame = NULL;
124             {
125                 android::AutoMutex lock(mFramesMutex);
126                 while (mFrames.empty() && !mDestroying) mFramesCondition.wait(mFramesMutex);
127                 if (!mDestroying) {
128                     frame = mFrames.itemAt(0);
129                     mFrames.removeAt(0);
130                 }
131             }
132 
133             if (frame) {
134                 mBufferSourceAdapter->handleFrameCallback(frame);
135                 frame->mMetaData.clear();
136 
137                 // signal return frame thread that it can dequeue a buffer now
138                 mBufferSourceAdapter->mReturnFrame->signal();
139 
140                 delete frame;
141             }
142 
143             return true;
144         }
145 
146     private:
147         BufferSourceAdapter* mBufferSourceAdapter;
148         android::Vector<CameraFrame *> mFrames;
149         android::Condition mFramesCondition;
150         android::Mutex mFramesMutex;
151         bool mDestroying;
152     };
153 
154     enum {
155         BUFFER_SOURCE_TAP_IN,
156         BUFFER_SOURCE_TAP_OUT
157     };
158 
159 // public member functions
160 public:
161     BufferSourceAdapter();
162     virtual ~BufferSourceAdapter();
163 
164     virtual status_t initialize();
165     virtual int setPreviewWindow(struct preview_stream_ops *source);
166     virtual int setFrameProvider(FrameNotifier *frameProvider);
167     virtual int setErrorHandler(ErrorNotifier *errorNotifier);
168     virtual int enableDisplay(int width, int height, struct timeval *refTime = NULL);
169     virtual int disableDisplay(bool cancel_buffer = true);
170     virtual status_t pauseDisplay(bool pause);
171 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
172     // Not implemented in this class
173     virtual status_t setSnapshotTimeRef(struct timeval *refTime = NULL) { return NO_ERROR; }
174 #endif
175     virtual bool supportsExternalBuffering();
176     virtual CameraBuffer * allocateBufferList(int width, int dummyHeight, const char* format, int &bytes, int numBufs);
177     virtual CameraBuffer *getBufferList(int *numBufs);
178     virtual uint32_t * getOffsets() ;
179     virtual int getFd() ;
180     virtual int freeBufferList(CameraBuffer * buflist);
181     virtual int maxQueueableBuffers(unsigned int& queueable);
182     virtual int minUndequeueableBuffers(int& unqueueable);
183     virtual bool match(const char * str);
184 
185     virtual CameraBuffer * getBuffers(bool reset = false);
186     virtual unsigned int getSize();
187     virtual int getBufferCount();
188 
189     static void frameCallback(CameraFrame* caFrame);
190     void addFrame(CameraFrame* caFrame);
191     void handleFrameCallback(CameraFrame* caFrame);
192     bool handleFrameReturn();
193 
194 private:
195     void destroy();
196     status_t returnBuffersToWindow();
197 
198 private:
199     preview_stream_ops_t*  mBufferSource;
200     FrameProvider *mFrameProvider; // Pointer to the frame provider interface
201 
202     mutable android::Mutex mLock;
203     int mBufferCount;
204     CameraBuffer *mBuffers;
205 
206     android::KeyedVector<buffer_handle_t *, int> mFramesWithCameraAdapterMap;
207     android::sp<ErrorNotifier> mErrorNotifier;
208     android::sp<ReturnFrame> mReturnFrame;
209     android::sp<QueueFrame> mQueueFrame;
210 
211     uint32_t mFrameWidth;
212     uint32_t mFrameHeight;
213     uint32_t mPreviewWidth;
214     uint32_t mPreviewHeight;
215 
216     int mBufferSourceDirection;
217 
218     const char *mPixelFormat;
219 };
220 
221 } // namespace Camera
222 } // namespace Ti
223 
224 #endif
225 
226 #endif
227