Skip to content

Commit

Permalink
A DVD menu is now defined as any time a NAV packet defines at least o…
Browse files Browse the repository at this point in the history
…ne button. This should allow more flexibility to skip some intros.

Refs #11292
  • Loading branch information
Richard committed Jun 30, 2013
1 parent 712a0c2 commit b16ccb6
Showing 1 changed file with 107 additions and 77 deletions.
184 changes: 107 additions & 77 deletions mythtv/libs/libmythtv/DVD/dvdringbuffer.cpp
Expand Up @@ -717,9 +717,6 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
dvdnav_cell_change_event_t *cell_event =
(dvdnav_cell_change_event_t*) (blockBuf);

// a menu is anything that isn't in the VTS domain
m_inMenu = !dvdnav_is_domain_vts(m_dvdnav);

// update information for the current cell
m_cellChanged = true;
if (m_pgcLength != cell_event->pgc_length)
Expand All @@ -736,6 +733,7 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
uint32_t pos;
uint32_t length;
m_still = dvdnav_get_next_still_flag(m_dvdnav);
m_titleParts = 0;
dvdnav_current_title_info(m_dvdnav, &m_title, &m_part);
dvdnav_get_number_of_parts(m_dvdnav, m_title, &m_titleParts);
dvdnav_get_position(m_dvdnav, &pos, &length);
Expand Down Expand Up @@ -800,13 +798,6 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
m_buttonSeenInCell = false;

IncrementButtonVersion;
if (m_inMenu)
{
m_autoselectsubtitle = true;
GetMythUI()->RestoreScreensaver();
}
else
GetMythUI()->DisableScreensaver();

// release buffer
if (blockBuf != m_dvdBlockWriteBuf)
Expand Down Expand Up @@ -889,8 +880,12 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
case DVDNAV_NAV_PACKET:
{
QMutexLocker lock(&m_seekLock);
bool lastInMenu = m_inMenu;

// retrieve the latest Presentation Control and
// Data Search Information structures
pci_t *pci = dvdnav_get_current_nav_pci(m_dvdnav);
dsi_t *dsi = dvdnav_get_current_nav_dsi(m_dvdnav);

// If the start PTS of this block is not the
// same as the end PTS of the last block,
Expand All @@ -913,91 +908,116 @@ int DVDRingBuffer::safe_read(void *data, uint sz)
}

m_endPts = pci->pci_gi.vobu_e_ptm;
m_inMenu = (pci->hli.hl_gi.btn_ns > 0);

QMutexLocker contextLocker(&m_contextLock);
if (m_context)
m_context->DecrRef();

m_context = new MythDVDContext();

m_context->m_pci = *pci;

m_context->m_pci.pci_gi.vobu_s_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_s_ptm);
m_context->m_pci.pci_gi.vobu_e_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_e_ptm);
if (m_inMenu && (dsi->synci.sp_synca[0] & 0x80000000) && !m_buttonExists)
{
LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Jumped into middle of menu: lba %1, dest %2")
.arg(pci->pci_gi.nv_pck_lbn)
.arg(pci->pci_gi.nv_pck_lbn - (dsi->synci.sp_synca[0] & 0x7fffffff)));

// We're in a menu, the subpicture packets are somewhere behind us
// and we've not decoded any subpicture.
// That probably means we've jumped into the middle of a menu.
// We'd better jump back to get the subpicture packet(s) otherwise
// there's no menu highlight to show.
m_seeking = false;
dvdnav_sector_search(m_dvdnav, pci->pci_gi.nv_pck_lbn - (dsi->synci.sp_synca[0] & 0x7fffffff), SEEK_SET);
}
else
{
QMutexLocker contextLocker(&m_contextLock);
if (m_context)
m_context->DecrRef();

if (pci->pci_gi.vobu_se_e_ptm != 0)
m_context->m_pci.pci_gi.vobu_se_e_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_se_e_ptm);
m_context = new MythDVDContext();

// get the latest nav
m_lastNav = (dvdnav_t *)blockBuf;
m_context->m_pci = *pci;

// retrieve the latest Data Search Information
dsi_t *dsi = dvdnav_get_current_nav_dsi(m_dvdnav);
m_context->m_pci.pci_gi.vobu_s_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_s_ptm);
m_context->m_pci.pci_gi.vobu_e_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_e_ptm);

m_context->m_dsi = *dsi;
if (pci->pci_gi.vobu_se_e_ptm != 0)
m_context->m_pci.pci_gi.vobu_se_e_ptm = AdjustTimestamp(m_context->m_pci.pci_gi.vobu_se_e_ptm);

// if we are in a looping menu, we don't want to reset the
// selected button when we restart
m_vobid = dsi->dsi_gi.vobu_vob_idn;
m_cellid = dsi->dsi_gi.vobu_c_idn;
if ((m_lastvobid == m_vobid) && (m_lastcellid == m_cellid)
&& m_lastButtonSeenInCell)
{
m_cellRepeated = true;
}
// get the latest nav
m_lastNav = (dvdnav_t *)blockBuf;

// update our status
m_currentTime = dvdnav_get_current_time(m_dvdnav);
m_currentpos = GetReadPosition();
m_context->m_dsi = *dsi;

if (m_seeking)
{
int relativetime =
(int)((m_seektime - m_currentTime)/ 90000);
if (abs(relativetime) <= 1)
if (m_inMenu != lastInMenu)
{
m_seeking = false;
m_seektime = 0;
if (m_inMenu)
{
m_autoselectsubtitle = true;
GetMythUI()->RestoreScreensaver();
}
else
GetMythUI()->DisableScreensaver();
}
else

// if we are in a looping menu, we don't want to reset the
// selected button when we restart
m_vobid = dsi->dsi_gi.vobu_vob_idn;
m_cellid = dsi->dsi_gi.vobu_c_idn;
if ((m_lastvobid == m_vobid) && (m_lastcellid == m_cellid)
&& m_lastButtonSeenInCell)
{
dvdnav_relative_time_search(m_dvdnav, relativetime * 2);
m_cellRepeated = true;
}
}

// update the button stream number if this is the
// first NAV pack containing button information
if ( (pci->hli.hl_gi.hli_ss & 0x03) == 0x01 )
{
m_buttonStreamID = 32;
int aspect = dvdnav_get_video_aspect(m_dvdnav);
// update our status
m_currentTime = dvdnav_get_current_time(m_dvdnav);
m_currentpos = GetReadPosition();

// workaround where dvd menu is
// present in VTS_DOMAIN. dvdnav adds 0x80 to stream id
// proper fix should be put in dvdnav sometime
int8_t spustream = dvdnav_get_active_spu_stream(m_dvdnav) & 0x7f;
if (m_seeking)
{
int relativetime =
(int)((m_seektime - m_currentTime)/ 90000);
if (abs(relativetime) <= 1)
{
m_seeking = false;
m_seektime = 0;
}
else
{
dvdnav_relative_time_search(m_dvdnav, relativetime * 2);
}
}

if (aspect != 0 && spustream > 0)
m_buttonStreamID += spustream;
// update the button stream number if this is the
// first NAV pack containing button information
if ( (pci->hli.hl_gi.hli_ss & 0x03) == 0x01 )
{
m_buttonStreamID = 32;
int aspect = dvdnav_get_video_aspect(m_dvdnav);

m_buttonSeenInCell = true;
}
// workaround where dvd menu is
// present in VTS_DOMAIN. dvdnav adds 0x80 to stream id
// proper fix should be put in dvdnav sometime
int8_t spustream = dvdnav_get_active_spu_stream(m_dvdnav) & 0x7f;

// debug
LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("DVDNAV_NAV_PACKET - time:%1, lba:%2, vob:%3, cell:%4, seeking:%5, seektime:%6")
.arg(m_context->GetStartPTS())
.arg(m_context->GetLBA())
.arg(m_vobid)
.arg(m_cellid)
.arg(m_seeking)
.arg(m_seektime));
if (aspect != 0 && spustream > 0)
m_buttonStreamID += spustream;

if (!m_seeking)
{
memcpy(dest + offset, blockBuf, DVD_BLOCK_SIZE);
tot += DVD_BLOCK_SIZE;
}
m_buttonSeenInCell = true;
}

// debug
LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("DVDNAV_NAV_PACKET - time:%1, lba:%2, vob:%3, cell:%4, seeking:%5, seektime:%6")
.arg(m_context->GetStartPTS())
.arg(m_context->GetLBA())
.arg(m_vobid)
.arg(m_cellid)
.arg(m_seeking)
.arg(m_seektime));

if (!m_seeking)
{
memcpy(dest + offset, blockBuf, DVD_BLOCK_SIZE);
tot += DVD_BLOCK_SIZE;
}
}
// release buffer
if (blockBuf != m_dvdBlockWriteBuf)
dvdnav_free_cache_block(m_dvdnav, blockBuf);
Expand Down Expand Up @@ -1855,7 +1875,17 @@ uint DVDRingBuffer::GetSubtitleLanguage(int id)
*/
int DVDRingBuffer::GetSubtitleTrackNum(uint stream_id)
{
return dvdnav_get_spu_logical_stream(m_dvdnav, stream_id);
int logstream = -1;

// VM always sets stream_id to zero if we're not in the VTS
// domain and always returns 0 (instead of -1) if nothing has
// been found, so only try to retrieve the logical stream if
// we *are* in the VTS domain or we *are* trying to map stream
// 0.
if (dvdnav_is_domain_vts(m_dvdnav) || (stream_id == 0))
logstream = dvdnav_get_spu_logical_stream(m_dvdnav, stream_id);

return logstream;
}

/** \brief converts the subtitle/audio lang code to iso639.
Expand Down

0 comments on commit b16ccb6

Please sign in to comment.