Fix CSCD output
[jpcrr.git] / streamtools / outputs / cscd-control.cpp
blob2befc5f115c32f74d04f51f0dced2305927c58be
1 #include <cstring>
2 #include "outputs/internal.hpp"
3 #include "outputs/argexpand.hpp"
4 #include "cscd.hpp"
5 #include <cstdio>
6 #include <cstdlib>
7 #include <stdexcept>
8 #include <vector>
9 #include <string>
10 #include <sstream>
12 namespace
14 class output_driver_cscd : public output_driver
16 public:
17 output_driver_cscd(const std::string& _filename, unsigned _level, unsigned long _maxsegframes)
19 filename = _filename;
20 level = _level;
21 maxsegframes = _maxsegframes;
22 set_video_callback(make_bound_method(*this, &output_driver_cscd::video_callback));
23 set_audio_callback(make_bound_method(*this, &output_driver_cscd::audio_callback));
26 ~output_driver_cscd()
28 dumper->end();
29 delete dumper;
32 void ready()
34 const video_settings& v = get_video_settings();
35 const audio_settings& a = get_audio_settings();
36 avi_cscd_dumper::global_parameters gp;
37 avi_cscd_dumper::segment_parameters sp;
38 gp.sampling_rate = a.get_rate();
39 gp.channel_count = 2;
40 gp.audio_16bit = true;
41 sp.fps_n = v.get_rate_num();
42 sp.fps_d = v.get_rate_denum();
43 if(!sp.fps_n || !sp.fps_d) {
44 sp.fps_n = 60;
45 sp.fps_d = 1;
47 sp.dataformat = avi_cscd_dumper::PIXFMT_RGBX;
48 sp.width = v.get_width();
49 sp.height = v.get_height();
50 sp.default_stride = true;
51 sp.stride = 4 * v.get_width();
52 sp.keyframe_distance = (level > 9) ? 300 : 1;
53 sp.deflate_level = (level > 9) ? (1+ level % 10) : level;
54 sp.max_segment_frames = maxsegframes;
55 dumper = new avi_cscd_dumper(filename, gp, sp);
58 void video_callback(uint64_t timestamp, const uint8_t* raw_rgbx_data)
60 dumper->video(raw_rgbx_data);
61 dumper->wait_frame_processing();
64 void audio_callback(short left, short right)
66 dumper->audio(&left, &right, 1, avi_cscd_dumper::SNDFMT_SIGNED_16NE);
68 private:
69 FILE* out;
70 std::string filename;
71 unsigned level;
72 avi_cscd_dumper* dumper;
73 unsigned long maxsegframes;
76 class output_driver_cscd_factory : output_driver_factory
78 public:
79 output_driver_cscd_factory()
80 : output_driver_factory("cscd")
84 output_driver& make(const std::string& type, const std::string& name, const std::string& parameters)
86 unsigned level = 7;
87 unsigned long maxsegframes = 0;
88 std::string p = parameters;
89 while(p != "") {
90 size_t s = p.find_first_of(",");
91 std::string n;
92 std::string x;
93 if(s < p.length()) {
94 x = p.substr(0, s);
95 n = p.substr(s + 1);
96 } else {
97 x = p;
98 n = "";
100 p = n;
101 if(x.substr(0, 6) == "level=") {
102 std::string y = x.substr(6);
103 char* e;
104 level = strtoul(y.c_str(), &e, 10);
105 if(level > 18 || *e)
106 throw std::runtime_error("Bad compression level");
108 if(x.substr(0, 13) == "maxsegframes=") {
109 std::string y = x.substr(13);
110 char* e;
111 maxsegframes = strtoul(y.c_str(), &e, 10);
112 if(*e)
113 throw std::runtime_error("Bad maxsegframes");
116 return *new output_driver_cscd(name, level, maxsegframes);
118 } factory1;