Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
dummy-image-generator.cpp
Go to the documentation of this file.
1/*
2 DummyImageGenerator - creating test output frames for simulated playback
3
4 Copyright (C)
5 2009, Joel Holdsworth <joel@airwebreathe.org.uk>,
6 Hermann Vosseler <Ichthyostega@web.de>
7
8  **Lumiera** is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by the
10  Free Software Foundation; either version 2 of the License, or (at your
11  option) any later version. See the file COPYING for further details.
12
13* *****************************************************************/
14
15
23
24#include <algorithm>
25
26
27namespace steam {
28namespace node {
29
30 using std::byte;
31 using std::clamp;
32
33 namespace { // implementation details
34
35 using Trip = std::array<byte,3>;
36
38 inline Trip
39 rgb_to_yuv (Trip const& rgb)
40 {
41 auto r = int(rgb[0]);
42 auto g = int(rgb[1]);
43 auto b = int(rgb[2]);
44 Trip yuv;
45 auto& [y,u,v] = yuv;
46 y = byte(clamp ( 0 + ( 299 * r + 587 * g + 114 * b) / 1000, 16,235)); // Luma clamped to MPEG scan range
47 u = byte(clamp (128 + (-168736 * r - 331264 * g + 500000 * b) / 1000000, 0, 255)); // Chroma components mapped according to Rec.601
48 v = byte(clamp (128 + ( 500000 * r - 418688 * g - 81312 * b) / 1000000, 0, 255)); // (but with integer arithmetics and slightly rounded coefficients)
49 return yuv;
50 }
51
52
53 void
54 rgb_buffer_to_yuy2 (byte* in, byte* out, uint cntPix)
55 {
56 REQUIRE (cntPix %2 == 0);
57 for (uint i = 0; i < cntPix; i += 2)
58 {// convert and interleave 2 pixels in one step
59 uint ip = i * 3; // Input uses (RGB)-triples
60 uint op = i * 2; // Output packed in groups with 2 bytes
61 Trip& rgb0 = reinterpret_cast<Trip&> (in[ip]);
62 Trip& rgb1 = reinterpret_cast<Trip&> (in[ip+3]);
63 Trip yuv0 = rgb_to_yuv (rgb0);
64 Trip yuv1 = rgb_to_yuv (rgb1);
65
66 auto& [y0,u0,v0] = yuv0;
67 auto& [y1,_u,_v] = yuv1; // note: this format discards half of the chroma information
68
69 out[op ] = y0;
70 out[op + 1] = u0;
71 out[op + 2] = y1;
72 out[op + 3] = v0;
73 } }
74
75
76 } // (End) implementation details
77
78
79
80
82 : fps_{fps}
83 , useRGB_{false}
84 , beat_{false}
85 , frame_{0}
86 { }
87
88 void
90 {
91 INFO (steam, "ImageGen: use format %d", displayFormat);
92 REQUIRE ( displayFormat == lumiera::DISPLAY_NONE
93 or displayFormat == lumiera::DISPLAY_YUV
94 or displayFormat == lumiera::DISPLAY_RGB);
95
96 useRGB_ = (displayFormat == lumiera::DISPLAY_RGB);
97 }
98
99 void
101 {
102 ++frame_;
103 if(frame_ > 2 * fps_)
104 frame_ = 0;
105
106 if(frame_ < 1 * fps_)
107 generateNoise (buffer);
108 else
109 generateBars (buffer);
110 }
111
112 void
114 { // create random snow...
115 for (uint i = 0; i < W*H*3; i+=3)
116 {
117 auto value = byte(rand());
118 buffer[i] = value;
119 buffer[i+1] = value;
120 buffer[i+2] = value;
121 }
122 }
123
125 void
127 {
128 using Row = std::array<Trip, W>;
129 using Img = std::array<Row, H>;
130
131 Img& img = reinterpret_cast<Img&> (*buffer);
132 Row& row = img[0];
133
134 const byte ON = byte(0xC0);
135 const byte OFF{0};
136
137 // classic NTSC colour bars --R---G---B--
138 std::array<Trip, 7> bars = {{{ ON, ON, ON}
139 ,{ ON, ON,OFF}
140 ,{OFF, ON, ON}
141 ,{OFF, ON,OFF}
142 ,{ ON,OFF, ON}
143 ,{ ON,OFF,OFF}
144 ,{OFF,OFF, ON}
145 }};
146
147 // create a colour strip pattern in the first row...
148 for (uint x = 0; x < W; ++x)
149 { // quantise into 7 columns
150 uint col = x * 7/W;
151 row[x] = bars[col];
152 }
153
154 // fill remaining rows of the frame with the same pattern
155 for (uint y = 1; y < H; ++y)
156 img[y] = row;
157 }
158
159
162 {
163 beat_ = not beat_;
164 DummyFrame outBuff = current();
165 // next output buffer to return
166
167 DummyFrame workspace = useRGB_? outBuff : workBuf_.data();
168 generateFrame (workspace);
169 if (not useRGB_)
170 rgb_buffer_to_yuy2(workBuf_.data(), outBuff, W*H);
171
172 return outBuff;
173
174 }
175
176
179 {
180 return beat_? outFrame_A_.data() : outFrame_B_.data();
181 }
182
183
184
185}} // namespace steam::node
void generateBars(DummyFrame buffer)
fill the RGB-Buffer with the well-known NTSC colour-bar pattern
DummyFrame next()
generate the next frame and occupy the alternate buffer.
void configure(lumiera::DisplayerInput)
DummyFrame current()
just re-return a pointer to the current frame without generating any new image data
std::array< std::byte, BUFF_SIZ > outFrame_A_
alternating output buffers
std::array< std::byte, WORK_SIZ > workBuf_
workspace for RGB calculation
std::array< std::byte, BUFF_SIZ > outFrame_B_
std::byte * DummyFrame
Generator for test dummy video frames to simulate playback of rendered output.
unsigned int uint
Definition integral.hpp:29
Node node(size_t id)
Definition dot-gen.hpp:165
DisplayerInput
Supported Displayer formats.
Trip rgb_to_yuv(Trip const &rgb)
slightly simplified conversion from RGB components to Y'CbCr with Rec.601 (MPEG style)
Steam-Layer implementation namespace root.