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 playback_fps)
135 {
136  if (m_videoProfile)
137  m_videoProfile->SetOutput(playback_fps);
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(DoubleRate).arg(MythVideoFrame::DeinterlacerPref(singlerate)).arg(MythVideoFrame::DeinterlacerPref(doublerate)));
176  m_videoBuffers.SetDeinterlacing(singlerate, doublerate, m_videoCodecID);
177 }
178 
184 bool MythVideoOutput::InputChanged(const QSize VideoDim, const QSize VideoDispDim,
185  float VideoAspect, MythCodecID CodecID,
186  bool& /*AspectOnly*/, int ReferenceFrames, bool /*ForceChange*/)
187 {
188  SourceChanged(VideoDim, VideoDispDim, VideoAspect);
189  m_maxReferenceFrames = ReferenceFrames;
190  AVCodecID avCodecId = myth2av_codecid(CodecID);
191  AVCodec* codec = avcodec_find_decoder(avCodecId);
192  QString codecName;
193  if (codec)
194  codecName = codec->name;
195  if (m_videoProfile)
196  m_videoProfile->SetInput(GetVideoDispDim(), 0 ,codecName);
197  m_videoCodecID = CodecID;
198  DiscardFrames(true, true);
199  // Update deinterlacers for any input change
201  return true;
202 }
203 
204 void MythVideoOutput::GetOSDBounds(QRect& Total, QRect& Visible,
205  float& VisibleAspect,
206  float& FontScaling,
207  float ThemeAspect) const
208 {
209  Total = GetDisplayVisibleRect();
210  Visible = GetVisibleOSDBounds(VisibleAspect, FontScaling, ThemeAspect);
211 }
212 
219 QRect MythVideoOutput::GetVisibleOSDBounds(float& VisibleAspect,
220  float& FontScaling,
221  float ThemeAspect) const
222 {
223  QRect dvr = GetDisplayVisibleRect();
224  float dispPixelAdj = 1.0F;
225  if (dvr.height() && dvr.width())
226  dispPixelAdj = (GetDisplayAspect() * dvr.height()) / dvr.width();
227 
228  float ova = GetOverridenVideoAspect();
229  QRect vr = GetVideoRect();
230  float vs = vr.height() ? static_cast<float>(vr.width()) / vr.height() : 1.0F;
231  VisibleAspect = ThemeAspect * (ova > 0.0F ? vs / ova : 1.F) * dispPixelAdj;
232 
233  FontScaling = 1.0F;
234  return { QPoint(0,0), dvr.size() };
235 }
236 
238 {
240 }
241 
242 void MythVideoOutput::SetFramesPlayed(long long FramesPlayed)
243 {
244  m_framesPlayed = FramesPlayed;
245 }
246 
248 {
249  return m_framesPlayed;
250 }
251 
253 {
254  return m_errorState != kError_None;
255 }
256 
258 {
259  return m_errorState;
260 }
261 
264 {
266 }
267 
270 {
272 }
273 
276 {
277  return static_cast<int>(m_videoBuffers.ValidVideoFrames());
278 }
279 
282 {
283  return static_cast<int>(m_videoBuffers.FreeVideoFrames());
284 }
285 
288 {
290 }
291 
295 {
297 }
298 
301 {
303 }
304 
307 {
308  return m_videoBuffers.GetStatus();
309 }
310 
314 {
316 }
317 
319 QRect MythVideoOutput::GetImageRect(const QRect Rect, QRect* DisplayRect)
320 {
321  qreal hscale = 0.0;
322  QSize video_size = GetVideoDispDim();
323  int image_height = video_size.height();
324  int image_width = (image_height > 720) ? 1920 :
325  (image_height > 576) ? 1280 : 720;
326  qreal image_aspect = static_cast<qreal>(image_width) / image_height;
327  qreal pixel_aspect = static_cast<qreal>(video_size.width()) / video_size.height();
328 
329  QRect rect1 = Rect;
330  if (DisplayRect && DisplayRect->isValid())
331  {
332  QTransform m0;
333  m0.scale(static_cast<qreal>(image_width) / DisplayRect->width(),
334  static_cast<qreal>(image_height) / DisplayRect->height());
335  rect1 = m0.mapRect(rect1);
336  rect1.translate(DisplayRect->left(), DisplayRect->top());
337  }
338  QRect result = rect1;
339 
340  QRect dvr_rec = GetDisplayVideoRect();
341  QRect vid_rec = GetVideoRect();
342 
343  hscale = image_aspect / pixel_aspect;
344  if (hscale < 0.99 || hscale > 1.01)
345  {
346  vid_rec.setLeft(static_cast<int>(lround(static_cast<qreal>(vid_rec.left()) * hscale)));
347  vid_rec.setWidth(static_cast<int>(lround(static_cast<qreal>(vid_rec.width()) * hscale)));
348  }
349 
350  qreal vscale = static_cast<qreal>(dvr_rec.width()) / image_width;
351  hscale = static_cast<qreal>(dvr_rec.height()) / image_height;
352  QTransform m1;
353  m1.translate(dvr_rec.left(), dvr_rec.top());
354  m1.scale(vscale, hscale);
355 
356  vscale = static_cast<qreal>(image_width) / vid_rec.width();
357  hscale = static_cast<qreal>(image_height) / vid_rec.height();
358  QTransform m2;
359  m2.scale(vscale, hscale);
360  m2.translate(-vid_rec.left(), -vid_rec.top());
361 
362  result = m2.mapRect(result);
363  result = m1.mapRect(result);
364  return result;
365 }
366 
374 {
375  static constexpr float kSafeMargin = 0.05F;
376  float dummy = NAN;
377  QRect result = GetVisibleOSDBounds(dummy, dummy, 1.0F);
378  int safex = static_cast<int>(static_cast<float>(result.width()) * kSafeMargin);
379  int safey = static_cast<int>(static_cast<float>(result.height()) * kSafeMargin);
380  return { result.left() + safex, result.top() + safey,
381  result.width() - (2 * safex), result.height() - (2 * safey) };
382 }
383 
388 {
390 }
391 
395 {
397 }
398 
401 {
403 }
404 
408 {
410 }
411 
415 {
417 }
418 
422 {
424 }
425 
428 void MythVideoOutput::DiscardFrames(bool KeyFrame, bool /*Flushed*/)
429 {
430  m_videoBuffers.DiscardFrames(KeyFrame);
431 }
MythVideoOutput::GetOSDBounds
virtual void GetOSDBounds(QRect &Total, QRect &Visible, float &VisibleAspect, float &FontScaling, float ThemeAspect) const
Definition: mythvideoout.cpp:204
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:96
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:184
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:541
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:281
MythVideoOutput::GetError
VideoErrorState GetError() const
Definition: mythvideoout.cpp:257
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:104
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:103
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:67
arg
arg(title).arg(filename).arg(doDelete))
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:110
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
mythplayer.h
MythVideoOutput::SetFramesPlayed
virtual void SetFramesPlayed(long long FramesPlayed)
Definition: mythvideoout.cpp:242
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:263
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:41
MythVideoOutput::ValidVideoFrames
virtual int ValidVideoFrames() const
Returns number of frames that are fully decoded.
Definition: mythvideoout.cpp:275
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:269
MythVideoOutput::DeLimboFrame
virtual void DeLimboFrame(MythVideoFrame *Frame)
Releases a frame for reuse if it is in limbo.
Definition: mythvideoout.cpp:400
MythVideoOutput::GetFrameStatus
QString GetFrameStatus() const
Returns string with status of each frame for debugging.
Definition: mythvideoout.cpp:306
VideoBuffers::EnoughFreeFrames
bool EnoughFreeFrames(void) const
Definition: videobuffers.cpp:779
MythVideoOutput::m_videoProfile
MythVideoProfilePtr m_videoProfile
Definition: mythvideoout.h:101
mythvideooutgpu.h
MythVideoOutput::GetNextFreeFrame
virtual MythVideoFrame * GetNextFreeFrame()
Blocks until it is possible to return a frame for decoding onto.
Definition: mythvideoout.cpp:387
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:319
MythVideoOutput::GetFramesPlayed
virtual long long GetFramesPlayed()
Definition: mythvideoout.cpp:247
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:428
MythVideoOutput::GetLastDecodedFrame
virtual MythVideoFrame * GetLastDecodedFrame()
Definition: mythvideoout.cpp:300
MythVideoOutput::m_videoCodecID
MythCodecID m_videoCodecID
Definition: mythvideoout.h:99
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:933
MythVideoFrame::DeinterlacerPref
static QString DeinterlacerPref(MythDeintType Deint)
Definition: mythframe.cpp:527
MythVideoOutput::EnoughFreeFrames
bool EnoughFreeFrames()
Returns true iff enough frames are available to decode onto.
Definition: mythvideoout.cpp:287
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:394
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:407
MythVideoOutput::IsErrored
bool IsErrored() const
Definition: mythvideoout.cpp:252
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
MythVideoOutput::SetVideoFrameRate
virtual void SetVideoFrameRate(float playback_fps)
Definition: mythvideoout.cpp:134
MythDeintType
MythDeintType
Definition: mythframe.h:65
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:237
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:97
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:373
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:85
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:294
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:313
MythVideoColourSpace::SupportedAttributes
PictureAttributeSupported SupportedAttributes(void) const
Definition: mythvideocolourspace.cpp:118
MythVideoOutput::m_maxReferenceFrames
int m_maxReferenceFrames
Definition: mythvideoout.h:100
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:219
MythVideoOutput::m_deinterlacing2X
bool m_deinterlacing2X
Definition: mythvideoout.h:109
MythVideoOutput::m_videoBuffers
VideoBuffers m_videoBuffers
Definition: mythvideoout.h:102
MythVideoOutput::m_videoColourSpace
MythVideoColourSpace m_videoColourSpace
Definition: mythvideoout.h:95
MythVideoOutput::DiscardFrame
virtual void DiscardFrame(MythVideoFrame *frame)
Releases frame from any queue onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:421
MythVideoOutput::m_deinterlacing
bool m_deinterlacing
Definition: mythvideoout.h:108
MythVideoOutput::DoneDisplayingFrame
virtual void DoneDisplayingFrame(MythVideoFrame *Frame)
Releases frame returned from GetLastShownFrame() onto the queue of frames ready for decoding onto.
Definition: mythvideoout.cpp:414