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(&param, 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