Ticket #8658: BD_title.diff

File BD_title.diff, 21.2 KB (added by stuartm, 14 years ago)
  • mythtv/libs/libmythtv/mythbdplayer.cpp

     
    5353    for (uint i = 0; i < total; i++)
    5454        times.push_back(player_ctx->buffer->BD()->GetChapterStartTime(i));
    5555}
     56
     57int 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
     64int 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
     71int 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
     81QString 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
     92bool 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
     101bool MythBDPlayer::NextTitle(void)
     102{
     103    return (bool)player_ctx->buffer->BD()->NextTitle();
     104}
     105
     106bool MythBDPlayer::PrevTitle(void)
     107{
     108    return (bool)player_ctx->buffer->BD()->PrevTitle();
     109}
  • mythtv/libs/libmythtv/mythbdplayer.h

     
    1111    virtual int     GetCurrentChapter(void);
    1212    virtual void    GetChapterTimes(QList<long long> &times);
    1313    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);
    1422};
    1523
    1624#endif // MYTHBDPLAYER_H
  • mythtv/libs/libmythtv/BDRingBuffer.cpp

     
    1313const char *keyfilepath = keyfile.toAscii().data();
    1414
    1515BDRingBufferPriv::BDRingBufferPriv()
    16     : bdnav(NULL)
     16    : bdnav(NULL), m_numTitles(0)
    1717{
    1818}
    1919
     
    5959            return false;
    6060
    6161        // Return an index of relevant titles (excludes dupe clips + titles)
    62         uint32_t numTitles = bd_get_titles(bdnav, TITLES_RELEVANT);
     62        m_numTitles = bd_get_titles(bdnav, TITLES_RELEVANT);
    6363        m_mainTitle = 0;
    64         m_mainTitleLength = 0;
     64        m_currentTitleLength = 0;
    6565        m_titlesize = 0;
    6666        m_currentTime = 0;
     67        m_currentTitleInfo = NULL;
    6768
    6869        VERBOSE(VB_IMPORTANT, LOC + QString("Found %1 relevant titles.")
    69                 .arg(numTitles));
     70                .arg(m_numTitles));
    7071
    7172        // 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)
    7376        {
    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)
    7779            {
    78                 m_mainTitle = m_currentTitleInfo->idx;
    79                 m_mainTitleLength = m_currentTitleInfo->duration;
     80                m_mainTitle = titleInfo->idx;
     81                titleLength = titleInfo->duration;
    8082            }
    8183        }
    8284
    8385        // 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);
    11387
    11488        return true;
    11589}
     
    145119                                    GetFrameRate()) / 90000.0f);
    146120}
    147121
     122int BDRingBufferPriv::GetCurrentTitle(void) const
     123{
     124    if (m_currentTitleInfo)
     125        return m_currentTitleInfo->idx;
     126    else
     127        return -1;
     128}
     129
     130int 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
     148bool 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
     195bool 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
     208bool 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
    148218uint64_t BDRingBufferPriv::GetTotalReadPosition(void)
    149219{
    150220    if (bdnav)
  • mythtv/libs/libmythtv/BDRingBuffer.h

     
    2323    BDRingBufferPriv();
    2424    virtual ~BDRingBufferPriv();
    2525
     26    uint32_t GetNumTitles(void) const { return m_numTitles; }
     27    int      GetCurrentTitle(void) const;
     28    int      GetTitleDuration(int title) const;
    2629    // Get the size in bytes of the current title (playlist item).
    2730    uint64_t GetTitleSize(void) const { return m_titlesize; }
    2831    // 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); }
    3033    uint64_t GetCurrentTime(void) { return (m_currentTime / 90000); }
    3134    uint64_t GetReadPosition(void);
    3235    uint64_t GetTotalReadPosition(void);
     
    4245    bool OpenFile(const QString &filename);
    4346    void close(void);
    4447
    45 //    void nextTrack(void);
    46 //    void prevTrack(void);
     48    bool SwitchTitle(uint title);
     49    bool NextTitle(void);
     50    bool PrevTitle(void);
    4751
    4852    int  safe_read(void *data, unsigned sz);
    4953    uint64_t Seek(uint64_t pos);
    5054
    5155  protected:
    5256    BLURAY            *bdnav;
     57    uint32_t           m_numTitles;
    5358    uint32_t           m_mainTitle; // Index number of main title
    54     uint64_t           m_mainTitleLength; // Main title's duration, in ticks (90Khz)
     59    uint64_t           m_currentTitleLength; // Selected title's duration, in ticks (90Khz)
    5560    BLURAY_TITLE_INFO *m_currentTitleInfo; // Selected title info from struct in bluray.h
    5661    uint64_t           m_titlesize;
    5762    uint64_t           m_currentTime;
  • mythtv/libs/libmythtv/tv_play.cpp

     
    59825982    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
    59835983}
    59845984
     5985int 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
     5995int 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
     6005int 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
     6016QString 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
     6026void 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
    59856045void TV::DoSkipCommercials(PlayerContext *ctx, int direction)
    59866046{
    59876047    NormalSpeed(ctx);
     
    98639923            int chapter = action.right(3).toInt();
    98649924            DoJumpChapter(actx, chapter);
    98659925        }
     9926        else if (action.left(11) == "JUMPTOTITLE")
     9927        {
     9928            int title = action.right(3).toInt();
     9929            DoSwitchTitle(actx, title);
     9930        }
    98669931        else if (action == "EDIT")
    98679932            StartProgramEditMode(actx);
    98689933        else if (action == "TOGGLEAUTOEXPIRE")
     
    999510060    else if (category == "SCHEDULERECORDING")
    999610061        title = FillOSDMenuSchedule(ctx, osd, select, level);
    999710062    else if (category == "AVCHAPTER")
     10063    {
    999810064        title = FillOSDMenuAVChapter(ctx, osd, select, level);
     10065    }
     10066    else if (category == "AVTITLE")
     10067    {
     10068        title = FillOSDMenuAVTitle(ctx, osd, select, level);
     10069    }
    999910070    else if (category ==  "PIP")
    1000010071        title = FillOSDMenuPxP(ctx, osd, select, level);
    1000110072    else if (category == "INPUTSWITCHING")
     
    1020710278    return result;
    1020810279}
    1020910280
     10281QString 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
    1021010310QString TV::FillOSDMenuJumpRec(const PlayerContext *ctx, OSD *osd, bool select,
    1021110311                               int level)
    1021210312{
  • mythtv/libs/libmythtv/tv_play.h

     
    443443    int  GetNumChapters(const PlayerContext*) const;
    444444    void GetChapterTimes(const PlayerContext*, QList<long long> &times) const;
    445445    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);
    446451    void DoJumpChapter(PlayerContext*, int direction);
    447452    void DoSkipCommercials(PlayerContext*, int direction);
    448453
    449     void DoQueueTranscode(PlayerContext*,QString profile);
     454    void DoQueueTranscode(PlayerContext*, QString profile);
    450455
    451456    void SetAutoCommercialSkip(const PlayerContext*,
    452457                               CommSkipMode skipMode = kCommSkipOff);
     
    585590                                   bool select, int level) const;
    586591    QString FillOSDMenuAVChapter(  const PlayerContext*, OSD *osd,
    587592                                   bool select, int level) const;
     593    QString FillOSDMenuAVTitle(    const PlayerContext *, OSD *osd,
     594                                   bool select, int level) const;
    588595    QString FillOSDMenuPxP(        const PlayerContext*, OSD *osd,
    589596                                   bool select, int level) const;
    590597    QString FillOSDMenuSwitchInput(const PlayerContext*, OSD *osd,
  • mythtv/libs/libmythtv/NuppelVideoPlayer.h

     
    165165    virtual void SetBookmark(void);
    166166    void SetKeyframeDistance(int keyframedistance);
    167167    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,
    169169                        bool video_codec_changed = false);
    170170    void SetFileLength(int total, int frames);
    171171    void Zoom(ZoomDirection direction);
     
    255255    bool PauseDecoder(void);
    256256    void UnpauseDecoder(void);
    257257    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);
    260259
    261260    // Seek stuff
    262261    virtual bool FastForward(float seconds);
     
    266265    // Chapter stuff
    267266    void JumpChapter(int chapter);
    268267
     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
    269273    // Commercial stuff
    270274    void SetAutoCommercialSkip(CommSkipMode autoskip)
    271275        { commBreakMap.SetAutoCommercialSkip(autoskip, framesPlayed); }
     
    365369        { tc_wrap[TC_AUDIO] = 0LL; return tc_wrap[TC_AUDIO]; }
    366370    long long ResyncAudioTimecodeOffset(void)
    367371        { tc_wrap[TC_AUDIO] = LONG_LONG_MIN; return 0L; }
    368     long long GetAudioTimecodeOffset(void) const 
     372    long long GetAudioTimecodeOffset(void) const
    369373        { return tc_wrap[TC_AUDIO]; }
    370374    void SaveAudioTimecodeOffset(long long v)
    371375        { savedAudioTimecodeOffset = v; }
     
    379383    virtual int  GetCurrentChapter(void);
    380384    virtual void GetChapterTimes(QList<long long> &times);
    381385
     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
    382392    // DVD public stuff
    383393    virtual void ChangeDVDTrack(bool ffw)       { (void) ffw;       }
    384394    virtual bool GoToDVDMenu(QString str)       { return false;     }
     
    551561    long long totalLength;
    552562    long long rewindtime;
    553563
    554     // -- end state stuff -- 
     564    // -- end state stuff --
    555565
    556566
    557567    // Input Video Attributes
     
    559569    QSize    video_dim;       ///< Video (input) buffer width & height
    560570    double   video_frame_rate;///< Video (input) Frame Rate (often inaccurate)
    561571    float    video_aspect;    ///< Video (input) Apect Ratio
    562     float    forced_video_aspect; 
     572    float    forced_video_aspect;
    563573    /// Video (input) Scan Type (interlaced, progressive, detect, ignore...)
    564574    FrameScanType m_scan;
    565575    /// Set when the user selects a scan type, overriding the detected one
     
    632642    float      next_play_speed;
    633643    bool       next_normal_speed;
    634644
    635     float      play_speed;   
    636     bool       normal_speed; 
     645    float      play_speed;
     646    bool       normal_speed;
    637647    int        frame_interval;///< always adjusted for play_speed
    638648    int        m_frame_interval;///< used to detect changes to frame_interval
    639649
    640     int        ffrew_skip;   
     650    int        ffrew_skip;
    641651
    642652    // Audio and video synchronization stuff
    643653    VideoSync *videosync;
     
    648658    bool       lastsync;
    649659    bool       decode_extra_audio;
    650660    int        repeat_delay;
    651  
     661
    652662    // Time Code stuff
    653663    int        prevtc;        ///< 32 bit timecode if last VideoFrame shown
    654664    int        prevrp;        ///< repeat_pict of last frame
  • mythtv/libs/libmythtv/tvosdmenuentry.cpp

     
    194194    curMenuEntries.append(new TVOSDMenuEntry(
    195195        "AVCHAPTER",         -1,  0,  1,  0, "Chapter"));
    196196    curMenuEntries.append(new TVOSDMenuEntry(
     197        "AVTITLE",           -1,  0,  1,  0, "Title"));
     198    curMenuEntries.append(new TVOSDMenuEntry(
    197199        "GUIDE",              1,  1,  0,  0, "Program Guide"));
    198200    curMenuEntries.append(new TVOSDMenuEntry(
    199201        "PIP",                1,  1,  1, -1, "Picture-in-Picture"));