Ticket #511: dvd_seeking3.patch

File dvd_seeking3.patch, 15.3 KB (added by skamithi@…, 14 years ago)

patch to improve ff/rew using internal dvd player.

  • NuppelVideoPlayer.cpp

     
    47624767    }
    47634768}
    47644769
     4770void NuppelVideoPlayer::ChangeDVDTrack(bool ffw)
     4771{
     4772    if ( !ringBuffer->isDVD())
     4773       return;
     4774
     4775    GetDecoder()->ChangeDVDTrack(ffw);
     4776    usleep(100000);
     4777    ClearAfterSeek();
     4778}
     4779
  • NuppelVideoPlayer.h

     
    249249    void CheckTVChain();
    250250    void FileChangedCallback();
    251251
     252    // DVD public stuff
     253    void ChangeDVDTrack(bool ffw);
     254
    252255  protected:
    253256    void DisplayPauseFrame(void);
    254257    void DisplayNormalFrame(void);
  • decoderbase.cpp

     
    8888    // Overwrites current positionmap with entire contents of database
    8989    QMap<long long, long long> posMap;
    9090
    91 
    92     if ((positionMapType == MARK_UNSET) ||
     91    if (ringBuffer->isDVD())
     92    {
     93        keyframedist = 15;
     94        if (fps < 26 && fps > 24)
     95           keyframedist = 12;
     96        long long totframes =(long long) (ringBuffer->GetTotalTimeOfTitle() * fps);
     97        posMap[totframes] = ringBuffer->GetTotalReadPosition();
     98    }
     99    else if ((positionMapType == MARK_UNSET) ||
    93100        (keyframedist == -1))
    94101    {
    95102        m_playbackinfo->GetPositionMap(posMap, MARK_GOP_BYFRAME);
     
    296303    bool ret_val = m_positionMap.size() > old_posmap_size;
    297304    if (ret_val && keyframedist > 0)
    298305    {
    299         long long totframes =
    300             m_positionMap[m_positionMap.size()-1].index * keyframedist;
    301         int length = (int)((totframes * 1.0) / fps);
     306        long long totframes;
     307        int length;
     308        if (ringBuffer->isDVD())
     309        {
     310            totframes = m_positionMap[m_positionMap.size()-1].index;
     311            length = ringBuffer->GetTotalTimeOfTitle();
     312        }
     313        else
     314        {
     315            totframes =
     316                m_positionMap[m_positionMap.size()-1].index * keyframedist;
     317            length = (int)((totframes * 1.0) / fps);
     318        }
    302319        GetNVP()->SetFileLength(length, totframes);
    303320        GetNVP()->SetKeyframeDistance(keyframedist);
    304321        posmapStarted = true;
     
    392409    if (m_positionMap.empty())
    393410        return false;
    394411
    395     // Find keyframe <= desiredFrame, store in lastKey (frames)
    396     int pos_idx1, pos_idx2;
     412    if (ringBuffer->isDVD())
     413    {
     414        long long pos = DVDFindPosition(desiredFrame);
     415        ringBuffer->Seek(pos,SEEK_SET);
     416        lastKey = desiredFrame+1;
     417    }
     418    else
     419    {
     420        // Find keyframe <= desiredFrame, store in lastKey (frames)
     421        int pos_idx1, pos_idx2;
    397422
    398     FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2);
     423        FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2);
    399424
    400     int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;
     425        int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;
    401426
    402     if (hasKeyFrameAdjustTable)
    403         lastKey = m_positionMap[pos_idx].adjFrame;
    404     else
    405         lastKey = m_positionMap[pos_idx].index * keyframedist;
    406 
    407     long long keyPos = m_positionMap[pos_idx].pos;
    408     long long curPosition = ringBuffer->GetReadPosition();
    409     long long diff = keyPos - curPosition;
    410 
    411     // Don't rewind further than we have space to store video
    412     while (keyPos <= 0)
    413     {
    414         pos_idx++;
    415         if (pos_idx >= (int)m_positionMap.size())
    416         {
    417             diff = 0;
    418             return false;
    419         }
    420427        if (hasKeyFrameAdjustTable)
    421428            lastKey = m_positionMap[pos_idx].adjFrame;
    422429        else
    423430            lastKey = m_positionMap[pos_idx].index * keyframedist;
    424         keyPos = m_positionMap[pos_idx].pos;
    425431
    426         diff = keyPos - curPosition;
     432        long long keyPos = m_positionMap[pos_idx].pos;
     433        long long curPosition = ringBuffer->GetReadPosition();
     434        long long diff = keyPos - curPosition;
     435
     436        // Don't rewind further than we have space to store video
     437        while (keyPos <= 0)
     438        {
     439            pos_idx++;
     440            if (pos_idx >= (int)m_positionMap.size())
     441           {
     442                diff = 0;
     443                return false;
     444            }
     445            if (hasKeyFrameAdjustTable)
     446                lastKey = m_positionMap[pos_idx].adjFrame;
     447            else
     448                lastKey = m_positionMap[pos_idx].index * keyframedist;
     449                keyPos = m_positionMap[pos_idx].pos;
     450
     451             diff = keyPos - curPosition;
     452         }
     453
     454         ringBuffer->Seek(diff, SEEK_CUR);
    427455    }
    428456
    429     ringBuffer->Seek(diff, SEEK_CUR);
    430    
    431457    framesPlayed = lastKey;
    432458    framesRead = lastKey;
    433459
     
    455481    if (desiredFrame < framesPlayed)
    456482        return DoRewind(desiredFrame, doflush);
    457483
     484
    458485    bool oldrawstate = getrawframes;
    459486    getrawframes = false;
    460487
    461488    long long last_frame = 0;
    462     if (!m_positionMap.empty())
     489    if (ringBuffer->isDVD())
     490        last_frame = m_positionMap[m_positionMap.size()-1].index;
     491    else if (!m_positionMap.empty())
    463492        last_frame = m_positionMap[m_positionMap.size()-1].index * keyframedist;
    464493
    465494    if (desiredFrame > last_frame)
     
    474503
    475504    bool needflush = false;
    476505
     506    if (ringBuffer->isDVD())
     507        last_frame = m_positionMap[m_positionMap.size()-1].index;
    477508    if (!m_positionMap.empty())
    478509        last_frame = m_positionMap[m_positionMap.size()-1].index * keyframedist;
    479510
     
    506537    if (m_positionMap.empty())
    507538        return false;
    508539
    509     // Find keyframe >= desiredFrame, store in lastKey
    510     // if exactseeks, use keyframe <= desiredFrame
    511     int pos_idx1, pos_idx2;
    512     FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2);
     540    if (ringBuffer->isDVD())
     541    {
     542        long long pos = DVDFindPosition(desiredFrame);
     543        ringBuffer->Seek(pos,SEEK_SET);
     544        lastKey = desiredFrame+1;
     545        framesPlayed = lastKey;
     546        framesRead = lastKey;
     547    }
     548    else
     549    {
     550        // Find keyframe >= desiredFrame, store in lastKey
     551        // if exactseeks, use keyframe <= desiredFrame
     552        int pos_idx1, pos_idx2;
     553        FindPosition(desiredFrame, hasKeyFrameAdjustTable, pos_idx1, pos_idx2);
    513554
    514     int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;
     555        int pos_idx = pos_idx1 < pos_idx2 ? pos_idx1 : pos_idx2;
    515556
    516     if (hasKeyFrameAdjustTable)
    517         lastKey = m_positionMap[pos_idx].adjFrame;
    518     else
    519         lastKey = m_positionMap[pos_idx].index * keyframedist;
     557        if (hasKeyFrameAdjustTable)
     558            lastKey = m_positionMap[pos_idx].adjFrame;
     559        else
     560            lastKey = m_positionMap[pos_idx].index * keyframedist;
    520561
    521     long long keyPos = m_positionMap[pos_idx].pos;
     562        long long keyPos = m_positionMap[pos_idx].pos;
    522563
    523     if (framesPlayed < lastKey)
    524     {
    525         long long diff = keyPos - ringBuffer->GetReadPosition();
     564        if (framesPlayed < lastKey)
     565        {
     566            long long diff = keyPos - ringBuffer->GetReadPosition();
    526567
    527         ringBuffer->Seek(diff, SEEK_CUR);
    528         needflush = true;
    529    
    530         framesPlayed = lastKey;
    531         framesRead = lastKey;
     568            ringBuffer->Seek(diff, SEEK_CUR);
     569            needflush = true;
     570     
     571            framesPlayed = lastKey;
     572            framesRead = lastKey;
     573        }
    532574    }
    533575
    534576    int normalframes = desiredFrame - framesPlayed;
     
    577619    waitingForChange = true;
    578620}
    579621 
     622void DecoderBase::ChangeDVDTrack(bool ffw)
     623{
     624    bool result = true;
     625    if (!ringBuffer->isDVD())
     626        return;
     627
     628    uint prevcellstart = ringBuffer->GetCellStart();
     629
     630    if (ffw)
     631        result = ringBuffer->nextTrack();
     632    else
     633        ringBuffer->prevTrack();
     634
     635    if (result)
     636   {
     637
     638        if ((prevcellstart == 0 && ffw) || (prevcellstart != 0 ))
     639        {
     640           while (prevcellstart == ringBuffer->GetCellStart())
     641           {
     642               usleep(10000);
     643           }
     644        }
     645
     646        uint elapsed = ringBuffer->GetCellStart();
     647
     648        if (elapsed == 0)
     649           SeekReset(framesPlayed,0,true);
     650
     651        // update frames played
     652        long long played = (int) (elapsed * fps);
     653
     654        framesPlayed = played;
     655        GetNVP()->getVideoOutput()->SetFramesPlayed(played+1);
     656        GetNVP()->SetFramesPlayed(played+1);
     657   }
     658}
     659
     660long long DecoderBase::DVDFindPosition(long long desiredFrame)
     661{
     662    if ( !ringBuffer->isDVD())
     663       return 0;
     664   
     665   int size = m_positionMap.size() - 1;
     666   int multiplier = m_positionMap[size].pos / m_positionMap[size].index ;
     667   return (long long) (desiredFrame * multiplier);
     668}
  • decoderbase.h

     
    8585    void SetWaitForChange(void);
    8686    void SetReadAdjust(long long adjust);
    8787
     88    // DVD public stuff
     89    void ChangeDVDTrack(bool ffw);
     90    long long DVDFindPosition(long long desiredFrame);
     91
    8892  protected:
    8993    void FileChanged(void);
    9094
  • RingBuffer.h

     
    7777    bool isDVD(void) const { return dvdPriv; }
    7878    void getPartAndTitle(int &title, int &part);
    7979    void getDescForPos(QString &desc);
    80     void nextTrack(void);
     80    bool nextTrack(void);
    8181    void prevTrack(void);
     82    uint GetTotalTimeOfTitle(void);
     83    uint GetCellStart(void);
     84    long long GetTotalReadPosition(void);
    8285
    8386    long long SetAdjustFilesize(void);
    8487   
  • RingBuffer.cpp

     
    11121112/** \fn RingBuffer::nextTrack(void)
    11131113 *  \brief Calls DVDRingBufferPriv::nextTrack(void)
    11141114 */
    1115 void RingBuffer::nextTrack(void)
     1115bool RingBuffer::nextTrack(void)
    11161116{
    11171117   if (dvdPriv)
    1118        dvdPriv->nextTrack();
     1118       return dvdPriv->nextTrack();
     1119   return false;
    11191120}
    11201121
    11211122/** \fn RingBuffer::prevTrack(void)
     
    11271128       dvdPriv->prevTrack();
    11281129}
    11291130
     1131/** \fn RingBuffer::GetTotalTimeOfTitle(void)
     1132 *  \brief Calls DVDRingBufferPriv::GetTotalTimeOfTitle(void)
     1133 */
     1134uint RingBuffer::GetTotalTimeOfTitle(void)
     1135{
     1136   if (dvdPriv)
     1137       return dvdPriv->GetTotalTimeOfTitle();
     1138   return 0;
     1139}
     1140
     1141/** \fn RingBuffer::GetCellStart(void)
     1142 *  \brief Calls DVDRingBufferPriv::GetCellStart(void)
     1143 */
     1144uint RingBuffer::GetCellStart(void)
     1145{
     1146   if (dvdPriv)
     1147       return dvdPriv->GetCellStart();
     1148   return 0;
     1149}
     1150
     1151/** \fn RingBuffer::GetTotalReadPosition(void)
     1152 *  \brief Calls DVDRingBufferPriv::GetTotalReadPosition(void)
     1153 */
     1154long long RingBuffer::GetTotalReadPosition(void)
     1155{
     1156   if (dvdPriv)
     1157       return dvdPriv->GetTotalReadPosition();
     1158   return 0;
     1159}
     1160
     1161
  • DVDRingBuffer.cpp

     
    326327    return tot;
    327328}
    328329
    329 void DVDRingBufferPriv::nextTrack(void)
     330bool DVDRingBufferPriv::nextTrack(void)
    330331{
    331332    int newPart = part + 1;
    332     if (newPart < maxPart)
     333    if (newPart < maxPart)
     334   {
    333335        dvdnav_part_play(dvdnav, title, newPart);
     336        return true;
     337   }
     338   return false;
    334339}
    335340
    336341void DVDRingBufferPriv::prevTrack(void)
    337342{
    338343    int newPart = part - 1;
    339     if (newPart < 0)
    340         newPart = 0;
     344    if (newPart > 0)
     345        dvdnav_part_play(dvdnav, title, newPart);
     346    else
     347        Seek(0,SEEK_SET); // May cause picture to become jumpy.
     348}
    341349
    342     dvdnav_part_play(dvdnav, title, newPart);
     350uint DVDRingBufferPriv::GetTotalTimeOfTitle(void)
     351{
     352    return pgcLength/90000; // 90000 ticks = 1 second
    343353}
    344354
     355uint DVDRingBufferPriv::GetCellStart(void)
     356{
     357    return cellStart/90000;
     358}
     359
    345360#endif // HAVE_DVDNAV
  • DVDRingBuffer.h

     
    22#ifndef DVD_RING_BUFFER_H_
    33#define DVD_RING_BUFFER_H_
    44
    5 #define DVD_BLOCK_SIZE 2048
     5#define DVD_BLOCK_SIZE 2048LL
    66#define DVD_MENU_MAX 7
    77
    88#include <qstring.h>
     
    5859    void GetDescForPos(QString &desc) const;
    5960    void GetPartAndTitle(int &_part, int &_title) const
    6061        { _part  = part; _title = _title; }
     62    uint GetTotalTimeOfTitle(void);
     63    uint GetCellStart(void);
    6164
    6265    // commands
    6366    bool OpenFile(const QString &filename);
    6467    void close(void);
    65     void nextTrack(void);
     68    bool nextTrack(void);
    6669    void prevTrack(void);
    6770    int  safe_read(void *data, unsigned sz);
    6871    long long Seek(long long pos, int whence);
  • tv_play.cpp

     
    20272027        {
    20282028            if (prbuffer->isDVD())
    20292029            {
    2030                 prbuffer->prevTrack();
     2030                nvp->ChangeDVDTrack(0);
    20312031                UpdateOSDSeekMessage(tr("Previous Chapter"),
    20322032                                     osd_general_timeout);
    20332033            }
     
    20402040        {
    20412041            if (prbuffer->isDVD())
    20422042            {
    2043                 prbuffer->nextTrack();
     2043                nvp->ChangeDVDTrack(1);
    20442044                UpdateOSDSeekMessage(tr("Next Chapter"), osd_general_timeout);
    20452045            }
    20462046            else
     
    23202320            {
    23212321                if (prbuffer->isDVD())
    23222322                {
    2323                     prbuffer->prevTrack();
     2323                    nvp->ChangeDVDTrack(0);
    23242324                    UpdateOSDSeekMessage(tr("Previous Chapter"),
    23252325                                         osd_general_timeout);
    23262326                }
     
    23332333            {
    23342334                if (prbuffer->isDVD())
    23352335                {
    2336                     prbuffer->nextTrack();
     2336                    nvp->ChangeDVDTrack(1);
    23372337                    UpdateOSDSeekMessage(tr("Next Chapter"),
    23382338                                         osd_general_timeout);
    23392339                }
     
    25542554        return;
    25552555
    25562556    oset = GetOSD()->GetSet("status");
    2557     if ((oset) && (oset->Displaying()) && !prbuffer->isDVD())
    2558     {
    2559         InfoMap infoMap;
    2560         pbinfoLock.lock();
    2561         playbackinfo->ToMap(infoMap);
    2562         pbinfoLock.unlock();
    2563         GetOSD()->HideSet("status");
    2564         GetOSD()->ClearAllText("program_info");
    2565         GetOSD()->SetText("program_info", infoMap, osd_prog_info_timeout);
    2566     }
    2567     else
    2568     {
    2569         QString desc = "";
    2570         int pos = nvp->calcSliderPos(desc);
    2571         GetOSD()->HideSet("program_info");
    2572         GetOSD()->StartPause(pos, false, tr("Position"), desc,
    2573                              osd_prog_info_timeout);
    2574         update_osd_pos = true;
    2575     }
     2557    QString desc = "";
     2558    int pos = nvp->calcSliderPos(desc);
     2559    GetOSD()->HideSet("program_info");
     2560    GetOSD()->StartPause(pos, false, tr("Position"), desc,
     2561                         osd_prog_info_timeout);
     2562    update_osd_pos = true;
     2563
    25762564}
    25772565
    25782566bool TV::DoNVPSeek(float time)
     
    33303318    if (activenvp != nvp)
    33313319        return;
    33323320
     3321    if (prbuffer->isDVD())
     3322       usleep(100000);
     3323
    33333324    QString desc = "";
    33343325    int pos = nvp->calcSliderPos(desc);
    33353326    bool slidertype = StateIsLiveTV(GetState());