mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-20 03:01:52 +08:00
[fix] align MiniRtc media interfaces and timestamps
This commit is contained in:
@@ -75,7 +75,7 @@ int SessionDeviceManager::InitializeScreenCapturer() {
|
|||||||
const int init_ret = screen_capturer_->Init(
|
const int init_ret = screen_capturer_->Init(
|
||||||
fps, [this, fps](unsigned char *data, int size, int width, int height,
|
fps, [this, fps](unsigned char *data, int size, int width, int height,
|
||||||
const char *display_name,
|
const char *display_name,
|
||||||
const XNativeVideoFrame *native_frame) {
|
const MiniRtcNativeVideoFrame *native_frame) {
|
||||||
const auto now_time = std::chrono::steady_clock::now();
|
const auto now_time = std::chrono::steady_clock::now();
|
||||||
if (!ShouldSendCapturedFrame(now_time, fps)) {
|
if (!ShouldSendCapturedFrame(now_time, fps)) {
|
||||||
return;
|
return;
|
||||||
@@ -137,7 +137,7 @@ int SessionDeviceManager::InitializeScreenCapturer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XVideoFrame frame{};
|
MiniRtcVideoFrame frame{};
|
||||||
frame.data = reinterpret_cast<const char *>(data);
|
frame.data = reinterpret_cast<const char *>(data);
|
||||||
frame.size = size;
|
frame.size = size;
|
||||||
frame.width = width;
|
frame.width = width;
|
||||||
@@ -206,8 +206,11 @@ int SessionDeviceManager::StartSpeakerCapturer() {
|
|||||||
static_cast<SpeakerCapturer *>(speaker_capturer_factory_->Create());
|
static_cast<SpeakerCapturer *>(speaker_capturer_factory_->Create());
|
||||||
const int init_ret = speaker_capturer_->Init(
|
const int init_ret = speaker_capturer_->Init(
|
||||||
[this](unsigned char *data, size_t size, const char *audio_name) {
|
[this](unsigned char *data, size_t size, const char *audio_name) {
|
||||||
SendAudioFrame(owner_.peer_, reinterpret_cast<const char *>(data),
|
MiniRtcAudioFrame frame{};
|
||||||
size, owner_.audio_label_.c_str());
|
frame.data = reinterpret_cast<const char *>(data);
|
||||||
|
frame.size = size;
|
||||||
|
frame.captured_timestamp = GetSystemTimeMicros(owner_.peer_);
|
||||||
|
SendAudioFrame(owner_.peer_, &frame, owner_.audio_label_.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (init_ret != 0) {
|
if (init_ret != 0) {
|
||||||
|
|||||||
@@ -269,11 +269,22 @@ void GuiRuntime::SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) {
|
|||||||
|
|
||||||
if (1) {
|
if (1) {
|
||||||
std::shared_lock lock(runtime->remote_sessions_mutex_);
|
std::shared_lock lock(runtime->remote_sessions_mutex_);
|
||||||
|
uint64_t captured_timestamp = 0;
|
||||||
for (const auto &it : runtime->remote_sessions_) {
|
for (const auto &it : runtime->remote_sessions_) {
|
||||||
auto props = it.second;
|
auto props = it.second;
|
||||||
if (props->connection_status_.load() == ConnectionStatus::Connected) {
|
if (props->connection_status_.load() == ConnectionStatus::Connected) {
|
||||||
if (props->peer_) {
|
if (props->peer_) {
|
||||||
SendAudioFrame(props->peer_, (const char *)stream, len,
|
if (captured_timestamp == 0) {
|
||||||
|
const int64_t timestamp_us = GetSystemTimeMicros(props->peer_);
|
||||||
|
if (timestamp_us > 0) {
|
||||||
|
captured_timestamp = static_cast<uint64_t>(timestamp_us);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MiniRtcAudioFrame frame{};
|
||||||
|
frame.data = reinterpret_cast<const char *>(stream);
|
||||||
|
frame.size = static_cast<size_t>(len);
|
||||||
|
frame.captured_timestamp = captured_timestamp;
|
||||||
|
SendAudioFrame(props->peer_, &frame,
|
||||||
runtime->audio_label_.c_str());
|
runtime->audio_label_.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,29 +301,6 @@ void GuiRuntime::SdlCaptureAudioIn(void *userdata, Uint8 *stream, int len) {
|
|||||||
void GuiRuntime::SdlCaptureAudioOut([[maybe_unused]] void *userdata,
|
void GuiRuntime::SdlCaptureAudioOut([[maybe_unused]] void *userdata,
|
||||||
[[maybe_unused]] Uint8 *stream,
|
[[maybe_unused]] Uint8 *stream,
|
||||||
[[maybe_unused]] int len) {
|
[[maybe_unused]] int len) {
|
||||||
// GuiApplication *runtime = (GuiApplication *)userdata;
|
|
||||||
// for (auto it : runtime->remote_sessions_) {
|
|
||||||
// auto props = it.second;
|
|
||||||
// if (props->connection_status_ == SignalStatus::SignalConnected) {
|
|
||||||
// SendAudioFrame(props->peer_, (const char *)stream, len);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!runtime->audio_buffer_fresh_) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// SDL_memset(stream, 0, len);
|
|
||||||
|
|
||||||
// if (runtime->audio_len_ == 0) {
|
|
||||||
// return;
|
|
||||||
// } else {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// len = (len > runtime->audio_len_ ? runtime->audio_len_ : len);
|
|
||||||
// SDL_MixAudioFormat(stream, runtime->audio_buffer_, AUDIO_S16LSB, len,
|
|
||||||
// SDL_MIX_MAXVOLUME);
|
|
||||||
// runtime->audio_buffer_fresh_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace crossdesk
|
} // namespace crossdesk
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ void PeerEventHandler::OnConnectionStatus(ConnectionStatus status,
|
|||||||
|
|
||||||
void PeerEventHandler::OnNetStatusReport(
|
void PeerEventHandler::OnNetStatusReport(
|
||||||
const char* client_id, size_t client_id_size, TraversalMode mode,
|
const char* client_id, size_t client_id_size, TraversalMode mode,
|
||||||
const XNetTrafficStats* net_traffic_stats, const char* user_id,
|
const MiniRtcNetTrafficStats* net_traffic_stats, const char* user_id,
|
||||||
const size_t user_id_size, void* user_data) {
|
const size_t user_id_size, void* user_data) {
|
||||||
auto* handler = static_cast<PeerEventHandler*>(user_data);
|
auto* handler = static_cast<PeerEventHandler*>(user_data);
|
||||||
GuiRuntime* runtime = handler ? &handler->owner_ : nullptr;
|
GuiRuntime* runtime = handler ? &handler->owner_ : nullptr;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class PeerEventHandler {
|
|||||||
public:
|
public:
|
||||||
explicit PeerEventHandler(GuiRuntime &owner);
|
explicit PeerEventHandler(GuiRuntime &owner);
|
||||||
|
|
||||||
static void OnReceiveVideoBuffer(const XVideoFrame *video_frame,
|
static void OnReceiveVideoBuffer(const MiniRtcVideoFrame *video_frame,
|
||||||
const char *user_id, size_t user_id_size,
|
const char *user_id, size_t user_id_size,
|
||||||
const char *src_id, size_t src_id_size,
|
const char *src_id, size_t src_id_size,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
size_t user_id_size, void *user_data);
|
size_t user_id_size, void *user_data);
|
||||||
static void OnNetStatusReport(const char *client_id, size_t client_id_size,
|
static void OnNetStatusReport(const char *client_id, size_t client_id_size,
|
||||||
TraversalMode mode,
|
TraversalMode mode,
|
||||||
const XNetTrafficStats *net_traffic_stats,
|
const MiniRtcNetTrafficStats *net_traffic_stats,
|
||||||
const char *user_id, size_t user_id_size,
|
const char *user_id, size_t user_id_size,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ namespace {
|
|||||||
|
|
||||||
constexpr auto kBackgroundSnapshotInterval = std::chrono::seconds(1);
|
constexpr auto kBackgroundSnapshotInterval = std::chrono::seconds(1);
|
||||||
|
|
||||||
const XNativeVideoFrame* GetNativeVideoFrame(const XVideoFrame* frame) {
|
const MiniRtcNativeVideoFrame* GetNativeVideoFrame(const MiniRtcVideoFrame* frame) {
|
||||||
if (!frame || !frame->native_frame) {
|
if (!frame || !frame->native_frame) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const auto* native = frame->native_frame;
|
const auto* native = frame->native_frame;
|
||||||
return native->struct_size >=
|
return native->struct_size >=
|
||||||
static_cast<uint32_t>(sizeof(XNativeVideoFrame)) &&
|
static_cast<uint32_t>(sizeof(MiniRtcNativeVideoFrame)) &&
|
||||||
native->owner && native->copy_to_nv12
|
native->owner && native->copy_to_nv12
|
||||||
? native
|
? native
|
||||||
: nullptr;
|
: nullptr;
|
||||||
@@ -29,7 +29,7 @@ const XNativeVideoFrame* GetNativeVideoFrame(const XVideoFrame* frame) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void PeerEventHandler::OnReceiveVideoBuffer(
|
void PeerEventHandler::OnReceiveVideoBuffer(
|
||||||
const XVideoFrame* video_frame, const char* user_id, size_t user_id_size,
|
const MiniRtcVideoFrame* video_frame, const char* user_id, size_t user_id_size,
|
||||||
const char* src_id, size_t src_id_size, void* user_data) {
|
const char* src_id, size_t src_id_size, void* user_data) {
|
||||||
auto* handler = static_cast<PeerEventHandler*>(user_data);
|
auto* handler = static_cast<PeerEventHandler*>(user_data);
|
||||||
GuiRuntime* runtime = handler ? &handler->owner_ : nullptr;
|
GuiRuntime* runtime = handler ? &handler->owner_ : nullptr;
|
||||||
@@ -109,7 +109,7 @@ void PeerEventHandler::OnReceiveVideoBuffer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t frame_size = video_frame->size;
|
size_t frame_size = video_frame->size;
|
||||||
const XNativeVideoFrame* native_frame =
|
const MiniRtcNativeVideoFrame* native_frame =
|
||||||
GetNativeVideoFrame(video_frame);
|
GetNativeVideoFrame(video_frame);
|
||||||
if (native_frame) {
|
if (native_frame) {
|
||||||
frame_size = static_cast<size_t>(native_frame->width) *
|
frame_size = static_cast<size_t>(native_frame->width) *
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ struct RemoteSession {
|
|||||||
int fps_ = 0;
|
int fps_ = 0;
|
||||||
int frame_count_ = 0;
|
int frame_count_ = 0;
|
||||||
std::chrono::steady_clock::time_point last_time_;
|
std::chrono::steady_clock::time_point last_time_;
|
||||||
XNetTrafficStats net_traffic_stats_{};
|
MiniRtcNetTrafficStats net_traffic_stats_{};
|
||||||
|
|
||||||
using QueuedFile = FileTransferState::QueuedFile;
|
using QueuedFile = FileTransferState::QueuedFile;
|
||||||
using FileTransferStatus = FileTransferState::FileTransferStatus;
|
using FileTransferStatus = FileTransferState::FileTransferStatus;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class NativeVideoFrameRef {
|
|||||||
public:
|
public:
|
||||||
NativeVideoFrameRef() = default;
|
NativeVideoFrameRef() = default;
|
||||||
|
|
||||||
explicit NativeVideoFrameRef(const XNativeVideoFrame *frame) {
|
explicit NativeVideoFrameRef(const MiniRtcNativeVideoFrame *frame) {
|
||||||
if (frame && frame->owner && frame->retain && frame->release) {
|
if (frame && frame->owner && frame->retain && frame->release) {
|
||||||
frame_ = *frame;
|
frame_ = *frame;
|
||||||
frame_.struct_size = sizeof(frame_);
|
frame_.struct_size = sizeof(frame_);
|
||||||
@@ -79,18 +79,18 @@ public:
|
|||||||
std::swap(valid_, other.valid_);
|
std::swap(valid_, other.valid_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XNativeVideoFrame *Get() const { return valid_ ? &frame_ : nullptr; }
|
const MiniRtcNativeVideoFrame *Get() const { return valid_ ? &frame_ : nullptr; }
|
||||||
explicit operator bool() const { return valid_; }
|
explicit operator bool() const { return valid_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XNativeVideoFrame frame_{};
|
MiniRtcNativeVideoFrame frame_{};
|
||||||
bool valid_ = false;
|
bool valid_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const XNativeVideoFrame *GetOpenGlNativeFrame(
|
const MiniRtcNativeVideoFrame *GetOpenGlNativeFrame(
|
||||||
const XNativeVideoFrame &frame) {
|
const MiniRtcNativeVideoFrame &frame) {
|
||||||
const XNativeVideoFrame *native = &frame;
|
const MiniRtcNativeVideoFrame *native = &frame;
|
||||||
if (native->struct_size < static_cast<uint32_t>(sizeof(XNativeVideoFrame)) ||
|
if (native->struct_size < static_cast<uint32_t>(sizeof(MiniRtcNativeVideoFrame)) ||
|
||||||
!native->owner || !native->retain || !native->release ||
|
!native->owner || !native->retain || !native->release ||
|
||||||
!native->copy_to_nv12 || native->width == 0 || native->height == 0 ||
|
!native->copy_to_nv12 || native->width == 0 || native->height == 0 ||
|
||||||
(native->width & 1U) != 0 || (native->height & 1U) != 0 ||
|
(native->width & 1U) != 0 || (native->height & 1U) != 0 ||
|
||||||
@@ -98,7 +98,7 @@ const XNativeVideoFrame *GetOpenGlNativeFrame(
|
|||||||
native->height > static_cast<uint32_t>(std::numeric_limits<int>::max())) {
|
native->height > static_cast<uint32_t>(std::numeric_limits<int>::max())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (native->type == XNativeVideoFrameCpuNv12) {
|
if (native->type == MiniRtcNativeVideoFrameCpuNv12) {
|
||||||
return native->payload.cpu_nv12.y_plane &&
|
return native->payload.cpu_nv12.y_plane &&
|
||||||
native->payload.cpu_nv12.uv_plane &&
|
native->payload.cpu_nv12.uv_plane &&
|
||||||
native->payload.cpu_nv12.y_stride >= native->width &&
|
native->payload.cpu_nv12.y_stride >= native->width &&
|
||||||
@@ -106,7 +106,7 @@ const XNativeVideoFrame *GetOpenGlNativeFrame(
|
|||||||
? native
|
? native
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
if (native->type == XNativeVideoFrameCudaNv12) {
|
if (native->type == MiniRtcNativeVideoFrameCudaNv12) {
|
||||||
return native->payload.cuda_nv12.y_device_pointer != 0 &&
|
return native->payload.cuda_nv12.y_device_pointer != 0 &&
|
||||||
native->payload.cuda_nv12.uv_device_pointer != 0 &&
|
native->payload.cuda_nv12.uv_device_pointer != 0 &&
|
||||||
native->payload.cuda_nv12.y_stride >= native->width &&
|
native->payload.cuda_nv12.y_stride >= native->width &&
|
||||||
@@ -457,7 +457,7 @@ struct OpenGlVideoRenderer::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PrepareCudaContext(const NativeVideoFrameRef &native_frame) {
|
bool PrepareCudaContext(const NativeVideoFrameRef &native_frame) {
|
||||||
const XNativeVideoFrame *frame = native_frame.Get();
|
const MiniRtcNativeVideoFrame *frame = native_frame.Get();
|
||||||
if (!frame || !frame->payload.cuda_nv12.context ||
|
if (!frame || !frame->payload.cuda_nv12.context ||
|
||||||
cuda_interop_disabled ||
|
cuda_interop_disabled ||
|
||||||
!cuda_sync_functions_available ||
|
!cuda_sync_functions_available ||
|
||||||
@@ -564,7 +564,7 @@ struct OpenGlVideoRenderer::Impl {
|
|||||||
|
|
||||||
CudaUploadResult CopyCudaFrameToUploadBuffer(
|
CudaUploadResult CopyCudaFrameToUploadBuffer(
|
||||||
const NativeVideoFrameRef &native_frame, size_t *upload_slot_index) {
|
const NativeVideoFrameRef &native_frame, size_t *upload_slot_index) {
|
||||||
const XNativeVideoFrame *frame = native_frame.Get();
|
const MiniRtcNativeVideoFrame *frame = native_frame.Get();
|
||||||
if (!upload_slot_index || !PrepareCudaContext(native_frame)) {
|
if (!upload_slot_index || !PrepareCudaContext(native_frame)) {
|
||||||
return CudaUploadResult::unavailable;
|
return CudaUploadResult::unavailable;
|
||||||
}
|
}
|
||||||
@@ -1096,11 +1096,11 @@ OpenGlVideoRenderer::SubmitNv12Internal(std::string_view remote_id,
|
|||||||
|
|
||||||
OpenGlVideoRenderer::SubmitResult
|
OpenGlVideoRenderer::SubmitResult
|
||||||
OpenGlVideoRenderer::SubmitNativeFrame(std::string_view remote_id,
|
OpenGlVideoRenderer::SubmitNativeFrame(std::string_view remote_id,
|
||||||
const XNativeVideoFrame &frame) {
|
const MiniRtcNativeVideoFrame &frame) {
|
||||||
if (!IsReady()) {
|
if (!IsReady()) {
|
||||||
return SubmitResult::failed;
|
return SubmitResult::failed;
|
||||||
}
|
}
|
||||||
const XNativeVideoFrame *native = GetOpenGlNativeFrame(frame);
|
const MiniRtcNativeVideoFrame *native = GetOpenGlNativeFrame(frame);
|
||||||
if (!native) {
|
if (!native) {
|
||||||
return SubmitResult::failed;
|
return SubmitResult::failed;
|
||||||
}
|
}
|
||||||
@@ -1144,7 +1144,7 @@ OpenGlVideoRenderer::SubmitNativeFrame(std::string_view remote_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && USE_CUDA
|
#if defined(_WIN32) && USE_CUDA
|
||||||
if (native->type == XNativeVideoFrameCudaNv12 &&
|
if (native->type == MiniRtcNativeVideoFrameCudaNv12 &&
|
||||||
impl_->cuda_cpu_fallback.load(std::memory_order_acquire)) {
|
impl_->cuda_cpu_fallback.load(std::memory_order_acquire)) {
|
||||||
const size_t required_size =
|
const size_t required_size =
|
||||||
static_cast<size_t>(native->width) * native->height * 3U / 2U;
|
static_cast<size_t>(native->width) * native->height * 3U / 2U;
|
||||||
@@ -1295,13 +1295,13 @@ OpenGlVideoRenderer::RenderLatest(std::string_view remote_id,
|
|||||||
bool use_pixel_unpack_buffer = false;
|
bool use_pixel_unpack_buffer = false;
|
||||||
size_t cuda_upload_slot = 0;
|
size_t cuda_upload_slot = 0;
|
||||||
std::vector<unsigned char> cpu_fallback;
|
std::vector<unsigned char> cpu_fallback;
|
||||||
if (const XNativeVideoFrame *native = active_native_frame.Get()) {
|
if (const MiniRtcNativeVideoFrame *native = active_native_frame.Get()) {
|
||||||
if (native->type == XNativeVideoFrameCpuNv12 &&
|
if (native->type == MiniRtcNativeVideoFrameCpuNv12 &&
|
||||||
native->payload.cpu_nv12.y_stride == native->width &&
|
native->payload.cpu_nv12.y_stride == native->width &&
|
||||||
native->payload.cpu_nv12.uv_stride == native->width) {
|
native->payload.cpu_nv12.uv_stride == native->width) {
|
||||||
y_data = native->payload.cpu_nv12.y_plane;
|
y_data = native->payload.cpu_nv12.y_plane;
|
||||||
uv_data = native->payload.cpu_nv12.uv_plane;
|
uv_data = native->payload.cpu_nv12.uv_plane;
|
||||||
} else if (native->type == XNativeVideoFrameCudaNv12) {
|
} else if (native->type == MiniRtcNativeVideoFrameCudaNv12) {
|
||||||
#if defined(_WIN32) && USE_CUDA
|
#if defined(_WIN32) && USE_CUDA
|
||||||
const auto cuda_result = impl_->CopyCudaFrameToUploadBuffer(
|
const auto cuda_result = impl_->CopyCudaFrameToUploadBuffer(
|
||||||
active_native_frame, &cuda_upload_slot);
|
active_native_frame, &cuda_upload_slot);
|
||||||
@@ -1603,7 +1603,7 @@ bool OpenGlVideoRenderer::CopyLatestNv12(
|
|||||||
*output = std::move(cpu_frame);
|
*output = std::move(cpu_frame);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (const XNativeVideoFrame *native = native_frame.Get()) {
|
if (const MiniRtcNativeVideoFrame *native = native_frame.Get()) {
|
||||||
const size_t required_size =
|
const size_t required_size =
|
||||||
static_cast<size_t>(native->width) * native->height * 3U / 2U;
|
static_cast<size_t>(native->width) * native->height * 3U / 2U;
|
||||||
output->resize(required_size);
|
output->resize(required_size);
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
SubmitResult SubmitCachedNv12(std::string_view remote_id, const uint8_t *data,
|
SubmitResult SubmitCachedNv12(std::string_view remote_id, const uint8_t *data,
|
||||||
size_t size, int width, int height) override;
|
size_t size, int width, int height) override;
|
||||||
SubmitResult SubmitNativeFrame(std::string_view remote_id,
|
SubmitResult SubmitNativeFrame(std::string_view remote_id,
|
||||||
const XNativeVideoFrame &frame) override;
|
const MiniRtcNativeVideoFrame &frame) override;
|
||||||
|
|
||||||
// Draws below Slint while its OpenGL context is current. All dimensions are
|
// Draws below Slint while its OpenGL context is current. All dimensions are
|
||||||
// physical pixels in the window client area. corner_radius_pixels clips the
|
// physical pixels in the window client area. corner_radius_pixels clips the
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ int ScreenCapturerLinux::Init(const int fps, cb_desktop_data cb) {
|
|||||||
callback_orig_ = std::move(cb);
|
callback_orig_ = std::move(cb);
|
||||||
callback_ = [this](unsigned char* data, int size, int width, int height,
|
callback_ = [this](unsigned char* data, int size, int width, int height,
|
||||||
const char* reported_stream_id,
|
const char* reported_stream_id,
|
||||||
const XNativeVideoFrame* native_frame) {
|
const MiniRtcNativeVideoFrame* native_frame) {
|
||||||
const std::string mapped_stream_id = MapStreamId(reported_stream_id);
|
const std::string mapped_stream_id = MapStreamId(reported_stream_id);
|
||||||
if (mapped_stream_id.empty()) {
|
if (mapped_stream_id.empty()) {
|
||||||
if (!invalid_stream_id_logged_.exchange(true,
|
if (!invalid_stream_id_logged_.exchange(true,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class MacMetalVideoRenderer final : public VideoRenderer {
|
|||||||
// Retains an IOSurface-backed VideoToolbox CVPixelBuffer until the Metal
|
// Retains an IOSurface-backed VideoToolbox CVPixelBuffer until the Metal
|
||||||
// command buffer using it has completed.
|
// command buffer using it has completed.
|
||||||
SubmitResult SubmitNativeFrame(std::string_view remote_id,
|
SubmitResult SubmitNativeFrame(std::string_view remote_id,
|
||||||
const XNativeVideoFrame& frame) override;
|
const MiniRtcNativeVideoFrame& frame) override;
|
||||||
|
|
||||||
// Seeds a newly selected stream from its retained CPU snapshot without
|
// Seeds a newly selected stream from its retained CPU snapshot without
|
||||||
// replacing a newer decoded frame that is already queued or rendering.
|
// replacing a newer decoded frame that is already queued or rendering.
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class NativeVideoFrameRef {
|
|||||||
public:
|
public:
|
||||||
NativeVideoFrameRef() = default;
|
NativeVideoFrameRef() = default;
|
||||||
|
|
||||||
explicit NativeVideoFrameRef(const XNativeVideoFrame* frame) {
|
explicit NativeVideoFrameRef(const MiniRtcNativeVideoFrame* frame) {
|
||||||
if (frame && frame->owner && frame->retain && frame->release) {
|
if (frame && frame->owner && frame->retain && frame->release) {
|
||||||
frame_ = *frame;
|
frame_ = *frame;
|
||||||
frame_.struct_size = sizeof(frame_);
|
frame_.struct_size = sizeof(frame_);
|
||||||
@@ -236,21 +236,21 @@ class NativeVideoFrameRef {
|
|||||||
std::swap(valid_, other.valid_);
|
std::swap(valid_, other.valid_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const XNativeVideoFrame* Get() const {
|
const MiniRtcNativeVideoFrame* Get() const {
|
||||||
return valid_ ? &frame_ : nullptr;
|
return valid_ ? &frame_ : nullptr;
|
||||||
}
|
}
|
||||||
explicit operator bool() const { return valid_; }
|
explicit operator bool() const { return valid_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XNativeVideoFrame frame_{};
|
MiniRtcNativeVideoFrame frame_{};
|
||||||
bool valid_ = false;
|
bool valid_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const XNativeVideoFrame* GetMacNativeFrame(
|
const MiniRtcNativeVideoFrame* GetMacNativeFrame(
|
||||||
const XNativeVideoFrame& frame) {
|
const MiniRtcNativeVideoFrame& frame) {
|
||||||
const XNativeVideoFrame* native = &frame;
|
const MiniRtcNativeVideoFrame* native = &frame;
|
||||||
if (native->struct_size < static_cast<uint32_t>(sizeof(*native)) ||
|
if (native->struct_size < static_cast<uint32_t>(sizeof(*native)) ||
|
||||||
native->type != XNativeVideoFrameCVPixelBuffer ||
|
native->type != MiniRtcNativeVideoFrameCVPixelBuffer ||
|
||||||
!native->payload.cv_pixel_buffer || !native->owner || !native->retain ||
|
!native->payload.cv_pixel_buffer || !native->owner || !native->retain ||
|
||||||
!native->release || !native->copy_to_nv12 || native->width == 0 ||
|
!native->release || !native->copy_to_nv12 || native->width == 0 ||
|
||||||
native->height == 0 || (native->width & 1U) != 0 ||
|
native->height == 0 || (native->width & 1U) != 0 ||
|
||||||
@@ -471,7 +471,7 @@ fragment half4 nv12_fragment(
|
|||||||
- 16.0 / 255.0);
|
- 16.0 / 255.0);
|
||||||
const float2 uv = uv_texture.sample(video_sampler, in.texcoord).rg - 0.5;
|
const float2 uv = uv_texture.sample(video_sampler, in.texcoord).rg - 0.5;
|
||||||
// BT.601 limited-range NV12, matching the previous libyuv NV12ToABGR/RAW
|
// BT.601 limited-range NV12, matching the previous libyuv NV12ToABGR/RAW
|
||||||
// path. MiniRTC's current XVideoFrame API does not carry color metadata, so
|
// path. MiniRTC's current MiniRtcVideoFrame API does not carry color metadata, so
|
||||||
// retaining the established matrix avoids a platform-only color change.
|
// retaining the established matrix avoids a platform-only color change.
|
||||||
const float3 rgb = float3(y + 1.59602678 * uv.y,
|
const float3 rgb = float3(y + 1.59602678 * uv.y,
|
||||||
y - 0.39176229 * uv.x - 0.81296764 * uv.y,
|
y - 0.39176229 * uv.x - 0.81296764 * uv.y,
|
||||||
@@ -751,11 +751,11 @@ MacMetalVideoRenderer::SubmitResult MacMetalVideoRenderer::SubmitNv12(
|
|||||||
}
|
}
|
||||||
|
|
||||||
MacMetalVideoRenderer::SubmitResult MacMetalVideoRenderer::SubmitNativeFrame(
|
MacMetalVideoRenderer::SubmitResult MacMetalVideoRenderer::SubmitNativeFrame(
|
||||||
std::string_view remote_id, const XNativeVideoFrame& frame) {
|
std::string_view remote_id, const MiniRtcNativeVideoFrame& frame) {
|
||||||
if (!IsReady()) {
|
if (!IsReady()) {
|
||||||
return SubmitResult::failed;
|
return SubmitResult::failed;
|
||||||
}
|
}
|
||||||
const XNativeVideoFrame* native = GetMacNativeFrame(frame);
|
const MiniRtcNativeVideoFrame* native = GetMacNativeFrame(frame);
|
||||||
if (!native) {
|
if (!native) {
|
||||||
return SubmitResult::failed;
|
return SubmitResult::failed;
|
||||||
}
|
}
|
||||||
@@ -1322,7 +1322,7 @@ bool MacMetalVideoRenderer::CopyLatestNv12(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const XNativeVideoFrame* native = native_frame.Get();
|
const MiniRtcNativeVideoFrame* native = native_frame.Get();
|
||||||
const size_t y_size = static_cast<size_t>(native->width) * native->height;
|
const size_t y_size = static_cast<size_t>(native->width) * native->height;
|
||||||
output->resize(y_size + y_size / 2);
|
output->resize(y_size + y_size / 2);
|
||||||
return native->copy_to_nv12(native->owner, output->data(), output->size()) ==
|
return native->copy_to_nv12(native->owner, output->data(), output->size()) ==
|
||||||
|
|||||||
@@ -695,9 +695,9 @@ void ScreenCapturerSckImpl::OnNewCVPixelBuffer(CVPixelBufferRef pixelBuffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XNativeVideoFrame native_frame{};
|
MiniRtcNativeVideoFrame native_frame{};
|
||||||
native_frame.struct_size = sizeof(native_frame);
|
native_frame.struct_size = sizeof(native_frame);
|
||||||
native_frame.type = XNativeVideoFrameCVPixelBuffer;
|
native_frame.type = MiniRtcNativeVideoFrameCVPixelBuffer;
|
||||||
native_frame.width = static_cast<uint32_t>(width);
|
native_frame.width = static_cast<uint32_t>(width);
|
||||||
native_frame.height = static_cast<uint32_t>(height);
|
native_frame.height = static_cast<uint32_t>(height);
|
||||||
native_frame.payload.cv_pixel_buffer = pixelBuffer;
|
native_frame.payload.cv_pixel_buffer = pixelBuffer;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public:
|
|||||||
// Retains a platform-native decoded frame when the backend supports its
|
// Retains a platform-native decoded frame when the backend supports its
|
||||||
// storage and handle types. Unsupported backends keep the default fallback.
|
// storage and handle types. Unsupported backends keep the default fallback.
|
||||||
virtual SubmitResult SubmitNativeFrame(std::string_view,
|
virtual SubmitResult SubmitNativeFrame(std::string_view,
|
||||||
const XNativeVideoFrame&) {
|
const MiniRtcNativeVideoFrame&) {
|
||||||
return SubmitResult::failed;
|
return SubmitResult::failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ int ScreenCapturerWin::Init(const int fps, cb_desktop_data cb) {
|
|||||||
}
|
}
|
||||||
cb_ = [this](unsigned char* data, int size, int w, int h,
|
cb_ = [this](unsigned char* data, int size, int w, int h,
|
||||||
const char* reported_stream_id,
|
const char* reported_stream_id,
|
||||||
const XNativeVideoFrame* native_frame) {
|
const MiniRtcNativeVideoFrame* native_frame) {
|
||||||
if (secure_desktop_capture_active_.load(std::memory_order_relaxed)) {
|
if (secure_desktop_capture_active_.load(std::memory_order_relaxed)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -530,7 +530,7 @@ int ScreenCapturerWin::Destroy() {
|
|||||||
|
|
||||||
void ScreenCapturerWin::EmitCapturedFrame(
|
void ScreenCapturerWin::EmitCapturedFrame(
|
||||||
unsigned char* data, int size, int width, int height,
|
unsigned char* data, int size, int width, int height,
|
||||||
const char* stream_id, const XNativeVideoFrame* native_frame) {
|
const char* stream_id, const MiniRtcNativeVideoFrame* native_frame) {
|
||||||
if (!cb_orig_) {
|
if (!cb_orig_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class ScreenCapturerWin : public ScreenCapturer {
|
|||||||
void RebuildAliasesFromImpl();
|
void RebuildAliasesFromImpl();
|
||||||
void EmitCapturedFrame(unsigned char* data, int size, int width, int height,
|
void EmitCapturedFrame(unsigned char* data, int size, int width, int height,
|
||||||
const char* stream_id,
|
const char* stream_id,
|
||||||
const XNativeVideoFrame* native_frame = nullptr);
|
const MiniRtcNativeVideoFrame* native_frame = nullptr);
|
||||||
void StopSecureCaptureThread();
|
void StopSecureCaptureThread();
|
||||||
bool RestartCaptureBackendAfterSecureDesktop();
|
bool RestartCaptureBackendAfterSecureDesktop();
|
||||||
void SecureDesktopCaptureLoop();
|
void SecureDesktopCaptureLoop();
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ CapturedNv12Frame::CapturedNv12Frame(
|
|||||||
width_(width),
|
width_(width),
|
||||||
height_(height) {
|
height_(height) {
|
||||||
descriptor_.struct_size = sizeof(descriptor_);
|
descriptor_.struct_size = sizeof(descriptor_);
|
||||||
descriptor_.type = XNativeVideoFrameCpuNv12;
|
descriptor_.type = MiniRtcNativeVideoFrameCpuNv12;
|
||||||
descriptor_.width = width_;
|
descriptor_.width = width_;
|
||||||
descriptor_.height = height_;
|
descriptor_.height = height_;
|
||||||
descriptor_.payload.cpu_nv12 = {
|
descriptor_.payload.cpu_nv12 = {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class CapturedNv12FramePool final
|
|||||||
|
|
||||||
class CapturedNv12Frame final {
|
class CapturedNv12Frame final {
|
||||||
public:
|
public:
|
||||||
const XNativeVideoFrame* Descriptor() const { return &descriptor_; }
|
const MiniRtcNativeVideoFrame* Descriptor() const { return &descriptor_; }
|
||||||
size_t Size() const { return storage_.size(); }
|
size_t Size() const { return storage_.size(); }
|
||||||
|
|
||||||
void AddRef();
|
void AddRef();
|
||||||
@@ -70,7 +70,7 @@ class CapturedNv12Frame final {
|
|||||||
std::vector<uint8_t> storage_;
|
std::vector<uint8_t> storage_;
|
||||||
uint32_t width_ = 0;
|
uint32_t width_ = 0;
|
||||||
uint32_t height_ = 0;
|
uint32_t height_ = 0;
|
||||||
XNativeVideoFrame descriptor_{};
|
MiniRtcNativeVideoFrame descriptor_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace crossdesk
|
} // namespace crossdesk
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ScreenCapturer {
|
|||||||
// duration of the callback; retain its owner before using it asynchronously.
|
// duration of the callback; retain its owner before using it asynchronously.
|
||||||
typedef std::function<void(unsigned char* data, int size, int width,
|
typedef std::function<void(unsigned char* data, int size, int width,
|
||||||
int height, const char* stream_id,
|
int height, const char* stream_id,
|
||||||
const XNativeVideoFrame* native_frame)>
|
const MiniRtcNativeVideoFrame* native_frame)>
|
||||||
cb_desktop_data;
|
cb_desktop_data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ void DispatchMain(dispatch_block_t block) {
|
|||||||
generation:(uint64_t)generation;
|
generation:(uint64_t)generation;
|
||||||
- (BOOL)isControllerGenerationActive:(uint64_t)generation;
|
- (BOOL)isControllerGenerationActive:(uint64_t)generation;
|
||||||
- (BOOL)isControllerGenerationCurrent:(uint64_t)generation;
|
- (BOOL)isControllerGenerationCurrent:(uint64_t)generation;
|
||||||
- (void)handleVideoFrame:(const XVideoFrame *)frame
|
- (void)handleVideoFrame:(const MiniRtcVideoFrame *)frame
|
||||||
sourceID:(const char *)sourceID
|
sourceID:(const char *)sourceID
|
||||||
sourceIDSize:(size_t)sourceIDSize;
|
sourceIDSize:(size_t)sourceIDSize;
|
||||||
- (void)enqueueVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
- (void)enqueueVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer
|
||||||
@@ -214,7 +214,7 @@ void DispatchMain(dispatch_block_t block) {
|
|||||||
size:(size_t)size
|
size:(size_t)size
|
||||||
sourceID:(const char *)sourceID
|
sourceID:(const char *)sourceID
|
||||||
sourceIDSize:(size_t)sourceIDSize;
|
sourceIDSize:(size_t)sourceIDSize;
|
||||||
- (void)handleStats:(const XNetTrafficStats *)stats mode:(TraversalMode)mode;
|
- (void)handleStats:(const MiniRtcNetTrafficStats *)stats mode:(TraversalMode)mode;
|
||||||
- (void)sendMessage:(const std::string &)message
|
- (void)sendMessage:(const std::string &)message
|
||||||
reliable:(BOOL)reliable
|
reliable:(BOOL)reliable
|
||||||
stream:(const char *)stream;
|
stream:(const char *)stream;
|
||||||
@@ -227,7 +227,7 @@ void DispatchMain(dispatch_block_t block) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void OnVideoFrame(const XVideoFrame *frame, const char *, size_t,
|
void OnVideoFrame(const MiniRtcVideoFrame *frame, const char *, size_t,
|
||||||
const char *source_id, size_t source_id_size,
|
const char *source_id, size_t source_id_size,
|
||||||
void *user_data) {
|
void *user_data) {
|
||||||
auto *context = static_cast<CallbackContext *>(user_data);
|
auto *context = static_cast<CallbackContext *>(user_data);
|
||||||
@@ -298,7 +298,7 @@ void OnConnectionState(ConnectionStatus status, const char *remote_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OnNetworkStats(const char *peer_id, size_t peer_id_size,
|
void OnNetworkStats(const char *peer_id, size_t peer_id_size,
|
||||||
TraversalMode mode, const XNetTrafficStats *stats,
|
TraversalMode mode, const MiniRtcNetTrafficStats *stats,
|
||||||
const char *, size_t, void *user_data) {
|
const char *, size_t, void *user_data) {
|
||||||
auto *context = static_cast<CallbackContext *>(user_data);
|
auto *context = static_cast<CallbackContext *>(user_data);
|
||||||
CrossDeskRTCBridge *owner = context ? context->owner : nil;
|
CrossDeskRTCBridge *owner = context ? context->owner : nil;
|
||||||
@@ -1114,7 +1114,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id,
|
|||||||
return active == 0 || active == generation;
|
return active == 0 || active == generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleVideoFrame:(const XVideoFrame *)frame
|
- (void)handleVideoFrame:(const MiniRtcVideoFrame *)frame
|
||||||
sourceID:(const char *)sourceID
|
sourceID:(const char *)sourceID
|
||||||
sourceIDSize:(size_t)sourceIDSize {
|
sourceIDSize:(size_t)sourceIDSize {
|
||||||
if (!frame || frame->width == 0 || frame->height == 0) return;
|
if (!frame || frame->width == 0 || frame->height == 0) return;
|
||||||
@@ -1124,12 +1124,12 @@ Params MakeParams(const RTCState &state, const std::string &user_id,
|
|||||||
static_cast<size_t>(_selectedDisplay.load()));
|
static_cast<size_t>(_selectedDisplay.load()));
|
||||||
if (source != expected) return;
|
if (source != expected) return;
|
||||||
}
|
}
|
||||||
const XNativeVideoFrame *native_frame = frame->native_frame;
|
const MiniRtcNativeVideoFrame *native_frame = frame->native_frame;
|
||||||
const bool has_native_pixel_buffer =
|
const bool has_native_pixel_buffer =
|
||||||
native_frame &&
|
native_frame &&
|
||||||
native_frame->struct_size >=
|
native_frame->struct_size >=
|
||||||
static_cast<uint32_t>(sizeof(XNativeVideoFrame)) &&
|
static_cast<uint32_t>(sizeof(MiniRtcNativeVideoFrame)) &&
|
||||||
native_frame->type == XNativeVideoFrameCVPixelBuffer &&
|
native_frame->type == MiniRtcNativeVideoFrameCVPixelBuffer &&
|
||||||
native_frame->payload.cv_pixel_buffer;
|
native_frame->payload.cv_pixel_buffer;
|
||||||
if (has_native_pixel_buffer) {
|
if (has_native_pixel_buffer) {
|
||||||
CVPixelBufferRef pixel_buffer =
|
CVPixelBufferRef pixel_buffer =
|
||||||
@@ -1584,7 +1584,7 @@ Params MakeParams(const RTCState &state, const std::string &user_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleStats:(const XNetTrafficStats *)stats mode:(TraversalMode)mode {
|
- (void)handleStats:(const MiniRtcNetTrafficStats *)stats mode:(TraversalMode)mode {
|
||||||
if (!stats) return;
|
if (!stats) return;
|
||||||
const NSUInteger bitrate = stats->total_inbound_stats.bitrate;
|
const NSUInteger bitrate = stats->total_inbound_stats.bitrate;
|
||||||
const float loss = stats->video_inbound_stats.loss_rate;
|
const float loss = stats->video_inbound_stats.loss_rate;
|
||||||
|
|||||||
Vendored
+1
-1
Submodule deps/submodules/minirtc updated: 454a0c544a...53c125435e
Reference in New Issue
Block a user