1 /*
2 ** Copyright (c) 2012 The Linux Foundation. All rights reserved.
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 /*#error uncomment this for compiler test!*/
18 
19 #define ALOG_NDEBUG 0
20 #define ALOG_NIDEBUG 0
21 #define LOG_TAG "QCameraHWI_Record"
22 #include <utils/Log.h>
23 #include <utils/threads.h>
24 #include <cutils/properties.h>
25 #include <fcntl.h>
26 #include <sys/mman.h>
27 
28 #include "QCameraStream.h"
29 
30 
31 #define LIKELY(exp)   __builtin_expect(!!(exp), 1)
32 #define UNLIKELY(exp) __builtin_expect(!!(exp), 0)
33 
34 /* QCameraStream_record class implementation goes here*/
35 /* following code implement the video streaming capture & encoding logic of this class*/
36 // ---------------------------------------------------------------------------
37 // QCameraStream_record createInstance()
38 // ---------------------------------------------------------------------------
39 namespace android {
40 
41 
createInstance(int cameraId,camera_mode_t mode)42 QCameraStream* QCameraStream_record::createInstance(int cameraId,
43                                       camera_mode_t mode)
44 {
45   ALOGV("%s: BEGIN", __func__);
46   QCameraStream* pme = new QCameraStream_record(cameraId, mode);
47   ALOGV("%s: END", __func__);
48   return pme;
49 }
50 
51 // ---------------------------------------------------------------------------
52 // QCameraStream_record deleteInstance()
53 // ---------------------------------------------------------------------------
deleteInstance(QCameraStream * ptr)54 void QCameraStream_record::deleteInstance(QCameraStream *ptr)
55 {
56   ALOGV("%s: BEGIN", __func__);
57   if (ptr){
58     ptr->release();
59     delete ptr;
60     ptr = NULL;
61   }
62   ALOGV("%s: END", __func__);
63 }
64 
65 // ---------------------------------------------------------------------------
66 // QCameraStream_record Constructor
67 // ---------------------------------------------------------------------------
QCameraStream_record(int cameraId,camera_mode_t mode)68 QCameraStream_record::QCameraStream_record(int cameraId,
69                                            camera_mode_t mode)
70   :QCameraStream(cameraId,mode),
71    mDebugFps(false)
72 {
73   mHalCamCtrl = NULL;
74   char value[PROPERTY_VALUE_MAX];
75   ALOGV("%s: BEGIN", __func__);
76 
77   property_get("persist.debug.sf.showfps", value, "0");
78   mDebugFps = atoi(value);
79 
80   ALOGV("%s: END", __func__);
81 }
82 
83 // ---------------------------------------------------------------------------
84 // QCameraStream_record Destructor
85 // ---------------------------------------------------------------------------
~QCameraStream_record()86 QCameraStream_record::~QCameraStream_record() {
87   ALOGV("%s: BEGIN", __func__);
88   if(mActive) {
89     stop();
90   }
91   if(mInit) {
92     release();
93   }
94   mInit = false;
95   mActive = false;
96   ALOGV("%s: END", __func__);
97 
98 }
99 
100 // ---------------------------------------------------------------------------
101 // QCameraStream_record Callback from mm_camera
102 // ---------------------------------------------------------------------------
record_notify_cb(mm_camera_ch_data_buf_t * bufs_new,void * user_data)103 static void record_notify_cb(mm_camera_ch_data_buf_t *bufs_new,
104                               void *user_data)
105 {
106   QCameraStream_record *pme = (QCameraStream_record *)user_data;
107   mm_camera_ch_data_buf_t *bufs_used = 0;
108   ALOGV("%s: BEGIN", __func__);
109 
110   /*
111   * Call Function Process Video Data
112   */
113   pme->processRecordFrame(bufs_new);
114   ALOGV("%s: END", __func__);
115 }
116 
117 // ---------------------------------------------------------------------------
118 // QCameraStream_record
119 // ---------------------------------------------------------------------------
init()120 status_t QCameraStream_record::init()
121 {
122   status_t ret = NO_ERROR;
123   ALOGV("%s: BEGIN", __func__);
124   mInit = true;
125   ALOGV("%s: END", __func__);
126   return ret;
127 }
128 // ---------------------------------------------------------------------------
129 // QCameraStream_record
130 // ---------------------------------------------------------------------------
131 
start()132 status_t QCameraStream_record::start()
133 {
134   status_t ret = NO_ERROR;
135   ALOGE("%s: BEGIN", __func__);
136 
137   ret = initEncodeBuffers();
138   if (NO_ERROR!=ret) {
139     ALOGE("%s ERROR: Buffer Allocation Failed\n",__func__);
140     return ret;
141   }
142   Mutex::Autolock l(&mHalCamCtrl->mRecordLock);
143   mHalCamCtrl->mReleasedRecordingFrame = false;
144 
145   mHalCamCtrl->mStartRecording  = true;
146 
147   ALOGV("%s: END", __func__);
148   return ret;
149 }
150 
151 // ---------------------------------------------------------------------------
152 // QCameraStream_record
153 // ---------------------------------------------------------------------------
stop()154 void QCameraStream_record::stop()
155 {
156   status_t ret = NO_ERROR;
157   ALOGE("%s: BEGIN", __func__);
158   mHalCamCtrl->mStartRecording  = false;
159   Mutex::Autolock l(&mHalCamCtrl->mRecordLock);
160   {
161         mHalCamCtrl->mRecordFrameLock.lock();
162         mHalCamCtrl->mReleasedRecordingFrame = true;
163         mHalCamCtrl->mRecordWait.signal();
164         mHalCamCtrl-> mRecordFrameLock.unlock();
165   }
166 
167   for(int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
168     if (mHalCamCtrl->mStoreMetaDataInFrame) {
169       struct encoder_media_buffer_type * packet =
170           (struct encoder_media_buffer_type  *)
171           mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
172       native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
173       mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
174 		    mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);
175     }
176   }
177   ALOGV("%s: END", __func__);
178 
179 }
180 // ---------------------------------------------------------------------------
181 // QCameraStream_record
182 // ---------------------------------------------------------------------------
release()183 void QCameraStream_record::release()
184 {
185   status_t ret = NO_ERROR;
186   ALOGV("%s: BEGIN", __func__);
187   ALOGV("%s: END", __func__);
188 }
189 
processRecordFrame(void * data)190 status_t QCameraStream_record::processRecordFrame(void *data)
191 {
192   ALOGE("%s : BEGIN",__func__);
193   ALOGE("%s : END",__func__);
194   return NO_ERROR;
195 }
196 
197 //Record Related Functions
initEncodeBuffers()198 status_t QCameraStream_record::initEncodeBuffers()
199 {
200   ALOGE("%s : BEGIN",__func__);
201   status_t ret = NO_ERROR;
202     for (int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
203       if (mHalCamCtrl->mStoreMetaDataInFrame) {
204         mHalCamCtrl->mRecordingMemory.metadata_memory[cnt] =
205           mHalCamCtrl->mGetMemory(-1,
206           sizeof(struct encoder_media_buffer_type), 1, (void *)this);
207         struct encoder_media_buffer_type * packet =
208           (struct encoder_media_buffer_type  *)
209           mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
210         packet->meta_handle = native_handle_create(1, 3); //1 fd, 1 offset,1 size and 1 data
211         packet->buffer_type = kMetadataBufferTypeCameraSource;
212         native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
213         nh->data[0] = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->fd;
214         nh->data[1] = 0;
215         nh->data[2] = mHalCamCtrl->mPreviewMemory.private_buffer_handle[cnt]->size;
216         nh->data[3] = (uint32_t)mHalCamCtrl->mPreviewMemory.camera_memory[cnt]->data;
217       }
218     }
219     ALOGE("%s : END",__func__);
220     return NO_ERROR;
221 }
222 
releaseEncodeBuffer()223 void QCameraStream_record::releaseEncodeBuffer() {
224   for(int cnt = 0; cnt < mHalCamCtrl->mPreviewMemory.buffer_count; cnt++) {
225     if (mHalCamCtrl->mStoreMetaDataInFrame) {
226       struct encoder_media_buffer_type * packet =
227           (struct encoder_media_buffer_type  *)
228           mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->data;
229       native_handle_delete(const_cast<native_handle_t *>(packet->meta_handle));
230       mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]->release(
231         mHalCamCtrl->mRecordingMemory.metadata_memory[cnt]);
232 
233     }
234   }
235 }
236 
releaseRecordingFrame(const void * opaque)237 void QCameraStream_record::releaseRecordingFrame(const void *opaque)
238 {
239     Mutex::Autolock rLock(&mHalCamCtrl->mRecordFrameLock);
240     mHalCamCtrl->mReleasedRecordingFrame = true;
241     mHalCamCtrl->mRecordWait.signal();
242     ALOGE("%s, Signaling from-",__func__);
243 }
244 
debugShowVideoFPS() const245 void QCameraStream_record::debugShowVideoFPS() const
246 {
247 
248 }
249 
takeLiveSnapshot()250 status_t  QCameraStream_record::takeLiveSnapshot(){
251 	return true;
252 }
253 
254 }//namespace android
255