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