diff options
author | ace20022 <ace20022@ymail.com> | 2017-06-19 15:33:45 +0200 |
---|---|---|
committer | ace20022 <ace20022@ymail.com> | 2017-07-07 09:02:52 +0200 |
commit | a73923eda1d6717f7f7c417c029e632605ed3f62 (patch) | |
tree | 684e36d295cbd5f34796c8b2acccec46c320a2b5 | |
parent | 40e75d28d67e6374c3d1959b547f0e0c9127fb70 (diff) |
[bluray] Use bd_open_stream for Blu-ray image files. This makes BD-J menus from image files functional.
-rw-r--r-- | lib/DllLibbluray.h | 5 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp | 78 | ||||
-rw-r--r-- | xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.h | 3 | ||||
-rw-r--r-- | xbmc/filesystem/BlurayDirectory.cpp | 2 |
4 files changed, 78 insertions, 10 deletions
diff --git a/lib/DllLibbluray.h b/lib/DllLibbluray.h index b7d9ff2272..63e0879000 100644 --- a/lib/DllLibbluray.h +++ b/lib/DllLibbluray.h @@ -31,6 +31,8 @@ extern "C" #include <libbluray/overlay.h> } +typedef int(*read_blocks_f)(void *handle, void *buf, int lba, int num_blocks); + class DllLibblurayInterface { public: @@ -41,6 +43,7 @@ public: virtual void bd_free_title_info(BLURAY_TITLE_INFO *title_info)=0; virtual BLURAY *bd_open(const char* device_path, const char* keyfile_path)=0; virtual int bd_open_disc(BLURAY *bd, const char *device_path, const char *keyfile_path)=0; + virtual int bd_open_stream(BLURAY *bd, void *read_blocks_handle, read_blocks_f func) = 0; virtual BLURAY *bd_init(void)= 0; virtual void bd_close(BLURAY *bd)=0; virtual int64_t bd_seek(BLURAY *bd, uint64_t pos)=0; @@ -92,6 +95,7 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface DEFINE_METHOD1(void, bd_free_title_info, (BLURAY_TITLE_INFO *p1)) DEFINE_METHOD2(BLURAY*, bd_open, (const char* p1, const char* p2)) DEFINE_METHOD3(int, bd_open_disc, (BLURAY *p1, const char *p2, const char *p3)) + DEFINE_METHOD3(int, bd_open_stream, (BLURAY *p1, void *p2, read_blocks_f p3)) DEFINE_METHOD0(BLURAY*, bd_init) DEFINE_METHOD1(void, bd_close, (BLURAY *p1)) DEFINE_METHOD2(int64_t, bd_seek, (BLURAY *p1, uint64_t p2)) @@ -140,6 +144,7 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface RESOLVE_METHOD_RENAME(bd_free_title_info, bd_free_title_info) RESOLVE_METHOD_RENAME(bd_open, bd_open) RESOLVE_METHOD(bd_open_disc) + RESOLVE_METHOD(bd_open_stream) RESOLVE_METHOD(bd_init) RESOLVE_METHOD_RENAME(bd_close, bd_close) RESOLVE_METHOD_RENAME(bd_seek, bd_seek) diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp index 7c587b4c56..a23b4c843f 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp @@ -20,6 +20,7 @@ #include "system.h" #include <functional> +#include <limits> #include "DVDInputStreamBluray.h" #include "IVideoPlayer.h" @@ -50,6 +51,22 @@ using namespace XFILE; + +static int read_blocks(void* handle, void* buf, int lba, int num_blocks) +{ + int result = -1; + CDVDInputStreamFile* lpstream = reinterpret_cast<CDVDInputStreamFile*>(handle); + int64_t offset = static_cast<int64_t>(lba) * 2048; + if (lpstream->Seek(offset, SEEK_SET) >= 0) + { + int64_t size = static_cast<int64_t>(num_blocks) * 2048; + if (size <= std::numeric_limits<int>::max()) + result = lpstream->Read(reinterpret_cast<uint8_t*>(buf), static_cast<int>(size)) / 2048; + } + + return result; +} + void DllLibbluray::file_close(BD_FILE_H *file) { if (file) @@ -194,7 +211,7 @@ void bluray_overlay_argb_cb(void *this_gen, const struct bd_argb_overlay_s * co #endif CDVDInputStreamBluray::CDVDInputStreamBluray(IVideoPlayer* player, const CFileItem& fileitem) : - CDVDInputStream(DVDSTREAM_TYPE_BLURAY, fileitem) + CDVDInputStream(DVDSTREAM_TYPE_BLURAY, fileitem), m_pstream(nullptr) { m_title = NULL; m_clip = (uint32_t)-1; @@ -279,18 +296,38 @@ bool CDVDInputStreamBluray::Open() std::string filename; std::string root; - if(URIUtils::IsProtocol(strPath, "bluray")) + bool openStream = false; + + // The item was selected via the simple menu + if (URIUtils::IsProtocol(strPath, "bluray")) { CURL url(strPath); - root = url.GetHostName(); + root = url.GetHostName(); filename = URIUtils::GetFileName(url.GetFileName()); + + // check for a menu call for an image file + if (StringUtils::EqualsNoCase(filename, "menu")) + { + //get rid of the udf:// protocol + CURL url2(root); + std::string root2 = url2.GetHostName(); + CURL url(root2); + CFileItem item(url, false); + if (item.IsDiscImage()) + { + if (!OpenStream(item)) + return false; + + openStream = true; + } + } } - else if(URIUtils::HasExtension(strPath, ".iso|.img|.udf")) + else if (m_item.IsDiscImage()) { - CURL url("udf://"); - url.SetHostName(strPath); - root = url.Get(); - filename = "index.bdmv"; + if (!OpenStream(m_item)) + return false; + + openStream = true; } else { @@ -335,7 +372,15 @@ bool CDVDInputStreamBluray::Open() CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s", root.c_str()); - if (!m_dll->bd_open_disc(m_bd, root.c_str(), NULL)) + if (openStream) + { + if (!m_dll->bd_open_stream(m_bd, m_pstream.get(), read_blocks)) + { + CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to open %s in stream mode", CURL::GetRedacted(root).c_str()); + return false; + } + } + else if (!m_dll->bd_open_disc(m_bd, root.c_str(), NULL)) { CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to open %s", root.c_str()); return false; @@ -467,6 +512,7 @@ void CDVDInputStreamBluray::Close() } m_bd = NULL; m_title = NULL; + m_pstream.reset(); } void CDVDInputStreamBluray::ProcessEvent() { @@ -1236,3 +1282,17 @@ void CDVDInputStreamBluray::SetupPlayerSettings() m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_CACHE_ROOT, cacheDir.c_str()); #endif } + +bool CDVDInputStreamBluray::OpenStream(CFileItem &item) +{ + m_pstream.reset(new CDVDInputStreamFile(item)); + + if (!m_pstream->Open()) + { + CLog::Log(LOGERROR, "Error opening image file %s", CURL::GetRedacted(item.GetPath()).c_str()); + Close(); + return false; + } + + return true; +} diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.h b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.h index b833edb083..608d187834 100644 --- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.h +++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.h @@ -31,6 +31,7 @@ extern "C" #include <libbluray/keys.h> #include <libbluray/overlay.h> #include <libbluray/player_settings.h> +#include "DVDInputStreamFile.h" } #define MAX_PLAYLIST_ID 99999 @@ -172,5 +173,7 @@ protected: #endif private: + bool OpenStream(CFileItem &item); void SetupPlayerSettings(); + std::unique_ptr<CDVDInputStreamFile> m_pstream; }; diff --git a/xbmc/filesystem/BlurayDirectory.cpp b/xbmc/filesystem/BlurayDirectory.cpp index 95f0deb63c..64b4effe93 100644 --- a/xbmc/filesystem/BlurayDirectory.cpp +++ b/xbmc/filesystem/BlurayDirectory.cpp @@ -136,7 +136,7 @@ void CBlurayDirectory::GetRoot(CFileItemList &items) item->SetIconImage("DefaultVideoPlaylists.png"); items.Add(item); - path.SetFileName("BDMV/MovieObject.bdmv"); + path.SetFileName("menu"); item.reset(new CFileItem()); item->SetPath(path.Get()); item->m_bIsFolder = false; |