Merge pull request #120 from cgutman/nvenc_linux
Add basic NVENC support on Linux
This commit is contained in:
@@ -528,7 +528,7 @@
|
|||||||
}
|
}
|
||||||
if (this.platform == "linux") {
|
if (this.platform == "linux") {
|
||||||
this.tabs = this.tabs.filter(el => {
|
this.tabs = this.tabs.filter(el => {
|
||||||
return el.id !== "nv" && el.id !== "amd";
|
return el.id !== "amd";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ enum class mem_type_e {
|
|||||||
system,
|
system,
|
||||||
vaapi,
|
vaapi,
|
||||||
dxgi,
|
dxgi,
|
||||||
|
cuda,
|
||||||
unknown
|
unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ struct shm_attr_t : public x11_attr_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type) {
|
std::shared_ptr<display_t> display(platf::mem_type_e hwdevice_type) {
|
||||||
if(hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi) {
|
if(hwdevice_type != platf::mem_type_e::system && hwdevice_type != platf::mem_type_e::vaapi && hwdevice_type != platf::mem_type_e::cuda) {
|
||||||
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
|
BOOST_LOG(error) << "Could not initialize display with the given hw device type."sv;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -511,11 +511,14 @@ std::vector<uint8_t> replace(const std::string_view &original, const std::string
|
|||||||
std::vector<uint8_t> replaced;
|
std::vector<uint8_t> replaced;
|
||||||
|
|
||||||
auto begin = std::begin(original);
|
auto begin = std::begin(original);
|
||||||
auto next = std::search(begin, std::end(original), std::begin(old), std::end(old));
|
auto end = std::end(original);
|
||||||
|
auto next = std::search(begin, end, std::begin(old), std::end(old));
|
||||||
|
|
||||||
std::copy(begin, next, std::back_inserter(replaced));
|
std::copy(begin, next, std::back_inserter(replaced));
|
||||||
std::copy(std::begin(_new), std::end(_new), std::back_inserter(replaced));
|
if(next != end) {
|
||||||
std::copy(next + old.size(), std::end(original), std::back_inserter(replaced));
|
std::copy(std::begin(_new), std::end(_new), std::back_inserter(replaced));
|
||||||
|
std::copy(next + old.size(), end, std::back_inserter(replaced));
|
||||||
|
}
|
||||||
|
|
||||||
return replaced;
|
return replaced;
|
||||||
}
|
}
|
||||||
@@ -866,7 +869,7 @@ void videoBroadcastThread(udp::socket &sock) {
|
|||||||
video_packet->packet.flags |= FLAG_EOF;
|
video_packet->packet.flags |= FLAG_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
video_packet->rtp.header = FLAG_EXTENSION;
|
video_packet->rtp.header = 0x80 | FLAG_EXTENSION;
|
||||||
video_packet->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + fecIndex);
|
video_packet->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + fecIndex);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -883,7 +886,7 @@ void videoBroadcastThread(udp::socket &sock) {
|
|||||||
|
|
||||||
inspect->packet.frameIndex = packet->pts;
|
inspect->packet.frameIndex = packet->pts;
|
||||||
|
|
||||||
inspect->rtp.header = FLAG_EXTENSION;
|
inspect->rtp.header = 0x80 | FLAG_EXTENSION;
|
||||||
inspect->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + x);
|
inspect->rtp.sequenceNumber = util::endian::big<uint16_t>(lowseq + x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ platf::pix_fmt_e map_pix_fmt(AVPixelFormat fmt);
|
|||||||
|
|
||||||
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
|
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
|
||||||
util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
|
util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
|
||||||
|
util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx);
|
||||||
|
|
||||||
int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format);
|
int hwframe_ctx(ctx_t &ctx, buffer_t &hwdevice, AVPixelFormat format);
|
||||||
|
|
||||||
@@ -402,12 +403,16 @@ void end_capture_async(capture_thread_async_ctx_t &ctx);
|
|||||||
auto capture_thread_async = safe::make_shared<capture_thread_async_ctx_t>(start_capture_async, end_capture_async);
|
auto capture_thread_async = safe::make_shared<capture_thread_async_ctx_t>(start_capture_async, end_capture_async);
|
||||||
auto capture_thread_sync = safe::make_shared<capture_thread_sync_ctx_t>(start_capture_sync, end_capture_sync);
|
auto capture_thread_sync = safe::make_shared<capture_thread_sync_ctx_t>(start_capture_sync, end_capture_sync);
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
static encoder_t nvenc {
|
static encoder_t nvenc {
|
||||||
"nvenc"sv,
|
"nvenc"sv,
|
||||||
{ (int)nv::profile_h264_e::high, (int)nv::profile_hevc_e::main, (int)nv::profile_hevc_e::main_10 },
|
{ (int)nv::profile_h264_e::high, (int)nv::profile_hevc_e::main, (int)nv::profile_hevc_e::main_10 },
|
||||||
|
#ifdef _WIN32
|
||||||
AV_HWDEVICE_TYPE_D3D11VA,
|
AV_HWDEVICE_TYPE_D3D11VA,
|
||||||
AV_PIX_FMT_D3D11,
|
AV_PIX_FMT_D3D11,
|
||||||
|
#else
|
||||||
|
AV_HWDEVICE_TYPE_CUDA,
|
||||||
|
AV_PIX_FMT_CUDA,
|
||||||
|
#endif
|
||||||
AV_PIX_FMT_NV12, AV_PIX_FMT_P010,
|
AV_PIX_FMT_NV12, AV_PIX_FMT_P010,
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -432,10 +437,16 @@ static encoder_t nvenc {
|
|||||||
std::make_optional<encoder_t::option_t>({ "qp"s, &config::video.qp }),
|
std::make_optional<encoder_t::option_t>({ "qp"s, &config::video.qp }),
|
||||||
"h264_nvenc"s,
|
"h264_nvenc"s,
|
||||||
},
|
},
|
||||||
|
#ifdef _WIN32
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
dxgi_make_hwdevice_ctx
|
dxgi_make_hwdevice_ctx
|
||||||
|
#else
|
||||||
|
SYSTEM_MEMORY,
|
||||||
|
cuda_make_hwdevice_ctx
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
static encoder_t amdvce {
|
static encoder_t amdvce {
|
||||||
"amdvce"sv,
|
"amdvce"sv,
|
||||||
{ FF_PROFILE_H264_HIGH, FF_PROFILE_HEVC_MAIN },
|
{ FF_PROFILE_H264_HIGH, FF_PROFILE_HEVC_MAIN },
|
||||||
@@ -537,8 +548,8 @@ static encoder_t vaapi {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static std::vector<encoder_t> encoders {
|
static std::vector<encoder_t> encoders {
|
||||||
#ifdef _WIN32
|
|
||||||
nvenc,
|
nvenc,
|
||||||
|
#ifdef _WIN32
|
||||||
amdvce,
|
amdvce,
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@@ -1649,6 +1660,19 @@ util::Either<buffer_t, int> vaapi_make_hwdevice_ctx(platf::hwdevice_t *base) {
|
|||||||
return hw_device_buf;
|
return hw_device_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *base) {
|
||||||
|
buffer_t hw_device_buf;
|
||||||
|
|
||||||
|
auto status = av_hwdevice_ctx_create(&hw_device_buf, AV_HWDEVICE_TYPE_CUDA, nullptr, nullptr, 0);
|
||||||
|
if(status < 0) {
|
||||||
|
char string[AV_ERROR_MAX_STRING_SIZE];
|
||||||
|
BOOST_LOG(error) << "Failed to create a CUDA device: "sv << av_make_error_string(string, AV_ERROR_MAX_STRING_SIZE, status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hw_device_buf;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1716,7 +1740,9 @@ platf::mem_type_e map_dev_type(AVHWDeviceType type) {
|
|||||||
return platf::mem_type_e::dxgi;
|
return platf::mem_type_e::dxgi;
|
||||||
case AV_HWDEVICE_TYPE_VAAPI:
|
case AV_HWDEVICE_TYPE_VAAPI:
|
||||||
return platf::mem_type_e::vaapi;
|
return platf::mem_type_e::vaapi;
|
||||||
case AV_PICTURE_TYPE_NONE:
|
case AV_HWDEVICE_TYPE_CUDA:
|
||||||
|
return platf::mem_type_e::cuda;
|
||||||
|
case AV_HWDEVICE_TYPE_NONE:
|
||||||
return platf::mem_type_e::system;
|
return platf::mem_type_e::system;
|
||||||
default:
|
default:
|
||||||
return platf::mem_type_e::unknown;
|
return platf::mem_type_e::unknown;
|
||||||
|
|||||||
Reference in New Issue
Block a user