Increase accuracy of fps for nvenc and proper pixel format

This commit is contained in:
loki 2020-04-19 00:10:47 +03:00
commit 70bf11ec27
3 changed files with 18 additions and 8 deletions

View file

@ -39,6 +39,7 @@ enum class pix_fmt_e {
yuv420p,
yuv420p10,
nv12,
p010,
unknown
};

View file

@ -326,7 +326,11 @@ public:
ctx->VideoProcessorSetOutputColorSpace(processor.get(), (D3D11_VIDEO_PROCESSOR_COLOR_SPACE*)&colorspace);
}
int init(std::shared_ptr<platf::display_t> 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<platf::display_t> 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<platf::hwdevice_t> 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;

View file

@ -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<platf::hwdevice_t> 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<sync_session_t> 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;
}