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.user_data = (void *)stream;
141 stream->s_config.stream_cb = stream_cb;
142 stream->s_config.stream_cb_sync = NULL;
143 stream->s_config.userdata = userdata;
144 stream->num_of_bufs = num_bufs;
145
146 stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
147 source_stream_info = (cam_stream_info_t *) source->s_info_buf.buf.buffer;
148 memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
149 stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
150 stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
151 stream->s_config.stream_info->fmt = source_stream_info->fmt;
152 stream->s_config.stream_info->dim = source_stream_info->dim;
153 stream->s_config.padding_info = cam_cap->padding_info;
154
155
156 stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
157 stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
158 stream->s_config.stream_info->reprocess_config.online.input_stream_type = source->s_config.stream_info->stream_type;
159 stream->s_config.stream_info->reprocess_config.pp_feature_config = pp_config;
160
161 rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
162 if (MM_CAMERA_OK != rc) {
163 LOGE("config preview stream err=%d\n", rc);
164 return NULL;
165 }
166
167 return stream;
168 }
169
mm_app_add_reprocess_channel(mm_camera_test_obj_t * test_obj,mm_camera_stream_t * source_stream)170 mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
171 mm_camera_stream_t *source_stream)
172 {
173 mm_camera_channel_t *channel = NULL;
174 mm_camera_stream_t *stream = NULL;
175
176 if ( NULL == source_stream ) {
177 LOGE(" add reprocess stream failed\n");
178 return NULL;
179 }
180
181 channel = mm_app_add_channel(test_obj,
182 MM_CHANNEL_TYPE_REPROCESS,
183 NULL,
184 NULL,
185 NULL);
186 if (NULL == channel) {
187 LOGE(" add channel failed");
188 return NULL;
189 }
190
191 // pp feature config
192 cam_pp_feature_config_t pp_config;
193 memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
194
195 cam_capability_t *caps = ( cam_capability_t * ) ( test_obj->cap_buf.buf.buffer );
196 if (caps->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
197 pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
198 pp_config.sharpness = test_obj->reproc_sharpness;
199 }
200
201 if (test_obj->reproc_wnr.denoise_enable) {
202 pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
203 pp_config.denoise2d = test_obj->reproc_wnr;
204 }
205
206 if (test_obj->enable_CAC) {
207 pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
208 }
209
210 uint8_t minStreamBufNum = source_stream->num_of_bufs;
211 stream = mm_app_add_reprocess_stream_from_source(test_obj,
212 channel,
213 source_stream,
214 mm_app_reprocess_notify_cb,
215 pp_config,
216 (void *)test_obj,
217 minStreamBufNum);
218 if (NULL == stream) {
219 LOGE(" add reprocess stream failed\n");
220 mm_app_del_channel(test_obj, channel);
221 return NULL;
222 }
223 test_obj->reproc_stream = stream;
224
225 return channel;
226 }
227
mm_app_start_reprocess(mm_camera_test_obj_t * test_obj)228 int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
229 {
230 int rc = MM_CAMERA_OK;
231 mm_camera_channel_t *r_ch = NULL;
232
233 mm_camera_queue_init(&test_obj->pp_frames,
234 mm_app_release_ppinput,
235 ( void * ) test_obj);
236
237 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
238 if (MM_CAMERA_OK != rc) {
239 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
240 return rc;
241 }
242
243 rc = mm_app_start_channel(test_obj, r_ch);
244 if (MM_CAMERA_OK != rc) {
245 LOGE("start reprocess failed rc=%d\n", 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 LOGE(" No initialized reprocess channel d rc=%d\n", rc);
261 return rc;
262 }
263
264 rc = mm_app_stop_and_del_channel(test_obj, r_ch);
265 if (MM_CAMERA_OK != rc) {
266 LOGE("Stop Preview failed rc=%d\n", rc);
267 }
268
269 mm_qcamera_queue_release(&test_obj->pp_frames);
270 test_obj->reproc_stream = NULL;
271
272 return rc;
273 }
274
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)275 int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
276 mm_camera_buf_def_t *frame,
277 uint32_t meta_idx,
278 mm_camera_super_buf_t *super_buf,
279 mm_camera_stream_t *src_meta)
280 {
281 int rc = MM_CAMERA_OK;
282 mm_camera_channel_t *r_ch = NULL;
283 mm_camera_super_buf_t *src_buf = NULL;
284
285 if ( ( NULL == test_obj ) ||
286 ( NULL == frame ) ||
287 ( NULL == super_buf )) {
288 LOGE(" Invalid input rc=%d\n", rc);
289 return rc;
290 }
291
292 if ( NULL == test_obj->reproc_stream ) {
293 LOGE(" No reprocess stream rc=%d\n", rc);
294 return rc;
295 }
296
297 r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
298 if (MM_CAMERA_OK != rc) {
299 LOGE(" No reprocess channel rc=%d\n", rc);
300 return rc;
301 }
302
303 src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
304 if ( NULL == src_buf ) {
305 LOGE(" No resources for src frame rc=%d\n", rc);
306 return -1;
307 }
308 memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
309 mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
310
311 cam_stream_parm_buffer_t param;
312 memset(¶m, 0, sizeof(cam_stream_parm_buffer_t));
313 param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
314 param.reprocess.buf_index = frame->buf_idx;
315 param.reprocess.frame_idx = frame->frame_idx;
316 if (src_meta != NULL) {
317 param.reprocess.meta_present = 1;
318 param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
319 param.reprocess.meta_buf_index = meta_idx;
320 } else {
321 LOGE(" No metadata source stream rc=%d\n", rc);
322 }
323
324 test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
325 rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
326 r_ch->ch_id,
327 test_obj->reproc_stream->s_id,
328 &test_obj->reproc_stream->s_config.stream_info->parm_buf);
329
330 return rc;
331 }
332
mm_app_release_ppinput(void * data,void * user_data)333 void mm_app_release_ppinput(void *data, void *user_data)
334 {
335 uint32_t i = 0;
336 mm_camera_super_buf_t *recvd_frame = ( mm_camera_super_buf_t * ) data;
337 mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
338
339 for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
340 if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
341 recvd_frame->ch_id,
342 recvd_frame->bufs[i])) {
343 LOGE(" Failed in Qbuf\n");
344 }
345 mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
346 ION_IOC_INV_CACHES);
347 }
348 }
349
350