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
26namespace Ti {
27namespace 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
36class BufferSourceAdapter : public DisplayAdapter
37{
38// private types
39private:
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:
47        ReturnFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
48            android::AutoMutex lock(mReturnFrameMutex);
49            mDestroying = false;
50            mFrameCount = 0;
51        }
52
53        ~ReturnFrame() {
54            android::AutoMutex lock(mReturnFrameMutex);
55         }
56
57        void signal() {
58            android::AutoMutex lock(mReturnFrameMutex);
59            mFrameCount++;
60            mReturnFrameCondition.signal();
61        }
62
63        virtual void requestExit() {
64            Thread::requestExit();
65
66            android::AutoMutex lock(mReturnFrameMutex);
67            mDestroying = true;
68            mReturnFrameCondition.signal();
69        }
70
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:
94        QueueFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
95            mDestroying = false;
96        }
97
98        ~QueueFrame() {
99         }
100
101        void addFrame(CameraFrame *frame) {
102            android::AutoMutex lock(mFramesMutex);
103            mFrames.add(new CameraFrame(*frame));
104            mFramesCondition.signal();
105        }
106
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
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
160public:
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
194private:
195    void destroy();
196    status_t returnBuffersToWindow();
197
198private:
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