Skip to content

Commit

Permalink
allow resume on selected part of stack & stacking issues fix
Browse files Browse the repository at this point in the history
stacking dialog in GUIWindowVideoBase - code generalization in CApp::PlayStack
clean up GetResumeItemString to use offset value from GetResumeItemOffset (for iso stacks)
  • Loading branch information
Voyager-xbmc committed Apr 3, 2012
1 parent e0a1d73 commit 0107c01
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 202 deletions.
159 changes: 97 additions & 62 deletions xbmc/Application.cpp
Expand Up @@ -3556,88 +3556,123 @@ bool CApplication::PlayStack(const CFileItem& item, bool bRestart)
if (!item.IsStack())
return false;

// see if we have the info in the database
// TODO: If user changes the time speed (FPS via framerate conversion stuff)
// then these times will be wrong.
// Also, this is really just a hack for the slow load up times we have
// A much better solution is a fast reader of FPS and fileLength
// that we can use on a file to get it's time.
vector<int> times;
bool haveTimes(false);
CVideoDatabase dbs;
if (dbs.Open())

// case 1: stacked ISOs
if (CFileItem(CStackDirectory::GetFirstStackedFile(item.GetPath()),false).IsDVDImage())
{
dbs.GetVideoSettings(item.GetPath(), g_settings.m_currentVideoSettings);
haveTimes = dbs.GetStackTimes(item.GetPath(), times);
dbs.Close();
}
CStackDirectory dir;
CFileItemList movieList;
dir.GetDirectory(item.GetPath(), movieList);

int selectedFile = 1; // if playing from beginning, play file 1.
long startoffset = item.m_lStartOffset;

// calculate the total time of the stack
CStackDirectory dir;
dir.GetDirectory(item.GetPath(), *m_currentStack);
long totalTime = 0;
for (int i = 0; i < m_currentStack->Size(); i++)
{
if (haveTimes)
(*m_currentStack)[i]->m_lEndOffset = times[i];
else
// We instructed the stack to resume.
if (startoffset == STARTOFFSET_RESUME) // selected file is not specified, pick the 'last' resume point
startoffset = CGUIWindowVideoBase::GetResumeItemOffset(&item);

if (startoffset & 0xF0000000) /* selected part is specified as a flag */
{
int duration;
if (!CDVDFileInfo::GetFileDuration((*m_currentStack)[i]->GetPath(), duration))
{
m_currentStack->Clear();
return false;
}
totalTime += duration / 1000;
(*m_currentStack)[i]->m_lEndOffset = totalTime;
times.push_back(totalTime);
}
}
selectedFile = (startoffset>>28);
startoffset = startoffset & ~0xF0000000;

double seconds = item.m_lStartOffset / 75.0;
// set startoffset in movieitem. The remaining startoffset is either 0 (just play part from beginning) or positive (then we use STARTOFFSET_RESUME).
if (selectedFile > 0 && selectedFile <= (int)movieList.Size())
movieList[selectedFile - 1]->m_lStartOffset = startoffset > 0 ? STARTOFFSET_RESUME : 0;
}

if (!haveTimes || item.m_lStartOffset == STARTOFFSET_RESUME )
{ // have our times now, so update the dB
// finally play selected item
if (selectedFile > 0 && selectedFile <= (int)movieList.Size())
return PlayFile(*(movieList[selectedFile - 1]));
}
// case 2: all other stacks
else
{
// see if we have the info in the database
// TODO: If user changes the time speed (FPS via framerate conversion stuff)
// then these times will be wrong.
// Also, this is really just a hack for the slow load up times we have
// A much better solution is a fast reader of FPS and fileLength
// that we can use on a file to get it's time.
vector<int> times;
bool haveTimes(false);
CVideoDatabase dbs;
if (dbs.Open())
{
if( !haveTimes )
dbs.SetStackTimes(item.GetPath(), times);
dbs.GetVideoSettings(item.GetPath(), g_settings.m_currentVideoSettings);
haveTimes = dbs.GetStackTimes(item.GetPath(), times);
dbs.Close();
}

if( item.m_lStartOffset == STARTOFFSET_RESUME )

// calculate the total time of the stack
CStackDirectory dir;
dir.GetDirectory(item.GetPath(), *m_currentStack);
long totalTime = 0;
for (int i = 0; i < m_currentStack->Size(); i++)
{
if (haveTimes)
(*m_currentStack)[i]->m_lEndOffset = times[i];
else
{
// can only resume seek here, not dvdstate
CBookmark bookmark;
if( dbs.GetResumeBookMark(item.GetPath(), bookmark) )
seconds = bookmark.timeInSeconds;
else
seconds = 0.0f;
int duration;
if (!CDVDFileInfo::GetFileDuration((*m_currentStack)[i]->GetPath(), duration))
{
m_currentStack->Clear();
return false;
}
totalTime += duration / 1000;
(*m_currentStack)[i]->m_lEndOffset = totalTime;
times.push_back(totalTime);
}
dbs.Close();
}
}

*m_itemCurrentFile = item;
m_currentStackPosition = 0;
m_eCurrentPlayer = EPC_NONE; // must be reset on initial play otherwise last player will be used
double seconds = item.m_lStartOffset / 75.0;

if (seconds > 0)
{
// work out where to seek to
for (int i = 0; i < m_currentStack->Size(); i++)
if (!haveTimes || item.m_lStartOffset == STARTOFFSET_RESUME )
{ // have our times now, so update the dB
if (dbs.Open())
{
if( !haveTimes )
dbs.SetStackTimes(item.GetPath(), times);

if( item.m_lStartOffset == STARTOFFSET_RESUME )
{
// can only resume seek here, not dvdstate
CBookmark bookmark;
if( dbs.GetResumeBookMark(item.GetPath(), bookmark) )
seconds = bookmark.timeInSeconds;
else
seconds = 0.0f;
}
dbs.Close();
}
}

*m_itemCurrentFile = item;
m_currentStackPosition = 0;
m_eCurrentPlayer = EPC_NONE; // must be reset on initial play otherwise last player will be used

if (seconds > 0)
{
if (seconds < (*m_currentStack)[i]->m_lEndOffset)
// work out where to seek to
for (int i = 0; i < m_currentStack->Size(); i++)
{
CFileItem item(*(*m_currentStack)[i]);
long start = (i > 0) ? (*m_currentStack)[i-1]->m_lEndOffset : 0;
item.m_lStartOffset = (long)(seconds - start) * 75;
m_currentStackPosition = i;
return PlayFile(item, true);
if (seconds < (*m_currentStack)[i]->m_lEndOffset)
{
CFileItem item(*(*m_currentStack)[i]);
long start = (i > 0) ? (*m_currentStack)[i-1]->m_lEndOffset : 0;
item.m_lStartOffset = (long)(seconds - start) * 75;
m_currentStackPosition = i;
return PlayFile(item, true);
}
}
}
}

return PlayFile(*(*m_currentStack)[0], true);
return PlayFile(*(*m_currentStack)[0], true);
}
return false;
}

bool CApplication::PlayFile(const CFileItem& item, bool bRestart)
Expand Down
1 change: 0 additions & 1 deletion xbmc/settings/GUISettings.cpp
Expand Up @@ -707,7 +707,6 @@ void CGUISettings::Initialize()
myVideosSelectActions.insert(make_pair(22081, SELECT_ACTION_INFO));

AddInt(vid, "myvideos.selectaction", 22079, SELECT_ACTION_PLAY_OR_RESUME, myVideosSelectActions, SPIN_CONTROL_TEXT);
AddBool(NULL, "myvideos.treatstackasfile", 20051, true);
AddBool(vid, "myvideos.extractflags",20433, true);
AddBool(vid, "myvideos.replacelabels", 20419, true);
AddBool(NULL, "myvideos.extractthumb",20433, true);
Expand Down
3 changes: 2 additions & 1 deletion xbmc/settings/GUISettings.h
Expand Up @@ -186,7 +186,8 @@ enum VideoSelectAction
SELECT_ACTION_RESUME,
SELECT_ACTION_INFO,
SELECT_ACTION_MORE,
SELECT_ACTION_PLAY
SELECT_ACTION_PLAY,
SELECT_ACTION_PLAYPART
};

enum SubtitleAlign
Expand Down

0 comments on commit 0107c01

Please sign in to comment.