Skip to content
Open
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
3 changes: 2 additions & 1 deletion fluster/decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from abc import ABC, abstractmethod
from functools import lru_cache
from shutil import which
from typing import List, Optional, Type
from typing import Any, Dict, List, Optional, Type

from fluster.codec import Codec, OutputFormat
from fluster.utils import normalize_binary_cmd
Expand Down Expand Up @@ -47,6 +47,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
raise Exception("Not implemented")
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/av1_aom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -38,6 +39,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
fmt = "--rawvideo"
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/av1_dav1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -37,6 +38,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
fmt = "yuv"
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/chromium.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# License along with this library. If not, see <https://www.gnu.org/licenses/>.

from functools import lru_cache
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand Down Expand Up @@ -50,6 +51,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
return str(main(input_filepath))

Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/cros_codecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -38,6 +39,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""

Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -36,5 +37,6 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
return file_checksum(input_filepath)
8 changes: 7 additions & 1 deletion fluster/decoders/ffmpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import re
import subprocess
from functools import lru_cache
from typing import Dict, Optional, Tuple
from typing import Any, Dict, Optional, Tuple

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand Down Expand Up @@ -70,6 +70,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
command = [self.binary, "-hide_banner", "-nostdin"]
Expand Down Expand Up @@ -99,6 +100,11 @@ def decode(
elif self.ffmpeg_codec:
command.extend(["-codec", self.ffmpeg_codec])

# Optional decoder parameters
if optional_params:
for key, value in optional_params.items():
command.extend([key, str(value)])

# Input file
command.extend(["-i", input_filepath])

Expand Down
16 changes: 13 additions & 3 deletions fluster/decoders/gstreamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import shlex
import subprocess
from functools import lru_cache
from typing import List, Optional
from typing import Any, Dict, List, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand Down Expand Up @@ -109,14 +109,21 @@ def gen_pipeline(
input_filepath: str,
output_filepath: Optional[str],
output_format: OutputFormat,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Generate the GStreamer pipeline used to decode the test vector"""
output = f"location={output_filepath}" if output_filepath else ""

decoder_params = ""
if optional_params:
for key, value in optional_params.items():
decoder_params += f" {key}={value} "
Copy link
Contributor

@ylatuya ylatuya Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional parameter names and values can't be translated 1-to-1 to an implementation's property name and value.

If a test vector requires a parameter to be configured, there is no guarantee that the ffmpeg and gstreamer decoders for that codec will use the same property name. The mapping from the optional parameter key name to the property name must be done in the decoder's implementation.

Let's imagine there is a test vector for AV1 that requires enabling a feature named cool_feature. The test vector will define cool_feature = true. The ffmpeg av1 decoder will map this into enable_cool_feature = 1 and the GStreamer AV1 decoder will map this into cool_feature_enabled = True.

The mapping from optional_params into a decoder property must be done in the decoder implementation, not in a generic way in the base class.


return PIPELINE_TPL.format(
self.cmd,
input_filepath,
self.parser if self.parser else "parsebin",
self.decoder_bin,
self.decoder_bin + decoder_params,
self.caps,
self.sink,
output,
Expand Down Expand Up @@ -149,6 +156,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decode the test vector and do the checksum"""
# When using videocodectestsink we can avoid writing files to disk
Expand All @@ -162,7 +170,7 @@ def decode(
data = run_command_with_output(command, timeout=timeout, verbose=verbose).splitlines()
return self.parse_videocodectestsink_md5sum(data)

pipeline = self.gen_pipeline(input_filepath, output_filepath, output_format)
pipeline = self.gen_pipeline(input_filepath, output_filepath, output_format, optional_params)
run_command(shlex.split(pipeline), timeout=timeout, verbose=verbose)
return file_checksum(output_filepath)

Expand Down Expand Up @@ -193,6 +201,7 @@ def gen_pipeline(
input_filepath: str,
output_filepath: Optional[str],
output_format: OutputFormat,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
raw_caps = "video/x-raw"
try:
Expand Down Expand Up @@ -785,6 +794,7 @@ def gen_pipeline(
input_filepath: str,
output_filepath: Optional[str],
output_format: OutputFormat,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
caps = f"{self.caps} ! videoconvert dither=none ! video/x-raw,format={output_format_to_gst(output_format)}"
output = f"location={output_filepath}" if output_filepath else ""
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/h264_jct_vt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -38,6 +39,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
run_command(
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/h265_jct_vt.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -38,6 +39,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
run_command(
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/h266_vvc_vtm.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -37,6 +38,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
# pylint: disable=unused-argument
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/h266_vvdec.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -37,6 +38,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
run_command(
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/iso_mpeg2_aac.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
import glob
import os
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -40,6 +41,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
# Addition of .pcm as extension is a must. If it is something else, e.g. ".out" the decoder will output a
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/iso_mpeg2_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import glob
import os
import tempfile
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -41,6 +42,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
with tempfile.TemporaryDirectory() as temp_dir:
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/iso_mpeg4_aac.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# License along with this library. If not, see <https://www.gnu.org/licenses/>.

import glob
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -40,6 +41,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
# Addition of .pcm as extension is a must. If it is something else, e.g. ".out" the decoder will output a
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/iso_mpeg4_aac_er.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# License along with this library. If not, see <https://www.gnu.org/licenses/>.

import glob
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -40,6 +41,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
output_filepath += ".raw"
Expand Down
3 changes: 2 additions & 1 deletion fluster/decoders/iso_mpeg4_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
import os
import subprocess
from typing import Tuple
from typing import Any, Dict, Optional, Tuple

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -41,6 +41,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath to output_filepath"""
width, height = self._get_video_resolution(input_filepath, verbose)
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/libvpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand Down Expand Up @@ -42,6 +43,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
fmt = None
Expand Down
2 changes: 2 additions & 0 deletions fluster/decoders/vk_video_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <https://www.gnu.org/licenses/>.
from typing import Any, Dict, Optional

from fluster.codec import Codec, OutputFormat
from fluster.decoder import Decoder, register_decoder
Expand All @@ -38,6 +39,7 @@ def decode(
timeout: int,
verbose: bool,
keep_files: bool,
optional_params: Optional[Dict[str, Any]] = None,
) -> str:
"""Decodes input_filepath in output_filepath"""
codec_mapping = {
Expand Down
1 change: 1 addition & 0 deletions fluster/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def _execute_decode(self) -> str:
self.timeout,
self.verbose,
keep_files_for_decode,
self.test_vector.optional_params,
)

def _cleanup_if_needed(self) -> None:
Expand Down
Loading