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#include "QCameraHAL3SnapshotTest.h"
30#include "QCameraHAL3MainTestContext.h"
31
32
33namespace qcamera {
34
35hal3_camera_lib_test *Snapshot_CamObj_handle;
36int fcount_captured;
37extern pthread_mutex_t TestAppLock;
38QCameraHAL3SnapshotTest::QCameraHAL3SnapshotTest(int req_cap) :
39    QCameraHAL3Test(0),
40    mCaptureHandle(NULL),
41    mSnapshotStream(NULL),
42    mRequestedCapture(req_cap)
43{
44
45}
46
47void QCameraHAL3SnapshotTest::initTest(hal3_camera_lib_test *handle,
48        int testcase, int camid, int w, int h)
49{
50    fcount_captured = 0;
51    Snapshot_CamObj_handle = handle;
52    LOGD("\ntestcase %d  %d and %d ",testcase, w, h);
53    configureSnapshotStream(&(handle->test_obj), camid, w, h);
54
55    constructDefaultRequest(&(handle->test_obj), 0);
56    LOGD("\n Snapshot Default stream setting read");
57
58    LOGD("\n Snapshot stream configured");
59    snapshotThreadCreate(MENU_START_CAPTURE, hal3appSnapshotProcessBuffers);
60    (mRequest.frame_number) = 0;
61    snapshotProcessCaptureRequest(&(handle->test_obj), 0);
62    LOGD("\n Snapshot Process Capture Request Sent");
63}
64
65void QCameraHAL3SnapshotTest::constructDefaultRequest(
66        hal3_camera_test_obj_t *my_test_obj, int camid)
67{
68    camera3_device_t *device_handle = my_test_obj->device;
69    LOGD("Camera ID : %d",camid);
70    mMetaDataPtr[0]= device_handle->ops->construct_default_request_settings(my_test_obj->device,
71            CAMERA3_TEMPLATE_PREVIEW);
72    mMetaDataPtr[1] = device_handle->ops->construct_default_request_settings(my_test_obj->device,
73            CAMERA3_TEMPLATE_STILL_CAPTURE);
74}
75
76void QCameraHAL3SnapshotTest::configureSnapshotStream(hal3_camera_test_obj_t *my_test_obj,
77        int camid, int w, int h)
78{
79    camera3_device_t *device_handle = my_test_obj->device;
80    LOGD(" configureSnapshotStream testcase dim :%d  X %d", w, h);
81    mPreviewStream = new camera3_stream_t;
82    mSnapshotStream = new camera3_stream_t;
83
84    memset(mPreviewStream, 0, sizeof(camera3_stream_t));
85    memset(mSnapshotStream, 0, sizeof(camera3_stream_t));
86    mPreviewStream = initStream(CAMERA3_STREAM_OUTPUT, camid, PREVIEW_WIDTH, PREVIEW_HEIGHT, 0,
87            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, HAL3_DATASPACE_UNKNOWN);
88    mSnapshotStream = initStream(CAMERA3_STREAM_OUTPUT, camid, SNAPSHOT_CAPTURE_WIDTH,
89            SNAPSHOT_CAPTURE_HEIGHT, 0, HAL_PIXEL_FORMAT_BLOB, HAL3_DATASPACE_JFIF);
90
91    mSnapshotConfig = configureStream(CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE, 2);
92    mSnapshotConfig.streams[0] = mPreviewStream;
93    mSnapshotConfig.streams[1] = mSnapshotStream;
94    device_handle->ops->configure_streams(my_test_obj->device, &(mSnapshotConfig));
95}
96
97void QCameraHAL3SnapshotTest::snapshotProcessCaptureRequest(
98                hal3_camera_test_obj_t *my_test_obj, int camid)
99{
100    int width, height;
101    camera3_device_t *device_handle = my_test_obj->device;
102    width = mSnapshotStream->width;
103    height = mSnapshotStream->height;
104    snapshotAllocateBuffers(width, height);
105    mRequest.settings = mMetaDataPtr[1];
106    mRequest.input_buffer = NULL;
107    mRequest.num_output_buffers = 1;
108    mSnapshotStreamBuffs.stream = mSnapshotStream;
109    mSnapshotStreamBuffs.status = 0;
110    mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
111    mSnapshotStreamBuffs.release_fence = -1;
112    mSnapshotStreamBuffs.acquire_fence = -1;
113    mRequest.output_buffers = &(mSnapshotStreamBuffs);
114    LOGD("Calling HAL3APP capture request for camid : %d", camid);
115    device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
116    (mRequest.frame_number)++;
117}
118
119void QCameraHAL3SnapshotTest::snapshotProcessCaptureRequestRepeat(
120                    hal3_camera_lib_test *my_hal3test_obj, int camid)
121{
122    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
123    LOGD("\nSnapshot Requested Capture : %d and Received Capture : %d",
124            mRequestedCapture, fcount_captured);
125    if (mRequestedCapture == fcount_captured) {
126        LOGD("\n Snapshot is running successfully Ending test");
127        fflush(stdout);
128        LOGD("\n Capture Done , Recieved Frame : %d", fcount_captured);
129        snapshotTestEnd(my_hal3test_obj, camid);
130    }
131    else {
132        camera3_device_t *device_handle = my_test_obj->device;
133        mRequest.settings = mMetaDataPtr[1];
134        mRequest.input_buffer = NULL;
135        mRequest.num_output_buffers = 1;
136        mSnapshotStreamBuffs.stream = mSnapshotStream;
137        mSnapshotStreamBuffs.buffer = (const native_handle_t**)&mCaptureHandle;
138        mSnapshotStreamBuffs.release_fence = -1;
139        mSnapshotStreamBuffs.acquire_fence = -1;
140        mRequest.output_buffers = &(mSnapshotStreamBuffs);
141        LOGD("Calling HAL3APP repeat capture request repeat %d and %d",
142                mRequestedCapture, fcount_captured);
143        device_handle->ops->process_capture_request(my_test_obj->device, &(mRequest));
144        (mRequest.frame_number)++;
145    }
146}
147
148void QCameraHAL3SnapshotTest::snapshotTestEnd(
149        hal3_camera_lib_test *my_hal3test_obj, int camid)
150{
151    buffer_thread_msg_t msg;
152    extern pthread_mutex_t gCamLock;
153    hal3_camera_test_obj_t *my_test_obj = &(my_hal3test_obj->test_obj);
154    camera3_device_t *device_handle = my_test_obj->device;
155    device_handle->ops->flush(my_test_obj->device);
156    LOGD("%s Closing Camera %d", __func__, camid);
157    ioctl(mCaptureMemInfo.ion_fd, ION_IOC_FREE, &mCaptureMemInfo.ion_handle);
158    close(mCaptureMemInfo.ion_fd);
159    mCaptureMemInfo.ion_fd = -1;
160    memset(&msg, 0, sizeof(buffer_thread_msg_t));
161    msg.stop_thread = 1;
162    write(pfd[1], &msg, sizeof(buffer_thread_msg_t));
163}
164
165void QCameraHAL3SnapshotTest::snapshotAllocateBuffers(int width, int height)
166{
167    mCaptureHandle= allocateBuffers(width, height, &mCaptureMemInfo);
168}
169
170bool QCameraHAL3SnapshotTest::snapshotThreadCreate(int testcase_id,
171                void *(*hal3_thread_ops)(void *))
172{
173    int32_t ret = 0;
174    buffer_thread_t thread;
175    pthread_attr_t attr;
176    if (pipe(pfd) < 0) {
177        LOGE("%s:Test:%d Error in creating the pipe", __func__, testcase_id);
178    }
179    pthread_attr_init(&attr);
180    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
181    pthread_mutex_init(&thread.mutex, NULL);
182    pthread_cond_init(&thread.cond, NULL);
183    thread.is_thread_started = 0;
184    thread.readfd = pfd[0];
185    thread.writefd = pfd[1];
186    thread.data_obj = this;
187    ret = pthread_create(&thread.td, &attr, hal3_thread_ops, &thread );
188    pthread_setname_np(thread.td, "TestApp_Thread");
189    if (ret < 0) {
190        LOGE("Failed to create status thread");
191        return 0;
192    }
193    pthread_mutex_lock(&thread.mutex);
194    while(thread.is_thread_started == 0) {
195        pthread_cond_wait(&thread.cond, &thread.mutex);
196    }
197    pthread_mutex_unlock(&thread.mutex);
198    return 1;
199}
200
201void * hal3appSnapshotProcessBuffers(void *data)
202{
203    buffer_thread_t *thread = (buffer_thread_t*)data;
204    int32_t readfd, writefd;
205    hal3_camera_lib_test *hal3_test_handle;
206    pthread_mutex_lock(&thread->mutex);
207    thread->is_thread_started = 1;
208    readfd = thread->readfd;
209    writefd = thread->writefd;
210    QCameraHAL3SnapshotTest *obj;
211    obj = (QCameraHAL3SnapshotTest *)thread->data_obj;
212    pthread_cond_signal(&thread->cond);
213    pthread_mutex_unlock(&thread->mutex);
214    struct pollfd pollfds;
215    int32_t num_of_fds = 1;
216    bool sthread_exit = 0;
217    int32_t ready = 0;
218    pollfds.fd = readfd;
219    pollfds.events = POLLIN | POLLPRI;
220    while(!sthread_exit) {
221        ready = poll(&pollfds, (nfds_t)num_of_fds, -1);
222        if (ready > 0) {
223            LOGD("Got some events");
224            if (pollfds.revents & (POLLIN | POLLPRI)) {
225                ssize_t nread = 0;
226                buffer_thread_msg_t msg;
227                nread = read(pollfds.fd, &msg, sizeof(buffer_thread_msg_t));
228                if (nread < 0) {
229                    LOGE("Unable to read the message");
230                }
231                if (msg.stop_thread) {
232                    break;
233                }
234                hal3_test_handle = Snapshot_CamObj_handle;
235                obj->snapshotProcessCaptureRequestRepeat(hal3_test_handle, 0);
236            }
237        }
238        else {
239            LOGE("Unable to poll exiting the thread");
240            break;
241        }
242    }
243    LOGD("Sensor thread is exiting");
244    close(readfd);
245    close(writefd);
246    pthread_mutex_unlock(&TestAppLock);
247    pthread_exit(0);
248    return NULL;
249}
250
251void QCameraHAL3SnapshotTest::captureRequestRepeat(
252        hal3_camera_lib_test *my_hal3test_obj, int camid, int testcase)
253{
254    if(my_hal3test_obj == NULL) {
255        LOGD("camid :%d and testcase : %d handle is NULL", camid, testcase);
256    }
257}
258
259QCameraHAL3SnapshotTest::~QCameraHAL3SnapshotTest()
260{
261
262}
263
264}
265