(&self, frame: &ffi::xcw_native_frame)
| 479 | } |
| 480 | |
| 481 | fn handle_frame(&self, frame: &ffi::xcw_native_frame) { |
| 482 | let description = unsafe { copy_ffi_bytes(frame.description) }; |
| 483 | let Some(data) = (unsafe { copy_ffi_bytes(frame.data) }) else { |
| 484 | return; |
| 485 | }; |
| 486 | let packet = Arc::new(FramePacket { |
| 487 | frame_sequence: frame.frame_sequence, |
| 488 | timestamp_us: frame.timestamp_us, |
| 489 | is_keyframe: frame.is_keyframe, |
| 490 | width: frame.width, |
| 491 | height: frame.height, |
| 492 | codec: c_string(frame.codec), |
| 493 | description, |
| 494 | data, |
| 495 | }); |
| 496 | |
| 497 | self.metrics.frames_encoded.fetch_add(1, Ordering::Relaxed); |
| 498 | if packet.is_keyframe { |
| 499 | self.metrics |
| 500 | .keyframes_encoded |
| 501 | .fetch_add(1, Ordering::Relaxed); |
| 502 | *self.latest_keyframe.write().unwrap() = Some(packet.clone()); |
| 503 | } |
| 504 | |
| 505 | self.display_ready.store(true, Ordering::Relaxed); |
| 506 | self.display_width |
| 507 | .store(packet.width as u64, Ordering::Relaxed); |
| 508 | self.display_height |
| 509 | .store(packet.height as u64, Ordering::Relaxed); |
| 510 | self.frame_sequence |
| 511 | .store(packet.frame_sequence, Ordering::Relaxed); |
| 512 | self.last_frame_ms.store(now_ms(), Ordering::Relaxed); |
| 513 | debug!( |
| 514 | udid = %self.udid, |
| 515 | sequence = packet.frame_sequence, |
| 516 | keyframe = packet.is_keyframe, |
| 517 | "native frame received" |
| 518 | ); |
| 519 | let _ = self.sender.send(packet); |
| 520 | if matches!(*self.state.lock().unwrap(), SessionState::Attaching) { |
| 521 | *self.state.lock().unwrap() = SessionState::Ready; |
| 522 | self.start_condvar.notify_all(); |
| 523 | } |
| 524 | } |
| 525 | } |
| 526 | |
| 527 | unsafe fn copy_ffi_bytes(bytes: ffi::xcw_native_shared_bytes) -> Option<Bytes> { |
no test coverage detected