Skip to content

Commit

Permalink
move new code to its own source file ApplicationStackHelper.cpp/.h
Browse files Browse the repository at this point in the history
  • Loading branch information
Voyager1 committed Dec 28, 2017
1 parent 3e9f8a0 commit d90d11d
Show file tree
Hide file tree
Showing 5 changed files with 508 additions and 453 deletions.
268 changes: 0 additions & 268 deletions xbmc/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4995,271 +4995,3 @@ bool CApplication::NotifyActionListeners(const CAction &action) const

return false;
}

CApplicationStackHelper::CApplicationStackHelper(void)
: m_currentStack(new CFileItemList)
, m_currentStackPosition(0)
, m_currentStackIsDiscImageStack(false)
{
}

CApplicationStackHelper::~CApplicationStackHelper(void)
{
}

void CApplicationStackHelper::Clear()
{
m_currentStackPosition = 0;
m_currentStack->Clear();
}

void CApplicationStackHelper::OnPlayBackStarted(const CFileItem& item)
{
CSingleLock lock(m_critSection);

// time to clean up stack map
if (!HasRegisteredStack(item))
m_stackmap.clear();
else
{
CFileItemPtr stack = GetRegisteredStack(item);
Stackmap::iterator itr = m_stackmap.begin();
while (itr != m_stackmap.end())
{
if (itr->second->m_pStack != stack)
{
itr = m_stackmap.erase(itr);
}
else
{
++itr;
}
}
}
return;
}

bool CApplicationStackHelper::InitializeStack(const CFileItem & item)
{
if (!item.IsStack())
return false;

CFileItemPtr stack(new CFileItem(item));

Clear();
// read and determine kind of stack
CStackDirectory dir;
if (!dir.GetDirectory(item.GetURL(), *m_currentStack) || m_currentStack->IsEmpty())
return false;
for (int i = 0; i < m_currentStack->Size(); i++)
{
// keep cross-references between stack parts and the stack
SetRegisteredStack(GetStackPartFileItem(i), stack);
SetRegisteredStackPartNumber(GetStackPartFileItem(i), i);
}
m_currentStackIsDiscImageStack = CFileItem(CStackDirectory::GetFirstStackedFile(item.GetPath()), false).IsDiscImage();

return true;
}

int CApplicationStackHelper::InitializeStackStartPartAndOffset(const CFileItem& item)
{
CVideoDatabase dbs;
int startoffset = 0;

// case 1: stacked ISOs
if (m_currentStackIsDiscImageStack)
{
// first assume values passed to the stack
int selectedFile = item.m_lStartPartNumber;
startoffset = item.m_lStartOffset;

// check if we instructed the stack to resume from default
if (startoffset == STARTOFFSET_RESUME) // selected file is not specified, pick the 'last' resume point
{
if (dbs.Open())
{
CBookmark bookmark;
std::string path = item.GetPath();
if (item.HasProperty("original_listitem_url") && URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
path = item.GetProperty("original_listitem_url").asString();
if (dbs.GetResumeBookMark(path, bookmark))
{
startoffset = (int)(bookmark.timeInSeconds * 75);
selectedFile = bookmark.partNumber;
}
dbs.Close();
}
else
CLog::LogF(LOGERROR, "Cannot open VideoDatabase");
}

// make sure that the selected part is within the boundaries
if (selectedFile <= 0)
{
CLog::LogF(LOGWARNING, "Selected part %d out of range, playing part 1", selectedFile);
selectedFile = 1;
}
else if (selectedFile > m_currentStack->Size())
{
CLog::LogF(LOGWARNING, "Selected part %d out of range, playing part %d", selectedFile, m_currentStack->Size());
selectedFile = m_currentStack->Size();
}

// set startoffset in selected item, track stack item for updating purposes, and finally play disc part
m_currentStackPosition = selectedFile - 1;
startoffset = startoffset > 0 ? STARTOFFSET_RESUME : 0;
}
// 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.
std::vector<int> times;
bool haveTimes(false);

if (dbs.Open())
{
haveTimes = dbs.GetStackTimes(item.GetPath(), times);
dbs.Close();
}

// calculate the total time of the stack
long totalTime = 0;
for (int i = 0; i < m_currentStack->Size(); i++)
{
if (haveTimes)
{
// set end time in every part
GetStackPartFileItem(i).m_lEndOffset = times[i];
}
else
{
int duration;
if (!CDVDFileInfo::GetFileDuration(GetStackPartFileItem(i).GetPath(), duration))
{
m_currentStack->Clear();
return PLAYBACK_FAIL;
}
totalTime += duration / 1000;
// set end time in every part
GetStackPartFileItem(i).m_lEndOffset = totalTime;
times.push_back(totalTime);
}
// set start time in every part
SetRegisteredStackPartStartTime(GetStackPartFileItem(i), GetStackPartStartTime(i));
}
// set total time in every part
totalTime = GetStackTotalTime();
for (int i = 0; i < m_currentStack->Size(); i++)
SetRegisteredStackTotalTime(GetStackPartFileItem(i), totalTime);

double seconds = item.m_lStartOffset / 75.0;

if (!haveTimes || item.m_lStartOffset == STARTOFFSET_RESUME)
{
if (dbs.Open())
{
// have our times now, so update the dB
if (!haveTimes && !times.empty())
dbs.SetStackTimes(item.GetPath(), times);

if (item.m_lStartOffset == STARTOFFSET_RESUME)
{
// can only resume seek here, not dvdstate
CBookmark bookmark;
std::string path = item.GetPath();
if (item.HasProperty("original_listitem_url") && URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
path = item.GetProperty("original_listitem_url").asString();
if (dbs.GetResumeBookMark(path, bookmark))
seconds = bookmark.timeInSeconds;
else
seconds = 0.0f;
}
dbs.Close();
}
}

m_currentStackPosition = GetStackPartNumberAtTime(seconds);
startoffset = (seconds - GetStackPartStartTime(m_currentStackPosition)) * 75;
}
return startoffset;
}

int CApplicationStackHelper::GetStackPartNumberAtTime(double seconds)
{
if (seconds > 0)
{
// work out where to seek to
for (int partNumber = 0; partNumber < m_currentStack->Size(); partNumber++)
{
if (seconds < GetStackPartEndTime(partNumber))
return partNumber;
}
}
return 0;
}

void CApplicationStackHelper::ClearAllRegisteredStackInformation()
{
m_stackmap.clear();
}

CFileItemPtr CApplicationStackHelper::GetRegisteredStack(const CFileItem& item)
{
return GetStackPartInformation(item.GetPath())->m_pStack;
}

bool CApplicationStackHelper::HasRegisteredStack(const CFileItem & item)
{
return (m_stackmap.count(item.GetPath()) > 0 && m_stackmap[item.GetPath()]->m_pStack != nullptr);
}

void CApplicationStackHelper::SetRegisteredStack(const CFileItem& item, CFileItemPtr stackItem)
{
GetStackPartInformation(item.GetPath())->m_pStack = stackItem;
}

int CApplicationStackHelper::GetRegisteredStackPartNumber(const CFileItem& item)
{
return GetStackPartInformation(item.GetPath())->m_lStackPartNumber;
}

void CApplicationStackHelper::SetRegisteredStackPartNumber(const CFileItem& item, int partNumber)
{
GetStackPartInformation(item.GetPath())->m_lStackPartNumber = partNumber;
}

int CApplicationStackHelper::GetRegisteredStackPartStartTime(const CFileItem& item)
{
return GetStackPartInformation(item.GetPath())->m_lStackPartStartTime;
}

void CApplicationStackHelper::SetRegisteredStackPartStartTime(const CFileItem& item, int startTime)
{
GetStackPartInformation(item.GetPath())->m_lStackPartStartTime = startTime;
}

int CApplicationStackHelper::GetRegisteredStackTotalTime(const CFileItem& item)
{
return GetStackPartInformation(item.GetPath())->m_lStackTotalTime;
}

void CApplicationStackHelper::SetRegisteredStackTotalTime(const CFileItem& item, int totalTime)
{
GetStackPartInformation(item.GetPath())->m_lStackTotalTime = totalTime;
}

CApplicationStackHelper::StackPartInformationPtr CApplicationStackHelper::GetStackPartInformation(std::string key)
{
if (m_stackmap.count(key) == 0)
{
StackPartInformationPtr value (new StackPartInformation());
m_stackmap[key] = value;
}
return m_stackmap[key];
}
Loading

0 comments on commit d90d11d

Please sign in to comment.