MythTV  master
mythvideoout.cpp
Go to the documentation of this file.
1 // std
2 #include <cmath>
3 #include <cstdlib>
4 
5 // MythTV
10 #include "libmythui/mythuihelper.h"
11 
12 #include "decoders/decoderbase.h"
14 #include "mythavutil.h"
15 #include "mythplayer.h"
16 #include "mythvideoout.h"
17 #include "mythvideooutgpu.h"
18 #include "mythvideooutnull.h"
19 #include "mythvideoprofile.h"
20 #include "osd.h"
21 
22 #define LOC QString("VideoOutput: ")
23 
25 {
27  MythVideoOutputGPU::GetRenderOptions(Options, Render);
28 }
29 
100  m_dbLetterboxColour(static_cast<LetterBoxColour>(gCoreContext->GetNumSetting("LetterboxColour", 0)))
101 {
103 }
104 
110 bool MythVideoOutput::Init(const QSize VideoDim, const QSize VideoDispDim,
111  float VideoAspect, const QRect WindowRect, MythCodecID CodecID)
112 {
113  m_videoCodecID = CodecID;
114  bool wasembedding = IsEmbedding();
115  QRect oldrect;
116  if (wasembedding)
117  {
118  oldrect = GetEmbeddingRect();
119  EmbedPlayback(false, {});
120  }
121 
122  bool mainSuccess = InitBounds(VideoDim, VideoDispDim, VideoAspect, WindowRect);
123 
124  if (m_videoProfile)
125  m_videoProfile->SetInput(GetVideoDispDim());
126 
127  if (wasembedding)
128  EmbedPlayback(true, oldrect);
129 
130  VideoAspectRatioChanged(VideoAspect); // apply aspect ratio and letterbox mode
131 
132  return mainSuccess;
133 }
134 
135 void MythVideoOutput::SetVideoFrameRate(float VideoFrameRate)
136 {
137  if (m_videoProfile)
138  m_videoProfile->SetOutput(VideoFrameRate);
139 }
140 
141 void MythVideoOutput::SetDeinterlacing(bool Enable, bool DoubleRate, MythDeintType Force /*=DEINT_NONE*/)
142 {
143 
144 
145  if (!Enable)
146  {
147  m_deinterlacing = false;
148  m_deinterlacing2X = false;
151  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Disabled all deinterlacing");
152  return;
153  }
154 
155  m_deinterlacing = Enable;
156  m_deinterlacing2X = DoubleRate;
157  m_forcedDeinterlacer = Force;
158 
159  MythDeintType singlerate = DEINT_NONE;
160  MythDeintType doublerate = DEINT_NONE;
161  if (DEINT_NONE != Force)
162  {
163  singlerate = Force;
164  if (DoubleRate)
165  doublerate = Force;
166  LOG(VB_PLAYBACK, LOG_INFO, LOC + "Overriding deinterlacers");
167  }
168  else if (m_videoProfile)
169  {
170  singlerate = MythVideoFrame::ParseDeinterlacer(m_videoProfile->GetSingleRatePreferences());
171  if (DoubleRate)
172  doublerate = MythVideoFrame::ParseDeinterlacer(m_videoProfile->GetDoubleRatePreferences());
173  }
174 
175  LOG(VB_GENERAL, LOG_INFO, LOC + QString("SetDeinterlacing (Doublerate %1): Single %2 Double %3")
176  .arg(QString::number(DoubleRate),
178  MythVideoFrame::DeinterlacerPref(doublerate)));
179  m_videoBuffers.SetDeinterlacing(singlerate, doublerate, m_videoCodecID);
180 }
181 
187 bool MythVideoOutput::InputChanged(const QSize VideoDim, const QSize VideoDispDim,
188  float VideoAspect, MythCodecID CodecID,
189  bool& /*AspectOnly*/, int ReferenceFrames, bool /*ForceChange*/)
190 {
191  SourceChanged(VideoDim, VideoDispDim, VideoAspect);
192  m_maxReferenceFrames = ReferenceFrames;
193  AVCodecID avCodecId = myth2av_codecid(CodecID);
194  const AVCodec* codec = avcodec_find_decoder(avCodecId);
195  QString codecName;
196  if (codec)
197  codecName = codec->name;
198  if (m_videoProfile)
199  m_videoProfile->SetInput(GetVideoDispDim(), 0 ,codecName);
200  m_videoCodecID = CodecID;
201  DiscardFrames(true, true);
202  // Update deinterlacers for any input change
204  return true;
205 }
206 
207 void MythVideoOutput::GetOSDBounds(QRect& Total, QRect& Visible,
208  float& VisibleAspect,
209  float& FontScaling,
210  float ThemeAspect) const
211 {
212  Total = GetDisplayVisibleRect();
213  Visible = GetVisibleOSDBounds(VisibleAspect, FontScaling, ThemeAspect);
214 }
215 
222 QRect MythVideoOutput::GetVisibleOSDBounds(float& VisibleAspect,
223  float& FontScaling,
224  float ThemeAspect) const
225 {
226  QRect dvr = GetDisplayVisibleRect();
227  float dispPixelAdj = 1.0F;
228  if (dvr.height() && dvr.width())
229  dispPixelAdj = (GetDisplayAspect() * dvr.height()) / dvr.width();
230 
231  float ova = GetOverridenVideoAspect();
232  QRect vr = GetVideoRect();
233  float vs = vr.height() ? static_cast<float>(vr.width()) / vr.height() : 1.0F;
234  VisibleAspect = ThemeAspect * (ova > 0.0F ? vs / ova : 1.F) * dispPixelAdj;
235 
236  FontScaling = 1.0F;
237  return { QPoint(0,0), dvr.size() };
238 }
239 
241 {
243 }
244 
245 void MythVideoOutput::SetFramesPlayed(long long FramesPlayed)
246 {
247  m_framesPlayed = FramesPlayed;
248 }
249 
251 {
252  return m_framesPlayed;
253 }
254 
256 {
257  return m_errorState != kError_None;
258 }
259 
261 {
262  return m_errorState;
263 }
264 
267 {
269 }
270 
273 {
275 }
276 
279 {
280  return static_cast<int>(m_videoBuffers.ValidVideoFrames());
281 }
282 
285 {
286  return static_cast<int>(m_videoBuffers.FreeVideoFrames());
287 }
288 
291 {
293 }
294 
298 {
300 }
301 
304 {
306 }
307 
310 {
311  return m_videoBuffers.GetStatus();
312 }
313 
317 {
319 }
320 
322 QRect MythVideoOutput::GetImageRect(const QRect Rect, QRect* DisplayRect)
323 {
324  qreal hscale = 0.0;
325  QSize video_size = GetVideoDispDim();
326  int image_height = video_size.height();
327  int image_width = (image_height > 720) ? 1920 :
328  (image_height > 576) ? 1280 : 720;
329  qreal image_aspect = static_cast<qreal>(image_width) / image_height;
330  qreal pixel_aspect = static_cast<qreal>(video_size.width()) / video_size.height();
331 
332  QRect rect1 = Rect;
333  if (DisplayRect && DisplayRect->isValid())
334  {
335  QTransform m0;
336  m0.scale(static_cast<qreal>(image_width) / DisplayRect->width(),
337  static_cast<qreal>(image_height) / DisplayRect->height());
338  rect1 = m0.mapRect(rect1);
339  rect1.translate(DisplayRect->left(), DisplayRect->top());
340  }
341  QRect result = rect1;
342 
343  QRect dvr_rec = GetDisplayVideoRect();
344  QRect vid_rec = GetVideoRect();
345 
346  hscale = image_aspect / pixel_aspect;
347  if (hscale < 0.99 || hscale > 1.01)
348  {
349  vid_rec.setLeft(static_cast<int>(lround(static_cast<qreal>(vid_rec.left()) * hscale)));
350  vid_rec.setWidth(static_cast<int>(lround(static_cast<qreal>(vid_rec.width()) * hscale)));
351  }
352 
353  qreal vscale = static_cast<qreal>(dvr_rec.width()) / image_width;
354  hscale = static_cast<qreal>(dvr_rec.height()) / image_height;
355  QTransform m1;
356  m1.translate(dvr_rec.left(), dvr_rec.top());
357  m1.scale(vscale, hscale);
358 
359  vscale = static_cast<qreal>(image_width) / vid_rec.width();
360  hscale = static_cast<qreal>(image_height) / vid_rec.height();
361  QTransform m2;
362  m2.scale(vscale, hscale);
363  m2.translate(-vid_rec.left(), -vid_rec.top());
364 
365  result = m2.mapRect(result);
366  result = m1.mapRect(result);
367  return result;
368 }
369 
377 {
378  static constexpr float kSafeMargin = 0.05F;
379  float dummy = NAN;
380  QRect result = GetVisibleOSDBounds(dummy, dummy, 1.0F);
381  int safex = static_cast<int>(static_cast<float>(result.width()) * kSafeMargin);
382  int safey = static_cast<int>(static_cast<float>(result.height()) * kSafeMargin);
383  return { result.left() + safex, result.top() + safey,
384  result.width() - (2 * safex), result.height() - (2 * safey) };
385 }
386 
391 {
393 }
394 
398 {
400 }
401 
404 {
406 }
407 
411 {
413 }
414 
418 {
420 }
421 
425 {
427 }
428 
431 void MythVideoOutput::DiscardFrames(bool KeyFrame, bool /*Flushed*/)
432 {
433  m_videoBuffers.DiscardFrames(KeyFrame);
434 }
MythVideoOutput::GetOSDBounds
virtual void GetOSDBounds(QRect &Total, QRect &Visible, float &VisibleAspect, float &FontScaling, float ThemeAspect) const
Definition: mythvideoout.cpp:207
VideoBuffers::ValidVideoFrames
uint ValidVideoFrames(void) const
Definition: videobuffers.cpp:770
MythVideoBounds::IsEmbedding
bool IsEmbedding(void) const
Definition: mythvideobounds.h:68
VideoBuffers::ReleaseFrame
void ReleaseFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:361
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:187
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:513
MythVideoFrame::ParseDeinterlacer
static MythDeintType ParseDeinterlacer(const QString &Deinterlacer)
Definition: mythframe.cpp:544
MythVideoBounds::EmbedPlayback
virtual void EmbedPlayback(bool Embed, QRect Rect)
Definition: mythvideobounds.cpp:684
MythVideoOutput::FreeVideoFrames
int FreeVideoFrames()
Returns number of frames available for decoding onto.
Definition: mythvideoout.cpp:284
MythVideoOutput::GetError
VideoErrorState GetError() const
Definition: mythvideoout.cpp:260
VideoBuffers::GetNextFreeFrame
MythVideoFrame * GetNextFreeFrame(BufferType EnqueueTo=kVideoBuffer_limbo)
Gets a frame from available buffers list.
Definition: videobuffers.cpp:320
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:785
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:200
osd.h
MythVideoOutput::m_forcedDeinterlacer
MythDeintType m_forcedDeinterlacer
Definition: mythvideoout.h:109
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythplayer.h
MythVideoOutput::SetFramesPlayed
virtual void SetFramesPlayed(long long FramesPlayed)
Definition: mythvideoout.cpp:245
MythVideoBounds::GetVideoRect
QRect GetVideoRect(void) const
Definition: mythvideobounds.h:76
Visible
Definition: channelsettings.cpp:416
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:266
MythVideoOutputGPU::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options, MythRender *Render)
Definition: mythvideooutgpu.cpp:25
MythCodecID
MythCodecID
Definition: mythcodecid.h:10
MythVideoOutput::Init
virtual bool Init(QSize VideoDim, QSize VideoDispDim, float VideoAspect, QRect WindowRect, MythCodecID CodecID)
Definition: mythvideoout.cpp:110
mythvideooutnull.h
mythlogging.h
RenderOptions
Definition: mythvideoprofile.h:41
MythVideoOutput::ValidVideoFrames
virtual int ValidVideoFrames() const
Returns number of frames that are fully decoded.
Definition: mythvideoout.cpp:278
MythVideoBounds::SourceChanged
void SourceChanged(QSize VideoDim, QSize VideoDispDim, float Aspect)
Update for new source video dimensions and aspect ratio.
Definition: mythvideobounds.cpp:525
MythVideoOutput::ClearAfterSeek
virtual void ClearAfterSeek()
Tells video output to toss decoded buffers due to a seek.
Definition: mythvideoout.cpp:272
MythVideoOutput::DeLimboFrame
virtual void DeLimboFrame(MythVideoFrame *Frame)
Releases a frame for reuse if it is in limbo.
Definition: mythvideoout.cpp:403
MythVideoOutput::GetFrameStatus
QString GetFrameStatus() const
Returns string with status of each frame for debugging.
Definition: mythvideoout.cpp:309
VideoBuffers::EnoughFreeFrames
bool EnoughFreeFrames(void) const
Definition: videobuffers.cpp:780
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:390
VideoBuffers::StartDisplayingFrame
void StartDisplayingFrame(void)
Definition: videobuffers.cpp:408
MythVideoOutput::GetImageRect
QRect GetImageRect(QRect Rect, QRect *DisplayRect=nullptr)
translates caption/dvd button rectangle into 'screen' space
Definition: mythvideoout.cpp:322
MythVideoOutput::GetFramesPlayed
virtual long long GetFramesPlayed()
Definition: mythvideoout.cpp:250
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:431
MythVideoOutput::GetLastDecodedFrame
virtual MythVideoFrame * GetLastDecodedFrame()
Definition: mythvideoout.cpp:303
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:55
MythVideoBounds::GetVideoDispDim
QSize GetVideoDispDim(void) const
Definition: mythvideobounds.h:71
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:290
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:397
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:410
MythVideoOutput::IsErrored
bool IsErrored() const
Definition: mythvideoout.cpp:255
MythVideoOutputNull::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options)
Definition: mythvideooutnull.cpp:15
mthreadpool.h
LOC
#define LOC
Definition: mythvideoout.cpp:22
mythuihelper.h
VideoBuffers::GetLastShownFrame
MythVideoFrame * GetLastShownFrame(void)
Definition: videobuffers.cpp:765
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:424
myth2av_codecid
AVCodecID myth2av_codecid(MythCodecID codec_id)
Definition: mythcodecid.cpp:228
VideoBuffers::DiscardFrame
void DiscardFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:451
mythcorecontext.h
MythVideoOutput::GetSupportedPictureAttributes
PictureAttributeSupported GetSupportedPictureAttributes()
Definition: mythvideoout.cpp:240
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:760
mythavutil.h
MythVideoOutput::MythVideoOutput
MythVideoOutput()
Definition: mythvideoout.cpp:99
VideoBuffers::SetPrebuffering
void SetPrebuffering(bool Normal)
Definition: videobuffers.cpp:282
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:376
VideoBuffers::ClearAfterSeek
void ClearAfterSeek(void)
Clear used frames after seeking.
Definition: videobuffers.cpp:896
VideoBuffers::DoneDisplayingFrame
void DoneDisplayingFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:418
decoderbase.h
MythVideoBounds::InitBounds
bool InitBounds(QSize VideoDim, QSize VideoDispDim, float Aspect, QRect WindowRect)
Definition: mythvideobounds.cpp:452
VideoBuffers::FreeVideoFrames
uint FreeVideoFrames(void) const
Definition: videobuffers.cpp:775
mythcodeccontext.h
MythVideoOutput::GetRenderOptions
static void GetRenderOptions(RenderOptions &Options, MythRender *Render)
Definition: mythvideoout.cpp:24
MythVideoOutput::SetDeinterlacing
virtual void SetDeinterlacing(bool Enable, bool DoubleRate, MythDeintType Force=DEINT_NONE)
Definition: mythvideoout.cpp:141
MythVideoFrame
Definition: mythframe.h:88
VideoBuffers::DiscardFrames
void DiscardFrames(bool NextFrameIsKeyFrame)
Definition: videobuffers.cpp:809
VideoBuffers::DeLimboFrame
void DeLimboFrame(MythVideoFrame *Frame)
Definition: videobuffers.cpp:378
MythVideoOutput::EnoughDecodedFrames
bool EnoughDecodedFrames()
Returns true iff there are plenty of decoded frames ready for display.
Definition: mythvideoout.cpp:297
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:316
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:1012
MythVideoOutput::GetVisibleOSDBounds
QRect GetVisibleOSDBounds(float &VisibleAspect, float &FontScaling, float ThemeAspect) const
Returns visible portions of total OSD bounds.
Definition: mythvideoout.cpp:222
MythVideoOutput::SetVideoFrameRate
virtual void SetVideoFrameRate(float VideoFrameRate)
Definition: mythvideoout.cpp:135
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:417