48#include <drm_fourcc.h>
53#include <libavcodec/avcodec.h>
54#include <libavutil/hwcontext_drm.h>
55#include <libavutil/pixdesc.h>
56#include <libavfilter/buffersink.h>
57#include <libavfilter/buffersrc.h>
58#include <libavutil/opt.h>
100 m_disableOglOsd =
m_pConfig->ConfigDisableOglOsd;
164 if (!frame || dispWidth == 0 || dispHeight == 0)
165 return { dispX, dispY, dispWidth, dispHeight };
167 double frameWidth = frame->width > 0 ? frame->width : 1.0;
168 double frameHeight = frame->height > 0 ? frame->height : 1.0;
169 double frameSar = av_q2d(frame->sample_aspect_ratio) ? av_q2d(frame->sample_aspect_ratio) : 1.0;
170 double dispAspect =
static_cast<double>(dispWidth) /
static_cast<double>(dispHeight);
171 double frameAspect = frameWidth / frameHeight * frameSar;
173 double picWidthD = dispWidth;
174 double picHeightD = dispHeight;
176 if (dispAspect > frameAspect) {
178 picWidthD = dispHeight * frameAspect;
179 if (picWidthD <= 0 || picWidthD > dispWidth)
180 picWidthD = dispWidth;
183 picHeightD = dispWidth / frameAspect;
184 if (picHeightD <= 0 || picHeightD > dispHeight)
185 picHeightD = dispHeight;
189 uint64_t picWidth = std::llround(std::max(0.0, picWidthD));
190 uint64_t picHeight = std::llround(std::max(0.0, picHeightD));
192 int64_t offsetX =
static_cast<int64_t
>(dispWidth) -
static_cast<int64_t
>(picWidth);
193 int64_t offsetY =
static_cast<int64_t
>(dispHeight) -
static_cast<int64_t
>(picHeight);
194 uint64_t posX = dispX +
static_cast<uint64_t
>(std::max<int64_t>(0, offsetX / 2));
195 uint64_t posY = dispY +
static_cast<uint64_t
>(std::max<int64_t>(0, offsetY / 2));
197 return { posX, posY, picWidth, picHeight };
207 AVFrame *frame = buf ? buf->
frame :
nullptr;
230 fittedRect.
x, fittedRect.
y, fittedRect.
w, fittedRect.
h,
256 LOGDEBUG2(
L_DRM,
"videorender: %s: SetPlaneZpos: video->plane_id %d -> zpos %" PRIu64
", osd->plane_id %d -> zpos %" PRIu64
"", __FUNCTION__,
283 AVFrame *frame = buf ? buf->
frame :
nullptr;
305 int64_t centerOffsetX =
static_cast<int64_t
>(dispWidth) -
static_cast<int64_t
>(fittedRect.
w);
306 int64_t centerOffsetY =
static_cast<int64_t
>(dispHeight) -
static_cast<int64_t
>(fittedRect.
h);
307 centerOffsetX = std::max<int64_t>(0, centerOffsetX / 2);
308 centerOffsetY = std::max<int64_t>(0, centerOffsetY / 2);
312 uint64_t crtcW = std::llround(crtcWD);
313 uint64_t crtcH = std::llround(crtcHD);
315 double spaceW = dispWidth - crtcW - centerOffsetX;
316 double spaceH = dispHeight - crtcH - centerOffsetY;
323 crtcX, crtcY, crtcW, crtcH,
340 LOGDEBUG2(
L_GRAB,
"videorender: %s: Trigger osd grab arrived", __FUNCTION__);
349 LOGDEBUG2(
L_GRAB,
"videorender: %s: Trigger video grab arrived", __FUNCTION__);
358 LOGDEBUG2(
L_GRAB,
"videorender: %s: Trigger pip grab arrived", __FUNCTION__);
379 MODESET_OSD = (1 << 0),
380 MODESET_VIDEO = (1 << 1),
381 MODESET_PIP = (1 << 2)
389 drmModeAtomicReqPtr modeReq;
390 uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT;
392 if (!(modeReq = drmModeAtomicAlloc())) {
393 LOGERROR(
"videorender: %s: cannot allocate atomic request (%d): %m", __FUNCTION__, errno);
401 modeSet |= MODESET_VIDEO;
409 modeSet |= MODESET_VIDEO;
416 modeSet |= MODESET_PIP;
420 modeSet |= MODESET_PIP;
423 modeSet |= MODESET_PIP;
429 modeSet |= MODESET_OSD;
439 drmModeAtomicFree(modeReq);
444 if (drmModeAtomicCommit(fdDrm, modeReq, flags, NULL) != 0) {
445 if (modeSet & MODESET_OSD)
447 if (modeSet & MODESET_VIDEO)
449 if (modeSet & MODESET_PIP)
452 drmModeAtomicFree(modeReq);
453 LOGERROR(
"videorender: %s: page flip failed (%d): %m", __FUNCTION__, errno);
457 drmModeAtomicFree(modeReq);
471 LOGDEBUG2(
L_AV_SYNC,
"Frame %s (drop %d, dup %d) Pkts %d Frames %d UsedBytes %d audio %s video %s Delay %dms diff %dms",
472 audioBehindVideoByMs > 0 ?
"duped" :
"dropped",
481 audioBehindVideoByMs);
483 if (audioBehindVideoByMs > 0)
499 if (!frame || !frame->opaque_ref)
502 int *frameFlags = (
int *)frame->opaque_ref->data;
515 if (!frame->opaque_ref) {
516 frame->opaque_ref = av_buffer_allocz(
sizeof(*frameFlags));
517 if (!frame->opaque_ref) {
518 LOGFATAL(
"videorender: %s: cannot allocate private frame data", __FUNCTION__);
522 frameFlags = (
int *)frame->opaque_ref->data;
537 if (buf && buf->
frame)
538 av_frame_free(&buf->
frame);
539 if (pipBuf && pipBuf->
frame)
540 av_frame_free(&pipBuf->
frame);
545 LOGERROR(
"threads: display thread: drmHandleEvent failed!");
548 if (buf && buf->
frame) {
581 bool pageFlipDone =
false;
634 pageFlipDone =
PageFlip(drmBuffer, pipBuf);
645 pageFlipDone =
PageFlip(NULL, pipBuf);
664 LOGDEBUG2(
L_DRM,
"videorender: %s: closing, set a black FB", __FUNCTION__);
678 int64_t videoPtsMs = pts * 1000 * av_q2d(
m_timebase);
702 if (m_disableOglOsd) {
709 m_pNextBo = gbm_surface_lock_front_buffer(
m_pDrmDevice->GbmSurface());
714 LOGERROR(
"videorender: %s: Failed to get GL buffer", __FUNCTION__);
722 gbm_surface_release_buffer(
m_pDrmDevice->GbmSurface(), m_bo);
739#define MIN(a, b) ((a) < (b) ? (a) : (b))
754 int width,
int height,
int pitch,
755 const uint8_t * argb,
int x,
int y)
758 if (m_disableOglOsd) {
759 LOGDEBUG2(
L_OSD,
"videorender: %s: width %d height %d pitch %d argb %p x %d y %d pitch buf %d xi %d yi %d", __FUNCTION__,
761 for (
int i = 0; i < height; ++i) {
769 m_pNextBo = gbm_surface_lock_front_buffer(
m_pDrmDevice->GbmSurface());
774 LOGERROR(
"videorender: %s: Failed to get GL buffer", __FUNCTION__);
782 gbm_surface_release_buffer(
m_pDrmDevice->GbmSurface(), m_bo);
796 for (
int i = 0; i < height; ++i) {
798 argb + i * pitch, (
size_t)pitch);
814 LOGDEBUG(
"videorender: %s", __FUNCTION__);
824static void ReleaseFrame( __attribute__ ((unused))
void *opaque, uint8_t *data)
826 AVDRMFrameDescriptor *primedata = (AVDRMFrameDescriptor *)data;
883 buf->
Setup(drmDeviceFd, inframe->width, inframe->height, DRM_FORMAT_NV12,
nullptr,
true);
886 if (drmPrimeHandleToFD(drmDeviceFd, buf->
PrimeHandle(0), DRM_CLOEXEC | DRM_RDWR, &dmaBufHandle))
887 LOGFATAL(
"videorender: %s: Failed to retrieve the Prime FD (%d): %m", __FUNCTION__, errno);
892 for (
int i = 0; i < inframe->height; ++i)
893 memcpy(buf->
Plane(0) + i * buf->
Pitch(0), inframe->data[0] + i * inframe->linesize[0], inframe->linesize[0]);
895 for (
int i = 0; i < inframe->height / 2; ++i)
896 memcpy(buf->
Plane(1) + i * buf->
Pitch(1), inframe->data[1] + i * inframe->linesize[1], inframe->linesize[1]);
898 AVFrame *frame = av_frame_alloc();
899 frame->pts = inframe->pts;
900 frame->width = inframe->width;
901 frame->height = inframe->height;
902 frame->format = AV_PIX_FMT_DRM_PRIME;
903 frame->sample_aspect_ratio = inframe->sample_aspect_ratio;
905 frame->format = AV_PIX_FMT_DRM_PRIME;
906 AVDRMFrameDescriptor *primedata = (AVDRMFrameDescriptor *)av_mallocz(
sizeof(AVDRMFrameDescriptor));
908 frame->data[0] = (uint8_t *)primedata;
909 frame->buf[0] = av_buffer_create((uint8_t *)primedata,
sizeof(*primedata),
ReleaseFrame, NULL, AV_BUFFER_FLAG_READONLY);
911 av_frame_free(&inframe);
922 AVDRMFrameDescriptor *primedata = (AVDRMFrameDescriptor *)frame->data[0];
923 buf->
Setup(drmDeviceFd, frame->width, frame->height, 0, primedata,
false);
945 std::atomic<cBufferStrategy*> &bufferReuseStrategy,
946 std::atomic<cDecodingStrategy*> &decodingStrategy,
950 if (bufferReuseStrategy ==
nullptr) {
953 else if (frame->format == AV_PIX_FMT_DRM_PRIME)
959 if (decodingStrategy ==
nullptr) {
960 if (frame->format == AV_PIX_FMT_DRM_PRIME)
970 AVDRMFrameDescriptor *primedata = (AVDRMFrameDescriptor *)frame->data[0];
971 cDrmBuffer *buf = bufferReuseStrategy.load()->GetBuffer(drmBufferPool, primedata);
974 LOGFATAL(
"videorender: %s: no free DRM buffer found. This is a bug.", __FUNCTION__);
976 frame = decodingStrategy.load()->PrepareDrmBuffer(buf,
m_pDrmDevice->
Fd(), frame);
979 buf->SetPresentationPending(
true);
981 drmBufferQueue->
Push(buf);
1058 LOGDEBUG2(
L_TRICK,
"videorender: %s: set trick speed %d %s", __FUNCTION__, speed, forward ?
"forward" :
"backward");
1114 LOGWARNING(
"videorender: %s: timed out after %dms", __FUNCTION__, timeout);
1138 for (
int plane = 0; plane < buf->
NumPlanes(); plane++) {
1139 LOGDEBUG2(
L_GRAB,
"videorender: %s: VIDEO plane %d address %p pitch %d offset %d handle %d size %d", __FUNCTION__,
1167 for (
int plane = 0; plane < buf->
NumPlanes(); plane++) {
1168 LOGDEBUG2(
L_GRAB,
"videorender: %s: PIP plane %d address %p pitch %d offset %d handle %d size %d", __FUNCTION__,
1197 for (
int plane = 0; plane < buf->
NumPlanes(); plane++) {
1198 LOGDEBUG2(
L_GRAB,
"videorender: %s: OSD plane %d address %p pitch %d offset %d handle %d size %d", __FUNCTION__,
1247 LOGERROR(
"videorender: %s: unknown grab requested", __FUNCTION__);
1251 LOGDEBUG2(
L_GRAB,
"videorender: %s: %s size %d %dx%d at %d|%d %p", __FUNCTION__, type == 0 ?
"VIDEO" : (type == 1 ?
"OSD" :
"PIP"),
1306 LOGFATAL(
"videorender: %s: failed", __FUNCTION__);
1318 if (m_disableOglOsd) {
1327 LOGDEBUG2(
L_DRM,
"videorender: %s: Try to create a black FB", __FUNCTION__);
1334 drmModeAtomicReqPtr modeReq;
1335 const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
1336 uint32_t modeID = 0;
1339 LOGFATAL(
"videorender: %s: Failed to create mode property blob.", __FUNCTION__);
1340 if (!(modeReq = drmModeAtomicAlloc()))
1341 LOGFATAL(
"videorender: %s: cannot allocate atomic request (%d): %m", __FUNCTION__, errno);
1344 DRM_MODE_OBJECT_CRTC,
"MODE_ID", modeID);
1348 DRM_MODE_OBJECT_CRTC,
"ACTIVE", 1);
1360 if (m_disableOglOsd) {
1384 if (drmModeAtomicCommit(
m_pDrmDevice->
Fd(), modeReq, flags, NULL) != 0) {
1390 drmModeAtomicFree(modeReq);
1391 LOGFATAL(
"videorender: %s: cannot set atomic mode (%d): %m", __FUNCTION__, errno);
1394 drmModeAtomicFree(modeReq);
1420 if (m_disableOglOsd) {
1427 gbm_bo_destroy(m_pNextBo);
1429 gbm_bo_destroy(m_pOldBo);
1455 LOGDEBUG(
"videorender: %s: %d %d %d %d%s", __FUNCTION__, rect.X(), rect.Y(), rect.Width(), rect.Height(),
m_videoIsScaled ?
", video is scaled" :
"");
Audio and alsa module header file.
uint8_t * BufToRgb(cDrmBuffer *buf, int *size, int dstW, int dstH, enum AVPixelFormat dstPixFmt)
Convert a DRM buffer to rgb format image.
Some helper functions header file.
virtual void OnEventReceived(const Event &)=0
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
cDrmBuffer * GetBuffer(cDrmBufferPool *, AVDRMFrameDescriptor *) override
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
AVFrame * PrepareDrmBuffer(cDrmBuffer *, int, AVFrame *) override
cDrmBuffer * FindUninitilized(void)
cDrmBuffer * FindByDmaBufHandle(int)
cDrmBuffer * FindNoPresentationPending(void)
void DestroyAllExcept(cDrmBuffer *)
void Setup(int, uint32_t, uint32_t, uint32_t, AVDRMFrameDescriptor *, bool)
Setup the buffer.
void FillBlack(void)
Color the buffer black.
uint32_t PrimeHandle(int idx)
AVFrame * frame
associated AVFrame
void PresentationFinished(void)
void Destroy(void)
Clear and destroy the buffer object and its parameters.
void SetDmaBufHandle(uint32_t fd)
void SetDestroyAfterUse(bool val)
int CreatePropertyBlob(uint32_t *)
Creates a property blob.
int SetPropertyRequest(drmModeAtomicReqPtr, uint32_t, uint32_t, const char *, uint64_t)
Add a property to a request.
uint64_t DisplayHeight(void)
int HandleEvent(void)
Polls for a drm event.
uint64_t DisplayWidth(void)
uint64_t ZposPrimary(void)
uint64_t ZposOverlay(void)
cDrmPlane * PipPlane(void)
void SaveCrtc(void)
Saves information of a CRTC.
void RestoreCrtc(void)
Restore information of a CRTC.
void Close(void)
Close drm file handle.
cDrmPlane * OsdPlane(void)
cDrmPlane * VideoPlane(void)
uint32_t ConnectorId(void)
int Init(void)
Initiate the drm device.
void InitEvent(void)
Init the event context.
cDrmPlane - DRM plane class
void SetParams(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
Set the modesetting parameters of a plane.
void ClearPlane(drmModeAtomicReqPtr)
Clear plane from drm.
void SetZpos(uint64_t zpos)
void FreeProperties(void)
Free the previously filled plane properties.
void SetPlane(drmModeAtomicReqPtr)
Set all other plane properties.
void SetPlaneZpos(drmModeAtomicReqPtr)
Set the plane zpos property.
void DumpParameters(const char *)
Dump the plane parameter modesetting values.
void Clear(void)
Remove all elements from the queue.
T * Pop(void)
Pop an element from the back of the queue.
bool IsEmpty(void)
Check if the queue is empty.
bool IsFull(void)
Check if the queue is full.
bool Push(T *element)
Push an element to the front of the queue.
size_t Size(void)
Get the current size of the queue.
int64_t GetHardwareOutputPtsMs(void)
Get the hardware output PTS in milliseconds.
void DropSamplesOlderThanPtsMs(int64_t)
Drop samples older than the given PTS.
int GetUsedBytes(void)
Get used bytes in audio ringbuffer.
void SetPaused(bool)
Set audio playback paused state.
const char * ConfigDisplayResolution
display resolution (syntax: "1920x1080@50")
int ConfigPipAltTopPercent
0 = aligned to top, 100 = aligned to bottom
int ConfigPipLeftPercent
0 = aligned to left, 100 = aligned to right
int ConfigPipAltLeftPercent
0 = aligned to left, 100 = aligned to right
int ConfigPipAltScalePercent
alternative scale factor of pip video
int ConfigPipTopPercent
0 = aligned to top, 100 = aligned to bottom
int ConfigPipScalePercent
scale factor of pip video
int GetVideoAudioDelayMs(void)
bool IsBufferingThresholdReached(void)
Check if the buffering threshold has been reached.
cVideoStream * VideoStream(void)
cSoftHdConfig * Config(void)
void SetScreenSize(int, int, uint32_t)
Set the screen size.
cSoftHdAudio * Audio(void)
cSoftHdGrab - Grabber class
void SetBuf(cDrmBuffer *buf)
cDrmBuffer * GetBuf(void)
void SetRect(int x, int y, int width, int height)
void FreeBuf(void)
Free the grab buffer.
void SetData(uint8_t *result)
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
void SetScreenSize(int, int, uint32_t)
Wrapper to set the screen size in the device.
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
void ConvertPipBufToRgb(void)
Convert the pip drm buffer to an rgb image.
std::atomic< bool > m_resumeAudioScheduled
set, if audio resume is scheduled after a pause
void ConvertVideoBufToRgb(void)
Convert the video drm buffer to an rgb image.
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
cDrmBufferPool m_pipDrmBufferPool
PIP pool of drm buffers.
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
int64_t m_pts
current video PTS
cSoftHdGrab * GetGrab(int *, int *, int *, int *, int *, int)
Get the grabbed image.
int m_trickSpeed
current trick speed
cSoftHdGrab m_grabVideo
keeps the current grabbed video
int SetOsdBuffer(drmModeAtomicReqPtr)
Modesetting for osd.
void ClearDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
void Init(void)
Initialize the renderer.
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.
cMutex m_trickspeedMutex
mutex used while accessing trickspeed parameters
cQueue< cDrmBuffer > m_drmBufferQueue
queue for DRM buffers to be displayed (VIDEO_SURFACES_MAX is defined in thread.h)
cRect m_lastVideoGrab
crtc rect of the last shown video frame
virtual ~cVideoRender(void)
cVideoRender destructor
cRect m_videoRect
rect of the currently displayed video
bool m_startgrab
internal flag to trigger grabbing
void GetStats(int *, int *, int *)
Get some rendering statistics.
std::atomic< cDecodingStrategy * > m_pipDecodingStrategy
strategy for decoding setup
void SetTrickSpeed(int, int)
Set the trickspeed parameters.
std::atomic< cBufferStrategy * > m_bufferReuseStrategy
strategy to select drm buffers
void DisplayBlackFrame(void)
void SetVideoClock(int64_t)
Wrapper to set the video clock (m_pts)
cSoftHdAudio * m_pAudio
pointer to cSoftHdAudio
AVRational m_timebase
timebase used for pts, set by first RenderFrame()
void PushMainFrame(AVFrame *)
void SetVideoOutputPosition(const cRect &)
Set size and position of the video on the screen.
cVideoRender(cSoftHdDevice *)
cVideoRender constructor
int GetFrameFlags(AVFrame *)
Get frame flags.
int m_pipTopPercent
top margin for pip
cDrmBuffer * m_pBufOsd
pointer to osd drm buffer object
int64_t GetOutputPtsMs(void)
Get the output PTS in milliseconds.
cSoftHdDevice * m_pDevice
pointer to cSoftHdDevice
int m_framePresentationCounter
number of times the current frame has to be shown (for slow motion)
std::atomic< cBufferStrategy * > m_pipBufferReuseStrategy
strategy to select drm buffers
cSoftHdConfig * m_pConfig
pointer to cSoftHdConfig
void ClearPipDecoderToDisplayQueue(void)
Clear (empty) the decoder to display queue.
void ClearGrab(void)
Clear the grab drm buffers.
cSoftHdGrab m_grabOsd
keeps the current grabbed osd
int CommitBuffer(cDrmBuffer *, cDrmBuffer *)
Commit the frame to the hardware.
int TriggerGrab(void)
Trigger a screen grab.
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....
cRect m_lastPipGrab
crtc rect of the last shown pip frame
void LogDroppedDuped(int64_t, int64_t, int)
Log A/V sync debug message.
void SetPipBuffer(cDrmBuffer *)
Modesetting for pip.
bool DisplayFrame()
Display the frame (video and/or osd)
void ConvertOsdBufToRgb(void)
Convert the osd drm buffer to an rgb image.
void SetVideoBuffer(cDrmBuffer *)
Modesetting for video.
cDrmBuffer * m_pCurrentlyPipDisplayed
pointer to currently displayed DRM buffer
int64_t GetVideoClock(void)
Wrapper to get the video clock (m_pts)
int GetTrickForward(void)
Get the current trickspeed direction.
void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD ARGB image.
cDrmDevice * m_pDrmDevice
pointer cDrmDevice object
void Grab(cDrmBuffer *, cDrmBuffer *)
Grab video and osd.
cMutex m_timebaseMutex
mutex used around m_timebase
cMutex m_videoClockMutex
mutex used around m_pts
std::atomic< cDecodingStrategy * > m_decodingStrategy
strategy for decoding setup
int GetTrickSpeed(void)
Get the current trickspeed.
bool m_lastFrameWasDropped
true, if the last frame was dropped
bool PageFlip(cDrmBuffer *, cDrmBuffer *)
Do the pageflip.
int m_pipLeftPercent
left margin for pip
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 ResetFrameCounter(void)
Send start condition to video thread.
int m_startCounter
counter for displayed frames, indicates a video start
bool m_trickForward
true, if trickspeed plays forward
bool m_videoIsScaled
true, if the currently displayed video is scaled
void ExitDisplayThread(void)
Stop display thread.
cDrmBuffer m_bufBlack
black drm buffer object
cSoftHdGrab m_grabPip
keeps the current grabbed pip video
size_t GetAvPacketsFilled(void)
std::variant< PlayEvent, PauseEvent, StopEvent, TrickSpeedEvent, StillPictureEvent, DetachEvent, AttachEvent, BufferUnderrunEvent, BufferingThresholdReachedEvent, PipEvent > Event
Logger class header file.
#define LOGFATAL
Logger macros.
Misc function header file.
static const char * Timestamp2String(int64_t ts, uint8_t divisor)
Workaround for av_err2str() not working with C++.
Thread classes header file.
static void ReleaseFrame(__attribute__((unused)) void *opaque, uint8_t *data)
Callback free primedata if av_buffer is unreferenced.
static sRect ComputeFittedRect(AVFrame *frame, uint64_t dispX, uint64_t dispY, uint64_t dispWidth, uint64_t dispHeight)
Fits the video frame into a given area.
Rendering class header file.
#define AV_SYNC_THRESHOLD_AUDIO_BEHIND_VIDEO_MS
threshold in ms, when to duplicate video frames to keep audio and video in sync
#define AV_SYNC_THRESHOLD_AUDIO_AHEAD_VIDEO_MS
threshold in ms, when to drop video frames to keep audio and video in sync