@@ -18,7 +18,14 @@ struct usbd_video_priv {
18
18
uint8_t power_mode ;
19
19
uint8_t error_code ;
20
20
struct video_entity_info info [3 ];
21
- uint8_t * ep_buffer ;
21
+ uint8_t * ep_buf0 ;
22
+ uint8_t * ep_buf1 ;
23
+ bool ep_buf0_ready ;
24
+ bool ep_buf1_ready ;
25
+ uint32_t ep_buf0_len ;
26
+ uint32_t ep_buf1_len ;
27
+ uint8_t ep_buf_idx ;
28
+ bool stream_finish ;
22
29
uint32_t max_packets ;
23
30
uint8_t * stream_buf ;
24
31
uint32_t stream_len ;
@@ -749,6 +756,40 @@ static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dw
749
756
g_usbd_video [busid ].stream_headerlen = 2 ;
750
757
}
751
758
759
+ static uint32_t usbd_video_prepare_ep_buf_data (uint8_t busid , uint32_t remain , uint8_t * ep_buf )
760
+ {
761
+ struct video_payload_header * header ;
762
+ uint32_t len ;
763
+ uint32_t offset ;
764
+
765
+ len = MIN (remain , (g_usbd_video [busid ].probe .dwMaxPayloadTransferSize - g_usbd_video [busid ].stream_headerlen ) * g_usbd_video [busid ].max_packets );
766
+ offset = 0 ;
767
+ while (len > 0 ) {
768
+ header = (struct video_payload_header * )& ep_buf [offset ];
769
+ header -> bHeaderLength = g_usbd_video [busid ].stream_headerlen ;
770
+ header -> headerInfoUnion .bmheaderInfo = 0 ;
771
+ header -> headerInfoUnion .headerInfoBits .endOfHeader = 1 ;
772
+ header -> headerInfoUnion .headerInfoBits .endOfFrame = 0 ;
773
+ header -> headerInfoUnion .headerInfoBits .frameIdentifier = g_usbd_video [busid ].stream_frameid ;
774
+
775
+ uint32_t len2 = MIN (len , g_usbd_video [busid ].probe .dwMaxPayloadTransferSize - g_usbd_video [busid ].stream_headerlen );
776
+
777
+ usb_memcpy (& ep_buf [offset + g_usbd_video [busid ].stream_headerlen ],
778
+ & g_usbd_video [busid ].stream_buf [g_usbd_video [busid ].stream_offset ],
779
+ len2 );
780
+
781
+ g_usbd_video [busid ].stream_offset += len2 ;
782
+ len -= len2 ;
783
+ offset += (len2 + g_usbd_video [busid ].stream_headerlen );
784
+
785
+ if (g_usbd_video [busid ].stream_offset == g_usbd_video [busid ].stream_len ) {
786
+ header -> headerInfoUnion .headerInfoBits .endOfFrame = 1 ;
787
+ }
788
+ }
789
+
790
+ return offset ;
791
+ }
792
+
752
793
struct usbd_interface * usbd_video_init_intf (uint8_t busid ,
753
794
struct usbd_interface * intf ,
754
795
uint32_t dwFrameInterval ,
@@ -776,60 +817,68 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid,
776
817
777
818
bool usbd_video_stream_split_transfer (uint8_t busid , uint8_t ep )
778
819
{
779
- struct video_payload_header * header ;
780
820
uint32_t remain ;
781
- uint32_t len ;
782
- uint32_t offset ;
783
821
784
- remain = g_usbd_video [busid ].stream_len - g_usbd_video [busid ].stream_offset ;
785
-
786
- if (remain == 0 ) {
787
- g_usbd_video [busid ].stream_frameid ^= 1 ;
788
- return true;
822
+ if (g_usbd_video [busid ].ep_buf1_ready && (g_usbd_video [busid ].ep_buf_idx == 0 )) { /* callback: buf1 ready and buf0 was sent */
823
+ g_usbd_video [busid ].ep_buf0_ready = false;
824
+ g_usbd_video [busid ].ep_buf_idx = 1 ;
825
+ usbd_ep_start_write (busid , ep , g_usbd_video [busid ].ep_buf1 , g_usbd_video [busid ].ep_buf1_len );
826
+ } else if (g_usbd_video [busid ].ep_buf0_ready && (g_usbd_video [busid ].ep_buf_idx == 1 )) { /* callback: buf0 ready and buf1 was sent */
827
+ g_usbd_video [busid ].ep_buf1_ready = false;
828
+ g_usbd_video [busid ].ep_buf_idx = 0 ;
829
+ usbd_ep_start_write (busid , ep , g_usbd_video [busid ].ep_buf0 , g_usbd_video [busid ].ep_buf0_len );
830
+ } else {
831
+ if (g_usbd_video [busid ].stream_finish ) {
832
+ return true;
833
+ }
789
834
}
790
835
791
- len = MIN (remain , (g_usbd_video [busid ].probe .dwMaxPayloadTransferSize - g_usbd_video [busid ].stream_headerlen ) * g_usbd_video [busid ].max_packets );
792
-
793
- offset = 0 ;
794
- while (len > 0 ) {
795
- header = (struct video_payload_header * )& g_usbd_video [busid ].ep_buffer [offset ];
796
- header -> bHeaderLength = g_usbd_video [busid ].stream_headerlen ;
797
- header -> headerInfoUnion .bmheaderInfo = 0 ;
798
- header -> headerInfoUnion .headerInfoBits .endOfHeader = 1 ;
799
- header -> headerInfoUnion .headerInfoBits .endOfFrame = 0 ;
800
- header -> headerInfoUnion .headerInfoBits .frameIdentifier = g_usbd_video [busid ].stream_frameid ;
801
-
802
- uint32_t len2 = MIN (len , g_usbd_video [busid ].probe .dwMaxPayloadTransferSize - g_usbd_video [busid ].stream_headerlen );
803
-
804
- usb_memcpy (& g_usbd_video [busid ].ep_buffer [offset + g_usbd_video [busid ].stream_headerlen ],
805
- & g_usbd_video [busid ].stream_buf [g_usbd_video [busid ].stream_offset ],
806
- len2 );
807
-
808
- g_usbd_video [busid ].stream_offset += len2 ;
809
- len -= len2 ;
810
- offset += (len2 + g_usbd_video [busid ].stream_headerlen );
836
+ if (!g_usbd_video [busid ].ep_buf0_ready ) {
837
+ remain = g_usbd_video [busid ].stream_len - g_usbd_video [busid ].stream_offset ;
838
+ if (remain == 0 ) {
839
+ g_usbd_video [busid ].stream_frameid ^= 1 ;
840
+ g_usbd_video [busid ].stream_finish = true;
841
+ } else {
842
+ g_usbd_video [busid ].ep_buf0_len = usbd_video_prepare_ep_buf_data (busid , remain , g_usbd_video [busid ].ep_buf0 );
843
+ g_usbd_video [busid ].ep_buf0_ready = true;
844
+ if (!g_usbd_video [busid ].ep_buf1_ready ) {
845
+ g_usbd_video [busid ].ep_buf_idx = 0 ;
846
+ usbd_ep_start_write (busid , ep , g_usbd_video [busid ].ep_buf0 , g_usbd_video [busid ].ep_buf0_len );
847
+ }
848
+ }
849
+ }
811
850
812
- if (g_usbd_video [busid ].stream_offset == g_usbd_video [busid ].stream_len ) {
813
- header -> headerInfoUnion .headerInfoBits .endOfFrame = 1 ;
851
+ if (!g_usbd_video [busid ].ep_buf1_ready ) {
852
+ remain = g_usbd_video [busid ].stream_len - g_usbd_video [busid ].stream_offset ;
853
+ if (remain == 0 ) {
854
+ g_usbd_video [busid ].stream_frameid ^= 1 ;
855
+ g_usbd_video [busid ].stream_finish = true;
856
+ } else {
857
+ g_usbd_video [busid ].ep_buf1_len = usbd_video_prepare_ep_buf_data (busid , remain , g_usbd_video [busid ].ep_buf1 );
858
+ g_usbd_video [busid ].ep_buf1_ready = true;
814
859
}
815
860
}
816
861
817
- usbd_ep_start_write (busid , ep , g_usbd_video [busid ].ep_buffer , offset );
818
862
return false;
819
863
}
820
864
821
- int usbd_video_stream_start_write (uint8_t busid , uint8_t ep , uint8_t * ep_buffer , uint32_t ep_bufsize , uint8_t * stream_buf , uint32_t stream_len )
865
+ int usbd_video_stream_start_write (uint8_t busid , uint8_t ep , uint8_t * ep_buf0 , uint8_t * ep_buf1 , uint32_t ep_bufsize , uint8_t * stream_buf , uint32_t stream_len )
822
866
{
823
- if (usb_device_is_configured (busid ) == 0 ) {
867
+ if (( usb_device_is_configured (busid ) == 0 ) || ( stream_len == 0 ) ) {
824
868
return -1 ;
825
869
}
826
870
827
- g_usbd_video [busid ].ep_buffer = ep_buffer ;
871
+ g_usbd_video [busid ].ep_buf0 = ep_buf0 ;
872
+ g_usbd_video [busid ].ep_buf1 = ep_buf1 ;
873
+ g_usbd_video [busid ].ep_buf0_ready = false;
874
+ g_usbd_video [busid ].ep_buf1_ready = false;
875
+ g_usbd_video [busid ].ep_buf_idx = 0 ;
876
+ g_usbd_video [busid ].stream_finish = false;
828
877
g_usbd_video [busid ].max_packets = ep_bufsize / g_usbd_video [busid ].probe .dwMaxPayloadTransferSize ;
829
878
g_usbd_video [busid ].stream_buf = stream_buf ;
830
879
g_usbd_video [busid ].stream_len = stream_len ;
831
880
g_usbd_video [busid ].stream_offset = 0 ;
832
881
833
882
usbd_video_stream_split_transfer (busid , ep );
834
883
return 0 ;
835
- }
884
+ }
0 commit comments