vdr-plugin-softhddevice-drm-gles 1.6.4-d0291bb
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
64#define AV_SYNC_THRESHOLD_AUDIO_BEHIND_VIDEO_MS 35
65#define AV_SYNC_THRESHOLD_AUDIO_AHEAD_VIDEO_MS 5
66
71
76
81
90public:
91 virtual ~cBufferStrategy() = default;
93};
94
104
114
124
131public:
132 virtual ~cDecodingStrategy() = default;
134};
135
142public:
143 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
144};
145
152public:
153 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
154};
155
163class cVideoRender : public cThread {
164public:
166 ~cVideoRender(void);
167
168 void Init(void);
169 void Exit(void);
170 void Stop(void);
171 void Halt(void) { m_mutex.lock(); };
172 void Resume(void) { m_mutex.unlock(); };
173
174 void SetVideoOutputPosition(const cRect &);
175 void SetScreenSize(int, int, double);
176 int64_t GetVideoClock(void) { return m_pts; };
177 void GetStats(int *, int *, int *);
178 void ResetFrameCounter(void);
179 void Reset();
183
184 void ProcessEvents(void);
189
190 // OSD
191 void OsdClear(void);
192 void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int);
193
194 // TrickSpeed/ Stillpicture
195 void SetTrickSpeed(double, bool, bool);
196 bool IsTrickSpeed(void) { return m_trickspeed; };
198 void SetStillpicture(bool active) { m_stillpicture = active; };
199 bool IsStillpicture(void) { return m_stillpicture; };
200
201 // Grab
202 int TriggerGrab(void);
203 void ClearGrabBuffers(void);
207
208 // DRM
209 int DrmHandleEvent(void);
210 bool CanHandleHdr(void);
212
213 // Frame and buffer
214 bool DisplayFrame();
215 int GetFramesFilled(void) { return m_drmBufferQueue.Size(); };
216 void PushMainFrame(AVFrame *);
217 void PushPipFrame(AVFrame *);
219 void DisplayBlackFrame(void);
221 bool IsOutputBufferFull(void);
227
228#ifdef USE_GLES
229 // GLES
230 void DisableOglOsd(void) { m_disableOglOsd = true; };
231 void EnableOglOsd(void) { m_disableOglOsd = false; };
232 bool OglOsdDisabled(void) { return m_disableOglOsd; };
236 int GlInitiated(void) { return m_pDrmDevice->GlInitiated(); };
237#endif
238
239 // PIP
240 void SetPipActive(bool on) { m_pipActive = on; };
242 void SetPipSize(bool);
243
244protected:
245 virtual void Action(void);
246
247private:
251 std::mutex m_mutex;
252 std::vector<Event> m_eventQueue;
254
257 std::atomic<double> m_trickspeedFactor = 0;
258 std::atomic<bool> m_trickspeed = false;
259 std::atomic<bool> m_forwardTrickspeed = true;
260 std::atomic<bool> m_stillpicture = false;
261 std::atomic<int> m_framePresentationCounter = 0;
264
265 bool m_startgrab = false;
270
276 std::mutex m_timebaseMutex;
277 std::atomic<int64_t> m_pts = AV_NOPTS_VALUE;
278
280 bool m_videoIsScaled = false;
284
290 bool m_osdShown = false;
291 std::atomic<bool> m_videoPlaybackPaused = true;
292 std::atomic<bool> m_resumeAudioScheduled = false;
294 std::atomic<bool> m_displayOneFrameThenPause = false;
297
301 std::atomic<cBufferStrategy *> m_bufferReuseStrategy = nullptr;
302 std::atomic<cBufferStrategy *> m_pipBufferReuseStrategy = nullptr;
303 std::atomic<cDecodingStrategy *> m_decodingStrategy = nullptr;
304 std::atomic<cDecodingStrategy *> m_pipDecodingStrategy = nullptr;
305
307 bool m_hasDoneHdrModeset = false;
308 std::atomic<bool> m_enableHdr = false;
310 bool m_colorRangeStored = false;
311
312#ifdef USE_GLES
314 struct gbm_bo *m_bo;
315 struct gbm_bo *m_pOldBo;
317#endif
318
319 std::atomic<bool> m_pipActive = false;
320
321 int GetFrameFlags(AVFrame *);
322 void SetFrameFlags(AVFrame *, int);
323 void SetVideoClock(int64_t pts) { m_pts = pts; };
324 bool PageFlip(cDrmBuffer *, cDrmBuffer *);
329 void CreateGrabBuffers(bool);
330 void LogDroppedDuped(int64_t, int64_t, int);
332 void PushFrame(AVFrame *, bool, std::atomic<cBufferStrategy*> &, std::atomic<cDecodingStrategy*> &, cQueue<cDrmBuffer> *, cDrmBufferPool *);
334 void SetHdrBlob(struct hdr_output_metadata);
336 void RestoreColorSpace();
337};
338
339#endif
Event Receiver.
Definition event.h:91
DRM Buffer: Get a Hardware Buffer to Reuse.
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
DRM Buffer: Get a Software Buffer to Reuse.
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
DRM Buffer: Get a Buffer to Use Once.
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
DRM Buffer Getting-Strategy.
Definition videorender.h:89
virtual cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *)=0
virtual ~cBufferStrategy()=default
Prepare DRM Buffer for Hardware Decoding.
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
Prepare DRM Buffer for Software Decoding.
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
Strategy to Prepare DRM Buffer for Decoding.
virtual AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *)=0
virtual ~cDecodingStrategy()=default
DRM Buffer Pool.
Definition drmbuffer.h:139
DRM Buffer.
Definition drmbuffer.h:46
DRM Device.
Definition drmdevice.h:43
EGLDisplay EglDisplay(void)
Definition drmdevice.h:70
int GlInitiated(void)
Definition drmdevice.h:72
EGLSurface EglSurface(void)
Definition drmdevice.h:69
EGLContext EglContext(void)
Definition drmdevice.h:71
Grabbing Buffer.
Definition grab.h:53
HDR Metadata.
Definition drmhdr.h:109
size_t Size(void)
Get the current size of the queue.
Definition queue.h:121
Audio Interface.
Definition audio.h:50
Plugin Configuration.
Definition config.h:29
Output Device Implementation.
Video Renderer.
void PushPipFrame(AVFrame *)
Push a PiP frame into the render ringbuffer.
void SetFrameFlags(AVFrame *, int)
Set frame flags.
int m_numWrongProgressive
counter for progressive frames sent in an interlaced stream (only used for logging)
int DrmHandleEvent(void)
Wrapper for drmHandleEvent()
bool IsOutputBufferFull(void)
Check, if the main render output buffer is full.
int m_framesDuped
number of frames duplicated
void SetHdrBlob(struct hdr_output_metadata)
Create an hdr blob and set it for the connector.
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)
void Reset()
Reset the renderer.
bool CanHandleHdr(void)
Return true, if the device can handle HDR.
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)
void CreateGrabBuffers(bool)
Copy current video, osd and pip buffers to dedicated grabbing buffers.
int SetVideoBuffer(cDrmBuffer *)
Modesetting for video.
cDrmBufferPool m_pipDrmBufferPool
PIP pool of drm buffers.
cGrabBuffer m_grabVideo
keeps the current grabbed video
void ProcessEvents(void)
Process queued events and forward to event receiver.
int m_framesDropped
number of frames dropped
void OsdClear(void)
Clear the OSD (draw an empty/ transparent OSD)
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
int SetOsdBuffer(drmModeAtomicReqPtr)
Modesetting for osd.
void ScheduleResyncAtPtsMs(int64_t ptsMs)
void ClearDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
void Init(void)
Initialize the renderer.
void ResetDecodingStrategy()
std::atomic< bool > m_videoPlaybackPaused
set, if playback is frozen (used for pause)
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.
void SetColorSpace(drmColorRange)
Set kms color space, color encoding and color range.
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)
~cVideoRender(void)
Destroy the video renderer.
cRect m_videoRect
rect of the currently displayed video
void EnableOglOsd(void)
bool m_startgrab
internal flag to trigger grabbing
void ResetPipBufferReuseStrategy()
void GetStats(int *, int *, int *)
Get some rendering statistics.
std::atomic< cDecodingStrategy * > m_pipDecodingStrategy
strategy for decoding setup
cGrabBuffer * GetGrabbedOsdBuffer(void)
std::atomic< cBufferStrategy * > m_bufferReuseStrategy
strategy to select drm buffers
void DisplayBlackFrame(void)
Display a black video frame.
bool IsStillpicture(void)
cSoftHdAudio * m_pAudio
pointer to cSoftHdAudio
AVRational m_timebase
timebase used for pts, set by first RenderFrame()
void PushMainFrame(AVFrame *)
Push a main frame into the render ringbuffer.
std::mutex m_mutex
mutex for thread control
std::atomic< int64_t > m_pts
current video PTS
void SetVideoOutputPosition(const cRect &)
Set size and position of the video on the screen.
int GetFrameFlags(AVFrame *)
Get frame flags.
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
int64_t GetOutputPtsMs(void)
Get the output PTS in milliseconds.
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 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.
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)
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.
void Resume(void)
void SetStillpicture(bool active)
bool DisplayFrame()
Display the frame (video and/or osd)
bool m_disableOglOsd
set, if ogl osd is disabled
void Stop(void)
Stop the thread.
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 OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD ARGB image.
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
void SetScreenSize(int, int, double)
Wrapper to set the screen size in the device.
int64_t PtsToMs(int64_t)
Convert a PTS to milliseconds.
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
void SetPipSize(bool)
Set the size and position of the pip window.
bool PageFlip(cDrmBuffer *, cDrmBuffer *)
Do the pageflip.
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
void RestoreColorSpace()
Restore color space, color encoding and color range to BT709 and the original color range.
void ResetFrameCounter(void)
Send start condition to video thread.
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)
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.
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
Misc Functions.
Thread-safe Queue.
drmColorSpace
Definition videorender.h:67
@ COLORSPACE_BT2020_RGB
Definition videorender.h:69
@ COLORSPACE_BT709_YCC
Definition videorender.h:68
drmColorRange
Definition videorender.h:77
@ COLORRANGE_FULL
Definition videorender.h:79
@ COLORRANGE_LIMITED
Definition videorender.h:78
drmColorEncoding
Definition videorender.h:72
@ COLORENCODING_BT2020
Definition videorender.h:74
@ COLORENCODING_BT709
Definition videorender.h:73