Skip to content

Commit

Permalink
Add cpu_used and g_threads options
Browse files Browse the repository at this point in the history
  • Loading branch information
varsill committed Feb 26, 2025
1 parent 6e4e5b9 commit cc7676b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 10 deletions.
9 changes: 9 additions & 0 deletions c_src/membrane_vpx_plugin/vpx_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ vpx_img_fmt_t translate_pixel_format(PixelFormat pixel_format) {
void apply_user_encoder_config(vpx_codec_enc_cfg_t *config, user_encoder_config *user_config) {
config->g_lag_in_frames = user_config->g_lag_in_frames;
config->rc_target_bitrate = user_config->rc_target_bitrate;
config->g_threads = user_config->g_threads;
}

UNIFEX_TERM create(
Expand All @@ -40,6 +41,7 @@ UNIFEX_TERM create(
unsigned int height,
PixelFormat pixel_format,
unsigned int encoding_deadline,
unsigned int cpu_used,
user_encoder_config user_config
) {
UNIFEX_TERM result;
Expand Down Expand Up @@ -72,6 +74,13 @@ UNIFEX_TERM create(
if (vpx_codec_enc_init(&state->codec_context, state->codec_interface, &config, 0)) {
return result_error(env, "Failed to initialize encoder", create_result_error, NULL, state);
}

vpx_codec_err_t res = vpx_codec_control(&state->codec_context, VP8E_SET_CPUUSED, cpu_used); // VP8E_SET_CPUUSED
// is valid for both VP8 and VP9 codecs ¯\_(ツ)_/¯
if(res != VPX_CODEC_OK){
return result_error(env, "Failed to set codec control cpu-used parameter", create_result_error, NULL, state);
}

if (!vpx_img_alloc(&state->img, translate_pixel_format(pixel_format), width, height, 1)) {
return result_error(
env, "Failed to allocate image", create_result_error, &state->codec_context, state
Expand Down
4 changes: 3 additions & 1 deletion c_src/membrane_vpx_plugin/vpx_encoder.spec.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ type encoded_frame :: %EncodedFrame{

type user_encoder_config :: %UserEncoderConfig{
g_lag_in_frames: unsigned,
rc_target_bitrate: unsigned
rc_target_bitrate: unsigned,
g_threads: unsigned
}

spec create(
Expand All @@ -23,6 +24,7 @@ spec create(
height :: unsigned,
pixel_format,
encoding_deadline :: unsigned,
cpu_used :: unsigned,
user_encoder_config
) :: {:ok :: label, state} | {:error :: label, reason :: atom}

Expand Down
18 changes: 18 additions & 0 deletions lib/membrane_vpx/encoder/vp8_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ defmodule Membrane.VP8.Encoder do
Note that this is a maximum value -- the encoder may produce frames
sooner than the given limit. If set to 0 this feature will be disabled.
"""
],
cpu_used: [
spec: non_neg_integer(),
default: 0,
description: """
A parameter used to balance between compression and performance.
Setting a lower value increases the encoding time but improves the quality and compression efficiency of the
output video. Setting a higher value speeds up the encoding at the cost of lower quality and large file sizes.
The parameter needs to be in range 0-15.
"""
],
g_threads: [
spec: pos_integer(),
default: 1,
description: """
Specifies how many OS threads can be used by the encoder.
"""
]

def_input_pad :input,
Expand Down
18 changes: 18 additions & 0 deletions lib/membrane_vpx/encoder/vp9_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ defmodule Membrane.VP9.Encoder do
Note that this is a maximum value -- the encoder may produce frames
sooner than the given limit. If set to 0 this feature will be disabled.
"""
],
cpu_used: [
spec: non_neg_integer(),
default: 0,
description: """
A parameter used to balance between compression and performance.
Setting a lower value increases the encoding time but improves the quality and compression efficiency of the
output video. Setting a higher value speeds up the encoding at the cost of lower quality and large file sizes.
The parameter needs to be in range 0-15.
"""
],
g_threads: [
spec: pos_integer(),
default: 1,
description: """
Specifies how many OS threads can be used by the encoder.
"""
]

def_input_pad :input,
Expand Down
21 changes: 14 additions & 7 deletions lib/membrane_vpx/encoder/vpx_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ defmodule Membrane.VPx.Encoder do

@type unprocessed_user_encoder_config :: %{
g_lag_in_frames: non_neg_integer(),
rc_target_bitrate: pos_integer() | :auto
rc_target_bitrate: pos_integer() | :auto,
g_threads: pos_integer()
}
@type user_encoder_config :: %{
g_lag_in_frames: non_neg_integer(),
rc_target_bitrate: pos_integer()
rc_target_bitrate: pos_integer(),
g_threads: pos_integer()
}

@type encoded_frame :: %{payload: binary(), pts: non_neg_integer(), is_keyframe: boolean()}
Expand All @@ -28,10 +30,11 @@ defmodule Membrane.VPx.Encoder do
encoding_deadline: non_neg_integer() | :auto,
user_encoder_config: Membrane.VPx.Encoder.unprocessed_user_encoder_config(),
encoder_ref: reference() | nil,
force_next_keyframe: boolean()
force_next_keyframe: boolean(),
cpu_used: non_neg_integer()
}

@enforce_keys [:codec, :codec_module, :encoding_deadline, :user_encoder_config]
@enforce_keys [:codec, :codec_module, :encoding_deadline, :user_encoder_config, :cpu_used]
defstruct @enforce_keys ++
[
encoder_ref: nil,
Expand All @@ -54,8 +57,10 @@ defmodule Membrane.VPx.Encoder do
encoding_deadline: opts.encoding_deadline,
user_encoder_config: %{
g_lag_in_frames: opts.g_lag_in_frames,
rc_target_bitrate: opts.rc_target_bitrate
}
rc_target_bitrate: opts.rc_target_bitrate,
g_threads: opts.g_threads
},
cpu_used: opts.cpu_used
}

{[], state}
Expand Down Expand Up @@ -141,6 +146,7 @@ defmodule Membrane.VPx.Encoder do
height,
pixel_format,
encoding_deadline,
state.cpu_used,
user_encoder_config
)

Expand All @@ -165,7 +171,8 @@ defmodule Membrane.VPx.Encoder do

%{
g_lag_in_frames: user_encoder_config.g_lag_in_frames,
rc_target_bitrate: rc_target_bitrate
rc_target_bitrate: rc_target_bitrate,
g_threads: user_encoder_config.g_threads
}
end

Expand Down
21 changes: 19 additions & 2 deletions lib/membrane_vpx/encoder/vpx_encoder_native.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,27 @@ defmodule Membrane.VPx.Encoder.Native do
pos_integer(),
Membrane.RawVideo.pixel_format(),
non_neg_integer(),
non_neg_integer(),
Membrane.VPx.Encoder.user_encoder_config()
) :: reference()
def create!(codec, width, height, pixel_format, encoding_deadline, user_encoder_config) do
case create(codec, width, height, pixel_format, encoding_deadline, user_encoder_config) do
def create!(
codec,
width,
height,
pixel_format,
encoding_deadline,
cpu_used,
user_encoder_config
) do
case create(
codec,
width,
height,
pixel_format,
encoding_deadline,
cpu_used,
user_encoder_config
) do
{:ok, decoder_ref} -> decoder_ref
{:error, reason} -> raise "Failed to create native encoder: #{inspect(reason)}"
end
Expand Down

0 comments on commit cc7676b

Please sign in to comment.