-
Notifications
You must be signed in to change notification settings - Fork 1
/
encode_rt.hpp
153 lines (130 loc) · 3.87 KB
/
encode_rt.hpp
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
#pragma once
#include "base.hpp"
#ifdef DECODE_FFMPEG
#include "decode_ffmpeg.hpp"
#else
#ifdef DECODE_OPENCV
#include "decode_opencv.hpp"
#endif
#endif
class Encoder_RT : public Encoder {
private:
Font *fnt;
B *frame;
int contrast;
#ifdef DECODE_FFMPEG
Decoder_FFmpeg *decoder;
#else
#ifdef DECODE_OPENCV
Decoder_OpenCV *decoder;
#endif
#endif
public:
int xy;
Encoder_RT(
std::string video,
std::string font,
std::string scale,
int fps,
int _contrast,
char *name,
int _debug = 0) : Encoder(_debug) {
contrast = _contrast;
fnt = new Font(font);
#ifdef DECODE_FFMPEG
decoder = new Decoder_FFmpeg(video);
#else
#ifdef DECODE_OPENCV
decoder = new Decoder_OpenCV(video);
#endif
#endif
VideoProperties *vp = decoder->analysis();
if (!vp) {
throws("Failed to analysis video.");
return;
}
const int _w = vp->width;
const int _h = vp->height;
const double _r = vp->rate;
mo = 0.5 + ((double)_r) / ((double)fps);
if (!mo) {
mo = 1;
}
clk = mo * 1000000LL / _r;
const int max_z = get_console_size();
const int max_x = max_z & 65535, max_y = ((max_z >> 16) - 1) << 1;
sscanf(scale.c_str(), "%d:%d", &x, &y);
if (x) {
if (y) {
// x = x;
// y = y;
} else {
// x = x;
y = (_h * x + (_w >> 1)) / _w;
}
} else {
if (y) {
x = (_w * y + (_h >> 1)) / _h;
// y = y;
} else {
const int max_yx = (_w * max_y + (_h >> 1)) / _h;
x = std::min(max_x, max_yx);
const int max_xy = (_h * max_x + (_w >> 1)) / _w;
y = std::min(max_y, max_xy);
}
}
if (y % 2) {
if (y == max_y + 1) {
y = max_y;
} else {
y++;
}
}
xy = x * y;
printf("[%d:%d %.2lfHz] -%s-> [%d:%d %.2lfHz] %.3lfs/%dms %s\n",
_w, _h, _r, name,
x, y, _r / mo,
vp->duration, clk / 1000,
debug ? "[debug]" : "");
// [1444:1080 29.97Hz] -> [75:56 29.97Hz] 232.065s/33ms [debug]
if (decoder->ready_to_read(x, y)) {
throws("Failed to read video.");
return;
}
print_size = (x + 1) * (y >> 1);
frame = (B *)malloc(xy);
buffer = (char *)malloc(print_size + 2);
}
inline int read_a_frame() {
return decoder->read_a_frame(frame);
}
inline void refresh_buffer() {
if (contrast) {
int max_pixel = 0, min_pixel = 255;
for (auto j = 0; j < xy; j++) {
if (frame[j] > max_pixel) max_pixel = frame[j];
if (frame[j] < min_pixel) min_pixel = frame[j];
}
if (max_pixel ^ min_pixel) {
int range = max_pixel - min_pixel;
for (auto j = 0; j < xy; j++) {
frame[j] = (frame[j] - min_pixel) * 0xff / range;
}
} else {
memset(frame, max_pixel & 128 ? 0xff : 0x00, xy);
}
}
int buffer_tail = 0;
for (auto j = 0; j < (y >> 1); j++) {
for (auto k = 0; k < x; k++) {
buffer[buffer_tail++] = fnt->get(frame[(j << 1) * x + k],
frame[(j << 1 | 1) * x + k]);
}
buffer[buffer_tail++] = '\n';
}
buffer[buffer_tail++] = '\n';
}
inline void cls() {
decoder->cls();
}
};