Roly's Blog

Whatever will be, will be, the future's not ours to see.

0%

Analyzing control flow in ffmpeg.c source file with cflow

用cflow分析ffmpeg.c源文件中的函数调用图, 函数调用图(call graph,也称为call multigraph),属于控制流图,可以展示程序中函数之间的关系。函数调用图可以由动态程序分析产生(动态函数调用图),也可以由静态程序分析产生(静态函数调用图)

GNU cflow

GNU cflow is a flow graph generator that is part of the GNU Project. It’s able to generate the direct and inverted call graph of a C program

Analyzing-control-flow-in-ffmpeg-c-source-file-with-cflow1

使用cflow分析ffmpeg.c源文件中的函数调用图

使用FFmpeg n4.3分支源码,生成下面静态函数调用图,

1
git clone --branch n4.3 --depth 1 https://github.com/FFmpeg/FFmpeg.git
1
cflow fftools/ffmpeg.c

下面是只保留ffmpeg.c中的主要流程的简短的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
main() 
ffmpeg_parse_options()
transcode()
transcode_init()
init_input_stream()
init_output_stream()
transcode_step()
choose_output()
configure_filtergraph()
process_input()
get_input_packet()
av_read_frame()
process_input_packet()
decode_audio()
decode()
avcodec_send_packet()
avcodec_receive_frame()
send_frame_to_filters()
ifilter_send_frame()
av_buffersrc_add_frame_flags()
decode_video()
decode()
avcodec_send_packet()
avcodec_receive_frame()
send_frame_to_filters()
ifilter_send_frame()
av_buffersrc_add_frame_flags()
transcode_subtitles()
do_streamcopy()
reap_filters()
init_output_stream()
av_buffersink_get_frame_flags()
do_video_out()
avcodec_send_frame()
avcodec_receive_packet()
output_packet()
write_packet()
do_audio_out()
avcodec_send_frame()
avcodec_receive_packet()
output_packet()
write_packet()
close_output_stream()
print_report()
psnr()
print_final_stats()
process_input_packet()
flush_encoders()

下面是只保留ffmpeg.c中的主要流程的简短的输出(保留行号):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
main() <int main (int argc, char **argv) at fftools/ffmpeg.c:4819>:
ffmpeg_parse_options()
transcode() <int transcode (void) at fftools/ffmpeg.c:4627>:
transcode_init() <int transcode_init (void) at fftools/ffmpeg.c:3624>:
init_input_stream() <int init_input_stream (int ist_index, char *error, int error_len) at fftools/ffmpeg.c:2870>:
init_output_stream() <int init_output_stream (OutputStream *ost, char *error, int error_len) at fftools/ffmpeg.c:3419>:
transcode_step() <int transcode_step (void) at fftools/ffmpeg.c:4552>:
choose_output() <OutputStream *choose_output (void) at fftools/ffmpeg.c:3827>:
configure_filtergraph()
process_input() <int process_input (int file_index) at fftools/ffmpeg.c:4218>:
get_input_packet() <int get_input_packet (InputFile *f, AVPacket *pkt) at fftools/ffmpeg.c:4094>:
av_read_frame()
process_input_packet() <int process_input_packet (InputStream *ist, const AVPacket *pkt, int no_eof) at fftools/ffmpeg.c:2547>:
decode_audio() <int decode_audio (InputStream *ist, AVPacket *pkt, int *got_output, int *decode_failed) at fftools/ffmpeg.c:2259>:
decode() <int decode (AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt) at fftools/ffmpeg.c:2210>:
avcodec_send_packet()
avcodec_receive_frame()
send_frame_to_filters() <int send_frame_to_filters (InputStream *ist, AVFrame *decoded_frame) at fftools/ffmpeg.c:2233>:
ifilter_send_frame() <int ifilter_send_frame (InputFilter *ifilter, AVFrame *frame) at fftools/ffmpeg.c:2106>:
av_buffersrc_add_frame_flags()
decode_video() <int decode_video (InputStream *ist, AVPacket *pkt, int *got_output, int64_t *duration_pts, int eof, int *decode_failed) at fftools/ffmpeg.c:2321>:
decode() <int decode (AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt) at fftools/ffmpeg.c:2210>:
avcodec_send_packet()
avcodec_receive_frame()
send_frame_to_filters() <int send_frame_to_filters (InputStream *ist, AVFrame *decoded_frame) at fftools/ffmpeg.c:2233>:
ifilter_send_frame() <int ifilter_send_frame (InputFilter *ifilter, AVFrame *frame) at fftools/ffmpeg.c:2106>:
av_buffersrc_add_frame_flags()
transcode_subtitles() <int transcode_subtitles (InputStream *ist, AVPacket *pkt, int *got_output, int *decode_failed) at fftools/ffmpeg.c:2454>:
do_streamcopy() <void do_streamcopy (InputStream *ist, OutputStream *ost, const AVPacket *pkt) at fftools/ffmpeg.c:1979>:
reap_filters() <int reap_filters (int flush) at fftools/ffmpeg.c:1413>:
init_output_stream() <int init_output_stream (OutputStream *ost, char *error, int error_len) at fftools/ffmpeg.c:3419>:
av_buffersink_get_frame_flags()
do_video_out() <void do_video_out (OutputFile *of, OutputStream *ost, AVFrame *next_picture, double sync_ipts) at fftools/ffmpeg.c:1042>:
avcodec_send_frame()
avcodec_receive_packet()
output_packet() <void output_packet (OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof) at fftools/ffmpeg.c:860>:
write_packet() <void write_packet (OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue) at fftools/ffmpeg.c:701>:
do_audio_out() <void do_audio_out (OutputFile *of, OutputStream *ost, AVFrame *frame) at fftools/ffmpeg.c:899>:
avcodec_send_frame()
avcodec_receive_packet()
output_packet() <void output_packet (OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof) at fftools/ffmpeg.c:860>:
write_packet() <void write_packet (OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue) at fftools/ffmpeg.c:701>:
close_output_stream() <void close_output_stream (OutputStream *ost) at fftools/ffmpeg.c:838>:
print_report() <void print_report (int is_last_report, int64_t timer_start, int64_t cur_time) at fftools/ffmpeg.c:1634>:
psnr() <double psnr (double d) at fftools/ffmpeg.c:1344>:
print_final_stats() <void print_final_stats (int64_t total_size) at fftools/ffmpeg.c:1517>:
process_input_packet() <int process_input_packet (InputStream *ist, const AVPacket *pkt, int no_eof) at fftools/ffmpeg.c:2547>:
flush_encoders() <void flush_encoders (void) at fftools/ffmpeg.c:1846>: