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.