@@ -33,12 +33,153 @@ 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 = 0 ;
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 ("- Capabilities:" );
61+ while (caps .format_caps [i ].pixelformat ) {
62+ const struct video_format_cap * fcap = & caps .format_caps [i ];
63+ /* fourcc to string */
64+ LOG_INF (" %s width [%u; %u; %u] height [%u; %u; %u]" ,
65+ VIDEO_FOURCC_TO_STR (fcap -> pixelformat ), fcap -> width_min , fcap -> width_max ,
66+ fcap -> width_step , fcap -> height_min , fcap -> height_max , fcap -> height_step );
67+ i ++ ;
68+ }
69+
70+ /* Get default/native format */
71+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
72+ if (video_get_format (encoder_dev , & fmt )) {
73+ LOG_ERR ("Unable to retrieve video format" );
74+ return -1 ;
75+ }
76+
77+ LOG_INF ("Video encoder device detected, format: %s %ux%u" ,
78+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
79+
80+ #if CONFIG_VIDEO_FRAME_HEIGHT
81+ fmt .height = CONFIG_VIDEO_FRAME_HEIGHT ;
82+ #endif
83+
84+ #if CONFIG_VIDEO_FRAME_WIDTH
85+ fmt .width = CONFIG_VIDEO_FRAME_WIDTH ;
86+ #endif
87+
88+ /* Set output format */
89+ if (strcmp (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT , "" )) {
90+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT );
91+ }
92+
93+ LOG_INF ("- Video encoded format: %s %ux%u" , VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width ,
94+ fmt .height );
95+
96+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
97+ if (video_set_format (encoder_dev , & fmt )) {
98+ LOG_ERR ("Unable to set format" );
99+ return -1 ;
100+ }
101+
102+ /* Alloc output buffer */
103+ size = fmt .sizeimage ;
104+ if (size == 0 ) {
105+ LOG_ERR ("Encoder driver must set sizeimage" );
106+ return -1 ;
107+ }
108+
109+ buffer = video_buffer_aligned_alloc (size , CONFIG_VIDEO_BUFFER_POOL_ALIGN , K_FOREVER );
110+ if (buffer == NULL ) {
111+ LOG_ERR ("Unable to alloc compressed video buffer size=%d" , size );
112+ return -1 ;
113+ }
114+
115+ buffer -> type = VIDEO_BUF_TYPE_OUTPUT ;
116+ video_enqueue (encoder_dev , buffer );
117+
118+ /* Set input format */
119+ if (strcmp (CONFIG_VIDEO_PIXEL_FORMAT , "" )) {
120+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_PIXEL_FORMAT );
121+ }
122+
123+ LOG_INF ("- Video input format: %s %ux%u" , VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width ,
124+ fmt .height );
125+
126+ fmt .type = VIDEO_BUF_TYPE_INPUT ;
127+ if (video_set_format (encoder_dev , & fmt )) {
128+ LOG_ERR ("Unable to set input format" );
129+ return -1 ;
130+ }
131+
132+ /* Start video encoder */
133+ if (video_stream_start (encoder_dev , VIDEO_BUF_TYPE_INPUT )) {
134+ LOG_ERR ("Unable to start video encoder (input)" );
135+ return -1 ;
136+ }
137+ if (video_stream_start (encoder_dev , VIDEO_BUF_TYPE_OUTPUT )) {
138+ LOG_ERR ("Unable to start video encoder (output)" );
139+ return -1 ;
140+ }
141+
142+ return 0 ;
143+ }
144+
145+ int encode_frame (struct video_buffer * in , struct video_buffer * * out )
146+ {
147+ int ret ;
148+
149+ in -> type = VIDEO_BUF_TYPE_INPUT ;
150+ video_enqueue (encoder_dev , in );
151+
152+ (* out )-> type = VIDEO_BUF_TYPE_OUTPUT ;
153+ ret = video_dequeue (encoder_dev , out , K_FOREVER );
154+ if (ret ) {
155+ LOG_ERR ("Unable to dequeue encoder buf" );
156+ return ret ;
157+ }
158+
159+ return 0 ;
160+ }
161+
162+ void stop_encoder (void )
163+ {
164+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_OUTPUT )) {
165+ LOG_ERR ("Unable to stop encoder (output)" );
166+ }
167+
168+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_INPUT )) {
169+ LOG_ERR ("Unable to stop encoder (input)" );
170+ }
171+ }
172+ #endif
173+
36174int main (void )
37175{
38176 struct sockaddr_in addr , client_addr ;
39177 socklen_t client_addr_len = sizeof (client_addr );
40178 struct video_buffer * buffers [CONFIG_VIDEO_CAPTURE_N_BUFFERING ];
41179 struct video_buffer * vbuf = & (struct video_buffer ){};
180+ #if DT_HAS_CHOSEN (zephyr_videoenc )
181+ struct video_buffer * vbuf_out = & (struct video_buffer ){};
182+ #endif
42183 int ret , sock , client ;
43184 struct video_format fmt ;
44185 struct video_caps caps ;
@@ -267,6 +408,13 @@ int main(void)
267408
268409 LOG_INF ("TCP: Accepted connection" );
269410
411+ #if DT_HAS_CHOSEN (zephyr_videoenc )
412+ if (configure_encoder ()) {
413+ LOG_ERR ("Unable to configure video encoder" );
414+ return 0 ;
415+ }
416+ #endif
417+
270418 /* Enqueue Buffers */
271419 for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
272420 video_enqueue (video_dev , buffers [i ]);
@@ -290,16 +438,28 @@ int main(void)
290438 return 0 ;
291439 }
292440
293- LOG_INF ("Sending frame %d" , i ++ );
441+ #if DT_HAS_CHOSEN (zephyr_videoenc )
442+ encode_frame (vbuf , & vbuf_out );
294443
444+ LOG_INF ("Sending compressed frame %d (size=%d bytes)" , i ++ ,
445+ vbuf_out -> bytesused );
446+ /* Send compressed video buffer to TCP client */
447+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
448+
449+ vbuf_out -> type = VIDEO_BUF_TYPE_OUTPUT ;
450+ video_enqueue (encoder_dev , vbuf_out );
451+ #else
452+ LOG_INF ("Sending frame %d" , i ++ );
295453 /* Send video buffer to TCP client */
296454 ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
455+ #endif
297456 if (ret && ret != - EAGAIN ) {
298457 /* client disconnected */
299458 LOG_ERR ("TCP: Client disconnected %d" , ret );
300459 close (client );
301460 }
302461
462+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
303463 (void )video_enqueue (video_dev , vbuf );
304464 } while (!ret );
305465
@@ -309,8 +469,13 @@ int main(void)
309469 return 0 ;
310470 }
311471
472+ #if DT_HAS_CHOSEN (zephyr_videoenc )
473+ stop_encoder ();
474+ #endif
475+
312476 /* Flush remaining buffers */
313477 do {
478+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
314479 ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
315480 } while (!ret );
316481
0 commit comments