1 /*
2 Copyright (c) 2012-2014, 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 #include "mm_qcamera_dbg.h"
31 #include "mm_qcamera_app.h"
32
mm_app_reprocess_notify_cb(mm_camera_super_buf_t * bufs,void * user_data)33 static void mm_app_reprocess_notify_cb(mm_camera_super_buf_t *bufs,
34 void *user_data)
35 {
36 mm_camera_buf_def_t *frame = bufs->bufs[0];
37 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
38 mm_camera_channel_t *channel = NULL;
39 mm_camera_stream_t *m_stream = NULL;
40 mm_camera_buf_def_t *m_frame = NULL;
41 mm_camera_super_buf_t *src_frame;
42 int i = 0;
43 int rc = 0;
44
45 CDBG_ERROR("%s: BEGIN - length=%zu, frame idx = %d\n",
46 __func__, frame->frame_len, frame->frame_idx);
47
48 /* find channel */
49 for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
50 if (pme->channels[i].ch_id == bufs->ch_id) {
51 channel = &pme->channels[i];
52 break;
53 }
54 }
55 if (NULL == channel) {
56 CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
57 return;
58 }
59
60 // We have only one stream and buffer
61 // in the reprocess channel.
62 m_stream = &channel->streams[0];
63 m_frame = bufs->bufs[0];
64
65 if ( pme->encodeJpeg ) {
66 pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
67 if ( NULL == pme->jpeg_buf.buf.buffer ) {
68 CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
69 goto exit;
70 }
71
72 pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
73 /* create a new jpeg encoding session */
74 rc = createEncodingSession(pme, m_stream, m_frame);
75 if (0 != rc) {
76 CDBG_ERROR("%s: error creating jpeg session", __func__);
77 free(pme->jpeg_buf.buf.buffer);
78 goto exit;
79 }
80
81 /* start jpeg encoding job */
82 CDBG_ERROR("Encoding reprocessed frame!!");
83 rc = encodeData(pme, bufs, m_stream);
84 pme->encodeJpeg = 0;
85 } else {
86 if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
87 bufs->ch_id,
88 frame)) {
89 CDBG_ERROR("%s: Failed in Reprocess Qbuf\n", __func__);
90 }
91 mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
92 ION_IOC_INV_CACHES);
93 }
94
95 exit:
96
97 // Release source frame
98 src_frame = ( mm_camera_super_buf_t * ) mm_qcamera_queue_dequeue(&pme->pp_frames, 1);
99 if ( NULL != src_frame ) {
100 mm_app_release_ppinput((void *) src_frame, (void *) pme);
101 }
102
103 CDBG_ERROR("%s: END\n", __func__);
104 }
105
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)106 mm_camera_stream_t * mm_app_add_reprocess_stream_from_source(mm_camera_test_obj_t *test_obj,
107 mm_camera_channel_t *channel,
108 mm_camera_stream_t *source,
109 mm_camera_buf_notify_t stream_cb,
110 cam_pp_feature_config_t pp_config,
111 void *userdata,
112 uint8_t num_bufs)
113 {
114 int rc = MM_CAMERA_OK;
115 mm_camera_stream_t *stream = NULL;
116 cam_capability_t *cam_cap = NULL;
117 cam_stream_info_t *source_stream_info;
118
119 if ( ( NULL == test_obj ) ||
120 ( NULL == channel ) ||
121 ( NULL == source ) ) {
122 CDBG_ERROR("%s: Invalid input\n", __func__);
123 return NULL;
124 }
125
126 cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
127
128 stream = mm_app_add_stream(test_obj, channel);
129 if (NULL == stream) {
130 CDBG_ERROR("%s: add stream failed\n", __func__);
131 return NULL;
132 }
133
134 stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
135 stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
136 stream->s_config.mem_vtbl.clean_invalidate_buf =
137 mm_app_stream_clean_invalidate_buf;
138 stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
139 stream->s_config.mem_vtbl.user_data = (void *)stream;
140 stream->s_config.stream_cb = stream_cb;
141 stream->s_config.userdata = userdata;
142 stream->num_of_bufs = num_bufs;
143
144 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
145 source_stream_info = (cam_stream_info_t *) source->s_info_buf.buf.buffer;
146 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
147 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
148 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
149 stream->s_config.stream_info->fmt = source_stream_info->fmt;
150 stream->s_config.stream_info->dim = source_stream_info->dim;
151 stream->s_config.padding_info = cam_cap->padding_info;
152
153
154 stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
155 stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
156 stream->s_config.stream_info->reprocess_config.online.input_stream_type = source->s_config.stream_info->stream_type;
157 stream->s_config.stream_info->reprocess_config.pp_feature_config = pp_config;
158
159 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
160 if (MM_CAMERA_OK != rc) {
161 CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
162 return NULL;
163 }
164
165 return stream;
166 }
167
mm_app_add_reprocess_channel(mm_camera_test_obj_t * test_obj,mm_camera_stream_t * source_stream)168 mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
169 mm_camera_stream_t *source_stream)
170 {
171 mm_camera_channel_t *channel = NULL;
172 mm_camera_stream_t *stream = NULL;
173
174 if ( NULL == source_stream ) {
175 CDBG_ERROR("%s: add reprocess stream failed\n", __func__);
176 return NULL;
177 }
178
179 channel = mm_app_add_channel(test_obj,
180 MM_CHANNEL_TYPE_REPROCESS,
181 NULL,
182 NULL,
183 NULL);
184 if (NULL == channel) {
185 CDBG_ERROR("%s: add channel failed", __func__);
186 return NULL;
187 }
188
189 // pp feature config
190 cam_pp_feature_config_t pp_config;
191 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
192
193 cam_capability_t *caps = ( cam_capability_t * ) ( test_obj->cap_buf.buf.buffer );
194 if (caps->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) {
195 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
196 pp_config.sharpness = test_obj->reproc_sharpness;
197 }
198
199 if (test_obj->reproc_wnr.denoise_enable) {
200 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
201 pp_config.denoise2d = test_obj->reproc_wnr;
202 }
203
204 if (test_obj->enable_CAC) {
205 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
206 }
207
208 uint8_t minStreamBufNum = source_stream->num_of_bufs;
209 stream = mm_app_add_reprocess_stream_from_source(test_obj,
210 channel,
211 source_stream,
212 mm_app_reprocess_notify_cb,
213 pp_config,
214 (void *)test_obj,
215 minStreamBufNum);
216 if (NULL == stream) {
217 CDBG_ERROR("%s: add reprocess stream failed\n", __func__);
218 mm_app_del_channel(test_obj, channel);
219 return NULL;
220 }
221 test_obj->reproc_stream = stream;
222
223 return channel;
224 }
225
mm_app_start_reprocess(mm_camera_test_obj_t * test_obj)226 int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
227 {
228 int rc = MM_CAMERA_OK;
229 mm_camera_channel_t *r_ch = NULL;
230
231 mm_camera_queue_init(&test_obj->pp_frames,
232 mm_app_release_ppinput,
233 ( void * ) test_obj);
234
235 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
236 if (MM_CAMERA_OK != rc) {
237 CDBG_ERROR("%s: No initialized reprocess channel d rc=%d\n",
238 __func__,
239 rc);
240 return rc;
241 }
242
243 rc = mm_app_start_channel(test_obj, r_ch);
244 if (MM_CAMERA_OK != rc) {
245 CDBG_ERROR("%s:start reprocess failed rc=%d\n", __func__, rc);
246 mm_app_del_channel(test_obj, r_ch);
247 return rc;
248 }
249
250 return rc;
251 }
252
mm_app_stop_reprocess(mm_camera_test_obj_t * test_obj)253 int mm_app_stop_reprocess(mm_camera_test_obj_t *test_obj)
254 {
255 int rc = MM_CAMERA_OK;
256 mm_camera_channel_t *r_ch = NULL;
257
258 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
259 if (MM_CAMERA_OK != rc) {
260 CDBG_ERROR("%s: No initialized reprocess channel d rc=%d\n",
261 __func__,
262 rc);
263 return rc;
264 }
265
266 rc = mm_app_stop_and_del_channel(test_obj, r_ch);
267 if (MM_CAMERA_OK != rc) {
268 CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
269 }
270
271 mm_qcamera_queue_release(&test_obj->pp_frames);
272 test_obj->reproc_stream = NULL;
273
274 return rc;
275 }
276
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)277 int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
278 mm_camera_buf_def_t *frame,
279 uint32_t meta_idx,
280 mm_camera_super_buf_t *super_buf,
281 mm_camera_stream_t *src_meta)
282 {
283 int rc = MM_CAMERA_OK;
284 mm_camera_channel_t *r_ch = NULL;
285 mm_camera_super_buf_t *src_buf = NULL;
286
287 if ( ( NULL == test_obj ) ||
288 ( NULL == frame ) ||
289 ( NULL == super_buf )) {
290 CDBG_ERROR("%s: Invalid input rc=%d\n",
291 __func__,
292 rc);
293 return rc;
294 }
295
296 if ( NULL == test_obj->reproc_stream ) {
297 CDBG_ERROR("%s: No reprocess stream rc=%d\n",
298 __func__,
299 rc);
300 return rc;
301 }
302
303 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
304 if (MM_CAMERA_OK != rc) {
305 CDBG_ERROR("%s: No reprocess channel rc=%d\n",
306 __func__,
307 rc);
308 return rc;
309 }
310
311 src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
312 if ( NULL == src_buf ) {
313 CDBG_ERROR("%s: No resources for src frame rc=%d\n",
314 __func__,
315 rc);
316 return -1;
317 }
318 memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
319 mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
320
321 cam_stream_parm_buffer_t param;
322 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
323 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
324 param.reprocess.buf_index = frame->buf_idx;
325 param.reprocess.frame_idx = frame->frame_idx;
326 if (src_meta != NULL) {
327 param.reprocess.meta_present = 1;
328 param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
329 param.reprocess.meta_buf_index = meta_idx;
330 } else {
331 CDBG_ERROR("%s: No metadata source stream rc=%d\n",
332 __func__,
333 rc);
334 }
335
336 test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
337 rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
338 r_ch->ch_id,
339 test_obj->reproc_stream->s_id,
340 &test_obj->reproc_stream->s_config.stream_info->parm_buf);
341
342 return rc;
343 }
344
mm_app_release_ppinput(void * data,void * user_data)345 void mm_app_release_ppinput(void *data, void *user_data)
346 {
347 uint32_t i = 0;
348 mm_camera_super_buf_t *recvd_frame = ( mm_camera_super_buf_t * ) data;
349 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
350
351 for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
352 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
353 recvd_frame->ch_id,
354 recvd_frame->bufs[i])) {
355 CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
356 }
357 mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
358 ION_IOC_INV_CACHES);
359 }
360 }
361
362