Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

FIX: Add HD DVD detection and handling for HD DVD specific external play... #1348

Merged
2 commits merged into from

2 participants

@SlrG

Using an external player for HD DVD discs at the moment fails, because the player is called again and again in what seems to be an endless loop.

Simple reason is, that it is called for every single *.evo file on the disc, while it should be one time only.

This fix checks inserted discs for .xpl or HV.ifo files (see: http://www.dvdafteredit.com/wiki/HD_DVD_Structure) and calls the external player once.

*.xpl files inside of an ADV_OBJ folder are HD DVD playlists on discs with so called "Advanced Content". Every single disc I own has them. It seems this is the most common disc type. As XBMC isnt't able to handle these files, the best is to hand them over to an external player.

Discs with only a HVDVD_TS folder and no ADV_OBJ folder seem to be less common. In the HVDVD_TS folder there may be HV*.ifo files. They contain Video Manager, Standard Title Set or Advanced Tile Set information. Stuff that is again handled best by an external player.

So if one of these filetypes is present, a single external player call is initiated, using the name of the found file. This has advantages and drawbacks.

Advantage is, that in theory the user will be able to use different external players for the two filetypes.
Drawback is, that in this case two external player rules will be needed.

The rules could be as follows:

<rule name="HDDVDxpl" filename="D:\\.*" filetypes="xpl" player="Disc_Player"/>
<rule name="HDDVDifo" filename="HV*" filetypes="ifo" player="Disc_Player"/>

Using only the first rule will be sufficient in most cases I guess.

If no rule is defined by the user, or no .xpl or HV.ifo files are present, the internal player will be used to playback the *.evo files, like it did before.

RE: // ToDo: add logic to identify main movie
This means the fix might be enhanced in the future to improve the order the internal player handles the *.evo files. At the moment they are sorted alphabetically which often plays very small files like menus, trailer et cetera before the main movie. I tried sorting by size, but this doesn't work for all discs. Sadly the biggest file is not always the right start of the main feature. I'm still experimenting on this.

UPDATE:
Added algorithm to identify main movie.
*.evo files will be sorted alphabetically first. Then the average size of the files larger than 1gb will be calculated. Files larger than this average will be added to top of a playlist preserving their alphabetical order. They will be followed by all other files sorted by descending size. This works for all discs I own, but may fail if certain conditions apply.

If a disc contains very large extra files (larger than calculated average size) and if these files are in front of the main movie when sorted alphabetically, they will be placed on top of the playlist, too. Shouldn't happen to often I think and is still an improvement to how things are now.

@ghost

you got 20 days to crack at it. assigning to october window.

@SlrG

Added algorithm to identify main movie.

@MartijnKaijser

@cptspiff
Ready to merge?

@ghost ghost was assigned
@ghost ghost merged commit 44174fc into xbmc:master
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 15, 2012
  1. @SlrG
Commits on Sep 16, 2012
  1. @SlrG
This page is out of date. Refresh to see the latest.
Showing with 115 additions and 0 deletions.
  1. +115 −0 xbmc/Autorun.cpp
View
115 xbmc/Autorun.cpp
@@ -136,6 +136,9 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded
return false;
}
+ // Sorting necessary for easier HDDVD handling
+ vecItems.Sort(SORT_METHOD_LABEL, SortOrderAscending);
+
bool bAllowVideo = true;
// bool bAllowPictures = true;
bool bAllowMusic = true;
@@ -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
if( bRoot )
{
+ CStdString hddvdname = "";
+ CFileItemPtr phddvdItem;
+
// check root folders next, for normal structured dvd's
for (int i = 0; i < vecItems.Size(); i++)
{
@@ -198,6 +204,115 @@ bool CAutorun::RunDisc(IDirectory* pDir, const CStdString& strDrive, int& nAdded
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
CStdString strExt;
if (name.Equals("MPEGAV"))
Something went wrong with that request. Please try again.