Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Improved DVD startup.

- probe the dvd titles to identify the first title that is definitely a
video sequence (as opposed to a still frame) and use this for the
initial startup/probe.

- retrieving chapter data is expensive over storage groups (potentially
2-3 seconds per title for up to 70 titles or more), so don't necessarily
scan all of the titles but do cache the results (they shouldn't change).

- the chapter data will also be used for improved chapter navigation.

This fixes/improves a few startup issues. By picking a valid video
sequence, we avoid some video artefacts at the beginning of playback and
avoid having to reset certain discs that have hit a stop sequence
(because we've scanned a menu) - with a knock-on improvement in startup
speed.
  • Loading branch information...
commit 8f103c6cad90479a1b3d80c47405481020eb1034 1 parent 70bcc33
Mark Kendall authored
View
69 mythtv/libs/libmythtv/dvdringbuffer.cpp
@@ -128,6 +128,7 @@ DVDRingBuffer::~DVDRingBuffer()
{
CloseDVD();
ClearMenuSPUParameters();
+ ClearChapterCache();
}
void DVDRingBuffer::CloseDVD(void)
@@ -140,6 +141,13 @@ void DVDRingBuffer::CloseDVD(void)
}
}
+void DVDRingBuffer::ClearChapterCache(void)
+{
+ foreach (QList<uint64_t> chapters, m_chapterMap)
+ chapters.clear();
+ m_chapterMap.clear();
+}
+
long long DVDRingBuffer::Seek(long long pos, int whence, bool has_lock)
{
VERBOSE(VB_FILE, LOC + QString("Seek(%1,%2,%3)")
@@ -313,8 +321,6 @@ bool DVDRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
dvdnav_set_PGC_positioning_flag(m_dvdnav, 1);
int32_t num_titles = 0;
- int32_t num_parts = 0;
-
res = dvdnav_get_number_of_titles(m_dvdnav, &num_titles);
if (num_titles == 0 || res == DVDNAV_STATUS_ERR)
{
@@ -325,6 +331,8 @@ bool DVDRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
res = dvdnav_get_number_of_titles(m_dvdnav, &num_titles);
}
+ int start_title = 1;
+
if (res == DVDNAV_STATUS_ERR)
{
VERBOSE(VB_IMPORTANT,
@@ -335,24 +343,61 @@ bool DVDRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
VERBOSE(VB_IMPORTANT, QString("There are %1 titles on the disk")
.arg(num_titles));
- for (int i = 1; i < num_titles + 1; i++)
+ // We do this once and chose the first title with a reasonanble length,
+ // cache the results for those we probe and probe the remainder as
+ // needed
+ if (!m_chapterMap.size())
{
- res = dvdnav_get_number_of_parts(m_dvdnav, i, &num_parts);
- if (res != DVDNAV_STATUS_ERR)
+ for (int i = 1; i < num_titles + 1; i++)
{
- VERBOSE(VB_IMPORTANT, LOC + QString("Title %1 has %2 parts.")
- .arg(i).arg(num_parts));
+ uint64_t *times;
+ uint64_t duration;
+ uint32_t count = dvdnav_describe_title_chapters(m_dvdnav, i,
+ &times,
+ &duration);
+ if (count < 1)
+ {
+ VERBOSE(VB_IMPORTANT, LOC_ERR +
+ QString("Failed to get chapters for title %1").arg(i));
+ continue;
+ }
+
+ float length = (float)duration / 90000.0f;
+ VERBOSE(VB_GENERAL, LOC +
+ QString("Title %1: chapters %2 duration %3")
+ .arg(i).arg(count).arg(length));
+
+ QList<uint64_t> chapters;
+ for (uint j = 0; j < count; j++)
+ chapters.append(times[j] / 90000);
+ delete times;
+ m_chapterMap.insert(i, chapters);
+
+ if (length > 5)
+ break;
}
- else
+ }
+
+ QMapIterator<uint, QList<uint64_t> > it(m_chapterMap);
+ uint64_t longest = 0;
+ while (it.hasNext())
+ {
+ it.next();
+ if (it.value().size())
{
- VERBOSE(VB_IMPORTANT, LOC_ERR +
- QString("Failed to get number of parts for title %1")
- .arg(i));
+ uint title = it.key();
+ uint64_t last = it.value().last();
+ if (last > longest)
+ {
+ start_title = title;
+ longest = last;
+ }
}
}
}
- dvdnav_title_play(m_dvdnav, 1);
+ VERBOSE(VB_GENERAL, LOC + QString("Starting with title %1").arg(start_title));
+ dvdnav_title_play(m_dvdnav, start_title);
dvdnav_current_title_info(m_dvdnav, &m_title, &m_part);
dvdnav_get_title_string(m_dvdnav, &m_dvdname);
dvdnav_get_serial_string(m_dvdnav, &m_serialnumber);
View
2  mythtv/libs/libmythtv/dvdringbuffer.h
@@ -183,6 +183,7 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
uint64_t m_seektime;
uint m_currentTime;
QMap<uint, uint> m_seekSpeedMap;
+ QMap<uint, QList<uint64_t> > m_chapterMap;
MythDVDPlayer *m_parent;
@@ -211,6 +212,7 @@ class MTV_PUBLIC DVDRingBuffer : public RingBuffer
QMutex m_seekLock;
long long Seek(long long time);
+ void ClearChapterCache(void);
uint ConvertLangCode(uint16_t code);
void SelectDefaultButton(void);
void WaitForPlayer(void);
Please sign in to comment.
Something went wrong with that request. Please try again.