vdr-plugin-softhddevice-drm-gles 1.5.9-20e15de
videorender.h
Go to the documentation of this file.
1
22#ifndef __VIDEORENDER_H
23#define __VIDEORENDER_H
24
25#include <atomic>
26#include <cstdint>
27#include <mutex>
28#include <vector>
29
30#include <xf86drmMode.h>
31
32extern "C" {
33#include <libavutil/frame.h>
34#include <libavutil/hwcontext_drm.h>
35}
36
37#ifdef USE_GLES
38#include <gbm.h>
39#include <EGL/egl.h>
40#endif
41
42#include <vdr/osd.h>
43#include <vdr/thread.h>
44
45#include "drmbuffer.h"
46#ifdef USE_GLES
47#include "drmdevice.h"
48#endif
49#include "event.h"
50#include "grab.h"
51#include "misc.h"
52#include "queue.h"
53#include "threads.h"
54
55#ifndef USE_GLES
56class cDrmDevice;
57#endif
58class cSoftHdDevice;
59class cSoftHdConfig;
60class cSoftHdAudio;
61
62#define AV_SYNC_THRESHOLD_AUDIO_BEHIND_VIDEO_MS 35
63#define AV_SYNC_THRESHOLD_AUDIO_AHEAD_VIDEO_MS 5
64
66public:
67 virtual ~cBufferStrategy() = default;
68 virtual cDrmBuffer *GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) = 0;
69};
70
72public:
73 cDrmBuffer *GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override;
74};
75
77public:
78 cDrmBuffer *GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override;
79};
80
82public:
83 cDrmBuffer *GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override;
84};
85
87public:
88 virtual ~cDecodingStrategy() = default;
89 virtual AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) = 0;
90};
91
93public:
94 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
95};
96
98public:
99 AVFrame *PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override;
100};
101
106{
107public:
109 ~cVideoRender(void);
110
111 void Init(void);
112 void Exit(void);
113
114 void SetVideoOutputPosition(const cRect &);
115 void SetScreenSize(int, int, double);
116 int64_t GetVideoClock(void) { return m_pts; };
117 void GetStats(int *, int *, int *);
118 void ResetFrameCounter(void);
119 void Reset();
120 void SetPlaybackPaused(bool pause) { m_videoPlaybackPaused = pause; };
121 void SetScheduleAudioResume(bool resume) { m_resumeAudioScheduled = resume; };
122
123 void ProcessEvents(void);
128
129 // OSD
130 void OsdClear(void);
131 void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int);
132
133 // TrickSpeed/ Stillpicture
134 void SetTrickSpeed(double, bool, bool);
135 bool IsTrickSpeed(void) { return m_trickspeed; };
137 void SetStillpicture(bool active) { m_stillpicture = active; };
138 bool IsStillpicture(void) { return m_stillpicture; };
139
140 // Grab
141 int TriggerGrab(void);
142 void ClearGrabBuffers(void);
146
147 // Threads
148 void ExitDisplayThread(void);
151
152 // DRM
153 int DrmHandleEvent(void);
154
155 // Frame and buffer
156 bool DisplayFrame();
157 int GetFramesFilled(void) { return m_drmBufferQueue.Size(); };
158 void PushMainFrame(AVFrame *);
159 void PushPipFrame(AVFrame *);
160 int64_t GetOutputPtsMs(void);
161 void DisplayBlackFrame(void);
163 bool IsOutputBufferFull(void);
166 void ScheduleResyncAtPtsMs(int64_t ptsMs) { m_scheduleResyncAtPtsMs = ptsMs; };
169
170#ifdef USE_GLES
171 // GLES
172 void DisableOglOsd(void) { m_disableOglOsd = true; };
173 void EnableOglOsd(void) { m_disableOglOsd = false; };
174 bool OglOsdDisabled(void) { return m_disableOglOsd; };
175 EGLSurface EglSurface(void) { return m_pDrmDevice->EglSurface(); };
176 EGLDisplay EglDisplay(void) { return m_pDrmDevice->EglDisplay(); };
177 EGLContext EglContext(void) { return m_pDrmDevice->EglContext(); };
178 int GlInitiated(void) { return m_pDrmDevice->GlInitiated(); };
179#endif
180
181 // PIP
182 void SetPipActive(bool on) { m_pipActive = on; };
184 void SetPipSize(bool);
185
186private:
191 std::vector<Event> m_eventQueue;
193
196 std::atomic<double> m_trickspeedFactor = 0;
197 std::atomic<bool> m_trickspeed = false;
198 std::atomic<bool> m_forwardTrickspeed = true;
199 std::atomic<bool> m_stillpicture = false;
200 std::atomic<int> m_framePresentationCounter = 0;
203
204 bool m_startgrab = false;
205 cCondVar m_grabCond;
209
214 AVRational m_timebase;
215 std::mutex m_timebaseMutex;
216 std::atomic<int64_t> m_pts = AV_NOPTS_VALUE;
217
219 bool m_videoIsScaled = false;
223
229 bool m_osdShown = false;
230 std::atomic<bool> m_videoPlaybackPaused = true;
231 std::atomic<bool> m_resumeAudioScheduled = false;
232 std::atomic<bool> m_displayOneFrameThenPause = false;
235
239 std::atomic<cBufferStrategy *> m_bufferReuseStrategy = nullptr;
240 std::atomic<cBufferStrategy *> m_pipBufferReuseStrategy = nullptr;
241 std::atomic<cDecodingStrategy *> m_decodingStrategy = nullptr;
242 std::atomic<cDecodingStrategy *> m_pipDecodingStrategy = nullptr;
243
244#ifdef USE_GLES
245 bool m_disableOglOsd;
246 struct gbm_bo *m_bo;
247 struct gbm_bo *m_pOldBo;
248 struct gbm_bo *m_pNextBo;
249#endif
250
251 std::atomic<bool> m_pipActive = false;
252
253 int GetFrameFlags(AVFrame *);
254 void SetFrameFlags(AVFrame *, int);
255 void SetVideoClock(int64_t pts) { m_pts = pts; };
256 bool PageFlip(cDrmBuffer *, cDrmBuffer *);
258 int SetOsdBuffer(drmModeAtomicReqPtr);
261 void CreateGrabBuffers(bool);
262 void LogDroppedDuped(int64_t, int64_t, int);
263 int64_t PtsToMs(int64_t);
264 void PushFrame(AVFrame *, bool, std::atomic<cBufferStrategy*> &, std::atomic<cDecodingStrategy*> &, cQueue<cDrmBuffer> *, cDrmBufferPool *);
265 int GetFramePresentationCount(int64_t);
266};
267
268#endif
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
virtual cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *)=0
virtual ~cBufferStrategy()=default
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
virtual AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *)=0
virtual ~cDecodingStrategy()=default
Display thread class.
Definition threads.h:65
void Halt(void)
Definition threads.h:69
void Resume(void)
Definition threads.h:70
cGrabBuffer - Grab buffer class
Definition grab.h:53
Thread-safe queue class.
Definition queue.h:36
size_t Size(void)
Get the current size of the queue.
Definition queue.h:128
cSoftHdAudio - Audio class
Definition audio.h:51
cVideoRender - Video render class
void PushPipFrame(AVFrame *)
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
bool m_osdShown
set, if osd is shown currently
cCondVar m_grabCond
condition gets signalled, if renederer finished to clone the grabbed buffers
cDrmBuffer * m_pCurrentlyDisplayed
pointer to currently displayed DRM buffer
int m_pipScalePercent
scale factor for pip
int GetFramesFilled(void)
std::atomic< bool > m_resumeAudioScheduled
set, if audio resume is scheduled after a pause
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 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)
cDisplayThread * m_pDisplayThread
pointer to display thread
std::atomic< int > m_framePresentationCounter
number of times the current frame has to be shown (for slow-motion)
cGrabBuffer * GetGrabbedPipBuffer(void)
double m_refreshRateHz
screen refresh rate in Hz
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.
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)
cVideoRender destructor
cRect m_videoRect
rect of the currently displayed video
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)
bool IsStillpicture(void)
cSoftHdAudio * m_pAudio
pointer to cSoftHdAudio
AVRational m_timebase
timebase used for pts, set by first RenderFrame()
void PushMainFrame(AVFrame *)
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
std::mutex m_timebaseMutex
mutex used around m_timebase
int64_t GetOutputPtsMs(void)
Get the output PTS in milliseconds.
cSoftHdDevice * m_pDevice
pointer to cSoftHdDevice
void SetPipActive(bool on)
std::atomic< cBufferStrategy * > m_pipBufferReuseStrategy
strategy to select drm buffers
std::atomic< bool > m_stillpicture
true, if stillpicture is active
cSoftHdConfig * m_pConfig
pointer to cSoftHdConfig
void DisplayThreadHalt(void)
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.
void LogDroppedDuped(int64_t, int64_t, int)
Log A/V sync debug message.
void SetStillpicture(bool active)
bool DisplayFrame()
Display the frame (video and/or osd)
void SchedulePlaybackStartAtPtsMs(int64_t ptsMs)
bool IsTrickSpeed(void)
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)
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)
bool PageFlip(cDrmBuffer *, cDrmBuffer *)
Do the pageflip.
int m_pipLeftPercent
left margin for pip
void SetPlaybackPaused(bool pause)
cDrmBufferPool m_drmBufferPool
pool of drm buffers
std::atomic< int64_t > m_schedulePlaybackStartAtPtsMs
if set, frames with PTS older than this will be dropped
void DisplayThreadResume(void)
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
int GetFramePresentationCount(int64_t)
Get the number of times the current frame shall be presented in trickspeed mode.
void ExitDisplayThread(void)
Stop display thread.
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.
State machine and event header file.
Grabber header file.
Misc function header file.
#define AV_NOPTS_VALUE
Definition misc.h:69
#define VIDEO_SURFACES_MAX
Definition misc.h:72
Thread-safe queue header file.
Thread classes header file.