@@ -18,6 +18,9 @@ LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL);
18
18
#define MY_PORT 5000
19
19
#define MAX_CLIENT_QUEUE 1
20
20
21
+ /* Assuming that video encoder will at least compress to this ratio */
22
+ #define ESTIMATED_COMPRESSION_RATIO 10
23
+
21
24
static ssize_t sendall (int sock , const void * buf , size_t len )
22
25
{
23
26
while (len ) {
@@ -33,12 +36,141 @@ static ssize_t sendall(int sock, const void *buf, size_t len)
33
36
return 0 ;
34
37
}
35
38
39
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
40
+ const struct device * encoder_dev = NULL ;
41
+
42
+ int configure_encoder ()
43
+ {
44
+ struct video_buffer * buffer ;
45
+ struct video_format fmt ;
46
+ struct video_caps caps ;
47
+ uint32_t size ;
48
+ int i = 0 ;
49
+
50
+ encoder_dev = DEVICE_DT_GET (DT_CHOSEN (zephyr_videoenc ));
51
+ if (!device_is_ready (encoder_dev )) {
52
+ LOG_ERR ("%s: encoder video device not ready." ,
53
+ encoder_dev -> name );
54
+ return -1 ;
55
+ }
56
+
57
+ /* Get capabilities */
58
+ caps .type = VIDEO_BUF_TYPE_OUTPUT ;
59
+ if (video_get_caps (encoder_dev , & caps )) {
60
+ LOG_ERR ("Unable to retrieve video capabilities" );
61
+ return -1 ;
62
+ }
63
+
64
+ LOG_INF ("- Capabilities:" );
65
+ while (caps .format_caps [i ].pixelformat ) {
66
+ const struct video_format_cap * fcap = & caps .format_caps [i ];
67
+ /* fourcc to string */
68
+ LOG_INF (" %s width [%u; %u; %u] height [%u; %u; %u]" ,
69
+ VIDEO_FOURCC_TO_STR (fcap -> pixelformat ),
70
+ fcap -> width_min , fcap -> width_max , fcap -> width_step ,
71
+ fcap -> height_min , fcap -> height_max , fcap -> height_step );
72
+ i ++ ;
73
+ }
74
+
75
+ /* Get default/native format */
76
+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
77
+ if (video_get_format (encoder_dev , & fmt )) {
78
+ LOG_ERR ("Unable to retrieve video format" );
79
+ return -1 ;
80
+ }
81
+
82
+ printk ("Video encoder device detected, format: %s %ux%u\n" ,
83
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
84
+
85
+ #if CONFIG_VIDEO_FRAME_HEIGHT
86
+ fmt .height = CONFIG_VIDEO_FRAME_HEIGHT ;
87
+ #endif
88
+
89
+ #if CONFIG_VIDEO_FRAME_WIDTH
90
+ fmt .width = CONFIG_VIDEO_FRAME_WIDTH ;
91
+ #endif
92
+
93
+ if (strcmp (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT , "" )) {
94
+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_ENCODED_PIXEL_FORMAT );
95
+ }
96
+
97
+ LOG_INF ("- Video encoded format: %s %ux%u" ,
98
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
99
+
100
+ fmt .type = VIDEO_BUF_TYPE_OUTPUT ;
101
+ if (video_set_format (encoder_dev , & fmt )) {
102
+ LOG_ERR ("Unable to set format" );
103
+ return -1 ;
104
+ }
105
+
106
+ /* Set input format */
107
+ if (strcmp (CONFIG_VIDEO_PIXEL_FORMAT , "" )) {
108
+ fmt .pixelformat = VIDEO_FOURCC_FROM_STR (CONFIG_VIDEO_PIXEL_FORMAT );
109
+ }
110
+
111
+ LOG_INF ("- Video input format: %s %ux%u" ,
112
+ VIDEO_FOURCC_TO_STR (fmt .pixelformat ), fmt .width , fmt .height );
113
+
114
+ fmt .type = VIDEO_BUF_TYPE_INPUT ;
115
+ if (video_set_format (encoder_dev , & fmt )) {
116
+ LOG_ERR ("Unable to set input format" );
117
+ return 0 ;
118
+ }
119
+
120
+ /* Alloc output buffer */
121
+ size = fmt .width * fmt .height / ESTIMATED_COMPRESSION_RATIO ;
122
+ buffer = video_buffer_aligned_alloc (size , CONFIG_VIDEO_BUFFER_POOL_ALIGN ,
123
+ K_FOREVER );
124
+ if (buffer == NULL ) {
125
+ LOG_ERR ("Unable to alloc compressed video buffer size=%d" , size );
126
+ return -1 ;
127
+ }
128
+ buffer -> type = VIDEO_BUF_TYPE_OUTPUT ;
129
+ video_enqueue (encoder_dev , buffer );
130
+
131
+ /* Start video encoder */
132
+ buffer -> type = VIDEO_BUF_TYPE_OUTPUT ;
133
+ if (video_stream_start (encoder_dev , VIDEO_BUF_TYPE_OUTPUT )) {
134
+ LOG_ERR ("Unable to start video encoder" );
135
+ return -1 ;
136
+ }
137
+
138
+ return 0 ;
139
+ }
140
+
141
+ int encode_frame (struct video_buffer * in , struct video_buffer * * out )
142
+ {
143
+ int ret ;
144
+
145
+ in -> type = VIDEO_BUF_TYPE_INPUT ;
146
+ video_enqueue (encoder_dev , in );
147
+
148
+ (* out )-> type = VIDEO_BUF_TYPE_OUTPUT ;
149
+ ret = video_dequeue (encoder_dev , out , K_FOREVER );
150
+ if (ret ) {
151
+ LOG_ERR ("Unable to dequeue encoder buf" );
152
+ return ret ;
153
+ }
154
+
155
+ return 0 ;
156
+ }
157
+
158
+ void stop_encoder (void )
159
+ {
160
+ if (video_stream_stop (encoder_dev , VIDEO_BUF_TYPE_OUTPUT ))
161
+ LOG_ERR ("Unable to stop encoder" );
162
+ }
163
+ #endif
164
+
36
165
int main (void )
37
166
{
38
167
struct sockaddr_in addr , client_addr ;
39
168
socklen_t client_addr_len = sizeof (client_addr );
40
169
struct video_buffer * buffers [CONFIG_VIDEO_CAPTURE_N_BUFFERING ];
41
170
struct video_buffer * vbuf = & (struct video_buffer ){};
171
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
172
+ struct video_buffer * vbuf_out = & (struct video_buffer ){};
173
+ #endif
42
174
int ret , sock , client ;
43
175
struct video_format fmt ;
44
176
struct video_caps caps ;
@@ -267,6 +399,13 @@ int main(void)
267
399
268
400
printk ("TCP: Accepted connection\n" );
269
401
402
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
403
+ if (configure_encoder ()) {
404
+ LOG_ERR ("Unable to configure video encoder" );
405
+ return 0 ;
406
+ }
407
+ #endif
408
+
270
409
/* Enqueue Buffers */
271
410
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
272
411
video_enqueue (video_dev , buffers [i ]);
@@ -290,16 +429,27 @@ int main(void)
290
429
return 0 ;
291
430
}
292
431
293
- printk ("\rSending frame %d\n" , i ++ );
432
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
433
+ encode_frame (vbuf , & vbuf_out );
294
434
435
+ printk ("\rSending compressed frame %d (size=%d bytes)\n" , i ++ , vbuf_out -> bytesused );
436
+ /* Send compressed video buffer to TCP client */
437
+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
438
+
439
+ vbuf_out -> type = VIDEO_BUF_TYPE_OUTPUT ;
440
+ video_enqueue (encoder_dev , vbuf_out );
441
+ #else
442
+ printk ("\rSending frame %d\n" , i ++ );
295
443
/* Send video buffer to TCP client */
296
444
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
445
+ #endif
297
446
if (ret && ret != - EAGAIN ) {
298
447
/* client disconnected */
299
448
printk ("\nTCP: Client disconnected %d\n" , ret );
300
449
close (client );
301
450
}
302
451
452
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
303
453
(void )video_enqueue (video_dev , vbuf );
304
454
} while (!ret );
305
455
@@ -309,8 +459,13 @@ int main(void)
309
459
return 0 ;
310
460
}
311
461
462
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
463
+ stop_encoder ();
464
+ #endif
465
+
312
466
/* Flush remaining buffers */
313
467
do {
468
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
314
469
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
315
470
} while (!ret );
316
471
0 commit comments