mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #95 from kwagyeman/master
Add a new mjpeg module for Mjpeg support.
This commit is contained in:
commit
d18d898203
@ -140,10 +140,11 @@ OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/img/,\
|
|||||||
rgb2rgb_tab.o \
|
rgb2rgb_tab.o \
|
||||||
median.o \
|
median.o \
|
||||||
point.o \
|
point.o \
|
||||||
|
rectangle.o \
|
||||||
bmp.o \
|
bmp.o \
|
||||||
ppm.o \
|
ppm.o \
|
||||||
gif.o \
|
gif.o \
|
||||||
rectangle.o \
|
mjpeg.o \
|
||||||
fast.o \
|
fast.o \
|
||||||
freak.o \
|
freak.o \
|
||||||
template.o \
|
template.o \
|
||||||
@ -161,6 +162,7 @@ OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/py/, \
|
|||||||
py_time.o \
|
py_time.o \
|
||||||
mlx90620.o \
|
mlx90620.o \
|
||||||
py_gif.o \
|
py_gif.o \
|
||||||
|
py_mjpeg.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
ifeq ($(TARGET), OPENMV1)
|
ifeq ($(TARGET), OPENMV1)
|
||||||
|
|||||||
@ -43,10 +43,11 @@ SRCS += $(addprefix img/, \
|
|||||||
rgb2rgb_tab.c \
|
rgb2rgb_tab.c \
|
||||||
median.c \
|
median.c \
|
||||||
point.c \
|
point.c \
|
||||||
|
rectangle.c \
|
||||||
bmp.c \
|
bmp.c \
|
||||||
ppm.c \
|
ppm.c \
|
||||||
gif.c \
|
gif.c \
|
||||||
rectangle.c \
|
mjpeg.c \
|
||||||
fast.c \
|
fast.c \
|
||||||
freak.c \
|
freak.c \
|
||||||
template.c \
|
template.c \
|
||||||
@ -64,6 +65,7 @@ SRCS += $(addprefix py/, \
|
|||||||
py_time.c \
|
py_time.c \
|
||||||
mlx90620.c \
|
mlx90620.c \
|
||||||
py_gif.c \
|
py_gif.c \
|
||||||
|
py_mjpeg.c \
|
||||||
)
|
)
|
||||||
|
|
||||||
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))
|
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))
|
||||||
|
|||||||
@ -54,7 +54,7 @@ void *fb_alloc0(uint32_t size)
|
|||||||
|
|
||||||
void *fb_alloc_all(uint32_t *size)
|
void *fb_alloc_all(uint32_t *size)
|
||||||
{
|
{
|
||||||
int temp = pointer - ((char *) FB_PIXELS()) - sizeof(uint32_t);
|
int32_t temp = pointer - ((char *) FB_PIXELS()) - sizeof(uint32_t);
|
||||||
|
|
||||||
if (temp < sizeof(uint32_t)) {
|
if (temp < sizeof(uint32_t)) {
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
|||||||
@ -173,6 +173,8 @@ extern const int8_t lab_table[196608];
|
|||||||
__typeof__ (img1) _img1 = (img1); \
|
__typeof__ (img1) _img1 = (img1); \
|
||||||
(_img0->w==_img1->w)&&(_img0->h==_img1->h)&&(_img0->bpp==_img1->bpp); })
|
(_img0->w==_img1->w)&&(_img0->h==_img1->h)&&(_img0->bpp==_img1->bpp); })
|
||||||
|
|
||||||
|
#define IM_JPEG_QUALITY (50)
|
||||||
|
|
||||||
// Main Ram = 196,608 bytes
|
// Main Ram = 196,608 bytes
|
||||||
// -
|
// -
|
||||||
// struct framebuffer = 20 bytes
|
// struct framebuffer = 20 bytes
|
||||||
@ -434,6 +436,11 @@ void gif_open(FIL *fp, int width, int height, bool color, bool loop);
|
|||||||
void gif_add_frame(FIL *fp, image_t *img, uint16_t delay);
|
void gif_add_frame(FIL *fp, image_t *img, uint16_t delay);
|
||||||
void gif_close(FIL *fp);
|
void gif_close(FIL *fp);
|
||||||
|
|
||||||
|
/* MJPEG functions */
|
||||||
|
void mjpeg_open(FIL *fp, int width, int height);
|
||||||
|
void mjpeg_add_frame(FIL *fp, uint32_t *frames, uint32_t *bytes, image_t *img);
|
||||||
|
void mjpeg_close(FIL *fp, uint32_t *frames, uint32_t *bytes, float fps);
|
||||||
|
|
||||||
/* Basic image functions */
|
/* Basic image functions */
|
||||||
int imlib_get_pixel(image_t *img, int x, int y);
|
int imlib_get_pixel(image_t *img, int x, int y);
|
||||||
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
||||||
|
|||||||
149
src/omv/img/mjpeg.c
Normal file
149
src/omv/img/mjpeg.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the OpenMV project.
|
||||||
|
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||||
|
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||||
|
*
|
||||||
|
* A super simple MJPEG encoder.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "ff_wrapper.h"
|
||||||
|
#include "imlib.h"
|
||||||
|
#include "fb_alloc.h"
|
||||||
|
|
||||||
|
#define SIZE_OFFSET (1*4)
|
||||||
|
#define MICROS_OFFSET (8*4)
|
||||||
|
#define FRAMES_OFFSET (12*4)
|
||||||
|
#define RATE_0_OFFSET (19*4)
|
||||||
|
#define LENGTH_0_OFFSET (21*4)
|
||||||
|
#define RATE_1_OFFSET (33*4)
|
||||||
|
#define LENGTH_1_OFFSET (35*4)
|
||||||
|
#define MOVI_OFFSET (54*4)
|
||||||
|
|
||||||
|
void mjpeg_open(FIL *fp, int width, int height)
|
||||||
|
{
|
||||||
|
write_data(fp, "RIFF", 4); // FOURCC fcc; - 0
|
||||||
|
write_long(fp, 0); // DWORD cb; size - updated on close - 1
|
||||||
|
write_data(fp, "AVI ", 4); // FOURCC fcc; - 2
|
||||||
|
|
||||||
|
write_data(fp, "LIST", 4); // FOURCC fcc; - 3
|
||||||
|
write_long(fp, 192); // DWORD cb; - 4
|
||||||
|
write_data(fp, "hdrl", 4); // FOURCC fcc; - 5
|
||||||
|
|
||||||
|
write_data(fp, "avih", 4); // FOURCC fcc; - 6
|
||||||
|
write_long(fp, 56); // DWORD cb; - 7
|
||||||
|
write_long(fp, 0); // DWORD dwMicroSecPerFrame; micros - updated on close - 8
|
||||||
|
write_long(fp, 0); // DWORD dwMaxBytesPerSec; updated on close - 9
|
||||||
|
write_long(fp, 4); // DWORD dwPaddingGranularity; - 10
|
||||||
|
write_long(fp, 0); // DWORD dwFlags; - 11
|
||||||
|
write_long(fp, 0); // DWORD dwTotalFrames; frames - updated on close - 12
|
||||||
|
write_long(fp, 0); // DWORD dwInitialFrames; - 13
|
||||||
|
write_long(fp, 1); // DWORD dwStreams; - 14
|
||||||
|
write_long(fp, 0); // DWORD dwSuggestedBufferSize; - 15
|
||||||
|
write_long(fp, width); // DWORD dwWidth; - 16
|
||||||
|
write_long(fp, height); // DWORD dwHeight; - 17
|
||||||
|
write_long(fp, 1000); // DWORD dwScale; - 18
|
||||||
|
write_long(fp, 0); // DWORD dwRate; rate - updated on close - 19
|
||||||
|
write_long(fp, 0); // DWORD dwStart; - 20
|
||||||
|
write_long(fp, 0); // DWORD dwLength; length - updated on close - 21
|
||||||
|
|
||||||
|
write_data(fp, "LIST", 4); // FOURCC fcc; - 22
|
||||||
|
write_long(fp, 116); // DWORD cb; - 23
|
||||||
|
write_data(fp, "strl", 4); // FOURCC fcc; - 24
|
||||||
|
|
||||||
|
write_data(fp, "strh", 4); // FOURCC fcc; - 25
|
||||||
|
write_long(fp, 56); // DWORD cb; - 26
|
||||||
|
write_data(fp, "vids", 4); // FOURCC fccType; - 27
|
||||||
|
write_data(fp, "MJPG", 4); // FOURCC fccHandler; - 28
|
||||||
|
write_long(fp, 0); // DWORD dwFlags; - 29
|
||||||
|
write_word(fp, 0); // WORD wPriority; - 30
|
||||||
|
write_word(fp, 0); // WORD wLanguage; - 30.5
|
||||||
|
write_long(fp, 0); // DWORD dwInitialFrames; - 31
|
||||||
|
write_long(fp, 1000); // DWORD dwScale; - 32
|
||||||
|
write_long(fp, 0); // DWORD dwRate; rate - updated on close - 33
|
||||||
|
write_long(fp, 0); // DWORD dwStart; - 34
|
||||||
|
write_long(fp, 0); // DWORD dwLength; length - updated on close - 35
|
||||||
|
write_long(fp, 0); // DWORD dwSuggestedBufferSize; - 36
|
||||||
|
write_long(fp, IM_JPEG_QUALITY * 100); // DWORD dwQuality; - 37
|
||||||
|
write_long(fp, 0); // DWORD dwSampleSize; - 38
|
||||||
|
write_word(fp, 0); // short int left; - 39
|
||||||
|
write_word(fp, 0); // short int top; - 39.5
|
||||||
|
write_word(fp, 0); // short int right; - 40
|
||||||
|
write_word(fp, 0); // short int bottom; - 40.5
|
||||||
|
|
||||||
|
write_data(fp, "strf", 4); // FOURCC fcc; - 41
|
||||||
|
write_long(fp, 40); // DWORD cb; - 42
|
||||||
|
write_long(fp, 40); // DWORD biSize; - 43
|
||||||
|
write_long(fp, width); // LONG biWidth; - 44
|
||||||
|
write_long(fp, height); // LONG biHeight; - 45
|
||||||
|
write_word(fp, 1); // WORD biPlanes; - 46
|
||||||
|
write_word(fp, 24); // WORD biBitCount; - 46.5
|
||||||
|
write_data(fp, "MJPG", 4); // DWORD biCompression; - 47
|
||||||
|
write_long(fp, 0); // DWORD biSizeImage; - 48
|
||||||
|
write_long(fp, 0); // LONG biXPelsPerMeter; - 49
|
||||||
|
write_long(fp, 0); // LONG biYPelsPerMeter; - 50
|
||||||
|
write_long(fp, 0); // DWORD biClrUsed; - 51
|
||||||
|
write_long(fp, 0); // DWORD biClrImportant; - 52
|
||||||
|
|
||||||
|
write_data(fp, "LIST", 4); // FOURCC fcc; - 53
|
||||||
|
write_long(fp, 0); // DWORD cb; movi - updated on close - 54
|
||||||
|
write_data(fp, "movi", 4); // FOURCC fcc; - 55
|
||||||
|
}
|
||||||
|
|
||||||
|
void mjpeg_add_frame(FIL *fp, uint32_t *frames, uint32_t *bytes, image_t *img)
|
||||||
|
{
|
||||||
|
write_data(fp, "00dc", 4); // FOURCC fcc;
|
||||||
|
*frames += 1;
|
||||||
|
if (IM_IS_JPEG(img)) {
|
||||||
|
int pad = (((img->bpp + 3) / 4) * 4) - img->bpp;
|
||||||
|
write_long(fp, img->bpp + pad); // DWORD cb;
|
||||||
|
write_data(fp, img->pixels, img->bpp + pad); // reading past okay
|
||||||
|
*bytes += img->bpp + pad;
|
||||||
|
} else {
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t *buffer = fb_alloc_all(&size);
|
||||||
|
image_t out = { .w=img->w, .h=img->h, .bpp=size, .pixels=buffer };
|
||||||
|
// When jpeg_compress needs more memory than in currently allocated it
|
||||||
|
// will try to realloc. MP will detect that the pointer is outside of
|
||||||
|
// the heap and return NULL which will cause an out of memory error.
|
||||||
|
jpeg_compress(img, &out, IM_JPEG_QUALITY);
|
||||||
|
int pad = (((out.bpp + 3) / 4) * 4) - out.bpp;
|
||||||
|
write_long(fp, out.bpp + pad); // DWORD cb;
|
||||||
|
write_data(fp, out.pixels, out.bpp + pad); // reading past okay
|
||||||
|
*bytes += out.bpp + pad;
|
||||||
|
fb_free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mjpeg_close(FIL *fp, uint32_t *frames, uint32_t *bytes, float fps)
|
||||||
|
{
|
||||||
|
// Needed
|
||||||
|
file_seek(fp, SIZE_OFFSET);
|
||||||
|
write_long(fp, 216 + (*frames * 8) + *bytes);
|
||||||
|
// Needed
|
||||||
|
file_seek(fp, MICROS_OFFSET);
|
||||||
|
write_long(fp, (!fast_roundf(fps)) ? 0 :
|
||||||
|
fast_roundf(1000000 / fps));
|
||||||
|
write_long(fp, (!(*frames)) ? 0 :
|
||||||
|
fast_roundf((((*frames * 8) + *bytes) * fps) / *frames));
|
||||||
|
// Needed
|
||||||
|
file_seek(fp, FRAMES_OFFSET);
|
||||||
|
write_long(fp, *frames);
|
||||||
|
// Probably not needed but writing it just in case.
|
||||||
|
file_seek(fp, RATE_0_OFFSET);
|
||||||
|
write_long(fp, fast_roundf(fps * 1000));
|
||||||
|
// Probably not needed but writing it just in case.
|
||||||
|
file_seek(fp, LENGTH_0_OFFSET);
|
||||||
|
write_long(fp, (!fast_roundf(fps)) ? 0 :
|
||||||
|
fast_roundf((*frames * 1000) / fps));
|
||||||
|
// Probably not needed but writing it just in case.
|
||||||
|
file_seek(fp, RATE_1_OFFSET);
|
||||||
|
write_long(fp, fast_roundf(fps * 1000));
|
||||||
|
// Probably not needed but writing it just in case.
|
||||||
|
file_seek(fp, LENGTH_1_OFFSET);
|
||||||
|
write_long(fp, (!fast_roundf(fps)) ? 0 :
|
||||||
|
fast_roundf((*frames * 1000) / fps));
|
||||||
|
// Needed
|
||||||
|
file_seek(fp, MOVI_OFFSET);
|
||||||
|
write_long(fp, 4 + (*frames * 8) + *bytes);
|
||||||
|
file_close(fp);
|
||||||
|
}
|
||||||
119
src/omv/py/py_mjpeg.c
Normal file
119
src/omv/py/py_mjpeg.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the OpenMV project.
|
||||||
|
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
|
||||||
|
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||||
|
*
|
||||||
|
* MJPEG Python module.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "mp.h"
|
||||||
|
#include "ff_wrapper.h"
|
||||||
|
#include "framebuffer.h"
|
||||||
|
#include "sensor.h"
|
||||||
|
#include "py_assert.h"
|
||||||
|
#include "py_helper.h"
|
||||||
|
#include "py_image.h"
|
||||||
|
|
||||||
|
static const mp_obj_type_t py_mjpeg_type; // forward declare
|
||||||
|
// Mjpeg class
|
||||||
|
typedef struct py_mjpeg_obj {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
uint32_t frames;
|
||||||
|
uint32_t bytes;
|
||||||
|
FIL fp;
|
||||||
|
} py_mjpeg_obj_t;
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_open(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *mjpeg = m_new_obj(py_mjpeg_obj_t);
|
||||||
|
mjpeg->width = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_width), fb->w);
|
||||||
|
mjpeg->height = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_height), fb->h);
|
||||||
|
mjpeg->frames = 0; // private
|
||||||
|
mjpeg->bytes = 0; // private
|
||||||
|
mjpeg->base.type = &py_mjpeg_type;
|
||||||
|
|
||||||
|
file_write_open(&mjpeg->fp, mp_obj_str_get_str(args[0]));
|
||||||
|
mjpeg_open(&mjpeg->fp, mjpeg->width, mjpeg->height);
|
||||||
|
return mjpeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_width(mp_obj_t mjpeg_obj)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
|
||||||
|
return mp_obj_new_int(arg_mjpeg->width);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_height(mp_obj_t mjpeg_obj)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
|
||||||
|
return mp_obj_new_int(arg_mjpeg->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_size(mp_obj_t mjpeg_obj)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
|
||||||
|
return mp_obj_new_int(f_size(&arg_mjpeg->fp));
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_add_frame(mp_obj_t mjpeg_obj, mp_obj_t img_obj)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
|
||||||
|
image_t *arg_img = py_image_cobj(img_obj);
|
||||||
|
PY_ASSERT_FALSE_MSG((arg_mjpeg->width != arg_img->w)
|
||||||
|
|| (arg_mjpeg->height != arg_img->h),
|
||||||
|
"Unexpected image geometry");
|
||||||
|
|
||||||
|
mjpeg_add_frame(&arg_mjpeg->fp, &arg_mjpeg->frames, &arg_mjpeg->bytes, arg_img);
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
static mp_obj_t py_mjpeg_close(mp_obj_t mjpeg_obj, mp_obj_t fps_obj)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *arg_mjpeg = mjpeg_obj;
|
||||||
|
mjpeg_close(&arg_mjpeg->fp, &arg_mjpeg->frames, &arg_mjpeg->bytes, mp_obj_get_float(fps_obj));
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void py_mjpeg_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
|
||||||
|
{
|
||||||
|
py_mjpeg_obj_t *self = self_in;
|
||||||
|
mp_printf(print, "<mjpeg width:%d height:%d>", self->width, self->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_width_obj, py_mjpeg_width);
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_height_obj, py_mjpeg_height);
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mjpeg_size_obj, py_mjpeg_size);
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_mjpeg_add_frame_obj, py_mjpeg_add_frame);
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_mjpeg_close_obj, py_mjpeg_close);
|
||||||
|
static const mp_map_elem_t locals_dict_table[] = {
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_width), (mp_obj_t)&py_mjpeg_width_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_height), (mp_obj_t)&py_mjpeg_height_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_size), (mp_obj_t)&py_mjpeg_size_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_add_frame), (mp_obj_t)&py_mjpeg_add_frame_obj },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&py_mjpeg_close_obj },
|
||||||
|
{ NULL, NULL },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(locals_dict, locals_dict_table);
|
||||||
|
|
||||||
|
static const mp_obj_type_t py_mjpeg_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_Mjpeg,
|
||||||
|
.print = py_mjpeg_print,
|
||||||
|
.locals_dict = (mp_obj_t)&locals_dict,
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_mjpeg_open_obj, 1, py_mjpeg_open);
|
||||||
|
static const mp_map_elem_t globals_dict_table[] = {
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_mjpeg) },
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_Mjpeg), (mp_obj_t)&py_mjpeg_open_obj },
|
||||||
|
{ NULL, NULL },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t mjpeg_module = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.name = MP_QSTR_mjpeg,
|
||||||
|
.globals = (mp_obj_t)&globals_dict,
|
||||||
|
};
|
||||||
31
usr/examples/mjpeg.py
Normal file
31
usr/examples/mjpeg.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Mjpeg recording example:
|
||||||
|
#
|
||||||
|
# You can use your OpenMV Cam to record mjpeg files. You can either feed the
|
||||||
|
# recorder object JPEG frames or RGB565/Grayscale frames. Once you've finished
|
||||||
|
# recording an Mjpeg file you can use VLC to play it. If you're on Ubuntu then
|
||||||
|
# the built-in video player will work too.
|
||||||
|
|
||||||
|
import sensor, image, time, mjpeg
|
||||||
|
|
||||||
|
sensor.reset()
|
||||||
|
sensor.set_framesize(sensor.QVGA)
|
||||||
|
sensor.set_pixformat(sensor.RGB565) # you can also use grayscale
|
||||||
|
|
||||||
|
# Warm up the cam
|
||||||
|
for i in range(10):
|
||||||
|
sensor.snapshot()
|
||||||
|
|
||||||
|
# FPS clock
|
||||||
|
clock = time.clock()
|
||||||
|
mjpeg = mjpeg.Mjpeg("/test.mjpeg") # video setup to use current resolution
|
||||||
|
|
||||||
|
for i in range(300):
|
||||||
|
clock.tick()
|
||||||
|
img = sensor.snapshot()
|
||||||
|
mjpeg.add_frame(img)
|
||||||
|
# Print FPS.
|
||||||
|
# Note: Actual FPS is higher, the IDE slows down streaming.
|
||||||
|
print(clock.fps())
|
||||||
|
|
||||||
|
mjpeg.close(clock.fps())
|
||||||
|
print("done")
|
||||||
Loading…
Reference in New Issue
Block a user