Fix some problems reported by Valgrind
[jpcrr.git] / streamtools / output-drv-rawi420.cpp
blob64e02dcd18c805a1447fc7f04482336c41ce5258
1 #include <cstring>
2 #include "output-drv.hpp"
3 #include <iostream>
4 #include <fstream>
5 #include <stdexcept>
6 #include <vector>
7 #include <string>
8 #include <sstream>
9 #include "rgbtorgb.hh"
11 namespace
13 class output_driver_rawi420 : public output_driver
15 public:
16 output_driver_rawi420(const std::string& filename, bool _uvswap)
18 uvswap = _uvswap;
19 if(filename != "-")
20 out = new std::ofstream(filename.c_str(), std::ios_base::binary);
21 else
22 out = &std::cout;
23 if(!*out)
24 throw std::runtime_error("Unable to open output file");
25 set_video_callback<output_driver_rawi420>(*this, &output_driver_rawi420::video_callback);
28 ~output_driver_rawi420()
30 if(out != &std::cout)
31 delete out;
34 void ready()
36 const video_settings& v = get_video_settings();
37 framesize = 4 * v.get_width() * v.get_height();
38 width = v.get_width();
41 void video_callback(uint64_t timestamp, const uint8_t* raw_rgbx_data)
43 std::vector<unsigned char> tmp(framesize * 3 / 8);
44 size_t primarysize = framesize / 4;
45 size_t offs1 = primarysize / 4;
46 size_t offs2 = 0;
47 if(uvswap)
48 std::swap(offs1, offs2);
49 Convert32To_I420Frame(raw_rgbx_data, &tmp[0], framesize / 4, width);
50 size_t r;
51 out->write((const char*)&tmp[0], primarysize);
52 if(!*out) {
53 std::stringstream str;
54 str << "Error writing frame to file (requested " << primarysize << ", got " << r
55 << ")";
56 throw std::runtime_error(str.str());
58 //Swap U and V.
59 out->write((const char*)&tmp[primarysize + offs1], primarysize / 4);
60 if(!*out) {
61 std::stringstream str;
62 str << "Error writing frame to file (requested " << primarysize / 4 << ", got "
63 << r << ")";
64 throw std::runtime_error(str.str());
66 out->write((const char*)&tmp[primarysize + offs2], primarysize / 4);
67 if(!*out) {
68 std::stringstream str;
69 str << "Error writing frame to file (requested " << primarysize / 4 << ", got "
70 << r << ")";
71 throw std::runtime_error(str.str());
74 private:
75 std::ostream* out;
76 size_t framesize;
77 size_t width;
78 bool uvswap;
81 class output_driver_rawi420_factory : output_driver_factory
83 public:
84 output_driver_rawi420_factory(const std::string& name, bool _uvswap)
85 : output_driver_factory(name)
87 uvswap = _uvswap;
90 output_driver& make(const std::string& type, const std::string& name, const std::string& parameters)
92 if(parameters != "")
93 throw std::runtime_error("rawi420 output does not take parameters");
94 return *new output_driver_rawi420(name, uvswap);
96 private:
97 bool uvswap;
99 output_driver_rawi420_factory fact1("rawi420", false);
100 output_driver_rawi420_factory fact2("rawi420-uvswap", true);