1 /*
2 Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 // Camera dependencies
31 #include "mm_qcamera_app.h"
32 #include "mm_qcamera_dbg.h"
33
mm_app_reprocess_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)34 static void mm_app_reprocess_notify_cb(mm_camera_super_buf_t *bufs,
35 void *user_data)
36 {
37 mm_camera_buf_def_t *frame = bufs->bufs[0];
38 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
39 mm_camera_channel_t *channel = NULL;
40 mm_camera_stream_t *m_stream = NULL;
41 mm_camera_buf_def_t *m_frame = NULL;
42 mm_camera_super_buf_t *src_frame;
43 int i = 0;
44 int rc = 0;
45
46 LOGE(" BEGIN - length=%zu, frame idx = %d\n",
47 frame->frame_len, frame->frame_idx);
48
49 /* find channel */
50 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
51 if (pme->channels[i].ch_id == bufs->ch_id) {
52 channel = &pme->channels[i];
53 break;
54 }
55 }
56 if (NULL == channel) {
57 LOGE(" Wrong channel id (%d)", bufs->ch_id);
58 return;
59 }
60
61 // We have only one stream and buffer
62 // in the reprocess channel.
63 m_stream = &channel->streams[0];
64 m_frame = bufs->bufs[0];
65
66 if ( pme->encodeJpeg ) {
67 pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
68 if ( NULL == pme->jpeg_buf.buf.buffer ) {
69 LOGE(" error allocating jpeg output buffer");
70 goto exit;
71 }
72
73 pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
74 /* create a new jpeg encoding session */
75 rc = createEncodingSession(pme, m_stream, m_frame);
76 if (0 != rc) {
77 LOGE(" error creating jpeg session");
78 free(pme->jpeg_buf.buf.buffer);
79 goto exit;
80 }
81
82 /* start jpeg encoding job */
83 LOGE("Encoding reprocessed frame!!");
84 rc = encodeData(pme, bufs, m_stream);
85 pme->encodeJpeg = 0;
86 } else {
87 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
88 bufs->ch_id,
89 frame)) {
90 LOGE(" Failed in Reprocess Qbuf\n");
91 }
92 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
93 ION_IOC_INV_CACHES);
94 }
95
96 exit:
97
98 // Release source frame
99 src_frame = ( mm_camera_super_buf_t * ) mm_qcamera_queue_dequeue(&pme->pp_frames, 1);
100 if ( NULL != src_frame ) {
101 mm_app_release_ppinput((void *) src_frame, (void *) pme);
102 }
103
104 LOGE(" END\n");
105 }
106
mm_app_add_reprocess_stream_from_source(mm_camera_test_obj_t * test_obj,mm_camera_channel_t * channel,mm_camera_stream_t * source,mm_camera_buf_notify_t stream_cb,cam_pp_feature_config_t pp_config,void * userdata,uint8_t num_bufs)107 mm_camera_stream_t * mm_app_add_reprocess_stream_from_source(mm_camera_test_obj_t *test_obj,
108 mm_camera_channel_t *channel,
109 mm_camera_stream_t *source,
110 mm_camera_buf_notify_t stream_cb,
111 cam_pp_feature_config_t pp_config,
112 void *userdata,
113 uint8_t num_bufs)
114 {
115 int rc = MM_CAMERA_OK;
116 mm_camera_stream_t *stream = NULL;
117 cam_capability_t *cam_cap = NULL;
118 cam_stream_info_t *source_stream_info;
119
120 if ( ( NULL == test_obj ) ||
121 ( NULL == channel ) ||
122 ( NULL == source ) ) {
123 LOGE(" Invalid input\n");
124 return NULL;
125 }
126
127 cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
128
129 stream = mm_app_add_stream(test_obj, channel);
130 if (NULL == stream) {
131 LOGE(" add stream failed\n");
132 return NULL;
133 }
134
135 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
136 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
137 stream->s_config.mem_vtbl.clean_invalidate_buf =
138 mm_app_stream_clean_invalidate_buf;
139 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
140 stream->s_config.mem_vtbl.clean_buf = mm_app_stream_clean_buf;
141 stream->s_config.mem_vtbl.user_data = (void *)stream;
142 stream->s_config.stream_cb = stream_cb;
143 stream->s_config.stream_cb_sync = NULL;
144 stream->s_config.userdata = userdata;
145 stream->num_of_bufs = num_bufs;
146
147 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
148 source_stream_info = (cam_stream_info_t *) source->s_info_buf.buf.buffer;
149 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
150 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
151 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
152 stream->s_config.stream_info->fmt = source_stream_info->fmt;
153 stream->s_config.stream_info->dim = source_stream_info->dim;
154 stream->s_config.padding_info = cam_cap->padding_info;
155 stream->s_config.stream_info->num_bufs = num_bufs;
156
157 stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
158 stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
159 stream->s_config.stream_info->reprocess_config.online.input_stream_type = source->s_config.stream_info->stream_type;
160 stream->s_config.stream_info->reprocess_config.pp_feature_config = pp_config;
161
162 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
163 if (MM_CAMERA_OK != rc) {
164 LOGE("config preview stream err=%d\n", rc);
165 return NULL;
166 }
167
168 return stream;
169 }
170
mm_app_add_reprocess_channel(mm_camera_test_obj_t * test_obj,mm_camera_stream_t * source_stream)171 mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
172 mm_camera_stream_t *source_stream)
173 {
174 mm_camera_channel_t *channel = NULL;
175 mm_camera_stream_t *stream = NULL;
176
177 if ( NULL == source_stream ) {
178 LOGE(" add reprocess stream failed\n");
179 return NULL;
180 }
181
182 channel = mm_app_add_channel(test_obj,
183 MM_CHANNEL_TYPE_REPROCESS,
184 NULL,
185 NULL,
186 NULL);
187 if (NULL == channel) {
188 LOGE(" add channel failed");
189 return NULL;
190 }
191
192 // pp feature config
193 cam_pp_feature_config_t pp_config;
194 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
195
196 cam_capability_t *caps = ( cam_capability_t * ) ( test_obj->cap_buf.buf.buffer );
197 if (caps->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
198 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
199 pp_config.sharpness = test_obj->reproc_sharpness;
200 }
201
202 if (test_obj->reproc_wnr.denoise_enable) {
203 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
204 pp_config.denoise2d = test_obj->reproc_wnr;
205 }
206
207 if (test_obj->enable_CAC) {
208 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
209 }
210
211 uint8_t minStreamBufNum = source_stream->num_of_bufs;
212 stream = mm_app_add_reprocess_stream_from_source(test_obj,
213 channel,
214 source_stream,
215 mm_app_reprocess_notify_cb,
216 pp_config,
217 (void *)test_obj,
218 minStreamBufNum);
219 if (NULL == stream) {
220 LOGE(" add reprocess stream failed\n");
221 mm_app_del_channel(test_obj, channel);
222 return NULL;
223 }
224 test_obj->reproc_stream = stream;
225
226 return channel;
227 }
228
mm_app_start_reprocess(mm_camera_test_obj_t * test_obj)229 int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
230 {
231 int rc = MM_CAMERA_OK;
232 mm_camera_channel_t *r_ch = NULL;
233
234 mm_camera_queue_init(&test_obj->pp_frames,
235 mm_app_release_ppinput,
236 ( void * ) test_obj);
237
238 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
239 if (MM_CAMERA_OK != rc) {
240 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
241 return rc;
242 }
243
244 rc = mm_app_start_channel(test_obj, r_ch);
245 if (MM_CAMERA_OK != rc) {
246 LOGE("start reprocess failed rc=%d\n", rc);
247 mm_app_del_channel(test_obj, r_ch);
248 return rc;
249 }
250
251 return rc;
252 }
253
mm_app_stop_reprocess(mm_camera_test_obj_t * test_obj)254 int mm_app_stop_reprocess(mm_camera_test_obj_t *test_obj)
255 {
256 int rc = MM_CAMERA_OK;
257 mm_camera_channel_t *r_ch = NULL;
258
259 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
260 if (MM_CAMERA_OK != rc) {
261 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
262 return rc;
263 }
264
265 rc = mm_app_stop_and_del_channel(test_obj, r_ch);
266 if (MM_CAMERA_OK != rc) {
267 LOGE("Stop Preview failed rc=%d\n", rc);
268 }
269
270 mm_qcamera_queue_release(&test_obj->pp_frames);
271 test_obj->reproc_stream = NULL;
272
273 return rc;
274 }
275
mm_app_do_reprocess(mm_camera_test_obj_t * test_obj,mm_camera_buf_def_t * frame,uint32_t meta_idx,mm_camera_super_buf_t * super_buf,mm_camera_stream_t * src_meta)276 int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
277 mm_camera_buf_def_t *frame,
278 uint32_t meta_idx,
279 mm_camera_super_buf_t *super_buf,
280 mm_camera_stream_t *src_meta)
281 {
282 int rc = MM_CAMERA_OK;
283 mm_camera_channel_t *r_ch = NULL;
284 mm_camera_super_buf_t *src_buf = NULL;
285
286 if ( ( NULL == test_obj ) ||
287 ( NULL == frame ) ||
288 ( NULL == super_buf )) {
289 LOGE(" Invalid input rc=%d\n", rc);
290 return rc;
291 }
292
293 if ( NULL == test_obj->reproc_stream ) {
294 LOGE(" No reprocess stream rc=%d\n", rc);
295 return rc;
296 }
297
298 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
299 if (MM_CAMERA_OK != rc) {
300 LOGE(" No reprocess channel rc=%d\n", rc);
301 return rc;
302 }
303
304 src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
305 if ( NULL == src_buf ) {
306 LOGE(" No resources for src frame rc=%d\n", rc);
307 return -1;
308 }
309 memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
310 mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
311
312 cam_stream_parm_buffer_t param;
313 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
314 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
315 param.reprocess.buf_index = frame->buf_idx;
316 param.reprocess.frame_idx = frame->frame_idx;
317 if (src_meta != NULL) {
318 param.reprocess.meta_present = 1;
319 param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
320 param.reprocess.meta_buf_index = meta_idx;
321 } else {
322 LOGE(" No metadata source stream rc=%d\n", rc);
323 }
324
325 test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
326 rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
327 r_ch->ch_id,
328 test_obj->reproc_stream->s_id,
329 &test_obj->reproc_stream->s_config.stream_info->parm_buf);
330
331 return rc;
332 }
333
mm_app_release_ppinput(void * data,void * user_data)334 void mm_app_release_ppinput(void *data, void *user_data)
335 {
336 uint32_t i = 0;
337 mm_camera_super_buf_t *recvd_frame = ( mm_camera_super_buf_t * ) data;
338 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
339
340 for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
341 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
342 recvd_frame->ch_id,
343 recvd_frame->bufs[i])) {
344 LOGE(" Failed in Qbuf\n");
345 }
346 mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
347 ION_IOC_INV_CACHES);
348 }
349 }
350
351