Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[bluray] Initial support for menu's, no BD-J supported

Code will fall back to longest item if there is not first play
hdmv item. However it will still try menu's if there is only
some unnsupported BD-J titles. This could possible fail to
play if it switches into BD-J mode later in menu's.

Starting index.bdmv will still only play longest title,
to attempt playback with menu's, start the MovieObject.bdmv
  • Loading branch information...
commit 226c8504e78ff56e98318f9beb475d66a94bea95 1 parent 9b1dd39
Joakim Plate elupus authored
32 lib/DllLibbluray.h
View
@@ -30,6 +30,8 @@ extern "C"
#include <libbluray/bluray.h>
#include <libbluray/filesystem.h>
#include <libbluray/log_control.h>
+#include <libbluray/keys.h>
+#include <libbluray/overlay.h>
}
class DllLibblurayInterface
@@ -65,6 +67,16 @@ class DllLibblurayInterface
virtual void bd_set_debug_mask(uint32_t mask)=0;
virtual uint32_t bd_get_debug_mask(void)=0;
virtual const BLURAY_DISC_INFO *bd_get_disc_info(BLURAY *bd)=0;
+
+ virtual int bd_get_event (BLURAY *bd, BD_EVENT *event)=0;
+ virtual int bd_play (BLURAY *bd)=0;
+ virtual int bd_read_ext (BLURAY *bd, unsigned char *buf, int len, BD_EVENT *event)=0;
+ virtual int bd_read_skip_still (BLURAY *bd)=0;
+ virtual int bd_user_input (BLURAY *bd, int64_t pts, uint32_t key)=0;
+ virtual int bd_set_player_setting (BLURAY *bd, uint32_t idx, uint32_t value)=0;
+ virtual int bd_set_player_setting_str (BLURAY *bd, uint32_t idx, const char *s)=0;
+ virtual void bd_register_overlay_proc (BLURAY *bd, void *handle, bd_overlay_proc_f func)=0;
+ virtual int bd_menu_call (BLURAY *bd, int64_t pts)=0;
};
class DllLibbluray : public DllDynamic, DllLibblurayInterface
@@ -100,6 +112,16 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface
DEFINE_METHOD0(uint32_t, bd_get_debug_mask)
DEFINE_METHOD1(const BLURAY_DISC_INFO*, bd_get_disc_info, (BLURAY *p1))
+ DEFINE_METHOD2(int, bd_get_event, (BLURAY *p1, BD_EVENT *p2))
+ DEFINE_METHOD1(int, bd_play, (BLURAY *p1))
+ DEFINE_METHOD4(int, bd_read_ext, (BLURAY *p1, unsigned char *p2, int p3, BD_EVENT *p4))
+ DEFINE_METHOD1(int, bd_read_skip_still, (BLURAY *p1))
+ DEFINE_METHOD3(int, bd_user_input, (BLURAY *p1, int64_t p2, uint32_t p3))
+ DEFINE_METHOD3(int, bd_set_player_setting, (BLURAY *p1, uint32_t p2, uint32_t p3))
+ DEFINE_METHOD3(int, bd_set_player_setting_str, (BLURAY *p1, uint32_t p2, const char *p3))
+ DEFINE_METHOD3(void, bd_register_overlay_proc, (BLURAY *p1, void *p2, bd_overlay_proc_f p3))
+ DEFINE_METHOD2(int, bd_menu_call, (BLURAY *p1, int64_t p2))
+
BEGIN_METHOD_RESOLVE()
RESOLVE_METHOD(bd_get_titles)
RESOLVE_METHOD(bd_get_title_info)
@@ -129,6 +151,16 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface
RESOLVE_METHOD(bd_set_debug_mask)
RESOLVE_METHOD(bd_get_debug_mask)
RESOLVE_METHOD(bd_get_disc_info)
+
+ RESOLVE_METHOD(bd_get_event)
+ RESOLVE_METHOD(bd_play)
+ RESOLVE_METHOD(bd_read_ext)
+ RESOLVE_METHOD(bd_read_skip_still)
+ RESOLVE_METHOD(bd_user_input)
+ RESOLVE_METHOD(bd_set_player_setting)
+ RESOLVE_METHOD(bd_set_player_setting_str)
+ RESOLVE_METHOD(bd_register_overlay_proc)
+ RESOLVE_METHOD(bd_menu_call)
END_METHOD_RESOLVE()
public:
2  xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp
View
@@ -54,7 +54,7 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IDVDPlayer* pPlayer,
}
#ifdef HAVE_LIBBLURAY
else if (item.IsType(".bdmv") || item.IsType(".mpls") || content == "bluray/iso")
- return new CDVDInputStreamBluray();
+ return new CDVDInputStreamBluray(pPlayer);
#endif
else if(file.substr(0, 6) == "rtp://"
|| file.substr(0, 7) == "rtsp://"
475 xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp
View
@@ -22,6 +22,11 @@
#ifdef HAVE_LIBBLURAY
#include "DVDInputStreamBluray.h"
+#include "IDVDPlayer.h"
+#include "DVDCodecs/Overlay/DVDOverlay.h"
+#include "DVDCodecs/Overlay/DVDOverlayImage.h"
+#include "settings/GUISettings.h"
+#include "LangInfo.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
#include "filesystem/File.h"
@@ -195,10 +200,17 @@ void DllLibbluray::bluray_logger(const char* msg)
CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Logger - %s", msg);
}
-CDVDInputStreamBluray::CDVDInputStreamBluray() :
+
+static void bluray_overlay_cb(void *this_gen, const BD_OVERLAY * ov)
+{
+ static_cast<CDVDInputStreamBluray*>(this_gen)->OverlayCallback(ov);
+}
+
+CDVDInputStreamBluray::CDVDInputStreamBluray(IDVDPlayer* player) :
CDVDInputStream(DVDSTREAM_TYPE_BLURAY)
{
m_title = NULL;
+ m_clip = 0;
m_bd = NULL;
m_dll = new DllLibbluray;
if (!m_dll->Load())
@@ -206,6 +218,8 @@ CDVDInputStreamBluray::CDVDInputStreamBluray() :
delete m_dll;
m_dll = NULL;
}
+ m_content = "video/x-mpegts";
+ m_player = player;
}
CDVDInputStreamBluray::~CDVDInputStreamBluray()
@@ -250,33 +264,15 @@ BLURAY_TITLE_INFO* CDVDInputStreamBluray::GetTitleFile(const std::string& filena
return NULL;
}
- int titles = m_dll->bd_get_titles(m_bd, TITLES_ALL, 0);
- if(titles < 0)
- {
- CLog::Log(LOGERROR, "get_playlist_title - unable to get list of titles");
- return NULL;
- }
-
- BLURAY_TITLE_INFO *t;
- for(int i=0; i < titles; i++)
- {
- t = m_dll->bd_get_title_info(m_bd, i, 0);
- if(!t)
- {
- CLog::Log(LOGDEBUG, "get_playlist_title - unable to get title %d", i);
- continue;
- }
- if(t->playlist == playlist)
- return t;
- m_dll->bd_free_title_info(t);
- }
-
- return NULL;
+ return m_dll->bd_get_playlist_info(m_bd, playlist, 0);
}
bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content)
{
+ if(m_player == NULL)
+ return false;
+
CStdString strPath;
URIUtils::GetDirectory(strFile,strPath);
URIUtils::RemoveSlashAtEnd(strPath);
@@ -299,7 +295,7 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
m_dll->bd_register_dir(DllLibbluray::dir_open);
m_dll->bd_register_file(DllLibbluray::file_open);
m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
- m_dll->bd_set_debug_mask(DBG_CRIT);
+ m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);
CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s", strPath.c_str());
m_bd = m_dll->bd_open(strPath.c_str(), NULL);
@@ -353,28 +349,76 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
CStdString filename = URIUtils::GetFileName(strFile);
if(filename.Equals("index.bdmv"))
{
+ m_navmode = false;
m_title = GetTitleLongest();
}
else if(URIUtils::GetExtension(filename).Equals(".mpls"))
{
+ m_navmode = false;
m_title = GetTitleFile(filename);
}
+ else if(filename.Equals("MovieObject.bdmv"))
+ {
+ m_navmode = true;
+ if (m_navmode && !disc_info->first_play_supported) {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - Can't play disc in HDMV navigation mode - First Play title not supported");
+ m_navmode = false;
+ }
+
+ if (m_navmode && disc_info->num_unsupported_titles > 0) {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - Unsupported titles found - Some titles can't be played in navigation mode");
+ }
+
+ if(!m_navmode)
+ m_title = GetTitleLongest();
+ }
else
{
CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - unsupported bluray file selected %s", strPath.c_str());
return false;
}
- if(!m_title)
+ if(m_navmode)
{
- CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to get title info");
- return false;
- }
+ int region = g_guiSettings.GetInt("dvds.playerregion");
+ if(region == 0)
+ {
+ CLog::Log(LOGWARNING, "CDVDInputStreamBluray::Open - region dvd must be set in setting, assuming region 1");
+ region = 1;
+ }
+ m_dll->bd_set_player_setting (m_bd, BLURAY_PLAYER_SETTING_REGION_CODE, region);
+ m_dll->bd_set_player_setting (m_bd, BLURAY_PLAYER_SETTING_PARENTAL, 0);
+ m_dll->bd_set_player_setting (m_bd, BLURAY_PLAYER_SETTING_PLAYER_PROFILE, 0);
+ m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_AUDIO_LANG, g_langInfo.GetDVDAudioLanguage().c_str());
+ m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_PG_LANG, g_langInfo.GetDVDSubtitleLanguage().c_str());
+ m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_MENU_LANG, g_langInfo.GetDVDMenuLanguage().c_str());
+ m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_COUNTRY_CODE, "us");
+ m_dll->bd_register_overlay_proc (m_bd, this, bluray_overlay_cb);
+
+ m_dll->bd_get_event(m_bd, NULL);
+
- if(m_dll->bd_select_title(m_bd, m_title->idx) == 0 )
+ if(m_dll->bd_play(m_bd) <= 0)
+ {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed play disk %s", strPath.c_str());
+ return false;
+ }
+ m_hold = HOLD_DATA;
+ m_title_playing = false;
+ }
+ else
{
- CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to select title %d", m_title->idx);
- return false;
+ if(!m_title)
+ {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to get title info");
+ return false;
+ }
+
+ if(m_dll->bd_select_playlist(m_bd, m_title->playlist) == 0 )
+ {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to select title %d", m_title->idx);
+ return false;
+ }
}
return true;
@@ -385,17 +429,324 @@ void CDVDInputStreamBluray::Close()
{
if (!m_dll)
return;
+ if(m_title)
+ m_dll->bd_free_title_info(m_title);
if(m_bd)
+ {
+ m_dll->bd_register_overlay_proc(m_bd, NULL, NULL);
m_dll->bd_close(m_bd);
+ }
m_bd = NULL;
- if(m_title)
- m_dll->bd_free_title_info(m_title);
m_title = NULL;
}
int CDVDInputStreamBluray::Read(BYTE* buf, int buf_size)
{
- return m_dll->bd_read(m_bd, buf, buf_size);
+ if(m_navmode)
+ {
+ int result = 0;
+ do {
+
+ if(m_hold == HOLD_HELD)
+ return 0;
+
+ if(m_hold == HOLD_SKIP)
+ {
+ /* m_event already holds data */
+ m_hold = HOLD_DATA;
+ result = 0;
+ }
+ else
+ {
+ result = m_dll->bd_read_ext (m_bd, buf, buf_size, &m_event);
+
+ if(m_hold == HOLD_NONE)
+ {
+ /* Check for holding events */
+ switch(m_event.event) {
+ case BD_EVENT_SEEK:
+ case BD_EVENT_TITLE:
+ if(m_title_playing)
+ m_player->OnDVDNavResult(NULL, 1);
+ m_hold = HOLD_HELD;
+ return result;
+
+ case BD_EVENT_PLAYLIST:
+ case BD_EVENT_PLAYITEM:
+ m_hold = HOLD_HELD;
+ return result;
+ default:
+ break;
+ }
+ }
+ if(result > 0)
+ m_hold = HOLD_NONE;
+ }
+ int pid = -1;
+ switch (m_event.event) {
+
+ case BD_EVENT_ERROR:
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray - BD_EVENT_ERROR");
+ return -1;
+
+ case BD_EVENT_ENCRYPTED:
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray - BD_EVENT_ENCRYPTED");
+ return -1;
+
+ /* playback control */
+
+ case BD_EVENT_SEEK:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_SEEK");
+ break;
+
+ case BD_EVENT_STILL_TIME:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_STILL_TIME %d", m_event.param);
+ return 0;
+
+ case BD_EVENT_STILL:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_STILL %d", m_event.param);
+ break;
+
+ /* playback position */
+
+ case BD_EVENT_ANGLE:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_ANGLE %d", m_event.param);
+ break;
+
+ case BD_EVENT_END_OF_TITLE:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_END_OF_TITLE %d", m_event.param);
+ m_title_playing = false;
+ break;
+
+ case BD_EVENT_TITLE:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_TITLE %d", m_event.param);
+ if(m_title)
+ m_dll->bd_free_title_info(m_title);
+ m_title = m_dll->bd_get_title_info(m_bd, m_event.param, 0);
+ m_title_playing = true;
+ break;
+
+ case BD_EVENT_PLAYLIST:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PLAYLIST %d", m_event.param);
+ if(m_title)
+ m_dll->bd_free_title_info(m_title);
+ m_title = m_dll->bd_get_playlist_info(m_bd, m_event.param, 0);
+ break;
+
+ case BD_EVENT_PLAYITEM:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PLAYITEM %d", m_event.param);
+ m_clip = m_event.param;
+ break;
+
+ case BD_EVENT_CHAPTER:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_CHAPTER %d", m_event.param);
+ break;
+
+ /* stream selection */
+
+ case BD_EVENT_AUDIO_STREAM:
+ pid = -1;
+ if(m_title
+ && m_title->clip_count > m_clip
+ && m_title->clips[m_clip].audio_stream_count > (uint8_t)(m_event.param - 1))
+ pid = m_title->clips[m_clip].audio_streams[m_event.param-1].pid;
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_AUDIO_STREAM %d %d", m_event.param, pid);
+ m_player->OnDVDNavResult((void*)&pid, 2);
+ break;
+
+ case BD_EVENT_PG_TEXTST:
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PG_TEXTST %d", m_event.param);
+ pid = m_event.param;
+ m_player->OnDVDNavResult((void*)&pid, 4);
+ break;
+
+ case BD_EVENT_PG_TEXTST_STREAM:
+ pid = -1;
+ if(m_title
+ && m_title->clip_count > m_clip
+ && m_title->clips[m_clip].pg_stream_count > (uint8_t)(m_event.param - 1))
+ pid = m_title->clips[m_clip].pg_streams[m_event.param-1].pid;
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PG_TEXTST_STREAM %d, %d", m_event.param, pid);
+ m_player->OnDVDNavResult((void*)&pid, 3);
+ break;
+
+ case BD_EVENT_IG_STREAM:
+ case BD_EVENT_SECONDARY_AUDIO:
+ case BD_EVENT_SECONDARY_AUDIO_STREAM:
+ case BD_EVENT_SECONDARY_VIDEO:
+ case BD_EVENT_SECONDARY_VIDEO_SIZE:
+ case BD_EVENT_SECONDARY_VIDEO_STREAM:
+
+ case BD_EVENT_NONE:
+ break;
+
+ default:
+ CLog::Log(LOGWARNING, "CDVDInputStreamBluray - unhandled libbluray event %d [param %d]", m_event.event, m_event.param);
+ break;
+ }
+
+ } while(result == 0);
+
+ return result;
+ }
+ else
+ return m_dll->bd_read(m_bd, buf, buf_size);
+}
+
+static uint8_t clamp(double v)
+{
+ return (v) > 255.0 ? 255 : ((v) < 0.0 ? 0 : (uint8_t)(v+0.5f));
+}
+
+static uint32_t build_rgba(const BD_PG_PALETTE_ENTRY &e)
+{
+ double r = 1.164 * (e.Y - 16) + 1.596 * (e.Cr - 128);
+ double g = 1.164 * (e.Y - 16) - 0.391 * (e.Cb - 128) - 0.813 * (e.Cr - 128);
+ double b = 1.164 * (e.Y - 16) + 2.018 * (e.Cb - 128);
+ return (uint32_t)e.T << PIXEL_ASHIFT
+ | (uint32_t)clamp(r) << PIXEL_RSHIFT
+ | (uint32_t)clamp(g) << PIXEL_GSHIFT
+ | (uint32_t)clamp(b) << PIXEL_BSHIFT;
+}
+
+void CDVDInputStreamBluray::OverlayCallback(const BD_OVERLAY * const ov)
+{
+
+ CDVDOverlayGroup* group = new CDVDOverlayGroup();
+ group->bForced = true;
+
+ if(ov == NULL)
+ {
+ for(unsigned i = 0; i < 2; ++i)
+ {
+ for(std::vector<CDVDOverlayImage*>::iterator it = m_overlays[i].begin(); it != m_overlays[i].end(); ++it)
+ (*it)->Release();
+ m_overlays[i].clear();
+ }
+
+ m_player->OnDVDNavResult(group, 0);
+ return;
+ }
+
+ group->iPTSStartTime = ov->pts;
+ group->iPTSStopTime = 0;
+
+ if (ov->plane > 1)
+ {
+ CLog::Log(LOGWARNING, "CDVDInputStreamBluray - Ignoring overlay with multiple planes");
+ group->Release();
+ return;
+ }
+
+ std::vector<CDVDOverlayImage*>& plane(m_overlays[ov->plane]);
+
+ /* fixup existing overlays */
+ for(std::vector<CDVDOverlayImage*>::iterator it = plane.begin(); it != plane.end();)
+ {
+ /* if it's fully outside we are done */
+ if(ov->x + ov->w <= (*it)->x
+ || ov->x >= (*it)->x + (*it)->width
+ || ov->y + ov->h <= (*it)->y
+ || ov->y >= (*it)->y + (*it)->height)
+ {
+ ++it;
+ continue;
+ }
+
+ int y1 = std::max<int>((*it)->y , ov->y);
+ int y2 = std::min<int>((*it)->y + (*it)->height, ov->y + ov->h);
+ int x1 = std::max<int>((*it)->x , ov->x);
+ int x2 = std::min<int>((*it)->x + (*it)->width , ov->x + ov->w);
+
+ /* if all should be cleared, delete */
+ if(x1 == (*it)->x
+ && x2 == (*it)->x + (*it)->width
+ && y1 == (*it)->y
+ && y2 == (*it)->y + (*it)->height)
+ {
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - Delete(%d) %d-%dx%d-%d", ov->plane, x1, x2, y1, y2);
+ it = plane.erase(it);
+ continue;
+ }
+#if(1)
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - Clearing(%d) %d-%dx%d-%d", ov->plane, x1, x2, y1, y2);
+
+ /* replace overlay with a new copy*/
+ CDVDOverlayImage* overlay = new CDVDOverlayImage(*(*it));
+ (*it)->Release();
+ (*it) = overlay;
+
+ /* any old hw overlay must be released */
+ SAFE_RELEASE(overlay->m_overlay);
+
+ /* clear out overlap */
+ y1 -= overlay->y;
+ y2 -= overlay->y;
+ x1 -= overlay->x;
+ x2 -= overlay->x;
+
+ /* find fully transparent */
+ int transp = 0;
+ for(; transp < overlay->palette_colors; ++transp)
+ {
+ if(((overlay->palette[transp] >> PIXEL_ASHIFT) & 0xff) == 0)
+ break;
+ }
+
+ if(transp == overlay->palette_colors)
+ {
+ CLog::Log(LOGERROR, "CDVDInputStreamBluray - failed to find transparent color");
+ continue;
+ }
+
+ for(int y = y1; y < y2; ++y)
+ {
+ BYTE* line = overlay->data + y * overlay->linesize;
+ for(int x = x1; x < x2; ++x)
+ line[x] = transp;
+ }
+ ++it;
+#endif
+ }
+
+
+ /* uncompress and draw bitmap */
+ if (ov->img)
+ {
+ CDVDOverlayImage* overlay = new CDVDOverlayImage();
+
+ if (ov->palette)
+ {
+ overlay->palette_colors = 256;
+ overlay->palette = (uint32_t*)calloc(overlay->palette_colors, 4);
+
+ for(unsigned i = 0; i < 256; i++)
+ overlay->palette[i] = build_rgba(ov->palette[i]);
+ }
+
+ const BD_PG_RLE_ELEM *rlep = ov->img;
+ uint8_t *img = (uint8_t*) malloc(ov->w * ov->h);
+ unsigned pixels = ov->w * ov->h;
+
+ for (unsigned i = 0; i < pixels; i += rlep->len, rlep++) {
+ memset(img + i, rlep->color, rlep->len);
+ }
+
+ overlay->data = img;
+ overlay->linesize = ov->w;
+ overlay->x = ov->x;
+ overlay->y = ov->y;
+ overlay->height = ov->h;
+ overlay->width = ov->w;
+ plane.push_back(overlay);
+ }
+
+ for(unsigned i = 0; i < 2; ++i)
+ {
+ for(std::vector<CDVDOverlayImage*>::iterator it = m_overlays[i].begin(); it != m_overlays[i].end(); ++it)
+ group->m_overlays.push_back((*it)->Acquire());
+ }
+ m_player->OnDVDNavResult(group, 0);
}
int CDVDInputStreamBluray::GetTotalTime()
@@ -499,10 +850,10 @@ static bool find_stream(int pid, BLURAY_STREAM_INFO *info, int count, char* lang
void CDVDInputStreamBluray::GetStreamInfo(int pid, char* language)
{
- if(m_title->clip_count == 0)
+ if(!m_title || m_clip >= m_title->clip_count)
return;
- BLURAY_CLIP_INFO *clip = m_title->clips;
+ BLURAY_CLIP_INFO *clip = m_title->clips+m_clip;
if(find_stream(pid, clip->audio_streams, clip->audio_stream_count, language))
return;
@@ -514,4 +865,56 @@ void CDVDInputStreamBluray::GetStreamInfo(int pid, char* language)
return;
}
+CDVDInputStream::ENextStream CDVDInputStreamBluray::NextStream()
+{
+ if(!m_navmode)
+ return NEXTSTREAM_NONE;
+
+ if(m_hold == HOLD_HELD)
+ {
+ m_hold = HOLD_SKIP;
+ return NEXTSTREAM_OPEN;
+ }
+ if(m_hold == HOLD_NONE)
+ {
+ m_hold = HOLD_DATA;
+ m_dll->bd_read_skip_still(m_bd);
+ }
+ return NEXTSTREAM_RETRY;
+}
+
+void CDVDInputStreamBluray::UserInput(bd_vk_key_e vk)
+{
+ if(m_bd == NULL || !m_navmode)
+ return;
+ m_dll->bd_user_input(m_bd, -1, vk);
+}
+
+void CDVDInputStreamBluray::OnMenu()
+{
+ if(m_bd == NULL || !m_navmode)
+ return;
+
+ if(m_dll->bd_user_input(m_bd, -1, BD_VK_POPUP) >= 0)
+ return;
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - popup failed, trying root");
+
+ if(m_dll->bd_user_input(m_bd, -1, BD_VK_ROOT_MENU) >= 0)
+ return;
+
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - root failed, trying explicit");
+ if(m_dll->bd_menu_call(m_bd, -1) >= 0)
+ return;
+ CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - root failed");
+}
+
+bool CDVDInputStreamBluray::IsInMenu()
+{
+ if(m_bd == NULL || !m_navmode)
+ return false;
+ if(m_overlays[BD_OVERLAY_IG].size() > 0)
+ return true;
+ return false;
+}
+
#endif
59 xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h
View
@@ -23,18 +23,27 @@
#include "DVDInputStream.h"
+
+extern "C"
+{
+#include <libbluray/bluray.h>
+#include <libbluray/keys.h>
+#include <libbluray/overlay.h>
+}
+
+class CDVDOverlayImage;
class DllLibbluray;
-typedef struct bluray BLURAY;
-typedef struct bd_title_info BLURAY_TITLE_INFO;
+class IDVDPlayer;
class CDVDInputStreamBluray
: public CDVDInputStream
, public CDVDInputStream::IDisplayTime
, public CDVDInputStream::IChapter
, public CDVDInputStream::ISeekTime
+ , public CDVDInputStream::IMenus
{
public:
- CDVDInputStreamBluray();
+ CDVDInputStreamBluray(IDVDPlayer* player);
virtual ~CDVDInputStreamBluray();
virtual bool Open(const char* strFile, const std::string &content);
virtual void Close();
@@ -44,6 +53,36 @@ class CDVDInputStreamBluray
virtual bool IsEOF();
virtual __int64 GetLength();
virtual int GetBlockSize() { return 6144; }
+ virtual ENextStream NextStream();
+
+
+ /* IMenus */
+ virtual void ActivateButton() { UserInput(BD_VK_ENTER); }
+ virtual void SelectButton(int iButton)
+ {
+ if(iButton < 10)
+ UserInput((bd_vk_key_e)(BD_VK_0 + iButton));
+ }
+ virtual int GetCurrentButton() { return 0; }
+ virtual int GetTotalButtons() { return 0; }
+ virtual void OnUp() { UserInput(BD_VK_UP); }
+ virtual void OnDown() { UserInput(BD_VK_DOWN); }
+ virtual void OnLeft() { UserInput(BD_VK_LEFT); }
+ virtual void OnRight() { UserInput(BD_VK_RIGHT); }
+ virtual void OnMenu();
+ virtual void OnBack()
+ {
+ if(IsInMenu())
+ OnMenu();
+ }
+ virtual void OnNext() {}
+ virtual void OnPrevious() {}
+ virtual bool IsInMenu();
+ virtual bool OnMouseMove(const CPoint &point) { return false; }
+ virtual bool OnMouseClick(const CPoint &point) { return false; }
+ virtual double GetTimeStampCorrection() { return 0.0; }
+
+ void UserInput(bd_vk_key_e vk);
int GetChapter();
int GetChapterCount();
@@ -56,11 +95,25 @@ class CDVDInputStreamBluray
void GetStreamInfo(int pid, char* language);
+ void OverlayCallback(const BD_OVERLAY * const);
+
BLURAY_TITLE_INFO* GetTitleLongest();
BLURAY_TITLE_INFO* GetTitleFile(const std::string& name);
protected:
+ IDVDPlayer* m_player;
DllLibbluray *m_dll;
BLURAY* m_bd;
BLURAY_TITLE_INFO* m_title;
+ bool m_title_playing;
+ uint32_t m_clip;
+ bool m_navmode;
+ std::vector<CDVDOverlayImage*> m_overlays[2];
+ enum EHoldState {
+ HOLD_NONE = 0,
+ HOLD_HELD,
+ HOLD_SKIP,
+ HOLD_DATA,
+ } m_hold;
+ BD_EVENT m_event;
};
19 xbmc/cores/dvdplayer/DVDPlayer.cpp
View
@@ -855,7 +855,8 @@ bool CDVDPlayer::IsBetterStream(CCurrentStream& current, CDemuxStream* stream)
if(m_PlayerOptions.video_only && current.type != STREAM_VIDEO)
return false;
- if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ if (m_pInputStream && ( m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
+ || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
{
int source_type;
@@ -3064,6 +3065,22 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
// since we call ffmpeg functions to decode, this is being called in the same thread as ::Process() is
int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
{
+ if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY))
+ {
+ if(iMessage == 0)
+ m_overlayContainer.Add((CDVDOverlay*)pData);
+ else if(iMessage == 1)
+ m_messenger.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH));
+ else if(iMessage == 2)
+ m_dvd.iSelectedAudioStream = *(int*)pData;
+ else if(iMessage == 3)
+ m_dvd.iSelectedSPUStream = *(int*)pData;
+ else if(iMessage == 4)
+ m_dvdPlayerVideo.EnableSubtitle(*(int*)pData ? true: false);
+
+ return 0;
+ }
+
if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
{
CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;

3 comments on commit 226c850

arnova
Collaborator

This fails to compile on Linux systems which don't have libbluray installed

Joakim Plate
Collaborator
arnova
Collaborator

Fixed compile error in 8d0d0b3

Please sign in to comment.
Something went wrong with that request. Please try again.