summaryrefslogtreecommitdiff
path: root/camera/QCameraStream.h
blob: 5724dbb3812fb89b6c49ceb208a9da92ee3296ff (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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*
** Copyright 2008, Google Inc.
** Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
**
** 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 ANDROID_HARDWARE_QCAMERA_STREAM_H
#define ANDROID_HARDWARE_QCAMERA_STREAM_H


#include <utils/threads.h>

#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <utils/threads.h>

#include "QCameraHWI.h"
#include "QCameraHWI_Mem.h"
#include "QCamera_Intf.h"
extern "C" {
#include <mm_camera_interface2.h>

#define DEFAULT_STREAM_WIDTH 320
#define DEFAULT_STREAM_HEIGHT 240
#define DEFAULT_LIVESHOT_WIDTH 2592
#define DEFAULT_LIVESHOT_HEIGHT 1944

#define MM_CAMERA_CH_PREVIEW_MASK    (0x01 << MM_CAMERA_CH_PREVIEW)
#define MM_CAMERA_CH_VIDEO_MASK      (0x01 << MM_CAMERA_CH_VIDEO)
#define MM_CAMERA_CH_SNAPSHOT_MASK   (0x01 << MM_CAMERA_CH_SNAPSHOT)

} /* extern C*/



typedef struct snap_hdr_record_t_ {
  bool hdr_on;
  int  num_frame;
  int  num_raw_received;

  /*in terms of 2^(n/6), e.g -6 means (1/2)x, while 12 is 4x*/
  int  exp[MAX_HDR_EXP_FRAME_NUM];
  mm_camera_ch_data_buf_t *recvd_frame[MAX_HDR_EXP_FRAME_NUM];
} snap_hdr_record_t;


namespace android {

class QCameraHardwareInterface;

class StreamQueue {
private:
    Mutex mQueueLock;
    Condition mQueueWait;
    bool mInitialized;

    //Vector<struct msm_frame *> mContainer;
    Vector<void *> mContainer;
public:
    StreamQueue();
    virtual ~StreamQueue();
    bool enqueue(void *element);
    void flush();
    void* dequeue();
    void init();
    void deinit();
    bool isInitialized();
bool isEmpty();
};


class QCameraStream { //: public virtual RefBase{

public:
    bool mInit;
    bool mActive;

    virtual status_t    init();
    virtual status_t    start();
    virtual void        stop();
    virtual void        release();

    status_t setFormat(uint8_t ch_type_mask, cam_format_t previewFmt);
    status_t setMode(int enable);

    virtual void        setHALCameraControl(QCameraHardwareInterface* ctrl);

    //static status_t     openChannel(mm_camera_t *, mm_camera_channel_type_t ch_type);
    virtual status_t    initChannel(int cameraId, uint32_t ch_type_mask);
    virtual status_t    deinitChannel(int cameraId, mm_camera_channel_type_t ch_type);
    virtual void releaseRecordingFrame(const void *opaque)
    {
      ;
    }
#if 0 // mzhu
    virtual status_t getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize)
    {
      return NO_ERROR;
    }
#endif // mzhu
    virtual void prepareHardware()
    {
      ;
    }
    virtual sp<IMemoryHeap> getHeap() const{return NULL;}
    virtual status_t    initDisplayBuffers(){return NO_ERROR;}
    virtual status_t initPreviewOnlyBuffers(){return NO_ERROR;}
    virtual sp<IMemoryHeap> getRawHeap() const {return NULL;}
    virtual void *getLastQueuedFrame(void){return NULL;}
    virtual status_t takePictureZSL(void){return NO_ERROR;}
    virtual status_t takeLiveSnapshot(){return NO_ERROR;}
    virtual status_t takePictureLiveshot(mm_camera_ch_data_buf_t* recvd_frame){return NO_ERROR;}
	virtual void setModeLiveSnapshot(bool){;}
    virtual status_t initSnapshotBuffers(cam_ctrl_dimension_t *dim,
                                 int num_of_buf){return NO_ERROR;}

    virtual void setFullSizeLiveshot(bool){};
    /* Set the ANativeWindow */
    virtual int setPreviewWindow(preview_stream_ops_t* window) {return NO_ERROR;}
    virtual void notifyROIEvent(fd_roi_t roi) {;}
    virtual void notifyWDenoiseEvent(cam_ctrl_status_t status, void * cookie) {};
    virtual void resetSnapshotCounters(void ){};
    virtual void InitHdrInfoForSnapshot(bool HDR_on, int number_frames, int *exp ) {};
    virtual void notifyHdrEvent(cam_ctrl_status_t status, void * cookie) {};

    QCameraStream();
    QCameraStream(int, camera_mode_t);
    virtual             ~QCameraStream();
    QCameraHardwareInterface*  mHalCamCtrl;
    mm_camera_ch_crop_t mCrop;

    int mCameraId;
    camera_mode_t myMode;

    mutable Mutex mStopCallbackLock;
    mutable Mutex mPreviewFrameLock;
	int     mSnapshotDataCallingBack;
    int     mFreeSnapshotBufAfterDataCb;
private:
   StreamQueue mBusyQueue;
   StreamQueue mFreeQueue;
public:
     friend void liveshot_callback(mm_camera_ch_data_buf_t *frame,void *user_data);
};

/*
*   Record Class
*/
class QCameraStream_record : public QCameraStream {
public:
  status_t    init();
  status_t    start() ;
  void        stop()  ;
  void        release() ;

  static QCameraStream*  createInstance(int cameraId, camera_mode_t);
  static void            deleteInstance(QCameraStream *p);

  QCameraStream_record() {};
  virtual             ~QCameraStream_record();

  status_t processRecordFrame(void *data);
  status_t initEncodeBuffers();
  status_t getBufferInfo(sp<IMemory>& Frame, size_t *alignedSize);
  //sp<IMemoryHeap> getHeap() const;

  void releaseRecordingFrame(const void *opaque);
  void debugShowVideoFPS() const;

  status_t takeLiveSnapshot();
private:
  QCameraStream_record(int, camera_mode_t);
  void releaseEncodeBuffer();

  cam_ctrl_dimension_t             dim;
  bool mDebugFps;

  mm_camera_reg_buf_t              mRecordBuf;
  //int                              record_frame_len;
  //static const int                 maxFrameCnt = 16;
  //camera_memory_t                 *mCameraMemoryPtr[maxFrameCnt];
  //int                              mNumRecordFrames;
  //sp<PmemPool>                     mRecordHeap[maxFrameCnt];
  struct msm_frame                *recordframes;
  //uint32_t                         record_offset[VIDEO_BUFFER_COUNT];
  mm_camera_ch_data_buf_t          mRecordedFrames[MM_CAMERA_MAX_NUM_FRAMES];
  //Mutex                            mRecordFreeQueueLock;
  //Vector<mm_camera_ch_data_buf_t>  mRecordFreeQueue;

  int mJpegMaxSize;
  QCameraStream *mStreamSnap;

};

class QCameraStream_preview : public QCameraStream {
public:
    status_t    init();
    status_t    start() ;
    void        stop()  ;
    void        release() ;

    static QCameraStream*  createInstance(int, camera_mode_t);
    static void            deleteInstance(QCameraStream *p);

    QCameraStream_preview() {};
    virtual             ~QCameraStream_preview();
    void *getLastQueuedFrame(void);
    /*init preview buffers with display case*/
    status_t initDisplayBuffers();
    /*init preview buffers without display case*/
    status_t initPreviewOnlyBuffers();

    status_t processPreviewFrame(mm_camera_ch_data_buf_t *frame);

    /*init preview buffers with display case*/
    status_t processPreviewFrameWithDisplay(mm_camera_ch_data_buf_t *frame);
    /*init preview buffers without display case*/
    status_t processPreviewFrameWithOutDisplay(mm_camera_ch_data_buf_t *frame);

    int setPreviewWindow(preview_stream_ops_t* window);
    void notifyROIEvent(fd_roi_t roi);
    friend class QCameraHardwareInterface;

private:
    QCameraStream_preview(int cameraId, camera_mode_t);
    /*allocate and free buffers with display case*/
    status_t                 getBufferFromSurface();
    status_t                 putBufferToSurface();

    /*allocate and free buffers without display case*/
    status_t                 getBufferNoDisplay();
    status_t                 freeBufferNoDisplay();

    void                     dumpFrameToFile(struct msm_frame* newFrame);
    bool                     mFirstFrameRcvd;

    int8_t                   my_id;
    mm_camera_op_mode_type_t op_mode;
    cam_ctrl_dimension_t     dim;
    struct msm_frame        *mLastQueuedFrame;
    mm_camera_reg_buf_t      mDisplayBuf;
    mm_cameara_stream_buf_t  mDisplayStreamBuf;
    Mutex                   mDisplayLock;
    preview_stream_ops_t   *mPreviewWindow;
    static const int        kPreviewBufferCount = PREVIEW_BUFFER_COUNT;
    mm_camera_ch_data_buf_t mNotifyBuffer[16];
    int8_t                  mNumFDRcvd;
    int                     mVFEOutputs;
    int                     mHFRFrameCnt;
    int                     mHFRFrameSkip;
};

/* Snapshot Class - handle data flow*/
class QCameraStream_Snapshot : public QCameraStream {
public:
    status_t    init();
    status_t    start();
    void        stop();
    void        release();
    void        prepareHardware();
    static QCameraStream* createInstance(int cameraId, camera_mode_t);
    static void deleteInstance(QCameraStream *p);

    status_t takePictureZSL(void);
    status_t takePictureLiveshot(mm_camera_ch_data_buf_t* recvd_frame);
    status_t receiveRawPicture(mm_camera_ch_data_buf_t* recvd_frame);
    void receiveCompleteJpegPicture(jpeg_event_t event);
	void jpegErrorHandler(jpeg_event_t event);
    void receiveJpegFragment(uint8_t *ptr, uint32_t size);
    void deInitBuffer(void);
    sp<IMemoryHeap> getRawHeap() const;
    int getSnapshotState();
    /*Temp: to be removed once event handling is enabled in mm-camera*/
    void runSnapshotThread(void *data);
    bool isZSLMode();
    void setFullSizeLiveshot(bool);
    void notifyWDenoiseEvent(cam_ctrl_status_t status, void * cookie);
    friend void liveshot_callback(mm_camera_ch_data_buf_t *frame,void *user_data);
    void resetSnapshotCounters(void );
    void InitHdrInfoForSnapshot(bool HDR_on, int number_frames, int *exp );
    void notifyHdrEvent(cam_ctrl_status_t status, void * cookie);
    bool getSnapJpegCbState(void);
    void setSnapJpegCbState(bool state);

private:
    QCameraStream_Snapshot(int, camera_mode_t);
    virtual ~QCameraStream_Snapshot();

    /* snapshot related private members */
    status_t initJPEGSnapshot(int num_of_snapshots);
    status_t initRawSnapshot(int num_of_snapshots);
    status_t initZSLSnapshot(void);
    status_t initFullLiveshot(void);
	status_t cancelPicture();
    void notifyShutter(common_crop_t *crop,
                       bool play_shutter_sound);
    status_t initSnapshotBuffers(cam_ctrl_dimension_t *dim,
                                 int num_of_buf);
    status_t initRawSnapshotBuffers(cam_ctrl_dimension_t *dim,
                                    int num_of_buf);
    status_t deinitRawSnapshotBuffers(void);
    status_t deinitSnapshotBuffers(void);
    status_t initRawSnapshotChannel(cam_ctrl_dimension_t* dim,
                                    int num_snapshots);
    status_t initSnapshotFormat(cam_ctrl_dimension_t *dim);
    status_t takePictureRaw(void);
    status_t takePictureJPEG(void);
    status_t startStreamZSL(void);
    void deinitSnapshotChannel(mm_camera_channel_type_t);
    status_t configSnapshotDimension(cam_ctrl_dimension_t* dim);
    status_t encodeData(mm_camera_ch_data_buf_t* recvd_frame,
                        common_crop_t *crop_info,
                        int frame_len,
                        bool enqueued);
    status_t encodeDisplayAndSave(mm_camera_ch_data_buf_t* recvd_frame,
                                  bool enqueued);
    status_t setZSLChannelAttribute(void);
    void handleError();
    void setSnapshotState(int state);
    void setModeLiveSnapshot(bool);
    bool isLiveSnapshot(void);
    void stopPolling(void);
    bool isFullSizeLiveshot(void);
    status_t doWaveletDenoise(mm_camera_ch_data_buf_t* frame);
    status_t sendWDenoiseStartMsg(mm_camera_ch_data_buf_t * frame);
    void lauchNextWDenoiseFromQueue();
    status_t doHdrProcessing( );

    /* Member variables */

    int mSnapshotFormat;
    int mPictureWidth;
    int mPictureHeight;
    cam_format_t mPictureFormat;
    int mPostviewWidth;
    int mPostviewHeight;
    int mThumbnailWidth;
    int mThumbnailHeight;
    cam_format_t mThumbnailFormat;
	int mJpegOffset;
    int mSnapshotState;
    int mNumOfSnapshot;
	int mNumOfRecievedJPEG;
    bool mModeLiveSnapshot;
    bool mBurstModeFlag;
	int mActualPictureWidth;
    int mActualPictureHeight;
    bool mJpegDownscaling;
    sp<AshmemPool> mJpegHeap;
    /*TBD:Bikas: This is defined in HWI too.*/
#ifdef USE_ION
    sp<IonPool>  mDisplayHeap;
    sp<IonPool>  mPostviewHeap;
#else
    sp<PmemPool>  mDisplayHeap;
    sp<PmemPool>  mPostviewHeap;
#endif
    mm_camera_ch_data_buf_t *mCurrentFrameEncoded;
    mm_cameara_stream_buf_t mSnapshotStreamBuf;
    mm_cameara_stream_buf_t mPostviewStreamBuf;
    StreamQueue             mSnapshotQueue;
    static const int        mMaxSnapshotBufferCount = 16;
    int                     mSnapshotBufferNum;
    int                     mMainfd[mMaxSnapshotBufferCount];
    int                     mThumbfd[mMaxSnapshotBufferCount];
    int                     mMainSize;
    int                     mThumbSize;
	camera_memory_t        *mCameraMemoryPtrMain[mMaxSnapshotBufferCount];
	camera_memory_t        *mCameraMemoryPtrThumb[mMaxSnapshotBufferCount];
    int                     mJpegSessionId;
	int                     dump_fd;
    bool mFullLiveshot;
    StreamQueue             mWDNQueue; // queue to hold frames while one frame is sent out for WDN
    bool                    mIsDoingWDN; // flag to indicate if WDN is going on (one frame is sent out for WDN)
	bool                    mDropThumbnail;
	int                     mJpegQuality;
    snap_hdr_record_t       mHdrInfo;
    int hdrRawCount;
    int hdrJpegCount;
}; // QCameraStream_Snapshot


}; // namespace android

#endif