@@ -56,6 +56,20 @@ void video_task(void* param);
5656void freertos_init (void );
5757#endif
5858
59+ #if !defined(CFG_EXAMPLE_VIDEO_READONLY ) || defined(CFG_EXAMPLE_VIDEO_BUFFERLESS )
60+ /* EBU color bars: https://stackoverflow.com/questions/6939422 */
61+ static uint8_t const bar_color [8 ][4 ] = {
62+ /* Y, U, Y, V */
63+ { 235 , 128 , 235 , 128 }, /* 100% White */
64+ { 219 , 16 , 219 , 138 }, /* Yellow */
65+ { 188 , 154 , 188 , 16 }, /* Cyan */
66+ { 173 , 42 , 173 , 26 }, /* Green */
67+ { 78 , 214 , 78 , 230 }, /* Magenta */
68+ { 63 , 102 , 63 , 240 }, /* Red */
69+ { 32 , 240 , 32 , 118 }, /* Blue */
70+ { 16 , 128 , 16 , 128 }, /* Black */
71+ };
72+ #endif
5973
6074//--------------------------------------------------------------------+
6175// Main
@@ -111,12 +125,43 @@ void tud_resume_cb(void) {
111125 blink_interval_ms = tud_mounted () ? BLINK_MOUNTED : BLINK_NOT_MOUNTED ;
112126}
113127
128+ #ifdef CFG_EXAMPLE_VIDEO_BUFFERLESS
129+
130+ #ifndef CFG_EXAMPLE_VIDEO_DISABLE_MJPEG
131+ #error Demo only supports YUV2 please define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG
132+ #endif
133+
134+ void tud_video_prepare_payload_cb (uint_fast8_t ctl_idx , uint_fast8_t stm_idx , tud_video_payload_request_t * request )
135+ {
136+ static uint32_t frame_counter = 0 ;
137+ (void )ctl_idx ;
138+ (void )stm_idx ;
139+
140+ /* Offset will be zero at the start of a new frame */
141+ if (!request -> offset ) frame_counter ++ ;
142+
143+ for (size_t buf_pos = 0 ; buf_pos < request -> length ; buf_pos += 2 ) {
144+
145+ /* Position within the current line (pixel relative) */
146+ int line_pos = ((request -> offset + buf_pos )>>1 ) % FRAME_WIDTH ;
147+
148+ /* Choose color based on the position and change the table offset every 4 frames */
149+ const uint8_t * color = bar_color [(line_pos /(FRAME_WIDTH / 8 ) + (frame_counter >>2 )) % 8 ];
150+
151+ /* Copy pixel data for odd or even pixels */
152+ memcpy (& ((uint8_t * )request -> buf )[buf_pos ], & color [(line_pos & 1 ) ? 2 : 0 ], 2 );
153+ }
154+
155+ }
156+ #endif
157+
114158//--------------------------------------------------------------------+
115159// USB Video
116160//--------------------------------------------------------------------+
117161static unsigned frame_num = 0 ;
118162static unsigned tx_busy = 0 ;
119163static unsigned interval_ms = 1000 / FRAME_RATE ;
164+ #ifndef CFG_EXAMPLE_VIDEO_BUFFERLESS
120165
121166#ifdef CFG_EXAMPLE_VIDEO_READONLY
122167// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data.
@@ -145,18 +190,6 @@ static struct {
145190static uint8_t frame_buffer [FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 ];
146191
147192static void fill_color_bar (uint8_t * buffer , unsigned start_position ) {
148- /* EBU color bars: https://stackoverflow.com/questions/6939422 */
149- static uint8_t const bar_color [8 ][4 ] = {
150- /* Y, U, Y, V */
151- { 235 , 128 , 235 , 128 }, /* 100% White */
152- { 219 , 16 , 219 , 138 }, /* Yellow */
153- { 188 , 154 , 188 , 16 }, /* Cyan */
154- { 173 , 42 , 173 , 26 }, /* Green */
155- { 78 , 214 , 78 , 230 }, /* Magenta */
156- { 63 , 102 , 63 , 240 }, /* Red */
157- { 32 , 240 , 32 , 118 }, /* Blue */
158- { 16 , 128 , 16 , 128 }, /* Black */
159- };
160193 uint8_t * p ;
161194
162195 /* Generate the 1st line */
@@ -183,6 +216,8 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
183216
184217#endif
185218
219+ #endif /* NDEF CFG_EXAMPLE_VIDEO_BUFFERLESS */
220+
186221static void video_send_frame (void ) {
187222 static unsigned start_ms = 0 ;
188223 static unsigned already_sent = 0 ;
@@ -197,7 +232,9 @@ static void video_send_frame(void) {
197232 already_sent = 1 ;
198233 tx_busy = 1 ;
199234 start_ms = board_millis ();
200- #ifdef CFG_EXAMPLE_VIDEO_READONLY
235+ #if defined(CFG_EXAMPLE_VIDEO_BUFFERLESS )
236+ tud_video_n_frame_xfer (0 , 0 , NULL , FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
237+ #elif defined (CFG_EXAMPLE_VIDEO_READONLY )
201238 #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG )
202239 tud_video_n_frame_xfer (0 , 0 , (void * )(uintptr_t )& frame_buffer [(frame_num % (FRAME_WIDTH / 2 )) * 4 ],
203240 FRAME_WIDTH * FRAME_HEIGHT * 16 /8 );
@@ -220,7 +257,9 @@ static void video_send_frame(void) {
220257 start_ms += interval_ms ;
221258 tx_busy = 1 ;
222259
223- #ifdef CFG_EXAMPLE_VIDEO_READONLY
260+ #if defined(CFG_EXAMPLE_VIDEO_BUFFERLESS )
261+ tud_video_n_frame_xfer (0 , 0 , NULL , FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
262+ #elif defined(CFG_EXAMPLE_VIDEO_READONLY )
224263 #if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG )
225264 tud_video_n_frame_xfer (0 , 0 , (void * )(uintptr_t )& frame_buffer [(frame_num % (FRAME_WIDTH / 2 )) * 4 ],
226265 FRAME_WIDTH * FRAME_HEIGHT * 16 /8 );
0 commit comments