@@ -31,12 +31,119 @@ static ssize_t sendall(int sock, const void *buf, size_t len)
31
31
return 0 ;
32
32
}
33
33
34
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
35
+ const struct device * encoder_dev = NULL ;
36
+
37
+ int configure_encoder ()
38
+ {
39
+ struct video_buffer * buffer ;
40
+ struct video_format fmt ;
41
+ struct video_caps caps ;
42
+ enum video_buf_type type = VIDEO_BUF_TYPE_OUTPUT ;
43
+ uint32_t size ;
44
+ if (encoder_dev )
45
+ return 0 ;
46
+
47
+ encoder_dev = DEVICE_DT_GET (DT_CHOSEN (zephyr_videoenc ));
48
+ if (!device_is_ready (encoder_dev )) {
49
+ LOG_ERR ("%s: video device not ready." , encoder_dev -> name );
50
+ return -1 ;
51
+ }
52
+ LOG_INF ("Video device: %s" , encoder_dev -> name );
53
+
54
+ /* Get capabilities */
55
+ caps .type = type ;
56
+ if (video_get_caps (encoder_dev , & caps )) {
57
+ LOG_ERR ("Unable to retrieve video capabilities" );
58
+ return -1 ;
59
+ }
60
+
61
+ /* Get default/native format */
62
+ fmt .type = type ;
63
+ if (video_get_format (encoder_dev , & fmt )) {
64
+ LOG_ERR ("Unable to retrieve video format" );
65
+ return -1 ;
66
+ }
67
+
68
+ #if CONFIG_VIDEO_FRAME_HEIGHT
69
+ fmt .height = CONFIG_VIDEO_FRAME_HEIGHT ;
70
+ #endif
71
+
72
+ #if CONFIG_VIDEO_FRAME_WIDTH
73
+ fmt .width = CONFIG_VIDEO_FRAME_WIDTH ;
74
+ #endif
75
+
76
+ if (strcmp (CONFIG_VIDEO_PIXEL_FORMAT , "" )) {
77
+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_PIXEL_FORMAT );
78
+ }
79
+
80
+ LOG_INF ("- Video format: %s %ux%u" ,
81
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
82
+
83
+ if (video_set_format (encoder_dev , & fmt )) {
84
+ LOG_ERR ("Unable to set format" );
85
+ return -1 ;
86
+ }
87
+
88
+ printk ("Video device detected, format: %s %ux%u\n" ,
89
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
90
+
91
+ /* Alloc output buffer */
92
+ size = fmt .width * fmt .height / 10 ;/* Assuming H264 x10 compression ratio */
93
+ buffer = video_buffer_aligned_alloc (size , CONFIG_VIDEO_BUFFER_POOL_ALIGN ,
94
+ K_FOREVER );
95
+ if (buffer == NULL ) {
96
+ LOG_ERR ("Unable to alloc compressed video buffer size=%d" , size );
97
+ return -1 ;
98
+ }
99
+ buffer -> type = type ;
100
+ video_enqueue (encoder_dev , buffer );
101
+
102
+ /* Start video capture */
103
+ if (video_stream_start (encoder_dev , type )) {
104
+ LOG_ERR ("Unable to start video" );
105
+ return -1 ;
106
+ }
107
+
108
+ return 0 ;
109
+ }
110
+
111
+ int encode_frame (struct video_buffer * in , struct video_buffer * * out )
112
+ {
113
+ struct video_buffer vbuf_in ;
114
+ int ret ;
115
+
116
+ vbuf_in = * in ;/* Do not override capture video buffer */
117
+
118
+ vbuf_in .type = VIDEO_BUF_TYPE_INPUT ;
119
+ video_enqueue (encoder_dev , & vbuf_in );
120
+
121
+ (* out )-> type = VIDEO_BUF_TYPE_OUTPUT ;
122
+ ret = video_dequeue (encoder_dev , out , K_FOREVER );
123
+ if (ret ) {
124
+ LOG_ERR ("Unable to dequeue encoder buf" );
125
+ return ret ;
126
+ }
127
+
128
+ video_enqueue (encoder_dev , (* out ));
129
+
130
+ return 0 ;
131
+ }
132
+
133
+ void stop_encoder (void )
134
+ {
135
+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_OUTPUT ))
136
+ LOG_ERR ("Unable to stop encoder" );
137
+ }
138
+ #endif
139
+
34
140
int main (void )
35
141
{
36
142
struct sockaddr_in addr , client_addr ;
37
143
socklen_t client_addr_len = sizeof (client_addr );
38
144
struct video_buffer * buffers [2 ];
39
145
struct video_buffer * vbuf = & (struct video_buffer ){};
146
+ struct video_buffer * vbuf_out = & (struct video_buffer ){};
40
147
int ret , sock , client ;
41
148
struct video_format fmt ;
42
149
struct video_caps caps ;
@@ -265,6 +372,13 @@ int main(void)
265
372
266
373
printk ("TCP: Accepted connection\n" );
267
374
375
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
376
+ if (configure_encoder ()) {
377
+ LOG_ERR ("Unable to configure video encoder" );
378
+ return 0 ;
379
+ }
380
+ #endif
381
+
268
382
/* Enqueue Buffers */
269
383
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
270
384
video_enqueue (video_dev , buffers [i ]);
@@ -288,10 +402,17 @@ int main(void)
288
402
return 0 ;
289
403
}
290
404
291
- printk ("\rSending frame %d\n" , i ++ );
405
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
406
+ encode_frame (vbuf , & vbuf_out );
292
407
408
+ printk ("\rSending compressed frame %d (size=%d bytes)\n" , i ++ , vbuf_out -> bytesused );
409
+ /* Send compressed video buffer to TCP client */
410
+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
411
+ #else
412
+ printk ("\rSending frame %d\n" , i ++ );
293
413
/* Send video buffer to TCP client */
294
414
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
415
+ #endif
295
416
if (ret && ret != - EAGAIN ) {
296
417
/* client disconnected */
297
418
printk ("\nTCP: Client disconnected %d\n" , ret );
@@ -307,6 +428,10 @@ int main(void)
307
428
return 0 ;
308
429
}
309
430
431
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
432
+ stop_encoder ();
433
+ #endif
434
+
310
435
/* Flush remaining buffers */
311
436
do {
312
437
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
0 commit comments