From 70bf11ec27d12984f37afc5af18bdc02abec787c Mon Sep 17 00:00:00 2001 From: loki Date: Sun, 19 Apr 2020 00:10:47 +0300 Subject: [PATCH] Increase accuracy of fps for nvenc and proper pixel format --- sunshine/platform/common.h | 1 + sunshine/platform/windows_dxgi.cpp | 17 ++++++++++++----- sunshine/video.cpp | 8 +++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sunshine/platform/common.h b/sunshine/platform/common.h index c2983388..140b54b1 100644 --- a/sunshine/platform/common.h +++ b/sunshine/platform/common.h @@ -39,6 +39,7 @@ enum class pix_fmt_e { yuv420p, yuv420p10, nv12, + p010, unknown }; diff --git a/sunshine/platform/windows_dxgi.cpp b/sunshine/platform/windows_dxgi.cpp index c34931d1..7832d127 100644 --- a/sunshine/platform/windows_dxgi.cpp +++ b/sunshine/platform/windows_dxgi.cpp @@ -326,7 +326,11 @@ public: ctx->VideoProcessorSetOutputColorSpace(processor.get(), (D3D11_VIDEO_PROCESSOR_COLOR_SPACE*)&colorspace); } - int init(std::shared_ptr display, device_t::pointer device_p, device_ctx_t::pointer device_ctx_p, int in_width, int in_height, int out_width, int out_height) { + int init( + std::shared_ptr display, device_t::pointer device_p, device_ctx_t::pointer device_ctx_p, + int in_width, int in_height, int out_width, int out_height, + pix_fmt_e pix_fmt + ) { HRESULT status; platf::hwdevice_t::img = &img; @@ -377,13 +381,13 @@ public: t.ArraySize = 1; t.SampleDesc.Count = 1; t.Usage = D3D11_USAGE_DEFAULT; - t.Format = DXGI_FORMAT_NV12; + t.Format = pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010; t.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_VIDEO_ENCODER; dxgi::texture2d_t::pointer tex_p {}; status = device_p->CreateTexture2D(&t, nullptr, &tex_p); if(FAILED(status)) { - BOOST_LOG(error) << "Failed to create texture [0x"sv << util::hex(status).to_string_view() << ']'; + BOOST_LOG(error) << "Failed to create video output texture [0x"sv << util::hex(status).to_string_view() << ']'; return -1; } @@ -823,6 +827,7 @@ public: t.SampleDesc.Count = 1; t.Usage = D3D11_USAGE_DEFAULT; t.Format = format; + t.BindFlags = D3D11_BIND_RENDER_TARGET; dxgi::texture2d_t::pointer tex_p {}; auto status = device->CreateTexture2D(&t, nullptr, &tex_p); @@ -861,6 +866,7 @@ public: t.SampleDesc.Count = 1; t.Usage = D3D11_USAGE_DEFAULT; t.Format = format; + t.BindFlags = D3D11_BIND_RENDER_TARGET; dxgi::texture2d_t::pointer tex_p {}; auto status = device->CreateTexture2D(&t, &data, &tex_p); @@ -879,7 +885,7 @@ public: } std::shared_ptr make_hwdevice(int width, int height, pix_fmt_e pix_fmt) override { - if(pix_fmt != platf::pix_fmt_e::nv12) { + if(pix_fmt != platf::pix_fmt_e::nv12 && pix_fmt != platf::pix_fmt_e::p010) { BOOST_LOG(error) << "display_gpu_t doesn't support pixel format ["sv << (int)pix_fmt << ']'; return nullptr; @@ -892,7 +898,8 @@ public: device.get(), device_ctx.get(), this->width, this->height, - width, height); + width, height, + pix_fmt); if(ret) { return nullptr; diff --git a/sunshine/video.cpp b/sunshine/video.cpp index afdc4a39..c11c353d 100644 --- a/sunshine/video.cpp +++ b/sunshine/video.cpp @@ -213,7 +213,7 @@ struct sync_session_t { sync_session_ctx_t *ctx; std::chrono::steady_clock::time_point next_frame; - std::chrono::milliseconds delay; + std::chrono::nanoseconds delay; platf::img_t *img_tmp; std::shared_ptr hwdevice; @@ -256,7 +256,7 @@ static encoder_t nvenc { { (int)nv::profile_h264_e::high, (int)nv::profile_hevc_e::main, (int)nv::profile_hevc_e::main_10 }, AV_HWDEVICE_TYPE_D3D11VA, AV_PIX_FMT_D3D11, - AV_PIX_FMT_NV12, AV_PIX_FMT_NV12, + AV_PIX_FMT_NV12, AV_PIX_FMT_P010, { { { "forced-idr"s, 1 }, @@ -767,7 +767,7 @@ std::optional make_synced_session(platf::display_t *disp, const encode_session.ctx = &ctx; encode_session.next_frame = std::chrono::steady_clock::now(); - encode_session.delay = 1000ms / ctx.config.framerate; + encode_session.delay = std::chrono::nanoseconds { 1s } / ctx.config.framerate; auto pix_fmt = ctx.config.dynamicRange == 0 ? map_pix_fmt(encoder.static_pix_fmt) : map_pix_fmt(encoder.dynamic_pix_fmt); auto hwdevice = disp->make_hwdevice(ctx.config.width, ctx.config.height, pix_fmt); @@ -1327,6 +1327,8 @@ platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt) { return platf::pix_fmt_e::yuv420p; case AV_PIX_FMT_NV12: return platf::pix_fmt_e::nv12; + case AV_PIX_FMT_P010: + return platf::pix_fmt_e::p010; default: return platf::pix_fmt_e::unknown; }