Home | History | Annotate | Download | only in src
      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 
     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 
    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 
    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 
    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 
    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 
    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 
    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