1/*Copyright (c) 2016, The Linux Foundation. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#include "QCameraHAL3MainTestContext.h"
31#include "QCameraHAL3SnapshotTest.h"
32#include "QCameraHAL3RawSnapshotTest.h"
33#include "QCameraHAL3PreviewTest.h"
34
35#ifdef QCAMERA_HAL3_SUPPORT
36#define LIB_PATH /usr/lib/hw/camera.msm8953.so
37#else
38#define LIB_PATH /system/lib/hw/camera.msm8953.so
39#endif
40
41extern "C" {
42extern int set_camera_metadata_vendor_ops(const vendor_tag_ops_t *query_ops);
43}
44
45/*#ifdef CAMERA_CHIPSET_8953
46#define CHIPSET_LIB lib/hw/camera.msm8953.so
47#else
48#define CHIPSET_LIB lib/hw/camera.msm8937.so
49#endif*/
50
51#define CAM_LIB(s) STR_LIB_PATH(s)
52#define STR_LIB_PATH(s) #s
53
54namespace qcamera {
55
56QCameraHAL3PreviewTest *mPreviewtestCase = NULL;
57QCameraHAL3VideoTest *mVideotestCase = NULL;
58QCameraHAL3SnapshotTest *mSnapshottestCase = NULL;
59QCameraHAL3RawSnapshotTest *mRawSnapshottestCase = NULL;
60
61struct timeval start_time;
62int capture_received;
63int pfd[2];
64extern int test_case_end;
65extern int snapshot_buffer;
66
67pthread_cond_t mRequestAppCond;
68std::list<uint32_t> PreviewQueue;
69std::list<uint32_t> VideoQueue;
70
71pthread_mutex_t TestAppLock = PTHREAD_MUTEX_INITIALIZER;
72pthread_mutex_t mCaptureRequestLock = PTHREAD_MUTEX_INITIALIZER;
73
74
75
76static void camera_device_status_change(
77        const struct camera_module_callbacks* callbacks,
78        int camera_id, int new_status)
79{
80    /* Stub function */
81    if (callbacks == NULL) {
82        LOGD("Parameters are NULL %d %d", camera_id, new_status);
83    }
84}
85
86static void torch_mode_status_change(
87        const struct camera_module_callbacks* callbacks,
88        const char* camera_id, int new_status)
89{
90    /* Stub function */
91    if((callbacks == NULL) || (camera_id == NULL)) {
92        LOGD("Parameters are NULL %d", new_status);
93    }
94}
95
96static void Notify(
97        const camera3_callback_ops *cb,
98        const camera3_notify_msg *msg)
99{
100    /* Stub function */
101    if((cb == NULL) || (msg == NULL)) {
102        LOGD("Parameters are NULL ");
103    }
104}
105
106static void ProcessCaptureResult(
107        const camera3_callback_ops *cb,
108        const camera3_capture_result *result)
109{
110    buffer_thread_msg_t msg;
111    extern CameraHAL3Base *mCamHal3Base;
112    int frame_num;
113    extern int req_sent;
114    extern int preview_buffer_allocated;
115    extern int video_buffer_allocated;
116    int num;
117    if(cb == NULL) {
118        LOGD("callback returned is NULL");
119    }
120    LOGD("Cam Capture Result Callback %d and %d",
121            result->num_output_buffers, mCamHal3Base->mFrameCount);
122    if (mCamHal3Base->mTestCaseSelected == MENU_START_PREVIEW ||
123            mCamHal3Base->mTestCaseSelected == MENU_START_VIDEO) {
124        if (result->num_output_buffers == 1) {
125            frame_num = result->frame_number;
126            LOGD("Frame width:%d and height:%d and format:%d",
127                    result->output_buffers->stream->width,
128                    result->output_buffers->stream->height,
129                    result->output_buffers->stream->format);
130            (mCamHal3Base->mFrameCount)++;
131            LOGD("Preview/Video Capture Result %d and fcount: %d and req_Sent:%d and %d ",
132            result->num_output_buffers, mCamHal3Base->mFrameCount, req_sent, result->frame_number);
133            if (test_case_end == 0) {
134                if (mCamHal3Base->mTestCaseSelected == MENU_START_PREVIEW) {
135                    num = (result->frame_number)%preview_buffer_allocated;
136                    PreviewQueue.push_back(num);
137                }
138                else {
139                    num = (result->frame_number)%video_buffer_allocated;
140                           VideoQueue.push_back(num);
141                }
142                pthread_cond_signal(&mRequestAppCond);
143                memset(&msg, 0, sizeof(buffer_thread_msg_t));
144            }
145        }
146    }
147    else {
148        extern int fcount_captured;
149        if (result->num_output_buffers == 1) {
150            LOGD("snapshot/Raw Capture1 Result Callback %d and %d",
151                    result->num_output_buffers, fcount_captured);
152            (mCamHal3Base->mFrameCount)++;
153            fcount_captured++;
154            LOGD("\n Capture %d done preparing for capture ", fcount_captured);
155            memset(&msg, 0, sizeof(buffer_thread_msg_t));
156            write(pfd[1], &msg, sizeof(buffer_thread_msg_t));
157        }
158    }
159}
160
161CameraHAL3Base::CameraHAL3Base(int cameraIndex) :
162    mCameraIndex(cameraIndex),
163    mLibHandle(NULL),
164    mFrameCount(0),
165    mSecElapsed(1),
166    mTestCaseSelected(0),
167    mPreviewRunning(0),
168    mVideoRunning(0),
169    mSnapShotRunning(0),
170    binning_mode(0)
171{
172
173}
174
175
176int CameraHAL3Base::hal3appCameraTestLoad()
177{
178    int rc = HAL3_CAM_OK;
179    int numCam;
180    int32_t res = 0;
181    hal3_camera_test_obj_t *my_test_obj;
182    mLibHandle = new hal3_camera_lib_test;
183    memset(mLibHandle, 0, sizeof(hal3_camera_lib_handle));
184    rc = hal3appTestLoad(&mLibHandle->app_obj);
185    camera_module_t *my_if_handle = mLibHandle->app_obj.hal3_lib.halModule_t;
186    if (HAL3_CAM_OK != rc) {
187        LOGE("hal3 err\n");
188        goto EXIT;
189    }
190
191    numCam = my_if_handle->get_number_of_cameras();
192    printf("\n Number of Cameras are : %d ", numCam);
193    if (my_if_handle->get_vendor_tag_ops) {
194        mLibHandle->app_obj.mVendorTagOps = vendor_tag_ops_t();
195        my_if_handle->get_vendor_tag_ops(&(mLibHandle->app_obj.mVendorTagOps));
196
197        res = set_camera_metadata_vendor_ops(&(mLibHandle->app_obj.mVendorTagOps));
198        if (0 != res) {
199            printf("%s: Could not set vendor tag descriptor, "
200                    "received error %s (%d). \n", __func__,
201                    strerror(-res), res);
202            goto EXIT;
203        }
204    }
205    my_test_obj = &(mLibHandle->test_obj);
206    my_test_obj->module_cb.torch_mode_status_change = &torch_mode_status_change;
207    my_test_obj->module_cb.camera_device_status_change = &camera_device_status_change;
208    my_if_handle->set_callbacks(&(my_test_obj->module_cb));
209    my_if_handle->get_camera_info(0, &(mLibHandle->test_obj.cam_info));
210    camcap_info = mLibHandle->test_obj.cam_info;
211    hal3app_cam_settings = (camcap_info.static_camera_characteristics);
212    display_capability();
213    return numCam;
214    EXIT:
215    return rc;
216
217}
218
219void CameraHAL3Base::display_capability()
220{
221    ALOGE("Camera Here");
222    int i;
223    int *available_ir_modes = NULL;
224    if(hal3app_cam_settings.exists(QCAMERA3_IR_AVAILABLE_MODES)) {
225        ALOGE("\n mrad check1 ");
226        entry_hal3app = hal3app_cam_settings.find(QCAMERA3_IR_AVAILABLE_MODES);
227        available_ir_modes = (int *) malloc((entry_hal3app.count)*sizeof(int ));
228        for(i =0;i < (int)entry_hal3app.count; i++){
229                    available_ir_modes[i] = entry_hal3app.data.i32[i];
230            ALOGE("\n mrad cap %d ", available_ir_modes[i]);
231
232        }
233    }
234}
235
236int CameraHAL3Base::hal3appCameraLibOpen(int camid)
237{
238    int rc;
239    rc = hal3appCamOpen(&mLibHandle->app_obj, (int)camid, &(mLibHandle->test_obj));
240    if (rc != HAL3_CAM_OK) {
241        LOGE("hal3appCamOpen() camidx=%d, err=%d\n",
242                camid, rc);
243        goto EXIT;
244    }
245    rc = hal3appCamInitialize((int)camid, &mLibHandle->test_obj);
246    EXIT:
247    return rc;
248}
249
250int CameraHAL3Base::hal3appTestLoad(hal3_camera_app_t *my_hal3_app)
251{
252    memset(&my_hal3_app->hal3_lib, 0, sizeof(hal3_interface_lib_t));
253    printf("\nLibrary path is :%s", CAM_LIB(LIB_PATH));
254    my_hal3_app->hal3_lib.ptr = dlopen(CAM_LIB(LIB_PATH), RTLD_NOW);
255
256    if (!my_hal3_app->hal3_lib.ptr) {
257        LOGE("Error opening HAL libraries %s\n",
258                dlerror());
259        return -HAL3_CAM_E_GENERAL;
260    }
261    my_hal3_app->hal3_lib.halModule_t =
262        (camera_module_t*)dlsym(my_hal3_app->hal3_lib.ptr, HAL_MODULE_INFO_SYM_AS_STR);
263    if (my_hal3_app->hal3_lib.halModule_t == NULL) {
264        LOGE("Error opening HAL library %s\n",
265                dlerror());
266        return -HAL3_CAM_E_GENERAL;
267    }
268    return HAL3_CAM_OK;
269}
270
271int CameraHAL3Base::hal3appCamOpen(
272        hal3_camera_app_t *my_hal3_app,
273        int camid,
274        hal3_camera_test_obj_t *my_test_obj)
275{
276    camera_module_t *my_if_handle = my_hal3_app->hal3_lib.halModule_t;
277    my_if_handle->common.methods->open(&(my_if_handle->common), "0",
278            reinterpret_cast<hw_device_t**>(&(my_test_obj->device)));
279    printf("\n Camera ID %d Opened \n", camid);
280    return HAL3_CAM_OK;
281}
282
283int CameraHAL3Base::hal3appCamInitialize(int camid, hal3_camera_test_obj_t *my_test_obj)
284{
285    int rc = 0;
286    camera3_device_t *device_handle = my_test_obj->device;
287    my_test_obj->callback_ops.notify = &Notify;
288    my_test_obj->callback_ops.process_capture_result = &ProcessCaptureResult;
289    rc = device_handle->ops->initialize(my_test_obj->device, &(my_test_obj->callback_ops));
290    if (rc != HAL3_CAM_OK) {
291        LOGE("hal3appCamInitialize() camidx=%d, err=%d\n",
292                camid, rc);
293        goto EXIT;
294    }
295    EXIT:
296    return rc;
297}
298
299
300void CameraHAL3Base::hal3appCheckStream(int testcase, int camid)
301{
302    if (testcase != MENU_START_PREVIEW) {
303        if (mPreviewtestCase != NULL) {
304            mPreviewtestCase->previewTestEnd(mLibHandle, camid);
305            delete mPreviewtestCase;
306            mPreviewtestCase = NULL;
307        }
308    }
309    if (testcase != MENU_START_VIDEO){
310        if (mVideotestCase != NULL) {
311            mVideotestCase->videoTestEnd(mLibHandle, camid);
312            delete mVideotestCase;
313            mVideotestCase = NULL;
314        }
315    }
316
317    if (testcase != MENU_START_CAPTURE){
318        if (mSnapshottestCase != NULL) {
319            delete mSnapshottestCase;
320            mSnapshottestCase = NULL;
321        }
322    }
323
324    if (testcase != MENU_START_RAW_CAPTURE) {
325        if (mRawSnapshottestCase != NULL) {
326            delete mRawSnapshottestCase;
327            mRawSnapshottestCase = NULL;
328        }
329    }
330}
331
332
333int CameraHAL3Base::hal3appCameraPreviewInit(int testcase, int camid, int w, int h)
334{
335    extern int req_sent;
336    int testCaseEndComplete = 0;
337    if (w == 0 || h == 0) {
338        printf("\n Frame dimension is wrong");
339        return -1;
340    }
341    if ( mPreviewtestCase != NULL) {
342        if(testcase == MENU_TOGGLE_IR_MODE) {
343            ALOGE("\n IR mode requested is :%d", ir_mode);
344            mPreviewtestCase->ir_mode = ir_mode;
345        }
346        if(testcase == MENU_TOGGLE_SVHDR_MODE) {
347            ALOGE("\n SVHDR mode requested is :%d", svhdr_mode);
348            mPreviewtestCase->svhdr_mode = svhdr_mode;
349        }
350        return 0;
351    }
352    else {
353        testCaseEndComplete = 0;
354        do {
355            if (mVideoRunning == 1) {
356                hal3appCheckStream(MENU_START_PREVIEW, camid);
357            }
358            pthread_mutex_lock(&TestAppLock);
359            mTestCaseSelected = MENU_START_PREVIEW;
360            if (mVideoRunning != 1) {
361                hal3appCheckStream(MENU_START_PREVIEW, camid);
362            }
363            mPreviewtestCase = new QCameraHAL3PreviewTest(0);
364            printf("\n\n Testing the Resolution : %d X %d", w, h);
365            req_sent = 0;
366            PreviewQueue.clear();
367            capture_received = 0; mSecElapsed = 1;
368            snapshot_buffer = -1; mFrameCount = 0;
369            mPreviewtestCase->width = w; mPreviewtestCase->height = h;
370            mPreviewtestCase->ir_mode = 0; mPreviewtestCase->svhdr_mode = 0;
371            mPreviewtestCase->initTest(mLibHandle,
372                    (int) MENU_START_PREVIEW, camid, w, h);
373            testCaseEndComplete = 1;
374        }while(testCaseEndComplete != 1);
375    }
376    return 0;
377}
378
379int CameraHAL3Base::hal3appCameraVideoInit(int testcase, int camid, int w, int h)
380{
381    extern int req_sent;
382    int testCaseEndComplete = 0;
383    if (w == 0 || h == 0) {
384        printf("\n Frame dimension is wrong");
385        return -1;
386    }
387
388    if (mVideotestCase != NULL) {
389        if(testcase == MENU_TOGGLE_BINNING_CORRECTION) {
390            ALOGE("\n Binning Mode Requested is :%d", binning_mode);
391            mVideotestCase->binning_mode = binning_mode;
392        }
393        return 0;
394    }
395    else {
396        testCaseEndComplete = 0;
397        do {
398            if (mPreviewRunning == 1) {
399                hal3appCheckStream(MENU_START_VIDEO, camid);
400            }
401            pthread_mutex_lock(&TestAppLock);
402            mTestCaseSelected = MENU_START_VIDEO;
403            if (mPreviewRunning != 1) {
404                hal3appCheckStream(MENU_START_VIDEO, camid);
405            }
406            mVideotestCase = new QCameraHAL3VideoTest(0);
407            VideoQueue.clear();
408            printf("\n\nTesting the Resolution : %d X %d", w, h);
409            req_sent = 0;
410            capture_received =0; mSecElapsed = 1; test_case_end = 0;
411            mVideotestCase->width = w; mVideotestCase->height = h;
412            snapshot_buffer = -1; mFrameCount = 0;
413            mVideotestCase->initTest(mLibHandle,
414                    (int) MENU_START_VIDEO, camid, w, h);
415            testCaseEndComplete = 1;
416        }while(testCaseEndComplete !=1);
417    }
418    return 0;
419}
420
421
422int CameraHAL3Base::hal3appRawCaptureInit(hal3_camera_lib_test *handle, int camid, int req_cap)
423{
424    int testCaseEndComplete = 0;
425    if(handle == NULL) {
426        LOGE("Camera Handle is NULL");
427    }
428    if (mSnapShotRunning != 1) {
429        hal3appCheckStream(MENU_START_RAW_CAPTURE, camid);
430    }
431    testCaseEndComplete = 0;
432    do {
433        pthread_mutex_lock(&TestAppLock);
434        if (mSnapShotRunning == 1) {
435            hal3appCheckStream(MENU_START_RAW_CAPTURE, camid);
436        }
437        printf("\n capture:%d", req_cap);
438        mTestCaseSelected = MENU_START_RAW_CAPTURE;
439        mRawSnapshottestCase = new QCameraHAL3RawSnapshotTest(req_cap);
440        mRawSnapshottestCase->mRequestedCapture = req_cap;
441        mRawSnapshottestCase->initTest(mLibHandle,
442        (int) MENU_START_RAW_CAPTURE, camid, RAWSNAPSHOT_CAPTURE_WIDTH,
443                RAWSNAPSHOT_CAPTURE_HEIGHT);
444        testCaseEndComplete = 1;
445    }while(testCaseEndComplete !=1);
446    return 0;
447}
448
449int CameraHAL3Base::hal3appCameraCaptureInit(hal3_camera_lib_test *handle,
450        int camid, int req_cap)
451{
452    int testCaseEndComplete = 0;
453    if(handle == NULL) {
454        LOGE("Camera Handle is NULL");
455    }
456    if (mSnapShotRunning != 1) {
457        hal3appCheckStream(MENU_START_CAPTURE, camid);
458    }
459    testCaseEndComplete = 0;
460    do {
461        pthread_mutex_lock(&TestAppLock);
462        if (mSnapShotRunning == 1) {
463            hal3appCheckStream(MENU_START_CAPTURE, camid);
464        }
465        printf("\n capture:%d", req_cap);
466        mTestCaseSelected = MENU_START_CAPTURE;
467        mSnapshottestCase = new QCameraHAL3SnapshotTest(req_cap);
468        mSnapshottestCase->mRequestedCapture = req_cap;
469        mSnapshottestCase->initTest(mLibHandle,
470            (int) MENU_START_CAPTURE, camid, SNAPSHOT_CAPTURE_WIDTH, SNAPSHOT_CAPTURE_HEIGHT);
471        testCaseEndComplete = 1;
472    }while(testCaseEndComplete != 1);
473    return 0;
474}
475
476}
477
478