Fix integer overflow in ft_rendered_size_line
[ilaris-y4m-tools.git] / changefps.cpp
blobc6592e97ce7e92847dfececbc9b52bff0712403d
1 #include "yuv4mpeg.hpp"
2 #include "parseval.hpp"
3 #include "fpschanger.hpp"
4 #include <iostream>
6 int main(int argc, char** argv)
8 uint64_t infr = 0;
9 uint64_t outfr = 0;
10 uint32_t ofps_n = 25;
11 uint32_t ofps_d = 1;
12 uint32_t fps_n = 0;
13 uint32_t fps_d = 0;
14 size_t framesize = 0;
15 for(int i = 1; i < argc; i++) {
16 std::string arg = argv[i];
17 regex_results r;
18 if(r = regex("--fps=([1-9][0-9]*)", arg)) {
19 try {
20 fps_n = parse_value<unsigned>(r[1]);
21 fps_d = 1;
22 } catch(std::exception& e) {
23 std::cerr << "changefps: Bad fps '" << r[1] << "'" << std::endl;
24 return 1;
26 } else if(r = regex("--fps=([1-9][0-9]*)/([1-9][0-9]*)", arg)) {
27 try {
28 fps_n = parse_value<unsigned>(r[1]);
29 fps_d = parse_value<unsigned>(r[2]);
30 } catch(std::exception& e) {
31 std::cerr << "changefps: Bad fps '" << r[1] << "/" << r[2] << "'" << std::endl;
32 return 1;
34 } else {
35 std::cerr << "changefps: Unrecognized option '" << arg << "'" << std::endl;
36 return 1;
40 //Open files.
41 FILE* in = stdin;
42 FILE* out = stdout;
43 mark_pipe_as_binary(in);
44 mark_pipe_as_binary(out);
46 //Fixup header.
47 try {
48 regex_results r;
49 struct yuv4mpeg_stream_header strmh(in);
50 if(strmh.chroma == "rgb")
51 framesize = 3 * strmh.width * strmh.height;
52 else if(strmh.chroma == "420")
53 framesize = 3 * strmh.width * strmh.height / 2;
54 else if(strmh.chroma == "420p16")
55 framesize = 6 * strmh.width * strmh.height / 2;
56 else if(strmh.chroma == "422")
57 framesize = 2 * strmh.width * strmh.height;
58 else if(strmh.chroma == "422p16")
59 framesize = 4 * strmh.width * strmh.height;
60 else if(strmh.chroma == "444")
61 framesize = 3 * strmh.width * strmh.height;
62 else if(strmh.chroma == "444p16")
63 framesize = 6 * strmh.width * strmh.height;
64 else
65 throw std::runtime_error("Unsupported input chroma type '" + strmh.chroma + "'");
66 if(strmh.fps_n && strmh.fps_d) {
67 ofps_n = strmh.fps_n;
68 ofps_d = strmh.fps_d;
70 if(fps_n && fps_d) {
71 strmh.fps_n = fps_n;
72 strmh.fps_d = fps_d;
73 } else {
74 fps_n = ofps_n;
75 fps_d = ofps_d;
77 strmh.delete_extensions("VFR");
78 std::string _strmh = std::string(strmh);
79 write_or_die(out, _strmh);
81 unsigned duration = 0;
82 unsigned count = 0;
83 fpschanger timer(fps_n, fps_d, ofps_n, ofps_d);
84 std::string _framh, _framh2;
85 std::vector<char> buffer;
86 buffer.resize(framesize);
87 struct yuv4mpeg_frame_header framh;
89 //Frame loop.
90 next_input:
91 if(!read_line2(in, _framh))
92 return 0; //End.
93 framh = yuv4mpeg_frame_header(_framh);
94 infr++;
95 read_or_die(in, &buffer[0], buffer.size());
96 duration = framh.duration; //Default.
97 count = timer.duration(duration);
98 for(unsigned i = 0; i < count; i++) {
99 outfr++;
100 framh.duration = 1;
101 std::string _framh2 = framh;
102 write_or_die(out, _framh2);
103 write_or_die(out, &buffer[0], framesize);
105 goto next_input;
106 } catch(std::exception& e) {
107 std::cerr << "changefps: Error: " << e.what() << std::endl;
108 return 1;
110 std::cerr << "changefps: Read " << infr << " frames, wrote " << outfr << " frames." << std::endl;
111 return 0;