@@ -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
+ printk ("Video encoder device detected, format: %s %ux%u\n" ,
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 ;
@@ -268,6 +409,13 @@ int main(void)
268
409
269
410
printk ("TCP: Accepted connection\n" );
270
411
412
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
413
+ if (configure_encoder ()) {
414
+ LOG_ERR ("Unable to configure video encoder" );
415
+ return 0 ;
416
+ }
417
+ #endif
418
+
271
419
/* Enqueue Buffers */
272
420
for (i = 0 ; i < ARRAY_SIZE (buffers ); i ++ ) {
273
421
video_enqueue (video_dev , buffers [i ]);
@@ -291,16 +439,28 @@ int main(void)
291
439
return 0 ;
292
440
}
293
441
294
- printk ("\rSending frame %d\n" , i ++ );
442
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
443
+ encode_frame (vbuf , & vbuf_out );
295
444
445
+ printk ("\rSending compressed frame %d (size=%d bytes)\n" , i ++ ,
446
+ vbuf_out -> bytesused );
447
+ /* Send compressed video buffer to TCP client */
448
+ ret = sendall (client , vbuf_out -> buffer , vbuf_out -> bytesused );
449
+
450
+ vbuf_out -> type = VIDEO_BUF_TYPE_OUTPUT ;
451
+ video_enqueue (encoder_dev , vbuf_out );
452
+ #else
453
+ printk ("\rSending frame %d\n" , i ++ );
296
454
/* Send video buffer to TCP client */
297
455
ret = sendall (client , vbuf -> buffer , vbuf -> bytesused );
456
+ #endif
298
457
if (ret && ret != - EAGAIN ) {
299
458
/* client disconnected */
300
459
printk ("\nTCP: Client disconnected %d\n" , ret );
301
460
close (client );
302
461
}
303
462
463
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
304
464
(void )video_enqueue (video_dev , vbuf );
305
465
} while (!ret );
306
466
@@ -310,8 +470,13 @@ int main(void)
310
470
return 0 ;
311
471
}
312
472
473
+ #if DT_HAS_CHOSEN (zephyr_videoenc )
474
+ stop_encoder ();
475
+ #endif
476
+
313
477
/* Flush remaining buffers */
314
478
do {
479
+ vbuf -> type = VIDEO_BUF_TYPE_INPUT ;
315
480
ret = video_dequeue (video_dev , & vbuf , K_NO_WAIT );
316
481
} while (!ret );
317
482
0 commit comments