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程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

Python程序的文件头部声明小结

《Python程序的文件头部声明小结》在Python文件的顶部声明编码通常是必须的,尤其是在处理非ASCII字符时,下面就来介绍一下两种头部文件声明,具有一定的参考价值,感兴趣的可以了解一下... 目录一、# coding=utf-8二、#!/usr/bin/env python三、运行Python程序四、

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3

防止SpringBoot程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线