vdr-plugin-softhddevice-drm-gles 1.6.2
videorender.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
14#ifndef __VIDEORENDER_H
15#define __VIDEORENDER_H
16
17#include <atomic>
18#include <cstdint>
19#include <mutex>
20#include <vector>
21
22#include <xf86drmMode.h>
23
24extern "C" {
25#include <libavutil/frame.h>
26#include <libavutil/hwcontext_drm.h>
27}
28
29#ifdef USE_GLES
30#include <gbm.h>
31#include <EGL/egl.h>
32#endif
33
34#include <vdr/osd.h>
35#include <vdr/thread.h>
36
37#include "drmbuffer.h"
38#ifdef USE_GLES
39#include "drmdevice.h"
40#endif
41#include "drmhdr.h"
42#include "event.h"
43#include "grab.h"
44#include "misc.h"
45#include "queue.h"
46
47#ifndef USE_GLES
48class cDrmDevice;
49#endif
50class cSoftHdDevice;
51class cSoftHdConfig;
52class cSoftHdAudio;
53
59#define AV_SYNC_THRESHOLD_AUDIO_BEHIND_VIDEO_MS 35
60#define AV_SYNC_THRESHOLD_AUDIO_AHEAD_VIDEO_MS 5
61
66
71
76
81public:
82 virtual ~cBufferStrategy() = default;
84};
85
93
101
109
114public:
115 virtual ~cDecodingStrategy() = default;
117};
118
123public:
124 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
125};
126
131public:
132 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
133};
134
140class cVideoRender : public cThread {
141public:
143 ~cVideoRender(void);
144
145 void Init(void);
146 void Exit(void);
147 void Stop(void);
148 void Halt(void) { m_mutex.lock(); };
149 void Resume(void) { m_mutex.unlock(); };
150
151 void SetVideoOutputPosition(const cRect &);
152 void SetScreenSize(int, int, double);
153 int64_t GetVideoClock(void) { return m_pts; };
154 void GetStats(int *, int *, int *);
155 void ResetFrameCounter(void);
156 void Reset();
160
161 void ProcessEvents(void);
166
167 // OSD
168 void OsdClear(void);
169 void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int);
170
171 // TrickSpeed/ Stillpicture
172 void SetTrickSpeed(double, bool, bool);
173 bool IsTrickSpeed(void) { return m_trickspeed; };
175 void SetStillpicture(bool active) { m_stillpicture = active; };
176 bool IsStillpicture(void) { return m_stillpicture; };
177
178 // Grab
179 int TriggerGrab(void);
180 void ClearGrabBuffers(void);
184
185 // DRM
186 int DrmHandleEvent(void);
187 bool CanHandleHdr(void);
189
190 // Frame and buffer
191 bool DisplayFrame();
192 int GetFramesFilled(void) { return m_drmBufferQueue.Size(); };
193 void PushMainFrame(AVFrame *);
194 void PushPipFrame(AVFrame *);
196 void DisplayBlackFrame(void);
198 bool IsOutputBufferFull(void);
204
205#ifdef USE_GLES
206 // GLES
207 void DisableOglOsd(void) { m_disableOglOsd = true; };
208 void EnableOglOsd(void) { m_disableOglOsd = false; };
209 bool OglOsdDisabled(void) { return m_disableOglOsd; };
213 int GlInitiated(void) { return m_pDrmDevice->GlInitiated(); };
214#endif
215
216 // PIP
217 void SetPipActive(bool on) { m_pipActive = on; };
219 void SetPipSize(bool);
220
221protected:
222 virtual void Action(void);
223
224private:
228 std::mutex m_mutex;
229 std::vector<Event> m_eventQueue;
231
234 std::atomic<double> m_trickspeedFactor = 0;
235 std::atomic<bool> m_trickspeed = false;
236 std::atomic<bool> m_forwardTrickspeed = true;
237 std::atomic<bool> m_stillpicture = false;
238 std::atomic<int> m_framePresentationCounter = 0;
241
242 bool m_startgrab = false;
247
253 std::mutex m_timebaseMutex;
254 std::atomic<int64_t> m_pts = AV_NOPTS_VALUE;
255
257 bool m_videoIsScaled = false;
261
267 bool m_osdShown = false;
268 std::atomic<bool> m_videoPlaybackPaused = true;
269 std::atomic<bool> m_resumeAudioScheduled = false;
271 std::atomic<bool> m_displayOneFrameThenPause = false;
274
278 std::atomic<cBufferStrategy *> m_bufferReuseStrategy = nullptr;
279 std::atomic<cBufferStrategy *> m_pipBufferReuseStrategy = nullptr;
280 std::atomic<cDecodingStrategy *> m_decodingStrategy = nullptr;
281 std::atomic<cDecodingStrategy *> m_pipDecodingStrategy = nullptr;
282
284 bool m_hasDoneHdrModeset = false;
285 std::atomic<bool> m_enableHdr = false;
287 bool m_colorRangeStored = false;
288
289#ifdef USE_GLES
291 struct gbm_bo *m_bo;
292 struct gbm_bo *m_pOldBo;
294#endif
295
296 std::atomic<bool> m_pipActive = false;
297
298 int GetFrameFlags(AVFrame *);
299 void SetFrameFlags(AVFrame *, int);
300 void SetVideoClock(int64_t pts) { m_pts = pts; };
301 bool PageFlip(cDrmBuffer *, cDrmBuffer *);
306 void CreateGrabBuffers(bool);
307 void LogDroppedDuped(int64_t, int64_t, int);
309 void PushFrame(AVFrame *, bool, std::atomic<cBufferStrategy*> &, std::atomic<cDecodingStrategy*> &, cQueue<cDrmBuffer> *, cDrmBufferPool *);
311 void SetHdrBlob(struct hdr_output_metadata);
313 void RestoreColorSpace();
314};
315
318#endif
Event Receiver.
Definition event.h:85
DRM Buffer: Get a Hardware Buffer to Reuse.
Definition videorender.h:97
DRM Buffer: Get a Software Buffer to Reuse.
DRM Buffer: Get a Buffer to Use Once.
Definition videorender.h:89
DRM Buffer Getting-Strategy.
Definition videorender.h:80
virtual cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *)=0
virtual ~cBufferStrategy()=default
Prepare DRM Buffer for Hardware Decoding.
Prepare DRM Buffer for Software Decoding.
Strategy to Prepare DRM Buffer for Decoding.
virtual AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *)=0
virtual ~cDecodingStrategy()=default
DRM Buffer Pool.
Definition drmbuffer.h:138
DRM Buffer.
Definition drmbuffer.h:47
DRM Device.
Definition drmdevice.h:41
EGLDisplay EglDisplay(void)
Definition drmdevice.h:68
int GlInitiated(void)
Definition drmdevice.h:70
EGLSurface EglSurface(void)
Definition drmdevice.h:67
EGLContext EglContext(void)
Definition drmdevice.h:69
Grabbing Buffer.
Definition grab.h:49
HDR Metadata.
Definition drmhdr.h:105
size_t Size(void)
Get the current size of the queue.
Definition queue.h:124
Audio Interface.
Definition audio.h:46
Plugin Configuration.
Definition config.h:29
Output Device Implementation.
Video Renderer.
int m_numWrongProgressive
counter for progressive frames sent in an interlaced stream (only used for logging)
int m_framesDuped
number of frames duplicated
bool m_osdShown
set, if osd is shown currently
cCondVar m_grabCond
condition gets signalled, if renederer finished to clone the grabbed buffers
EGLSurface EglSurface(void)
cDrmBuffer * m_pCurrentlyDisplayed
pointer to currently displayed DRM buffer
int m_pipScalePercent
scale factor for pip
int GetFramesFilled(void)
struct gbm_bo * m_pOldBo
pointer to old gbm buffer object (for later free)
EGLDisplay EglDisplay(void)
std::atomic< bool > m_resumeAudioScheduled
set, if audio resume is scheduled after a pause
struct gbm_bo * m_bo
pointer to current gbm buffer object
void SetEnableHdr(bool enable)
std::atomic< bool > m_forwardTrickspeed
true, if trickspeed plays forward
void ResetBufferReuseStrategy()
std::atomic< bool > m_displayOneFrameThenPause
set, if only one frame shall be displayed and then pause playback
std::vector< Event > m_eventQueue
event queue for incoming events
void Halt(void)
cDrmBufferPool m_pipDrmBufferPool
PIP pool of drm buffers.
cGrabBuffer m_grabVideo
keeps the current grabbed video
int m_framesDropped
number of frames dropped
std::atomic< int > m_framePresentationCounter
number of times the current frame has to be shown (for slow-motion)
std::atomic< bool > m_enableHdr
hdr is enabled
cGrabBuffer * GetGrabbedPipBuffer(void)
double m_refreshRateHz
screen refresh rate in Hz
void ScheduleVideoPlaybackPauseAt(int64_t ptsMs)
std::atomic< bool > m_pipActive
true, if pip should be displayed
void ScheduleResyncAtPtsMs(int64_t ptsMs)
void ResetDecodingStrategy()
std::atomic< bool > m_videoPlaybackPaused
set, if playback is frozen (used for pause)
std::atomic< int64_t > m_scheduleResyncAtPtsMs
if set, a resync (enter state BUFFERING) will be forced at the given pts
bool IsForwardTrickspeed(void)
cQueue< cDrmBuffer > m_drmBufferQueue
queue for DRM buffers to be displayed (VIDEO_SURFACES_MAX is defined in thread.h)
cGrabBuffer m_grabPip
keeps the current grabbed pip video
cGrabBuffer * GetGrabbedVideoBuffer(void)
cRect m_videoRect
rect of the currently displayed video
void EnableOglOsd(void)
bool m_startgrab
internal flag to trigger grabbing
void ResetPipBufferReuseStrategy()
std::atomic< cDecodingStrategy * > m_pipDecodingStrategy
strategy for decoding setup
cGrabBuffer * GetGrabbedOsdBuffer(void)
std::atomic< cBufferStrategy * > m_bufferReuseStrategy
strategy to select drm buffers
bool IsStillpicture(void)
cSoftHdAudio * m_pAudio
pointer to cSoftHdAudio
AVRational m_timebase
timebase used for pts, set by first RenderFrame()
std::mutex m_mutex
mutex for thread control
std::atomic< int64_t > m_pts
current video PTS
int m_pipTopPercent
top margin for pip
cDrmBuffer * m_pBufOsd
pointer to osd drm buffer object
cHdrMetadata m_pHdrMetadata
hdr metadata object
std::mutex m_timebaseMutex
mutex used around m_timebase
EGLContext EglContext(void)
cSoftHdDevice * m_pDevice
pointer to cSoftHdDevice
void SetPipActive(bool on)
std::atomic< cBufferStrategy * > m_pipBufferReuseStrategy
strategy to select drm buffers
bool OglOsdDisabled(void)
std::atomic< bool > m_stillpicture
true, if stillpicture is active
cSoftHdConfig * m_pConfig
pointer to cSoftHdConfig
void SetVideoClock(int64_t pts)
IEventReceiver * m_pEventReceiver
pointer to event receiver
cQueue< cDrmBuffer > m_pipDrmBufferQueue
queue for PIP DRM buffers to be displayed (VIDEO_SURFACES_MAX is defined in thread....
cQueue< cDrmBuffer > * GetPipOutputBuffer(void)
void Resume(void)
void SetStillpicture(bool active)
bool m_disableOglOsd
set, if ogl osd is disabled
bool m_colorRangeStored
true, if the original color range was stored
void SchedulePlaybackStartAtPtsMs(int64_t ptsMs)
bool IsTrickSpeed(void)
bool m_hasDoneHdrModeset
true, if we ever created an hdr blob and did a modesetting
cDrmBuffer * m_pCurrentlyPipDisplayed
pointer to currently displayed DRM buffer
int64_t GetVideoClock(void)
void SetScheduleAudioResume(bool resume)
cDrmDevice * m_pDrmDevice
pointer cDrmDevice object
cGrabBuffer m_grabOsd
keeps the current grabbed osd
std::atomic< double > m_trickspeedFactor
current trick speed
std::atomic< int64_t > m_videoPlaybackPauseScheduledAt
if set, video will be paused at the given pts
std::atomic< cDecodingStrategy * > m_decodingStrategy
strategy for decoding setup
void SetDisplayOneFrameThenPause(bool pause)
std::atomic< bool > m_trickspeed
true, if trickspeed is active
bool m_lastFrameWasDropped
true, if the last frame was dropped
int m_pipLeftPercent
left margin for pip
void DisableOglOsd(void)
int GlInitiated(void)
void SetPlaybackPaused(bool pause)
cDrmBufferPool m_drmBufferPool
pool of drm buffers
drmColorRange m_originalColorRange
initial color range
std::atomic< int64_t > m_schedulePlaybackStartAtPtsMs
if set, frames with PTS older than this will be dropped
int m_startCounter
counter for displayed frames, indicates a video start
bool m_videoIsScaled
true, if the currently displayed video is scaled
struct gbm_bo * m_pNextBo
pointer to next gbm buffer object (for later free)
void ResetPipDecodingStrategy()
cQueue< cDrmBuffer > * GetMainOutputBuffer(void)
cDrmBuffer m_bufBlack
black drm buffer object
DRM Buffer Header File.
DRM Device Header File.
HDR (High Dynamic Range) Header File.
State Machine and Event Header File.
Grabbing Interface Header File.
#define AV_NOPTS_VALUE
Definition misc.h:74
#define VIDEO_SURFACES_MAX
maximum video surfaces kept by the filter and render queues
Definition misc.h:77
void PushPipFrame(AVFrame *)
Push a PiP frame into the render ringbuffer.
void SetFrameFlags(AVFrame *, int)
Set frame flags.
int DrmHandleEvent(void)
Wrapper for drmHandleEvent()
bool IsOutputBufferFull(void)
Check, if the main render output buffer is full.
void SetHdrBlob(struct hdr_output_metadata)
Create an hdr blob and set it for the connector.
void Reset()
Reset the renderer.
bool CanHandleHdr(void)
void CreateGrabBuffers(bool)
Copy current video, osd and pip buffers to dedicated grabbing buffers.
int SetVideoBuffer(cDrmBuffer *)
Modesetting for video.
void ProcessEvents(void)
Process queued events and forward to event receiver.
void OsdClear(void)
Clear the OSD (draw an empty/ transparent OSD)
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
int SetOsdBuffer(drmModeAtomicReqPtr)
Modesetting for osd.
void ClearDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
void Init(void)
Initialize the renderer.
void PushFrame(AVFrame *, bool, std::atomic< cBufferStrategy * > &, std::atomic< cDecodingStrategy * > &, cQueue< cDrmBuffer > *, cDrmBufferPool *)
Push the frame into the render ringbuffer.
void Exit(void)
Exit and cleanup the renderer.
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
void SetColorSpace(drmColorRange)
Set kms color space, color encoding and color range.
~cVideoRender(void)
Destroy the video renderer.
void GetStats(int *, int *, int *)
Get some rendering statistics.
void DisplayBlackFrame(void)
drmColorSpace
Definition videorender.h:62
drmColorRange
Definition videorender.h:72
void PushMainFrame(AVFrame *)
Push a main frame into the render ringbuffer.
void SetVideoOutputPosition(const cRect &)
Set size and position of the video on the screen.
int GetFrameFlags(AVFrame *)
Get frame flags.
int64_t GetOutputPtsMs(void)
Get the output PTS in milliseconds.
void ClearPipDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
int CommitBuffer(cDrmBuffer *, cDrmBuffer *)
Commit the frame to the hardware.
int TriggerGrab(void)
Trigger a screen grab.
int SetPipBuffer(cDrmBuffer *)
Modesetting for pip.
void ClearGrabBuffers(void)
Clear the grab drm buffers.
virtual void Action(void)
Thread loop, which tries to display frames and processes events.
void LogDroppedDuped(int64_t, int64_t, int)
Log A/V sync debug message.
bool DisplayFrame()
Display the frame (video and/or osd)
void Stop(void)
Stop the thread.
void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD ARGB image.
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
void SetScreenSize(int, int, double)
Wrapper to set the screen size in the device.
int64_t PtsToMs(int64_t)
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
void SetPipSize(bool)
Set the size and position of the pip window.
bool PageFlip(cDrmBuffer *, cDrmBuffer *)
Do the pageflip.
void RestoreColorSpace()
Restore color space, color encoding and color range to BT709 and the original color range.
drmColorEncoding
Definition videorender.h:67
void ResetFrameCounter(void)
Send start condition to video thread.
int GetFramePresentationCount(int64_t)
Get the number of times the current frame shall be presented in trickspeed mode.
void SetTrickSpeed(double, bool, bool)
Set the trickspeed parameters.
@ COLORSPACE_BT2020_RGB
Definition videorender.h:64
@ COLORSPACE_BT709_YCC
Definition videorender.h:63
@ COLORRANGE_FULL
Definition videorender.h:74
@ COLORRANGE_LIMITED
Definition videorender.h:73
@ COLORENCODING_BT2020
Definition videorender.h:69
@ COLORENCODING_BT709
Definition videorender.h:68
Misc Functions.
Thread-safe Queue.