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