@@ -33,12 +33,153 @@ 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 = 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
+
36
174
int main (void )
37
175
{
38
176
struct sockaddr_in addr , client_addr ;
39
177
socklen_t client_addr_len = sizeof (client_addr );
40
178
struct video_buffer * buffers [CONFIG_VIDEO_CAPTURE_N_BUFFERING ];
41
179
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
42
183
int ret , sock , client ;
43
184
struct video_format fmt ;
44
185
struct video_caps caps ;
@@ -267,6 +408,13 @@ int main(void)
267
408
268
409
LOG_INF ("TCP: Accepted connection" );
269
410
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
+
270
418
/* Enqueue Buffers */
271
419
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
272
420
video_enqueue (video_dev , buffers [i ]);
@@ -290,16 +438,28 @@ int main(void)
290
438
return 0 ;
291
439
}
292
440
293
- LOG_INF ("Sending frame %d" , i ++ );
441
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
442
+ encode_frame (vbuf , & vbuf_out );
294
443
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 ++ );
295
453
/* Send video buffer to TCP client */
296
454
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
455
+ #endif
297
456
if (ret && ret != - EAGAIN ) {
298
457
/* client disconnected */
299
458
LOG_ERR ("TCP: Client disconnected %d" , ret );
300
459
close (client );
301
460
}
302
461
462
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
303
463
(void )video_enqueue (video_dev , vbuf );
304
464
} while (!ret );
305
465
@@ -309,8 +469,13 @@ int main(void)
309
469
return 0 ;
310
470
}
311
471
472
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
473
+ stop_encoder ();
474
+ #endif
475
+
312
476
/* Flush remaining buffers */
313
477
do {
478
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
314
479
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
315
480
} while (!ret );
316
481
0 commit comments