MLT媒体程序框架02:源码剖析

以MLT自带的Melt命令行工具源码为例
去掉一些不重要的代码

melt.c

int main(int argc, char **argv)
{int i;mlt_consumer consumer = NULL;FILE *store = NULL;char *name = NULL;mlt_profile profile = NULL;int is_progress = 0;int is_silent = 0;int is_abort = 0;int is_getc = 0;int error = 0;mlt_profile backup_profile;mlt_repository repo = NULL;const char *repo_path = NULL;int is_consumer_explicit = 0;int is_setlocale = 0;// Handle abnormal exit situations.signal(SIGSEGV, abnormal_exit_handler);signal(SIGILL, abnormal_exit_handler);signal(SIGABRT, abnormal_exit_handler);// 设置地区,不设置默认是中国// 在程序中,区域是影响程序语言处理方式的环境变量,比如日期,时间,货币,数字和字符串的格式等。for (i = 1; i < argc; i++) {if (!strcmp(argv[i], "-setlocale")) {is_setlocale = 1;break;}}for (i = 1; i < argc; i++) {// Check for serialisation switchif (!strcmp(argv[i], "-serialise")) {name = argv[++i];if (name != NULL && strstr(name, ".melt"))store = fopen(name, "w");else {if (name == NULL || name[0] == '-')store = stdout;name = NULL;}}// Look for the profile optionelse if (!strcmp(argv[i], "-profile")) {// Construct the factoryif (!repo)repo = setup_factory(repo_path, is_setlocale);const char *pname = argv[++i];if (pname && pname[0] != '-')profile = mlt_profile_init(pname);} else if (!strcmp(argv[i], "-progress")) {is_progress = 1;} else if (!strcmp(argv[i], "-progress2")) {is_progress = 2;}// 查找,会打印对应的service种类和信息// Look for the query optionelse if (!strcmp(argv[i], "-query")) {// Construct the factoryif (!repo)repo = setup_factory(repo_path, is_setlocale);const char *pname = argv[++i];if (pname && pname[0] != '-') {if (!strcmp(pname, "consumers") || !strcmp(pname, "consumer"))query_services(repo, mlt_service_consumer_type);else if (!strcmp(pname, "filters") || !strcmp(pname, "filter"))query_services(repo, mlt_service_filter_type);else if (!strcmp(pname, "links") || !strcmp(pname, "link"))query_services(repo, mlt_service_link_type);else if (!strcmp(pname, "producers") || !strcmp(pname, "producer"))query_services(repo, mlt_service_producer_type);else if (!strcmp(pname, "transitions") || !strcmp(pname, "transition"))query_services(repo, mlt_service_transition_type);else if (!strcmp(pname, "profiles") || !strcmp(pname, "profile"))query_profiles();else if (!strcmp(pname, "presets") || !strcmp(pname, "preset"))query_presets();else if (!strncmp(pname, "format", 6))query_formats();else if (!strncmp(pname, "acodec", 6) || !strcmp(pname, "audio_codecs"))query_acodecs();else if (!strncmp(pname, "vcodec", 6) || !strcmp(pname, "video_codecs"))query_vcodecs();else if (!strncmp(pname, "consumer=", 9))query_metadata(repo,mlt_service_consumer_type,"consumer",strchr(pname, '=') + 1);else if (!strncmp(pname, "filter=", 7))query_metadata(repo, mlt_service_filter_type, "filter", strchr(pname, '=') + 1);else if (!strncmp(pname, "link=", 5))query_metadata(repo, mlt_service_link_type, "link", strchr(pname, '=') + 1);else if (!strncmp(pname, "producer=", 9))query_metadata(repo,mlt_service_producer_type,"producer",strchr(pname, '=') + 1);else if (!strncmp(pname, "transition=", 11))query_metadata(repo,mlt_service_transition_type,"transition",strchr(pname, '=') + 1);else if (!strncmp(pname, "profile=", 8))query_profile(strchr(pname, '=') + 1);else if (!strncmp(pname, "preset=", 7))query_preset(strchr(pname, '=') + 1);elsegoto query_all;} else {query_all:query_services(repo, mlt_service_consumer_type);query_services(repo, mlt_service_filter_type);query_services(repo, mlt_service_link_type);query_services(repo, mlt_service_producer_type);query_services(repo, mlt_service_transition_type);fprintf(stdout,"# You can query the metadata for a specific service using:\n""# -query <type>=<identifier>\n""# where <type> is one of: consumer, filter, producer, or transition.\n");}goto exit_factory;} else if (!strcmp(argv[i], "-silent")) {is_silent = 1;} else if (!strcmp(argv[i], "-quiet")) {is_silent = 1;mlt_log_set_level(MLT_LOG_QUIET);} else if (!strcmp(argv[i], "-verbose")) {mlt_log_set_level(MLT_LOG_VERBOSE);} else if (!strcmp(argv[i], "-timings")) {mlt_log_set_level(MLT_LOG_TIMINGS);} else if (!strcmp(argv[i], "-version") || !strcmp(argv[i], "--version")) {fprintf(stdout,"%s " VERSION "\n""Copyright (C) 2002-2023 Meltytech, LLC\n""<https://www.mltframework.org/>\n""This is free software; see the source for copying conditions.  There is NO\n""warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",basename(argv[0]));goto exit_factory;} else if (!strcmp(argv[i], "-debug")) {mlt_log_set_level(MLT_LOG_DEBUG);} else if (!strcmp(argv[i], "-abort")) {is_abort = 1;} else if (!strcmp(argv[i], "-getc")) {is_getc = 1;} else if (!repo && !strcmp(argv[i], "-repository")) {if (i + 1 < argc && argv[i + 1][0] != '-')repo_path = argv[++i];} else if (!strcmp(argv[i], "-consumer")) {is_consumer_explicit = 1;}}if (!is_silent && !isatty(STDIN_FILENO) && !is_progress)is_progress = 1;// Construct the factoryif (!repo)repo = setup_factory(repo_path, is_setlocale);// Create profile if not set explicitlyif (getenv("MLT_PROFILE"))// 根据环境变量去找到对应的profileprofile = mlt_profile_init(NULL);if (profile == NULL)profile = mlt_profile_init(NULL);elseprofile->is_explicit = 1;// 备份profile,然后加载consumer,如果profile在加载consumer的时候发生了改变,则表明这时候的profile信息是精确的// Look for the consumer option to load profile settings from consumer propertiesbackup_profile = mlt_profile_clone(profile);if (load_consumer(&consumer, profile, argc, argv) != EXIT_SUCCESS)goto exit_factory;// If the consumer changed the profile, then it is explicit.if (backup_profile && !profile->is_explicit&& (profile->width != backup_profile->width || profile->height != backup_profile->height|| profile->sample_aspect_num != backup_profile->sample_aspect_num|| profile->sample_aspect_den != backup_profile->sample_aspect_den|| profile->frame_rate_den != backup_profile->frame_rate_den|| profile->frame_rate_num != backup_profile->frame_rate_num|| profile->colorspace != backup_profile->colorspace))profile->is_explicit = 1;mlt_profile_close(backup_profile);backup_profile = NULL;// 除了第一个参数,把后面的参数都传递到factory中,用于生产producer// Get melt producerif (argc > 1)melt = mlt_factory_producer(profile, "melt", &argv[1]);if (melt) {// Generate an automatic profile if needed.if (!profile->is_explicit) {mlt_producer first_producer = mlt_properties_get_data(MLT_PRODUCER_PROPERTIES(melt),"first_producer",NULL);mlt_profile_from_producer(profile, first_producer);mlt_consumer melt_consumer = MLT_CONSUMER(mlt_service_consumer(MLT_PRODUCER_SERVICE(melt)));if (melt_consumer)mlt_consumer_connect(melt_consumer, NULL);mlt_producer_close(melt);melt = mlt_factory_producer(profile, "melt", &argv[1]);}double scale = mlt_properties_get_double(MLT_CONSUMER_PROPERTIES(consumer), "scale");if (scale > 0.0) {// 设置缩放set_preview_scale(&profile, &backup_profile, scale);}// Reload the consumer with the fully qualified profile.// The producer or auto-profile could have changed the profile.load_consumer(&consumer, profile, argc, argv);// See if producer has consumer already attachedif (!store && !consumer) {consumer = MLT_CONSUMER(mlt_service_consumer(MLT_PRODUCER_SERVICE(melt)));if (consumer) {// 增加引用计数mlt_properties_inc_ref(MLT_CONSUMER_PROPERTIES(consumer)); // because we explicitly close it// 设置传输回调函数mlt_properties_set_data(MLT_CONSUMER_PROPERTIES(consumer),"transport_callback",transport_action,0,NULL,NULL);}}// If we have no consumer, default to sdlif (store == NULL && consumer == NULL)consumer = create_consumer(profile, NULL);}// Set transport properties on consumer and produderif (consumer != NULL && melt != NULL) {mlt_properties_set_data(MLT_CONSUMER_PROPERTIES(consumer),"transport_producer",melt,0,NULL,NULL);mlt_properties_set_data(MLT_PRODUCER_PROPERTIES(melt),"transport_consumer",consumer,0,NULL,NULL);if (is_progress)mlt_properties_set_int(MLT_CONSUMER_PROPERTIES(consumer), "progress", is_progress);if (is_silent)mlt_properties_set_int(MLT_CONSUMER_PROPERTIES(consumer), "silent", is_silent);if (is_getc)mlt_properties_set_int(MLT_CONSUMER_PROPERTIES(consumer), "melt_getc", is_getc);}if (argc > 1 && melt != NULL && mlt_producer_get_length(melt) > 0) {// Parse the argumentsfor (i = 1; i < argc; i++) {if (!strcmp(argv[i], "-jack") && consumer) {setup_jack_transport(consumer, profile);} else if (!strcmp(argv[i], "-serialise")) {if (store != stdout)i++;} else {if (store != NULL)fprintf(store, "%s\n", argv[i]);i++;while (argv[i] != NULL && argv[i][0] != '-') {if (store != NULL)fprintf(store, "%s\n", argv[i]);i += 1;}i--;}}if (consumer != NULL && store == NULL) {// Get melt's propertiesmlt_properties melt_props = MLT_PRODUCER_PROPERTIES(melt);mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);if (is_consumer_explicit) {// Apply group settingsmlt_properties group = mlt_properties_get_data(melt_props, "group", 0);// properties继承mlt_properties_inherit(properties, group);}int in = mlt_properties_get_int(properties, "in");int out = mlt_properties_get_int(properties, "out");if (in > 0 || out > 0) {if (out == 0) {out = mlt_producer_get_length(melt) - 1;}mlt_producer_set_in_and_out(melt, in, out);mlt_producer_seek(melt, 0);}// Connect consumer to meltmlt_consumer_connect(consumer, MLT_PRODUCER_SERVICE(melt));// Start the consumermlt_events_listen(properties,consumer,"consumer-fatal-error",(mlt_listener) on_fatal_error);if (mlt_consumer_start(consumer) == 0) {// Try to exit gracefully upon these signalssignal(SIGINT, stop_handler);signal(SIGTERM, stop_handler);
#ifndef _WIN32signal(SIGHUP, stop_handler);signal(SIGPIPE, stop_handler);
#endif// Transport functionalitytransport(melt, consumer);// Stop the consumermlt_consumer_stop(consumer);}} else if (store != NULL && store != stdout && name != NULL) {fprintf(stderr, "Project saved as %s.\n", name);fclose(store);}} else {show_usage(argv[0]);}// Disconnect producer from consumer to prevent ref cycles from closing servicesif (consumer) {error = mlt_properties_get_int(MLT_CONSUMER_PROPERTIES(consumer), "melt_error");mlt_consumer_connect(consumer, NULL);if (!is_abort)mlt_events_fire(MLT_CONSUMER_PROPERTIES(consumer),"consumer-cleanup",mlt_event_data_none());}if (is_abort)return error;// Close the producerif (melt != NULL)mlt_producer_close(melt);// Close the consumerif (consumer != NULL)mlt_consumer_close(consumer);// Close the factorymlt_profile_close(profile);mlt_profile_close(backup_profile);exit_factory:// Workaround qmelt on OS X from crashing at exit.
#if !defined(__MACH__) || !defined(QT_GUI_LIB)mlt_factory_close();
#endifreturn error;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/806947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript中创建变量的方式 与 var和let有什么区别

一、创建变量的7种方式&#xff1a; 1、var 2、function 创建变量&#xff08;函数名是一个变量 3、let 4、const 创建常量 5、import 基于es6 的模块规范导出需要的信息 6、class 基于 es6 创建的类 7、Symbol 创建唯一值 二…

Linux进阶篇:centos7扩展root分区:LVM应用案例

centos7扩展root分区&#xff1a;LVM应用案例 当服务器根分区或者是root分区存储空间快用完的时候&#xff0c;并且重要的数据都在root分区下&#xff0c;当如何应对&#xff0c;没关系坐好&#xff0c;分分钟解决它&#xff0c;我们可以进行分区扩容。 一 添加一块新的硬盘 …

谈谈系列之移动时代,我的产品技术观

其实一直想着写这篇文章&#xff0c;但是缺乏灵感&#xff0c;下笔犯难。信息时代发展速度快到令人目不暇接&#xff0c;从最开始的个人PC&#xff0c;到拨号上网&#xff0c;再到光纤入户&#xff0c;再到现在4G/5G移动互联网&#xff0c;一晃也不过短短三四十年。程序主流语言…

java 读取zip文件的两种方式

以下是使用Java读取zip文件的两种实现方法&#xff1a; 方法1&#xff1a;使用java.util.zip.ZipInputStream类 import java.io.FileInputStream; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;public class ZipReader …

某中小型网游公司绩效管理诊断项目成功案例纪实

【客户行业】 网游行业 【问题类型】 绩效管理 【客户背景】 某中小型网游科技发展有限公司成立于2006年,是一家专业的网页游戏研发、互联网应用、手机游戏开发于一体的高新技术科技企业,位于北京市昌平区。公司自成立以来,一直稳步发展,到目前为止,员工人数约150人。近…

鸿蒙应用开发之图案密码锁组件

前面学习了导航组件,现在来学习另一个密码设置和验证组件,这种组件比较常用。因为当用触屏手机之后,屏幕上就可以滑动操作,比普通PC电脑要多一些功能了。早前的密码都是输入数字,没有滑动输入九宫格的密码。 大体如下面的界面: 采用这种密码,一般情况下是不用记住数字,…

pytest详解(一)

目录 前言安装检验 编写测试文件一个简单完整的pytest的组成结构 pytest运行用例时携带的参数&#xff08;常用&#xff09;pytest的用例命名规则pytest的常用运行方式pytest指定运行用例指定运行一个文件夹中的用例指定运行一个文件夹中的一个文件中的用例指定运行一个文件夹中…

汇编——SSE打包整数

SSE也可以进行整数向量的加法&#xff0c;示例如下&#xff1a; ;sse_integer.asm extern printfsection .datadummy db 13 align 16pdivector1 dd 1dd 2dd 3dd 4pdivector2 dd 5dd 6dd 7dd 8fmt1 db "Packed Integer Vector 1: %d, %d, %d, %d",…

【鹅厂摸鱼日记(二)】(生活篇)初到深圳的人情冷暖

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:重生之我在鹅厂摸鱼⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多知识   &#x1f51d;&#x1f51d; 摸鱼日记 1. 前言2. 鹅厂的人文关怀…

论文笔记:NEFTune: Noisy Embeddings Improve Instruction Finetuning

iclr 2024 reviewer 评分 5666 1 论文思路 论文的原理很简单&#xff1a;在finetune过程的词向量中引入一些均匀分布的噪声即可明显地提升模型的表现 2 方法评估

JavaScript数组操作方法全录

改变原数组的方法&#xff1a; push() - 将一个或多个元素添加到数组的末尾&#xff0c;并返回新数组的长度。 pop() - 从数组中移除最后一个元素&#xff0c;并返回该元素。 shift() - 从数组中移除第一个元素&#xff0c;并返回该元素。 unshift() - 将一个或多个元素添加到…

2024年第二届交通运输与建筑工程国际会议(IACTCE2024)

2024年第二届交通运输与建筑工程国际会议&#xff08;IACTCE2024&#xff09; 会议简介 本次会议旨在为从事交通建设工程等相关领域的专家学者、工程技术人员和研发人员提供一个平台&#xff0c;分享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff0c;拓宽研究思路…

docker 安装canal

一、新建文件夹 新建文件夹logs, 新建文件canal.properties instance.properties docker.compose.yml canal.propertie 修改如下&#xff1a; 修改instance.properties内容如下 1.1 canal.properties ################################################# ######### …

算法刷题应用知识补充---数论

这里写目录标题 快速幂求a^k%p题结 快速幂求逆元题结 扩展欧几里得求逆元题结 排列组合题结二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 快速幂求a^k%p 题 结 主要用到a的k次方&#xff0c;可以用多个a的…

fastadmin + laragon + nginx的后台访问路径配置

使用过fastadmin的小朋友都知道&#xff0c; fastadmin 默认的是不能访问admin模块的&#xff0c; 它在public 文件夹中又新建了一个 XXX.php 来指向 admin 模块的&#xff0c;作用像 index.php 的文件 以前我每次使用的时候&#xff0c;直接就到 config配置文件中把 admin 模块…

磁盘管理与逻辑卷

磁盘管理 会在linux中使用硬盘 分区 格式化&#xff08;重新安装文件系统&#xff09; 挂载 磁盘的硬件架构 扇区&#xff1a;一个扇区512字节&#xff0c;是磁盘的最小单位 磁道&#xff1a;同一盘片不同半径的同心圆 柱面&#xff1a;不同盘片相同半径构成的圆&#xf…

String类(1)

❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&a…

CC工具箱使用指南:【融合同类碎图斑】

一、简介 在一些经过不合理处理的数据中&#xff0c;经常会存在碎图斑&#xff0c;正常情况下用【融合】或【消除】工具即可解决。 但是【融合】工具会融掉无关的字段&#xff0c;【消除】工具则会将碎图斑融给不同用地类型的图斑。 如下图所示&#xff0c;因为B1面积更大&a…

Go-学会方法的基本使用

本节重点&#xff1a; 学会方法的基本使用 方法主要源于 OOP 语言&#xff0c;在传统面向对象语言中 (例如 C), 我们会用一个“类”来封装属于自己的数据和函数&#xff0c;这些类的函数就叫做方法。 虽然 Go 不是经典意义上的面向对象语言&#xff0c;但是我们可以在一些接收…

蓝桥杯嵌入式(G431)备赛笔记——PWM+LCD+按键

目录 题目要求&#xff08;真题&#xff09;&#xff1a; cubeMX配置&#xff1a; 小试牛刀&#xff1a; Keil代码&#xff1a; 效果演示&#xff1a; 题目要求&#xff08;真题&#xff09;&#xff1a; 使用第十一届第二场真题&#xff0c;练习PWM波部分的代码&#xff0c…