@@ -33,12 +33,171 @@ static ssize_t sendall(int sock, const void *buf, size_t len)
3333 return 0 ;
3434}
3535
36+ #if DT_HAS_CHOSEN (zephyr_videoenc )
37+ const struct device * encoder_dev ;
38+
39+ int configure_encoder (void )
40+ {
41+ struct video_buffer * buffer ;
42+ struct video_format fmt ;
43+ struct video_caps caps ;
44+ uint32_t size ;
45+ int i ;
46+
47+ encoder_dev = DEVICE_DT_GET (DT_CHOSEN (zephyr_videoenc ));
48+ if (!device_is_ready (encoder_dev )) {
49+ LOG_ERR ("%s: encoder video device not ready." , encoder_dev -> name );
50+ return -1 ;
51+ }
52+
53+ /* Get capabilities */
54+ caps .type = VIDEO_BUF_TYPE_OUTPUT ;
55+ if (video_get_caps (encoder_dev , & caps )) {
56+ LOG_ERR ("Unable to retrieve video capabilities" );
57+ return -1 ;
58+ }
59+
60+ LOG_INF ("- Encoder output capabilities:" );
61+ i = 0 ;
62+ while (caps .format_caps [i ].pixelformat ) {
63+ const struct video_format_cap * fcap = & caps .format_caps [i ];
64+ /* fourcc to string */
65+ LOG_INF (" %s width [%u; %u; %u] height [%u; %u; %u]" ,
66+ VIDEO_FOURCC_TO_STR (fcap -> pixelformat ), fcap -> width_min , fcap -> width_max ,
67+ fcap -> width_step , fcap -> height_min , fcap -> height_max , fcap -> height_step );
68+ i ++ ;
69+ }
70+
71+ caps .type = VIDEO_BUF_TYPE_INPUT ;
72+ if (video_get_caps (encoder_dev , & caps )) {
73+ LOG_ERR ("Unable to retrieve video capabilities" );
74+ return -1 ;
75+ }
76+
77+ LOG_INF ("- Encoder input capabilities:" );
78+ i = 0 ;
79+ while (caps .format_caps [i ].pixelformat ) {
80+ const struct video_format_cap * fcap = & caps .format_caps [i ];
81+ /* fourcc to string */
82+ LOG_INF (" %s width [%u; %u; %u] height [%u; %u; %u]" ,
83+ VIDEO_FOURCC_TO_STR (fcap -> pixelformat ), fcap -> width_min , fcap -> width_max ,
84+ fcap -> width_step , fcap -> height_min , fcap -> height_max , fcap -> height_step );
85+ i ++ ;
86+ }
87+
88+ /* Get default/native format */
89+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
90+ if (video_get_format (encoder_dev , & fmt )) {
91+ LOG_ERR ("Unable to retrieve video format" );
92+ return -1 ;
93+ }
94+
95+ LOG_INF ("Video encoder device detected, format: %s %ux%u" ,
96+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
97+
98+ #if CONFIG_VIDEO_FRAME_HEIGHT
99+ fmt .height = CONFIG_VIDEO_FRAME_HEIGHT ;
100+ #endif
101+
102+ #if CONFIG_VIDEO_FRAME_WIDTH
103+ fmt .width = CONFIG_VIDEO_FRAME_WIDTH ;
104+ #endif
105+
106+ /* Set output format */
107+ if (strcmp (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT , "" )) {
108+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT );
109+ }
110+
111+ LOG_INF ("- Video encoder output format: %s %ux%u" , VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width ,
112+ fmt .height );
113+
114+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
115+ if (video_set_format (encoder_dev , & fmt )) {
116+ LOG_ERR ("Unable to set format" );
117+ return -1 ;
118+ }
119+
120+ /* Alloc output buffer */
121+ size = fmt .size ;
122+ if (size == 0 ) {
123+ LOG_ERR ("Encoder driver must set format size" );
124+ return -1 ;
125+ }
126+
127+ buffer = video_buffer_aligned_alloc (size , CONFIG_VIDEO_BUFFER_POOL_ALIGN , K_FOREVER );
128+ if (buffer == NULL ) {
129+ LOG_ERR ("Unable to alloc compressed video buffer size=%d" , size );
130+ return -1 ;
131+ }
132+
133+ buffer -> type = VIDEO_BUF_TYPE_OUTPUT ;
134+ video_enqueue (encoder_dev , buffer );
135+
136+ /* Set input format */
137+ if (strcmp (CONFIG_VIDEO_PIXEL_FORMAT , "" )) {
138+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_PIXEL_FORMAT );
139+ }
140+
141+ LOG_INF ("- Video encoder input format: %s %ux%u" , VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width ,
142+ fmt .height );
143+
144+ fmt .type = VIDEO_BUF_TYPE_INPUT ;
145+ if (video_set_format (encoder_dev , & fmt )) {
146+ LOG_ERR ("Unable to set input format" );
147+ return -1 ;
148+ }
149+
150+ /* Start video encoder */
151+ if (video_stream_start (encoder_dev , VIDEO_BUF_TYPE_INPUT )) {
152+ LOG_ERR ("Unable to start video encoder (input)" );
153+ return -1 ;
154+ }
155+ if (video_stream_start (encoder_dev , VIDEO_BUF_TYPE_OUTPUT )) {
156+ LOG_ERR ("Unable to start video encoder (output)" );
157+ return -1 ;
158+ }
159+
160+ return 0 ;
161+ }
162+
163+ int encode_frame (struct video_buffer * in , struct video_buffer * * out )
164+ {
165+ int ret ;
166+
167+ in -> type = VIDEO_BUF_TYPE_INPUT ;
168+ video_enqueue (encoder_dev , in );
169+
170+ (* out )-> type = VIDEO_BUF_TYPE_OUTPUT ;
171+ ret = video_dequeue (encoder_dev , out , K_FOREVER );
172+ if (ret ) {
173+ LOG_ERR ("Unable to dequeue encoder buf" );
174+ return ret ;
175+ }
176+
177+ return 0 ;
178+ }
179+
180+ void stop_encoder (void )
181+ {
182+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_OUTPUT )) {
183+ LOG_ERR ("Unable to stop encoder (output)" );
184+ }
185+
186+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_INPUT )) {
187+ LOG_ERR ("Unable to stop encoder (input)" );
188+ }
189+ }
190+ #endif
191+
36192int main (void )
37193{
38194 struct sockaddr_in addr , client_addr ;
39195 socklen_t client_addr_len = sizeof (client_addr );
40196 struct video_buffer * buffers [CONFIG_VIDEO_CAPTURE_N_BUFFERING ];
41197 struct video_buffer * vbuf = & (struct video_buffer ){};
198+ #if DT_HAS_CHOSEN (zephyr_videoenc )
199+ struct video_buffer * vbuf_out = & (struct video_buffer ){};
200+ #endif
42201 int ret , sock , client ;
43202 struct video_format fmt ;
44203 struct video_caps caps ;
@@ -267,6 +426,13 @@ int main(void)
267426
268427 LOG_INF ("TCP: Accepted connection" );
269428
429+ #if DT_HAS_CHOSEN (zephyr_videoenc )
430+ if (configure_encoder ()) {
431+ LOG_ERR ("Unable to configure video encoder" );
432+ return 0 ;
433+ }
434+ #endif
435+
270436 /* Enqueue Buffers */
271437 for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
272438 video_enqueue (video_dev , buffers [i ]);
@@ -290,16 +456,28 @@ int main(void)
290456 return 0 ;
291457 }
292458
293- LOG_INF ("Sending frame %d" , i ++ );
459+ #if DT_HAS_CHOSEN (zephyr_videoenc )
460+ encode_frame (vbuf , & vbuf_out );
461+
462+ LOG_INF ("Sending compressed frame %d (size=%d bytes)" , i ++ ,
463+ vbuf_out -> bytesused );
464+ /* Send compressed video buffer to TCP client */
465+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
294466
467+ vbuf_out -> type = VIDEO_BUF_TYPE_OUTPUT ;
468+ video_enqueue (encoder_dev , vbuf_out );
469+ #else
470+ LOG_INF ("Sending frame %d" , i ++ );
295471 /* Send video buffer to TCP client */
296472 ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
473+ #endif
297474 if (ret && ret != - EAGAIN ) {
298475 /* client disconnected */
299476 LOG_ERR ("TCP: Client disconnected %d" , ret );
300477 close (client );
301478 }
302479
480+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
303481 (void )video_enqueue (video_dev , vbuf );
304482 } while (!ret );
305483
@@ -309,8 +487,13 @@ int main(void)
309487 return 0 ;
310488 }
311489
490+ #if DT_HAS_CHOSEN (zephyr_videoenc )
491+ stop_encoder ();
492+ #endif
493+
312494 /* Flush remaining buffers */
313495 do {
496+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
314497 ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
315498 } while (!ret );
316499
0 commit comments