24#include <libavcodec/avcodec.h>
27#include <vdr/dvbspu.h>
29#include <vdr/status.h>
30#include <vdr/thread.h>
142 cDevice::MakePrimaryDevice(
on);
183 if (!width || !height) {
196 LOGDEBUG2(
L_GRAB,
"device: %s: %d, %d, %d, %dx%d",
__FUNCTION__, size,
jpeg,
quality, width, height);
335 auto now = std::chrono::steady_clock::now();
414 auto now = std::chrono::steady_clock::now();
419 LOGGER->SetChannelSwitchDataReceivedTime(
now);
463 }
while (
avpkt !=
nullptr);
544 if (width <= 0 || height <= 0)
550 return cRect(x, y, width, height);
727 if (data[0] == 0x47) {
728 cDevice::StillPicture(data, size);
791 cCondWait::SleepMs(std::min(5,
timeoutMs));
796#if APIVERSNUM >= 30014
802bool cOutputDevice::DrainDevice(
void)
849 auto now = std::chrono::steady_clock::now();
867 auto now = std::chrono::steady_clock::now();
928 LOGDEBUG(
"Add display mode change event to %s mode %dx%d@%.2f%s",
1021 auto now = std::chrono::steady_clock::now();
1023 LOGDEBUG2(
L_AV_SYNC,
"TRACE: +%5dms firing BufferingThresholdReached - PTS: %s (a), %s (v) -> diff %dms - buffer fill levels: %ldms (a) %ldms (v) render queue %d",
1036 auto now = std::chrono::steady_clock::now();
1038 LOGDEBUG2(
L_AV_SYNC,
"TRACE: +%5dms BufferingThresholdReached, video waits for audio - PTS: %s (a), %s (v) -> diff %dms - buffer fill levels: %ldms (a) %ldms (v) render queue %d",
1103 auto now = std::chrono::steady_clock::now();
1105 LOGDEBUG2(
L_AV_SYNC,
"TRACE: +%5dms firing AudioBufferingThresholdReached, threshold %dms - PTS: %s (a), %s (v) -> diff %dms - audio buffer: %ldms -> %ldms",
1345 if (cDevice::Replaying()) {
1492 LOGDEBUG2(
L_CODEC,
"Stream: %02X%02X%02X | %02X | %02X%02X | %02X%02X%02X | %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
1535 if (
stream->IsInputBufferFull())
1548 auto now = std::chrono::steady_clock::now();
1553 LOGGER->SetChannelSwitchDataReceivedTime(
now);
1572 auto now = std::chrono::steady_clock::now();
1649 LOGDEBUG(
"Set display mode: %dx%d@%.2f%s",
1782 LOGERROR(
"device: display init failed -> start in detached mode");
2011 LOGDEBUG(
"device: audio only detected");
2015 LOGDEBUG(
"device: video only detected");
2022 LOGDEBUG(
"device: buffering threshold reached and no a/v available, keep BUFFERING state");
2069 LOGFATAL(
"STATE MACHINE: play event in PLAY state with NONE playback mode. This is a bug.");
Audio Interface Header File.
void FlushBuffers(void)
Flush the audio decoder buffers.
void Decode(const AVPacket *)
Forward an audio packet either to the decoder or passthrough.
AVCodecID GetCodecId() const
void Open(AVCodecID, AVCodecParameters *=nullptr, AVRational={ .num=1,.den=PTSTICKS })
Open and initiate the audio decoder.
void SetPassthroughMask(int)
Set audio pass-through mask.
void Close(void)
Close the audio decoder.
void SetHwDelayBaseline(void)
Set the hw delay baseline.
bool IsForwardTrickSpeed(void)
bool IsSlowTrickSpeed(void)
int64_t GetTrickSpeedPtsTimebaseUnits(void)
void SetPassthroughMask(int mask)
void ResetHwDelayBaseline(void)
Reset the hw delay baseline.
void ClockDriftCompensation(void)
Calculate clock drift compensation.
void ResetTrickSpeedPts(void)
void Exit(void)
Cleanup audio output module (alsa)
int64_t GetOutputPtsMs(void)
Get the output PTS of the ringbuffer.
void SetPaused(bool)
Set audio playback pause state.
void SetTrickSpeed(double, bool, bool)
Set the trickspeed.
int64_t GetHardwareOutputPtsTimebaseUnits(void)
Get the hardware output PTS in timebase units.
void DropSamplesOlderThanPtsMs(int64_t)
Drop samples older than the given PTS.
int64_t GetInputPtsMs(void)
int LazyInit(void)
Initialize audio output module (alsa)
void SetVolume(int)
Set mixer volume (0-1000)
void FlushBuffers(void)
Flush audio buffers.
void AdvanceTrickSpeedPts(int64_t)
Advance the pts in trickspeed mode and delay "playback".
std::atomic< int > StatMaxShortTermVideoJitterMs
logged max video jitter of the last 1000 packets
std::atomic< int > StatMaxShortTermAudioJitterMs
logged max audio jitter of the last 1000 packets
sDrmMode CurrentVideoDrmMode
currently used video drm mode
std::atomic< int > StatMaxLongTermAudioJitterMs
logged max overall audio jitter since stream start
int ConfigAdditionalBufferLengthMs
config size ms of a/v buffer
std::atomic< int > StatMaxLongTermVideoJitterMs
logged max overall video jitter since stream start
bool ConfigDisableDeint
disable deinterlacer
int ConfigVideoChannelSwitchMode
channel switch mode (enum ChannelSwitchMode)
int ConfigDecoderFallbackToSwNumPkts
maximum number of packets sent before fallback to sw decoder
int ConfigVideoAudioDelayMs
config audio delay
int ConfigDisableOglOsd
config disable ogl osd
sDrmMode RequestedDrmMode
is set to the requested mode which should be changed to
bool CompareCurrentMode(sDrmMode *)
Return true, if the given mode is equal to the current display mode.
sDrmMode AutoDetectedDrmMode
auto detected mode on the first startup (maybe equal to UserSetMode)
std::vector< sDrmMode > CollectedDrmModes
collected available drm modes on the current connector
int ConfigMaxSizeGPUImageCache
config max gpu image cache size
void RequestStopOpenGlThread(void)
Initiate a stop of the OpenGL thread without waiting.
void StopOpenGlThread(void)
Stop the OpenGL thread and cancel it if necessary.
void UnlockOpenGlThread(void)
Unlock the OpenGL thread.
bool LockOpenGlThread(void)
Lock the OpenGL thread.
void AddEvent(Event)
Add an event to the queue.
void Finish(void)
Clean up.
bool ProcessGrab(void)
Start the conversion.
bool Start(bool, int, int, int, int, int)
Start a grab in the video renderer.
int GetQuirks(void)
Get Hardware Quirks.
int GetShortTermMaxJitterMs(void)
int GetLongTermMaxJitterMs(void)
void PacketReceived(void)
Called each time a packet is received.
void Reset(void)
Resets the jitter tracker.
bool m_externalPlayerActive
true, if we detached for an external player
std::mutex m_sizeMutex
mutex to lock screen size (which is accessed by different threads)
virtual void TrickSpeed(int, bool)
Sets the device into a mode where replay is done slower.
cVideoRender * m_pRender
pointer to cVideoRender object
virtual bool CanReplay(void) const
Return true if this device can currently start a replay session.
cAudioDecoder * m_pAudioDecoder
pointer to cAudioDecoder object
bool m_initialized
true, if the plugin had a successful Initialize()
std::unique_ptr< cStateMachine > m_pStateMachine
void HandleStillPicture(const uchar *data, int size)
The still picture data received from VDR can contain multiple PES packets.
bool CheckAudioPlaybackStartConditions(void)
Returns true, if audio playback should start without respect to a/v-sync.
int m_audioChannelID
current audio channel ID
void SetVideoCodec(enum AVCodecID, AVCodecParameters *, AVRational)
Open a video codec.
void HandleDisplayModeChange(const sDrmMode &)
Set the display mode.
int MaxSizeGPUImageCache(void)
Get the maximum GPU image cache size.
void SetRenderPipActive(bool)
void SetPassthroughMask(int)
Set the passthrough mask (called from setup menu or conf)
int PlayPipVideo(const uchar *, int)
Play a video packet of the pip videostream.
virtual int PlayAudio(const uchar *, int, uchar)
Play an audio packet.
void EnterState(State)
Actions to be performed when entering a state.
void LeaveState(State)
Actions to be performed when leaving a state.
std::atomic< ChannelSwitchMode > m_channelSwitchMode
current channel switch mode
int PlayVideoPkts(AVPacket *)
Play a video packet.
void ResumeVideoThreads(void)
Resume the rendering and decoder thread.
void TriggerEvent(const Event &)
With this wrapper function, the device can directly act as an event reveiver.
bool HaltOpenGlThread(void)
Pause the OpenGL worker thread.
void SetEnableHdr(bool)
Enable HDR display mode.
int OglOsdIsDisabled(void)
Is the OpenGL/ES osd disabled?
std::atomic< bool > m_receivedAudio
flag if audio packets have been received
std::atomic< bool > m_draining
true, if the device is in draining mode (waiting for empty buffers)
virtual cSpuDecoder * GetSpuDecoder(void)
Get the device SPU decoder.
void PipChannelChange(int)
int64_t GetFirstAudioPtsMsToPlay()
Calculate the first audio PTS that should be played during synchronized playback.
cDvbSpuDecoder * m_pSpuDecoder
pointer to spu decoder
void Detach(void)
Detach the device.
void SetDecoderFallbackToSw(bool)
Force the decoder to fallback to software if the hardware decoder fails after the configured amount o...
virtual bool Flush(int=0)
Return true, if the output buffers are empty, false otherwise.
std::atomic< PlaybackMode > m_playbackMode
current playback mode
void FlushAudio(void)
Clear all audio data from the decoder and ringbuffer.
virtual bool HasDecoder(void) const
Tells whether this device has an MPEG decoder.
int GetBufferFillLevelThresholdMs()
Returns the buffer fill level threshold in milliseconds.
bool m_needsMakePrimary
true, if device should be made a primary device after attach
virtual uchar * GrabImage(int &, bool, int, int, int)
Grabs the currently visible screen image.
void Stop(void)
Called by VDR when the plugin is stopped.
void ResetChannelId(void)
Reset the channel ID (restarts audio)
cDeviceConfig * m_pConfig
pointer to cDeviceConfig object
void SetOsdSize(int, int)
Set the OSD size.
virtual ~cOutputDevice(void)
Destroy the device.
void SetEnableOglOsd(void)
Enables OpenGL/ES Osd.
virtual void SetVideoDisplayFormat(eVideoDisplayFormat)
Sets the video display format.
void Attach(void)
Attach the device again.
bool Initialize(void)
Initialize the device.
void OsdDraw(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD pixmap.
void ResetVideoFilter(void)
Reset the video deinterlace filter.
virtual void Freeze(void)
Puts the device into "freeze frame" mode.
cAudioStream * m_pAudio
pointer to cAudioStream object
cGrabber * m_pGrab
pointer to grabber object
bool CheckPlaybackStartConditions(void)
Check, if all conditions are met to start the playback.
void ResumePlayback(void)
Resume playback again.
cHardwareDevice * m_pHardwareDevice
pointer to hardware device description
virtual void Play(void)
Sets the device into play mode (after a previous trick mode, or pause)
cEventHandler * m_pEventHandler
event handler thread
void PipChannelSwap(bool)
virtual void ScaleVideo(const cRect &=cRect::Null)
Scale the currently shown video.
cOutputDevice(cDeviceConfig *)
Create the device.
int64_t GetFirstVideoPtsMsToPlay()
int PlayVideoInternal(cVideoStream *, cReassemblyBufferVideo *, const uchar *, int, bool, bool)
Play a video packet.
bool FastChannelSwitchInTransferMode(void)
void SetRenderPipSize(void)
void SetDisplayMode(int)
Trigger a display mode change event if the mode changed.
cReassemblyBufferAudio m_audioReassemblyBuffer
audio pes reassembly buffer
cJitterTracker m_videoJitterTracker
video jitter tracker
bool m_forceDetached
start the plugin in detached state
bool PipIsEnabled(void)
Returns true, if pip is currently enabled.
bool IsDetached(void) const
Returns true, if the device is detached.
void SetDisableDeint(void)
Disables deinterlacer (called from setup menu or conf)
void SetDrain(bool)
Set and log the drain state changes.
virtual void Replaying(const cControl *, const char *, const char *, bool)
Monitor a replay start or end.
static constexpr int MIN_BUFFER_FILL_LEVEL_THRESHOLD_MS
min buffering threshold in ms
cVideoStream * m_pPipStream
pointer to pip video stream
virtual void Clear(void)
Clears all video and audio data from the device.
int GetVideoAudioDelayMs(void)
cPipHandler * m_pPipHandler
pointer to pip handler
virtual bool SetPlayMode(ePlayMode)
Sets the device into the given play mode.
void SetAudioCodec(enum AVCodecID, AVCodecParameters *, AVRational)
Open an audio codec.
std::atomic< bool > m_receivedValidVideo
flag if valid video packets have been received
void HaltVideoThreads(void)
Pause the rendering and decoder thread.
bool IsDetachForced(void)
Returns true, the a detached plugin start was forced.
std::atomic< bool > m_receivedVideo
flag if video packets have been received
cReassemblyBufferVideo m_pipReassemblyBuffer
pip pes reassembly buffer
cReassemblyBufferVideo m_videoReassemblyBuffer
video pes reassembly buffer
cJitterTracker m_audioJitterTracker
audio jitter tracker
void OsdClose(void)
Close the OSD.
void ResetPipStream(void)
Resets pip stream and render pipeline.
virtual void SetVideoFormat(bool)
Set the video format.
void SetTrickSpeed(double, bool, bool)
Set the trickspeed in the renderer.
virtual void GetVideoSize(int &, int &, double &)
Get the video size.
virtual int64_t GetSTC(void)
Gets the current System Time Counter, which can be used to synchronize audio, video and subtitles.
void GetStats(int *, int *, int *)
Get statistics from the renderer.
void SetScreenSize(int, int)
Set the screen size.
bool m_pipUseAlt
use alternative pip position
void SetDisableOglOsd(void)
Disables OpenGL/ES Osd (called from setup menu or conf)
int InitAudio(bool)
Init the audio lazily.
virtual void SetVolumeDevice(int)
Sets the audio volume on this device (Volume = 0...255).
virtual void MakePrimaryDevice(bool)
Informs a device that it will be the primary device.
void ResumeOpenGlThread(void)
Resume the OpenGL worker thread.
void PausePlayback(bool)
Pause the playback.
virtual int PlayVideo(const uchar *, int)
Play a video packet of the main videostream.
std::atomic< bool > m_receivedValidAudio
flag if valid audio packets have been received
bool FastChannelSwitchAudioInTransferMode(void)
int PlayAudioPkts(AVPacket *)
Play an audio packet.
void ScheduleResyncAtPtsMs(int64_t)
Schedule aa a/v resync in the render thread at the given pts.
cDeviceOsdProvider * m_pOsdProvider
pointer to cDeviceOsdProvider object
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.
virtual cRect CanScaleVideo(const cRect &, int taCenter)
Ask the output, if it can scale video.
void PipSwapPosition(void)
bool SchedulePlaybackStart(void)
Schedules the playback start.
void ResumeFromPause(void)
Resume playback from pause state.
int Start(void)
Called by VDR when the plugin is started.
virtual void GetOsdSize(int &, int &, double &)
Returns the width, height and aspect ratio the OSD should have.
virtual void ChannelSwitch(const cDevice *, int, bool)
Monitor a channel switch triggered by VDR (cStatus::ChannelSwitch())
virtual void StillPicture(const uchar *, int)
Display the given I-frame as a still picture.
cVideoStream * m_pVideoStream
pointer to main video stream
int m_volume
track the volume in the device (for attach)
void ChannelChange(int)
Change the pip channel.
void SwapPosition(void)
Swap pip between normal and alternative position.
void Toggle(void)
Toggle picture-in-picture.
void Disable(void)
Stop picture-in-picture.
void ChannelSwap(bool)
Swap the pip channel with main live channel.
void Enable(void)
Start picture-in-picture.
void SetSize(void)
Set size and position for the pip window.
AVPacket * PopAvPacket(void) override
Pop an audio AVPacket from the reassembly buffer.
Video Stream Reassembly Buffer.
AVPacket * PopAvPacket(void) override
bool HasLeadingZero(const uint8_t *, int)
Check if video data has a leading zero byte before the start code.
bool ParseCodecHeader(const uint8_t *, int)
Parse video codec header to detect codec type.
void Reset(void)
Reset the reassembly buffer.
virtual void Push(const uint8_t *data, int size, int64_t pts)
void PushPipFrame(AVFrame *)
Push a PiP frame into the render ringbuffer.
bool IsOutputBufferFull(void)
Check, if the main render output buffer is full.
int GetFramesFilled(void)
void SetEnableHdr(bool enable)
void Reset()
Reset the renderer.
void ResetBufferReuseStrategy()
void ReInitDisplayMode(void)
Re-Initialize the drm device with current display mode settings.
void OsdClear(void)
Clear the OSD (draw an empty/ transparent OSD)
static constexpr int GetAudioBehindVideoStartThresholdMs(void)
void OsdDraw(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD ARGB image.
void ScheduleVideoPlaybackPauseAt(int64_t ptsMs)
void ScheduleResyncAtPtsMs(int64_t ptsMs)
void ClearDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
void ResetDecodingStrategy()
void Exit(void)
Exit and cleanup the renderer.
void ResetPipBufferReuseStrategy()
void GetStats(int *, int *, int *)
Get some rendering statistics.
void DisplayBlackFrame(void)
Display a black video frame.
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.
int64_t GetOutputPtsMs(void)
Get the output PTS in milliseconds.
void SetPipActive(bool on)
void ClearPipDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
cQueue< cDrmBuffer > * GetPipOutputBuffer(void)
void SetStillpicture(bool active)
void SchedulePlaybackStartAtPtsMs(int64_t ptsMs)
int64_t GetVideoClock(void)
void SetScheduleAudioResume(bool resume)
void SetDisplayOneFrameThenPause(bool pause)
void SetPipSize(bool)
Set the size and position of the pip window.
void SetPlaybackPaused(bool pause)
void ResetFrameCounter(void)
Send start condition to video thread.
int Init(void)
Initialize the renderer.
bool CanHandleMode(sDrmMode *)
Wrapper to check, if drm can handle the display mode.
void SetTrickSpeed(double, bool, bool)
Set the trickspeed parameters.
void ResetPipDecodingStrategy()
cQueue< cDrmBuffer > * GetMainOutputBuffer(void)
void GetVideoSize(int *, int *, double *)
Get video size and aspect ratio.
bool Drain(void)
Drains the video stream by finalizing any pending data.
bool BuffersEmpty(void)
Return true, if the input AVPacket, videofilter and drm output buffer queues are empty.
void Open(AVCodecID, AVCodecParameters *=nullptr, AVRational={ .num=1,.den=PTSTICKS })
Open a video codec.
void SetDecoderFallbackToSwNumPkts(int numPackets)
void StartDecoder()
Start the decoder.
void ClearVdrCoreToDecoderQueue(void)
Clears all video stream data, which is buffered to be decoded.
int GetVideoPacketMax(void)
size_t GetAvPacketsFilled(void)
void DisableDeint(bool disable)
void CloseDecoder(void)
Close the decoder.
void Exit(void)
Exit video stream.
void CancelFilterThread(void)
Stop filter thread.
void FlushDecoder(void)
Flush the decoder.
bool PushAvPacket(AVPacket *avpkt)
Pushes a pre-assembled AVPacket directly to the processing queue.
bool IsInputBufferFull(void)
void ResetFilterThreadNeededCheck()
int64_t GetInputPtsMs(void)
virtual void SetDeinterlacerDeactivated(bool deactivate)
void ResetTrickSpeedFramesSentCounter(void)
Audio Decoder Header File.
Plugin Configuration Header File.
Output Device Header File.
__attribute__((weak)) union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo
Grabbing Interface Header File.
std::variant< PlayEvent, PauseEvent, StopEvent, TrickSpeedEvent, StillPictureEvent, DetachEvent, AttachEvent, BufferUnderrunEvent, BufferingThresholdReachedEvent, ScheduleResyncAtPtsMsEvent, ResyncEvent, DisplayChangeEvent > Event
ChannelSwitchMode
Channel switch modes.
static void PrintStreamData(const uchar *payload)
Print the start code, stream id, length, first three bytes (start code) of the payload,...
@ CONFIG_DISPLAY_MODE_DEFAULT
@ CONFIG_DISPLAY_MODE_FOLLOW_VIDEO_INTERLACED
@ CONFIG_DISPLAY_MODE_FOLLOW_VIDEO
@ CONFIG_DISPLAY_MODE_MANUAL
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
#define LOGDEBUG
log to LOG_DEBUG
#define LOGERROR
log to LOG_ERR
static const char * Timestamp2StringMs(int64_t ts)
Input PTS is in ms.
#define LOGWARNING
log to LOG_WARN
#define LOGGER
shortcut to the logger
#define LOGFATAL
log to LOG_ERR and abort
@ L_AV_SYNC
audio/video sync logs
Describes a hardware device.
Jitter Tracking of Incoming Packets Header File.
OSD Provider Header File.
PES Packet Parser Header File.
PiP (Picture-in-Picture) Interface Header File.
Device State Machine and Event Handler Header File.
Holds possible display configurations.
bool interlaced
is this an interlaced mode?
double refreshRateHz
display refresh rate
Video Renderer (Display) Header File.
Video Input Stream Header File.