Merge pull request #4314 from MartijnKaijser/beta1
[vuplus_xbmc] / xbmc / filesystem / BlurayDirectory.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20 #include "system.h"
21 #ifdef HAVE_LIBBLURAY
22 #include "BlurayDirectory.h"
23 #include "utils/log.h"
24 #include "utils/URIUtils.h"
25 #include "utils/StringUtils.h"
26 #include "URL.h"
27 #include "DllLibbluray.h"
28 #include "FileItem.h"
29 #include "video/VideoInfoTag.h"
30 #include "guilib/LocalizeStrings.h"
31
32 namespace XFILE
33 {
34
35 #define MAIN_TITLE_LENGTH_PERCENT 70 /** Minumum length of main titles, based on longest title */
36
37 CBlurayDirectory::CBlurayDirectory()
38   : m_dll(NULL)
39   , m_bd(NULL)
40 {
41 }
42
43 CBlurayDirectory::~CBlurayDirectory()
44 {
45   Dispose();
46 }
47
48 void CBlurayDirectory::Dispose()
49 {
50   if(m_bd)
51   {
52     m_dll->bd_close(m_bd);
53     m_bd = NULL;
54   }
55   delete m_dll;
56   m_dll = NULL;
57 }
58
59 CFileItemPtr CBlurayDirectory::GetTitle(const BLURAY_TITLE_INFO* title, const CStdString& label)
60 {
61   CStdString buf;
62   CStdString chap;
63   CFileItemPtr item(new CFileItem("", false));
64   CURL path(m_url);
65   buf = StringUtils::Format("BDMV/PLAYLIST/%05d.mpls", title->playlist);
66   path.SetFileName(buf);
67   item->SetPath(path.Get());
68   int duration = (int)(title->duration / 90000);
69   item->GetVideoInfoTag()->m_duration = duration;
70   item->GetVideoInfoTag()->m_iTrack = title->playlist;
71   buf = StringUtils::Format(label.c_str(), title->playlist);
72   item->m_strTitle = buf;
73   item->SetLabel(buf);
74   chap = StringUtils::Format(g_localizeStrings.Get(25007), title->chapter_count, StringUtils::SecondsToTimeString(duration).c_str());
75   item->SetProperty("Addon.Summary", chap);
76   item->m_dwSize = 0;
77   item->SetIconImage("DefaultVideo.png");
78   for(unsigned int i = 0; i < title->clip_count; ++i)
79     item->m_dwSize += title->clips[i].pkt_count * 192;
80
81   return item;
82 }
83
84 void CBlurayDirectory::GetTitles(bool main, CFileItemList &items)
85 {
86   unsigned titles = m_dll->bd_get_titles(m_bd, TITLES_RELEVANT, 0);
87   CStdString buf;
88
89   std::vector<BLURAY_TITLE_INFO*> buffer;
90
91   uint64_t duration = 0;
92
93   for(unsigned i=0; i < titles; i++)
94   {
95     BLURAY_TITLE_INFO *t = m_dll->bd_get_title_info(m_bd, i, 0);
96     if(!t)
97     {
98       CLog::Log(LOGDEBUG, "CBlurayDirectory - unable to get title %d", i);
99       continue;
100     }
101     if(t->duration > duration)
102       duration = t->duration;
103
104     buffer.push_back(t);
105   }
106
107   if(main)
108     duration = duration * MAIN_TITLE_LENGTH_PERCENT / 100;
109   else
110     duration = 0;
111
112   for(std::vector<BLURAY_TITLE_INFO*>::iterator it = buffer.begin(); it != buffer.end(); ++it)
113   {
114     if((*it)->duration < duration)
115       continue;
116     items.Add(GetTitle(*it, main ? g_localizeStrings.Get(25004) /* Main Title */ : g_localizeStrings.Get(25005) /* Title */));
117   }
118
119
120   for(std::vector<BLURAY_TITLE_INFO*>::iterator it = buffer.begin(); it != buffer.end(); ++it)
121     m_dll->bd_free_title_info(*it);
122 }
123
124 void CBlurayDirectory::GetRoot(CFileItemList &items)
125 {
126     GetTitles(true, items);
127
128     CURL path(m_url);
129     CFileItemPtr item;
130
131     path.SetFileName(URIUtils::AddFileToFolder(m_url.GetFileName(), "titles"));
132     item.reset(new CFileItem());
133     item->SetPath(path.Get());
134     item->m_bIsFolder = true;
135     item->SetLabel(g_localizeStrings.Get(25002) /* All titles */);
136     item->SetIconImage("DefaultVideoPlaylists.png");
137     items.Add(item);
138
139     path.SetFileName("BDMV/MovieObject.bdmv");
140     item.reset(new CFileItem());
141     item->SetPath(path.Get());
142     item->m_bIsFolder = false;
143     item->SetLabel(g_localizeStrings.Get(25003) /* Menus */);
144     item->SetIconImage("DefaultProgram.png");
145     items.Add(item);
146 }
147
148 bool CBlurayDirectory::GetDirectory(const CStdString& path, CFileItemList &items)
149 {
150   Dispose();
151   m_url.Parse(path);
152   CStdString root = m_url.GetHostName();
153   CStdString file = m_url.GetFileName();
154   URIUtils::RemoveSlashAtEnd(file);
155   URIUtils::RemoveSlashAtEnd(root);
156
157   m_dll = new DllLibbluray();
158   if (!m_dll->Load())
159   {
160     CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to load dll");
161     return false;
162   }
163
164   m_dll->bd_register_dir(DllLibbluray::dir_open);
165   m_dll->bd_register_file(DllLibbluray::file_open);
166   m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
167   m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);
168
169   m_bd = m_dll->bd_open(root.c_str(), NULL);
170
171   if(!m_bd)
172   {
173     CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to open %s", root.c_str());
174     return false;
175   }
176
177   if(file == "")
178     GetRoot(items);
179   else if(file == "titles")
180     GetTitles(false, items);
181   else
182     return false;
183
184   items.AddSortMethod(SortByTrackNumber,  554, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
185   items.AddSortMethod(SortBySize,         553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size
186
187   return true;
188 }
189
190
191 } /* namespace XFILE */
192 #endif