183 changes: 83 additions & 100 deletions mythtv/libs/libmythtv/Bluray/mythbdplayer.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
// MythTV
#include "Bluray/mythbdbuffer.h"
#include "Bluray/mythbddecoder.h"
#include "Bluray/mythbdplayer.h"

#include <unistd.h> // for usleep()
// Std
#include <unistd.h>

#define LOC QString("BDPlayer: ")
#define LOC QString("BDPlayer: ")

MythBDPlayer::MythBDPlayer(PlayerFlags Flags)
: MythPlayer(Flags)
{
}

bool MythBDPlayer::HasReachedEof(void) const
{
Expand All @@ -19,17 +26,16 @@ void MythBDPlayer::PreProcessNormalFrame(void)
DisplayMenu();
}

bool MythBDPlayer::GoToMenu(const QString& str)
bool MythBDPlayer::GoToMenu(const QString& Menu)
{
if (m_playerCtx->m_buffer->BD() && m_videoOutput)
{
int64_t pts = 0;
VideoFrame *frame = m_videoOutput->GetLastShownFrame();
if (frame)
pts = (int64_t)(frame->timecode * 90);
return m_playerCtx->m_buffer->BD()->GoToMenu(str, pts);
}
return false;
if (!(m_playerCtx->m_buffer->BD() && m_videoOutput))
return false;

int64_t pts = 0;
VideoFrame *frame = m_videoOutput->GetLastShownFrame();
if (frame)
pts = static_cast<int64_t>(frame->timecode * 90);
return m_playerCtx->m_buffer->BD()->GoToMenu(Menu, pts);
}

void MythBDPlayer::DisplayMenu(void)
Expand All @@ -46,11 +52,8 @@ void MythBDPlayer::DisplayMenu(void)

void MythBDPlayer::DisplayPauseFrame(void)
{
if (m_playerCtx->m_buffer->IsBD() &&
m_playerCtx->m_buffer->BD()->IsInStillFrame())
{
if (m_playerCtx->m_buffer->IsBD() && m_playerCtx->m_buffer->BD()->IsInStillFrame())
SetScanType(kScan_Progressive);
}
DisplayMenu();
MythPlayer::DisplayPauseFrame();
}
Expand All @@ -74,10 +77,7 @@ bool MythBDPlayer::VideoLoop(void)
int nbframes = m_videoOutput ? m_videoOutput->ValidVideoFrames() : 0;

// completely drain the video buffers for certain situations
bool drain = m_playerCtx->m_buffer->BD()->BDWaitingForPlayer() &&
(nbframes > 0);

if (drain)
if (m_playerCtx->m_buffer->BD()->BDWaitingForPlayer() && (nbframes > 0))
{
if (nbframes < 2 && m_videoOutput)
m_videoOutput->UpdatePauseFrame(m_dispTimecode);
Expand Down Expand Up @@ -118,8 +118,7 @@ bool MythBDPlayer::VideoLoop(void)
// flag if we have no frame
if (nbframes == 0)
{
LOG(VB_PLAYBACK, LOG_WARNING, LOC +
"Warning: In BD Still but no video frames in queue");
LOG(VB_PLAYBACK, LOG_WARNING, LOC + "Warning: In BD Still but no video frames in queue");
usleep(10000);
return !IsErrored();
}
Expand All @@ -141,12 +140,11 @@ bool MythBDPlayer::VideoLoop(void)
return MythPlayer::VideoLoop();
}

bool MythBDPlayer::JumpToFrame(uint64_t frame)
bool MythBDPlayer::JumpToFrame(uint64_t Frame)
{
if (frame == ~0x0ULL)
if (Frame == ~0x0ULL)
return false;

return MythPlayer::JumpToFrame(frame);
return MythPlayer::JumpToFrame(Frame);
}

void MythBDPlayer::EventStart(void)
Expand All @@ -170,34 +168,30 @@ void MythBDPlayer::EventStart(void)
int MythBDPlayer::GetNumChapters(void)
{
if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen())
return m_playerCtx->m_buffer->BD()->GetNumChapters();
return static_cast<int>(m_playerCtx->m_buffer->BD()->GetNumChapters());
return -1;
}

int MythBDPlayer::GetCurrentChapter(void)
{
if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen())
return m_playerCtx->m_buffer->BD()->GetCurrentChapter() + 1;
return static_cast<int>(m_playerCtx->m_buffer->BD()->GetCurrentChapter() + 1);
return -1;
}

int64_t MythBDPlayer::GetChapter(int chapter)
int64_t MythBDPlayer::GetChapter(int Chapter)
{
uint total = GetNumChapters();
if (!total)
if (GetNumChapters() < 1)
return -1;

return (int64_t)m_playerCtx->m_buffer->BD()->GetChapterStartFrame(chapter-1);
uint32_t chapter = static_cast<uint32_t>(Chapter - 1);
return static_cast<int64_t>(m_playerCtx->m_buffer->BD()->GetChapterStartFrame(chapter));
}

void MythBDPlayer::GetChapterTimes(QList<long long> &times)
void MythBDPlayer::GetChapterTimes(QList<long long> &ChapterTimes)
{
uint total = GetNumChapters();
if (!total)
return;

uint total = static_cast<uint>(GetNumChapters());
for (uint i = 0; i < total; i++)
times.push_back(m_playerCtx->m_buffer->BD()->GetChapterStartTime(i));
ChapterTimes.push_back(static_cast<long long>(m_playerCtx->m_buffer->BD()->GetChapterStartTime(i)));
}

int MythBDPlayer::GetNumTitles(void) const
Expand All @@ -206,14 +200,14 @@ int MythBDPlayer::GetNumTitles(void) const
return 0;

if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen())
return m_playerCtx->m_buffer->BD()->GetNumTitles();
return static_cast<int>(m_playerCtx->m_buffer->BD()->GetNumTitles());
return 0;
}

int MythBDPlayer::GetNumAngles(void) const
{
if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen())
return m_playerCtx->m_buffer->BD()->GetNumAngles();
return static_cast<int>(m_playerCtx->m_buffer->BD()->GetNumAngles());
return 0;
}

Expand All @@ -227,60 +221,57 @@ int MythBDPlayer::GetCurrentTitle(void) const
int MythBDPlayer::GetCurrentAngle(void) const
{
if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen())
return m_playerCtx->m_buffer->BD()->GetCurrentAngle();
return static_cast<int>(m_playerCtx->m_buffer->BD()->GetCurrentAngle());
return -1;
}

int MythBDPlayer::GetTitleDuration(int title) const
int MythBDPlayer::GetTitleDuration(int Title) const
{
if (m_playerCtx->m_buffer->BD() && m_playerCtx->m_buffer->BD()->IsOpen() &&
title >= 0 && title < GetNumTitles())
Title >= 0 && Title < GetNumTitles())
{
return m_playerCtx->m_buffer->BD()->GetTitleDuration(title);
return m_playerCtx->m_buffer->BD()->GetTitleDuration(Title);
}
return 0;
}

QString MythBDPlayer::GetTitleName(int title) const
QString MythBDPlayer::GetTitleName(int Title) const
{
if (title >= 0 && title < GetNumTitles())
if (Title >= 0 && Title < GetNumTitles())
{
int secs = GetTitleDuration(title);
int secs = GetTitleDuration(Title);
// BD doesn't provide title names, so show title number and duration
int hours = secs / 60 / 60;
int minutes = (secs / 60) - (hours * 60);
secs = secs % 60;
QString name = QString("%1 (%2:%3:%4)").arg(title+1)
QString name = QString("%1 (%2:%3:%4)").arg(Title+1)
.arg(hours, 2, 10, QChar(48)).arg(minutes, 2, 10, QChar(48))
.arg(secs, 2, 10, QChar(48));
return name;
}
return QString();
}

QString MythBDPlayer::GetAngleName(int angle) const
QString MythBDPlayer::GetAngleName(int Angle) const
{
if (angle >= 1 && angle <= GetNumAngles())
{
QString name = tr("Angle %1").arg(angle);
return name;
}
if (Angle >= 1 && Angle <= GetNumAngles())
return tr("Angle %1").arg(Angle);
return QString();
}

bool MythBDPlayer::SwitchTitle(int title)
bool MythBDPlayer::SwitchTitle(int Title)
{
if (m_playerCtx->m_buffer->BD()->IsHDMVNavigation())
return false;

uint total = GetNumTitles();
if (!total || title == GetCurrentTitle() || title >= (int)total)
int total = GetNumTitles();
if ((total < 1) || Title == GetCurrentTitle() || (Title >= total))
return false;

Pause();

bool ok = false;
if (m_playerCtx->m_buffer->BD()->SwitchTitle(title))
if (m_playerCtx->m_buffer->BD()->SwitchTitle(static_cast<uint32_t>(Title)))
{
ResetCaptions();
if (OpenFile() != 0)
Expand All @@ -303,9 +294,9 @@ bool MythBDPlayer::NextTitle(void)
if (m_playerCtx->m_buffer->BD()->IsHDMVNavigation())
return false;

uint total = GetNumTitles();
int total = GetNumTitles();
int next = GetCurrentTitle() + 1;
if (!total || next >= (int)total)
if ((total < 1) || (next >= total))
return false;

return SwitchTitle(next);
Expand All @@ -316,73 +307,64 @@ bool MythBDPlayer::PrevTitle(void)
if (m_playerCtx->m_buffer->BD()->IsHDMVNavigation())
return false;

uint total = GetNumTitles();
uint total = static_cast<uint>(GetNumTitles());
int prev = GetCurrentTitle() - 1;
if (!total || prev < 0)
return false;

return SwitchTitle(prev);
}

bool MythBDPlayer::SwitchAngle(int angle)
bool MythBDPlayer::SwitchAngle(int Angle)
{
uint total = GetNumAngles();
if (!total || angle == GetCurrentAngle())
int total = GetNumAngles();
if (!total || Angle == GetCurrentAngle())
return false;

if (angle >= (int)total)
angle = 0;
if (Angle >= total)
Angle = 0;

return m_playerCtx->m_buffer->BD()->SwitchAngle(angle);
return m_playerCtx->m_buffer->BD()->SwitchAngle(static_cast<uint>(Angle));
}

bool MythBDPlayer::NextAngle(void)
{
uint total = GetNumAngles();
int total = GetNumAngles();
int next = GetCurrentAngle() + 1;
if (!total)
if (total < 1)
return false;

if (next >= (int)total)
if (next >= total)
next = 0;

return SwitchAngle(next);
}

bool MythBDPlayer::PrevAngle(void)
{
uint total = GetNumAngles();
int total = GetNumAngles();
int prev = GetCurrentAngle() - 1;
if (!total || total == 1)
if ((total < 1) || total == 1)
return false;

if (prev < 0)
prev = total;

return SwitchAngle(prev);
}

void MythBDPlayer::SetBookmark(bool clear)
void MythBDPlayer::SetBookmark(bool Clear)
{
QStringList fields;
QString name;
QString serialid;
QString bdstate;

if (!m_playerCtx->m_buffer->IsInMenu() &&
(m_playerCtx->m_buffer->IsBookmarkAllowed() || clear))
if (!m_playerCtx->m_buffer->IsInMenu() && (m_playerCtx->m_buffer->IsBookmarkAllowed() || Clear))
{
QString name;
QString serialid;
if (!m_playerCtx->m_buffer->BD()->GetNameAndSerialNum(name, serialid))
{
LOG(VB_GENERAL, LOG_ERR, LOC +
"BD has no name and serial number. Cannot set bookmark.");
LOG(VB_GENERAL, LOG_ERR, LOC + "BD has no name and serial number. Cannot set bookmark.");
return;
}

if (!clear && !m_playerCtx->m_buffer->BD()->GetBDStateSnapshot(bdstate))
QString bdstate;
if (!Clear && !m_playerCtx->m_buffer->BD()->GetBDStateSnapshot(bdstate))
{
LOG(VB_GENERAL, LOG_ERR, LOC +
"Unable to retrieve BD state. Cannot set bookmark.");
LOG(VB_GENERAL, LOG_ERR, LOC + "Unable to retrieve BD state. Cannot set bookmark.");
return;
}

Expand All @@ -391,41 +373,42 @@ void MythBDPlayer::SetBookmark(bool clear)
m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);
if (m_playerCtx->m_playingInfo)
{
QStringList fields;
fields += serialid;
fields += name;

if (!clear)
if (!Clear)
{
LOG(VB_PLAYBACK, LOG_INFO, LOC + "Set bookmark");
fields += bdstate;
}
else
{
LOG(VB_PLAYBACK, LOG_INFO, LOC + "Clear bookmark");
}

ProgramInfo::SaveBDBookmark(fields);

}
m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
}
}

uint64_t MythBDPlayer::GetBookmark(void)
{
if (gCoreContext->IsDatabaseIgnored() || !m_playerCtx->m_buffer->IsBD())
return 0;

QString name;
QString serialid;
uint64_t frames = 0;
if (gCoreContext->IsDatabaseIgnored() || !m_playerCtx->m_buffer->IsBD())
return frames;

m_playerCtx->LockPlayingInfo(__FILE__, __LINE__);

if (m_playerCtx->m_playingInfo)
{
QString name;
QString serialid;
if (!m_playerCtx->m_buffer->BD()->GetNameAndSerialNum(name, serialid))
{
m_playerCtx->UnlockPlayingInfo(__FILE__, __LINE__);
return 0;
return frames;
}

QStringList bdbookmark = m_playerCtx->m_playingInfo->QueryBDBookmark(serialid);
Expand All @@ -442,8 +425,8 @@ uint64_t MythBDPlayer::GetBookmark(void)
return frames;;
}

void MythBDPlayer::CreateDecoder(char *testbuf, int testreadsize)
void MythBDPlayer::CreateDecoder(char *TestBuffer, int TestReadSize)
{
if (MythBDDecoder::CanHandle(testbuf, m_playerCtx->m_buffer->GetFilename(), testreadsize))
if (MythBDDecoder::CanHandle(TestBuffer, m_playerCtx->m_buffer->GetFilename(), TestReadSize))
SetDecoder(new MythBDDecoder(this, *m_playerCtx->m_playingInfo, m_playerFlags));
}
99 changes: 44 additions & 55 deletions mythtv/libs/libmythtv/Bluray/mythbdplayer.h
Original file line number Diff line number Diff line change
@@ -1,76 +1,65 @@
#ifndef MYTHBDPLAYER_H
#define MYTHBDPLAYER_H

// Qt headers
// Qt
#include <QCoreApplication>

// MythTV headers
// MythTV
#include "mythplayer.h"

class MythBDPlayer : public MythPlayer
{
Q_DECLARE_TR_FUNCTIONS(MythBDPlayer);
Q_DECLARE_TR_FUNCTIONS(MythBDPlayer)

public:
explicit MythBDPlayer(PlayerFlags flags = kNoFlags)
: MythPlayer(flags) {}
bool HasReachedEof(void) const override; // MythPlayer
bool GoToMenu(const QString& str) override; // MythPlayer
int GetNumChapters(void) override; // MythPlayer
int GetCurrentChapter(void) override; // MythPlayer
void GetChapterTimes(QList<long long> &times) override; // MythPlayer
int64_t GetChapter(int chapter) override; // MythPlayer
explicit MythBDPlayer(PlayerFlags Flags = kNoFlags);
bool HasReachedEof (void) const override;
bool GoToMenu (const QString& Menu) override;
int GetNumChapters (void) override;
int GetCurrentChapter (void) override;
void GetChapterTimes (QList<long long> &ChapterTimes) override;
int64_t GetChapter (int Chapter) override;
int GetNumTitles (void) const override;
int GetNumAngles (void) const override;
int GetCurrentTitle (void) const override;
int GetCurrentAngle (void) const override;
int GetTitleDuration (int Title) const override;
QString GetTitleName (int Title) const override;
QString GetAngleName (int Angle) const override;
bool SwitchTitle (int Title) override;
bool PrevTitle (void) override;
bool NextTitle (void) override;
bool SwitchAngle (int Angle) override;
bool PrevAngle (void) override;
bool NextAngle (void) override;
void SetBookmark (bool Clear) override;
uint64_t GetBookmark (void) override;

int GetNumTitles(void) const override; // MythPlayer
int GetNumAngles(void) const override; // MythPlayer
int GetCurrentTitle(void) const override; // MythPlayer
int GetCurrentAngle(void) const override; // MythPlayer
int GetTitleDuration(int title) const override; // MythPlayer
QString GetTitleName(int title) const override; // MythPlayer
QString GetAngleName(int angle) const override; // MythPlayer
bool SwitchTitle(int title) override; // MythPlayer
bool PrevTitle(void) override; // MythPlayer
bool NextTitle(void) override; // MythPlayer
bool SwitchAngle(int angle) override; // MythPlayer
bool PrevAngle(void) override; // MythPlayer
bool NextAngle(void) override; // MythPlayer
void SetBookmark(bool clear) override; // MythPlayer
uint64_t GetBookmark(void) override; // MythPlayer

// Non-const gets
// Disable screen grabs for Bluray
char *GetScreenGrabAtFrame(uint64_t /*frameNum*/, bool /*absolute*/,
int &/*buflen*/, int &/*vw*/, int &/*vh*/,
float &/*ar*/) override // MythPlayer
char *GetScreenGrabAtFrame(uint64_t /*FrameNum*/, bool /*Absolute*/, int &/*BufferSize*/,
int &/*FrameWidth*/, int &/*FrameHeight*/, float &/*AspectRatio*/) override
{ return nullptr; }
char *GetScreenGrab(int /*secondsin*/, int &/*bufflen*/,
int &/*vw*/, int &/*vh*/, float &/*ar*/) override // MythPlayer
char *GetScreenGrab(int /*SecondsIn*/, int &/*BufferSize*/, int &/*FrameWidth*/,
int &/*FrameHeight*/, float &/*AspectRatio*/) override
{ return nullptr; }

protected:
// Playback
void VideoStart(void) override; // MythPlayer
bool VideoLoop(void) override; // MythPlayer
void EventStart(void) override; // MythPlayer
void DisplayPauseFrame(void) override; // MythPlayer
void PreProcessNormalFrame(void) override; // MythPlayer

// Seek stuff
bool JumpToFrame(uint64_t frame) override; // MythPlayer

// Private decoder stuff
void CreateDecoder(char *testbuf, int testreadsize) override; // MythPlayer

// Non-const gets
// Disable screen grabs for Bluray
void SeekForScreenGrab(uint64_t &/*number*/, uint64_t /*frameNum*/,
bool /*absolute*/) override // MythPlayer
{}
void VideoStart (void) override;
bool VideoLoop (void) override;
void EventStart (void) override;
void DisplayPauseFrame (void) override;
void PreProcessNormalFrame(void) override;
bool JumpToFrame (uint64_t Frame) override;
void CreateDecoder (char *TestBuffer, int TestReadSize) override;
void SeekForScreenGrab (uint64_t &/*Number*/, uint64_t /*FrameNumber*/,
bool /*Absolute*/) override {}

private:
void DisplayMenu(void);
bool m_stillFrameShowing {false};
QString m_initialBDState;
Q_DISABLE_COPY(MythBDPlayer)
void DisplayMenu(void);

bool m_stillFrameShowing { false };
QString m_initialBDState;
};

#endif // MYTHBDPLAYER_H
#endif