MythTV  master
mythvideoout.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "osd.h"
3 #include "mythplayer.h"
4 #include "mythvideoprofile.h"
5 #include "decoderbase.h"
6 #include "mythcorecontext.h"
7 #include "mythlogging.h"
8 #include "mythmainwindow.h"
9 #include "mythuihelper.h"
10 #include "mythavutil.h"
11 #include "mthreadpool.h"
12 #include "mythcodeccontext.h"
13 #include "mythvideooutnull.h"
14 #include "mythvideooutgpu.h"
15 #include "mythvideoout.h"
16 
17 // std
18 #include <cmath>
19 #include <cstdlib>
20 
21 #define LOC QString("VideoOutput: ")
22 
24 {
26  MythVideoOutputGPU::GetRenderOptions(Options, Render);
27 }
28 
99 {
100  m_dbLetterboxColour = static_cast<LetterBoxColour>(gCoreContext->GetNumSetting("LetterboxColour", 0));
102 }
103 
109 bool MythVideoOutput::Init(const QSize VideoDim, const QSize VideoDispDim,
110  float VideoAspect, const QRect WindowRect, MythCodecID CodecID)
111 {
112  m_videoCodecID = CodecID;
113  bool wasembedding = IsEmbedding();
114  QRect oldrect;
115  if (wasembedding)
116  {
117  oldrect = GetEmbeddingRect();
118  EmbedPlayback(false, {});
119  }
120 
121  bool mainSuccess = InitBounds(VideoDim, VideoDispDim, VideoAspect, WindowRect);
122 
123  if (m_videoProfile)
124  m_videoProfile->SetInput(GetVideoDispDim());
125 
126  if (wasembedding)
127  EmbedPlayback(true, oldrect);
128 
129  VideoAspectRatioChanged(VideoAspect); // apply aspect ratio and letterbox mode
130 
131  return mainSuccess;
132 }
133 
134 void MythVideoOutput::SetVideoFrameRate(float VideoFrameRate)
135 {
136  if (m_videoProfile)
137  m_videoProfile->SetOutput(VideoFrameRate);
138 }
139 
140 void MythVideoOutput::SetDeinterlacing(bool Enable, bool DoubleRate, MythDeintType Force /*=DEINT_NONE*/)
141 {
142 
143 
144  if (!Enable)
145  {
146  m_deinterlacing = false;
147  m_deinterlacing2X = false;
150  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled all deinterlacing");
151  return;
152  }
153 
154  m_deinterlacing = Enable;
155  m_deinterlacing2X = DoubleRate;
156  m_forcedDeinterlacer = Force;
157 
158  MythDeintType singlerate = DEINT_NONE;
159  MythDeintType doublerate = DEINT_NONE;
160  if (DEINT_NONE != Force)
161  {
162  singlerate = Force;
163  if (DoubleRate)
164  doublerate = Force;
165  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Overriding deinterlacers");
166  }
167  else if (m_videoProfile)
168  {
169  singlerate = MythVideoFrame::ParseDeinterlacer(m_videoProfile->GetSingleRatePreferences());
170  if (DoubleRate)
171  doublerate = MythVideoFrame::ParseDeinterlacer(m_videoProfile->GetDoubleRatePreferences());
172  }
173 
174  LOG(VB_GENERAL, LOG_INFO, LOC + QString("SetDeinterlacing (Doublerate %1): Single %2 Double %3")
175  .arg(QString::number(DoubleRate),
177  MythVideoFrame::DeinterlacerPref(doublerate)));
178  m_videoBuffers.SetDeinterlacing(singlerate, doublerate, m_videoCodecID);
179 }
180 
186 bool MythVideoOutput::InputChanged(const QSize VideoDim, const QSize VideoDispDim,
187  float VideoAspect, MythCodecID CodecID,
188  bool& /*AspectOnly*/, int ReferenceFrames, bool /*ForceChange*/)
189 {
190  SourceChanged(VideoDim, VideoDispDim, VideoAspect);
191  m_maxReferenceFrames = ReferenceFrames;
192  AVCodecID avCodecId = myth2av_codecid(CodecID);
193  AVCodec* codec = avcodec_find_decoder(avCodecId);
194  QString codecName;
195  if (codec)
196  codecName = codec->name;
197  if (m_videoProfile)
198  m_videoProfile->SetInput(GetVideoDispDim(), 0 ,codecName);
199  m_videoCodecID = CodecID;
200  DiscardFrames(true, true);
201  // Update deinterlacers for any input change
203  return true;
204 }
205 
206 void MythVideoOutput::GetOSDBounds(QRect& Total, QRect& Visible,
207  float& VisibleAspect,
208  float& FontScaling,
209  float ThemeAspect) const
210 {
211  Total = GetDisplayVisibleRect();
212  Visible = GetVisibleOSDBounds(VisibleAspect, FontScaling, ThemeAspect);
213 }
214 
221 QRect MythVideoOutput::GetVisibleOSDBounds(float& VisibleAspect,
222  float& FontScaling,
223  float ThemeAspect) const
224 {
225  QRect dvr = GetDisplayVisibleRect();
226  float dispPixelAdj = 1.0F;
227  if (dvr.height() && dvr.width())
228  dispPixelAdj = (GetDisplayAspect() * dvr.height()) / dvr.width();
229 
230  float ova = GetOverridenVideoAspect();
231  QRect vr = GetVideoRect();
232  float vs = vr.height() ? static_cast<float>(vr.width()) / vr.height() : 1.0F;
233  VisibleAspect = ThemeAspect * (ova > 0.0F ? vs / ova : 1.F) * dispPixelAdj;
234 
235  FontScaling = 1.0F;
236  return { QPoint(0,0), dvr.size() };
237 }
238 
240 {
242 }
243 
244 void MythVideoOutput::SetFramesPlayed(long long FramesPlayed)
245 {
246  m_framesPlayed = FramesPlayed;
247 }
248 
250 {
251  return m_framesPlayed;
252 }
253 
255 {
256  return m_errorState != kError_None;
257 }
258 
260 {
261  return m_errorState;
262 }
263 
266 {
268 }
269 
272 {
274 }
275 
278 {
279  return static_cast<int>(m_videoBuffers.ValidVideoFrames());
280 }
281 
284 {
285  return static_cast<int>(m_videoBuffers.FreeVideoFrames());
286 }
287 
290 {
292 }
293 
297 {
299 }
300 
303 {
305 }
306 
309 {
310  return m_videoBuffers.GetStatus();
311 }
312 
316 {
318 }
319 
321 QRect MythVideoOutput::GetImageRect(const QRect Rect, QRect* DisplayRect)
322 {
323  qreal hscale = 0.0;
324  QSize video_size = GetVideoDispDim();
325  int image_height = video_size.height();
326  int image_width = (image_height > 720) ? 1920 :
327  (image_height > 576) ? 1280 : 720;
328  qreal image_aspect = static_cast<qreal>(image_width) / image_height;
329  qreal pixel_aspect = static_cast<qreal>(video_size.width()) / video_size.height();
330 
331  QRect rect1 = Rect;
332  if (DisplayRect && DisplayRect->isValid())
333  {
334  QTransform m0;
335  m0.scale(static_cast<qreal>(image_width) / DisplayRect->width(),
336  static_cast<qreal>(image_height) / DisplayRect->height());
337  rect1 = m0.mapRect(rect1);
338  rect1.translate(DisplayRect->left(), DisplayRect->top());
339  }
340  QRect result = rect1;
341 
342  QRect dvr_rec = GetDisplayVideoRect();
343  QRect vid_rec = GetVideoRect();
344 
345  hscale = image_aspect / pixel_aspect;
346  if (hscale < 0.99 || hscale > 1.01)
347  {
348  vid_rec.setLeft(static_cast<int>(lround(static_cast<qreal>(vid_rec.left()) * hscale)));
349  vid_rec.setWidth(static_cast<int>(lround(static_cast<qreal>(vid_rec.width()) * hscale)));
350  }
351 
352  qreal vscale = static_cast<qreal>(dvr_rec.width()) / image_width;
353  hscale = static_cast<qreal>(dvr_rec.height()) / image_height;
354  QTransform m1;
355  m1.translate(dvr_rec.left(), dvr_rec.top());
356  m1.scale(vscale, hscale);
357 
358  vscale = static_cast<qreal>(image_width) / vid_rec.width();
359  hscale = static_cast<qreal>(image_height) / vid_rec.height();
360  QTransform m2;
361  m2.scale(vscale, hscale);
362  m2.translate(-vid_rec.left(), -vid_rec.top());
363 
364  result = m2.mapRect(result);
365  result = m1.mapRect(result);
366  return result;
367 }
368 
376 {
377  static constexpr float kSafeMargin = 0.05F;
378  float dummy = NAN;
379  QRect result = GetVisibleOSDBounds(dummy, dummy, 1.0F);
380  int safex = static_cast<int>(static_cast<float>(result.width()) * kSafeMargin);
381  int safey = static_cast<int>(static_cast<float>(result.height()) * kSafeMargin);
382  return { result.left() + safex, result.top() + safey,
383  result.width() - (2 * safex), result.height() - (2 * safey) };
384 }
385 
390 {
392 }
393 
397 {
399 }
400 
403 {
405 }
406 
410 {
412 }
413 
417 {
419 }
420 
424 {
426 }
427 
430 void MythVideoOutput::DiscardFrames(bool KeyFrame, bool /*Flushed*/)
431 {
432  m_videoBuffers.DiscardFrames(KeyFrame);
433 }
MythVideoOutput::GetOSDBounds
virtual void GetOSDBounds(QRect &Total, QRect &Visible, float &VisibleAspect, float &FontScaling, float ThemeAspect) const
Definition: mythvideoout.cpp:206
VideoBuffers::ValidVideoFrames
uint ValidVideoFrames(void) const
Definition: videobuffers.cpp:769
MythVideoBounds::IsEmbedding
bool IsEmbedding(void) const
Definition: mythvideobounds.h:68
VideoBuffers::ReleaseFrame
void ReleaseFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:360
MythVideoOutput::m_dbLetterboxColour
LetterBoxColour m_dbLetterboxColour
Definition: mythvideoout.h:95
MythVideoOutput::InputChanged
virtual bool InputChanged(QSize VideoDim, QSize VideoDispDim, float VideoAspect, MythCodecID CodecID, bool &AspectChanged, int ReferenceFrames, bool ForceChange)
Tells video output to discard decoded frames and wait for new ones.
Definition: mythvideoout.cpp:186
PictureAttributeSupported
PictureAttributeSupported
Definition: videoouttypes.h:116
mythvideoout.h
MythVideoBounds::VideoAspectRatioChanged
void VideoAspectRatioChanged(float Aspect)
Calls SetVideoAspectRatio(float aspect), then calls MoveResize() to apply changes.
Definition: mythvideobounds.cpp:512
MythVideoFrame::ParseDeinterlacer
static MythDeintType ParseDeinterlacer(const QString &Deinterlacer)
Definition: mythframe.cpp:544
MythVideoBounds::EmbedPlayback
virtual void EmbedPlayback(bool Embed, QRect Rect)
Definition: mythvideobounds.cpp:683
MythVideoOutput::FreeVideoFrames
int FreeVideoFrames()
Returns number of frames available for decoding onto.
Definition: mythvideoout.cpp:283
MythVideoOutput::GetError
VideoErrorState GetError() const
Definition: mythvideoout.cpp:259
VideoBuffers::GetNextFreeFrame
MythVideoFrame * GetNextFreeFrame(BufferType EnqueueTo=kVideoBuffer_limbo)
Gets a frame from available buffers list.
Definition: videobuffers.cpp:319
MythVideoOutput::m_framesPlayed
long long m_framesPlayed
Definition: mythvideoout.h:103
kError_None
@ kError_None
Definition: videoouttypes.h:184
MythVideoBounds::GetDisplayVisibleRect
QRect GetDisplayVisibleRect(void) const
Definition: mythvideobounds.h:73
MythVideoOutput::m_errorState
VideoErrorState m_errorState
Definition: mythvideoout.h:102
Frame
Definition: zmdefines.h:93
VideoBuffers::EnoughDecodedFrames
bool EnoughDecodedFrames(void) const
Definition: videobuffers.cpp:784
MythVideoBounds::GetDisplayAspect
float GetDisplayAspect(void) const
Definition: mythvideobounds.h:82
VideoErrorState
VideoErrorState
Definition: videoouttypes.h:182
DEINT_NONE
@ DEINT_NONE
Definition: mythframe.h:69
VideoBuffers::SetDeinterlacing
void SetDeinterlacing(MythDeintType Single, MythDeintType Double, MythCodecID CodecID)
Definition: videobuffers.cpp:199
osd.h
MythVideoOutput::m_forcedDeinterlacer
MythDeintType m_forcedDeinterlacer
Definition: mythvideoout.h:109
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
mythplayer.h
MythVideoOutput::SetFramesPlayed
virtual void SetFramesPlayed(long long FramesPlayed)
Definition: mythvideoout.cpp:244
MythVideoBounds::GetVideoRect
QRect GetVideoRect(void) const
Definition: mythvideobounds.h:76
Visible
Definition: channelsettings.cpp:391
MythVideoBounds::GetDisplayVideoRect
QRect GetDisplayVideoRect(void) const
Definition: mythvideobounds.h:77
MythVideoOutput::SetPrebuffering
void SetPrebuffering(bool Normal)
Sets whether to use a normal number of buffers or fewer buffers.
Definition: mythvideoout.cpp:265
MythVideoOutputGPU::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options, MythRender *Render)
Definition: mythvideooutgpu.cpp:20
MythCodecID
MythCodecID
Definition: mythcodecid.h:10
MythVideoOutput::Init
virtual bool Init(QSize VideoDim, QSize VideoDispDim, float VideoAspect, QRect WindowRect, MythCodecID CodecID)
Definition: mythvideoout.cpp:109
mythvideooutnull.h
mythlogging.h
RenderOptions
Definition: mythvideoprofile.h:45
MythVideoOutput::ValidVideoFrames
virtual int ValidVideoFrames() const
Returns number of frames that are fully decoded.
Definition: mythvideoout.cpp:277
MythVideoBounds::SourceChanged
void SourceChanged(QSize VideoDim, QSize VideoDispDim, float Aspect)
Update for new source video dimensions and aspect ratio.
Definition: mythvideobounds.cpp:524
MythVideoOutput::ClearAfterSeek
virtual void ClearAfterSeek()
Tells video output to toss decoded buffers due to a seek.
Definition: mythvideoout.cpp:271
MythVideoOutput::DeLimboFrame
virtual void DeLimboFrame(MythVideoFrame *Frame)
Releases a frame for reuse if it is in limbo.
Definition: mythvideoout.cpp:402
MythVideoOutput::GetFrameStatus
QString GetFrameStatus() const
Returns string with status of each frame for debugging.
Definition: mythvideoout.cpp:308
VideoBuffers::EnoughFreeFrames
bool EnoughFreeFrames(void) const
Definition: videobuffers.cpp:779
MythVideoOutput::m_videoProfile
MythVideoProfilePtr m_videoProfile
Definition: mythvideoout.h:100
mythvideooutgpu.h
MythVideoOutput::GetNextFreeFrame
virtual MythVideoFrame * GetNextFreeFrame()
Blocks until it is possible to return a frame for decoding onto.
Definition: mythvideoout.cpp:389
VideoBuffers::StartDisplayingFrame
void StartDisplayingFrame(void)
Definition: videobuffers.cpp:407
MythVideoOutput::GetImageRect
QRect GetImageRect(QRect Rect, QRect *DisplayRect=nullptr)
translates caption/dvd button rectangle into 'screen' space
Definition: mythvideoout.cpp:321
MythVideoOutput::GetFramesPlayed
virtual long long GetFramesPlayed()
Definition: mythvideoout.cpp:249
MythVideoBounds::GetEmbeddingRect
QRect GetEmbeddingRect(void) const
Definition: mythvideobounds.h:78
mythvideoprofile.h
MythVideoOutput::DiscardFrames
virtual void DiscardFrames(bool KeyFrame, bool Flushed)
Releases all frames not being actively displayed from any queue onto the queue of frames ready for de...
Definition: mythvideoout.cpp:430
MythVideoOutput::GetLastDecodedFrame
virtual MythVideoFrame * GetLastDecodedFrame()
Definition: mythvideoout.cpp:302
MythVideoOutput::m_videoCodecID
MythCodecID m_videoCodecID
Definition: mythvideoout.h:98
MythVideoBounds::GetOverridenVideoAspect
float GetOverridenVideoAspect(void) const
Definition: mythvideobounds.h:72
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
MythVideoBounds::GetVideoDispDim
QSize GetVideoDispDim(void) const
Definition: mythvideobounds.h:71
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:936
MythVideoFrame::DeinterlacerPref
static QString DeinterlacerPref(MythDeintType Deint)
Definition: mythframe.cpp:530
MythVideoOutput::EnoughFreeFrames
bool EnoughFreeFrames()
Returns true iff enough frames are available to decode onto.
Definition: mythvideoout.cpp:289
MythVideoOutput::ReleaseFrame
virtual void ReleaseFrame(MythVideoFrame *Frame)
Releases a frame from the ready for decoding queue onto the queue of frames ready for display.
Definition: mythvideoout.cpp:396
MythVideoOutput::StartDisplayingFrame
virtual void StartDisplayingFrame()
Tell GetLastShownFrame() to return the next frame from the head of the queue of frames to display.
Definition: mythvideoout.cpp:409
MythVideoOutput::IsErrored
bool IsErrored() const
Definition: mythvideoout.cpp:254
MythVideoOutputNull::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options)
Definition: mythvideooutnull.cpp:15
mthreadpool.h
LOC
#define LOC
Definition: mythvideoout.cpp:21
mythuihelper.h
VideoBuffers::GetLastShownFrame
MythVideoFrame * GetLastShownFrame(void)
Definition: videobuffers.cpp:764
MythDeintType
MythDeintType
Definition: mythframe.h:67
MythVideoOutput::DiscardFrame
virtual void DiscardFrame(MythVideoFrame *Frame)
Releases frame from any queue onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:423
myth2av_codecid
AVCodecID myth2av_codecid(MythCodecID codec_id)
Definition: mythcodecid.cpp:228
VideoBuffers::DiscardFrame
void DiscardFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:450
mythcorecontext.h
MythVideoOutput::GetSupportedPictureAttributes
PictureAttributeSupported GetSupportedPictureAttributes()
Definition: mythvideoout.cpp:239
MythRender
Definition: mythrender_base.h:23
kLetterBoxColour_Gray25
@ kLetterBoxColour_Gray25
Definition: videoouttypes.h:90
LetterBoxColour
LetterBoxColour
Definition: videoouttypes.h:86
MythVideoOutput::m_clearColor
uint8_t m_clearColor
Definition: mythvideoout.h:96
VideoBuffers::GetLastDecodedFrame
MythVideoFrame * GetLastDecodedFrame(void)
Definition: videobuffers.cpp:759
mythavutil.h
MythVideoOutput::MythVideoOutput
MythVideoOutput()
Definition: mythvideoout.cpp:98
VideoBuffers::SetPrebuffering
void SetPrebuffering(bool Normal)
Definition: videobuffers.cpp:281
MythVideoOutput::GetSafeRect
QRect GetSafeRect()
Returns a QRect describing an area of the screen on which it is 'safe' to render the On Screen Displa...
Definition: mythvideoout.cpp:375
VideoBuffers::ClearAfterSeek
void ClearAfterSeek(void)
Clear used frames after seeking.
Definition: videobuffers.cpp:895
VideoBuffers::DoneDisplayingFrame
void DoneDisplayingFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:417
decoderbase.h
MythVideoBounds::InitBounds
bool InitBounds(QSize VideoDim, QSize VideoDispDim, float Aspect, QRect WindowRect)
Definition: mythvideobounds.cpp:451
VideoBuffers::FreeVideoFrames
uint FreeVideoFrames(void) const
Definition: videobuffers.cpp:774
mythcodeccontext.h
MythVideoOutput::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options, MythRender *Render)
Definition: mythvideoout.cpp:23
MythVideoOutput::SetDeinterlacing
virtual void SetDeinterlacing(bool Enable, bool DoubleRate, MythDeintType Force=DEINT_NONE)
Definition: mythvideoout.cpp:140
MythVideoFrame
Definition: mythframe.h:88
VideoBuffers::DiscardFrames
void DiscardFrames(bool NextFrameIsKeyFrame)
Definition: videobuffers.cpp:808
VideoBuffers::DeLimboFrame
void DeLimboFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:377
MythVideoOutput::EnoughDecodedFrames
bool EnoughDecodedFrames()
Returns true iff there are plenty of decoded frames ready for display.
Definition: mythvideoout.cpp:296
MythVideoOutput::GetLastShownFrame
virtual MythVideoFrame * GetLastShownFrame()
Returns frame from the head of the ready to be displayed queue, if StartDisplayingFrame has been call...
Definition: mythvideoout.cpp:315
MythVideoColourSpace::SupportedAttributes
PictureAttributeSupported SupportedAttributes(void) const
Definition: mythvideocolourspace.cpp:101
MythVideoOutput::m_maxReferenceFrames
int m_maxReferenceFrames
Definition: mythvideoout.h:99
mythmainwindow.h
VideoBuffers::GetStatus
QString GetStatus(uint Num=0) const
Definition: videobuffers.cpp:1011
MythVideoOutput::GetVisibleOSDBounds
QRect GetVisibleOSDBounds(float &VisibleAspect, float &FontScaling, float ThemeAspect) const
Returns visible portions of total OSD bounds.
Definition: mythvideoout.cpp:221
MythVideoOutput::SetVideoFrameRate
virtual void SetVideoFrameRate(float VideoFrameRate)
Definition: mythvideoout.cpp:134
MythVideoOutput::m_deinterlacing2X
bool m_deinterlacing2X
Definition: mythvideoout.h:108
MythVideoOutput::m_videoBuffers
VideoBuffers m_videoBuffers
Definition: mythvideoout.h:101
MythVideoOutput::m_videoColourSpace
MythVideoColourSpace m_videoColourSpace
Definition: mythvideoout.h:94
MythVideoOutput::m_deinterlacing
bool m_deinterlacing
Definition: mythvideoout.h:107
MythVideoOutput::DoneDisplayingFrame
virtual void DoneDisplayingFrame(MythVideoFrame *Frame)
Releases frame returned from GetLastShownFrame() onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:416