Conversation
|
Too many files changed for review. ( |
| #[cfg(target_os = "windows")] | ||
| struct WindowsTimerResolution; | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| impl WindowsTimerResolution { | ||
| fn set_high_precision() -> Self { | ||
| unsafe { | ||
| windows::Win32::Media::timeBeginPeriod(1); | ||
| } | ||
| Self | ||
| } | ||
| } | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| impl Drop for WindowsTimerResolution { | ||
| fn drop(&mut self) { | ||
| unsafe { | ||
| windows::Win32::Media::timeEndPeriod(1); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
timeBeginPeriod/timeEndPeriod can fail, and timeEndPeriod should ideally only run if timeBeginPeriod succeeded. Tracking that state avoids making the global timer resolution worse if begin fails.
| #[cfg(target_os = "windows")] | |
| struct WindowsTimerResolution; | |
| #[cfg(target_os = "windows")] | |
| impl WindowsTimerResolution { | |
| fn set_high_precision() -> Self { | |
| unsafe { | |
| windows::Win32::Media::timeBeginPeriod(1); | |
| } | |
| Self | |
| } | |
| } | |
| #[cfg(target_os = "windows")] | |
| impl Drop for WindowsTimerResolution { | |
| fn drop(&mut self) { | |
| unsafe { | |
| windows::Win32::Media::timeEndPeriod(1); | |
| } | |
| } | |
| } | |
| #[cfg(target_os = "windows")] | |
| struct WindowsTimerResolution { | |
| enabled: bool, | |
| } | |
| #[cfg(target_os = "windows")] | |
| impl WindowsTimerResolution { | |
| fn set_high_precision() -> Self { | |
| let enabled = unsafe { windows::Win32::Media::timeBeginPeriod(1) } == 0; | |
| Self { enabled } | |
| } | |
| } | |
| #[cfg(target_os = "windows")] | |
| impl Drop for WindowsTimerResolution { | |
| fn drop(&mut self) { | |
| if self.enabled { | |
| let _ = unsafe { windows::Win32::Media::timeEndPeriod(1) }; | |
| } | |
| } | |
| } |
| if width == 0 || height == 0 { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
NV12 is 4:2:0, so odd dimensions tend to produce subtle indexing issues (especially on the UV plane). Even if the stride is aligned, it’s safer to reject odd sizes here.
| if width == 0 || height == 0 { | |
| return false; | |
| } | |
| if width == 0 || height == 0 || !width.is_multiple_of(2) || !height.is_multiple_of(2) { | |
| return false; | |
| } |
| let _ = self.tx.try_send(RendererMessage::RenderFrame { | ||
| segment_frames, | ||
| uniforms, | ||
| finished: finished_tx, | ||
| cursor, | ||
| }) | ||
| .await; | ||
| }); |
There was a problem hiding this comment.
try_send dropping render requests is fine for perf, but swallowing Closed makes failures silent and hard to debug.
| let _ = self.tx.try_send(RendererMessage::RenderFrame { | |
| segment_frames, | |
| uniforms, | |
| finished: finished_tx, | |
| cursor, | |
| }) | |
| .await; | |
| }); | |
| match self.tx.try_send(RendererMessage::RenderFrame { | |
| segment_frames, | |
| uniforms, | |
| finished: finished_tx, | |
| cursor, | |
| }) { | |
| Ok(()) => {} | |
| Err(mpsc::error::TrySendError::Full(_)) => {} | |
| Err(mpsc::error::TrySendError::Closed(_)) => { | |
| tracing::warn!("Failed to send render request to renderer (channel closed)"); | |
| } | |
| } |
| cache.clear(); | ||
| last_decoded_frame = None; | ||
| } | ||
| pending_requests.sort_by_key(|r| r.frame); |
There was a problem hiding this comment.
Minor perf nit: sort_by_key is stable and a bit heavier than needed here. sort_unstable_by_key should be fine since you only need ordering by frame.
| pending_requests.sort_by_key(|r| r.frame); | |
| pending_requests.sort_unstable_by_key(|r| r.frame); |
| let cached = CachedFrame { | ||
| number: frame_number, | ||
| _texture: mf_frame.textures.nv12.texture.clone(), | ||
| _shared_handle: Some(mf_frame.textures.nv12.handle), |
There was a problem hiding this comment.
Nit: if mf_frame.textures.nv12.handle can ever be NULL, storing it as Some(NULL) makes it easy to accidentally treat as valid later.
| _shared_handle: Some(mf_frame.textures.nv12.handle), | |
| _shared_handle: Some(mf_frame.textures.nv12.handle) | |
| .filter(|h| h.0 != std::ptr::null_mut()), |
Introduces several important changes to video frame handling, GPU diagnostics, and platform support, primarily focusing on improving NV12 frame processing and enhancing system diagnostics structures. The updates ensure consistent handling of strides in NV12 frame data across Rust and TypeScript code, expand GPU/system diagnostics for Windows, and introduce new dependencies and platform-specific improvements.