7#include <QCoreApplication>
24#include "libbluray/bluray.h"
32#include <libbluray/log_control.h>
33#include <libbluray/meta_data.h>
34#include <libbluray/overlay.h>
35#include <libbluray/keys.h>
37#include "util/log_control.h"
38#include "libbluray/bdnav/meta_data.h"
39#include "libbluray/decoders/overlay.h"
40#include "libbluray/keys.h"
43#define LOC QString("BDBuffer: ")
68 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(Message).trimmed());
71static int BDRead(
void *Handle,
void *
Buf,
int LBA,
int NumBlocks)
73 if (
MythFileSeek(*(
static_cast<int*
>(Handle)), LBA * 2048LL, SEEK_SET) != -1)
75 static_cast<size_t>(NumBlocks) * 2048) / 2048);
81 m_tryHDMVNavigation(qEnvironmentVariableIsSet(
"MYTHTV_HDMV")),
82 m_overlayPlanes(2, nullptr),
83 m_mainThread(QThread::currentThread())
100 bd_free_title_info(it.value());
103 bd_free_title_info(it.value());
127 ((Whence == SEEK_SET && Position ==
m_readPos) || (Whence == SEEK_CUR && Position == 0)))
135 long long newposition = (SEEK_SET == Whence) ? Position :
m_readPos + Position;
140 if ((SEEK_END == Whence) || ((SEEK_CUR == Whence) && newposition != 0))
162 QString cmd = QString(
"Seek(%1, %2)").arg(Position)
164 LOG(VB_GENERAL, LOG_ERR,
LOC + cmd +
" Failed" +
ENO);
174 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Seeking to '%1'").arg(Position));
177 return static_cast<uint64_t
>(bd_seek_time(
m_bdnav, Position));
212 else if (Actions.contains(
ACTION_0))
214 else if (Actions.contains(
ACTION_1))
216 else if (Actions.contains(
ACTION_2))
218 else if (Actions.contains(
ACTION_3))
220 else if (Actions.contains(
ACTION_4))
222 else if (Actions.contains(
ACTION_5))
224 else if (Actions.contains(
ACTION_6))
226 else if (Actions.contains(
ACTION_7))
228 else if (Actions.contains(
ACTION_8))
230 else if (Actions.contains(
ACTION_9))
249 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
276 QString
filename = QDir(QDir::cleanPath(Filename)).canonicalPath();
279 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"%1 nonexistent").arg(Filename));
284 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Opened MythBDBuffer device at %1")
289 bd_set_debug_mask(DBG_CRIT | DBG_NAV | DBG_BLURAY);
307 QString keyfile = QString(
"%1/KEYDB.cfg").arg(
GetConfDir());
338 const meta_dl *metaDiscLibrary = bd_get_meta(
m_bdnav);
342 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Disc Title: %1 (%2)")
343 .arg(metaDiscLibrary->di_name, metaDiscLibrary->language_code));
344 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Alternative Title: %1")
345 .arg(metaDiscLibrary->di_alternative));
346 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Disc Number: %1 of %2")
347 .arg(metaDiscLibrary->di_set_number).arg(metaDiscLibrary->di_num_sets));
355 const BLURAY_DISC_INFO *discinfo = bd_get_disc_info(
m_bdnav);
358 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to retrieve disc info");
367 if ((discinfo->aacs_detected && !discinfo->aacs_handled) ||
368 (discinfo->bdplus_detected && !discinfo->bdplus_handled))
384 bd_set_player_setting(
m_bdnav, BLURAY_PLAYER_SETTING_PARENTAL, 99);
389 std::string country = QScountry.toLatin1().data();
390 bd_set_player_setting_str(
m_bdnav, BLURAY_PLAYER_SETTING_AUDIO_LANG, langpref.c_str());
392 bd_set_player_setting_str(
m_bdnav, BLURAY_PLAYER_SETTING_PG_LANG, langpref.c_str());
394 bd_set_player_setting_str(
m_bdnav, BLURAY_PLAYER_SETTING_MENU_LANG, langpref.c_str());
396 bd_set_player_setting_str(
m_bdnav, BLURAY_PLAYER_SETTING_COUNTRY_CODE, country.c_str());
400 bd_set_player_setting(
m_bdnav, BLURAY_PLAYER_SETTING_REGION_CODE, regioncode);
402 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Using %1 as keyfile...").arg(keyfile));
405 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Retrieving title list (please wait).");
413 m_lastError = tr(
"Unable to find any Blu-ray compatible titles");
422 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"*** Blu-ray Disc Information ***");
423 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"First Play Supported: %1")
424 .arg(discinfo->first_play_supported ?
"yes" :
"no"));
425 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Top Menu Supported: %1")
426 .arg(discinfo->top_menu_supported ?
"yes" :
"no"));
427 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Number of HDMV Titles: %1")
428 .arg(discinfo->num_hdmv_titles));
429 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Number of BD-J Titles: %1")
430 .arg(discinfo->num_bdj_titles));
431 if (discinfo->num_bdj_titles && discinfo->bdj_detected)
433 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"BD-J Supported: %1")
434 .arg(discinfo->bdj_handled ?
"yes" :
"no"));
436 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Number of Unsupported Titles: %1")
437 .arg(discinfo->num_unsupported_titles));
438 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"AACS present on disc: %1")
439 .arg(discinfo->aacs_detected ?
"yes" :
"no"));
440 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"libaacs used: %1")
441 .arg(discinfo->libaacs_detected ?
"yes" :
"no"));
442 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"AACS handled: %1")
443 .arg(discinfo->aacs_handled ?
"yes" :
"no"));
444 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"BD+ present on disc: %1")
445 .arg(discinfo->bdplus_detected ?
"yes" :
"no"));
446 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"libbdplus used: %1")
447 .arg(discinfo->libbdplus_detected ?
"yes" :
"no"));
448 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"BD+ handled: %1")
449 .arg(discinfo->bdplus_handled ?
"yes" :
"no"));
486 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using HDMV navigation mode.");
495 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using title navigation mode.");
498 uint64_t titleLength = 0;
499 BLURAY_TITLE_INFO *titleInfo =
nullptr;
506 if (titleLength == 0 || (titleInfo->duration > titleLength))
509 titleLength = titleInfo->duration;
519 m_lastError = tr(
"Unable to find any usable Blu-ray titles");
542 return static_cast<long long>(bd_tell(
m_bdnav));
562 return bd_get_current_chapter(
m_bdnav);
572 return duration_cast<std::chrono::milliseconds>(
start);
581 return duration_cast<std::chrono::seconds>(
start);
612 if (numTitles <= 0 || Title < 0 || Title >=
static_cast<int>(numTitles))
645 bd_select_title(
m_bdnav, Index);
655 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SwitchPlaylist - start");
663 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"SwitchPlaylist - end");
679 BLURAY_TITLE_INFO* result = bd_get_title_info(
m_bdnav, Index, 0);
682 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Found title %1 info").arg(Index));
698 BLURAY_TITLE_INFO* result = bd_get_playlist_info(
m_bdnav, Index, 0);
701 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Found playlist %1 info").arg(Index));
724 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"New title info: Index %1 Playlist: %2 Duration: %3 ""Chapters: %5")
726 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"New title info: Clips: %1 Angles: %2 Title Size: %3 Frame Rate %4")
730 for (
uint i = 0; i < chapter_count; i++)
733 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Chapter %1 found @ [%2]->%3")
736 QString::number(framenum)));
739 int still = BLURAY_STILL_NONE;
740 std::chrono::seconds time = 0s;
745 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
746 QString(
"Clip %1 stillmode %2 stilltime %3 videostreams %4 audiostreams %5 igstreams %6")
759 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning: more than 1 clip, following still "
760 "frame analysis may be wrong");
763 if (still == BLURAY_STILL_TIME)
765 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Entering still frame (%1 seconds) UNSUPPORTED").arg(time.count()));
768 else if (still == BLURAY_STILL_INFINITE)
770 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Entering infinite still frame.");
790 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Switching to Angle '%1'").arg(Angle));
791 bd_seamless_angle_change(
m_bdnav, Angle);
804 return bd_get_title_size(
m_bdnav);
810 int64_t newTimestamp = Timestamp;
811 if ((newTimestamp != AV_NOPTS_VALUE) && (newTimestamp >=
m_timeDiff))
825 result = bd_read_ext(
m_bdnav,
static_cast<unsigned char*
>(
Buffer),
826 static_cast<int>(Size), &event);
841 result = bd_read(
m_bdnav,
static_cast<unsigned char*
>(
Buffer),
static_cast<int>(Size));
878 case BLURAY_VIDEO_RATE_24000_1001:
return 23.97;
879 case BLURAY_VIDEO_RATE_24:
return 24.00;
880 case BLURAY_VIDEO_RATE_25:
return 25.00;
881 case BLURAY_VIDEO_RATE_30000_1001:
return 29.97;
882 case BLURAY_VIDEO_RATE_50:
return 50.00;
883 case BLURAY_VIDEO_RATE_60000_1001:
return 59.94;
899 const BLURAY_STREAM_INFO* stream =
FindStream(
StreamID, clip.audio_streams, clip.audio_stream_count);
902 const uint8_t* lang = stream->lang;
907 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Audio Lang: 0x%1 Code: %2")
919 const BLURAY_STREAM_INFO* stream =
FindStream(
StreamID, clip.pg_streams, clip.pg_stream_count);
922 const uint8_t* lang = stream->lang;
927 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Subtitle Lang: 0x%1 Code: %2")
934 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"Key %1 (pts %2)").arg(Key).arg(Pts.count()));
939 bd_user_input(
m_bdnav, Pts.count(),
static_cast<uint32_t
>(Key));
946 if (Pts <= 0 || X == 0 || Y == 0)
948 bd_mouse_select(
m_bdnav, Pts, X, Y);
960 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Top Menu not supported");
964 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"GoToMenu %1").arg(Menu));
966 if (Menu.compare(
"root") == 0)
968 if (bd_menu_call(
m_bdnav, Pts.count()))
970 LOG(VB_PLAYBACK, LOG_INFO,
LOC +QString(
"Invoked Top Menu (pts %1)").arg(Pts.count()));
974 else if (Menu.compare(
"popup") == 0)
1006 switch (
Event.event) {
1009 case BD_EVENT_ERROR:
1010 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_ERROR %1").arg(
Event.param));
1012 case BD_EVENT_ENCRYPTED:
1013 LOG(VB_GENERAL, LOG_ERR,
LOC +
"EVENT_ENCRYPTED, playback will fail.");
1018 case BD_EVENT_ANGLE:
1019 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_ANGLE %1").arg(
Event.param));
1022 case BD_EVENT_TITLE:
1023 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_TITLE %1 (old %2)")
1027 case BD_EVENT_END_OF_TITLE:
1031 case BD_EVENT_PLAYLIST:
1032 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_PLAYLIST %1 (old %2)")
1039 case BD_EVENT_PLAYITEM:
1040 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_PLAYITEM %1").arg(
Event.param));
1046 int64_t diff = in - out;
1049 LOG(VB_PLAYBACK, LOG_DEBUG,
LOC + QString(
"PTS discontinuity - waiting for decoder: this %1, last %2, diff %3")
1050 .arg(in).arg(out).arg(diff));
1061 case BD_EVENT_CHAPTER:
1063 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_CHAPTER %1").arg(
Event.param));
1066 case BD_EVENT_PLAYMARK:
1068 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_PLAYMARK"));
1072 case BD_EVENT_PLAYLIST_STOP:
1074 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"ToDo EVENT_PLAYLIST_STOP %1")
1078 case BD_EVENT_STILL:
1079 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_STILL %1").arg(
Event.param));
1081 case BD_EVENT_STILL_TIME:
1084 std::this_thread::sleep_for(10ms);
1087 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SEEK"));
1092 case BD_EVENT_AUDIO_STREAM:
1093 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_AUDIO_STREAM %1").arg(
Event.param));
1096 case BD_EVENT_IG_STREAM:
1097 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_IG_STREAM %1").arg(
Event.param));
1100 case BD_EVENT_PG_TEXTST_STREAM:
1101 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_PG_TEXTST_STREAM %1").arg(
Event.param));
1104 case BD_EVENT_SECONDARY_AUDIO_STREAM:
1105 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SECONDARY_AUDIO_STREAM %1").arg(
Event.param));
1108 case BD_EVENT_SECONDARY_VIDEO_STREAM:
1109 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SECONDARY_VIDEO_STREAM %1").arg(
Event.param));
1113 case BD_EVENT_PG_TEXTST:
1114 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_PG_TEXTST %1")
1115 .arg(
Event.param ?
"enable" :
"disable"));
1118 case BD_EVENT_SECONDARY_AUDIO:
1119 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SECONDARY_AUDIO %1")
1120 .arg(
Event.param ?
"enable" :
"disable"));
1123 case BD_EVENT_SECONDARY_VIDEO:
1124 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SECONDARY_VIDEO %1")
1125 .arg(
Event.param ?
"enable" :
"disable"));
1128 case BD_EVENT_SECONDARY_VIDEO_SIZE:
1129 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_SECONDARY_VIDEO_SIZE %1")
1130 .arg(
Event.param==0 ?
"PIP" :
"fullscreen"));
1138 std::this_thread::sleep_for(40ms);
1143 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EVENT_MENU %1")
1144 .arg(
Event.param==0 ?
"no" :
"yes"));
1148 case BD_EVENT_KEY_INTEREST_TABLE:
1150 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"ToDo EVENT_KEY_INTEREST_TABLE %1")
1154 case BD_EVENT_UO_MASK_CHANGED:
1156 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"ToDo EVENT_UO_MASK_CHANGED %1")
1161 LOG(VB_PLAYBACK, LOG_ERR,
LOC + QString(
"Unknown Event! %1 %2")
1180 BLURAY_STREAM_INFO* Streams,
1183 const BLURAY_STREAM_INFO* stream =
nullptr;
1184 for (
int i = 0; i < StreamCount && !stream; i++)
1186 stream = &Streams[i];
1195 if (
FindStream(StreamId, clip.audio_streams, clip.audio_stream_count) ||
1196 FindStream(StreamId, clip.video_streams, clip.video_stream_count) ||
1197 FindStream(StreamId, clip.ig_streams, clip.ig_stream_count) ||
1198 FindStream(StreamId, clip.pg_streams, clip.pg_stream_count) ||
1199 FindStream(StreamId, clip.sec_audio_streams, clip.sec_audio_stream_count) ||
1200 FindStream(StreamId, clip.sec_video_streams, clip.sec_video_stream_count))
1229 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Waiting for player's buffers to drain");
1233 std::this_thread::sleep_for(10ms);
1236 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Player wait state was not cleared");
1250 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Starting from beginning...");
1262 return !SerialNum.isEmpty();
1273 State = QString(
"title:%1,time:%2,angle:%3").arg(title).arg(time.count()).arg(angle);
1276 return !
State.isEmpty();
1283 QStringList states =
State.split(
",", Qt::SkipEmptyParts);
1284 QHash<QString, uint64_t> settings;
1286 for (
const QString& state : std::as_const(states))
1288 QStringList keyvalue = state.split(
":", Qt::SkipEmptyParts);
1289 if (keyvalue.length() != 2)
1291 LOG(VB_PLAYBACK, LOG_ERR,
LOC + QString(
"Invalid BD state: %1 (%2)")
1292 .arg(state,
State));
1296 settings[keyvalue[0]] = keyvalue[1].toULongLong();
1301 if (settings.contains(
"title") && settings.contains(
"time"))
1303 uint32_t title =
static_cast<uint32_t
>(settings[
"title"]);
1304 uint64_t time = settings[
"time"];
1307 if (settings.contains(
"angle"))
1308 angle = settings[
"angle"];
1359 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"--------------------"));
1360 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay->cmd = %1, %2")
1361 .arg(Overlay->cmd).arg(Overlay->plane));
1362 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay rect = (%1,%2,%3,%4)")
1363 .arg(Overlay->x).arg(Overlay->y).arg(Overlay->w).arg(Overlay->h));
1364 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay->pts = %1")
1365 .arg(Overlay->pts));
1366 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"update palette = %1")
1367 .arg(Overlay->palette_update_flag ?
"yes":
"no"));
1371 switch(Overlay->cmd)
1373 case BD_OVERLAY_INIT:
1379 case BD_OVERLAY_CLOSE:
1394 case BD_OVERLAY_HIDE:
1395 case BD_OVERLAY_CLEAR:
1399 case BD_OVERLAY_WIPE:
1401 osd->
Wipe(Overlay->x, Overlay->y, Overlay->w, Overlay->h);
1403 case BD_OVERLAY_DRAW:
1406 const BD_PG_RLE_ELEM *rlep = Overlay->img;
1407 int actual = Overlay->w * Overlay->h;
1408 uint8_t *data = osd->
m_image.bits();
1409 data = &data[(Overlay->y * osd->
m_image.bytesPerLine()) + Overlay->x];
1410 for (
int i = 0; i < actual; i += rlep->len, rlep++)
1412 int dst_y = (i / Overlay->w) * osd->
m_image.bytesPerLine();
1413 int dst_x = (i % Overlay->w);
1414 memset(data + dst_y + dst_x, rlep->color, rlep->len);
1420 case BD_OVERLAY_FLUSH:
1424 newOverlay->m_image = osd->
m_image.convertToFormat(QImage::Format_ARGB32);
1425 newOverlay->m_pts = Overlay->pts;
1439 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"--------------------"));
1440 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay->cmd,plane = %1, %2")
1441 .arg(Overlay->cmd).arg(Overlay->plane));
1442 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay->(x,y,w,h) = %1,%2,%3x%4 - %5")
1443 .arg(Overlay->x).arg(Overlay->y).arg(Overlay->w).arg(Overlay->h).arg(Overlay->stride));
1444 LOG(VB_PLAYBACK, LOG_DEBUG, QString(
"overlay->pts = %1").arg(Overlay->pts));
1447 switch(Overlay->cmd)
1449 case BD_ARGB_OVERLAY_INIT:
1454 case BD_ARGB_OVERLAY_CLOSE:
1469 case BD_ARGB_OVERLAY_DRAW:
1473 uint8_t* data = osd->
m_image.bits();
1474 int32_t srcOffset = 0;
1475 int32_t dstOffset = (Overlay->y * osd->
m_image.bytesPerLine()) + (Overlay->x * 4);
1476 for (
uint16_t y = 0; y < Overlay->h; y++)
1478 memcpy(&data[dstOffset], &Overlay->argb[srcOffset], Overlay->w * 4_UZ);
1479 dstOffset += osd->
m_image.bytesPerLine();
1480 srcOffset += Overlay->stride;
1484 case BD_ARGB_OVERLAY_FLUSH:
1490 newOverlay->m_pts = Overlay->pts;
1495 LOG(VB_PLAYBACK, LOG_ERR, QString(
"Unknown ARGB overlay - %1").arg(Overlay->cmd));
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
A class to allow a MythMediaBuffer to read from BDs.
uint64_t GetTotalReadPosition(void)
QRecursiveMutex m_infoLock
void ClickButton(int64_t Pts, uint16_t X, uint16_t Y)
QHash< uint32_t, BLURAY_TITLE_INFO * > m_cachedTitleInfo
std::chrono::seconds GetTotalTimeOfTitle(void) const
std::chrono::seconds GetCurrentTime(void) const
int m_currentPGTextSTStream
void IgnoreWaitStates(bool Ignore) override
bool HandleAction(const QStringList &Actions, mpeg::chrono::pts Pts) override
bool GetNameAndSerialNum(QString &Name, QString &SerialNum) override
bool HandleBDEvents(void)
bool m_secondaryVideoIsFullscreen
std::chrono::milliseconds GetChapterStartTimeMs(uint32_t Chapter)
void HandleBDEvent(BD_EVENT &Event)
bool RestoreBDStateSnapshot(const QString &State)
Restore a BD snapshot.
void GetDescForPos(QString &Desc)
BLURAY_TITLE_INFO * GetPlaylistInfo(uint32_t Index)
void SkipBDWaitingForPlayer(void)
int SafeRead(void *Buffer, uint Size) override
void ProgressUpdate(void)
bool IsOpen(void) const override
QHash< uint32_t, BLURAY_TITLE_INFO * > m_cachedPlaylistInfo
long long GetReadPosition(void) const override
int GetCurrentTitle(void)
MythBDOverlay * GetOverlay(void)
bool IsReadingBlocked(void)
bool m_secondaryAudioEnabled
int64_t AdjustTimestamp(int64_t Timestamp) const
void UnblockReading(void)
uint32_t GetNumTitles(void) const
bool StartFromBeginning(void) override
int m_currentSecondaryVideoStream
uint32_t GetCurrentChapter(void)
bool IsValidStream(uint StreamId)
uint64_t GetCurrentAngle(void) const
QList< MythBDOverlay * > m_overlayImages
double GetFrameRate(void)
std::chrono::seconds GetTitleDuration(int Title)
BLURAY_TITLE_INFO * m_currentTitleInfo
bool SwitchAngle(uint Angle)
MythBDBuffer(const QString &Filename)
uint64_t GetNumAngles(void) const
bool GetBDStateSnapshot(QString &State)
Get a snapshot of the current BD state.
bool OpenFile(const QString &Filename, std::chrono::milliseconds Retry=kDefaultOpenTimeout) override
Opens a bluray device for reading.
QVector< MythBDOverlay * > m_overlayPlanes
mpeg::chrono::pts m_currentTitleLength
void SubmitOverlay(const bd_overlay_s *Overlay)
int GetAudioLanguage(uint StreamID)
std::chrono::seconds m_stillTime
mpeg::chrono::pts m_currentTime
bool SwitchTitle(uint32_t Index)
static const BLURAY_STREAM_INFO * FindStream(uint StreamID, BLURAY_STREAM_INFO *Streams, int StreamCount)
Find the stream with the given ID from an array of streams.
long long SeekInternal(long long Position, int Whence) override
uint64_t m_currentTitleAngleCount
int GetSubtitleLanguage(uint StreamID)
bool IsHDMVNavigation(void) const
void SubmitARGBOverlay(const bd_argb_overlay_s *Overlay)
int m_currentSecondaryAudioStream
uint32_t GetNumChapters(void)
bool UpdateTitleInfo(void)
BLURAY_TITLE_INFO * GetTitleInfo(uint32_t Index)
bool m_secondaryVideoEnabled
void PressButton(int32_t Key, mpeg::chrono::pts Pts)
bool m_firstPlaySupported
bool BDWaitingForPlayer(void) const
bool GoToMenu(const QString &Menu, mpeg::chrono::pts Pts)
jump to a Blu-ray root or popup menu
uint64_t GetChapterStartFrame(uint32_t Chapter)
uint64_t GetTitleSize(void) const
std::chrono::seconds GetChapterStartTime(uint32_t Chapter)
bool SwitchPlaylist(uint32_t Index)
bool IsInStillFrame(void) const override
bool GetNameAndSerialNum(QString &Name, QString &SerialNum)
void SetPalette(const BD_PG_PALETTE_ENTRY *Palette)
static ImageType inspectImage(const QString &path)
QString GetSetting(const QString &key, const QString &defaultval="")
int GetNumSetting(const QString &key, int defaultval=0)
MythLocale * GetLocale(void) const
This class is used as a container for messages.
static const Type kUpdateTvProgressEventType
QString GetCountryCode() const
bool IsInMenu(void) const override
QString m_discSerialNumber
MythOpticalState m_processState
Contains listing of PMT Stream ID's for various A/V Stream types.
int iso639_key_to_canonical_key(int iso639_2)
ISO 639-1 and ISO 639-2 support functions.
static QString iso639_key_to_str3(int code)
static int iso639_str3_to_key(const unsigned char *iso639_2)
bool is_current_thread(MThread *thread)
Use this to determine if you are in the named thread.
static void BDLogger(const char *Message)
static void FileOpenedCallback(void *Data)
static int BDRead(void *Handle, void *Buf, int LBA, int NumBlocks)
static void HandleOverlayCallback(void *Data, const bd_overlay_s *const Overlay)
static void HandleARGBOverlayCallback(void *Data, const bd_argb_overlay_s *const Overlay)
static constexpr int32_t BD_BLOCK_SIZE
void MythBDIORedirect(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
ssize_t MythFileRead(int FileID, void *Buffer, size_t Count)
off_t MythFileSeek(int FileID, off_t Offset, int Whence)
int MythfileClose(int FileID)
void MythFileOpenRegisterCallback(const char *Pathname, void *Object, callback_t Func)
int MythFileOpen(const char *Pathname, int Flags)
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
static constexpr const char * ACTION_7
static constexpr const char * ACTION_5
static constexpr const char * ACTION_0
static constexpr const char * ACTION_LEFT
static constexpr const char * ACTION_DOWN
static constexpr const char * ACTION_3
static constexpr const char * ACTION_1
static constexpr const char * ACTION_4
static constexpr const char * ACTION_RIGHT
static constexpr const char * ACTION_SELECT
static constexpr const char * ACTION_UP
static constexpr const char * ACTION_6
static constexpr const char * ACTION_8
static constexpr const char * ACTION_2
static constexpr const char * ACTION_9
QString formatTime(std::chrono::milliseconds msecs, QString fmt)
Format a milliseconds time value.
QString intToPaddedString(int n, int width=2)
Creates a zero padded string representation of an integer.
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
#define ACTION_CHANNELDOWN