@@ -17,6 +17,16 @@ use core_video_sys::{
17
17
CVPixelBufferLockBaseAddress , CVPixelBufferRef , CVPixelBufferUnlockBaseAddress ,
18
18
} ;
19
19
20
+ // Returns a frame's presentation timestamp in nanoseconds since an arbitrary start time.
21
+ // This is typically yielded from a monotonic clock started on system boot.
22
+ pub fn get_pts_in_nanoseconds ( sample_buffer : & CMSampleBuffer ) -> u64 {
23
+ let pts = sample_buffer. sys_ref . get_presentation_timestamp ( ) ;
24
+
25
+ let seconds = unsafe { CMTimeGetSeconds ( pts) } ;
26
+
27
+ ( seconds * 1_000_000_000. ) . trunc ( ) as u64
28
+ }
29
+
20
30
pub unsafe fn create_yuv_frame ( sample_buffer : CMSampleBuffer ) -> Option < YUVFrame > {
21
31
// Check that the frame status is complete
22
32
let buffer_ref = & ( * sample_buffer. sys_ref ) ;
@@ -47,8 +57,7 @@ pub unsafe fn create_yuv_frame(sample_buffer: CMSampleBuffer) -> Option<YUVFrame
47
57
}
48
58
}
49
59
50
- //let epoch = CMSampleBufferGetPresentationTimeStamp(buffer_ref).epoch;
51
- let epoch = sample_buffer. sys_ref . get_presentation_timestamp ( ) . value ;
60
+ let display_time = get_pts_in_nanoseconds ( & sample_buffer) ;
52
61
let pixel_buffer = CMSampleBufferGetImageBuffer ( buffer_ref) as CVPixelBufferRef ;
53
62
54
63
CVPixelBufferLockBaseAddress ( pixel_buffer, 0 ) ;
@@ -78,7 +87,7 @@ pub unsafe fn create_yuv_frame(sample_buffer: CMSampleBuffer) -> Option<YUVFrame
78
87
CVPixelBufferUnlockBaseAddress ( pixel_buffer, 0 ) ;
79
88
80
89
YUVFrame {
81
- display_time : epoch as u64 ,
90
+ display_time,
82
91
width : width as i32 ,
83
92
height : height as i32 ,
84
93
luminance_bytes,
@@ -90,8 +99,8 @@ pub unsafe fn create_yuv_frame(sample_buffer: CMSampleBuffer) -> Option<YUVFrame
90
99
}
91
100
92
101
pub unsafe fn create_bgr_frame ( sample_buffer : CMSampleBuffer ) -> Option < BGRFrame > {
102
+ let display_time = get_pts_in_nanoseconds ( & sample_buffer) ;
93
103
let buffer_ref = & ( * sample_buffer. sys_ref ) ;
94
- let epoch = sample_buffer. sys_ref . get_presentation_timestamp ( ) . value ;
95
104
let pixel_buffer = CMSampleBufferGetImageBuffer ( buffer_ref) as CVPixelBufferRef ;
96
105
97
106
CVPixelBufferLockBaseAddress ( pixel_buffer, 0 ) ;
@@ -117,16 +126,16 @@ pub unsafe fn create_bgr_frame(sample_buffer: CMSampleBuffer) -> Option<BGRFrame
117
126
CVPixelBufferUnlockBaseAddress ( pixel_buffer, 0 ) ;
118
127
119
128
Some ( BGRFrame {
120
- display_time : epoch as u64 ,
129
+ display_time,
121
130
width : width as i32 , // width does not give accurate results - https://stackoverflow.com/questions/19587185/cvpixelbuffergetbytesperrow-for-cvimagebufferref-returns-unexpected-wrong-valu
122
131
height : height as i32 ,
123
132
data : remove_alpha_channel ( cropped_data) ,
124
133
} )
125
134
}
126
135
127
136
pub unsafe fn create_bgra_frame ( sample_buffer : CMSampleBuffer ) -> Option < BGRAFrame > {
137
+ let display_time = get_pts_in_nanoseconds ( & sample_buffer) ;
128
138
let buffer_ref = & ( * sample_buffer. sys_ref ) ;
129
- let epoch = sample_buffer. sys_ref . get_presentation_timestamp ( ) . value ;
130
139
let pixel_buffer = CMSampleBufferGetImageBuffer ( buffer_ref) as CVPixelBufferRef ;
131
140
132
141
CVPixelBufferLockBaseAddress ( pixel_buffer, 0 ) ;
@@ -149,16 +158,16 @@ pub unsafe fn create_bgra_frame(sample_buffer: CMSampleBuffer) -> Option<BGRAFra
149
158
CVPixelBufferUnlockBaseAddress ( pixel_buffer, 0 ) ;
150
159
151
160
Some ( BGRAFrame {
152
- display_time : epoch as u64 ,
161
+ display_time,
153
162
width : width as i32 , // width does not give accurate results - https://stackoverflow.com/questions/19587185/cvpixelbuffergetbytesperrow-for-cvimagebufferref-returns-unexpected-wrong-valu
154
163
height : height as i32 ,
155
164
data,
156
165
} )
157
166
}
158
167
159
168
pub unsafe fn create_rgb_frame ( sample_buffer : CMSampleBuffer ) -> Option < RGBFrame > {
169
+ let display_time = get_pts_in_nanoseconds ( & sample_buffer) ;
160
170
let buffer_ref = & ( * sample_buffer. sys_ref ) ;
161
- let epoch = sample_buffer. sys_ref . get_presentation_timestamp ( ) . value ;
162
171
let pixel_buffer = CMSampleBufferGetImageBuffer ( buffer_ref) as CVPixelBufferRef ;
163
172
164
173
CVPixelBufferLockBaseAddress ( pixel_buffer, 0 ) ;
@@ -184,7 +193,7 @@ pub unsafe fn create_rgb_frame(sample_buffer: CMSampleBuffer) -> Option<RGBFrame
184
193
CVPixelBufferUnlockBaseAddress ( pixel_buffer, 0 ) ;
185
194
186
195
Some ( RGBFrame {
187
- display_time : epoch as u64 ,
196
+ display_time,
188
197
width : width as i32 , // width does not give accurate results - https://stackoverflow.com/questions/19587185/cvpixelbuffergetbytesperrow-for-cvimagebufferref-returns-unexpected-wrong-valu
189
198
height : height as i32 ,
190
199
data : convert_bgra_to_rgb ( cropped_data) ,
0 commit comments