Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VPL の H.265 に対応 #338

Merged
merged 4 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"name": "Windows",
"includePath": [
"${workspaceFolder}/src",
"${workspaceFolder}/src/hwenc/include",
"${workspaceFolder}/third_party/NvCodec/include",
"${workspaceFolder}/third_party/NvCodec/NvCodec",
"${workspaceFolder}/_install/windows_x86_64/release/webrtc/include",
Expand Down Expand Up @@ -33,6 +34,7 @@
"name": "Ubuntu 22.04 x86_64",
"includePath": [
"${workspaceFolder}/src",
"${workspaceFolder}/src/hwenc/include",
"${workspaceFolder}/third_party/NvCodec/include",
"${workspaceFolder}/third_party/NvCodec/NvCodec",
"${workspaceFolder}/_install/ubuntu-22.04_x86_64/release/webrtc/include",
Expand Down Expand Up @@ -61,7 +63,8 @@
"BOOST_NO_CXX98_FUNCTION_BASE",
"RTC_ENABLE_H265"
],
"compilerPath": "${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/llvm/clang/bin/clang++",
// "compilerPath": "${workspaceFolder}/_install/ubuntu-20.04_x86_64/release/llvm/clang/bin/clang++",
"compilerPath": "/usr/bin/clang++-18",
"compilerArgs": ["-nostdinc++"],
"cStandard": "c11",
"cppStandard": "c++17",
Expand Down
19 changes: 11 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ string(SUBSTRING "${MOMO_COMMIT}" 0 8 MOMO_COMMIT_SHORT)
string(SUBSTRING "${WEBRTC_COMMIT}" 0 8 WEBRTC_COMMIT_SHORT)
configure_file(src/momo_version.gen.h.template ${CMAKE_CURRENT_BINARY_DIR}/momo_version.gen.h)
target_include_directories(momo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(momo PRIVATE src/hwenc/include)

target_sources(momo
PRIVATE
Expand Down Expand Up @@ -273,6 +274,7 @@ if ("${TARGET_OS}" STREQUAL "windows")
WIN32_LEAN_AND_MEAN
UNICODE
_UNICODE
RTC_ENABLE_H265
)

# NVIDIA Video Codec SDK
Expand Down Expand Up @@ -350,9 +352,9 @@ if ("${TARGET_OS}" STREQUAL "windows")
if (USE_VPL_ENCODER)
target_sources(momo
PRIVATE
src/hwenc_vpl/vpl_session.cpp
src/hwenc_vpl/vpl_video_decoder.cpp
src/hwenc_vpl/vpl_video_encoder.cpp
src/hwenc/src/hwenc_vpl/vpl_session_impl.cpp
src/hwenc/src/hwenc_vpl/vpl_video_decoder.cpp
src/hwenc/src/hwenc_vpl/vpl_video_encoder.cpp
)
target_include_directories(momo PRIVATE ${VPL_ROOT_DIR}/include)
target_link_libraries(momo
Expand All @@ -376,6 +378,7 @@ elseif (TARGET_OS STREQUAL "macos")
PRIVATE
WEBRTC_POSIX
WEBRTC_MAC
RTC_ENABLE_H265
)

target_link_libraries(momo
Expand Down Expand Up @@ -480,11 +483,11 @@ elseif (TARGET_OS STREQUAL "linux")
find_package(VPL REQUIRED)
target_sources(momo
PRIVATE
src/hwenc_vpl/vpl_session.cpp
src/hwenc_vpl/vpl_video_decoder.cpp
src/hwenc_vpl/vpl_video_encoder.cpp
src/hwenc_vpl/vaapi_utils_drm.cpp
src/hwenc_vpl/vaapi_utils.cpp
src/hwenc/src/hwenc_vpl/vpl_session_impl.cpp
src/hwenc/src/hwenc_vpl/vpl_video_decoder.cpp
src/hwenc/src/hwenc_vpl/vpl_video_encoder.cpp
src/hwenc/src/hwenc_vpl/vaapi_utils_drm.cpp
src/hwenc/src/hwenc_vpl/vaapi_utils.cpp
)
target_link_libraries(momo
PRIVATE
Expand Down
3 changes: 3 additions & 0 deletions src/hwenc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sora C++ SDK から持ってきたハードウェアエンコーダ/デコーダを配置するディレクトリ

sora-cpp-sdk からコピペしやすいように、ディレクトリを独立させました。
14 changes: 14 additions & 0 deletions src/hwenc/include/sora/hwenc_vpl/vpl_session.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef SORA_HWENC_VPL_VPL_SESSION_H_
#define SORA_HWENC_VPL_VPL_SESSION_H_

#include <memory>

namespace sora {

struct VplSession {
static std::shared_ptr<VplSession> Create();
};

} // namespace sora

#endif
25 changes: 25 additions & 0 deletions src/hwenc/include/sora/hwenc_vpl/vpl_video_decoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef SORA_HWENC_VPL_VPL_VIDEO_DECODER_H_
#define SORA_HWENC_VPL_VPL_VIDEO_DECODER_H_

#include <memory>

// WebRTC
#include <api/video/video_codec_type.h>
#include <api/video_codecs/video_decoder.h>

#include "vpl_session.h"

namespace sora {

class VplVideoDecoder : public webrtc::VideoDecoder {
public:
static bool IsSupported(std::shared_ptr<VplSession> session,
webrtc::VideoCodecType codec);
static std::unique_ptr<VplVideoDecoder> Create(
std::shared_ptr<VplSession> session,
webrtc::VideoCodecType codec);
};

} // namespace sora

#endif
25 changes: 25 additions & 0 deletions src/hwenc/include/sora/hwenc_vpl/vpl_video_encoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef SORA_HWENC_VPL_VPL_VIDEO_ENCODER_H_
#define SORA_HWENC_VPL_VPL_VIDEO_ENCODER_H_

#include <memory>

// WebRTC
#include <api/video/video_codec_type.h>
#include <api/video_codecs/video_encoder.h>

#include "vpl_session.h"

namespace sora {

class VplVideoEncoder : public webrtc::VideoEncoder {
public:
static bool IsSupported(std::shared_ptr<VplSession> session,
webrtc::VideoCodecType codec);
static std::unique_ptr<VplVideoEncoder> Create(
std::shared_ptr<VplSession> session,
webrtc::VideoCodecType codec);
};

} // namespace sora

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ or https://software.intel.com/en-us/media-client-solutions-support.

#include "vaapi_utils.h"

namespace sora {

mfxStatus va_to_mfx_status(VAStatus va_res) {
mfxStatus mfxRes = MFX_ERR_NONE;

Expand Down Expand Up @@ -50,4 +52,6 @@ mfxStatus va_to_mfx_status(VAStatus va_res) {
break;
}
return mfxRes;
}
}

} // namespace sora
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ The original version of this sample may be obtained from https://software.intel.
or https://software.intel.com/en-us/media-client-solutions-support.
\**********************************************************************************/

#ifndef VAAPI_UTILS_H_
#define VAAPI_UTILS_H_

// oneVPL
#include <vpl/mfxdefs.h>
#ifndef SORA_HWENC_VPL_VAAPI_UTILS_H_
#define SORA_HWENC_VPL_VAAPI_UTILS_H_

// libva
#include <va/va.h>

// Intel VPL
#include <vpl/mfxdefs.h>

namespace sora {

class CLibVA {
public:
virtual ~CLibVA(void) {}
Expand All @@ -41,4 +43,6 @@ class CLibVA {

mfxStatus va_to_mfx_status(VAStatus va_res);

#endif // VAAPI_UTILS_H_
} // namespace sora

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ or https://software.intel.com/en-us/media-client-solutions-support.
// libva
#include <va/va_drm.h>

namespace sora {

constexpr mfxU32 MFX_DRI_MAX_NODES_NUM = 16;
constexpr mfxU32 MFX_DRI_RENDER_START_INDEX = 128;
constexpr mfxU32 MFX_DRI_CARD_START_INDEX = 0;
Expand Down Expand Up @@ -131,4 +133,6 @@ std::unique_ptr<DRMLibVA> CreateDRMLibVA(const std::string& devicePath) {
} catch (std::exception& e) {
return nullptr;
}
}
}

} // namespace sora
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ The original version of this sample may be obtained from https://software.intel.
or https://software.intel.com/en-us/media-client-solutions-support.
\**********************************************************************************/

#ifndef VAAPI_UTILS_DRM_H_
#define VAAPI_UTILS_DRM_H_
#ifndef SORA_HWENC_VPL_VAAPI_UTILS_DRM_H_
#define SORA_HWENC_VPL_VAAPI_UTILS_DRM_H_

#include <memory>
#include <string>

#include "vaapi_utils.h"

namespace sora {

class DRMLibVA : public CLibVA {
public:
DRMLibVA(const std::string& devicePath);
Expand All @@ -40,4 +42,6 @@ class DRMLibVA : public CLibVA {

std::unique_ptr<DRMLibVA> CreateDRMLibVA(const std::string& devicePath = "");

#endif // VAAPI_UTILS_DRM_H_
} // namespace sora

#endif
90 changes: 90 additions & 0 deletions src/hwenc/src/hwenc_vpl/vpl_session_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "sora/hwenc_vpl/vpl_session.h"

#include <rtc_base/logging.h>

// Intel VPL
#include <vpl/mfxdispatcher.h>
#include <vpl/mfxvideo.h>

#ifdef __linux__
#include "vaapi_utils_drm.h"
#endif

namespace sora {

struct VplSessionImpl : VplSession {
~VplSessionImpl();

mfxLoader loader = nullptr;
mfxSession session = nullptr;

#ifdef __linux__
std::unique_ptr<DRMLibVA> libva;
#endif
};

VplSessionImpl::~VplSessionImpl() {
MFXClose(session);
MFXUnload(loader);
}

std::shared_ptr<VplSession> VplSession::Create() {
std::shared_ptr<VplSessionImpl> session(new VplSessionImpl());

mfxStatus sts = MFX_ERR_NONE;

session->loader = MFXLoad();
if (session->loader == nullptr) {
RTC_LOG(LS_VERBOSE) << "Failed to MFXLoad";
return nullptr;
}

MFX_ADD_PROPERTY_U32(session->loader, "mfxImplDescription.Impl",
MFX_IMPL_TYPE_HARDWARE);

sts = MFXCreateSession(session->loader, 0, &session->session);
if (sts != MFX_ERR_NONE) {
RTC_LOG(LS_VERBOSE) << "Failed to MFXCreateSession: sts=" << sts;
return nullptr;
}

#ifdef __linux__
session->libva = CreateDRMLibVA();
if (!session->libva) {
return nullptr;
}

sts = MFXVideoCORE_SetHandle(
session->session, static_cast<mfxHandleType>(MFX_HANDLE_VA_DISPLAY),
session->libva->GetVADisplay());
if (sts != MFX_ERR_NONE) {
return nullptr;
}
#endif

// Query selected implementation and version
mfxIMPL impl;
sts = MFXQueryIMPL(session->session, &impl);
if (sts != MFX_ERR_NONE) {
RTC_LOG(LS_VERBOSE) << "Failed to MFXQueryIMPL: sts=" << sts;
return nullptr;
}

mfxVersion ver;
sts = MFXQueryVersion(session->session, &ver);
if (sts != MFX_ERR_NONE) {
RTC_LOG(LS_VERBOSE) << "Failed to MFXQueryVersion: sts=" << sts;
return nullptr;
}

RTC_LOG(LS_VERBOSE) << "Intel VPL Implementation: "
<< (impl == MFX_IMPL_SOFTWARE ? "SOFTWARE" : "HARDWARE");
RTC_LOG(LS_VERBOSE) << "Intel VPL Version: " << ver.Major << "." << ver.Minor;
return session;
}

mfxSession GetVplSession(std::shared_ptr<VplSession> session) {
return std::static_pointer_cast<VplSessionImpl>(session)->session;
}

} // namespace sora
17 changes: 17 additions & 0 deletions src/hwenc/src/hwenc_vpl/vpl_session_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef SORA_HWENC_VPL_VPL_SESSION_IMPL_H_
#define SORA_HWENC_VPL_VPL_SESSION_IMPL_H_

#include <iostream>

// Intel VPL
#include <vpl/mfxvideo++.h>

#include "sora/hwenc_vpl/vpl_session.h"

namespace sora {

mfxSession GetVplSession(std::shared_ptr<VplSession> session);

} // namespace sora

#endif
38 changes: 38 additions & 0 deletions src/hwenc/src/hwenc_vpl/vpl_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef SORA_HWENC_VPL_VPL_UTILS_H_
#define SORA_HWENC_VPL_VPL_UTILS_H_

// WebRTC
#include <api/video/video_codec_type.h>

// Intel VPL
#include <vpl/mfxdefs.h>

#define VPL_CHECK_RESULT(P, X, ERR) \
{ \
if ((X) > (P)) { \
RTC_LOG(LS_ERROR) << "Intel VPL Error: " << ERR; \
throw ERR; \
} \
}

namespace sora {

static mfxU32 ToMfxCodec(webrtc::VideoCodecType codec) {
return codec == webrtc::kVideoCodecVP8 ? MFX_CODEC_VP8
: codec == webrtc::kVideoCodecVP9 ? MFX_CODEC_VP9
: codec == webrtc::kVideoCodecH264 ? MFX_CODEC_AVC
: codec == webrtc::kVideoCodecH265 ? MFX_CODEC_HEVC
: MFX_CODEC_AV1;
}

static std::string CodecToString(mfxU32 codec) {
return codec == MFX_CODEC_VP8 ? "MFX_CODEC_VP8"
: codec == MFX_CODEC_VP9 ? "MFX_CODEC_VP9"
: codec == MFX_CODEC_AV1 ? "MFX_CODEC_AV1"
: codec == MFX_CODEC_AVC ? "MFX_CODEC_AVC"
: codec == MFX_CODEC_HEVC ? "MFX_CODEC_HEVC"
: "MFX_CODEC_UNKNOWN";
}

} // namespace sora
#endif
Loading