Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Cleanup ISO stack resume code #1099

Merged
merged 2 commits into from

3 participants

@Voyager1
Collaborator

this pull request addresses a number of things in the sphere of resume-play of ISO stacks.

1) move the intelligence down from GUIWindowVideoBase to the VideoDatabase. All we need to know in the GUIWindowVideoBase is what to do with a Bookmark that contains a partnumber > 0.
The VideoDatabase methods GetBookmarksForFile and GetResumePoint know how to deal with ISO stacks now, which makes the code more reusable for non-GUI callers.

2) the resume "flag" as well as "percent complete" for an ISO stack (the little white triangle in Confluence lists) now correctly shows. This was not the case due to the VideoInfoTag resume bookmark not set (prior to the code changes described above in 1). The rule is that the bookmark of the "highest" part counts.

3) additional code cleanup and refactoring - see comments below.

@theuni
Owner

Not my area of code to comment on, but kudos on splitting out the whitespace. That makes all the difference for review.

@Voyager1
Collaborator

I've added more commits:

  • moving the GetResumeItemOffset code to a more logical place i.e. VideoDatabase. This way Application doesn't have to call GUIWindowVideoBase any longer
  • got rid of the crazy bit manipulation to code the part number as part of the startoffset.
@Voyager1
Collaborator

the work is done. I've added one final commit to make sure the SaveFileStateJob properly updates the list. The reason is that for an ISO stack, the current item is actually the part being played, which in itself does not show up in the library list. Therefore, we need to notify the list to update that stack item. Otherwise, we have unexpected results with a bookmark of the "wrong part" being used (unless you reload the list by stepping out and coming back).

@jmarshallnz
Owner

On the whole it looks nice. Please squash down the fixup commits and I'll give it another going over.

The only thing I don't particularly like is the non-videodb code in the videodatabase. Not sure if there's a "nice" way to deal with that though.

@Voyager1
Collaborator

hi jmarshall - thanks for the code review. I've addressed the pointer comment and retested the code. Commits are squashed.

Regarding the videodatabase code, I agree, I've used Directory/FileItem classes to parse out the stack parts and also there's two new methods that take FileItem ptrs as arguments (the code copied down from GUIWindowVideoBase). The only way I see is to pass a VideoInfoTag instead of a FileItem ptr. But I would then have to move some checking code back to GUIWindowVideoBase (and wherever else this is called).

@Voyager1
Collaborator

any other comments - if not, can we assign it to the July milestone?

@Voyager1
Collaborator

@jmarshallnz - I've addressed all your comments (I believe).

  • The missing delete is addressed through a smart pointer, consistent with other code.
  • The vector is now cleared using clear()
  • The CApplication member (now protected) is no longer read by another thread, but passed by value to the savefilestatejob.

note: I rebased & left this for your review as a separate commit. When you're ok with final code, I'll squash before you pull.

@jmarshallnz
Owner

Fixes look OK - rebase down and I'll give it another overview in case I've missed a simpler way to do it (I don't think so though - ISO stacks are really messy)

@Voyager1
Collaborator

@jmarshallnz - done - rebased and squashed (except indentations for easy review)

@jmarshallnz
Owner

Ok, the code looks OK, but I really think the two new functions to VideoDatabase don't really belong there - eg GetResumeItemOffset has a path that doesn't hit the db at all (and thus HasResumeItemOffset also has such a path).

IMO having those as statics in VideoBase seems just as reasonable - the only addition I think would be some videodb open/closing internal to GetResumeItemOffset, rather than being external?

@Voyager1
Collaborator

@jmarshallnz - once again, done.

@jmarshallnz
Owner

Forget to push?

@Voyager1
Collaborator

no, it's all there. See commit 02eff8f

@jmarshallnz
Owner

Sorry, I wasn't clear (thus didn't notice the difference) - the two statics should be in CGUIWindowVideoBase rather than CVideoDatabase.

@Voyager1
Collaborator

ah. The whole point was move them out of CGUIWindowVideoBase because CApplication calls them. I don't like that, as it violates the layering.
EDIT:
let me know if you prefer CApplication calling CGUIWindowVideoBase - I can make that change but it wouldn't make me happy :-(

@Voyager1
Collaborator

I could also move the code back to CGUIWindowVideoBase as you suggest and have CApplication call a stripped down version of it (essentially the part that gets the Bookmark from the VideoDatabase. That would probably be the best way overall.

@Voyager1
Collaborator

@jmarshallnz - once again, I have implemented your comments, I believe it must be ready for pulling now ;-)

@jmarshallnz
Owner

Looks good.

@jmarshallnz jmarshallnz merged commit 76f766f into xbmc:master
@Voyager1 Voyager1 deleted the Voyager1:cleanup-resume-iso-stack-code branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 5, 2012
  1. clean up resume play for stacked ISO files

    Voyager-xbmc authored
This page is out of date. Refresh to see the latest.
View
38 xbmc/Application.cpp
@@ -370,6 +370,7 @@ CApplication::CApplication(void)
#endif
#endif
, m_itemCurrentFile(new CFileItem)
+ , m_stackFileItemToUpdate(new CFileItem)
, m_progressTrackingVideoResumeBookmark(*new CBookmark)
, m_progressTrackingItem(new CFileItem)
, m_videoInfoScanner(new CVideoInfoScanner)
@@ -3605,26 +3606,35 @@ bool CApplication::PlayStack(const CFileItem& item, bool bRestart)
CFileItemList movieList;
dir.GetDirectory(item.GetPath(), movieList);
- int selectedFile = 1; // if playing from beginning, play file 1.
- long startoffset = item.m_lStartOffset;
+ // first assume values passed to the stack
+ int selectedFile = item.m_lStartPartNumber;
+ int startoffset = item.m_lStartOffset;
- // We instructed the stack to resume.
+ // check if we instructed the stack to resume from default
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 */
{
- selectedFile = (startoffset>>28);
- startoffset = startoffset & ~0xF0000000;
-
- // 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 (dbs.Open())
+ {
+ CBookmark bookmark;
+ if (dbs.GetResumeBookMark(item.GetPath(), bookmark))
+ {
+ startoffset = (int)(bookmark.timeInSeconds*75);
+ selectedFile = bookmark.partNumber;
+ }
+ dbs.Close();
+ }
+ else
+ CLog::Log(LOGERROR, "%s - Cannot open VideoDatabase", __FUNCTION__);
}
- // finally play selected item
+ // set startoffset in movieitem, track stack item for updating purposes, and finally play disc part
if (selectedFile > 0 && selectedFile <= (int)movieList.Size())
+ {
+ movieList[selectedFile - 1]->m_lStartOffset = startoffset > 0 ? STARTOFFSET_RESUME : 0;
+ movieList[selectedFile - 1]->SetProperty("stackFileItemToUpdate", true);
+ *m_stackFileItemToUpdate = item;
return PlayFile(*(movieList[selectedFile - 1]));
+ }
}
// case 2: all other stacks
else
@@ -4290,6 +4300,7 @@ void CApplication::SaveFileState(bool bForeground /* = false */)
if (bForeground)
{
CSaveFileStateJob job(*m_progressTrackingItem,
+ *m_stackFileItemToUpdate,
m_progressTrackingVideoResumeBookmark,
m_progressTrackingPlayCountUpdate);
@@ -4299,6 +4310,7 @@ void CApplication::SaveFileState(bool bForeground /* = false */)
else
{
CJob* job = new CSaveFileStateJob(*m_progressTrackingItem,
+ *m_stackFileItemToUpdate,
m_progressTrackingVideoResumeBookmark,
m_progressTrackingPlayCountUpdate);
CJobManager::GetInstance().AddJob(job, NULL);
View
2  xbmc/Application.h
@@ -370,6 +370,8 @@ class CApplication : public CXBApplicationEx, public IPlayerCallback, public IMs
CFileItemPtr m_itemCurrentFile;
CFileItemList* m_currentStack;
+ CFileItemPtr m_stackFileItemToUpdate;
+
CStdString m_prevMedia;
CSplash* m_splash;
ThreadIdentifier m_threadID; // application thread ID. Used in applicationMessanger to know where we are firing a thread with delay from.
View
5 xbmc/FileItem.cpp
@@ -74,6 +74,7 @@ CFileItem::CFileItem(const CSong& song)
m_strPath = song.strFileName;
GetMusicInfoTag()->SetSong(song);
m_lStartOffset = song.iStartOffset;
+ m_lStartPartNumber = 0;
SetProperty("item_start", song.iStartOffset);
m_lEndOffset = song.iEndOffset;
m_strThumbnailImage = song.strThumb;
@@ -297,6 +298,7 @@ const CFileItem& CFileItem::operator=(const CFileItem& item)
}
m_lStartOffset = item.m_lStartOffset;
+ m_lStartPartNumber = item.m_lStartPartNumber;
m_lEndOffset = item.m_lEndOffset;
m_strDVDLabel = item.m_strDVDLabel;
m_strTitle = item.m_strTitle;
@@ -333,6 +335,7 @@ void CFileItem::Reset()
m_dateTime.Reset();
m_iDriveType = CMediaSource::SOURCE_TYPE_UNKNOWN;
m_lStartOffset = 0;
+ m_lStartPartNumber = 0;
m_lEndOffset = 0;
m_iprogramCount = 0;
m_idepth = 1;
@@ -371,6 +374,7 @@ void CFileItem::Archive(CArchive& ar)
ar << m_iprogramCount;
ar << m_idepth;
ar << m_lStartOffset;
+ ar << m_lStartPartNumber;
ar << m_lEndOffset;
ar << m_iLockMode;
ar << m_strLockCode;
@@ -417,6 +421,7 @@ void CFileItem::Archive(CArchive& ar)
ar >> m_iprogramCount;
ar >> m_idepth;
ar >> m_lStartOffset;
+ ar >> m_lStartPartNumber;
ar >> m_lEndOffset;
int temp;
ar >> temp;
View
1  xbmc/FileItem.h
@@ -310,6 +310,7 @@ class CFileItem :
int m_iprogramCount;
int m_idepth;
int m_lStartOffset;
+ int m_lStartPartNumber;
int m_lEndOffset;
LockType m_iLockMode;
CStdString m_strLockCode;
View
2  xbmc/dialogs/GUIDialogContextMenu.cpp
@@ -308,7 +308,7 @@ void CGUIDialogContextMenu::GetContextButtons(const CStdString &type, const CFil
{
// We need to check if there is a detected is inserted!
buttons.Add(CONTEXT_BUTTON_PLAY_DISC, 341); // Play CD/DVD!
- if (CGUIWindowVideoBase::GetResumeItemOffset(item.get()) > 0)
+ if (CGUIWindowVideoBase::HasResumeItemOffset(item.get()))
buttons.Add(CONTEXT_BUTTON_RESUME_DISC, CGUIWindowVideoBase::GetResumeString(*(item.get()))); // Resume Disc
buttons.Add(CONTEXT_BUTTON_EJECT_DISC, 13391); // Eject/Load CD/DVD!
View
9 xbmc/utils/SaveFileStateJob.h
@@ -8,13 +8,16 @@
class CSaveFileStateJob : public CJob
{
CFileItem m_item;
+ CFileItem m_item_discstack;
CBookmark m_bookmark;
bool m_updatePlayCount;
public:
CSaveFileStateJob(const CFileItem& item,
+ const CFileItem& item_discstack,
const CBookmark& bookmark,
bool updatePlayCount)
: m_item(item),
+ m_item_discstack(item_discstack),
m_bookmark(bookmark),
m_updatePlayCount(updatePlayCount) {}
virtual ~CSaveFileStateJob() {}
@@ -85,6 +88,12 @@ bool CSaveFileStateJob::DoWork()
videodatabase.SetStreamDetailsForFile(m_item.GetVideoInfoTag()->m_streamDetails,progressTrackingFile);
updateListing = true;
}
+ // in order to properly update the the list, we need to update the stack item which is held in g_application.m_stackFileItemToUpdate
+ if (m_item.HasProperty("stackFileItemToUpdate"))
+ {
+ m_item = m_item_discstack; // as of now, the item is replaced by the discstack item
+ videodatabase.GetResumePoint(*m_item.GetVideoInfoTag());
+ }
videodatabase.Close();
if (updateListing)
View
1  xbmc/video/Bookmark.cpp
@@ -32,6 +32,7 @@ void CBookmark::Reset()
seasonNumber = 0;
timeInSeconds = 0.0f;
totalTimeInSeconds = 0.0f;
+ partNumber = 0;
type = STANDARD;
}
View
1  xbmc/video/Bookmark.h
@@ -31,6 +31,7 @@ class CBookmark
void Reset();
double timeInSeconds;
double totalTimeInSeconds;
+ long partNumber;
CStdString thumbNailImage;
CStdString playerState;
CStdString player;
View
111 xbmc/video/VideoDatabase.cpp
@@ -2253,41 +2253,55 @@ void CVideoDatabase::GetFilePathById(int idMovie, CStdString &filePath, VIDEODB_
}
//********************************************************************************************************************************
-void CVideoDatabase::GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type /*= CBookmark::STANDARD*/, bool bAppend)
+void CVideoDatabase::GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type /*= CBookmark::STANDARD*/, bool bAppend, long partNumber)
{
try
{
- int idFile = GetFileId(strFilenameAndPath);
- if (idFile < 0) return ;
- if (!bAppend)
- bookmarks.erase(bookmarks.begin(), bookmarks.end());
- if (NULL == m_pDB.get()) return ;
- if (NULL == m_pDS.get()) return ;
-
- CStdString strSQL=PrepareSQL("select * from bookmark where idFile=%i and type=%i order by timeInSeconds", idFile, (int)type);
- m_pDS->query( strSQL.c_str() );
- while (!m_pDS->eof())
+ if (URIUtils::IsStack(strFilenameAndPath) && CFileItem(CStackDirectory::GetFirstStackedFile(strFilenameAndPath),false).IsDVDImage())
{
- CBookmark bookmark;
- bookmark.timeInSeconds = m_pDS->fv("timeInSeconds").get_asDouble();
- bookmark.totalTimeInSeconds = m_pDS->fv("totalTimeInSeconds").get_asDouble();
- bookmark.thumbNailImage = m_pDS->fv("thumbNailImage").get_asString();
- bookmark.playerState = m_pDS->fv("playerState").get_asString();
- bookmark.player = m_pDS->fv("player").get_asString();
- bookmark.type = type;
- if (type == CBookmark::EPISODE)
+ CStackDirectory dir;
+ CFileItemList fileList;
+ dir.GetDirectory(strFilenameAndPath, fileList);
+ if (!bAppend)
+ bookmarks.clear();
+ for (int i = fileList.Size() - 1; i >= 0; i--) // put the bookmarks of the highest part first in the list
+ GetBookMarksForFile(fileList[i]->GetPath(), bookmarks, type, true, (i+1));
+ }
+ else
+ {
+ int idFile = GetFileId(strFilenameAndPath);
+ if (idFile < 0) return ;
+ if (!bAppend)
+ bookmarks.erase(bookmarks.begin(), bookmarks.end());
+ if (NULL == m_pDB.get()) return ;
+ if (NULL == m_pDS.get()) return ;
+
+ CStdString strSQL=PrepareSQL("select * from bookmark where idFile=%i and type=%i order by timeInSeconds", idFile, (int)type);
+ m_pDS->query( strSQL.c_str() );
+ while (!m_pDS->eof())
{
- CStdString strSQL2=PrepareSQL("select c%02d, c%02d from episode where c%02d=%i order by c%02d, c%02d", VIDEODB_ID_EPISODE_EPISODE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_BOOKMARK, m_pDS->fv("idBookmark").get_asInt(), VIDEODB_ID_EPISODE_SORTSEASON, VIDEODB_ID_EPISODE_SORTEPISODE);
- m_pDS2->query(strSQL2.c_str());
- bookmark.episodeNumber = m_pDS2->fv(0).get_asInt();
- bookmark.seasonNumber = m_pDS2->fv(1).get_asInt();
- m_pDS2->close();
+ CBookmark bookmark;
+ bookmark.timeInSeconds = m_pDS->fv("timeInSeconds").get_asDouble();
+ bookmark.partNumber = partNumber;
+ bookmark.totalTimeInSeconds = m_pDS->fv("totalTimeInSeconds").get_asDouble();
+ bookmark.thumbNailImage = m_pDS->fv("thumbNailImage").get_asString();
+ bookmark.playerState = m_pDS->fv("playerState").get_asString();
+ bookmark.player = m_pDS->fv("player").get_asString();
+ bookmark.type = type;
+ if (type == CBookmark::EPISODE)
+ {
+ CStdString strSQL2=PrepareSQL("select c%02d, c%02d from episode where c%02d=%i order by c%02d, c%02d", VIDEODB_ID_EPISODE_EPISODE, VIDEODB_ID_EPISODE_SEASON, VIDEODB_ID_EPISODE_BOOKMARK, m_pDS->fv("idBookmark").get_asInt(), VIDEODB_ID_EPISODE_SORTSEASON, VIDEODB_ID_EPISODE_SORTEPISODE);
+ m_pDS2->query(strSQL2.c_str());
+ bookmark.episodeNumber = m_pDS2->fv(0).get_asInt();
+ bookmark.seasonNumber = m_pDS2->fv(1).get_asInt();
+ m_pDS2->close();
+ }
+ bookmarks.push_back(bookmark);
+ m_pDS->next();
}
- bookmarks.push_back(bookmark);
- m_pDS->next();
+ //sort(bookmarks.begin(), bookmarks.end(), SortBookmarks);
+ m_pDS->close();
}
- //sort(bookmarks.begin(), bookmarks.end(), SortBookmarks);
- m_pDS->close();
}
catch (...)
{
@@ -2940,7 +2954,7 @@ bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const
return retVal;
}
-bool CVideoDatabase::GetResumePoint(CVideoInfoTag& tag) const
+bool CVideoDatabase::GetResumePoint(CVideoInfoTag& tag)
{
if (tag.m_iFileId < 0)
return false;
@@ -2949,17 +2963,38 @@ bool CVideoDatabase::GetResumePoint(CVideoInfoTag& tag) const
try
{
- CStdString strSQL=PrepareSQL("select timeInSeconds, totalTimeInSeconds from bookmark where idFile=%i and type=%i order by timeInSeconds", tag.m_iFileId, CBookmark::RESUME);
- m_pDS2->query( strSQL.c_str() );
- if (!m_pDS2->eof())
+ if (URIUtils::IsStack(tag.m_strFileNameAndPath) && CFileItem(CStackDirectory::GetFirstStackedFile(tag.m_strFileNameAndPath),false).IsDVDImage())
{
- tag.m_resumePoint.timeInSeconds = m_pDS2->fv(0).get_asDouble();
- tag.m_resumePoint.totalTimeInSeconds = m_pDS2->fv(1).get_asDouble();
- tag.m_resumePoint.type = CBookmark::RESUME;
-
- match = true;
+ CStackDirectory dir;
+ CFileItemList fileList;
+ dir.GetDirectory(tag.m_strFileNameAndPath, fileList);
+ tag.m_resumePoint.Reset();
+ for (int i = fileList.Size() - 1; i >= 0; i--)
+ {
+ CBookmark bookmark;
+ if (GetResumeBookMark(fileList[i]->GetPath(), bookmark))
+ {
+ tag.m_resumePoint = bookmark;
+ tag.m_resumePoint.partNumber = (i+1); /* store part number in here */
+ match = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ CStdString strSQL=PrepareSQL("select timeInSeconds, totalTimeInSeconds from bookmark where idFile=%i and type=%i order by timeInSeconds", tag.m_iFileId, CBookmark::RESUME);
+ m_pDS2->query( strSQL.c_str() );
+ if (!m_pDS2->eof())
+ {
+ tag.m_resumePoint.timeInSeconds = m_pDS2->fv(0).get_asDouble();
+ tag.m_resumePoint.totalTimeInSeconds = m_pDS2->fv(1).get_asDouble();
+ tag.m_resumePoint.partNumber = 0; // regular files or non-iso stacks don't need partNumber
+ tag.m_resumePoint.type = CBookmark::RESUME;
+ match = true;
+ }
+ m_pDS2->close();
}
- m_pDS2->close();
}
catch (...)
{
View
4 xbmc/video/VideoDatabase.h
@@ -463,7 +463,7 @@ class CVideoDatabase : public CDatabase
bool GetStackTimes(const CStdString &filePath, std::vector<int> &times);
void SetStackTimes(const CStdString &filePath, std::vector<int> &times);
- void GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type = CBookmark::STANDARD, bool bAppend=false);
+ void GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type = CBookmark::STANDARD, bool bAppend=false, long partNumber=0);
void AddBookMarkToFile(const CStdString& strFilenameAndPath, const CBookmark &bookmark, CBookmark::EType type = CBookmark::STANDARD);
bool GetResumeBookMark(const CStdString& strFilenameAndPath, CBookmark &bookmark);
void DeleteResumeBookMark(const CStdString &strFilenameAndPath);
@@ -472,7 +472,7 @@ class CVideoDatabase : public CDatabase
bool GetBookMarkForEpisode(const CVideoInfoTag& tag, CBookmark& bookmark);
void AddBookMarkForEpisode(const CVideoInfoTag& tag, const CBookmark& bookmark);
void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
- bool GetResumePoint(CVideoInfoTag& tag) const;
+ bool GetResumePoint(CVideoInfoTag& tag);
// scraper settings
void SetScraperForPath(const CStdString& filePath, const ADDON::ScraperPtr& info, const VIDEO::SScanSettings& settings);
View
69 xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -816,20 +816,22 @@ void CGUIWindowVideoBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItem
}
}
-int CGUIWindowVideoBase::GetResumeItemOffset(const CFileItem *item)
+void CGUIWindowVideoBase::GetResumeItemOffset(const CFileItem *item, int& startoffset, int& partNumber)
{
// do not resume livetv
if (item->IsLiveTV())
- return 0;
+ return;
- CVideoDatabase db;
- db.Open();
- long startoffset = 0;
+ startoffset = 0;
+ partNumber = 0;
if (!item->IsNFO() && !item->IsPlayList())
{
if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0.0)
- startoffset = (long)(item->GetVideoInfoTag()->m_resumePoint.timeInSeconds*75);
+ {
+ startoffset = (int)(item->GetVideoInfoTag()->m_resumePoint.timeInSeconds*75);
+ partNumber = item->GetVideoInfoTag()->m_resumePoint.partNumber;
+ }
else
{
CBookmark bookmark;
@@ -837,32 +839,27 @@ int CGUIWindowVideoBase::GetResumeItemOffset(const CFileItem *item)
if ((item->IsVideoDb() || item->IsDVD()) && item->HasVideoInfoTag())
strPath = item->GetVideoInfoTag()->m_strFileNameAndPath;
+ CVideoDatabase db;
+ if (!db.Open())
+ {
+ CLog::Log(LOGERROR, "%s - Cannot open VideoDatabase", __FUNCTION__);
+ return;
+ }
if (db.GetResumeBookMark(strPath, bookmark))
- startoffset = (long)(bookmark.timeInSeconds*75);
-
- if (URIUtils::IsStack(strPath) && CFileItem(CStackDirectory::GetFirstStackedFile(strPath),false).IsDVDImage())
{
- CStackDirectory dir;
- CFileItemList movies;
- dir.GetDirectory(strPath, movies);
-
- /* check if any of the stacked files have a resume bookmark */
- for (int i = 0; i < movies.Size(); i++)
- {
- CBookmark bookmark;
- if (db.GetResumeBookMark(movies[i]->GetPath(), bookmark))
- {
- startoffset = (long)(bookmark.timeInSeconds);
- startoffset += 0x10000000 * (i+1); /* store file number in here */
- // don't break, we take the last one!
- }
- }
+ startoffset = (int)(bookmark.timeInSeconds*75);
+ partNumber = bookmark.partNumber;
}
+ db.Close();
}
}
- db.Close();
+}
- return startoffset;
+bool CGUIWindowVideoBase::HasResumeItemOffset(const CFileItem *item)
+{
+ int startoffset, partNumber = 0;
+ GetResumeItemOffset(item, startoffset, partNumber);
+ return startoffset > 0;
}
bool CGUIWindowVideoBase::OnClick(int iItem)
@@ -1017,20 +1014,15 @@ CStdString CGUIWindowVideoBase::GetResumeString(CFileItem item)
if (item.IsVideoDb() || item.IsDVD())
itemPath = item.GetVideoInfoTag()->m_strFileNameAndPath;
- if (URIUtils::IsStack(itemPath) && CFileItem(CStackDirectory::GetFirstStackedFile(itemPath),false).IsDVDImage())
+ if (db.GetResumeBookMark(itemPath, bookmark))
{
- int startoffset = GetResumeItemOffset(&item);
- if (startoffset > 0)
+ resumeString.Format(g_localizeStrings.Get(12022).c_str(), StringUtils::SecondsToTimeString(lrint(bookmark.timeInSeconds)).c_str());
+ if (bookmark.partNumber > 0)
{
- int selectedPart = (startoffset>>28);
- startoffset = startoffset & ~0xF0000000;
- partString.Format(g_localizeStrings.Get(23051).c_str(), selectedPart);
- resumeString.Format(g_localizeStrings.Get(12022).c_str(), StringUtils::SecondsToTimeString(lrint(startoffset)).c_str());
+ partString.Format(g_localizeStrings.Get(23051).c_str(), bookmark.partNumber);
resumeString.append(" (").append(partString).append(")");
}
}
- else if (db.GetResumeBookMark(itemPath, bookmark) )
- resumeString.Format(g_localizeStrings.Get(12022).c_str(), StringUtils::SecondsToTimeString(lrint(bookmark.timeInSeconds)).c_str());
db.Close();
}
return resumeString;
@@ -1233,7 +1225,7 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
// if autoresume is enabled then add restart video button
// check to see if the Resume Video button is applicable
// only if the video is NOT a DVD (in that case the resume button will be added by CGUIDialogContextMenu::GetContextButtons)
- if (!item->IsDVD() && GetResumeItemOffset(item.get()) > 0)
+ if (!item->IsDVD() && HasResumeItemOffset(item.get()))
{
buttons.Add(CONTEXT_BUTTON_RESUME_ITEM, GetResumeString(*(item.get()))); // Resume Video
}
@@ -1280,7 +1272,7 @@ bool CGUIWindowVideoBase::OnPlayStackPart(int iItem)
if (CFileItem(CStackDirectory::GetFirstStackedFile(path),false).IsDVDImage())
{
CStdString resumeString = CGUIWindowVideoBase::GetResumeString(*(parts[selectedFile - 1].get()));
- stack->m_lStartOffset = 0x10000000 * (selectedFile); /* store file number in here */
+ stack->m_lStartOffset = 0;
if (!resumeString.IsEmpty())
{
CContextButtons choices;
@@ -1288,10 +1280,11 @@ bool CGUIWindowVideoBase::OnPlayStackPart(int iItem)
choices.Add(SELECT_ACTION_PLAY, 12021); // Start from beginning
int value = CGUIDialogContextMenu::ShowAndGetChoice(choices);
if (value == SELECT_ACTION_RESUME)
- stack->m_lStartOffset += (long)CGUIWindowVideoBase::GetResumeItemOffset(parts[selectedFile - 1].get());
+ GetResumeItemOffset(parts[selectedFile - 1].get(), stack->m_lStartOffset, stack->m_lStartPartNumber);
else if (value != SELECT_ACTION_PLAY)
return false; // if not selected PLAY, then we changed our mind so return
}
+ stack->m_lStartPartNumber = selectedFile;
}
// regular stack
else
View
3  xbmc/video/windows/GUIWindowVideoBase.h
@@ -35,7 +35,8 @@ class CGUIWindowVideoBase : public CGUIMediaWindow, public IBackgroundLoaderObse
virtual bool OnAction(const CAction &action);
void PlayMovie(const CFileItem *item);
- static int GetResumeItemOffset(const CFileItem *item);
+ static void GetResumeItemOffset(const CFileItem *item, int& startoffset, int& partNumber);
+ static bool HasResumeItemOffset(const CFileItem *item);
void AddToDatabase(int iItem);
virtual void OnInfo(CFileItem* pItem, const ADDON::ScraperPtr& scraper);
Something went wrong with that request. Please try again.