Add resizer letterbox2
[jpcrr.git] / streamtools / output-drv.cpp
blobf2d29b993421f1d5d743ba0b8fdbc3726cea9adb
1 #include "output-drv.hpp"
2 #include <stdexcept>
3 #include <list>
4 #include "dedup.hpp"
6 class audio_dyncall_null : public audio_dyncall_base
8 void operator()(short left, short right)
13 class audio_end_dyncall_null : public audio_end_dyncall_base
15 void operator()()
20 class video_dyncall_null : public video_dyncall_base
22 void operator()(uint64_t timestamp, const uint8_t* raw_rgbx_data)
27 class subtitle_dyncall_null : public subtitle_dyncall_base
29 void operator()(uint64_t basetime, uint64_t duration, const uint8_t* text)
34 audio_settings::audio_settings(uint32_t _rate)
36 rate = _rate;
39 uint32_t audio_settings::get_rate() const
41 return rate;
44 audio_dyncall_base::~audio_dyncall_base()
48 audio_end_dyncall_base::~audio_end_dyncall_base()
52 video_settings::video_settings(uint32_t _width, uint32_t _height, uint32_t _rate_num, uint32_t _rate_denum)
54 width = _width;
55 height = _height;
56 rate_num = _rate_num;
57 rate_denum = _rate_denum;
60 uint32_t video_settings::get_width() const
62 return width;
65 uint32_t video_settings::get_height() const
67 return height;
70 uint32_t video_settings::get_rate_num() const
72 return rate_num;
75 uint32_t video_settings::get_rate_denum() const
77 return rate_denum;
80 video_dyncall_base::~video_dyncall_base()
84 subtitle_settings::subtitle_settings()
88 subtitle_dyncall_base::~subtitle_dyncall_base()
92 const audio_settings& output_driver::get_audio_settings()
94 return asettings;
97 const video_settings& output_driver::get_video_settings()
99 return vsettings;
102 const subtitle_settings& output_driver::get_subtitle_settings()
104 return ssettings;
107 output_driver::output_driver()
108 : asettings(0), vsettings(0, 0, 0, 0), ssettings()
110 audio_handler = new audio_dyncall_null();
111 audio_end_handler = new audio_end_dyncall_null();
112 video_handler = new video_dyncall_null();
113 subtitle_handler = new subtitle_dyncall_null();
116 output_driver::~output_driver()
118 delete audio_handler;
119 delete audio_end_handler;
120 delete video_handler;
121 delete subtitle_handler;
124 void output_driver::do_audio_callback(short left, short right)
126 (*audio_handler)(left, right);
129 void output_driver::do_audio_end_callback()
131 (*audio_end_handler)();
134 void output_driver::do_video_callback(uint64_t timestamp, const uint8_t* raw_rgbx_data)
136 (*video_handler)(timestamp, raw_rgbx_data);
139 void output_driver::do_subtitle_callback(uint64_t basetime, uint64_t duration, const uint8_t* text)
141 (*subtitle_handler)(basetime, duration, text);
144 void output_driver::set_audio_settings(audio_settings a)
146 asettings = a;
149 void output_driver::set_video_settings(video_settings v)
151 vsettings = v;
154 void output_driver::set_subtitle_settings(subtitle_settings s)
156 ssettings = s;
159 std::map<std::string, output_driver_factory*>* output_driver_factory::factories;
161 output_driver_factory::~output_driver_factory()
165 output_driver_factory::output_driver_factory(const std::string& type)
167 if(!factories)
168 factories = new std::map<std::string, output_driver_factory*>();
169 (*factories)[type] = this;
172 output_driver& output_driver_factory::make_by_type(const std::string& type, const std::string& name,
173 const std::string& parameters)
175 if(!factories || !factories->count(type))
176 throw std::runtime_error("Unknown output driver type");
177 return (*factories)[type]->make(type, name, parameters);
180 namespace
182 std::list<output_driver*> drivers;
183 audio_settings asettings(0);
184 video_settings vsettings(0, 0, 0, 0);
185 subtitle_settings ssettings;
186 dedup dedupper(0, 0, 0);
189 void distribute_audio_callback(short left, short right)
191 for(std::list<output_driver*>::iterator i = drivers.begin(); i != drivers.end(); ++i)
192 (*i)->do_audio_callback(left, right);
194 void distribute_video_callback(uint64_t timestamp, const uint8_t* raw_rgbx_data)
196 for(std::list<output_driver*>::iterator i = drivers.begin(); i != drivers.end(); ++i)
197 (*i)->do_video_callback(timestamp, raw_rgbx_data);
200 void distribute_subtitle_callback(uint64_t basetime, uint64_t duration, const uint8_t* text)
202 for(std::list<output_driver*>::iterator i = drivers.begin(); i != drivers.end(); ++i)
203 (*i)->do_subtitle_callback(basetime, duration, text);
206 void set_audio_parameters(audio_settings a)
208 asettings = a;
211 void set_video_parameters(video_settings v)
213 vsettings = v;
216 void set_subtitle_parameters(subtitle_settings s)
218 ssettings = s;
221 void add_output_driver(const std::string& type, const std::string& name, const std::string& parameters)
223 output_driver& driver = output_driver_factory::make_by_type(type, name, parameters);
224 drivers.push_back(&driver);
225 driver.set_audio_settings(asettings);
226 driver.set_video_settings(vsettings);
227 driver.set_subtitle_settings(ssettings);
228 driver.ready();
231 void close_output_drivers()
233 for(std::list<output_driver*>::iterator i = drivers.begin(); i != drivers.end(); ++i)
234 (*i)->do_audio_end_callback();
235 for(std::list<output_driver*>::iterator i = drivers.begin(); i != drivers.end(); ++i)
236 delete *i;
237 drivers.clear();
240 void distribute_audio_callback(npair<short> sample)
242 distribute_audio_callback(sample.get_x(), sample.get_y());
245 void distribute_subtitle_callback(struct packet& p)
247 uint64_t basetime = p.rp_timestamp;
248 uint64_t duration = 0;
249 uint8_t* text = NULL;
250 if(p.rp_major != 4 || p.rp_minor != 0 || p.rp_payload.size() < 8)
251 return; //Bad subtitle packet.
252 for(size_t i = 0; i < 8; i++)
253 duration |= ((uint64_t)p.rp_payload[i] << (56 - 8 * i));
254 text = &p.rp_payload[8];
255 distribute_subtitle_callback(basetime, duration, text);
258 std::string get_output_driver_list()
260 bool first = true;
261 if(!output_driver_factory::factories)
262 return "";
263 std::string c;
264 std::map<std::string, output_driver_factory*>& f = *output_driver_factory::factories;
265 for(std::map<std::string, output_driver_factory*>::iterator i = f.begin(); i != f.end(); ++i) {
266 if(first)
267 c = i->first;
268 else
269 c = c + " " + i->first;
270 first = false;
272 return c;