@@ -33,12 +33,171 @@ static ssize_t sendall(int sock, const void *buf, size_t len)
33
33
return 0 ;
34
34
}
35
35
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_INPUT ;
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 input 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_OUTPUT ;
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 output 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 encoded 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 .sizeimage ;
122
+ if (size == 0 ) {
123
+ LOG_ERR ("Encoder driver must set sizeimage" );
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 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
+
36
192
int main (void )
37
193
{
38
194
struct sockaddr_in addr , client_addr ;
39
195
socklen_t client_addr_len = sizeof (client_addr );
40
196
struct video_buffer * buffers [CONFIG_VIDEO_CAPTURE_N_BUFFERING ];
41
197
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
42
201
int ret , sock , client ;
43
202
struct video_format fmt ;
44
203
struct video_caps caps ;
@@ -267,6 +426,13 @@ int main(void)
267
426
268
427
LOG_INF ("TCP: Accepted connection" );
269
428
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
+
270
436
/* Enqueue Buffers */
271
437
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
272
438
video_enqueue (video_dev , buffers [i ]);
@@ -290,16 +456,28 @@ int main(void)
290
456
return 0 ;
291
457
}
292
458
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 );
294
466
467
+ vbuf_out -> type = VIDEO_BUF_TYPE_OUTPUT ;
468
+ video_enqueue (encoder_dev , vbuf_out );
469
+ #else
470
+ LOG_INF ("Sending frame %d" , i ++ );
295
471
/* Send video buffer to TCP client */
296
472
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
473
+ #endif
297
474
if (ret && ret != - EAGAIN ) {
298
475
/* client disconnected */
299
476
LOG_ERR ("TCP: Client disconnected %d" , ret );
300
477
close (client );
301
478
}
302
479
480
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
303
481
(void )video_enqueue (video_dev , vbuf );
304
482
} while (!ret );
305
483
@@ -309,8 +487,13 @@ int main(void)
309
487
return 0 ;
310
488
}
311
489
490
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
491
+ stop_encoder ();
492
+ #endif
493
+
312
494
/* Flush remaining buffers */
313
495
do {
496
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
314
497
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
315
498
} while (!ret );
316
499
0 commit comments