vdr-plugin-softhddevice-drm-gles 1.6.7
softhddevice.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
13#ifndef __SOFTHDDEVICE_H
14#define __SOFTHDDEVICE_H
15
16#if __cplusplus < 201703L
17#error "C++17 or higher is required"
18#endif
19
20#include <atomic>
21#include <mutex>
22
23extern "C"
24{
25#include <libavcodec/avcodec.h>
26}
27
28#include <vdr/device.h>
29#include <vdr/osd.h>
30#include <vdr/status.h>
31#include <vdr/thread.h>
32
33#include "config.h"
34#include "event.h"
35#include "hardwaredevice.h"
36#include "jittertracker.h"
37#include "pes.h"
38
39class cAudioDecoder;
40class cDvbSpuDecoder;
41class cPipHandler;
42class cPipReceiver;
43class cSpuDecoder;
44class cSoftHdAudio;
45class cSoftHdDevice;
46class cSoftHdGrab;
48class cVideoRender;
49class cVideoStream;
50
61// State machine definitions
62// Implementing C++17 visitor pattern
63
64template<class... Ts>
65struct overload : Ts... { using Ts::operator()...; };
66template<class... Ts> overload(Ts...) -> overload<Ts...>;
67
75
76inline const char* EventToString(const Event& e) {
77 return std::visit(overload{
78 [](const PlayEvent&) -> const char* { return "PlayEvent"; },
79 [](const PauseEvent&) -> const char* { return "PauseEvent"; },
80 [](const StopEvent&) -> const char* { return "StopEvent"; },
81 [](const TrickSpeedEvent&) -> const char* { return "TrickSpeedEvent"; },
82 [](const StillPictureEvent&) -> const char* { return "StillPictureEvent"; },
83 [](const DetachEvent&) -> const char* { return "DetachEvent"; },
84 [](const AttachEvent&) -> const char* { return "AttachEvent"; },
85 [](const BufferUnderrunEvent& e) -> const char* { return e.type == AUDIO ? "BufferUnderrunEvent: Audio" : "BufferUnderrunEvent: Video"; },
86 [](const BufferingThresholdReachedEvent&) -> const char* { return "BufferingThresholdReachedEvent"; },
87 [](const ScheduleResyncAtPtsMsEvent&) -> const char* { return "ScheduleResyncAtPtsMsEvent"; },
88 [](const ResyncEvent&) -> const char* { return "ResyncEvent"; },
89 [](const DisplayChangeEvent&) -> const char* { return "DisplayChangeEvent"; },
90 }, e);
91}
92
93inline const char* StateToString(State s) {
94 switch(s) {
95 case State::STOP: return "STOP";
96 case State::BUFFERING: return "BUFFERING";
97 case State::PLAY: return "PLAY";
98 case State::TRICK_SPEED: return "TRICK_SPEED";
99 case State::DETACHED: return "DETACHED";
100 }
101 return "Unknown";
102}
103
110
118class cEventHandler : public cThread {
119public:
121 virtual ~cEventHandler(void);
122
123 void AddEvent(Event);
124protected:
125 virtual void Action(void) override;
126private:
128 std::mutex m_mutex;
129 std::vector<Event> m_eventQueue;
131};
132
138class cSoftHdDevice : public cDevice, public IEventReceiver, public cStatus {
139public:
141 virtual ~cSoftHdDevice(void);
142
143 //
144 // virtual cDevice
145 //
146protected:
147 virtual void MakePrimaryDevice(bool);
148 virtual void ChannelSwitch(const cDevice *, int, bool);
149
150public:
151 virtual cString DeviceName(void) const { return "softhddevice-drm-gles"; }
152 virtual bool HasDecoder(void) const;
153
154 // SPU facilities
155 virtual cSpuDecoder * GetSpuDecoder(void);
156
157 // player facilities
158 virtual bool CanReplay(void) const;
159 virtual bool SetPlayMode(ePlayMode);
160 virtual int PlayVideo(const uchar *, int);
161 virtual int PlayAudio(const uchar *, int, uchar);
162 virtual int64_t GetSTC(void);
163 virtual cRect CanScaleVideo(const cRect &, int taCenter);
164 virtual void ScaleVideo(const cRect & = cRect::Null);
165 virtual void TrickSpeed(int, bool);
166 virtual void Clear(void);
167 virtual void Play(void);
168 virtual void Freeze(void);
169 virtual void StillPicture(const uchar *, int);
170 virtual bool Poll(cPoller &, int = 0);
171 virtual bool Flush(int = 0);
172
173 // Image Grab facilities
174 virtual uchar *GrabImage(int &, bool, int, int, int);
175
176 // video format facilities
178 virtual void SetVideoFormat(bool);
179 virtual void GetVideoSize(int &, int &, double &);
180 virtual void GetOsdSize(int &, int &, double &);
181
182 // track facilities
183 virtual void SetAudioTrackDevice(eTrackType);
184
185 // audio facilities
186 virtual int GetAudioChannelDevice(void);
187 virtual void SetAudioChannelDevice(int);
188 virtual void SetVolumeDevice(int);
189 virtual void SetDigitalAudioDevice(bool);
190
191 //
192 // wrapped by cPluginSoftHdDevice
193 //
194 bool Initialize(void);
195 int Start(void);
196 void Stop(void);
197
198 //
199 // cSoftHdDevice public methods
200 //
201 cSoftHdConfig *Config(void) { return m_pConfig; };
203 cVideoRender *Render(void) { return m_pRender; };
204 cSoftHdAudio *Audio(void) { return m_pAudio; };
205
206 void SetDisableDeint(void);
207 void SetDecoderNeedsIFrame(void);
208 void SetParseH264Dimensions(void);
209 void SetDecoderFallbackToSw(bool);
210 void SetEnableHdr(bool);
211 void SetDisplayMode(int);
212
213 // osd
214#ifdef USE_GLES
215 int MaxSizeGPUImageCache(void);
216 int OglOsdIsDisabled(void);
217 void SetDisableOglOsd(void);
218 void SetEnableOglOsd(void);
219#endif
220 void OsdClose(void);
221 void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int);
222 void SetOsdSize(int, int);
223 void SetScreenSize(int, int);
224
225 // audio
228 void SetPassthroughMask(int);
229 void ResetChannelId(void);
230
231 // Logging, statistics
232 void GetStats(int *, int *, int *);
233 std::chrono::steady_clock::time_point GetChannelSwitchStartTime(void) { return m_channelSwitchStartTime; };
234 std::chrono::steady_clock::time_point GetChannelSwitchFirstPacketTime(void) { return m_dataReceivedTime; };
235
236 // Mediaplayer
239 int PlayAudioPkts(AVPacket *);
240 int PlayVideoPkts(AVPacket *);
241
242 // detach/ attach
243 void Detach(void);
244 void Attach(void);
245 bool IsDetached(void) const;
246 void ResetOsdProvider(void) { m_pOsdProvider = nullptr; }
247 bool IsOsdProviderSet(void) const { return m_pOsdProvider != nullptr; }
248 void SetStartDetached(void) { m_forceDetached = true; };
249
252
253 // pip wrapper functions
254 void SetDisablePip(void) { m_disablePip = true; };
255 bool PipIsEnabled(void);
256 void PipEnable(void);
257 void PipDisable(void);
258 void PipToggle(void);
259 void PipChannelChange(int);
260 void PipChannelSwap(bool);
261 void PipSwapPosition(void);
262 void PipSetSize(void);
263 void SetRenderPipSize(void);
264 void SetRenderPipActive(bool);
265
266 // pip functions
267 int PlayPipVideo(const uchar *, int);
270 void ResetPipStream(void);
272
273private:
274 static constexpr int MIN_BUFFER_FILL_LEVEL_THRESHOLD_MS = 450;
275
276 std::atomic<State> m_state = DETACHED;
277 std::mutex m_eventMutex;
278 bool m_needsMakePrimary = false;
292 std::chrono::steady_clock::time_point m_channelSwitchStartTime;
293 std::chrono::steady_clock::time_point m_dataReceivedTime;
294
295 std::atomic<PlaybackMode> m_playbackMode = NONE;
298
302 mutable std::mutex m_mutex;
303 std::mutex m_sizeMutex;
304 std::atomic<bool> m_receivedAudio = false;
305 std::atomic<bool> m_receivedVideo = false;
306 std::atomic<bool> m_receivedValidAudio = false;
307 std::atomic<bool> m_receivedValidVideo = false;
309 bool m_drmCanDisplayPip = true;
310 bool m_disablePip = false;
311 int m_volume = 0;
312
317
318 bool m_forceDetached = false;
320
321 int PlayVideoInternal(cVideoStream *, cReassemblyBufferVideo *, const uchar *, int, bool, bool);
322 void FlushAudio(void);
323 void OnEventReceived(const Event&);
324 void HandleStillPicture(const uchar *data, int size);
325 void HandleDisplayModeChange(const sDrmMode &);
328
330
331 // State machine
332 void SetState(State);
334 void OnLeavingState(State);
335};
336
337#endif
Event Receiver.
Definition event.h:82
Audio Decoder.
Definition codec_audio.h:59
Event handler thread.
void AddEvent(Event)
Add an event to the queue.
std::vector< Event > m_eventQueue
event fifo queue
std::mutex m_mutex
queue mutex
virtual ~cEventHandler(void)
Stop and delete the event handler thread.
IEventReceiver * m_pEventReceiver
pointer to event receiver
virtual void Action(void) override
Periodically send events in the queue to the final event receiver/handler.
cSoftHdDevice * m_pDevice
pointer to device
Hardware device.
Jitter Tracker.
PiP Stream Handler.
Definition pipreceiver.h:55
Receiver for PiP Stream.
Definition pipreceiver.h:31
Audio Stream Reassembly Buffer.
Definition pes.h:178
Video Stream Reassembly Buffer.
Definition pes.h:145
Audio Interface.
Definition audio.h:51
Plugin Configuration.
Definition config.h:49
int ConfigVideoAudioDelayMs
config audio delay
Definition config.h:68
Output Device Implementation.
void SetState(State)
Sets the device into the given state.
void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD pixmap.
cReassemblyBufferVideo m_videoReassemblyBuffer
video pes reassembly buffer
void Stop(void)
Called by VDR when the plugin is stopped.
bool m_pipUseAlt
use alternative pip position
cReassemblyBufferVideo m_pipReassemblyBuffer
pip pes reassembly buffer
void PipChannelSwap(bool)
cVideoStream * m_pPipStream
pointer to pip video stream
void FlushAudio(void)
Clear all audio data from the decoder and ringbuffer.
void PipSwapPosition(void)
static constexpr int MIN_BUFFER_FILL_LEVEL_THRESHOLD_MS
min buffering threshold in ms
int m_volume
track the volume in the device (for attach)
void SetScreenSize(int, int)
Set the screen size.
virtual void StillPicture(const uchar *, int)
Display the given I-frame as a still picture.
void PipSetSize(void)
void HandleDisplayModeChange(const sDrmMode &)
Set the display mode.
cSoftOsdProvider * m_pOsdProvider
pointer to cSoftOsdProvider object
cVideoStream * m_pVideoStream
pointer to main video stream
cReassemblyBufferAudio m_audioReassemblyBuffer
audio pes reassembly buffer
int MaxSizeGPUImageCache(void)
Get the maximum GPU image cache size.
std::atomic< bool > m_receivedAudio
flag if audio packets have been received
void SetRenderPipSize(void)
cDvbSpuDecoder * m_pSpuDecoder
pointer to spu decoder
void OnEnteringState(State)
Actions to be performed when entering a state.
int Start(void)
Called by VDR when the plugin is started.
void SetEnableOglOsd(void)
Enables OpenGL/ES Osd.
virtual void GetVideoSize(int &, int &, double &)
Get the video size.
bool IsOsdProviderSet(void) const
int PlayAudioPkts(AVPacket *)
Play an audio packet.
virtual void GetOsdSize(int &, int &, double &)
Returns the width, height and aspect ratio the OSD should have.
void SetEnableHdr(bool)
Enable HDR display mode.
void SetRenderPipActive(bool)
void GetStats(int *, int *, int *)
Get statistics from the renderer.
void ResetChannelId(void)
Reset the channel ID (restarts audio)
cHardwareDevice * m_pHardwareDevice
pointer to hardware device description
virtual bool CanReplay(void) const
Return true if this device can currently start a replay session.
virtual void SetDigitalAudioDevice(bool)
bool UsePip(void)
std::mutex m_mutex
mutex to lock the state machine
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
virtual void Clear(void)
Clears all video and audio data from the device.
cEventHandler * m_pEventHandler
event handler thread
void OnEventReceived(const Event &)
Event handler for playback state transitions.
cPipHandler * m_pPipHandler
pointer to pip handler
void Detach(void)
Detach the device.
virtual int PlayVideo(const uchar *, int)
Play a video packet of the main videostream.
void SetStartDetached(void)
void ResetPipStream(void)
Resets pip stream and render pipeline.
int GetVideoAudioDelayMs(void)
std::chrono::steady_clock::time_point m_dataReceivedTime
timestamp, when the first audio or video data after a channel switch arrives in Play*()
std::atomic< State > m_state
current plugin state, normal plugin start sets detached state
void OnLeavingState(State)
Actions to be performed when leaving a state.
void SetDisablePip(void)
virtual bool SetPlayMode(ePlayMode)
Sets the device into the given play mode.
cAudioDecoder * m_pAudioDecoder
pointer to cAudioDecoder object
void SetDrmCanDisplayPip(bool canDisplay)
void SetAudioCodec(enum AVCodecID, AVCodecParameters *, AVRational)
Open an audio codec.
virtual void Play(void)
Sets the device into play mode (after a previous trick mode, or pause)
bool IsBufferingThresholdReached(void)
Check if the buffering threshold has been reached.
cVideoRender * m_pRender
pointer to cVideoRender object
virtual void SetAudioChannelDevice(int)
void SetOsdSize(int, int)
Set the OSD size.
cSoftHdGrab * m_pGrab
pointer to grabber object
int OglOsdIsDisabled(void)
Is the OpenGL/ES osd disabled?
int PlayPipVideo(const uchar *, int)
Play a video packet of the pip videostream.
bool m_needsMakePrimary
true, if device should be made a primary device after attach
virtual void ChannelSwitch(const cDevice *, int, bool)
Monitor a channel switch triggered by VDR (cStatus::ChannelSwitch())
cSoftHdAudio * m_pAudio
pointer to cSoftHdAudio object
std::chrono::steady_clock::time_point GetChannelSwitchFirstPacketTime(void)
cSoftHdConfig * m_pConfig
pointer to cSoftHdConfig object
void ResetOsdProvider(void)
virtual cRect CanScaleVideo(const cRect &, int taCenter)
Ask the output, if it can scale video.
bool m_disablePip
true, if pip was disabled by the user
virtual void SetVolumeDevice(int)
Sets the audio volume on this device (Volume = 0...255).
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles.
virtual bool Flush(int=0)
Flush the device output buffers.
bool IsDetached(void) const
Returns true, if the device is detached.
cVideoRender * Render(void)
virtual void TrickSpeed(int, bool)
Sets the device into a mode where replay is done slower.
cVideoStream * VideoStream(void)
std::chrono::steady_clock::time_point m_channelSwitchStartTime
timestamp, when VDR triggered a channel switch
void SetDecoderFallbackToSw(bool)
Force the decoder to fallback to software if the hardware decoder fails after the configured amount o...
virtual int PlayAudio(const uchar *, int, uchar)
Play an audio packet.
void PipToggle(void)
bool PipIsEnabled(void)
Returns true, if pip is currently enabled.
std::mutex m_sizeMutex
mutex to lock screen size (which is accessed by different threads)
std::chrono::steady_clock::time_point GetChannelSwitchStartTime(void)
bool Initialize(void)
Initialize the device.
std::atomic< bool > m_receivedVideo
flag if video packets have been received
void SetDecoderNeedsIFrame(void)
Forces the h264 decoder to wait for an I-Frame to start.
virtual int GetAudioChannelDevice(void)
int PlayVideoPkts(AVPacket *)
Play a video packet.
std::atomic< bool > m_receivedValidAudio
flag if valid audio packets have been received
cJitterTracker m_audioJitterTracker
audio jitter tracker
virtual cString DeviceName(void) const
std::atomic< bool > m_receivedValidVideo
flag if valid video packets have been received
int GetBufferFillLevelThresholdMs()
Returns the buffer fill level threshold in milliseconds.
void HandleStillPicture(const uchar *data, int size)
The still picture data received from VDR can contain multiple PES packets.
int PlayVideoInternal(cVideoStream *, cReassemblyBufferVideo *, const uchar *, int, bool, bool)
Play a video packet.
std::mutex m_eventMutex
mutex to protect event queue
virtual void SetVideoDisplayFormat(eVideoDisplayFormat)
Sets the video display format.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
void SetParseH264Dimensions(void)
Parse the h264 stream width and height before starting the decoder.
void SetDisableOglOsd(void)
Disables OpenGL/ES Osd (called from setup menu or conf)
cSoftHdConfig * Config(void)
bool m_forceDetached
start the plugin in detached state
virtual ~cSoftHdDevice(void)
Destroy the device.
int GetMinBufferFillLevelThresholdMs(void)
int m_audioChannelID
current audio channel ID
void PipDisable(void)
virtual void SetVideoFormat(bool)
Set the video format.
virtual void MakePrimaryDevice(bool)
Informs a device that it will be the primary device.
void SetVideoCodec(enum AVCodecID, AVCodecParameters *, AVRational)
Open a video codec.
void PipEnable(void)
void SetPassthroughMask(int)
Set the passthrough mask (called from setup menu or conf)
void SetDisableDeint(void)
Disables deinterlacer (called from setup menu or conf)
virtual uchar * GrabImage(int &, bool, int, int, int)
Grabs the currently visible screen image.
virtual cSpuDecoder * GetSpuDecoder(void)
Get the device SPU decoder.
cJitterTracker m_videoJitterTracker
video jitter tracker
virtual void SetAudioTrackDevice(eTrackType)
bool m_drmCanDisplayPip
true, if the drm device is able to display a pip video
std::atomic< PlaybackMode > m_playbackMode
current playback mode
void OsdClose(void)
Close the OSD.
int64_t GetFirstAudioPtsMsToPlay()
Calculate the first audio PTS that should be played during synchronized playback.
bool IsVideoOnlyPlayback(void)
virtual void ScaleVideo(const cRect &=cRect::Null)
Scale the currently shown video.
int64_t GetFirstVideoPtsMsToPlay()
void SetDisplayMode(int)
Trigger a display mode change event if the mode changed.
cSoftHdAudio * Audio(void)
void PipChannelChange(int)
virtual bool Poll(cPoller &, int=0)
Return true if the device itself or any of the file handles in poller is ready for further action.
void Attach(void)
Attach the device again.
bool m_externalPlayerActive
true, if we detached for an external player
void ToggleRenderPipPosition(void)
Grabbing Processor.
Definition grab.h:79
Plugin OSD provider.
Video Renderer.
Video Input Stream.
Definition videostream.h:47
Plugin Configuration Header File.
State Machine and Event Header File.
PlaybackMode
const char * EventToString(const Event &e)
State
const char * StateToString(State s)
@ AUDIO_AND_VIDEO
@ VIDEO_ONLY
@ AUDIO_ONLY
@ NONE
@ PLAY
@ STOP
@ BUFFERING
@ TRICK_SPEED
@ DETACHED
std::variant< PlayEvent, PauseEvent, StopEvent, TrickSpeedEvent, StillPictureEvent, DetachEvent, AttachEvent, BufferUnderrunEvent, BufferingThresholdReachedEvent, ScheduleResyncAtPtsMsEvent, ResyncEvent, DisplayChangeEvent > Event
Definition event.h:73
@ AUDIO
Definition event.h:31
Describes a hardware device.
Jitter Tracking of Incoming Packets Header File.
PES Packet Parser Header File.
Holds possible display configurations.
Definition config.h:30