Loading...
Searching...
No Matches
VideoNodeRenderer.hpp
1#pragma once
2#include <Gfx/Graph/NodeRenderer.hpp>
3#include <Gfx/Graph/VideoNode.hpp>
4#include <Gfx/Graph/decoders/GPUVideoDecoder.hpp>
5#include <Video/VideoInterface.hpp>
6
7namespace score::gfx
8{
9class GPUVideoDecoder;
10
24 bool hasDecoder, const Video::ImageFormat& built, const Video::ImageFormat& src,
25 AVPixelFormat fmt, int w, int h) noexcept
26{
27 if(!hasDecoder)
28 return true;
29
30 // A fielded source hands over half-height frames while describing the whole
31 // picture, so the two heights are compared in the same units -- get this
32 // wrong and every frame looks like a size change.
33 const int pictureH = (src.interlacing == Video::Interlacing::Fields) ? h * 2 : h;
34
35 return fmt != built.pixel_format || w != built.width || pictureH != built.height
36 || src.output_format != built.output_format || src.tonemap != built.tonemap
37 // The colour description comes from the decoder, not the frame, and a
38 // live input may revise it while running -- a sender that starts
39 // declaring HDR. The matrix is baked into the shader, so that
40 // rebuilds.
41 || src.color_space != built.color_space || src.color_range != built.color_range
42 || src.color_trc != built.color_trc
43 || src.color_primaries != built.color_primaries
44 // Interlacing changes the texture geometry; the deinterlace MODE does
45 // not -- it is a uniform, so switching weave to bob must not rebuild.
46 || src.interlacing != built.interlacing;
47}
48
59{
60public:
61 QRhiTexture* texture() const noexcept { return m_rt.texture; }
62
65 void update(
66 RenderList& renderer, QRhiResourceUpdateBatch& res, const Port& output,
67 const Video::ImageFormat& format, const VideoMaterialUBO& material,
68 const QShader& vertex, const QShader& fragment, QRhiBuffer* processUBO,
69 std::span<const Sampler> samplers);
70
72 void render(
73 RenderList& renderer, QRhiCommandBuffer& cb, QRhiResourceUpdateBatch*& res,
74 const MeshBuffers& mesh);
75
77 void releasePipeline();
78 void release();
79
80private:
82 Pipeline m_pipeline;
83 QRhiBuffer* m_material{};
84 int64_t m_renderedFrame{-1};
85};
86
88{
89public:
90 explicit VideoNodeRenderer(
91 const VideoNodeBase& node, VideoFrameShare& frames) noexcept;
93
94 VideoNodeRenderer() = delete;
95 VideoNodeRenderer(const VideoNodeRenderer&) = delete;
97 VideoNodeRenderer& operator=(const VideoNodeRenderer&) = delete;
98 VideoNodeRenderer& operator=(VideoNodeRenderer&&) = delete;
99
100 TextureRenderTarget renderTargetForInput(const Port& input) override;
101
102 void createGpuDecoder();
103 void setupGpuDecoder(RenderList& r);
104 void checkFormat(RenderList& r, AVPixelFormat fmt, int w, int h);
105
106 void init(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
107 void runRenderPass(RenderList&, QRhiCommandBuffer& commands, Edge& edge) override;
108
109 void update(RenderList& renderer, QRhiResourceUpdateBatch& res, Edge* edge) override;
110 void runInitialPasses(
111 RenderList&, QRhiCommandBuffer& commands, QRhiResourceUpdateBatch*& res,
112 Edge& edge) override;
113 QRhiTexture* textureForOutput(const Port& output) override;
114 void release(RenderList& r) override;
115
116 void initState(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
117 void releaseState(RenderList& renderer) override;
118 void addOutputPass(
119 RenderList& renderer, Edge& edge, QRhiResourceUpdateBatch& res) override;
120 void removeOutputPass(RenderList& renderer, Edge& edge) override;
121 bool hasOutputPassForEdge(Edge& edge) const override;
122
123private:
124 void createPipelines(RenderList& r);
125 void displayFrame(AVFrame& frame, RenderList& renderer, QRhiResourceUpdateBatch& res);
126 Video::VideoMetadata& decoder() const noexcept;
127
128 const VideoNodeBase& node() const noexcept
129 {
130 return static_cast<const VideoNodeBase&>(NodeRenderer::node);
131 }
132 VideoFrameShare& reader;
133
134 PassMap m_p;
135 MeshBuffers m_meshBuffer{};
136 QRhiBuffer* m_processUBO{};
137 QRhiBuffer* m_materialUBO{};
138
140
141 std::unique_ptr<GPUVideoDecoder> m_gpu;
142 std::pair<QShader, QShader> m_shaders;
143
144 Video::ImageFormat m_frameFormat{};
145
148 float m_fieldParity{};
149
152 bool m_fieldPartnerValid{};
153 bool m_sawField{};
154 score::gfx::ScaleMode m_currentScaleMode{};
155 QSize m_scaleRenderSize{};
156
157 std::shared_ptr<RefcountedFrame> m_currentFrame{};
158 int64_t m_currentFrameIdx{-1};
159 bool m_recomputeScale{};
160 VideoOwnTexture m_ownTexture;
161};
162
163}
Renderer for a given node.
Definition NodeRenderer.hpp:11
List of nodes to be rendered to an output.
Definition RenderList.hpp:33
Definition VideoNode.hpp:82
Definition VideoNodeRenderer.hpp:88
QRhiTexture * textureForOutput(const Port &output) override
Definition VideoNodeRenderer.cpp:393
bool hasOutputPassForEdge(Edge &edge) const override
Check if this renderer already has an output pass for the given edge.
Definition VideoNodeRenderer.cpp:264
void removeOutputPass(RenderList &renderer, Edge &edge) override
Definition VideoNodeRenderer.cpp:253
void releaseState(RenderList &renderer) override
Definition VideoNodeRenderer.cpp:270
void addOutputPass(RenderList &renderer, Edge &edge, QRhiResourceUpdateBatch &res) override
Create a pass for a new output edge (pipeline, SRB, processUBO).
Definition VideoNodeRenderer.cpp:234
void initState(RenderList &renderer, QRhiResourceUpdateBatch &res) override
Definition VideoNodeRenderer.cpp:203
The decoded frame, converted to RGBA into a texture of the renderer's own.
Definition VideoNodeRenderer.hpp:59
void update(RenderList &renderer, QRhiResourceUpdateBatch &res, const Port &output, const Video::ImageFormat &format, const VideoMaterialUBO &material, const QShader &vertex, const QShader &fragment, QRhiBuffer *processUBO, std::span< const Sampler > samplers)
Definition VideoNodeRenderer.cpp:24
void render(RenderList &renderer, QRhiCommandBuffer &cb, QRhiResourceUpdateBatch *&res, const MeshBuffers &mesh)
Draws the frame into the texture, once per frame.
Definition VideoNodeRenderer.cpp:66
void releasePipeline()
The decoder's samplers were rebuilt.
Definition VideoNodeRenderer.cpp:84
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
bool videoDecoderNeedsRebuild(bool hasDecoder, const Video::ImageFormat &built, const Video::ImageFormat &src, AVPixelFormat fmt, int w, int h) noexcept
Whether the GPU decoder has to be rebuilt for this frame.
Definition VideoNodeRenderer.hpp:23
ScaleMode
How to resize a texture to adapt it to a viewport.
Definition Scale.hpp:10
Definition VideoInterface.hpp:29
Definition VideoInterface.hpp:73
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:220
Definition Mesh.hpp:95
Useful abstraction for storing a graphics pipeline and associated resource bindings.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:262
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:199
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:291
Definition VideoNode.hpp:31
UBO shared across all video objects.
Definition CommonUBOs.hpp:108