Skip to content
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
2 changes: 1 addition & 1 deletion docs/guide/advanced/video-codecs.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ PeerConnectionFactory factory = PeerConnectionFactory.builder()

Hardware encoders produce a single layer. A stream that asks for SVC, such as an AV1 stream with a scalability mode like `L1T3`, is encoded in software.

VP9 can be encoded in hardware too, with the VP9 encoder of the GPU driver, which Intel GPUs have: through Media Foundation on Windows and VA-API on Linux. It is off by default, since it has not been tested on such a GPU yet; turn it on with a system property before the factory is created:
VP9 can be encoded in hardware too, with the VP9 encoder of the GPU driver, which Intel GPUs have: through VA-API on Linux, and through Media Foundation on Windows. On Windows it is off by default, since it has not been tested on such a GPU yet; turn it on with a system property before the factory is created:

```java
System.setProperty("webrtc.hardware.vp9Encoder", "true");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@

namespace jni
{
// The Java system property that turns on hardware VP9 encoding, which is
// off by default: only Intel GPUs encode VP9, and the encoder has not been
// tested on one.
// The Java system property that turns on hardware VP9 encoding on
// Windows, which is off by default: only Intel GPUs encode VP9, and the
// Media Foundation encoder has not been tested on one. VA-API encodes VP9
// on Linux regardless.
constexpr const char * kHardwareVp9EncoderProperty = "webrtc.hardware.vp9Encoder";

// Whether hardware VP9 encoding is turned on: the Java system property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ namespace jni
// Creates VA-API encoders on the GPU whose driver encodes H.264, as Intel
// and AMD drivers do. It offers H.264 in the profiles WebRTC's software
// encoder offers too, and only with packetization mode 1: mode 0 needs
// each NAL unit to fit a packet. It offers H.265 Main as well where the
// driver encodes it, and VP9 profile 0 where the driver encodes it and
// hardware VP9 encoding is turned on.
// each NAL unit to fit a packet. It offers H.265 Main and VP9 profile 0
// as well where the driver encodes them.
class VaapiVideoEncoderFactory : public webrtc::VideoEncoderFactory
{
public:
// Returns a factory, or null if no GPU driver encodes H.264
// through VA-API.
static std::unique_ptr<VaapiVideoEncoderFactory> Create(bool vp9Enabled);
static std::unique_ptr<VaapiVideoEncoderFactory> Create();

~VaapiVideoEncoderFactory() override = default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/

#include "media/video/codec/HardwareCodecOptions.h"
#include "media/video/codec/HardwareVideoDecoderFactory.h"
#include "media/video/codec/HardwareVideoEncoderFactory.h"
#include "media/video/codec/linux/VaapiVideoDecoderFactory.h"
Expand All @@ -33,10 +32,7 @@ namespace jni
if (auto nvenc = NvencVideoEncoderFactory::Create()) {
factories.push_back(std::move(nvenc));
}
// VP9 only if asked for: it has not been tested on an Intel GPU yet.
auto vaapi = VaapiVideoEncoderFactory::Create(IsHardwareVp9EncoderEnabled());

if (vaapi) {
if (auto vaapi = VaapiVideoEncoderFactory::Create()) {
factories.push_back(std::move(vaapi));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

namespace jni
{
std::unique_ptr<VaapiVideoEncoderFactory> VaapiVideoEncoderFactory::Create(bool vp9Enabled)
std::unique_ptr<VaapiVideoEncoderFactory> VaapiVideoEncoderFactory::Create()
{
VaapiLibrary * library = VaapiLibrary::Get();

Expand All @@ -39,13 +39,10 @@ namespace jni
const bool h265 = library->EncodeEntrypoint(VAProfileHEVCMain, &h265Entrypoint);

VAEntrypoint vp9Entrypoint = VAEntrypointEncSlice;
const bool vp9 = vp9Enabled && library->EncodeEntrypoint(VAProfileVP9Profile0, &vp9Entrypoint);
const bool vp9 = library->EncodeEntrypoint(VAProfileVP9Profile0, &vp9Entrypoint);

RTC_LOG(LS_INFO) << "VA-API (" << library->Vendor() << ") H.265 encoding: " << h265;

if (vp9Enabled) {
RTC_LOG(LS_INFO) << "VA-API (" << library->Vendor() << ") VP9 encoding: " << vp9;
}
RTC_LOG(LS_INFO) << "VA-API (" << library->Vendor() << ") H.265 encoding: " << h265 << ", VP9 encoding: "
<< vp9;

return std::unique_ptr<VaapiVideoEncoderFactory>(
new VaapiVideoEncoderFactory(*library, h265, h265Entrypoint, vp9, vp9Entrypoint));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@
* stream that asks for SVC is encoded in software. H.265 (Main profile) is
* encoded with NVENC or Media Foundation on GPUs that have an H.265 encoder.
* VP9 (profile 0) is encoded on GPUs that have a VP9 encoder, which are
* Intel's, with Media Foundation on Windows and VA-API on Linux, but only
* with the system property
* {@code webrtc.hardware.vp9Encoder} set to {@code true} when the factory is
* created: the encoder has not been tested on such a GPU yet. Without it, VP9
* is encoded with libvpx. On Linux, H.265 is encoded with NVENC on NVIDIA
* Intel's: with VA-API on Linux, and with Media Foundation on Windows only
* with the system property {@code webrtc.hardware.vp9Encoder} set to
* {@code true} when the factory is created, since that encoder has not been
* tested on such a GPU yet. Otherwise VP9 is encoded with libvpx. On Linux, H.265 is encoded with NVENC on NVIDIA
* GPUs and with VA-API on the GPUs of Intel and AMD whose driver encodes it.
* A hardware encoder that fails to start, for example because the GPU has no
* encoder sessions left, or fails while encoding, is replaced by the next one
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ private PeerConnectionFactory hardwareCallFactory() {

@Test
void vp9HardwareEncodingIsOptIn() throws Exception {
assumeTrue(OS.contains("win") || OS.contains("linux"),
"hardware encoders are implemented on Windows and Linux only");
// On Linux, VA-API encodes VP9 without it.
assumeTrue(OS.contains("win"), "hardware VP9 encoding is opt-in on Windows only");
assumeTrue(System.getProperty(VP9_ENCODER_PROPERTY) == null, VP9_ENCODER_PROPERTY + " is set");

PeerConnectionFactory hardware = hardwareFactory();
Expand Down
Loading