Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2012-2013, 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 #include "mm_qcamera_dbg.h"
     31 #include "mm_qcamera_app.h"
     32 
     33 static void mm_app_reprocess_notify_cb(mm_camera_super_buf_t *bufs,
     34                                    void *user_data)
     35 {
     36     mm_camera_buf_def_t *frame = bufs->bufs[0];
     37     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
     38     mm_camera_channel_t *channel = NULL;
     39     mm_camera_stream_t *m_stream = NULL;
     40     mm_camera_buf_def_t *m_frame = NULL;
     41     mm_camera_super_buf_t *src_frame;
     42     int i = 0;
     43     int rc = 0;
     44 
     45     CDBG_ERROR("%s: BEGIN - length=%d, frame idx = %d\n",
     46          __func__, frame->frame_len, frame->frame_idx);
     47 
     48     /* find channel */
     49     for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
     50         if (pme->channels[i].ch_id == bufs->ch_id) {
     51             channel = &pme->channels[i];
     52             break;
     53         }
     54     }
     55     if (NULL == channel) {
     56         CDBG_ERROR("%s: Wrong channel id (%d)", __func__, bufs->ch_id);
     57         return;
     58     }
     59 
     60     // We have only one stream and buffer
     61     // in the reprocess channel.
     62     m_stream = &channel->streams[0];
     63     m_frame = bufs->bufs[0];
     64 
     65     if ( pme->encodeJpeg ) {
     66         pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
     67         if ( NULL == pme->jpeg_buf.buf.buffer ) {
     68             CDBG_ERROR("%s: error allocating jpeg output buffer", __func__);
     69             goto exit;
     70         }
     71 
     72         pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
     73         /* create a new jpeg encoding session */
     74         rc = createEncodingSession(pme, m_stream, m_frame);
     75         if (0 != rc) {
     76             CDBG_ERROR("%s: error creating jpeg session", __func__);
     77             free(pme->jpeg_buf.buf.buffer);
     78             goto exit;
     79         }
     80 
     81         /* start jpeg encoding job */
     82         CDBG_ERROR("Encoding reprocessed frame!!");
     83         rc = encodeData(pme, bufs, m_stream);
     84         pme->encodeJpeg = 0;
     85     } else {
     86         if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
     87                                                 bufs->ch_id,
     88                                                 frame)) {
     89             CDBG_ERROR("%s: Failed in Reprocess Qbuf\n", __func__);
     90         }
     91         mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
     92                          ION_IOC_INV_CACHES);
     93     }
     94 
     95 exit:
     96 
     97 // Release source frame
     98     src_frame = ( mm_camera_super_buf_t * ) mm_qcamera_queue_dequeue(&pme->pp_frames, 1);
     99     if ( NULL != src_frame ) {
    100         mm_app_release_ppinput((void *) src_frame, (void *) pme);
    101     }
    102 
    103     CDBG_ERROR("%s: END\n", __func__);
    104 }
    105 
    106 mm_camera_stream_t * mm_app_add_reprocess_stream_from_source(mm_camera_test_obj_t *test_obj,
    107                                                              mm_camera_channel_t *channel,
    108                                                              mm_camera_stream_t *source,
    109                                                              mm_camera_buf_notify_t stream_cb,
    110                                                              cam_pp_feature_config_t pp_config,
    111                                                              void *userdata,
    112                                                              uint8_t num_bufs)
    113 {
    114     int rc = MM_CAMERA_OK;
    115     mm_camera_stream_t *stream = NULL;
    116     cam_capability_t *cam_cap = NULL;
    117     cam_stream_info_t *source_stream_info;
    118 
    119     if ( ( NULL == test_obj ) ||
    120          ( NULL == channel ) ||
    121          ( NULL == source ) ) {
    122         CDBG_ERROR("%s: Invalid input\n", __func__);
    123         return NULL;
    124     }
    125 
    126     cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    127 
    128     stream = mm_app_add_stream(test_obj, channel);
    129     if (NULL == stream) {
    130         CDBG_ERROR("%s: add stream failed\n", __func__);
    131         return NULL;
    132     }
    133 
    134     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    135     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    136     stream->s_config.mem_vtbl.clean_invalidate_buf =
    137       mm_app_stream_clean_invalidate_buf;
    138     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    139     stream->s_config.mem_vtbl.user_data = (void *)stream;
    140     stream->s_config.stream_cb = stream_cb;
    141     stream->s_config.userdata = userdata;
    142     stream->num_of_bufs = num_bufs;
    143 
    144     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    145     source_stream_info = (cam_stream_info_t *) source->s_info_buf.buf.buffer;
    146     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    147     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
    148     stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    149     stream->s_config.stream_info->fmt = source_stream_info->fmt;
    150     stream->s_config.stream_info->dim = source_stream_info->dim;
    151     stream->s_config.padding_info = cam_cap->padding_info;
    152 
    153 
    154     stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
    155     stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
    156     stream->s_config.stream_info->reprocess_config.online.input_stream_type = source->s_config.stream_info->stream_type;
    157     stream->s_config.stream_info->reprocess_config.pp_feature_config = pp_config;
    158 
    159     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    160     if (MM_CAMERA_OK != rc) {
    161         CDBG_ERROR("%s:config preview stream err=%d\n", __func__, rc);
    162         return NULL;
    163     }
    164 
    165     return stream;
    166 }
    167 
    168 mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
    169                                                    mm_camera_stream_t *source_stream)
    170 {
    171     mm_camera_channel_t *channel = NULL;
    172     mm_camera_stream_t *stream = NULL;
    173 
    174     if ( NULL == source_stream ) {
    175         CDBG_ERROR("%s: add reprocess stream failed\n", __func__);
    176         return NULL;
    177     }
    178 
    179     channel = mm_app_add_channel(test_obj,
    180                                  MM_CHANNEL_TYPE_REPROCESS,
    181                                  NULL,
    182                                  NULL,
    183                                  NULL);
    184     if (NULL == channel) {
    185         CDBG_ERROR("%s: add channel failed", __func__);
    186         return NULL;
    187     }
    188 
    189     // pp feature config
    190     cam_pp_feature_config_t pp_config;
    191     memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
    192 
    193     cam_capability_t *caps = ( cam_capability_t * ) ( test_obj->cap_buf.buf.buffer );
    194     if (caps->min_required_pp_mask & CAM_QCOM_FEATURE_SHARPNESS) {
    195         pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
    196         pp_config.sharpness = test_obj->reproc_sharpness;
    197     }
    198 
    199     if (test_obj->reproc_wnr.denoise_enable) {
    200         pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
    201         pp_config.denoise2d = test_obj->reproc_wnr;
    202     }
    203 
    204     if (test_obj->enable_CAC) {
    205         pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
    206     }
    207 
    208     uint8_t minStreamBufNum = source_stream->num_of_bufs;
    209     stream = mm_app_add_reprocess_stream_from_source(test_obj,
    210                                      channel,
    211                                      source_stream,
    212                                      mm_app_reprocess_notify_cb,
    213                                      pp_config,
    214                                      (void *)test_obj,
    215                                      minStreamBufNum);
    216     if (NULL == stream) {
    217         CDBG_ERROR("%s: add reprocess stream failed\n", __func__);
    218         mm_app_del_channel(test_obj, channel);
    219         return NULL;
    220     }
    221     test_obj->reproc_stream = stream;
    222 
    223     return channel;
    224 }
    225 
    226 int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
    227 {
    228     int rc = MM_CAMERA_OK;
    229     mm_camera_channel_t *r_ch = NULL;
    230 
    231     mm_camera_queue_init(&test_obj->pp_frames,
    232                          mm_app_release_ppinput,
    233                          ( void * ) test_obj);
    234 
    235     r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
    236     if (MM_CAMERA_OK != rc) {
    237         CDBG_ERROR("%s: No initialized reprocess channel d rc=%d\n",
    238                     __func__,
    239                     rc);
    240         return rc;
    241     }
    242 
    243     rc = mm_app_start_channel(test_obj, r_ch);
    244     if (MM_CAMERA_OK != rc) {
    245         CDBG_ERROR("%s:start reprocess failed rc=%d\n", __func__, rc);
    246         mm_app_del_channel(test_obj, r_ch);
    247         return rc;
    248     }
    249 
    250     return rc;
    251 }
    252 
    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         CDBG_ERROR("%s: No initialized reprocess channel d rc=%d\n",
    261                     __func__,
    262                     rc);
    263         return rc;
    264     }
    265 
    266     rc = mm_app_stop_and_del_channel(test_obj, r_ch);
    267     if (MM_CAMERA_OK != rc) {
    268         CDBG_ERROR("%s:Stop Preview failed rc=%d\n", __func__, rc);
    269     }
    270 
    271     mm_qcamera_queue_release(&test_obj->pp_frames);
    272     test_obj->reproc_stream = NULL;
    273 
    274     return rc;
    275 }
    276 
    277 int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
    278                         mm_camera_buf_def_t *frame,
    279                         uint8_t meta_idx,
    280                         mm_camera_super_buf_t *super_buf,
    281                         mm_camera_stream_t *src_meta)
    282 {
    283     int rc = MM_CAMERA_OK;
    284     mm_camera_channel_t *r_ch = NULL;
    285     mm_camera_super_buf_t *src_buf = NULL;
    286 
    287     if ( ( NULL == test_obj ) ||
    288          ( NULL == frame ) ||
    289          ( NULL == super_buf )) {
    290         CDBG_ERROR("%s: Invalid input rc=%d\n",
    291                     __func__,
    292                     rc);
    293         return rc;
    294     }
    295 
    296     if ( NULL == test_obj->reproc_stream ) {
    297         CDBG_ERROR("%s: No reprocess stream rc=%d\n",
    298                     __func__,
    299                     rc);
    300         return rc;
    301     }
    302 
    303     r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
    304     if (MM_CAMERA_OK != rc) {
    305         CDBG_ERROR("%s: No reprocess channel rc=%d\n",
    306                     __func__,
    307                     rc);
    308         return rc;
    309     }
    310 
    311     src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
    312     if ( NULL == src_buf ) {
    313         CDBG_ERROR("%s: No resources for src frame rc=%d\n",
    314                     __func__,
    315                     rc);
    316         return -1;
    317     }
    318     memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
    319     mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
    320 
    321     cam_stream_parm_buffer_t param;
    322     memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
    323     param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
    324     param.reprocess.buf_index = frame->buf_idx;
    325     param.reprocess.frame_idx = frame->frame_idx;
    326     if (src_meta != NULL) {
    327         param.reprocess.meta_present = 1;
    328         param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
    329         param.reprocess.meta_buf_index = meta_idx;
    330     } else {
    331         CDBG_ERROR("%s: No metadata source stream rc=%d\n",
    332                    __func__,
    333                    rc);
    334     }
    335 
    336     test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
    337     rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
    338                                               r_ch->ch_id,
    339                                               test_obj->reproc_stream->s_id,
    340                                               &test_obj->reproc_stream->s_config.stream_info->parm_buf);
    341 
    342     return rc;
    343 }
    344 
    345 void mm_app_release_ppinput(void *data, void *user_data)
    346 {
    347     int i = 0;
    348     mm_camera_super_buf_t *recvd_frame  = ( mm_camera_super_buf_t * ) data;
    349     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
    350 
    351     for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
    352         if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
    353                                                 recvd_frame->ch_id,
    354                                                 recvd_frame->bufs[i])) {
    355             CDBG_ERROR("%s: Failed in Qbuf\n", __func__);
    356         }
    357         mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
    358                          ION_IOC_INV_CACHES);
    359     }
    360 }
    361 
    362