Loading...
Searching...
No Matches
DirectVideoNodeRenderer.hpp
1#pragma once
2#include <Gfx/Graph/NodeRenderer.hpp>
3#include <Gfx/Graph/VideoNode.hpp>
4#include <Video/VideoInterface.hpp>
5
6#include <vector>
7
8class QRhi;
9
10extern "C" {
11struct AVFormatContext;
12struct AVCodecContext;
13struct AVStream;
14struct AVFrame;
15struct AVPacket;
16struct AVBufferRef;
17struct SwsContext;
18#include <libavutil/pixfmt.h>
19}
20
21namespace Video
22{
23class Rescale;
24}
25
26namespace score::gfx
27{
28class GPUVideoDecoder;
29struct PixelFormatInfo;
30
47{
48public:
50 const VideoNodeBase& node, const Video::VideoMetadata& metadata) noexcept;
52
53 DirectVideoNodeRenderer() = delete;
56 DirectVideoNodeRenderer& operator=(const DirectVideoNodeRenderer&) = delete;
58
59 TextureRenderTarget renderTargetForInput(const Port& input) override;
60
61 void init(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
62 void runRenderPass(RenderList&, QRhiCommandBuffer& commands, Edge& edge) override;
63 void update(RenderList& renderer, QRhiResourceUpdateBatch& res, Edge* edge) override;
64 void release(RenderList& r) override;
65
66 void initState(RenderList& renderer, QRhiResourceUpdateBatch& res) override;
67 void releaseState(RenderList& renderer) override;
68 void addOutputPass(
69 RenderList& renderer, Edge& edge, QRhiResourceUpdateBatch& res) override;
70 void removeOutputPass(RenderList& renderer, Edge& edge) override;
71 bool hasOutputPassForEdge(Edge& edge) const override;
72
73private:
74 const VideoNodeBase& node() const noexcept
75 {
76 return static_cast<const VideoNodeBase&>(NodeRenderer::node);
77 }
78
79 bool openFile(score::gfx::GraphicsApi api, QRhi* rhi = nullptr);
80 void closeFile();
81 bool seekAndDecode(int64_t flicks);
82 bool isSequentialRead(int64_t flicks) const;
83 bool readNextPacketRaw();
84 bool readNextPacketAVCodec();
85
86 void createGpuDecoder(QRhi& rhi);
87 score::gfx::PixelFormatInfo hwPixelFormatInfo() const;
88 std::unique_ptr<GPUVideoDecoder> tryCreateZeroCopyDecoder(QRhi& rhi);
89 void setupGpuDecoder(RenderList& r);
90 void createPipelines(RenderList& r);
91
92 // Hardware decoding
93 AVPixelFormat selectHardwareAcceleration(
94 score::gfx::GraphicsApi api, int codec_id) const;
95 bool setupHardwareDecoder(
96 const void* codec, AVPixelFormat hwPixFmt);
97 static enum AVPixelFormat negotiateHWFormat(
98 AVCodecContext* ctx, const enum AVPixelFormat* pix_fmts);
99 void transferHWFrame();
100
101 // Video file info
102 std::string m_filePath;
103 Video::ImageFormat m_frameFormat{};
104 double m_fps{};
105 double m_flicks_per_dts{};
106 double m_dts_per_flicks{};
107 bool m_useAVCodec{true};
108
109 // Own LibAV context
110 AVFormatContext* m_formatContext{};
111 AVCodecContext* m_codecContext{};
112 const void* m_codec{}; // AVCodec*
113 AVStream* m_avstream{};
114 AVFrame* m_decodedFrame{};
115
116 // Hardware decode state
117 AVBufferRef* m_hwDeviceCtx{};
118 AVPixelFormat m_hwPixelFormat{AV_PIX_FMT_NONE};
119 AVPixelFormat m_hwSwFormat{AV_PIX_FMT_NONE};
120 std::vector<const char*> m_vkEnabledExtensions; // kept alive for FFmpeg
121 AVFrame* m_swTransferFrame{};
122 score::gfx::GraphicsApi m_rhiApi{};
123 QRhi* m_rhi{};
124 bool m_hwSwFormatChecked{false};
125 bool m_zeroCopyFailed{false};
126 bool m_sharedVulkanDevice{false}; // true if FFmpeg uses QRhi's VkDevice
127
128 // Render state
129 PassMap m_p;
130 MeshBuffers m_meshBuffer{};
131 QRhiBuffer* m_processUBO{};
132 QRhiBuffer* m_materialUBO{};
133
134 struct Material
135 {
136 float scale_w{}, scale_h{};
137 float tex_w{}, tex_h{};
138 };
139
140 std::unique_ptr<GPUVideoDecoder> m_gpu;
141 QShader m_cachedVertexShader;
142 QShader m_cachedFragmentShader;
143 score::gfx::ScaleMode m_currentScaleMode{};
144
145 int64_t m_lastRequestedFlicks{-1};
146 int64_t m_lastDecodedDts{INT64_MIN};
147 bool m_recomputeScale{true};
148};
149
150}
Renderer for intra-only video codecs with instant seeking.
Definition DirectVideoNodeRenderer.hpp:47
bool hasOutputPassForEdge(Edge &edge) const override
Check if this renderer already has an output pass for the given edge.
Definition DirectVideoNodeRenderer.cpp:1492
void initState(RenderList &renderer, QRhiResourceUpdateBatch &res) override
Definition DirectVideoNodeRenderer.cpp:1263
void removeOutputPass(RenderList &renderer, Edge &edge) override
Definition DirectVideoNodeRenderer.cpp:1480
void addOutputPass(RenderList &renderer, Edge &edge, QRhiResourceUpdateBatch &res) override
Create a pass for a new output edge (pipeline, SRB, processUBO).
Definition DirectVideoNodeRenderer.cpp:1461
void releaseState(RenderList &renderer) override
Definition DirectVideoNodeRenderer.cpp:1498
Renderer for a given node.
Definition NodeRenderer.hpp:11
List of nodes to be rendered to an output.
Definition RenderList.hpp:30
Definition VideoNode.hpp:73
Graphics rendering pipeline for ossia score.
Definition Filter/PreviewWidget.hpp:11
GraphicsApi
Available graphics APIs to use.
Definition RenderState.hpp:22
ScaleMode
How to resize a texture to adapt it to a viewport.
Definition Scale.hpp:10
Definition VideoInterface.hpp:26
Definition VideoInterface.hpp:54
Connection between two score::gfx::Port.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:103
Definition Mesh.hpp:94
Definition GPUVideoDecoder.hpp:29
Port of a score::gfx::Node.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:82
Useful abstraction for storing all the data related to a render target.
Definition score-plugin-gfx/Gfx/Graph/Utils.hpp:152