Skip to content

Commit cc00ce4

Browse files
committed
docs: add GStreamer audio playback runner usage and GST debug guidance
- Backend/stack selection examples (pipewire/pulseaudio/alsa; base/overlay/auto) - Assets provisioning (local directory, local tarball, optional URL fetch) - Caps inference vs forced caps behavior (--rate/--channels) - GST debug controls (GST_DEBUG level) and where logs are written - Typical CI usage patterns (null sink, non-interactive runs) Signed-off-by: Srikanth Muppandam <smuppand@qti.qualcomm.com>
1 parent da85edc commit cc00ce4

1 file changed

Lines changed: 348 additions & 0 deletions

File tree

  • Runner/suites/Multimedia/GSTreamer/Audio/Audio_Playback
Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
# Audio_Playback (GStreamer) — Runner Test
2+
3+
This directory contains the **Audio_Playback** validation test for Qualcomm Linux Testkit runners.
4+
5+
It validates audio **playback** using **GStreamer (`gst-launch-1.0`)** with an auto-selected backend:
6+
- **PipeWire**
7+
- **PulseAudio**
8+
- **ALSA (direct)**
9+
10+
The script is designed to be **CI/LAVA-friendly**:
11+
- Writes **PASS/FAIL/SKIP** into `Audio_Playback.res`
12+
- Always **exits 0** (even on FAIL/SKIP) to avoid terminating LAVA jobs early
13+
- Logs the **final `gst-launch-1.0` command** to console and to log files
14+
15+
---
16+
17+
## Location in repo
18+
19+
Expected path:
20+
21+
```
22+
Runner/suites/Multimedia/GSTreamer/Audio/Audio_Playback/run.sh
23+
```
24+
25+
Required shared utils (sourced from `Runner/utils` via `init_env`):
26+
- `functestlib.sh`
27+
- `lib_gstreamer.sh`
28+
- optional: `audio_common.sh` (wrapper/aliases if present)
29+
30+
---
31+
32+
## What this test does
33+
34+
At a high level, the test:
35+
36+
1. Finds and sources `init_env`
37+
2. Sources:
38+
- `$TOOLS/functestlib.sh`
39+
- `$TOOLS/lib_gstreamer.sh`
40+
- optionally `$TOOLS/audio_common.sh`
41+
3. Resolves or accepts a clip path
42+
4. Ensures the clip is present locally (supports device-provided assets via `--assets` / `--clips-dir`,
43+
and optionally remote fetch via `--assets-url` if the helper exists)
44+
5. Builds a **backend chain** (auto: pipewire → pulseaudio → alsa)
45+
6. Selects a sink (optional `--sink`, optional `--null-sink`)
46+
7. Constructs a **multi-line** `gst-launch-1.0` playback pipeline
47+
8. Runs the pipeline for the requested duration (watchdog timeout)
48+
9. Applies **post-validation evidence** (streaming/path activity) and emits PASS/FAIL/SKIP
49+
10. Collects best-effort diagnostics:
50+
- mixer dump
51+
- dmesg scan
52+
53+
---
54+
55+
## PASS / FAIL / SKIP criteria
56+
57+
### PASS
58+
- `gst-launch-1.0` either:
59+
- exits `0`, or
60+
- is killed by watchdog timeout (`124` or `143`) **when a duration timeout is used**
61+
- **AND** evidence indicates the audio path was active, such as:
62+
- PipeWire stream RUNNING, or
63+
- PulseAudio stream/sink-input exists, or
64+
- ALSA PCM substream RUNNING, or
65+
- ASoC DAPM path shows `On` (fallback heuristic)
66+
67+
### FAIL
68+
- A backend was attempted and the run did not meet PASS criteria (e.g., immediate pipeline failure, no evidence of activity)
69+
70+
### SKIP
71+
- Missing required tools (`gst-launch-1.0`, `gst-inspect-1.0`)
72+
- No usable backend found
73+
- Clip missing and assets not available
74+
- Invalid arguments or required values missing
75+
76+
**Note:** The test always exits `0` even for FAIL/SKIP. The `.res` file is the source of truth.
77+
78+
---
79+
80+
## Logs and artifacts
81+
82+
By default, logs are written relative to the script working directory:
83+
84+
```
85+
./Audio_Playback.res
86+
./logs/Audio_Playback/
87+
gst.log
88+
mixers.txt
89+
clip_meta.txt
90+
dmesg/
91+
(dmesg scan outputs)
92+
```
93+
94+
The final `gst-launch-1.0` command is always printed to the console.
95+
96+
---
97+
98+
## Dependencies
99+
100+
### Required
101+
- `gst-launch-1.0`
102+
- `gst-inspect-1.0`
103+
104+
### Recommended (for best results)
105+
- `gst-discoverer-1.0` (for clip metadata and cap inference)
106+
- For PipeWire backend:
107+
- `pipewire` running
108+
- `wpctl` available
109+
- `pipewiresink` GStreamer plugin (preferred)
110+
- For PulseAudio backend:
111+
- `pulseaudio` or `pipewire-pulse` running
112+
- `pactl` available
113+
- `pulsesink` GStreamer plugin
114+
- For ALSA backend:
115+
- `alsasink` GStreamer plugin
116+
- proper hw device path (default `hw:0,0`)
117+
118+
---
119+
120+
## Caps negotiation behavior (important)
121+
122+
The pipeline only forces caps (`audio/x-raw,rate=...,channels=...`) when:
123+
124+
- User explicitly sets `--rate` and/or `--channels`, **OR**
125+
- Inference succeeded via `gst-discoverer-1.0`
126+
127+
Otherwise the test **does NOT force caps** and lets GStreamer negotiate.
128+
This reduces false failures on hardware with unusual constraints.
129+
130+
---
131+
132+
## Usage
133+
134+
Run:
135+
136+
```
137+
./run.sh [options]
138+
```
139+
140+
Help:
141+
142+
```
143+
./run.sh --help
144+
```
145+
146+
### Options
147+
148+
- `--backend <auto|pipewire|pulseaudio|alsa>`
149+
- Default: `auto` (tries pipewire → pulseaudio → alsa)
150+
151+
- `--stack <auto|base|overlay>`
152+
- Default: `auto`
153+
- `auto` : detect overlay (audioreach modules) and apply overlay setup only if detected
154+
- `base` : force base (do not run overlay setup even if audioreach modules are present)
155+
- `overlay` : force overlay setup (SKIP if overlay setup fails)
156+
157+
- `--format <wav|aac|mp3|flac>`
158+
- Default: `wav`
159+
160+
- `--duration <N|Ns|Nm|Nh|MM:SS|HH:MM:SS>`
161+
- Default: `${RUNTIMESEC:-10s}`
162+
163+
- `--clipdur <short|medium|long>`
164+
- Used with `resolve_clip()` when `--clip` is not specified
165+
- Default: `short`
166+
167+
- `--clip <path>`
168+
- Override resolved clip path
169+
170+
- `--clips-dir <dir>`
171+
- Points to **already untarred** clips directory on device.
172+
- Sets `AUDIO_CLIPS_BASE_DIR`
173+
174+
- `--assets <path>`
175+
- Device-provided assets (no network):
176+
- If directory: treated as `--clips-dir`
177+
- If file: `.tar` / `.tar.gz` extracted into `clips-dir` (or `AudioClips` under script dir)
178+
179+
- `--assets-url <url>`
180+
- Optional remote tarball URL (used only if clip missing and helper exists)
181+
182+
- `--rate <Hz>`
183+
- Forces output caps **rate** after decode/resample
184+
- Example: `48000`
185+
186+
- `--channels <N>`
187+
- Forces output caps **channels** after decode/resample
188+
- Example: `1` or `2`
189+
190+
- `--sink <idOrName>`
191+
- For PipeWire: numeric id or substring match in `wpctl status`
192+
- For PulseAudio: sink name or numeric index
193+
194+
- `--null-sink`
195+
- Prefer null/dummy sink if available (useful for silent CI runs)
196+
197+
- `--gst-debug <level>`
198+
- Sets `GST_DEBUG=<level>` (single numeric level)
199+
- Values:
200+
- `1` ERROR
201+
- `2` WARNING
202+
- `3` FIXME
203+
- `4` INFO
204+
- `5` DEBUG
205+
- `6` LOG
206+
- `7` TRACE
207+
- `9` MEMDUMP
208+
- Default: `2`
209+
210+
---
211+
212+
## Examples
213+
214+
### 1) Basic WAV playback (auto backend)
215+
216+
```
217+
./run.sh --format wav --clip /var/yesterday_48KHz.wav --duration 10s
218+
```
219+
220+
### 2) Base stack (force no overlay actions)
221+
222+
```
223+
./run.sh --stack base --format wav --clip /var/yesterday_48KHz.wav --duration 10s
224+
```
225+
226+
### 3) Overlay stack (force overlay setup)
227+
228+
```
229+
./run.sh --stack overlay --format wav --clip /var/yesterday_48KHz.wav --duration 10s
230+
```
231+
232+
### 4) AAC playback (matches your reference pipeline intent)
233+
234+
Your reference pipeline:
235+
236+
```
237+
gst-launch-1.0 filesrc location=/opt/aac_48k_mono.aac ! aacparse ! avdec_aac ! audioconvert ! audioresample ! audio/x-raw,rate=48000,channels=1 ! alsasink device=hw:0,0
238+
```
239+
240+
Equivalent test invocation:
241+
242+
```
243+
./run.sh --format aac --clip /opt/aac_48k_mono.aac --rate 48000 --channels 1 --duration 10s
244+
```
245+
246+
### 5) FLAC 48k stereo playback (reference intent)
247+
248+
```
249+
./run.sh --format flac --clip /opt/flac_48k_stereo.flac --rate 48000 --channels 2 --duration 10s
250+
```
251+
252+
### 6) MP3 44.1k stereo playback (reference intent)
253+
254+
```
255+
./run.sh --format mp3 --clip /opt/mp3_44k1_stereo.mp3 --rate 44100 --channels 2 --duration 10s
256+
```
257+
258+
### 7) Prefer a null/dummy sink for CI
259+
260+
```
261+
./run.sh --null-sink --format wav --clip /var/yesterday_48KHz.wav --duration 10s
262+
```
263+
264+
### 8) Choose a specific sink
265+
266+
PipeWire example:
267+
268+
```
269+
./run.sh --backend pipewire --sink speaker --format wav --clip /var/yesterday_48KHz.wav --duration 10s
270+
```
271+
272+
PulseAudio example:
273+
274+
```
275+
./run.sh --backend pulseaudio --sink 0 --format wav --clip /var/yesterday_48KHz.wav --duration 10s
276+
```
277+
278+
### 9) Use device-provided local assets (tar.gz)
279+
280+
```
281+
./run.sh --assets /opt/audio_clips.tar.gz --format wav --clipdur short --duration 10s
282+
```
283+
284+
### 10) Use device-provided untar directory
285+
286+
```
287+
./run.sh --clips-dir /opt/AudioClips --format wav --clipdur short --duration 10s
288+
```
289+
290+
### 11) Increase GStreamer debug verbosity
291+
292+
```
293+
./run.sh --gst-debug 5 --format wav --clip /var/yesterday_48KHz.wav --duration 10s
294+
```
295+
296+
---
297+
298+
## Troubleshooting
299+
300+
### A) “SKIP: Missing gstreamer runtime”
301+
- Ensure `gst-launch-1.0` and `gst-inspect-1.0` are installed in the image.
302+
303+
### B) PipeWire/PulseAudio backend not used
304+
- Ensure the daemon is running:
305+
- PipeWire: `pgrep -x pipewire`
306+
- PulseAudio: `pgrep -x pulseaudio` or `pgrep -x pipewire-pulse`
307+
- Ensure control tools exist:
308+
- PipeWire: `wpctl`
309+
- PulseAudio: `pactl`
310+
- Ensure plugin exists:
311+
- PipeWire: `pipewiresink`
312+
- PulseAudio: `pulsesink`
313+
314+
### C) ALSA backend fails
315+
- Confirm `alsasink` plugin exists:
316+
- `gst-inspect-1.0 alsasink`
317+
- Confirm device is correct (default `hw:0,0` in the test):
318+
- You can update the default in the test or extend args later if needed.
319+
320+
### D) “FAIL: evidence=0”
321+
- If audio is routed through a sound server, ensure the sound server interfaces are accessible.
322+
- Check `logs/Audio_Playback/gst.log`, `mixers.txt`, and `dmesg/` outputs.
323+
- Try forcing `--gst-debug 5` for more detail.
324+
325+
---
326+
327+
## Notes for CI / LAVA
328+
329+
- The test always exits `0`.
330+
- Use the `.res` file for result:
331+
- `PASS`
332+
- `FAIL`
333+
- `SKIP`
334+
335+
---
336+
337+
## Maintainers
338+
339+
- This test is intended to be robust and easy to extend alongside:
340+
- `Audio_Record`
341+
- `Audio_Duplex_Loopback`
342+
- `Audio_Concurrency`
343+
344+
Follow the same conventions:
345+
- Keep **usage in run.sh**
346+
- Use shared helpers in `Runner/utils/lib_gstreamer.sh` and `audio_common.sh`
347+
- Use `log_*` helpers from `functestlib.sh`
348+
- Always emit `.res` and exit `0`

0 commit comments

Comments
 (0)