@@ -26,6 +26,7 @@ typedef struct _webcam_obj_t {
2626 void * buffers [NUM_BUFFERS ];
2727 size_t buffer_length ;
2828 int frame_count ;
29+ unsigned char * gray_buffer ; // Persistent buffer for memoryview
2930} webcam_obj_t ;
3031
3132static void yuyv_to_grayscale_240x240 (unsigned char * yuyv , unsigned char * gray , int in_width , int in_height ) {
@@ -106,7 +107,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
106107 buf .memory = V4L2_MEMORY_MMAP ;
107108 buf .index = i ;
108109 if (ioctl (self -> fd , VIDIOC_QBUF , & buf ) < 0 ) {
109- fprintf (stderr , "Cannot queue buffer: %s\n" , strerror (errno ));
110+ fprintf (stderr , "Cannot queue buffer: %s\n" , strerror (errno ));
110111 return -1 ;
111112 }
112113 }
@@ -118,6 +119,12 @@ static int init_webcam(webcam_obj_t *self, const char *device) {
118119 }
119120
120121 self -> frame_count = 0 ;
122+ self -> gray_buffer = (unsigned char * )malloc (OUTPUT_WIDTH * OUTPUT_HEIGHT );
123+ if (!self -> gray_buffer ) {
124+ fprintf (stderr , "Cannot allocate gray buffer: %s\n" , strerror (errno ));
125+ close (self -> fd );
126+ return -1 ;
127+ }
121128 return 0 ;
122129}
123130
@@ -133,6 +140,11 @@ static void deinit_webcam(webcam_obj_t *self) {
133140 }
134141 }
135142
143+ if (self -> gray_buffer ) {
144+ free (self -> gray_buffer );
145+ self -> gray_buffer = NULL ;
146+ }
147+
136148 close (self -> fd );
137149 self -> fd = -1 ;
138150}
@@ -145,20 +157,17 @@ static mp_obj_t capture_frame(webcam_obj_t *self) {
145157 mp_raise_OSError (MP_EIO );
146158 }
147159
148- unsigned char * gray = (unsigned char * )malloc (OUTPUT_WIDTH * OUTPUT_HEIGHT );
149- if (!gray ) {
160+ if (!self -> gray_buffer ) {
150161 mp_raise_OSError (MP_ENOMEM );
151162 }
152163
153- yuyv_to_grayscale_240x240 (self -> buffers [buf .index ], gray , WIDTH , HEIGHT );
164+ yuyv_to_grayscale_240x240 (self -> buffers [buf .index ], self -> gray_buffer , WIDTH , HEIGHT );
154165
155166 char filename [32 ];
156167 snprintf (filename , sizeof (filename ), "frame_%03d.raw" , self -> frame_count ++ );
157- save_raw (filename , gray , OUTPUT_WIDTH , OUTPUT_HEIGHT );
158-
159- mp_obj_t result = mp_obj_new_bytes (gray , OUTPUT_WIDTH * OUTPUT_HEIGHT );
168+ save_raw (filename , self -> gray_buffer , OUTPUT_WIDTH , OUTPUT_HEIGHT );
160169
161- free ( gray );
170+ mp_obj_t result = mp_obj_new_memoryview ( 0x01 , OUTPUT_WIDTH * OUTPUT_HEIGHT , self -> gray_buffer );
162171
163172 if (ioctl (self -> fd , VIDIOC_QBUF , & buf ) < 0 ) {
164173 mp_raise_OSError (MP_EIO );
@@ -177,6 +186,7 @@ static mp_obj_t webcam_init(size_t n_args, const mp_obj_t *args) {
177186 webcam_obj_t * self = m_new_obj (webcam_obj_t );
178187 self -> base .type = & webcam_type ;
179188 self -> fd = -1 ;
189+ self -> gray_buffer = NULL ;
180190
181191 if (init_webcam (self , device ) < 0 ) {
182192 mp_raise_OSError (MP_EIO );
0 commit comments