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 uint32_t rdi_len = 0;
     34 
     35 static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame,
     36                                   char *name,
     37                                   char *ext,
     38                                   int frame_idx)
     39 {
     40     char file_name[64];
     41     int file_fd;
     42     int i;
     43 
     44     if (frame != NULL) {
     45 
     46         snprintf(file_name, sizeof(file_name), "/data/%s_%03d.%s", name, frame_idx, ext);
     47         file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
     48         if (file_fd < 0) {
     49             CDBG_ERROR("%s: cannot open file %s \n", __func__, file_name);
     50         } else {
     51             for (i = 0; i < frame->num_planes; i++) {
     52                 write(file_fd,
     53                       (uint8_t *)frame->buffer + frame->planes[i].data_offset,
     54                       rdi_len);
     55             }
     56 
     57             close(file_fd);
     58             CDBG("%s: dump rdi frame %s", __func__,file_name);
     59         }
     60     }
     61 }
     62 
     63 static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
     64                                  void *user_data)
     65 {
     66     char file_name[64];
     67     mm_camera_buf_def_t *frame = bufs->bufs[0];
     68     mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
     69 
     70     CDBG("%s: BEGIN - length=%d, frame idx = %d stream_id=%d\n",
     71          __func__, frame->frame_len, frame->frame_idx, frame->stream_id);
     72     snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle);
     73     mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx);
     74 
     75     if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
     76                                             bufs->ch_id,
     77                                             frame)) {
     78         CDBG_ERROR("%s: Failed in RDI Qbuf\n", __func__);
     79     }
     80     mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
     81                      ION_IOC_INV_CACHES);
     82 
     83     CDBG("%s: END\n", __func__);
     84 }
     85 
     86 mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj,
     87                                                mm_camera_channel_t *channel,
     88                                                mm_camera_buf_notify_t stream_cb,
     89                                                void *userdata,
     90                                                uint8_t num_bufs,
     91                                                uint8_t num_burst)
     92 {
     93     int rc = MM_CAMERA_OK;
     94     int i;
     95     mm_camera_stream_t *stream = NULL;
     96     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
     97     cam_format_t fmt = CAM_FORMAT_MAX;
     98     cam_stream_buf_plane_info_t *buf_planes;
     99 
    100     stream = mm_app_add_stream(test_obj, channel);
    101     if (NULL == stream) {
    102         CDBG_ERROR("%s: add stream failed\n", __func__);
    103         return NULL;
    104     }
    105 
    106     CDBG_ERROR("%s: raw_dim w:%d height:%d\n", __func__, cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
    107     for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) {
    108         CDBG_ERROR("%s: supported_raw_fmts[%d]=%d\n", __func__, i, cam_cap->supported_raw_fmts[i]);
    109         if (((CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i]) &&
    110             (CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i])) ||
    111             (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_META_RAW_8BIT) ||
    112             (cam_cap->supported_raw_fmts[i] == CAM_FORMAT_JPEG_RAW_8BIT))
    113         {
    114             fmt = cam_cap->supported_raw_fmts[i];
    115             CDBG_ERROR("%s: fmt=%d\n", __func__, fmt);
    116         }
    117     }
    118 
    119     if (CAM_FORMAT_MAX == fmt) {
    120         CDBG_ERROR("%s: rdi format not supported\n", __func__);
    121         return NULL;
    122     }
    123 
    124     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    125     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    126     stream->s_config.mem_vtbl.clean_invalidate_buf =
    127       mm_app_stream_clean_invalidate_buf;
    128     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    129     stream->s_config.mem_vtbl.user_data = (void *)stream;
    130     stream->s_config.stream_cb = stream_cb;
    131     stream->s_config.userdata = userdata;
    132     stream->num_of_bufs = num_bufs;
    133 
    134     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    135     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    136     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
    137     if (num_burst == 0) {
    138         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    139     } else {
    140         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    141         stream->s_config.stream_info->num_of_burst = num_burst;
    142     }
    143     stream->s_config.stream_info->fmt = fmt;
    144     CDBG("%s: RAW: w: %d, h: %d ", __func__,
    145        cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
    146 
    147     stream->s_config.stream_info->dim.width = cam_cap->raw_dim[0].width;
    148     stream->s_config.stream_info->dim.height = cam_cap->raw_dim[0].height;
    149     stream->s_config.padding_info = cam_cap->padding_info;
    150 
    151     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    152     if (MM_CAMERA_OK != rc) {
    153         CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
    154         return NULL;
    155     }
    156 
    157     buf_planes = &stream->s_config.stream_info->buf_planes;
    158     rdi_len = buf_planes->plane_info.mp[0].len;
    159     CDBG("%s: plane_info %dx%d len:%d frame_len:%d\n", __func__,
    160         buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
    161         buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
    162 
    163     return stream;
    164 }
    165 
    166 mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
    167                                                 mm_camera_channel_t *channel,
    168                                                 mm_camera_buf_notify_t stream_cb,
    169                                                 void *userdata,
    170                                                 uint8_t num_bufs,
    171                                                 uint8_t num_burst)
    172 {
    173     int rc = MM_CAMERA_OK;
    174     mm_camera_stream_t *stream = NULL;
    175     cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
    176 
    177     stream = mm_app_add_stream(test_obj, channel);
    178     if (NULL == stream) {
    179         CDBG_ERROR("%s: add stream failed\n", __func__);
    180         return NULL;
    181     }
    182 
    183     stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
    184     stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
    185     stream->s_config.mem_vtbl.clean_invalidate_buf =
    186       mm_app_stream_clean_invalidate_buf;
    187     stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
    188     stream->s_config.mem_vtbl.user_data = (void *)stream;
    189     stream->s_config.stream_cb = stream_cb;
    190     stream->s_config.userdata = userdata;
    191     stream->num_of_bufs = num_bufs;
    192 
    193     stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
    194     memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
    195     stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
    196     if (num_burst == 0) {
    197         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
    198     } else {
    199         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
    200         stream->s_config.stream_info->num_of_burst = num_burst;
    201     }
    202     stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
    203     stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
    204     stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
    205     stream->s_config.padding_info = cam_cap->padding_info;
    206 
    207     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
    208     if (MM_CAMERA_OK != rc) {
    209         CDBG_ERROR("%s:config rdi stream err=%d\n", __func__, rc);
    210         return NULL;
    211     }
    212 
    213     return stream;
    214 }
    215 
    216 mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
    217 {
    218     mm_camera_channel_t *channel = NULL;
    219     mm_camera_stream_t *stream = NULL;
    220 
    221     channel = mm_app_add_channel(test_obj,
    222                                  MM_CHANNEL_TYPE_RDI,
    223                                  NULL,
    224                                  NULL,
    225                                  NULL);
    226     if (NULL == channel) {
    227         CDBG_ERROR("%s: add channel failed", __func__);
    228         return NULL;
    229     }
    230 
    231     stream = mm_app_add_rdi_stream(test_obj,
    232                                        channel,
    233                                        mm_app_rdi_notify_cb,
    234                                        (void *)test_obj,
    235                                        RDI_BUF_NUM,
    236                                        num_burst);
    237     if (NULL == stream) {
    238         CDBG_ERROR("%s: add stream failed\n", __func__);
    239         mm_app_del_channel(test_obj, channel);
    240         return NULL;
    241     }
    242 
    243     CDBG("%s: channel=%d stream=%d\n", __func__, channel->ch_id, stream->s_id);
    244     return channel;
    245 }
    246 
    247 int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
    248                                 mm_camera_channel_t *channel)
    249 {
    250     int rc = MM_CAMERA_OK;
    251     mm_camera_stream_t *stream = NULL;
    252     uint8_t i;
    253 
    254     rc = mm_app_stop_channel(test_obj, channel);
    255     if (MM_CAMERA_OK != rc) {
    256         CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
    257     }
    258 
    259     if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
    260         for (i = 0; i < channel->num_streams; i++) {
    261             stream = &channel->streams[i];
    262             rc = mm_app_del_stream(test_obj, channel, stream);
    263             if (MM_CAMERA_OK != rc) {
    264                 CDBG_ERROR("%s:del stream(%d) failed rc=%d\n", __func__, i, rc);
    265             }
    266         }
    267     } else {
    268         CDBG_ERROR("%s: num_streams = %d. Should not be more than %d\n",
    269             __func__, channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
    270     }
    271 
    272     rc = mm_app_del_channel(test_obj, channel);
    273     if (MM_CAMERA_OK != rc) {
    274         CDBG_ERROR("%s:delete channel failed rc=%d\n", __func__, rc);
    275     }
    276 
    277     return rc;
    278 }
    279 
    280 int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
    281 {
    282     int rc = MM_CAMERA_OK;
    283     mm_camera_channel_t *channel = NULL;
    284 
    285     channel = mm_app_add_rdi_channel(test_obj, num_burst);
    286     if (NULL == channel) {
    287         CDBG_ERROR("%s: add channel failed", __func__);
    288         return -MM_CAMERA_E_GENERAL;
    289     }
    290 
    291     rc = mm_app_start_channel(test_obj, channel);
    292     if (MM_CAMERA_OK != rc) {
    293         CDBG_ERROR("%s:start rdi failed rc=%d\n", __func__, rc);
    294         mm_app_del_channel(test_obj, channel);
    295         return rc;
    296     }
    297 
    298     return rc;
    299 }
    300 
    301 int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
    302 {
    303     int rc = MM_CAMERA_OK;
    304 
    305     mm_camera_channel_t *channel =
    306         mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
    307 
    308     rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
    309     if (MM_CAMERA_OK != rc) {
    310         CDBG_ERROR("%s:Stop RDI failed rc=%d\n", __func__, rc);
    311     }
    312 
    313     return rc;
    314 }
    315 
    316