Skip to content

Commit

Permalink
adds the ability to play a specific title on a DVD or BluRay from fil…
Browse files Browse the repository at this point in the history
…ename

dvdname.titNN.iso will play title NN (playlist NNNNN.mpls on BR)
a ttile in a DVD folder can be played with
DVDname.titNN/VIDEO_TS/VIDEO_TS.IFO in particular a set of links
DVDname.titNN -> DVD/VIDEO_TS/VIDEO_TS
  • Loading branch information
dragonflight committed Nov 5, 2012
1 parent b061d5b commit 6399b48
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 14 deletions.
25 changes: 22 additions & 3 deletions xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp
Expand Up @@ -274,13 +274,25 @@ BLURAY_TITLE_INFO* CDVDInputStreamBluray::GetTitleFile(const std::string& filena

bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content)
{
int title = 100000;
if(m_player == NULL)
return false;
CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s", strFile);

CStdString strPath(strFile);
CStdString filename;
CStdString root;

int iPos = strPath.ReverseFind('?');
if( iPos > 0
&& iPos > strPath.ReverseFind('/')
&& iPos > strPath.ReverseFind('\\')
&& strPath.Mid(iPos,7).CompareNoCase("?title") )
{
title = atoi( strPath.Mid(iPos+7).c_str());
strPath = strPath.Left(iPos);
}

This comment has been minimized.

Copy link
@jmarshallnz

jmarshallnz Nov 5, 2012

Use CURL to parse the URL, then just grab out the URL option directly?

This comment has been minimized.

Copy link
@dragonflight

dragonflight Nov 5, 2012

Author Owner

I thought of that, tried it, but something about the way options worked didn't. I will look at it again and either remember why I didn't do it or do it

if(strPath.Left(7).Equals("bluray:"))
{
CURL url(strPath);
Expand All @@ -289,6 +301,7 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
}
else
{
filename = URIUtils::GetFileName(strPath);
URIUtils::GetDirectory(strPath,strPath);
URIUtils::RemoveSlashAtEnd(strPath);

Expand All @@ -304,7 +317,6 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
URIUtils::RemoveSlashAtEnd(strPath);
}
root = strPath;
filename = URIUtils::GetFileName(strFile);
}

This comment has been minimized.

Copy link
@jmarshallnz

jmarshallnz Nov 5, 2012

why?

This comment has been minimized.

Copy link
@dragonflight

dragonflight Nov 5, 2012

Author Owner

Because before my changes strPath and strFile were the same, but now strPath is strFile without the optional ?title.
The move to the top is because strPath gets modifed in the middle


if (!m_dll)
Expand All @@ -315,7 +327,11 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);

CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s", root.c_str());
if( title == 100000 )
CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s, %s", root.c_str(), filename.c_str());
else
CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s, %s title=%d", root.c_str(), filename.c_str(), title);

m_bd = m_dll->bd_open(root.c_str(), NULL);

if(!m_bd)
Expand Down Expand Up @@ -366,7 +382,10 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
if(filename.Equals("index.bdmv"))
{
m_navmode = false;
m_title = GetTitleLongest();
if( title >= 100000 || title == 0 )

This comment has been minimized.

Copy link
@jmarshallnz

jmarshallnz Nov 5, 2012

perhaps default title to 0 ?

This comment has been minimized.

Copy link
@dragonflight

dragonflight Nov 5, 2012

Author Owner

I wanted to differentiate between doing nothing or choosing the longest. in the case of BR they are the same (today), but in the case of DVDs it would be the difference between playing the menu or playing the longest title (which I haven't implemented)

m_title = GetTitleLongest();
else
m_title = m_dll->bd_get_playlist_info(m_bd, abs(title), 0);

This comment has been minimized.

Copy link
@jmarshallnz

jmarshallnz Nov 5, 2012

can title be negative?

This comment has been minimized.

Copy link
@dragonflight

dragonflight Nov 5, 2012

Author Owner

I missed this change. I originally used negative titles to disable my attempt to decide when the title was finished playing, but after playing with this the last month it seems to always (knock on wood) work so I removed it for this submit, so no it shouldn't be negative

}
else if(URIUtils::GetExtension(filename).Equals(".mpls"))
{
Expand Down
57 changes: 52 additions & 5 deletions xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamNavigator.cpp
Expand Up @@ -52,6 +52,7 @@ CDVDInputStreamNavigator::CDVDInputStreamNavigator(IDVDPlayer* player) : CDVDInp
m_bEOF = false;
m_icurrentGroupId = 0;
m_lastevent = DVDNAV_NOP;
m_bFinishedPGC = false;

memset(m_lastblock, 0, sizeof(m_lastblock));
}
Expand All @@ -64,6 +65,7 @@ CDVDInputStreamNavigator::~CDVDInputStreamNavigator()
bool CDVDInputStreamNavigator::Open(const char* strFile, const std::string& content)
{
char* strDVDFile;
int start_title = 100000;
m_icurrentGroupId = 0;
if (!CDVDInputStream::Open(strFile, "video/x-dvd-mpeg"))
return false;
Expand All @@ -83,6 +85,12 @@ bool CDVDInputStreamNavigator::Open(const char* strFile, const std::string& cont
// at least one path separator character.

strDVDFile = strdup(strFile);
char *p = rindex(strDVDFile, '?');
if( p && strncasecmp( p, "?title=", 7) == 0 )
{
start_title = atoi( p+7 );
*p = 0;
}
int len = strlen(strDVDFile);

if(len >= 13 // +1 on purpose, to include a separator char before the searched string
Expand All @@ -94,6 +102,16 @@ bool CDVDInputStreamNavigator::Open(const char* strFile, const std::string& cont
&& strncasecmp(strDVDFile + len - 8, "VIDEO_TS", 8) == 0)
strDVDFile[len - 9] = '\0';

len = strlen(strDVDFile);
if( start_title < 100000 )
;
else if(len >= 6 // .TITNN
&& strncasecmp(strDVDFile + len - 6, ".TIT", 4) == 0)
start_title = atoi( strDVDFile + len - 2 );
else if(len >= 6 // .TRKNN // historical reasons
&& strncasecmp(strDVDFile + len - 6, ".TRK", 4) == 0)
start_title = atoi( strDVDFile + len - 2 );

#if defined(TARGET_DARWIN_OSX)
// if physical DVDs, libdvdnav wants "/dev/rdiskN" device name for OSX,
// strDVDFile will get realloc'ed and replaced IF this is a physical DVD.
Expand Down Expand Up @@ -185,8 +203,29 @@ bool CDVDInputStreamNavigator::Open(const char* strFile, const std::string& cont
return false;
}

m_iTitle = m_iTitleCount = 0;
m_iPart = m_iPartCount = 0;
m_iTime = m_iTotalTime = 0;
m_iPlayTitle = 0;

if( start_title < 100000 )
{
int len, event, parts;
uint8_t buf[2048];
uint8_t* buf_ptr = buf;
CLog::Log(LOGDEBUG, "*************** setting title to %d", start_title);
m_iTitle = start_title;
m_iPlayTitle = start_title;
m_iPlayTitleTotalTime = 0;
// m_dll.dvdnav_part_play(m_dvdnav, 0, 1);
m_dll.dvdnav_part_play(m_dvdnav, m_iTitle, 1);
// these all get fixed up in DVDNAV_CELL_CHANGE
m_iTitleCount = 0;
m_iPart = m_iPartCount = 0;
m_iTime = m_iTotalTime = 0;
}
// jump directly to title menu
if(g_guiSettings.GetBool("dvds.automenu"))
else if(g_guiSettings.GetBool("dvds.automenu"))
{
int len, event;
uint8_t buf[2048];
Expand All @@ -208,9 +247,6 @@ bool CDVDInputStreamNavigator::Open(const char* strFile, const std::string& cont
m_iVobUnitCorrection = 0LL;
m_bInMenu = false;
m_holdmode = HOLDMODE_NONE;
m_iTitle = m_iTitleCount = 0;
m_iPart = m_iPartCount = 0;
m_iTime = m_iTotalTime = 0;

return true;
}
Expand Down Expand Up @@ -464,9 +500,16 @@ int CDVDInputStreamNavigator::ProcessBlock(BYTE* dest_buffer, int* read)
m_iCellStart = cell_change_event->cell_start; // store cell time as we need that for time later
m_iTime = (int) (m_iCellStart / 90);
m_iTotalTime = (int) (cell_change_event->pgc_length / 90);
if( m_iTitle == m_iPlayTitle )
m_iPlayTitleTotalTime = m_iTotalTime;
m_icurrentGroupId = cell_change_event->pgN * 1000 + cell_change_event->cellN;

iNavresult = m_pDVDPlayer->OnDVDNavResult(buf, DVDNAV_CELL_CHANGE);
if( m_iPlayTitle && m_bFinishedPGC ) {
m_bEOF = true;
iNavresult = m_pDVDPlayer->OnDVDNavResult(buf, DVDNAV_STOP);
}
else
iNavresult = m_pDVDPlayer->OnDVDNavResult(buf, DVDNAV_CELL_CHANGE);
}
break;

Expand Down Expand Up @@ -516,6 +559,10 @@ int CDVDInputStreamNavigator::ProcessBlock(BYTE* dest_buffer, int* read)

CLog::Log(LOGDEBUG, "DVDNAV_NAV_PACKET - DISCONTINUITY FROM:%"PRId64" TO:%"PRId64" DIFF:%"PRId64, (m_iVobUnitStop * 1000)/90, ((int64_t)pci->pci_gi.vobu_s_ptm*1000)/90, (gap*1000)/90);
}
if( m_iTitle == m_iPlayTitle && pci->pci_gi.vobu_e_ptm/90 >= m_iTotalTime-1 )
{
m_bFinishedPGC = true;
}

m_iVobUnitStart = pci->pci_gi.vobu_s_ptm;
m_iVobUnitStop = pci->pci_gi.vobu_e_ptm;
Expand Down
Expand Up @@ -154,6 +154,7 @@ class CDVDInputStreamNavigator

int m_iTotalTime;
int m_iTime;
bool m_bFinishedPGC;
int64_t m_iCellStart; // start time of current cell in pts units (90khz clock)

bool m_bInMenu;
Expand All @@ -164,7 +165,8 @@ class CDVDInputStreamNavigator

int m_iTitleCount;
int m_iTitle;

int m_iPlayTitle;
int m_iPlayTitleTotalTime;
int m_iPartCount;
int m_iPart;

Expand Down
28 changes: 23 additions & 5 deletions xbmc/cores/dvdplayer/DVDPlayer.cpp
Expand Up @@ -557,6 +557,8 @@ bool CDVDPlayer::OpenInputStream()
{
m_filename = g_mediaManager.TranslateDevicePath("");
}

int title = 100000;
retry:
// before creating the input stream, if this is an HLS playlist then get the
// most appropriate bitrate based on our network settings
Expand All @@ -579,18 +581,34 @@ bool CDVDPlayer::OpenInputStream()
else
m_pInputStream->SetFileItem(m_item);

if (!m_pInputStream->Open(m_filename.c_str(), m_mimetype))
if( title >= 100000 ) // match filename.titnnn.iso
{
int t, n=-1, len;
char *p, *q;
p = strdup(m_filename.c_str());
len = strlen( p );
if( len > 4 && strcasecmp(&p[len-4], ".iso" ) == 0 )
{
p[len-4] = 0;
if( (q = rindex(p, '.'))
&& strcasecmp( q, ".tit" )
&& sscanf( q+4, "%d%n", &t, &n ) >= 1
&& q[n+4] == 0 )
title = t;
}
free( p );
}
if( title < 100000 )
filename.AppendFormat("?title=%d",title);

if (!m_pInputStream->Open(filename.c_str(), m_mimetype))
{
if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
{
CLog::Log(LOGERROR, "CDVDPlayer::OpenInputStream - failed to open [%s] as DVD ISO, trying Bluray", m_filename.c_str());
m_mimetype = "bluray/iso";
filename = m_filename;
filename = filename + "/BDMV/index.bdmv";
int title = (int)m_item.GetProperty("BlurayStartingTitle").asInteger();
if( title )
filename.AppendFormat("?title=%d",title);

m_filename = filename;
goto retry;
}
Expand Down

0 comments on commit 6399b48

Please sign in to comment.