Skip to content

Commit

Permalink
MythDisplay: Extensive cleanup and refactor
Browse files Browse the repository at this point in the history
- the previous changes to MythDisplay resulted in a confusing API that
was amalgamated from various sources.
- cleanup API for consistency - mostly removing previous GUI/VIDEO/
DESKTOP mode stuff to ensure we always track the actual video mode in use
- start retrieving the EDID (X11 and DRM only at the moment)
- start using the EDID data (VideoColourspace)
- use the modeline to determine current screen resolution in
MythXDisplay - as it is more current than the old method.
- remove old, unused code from MythXDisplay.
- sundry changes to method signatures for consistency and ease of use
  • Loading branch information
mark-kendall committed Dec 26, 2019
1 parent 2ea1094 commit d6798be
Show file tree
Hide file tree
Showing 30 changed files with 605 additions and 595 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/decoders/mythvdpauhelper.cpp
Expand Up @@ -90,7 +90,7 @@ static const char* DummyGetError(VdpStatus /*status*/)
MythVDPAUHelper::MythVDPAUHelper(void)
: m_createdDevice(true)
{
m_display = OpenMythXDisplay(false);
m_display = MythXDisplay::OpenMythXDisplay(false);
if (!m_display)
return;

Expand Down
14 changes: 7 additions & 7 deletions mythtv/libs/libmythtv/mythplayer.cpp
Expand Up @@ -472,7 +472,7 @@ void MythPlayer::ReinitVideo(bool ForceUpdate)
// the display refresh rate may have been changed by VideoOutput
if (m_videoSync)
{
int ri = m_display->GetDisplayInfo(m_frameInterval).Rate();
int ri = m_display->GetRefreshInterval(m_frameInterval);
if (ri != m_videoSync->getRefreshInterval())
{
LOG(VB_PLAYBACK, LOG_INFO, LOC +
Expand Down Expand Up @@ -1535,7 +1535,7 @@ void MythPlayer::InitAVSync(void)
{
m_videoSync->Start();

m_refreshRate = m_display->GetDisplayInfo(m_frameInterval).Rate();
m_refreshRate = m_display->GetRefreshInterval(m_frameInterval);

m_rtcBase = 0;
m_priorAudioTimecode = 0;
Expand Down Expand Up @@ -2079,7 +2079,7 @@ bool MythPlayer::CanSupportDoubleRate(void)
else if (m_display)
{
// used by the decoder before m_videoSync is created
refreshinterval = m_display->GetDisplayInfo(m_frameInterval).Rate();
refreshinterval = m_display->GetRefreshInterval(m_frameInterval);
}

// At this point we may not have the correct frame rate.
Expand Down Expand Up @@ -2169,8 +2169,8 @@ void MythPlayer::VideoStart(void)
m_refreshRate = m_frameInterval;

float temp_speed = (m_playSpeed == 0.0F) ? m_audio.GetStretchFactor() : m_playSpeed;
int fr_int = (1000000.0 / m_videoFrameRate / static_cast<double>(temp_speed));
int rf_int = m_display->GetDisplayInfo(fr_int).Rate();
int fr_int = static_cast<int>(1000000.0 / m_videoFrameRate / static_cast<double>(temp_speed));
int displayinterval = m_display->GetRefreshInterval(fr_int);

// Default to interlaced playback but set the tracker to progressive
// Enable autodetection of interlaced/progressive from video stream
Expand All @@ -2195,13 +2195,13 @@ void MythPlayer::VideoStart(void)
}
else if (m_videoOutput)
{
m_videoSync = VideoSync::BestMethod(m_videoOutput, static_cast<uint>(rf_int));
m_videoSync = VideoSync::BestMethod(m_videoOutput, static_cast<uint>(displayinterval));
m_doubleFramerate = CanSupportDoubleRate(); // needs m_videoSync
m_videoOutput->SetDeinterlacing(true, m_doubleFramerate);
}

if (!m_videoSync)
m_videoSync = new BusyWaitVideoSync(m_videoOutput, rf_int);
m_videoSync = new BusyWaitVideoSync(m_videoOutput, displayinterval);

InitAVSync();
m_videoSync->Start();
Expand Down
20 changes: 9 additions & 11 deletions mythtv/libs/libmythtv/mythvideoout.cpp
Expand Up @@ -918,29 +918,28 @@ void MythVideoOutput::DiscardFrames(bool KeyFrame, bool /*unused*/)
*
* \param width,height Resolution of the video we will be playing
*/
void MythVideoOutput::ResizeForVideo(int Width, int Height)
void MythVideoOutput::ResizeForVideo(QSize Size)
{
if (!m_display)
return;
if (!m_display->UsingVideoModes())
return;

if (!Width || !Height)
if (Size.isEmpty())
{
Width = m_window.GetVideoDispDim().width();
Height = m_window.GetVideoDispDim().height();
if (!Width || !Height)
Size = m_window.GetVideoDispDim();
if (Size.isEmpty())
return;
}

float rate = m_dbDisplayProfile ? m_dbDisplayProfile->GetOutput() : 0.0F;

bool hide = m_display->NextModeIsLarger(Width, Height);
bool hide = m_display->NextModeIsLarger(Size);
MythMainWindow* window = GetMythMainWindow();
if (hide)
window->hide();

if (m_display->SwitchToVideo(Width, Height, static_cast<double>(rate)))
if (m_display->SwitchToVideo(Size, static_cast<double>(rate)))
{
// Switching to custom display resolution succeeded
// Make a note of the new size
Expand Down Expand Up @@ -987,21 +986,20 @@ void MythVideoOutput::InitDisplayMeasurements(void)
if (!m_display)
return;

DisplayInfo disp = m_display->GetDisplayInfo();
QString source = "Actual";
QString source = "Actual";

// get the physical dimensions (in mm) of the display. If using
// DisplayRes, this will be overridden when we call ResizeForVideo
float disp_aspect = m_window.GetDisplayAspect();
QSize disp_dim = m_dbDisplayDimensionsMM;
if (disp_dim.isEmpty())
disp_dim = disp.m_size;
disp_dim = m_display->GetPhysicalSize();
else
source = "Database";
m_window.SetDisplayProperties(disp_dim, disp_aspect);

// Determine window and screen dimensions in pixels
QSize screen_size = disp.m_res;
QSize screen_size = m_display->GetResolution();
QSize window_size = m_window.GetWindowRect().size();

if (screen_size.isEmpty())
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/mythvideoout.h
Expand Up @@ -68,7 +68,7 @@ class MythVideoOutput
virtual void EmbedInWidget(const QRect &EmbedRect);
bool IsEmbedding(void);
virtual void StopEmbedding(void);
virtual void ResizeForVideo(int Width = 0, int Height = 0);
virtual void ResizeForVideo(QSize Size = QSize());
virtual void Zoom(ZoomDirection Direction);
virtual void ToggleMoveBottomLine(void);
virtual void SaveBottomLine(void);
Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythtv/opengl/mythvideooutopengl.cpp
Expand Up @@ -229,7 +229,7 @@ bool MythVideoOutputOpenGL::Init(const QSize &VideoDim, const QSize &VideoDispDi

// Set the display mode if required
if (m_display->UsingVideoModes() && !m_window.IsEmbedding())
ResizeForVideo(size.width(), size.height());
ResizeForVideo(size);
InitDisplayMeasurements();

// Create buffers
Expand Down
8 changes: 4 additions & 4 deletions mythtv/libs/libmythtv/tv_play.cpp
Expand Up @@ -1293,10 +1293,10 @@ TV::~TV(void)
MythDisplay* display = MythDisplay::AcquireRelease();
if (display->UsingVideoModes())
{
bool hide = display->NextModeIsLarger(MythDisplay::GUI);
bool hide = display->NextModeIsLarger(display->GetGUIResolution());
if (hide)
mwnd->hide();
display->SwitchToGUI(MythDisplay::GUI, true);
display->SwitchToGUI(true);
if (hide)
mwnd->Show();
}
Expand Down Expand Up @@ -8639,10 +8639,10 @@ void TV::DoEditSchedule(int editType)
MythDisplay* display = MythDisplay::AcquireRelease();
if (display->UsingVideoModes())
{
bool hide = display->NextModeIsLarger(MythDisplay::GUI);
bool hide = display->NextModeIsLarger(display->GetGUIResolution());
if (hide)
mwnd->hide();
display->SwitchToGUI(MythDisplay::GUI, true);
display->SwitchToGUI(true);
if (hide)
mwnd->Show();
}
Expand Down
24 changes: 18 additions & 6 deletions mythtv/libs/libmythtv/videocolourspace.cpp
@@ -1,6 +1,7 @@
// MythTV
#include "mythcorecontext.h"
#include "mythlogging.h"
#include "mythdisplay.h"
#include "mythavutil.h"
#include "videocolourspace.h"

Expand Down Expand Up @@ -82,6 +83,17 @@ VideoColourSpace::VideoColourSpace(VideoColourSpace *Parent)
SetSaturation(m_dbSettings[kPictureAttribute_Colour]);
SetHue(m_dbSettings[kPictureAttribute_Hue]);
SetFullRange(m_dbSettings[kPictureAttribute_Range]);
MythDisplay* display = MythDisplay::AcquireRelease();
MythEDID& edid = display->GetEDID();
// We assume sRGB/Rec709 by default
if (edid.Valid() && !edid.IsSRGB())
{
m_customDisplayGamma = edid.Gamma();
m_customDisplayPrimaries = new ColourPrimaries;
MythEDID::Primaries displayprimaries = edid.ColourPrimaries();
memcpy(m_customDisplayPrimaries, &displayprimaries, sizeof(ColourPrimaries));
}
MythDisplay::AcquireRelease(false);
m_updatesDisabled = false;
Update();
}
Expand Down Expand Up @@ -259,7 +271,7 @@ void VideoColourSpace::Update(void)
m_primaryMatrix = GetPrimaryConversion(m_colourPrimaries, m_displayPrimaries);
bool primchanged = !qFuzzyCompare(tmpsrcgamma, m_colourGamma) ||
!qFuzzyCompare(tmpdspgamma, m_displayGamma) ||
!qFuzzyCompare(tmpmatrix, m_primaryMatrix);
!qFuzzyCompare(tmpmatrix, m_primaryMatrix);
Debug();
emit Updated(primchanged);
}
Expand Down Expand Up @@ -470,8 +482,9 @@ QMatrix4x4 VideoColourSpace::GetPrimaryConversion(int Source, int Dest)
QMatrix4x4 result; // identity
auto source = static_cast<AVColorPrimaries>(Source);
auto dest = static_cast<AVColorPrimaries>(Dest);
auto force = m_customDisplayPrimaries != nullptr;

if ((source == dest) || (m_primariesMode == PrimariesDisabled))
if (!force && ((source == dest) || (m_primariesMode == PrimariesDisabled)))
return result;

ColourPrimaries srcprimaries;
Expand All @@ -483,12 +496,11 @@ QMatrix4x4 VideoColourSpace::GetPrimaryConversion(int Source, int Dest)
// and destination. Most people will not notice the difference bt709 and bt610 etc
// and we avoid extra GPU processing.
// BT2020 is currently the main target - which is easily differentiated by its gamma.
if ((m_primariesMode == PrimariesAuto) && qFuzzyCompare(m_colourGamma + 1.0F, m_displayGamma + 1.0F))
if (!force && (m_primariesMode == PrimariesAuto) && qFuzzyCompare(m_colourGamma + 1.0F, m_displayGamma + 1.0F))
return result;

// N.B. Custom primaries are not yet implemented but will, some day soon,
// be read from the EDID
if (m_customDisplayPrimaries != nullptr)
// Use the display's chromaticities if not sRGB
if (force)
{
dstprimaries = *m_customDisplayPrimaries;
m_displayGamma = m_customDisplayGamma;
Expand Down
42 changes: 21 additions & 21 deletions mythtv/libs/libmythtv/videocolourspace.h
Expand Up @@ -73,27 +73,27 @@ class VideoColourSpace : public QObject, public QMatrix4x4, public ReferenceCoun
PictureAttributeSupported m_supportedAttributes {kPictureAttributeSupported_None};
QMap<PictureAttribute,int> m_dbSettings;

bool m_fullRange {true};
float m_brightness {0.0F};
float m_contrast {1.0F};
float m_saturation {1.0F};
float m_hue {0.0F};
float m_alpha {1.0F};
int m_colourSpace {AVCOL_SPC_UNSPECIFIED};
int m_colourSpaceDepth {8};
int m_range {AVCOL_RANGE_MPEG};
bool m_updatesDisabled {true};
int m_colourShifted {0};
int m_colourTransfer {AVCOL_TRC_BT709};
PrimariesMode m_primariesMode {PrimariesAuto};
int m_colourPrimaries {AVCOL_PRI_BT709};
int m_displayPrimaries {AVCOL_PRI_BT709};
float m_colourGamma {2.2F};
float m_displayGamma {2.2F};
QMatrix4x4 m_primaryMatrix;
float m_customDisplayGamma {2.2F};
ColourPrimaries *m_customDisplayPrimaries {nullptr};
VideoColourSpace *m_parent {nullptr};
bool m_fullRange { true };
float m_brightness { 0.0F };
float m_contrast { 1.0F };
float m_saturation { 1.0F };
float m_hue { 0.0F };
float m_alpha { 1.0F };
int m_colourSpace { AVCOL_SPC_UNSPECIFIED };
int m_colourSpaceDepth { 8 };
int m_range { AVCOL_RANGE_MPEG };
bool m_updatesDisabled { true };
int m_colourShifted { 0 };
int m_colourTransfer { AVCOL_TRC_BT709 };
PrimariesMode m_primariesMode { PrimariesAuto };
int m_colourPrimaries { AVCOL_PRI_BT709 };
int m_displayPrimaries { AVCOL_PRI_BT709 };
float m_colourGamma { 2.2F };
float m_displayGamma { 2.2F };
QMatrix4x4 m_primaryMatrix { };
float m_customDisplayGamma { 2.2F };
ColourPrimaries *m_customDisplayPrimaries { nullptr };
VideoColourSpace *m_parent { nullptr };
};

#endif

0 comments on commit d6798be

Please sign in to comment.