Loading...
Searching...
No Matches

Decodes P210 and P216 semi-planar 4:2:2 videos. More...

Inheritance diagram for score::gfx::P210Decoder:
score::gfx::GPUVideoDecoder

Detailed Description

Decodes P210 and P216 semi-planar 4:2:2 videos.

One layout, two bit depths:

  • Plane 0: Y (16-bit words), full resolution
  • Plane 1: UV interleaved (16-bit per component), half width, full height

P210 puts 10 bits in the HIGH bits of each word, so R16 unorm returns a value that is short of 1.0 at full scale and has to be renormalized – that is what the scale is for. P216 uses all 16 bits and wants no scaling at all, which is the only difference between the two and why they share this decoder.

P216 is what NDI delivers for a 16-bit source, and NDI delivers it as individual FIELDS: half-height frames at twice the rate. Those are uploaded into the two halves of one full-height texture (see planeRows) and resolved by score_tc, so nothing here weaves anything on the CPU.

Public Member Functions

 P210Decoder (Video::ImageFormat &d, const char *sampleScale=SCORE_GFX_MSB_ALIGNED_SCALE)
 
std::pair< QShader, QShader > init (RenderList &r) override
 Initialize a GPUVideoDecoder.
 
void exec (RenderList &, QRhiResourceUpdateBatch &res, AVFrame &frame) override
 Decode and upload a video frame to the GPU.
 
- Public Member Functions inherited from score::gfx::GPUVideoDecoder
virtual void release (RenderList &)
 This method will release all the created samplers and textures.
 

Public Attributes

Video::ImageFormat & decoder
 
const char * scale {SCORE_GFX_MSB_ALIGNED_SCALE}
 
- Public Attributes inherited from score::gfx::GPUVideoDecoder
std::vector< Sampler > samplers
 
bool hasFrame {}
 
bool failed {}
 
bool formatChanged {}
 

Static Public Attributes

static const constexpr auto frag
 

Additional Inherited Members

- Static Public Member Functions inherited from score::gfx::GPUVideoDecoder
static QRhiTextureSubresourceUploadDescription createTextureUpload (uint8_t *pixels, int w, int h, int bytesPerPixel, int stride)
 Utility method to create a QRhiTextureSubresourceUploadDescription.
 
static bool isTopField (const AVFrame &frame) noexcept
 Whether this frame carries the EVEN lines of its picture.
 
static PlaneRows planeRows (const Video::ImageFormat &fmt, const AVFrame &frame, int textureRows) noexcept
 
static QString vertexShader (bool invertY=false) noexcept
 

Member Function Documentation

◆ exec()

void score::gfx::P210Decoder::exec ( RenderList &  ,
QRhiResourceUpdateBatch &  res,
AVFrame &  frame 
)
inlineoverridevirtual

Decode and upload a video frame to the GPU.

Implements score::gfx::GPUVideoDecoder.

◆ init()

std::pair< QShader, QShader > score::gfx::P210Decoder::init ( RenderList &  r)
inlineoverridevirtual

Initialize a GPUVideoDecoder.

This method must :

  • Create samplers and textures for the video format.
  • Create shaders that will render the data put into these textures.

It returns a {vertex, fragment} shader pair.

Implements score::gfx::GPUVideoDecoder.

Member Data Documentation

◆ frag

const constexpr auto score::gfx::P210Decoder::frag
staticconstexpr
Initial value:
= R"_(#version 450
)_" SCORE_GFX_VIDEO_UNIFORMS R"_(
layout(binding=3) uniform sampler2D y_tex;
layout(binding=4) uniform sampler2D uv_tex;
layout(location = 0) in vec2 v_texcoord;
layout(location = 0) out vec4 fragColor;
%2
vec4 processTexture(vec4 tex) {
vec4 processed = convert_to_rgb(tex);
{ %1 }
return processed;
}
void main()
{
const float s = %3;
float y = s * texture(y_tex, score_tc(v_texcoord)).r;
float u = s * texture(uv_tex, score_tc(v_texcoord)).r;
float v = s * texture(uv_tex, score_tc(v_texcoord)).g;
fragColor = processTexture(vec4(y, u, v, 1.));
})_"

◆ scale

const char* score::gfx::P210Decoder::scale {SCORE_GFX_MSB_ALIGNED_SCALE}

"1.0" for P216, which uses every bit; the MSB-aligned renormalization for P210, whose ten bits sit at the top of a 16-bit word.


The documentation for this struct was generated from the following file: