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

2024-04-11 16:52

本文主要是介绍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;
}

这篇关于MLT媒体程序框架02:源码剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/894651

相关文章

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte