Clang LibTooling tool that finds all FFmpeg API calls in C/C++ source files. Reports which client functions call which FFmpeg APIs, grouped by source file.
Requires CMake 3.14+, LLVM/Clang 16+ dev libraries, and a C++17 compiler.
cmake -B build -G Ninja
cmake --build build
# or ninja -C build# Generate the target project compile_commands.json
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# or: meson setup build
# or: bear -- make
# Analyze all files in the compilation database
./build/ffmpeg-api-analyzer -p /path/to/build
# Or specify individual files
./build/ffmpeg-api-analyzer -p /path/to/build src/demuxer.c src/decoder.c./build/ffmpeg-api-analyzer file.c -- -I/path/to/ffmpeg/includeStub FFmpeg headers are included so you can test without installing FFmpeg:
./build/ffmpeg-api-analyzer examples/example.c -- -I examples/include
./build/ffmpeg-api-analyzer examples/example.cpp -- -I examples/includeJSON array with one object mapping source files to their client functions and the FFmpeg APIs each one calls:
[
{
"src/demuxer.c": {
"open_input": ["avformat_open_input", "avformat_find_stream_info"],
"close_input": ["avformat_close_input"]
}
}
]Running on examples/example.c:
[
{
"examples/example.c": {
"decode_video": [
"avformat_open_input",
"avformat_find_stream_info",
"avcodec_open2",
"avcodec_send_packet",
"av_frame_free",
"av_packet_free",
"avcodec_free_context",
"avformat_close_input",
"avcodec_find_decoder",
"avcodec_alloc_context3",
"av_frame_alloc",
"av_packet_alloc"
],
"encode_audio": [
"avcodec_open2",
"avcodec_free_context",
"avcodec_find_encoder",
"avcodec_alloc_context3"
],
"scale_frame": [
"sws_freeContext",
"sws_getContext"
]
}
}
]git clone https://github.com/mpv-player/mpv.git
cd mpv
# Generate the compilation database
meson setup build
./ffmpeg-api-analyzer -p buildResults: 68 source files, 277 calling functions, 242 unique FFmpeg APIs detected.
Sample output:
[
{
"audio/aframe.c": {
"free_frame": ["av_frame_free"],
"mp_aframe_config_copy": ["av_channel_layout_copy"],
"mp_aframe_copy_attributes": ["av_frame_copy_props"],
"mp_aframe_create": ["av_frame_alloc"],
"mp_aframe_from_avframe": ["av_frame_ref"],
"mp_aframe_new_ref": ["av_frame_ref"],
"mp_aframe_pool_allocate": ["av_buffer_pool_uninit", "av_freep", "av_buffer_pool_get"],
"mp_aframe_pool_destructor": ["av_buffer_pool_uninit"],
"mp_aframe_reset": ["av_frame_unref"],
"mp_aframe_skip_samples": ["av_frame_make_writable"],
"mp_aframe_to_avframe": ["av_frame_clone"]
},
"audio/chmap.c": {
"mp_chmap_diffn": ["av_popcount64_c"]
},
"audio/chmap_avchannel.c": {
"mp_chmap_to_av_layout": ["av_channel_layout_from_mask"]
}
}
]