Skip to content

Commit

Permalink
Merge pull request #1348 from SlrG/hddvdfix
Browse files Browse the repository at this point in the history
FIX: Add HD DVD detection and handling for HD DVD specific external play...
  • Loading branch information
Arne Morten Kvarving committed Oct 7, 2012
2 parents 2661fb4 + 3f9b06f commit 44174fc
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions xbmc/Autorun.cpp
Expand Up @@ -136,6 +136,9 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded
return false; return false;
} }


// Sorting necessary for easier HDDVD handling
vecItems.Sort(SORT_METHOD_LABEL, SortOrderAscending);

bool bAllowVideo = true; bool bAllowVideo = true;
// bool bAllowPictures = true; // bool bAllowPictures = true;
bool bAllowMusic = true; bool bAllowMusic = true;
Expand All @@ -149,6 +152,9 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded
// is this a root folder we have to check the content to determine a disc type // is this a root folder we have to check the content to determine a disc type
if( bRoot ) if( bRoot )
{ {
CStdString hddvdname = "";
CFileItemPtr phddvdItem;

// check root folders next, for normal structured dvd's // check root folders next, for normal structured dvd's
for (int i = 0; i < vecItems.Size(); i++) for (int i = 0; i < vecItems.Size(); i++)
{ {
Expand Down Expand Up @@ -198,6 +204,115 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded
return true; return true;
} }


// Check if the current foldername indicates a HD DVD structure (default is "HVDVD_TS").
// Most HD DVD will also include an "ADV_OBJ" folder for advanced content. This folder should be handled first.
// ToDo: for the time beeing, the DVD autorun settings are used to determine if the HD DVD should be started automatically.
CFileItemList items, sitems;

// Advanced Content HD DVD (most discs?)
if (name.Equals("ADV_OBJ"))
{
CLog::Log(LOGINFO,"HD DVD: Checking for playlist.");
// find playlist file
CDirectory::GetDirectory(pItem->GetPath(), items, "*.xpl");
if (items.Size())
{
// HD DVD Standard says the highest numbered playlist has to be handled first.
CLog::Log(LOGINFO,"HD DVD: Playlist found. Set filetypes to *.xpl for external player.");
items.Sort(SORT_METHOD_LABEL, SortOrderDescending);
phddvdItem = pItem;
hddvdname = URIUtils::GetFileName(items[0]->GetPath());
CLog::Log(LOGINFO,"HD DVD: " + items[0]->GetPath());
}
}

// Standard Content HD DVD (few discs?)
if (name.Equals("HVDVD_TS") && bAllowVideo
&& (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
{
if (hddvdname == "")
{
CLog::Log(LOGINFO,"HD DVD: Checking for ifo.");
// find Video Manager or Title Set Information
CDirectory::GetDirectory(pItem->GetPath(), items, "HV*.ifo");
if (items.Size())
{
// HD DVD Standard says the lowest numbered ifo has to be handled first.
CLog::Log(LOGINFO,"HD DVD: IFO found. Set filename to HV* and filetypes to *.ifo for external player.");
items.Sort(SORT_METHOD_LABEL, SortOrderAscending);
phddvdItem = pItem;
hddvdname = URIUtils::GetFileName(items[0]->GetPath());
CLog::Log(LOGINFO,"HD DVD: " + items[0]->GetPath());
}
}
// Find and sort *.evo files for internal playback.
// While this algorithm works for all of my HD DVDs, it may fail on other discs. If there are very large extras which are
// alphabetically before the main movie they will be sorted to the top of the playlist and get played first.
CDirectory::GetDirectory(pItem->GetPath(), items, "*.evo");
if (items.Size())
{
// Sort *.evo files in alphabetical order.
items.Sort(SORT_METHOD_LABEL, SortOrderAscending);
int64_t asize = 0;
int ecount = 0;
// calculate average size of elements above 1gb
for (int j = 0; j < items.Size(); j++)
if (items[j]->m_dwSize > 1000000000)
{
ecount++;
asize = asize + items[j]->m_dwSize;
}
asize = asize / ecount;
// Put largest files in alphabetical order to top of new list.
for (int j = 0; j < items.Size(); j++)
if (items[j]->m_dwSize >= asize)
sitems.Add (items[j]);
// Sort *.evo files by size.
items.Sort(SORT_METHOD_SIZE, SortOrderDescending);
// Add other files with descending size to bottom of new list.
for (int j = 0; j < items.Size(); j++)
if (items[j]->m_dwSize < asize)
sitems.Add (items[j]);
// Replace list with optimized list.
items.Clear();
items.Copy (sitems);
sitems.Clear();
}
if (hddvdname != "")
{
CFileItem item(URIUtils::AddFileToFolder(phddvdItem->GetPath(), hddvdname), false);
item.SetLabel(g_mediaManager.GetDiskLabel(strDrive));
item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty())
item.m_lStartOffset = STARTOFFSET_RESUME;

// get playername
CStdString hddvdplayer = CPlayerCoreFactory::GetPlayerName(CPlayerCoreFactory::GetDefaultPlayer(item));

// Single *.xpl or *.ifo files require an external player to handle playback.
// If no matching rule was found, DVDPlayer will be default player.
if (hddvdplayer != "DVDPlayer")
{
CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: "+ hddvdname);
g_application.PlayFile(item, false);
bPlaying = true;
return true;
} else
CLog::Log(LOGINFO,"HD DVD: No external player found. Fallback to internal one.");
}

// internal *.evo playback.
CLog::Log(LOGINFO,"HD DVD: Internal multifile playback initiated.");
g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
g_playlistPlayer.Play(0);
bPlaying = true;
return true;
}

// Video CDs can have multiple file formats. First we need to determine which one is used on the CD // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
CStdString strExt; CStdString strExt;
if (name.Equals("MPEGAV")) if (name.Equals("MPEGAV"))
Expand Down

0 comments on commit 44174fc

Please sign in to comment.