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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mlt.h"
#include "mlt_log.h"

int main(int argc, char *argv[])
{
if (argc < 3) {
fprintf(stderr, "Usage: %s input.mp4 output.mp4\n", argv[0]);
return 1;
}

const char *input_path = argv[1];
const char *output_path = argv[2];

// 1. 初始化 MLT 工厂(加载 modules)
const char* plugin_dir = getenv("MLT_REPOSITORY");
if (!plugin_dir) {
plugin_dir = "/home/cmder/mlttest/lib/mlt";
}

if (!mlt_factory_init(plugin_dir)) {
fprintf(stderr, "Failed to init MLT factory (tried: %s)\n", plugin_dir);
return 1;
}

// 启用日志以便调试
mlt_log_set_level(MLT_LOG_WARNING);
printf("MLT factory initialized, plugin directory: %s\n", plugin_dir);

// 2. 创建 profile(可以先用默认,再根据输入视频更新)
mlt_profile profile = mlt_profile_init(NULL);
if (!profile) {
fprintf(stderr, "Failed to create profile\n");
mlt_factory_close();
return 1;
}

// 3. 创建 producer,读取 MP4
// 先尝试明确指定 avformat,如果失败再尝试自动检测
mlt_producer producer = mlt_factory_producer(profile, "avformat", input_path);
if (!producer) {
// 如果明确指定失败,尝试让MLT自动选择
printf("Failed with 'avformat', trying auto-detect...\n");
producer = mlt_factory_producer(profile, NULL, input_path);
}

if (!producer) {
fprintf(stderr, "Failed to create producer for %s\n", input_path);
fprintf(stderr, "Please check:\n");
fprintf(stderr, " 1. File exists and is readable\n");
fprintf(stderr, " 2. MLT avformat plugin is loaded (libmltavformat.so)\n");
fprintf(stderr, " 3. File format is supported by FFmpeg\n");
mlt_profile_close(profile);
mlt_factory_close();
return 1;
}

printf("Producer created successfully\n");

// 根据输入视频更新 profile(分辨率 / fps)
mlt_profile_from_producer(profile, producer);

// 4. 创建亮度滤镜(这里用 CPU 的 brightness,内部做逐帧处理)
// 如果你有 OpenGL / movit 模块,可以把 "brightness" 换成 "movit.lift_gamma_gain"
mlt_filter brightness = mlt_factory_filter(profile, "brightness", NULL);
if (!brightness) {
fprintf(stderr, "Failed to create brightness filter\n");
mlt_producer_close(producer);
mlt_profile_close(profile);
mlt_factory_close();
return 1;
}

// 设置亮度参数:
// brightness filter 的 level 范围 [0, 15],1.0 是原始亮度,>1.0 就更亮
// 文档里这个参数叫 "level" :contentReference[oaicite:0]{index=0}
mlt_properties bprops = MLT_FILTER_PROPERTIES(brightness);
mlt_properties_set_double(bprops, "level", 1.5); // 提升亮度 1.5 倍
// 可选:单独调 alpha(不需要可以不设)
// mlt_properties_set_double(bprops, "alpha", 1.0);

// 把滤镜挂到 producer 上(每一帧解码出来后,都会走这个 filter)
if (mlt_producer_attach(producer, brightness) != 0) {
fprintf(stderr, "Failed to attach brightness filter\n");
mlt_filter_close(brightness);
mlt_producer_close(producer);
mlt_profile_close(profile);
mlt_factory_close();
return 1;
}

// 5. 创建 consumer,用 avformat 重新编码成 MP4
// input 传 output_path,相当于命令行:melt input.mp4 -consumer avformat:output.mp4 ...
mlt_consumer consumer = mlt_factory_consumer(profile, "avformat", output_path);
if (!consumer) {
fprintf(stderr, "Failed to create avformat consumer for %s\n", output_path);
mlt_filter_close(brightness);
mlt_producer_close(producer);
mlt_profile_close(profile);
mlt_factory_close();
return 1;
}

// 设置编码参数(按你项目的 ffmpeg 支持情况调整)
mlt_properties cprops = MLT_CONSUMER_PROPERTIES(consumer);

// vcodec: 用 libx264 或 h264_nvenc 等,取决于你的 ffmpeg 配置
mlt_properties_set(cprops, "vcodec", "libx264");
// 比特率(单位 bps)
mlt_properties_set_int(cprops, "bitrate", 4000000); // 4Mbps
// 帧率(从 profile 里拿)
char fps_str[64];
snprintf(fps_str, sizeof(fps_str), "%.3f", mlt_profile_fps(profile));
mlt_properties_set(cprops, "frame_rate", fps_str);

// 这里让 consumer 只写文件,不预览
mlt_properties_set(cprops, "real_time", "0");
// 可选:覆盖输出文件
mlt_properties_set_int(cprops, "overwrite", 1);

// 6. 连接 producer -> consumer
mlt_consumer_connect(consumer, MLT_PRODUCER_SERVICE(producer));

// 7. 启动消费(这个会内部循环拉取 frame,逐帧调用 filter,再编码)
if (mlt_consumer_start(consumer) != 0) {
fprintf(stderr, "Failed to start consumer\n");
mlt_consumer_close(consumer);
mlt_filter_close(brightness);
mlt_producer_close(producer);
mlt_profile_close(profile);
mlt_factory_close();
return 1;
}

// 等待 consumer 完成(阻塞到转码结束)
while (!mlt_consumer_is_stopped(consumer)) {
sleep(1);
}

// 8. 资源清理
mlt_consumer_close(consumer);
// 注意:producer 上已经 attach 了 filter,关闭 producer 会连带释放 filter;
// 如果你想手动控制,也可以先 mlt_producer_detach 再 mlt_filter_close
mlt_producer_close(producer);
mlt_profile_close(profile);
mlt_factory_close();

printf("Done. Wrote output to %s\n", output_path);
return 0;
}

阅读全文 »

程序员的工作特点:久坐、高强度脑力、屏幕时间长、偶有通宵 / on‑call / 出差。本文按“系统 → 风险 → 维护动作 → 红旗症状 → 工具/习惯”组织,并提供可执行清单。并非诊断或处方,若有基础病或症状请及时就医并遵循当地指南。

阅读全文 »
0%