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 pp_config.feature_mask |= CAM_QCOM_FEATURE_FLIP;
212
213 uint8_t minStreamBufNum = source_stream->num_of_bufs;
214 stream = mm_app_add_reprocess_stream_from_source(test_obj,
215 channel,
216 source_stream,
217 mm_app_reprocess_notify_cb,
218 pp_config,
219 (void *)test_obj,
220 minStreamBufNum);
221 if (NULL == stream) {
222 LOGE(" add reprocess stream failed\n");
223 mm_app_del_channel(test_obj, channel);
224 return NULL;
225 }
226 test_obj->reproc_stream = stream;
227
228 return channel;
229 }
230
mm_app_start_reprocess(mm_camera_test_obj_t * test_obj)231 int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
232 {
233 int rc = MM_CAMERA_OK;
234 mm_camera_channel_t *r_ch = NULL;
235
236 mm_camera_queue_init(&test_obj->pp_frames,
237 mm_app_release_ppinput,
238 ( void * ) test_obj);
239
240 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
241 if (MM_CAMERA_OK != rc) {
242 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
243 return rc;
244 }
245
246 rc = mm_app_start_channel(test_obj, r_ch);
247 if (MM_CAMERA_OK != rc) {
248 LOGE("start reprocess failed rc=%d\n", rc);
249 mm_app_del_channel(test_obj, r_ch);
250 return rc;
251 }
252
253 return rc;
254 }
255
mm_app_stop_reprocess(mm_camera_test_obj_t * test_obj)256 int mm_app_stop_reprocess(mm_camera_test_obj_t *test_obj)
257 {
258 int rc = MM_CAMERA_OK;
259 mm_camera_channel_t *r_ch = NULL;
260
261 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
262 if (MM_CAMERA_OK != rc) {
263 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
264 return rc;
265 }
266
267 rc = mm_app_stop_and_del_channel(test_obj, r_ch);
268 if (MM_CAMERA_OK != rc) {
269 LOGE("Stop Preview failed rc=%d\n", rc);
270 }
271
272 mm_qcamera_queue_release(&test_obj->pp_frames);
273 test_obj->reproc_stream = NULL;
274
275 return rc;
276 }
277
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)278 int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
279 mm_camera_buf_def_t *frame,
280 uint32_t meta_idx,
281 mm_camera_super_buf_t *super_buf,
282 mm_camera_stream_t *src_meta)
283 {
284 int rc = MM_CAMERA_OK;
285 mm_camera_channel_t *r_ch = NULL;
286 mm_camera_super_buf_t *src_buf = NULL;
287
288 if ( ( NULL == test_obj ) ||
289 ( NULL == frame ) ||
290 ( NULL == super_buf )) {
291 LOGE(" Invalid input rc=%d\n", rc);
292 return rc;
293 }
294
295 if ( NULL == test_obj->reproc_stream ) {
296 LOGE(" No reprocess stream rc=%d\n", rc);
297 return rc;
298 }
299
300 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
301 if (MM_CAMERA_OK != rc) {
302 LOGE(" No reprocess channel rc=%d\n", rc);
303 return rc;
304 }
305
306 src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
307 if ( NULL == src_buf ) {
308 LOGE(" No resources for src frame rc=%d\n", rc);
309 return -1;
310 }
311 memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
312 mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
313
314 cam_stream_parm_buffer_t param;
315 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
316 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
317 param.reprocess.buf_index = frame->buf_idx;
318 param.reprocess.frame_idx = frame->frame_idx;
319 if (src_meta != NULL) {
320 param.reprocess.meta_present = 1;
321 param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
322 param.reprocess.meta_buf_index = meta_idx;
323 } else {
324 LOGE(" No metadata source stream rc=%d\n", rc);
325 }
326
327 test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
328 rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
329 r_ch->ch_id,
330 test_obj->reproc_stream->s_id,
331 &test_obj->reproc_stream->s_config.stream_info->parm_buf);
332
333 return rc;
334 }
335
mm_app_release_ppinput(void * data,void * user_data)336 void mm_app_release_ppinput(void *data, void *user_data)
337 {
338 uint32_t i = 0;
339 mm_camera_super_buf_t *recvd_frame = ( mm_camera_super_buf_t * ) data;
340 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
341
342 for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
343 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
344 recvd_frame->ch_id,
345 recvd_frame->bufs[i])) {
346 LOGE(" Failed in Qbuf\n");
347 }
348 mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
349 ION_IOC_INV_CACHES);
350 }
351 }
352
353