XV-Display: reorganise image-generator code
This is a first step towards the ability to produce several different output formats... Refactor the code to separate - the double buffering - the actual image generation, which works in RGB - the conversion routine Furthermore, replace unsigned char by std::byte and introduce std::array and structured binding to avoid many usages of pointers; hopefully this makes the intention of the code clearer. Verified and cross-checked the actual converion logic; in fact this is a conversion to "YUV" as used by MPEG, which in more precise terms is Y'CrCb with Rec.601 colour space and a scan range limitation (16...235) on the Luma component.
This commit is contained in:
parent
42ce53aa09
commit
8fe50e37a4
8 changed files with 281 additions and 111 deletions
|
|
@ -96,7 +96,7 @@ namespace lumiera {
|
|||
* through the CL Interface.
|
||||
* @see DisplayService::allocate */
|
||||
inline void
|
||||
operator() (LumieraDisplayFrame frame)
|
||||
operator() (DummyFrame frame)
|
||||
{
|
||||
impl().put_ (&impl(),frame);
|
||||
}
|
||||
|
|
@ -126,9 +126,9 @@ extern "C" {
|
|||
#include "common/interface.h"
|
||||
|
||||
LUMIERA_INTERFACE_DECLARE (lumieraorg_Display, 0
|
||||
, LUMIERA_INTERFACE_SLOT (void, allocate,(LumieraDisplaySlot) )
|
||||
, LUMIERA_INTERFACE_SLOT (void, release,(LumieraDisplaySlot) )
|
||||
, LUMIERA_INTERFACE_SLOT (void, put,(LumieraDisplaySlot, LumieraDisplayFrame))
|
||||
, LUMIERA_INTERFACE_SLOT (void, allocate,(LumieraDisplaySlot) )
|
||||
, LUMIERA_INTERFACE_SLOT (void, release,(LumieraDisplaySlot) )
|
||||
, LUMIERA_INTERFACE_SLOT (void, put,(LumieraDisplaySlot, DummyFrame))
|
||||
);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@
|
|||
#ifndef LUMIERA_DISPLAY_HANDLES_H
|
||||
#define LUMIERA_DISPLAY_HANDLES_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
|
||||
typedef unsigned char * LumieraDisplayFrame;
|
||||
using DummyFrame = std::byte *;
|
||||
|
||||
|
||||
struct lumiera_displaySlot_struct
|
||||
{
|
||||
void (*put_)(lumiera_displaySlot_struct*, LumieraDisplayFrame);
|
||||
void (*put_)(lumiera_displaySlot_struct*, DummyFrame);
|
||||
};
|
||||
typedef struct lumiera_displaySlot_struct lumiera_displaySlot;
|
||||
typedef lumiera_displaySlot* LumieraDisplaySlot;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ namespace stage {
|
|||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (put,
|
||||
void, (LumieraDisplaySlot slotHandle, LumieraDisplayFrame frame),
|
||||
void, (LumieraDisplaySlot slotHandle, DummyFrame frame),
|
||||
{
|
||||
//skipping full checks for performance reasons
|
||||
REQUIRE (_instance && !lumiera_error_peek());
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ namespace stage {
|
|||
Dispatcher dispatcher_;
|
||||
FrameSignal hasFrame_;
|
||||
|
||||
LumieraDisplayFrame currBuffer_;
|
||||
DummyFrame currBuffer_;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -89,7 +89,7 @@ namespace stage {
|
|||
/* Implementation-level API to be used by DisplayService */
|
||||
|
||||
/** receive a frame to be displayed */
|
||||
inline void put (LumieraDisplayFrame);
|
||||
inline void put (DummyFrame);
|
||||
|
||||
|
||||
private:
|
||||
|
|
@ -161,7 +161,7 @@ namespace stage {
|
|||
|
||||
|
||||
void
|
||||
DisplayerSlot::put(LumieraDisplayFrame newFrame)
|
||||
DisplayerSlot::put(DummyFrame newFrame)
|
||||
{
|
||||
if (newFrame != currBuffer_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,56 +21,55 @@
|
|||
|
||||
#include "steam/engine/worker/dummy-image-generator.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace steam {
|
||||
namespace node {
|
||||
|
||||
|
||||
using std::byte;
|
||||
using std::clamp;
|
||||
|
||||
namespace { // implementation details
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
using Trip = std::array<byte,3>;
|
||||
|
||||
inline int
|
||||
clamp (const int &val, const int &maxval, const int &minval)
|
||||
/** slightly simplified conversion from RGB components to Y'CbCr with Rec.601 (MPEG style) */
|
||||
inline Trip
|
||||
rgb_to_yuv (Trip const& rgb)
|
||||
{
|
||||
if(val > maxval) return maxval;
|
||||
if(val < minval) return minval;
|
||||
return val;
|
||||
}
|
||||
|
||||
inline void
|
||||
rgb_to_yuv (int r, int g, int b, byte &y, byte &u, byte &v)
|
||||
{
|
||||
// This code isn't great, but it does the job
|
||||
y = (byte)clamp((299 * r + 587 * g + 114 * b) / 1000, 235, 16);
|
||||
v = (byte)clamp((500 * r - 419 * g - 81 * b) / 1000 + 127, 255, 0);
|
||||
u = (byte)clamp((-169 * r - 331 * g + 500 * b) / 1000 + 127, 255, 0);
|
||||
auto r = int(rgb[0]);
|
||||
auto g = int(rgb[1]);
|
||||
auto b = int(rgb[2]);
|
||||
Trip yuv;
|
||||
auto& [y,u,v] = yuv;
|
||||
y = byte(clamp ( 0 + ( 299 * r + 587 * g + 114 * b) / 1000, 16,235)); // Luma clamped to MPEG scan range
|
||||
u = byte(clamp (128 + (-169 * r - 331 * g + 500 * b) / 1000, 0, 255)); // Chroma components mapped according to Rec.601
|
||||
v = byte(clamp (128 + ( 500 * r - 419 * g - 81 * b) / 1000, 0, 255)); // (but with integer arithmetics and slightly rounded coefficients)
|
||||
return yuv;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rgb_buffer_to_yuy2 (unsigned char *in, unsigned char *out)
|
||||
rgb_buffer_to_yuy2 (byte* in, byte* out, uint cntPix)
|
||||
{
|
||||
for (uint i = 0; i < 320*240*2; i+=4)
|
||||
{
|
||||
byte y0, u0, v0;
|
||||
const byte r0 = *(in++);
|
||||
const byte g0 = *(in++);
|
||||
const byte b0 = *(in++);
|
||||
rgb_to_yuv(r0, g0, b0, y0, u0, v0);
|
||||
REQUIRE (cntPix %2 == 0);
|
||||
for (uint i = 0; i < cntPix; i += 2)
|
||||
{// convert and interleave 2 pixels in one step
|
||||
uint ip = i * 3; // Input uses (RGB)-triples
|
||||
uint op = i * 2; // Output packed in groups with 2 bytes
|
||||
Trip& rgb0 = reinterpret_cast<Trip&> (in[ip]);
|
||||
Trip& rgb1 = reinterpret_cast<Trip&> (in[ip+3]);
|
||||
Trip yuv0 = rgb_to_yuv (rgb0);
|
||||
Trip yuv1 = rgb_to_yuv (rgb1);
|
||||
|
||||
byte y1, u1, v1;
|
||||
const byte r1 = *(in++);
|
||||
const byte g1 = *(in++);
|
||||
const byte b1 = *(in++);
|
||||
rgb_to_yuv(r1, g1, b1, y1, u1, v1);
|
||||
auto& [y0,u0,v0] = yuv0;
|
||||
auto& [y1,_u,_v] = yuv1; // note: this format discards half of the chroma information
|
||||
|
||||
out[i] = y0;
|
||||
out[i + 1] = u0;
|
||||
out[i + 2] = y1;
|
||||
out[i + 3] = v0;
|
||||
out[op ] = y0;
|
||||
out[op + 1] = u0;
|
||||
out[op + 2] = y1;
|
||||
out[op + 3] = v0;
|
||||
} }
|
||||
|
||||
|
||||
|
|
@ -80,84 +79,81 @@ namespace node {
|
|||
|
||||
|
||||
DummyImageGenerator::DummyImageGenerator(uint fps)
|
||||
: current_(0)
|
||||
, frame_(0)
|
||||
, fps_(fps)
|
||||
: fps_{fps}
|
||||
, beat_{false}
|
||||
, frame_{0}
|
||||
{ }
|
||||
|
||||
|
||||
LumieraDisplayFrame
|
||||
DummyImageGenerator::next()
|
||||
void
|
||||
DummyImageGenerator::generateFrame (DummyFrame buffer)
|
||||
{
|
||||
|
||||
++frame_;
|
||||
if(frame_ > 2 * fps_)
|
||||
frame_ = 0;
|
||||
|
||||
if(frame_ < 1 * fps_)
|
||||
{
|
||||
{
|
||||
// create random snow...
|
||||
for(int i = 0; i < 320*240*3; i+=3)
|
||||
for (uint i = 0; i < W*H*3; i+=3)
|
||||
{
|
||||
byte value ( rand() );
|
||||
buf_[i] = value;
|
||||
buf_[i+1] = value;
|
||||
buf_[i+2] = value;
|
||||
auto value = byte(rand());
|
||||
buffer[i] = value;
|
||||
buffer[i+1] = value;
|
||||
buffer[i+2] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // create a colour strip pattern
|
||||
typedef unsigned char Row[320 * 3];
|
||||
typedef byte Row[W * 3];
|
||||
|
||||
unsigned char * row = buf_;
|
||||
byte* row = buffer;
|
||||
|
||||
// create a colour strip pattern in the first row...
|
||||
for(int x = 0; x < 320; ++x)
|
||||
for (uint x = 0; x < W; ++x)
|
||||
{
|
||||
byte &r = row[x*3];
|
||||
byte &g = row[x*3+1];
|
||||
byte &b = row[x*3+2];
|
||||
byte& r = row[x*3];
|
||||
byte& g = row[x*3+1];
|
||||
byte& b = row[x*3+2];
|
||||
|
||||
if (x < 1*320/7) r = 0xC0, g = 0xC0, b = 0xC0;
|
||||
else if(x < 2*320/7) r = 0xC0, g = 0xC0, b = 0x00;
|
||||
else if(x < 3*320/7) r = 0x00, g = 0xC0, b = 0xC0;
|
||||
else if(x < 4*320/7) r = 0x00, g = 0xC0, b = 0x00;
|
||||
else if(x < 5*320/7) r = 0xC0, g = 0x00, b = 0xC0;
|
||||
else if(x < 6*320/7) r = 0xC0, g = 0x00, b = 0x00;
|
||||
else r = 0x00, g = 0x00, b = 0xC0;
|
||||
const byte ON = byte(0xC0);
|
||||
const byte OFF{0};
|
||||
|
||||
if (x < 1*W/7) r = ON, g = ON, b = ON;
|
||||
else if(x < 2*W/7) r = ON, g = ON, b = OFF;
|
||||
else if(x < 3*W/7) r = OFF, g = ON, b = ON;
|
||||
else if(x < 4*W/7) r = OFF, g = ON, b = OFF;
|
||||
else if(x < 5*W/7) r = ON, g = OFF, b = ON;
|
||||
else if(x < 6*W/7) r = ON, g = OFF, b = OFF;
|
||||
else r = OFF, g = OFF, b = ON;
|
||||
}
|
||||
|
||||
// fill remaining rows of the frame with the same pattern
|
||||
for(int y = 1; y < 240; ++y)
|
||||
memcpy(buf_ + y*sizeof(Row), row, sizeof(Row));
|
||||
for (uint y = 1; y < H; ++y)
|
||||
memcpy(buffer + y*sizeof(Row), row, sizeof(Row));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DummyFrame
|
||||
DummyImageGenerator::next()
|
||||
{
|
||||
beat_ = not beat_;
|
||||
DummyFrame outBuff = current();
|
||||
// next output buffer to return
|
||||
|
||||
// select output buffer to return
|
||||
LumieraDisplayFrame outBuff;
|
||||
generateFrame (workBuf_.data());
|
||||
|
||||
if (!current_)
|
||||
{
|
||||
outBuff = outFrame_A_;
|
||||
current_= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
outBuff = outFrame_B_;
|
||||
current_= 0;
|
||||
}
|
||||
|
||||
rgb_buffer_to_yuy2(buf_, outBuff);
|
||||
rgb_buffer_to_yuy2(workBuf_.data(), outBuff, W*H);
|
||||
return outBuff;
|
||||
|
||||
}
|
||||
|
||||
|
||||
LumieraDisplayFrame
|
||||
DummyFrame
|
||||
DummyImageGenerator::current()
|
||||
{
|
||||
if (!current_) return outFrame_A_;
|
||||
else return outFrame_B_;
|
||||
return beat_? outFrame_A_.data() : outFrame_B_.data();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
** @todo obsolete since 2010, can be removed once we have a real player in the UI
|
||||
** @see stage::controller::PlaybackController
|
||||
** @see steam::play::DummyPlayerService
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -34,42 +34,44 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "include/display-facade.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
|
||||
namespace steam {
|
||||
namespace node {
|
||||
|
||||
|
||||
|
||||
|
||||
class DummyImageGenerator
|
||||
{
|
||||
|
||||
unsigned char buf_[320 * 240 * 3]; ///< working buffer for next frame
|
||||
|
||||
unsigned char outFrame_A_[320 * 240 * 4]; ///< output frame 1
|
||||
unsigned char outFrame_B_[320 * 240 * 4]; ///< output frame 2
|
||||
|
||||
uint current_;
|
||||
uint frame_;
|
||||
uint fps_;
|
||||
|
||||
|
||||
public:
|
||||
static const uint W = 320;
|
||||
static const uint H = 240;
|
||||
|
||||
DummyImageGenerator(uint fps);
|
||||
|
||||
~DummyImageGenerator() { }
|
||||
|
||||
/** generate the next frame and
|
||||
* occupy the alternate buffer.
|
||||
* @return the buffer containing the new frame
|
||||
*/
|
||||
LumieraDisplayFrame next();
|
||||
/** generate the next frame and occupy the alternate buffer.
|
||||
* @return the buffer containing the new frame */
|
||||
DummyFrame next();
|
||||
|
||||
/** just re-return a pointer to the current frame
|
||||
* without generating any new image data */
|
||||
LumieraDisplayFrame current();
|
||||
|
||||
DummyFrame current();
|
||||
|
||||
|
||||
private:
|
||||
static constexpr uint WORK_SIZ = W * H * 3;
|
||||
static constexpr uint BUFF_SIZ = W * H * 4;
|
||||
|
||||
bool beat_;
|
||||
uint frame_;
|
||||
|
||||
std::array<std::byte,WORK_SIZ> workBuf_; ///< workspace for RGB calculation
|
||||
std::array<std::byte,BUFF_SIZ> outFrame_A_; ///< alternating output buffers
|
||||
std::array<std::byte,BUFF_SIZ> outFrame_B_;
|
||||
|
||||
void generateFrame (DummyFrame buffer);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace test {
|
|||
namespace {
|
||||
const uint NUM_THREADS = 8; ///< for concurrent probes
|
||||
const uint NUM_SAMPLES = 80; ///< overall number measurement runs
|
||||
const uint NUM_INVOKES = 1'000'000; ///< invocations of the target per measurment
|
||||
const uint NUM_INVOKES = 1'000'000; ///< invocations of the target per measurement
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -130060,6 +130060,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node CREATED="1746753406837" ID="ID_458597358" MODIFIED="1746753420111" TEXT="aber das Video updatet nur, wenn die Maus bewegt wird"/>
|
||||
<node CREATED="1746753723320" ID="ID_1317517051" MODIFIED="1746753739591" TEXT="und zwar egal wo, es muß nur im Bereich des Lumiera-Fenster sein"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1746757140958" ID="ID_1593531865" MODIFIED="1746757194999" TEXT="hier fehlt uns Wissen über die Schnittstelle">
|
||||
<arrowlink COLOR="#b70f3e" DESTINATION="ID_1411409809" ENDARROW="Default" ENDINCLINATION="58;-133;" ID="Arrow_ID_1129084559" STARTARROW="None" STARTINCLINATION="-188;12;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#330f69" CREATED="1746718116512" ID="ID_415171245" MODIFIED="1746756819258" TEXT="und die Höhe der Dekoration ist auch nicht korrekt eingerechnet">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
|
|
@ -130109,6 +130113,174 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1746756977623" ID="ID_1960782604" MODIFIED="1746757001777" TEXT="und da das Dock beweglich ist, verwendet es wohl ein eigenes XWindow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746757051600" ID="ID_1411409809" MODIFIED="1746757194999" TEXT="Einschätzung">
|
||||
<linktarget COLOR="#b70f3e" DESTINATION="ID_1411409809" ENDARROW="Default" ENDINCLINATION="58;-133;" ID="Arrow_ID_1129084559" SOURCE="ID_1593531865" STARTARROW="None" STARTINCLINATION="-188;12;"/>
|
||||
<node CREATED="1746757057796" ID="ID_1825980418" MODIFIED="1746757071675" TEXT="an diesem Code ist viele unflexibel und hart codiert"/>
|
||||
<node CREATED="1746757072453" ID="ID_1065119380" MODIFIED="1746757089585" TEXT="für einen zuverlässigeren XV-Displayer müssen wir die Formate verstehen"/>
|
||||
<node CREATED="1746757090333" ID="ID_11791207" MODIFIED="1746757103652" TEXT="sowie das Thema Clipping/Keying/Compositing"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746893065718" ID="ID_1080057772" MODIFIED="1746893077566" TEXT="Mehr Flexibilität für das Pixelformat">
|
||||
<node CREATED="1746893079288" ID="ID_1996986668" MODIFIED="1746893093648" TEXT="schon die bestehenden Ansätze sind nicht kompatibel">
|
||||
<node CREATED="1746893095388" ID="ID_542989222" MODIFIED="1746893119924" TEXT="der XV-Code verwendet »Yuv«"/>
|
||||
<node CREATED="1746893120700" ID="ID_150794172" MODIFIED="1746893135491" TEXT="der pixbuf-Ansatz braucht RGB-Pixel"/>
|
||||
</node>
|
||||
<node CREATED="1746893143163" ID="ID_728521523" MODIFIED="1746893170062" TEXT="brauche Mechanismus zur Format-Bestimmung"/>
|
||||
<node CREATED="1746893172426" ID="ID_252885347" MODIFIED="1746893188715" TEXT="Image-Generator soll mehrere Formate unterstützen">
|
||||
<node CREATED="1746896060805" ID="ID_307284442" MODIFIED="1746896067887" TEXT="welche sind konkret bekannt?">
|
||||
<node CREATED="1746896069943" ID="ID_1946006105" MODIFIED="1746896077179" TEXT="Gdk::Pixbuf">
|
||||
<node CREATED="1746896096808" ID="ID_1859341105" LINK="https://gnome.pages.gitlab.gnome.org/gtkmm/classGdk_1_1Pixbuf.html#a5611379f1b3fd308cef781c2ed7ec9a7" MODIFIED="1746896111367" TEXT="API-Doc">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Tip: suche nach "image data"
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1746896115704" ID="ID_830630093" MODIFIED="1746896127222" TEXT="Beschreibung nicht ganz klar wegen Alpha"/>
|
||||
<node CREATED="1746896128024" ID="ID_1425663830" MODIFIED="1746896136962" TEXT="deute es so: es gibt zwei Varianten">
|
||||
<node CREATED="1746896138022" ID="ID_684097851" MODIFIED="1746896144257" TEXT="RGB : drei Bytes in Folge"/>
|
||||
<node CREATED="1746896144965" ID="ID_1166994604" MODIFIED="1746896151056" TEXT="RGBA : vier Bytes in Folge"/>
|
||||
<node CREATED="1746896606942" ID="ID_1779749459" MODIFIED="1746896636159" TEXT="könnte aber auch sein, daß der Platzt für α stets reserviert wird"/>
|
||||
</node>
|
||||
<node CREATED="1746896153645" ID="ID_1979121211" MODIFIED="1746896183972" TEXT="auf jeden Fall: interleved (R,G,B[,A]) and packed"/>
|
||||
</node>
|
||||
<node CREATED="1746896199230" ID="ID_741408214" MODIFIED="1746896206601" TEXT="XV: YUY2">
|
||||
<node CREATED="1746896326183" ID="ID_645436469" LINK="https://learn.microsoft.com/en-us/windows/win32/medfound/recommended-8-bit-yuv-formats-for-video-rendering" MODIFIED="1746896334677" TEXT="Artikel von Microsoft-Learn"/>
|
||||
<node CREATED="1746896350729" ID="ID_53313141" LINK="https://gstreamer.freedesktop.org/documentation/additional/design/mediatype-video-raw.html?gi-language=c" MODIFIED="1746896643175" TEXT="GStreamer: Raw video types">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1746896661544" ID="ID_158116185" MODIFIED="1746896663172" TEXT=""YUY2" packed 4:2:2 YUV"/>
|
||||
<node CREATED="1746896699379" ID="ID_1417105458" MODIFIED="1746896701443" TEXT="|Y0|U0|Y1|V0| |Y2|U2|Y3|V2|"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1746896775753" ID="ID_522887084" MODIFIED="1746896789587" TEXT="Vorsicht: auf dem Teppich bleiben">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1746896791415" ID="ID_299651976" MODIFIED="1746896805893" TEXT="es geht nur darum, erst mal diesen Image-Generator etwas flexibler zu machen">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1746896815060" ID="ID_1022113333" MODIFIED="1746896821031" TEXT="Generierung wird immer RGB sein"/>
|
||||
<node CREATED="1746896822170" ID="ID_795424268" MODIFIED="1746896842745" TEXT="brauche aber erweitertes Buffer-Management">
|
||||
<node CREATED="1746896843553" ID="ID_1850852470" MODIFIED="1746896858665" TEXT="abhängig vom Format wird ein 2.Arbeitsbuffer gebraucht"/>
|
||||
<node CREATED="1746896912285" ID="ID_246850547" MODIFIED="1746896922737" TEXT="brauche also pro Format ein Zuordnungs-Schema">
|
||||
<node CREATED="1746896924001" ID="ID_1285226369" MODIFIED="1746896934815" TEXT="RGB kann man direkt im Ausgabepuffer rechnen"/>
|
||||
<node CREATED="1746896935427" ID="ID_1399171111" MODIFIED="1746896942694" TEXT="für andere Formate muß Temp-Buffer nehmen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746896867877" ID="ID_718765609" MODIFIED="1746896882238" TEXT="bleibt aber im Prinzip ein fest-verdrahtetes Double-Buffering"/>
|
||||
<node CREATED="1746896889270" ID="ID_880503060" MODIFIED="1746896907698" TEXT="Idee: ggfs eine Über-Allokation für den Buffer, so daß jedes Format paßt">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746921512647" ID="ID_1654688911" MODIFIED="1746921530413" TEXT="erster Schritt: Code reorganisieren und klarer machen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1746921531585" ID="ID_156630022" MODIFIED="1746921551379" TEXT="den double-buffering-Mechanismus von der Bildgenerierung trennen"/>
|
||||
<node CREATED="1746921552092" ID="ID_492214837" MODIFIED="1746921563913" TEXT="die Farbraumkonvertierung als extra Schritt formulieren">
|
||||
<node CREATED="1746921707185" ID="ID_1757569540" MODIFIED="1746921715007" TEXT="dabei auch die Theorie nochmal verifizieren">
|
||||
<node CREATED="1746921716337" ID="ID_683787640" MODIFIED="1746921728880" TEXT=""yuv" ist selber ein ungenauer Begriff"/>
|
||||
<node CREATED="1746921729694" ID="ID_1983082888" MODIFIED="1746921740370" TEXT="gemeint ist meist YCrCb"/>
|
||||
<node CREATED="1746929700320" ID="ID_878404124" MODIFIED="1746929714669" TEXT="die Koeffizienten sind eindeutig von Rec.601 / MPEG"/>
|
||||
<node CREATED="1746929715402" ID="ID_1228492062" MODIFIED="1746929744583" TEXT="sie sind nur vereinfacht, damit man es mit 16bit Integer-Arrithmetik machen kann"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746929753402" ID="ID_1545724068" MODIFIED="1746929764957" TEXT="da ich nun die Rechnung auf Int umstelle, könnte man genauer rechnen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746921564743" ID="ID_472874597" MODIFIED="1746921696992" TEXT="umstellen auf std::array und möglichst Pointer durch Referenzen ersetzen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
sieht zwar nach nitpicking aus, aber da wir dann explizit per structured-Binding auf die Komponenten zugreifen, könnte der Code etwas klarer werden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1746929669548" ID="ID_485365336" MODIFIED="1746936730029" TEXT="tja... compiliert aber das Ausgabeformat stimmt nicht">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1746936697077" ID="ID_3029485" MODIFIED="1746936719015" TEXT="Vermutung: der Fehler steckt in der rgb_to_yuv-Konvertierung">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1746936576704" ID="ID_1002369760" MODIFIED="1746936722511" TEXT="zwei Fehler gemacht">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1746936592414" ID="ID_1482938348" MODIFIED="1746936639995" TEXT="das Tripel muß ein byte-Array sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...sonst ist es nicht möglich, das als virtuellen Zugriff für Input und Output zu verwenden
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1746936646298" ID="ID_86296092" MODIFIED="1746936667952" TEXT="die 2-Pixel-Schritte hab ich bereits in die Schleifenvariable genommen"/>
|
||||
</node>
|
||||
<node CREATED="1746936671244" ID="ID_1148968519" MODIFIED="1746936695084" TEXT="⟹ muß also doch direkt nach dem Zugriff auf die Input-Daten nach int casten"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1746893845732" ID="ID_217120465" MODIFIED="1746893853763" TEXT="Einsichten / Schlußfolgerungen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1746893871037" ID="ID_75343016" MODIFIED="1746893876488" TEXT="problematische Aspekte">
|
||||
<node CREATED="1746893877430" ID="ID_497483495" MODIFIED="1746893885023" TEXT="das konkrete Pixelformat und Layout"/>
|
||||
<node CREATED="1746893895370" ID="ID_219712401" MODIFIED="1746893906279" TEXT="benötigte externe LIbraries für eine Technologie">
|
||||
<node CREATED="1746895905012" ID="ID_813655508" MODIFIED="1746895950411" TEXT="die stellen ein Problem dar für Publication und Deployment"/>
|
||||
<node CREATED="1746895956446" ID="ID_1040915814" MODIFIED="1746895965881" TEXT="man möchte sie von der Kern-Applikation getrennt halten"/>
|
||||
<node CREATED="1746895966757" ID="ID_1182691383" MODIFIED="1746895974360" TEXT="dann also wohl per Plug-in einbinden"/>
|
||||
<node CREATED="1746895975163" ID="ID_517417723" MODIFIED="1746895985954" TEXT="damit ist die Komplexität im Build-System"/>
|
||||
<node CREATED="1746895987890" ID="ID_367836628" MODIFIED="1746896041287" TEXT="muß aber auch an die Paketierung denken">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn sonst endet man doch wieder mit z.B. einem Debian-Paket, das <i>build-depends on the world of media processing</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746893907208" ID="ID_273417317" MODIFIED="1746893913676" TEXT="Initialisierung des Playback">
|
||||
<node CREATED="1746895605925" ID="ID_264051602" MODIFIED="1746895615928" TEXT="muß zu dem Zeitpunkt">
|
||||
<node CREATED="1746895616820" ID="ID_1418854250" MODIFIED="1746895630951" TEXT="die konkrete Ausgabe-Technologie auswählen"/>
|
||||
<node CREATED="1746895632529" ID="ID_1371830854" MODIFIED="1746895690966" TEXT="für diese eine Ressource-Allocation + Initialisierung machen"/>
|
||||
<node CREATED="1746895712671" ID="ID_1685215425" MODIFIED="1746895725801" TEXT="dann ein jeweils passendes Handle auf diese Allocation halten"/>
|
||||
</node>
|
||||
<node CREATED="1746895741504" ID="ID_770645161" MODIFIED="1746895744643" TEXT="Vorraussetzungen">
|
||||
<node CREATED="1746895745674" ID="ID_1620017985" MODIFIED="1746895757740" TEXT="es muß grundsätzlich Code geben, der diese Technologie beherrscht"/>
|
||||
<node CREATED="1746895758448" ID="ID_712745956" MODIFIED="1746895768232" TEXT="man muß dafür auch eine Render-Pipeline konstruieren können"/>
|
||||
<node CREATED="1746895772998" ID="ID_691651282" MODIFIED="1746895845873" TEXT="die Technologie muß aber auch konkret aktivierbar sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
sie könnte zwar im System installiert und vorhanden sein, aber nicht richtig konfiguriert, vielleicht überhaupt nie nutzbar sein, oder aber derzeit grade nicht nutzbar (weil eine externe Verbindung oder Ressource fehlt)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1746895729204" ID="ID_677582239" MODIFIED="1746895739484" TEXT="Caching und Abkürzungen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue