mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
ffmpeg_audio_pipe_test drives one clip carefully. This is the other half: eight clips across containers, video and audio codecs, rates and channel counts, plus the two one-sided cases, each loaded, run, seeked both ways, reset and unloaded in one process - the core keeps its state in globals, so the second load is what finds what the first unload left behind. Then files that are truncated, stubbed, noise, empty or absent, and teardown while the decode thread is still working. It found two on its first run, both on the clip with no audio track: - retro_run declares int16_t audio_buffer[sample_rate / 20]. A clip with no audio has a sample rate of zero, so that is a zero-length array, which is undefined at the declaration, before anything reads it. UBSan said so. One element more costs nothing and is never read, since the frame count comes out of the same rate. - The decode thread creates the video buffer; the main thread waits on it in retro_run without checking that it exists. A clip with audio is paced by its audio and the buffer is there by the time the main thread arrives, which is why this had never shown. A clip with no audio has nothing to pace it, the main thread gets there first, and video_buffer_wait_for_finished_slot dereferences NULL - a segmentation fault on the first frame, every time. No buffer yet is no frame ready, which is what the duplicate-frame path already handles. Both are the kind a matrix finds and a single careful clip does not: the one-sided cases are where the assumptions that hold for ordinary media stop holding. The sweep is in the cores samples CI, plain and under both sanitizer sets, sharing the audio-pipe lane's libav* suppressions.