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