Skip to content
Permalink
Browse files

Enable local playback of video files.

- Extend ProgramInfo::GetPlaybackURL to check whether the underlying
video file is local or not and use the local path if available. The
logic for selecting local playback mirrors the existing recording logic.

- Refactor RingBuffer::Create to check local paths for the correct DVD
and bluray directory structures.

The main benefit here is a sizeable performance improvement when using
local playback for bluray and dvd.
  • Loading branch information
Mark Kendall
Mark Kendall committed May 20, 2011
1 parent ee692b1 commit f7d050b80731dbd1d7a42840041c7ad9032256a4
Showing with 61 additions and 57 deletions.
  1. +36 −4 mythtv/libs/libmyth/programinfo.cpp
  2. +24 −43 mythtv/libs/libmythtv/ringbuffer.cpp
  3. +1 −10 mythtv/libs/libmythtv/tv_play.cpp
@@ -1994,15 +1994,47 @@ QString ProgramInfo::QueryBasename(void) const
QString ProgramInfo::GetPlaybackURL(
bool checkMaster, bool forceCheckLocal) const
{
QString tmpURL;
QString basename = QueryBasename();

if (basename.isEmpty())
return "";

bool alwaysStream = gCoreContext->GetNumSetting("AlwaysStreamFiles", 0);
bool checklocal = !gCoreContext->GetNumSetting("AlwaysStreamFiles", 0) ||
forceCheckLocal;

if ((!alwaysStream) || (forceCheckLocal))
if (IsVideo())
{
QString fullpath = GetPathname();
if (!fullpath.startsWith("myth://", Qt::CaseInsensitive) || !checklocal)
return fullpath;

QUrl url = QUrl(fullpath);
QString path = url.path();
QString host = url.toString(QUrl::RemovePath).mid(7);
QStringList list = host.split(":", QString::SkipEmptyParts);
if (list.size())
{
host = list[0];
list = host.split("@", QString::SkipEmptyParts);
QString group;
if (list.size() > 0 && list.size() < 3)
{
host = list.size() == 1 ? list[0] : list[1];
group = list.size() == 1 ? QString() : list[0];
StorageGroup *sg = new StorageGroup(group, host);
if (sg)
{
QString local = sg->FindFile(path);
if (!local.isEmpty())
if (sg->FileExists(local))
return local;
}
}
}
return fullpath;
}

QString tmpURL;
if (checklocal)
{
// Check to see if the file exists locally
StorageGroup sgroup(storagegroup);
@@ -99,85 +99,66 @@ RingBuffer *RingBuffer::Create(
QString lfilename = xfilename;

if (write)
{
return new FileRingBuffer(
lfilename, write, usereadahead, timeout_ms);
}
return new FileRingBuffer(lfilename, write, usereadahead, timeout_ms);

bool is_dvd = false;
bool is_bd = false;
bool dvddir = false;
bool bddir = false;
bool httpurl = lfilename.startsWith("http://");
bool mythurl = lfilename.startsWith("myth://");
bool bdurl = lfilename.startsWith("bd:");
bool dvdurl = lfilename.startsWith("dvd:");
bool dvdext = lfilename.endsWith(".img") || lfilename.endsWith(".iso");

if (lfilename.startsWith("http://"))
{
if (httpurl)
return new StreamingRingBuffer(lfilename);
}

if (!stream_only && lfilename.startsWith("myth://"))
if (!stream_only && mythurl)
{
struct stat fileInfo;
if ((RemoteFile::Exists(lfilename, &fileInfo)) &&
(S_ISDIR(fileInfo.st_mode)))
{
QString tmpFile = lfilename + "/VIDEO_TS";
if (RemoteFile::Exists(tmpFile))
{
is_dvd = true;
}
else
{
tmpFile = lfilename + "/BDMV";
if (RemoteFile::Exists(tmpFile))
is_bd = true;
}
if (RemoteFile::Exists(lfilename + "/VIDEO_TS"))
dvddir = true;
else if (RemoteFile::Exists(lfilename + "/BDMV"))
bddir = true;
}
}

if ((lfilename.left(1) == "/") || (QFile::exists(lfilename)))
else if (!stream_only && !mythurl)
{
if (QFile::exists(lfilename + "/VIDEO_TS"))
dvddir = true;
else if (QFile::exists(lfilename + "/BDMV"))
bddir = true;
}
else if ((!stream_only) &&
((lfilename.startsWith("dvd:")) || is_dvd ||
((lfilename.startsWith("myth://")) &&
((lfilename.endsWith(".img")) ||
(lfilename.endsWith(".iso"))))))
{
is_dvd = true;

if (!stream_only && (dvdurl || dvddir || dvdext))
{
if (lfilename.left(6) == "dvd://") // 'Play DVD' sends "dvd:/" + dev
lfilename.remove(0,5); // e.g. "dvd://dev/sda"
else if (lfilename.left(5) == "dvd:/") // Less correct URI "dvd:" + path
lfilename.remove(0,4); // e.g. "dvd:/videos/ET"
else if (lfilename.left(4) == "dvd:") // Win32 URI "dvd:" + abs path
lfilename.remove(0,4); // e.g. "dvd:D:\"

if (QFile::exists(lfilename) || lfilename.startsWith("myth://"))
{
if (mythurl || QFile::exists(lfilename))
VERBOSE(VB_PLAYBACK, "Trying DVD at " + lfilename);
}
else
{
lfilename = "/dev/dvd";
}

return new DVDRingBuffer(lfilename);
}
else if ((!stream_only) && (lfilename.left(3) == "bd:" || is_bd))
else if (!stream_only && (bdurl || bddir))
{
is_bd = true;

if (lfilename.left(5) == "bd://") // 'Play DVD' sends "bd:/" + dev
lfilename.remove(0,4); // e.g. "bd://dev/sda"
else if (lfilename.left(4) == "bd:/") // Less correct URI "bd:" + path
lfilename.remove(0,3); // e.g. "bd:/videos/ET"

if (QFile::exists(lfilename) || lfilename.startsWith("myth://"))
{
if (mythurl || QFile::exists(lfilename))
VERBOSE(VB_PLAYBACK, "Trying BD at " + lfilename);
}
else
{
lfilename = "/dev/dvd";
}

return new BDRingBuffer(lfilename);
}
@@ -1941,16 +1941,7 @@ void TV::HandleStateChange(PlayerContext *mctx, PlayerContext *ctx)
TRANSITION(kState_None, kState_WatchingRecording))
{
ctx->LockPlayingInfo(__FILE__, __LINE__);
QString playbackURL;
if (ctx->playingInfo->IsRecording())
{
playbackURL = ctx->playingInfo->GetPlaybackURL(true);
}
else
{
playbackURL = ctx->playingInfo->GetPathname();
playbackURL.detach();
}
QString playbackURL = ctx->playingInfo->GetPlaybackURL(true);
ctx->UnlockPlayingInfo(__FILE__, __LINE__);

ctx->SetRingBuffer(RingBuffer::Create(playbackURL, false));

0 comments on commit f7d050b

Please sign in to comment.
You can’t perform that action at this time.