summaryrefslogtreecommitdiffstats
path: root/camera/inc/BufferSourceAdapter.h
blob: c006b9d57352ecb7344231fd414358b00206f363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 * Copyright (C) Texas Instruments - http://www.ti.com/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BUFFER_SOURCE_ADAPTER_H
#define BUFFER_SOURCE_ADAPTER_H

#ifdef OMAP_ENHANCEMENT_CPCAM

#include "CameraHal.h"
#include <ui/GraphicBufferMapper.h>
#include <hal_public.h>

namespace Ti {
namespace Camera {

/**
 * Handles enqueueing/dequeing buffers to tap-in/tap-out points
 * TODO(XXX): this class implements DisplayAdapter for now
 * but this will most likely change once tap-in/tap-out points
 * are better defined
 */

class BufferSourceAdapter : public DisplayAdapter
{
// private types
private:
    ///Constant declarations
    static const int NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;


    // helper class to return frame in different thread context
    class ReturnFrame : public android::Thread {
    public:
        ReturnFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
            android::AutoMutex lock(mReturnFrameMutex);
            mDestroying = false;
            mFrameCount = 0;
        }

        ~ReturnFrame() {
            android::AutoMutex lock(mReturnFrameMutex);
         }

        void signal() {
            android::AutoMutex lock(mReturnFrameMutex);
            mFrameCount++;
            mReturnFrameCondition.signal();
        }

        virtual void requestExit() {
            Thread::requestExit();

            android::AutoMutex lock(mReturnFrameMutex);
            mDestroying = true;
            mReturnFrameCondition.signal();
        }

        virtual bool threadLoop() {
            android::AutoMutex lock(mReturnFrameMutex);
            if ( 0 >= mFrameCount ) {
                mReturnFrameCondition.wait(mReturnFrameMutex);
            }
            if (!mDestroying) {
                mBufferSourceAdapter->handleFrameReturn();
                mFrameCount--;
            }
            return true;
        }

    private:
        BufferSourceAdapter* mBufferSourceAdapter;
        android::Condition mReturnFrameCondition;
        android::Mutex mReturnFrameMutex;
        int mFrameCount;
        bool mDestroying;
    };

    // helper class to queue frame in different thread context
    class QueueFrame : public android::Thread {
    public:
        QueueFrame(BufferSourceAdapter* __this) : mBufferSourceAdapter(__this) {
            mDestroying = false;
        }

        ~QueueFrame() {
         }

        void addFrame(CameraFrame *frame) {
            android::AutoMutex lock(mFramesMutex);
            mFrames.add(new CameraFrame(*frame));
            mFramesCondition.signal();
        }

        virtual void requestExit() {
            Thread::requestExit();

            mDestroying = true;

            android::AutoMutex lock(mFramesMutex);
            while (!mFrames.empty()) {
                CameraFrame *frame = mFrames.itemAt(0);
                mFrames.removeAt(0);
                frame->mMetaData.clear();
                delete frame;
            }
            mFramesCondition.signal();
        }

        virtual bool threadLoop() {
            CameraFrame *frame = NULL;
            {
                android::AutoMutex lock(mFramesMutex);
                while (mFrames.empty() && !mDestroying) mFramesCondition.wait(mFramesMutex);
                if (!mDestroying) {
                    frame = mFrames.itemAt(0);
                    mFrames.removeAt(0);
                }
            }

            if (frame) {
                mBufferSourceAdapter->handleFrameCallback(frame);
                frame->mMetaData.clear();

                if (frame->mFrameType != CameraFrame::REPROCESS_INPUT_FRAME) {
                    // signal return frame thread that it can dequeue a buffer now
                    mBufferSourceAdapter->mReturnFrame->signal();
                }

                delete frame;
            }

            return true;
        }

    private:
        BufferSourceAdapter* mBufferSourceAdapter;
        android::Vector<CameraFrame *> mFrames;
        android::Condition mFramesCondition;
        android::Mutex mFramesMutex;
        bool mDestroying;
    };

    enum {
        BUFFER_SOURCE_TAP_IN,
        BUFFER_SOURCE_TAP_OUT
    };

// public member functions
public:
    BufferSourceAdapter();
    virtual ~BufferSourceAdapter();

    virtual status_t initialize();
    virtual int setPreviewWindow(struct preview_stream_ops *source);
    virtual int setFrameProvider(FrameNotifier *frameProvider);
    virtual int setErrorHandler(ErrorNotifier *errorNotifier);
    virtual int enableDisplay(int width, int height, struct timeval *refTime = NULL);
    virtual int disableDisplay(bool cancel_buffer = true);
    virtual status_t pauseDisplay(bool pause);
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
    // Not implemented in this class
    virtual status_t setSnapshotTimeRef(struct timeval *refTime = NULL) { return NO_ERROR; }
#endif
    virtual bool supportsExternalBuffering();
    virtual CameraBuffer * allocateBufferList(int width, int dummyHeight, const char* format, int &bytes, int numBufs);
    virtual CameraBuffer *getBufferList(int *numBufs);
    virtual uint32_t * getOffsets() ;
    virtual int getFd() ;
    virtual int freeBufferList(CameraBuffer * buflist);
    virtual int maxQueueableBuffers(unsigned int& queueable);
    virtual int minUndequeueableBuffers(int& unqueueable);
    virtual bool match(const char * str);

    virtual CameraBuffer * getBuffers(bool reset = false);
    virtual unsigned int getSize();
    virtual int getBufferCount();

    static void frameCallback(CameraFrame* caFrame);
    void addFrame(CameraFrame* caFrame);
    void handleFrameCallback(CameraFrame* caFrame);
    bool handleFrameReturn();

private:
    void destroy();
    status_t returnBuffersToWindow();

private:
    preview_stream_ops_t*  mBufferSource;
    FrameProvider *mFrameProvider; // Pointer to the frame provider interface

    mutable android::Mutex mLock;
    int mBufferCount;
    CameraBuffer *mBuffers;

    android::KeyedVector<buffer_handle_t *, int> mFramesWithCameraAdapterMap;
    android::sp<ErrorNotifier> mErrorNotifier;
    android::sp<ReturnFrame> mReturnFrame;
    android::sp<QueueFrame> mQueueFrame;

    uint32_t mFrameWidth;
    uint32_t mFrameHeight;
    uint32_t mPreviewWidth;
    uint32_t mPreviewHeight;

    int mBufferSourceDirection;

    const char *mPixelFormat;
};

} // namespace Camera
} // namespace Ti

#endif

#endif