Ticket #8658: BD_title.diff
File BD_title.diff, 21.2 KB (added by , 14 years ago) |
---|
-
mythtv/libs/libmythtv/mythbdplayer.cpp
53 53 for (uint i = 0; i < total; i++) 54 54 times.push_back(player_ctx->buffer->BD()->GetChapterStartTime(i)); 55 55 } 56 57 int MythBDPlayer::GetNumTitles(void) const 58 { 59 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 60 return player_ctx->buffer->BD()->GetNumTitles(); 61 return 0; 62 } 63 64 int MythBDPlayer::GetCurrentTitle(void) const 65 { 66 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen()) 67 return player_ctx->buffer->BD()->GetCurrentTitle(); 68 return -1; 69 } 70 71 int MythBDPlayer::GetTitleDuration(int title) const 72 { 73 if (player_ctx->buffer->BD() && player_ctx->buffer->BD()->IsOpen() && 74 title >= 0 && title < GetNumTitles()) 75 { 76 return player_ctx->buffer->BD()->GetTitleDuration(title); 77 } 78 return 0; 79 } 80 81 QString MythBDPlayer::GetTitleName(int title) const 82 { 83 if (title >= 0 && title < GetNumTitles()) 84 { 85 // BD doesn't provide title names, so show title number and duration 86 return QObject::tr("%1 [%n minute(s)]", "", GetTitleDuration(title) / 60) 87 .arg(title + 1); 88 } 89 return QString(); 90 } 91 92 bool MythBDPlayer::SwitchTitle(int title) 93 { 94 uint total = GetNumTitles(); 95 if (!total) 96 return false; 97 98 return (bool)player_ctx->buffer->BD()->SwitchTitle(title); 99 } 100 101 bool MythBDPlayer::NextTitle(void) 102 { 103 return (bool)player_ctx->buffer->BD()->NextTitle(); 104 } 105 106 bool MythBDPlayer::PrevTitle(void) 107 { 108 return (bool)player_ctx->buffer->BD()->PrevTitle(); 109 } -
mythtv/libs/libmythtv/mythbdplayer.h
11 11 virtual int GetCurrentChapter(void); 12 12 virtual void GetChapterTimes(QList<long long> ×); 13 13 virtual int64_t GetChapter(int chapter); 14 15 virtual int GetNumTitles(void) const; 16 virtual int GetCurrentTitle(void) const; 17 virtual int GetTitleDuration(int title) const; 18 virtual QString GetTitleName(int title) const; 19 virtual bool SwitchTitle(int title); 20 virtual bool PrevTitle(void); 21 virtual bool NextTitle(void); 14 22 }; 15 23 16 24 #endif // MYTHBDPLAYER_H -
mythtv/libs/libmythtv/BDRingBuffer.cpp
13 13 const char *keyfilepath = keyfile.toAscii().data(); 14 14 15 15 BDRingBufferPriv::BDRingBufferPriv() 16 : bdnav(NULL) 16 : bdnav(NULL), m_numTitles(0) 17 17 { 18 18 } 19 19 … … 59 59 return false; 60 60 61 61 // Return an index of relevant titles (excludes dupe clips + titles) 62 uint32_tnumTitles = bd_get_titles(bdnav, TITLES_RELEVANT);62 m_numTitles = bd_get_titles(bdnav, TITLES_RELEVANT); 63 63 m_mainTitle = 0; 64 m_ mainTitleLength = 0;64 m_currentTitleLength = 0; 65 65 m_titlesize = 0; 66 66 m_currentTime = 0; 67 m_currentTitleInfo = NULL; 67 68 68 69 VERBOSE(VB_IMPORTANT, LOC + QString("Found %1 relevant titles.") 69 .arg( numTitles));70 .arg(m_numTitles)); 70 71 71 72 // Loop through the relevant titles and find the longest 72 for( unsigned i=0; i < numTitles; ++i) 73 uint64_t titleLength = 0; 74 BLURAY_TITLE_INFO *titleInfo = NULL; 75 for( unsigned i=0; i < m_numTitles; ++i) 73 76 { 74 m_currentTitleInfo = bd_get_title_info(bdnav, i); 75 if (m_mainTitleLength == 0 || 76 m_currentTitleInfo->duration > m_mainTitleLength) 77 titleInfo = bd_get_title_info(bdnav, i); 78 if (titleLength == 0 || titleInfo->duration > titleLength) 77 79 { 78 m_mainTitle = m_currentTitleInfo->idx;79 m_mainTitleLength = m_currentTitleInfo->duration;80 m_mainTitle = titleInfo->idx; 81 titleLength = titleInfo->duration; 80 82 } 81 83 } 82 84 83 85 // Now that we've settled on which index the main title is, get info. 84 m_currentTitleInfo = bd_get_title_info(bdnav, m_mainTitle); 85 bd_select_title(bdnav, m_mainTitle); 86 uint32_t chapter_count = m_currentTitleInfo->chapter_count; 87 VERBOSE(VB_IMPORTANT, LOC + QString("Longest title: index %1. " 88 "Duration: %2 (%3 mins) " 89 "Number of Chapters: %4") 90 .arg(m_mainTitle) 91 .arg(m_mainTitleLength) 92 .arg(m_mainTitleLength / (90000 * 60)) 93 .arg(chapter_count)); 94 VERBOSE(VB_PLAYBACK, LOC + QString("Frame Rate: %1").arg(GetFrameRate())); 95 if (chapter_count) 96 { 97 for (uint i = 0; i < chapter_count; i++) 98 { 99 uint64_t total_secs = GetChapterStartTime(i); 100 uint64_t framenum = GetChapterStartFrame(i); 101 int hours = (int)total_secs / 60 / 60; 102 int minutes = ((int)total_secs / 60) - (hours * 60); 103 double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60); 104 VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found @ [%2:%3:%4]->%5") 105 .arg(QString().sprintf("%02d", i + 1)) 106 .arg(QString().sprintf("%02d", hours)) 107 .arg(QString().sprintf("%02d", minutes)) 108 .arg(QString().sprintf("%06.3f", secs)) 109 .arg(framenum)); 110 } 111 } 112 m_titlesize = bd_get_title_size(bdnav); 86 SwitchTitle(m_mainTitle); 113 87 114 88 return true; 115 89 } … … 145 119 GetFrameRate()) / 90000.0f); 146 120 } 147 121 122 int BDRingBufferPriv::GetCurrentTitle(void) const 123 { 124 if (m_currentTitleInfo) 125 return m_currentTitleInfo->idx; 126 else 127 return -1; 128 } 129 130 int BDRingBufferPriv::GetTitleDuration(int title) const 131 { 132 int numTitles = GetNumTitles(); 133 134 if (numTitles > 0 && title >= 0 && title < numTitles) 135 { 136 BLURAY_TITLE_INFO *info = bd_get_title_info(bdnav, title); 137 if (!info) 138 return 0; 139 int duration = ((info->duration) / 90000.0f); 140 VERBOSE(VB_IMPORTANT, QString("Title: %1 Duration: %2 Duration (Min): %3").arg(title).arg(duration).arg(duration / 60)); 141 bd_free_title_info(info); 142 return duration; 143 } 144 else 145 return 0; 146 } 147 148 bool BDRingBufferPriv::SwitchTitle(uint title) 149 { 150 if (bdnav) 151 { 152 if (m_currentTitleInfo) 153 bd_free_title_info(m_currentTitleInfo); 154 155 m_currentTitleInfo = bd_get_title_info(bdnav, title); 156 157 if (!m_currentTitleInfo) 158 return false; 159 160 m_currentTitleLength = m_currentTitleInfo->duration; 161 bd_select_title(bdnav, title); 162 uint32_t chapter_count = m_currentTitleInfo->chapter_count; 163 VERBOSE(VB_IMPORTANT, LOC + QString("Selected title: index %1. " 164 "Duration: %2 (%3 mins) " 165 "Number of Chapters: %4") 166 .arg(title) 167 .arg(m_currentTitleLength) 168 .arg(m_currentTitleLength / (90000 * 60)) 169 .arg(chapter_count)); 170 VERBOSE(VB_PLAYBACK, LOC + QString("Frame Rate: %1").arg(GetFrameRate())); 171 if (chapter_count) 172 { 173 for (uint i = 0; i < chapter_count; i++) 174 { 175 uint64_t total_secs = GetChapterStartTime(i); 176 uint64_t framenum = GetChapterStartFrame(i); 177 int hours = (int)total_secs / 60 / 60; 178 int minutes = ((int)total_secs / 60) - (hours * 60); 179 double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60); 180 VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found @ [%2:%3:%4]->%5") 181 .arg(QString().sprintf("%02d", i + 1)) 182 .arg(QString().sprintf("%02d", hours)) 183 .arg(QString().sprintf("%02d", minutes)) 184 .arg(QString().sprintf("%06.3f", secs)) 185 .arg(framenum)); 186 } 187 } 188 m_titlesize = bd_get_title_size(bdnav); 189 return true; 190 } 191 else 192 return false; 193 } 194 195 bool BDRingBufferPriv::NextTitle(void) 196 { 197 if (!m_currentTitleInfo || !bdnav) 198 return false; 199 200 uint32_t nextTitle = m_currentTitleInfo->idx + 1; 201 202 if (nextTitle < GetNumTitles()) 203 return (bool)bd_select_title(bdnav, nextTitle); 204 205 return false; 206 } 207 208 bool BDRingBufferPriv::PrevTitle(void) 209 { 210 if (!m_currentTitleInfo || !bdnav || (m_currentTitleInfo->idx <= 0)) 211 return false; 212 213 uint32_t prevTitle = m_currentTitleInfo->idx - 1; 214 215 return (bool)bd_select_title(bdnav, prevTitle); 216 } 217 148 218 uint64_t BDRingBufferPriv::GetTotalReadPosition(void) 149 219 { 150 220 if (bdnav) -
mythtv/libs/libmythtv/BDRingBuffer.h
23 23 BDRingBufferPriv(); 24 24 virtual ~BDRingBufferPriv(); 25 25 26 uint32_t GetNumTitles(void) const { return m_numTitles; } 27 int GetCurrentTitle(void) const; 28 int GetTitleDuration(int title) const; 26 29 // Get the size in bytes of the current title (playlist item). 27 30 uint64_t GetTitleSize(void) const { return m_titlesize; } 28 31 // Get The total duration of the current title in 90Khz ticks. 29 uint64_t GetTotalTimeOfTitle(void) const { return (m_ mainTitleLength / 90000); }32 uint64_t GetTotalTimeOfTitle(void) const { return (m_currentTitleLength / 90000); } 30 33 uint64_t GetCurrentTime(void) { return (m_currentTime / 90000); } 31 34 uint64_t GetReadPosition(void); 32 35 uint64_t GetTotalReadPosition(void); … … 42 45 bool OpenFile(const QString &filename); 43 46 void close(void); 44 47 45 // void nextTrack(void); 46 // void prevTrack(void); 48 bool SwitchTitle(uint title); 49 bool NextTitle(void); 50 bool PrevTitle(void); 47 51 48 52 int safe_read(void *data, unsigned sz); 49 53 uint64_t Seek(uint64_t pos); 50 54 51 55 protected: 52 56 BLURAY *bdnav; 57 uint32_t m_numTitles; 53 58 uint32_t m_mainTitle; // Index number of main title 54 uint64_t m_ mainTitleLength; // Maintitle's duration, in ticks (90Khz)59 uint64_t m_currentTitleLength; // Selected title's duration, in ticks (90Khz) 55 60 BLURAY_TITLE_INFO *m_currentTitleInfo; // Selected title info from struct in bluray.h 56 61 uint64_t m_titlesize; 57 62 uint64_t m_currentTime; -
mythtv/libs/libmythtv/tv_play.cpp
5982 5982 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 5983 5983 } 5984 5984 5985 int TV::GetNumTitles(const PlayerContext *ctx) const 5986 { 5987 int num_titles = 0; 5988 ctx->LockDeleteNVP(__FILE__, __LINE__); 5989 if (ctx->nvp) 5990 num_titles = ctx->nvp->GetNumTitles(); 5991 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 5992 return num_titles; 5993 } 5994 5995 int TV::GetCurrentTitle(const PlayerContext *ctx) const 5996 { 5997 int currentTitle = 0; 5998 ctx->LockDeleteNVP(__FILE__, __LINE__); 5999 if (ctx->nvp) 6000 currentTitle = ctx->nvp->GetCurrentTitle(); 6001 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 6002 return currentTitle; 6003 } 6004 6005 int TV::GetTitleDuration(const PlayerContext *ctx, int title) const 6006 { 6007 int seconds = 0; 6008 ctx->LockDeleteNVP(__FILE__, __LINE__); 6009 if (ctx->nvp) 6010 seconds = ctx->nvp->GetTitleDuration(title); 6011 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 6012 return seconds; 6013 } 6014 6015 6016 QString TV::GetTitleName(const PlayerContext *ctx, int title) const 6017 { 6018 QString name; 6019 ctx->LockDeleteNVP(__FILE__, __LINE__); 6020 if (ctx->nvp) 6021 name = ctx->nvp->GetTitleName(title); 6022 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 6023 return name; 6024 } 6025 6026 void TV::DoSwitchTitle(PlayerContext *ctx, int title) 6027 { 6028 NormalSpeed(ctx); 6029 StopFFRew(ctx); 6030 6031 PauseAudioUntilBuffered(ctx); 6032 6033 osdInfo info; 6034 ctx->CalcNVPSliderPosition(info); 6035 info.text["description"] = tr("Jump Title"); 6036 info.text["title"] = tr("Searching"); 6037 UpdateOSDStatus(ctx, info, kOSDFunctionalType_Default); 6038 6039 ctx->LockDeleteNVP(__FILE__, __LINE__); 6040 if (ctx->nvp) 6041 ctx->nvp->SwitchTitle(title); 6042 ctx->UnlockDeleteNVP(__FILE__, __LINE__); 6043 } 6044 5985 6045 void TV::DoSkipCommercials(PlayerContext *ctx, int direction) 5986 6046 { 5987 6047 NormalSpeed(ctx); … … 9863 9923 int chapter = action.right(3).toInt(); 9864 9924 DoJumpChapter(actx, chapter); 9865 9925 } 9926 else if (action.left(11) == "JUMPTOTITLE") 9927 { 9928 int title = action.right(3).toInt(); 9929 DoSwitchTitle(actx, title); 9930 } 9866 9931 else if (action == "EDIT") 9867 9932 StartProgramEditMode(actx); 9868 9933 else if (action == "TOGGLEAUTOEXPIRE") … … 9995 10060 else if (category == "SCHEDULERECORDING") 9996 10061 title = FillOSDMenuSchedule(ctx, osd, select, level); 9997 10062 else if (category == "AVCHAPTER") 10063 { 9998 10064 title = FillOSDMenuAVChapter(ctx, osd, select, level); 10065 } 10066 else if (category == "AVTITLE") 10067 { 10068 title = FillOSDMenuAVTitle(ctx, osd, select, level); 10069 } 9999 10070 else if (category == "PIP") 10000 10071 title = FillOSDMenuPxP(ctx, osd, select, level); 10001 10072 else if (category == "INPUTSWITCHING") … … 10207 10278 return result; 10208 10279 } 10209 10280 10281 QString TV::FillOSDMenuAVTitle(const PlayerContext *ctx, OSD *osd, 10282 bool select, int level) const 10283 { 10284 QString result = QString(); 10285 QString title = tr("Title"); 10286 int num_titles = GetNumTitles(ctx); 10287 if (!num_titles) 10288 return result; 10289 10290 if (level == 0) 10291 { 10292 osd->DialogAddButton(title , "DIALOG_MENU_AVTITLE_1", true, select); 10293 } 10294 else if (level == 1) 10295 { 10296 result = title; 10297 int current_title = GetCurrentTitle(ctx); 10298 10299 for (int i = 0; i < num_titles; i++) 10300 { 10301 QString titleIdx = QString("%1").arg(i, 3, 10, QChar(48)); 10302 QString desc = GetTitleName(ctx, i); 10303 osd->DialogAddButton(desc, QString("JUMPTOTITLE%1").arg(titleIdx), 10304 false, current_title == (i + 1)); 10305 } 10306 } 10307 return result; 10308 } 10309 10210 10310 QString TV::FillOSDMenuJumpRec(const PlayerContext *ctx, OSD *osd, bool select, 10211 10311 int level) 10212 10312 { -
mythtv/libs/libmythtv/tv_play.h
443 443 int GetNumChapters(const PlayerContext*) const; 444 444 void GetChapterTimes(const PlayerContext*, QList<long long> ×) const; 445 445 int GetCurrentChapter(const PlayerContext*) const; 446 int GetNumTitles(const PlayerContext *ctx) const; 447 int GetCurrentTitle(const PlayerContext *ctx) const; 448 int GetTitleDuration(const PlayerContext *ctx, int title) const; 449 QString GetTitleName(const PlayerContext *ctx, int title) const; 450 void DoSwitchTitle(PlayerContext*, int title); 446 451 void DoJumpChapter(PlayerContext*, int direction); 447 452 void DoSkipCommercials(PlayerContext*, int direction); 448 453 449 void DoQueueTranscode(PlayerContext*, QString profile);454 void DoQueueTranscode(PlayerContext*, QString profile); 450 455 451 456 void SetAutoCommercialSkip(const PlayerContext*, 452 457 CommSkipMode skipMode = kCommSkipOff); … … 585 590 bool select, int level) const; 586 591 QString FillOSDMenuAVChapter( const PlayerContext*, OSD *osd, 587 592 bool select, int level) const; 593 QString FillOSDMenuAVTitle( const PlayerContext *, OSD *osd, 594 bool select, int level) const; 588 595 QString FillOSDMenuPxP( const PlayerContext*, OSD *osd, 589 596 bool select, int level) const; 590 597 QString FillOSDMenuSwitchInput(const PlayerContext*, OSD *osd, -
mythtv/libs/libmythtv/NuppelVideoPlayer.h
165 165 virtual void SetBookmark(void); 166 166 void SetKeyframeDistance(int keyframedistance); 167 167 void SetVideoParams(int w, int h, double fps, int keydist, 168 float a = 1.33333, FrameScanType scan = kScan_Ignore, 168 float a = 1.33333, FrameScanType scan = kScan_Ignore, 169 169 bool video_codec_changed = false); 170 170 void SetFileLength(int total, int frames); 171 171 void Zoom(ZoomDirection direction); … … 255 255 bool PauseDecoder(void); 256 256 void UnpauseDecoder(void); 257 257 void Pause(void); 258 bool Play(float speed = 1.0, bool normal = true, 259 bool unpauseaudio = true); 258 bool Play(float speed = 1.0, bool normal = true, bool unpauseaudio = true); 260 259 261 260 // Seek stuff 262 261 virtual bool FastForward(float seconds); … … 266 265 // Chapter stuff 267 266 void JumpChapter(int chapter); 268 267 268 // Title stuff 269 virtual bool SwitchTitle(int title) { return false; } 270 virtual bool NextTitle(void) { return false; } 271 virtual bool PrevTitle(void) { return false; } 272 269 273 // Commercial stuff 270 274 void SetAutoCommercialSkip(CommSkipMode autoskip) 271 275 { commBreakMap.SetAutoCommercialSkip(autoskip, framesPlayed); } … … 365 369 { tc_wrap[TC_AUDIO] = 0LL; return tc_wrap[TC_AUDIO]; } 366 370 long long ResyncAudioTimecodeOffset(void) 367 371 { tc_wrap[TC_AUDIO] = LONG_LONG_MIN; return 0L; } 368 long long GetAudioTimecodeOffset(void) const 372 long long GetAudioTimecodeOffset(void) const 369 373 { return tc_wrap[TC_AUDIO]; } 370 374 void SaveAudioTimecodeOffset(long long v) 371 375 { savedAudioTimecodeOffset = v; } … … 379 383 virtual int GetCurrentChapter(void); 380 384 virtual void GetChapterTimes(QList<long long> ×); 381 385 386 // Title public stuff 387 virtual int GetNumTitles(void) const { return 0; } 388 virtual int GetCurrentTitle(void) const { return 0; } 389 virtual int GetTitleDuration(int title) const { return 0; } 390 virtual QString GetTitleName(int title) const { return QString(); } 391 382 392 // DVD public stuff 383 393 virtual void ChangeDVDTrack(bool ffw) { (void) ffw; } 384 394 virtual bool GoToDVDMenu(QString str) { return false; } … … 551 561 long long totalLength; 552 562 long long rewindtime; 553 563 554 // -- end state stuff -- 564 // -- end state stuff -- 555 565 556 566 557 567 // Input Video Attributes … … 559 569 QSize video_dim; ///< Video (input) buffer width & height 560 570 double video_frame_rate;///< Video (input) Frame Rate (often inaccurate) 561 571 float video_aspect; ///< Video (input) Apect Ratio 562 float forced_video_aspect; 572 float forced_video_aspect; 563 573 /// Video (input) Scan Type (interlaced, progressive, detect, ignore...) 564 574 FrameScanType m_scan; 565 575 /// Set when the user selects a scan type, overriding the detected one … … 632 642 float next_play_speed; 633 643 bool next_normal_speed; 634 644 635 float play_speed; 636 bool normal_speed; 645 float play_speed; 646 bool normal_speed; 637 647 int frame_interval;///< always adjusted for play_speed 638 648 int m_frame_interval;///< used to detect changes to frame_interval 639 649 640 int ffrew_skip; 650 int ffrew_skip; 641 651 642 652 // Audio and video synchronization stuff 643 653 VideoSync *videosync; … … 648 658 bool lastsync; 649 659 bool decode_extra_audio; 650 660 int repeat_delay; 651 661 652 662 // Time Code stuff 653 663 int prevtc; ///< 32 bit timecode if last VideoFrame shown 654 664 int prevrp; ///< repeat_pict of last frame -
mythtv/libs/libmythtv/tvosdmenuentry.cpp
194 194 curMenuEntries.append(new TVOSDMenuEntry( 195 195 "AVCHAPTER", -1, 0, 1, 0, "Chapter")); 196 196 curMenuEntries.append(new TVOSDMenuEntry( 197 "AVTITLE", -1, 0, 1, 0, "Title")); 198 curMenuEntries.append(new TVOSDMenuEntry( 197 199 "GUIDE", 1, 1, 0, 0, "Program Guide")); 198 200 curMenuEntries.append(new TVOSDMenuEntry( 199 201 "PIP", 1, 1, 1, -1, "Picture-in-Picture"));