Skip to content

Commit 7f3942c

Browse files
committed
feat: add reference encoder for av1 and vp9
1 parent a2aea32 commit 7f3942c

File tree

6 files changed

+136
-8
lines changed

6 files changed

+136
-8
lines changed

Makefile

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
CONTRIB_DIR=contrib
22
DECODERS_DIR=decoders
3+
ENCODERS_DIR=encoders
34
SOOTHE=python3 ./soothe.py
45
CMAKE_GENERATOR=Unix Makefiles
56

@@ -15,9 +16,9 @@ check: ## check that very basic tests run
1516
$(SOOTHE) run -e dummy
1617

1718

18-
create_dirs=mkdir -p $(CONTRIB_DIR) $(DECODERS_DIR)
19+
create_dirs=mkdir -p $(CONTRIB_DIR) $(DECODERS_DIR) $(ENCODERS_DIR)
1920

20-
all_reference_decoders: h264_reference_decoder h265_reference_decoder av1_reference_decoder vp9_reference_decoder ## build all reference decoders
21+
all_reference_decoders: h264_reference_decoder h265_reference_decoder av1_reference_codec vp9_reference_codec ## build all reference decoders
2122

2223
h265_reference_decoder: ## build H.265 reference decoder
2324
$(create_dirs)
@@ -33,18 +34,20 @@ h264_reference_decoder: ## build H.264 reference decoder
3334
cd $(CONTRIB_DIR)/JM && cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Wno-stringop-truncation -Wno-stringop-overflow" && $(MAKE) -C build ldecod
3435
find $(CONTRIB_DIR)/JM/bin/umake -name "ldecod" -type f -exec cp {} $(DECODERS_DIR)/ \;
3536

36-
av1_reference_decoder: ## build AV1 reference decoder
37+
av1_reference_codec: ## build AV1 reference decoder and encoder
3738
$(create_dirs)
3839
cd $(CONTRIB_DIR) && git clone --branch=v3.12.1 https://aomedia.googlesource.com/aom --depth=1 || true
3940
cd $(CONTRIB_DIR)/aom && git stash && git pull && git stash apply || true
40-
cd $(CONTRIB_DIR)/aom && cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -Wno-stringop-overflow && $(MAKE) -j -C build aomdec
41+
cd $(CONTRIB_DIR)/aom && cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -Wno-stringop-overflow && $(MAKE) -j -C build
42+
find $(CONTRIB_DIR)/ -name "aomenc" -type f -exec cp {} $(ENCODERS_DIR)/ \;
4143
find $(CONTRIB_DIR)/ -name "aomdec" -type f -exec cp {} $(DECODERS_DIR)/ \;
4244

43-
vp9_reference_decoder: ## build VP9 reference decoder
45+
vp9_reference_codec: ## build VP9 reference decoder and encoder
4446
$(create_dirs)
4547
cd $(CONTRIB_DIR) && git clone --branch=v1.15.2 https://chromium.googlesource.com/webm/libvpx --depth=1 || true
4648
cd $(CONTRIB_DIR)/libvpx && git stash && git pull && git stash apply || true
4749
cd $(CONTRIB_DIR)/libvpx && ./configure --disable-unit-tests --enable-vp9 && $(MAKE) -j
50+
find $(CONTRIB_DIR)/libvpx -name "vpxenc" -type f -exec cp {} $(ENCODERS_DIR)/ \;
4851
find $(CONTRIB_DIR)/libvpx -name "vpxdec" -type f -exec cp {} $(DECODERS_DIR)/ \;
4952

5053
clean: ## remove contrib temporary folder
@@ -53,5 +56,5 @@ clean: ## remove contrib temporary folder
5356
dbg-%:
5457
echo "Value of $* = $($*)"
5558

56-
.PHONY: help all_reference_decoders h264_reference_decoder h265_reference_decoder av1_reference_decoder vp9_reference_decoder \
59+
.PHONY: help all_reference_decoders h264_reference_decoder h265_reference_decoder av1_reference_codec vp9_reference_codec \
5760
check install_deps clean

soothe/encoder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Encoder(NamedClass):
3737
description: str = ""
3838
binary: str = ""
3939
file_extension = ".bin"
40+
is_reference: bool = False
4041

4142
def __init__(self) -> None:
4243
if self.binary:

soothe/encoders/av1_aom.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Soothe - testing framework for encoders quality
2+
# Copyright (C) 2020, Fluendo, S.A.
3+
# Author: Pablo Marcos Oltra <[email protected]>, Fluendo, S.A.
4+
# Copyright (C) 2025, Igalia, S.L.
5+
# Author: Stéphane Cerveau <[email protected]>
6+
#
7+
# This library is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU Lesser General Public License
9+
# as published by the Free Software Foundation, either version 3
10+
# of the License, or (at your option) any later version.
11+
#
12+
# This library is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
# Lesser General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser General Public
18+
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
19+
20+
"""Module for AV1 reference encoder"""
21+
22+
from ..codec import Codec
23+
from ..encoder import Encoder, register_encoder
24+
from ..utils import run_command
25+
26+
27+
@register_encoder
28+
class AV1AOMEncoder(Encoder):
29+
"""libaom AV1 reference encoder implementation"""
30+
encoder_name = "libaom-AV1"
31+
codec = Codec.AV1
32+
description = "libaom AV1 reference encoder"
33+
binary = "aomenc"
34+
is_reference = True
35+
file_extension = ".webm"
36+
37+
def encode(
38+
self,
39+
input_file: str,
40+
output_file: str,
41+
timeout: int,
42+
verbose: bool,
43+
):
44+
"""Encodes input_file in output_file"""
45+
46+
cmd = [
47+
self.binary,
48+
"--webm", # Output WebM format
49+
"--cpu-used=4", # Speed vs quality trade-off
50+
"--end-usage=q", # Constant quality mode
51+
"--cq-level=30", # Quality level
52+
"--threads=4", # Number of threads
53+
"-o",
54+
output_file,
55+
input_file,
56+
]
57+
58+
run_command(cmd, timeout=timeout, verbose=verbose)

soothe/encoders/vp9_vpx.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Soothe - testing framework for encoders quality
2+
# Copyright (C) 2020, Fluendo, S.A.
3+
# Author: Pablo Marcos Oltra <[email protected]>, Fluendo, S.A.
4+
# Copyright (C) 2025, Igalia, S.L.
5+
# Author: Stéphane Cerveau <[email protected]>
6+
#
7+
# This library is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU Lesser General Public License
9+
# as published by the Free Software Foundation, either version 3
10+
# of the License, or (at your option) any later version.
11+
#
12+
# This library is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
# Lesser General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser General Public
18+
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
19+
20+
"""Module for VP9 reference encoder"""
21+
22+
from ..codec import Codec
23+
from ..encoder import Encoder, register_encoder
24+
from ..utils import run_command
25+
26+
27+
@register_encoder
28+
class VP9VPXEncoder(Encoder):
29+
"""libvpx VP9 reference encoder implementation"""
30+
encoder_name = "libvpx-VP9"
31+
codec = Codec.VP9
32+
description = "libvpx VP9 reference encoder"
33+
binary = "vpxenc"
34+
is_reference = True
35+
file_extension = ".webm"
36+
37+
def encode(
38+
self,
39+
input_file: str,
40+
output_file: str,
41+
timeout: int,
42+
verbose: bool,
43+
):
44+
"""Encodes input_file in output_file"""
45+
46+
cmd = [
47+
self.binary,
48+
"--codec=vp9", # Use VP9 codec
49+
"--good", # Good quality mode
50+
"--cpu-used=4", # Speed vs quality trade-off
51+
"--end-usage=q", # Constant quality mode
52+
"--cq-level=30", # Quality level
53+
"--threads=4", # Number of threads
54+
"--webm",
55+
"-o",
56+
output_file,
57+
input_file,
58+
]
59+
60+
run_command(cmd, timeout=timeout, verbose=verbose)

soothe/main.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Main: # pylint: disable=too-few-public-methods
4747
"""Main class for Soothe"""
4848

4949
def __init__(self) -> None:
50+
self.encoders_dir = ENCODERS_DIR
5051
self.decoders_dir = DECODERS_DIR
5152
self.assets_dir = os.path.join(os.path.dirname(__file__), '..',
5253
ASSETS_DIR)
@@ -56,9 +57,12 @@ def __init__(self) -> None:
5657

5758
self.args = self._create_argument_parser()
5859

59-
# Prepend to the PATH the decoders_dir so that we can run them
60+
# Prepend to the PATH the encoders_dir and decoders_dir so that we can
61+
# run them
6062
# without having to set the env for every single command
61-
os.environ["PATH"] = self.decoders_dir + os.path.pathsep + os.environ["PATH"]
63+
os.environ["PATH"] = (self.encoders_dir + os.path.pathsep +
64+
self.decoders_dir + os.path.pathsep +
65+
os.environ["PATH"])
6266

6367
def run(self) -> None:
6468
"""Run Soothe"""

soothe/soothe.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ def list_encoders(
257257
print('\nList of available encoders:')
258258
for encoder in ENCODERS:
259259
string = f'{encoder}'
260+
if hasattr(encoder, 'is_reference') and encoder.is_reference:
261+
string += ' [REFERENCE]'
260262
if check:
261263
string += ' … ' + (
262264
'✓' if encoder.check(verbose) else '𐄂'

0 commit comments

Comments
 (0)