@@ -16,6 +16,9 @@ LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL);
16
16
#define MY_PORT 5000
17
17
#define MAX_CLIENT_QUEUE 1
18
18
19
+ /* Assuming that video encoder will at least compress to this ratio */
20
+ #define ESTIMATED_COMPRESSION_RATIO 10
21
+
19
22
static ssize_t sendall (int sock , const void * buf , size_t len )
20
23
{
21
24
while (len ) {
@@ -31,12 +34,118 @@ static ssize_t sendall(int sock, const void *buf, size_t len)
31
34
return 0 ;
32
35
}
33
36
37
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
38
+ const struct device * encoder_dev = NULL ;
39
+
40
+ int configure_encoder ()
41
+ {
42
+ struct video_buffer * buffer ;
43
+ struct video_format fmt ;
44
+ struct video_caps caps ;
45
+ enum video_buf_type type = VIDEO_BUF_TYPE_OUTPUT ;
46
+ uint32_t size ;
47
+
48
+ encoder_dev = DEVICE_DT_GET (DT_CHOSEN (zephyr_videoenc ));
49
+ if (!device_is_ready (encoder_dev )) {
50
+ LOG_ERR ("%s: encoder video device not ready." ,
51
+ encoder_dev -> name );
52
+ return -1 ;
53
+ }
54
+ LOG_INF ("Encoder video device: %s" , encoder_dev -> name );
55
+
56
+ /* Get capabilities */
57
+ caps .type = type ;
58
+ if (video_get_caps (encoder_dev , & caps )) {
59
+ LOG_ERR ("Unable to retrieve video capabilities" );
60
+ return -1 ;
61
+ }
62
+
63
+ /* Get default/native format */
64
+ fmt .type = type ;
65
+ if (video_get_format (encoder_dev , & fmt )) {
66
+ LOG_ERR ("Unable to retrieve video format" );
67
+ return -1 ;
68
+ }
69
+
70
+ #if CONFIG_VIDEO_FRAME_HEIGHT
71
+ fmt .height = CONFIG_VIDEO_FRAME_HEIGHT ;
72
+ #endif
73
+
74
+ #if CONFIG_VIDEO_FRAME_WIDTH
75
+ fmt .width = CONFIG_VIDEO_FRAME_WIDTH ;
76
+ #endif
77
+
78
+ if (strcmp (CONFIG_VIDEO_PIXEL_FORMAT , "" )) {
79
+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_PIXEL_FORMAT );
80
+ }
81
+
82
+ LOG_INF ("- Video format: %s %ux%u" ,
83
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
84
+
85
+ if (video_set_format (encoder_dev , & fmt )) {
86
+ LOG_ERR ("Unable to set format" );
87
+ return -1 ;
88
+ }
89
+
90
+ printk ("Video device detected, format: %s %ux%u\n" ,
91
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
92
+
93
+ /* Alloc output buffer */
94
+ size = fmt .width * fmt .height / ESTIMATED_COMPRESSION_RATIO ;
95
+ buffer = video_buffer_aligned_alloc (size , CONFIG_VIDEO_BUFFER_POOL_ALIGN ,
96
+ K_FOREVER );
97
+ if (buffer == NULL ) {
98
+ LOG_ERR ("Unable to alloc compressed video buffer size=%d" , size );
99
+ return -1 ;
100
+ }
101
+ buffer -> type = type ;
102
+ video_enqueue (encoder_dev , buffer );
103
+
104
+ /* Start video capture */
105
+ if (video_stream_start (encoder_dev , type )) {
106
+ LOG_ERR ("Unable to start video" );
107
+ return -1 ;
108
+ }
109
+
110
+ return 0 ;
111
+ }
112
+
113
+ int encode_frame (struct video_buffer * in , struct video_buffer * * out )
114
+ {
115
+ struct video_buffer vbuf_in ;
116
+ int ret ;
117
+
118
+ vbuf_in = * in ;/* Do not override capture video buffer */
119
+
120
+ vbuf_in .type = VIDEO_BUF_TYPE_INPUT ;
121
+ video_enqueue (encoder_dev , & vbuf_in );
122
+
123
+ (* out )-> type = VIDEO_BUF_TYPE_OUTPUT ;
124
+ ret = video_dequeue (encoder_dev , out , K_FOREVER );
125
+ if (ret ) {
126
+ LOG_ERR ("Unable to dequeue encoder buf" );
127
+ return ret ;
128
+ }
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
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
147
+ struct video_buffer * vbuf_out = & (struct video_buffer ){};
148
+ #endif
40
149
int ret , sock , client ;
41
150
struct video_format fmt ;
42
151
struct video_caps caps ;
@@ -265,6 +374,13 @@ int main(void)
265
374
266
375
printk ("TCP: Accepted connection\n" );
267
376
377
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
378
+ if (configure_encoder ()) {
379
+ LOG_ERR ("Unable to configure video encoder" );
380
+ return 0 ;
381
+ }
382
+ #endif
383
+
268
384
/* Enqueue Buffers */
269
385
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
270
386
video_enqueue (video_dev , buffers [i ]);
@@ -288,10 +404,19 @@ int main(void)
288
404
return 0 ;
289
405
}
290
406
291
- printk ("\rSending frame %d\n" , i ++ );
407
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
408
+ encode_frame (vbuf , & vbuf_out );
409
+
410
+ printk ("\rSending compressed frame %d (size=%d bytes)\n" , i ++ , vbuf_out -> bytesused );
411
+ /* Send compressed video buffer to TCP client */
412
+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
292
413
414
+ video_enqueue (encoder_dev , vbuf_out );
415
+ #else
416
+ printk ("\rSending frame %d\n" , i ++ );
293
417
/* Send video buffer to TCP client */
294
418
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
419
+ #endif
295
420
if (ret && ret != - EAGAIN ) {
296
421
/* client disconnected */
297
422
printk ("\nTCP: Client disconnected %d\n" , ret );
@@ -307,6 +432,10 @@ int main(void)
307
432
return 0 ;
308
433
}
309
434
435
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
436
+ stop_encoder ();
437
+ #endif
438
+
310
439
/* Flush remaining buffers */
311
440
do {
312
441
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
0 commit comments