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 };