Skip to content

Commit 251e500

Browse files
vlc: add new bpg codec target (google#15820)
Signed-off-by: David Korczynski <david@adalogics.com>
1 parent 692fd86 commit 251e500

3 files changed

Lines changed: 53 additions & 4 deletions

File tree

projects/vlc/build.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,29 @@ make V=1 -j$(nproc) \
9595
.ass \
9696
.kate
9797

98+
# libbpg ships a hand-written Makefile that hardcodes CC=gcc, but the OSS-Fuzz
99+
# CFLAGS are clang-only (-gline-tables-only, -fsanitize=fuzzer-no-link), which
100+
# gcc rejects. Build it in its own make so a command-line CC/CXX override (which
101+
# beats the Makefile's CC=gcc and propagates to the inner libbpg sub-make)
102+
# forces clang, keeping libbpg instrumented.
103+
make V=1 -j$(nproc) CC="$CC" CXX="$CXX" .bpg
104+
105+
# libbpg bundles a forked libavcodec/libavutil. VLC normally builds each plugin
106+
# as a separate .so, so those symbols never clash with the ffmpeg contrib; but
107+
# the OSS-Fuzz static build links every plugin into one binary, where libbpg's
108+
# av_*/ff_*/avcodec_* duplicate ffmpeg's ("multiple definition" link errors).
109+
# Merge libbpg.a into a single relocatable object and localize every symbol
110+
# except the public bpg_* API: libbpg then resolves its own libav internally
111+
# while ffmpeg's symbols stay global for the avcodec plugin.
112+
for bpg_a in ../*/lib/libbpg.a; do
113+
[ -f "$bpg_a" ] || continue
114+
ld -r --whole-archive "$bpg_a" -o "${bpg_a}.merged.o"
115+
objcopy --wildcard --keep-global-symbol='bpg_*' "${bpg_a}.merged.o" "${bpg_a}.local.o"
116+
rm -f "$bpg_a" "${bpg_a}.merged.o"
117+
ar crs "$bpg_a" "${bpg_a}.local.o"
118+
rm -f "${bpg_a}.local.o"
119+
done
120+
98121
# libgme's CMake compiles with -fno-rtti, which is incompatible with the
99122
# -fsanitize=vptr check implied by SANITIZER=undefined ("invalid argument
100123
# '-fsanitize=vptr' not allowed with '-fno-rtti'"). Build it with that single
@@ -153,6 +176,7 @@ sed -i "s/${RULE}/${FUZZ_LDFLAGS}\n${RULE}/g" ./test/Makefile.am
153176
--disable-xcb \
154177
--disable-alsa \
155178
--disable-libva \
179+
--enable-bpg \
156180
--with-libfuzzer
157181
make V=1 -j$(nproc)
158182

projects/vlc/fuzzing-modules.patch

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ index 613cfab..e977d39 100644
2323
../modules/libfilesystem_plugin.la \
2424
../modules/libxml_plugin.la \
2525
../modules/libogg_plugin.la \
26-
@@ -537,13 +549,34 @@ libvlc_demux_dec_run_la_LIBADD += \
26+
@@ -537,13 +549,35 @@ libvlc_demux_dec_run_la_LIBADD += \
2727
../modules/libsubsusf_plugin.la \
2828
../modules/libsvcdsub_plugin.la \
2929
../modules/libtextst_plugin.la \
@@ -45,7 +45,8 @@ index 613cfab..e977d39 100644
4545
+ ../modules/libpng_plugin.la \
4646
+ ../modules/liblibass_plugin.la \
4747
+ ../modules/libkate_plugin.la \
48-
+ ../modules/libtelx_plugin.la
48+
+ ../modules/libtelx_plugin.la \
49+
+ ../modules/libbpg_plugin.la
4950
if HAVE_ZVBI
5051
libvlc_demux_dec_run_la_LIBADD += ../modules/libzvbi_plugin.la
5152
endif
@@ -63,7 +64,7 @@ diff --git a/test/src/input/demux-run.c b/test/src/input/demux-run.c
6364
index 92a5d92..1486f79 100644
6465
--- a/test/src/input/demux-run.c
6566
+++ b/test/src/input/demux-run.c
66-
@@ -417,7 +417,24 @@ int vlc_demux_process_memory(const struct vlc_run_args *args,
67+
@@ -417,7 +417,25 @@ int vlc_demux_process_memory(const struct vlc_run_args *args,
6768
f(codec_subsusf) \
6869
f(codec_svcdsub) \
6970
f(codec_textst) \
@@ -85,7 +86,8 @@ index 92a5d92..1486f79 100644
8586
+ f(codec_png) \
8687
+ f(codec_ass) \
8788
+ f(codec_kate) \
88-
+ f(codec_telx)
89+
+ f(codec_telx) \
90+
+ f(codec_bpg)
8991
#else
9092
#define DECODER_PLUGINS(f)
9193
#endif

projects/vlc/generate_seeds.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4784,6 +4784,29 @@ def gen_image(root):
47844784
JPEG (baseline/progressive/subsampling/grey/CMYK) for libpng / libjpeg."""
47854785
O = os.path.join(root, 'seeds', 'image')
47864786
os.makedirs(O, exist_ok=True)
4787+
4788+
# BPG (Better Portable Graphics) -> codec/bpg.c + bundled libbpg, reached
4789+
# via the image demux, which detects the 4-byte 'BPG\xFB' marker. bpg.c was
4790+
# never registered in the harness (absent from coverage). A structurally
4791+
# valid BPG header gets past detection and the libbpg header parse (the
4792+
# front door); libFuzzer mutates from there into the HEVC-based decoder.
4793+
def _ue7(v: int) -> bytes:
4794+
out = bytearray([v & 0x7F])
4795+
v >>= 7
4796+
while v:
4797+
out.insert(0, 0x80 | (v & 0x7F))
4798+
v >>= 7
4799+
return bytes(out)
4800+
4801+
bpg = (b'BPG\xfb' # magic
4802+
+ bytes([0x20]) # pixel_format=4:2:0(1), bit_depth_minus8=0
4803+
+ bytes([0x00]) # color_space=YCbCr, no extension/alpha
4804+
+ _ue7(16) + _ue7(16) # picture_width, picture_height
4805+
+ _ue7(0)) # picture_data_length (0 = to end of file)
4806+
bpg += bytes([0x00, 0x00, 0x01, 0x26, 0x01] + [0x00] * 32) # HEVC payload
4807+
with open(os.path.join(O, 'minimal.bpg'), 'wb') as f:
4808+
f.write(bpg)
4809+
47874810
SIG = b'\x89PNG\r\n\x1a\n'
47884811

47894812
def png(name, w, h, bd, ct, rows, before=b'', after=b'',

0 commit comments

Comments
 (0)