Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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 authored October 08, 2011
32  lib/DllLibbluray.h
@@ -30,6 +30,8 @@ extern "C"
30 30
 #include <libbluray/bluray.h>
31 31
 #include <libbluray/filesystem.h>
32 32
 #include <libbluray/log_control.h>
  33
+#include <libbluray/keys.h>
  34
+#include <libbluray/overlay.h>
33 35
 }
34 36
 
35 37
 class DllLibblurayInterface
@@ -65,6 +67,16 @@ class DllLibblurayInterface
65 67
   virtual void     bd_set_debug_mask(uint32_t mask)=0;
66 68
   virtual uint32_t bd_get_debug_mask(void)=0;
67 69
   virtual const BLURAY_DISC_INFO *bd_get_disc_info(BLURAY *bd)=0;
  70
+
  71
+  virtual int      bd_get_event                 (BLURAY *bd, BD_EVENT *event)=0;
  72
+  virtual int      bd_play                      (BLURAY *bd)=0;
  73
+  virtual int      bd_read_ext                  (BLURAY *bd, unsigned char *buf, int len, BD_EVENT *event)=0;
  74
+  virtual int      bd_read_skip_still           (BLURAY *bd)=0;
  75
+  virtual int      bd_user_input                (BLURAY *bd, int64_t pts, uint32_t key)=0;
  76
+  virtual int      bd_set_player_setting        (BLURAY *bd, uint32_t idx, uint32_t value)=0;
  77
+  virtual int      bd_set_player_setting_str    (BLURAY *bd, uint32_t idx, const char *s)=0;
  78
+  virtual void     bd_register_overlay_proc     (BLURAY *bd, void *handle, bd_overlay_proc_f func)=0;
  79
+  virtual int      bd_menu_call                 (BLURAY *bd, int64_t pts)=0;
68 80
 };
69 81
 
70 82
 class DllLibbluray : public DllDynamic, DllLibblurayInterface
@@ -100,6 +112,16 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface
100 112
   DEFINE_METHOD0(uint32_t,            bd_get_debug_mask)
101 113
   DEFINE_METHOD1(const BLURAY_DISC_INFO*, bd_get_disc_info,      (BLURAY *p1))
102 114
 
  115
+  DEFINE_METHOD2(int,                 bd_get_event,              (BLURAY *p1, BD_EVENT *p2))
  116
+  DEFINE_METHOD1(int,                 bd_play,                   (BLURAY *p1))
  117
+  DEFINE_METHOD4(int,                 bd_read_ext,               (BLURAY *p1, unsigned char *p2, int p3, BD_EVENT *p4))
  118
+  DEFINE_METHOD1(int,                 bd_read_skip_still,        (BLURAY *p1))
  119
+  DEFINE_METHOD3(int,                 bd_user_input,             (BLURAY *p1, int64_t p2, uint32_t p3))
  120
+  DEFINE_METHOD3(int,                 bd_set_player_setting,     (BLURAY *p1, uint32_t p2, uint32_t p3))
  121
+  DEFINE_METHOD3(int,                 bd_set_player_setting_str, (BLURAY *p1, uint32_t p2, const char *p3))
  122
+  DEFINE_METHOD3(void,                bd_register_overlay_proc,  (BLURAY *p1, void *p2, bd_overlay_proc_f p3))
  123
+  DEFINE_METHOD2(int,                 bd_menu_call,              (BLURAY *p1, int64_t p2))
  124
+
103 125
   BEGIN_METHOD_RESOLVE()
104 126
     RESOLVE_METHOD(bd_get_titles)
105 127
     RESOLVE_METHOD(bd_get_title_info)
@@ -129,6 +151,16 @@ class DllLibbluray : public DllDynamic, DllLibblurayInterface
129 151
     RESOLVE_METHOD(bd_set_debug_mask)
130 152
     RESOLVE_METHOD(bd_get_debug_mask)
131 153
     RESOLVE_METHOD(bd_get_disc_info)
  154
+
  155
+    RESOLVE_METHOD(bd_get_event)
  156
+    RESOLVE_METHOD(bd_play)
  157
+    RESOLVE_METHOD(bd_read_ext)
  158
+    RESOLVE_METHOD(bd_read_skip_still)
  159
+    RESOLVE_METHOD(bd_user_input)
  160
+    RESOLVE_METHOD(bd_set_player_setting)
  161
+    RESOLVE_METHOD(bd_set_player_setting_str)
  162
+    RESOLVE_METHOD(bd_register_overlay_proc)
  163
+    RESOLVE_METHOD(bd_menu_call)
132 164
   END_METHOD_RESOLVE()
133 165
 
134 166
 public:
2  xbmc/cores/dvdplayer/DVDInputStreams/DVDFactoryInputStream.cpp
@@ -54,7 +54,7 @@ CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IDVDPlayer* pPlayer,
54 54
   }
55 55
 #ifdef HAVE_LIBBLURAY
56 56
   else if (item.IsType(".bdmv") || item.IsType(".mpls") || content == "bluray/iso")
57  
-    return new CDVDInputStreamBluray();
  57
+    return new CDVDInputStreamBluray(pPlayer);
58 58
 #endif
59 59
   else if(file.substr(0, 6) == "rtp://"
60 60
        || file.substr(0, 7) == "rtsp://"
475  xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.cpp
@@ -22,6 +22,11 @@
22 22
 #ifdef HAVE_LIBBLURAY
23 23
 
24 24
 #include "DVDInputStreamBluray.h"
  25
+#include "IDVDPlayer.h"
  26
+#include "DVDCodecs/Overlay/DVDOverlay.h"
  27
+#include "DVDCodecs/Overlay/DVDOverlayImage.h"
  28
+#include "settings/GUISettings.h"
  29
+#include "LangInfo.h"
25 30
 #include "utils/log.h"
26 31
 #include "utils/URIUtils.h"
27 32
 #include "filesystem/File.h"
@@ -195,10 +200,17 @@ void DllLibbluray::bluray_logger(const char* msg)
195 200
   CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Logger - %s", msg);
196 201
 }
197 202
 
198  
-CDVDInputStreamBluray::CDVDInputStreamBluray() :
  203
+
  204
+static void bluray_overlay_cb(void *this_gen, const BD_OVERLAY * ov)
  205
+{
  206
+  static_cast<CDVDInputStreamBluray*>(this_gen)->OverlayCallback(ov);
  207
+}
  208
+
  209
+CDVDInputStreamBluray::CDVDInputStreamBluray(IDVDPlayer* player) :
199 210
   CDVDInputStream(DVDSTREAM_TYPE_BLURAY)
200 211
 {
201 212
   m_title = NULL;
  213
+  m_clip  = 0;
202 214
   m_bd    = NULL;
203 215
   m_dll = new DllLibbluray;
204 216
   if (!m_dll->Load())
@@ -206,6 +218,8 @@ CDVDInputStreamBluray::CDVDInputStreamBluray() :
206 218
     delete m_dll;
207 219
     m_dll = NULL;
208 220
   }
  221
+  m_content = "video/x-mpegts";
  222
+  m_player  = player;
209 223
 }
210 224
 
211 225
 CDVDInputStreamBluray::~CDVDInputStreamBluray()
@@ -250,33 +264,15 @@ BLURAY_TITLE_INFO* CDVDInputStreamBluray::GetTitleFile(const std::string& filena
250 264
     return NULL;
251 265
   }
252 266
 
253  
-  int titles = m_dll->bd_get_titles(m_bd, TITLES_ALL, 0);
254  
-  if(titles < 0)
255  
-  {
256  
-    CLog::Log(LOGERROR, "get_playlist_title - unable to get list of titles");
257  
-    return NULL;
258  
-  }
259  
-
260  
-  BLURAY_TITLE_INFO *t;
261  
-  for(int i=0; i < titles; i++)
262  
-  {
263  
-    t = m_dll->bd_get_title_info(m_bd, i, 0);
264  
-    if(!t)
265  
-    {
266  
-      CLog::Log(LOGDEBUG, "get_playlist_title - unable to get title %d", i);
267  
-      continue;
268  
-    }
269  
-    if(t->playlist == playlist)
270  
-      return t;
271  
-    m_dll->bd_free_title_info(t);
272  
-  }
273  
-
274  
-  return NULL;
  267
+  return m_dll->bd_get_playlist_info(m_bd, playlist, 0);
275 268
 }
276 269
 
277 270
 
278 271
 bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content)
279 272
 {
  273
+  if(m_player == NULL)
  274
+    return false;
  275
+
280 276
   CStdString strPath;
281 277
   URIUtils::GetDirectory(strFile,strPath);
282 278
   URIUtils::RemoveSlashAtEnd(strPath);
@@ -299,7 +295,7 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
299 295
   m_dll->bd_register_dir(DllLibbluray::dir_open);
300 296
   m_dll->bd_register_file(DllLibbluray::file_open);
301 297
   m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
302  
-  m_dll->bd_set_debug_mask(DBG_CRIT);
  298
+  m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);
303 299
 
304 300
   CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::Open - opening %s", strPath.c_str());
305 301
   m_bd = m_dll->bd_open(strPath.c_str(), NULL);
@@ -353,28 +349,76 @@ bool CDVDInputStreamBluray::Open(const char* strFile, const std::string& content
353 349
   CStdString filename = URIUtils::GetFileName(strFile);
354 350
   if(filename.Equals("index.bdmv"))
355 351
   {
  352
+    m_navmode = false;
356 353
     m_title = GetTitleLongest();
357 354
   }
358 355
   else if(URIUtils::GetExtension(filename).Equals(".mpls"))
359 356
   {
  357
+    m_navmode = false;
360 358
     m_title = GetTitleFile(filename);
361 359
   }
  360
+  else if(filename.Equals("MovieObject.bdmv"))
  361
+  {
  362
+    m_navmode = true;
  363
+    if (m_navmode && !disc_info->first_play_supported) {
  364
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - Can't play disc in HDMV navigation mode - First Play title not supported");
  365
+      m_navmode = false;
  366
+    }
  367
+
  368
+    if (m_navmode && disc_info->num_unsupported_titles > 0) {
  369
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - Unsupported titles found - Some titles can't be played in navigation mode");
  370
+    }
  371
+
  372
+    if(!m_navmode)
  373
+      m_title = GetTitleLongest();
  374
+  }
362 375
   else
363 376
   {
364 377
     CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - unsupported bluray file selected %s", strPath.c_str());
365 378
     return false;
366 379
   }
367 380
 
368  
-  if(!m_title)
  381
+  if(m_navmode)
369 382
   {
370  
-    CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to get title info");
371  
-    return false;
372  
-  }
  383
+    int region = g_guiSettings.GetInt("dvds.playerregion");
  384
+    if(region == 0)
  385
+    {
  386
+      CLog::Log(LOGWARNING, "CDVDInputStreamBluray::Open - region dvd must be set in setting, assuming region 1");
  387
+      region = 1;
  388
+    }
  389
+    m_dll->bd_set_player_setting    (m_bd, BLURAY_PLAYER_SETTING_REGION_CODE,  region);
  390
+    m_dll->bd_set_player_setting    (m_bd, BLURAY_PLAYER_SETTING_PARENTAL,     0);
  391
+    m_dll->bd_set_player_setting    (m_bd, BLURAY_PLAYER_SETTING_PLAYER_PROFILE, 0);
  392
+    m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_AUDIO_LANG,   g_langInfo.GetDVDAudioLanguage().c_str());
  393
+    m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_PG_LANG,      g_langInfo.GetDVDSubtitleLanguage().c_str());
  394
+    m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_MENU_LANG,    g_langInfo.GetDVDMenuLanguage().c_str());
  395
+    m_dll->bd_set_player_setting_str(m_bd, BLURAY_PLAYER_SETTING_COUNTRY_CODE, "us");
  396
+    m_dll->bd_register_overlay_proc (m_bd, this, bluray_overlay_cb);
  397
+
  398
+    m_dll->bd_get_event(m_bd, NULL);
  399
+
373 400
 
374  
-  if(m_dll->bd_select_title(m_bd, m_title->idx) == 0 )
  401
+    if(m_dll->bd_play(m_bd) <= 0)
  402
+    {
  403
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed play disk %s", strPath.c_str());
  404
+      return false;
  405
+    }
  406
+    m_hold = HOLD_DATA;
  407
+    m_title_playing = false;
  408
+  }
  409
+  else
375 410
   {
376  
-    CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to select title %d", m_title->idx);
377  
-    return false;
  411
+    if(!m_title)
  412
+    {
  413
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to get title info");
  414
+      return false;
  415
+    }
  416
+
  417
+    if(m_dll->bd_select_playlist(m_bd, m_title->playlist) == 0 )
  418
+    {
  419
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray::Open - failed to select title %d", m_title->idx);
  420
+      return false;
  421
+    }
378 422
   }
379 423
 
380 424
   return true;
@@ -385,17 +429,324 @@ void CDVDInputStreamBluray::Close()
385 429
 {
386 430
   if (!m_dll)
387 431
     return;
  432
+  if(m_title)
  433
+    m_dll->bd_free_title_info(m_title);
388 434
   if(m_bd)
  435
+  {
  436
+    m_dll->bd_register_overlay_proc(m_bd, NULL, NULL);
389 437
     m_dll->bd_close(m_bd);
  438
+  }
390 439
   m_bd = NULL;
391  
-  if(m_title)
392  
-    m_dll->bd_free_title_info(m_title);
393 440
   m_title = NULL;
394 441
 }
395 442
 
396 443
 int CDVDInputStreamBluray::Read(BYTE* buf, int buf_size)
397 444
 {
398  
-  return m_dll->bd_read(m_bd, buf, buf_size);
  445
+  if(m_navmode)
  446
+  {
  447
+    int result = 0;
  448
+    do {
  449
+
  450
+      if(m_hold == HOLD_HELD)
  451
+        return 0;
  452
+
  453
+      if(m_hold == HOLD_SKIP)
  454
+      {
  455
+        /* m_event already holds data */
  456
+        m_hold = HOLD_DATA;
  457
+        result = 0;
  458
+      }
  459
+      else
  460
+      {
  461
+        result = m_dll->bd_read_ext (m_bd, buf, buf_size, &m_event);
  462
+
  463
+        if(m_hold == HOLD_NONE)
  464
+        {
  465
+          /* Check for holding events */
  466
+          switch(m_event.event) {
  467
+            case BD_EVENT_SEEK:
  468
+            case BD_EVENT_TITLE:
  469
+              if(m_title_playing)
  470
+                m_player->OnDVDNavResult(NULL, 1);
  471
+              m_hold = HOLD_HELD;
  472
+              return result;
  473
+
  474
+            case BD_EVENT_PLAYLIST:
  475
+            case BD_EVENT_PLAYITEM:
  476
+              m_hold = HOLD_HELD;
  477
+              return result;
  478
+            default:
  479
+              break;
  480
+          }
  481
+        }
  482
+        if(result > 0)
  483
+          m_hold = HOLD_NONE;
  484
+      }
  485
+      int pid = -1;
  486
+      switch (m_event.event) {
  487
+
  488
+        case BD_EVENT_ERROR:
  489
+          CLog::Log(LOGERROR, "CDVDInputStreamBluray - BD_EVENT_ERROR");
  490
+          return -1;
  491
+
  492
+        case BD_EVENT_ENCRYPTED:
  493
+          CLog::Log(LOGERROR, "CDVDInputStreamBluray - BD_EVENT_ENCRYPTED");
  494
+          return -1;
  495
+
  496
+        /* playback control */
  497
+
  498
+        case BD_EVENT_SEEK:
  499
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_SEEK");
  500
+          break;
  501
+
  502
+        case BD_EVENT_STILL_TIME:
  503
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_STILL_TIME %d", m_event.param);
  504
+          return 0;
  505
+
  506
+        case BD_EVENT_STILL:
  507
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_STILL %d", m_event.param);
  508
+          break;
  509
+
  510
+        /* playback position */
  511
+
  512
+        case BD_EVENT_ANGLE:
  513
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_ANGLE %d", m_event.param);
  514
+          break;
  515
+
  516
+        case BD_EVENT_END_OF_TITLE:
  517
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_END_OF_TITLE %d", m_event.param);
  518
+          m_title_playing = false;
  519
+          break;
  520
+
  521
+        case BD_EVENT_TITLE:
  522
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_TITLE %d", m_event.param);
  523
+          if(m_title)
  524
+            m_dll->bd_free_title_info(m_title);
  525
+          m_title = m_dll->bd_get_title_info(m_bd, m_event.param, 0);
  526
+          m_title_playing = true;
  527
+          break;
  528
+
  529
+        case BD_EVENT_PLAYLIST:
  530
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PLAYLIST %d", m_event.param);
  531
+          if(m_title)
  532
+            m_dll->bd_free_title_info(m_title);
  533
+          m_title = m_dll->bd_get_playlist_info(m_bd, m_event.param, 0);
  534
+          break;
  535
+
  536
+        case BD_EVENT_PLAYITEM:
  537
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PLAYITEM %d", m_event.param);
  538
+          m_clip = m_event.param;
  539
+          break;
  540
+
  541
+        case BD_EVENT_CHAPTER:
  542
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_CHAPTER %d", m_event.param);
  543
+          break;
  544
+
  545
+        /* stream selection */
  546
+
  547
+        case BD_EVENT_AUDIO_STREAM:
  548
+          pid = -1;
  549
+          if(m_title
  550
+          && m_title->clip_count > m_clip
  551
+          && m_title->clips[m_clip].audio_stream_count > (uint8_t)(m_event.param - 1))
  552
+            pid = m_title->clips[m_clip].audio_streams[m_event.param-1].pid;
  553
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_AUDIO_STREAM %d %d", m_event.param, pid);
  554
+          m_player->OnDVDNavResult((void*)&pid, 2);
  555
+          break;
  556
+
  557
+        case BD_EVENT_PG_TEXTST:
  558
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PG_TEXTST %d", m_event.param);
  559
+          pid = m_event.param;
  560
+          m_player->OnDVDNavResult((void*)&pid, 4);
  561
+          break;
  562
+
  563
+        case BD_EVENT_PG_TEXTST_STREAM:
  564
+          pid = -1;
  565
+          if(m_title
  566
+          && m_title->clip_count > m_clip
  567
+          && m_title->clips[m_clip].pg_stream_count > (uint8_t)(m_event.param - 1))
  568
+            pid = m_title->clips[m_clip].pg_streams[m_event.param-1].pid;
  569
+          CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - BD_EVENT_PG_TEXTST_STREAM %d, %d", m_event.param, pid);
  570
+          m_player->OnDVDNavResult((void*)&pid, 3);
  571
+          break;
  572
+
  573
+        case BD_EVENT_IG_STREAM:
  574
+        case BD_EVENT_SECONDARY_AUDIO:
  575
+        case BD_EVENT_SECONDARY_AUDIO_STREAM:
  576
+        case BD_EVENT_SECONDARY_VIDEO:
  577
+        case BD_EVENT_SECONDARY_VIDEO_SIZE:
  578
+        case BD_EVENT_SECONDARY_VIDEO_STREAM:
  579
+
  580
+        case BD_EVENT_NONE:
  581
+          break;
  582
+
  583
+        default:
  584
+          CLog::Log(LOGWARNING, "CDVDInputStreamBluray - unhandled libbluray event %d [param %d]", m_event.event, m_event.param);
  585
+          break;
  586
+      }
  587
+
  588
+    } while(result == 0);
  589
+
  590
+    return result;
  591
+  }
  592
+  else
  593
+    return m_dll->bd_read(m_bd, buf, buf_size);
  594
+}
  595
+
  596
+static uint8_t  clamp(double v)
  597
+{
  598
+  return (v) > 255.0 ? 255 : ((v) < 0.0 ? 0 : (uint8_t)(v+0.5f));
  599
+}
  600
+
  601
+static uint32_t build_rgba(const BD_PG_PALETTE_ENTRY &e)
  602
+{
  603
+  double r = 1.164 * (e.Y - 16)                        + 1.596 * (e.Cr - 128);
  604
+  double g = 1.164 * (e.Y - 16) - 0.391 * (e.Cb - 128) - 0.813 * (e.Cr - 128);
  605
+  double b = 1.164 * (e.Y - 16) + 2.018 * (e.Cb - 128);
  606
+  return (uint32_t)e.T      << PIXEL_ASHIFT
  607
+       | (uint32_t)clamp(r) << PIXEL_RSHIFT
  608
+       | (uint32_t)clamp(g) << PIXEL_GSHIFT
  609
+       | (uint32_t)clamp(b) << PIXEL_BSHIFT;
  610
+}
  611
+
  612
+void CDVDInputStreamBluray::OverlayCallback(const BD_OVERLAY * const ov)
  613
+{
  614
+
  615
+  CDVDOverlayGroup* group   = new CDVDOverlayGroup();
  616
+  group->bForced = true;
  617
+
  618
+  if(ov == NULL)
  619
+  {
  620
+    for(unsigned i = 0; i < 2; ++i)
  621
+    {
  622
+      for(std::vector<CDVDOverlayImage*>::iterator it = m_overlays[i].begin(); it != m_overlays[i].end(); ++it)
  623
+        (*it)->Release();
  624
+      m_overlays[i].clear();
  625
+    }
  626
+
  627
+    m_player->OnDVDNavResult(group, 0);
  628
+    return;
  629
+  }
  630
+
  631
+  group->iPTSStartTime = ov->pts;
  632
+  group->iPTSStopTime  = 0;
  633
+
  634
+  if (ov->plane > 1)
  635
+  {
  636
+    CLog::Log(LOGWARNING, "CDVDInputStreamBluray - Ignoring overlay with multiple planes");
  637
+    group->Release();
  638
+    return;
  639
+  }
  640
+
  641
+  std::vector<CDVDOverlayImage*>& plane(m_overlays[ov->plane]);
  642
+
  643
+  /* fixup existing overlays */
  644
+  for(std::vector<CDVDOverlayImage*>::iterator it = plane.begin(); it != plane.end();)
  645
+  {
  646
+    /* if it's fully outside we are done */
  647
+    if(ov->x + ov->w <= (*it)->x
  648
+    || ov->x         >= (*it)->x + (*it)->width
  649
+    || ov->y + ov->h <= (*it)->y
  650
+    || ov->y         >= (*it)->y + (*it)->height)
  651
+    {
  652
+      ++it;
  653
+      continue;
  654
+    }
  655
+
  656
+    int y1 = std::max<int>((*it)->y                , ov->y);
  657
+    int y2 = std::min<int>((*it)->y + (*it)->height, ov->y + ov->h);
  658
+    int x1 = std::max<int>((*it)->x                , ov->x);
  659
+    int x2 = std::min<int>((*it)->x + (*it)->width , ov->x + ov->w);
  660
+
  661
+    /* if all should be cleared, delete */
  662
+    if(x1 == (*it)->x
  663
+    && x2 == (*it)->x + (*it)->width
  664
+    && y1 == (*it)->y
  665
+    && y2 == (*it)->y + (*it)->height)
  666
+    {
  667
+      CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - Delete(%d) %d-%dx%d-%d", ov->plane, x1, x2, y1, y2);
  668
+      it = plane.erase(it);
  669
+      continue;
  670
+    }
  671
+#if(1)
  672
+    CLog::Log(LOGDEBUG, "CDVDInputStreamBluray - Clearing(%d) %d-%dx%d-%d", ov->plane, x1, x2, y1, y2);
  673
+
  674
+    /* replace overlay with a new copy*/
  675
+    CDVDOverlayImage* overlay = new CDVDOverlayImage(*(*it));
  676
+    (*it)->Release();
  677
+    (*it) = overlay;
  678
+
  679
+    /* any old hw overlay must be released */
  680
+    SAFE_RELEASE(overlay->m_overlay);
  681
+
  682
+    /* clear out overlap */
  683
+    y1 -= overlay->y;
  684
+    y2 -= overlay->y;
  685
+    x1 -= overlay->x;
  686
+    x2 -= overlay->x;
  687
+
  688
+    /* find fully transparent */
  689
+    int transp = 0;
  690
+    for(; transp < overlay->palette_colors; ++transp)
  691
+    {
  692
+      if(((overlay->palette[transp] >> PIXEL_ASHIFT) & 0xff) == 0)
  693
+        break;
  694
+    }
  695
+
  696
+    if(transp == overlay->palette_colors)
  697
+    {
  698
+      CLog::Log(LOGERROR, "CDVDInputStreamBluray - failed to find transparent color");
  699
+      continue;
  700
+    }
  701
+
  702
+    for(int y = y1; y < y2; ++y)
  703
+    {
  704
+      BYTE* line = overlay->data + y * overlay->linesize;
  705
+      for(int x = x1; x < x2; ++x)
  706
+        line[x] = transp;
  707
+    }
  708
+    ++it;
  709
+#endif
  710
+  }
  711
+
  712
+
  713
+  /* uncompress and draw bitmap */
  714
+  if (ov->img)
  715
+  {
  716
+    CDVDOverlayImage* overlay = new CDVDOverlayImage();
  717
+
  718
+    if (ov->palette)
  719
+    {
  720
+      overlay->palette_colors = 256;
  721
+      overlay->palette        = (uint32_t*)calloc(overlay->palette_colors, 4);
  722
+
  723
+      for(unsigned i = 0; i < 256; i++)
  724
+        overlay->palette[i] = build_rgba(ov->palette[i]);
  725
+    }
  726
+
  727
+    const BD_PG_RLE_ELEM *rlep = ov->img;
  728
+    uint8_t *img = (uint8_t*) malloc(ov->w * ov->h);
  729
+    unsigned pixels = ov->w * ov->h;
  730
+
  731
+    for (unsigned i = 0; i < pixels; i += rlep->len, rlep++) {
  732
+      memset(img + i, rlep->color, rlep->len);
  733
+    }
  734
+
  735
+    overlay->data     = img;
  736
+    overlay->linesize = ov->w;
  737
+    overlay->x        = ov->x;
  738
+    overlay->y        = ov->y;
  739
+    overlay->height   = ov->h;
  740
+    overlay->width    = ov->w;
  741
+    plane.push_back(overlay);
  742
+  }
  743
+
  744
+  for(unsigned i = 0; i < 2; ++i)
  745
+  {
  746
+    for(std::vector<CDVDOverlayImage*>::iterator it = m_overlays[i].begin(); it != m_overlays[i].end(); ++it)
  747
+      group->m_overlays.push_back((*it)->Acquire());
  748
+  }
  749
+  m_player->OnDVDNavResult(group, 0);
399 750
 }
400 751
 
401 752
 int CDVDInputStreamBluray::GetTotalTime()
@@ -499,10 +850,10 @@ static bool find_stream(int pid, BLURAY_STREAM_INFO *info, int count, char* lang
499 850
 
500 851
 void CDVDInputStreamBluray::GetStreamInfo(int pid, char* language)
501 852
 {
502  
-  if(m_title->clip_count == 0)
  853
+  if(!m_title || m_clip >= m_title->clip_count)
503 854
     return;
504 855
 
505  
-  BLURAY_CLIP_INFO *clip = m_title->clips;
  856
+  BLURAY_CLIP_INFO *clip = m_title->clips+m_clip;
506 857
 
507 858
   if(find_stream(pid, clip->audio_streams, clip->audio_stream_count, language))
508 859
     return;
@@ -514,4 +865,56 @@ void CDVDInputStreamBluray::GetStreamInfo(int pid, char* language)
514 865
     return;
515 866
 }
516 867
 
  868
+CDVDInputStream::ENextStream CDVDInputStreamBluray::NextStream()
  869
+{
  870
+  if(!m_navmode)
  871
+    return NEXTSTREAM_NONE;
  872
+
  873
+  if(m_hold == HOLD_HELD)
  874
+  {
  875
+    m_hold = HOLD_SKIP;
  876
+    return NEXTSTREAM_OPEN;
  877
+  }
  878
+  if(m_hold == HOLD_NONE)
  879
+  {
  880
+    m_hold = HOLD_DATA;
  881
+    m_dll->bd_read_skip_still(m_bd);
  882
+  }
  883
+  return NEXTSTREAM_RETRY;
  884
+}
  885
+
  886
+void CDVDInputStreamBluray::UserInput(bd_vk_key_e vk)
  887
+{
  888
+  if(m_bd == NULL || !m_navmode)
  889
+    return;
  890
+  m_dll->bd_user_input(m_bd, -1, vk);
  891
+}
  892
+
  893
+void CDVDInputStreamBluray::OnMenu()
  894
+{
  895
+  if(m_bd == NULL || !m_navmode)
  896
+    return;
  897
+
  898
+  if(m_dll->bd_user_input(m_bd, -1, BD_VK_POPUP) >= 0)
  899
+    return;
  900
+  CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - popup failed, trying root");
  901
+
  902
+  if(m_dll->bd_user_input(m_bd, -1, BD_VK_ROOT_MENU) >= 0)
  903
+    return;
  904
+
  905
+  CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - root failed, trying explicit");
  906
+  if(m_dll->bd_menu_call(m_bd, -1) >= 0)
  907
+    return;
  908
+  CLog::Log(LOGDEBUG, "CDVDInputStreamBluray::OnMenu - root failed");
  909
+}
  910
+
  911
+bool CDVDInputStreamBluray::IsInMenu()
  912
+{
  913
+  if(m_bd == NULL || !m_navmode)
  914
+    return false;
  915
+  if(m_overlays[BD_OVERLAY_IG].size() > 0)
  916
+    return true;
  917
+  return false;
  918
+}
  919
+
517 920
 #endif
59  xbmc/cores/dvdplayer/DVDInputStreams/DVDInputStreamBluray.h
@@ -23,18 +23,27 @@
23 23
 
24 24
 #include "DVDInputStream.h"
25 25
 
  26
+
  27
+extern "C"
  28
+{
  29
+#include <libbluray/bluray.h>
  30
+#include <libbluray/keys.h>
  31
+#include <libbluray/overlay.h>
  32
+}
  33
+
  34
+class CDVDOverlayImage;
26 35
 class DllLibbluray;
27  
-typedef struct bluray BLURAY;
28  
-typedef struct bd_title_info BLURAY_TITLE_INFO;
  36
+class IDVDPlayer;
29 37
 
30 38
 class CDVDInputStreamBluray 
31 39
   : public CDVDInputStream
32 40
   , public CDVDInputStream::IDisplayTime
33 41
   , public CDVDInputStream::IChapter
34 42
   , public CDVDInputStream::ISeekTime
  43
+  , public CDVDInputStream::IMenus
35 44
 {
36 45
 public:
37  
-  CDVDInputStreamBluray();
  46
+  CDVDInputStreamBluray(IDVDPlayer* player);
38 47
   virtual ~CDVDInputStreamBluray();
39 48
   virtual bool Open(const char* strFile, const std::string &content);
40 49
   virtual void Close();
@@ -44,6 +53,36 @@ class CDVDInputStreamBluray
44 53
   virtual bool IsEOF();
45 54
   virtual __int64 GetLength();
46 55
   virtual int GetBlockSize() { return 6144; }
  56
+  virtual ENextStream NextStream();
  57
+
  58
+
  59
+  /* IMenus */
  60
+  virtual void ActivateButton()          { UserInput(BD_VK_ENTER); }
  61
+  virtual void SelectButton(int iButton)
  62
+  {
  63
+    if(iButton < 10)
  64
+      UserInput((bd_vk_key_e)(BD_VK_0 + iButton));
  65
+  }
  66
+  virtual int  GetCurrentButton()        { return 0; }
  67
+  virtual int  GetTotalButtons()         { return 0; }
  68
+  virtual void OnUp()                    { UserInput(BD_VK_UP); }
  69
+  virtual void OnDown()                  { UserInput(BD_VK_DOWN); }
  70
+  virtual void OnLeft()                  { UserInput(BD_VK_LEFT); }
  71
+  virtual void OnRight()                 { UserInput(BD_VK_RIGHT); }
  72
+  virtual void OnMenu();
  73
+  virtual void OnBack()
  74
+  {
  75
+    if(IsInMenu())
  76
+      OnMenu();
  77
+  }
  78
+  virtual void OnNext()                  {}
  79
+  virtual void OnPrevious()              {}
  80
+  virtual bool IsInMenu();
  81
+  virtual bool OnMouseMove(const CPoint &point)  { return false; }
  82
+  virtual bool OnMouseClick(const CPoint &point) { return false; }
  83
+  virtual double GetTimeStampCorrection()        { return 0.0; }
  84
+
  85
+  void UserInput(bd_vk_key_e vk);
47 86
 
48 87
   int GetChapter();
49 88
   int GetChapterCount();
@@ -56,11 +95,25 @@ class CDVDInputStreamBluray
56 95
 
57 96
   void GetStreamInfo(int pid, char* language);
58 97
 
  98
+  void OverlayCallback(const BD_OVERLAY * const);
  99
+
59 100
   BLURAY_TITLE_INFO* GetTitleLongest();
60 101
   BLURAY_TITLE_INFO* GetTitleFile(const std::string& name);
61 102
 
62 103
 protected:
  104
+  IDVDPlayer*   m_player;
63 105
   DllLibbluray *m_dll;
64 106
   BLURAY* m_bd;
65 107
   BLURAY_TITLE_INFO* m_title;
  108
+  bool               m_title_playing;
  109
+  uint32_t           m_clip;
  110
+  bool m_navmode;
  111
+  std::vector<CDVDOverlayImage*> m_overlays[2];
  112
+  enum EHoldState {
  113
+    HOLD_NONE = 0,
  114
+    HOLD_HELD,
  115
+    HOLD_SKIP,
  116
+    HOLD_DATA,
  117
+  } m_hold;
  118
+  BD_EVENT m_event;
66 119
 };
19  xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -855,7 +855,8 @@ bool CDVDPlayer::IsBetterStream(CCurrentStream& current, CDemuxStream* stream)
855 855
   if(m_PlayerOptions.video_only && current.type != STREAM_VIDEO)
856 856
     return false;
857 857
 
858  
-  if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
  858
+  if (m_pInputStream && ( m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
  859
+                       || m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) )
859 860
   {
860 861
     int source_type;
861 862
 
@@ -3064,6 +3065,22 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
3064 3065
 // since we call ffmpeg functions to decode, this is being called in the same thread as ::Process() is
3065 3066
 int CDVDPlayer::OnDVDNavResult(void* pData, int iMessage)
3066 3067
 {
  3068
+  if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY))
  3069
+  {
  3070
+    if(iMessage == 0)
  3071
+      m_overlayContainer.Add((CDVDOverlay*)pData);
  3072
+    else if(iMessage == 1)
  3073
+      m_messenger.Put(new CDVDMsg(CDVDMsg::GENERAL_FLUSH));
  3074
+    else if(iMessage == 2)
  3075
+      m_dvd.iSelectedAudioStream = *(int*)pData;
  3076
+    else if(iMessage == 3)
  3077
+      m_dvd.iSelectedSPUStream   = *(int*)pData;
  3078
+    else if(iMessage == 4)
  3079
+      m_dvdPlayerVideo.EnableSubtitle(*(int*)pData ? true: false);
  3080
+
  3081
+    return 0;
  3082
+  }
  3083
+
3067 3084
   if (m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
3068 3085
   {
3069 3086
     CDVDInputStreamNavigator* pStream = (CDVDInputStreamNavigator*)m_pInputStream;

0 notes on commit 226c850

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