/ components / micropython / port / src / omv / py / py_mjpeg.c
py_mjpeg.c
  1  /*
  2   * This file is part of the OpenMV project.
  3   * Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
  4   * This work is licensed under the MIT license, see the file LICENSE for details.
  5   *
  6   * MJPEG Python module.
  7   *
  8   */
  9  #include "mp.h"
 10  #include "vfs_wrapper.h"
 11  #include "framebuffer.h"
 12  #include "sensor.h"
 13  #include "py_assert.h"
 14  #include "py_helper.h"
 15  #include "py_image.h"
 16  
 17  static const mp_obj_type_t py_mjpeg_type; // forward declare
 18  // Mjpeg class
 19  typedef struct py_mjpeg_obj {
 20      mp_obj_base_t base;
 21      int width;
 22      int height;
 23      uint32_t frames;
 24      uint32_t bytes;
 25      mp_obj_t fp;
 26  } py_mjpeg_obj_t;
 27  
 28  static mp_obj_t py_mjpeg_open(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args)
 29  {
 30      py_mjpeg_obj_t *mjpeg = m_new_obj(py_mjpeg_obj_t);
 31      mjpeg->width  = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), MAIN_FB()->w);
 32      mjpeg->height = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), MAIN_FB()->h);
 33      mjpeg->frames = 0; // private
 34      mjpeg->bytes = 0; // private
 35      mjpeg->base.type = &py_mjpeg_type;
 36  
 37      file_write_open(&mjpeg->fp, mp_obj_str_get_str(args[0]));
 38      mjpeg_open(&mjpeg->fp, mjpeg->width, mjpeg->height);
 39      return mjpeg;
 40  }
 41  
 42  static mp_obj_t py_mjpeg_width(mp_obj_t mjpeg_obj)
 43  {
 44      py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
 45      return mp_obj_new_int(arg_mjpeg->width);
 46  }
 47  
 48  static mp_obj_t py_mjpeg_height(mp_obj_t mjpeg_obj)
 49  {
 50      py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
 51      return mp_obj_new_int(arg_mjpeg->height);
 52  }
 53  
 54  static mp_obj_t py_mjpeg_size(mp_obj_t mjpeg_obj)
 55  {
 56      py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
 57      return mp_obj_new_int(file_size(arg_mjpeg->fp));
 58  }
 59  
 60  static mp_obj_t py_mjpeg_add_frame(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args)
 61  {
 62      py_mjpeg_obj_t *arg_mjpeg = args[0];
 63      image_t *arg_img = py_image_cobj(args[1]);
 64      PY_ASSERT_FALSE_MSG((arg_mjpeg->width != arg_img->w)
 65                       || (arg_mjpeg->height != arg_img->h),
 66              "Unexpected image geometry");
 67  
 68      int arg_q = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_quality), 50);
 69      arg_q = IM_MIN(IM_MAX(arg_q, 1), 100);
 70      mjpeg_add_frame(&arg_mjpeg->fp, &arg_mjpeg->frames, &arg_mjpeg->bytes, arg_img, arg_q);
 71      return mp_const_none;
 72  }
 73  
 74  static mp_obj_t py_mjpeg_close(mp_obj_t mjpeg_obj, mp_obj_t fps_obj)
 75  {
 76      py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
 77      mjpeg_close(&arg_mjpeg->fp, &arg_mjpeg->frames, &arg_mjpeg->bytes, mp_obj_get_float(fps_obj));
 78      return mp_const_none;
 79  }
 80  
 81  static void py_mjpeg_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
 82  {
 83      py_mjpeg_obj_t *self = self_in;
 84      mp_printf(print, "<mjpeg width:%d height:%d>", self->width, self->height);
 85  }
 86  
 87  STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_width_obj, py_mjpeg_width);
 88  STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_height_obj, py_mjpeg_height);
 89  STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_size_obj, py_mjpeg_size);
 90  STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_mjpeg_add_frame_obj, 2, py_mjpeg_add_frame);
 91  STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_mjpeg_close_obj, py_mjpeg_close);
 92  static const mp_map_elem_t locals_dict_table[] = {
 93      { MP_OBJ_NEW_QSTR(MP_QSTR_width),       (mp_obj_t)&py_mjpeg_width_obj     },
 94      { MP_OBJ_NEW_QSTR(MP_QSTR_height),      (mp_obj_t)&py_mjpeg_height_obj    },
 95      { MP_OBJ_NEW_QSTR(MP_QSTR_size),        (mp_obj_t)&py_mjpeg_size_obj      },
 96      { MP_OBJ_NEW_QSTR(MP_QSTR_add_frame),   (mp_obj_t)&py_mjpeg_add_frame_obj },
 97      { MP_OBJ_NEW_QSTR(MP_QSTR_close),       (mp_obj_t)&py_mjpeg_close_obj     },
 98      { NULL, NULL },
 99  };
100  STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table);
101  
102  static const mp_obj_type_t py_mjpeg_type = {
103      { &mp_type_type },
104      .name  = MP_QSTR_Mjpeg,
105      .print = py_mjpeg_print,
106      .locals_dict = (mp_obj_t)&locals_dict,
107  };
108  
109  STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_mjpeg_open_obj, 1, py_mjpeg_open);
110  static const mp_map_elem_t globals_dict_table[] = {
111      { MP_OBJ_NEW_QSTR(MP_QSTR___name__),    MP_OBJ_NEW_QSTR(MP_QSTR_mjpeg) },
112      { MP_OBJ_NEW_QSTR(MP_QSTR_Mjpeg),       (mp_obj_t)&py_mjpeg_open_obj   },
113      { NULL, NULL },
114  };
115  STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
116  
117  const mp_obj_module_t mjpeg_module = {
118      .base = { &mp_type_module },
119      .globals = (mp_obj_t)&globals_dict,
120  };