Skip to content

Commit

Permalink
MythPlayerInterface: Restructure inheritance
Browse files Browse the repository at this point in the history
- this is how I should have implemented it in the first place...

- add a MythPlayerUIBase class that inherits from MythPlayer and adds
the main UI related objects that we need elsewhere
- use a simple A->B->C inheritance structure for incorporating all of
the interface subclasses into MythPlayerInterface

This ensures:-

- the full interface is still visible to the parent TV object
- all base class members are visible in the derived classes
- hence avoids duplication of member variables
- critically - each class in the inheritance line can be a QObject
  • Loading branch information
mark-kendall committed Oct 10, 2020
1 parent 4546495 commit 9a28281
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 86 deletions.
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/libmythtv.pro
Expand Up @@ -376,6 +376,7 @@ using_frontend {
# Video playback
HEADERS += tv_play.h
HEADERS += mythplayer.h
HEADERS += mythplayeruibase.h
HEADERS += mythplayerinterface.h
HEADERS += mythvideoscantracker.h
HEADERS += mythplayervisualiser.h
Expand All @@ -393,6 +394,7 @@ using_frontend {
HEADERS += mheg/netstream.h
SOURCES += tv_play.cpp
SOURCES += mythplayer.cpp
SOURCES += mythplayeruibase.cpp
SOURCES += mythplayerinterface.cpp
SOURCES += mythvideoscantracker.cpp
SOURCES += mythplayervisualiser.cpp
Expand Down
3 changes: 0 additions & 3 deletions mythtv/libs/libmythtv/mythplayer.h
Expand Up @@ -41,10 +41,7 @@

class ProgramInfo;
class InteractiveTV;
class DetectLetterbox;
class Jitterometer;
class QThread;
class QWidget;
class MythMediaBuffer;
class MythDecoderThread;

Expand Down
49 changes: 25 additions & 24 deletions mythtv/libs/libmythtv/mythplayeraudiointerface.cpp
Expand Up @@ -4,20 +4,21 @@
#include "mythmainwindow.h"
#include "mythplayeraudiointerface.h"

MythPlayerAudioInterface::MythPlayerAudioInterface(MythMainWindow* MainWindow, AudioPlayer* Audio)
: m_audioOut(Audio)
MythPlayerAudioInterface::MythPlayerAudioInterface(MythMainWindow* MainWindow, TV *Tv,
PlayerContext *Context, PlayerFlags Flags)
: MythPlayerVisualiser(MainWindow, Tv, Context, Flags)
{
m_audioGraph.SetPainter(MainWindow->GetPainter());
m_audioGraph.SetPainter(m_painter);
}

void MythPlayerAudioInterface::ResetAudio()
{
m_audioOut->Reset();
m_audio.Reset();
}

void MythPlayerAudioInterface::ReinitAudio()
{
(void)m_audioOut->ReinitAudio();
(void)m_audio.ReinitAudio();
}

const AudioOutputGraph& MythPlayerAudioInterface::GetAudioGraph() const
Expand All @@ -27,94 +28,94 @@ const AudioOutputGraph& MythPlayerAudioInterface::GetAudioGraph() const

void MythPlayerAudioInterface::SetupAudioGraph(double VideoFrameRate)
{
uint samplerate = static_cast<uint>(m_audioOut->GetSampleRate());
uint samplerate = static_cast<uint>(m_audio.GetSampleRate());
m_audioGraph.SetSampleRate(samplerate);
m_audioGraph.SetSampleCount(static_cast<unsigned>(samplerate / VideoFrameRate));
m_audioOut->addVisual(&m_audioGraph);
m_audio.addVisual(&m_audioGraph);
}

void MythPlayerAudioInterface::ClearAudioGraph()
{
m_audioOut->removeVisual(&m_audioGraph);
m_audio.removeVisual(&m_audioGraph);
m_audioGraph.Reset();
}

uint MythPlayerAudioInterface::GetVolume()
{
return m_audioOut->GetVolume();
return m_audio.GetVolume();
}

uint MythPlayerAudioInterface::AdjustVolume(int Change)
{
return m_audioOut->AdjustVolume(Change);
return m_audio.AdjustVolume(Change);
}

uint MythPlayerAudioInterface::SetVolume(int Volume)
{
return m_audioOut->SetVolume(Volume);
return m_audio.SetVolume(Volume);
}

bool MythPlayerAudioInterface::SetMuted(bool Mute)
{
return m_audioOut->SetMuted(Mute);
return m_audio.SetMuted(Mute);
}

MuteState MythPlayerAudioInterface::GetMuteState()
{
return m_audioOut->GetMuteState();
return m_audio.GetMuteState();
}

MuteState MythPlayerAudioInterface::SetMuteState(MuteState State)
{
return m_audioOut->SetMuteState(State);
return m_audio.SetMuteState(State);
}

MuteState MythPlayerAudioInterface::IncrMuteState()
{
return m_audioOut->IncrMuteState();
return m_audio.IncrMuteState();
}

bool MythPlayerAudioInterface::HasAudioOut() const
{
return m_audioOut->HasAudioOut();
return m_audio.HasAudioOut();
}

bool MythPlayerAudioInterface::IsMuted()
{
return m_audioOut->IsMuted();
return m_audio.IsMuted();
}

bool MythPlayerAudioInterface::CanUpmix()
{
return m_audioOut->CanUpmix();
return m_audio.CanUpmix();
}

bool MythPlayerAudioInterface::IsUpmixing()
{
return m_audioOut->IsUpmixing();
return m_audio.IsUpmixing();
}

bool MythPlayerAudioInterface::PlayerControlsVolume() const
{
return m_audioOut->ControlsVolume();
return m_audio.ControlsVolume();
}

bool MythPlayerAudioInterface::EnableUpmix(bool Enable, bool Toggle)
{
return m_audioOut->EnableUpmix(Enable, Toggle);
return m_audio.EnableUpmix(Enable, Toggle);
}

void MythPlayerAudioInterface::PauseAudioUntilBuffered()
{
m_audioOut->PauseAudioUntilBuffered();
m_audio.PauseAudioUntilBuffered();
}

void MythPlayerAudioInterface::SetupAudioOutput(float TimeStretch)
{
QString passthru = gCoreContext->GetBoolSetting("PassThruDeviceOverride", false) ?
gCoreContext->GetSetting("PassThruOutputDevice") : QString();
m_audioOut->SetAudioInfo(gCoreContext->GetSetting("AudioOutputDevice"), passthru,
m_audio.SetAudioInfo(gCoreContext->GetSetting("AudioOutputDevice"), passthru,
static_cast<uint>(gCoreContext->GetNumSetting("AudioSampleRate", 44100)));
m_audioOut->SetStretchFactor(TimeStretch);
m_audio.SetStretchFactor(TimeStretch);
}

9 changes: 3 additions & 6 deletions mythtv/libs/libmythtv/mythplayeraudiointerface.h
Expand Up @@ -4,14 +4,12 @@
// MythTV
#include "volumebase.h"
#include "audiooutputgraph.h"
#include "mythplayervisualiser.h"

class AudioPlayer;
class MythMainWindow;

class MythPlayerAudioInterface
class MythPlayerAudioInterface : public MythPlayerVisualiser
{
public:
MythPlayerAudioInterface(MythMainWindow* MainWindow, AudioPlayer* Audio);
MythPlayerAudioInterface(MythMainWindow* MainWindow, TV* Tv, PlayerContext* Context, PlayerFlags Flags);

void ResetAudio();
void ReinitAudio();
Expand All @@ -36,7 +34,6 @@ class MythPlayerAudioInterface

private:
Q_DISABLE_COPY(MythPlayerAudioInterface)
AudioPlayer* m_audioOut { nullptr };
AudioOutputGraph m_audioGraph;
};

Expand Down
20 changes: 4 additions & 16 deletions mythtv/libs/libmythtv/mythplayerinterface.cpp
Expand Up @@ -12,15 +12,9 @@

MythPlayerInterface::MythPlayerInterface(MythMainWindow* MainWindow, TV* Tv,
PlayerContext *Context, PlayerFlags Flags)
: MythPlayer(Context, Flags),
MythPlayerVisualiser(MainWindow, &m_audio),
MythVideoScanTracker(this),
MythPlayerAudioInterface(MainWindow, &m_audio),
m_mainWindow(MainWindow),
m_tv(Tv)
: MythPlayerAudioInterface(MainWindow, Tv, Context, Flags),
MythVideoScanTracker(this)
{
connect(m_tv, &TV::EmbedPlayback, this, &MythPlayerInterface::EmbedPlayback);
m_display = m_mainWindow->GetDisplay();
}

void MythPlayerInterface::EventLoop()
Expand Down Expand Up @@ -311,12 +305,6 @@ bool MythPlayerInterface::InitVideo()
return false;
}

void MythPlayerInterface::EmbedPlayback(bool Embed, const QRect& Rect)
{
// We cannot have multiple inheritance from QObject so we need to call directly
EmbedVisualiser(Embed, Rect);
}

void MythPlayerInterface::ReinitVideo(bool ForceUpdate)
{
MythPlayer::ReinitVideo(ForceUpdate);
Expand Down Expand Up @@ -518,12 +506,12 @@ void MythPlayerInterface::DisplayPauseFrame()
RenderVideoFrame(nullptr, scan, true, 0);
}

void MythPlayerInterface::DisplayNormalFrame(bool check_prebuffer)
void MythPlayerInterface::DisplayNormalFrame(bool CheckPrebuffer)
{
if (m_allPaused)
return;

if (check_prebuffer && !PrebufferEnoughFrames())
if (CheckPrebuffer && !PrebufferEnoughFrames())
return;

// clear the buffering state
Expand Down
13 changes: 2 additions & 11 deletions mythtv/libs/libmythtv/mythplayerinterface.h
Expand Up @@ -9,16 +9,10 @@
#include "jitterometer.h"
#include "mythplayer.h"

class MythPlayerInterface : public MythPlayer,
public MythPlayerVisualiser,
public MythVideoScanTracker,
public MythPlayerAudioInterface
class MythPlayerInterface : public MythPlayerAudioInterface, public MythVideoScanTracker
{
Q_OBJECT

public slots:
void EmbedPlayback(bool Embed, const QRect& Rect = {});

public:
MythPlayerInterface(MythMainWindow* MainWindow, TV* Tv, PlayerContext* Context, PlayerFlags Flags);

Expand Down Expand Up @@ -66,15 +60,12 @@ class MythPlayerInterface : public MythPlayer,
void RenderVideoFrame(VideoFrame* Frame, FrameScanType Scan, bool Prepare, int64_t Wait);
void DoDisplayVideoFrame(VideoFrame* Frame, int64_t Due);

MythMainWindow* m_mainWindow { nullptr };
TV* m_tv { nullptr };
MythDisplay* m_display { nullptr };
Jitterometer m_outputJmeter { "Player" };

// N.B. Editor - keep ringfenced and move into subclass
QElapsedTimer m_editUpdateTimer;
float m_speedBeforeEdit { 1.0 };
bool m_pausedBeforeEdit { false };
QElapsedTimer m_editUpdateTimer;
};

#endif
18 changes: 18 additions & 0 deletions mythtv/libs/libmythtv/mythplayeruibase.cpp
@@ -0,0 +1,18 @@
// MythTV
#include "mythmainwindow.h"
#include "mythplayeruibase.h"

/*! \class MythPlayerUIBase
*
* This is the base class for all user facing MythPlayer classes. It contains
* references to all of the major objects that will be needed for other UI player classes.
*/
MythPlayerUIBase::MythPlayerUIBase(MythMainWindow* MainWindow, TV* Tv, PlayerContext* Context, PlayerFlags Flags)
: MythPlayer(Context, Flags),
m_mainWindow(MainWindow),
m_tv(Tv),
m_render(MainWindow->GetRenderDevice()),
m_painter(MainWindow->GetPainter()),
m_display(MainWindow->GetDisplay())
{
}
21 changes: 21 additions & 0 deletions mythtv/libs/libmythtv/mythplayeruibase.h
@@ -0,0 +1,21 @@
#ifndef MYTHPLAYERUIBASE_H
#define MYTHPLAYERUIBASE_H

// MythTV
#include "mythplayer.h"

class MythPlayerUIBase : public MythPlayer
{
Q_OBJECT

public:
MythPlayerUIBase(MythMainWindow* MainWindow, TV* Tv, PlayerContext* Context, PlayerFlags Flags);

MythMainWindow* m_mainWindow { nullptr };
TV* m_tv { nullptr };
MythRender* m_render { nullptr };
MythPainter* m_painter { nullptr };
MythDisplay* m_display { nullptr };
};

#endif
21 changes: 8 additions & 13 deletions mythtv/libs/libmythtv/mythplayervisualiser.cpp
Expand Up @@ -2,14 +2,14 @@
#include "mythcorecontext.h"
#include "audioplayer.h"
#include "mythmainwindow.h"
#include "tv_play.h"
#include "mythplayervisualiser.h"

MythPlayerVisualiser::MythPlayerVisualiser(MythMainWindow *MainWindow, AudioPlayer *Audio)
: m_visualAudio(Audio)
MythPlayerVisualiser::MythPlayerVisualiser(MythMainWindow *MainWindow, TV *Tv,
PlayerContext *Context, PlayerFlags Flags)
: MythPlayerUIBase(MainWindow, Tv, Context, Flags)
{
m_mainWindow = MainWindow;
m_render = m_mainWindow->GetRenderDevice();
m_painter = m_mainWindow->GetPainter();
connect(m_tv, &TV::EmbedPlayback, this, &MythPlayerVisualiser::EmbedVisualiser);
}

MythPlayerVisualiser::~MythPlayerVisualiser()
Expand Down Expand Up @@ -40,7 +40,7 @@ void MythPlayerVisualiser::DestroyVisualiser()

bool MythPlayerVisualiser::CanVisualise()
{
return VideoVisual::CanVisualise(m_visualAudio, m_render);
return VideoVisual::CanVisualise(&m_audio, m_render);
}

bool MythPlayerVisualiser::IsVisualising()
Expand Down Expand Up @@ -68,15 +68,15 @@ bool MythPlayerVisualiser::EnableVisualiser(bool Enable, const QString &Name)
return false;
}
DestroyVisualiser();
m_visual = VideoVisual::Create(Name, m_visualAudio, m_render);
m_visual = VideoVisual::Create(Name, &m_audio, m_render);
return m_visual != nullptr;
}

/*! \brief Enable visualisation if possible, there is no video and user has requested.
*/
void MythPlayerVisualiser::AutoVisualise(bool HaveVideo)
{
if (!m_visualAudio->HasAudioIn() || HaveVideo)
if (!m_audio.HasAudioIn() || HaveVideo)
return;

if (!CanVisualise() || IsVisualising())
Expand All @@ -97,8 +97,3 @@ bool MythPlayerVisualiser::IsEmbedding()
{
return m_embedding;
}

QRect MythPlayerVisualiser::GetEmbeddingRect()
{
return m_embedRect;
}

0 comments on commit 9a28281

Please sign in to comment.