ffmpeg.c源码阅读
来源:互联网 发布:手机淘宝链接怎么弄 编辑:程序博客网 时间:2024/05/28 06:08
入口函数main
int main(int argc, char **argv){ int i, ret; int64_t ti; init_dynload(); register_exit(ffmpeg_cleanup); setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */ av_log_set_flags(AV_LOG_SKIP_REPEATED); parse_loglevel(argc, argv, options); if(argc>1 && !strcmp(argv[1], "-d")){ run_as_daemon=1; av_log_set_callback(log_callback_null); argc--; argv++; } //注册 avcodec_register_all();#if CONFIG_AVDEVICE avdevice_register_all();#endif avfilter_register_all(); av_register_all(); avformat_network_init(); //显示版本信息 show_banner(argc, argv, options); //解析输入参数,并打开输入输出 /* parse options and open all input/output files */ ret = ffmpeg_parse_options(argc, argv); if (ret < 0) exit_program(1); if (nb_output_files <= 0 && nb_input_files == 0) { show_usage(); av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name); exit_program(1); } /* file converter / grab */ if (nb_output_files <= 0) { av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n"); exit_program(1); }// if (nb_input_files == 0) {// av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");// exit_program(1);// } for (i = 0; i < nb_output_files; i++) { if (strcmp(output_files[i]->ctx->oformat->name, "rtp")) want_sdp = 0; } //开始转码 current_time = ti = getutime(); if (transcode() < 0) exit_program(1); ti = getutime() - ti; if (do_benchmark) { av_log(NULL, AV_LOG_INFO, "bench: utime=%0.3fs\n", ti / 1000000.0); } av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" frames successfully decoded, %"PRIu64" decoding errors\n", decode_error_stat[0], decode_error_stat[1]); if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1]) exit_program(69); exit_program(received_nb_signals ? 255 : main_return_code); return main_return_code;}
main 函数主要做了如下工作:
- 注册各种信息
- 解析参数并打开输入输出
- 持续转码
- 退出,清理
main - avcodec_register_all
以avcodec_register_all为例主要学习
void avcodec_register_all(void){ static AVOnce control = AV_ONCE_INIT; ff_thread_once(&control, register_all);}//只初始化一次#define ff_thread_once(control, routine) pthread_once(control, routine)//传入的静态函数static void register_all(void){ /* hardware accelerators */ REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); ... REGISTER_PARSER(H264, h264); REGISTER_PARSER(HEVC, hevc); ...}//宏定义//REGISTER_PARSER(H264, h264);#define REGISTER_PARSER(X, x) \ { \ //extern AVCodecParser ff_h264_parser; extern AVCodecParser ff_##x##_parser; \ //if (CONFIG_H264_PARSER) if (CONFIG_##X##_PARSER) \ //av_register_codec_parser(&ff_h264_parser); \ av_register_codec_parser(&ff_##x##_parser); \ }//注册void av_register_codec_parser(AVCodecParser *parser){ do { parser->next = av_first_parser; } while (parser->next != avpriv_atomic_ptr_cas((void * volatile *)&av_first_parser, parser->next, parser));}
一句话概括就是:遍历链表并把当前的AVCodec加到链表的尾部。
关于注册可以参考雷神的blog
main-show_banner
void show_banner(int argc, char **argv, const OptionDef *options){ int idx = locate_option(argc, argv, options, "version"); if (hide_banner || idx) return; print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO); print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_INFO); print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);}
打印一些信息,如下图
main - ffmpeg_parse_options
AVOption 结构体
移步到雷神的博客
阅读全文
0 0
- ffmpeg.c源码阅读
- ffmpeg开发系列-源码阅读
- ffmpeg demexing.c 源码编译
- FFmpeg源码分析之MpegTS.c
- 适合C/C++初学者阅读的源码
- Android内核源码阅读---ashmem.c
- Android内核源码阅读---ashmem.c
- apache1.3.39源码alloc.c阅读笔记
- apache1.3.39源码alloc.c阅读笔记
- apache1.3.39源码alloc.c阅读笔记
- apache1.3.39源码alloc.c阅读笔记
- apache1.3.39源码alloc.c阅读笔记
- 阅读json-c库源码的随笔
- Gaea源码阅读(五):C客户端
- contiki源码阅读之mmem.c
- Redis源码阅读之rdb.c
- Redis源码阅读之aof.c
- Redis源码阅读之ae.c
- 解决“Win 10 ipv6无网络权限/无Internet连接权限”问题
- powerdesigner相关整理
- Maven+SpringMVC+Swagger整合
- javaseday21补充(装饰设计模式 BufferedReader 的小弟 LineNumber 行号媒体文件的复制)
- css实现内容超长自动截取并显示省略号
- ffmpeg.c源码阅读
- JAVA互联网学习之Filter
- hdu 5707 Combine String dphen dp
- 单元测试心得
- JS打开摄像头并截图上传示例
- MQ相关
- HDU 2602 Bone Collector (01背包)
- Spark R安装成功的步骤
- updateByPrimaryKeySelective和updateByPrimaryKey区别