From c1fc20e5b0cf04e6568a7f7dd5ecf7cc99a1f45a Mon Sep 17 00:00:00 2001 From: baconyao Date: Fri, 19 Jul 2024 16:42:29 +0800 Subject: [PATCH 1/7] Initialize the scenraio of gst_v4l2_audio_video_synchronization --- .../bin/gst_resources_generator.py | 29 +++ .../gst_v4l2_audio_video_synchronization.py | 188 ++++++++++++++++++ .../video-codec-test-confs/genio-1200.json | 14 +- .../units/video-codec/jobs.pxu | 27 +++ .../units/video-codec/test-plan.pxu | 3 + 5 files changed, 260 insertions(+), 1 deletion(-) create mode 100755 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py index 78ee8af43b..4fe05d7ff7 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py @@ -61,6 +61,9 @@ def register_arguments() -> argparse.Namespace: class GstResources: + + VIDEO_GOLDEN_SAMPLES = "video_golden_samples" + def __init__(self, args: argparse.Namespace) -> None: self._args = args try: @@ -135,6 +138,32 @@ def gst_v4l2_video_decoder_md5_checksum_comparison( ] ) + def gst_v4l2_audio_video_synchronization( + self, scenario_data: Dict + ) -> None: + # TODO: check if there's desktop environment + has_desktop_env = True + video_sink = ( + scenario_data["video_sinks"]["desktop"] + if has_desktop_env + else scenario_data["video_sinks"]["non_desktop"] + ) + for item in scenario_data["cases"]: + for sample_file in item["golden_sample_files"]: + self._resource_items.append( + { + "scenario": self._current_scenario_name, + "video_sink": video_sink, + "decoder_plugin": item["decoder_plugin"], + "golden_sample_file_name": sample_file, + "golden_sample_file": os.path.join( + self._args.video_codec_testing_data_path, + self.VIDEO_GOLDEN_SAMPLES, + sample_file, + ), + } + ) + def main(self): for scenario in self._scenarios: self._current_scenario_name = scenario diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py new file mode 100755 index 0000000000..3aacadd9ec --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python3 +# This file is part of Checkbox. +# +# Copyright 2024 Canonical Ltd. +# Written by: +# Patrick Chang +# +# Checkbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. +# +# Checkbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Checkbox. If not, see . + +import argparse +import logging +import os +import shlex +import subprocess +from typing import Any + +logging.basicConfig(level=logging.INFO) + + +def register_arguments(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=( + "Script helps playing a golden sample video on specific display" + ' by the specific "video sink", e.g. waylandsink. The golden ' + "is special video for verifying AV Synchronization." + ), + ) + + parser.add_argument( + "-gp", + "--golden_sample_path", + required=True, + type=str, + help="Path of Golden Sample file", + ) + + parser.add_argument( + "-dp", + "--decoder_plugin", + required=True, + type=str, + help="Decoder plugin be used in gstreamer pipeline e.g. v4l2h264dec", + ) + + parser.add_argument( + "-vs", + "--video_sink", + default="waylandsink", + type=str, + help=( + "Specific value of video-sink for gstreamer that a video can be" + " displayed on. (Default: waylandsink)" + ), + ) + + args = parser.parse_args() + return args + + +def build_gst_command( + gst_bin: str, golden_sample_path: str, decoder: str, video_sink: str +) -> str: + """ + Builds a GStreamer command to process the golden sample. + + :param gst_bin: + The binary name of gstreamer. Default is "gst-launch-1.0" + You can assign the snap name to GST_LAUNCH_BIN env variable if you + want to using snap. + :param golden_sample: + The path to the golden sample file. + :param decoder: + The decoder to use for the video, e.g., "v4l2vp8dec", "v4l2vp9dec". + :param video_sink: + The specific sink for video displaying on, e.g. "waylandsink" + + :returns: + The GStreamer command to execute. + """ + + # FIXME: Why we did this? + # Because the 4K.mp4 golden sample need a special colorimetry "bt2020" + # that needs special pipeline configuration to get it streaming smoothly. + if golden_sample_path.endswith("4K.mp4"): + decoder = ( + "capssetter replace=true " + 'caps="video/x-h264, stream-format=(string)byte-stream, ' + "alignment=(string)au, level=(string)5.2, profile=(string)main, " + "width=(int)3840, height=(int)2160, framerate=(fraction)24/1, " + "pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)bt2020, " + "chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, " + 'bit-depth-chroma=(uint)8, parsed=(boolean)true" ! {}' + ).format(decoder) + + cmd = ( + "{} -v filesrc location={} ! qtdemux name=demux demux.video_0 !" + " queue ! parsebin ! {} ! v4l2convert " + "output-io-mode=dmabuf-import capture-io-mode=dmabuf ! {} " + "demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample !" + " autoaudiosink" + ).format(gst_bin, golden_sample_path, decoder, video_sink) + + return cmd + + +def execute_command(cmd: str, timeout: int = 30) -> None: + """ + Executes the GStreamer command to play video. + + :param cmd: + The GStreamer command to execute. + """ + try: + logging.info("Starting command: '{}'".format(cmd)) + ret = subprocess.run( + shlex.split(cmd), + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="utf-8", + timeout=timeout, + ) + logging.info(ret.stdout) + except subprocess.TimeoutExpired: + # Ignore the timeout exception because some golden samples's length is + # too long + pass + except Exception as e: + logging.error(e.stderr) + raise SystemExit(e.returncode) + + +def play_video_for_av_synchronization_test(args: Any) -> None: + """ + This function performs the following steps: + + 1. Checks if the golden sample file exists. + 2. Builds a GStreamer command to process the golden sample using the + specified decoder and video sink. + 3. Executes the GStreamer command. + + :param args: + An object containing the following attributes: + - `golden_sample_path` (str): The path to the golden sample file. + - `decoder_plugin` (str): The video decoder to use, e.g., + "v4l2vp8dec", "v4l2vp9dec". + - `video_sink` (str): The specific sink for video displaying on, + e.g. "waylandsink + + :raises SystemExit: + If the golden sample file or the golden MD5 checksum file does not + exist, or if the extracted MD5 checksum does not match the golden MD5 + checksum. + """ + # Check the golden sample exists + if not os.path.exists(args.golden_sample_path): + raise SystemExit( + "Golden Sample '{}' doesn't exist".format(args.golden_sample_path) + ) + gst_launch_bin = os.getenv("GST_LAUNCH_BIN", "gst-launch-1.0") + cmd = build_gst_command( + gst_bin=gst_launch_bin, + golden_sample_path=args.golden_sample_path, + decoder=args.decoder_plugin, + video_sink=args.video_sink, + ) + # The video will be displayed on the real display + execute_command(cmd) + + +def main() -> None: + args = register_arguments() + play_video_for_av_synchronization_test(args) + + +if __name__ == "__main__": + main() diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json index ee5d5f4b0c..2d8cbf53e4 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json @@ -24,6 +24,18 @@ "color_spaces": ["YUV"], "source_format": "webm" } - ] + ], + "gst_v4l2_audio_video_synchronization": { + "video_sinks": { + "desktop": "waylandsink", + "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + }, + "cases": [ + { + "decoder_plugin": "v4l2h264dec", + "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + } + ] + } } diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu index b1ad933470..76c8e769fe 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu @@ -27,3 +27,30 @@ flags: also-after-suspend environ: GST_LAUNCH_BIN command: gst_v4l2_video_decoder_md5_checksum_comparison.py -dp {{decoder_plugin}} -cs {{color_space}} -gp {{golden_sample_file}} -gmp {{golden_md5_checkum_file}} + +unit: template +template-engine: jinja2 +template-resource: video_codec_resource +template-filter: video_codec_resource.scenario == "gst_v4l2_audio_video_synchronization" +template-unit: job +template-id: ce-oem-video-codec/gst_v4l2_audio_video_synchronization +_template-summary: To check if the relative timing of audio and video is synchronized under a specific decoder +id: ce-oem-video-codec/{{ scenario }}-{{ decoder_plugin }}-{{ golden_sample_file_name }}-{{ video_sink }} +_summary: AV-Sync test of decoder {{ decoder_plugin }} with {{ golden_sample_file_name }} file +_purpose: To check if the relative timing of audio and video of {{ golden_sample_file_name }} file is synchronized under a specific {{ decoder_plugin }} decoder +plugin: user-interact-verify +category_id: video-codec +estimated_duration: 30s +imports: from com.canonical.plainbox import manifest +requires: manifest.has_video_codec == 'True' +flags: also-after-suspend +environ: GST_LAUNCH_BIN +_steps: + 1. Plug a headset/earphone to the device + 2. Adjust the audio sink to be headset via Gnome Settings or command + 3. Press enter to perform test +_verification: + Do you hear the beep sound and see the video be displayed? + Is the timing of audio and video synchronized? +command: + gst_v4l2_audio_video_synchronization.py -dp {{decoder_plugin}} -gp {{golden_sample_file}} -vs {{video_sink}} diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/test-plan.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/test-plan.pxu index fc43ebe1bc..7b346f7824 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/test-plan.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/test-plan.pxu @@ -11,7 +11,10 @@ id: ce-oem-video-codec-manual unit: test plan _name: Video Codec manual tests _description: Manual tests for Video Codec in before suspend and post suspend stage +bootstrap_include: + video_codec_resource include: + ce-oem-video-codec/gst_v4l2_audio_video_synchronization id: ce-oem-video-codec-automated unit: test plan From 2eb0773eaed214555b18f4bbf9d2b68ef4a665a7 Mon Sep 17 00:00:00 2001 From: baconyao Date: Mon, 22 Jul 2024 10:27:59 +0800 Subject: [PATCH 2/7] Add data json for 350, 510 and 700 platforms --- .../data/video-codec-test-confs/genio-350.json | 14 ++++++++++++++ .../data/video-codec-test-confs/genio-510.json | 15 +++++++++++++++ .../data/video-codec-test-confs/genio-700.json | 15 +++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json create mode 100644 contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json new file mode 100644 index 0000000000..1a48243e67 --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json @@ -0,0 +1,14 @@ +{ + "gst_v4l2_audio_video_synchronization": { + "video_sinks": { + "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + }, + "cases": [ + { + "decoder_plugin": "v4l2h264dec", + "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4"] + } + ] + } +} + diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json new file mode 100644 index 0000000000..15fd1eb52a --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json @@ -0,0 +1,15 @@ +{ + "gst_v4l2_audio_video_synchronization": { + "video_sinks": { + "desktop": "waylandsink", + "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + }, + "cases": [ + { + "decoder_plugin": "v4l2h264dec", + "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + } + ] + } +} + diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json new file mode 100644 index 0000000000..15fd1eb52a --- /dev/null +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json @@ -0,0 +1,15 @@ +{ + "gst_v4l2_audio_video_synchronization": { + "video_sinks": { + "desktop": "waylandsink", + "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + }, + "cases": [ + { + "decoder_plugin": "v4l2h264dec", + "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + } + ] + } +} + From dc75376677c1bc0f06b405734925d177419fc5d6 Mon Sep 17 00:00:00 2001 From: baconyao Date: Tue, 23 Jul 2024 13:16:26 +0800 Subject: [PATCH 3/7] Check has desktop environment from checkbox_support --- .../checkbox-provider-ce-oem/bin/gst_resources_generator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py index 4fe05d7ff7..4bb0ba0959 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py @@ -22,6 +22,7 @@ import json import logging from typing import Dict, List +from checkbox_support.scripts.image_checker import has_desktop_environment logging.basicConfig(level=logging.INFO) @@ -84,6 +85,7 @@ def __init__(self, args: argparse.Namespace) -> None: raise SystemExit("{}".format(e)) self._current_scenario_name = "" self._resource_items = [] + self._has_desktop_environment = has_desktop_environment() def _v4l2_video_decoder_md5_checksum_comparison_helper( self, @@ -141,11 +143,9 @@ def gst_v4l2_video_decoder_md5_checksum_comparison( def gst_v4l2_audio_video_synchronization( self, scenario_data: Dict ) -> None: - # TODO: check if there's desktop environment - has_desktop_env = True video_sink = ( scenario_data["video_sinks"]["desktop"] - if has_desktop_env + if self._has_desktop_environment else scenario_data["video_sinks"]["non_desktop"] ) for item in scenario_data["cases"]: From f64b0836e31556fbab939b8d1c7a071c8d3af7ac Mon Sep 17 00:00:00 2001 From: baconyao Date: Mon, 29 Jul 2024 09:42:16 +0800 Subject: [PATCH 4/7] Fix the option of video sinks --- .../bin/gst_resources_generator.py | 14 +++++++++----- .../data/video-codec-test-confs/genio-1200.json | 5 +++-- .../data/video-codec-test-confs/genio-350.json | 3 ++- .../data/video-codec-test-confs/genio-510.json | 5 +++-- .../data/video-codec-test-confs/genio-700.json | 5 +++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py index 4bb0ba0959..159ffa2d72 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py @@ -23,6 +23,7 @@ import logging from typing import Dict, List from checkbox_support.scripts.image_checker import has_desktop_environment +from checkbox_support.snap_utils.system import on_ubuntucore logging.basicConfig(level=logging.INFO) @@ -143,11 +144,14 @@ def gst_v4l2_video_decoder_md5_checksum_comparison( def gst_v4l2_audio_video_synchronization( self, scenario_data: Dict ) -> None: - video_sink = ( - scenario_data["video_sinks"]["desktop"] - if self._has_desktop_environment - else scenario_data["video_sinks"]["non_desktop"] - ) + video_sink = "" + if on_ubuntucore(): + video_sink = scenario_data["video_sinks"]["on_core"] + elif self._has_desktop_environment: + video_sink = scenario_data["video_sinks"]["on_desktop"] + else: + video_sink = scenario_data["video_sinks"]["on_desktop"] + for item in scenario_data["cases"]: for sample_file in item["golden_sample_files"]: self._resource_items.append( diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json index 2d8cbf53e4..cb4c75f710 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json @@ -27,8 +27,9 @@ ], "gst_v4l2_audio_video_synchronization": { "video_sinks": { - "desktop": "waylandsink", - "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + "on_desktop": "waylandsink", + "on_server": "kmssink connector-id=32 driver-name=mediatek", + "on_core": "kmssink connector-id=32 driver-name=mediatek" }, "cases": [ { diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json index 1a48243e67..8b2e4b743e 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json @@ -1,7 +1,8 @@ { "gst_v4l2_audio_video_synchronization": { "video_sinks": { - "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + "on_server": "kmssink connector-id=32 driver-name=mediatek", + "on_core": "kmssink connector-id=32 driver-name=mediatek" }, "cases": [ { diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json index 15fd1eb52a..4d6b1c5efb 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json @@ -1,8 +1,9 @@ { "gst_v4l2_audio_video_synchronization": { "video_sinks": { - "desktop": "waylandsink", - "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + "on_desktop": "waylandsink", + "on_server": "kmssink connector-id=32 driver-name=mediatek", + "on_core": "kmssink connector-id=32 driver-name=mediatek" }, "cases": [ { diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json index 15fd1eb52a..4d6b1c5efb 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json @@ -1,8 +1,9 @@ { "gst_v4l2_audio_video_synchronization": { "video_sinks": { - "desktop": "waylandsink", - "non_desktop": "kmssink connector-id=32 driver-name=mediatek" + "on_desktop": "waylandsink", + "on_server": "kmssink connector-id=32 driver-name=mediatek", + "on_core": "kmssink connector-id=32 driver-name=mediatek" }, "cases": [ { From d5e1a9d549fc174c9839b97995d920273204c755 Mon Sep 17 00:00:00 2001 From: baconyao Date: Mon, 29 Jul 2024 10:33:38 +0800 Subject: [PATCH 5/7] Enhance the explanation of verification field --- .../checkbox-provider-ce-oem/units/video-codec/jobs.pxu | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu index 76c8e769fe..bedd4e91b2 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu @@ -50,7 +50,8 @@ _steps: 2. Adjust the audio sink to be headset via Gnome Settings or command 3. Press enter to perform test _verification: - Do you hear the beep sound and see the video be displayed? - Is the timing of audio and video synchronized? + Ensure there's no delay between the audio output and the visual display + 1. Do you hear the beep sound and see the video be displayed? + 2. Is the timing of audio and video synchronized? command: gst_v4l2_audio_video_synchronization.py -dp {{decoder_plugin}} -gp {{golden_sample_file}} -vs {{video_sink}} From 9e9725b279089309113aa47ec61bc2ced2fdb079 Mon Sep 17 00:00:00 2001 From: baconyao Date: Mon, 29 Jul 2024 12:22:29 +0800 Subject: [PATCH 6/7] Support additional pipeline setting by defining it in configuration to keep the script as generic as possible --- .../bin/gst_resources_generator.py | 7 ++-- .../gst_v4l2_audio_video_synchronization.py | 35 +++++++++++-------- .../video-codec-test-confs/genio-1200.json | 19 +++++++++- .../video-codec-test-confs/genio-350.json | 15 +++++++- .../video-codec-test-confs/genio-510.json | 19 +++++++++- .../video-codec-test-confs/genio-700.json | 19 +++++++++- .../units/video-codec/jobs.pxu | 3 +- 7 files changed, 95 insertions(+), 22 deletions(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py index 159ffa2d72..abb41f9375 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py @@ -159,12 +159,15 @@ def gst_v4l2_audio_video_synchronization( "scenario": self._current_scenario_name, "video_sink": video_sink, "decoder_plugin": item["decoder_plugin"], - "golden_sample_file_name": sample_file, + "golden_sample_file_name": sample_file["file_name"], "golden_sample_file": os.path.join( self._args.video_codec_testing_data_path, self.VIDEO_GOLDEN_SAMPLES, - sample_file, + sample_file["file_name"], ), + "capssetter_pipeline": sample_file[ + "capssetter_pipeline" + ], } ) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py index 3aacadd9ec..8db9158e2a 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_v4l2_audio_video_synchronization.py @@ -64,12 +64,24 @@ def register_arguments(): ), ) + parser.add_argument( + "-cp", + "--capssetter_pipeline", + default="", + type=str, + help=("Specific value for caps setting. (Default: " ")"), + ) + args = parser.parse_args() return args def build_gst_command( - gst_bin: str, golden_sample_path: str, decoder: str, video_sink: str + gst_bin: str, + golden_sample_path: str, + decoder: str, + video_sink: str, + capssetter_pipeline: str, ) -> str: """ Builds a GStreamer command to process the golden sample. @@ -84,24 +96,18 @@ def build_gst_command( The decoder to use for the video, e.g., "v4l2vp8dec", "v4l2vp9dec". :param video_sink: The specific sink for video displaying on, e.g. "waylandsink" + :param capssetter_pipeline: + The specific value for caps setting :returns: The GStreamer command to execute. """ - # FIXME: Why we did this? - # Because the 4K.mp4 golden sample need a special colorimetry "bt2020" - # that needs special pipeline configuration to get it streaming smoothly. - if golden_sample_path.endswith("4K.mp4"): - decoder = ( - "capssetter replace=true " - 'caps="video/x-h264, stream-format=(string)byte-stream, ' - "alignment=(string)au, level=(string)5.2, profile=(string)main, " - "width=(int)3840, height=(int)2160, framerate=(fraction)24/1, " - "pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)bt2020, " - "chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, " - 'bit-depth-chroma=(uint)8, parsed=(boolean)true" ! {}' - ).format(decoder) + # Why we need capssetter_pipeline? + # Because some golden samples need a special colorimetry and configuration + # to get it streaming smoothly. + if capssetter_pipeline: + decoder = "{} ! {}".format(capssetter_pipeline, decoder) cmd = ( "{} -v filesrc location={} ! qtdemux name=demux demux.video_0 !" @@ -174,6 +180,7 @@ def play_video_for_av_synchronization_test(args: Any) -> None: golden_sample_path=args.golden_sample_path, decoder=args.decoder_plugin, video_sink=args.video_sink, + capssetter_pipeline=args.capssetter_pipeline, ) # The video will be displayed on the real display execute_command(cmd) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json index cb4c75f710..97d7a31b1a 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-1200.json @@ -34,7 +34,24 @@ "cases": [ { "decoder_plugin": "v4l2h264dec", - "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + "golden_sample_files": [ + { + "file_name": "480p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "720p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "1080p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "4K.mp4", + "capssetter_pipeline": "capssetter replace=true caps='video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, level=(string)5.2, profile=(string)main, width=(int)3840, height=(int)2160, framerate=(fraction)24/1, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)bt2020, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true'" + } + ] } ] } diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json index 8b2e4b743e..d9979a9f63 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-350.json @@ -7,7 +7,20 @@ "cases": [ { "decoder_plugin": "v4l2h264dec", - "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4"] + "golden_sample_files": [ + { + "file_name": "480p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "720p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "1080p.mp4", + "capssetter_pipeline": "" + } + ] } ] } diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json index 4d6b1c5efb..b64c271c59 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-510.json @@ -8,7 +8,24 @@ "cases": [ { "decoder_plugin": "v4l2h264dec", - "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + "golden_sample_files": [ + { + "file_name": "480p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "720p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "1080p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "4K.mp4", + "capssetter_pipeline": "capssetter replace=true caps='video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, level=(string)5.2, profile=(string)main, width=(int)3840, height=(int)2160, framerate=(fraction)24/1, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)bt2020, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true'" + } + ] } ] } diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json index 4d6b1c5efb..b64c271c59 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/data/video-codec-test-confs/genio-700.json @@ -8,7 +8,24 @@ "cases": [ { "decoder_plugin": "v4l2h264dec", - "golden_sample_files": ["480p.mp4", "720p.mp4", "1080p.mp4", "4K.mp4"] + "golden_sample_files": [ + { + "file_name": "480p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "720p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "1080p.mp4", + "capssetter_pipeline": "" + }, + { + "file_name": "4K.mp4", + "capssetter_pipeline": "capssetter replace=true caps='video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, level=(string)5.2, profile=(string)main, width=(int)3840, height=(int)2160, framerate=(fraction)24/1, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string)bt2020, chroma-format=(string)4:2:0, bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true'" + } + ] } ] } diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu index bedd4e91b2..05d4253744 100644 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/units/video-codec/jobs.pxu @@ -42,7 +42,6 @@ plugin: user-interact-verify category_id: video-codec estimated_duration: 30s imports: from com.canonical.plainbox import manifest -requires: manifest.has_video_codec == 'True' flags: also-after-suspend environ: GST_LAUNCH_BIN _steps: @@ -54,4 +53,4 @@ _verification: 1. Do you hear the beep sound and see the video be displayed? 2. Is the timing of audio and video synchronized? command: - gst_v4l2_audio_video_synchronization.py -dp {{decoder_plugin}} -gp {{golden_sample_file}} -vs {{video_sink}} + gst_v4l2_audio_video_synchronization.py -dp {{decoder_plugin}} -gp {{golden_sample_file}} -vs {{video_sink}} -cp "{{capssetter_pipeline}}" From 22a9022eaaa05d79105276d12a7575863045ff20 Mon Sep 17 00:00:00 2001 From: baconyao Date: Thu, 1 Aug 2024 17:01:11 +0800 Subject: [PATCH 7/7] Fix wrong sink value --- .../checkbox-provider-ce-oem/bin/gst_resources_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py index abb41f9375..0c412ddae7 100755 --- a/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py +++ b/contrib/checkbox-ce-oem/checkbox-provider-ce-oem/bin/gst_resources_generator.py @@ -150,7 +150,7 @@ def gst_v4l2_audio_video_synchronization( elif self._has_desktop_environment: video_sink = scenario_data["video_sinks"]["on_desktop"] else: - video_sink = scenario_data["video_sinks"]["on_desktop"] + video_sink = scenario_data["video_sinks"]["on_server"] for item in scenario_data["cases"]: for sample_file in item["golden_sample_files"]: