streamtools: Backport newer x264 driver
[jpcrr.git] / streamtools / outputs / x264.cpp
blobd85f61440a0ba4810c92d0189eaad5d266473f03
1 #include <cstring>
2 #include "outputs/internal.hpp"
3 #include "outputs/I420.hpp"
4 #include "outputs/argexpand.hpp"
5 #include <cstdio>
6 #include <stdexcept>
7 #include <vector>
8 #include <string>
9 #include <sstream>
11 namespace
13 std::string expand_options(const std::string& opts, uint32_t rn, uint32_t rd)
15 std::ostringstream ret;
16 if(rd)
17 ret << "--fps " << rn << "/" << rd << " ";
18 ret << expand_arguments_common(opts, "--", " ");
19 return ret.str();
22 class output_driver_x264 : public output_driver
24 public:
25 output_driver_x264(const std::string& _filename, const std::string& _options, bool _newres)
27 filename = _filename;
28 options = _options;
29 set_video_callback(make_bound_method(*this, &output_driver_x264::video_callback));
30 newres = _newres;
33 ~output_driver_x264()
35 pclose(out);
38 void ready()
40 const video_settings& v = get_video_settings();
41 framesize = 4 * v.get_width() * v.get_height();
42 width = v.get_width();
43 height = v.get_height();
45 std::stringstream commandline;
46 commandline << "x264 ";
47 commandline << expand_options(options, v.get_rate_num(), v.get_rate_denum());
48 commandline << " -o " << filename << " - ";
49 if(newres)
50 commandline << "--input-res ";
51 commandline << v.get_width() << "x" << v.get_height();
52 std::string s = commandline.str();
53 std::cerr << s << std::endl;
54 out = popen(s.c_str(), "w");
55 if(!out) {
56 std::stringstream str;
57 str << "Can't run x264 (" << s << ")";
58 throw std::runtime_error(str.str());
62 void video_callback(uint64_t timestamp, const uint8_t* raw_rgbx_data)
64 I420_convert_common(raw_rgbx_data, width, height, out, true);
66 private:
67 FILE* out;
68 std::string filename;
69 std::string options;
70 size_t framesize;
71 uint32_t width;
72 uint32_t height;
73 bool newres;
76 class output_driver_x264_factory : output_driver_factory
78 public:
79 output_driver_x264_factory()
80 : output_driver_factory("x264")
84 output_driver& make(const std::string& type, const std::string& name, const std::string& parameters)
86 return *new output_driver_x264(name, parameters, false);
88 } factory1;
90 class output_driver_x264n_factory : output_driver_factory
92 public:
93 output_driver_x264n_factory()
94 : output_driver_factory("x264n")
98 output_driver& make(const std::string& type, const std::string& name, const std::string& parameters)
100 return *new output_driver_x264(name, parameters, true);
102 } factory2;