12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
- use crate :: video_frame:: { VideoBuffer , VideoFrame } ;
15
+ use crate :: video_frame:: { I420Buffer , VideoBuffer , VideoFrame } ;
16
16
use crate :: video_source:: VideoResolution ;
17
17
use cxx:: SharedPtr ;
18
- use std:: sync:: {
19
- atomic:: { AtomicUsize , Ordering } ,
20
- Arc ,
21
- } ;
22
- use std:: time:: { SystemTime , UNIX_EPOCH } ;
18
+ use parking_lot:: Mutex ;
19
+ use std:: sync:: Arc ;
20
+ use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
23
21
use webrtc_sys:: video_frame as vf_sys;
22
+ use webrtc_sys:: video_frame:: ffi:: VideoRotation ;
24
23
use webrtc_sys:: video_track as vt_sys;
25
24
26
25
impl From < vt_sys:: ffi:: VideoResolution > for VideoResolution {
@@ -44,29 +43,64 @@ impl From<VideoResolution> for vt_sys::ffi::VideoResolution {
44
43
#[ derive( Clone ) ]
45
44
pub struct NativeVideoSource {
46
45
sys_handle : SharedPtr < vt_sys:: ffi:: VideoTrackSource > ,
47
- captured_frames : Arc < AtomicUsize > ,
46
+ inner : Arc < Mutex < VideoSourceInner > > ,
47
+ }
48
+
49
+ struct VideoSourceInner {
50
+ captured_frames : usize ,
48
51
}
49
52
50
53
impl NativeVideoSource {
51
54
pub fn new ( resolution : VideoResolution ) -> NativeVideoSource {
52
- Self {
55
+ let source = Self {
53
56
sys_handle : vt_sys:: ffi:: new_video_track_source ( & vt_sys:: ffi:: VideoResolution :: from (
54
- resolution,
57
+ resolution. clone ( ) ,
55
58
) ) ,
56
- captured_frames : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
57
- }
59
+ inner : Arc :: new ( Mutex :: new ( VideoSourceInner { captured_frames : 0 } ) ) ,
60
+ } ;
61
+
62
+ tokio:: spawn ( {
63
+ let source = source. clone ( ) ;
64
+ let i420 = I420Buffer :: new ( resolution. width , resolution. height ) ;
65
+ async move {
66
+ let mut interval = tokio:: time:: interval ( Duration :: from_millis ( 100 ) ) ; // 10 fps
67
+
68
+ loop {
69
+ interval. tick ( ) . await ;
70
+
71
+ let inner = source. inner . lock ( ) ;
72
+ if inner. captured_frames > 0 {
73
+ break ;
74
+ }
75
+
76
+ let mut builder = vf_sys:: ffi:: new_video_frame_builder ( ) ;
77
+ builder
78
+ . pin_mut ( )
79
+ . set_rotation ( VideoRotation :: VideoRotation0 ) ;
80
+ builder
81
+ . pin_mut ( )
82
+ . set_video_frame_buffer ( i420. as_ref ( ) . sys_handle ( ) ) ;
83
+
84
+ let now = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
85
+ builder. pin_mut ( ) . set_timestamp_us ( now. as_micros ( ) as i64 ) ;
86
+
87
+ source
88
+ . sys_handle
89
+ . on_captured_frame ( & builder. pin_mut ( ) . build ( ) ) ;
90
+ }
91
+ }
92
+ } ) ;
93
+
94
+ source
58
95
}
59
96
60
97
pub fn sys_handle ( & self ) -> SharedPtr < vt_sys:: ffi:: VideoTrackSource > {
61
98
self . sys_handle . clone ( )
62
99
}
63
100
64
- pub fn captured_frames ( & self ) -> usize {
65
- self . captured_frames . load ( Ordering :: Relaxed )
66
- }
67
-
68
101
pub fn capture_frame < T : AsRef < dyn VideoBuffer > > ( & self , frame : & VideoFrame < T > ) {
69
- self . captured_frames . fetch_add ( 1 , Ordering :: Relaxed ) ;
102
+ let mut inner = self . inner . lock ( ) ;
103
+ inner. captured_frames += 1 ;
70
104
71
105
let mut builder = vf_sys:: ffi:: new_video_frame_builder ( ) ;
72
106
builder. pin_mut ( ) . set_rotation ( frame. rotation . into ( ) ) ;
0 commit comments