Ticket #1043: mythdvd.2.patch

File mythdvd.2.patch, 51.1 KB (added by skamithi@…, 20 years ago)

Updated patch

  • NuppelVideoPlayer.h

     
    260260
    261261    // DVD public stuff
    262262    void ChangeDVDTrack(bool ffw);
     263    void ActivateDVDButton(void);
    263264
    264265  protected:
    265266    void DisplayPauseFrame(void);
     
    363364    void  SwitchToProgram(void);
    364365    void  JumpToProgram(void);
    365366
     367   // Private DVD stuff
     368   void DisplayDVDButton(void);
     369
    366370  private:
    367371    VideoOutputType forceVideoOutput;
    368372
     
    588592    LiveTVChain *livetvchain;
    589593    TV *m_tv;
    590594
     595    // DVD
     596    bool indvdstillframe;
     597
    591598    // Debugging variables
    592599    Jitterometer *output_jmeter;
    593600};
  • NuppelVideoPlayer.cpp

     
    169169      tc_avcheck_framecounter(0),   tc_diff_estimate(0),
    170170      // LiveTVChain stuff
    171171      livetvchain(NULL), m_tv(NULL),
     172      // DVD stuff
     173      indvdstillframe(false),
    172174      // Debugging variables
    173175      output_jmeter(NULL)
    174176{
     
    813815            deleteIter = deleteMap.begin();
    814816        }
    815817    }
    816     bookmarkseek = GetBookmark();
     818    if (!ringBuffer->isDVD()) // need this til proper DVD bookmarking is implemented
     819      bookmarkseek = GetBookmark();
    817820
    818821    return IsErrored() ? -1 : 0;
    819822}
     
    884887void NuppelVideoPlayer::ReleaseNextVideoFrame(VideoFrame *buffer,
    885888                                              long long timecode)
    886889{
    887     WrapTimecode(timecode, TC_VIDEO);
     890    if (!ringBuffer->isDVD())
     891      WrapTimecode(timecode, TC_VIDEO);
    888892    buffer->timecode = timecode;
    889893
    890894    videoOutput->ReleaseFrame(buffer);
     
    924928void NuppelVideoPlayer::AddTextData(char *buffer, int len,
    925929                                    long long timecode, char type)
    926930{
    927     WrapTimecode(timecode, TC_CC);
     931    if (!ringBuffer->isDVD())
     932        WrapTimecode(timecode, TC_CC);
    928933
    929934    if (subtitlesOn)
    930935    {
     
    18021807        return;
    18031808    }
    18041809
     1810    if (ringBuffer->IsInDVDMenu())
     1811        DisplayDVDButton();
     1812
    18051813    videofiltersLock.lock();
    18061814    videoOutput->ProcessFrame(NULL, osd, videoFilters, pipplayer);
    18071815    videofiltersLock.unlock();
     
    18161824    video_actually_paused = false;
    18171825    resetvideo = false;
    18181826
     1827   if (ringBuffer->IsDVDWaiting() || ringBuffer->InCellWithDVDStillFrame())
     1828      goto displayframe;
     1829
    18191830    prebuffering_lock.lock();
    18201831    if (prebuffering)
    18211832    {
     
    18771888    prebuffer_tries = 0;
    18781889    prebuffering_lock.unlock();
    18791890
     1891displayframe:
     1892
    18801893    videoOutput->StartDisplayingFrame();
    18811894
    18821895    VideoFrame *frame = videoOutput->GetLastShownFrame();
     
    19151928        yuv_wait.wakeAll();
    19161929    }
    19171930
     1931    if (ringBuffer->IsInDVDMenu())
     1932        DisplayDVDButton();
     1933   
    19181934    if (subtitlesOn)
    19191935    {
    19201936        ShowText();
     
    20072023            needsetpipplayer = false;
    20082024        }
    20092025
     2026        if (ringBuffer->isDVD())
     2027        {
     2028            int nbframes = videoOutput->ValidVideoFrames();
     2029            if (ringBuffer->InCellWithDVDStillFrame() && nbframes < 2)
     2030            {
     2031                indvdstillframe = true;
     2032                if (nbframes == 0)
     2033                    ringBuffer->Seek(ringBuffer->GetDVDCellStartPos(),SEEK_SET);
     2034                if (!pausevideo)
     2035                {
     2036                    PauseVideo(false);
     2037                    ringBuffer->HideDVDMenuButton(false);
     2038                }
     2039            }
     2040            if (ringBuffer->IsDVDWaiting() && nbframes < 2)
     2041                ringBuffer->DVDWaitSkip();
     2042            // restart playing after skipping still frame
     2043            if (indvdstillframe && nbframes > 1)
     2044            {
     2045                UnpauseVideo();
     2046                indvdstillframe = false;
     2047            }
     2048        }
    20102049        if (pausevideo)
    20112050        {
    20122051            usleep(frame_interval);
     
    21312170{
    21322171    ClearAfterSeek();
    21332172
    2134     framesPlayed = 0;
     2173    if (!ringBuffer->isDVD())
     2174       framesPlayed = 0;
    21352175
    21362176    GetDecoder()->Reset();
    21372177    errored |= GetDecoder()->IsErrored();
     
    27642804 */
    27652805void NuppelVideoPlayer::AddAudioData(char *buffer, int len, long long timecode)
    27662806{
    2767     WrapTimecode(timecode, TC_AUDIO);
     2807    if (!ringBuffer->isDVD())
     2808       WrapTimecode(timecode, TC_AUDIO);
    27682809
    27692810    int samplesize = (audio_channels * audio_bits) / 8; // bytes per sample
    27702811    if ((samplesize <= 0) || !audioOutput)
     
    45024543    posInfo.progBefore = false;
    45034544    posInfo.progAfter = false;
    45044545
    4505     if (ringBuffer->isDVD())
     4546    if (ringBuffer->IsInDVDMenu())
    45064547    {
    45074548        long long rPos = ringBuffer->GetReadPosition();
    45084549        long long tPos = 1;//ringBuffer->GetTotalReadPosition();
     
    45274568        playbackLen =
    45284569            (int)(((float)nvr_enc->GetFramesWritten() / video_frame_rate));
    45294570
    4530     float secsplayed = ((float)framesPlayed / video_frame_rate);
     4571    float secsplayed;
     4572    if (ringBuffer->isDVD())
     4573    {
     4574       if (!ringBuffer->IsInDVDMenu())
     4575           secsplayed = ringBuffer->GetDVDCurrentTime();
     4576    }
     4577    else
     4578       secsplayed = ((float)framesPlayed / video_frame_rate);
    45314579    playbackLen = max(playbackLen, 1);
    45324580    secsplayed  = min((float)playbackLen, max(secsplayed, 0.0f));
    45334581
     
    50725120
    50735121    GetDecoder()->ChangeDVDTrack(ffw);
    50745122    usleep(100000);
    5075     ClearAfterSeek();
     5123    ResetPlaying();
    50765124}
    50775125
     5126void NuppelVideoPlayer::DisplayDVDButton(void)
     5127{
     5128   if (!ringBuffer->IsInDVDMenu())
     5129       return;
     5130   
     5131   AVSubtitleRect *highlightButton;
     5132   OSDSet *subtitleOSD = NULL;
     5133   highlightButton = ringBuffer->GetDVDMenuButton();
     5134
     5135   subtitleLock.lock();
     5136   if (highlightButton != NULL)
     5137   {
     5138       osd->HideSet("subtitles");
     5139       osd->ClearAll("subtitles");
     5140       int h = highlightButton->h;
     5141       int w = highlightButton->w;
     5142       int linesize = highlightButton->linesize;
     5143       int x1 = highlightButton->x;
     5144       int y1 = highlightButton->y;
     5145       uint btnX = ringBuffer->DVDButtonPosX();
     5146       uint btnY = ringBuffer->DVDButtonPosY();
     5147       subtitleOSD = osd->GetSet("subtitles");
     5148
     5149       QImage hl_button(w,h,32);
     5150       hl_button.setAlphaBuffer(true);
     5151       for (int y = 0; y < h; y++)
     5152       {
     5153           for (int x = 0; x < w; x++)
     5154           {
     5155               const uint8_t color = highlightButton->bitmap[(y+y1)*linesize+(x+x1)];
     5156               const uint32_t pixel = highlightButton->rgba_palette[color];
     5157               hl_button.setPixel(x,y,pixel);
     5158           }
     5159       }
     5160       OSDTypeImage* image = new OSDTypeImage();
     5161       QImage scaledImage = hl_button.smoothScale(w+1,h+1);
     5162       image->SetPosition(QPoint(btnX-1, btnY+2));
     5163       image->LoadFromQImage(scaledImage);
     5164       subtitleOSD->AddType(image);
     5165       osd->SetVisible(subtitleOSD,0);
     5166   }
     5167   subtitleLock.unlock();
     5168}
     5169
     5170void NuppelVideoPlayer::ActivateDVDButton(void)
     5171{
     5172    if (!ringBuffer->isDVD())
     5173       return;
     5174   
     5175    ringBuffer->ActivateDVDButton();
     5176    osd->HideSet("subtitles");
     5177    osd->ClearAll("subtitles");
     5178    ringBuffer->HideDVDMenuButton(true);
     5179}
     5180
  • RingBuffer.cpp

     
    11931193    return 0;
    11941194}
    11951195
     1196/** \fn RingBuffer::InCellWithDVDStillFrame(void)
     1197 *  \brief Calls DVDRingBufferPriv::InCellWithDVDStillFrame(void)
     1198 */
     1199bool RingBuffer::InCellWithDVDStillFrame(void)
     1200{
     1201    if (dvdPriv)
     1202        return dvdPriv->InCellWithDVDStillFrame();
     1203    return false;
     1204}
     1205
     1206/** \fn RingBuffer::DVDSkipStillFrame(void)
     1207 *  \brief Calls DVDRingBufferPriv::DVDSkipStillFrame(void)
     1208 */
     1209void RingBuffer::DVDSkipStillFrame(void)
     1210{
     1211    if (dvdPriv)
     1212        dvdPriv->SkipStillFrame();
     1213}
     1214
     1215/** \fn RingBuffer::DVDWaitSkip(void)
     1216 *  \brief Calls DVDRingBufferPriv::DVDWaitSkip(void)
     1217 */
     1218void RingBuffer::DVDWaitSkip(void)
     1219{
     1220   if (dvdPriv)
     1221       dvdPriv->DVDWaitSkip();
     1222}
     1223
     1224/** \fn RingBuffer::IsDVDWaiting(void)
     1225 *  \brief Calls DVDRingBufferPriv::IsDVDWaiting(void)
     1226 */
     1227bool RingBuffer::IsDVDWaiting(void)
     1228{
     1229   if (dvdPriv)
     1230       return dvdPriv->IsDVDWaiting();
     1231   return false;
     1232}
     1233
     1234/** \fn RingBuffer::IsInDVDMenu(void)
     1235 *  \brief Calls DVDRingBufferPriv::IsInDVDMenu(void)
     1236 */
     1237bool RingBuffer::IsInDVDMenu(void)
     1238{
     1239   if (dvdPriv)
     1240       return dvdPriv->IsInMenu();
     1241   return false;
     1242}
     1243
     1244/** \fn RingBuffer::GoToDVDRootMenu(void)
     1245 *  \brief Calls DVDRingBufferPriv::GoToDVDRootMenu(void)
     1246 */
     1247void RingBuffer::GoToDVDRootMenu(void)
     1248{
     1249   if (dvdPriv)
     1250       dvdPriv->GoToRootMenu();
     1251}
     1252
     1253/** \fn RingBuffer::GoToDVDNextProgram(void)
     1254 *  \brief Calls DVDRingBufferPriv::GoToNextProgram(void)
     1255 */
     1256void RingBuffer::GoToDVDNextProgram(void)
     1257{
     1258   if (dvdPriv)
     1259       dvdPriv->GoToNextProgram();
     1260}
     1261
     1262/** \fn RingBuffer::GoToDVDPreviousProgram(void)
     1263 *  \brief Calls DVDRingBufferPriv::GoToPreviousProgram(void)
     1264 */
     1265void RingBuffer::GoToDVDPreviousProgram(void)
     1266{
     1267   if (dvdPriv)
     1268       dvdPriv->GoToPreviousProgram();
     1269}
     1270
     1271/** \fn RingBuffer::MoveDVDButtonLeft(void)
     1272 *  \brief Calls DVDRingBufferPriv::MoveDVDButtonLeft(void)
     1273 */
     1274void RingBuffer::MoveDVDButtonLeft(void)
     1275{
     1276   if (dvdPriv)
     1277       dvdPriv->MoveDVDButtonLeft();
     1278}
     1279
     1280/** \fn RingBuffer::MoveDVDButtonRight(void)
     1281 *  \brief Calls DVDRingBufferPriv::MoveDVDButtonRight(void)
     1282 */
     1283void RingBuffer::MoveDVDButtonRight(void)
     1284{
     1285   if (dvdPriv)
     1286       dvdPriv->MoveDVDButtonRight();
     1287}
     1288
     1289/** \fn RingBuffer::MoveDVDButtonUp(void)
     1290 *  \brief Calls DVDRingBufferPriv::MoveDVDButtonUp(void)
     1291 */
     1292void RingBuffer::MoveDVDButtonUp(void)
     1293{
     1294   if (dvdPriv)
     1295       dvdPriv->MoveDVDButtonUp();
     1296}
     1297
     1298/** \fn RingBuffer::MoveDVDButtonDown(void)
     1299 *  \brief Calls DVDRingBufferPriv::MoveDVDButtonDown(void)
     1300 */
     1301void RingBuffer::MoveDVDButtonDown(void)
     1302{
     1303   if (dvdPriv)
     1304       dvdPriv->MoveDVDButtonDown();
     1305}
     1306
     1307/** \fn RingBuffer::ActivateDVDButton(void)
     1308 *  \brief Calls DVDRingBufferPriv::ActivateDVDButton(void)
     1309 */
     1310void RingBuffer::ActivateDVDButton(void)
     1311{
     1312   if (dvdPriv)
     1313       dvdPriv->ActivateDVDButton();
     1314}
     1315
     1316/** \fn RingBuffer::NumDVDMenuButtons(void)
     1317 *  \brief Calls DVDRingBufferPriv::NumMenuButtons(void)
     1318 */
     1319int RingBuffer::NumDVDMenuButtons(void)
     1320{
     1321   if (dvdPriv)
     1322       return dvdPriv->NumMenuButtons();
     1323   return 0;
     1324}
     1325
     1326/** \fn RingBuffer::NumPartsInDVDTitle(void)
     1327 *  \brief Calls DVDRingBufferPriv::NumPartsInTitle(void)
     1328 */
     1329int RingBuffer::NumPartsInDVDTitle(void)
     1330{
     1331   if (dvdPriv)
     1332       return dvdPriv->NumPartsInTitle();
     1333   return 0;
     1334}
     1335
     1336/** \fn RingBuffer::GetDVDMenuSPUPkt(uint8_t *buf, int buf_size)
     1337 *  \brief Calls DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size)
     1338 */
     1339void RingBuffer::GetDVDMenuSPUPkt(uint8_t *buf, int buf_size)
     1340{
     1341   if (dvdPriv)
     1342       dvdPriv->GetMenuSPUPkt(buf,buf_size);
     1343}
     1344
     1345/** \fn RingBuffer::GetDVDMenuButton(void)
     1346 *  \brief Calls DVDRingBufferPriv::GetMenuButton(void)
     1347 */
     1348AVSubtitleRect *RingBuffer::GetDVDMenuButton(void)
     1349{
     1350   if (dvdPriv)
     1351       return dvdPriv->GetMenuButton();
     1352   return NULL;
     1353}
     1354
     1355/** \fn RingBuffer::IgnoringDVDStillorWait(void)
     1356 *  \brief Calls DVDRingBufferPriv::
     1357 */
     1358bool RingBuffer::IgnoringDVDStillorWait(void)
     1359{
     1360   if (dvdPriv)
     1361       return dvdPriv->IgnoringStillorWait();
     1362   return false;
     1363}
     1364
     1365/** \fn RingBuffer::IgnoreDVDStillOrWait(bool skip)
     1366 *  \brief Calls DVDRingBufferPriv::IgnoreStillOrWait()
     1367 */
     1368void RingBuffer::IgnoreDVDStillOrWait(bool skip)
     1369{
     1370   if (dvdPriv)
     1371       dvdPriv->IgnoreStillOrWait(skip);
     1372}
     1373
     1374/** \fn RingBuffer::GetDVDCurrentTime(void)
     1375 *  \brief Calls DVDRingBufferPriv::GetCurrentTime(void)
     1376 */
     1377uint RingBuffer::GetDVDCurrentTime(void)
     1378{
     1379   if (dvdPriv)
     1380       return dvdPriv->GetCurrentTime();
     1381   return 0;
     1382}
     1383
     1384/** \fn RingBuffer::HasDVDTitleChanged(void)
     1385 *  \brief Calls DVDRingBufferPriv::HasTitleChanged(void)
     1386 */
     1387bool RingBuffer::HasDVDTitleChanged(void)
     1388{
     1389   if (dvdPriv)
     1390       return dvdPriv->HasTitleChanged();
     1391   return false;
     1392}
     1393
     1394/** \fn RingBuffer::SetDVDTitleChanged(bool change)
     1395 *  \brief Calls DVDRingBufferPriv::SetDVDTitleChanged(bool change)
     1396 */
     1397void RingBuffer::SetDVDTitleChanged(bool change)
     1398{
     1399   if (dvdPriv)
     1400       dvdPriv->SetTitleChanged(change);
     1401}
     1402
     1403/** \fn RingBuffer::GetDVDCellStartPos(void)
     1404 *  \brief Calls DVDRingBufferPriv::GetDVDCellStartPos(void)
     1405 */
     1406long long RingBuffer::GetDVDCellStartPos(void)
     1407{
     1408   if (dvdPriv)
     1409       return dvdPriv->GetCellStartPos();   
     1410   return false;
     1411}
     1412
     1413/** \fn RingBuffer::HideDVDMenuButton(bool hide)
     1414 *  \brief Calls DVDRingBufferPriv::HideMenuButton(bool hide)
     1415 */
     1416void RingBuffer::HideDVDMenuButton(bool hide)
     1417{
     1418   if (dvdPriv)
     1419       dvdPriv->HideMenuButton(hide);
     1420}
     1421
     1422/** \fn RingBuffer::DVDButtonPosX(void)
     1423 *  \brief Calls DVDRingBufferPriv::ButtonPosX(void)
     1424 */
     1425uint RingBuffer::DVDButtonPosX(void)
     1426{
     1427   if (dvdPriv)
     1428       return dvdPriv->ButtonPosX();
     1429   return 0;
     1430}
     1431
     1432/** \fn RingBuffer::DVDButtonPosY(void)
     1433 *  \brief Calls DVDRingBufferPriv::ButtonPosY(void)
     1434 */
     1435uint RingBuffer::DVDButtonPosY(void)
     1436{
     1437   if (dvdPriv)
     1438       return dvdPriv->ButtonPosY();
     1439   return 0;
     1440}
  • DVDRingBuffer.h

     
    77
    88#include <qstring.h>
    99#include <qobject.h>
     10#include "util.h"
     11#include "avcodec.h"
    1012
    1113#ifdef HAVE_DVDNAV
    1214#   include <dvdnav/dvdnav.h>
     
    5658    bool IsInMenu(void) const { return (title == 0); }
    5759    bool IsOpen(void)   const { return dvdnav;       }
    5860    long long GetReadPosition(void);
    59     long long GetTotalReadPosition(void);
     61    long long GetTotalReadPosition(void) { return titleLength; }
    6062    void GetDescForPos(QString &desc) const;
    6163    void GetPartAndTitle(int &_part, int &_title) const
    6264        { _part  = part; _title = _title; }
    6365    uint GetTotalTimeOfTitle(void);
    6466    uint GetCellStart(void);
    65 
     67    bool InCellWithDVDStillFrame(void) { return cellHasStillFrame; }
     68    bool IsDVDWaiting(void) { return dvdWaiting; }
     69    int    NumPartsInTitle(void) { return titleParts; }
     70    void GetMenuSPUPkt(uint8_t *buf, int buf_size);
     71    AVSubtitleRect *GetMenuButton(void);
     72    bool IgnoringStillorWait(void) { return skipstillorwait; }
     73    bool HasTitleChanged(void) { return titleChanged; }
     74    long long GetCellStartPos(void) { return cellstartPos; }
     75    void HideMenuButton(bool hide);
     76    uint ButtonPosX(void) { return hl_startx; }
     77    uint ButtonPosY(void) { return hl_starty; }
     78   
    6679    // commands
    6780    bool OpenFile(const QString &filename);
    6881    void close(void);
     
    7083    void prevTrack(void);
    7184    int  safe_read(void *data, unsigned sz);
    7285    long long Seek(long long pos, int whence);
     86    void SkipStillFrame(void);
     87    void DVDWaitSkip(void);
     88    void GoToRootMenu(void);
     89    void GoToNextProgram(void);
     90    void GoToPreviousProgram(void);
     91    void MoveDVDButtonLeft(void);
     92    void MoveDVDButtonRight(void);
     93    void MoveDVDButtonUp(void);
     94    void MoveDVDButtonDown(void);
     95    void ActivateDVDButton(void);
     96    int NumMenuButtons(void);
     97    void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; }
     98    uint GetCurrentTime(void);
     99    void SetTitleChanged(bool change) { titleChanged = change; }
    73100       
    74101  protected:
    75102    dvdnav_t      *dvdnav;
     
    84111    dvdnav_t      *lastNav; // This really belongs in the player.
    85112    int            part;
    86113    int            title;
    87     int            maxPart;
    88     int            mainTitle;
     114    int            titleParts;
    89115    bool           gotStop;
     116    bool         cellHasStillFrame;
     117    bool         dvdWaiting;
     118    long long  titleLength;
     119    MythTimer stillFrameTimer;
     120    uint32_t   clut[16];
     121    uint8_t   button_color[4];
     122    uint8_t     button_alpha[4];
     123    uint16_t   hl_startx;
     124    uint16_t   hl_width;
     125    uint16_t   hl_starty;
     126    uint16_t   hl_height;
     127    bool         spuchanged;
     128    uint8_t     *menuSpuPkt;
     129    int            menuBuflength;
     130    uint8_t     *buttonBitmap;
     131    AVSubtitleRect *dvdMenuButton;
     132    int buttonCoords;
     133    bool skipstillorwait;
     134    bool spuStreamLetterbox;
     135    bool titleChanged;
     136    long long cellstartPos;
     137
     138    bool DrawMenuButton(uint8_t *spu_pkt, int buf_size);
     139    bool DVDButtonUpdate(bool b_mode);
     140    void ClearMenuSPUParameters(void);
     141    bool MenuButtonChanged(void);
     142    /* copied from dvdsub.c from ffmpeg */
     143    int get_nibble(const uint8_t *buf, int nibble_offset);
     144    int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
     145                           const uint8_t *buf, int nibble_offset, int buf_size);
     146    void guess_palette(uint32_t *rgba_palette,uint8_t *palette,
     147                                   uint8_t *alpha);
    90148};
    91149#endif // HAVE_DVDNAV
    92150#endif // DVD_RING_BUFFER_H_
  • avformatdecoder.cpp

     
    1818#include "mythdbcon.h"
    1919#include "iso639.h"
    2020#include "pespacket.h"
     21#include "audiooutput.h"
    2122
    2223#ifdef USING_XVMC
    2324#include "videoout_xv.h"
     
    424425void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames,
    425426                                bool doflush, bool discardFrames)
    426427{
     428
     429   if (ringBuffer->IsInDVDMenu())
     430       return;
     431
    427432    VERBOSE(VB_PLAYBACK, LOC +
    428433            QString("SeekReset(%1, %2, %3 flush, %4 discard)")
    429434            .arg(newKey).arg(skipFrames)
     
    478483
    479484        prevgoppos = 0;
    480485        gopset = false;
    481         framesPlayed = lastKey;
    482         framesRead = lastKey;
     486        if (!ringBuffer->isDVD())
     487        {
     488           framesPlayed = lastKey;
     489           framesRead = lastKey;
     490        }
    483491    }
    484492
    485493    // Skip all the desired number of skipFrames
     
    511519void AvFormatDecoder::Reset()
    512520{
    513521    DecoderBase::Reset();
     522    if (ringBuffer->isDVD())
     523    {
     524       posmapStarted = false;
     525       SyncPositionMap();
     526       framesPlayed = DVDCurrentFrameNumber();
     527       framesRead = framesPlayed;       
     528    }
    514529#if 0
    515530// This is causing problems, and may not be needed anymore since
    516531// we do not reuse the same file for different streams anymore. -- dtk
     
    643658    readcontext.max_packet_size = 0;
    644659    readcontext.priv_data = this;
    645660
    646     ic->pb.buffer_size = 32768;
     661    if (ringBuffer->isDVD())
     662       ic->pb.buffer_size = 2048;
     663    else
     664       ic->pb.buffer_size = 32768;
    647665    ic->pb.buffer = (unsigned char *)av_malloc(ic->pb.buffer_size);
    648666    ic->pb.buf_ptr = ic->pb.buffer;
    649667    ic->pb.write_flag = 0;
     
    725743        return -1;
    726744    }
    727745
    728     int ret = av_find_stream_info(ic);
     746    int ret;
     747    if (ringBuffer->isDVD())
     748   {
     749       AVPacket pkt1;
     750       while (ic->nb_streams == 0)
     751       {
     752           ret = av_read_frame(ic,&pkt1);
     753       }
     754       av_free_packet(&pkt1);
     755       ringBuffer->Seek(0,SEEK_SET);
     756       ringBuffer->IgnoreDVDStillOrWait(false);
     757   }
     758   else
     759       ret = av_find_stream_info(ic);
     760
    729761    if (ret < 0)
    730762    {
    731763        VERBOSE(VB_IMPORTANT, LOC_ERR + "Could not find codec parameters. " +
     
    739771
    740772    fmt->flags &= ~AVFMT_NOFILE;
    741773
    742     av_estimate_timings(ic);
     774    if (!ringBuffer->isDVD())
     775       av_estimate_timings(ic);
     776
    743777    av_read_frame_flush(ic);
    744778
    745779    // Scan for the initial A/V streams
     
    21062140{
    21072141    uint numStreams = subtitleStreams.size();
    21082142
     2143    if (ringBuffer->IsInDVDMenu())
     2144        return true;
     2145
    21092146    if ((currentSubtitleTrack >= 0) &&
    21102147        (currentSubtitleTrack < (int)numStreams))
    21112148    {
     
    22102247            // disable audio request if there are no audio streams anymore
    22112248            onlyvideo = 1;
    22122249        }
    2213 
     2250       
     2251        if (ringBuffer->HasDVDTitleChanged() &&
     2252            !ringBuffer->IsInDVDMenu())
     2253        {
     2254           ringBuffer->SetDVDTitleChanged(false);
     2255           posmapStarted = false;
     2256           m_positionMap.clear();
     2257           SyncPositionMap();
     2258           framesPlayed = DVDCurrentFrameNumber();
     2259           framesRead = framesPlayed;
     2260           VERBOSE(VB_PLAYBACK, LOC +
     2261                   QString("DVD Title Changed. Update framesPlayed: %1 ")
     2262                   .arg(framesPlayed));
     2263        }
     2264                   
    22142265        if (gotvideo)
    22152266        {
     2267                 bool draindvdpkts = (ringBuffer->IsInDVDMenu());
    22162268            if (lowbuffers && onlyvideo == 0 && lastapts < lastvpts + 100 &&
    2217                 lastapts > lastvpts - 10000)
     2269                lastapts > lastvpts - 10000 && !draindvdpkts)
    22182270            {
    22192271                //cout << "behind: " << lastapts << " " << lastvpts << endl;
    22202272                storevideoframes = true;
     
    22752327        if (pkt->dts != (int64_t)AV_NOPTS_VALUE)
    22762328            pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000);
    22772329
     2330        if (ringBuffer->InCellWithDVDStillFrame() &&
     2331            curstream->codec->codec_type == CODEC_TYPE_AUDIO)
     2332        {
     2333            VERBOSE(VB_PLAYBACK, LOC + "Audio in DVD Still Frame not supported yet. "
     2334                    "Dropping Frame");
     2335            av_free_packet(pkt);
     2336            continue;
     2337        }
     2338       
    22782339        if (storevideoframes &&
    22792340            curstream->codec->codec_type == CODEC_TYPE_VIDEO)
    22802341        {
     
    25062567                        ret = d->DecodeMPEG2Video(context, &mpa_pic,
    25072568                                                  &gotpicture, ptr, len);
    25082569                    else
     2570                    {
    25092571                        ret = avcodec_decode_video(context, &mpa_pic,
    25102572                                                   &gotpicture, ptr, len);
     2573                       // Reparse it to not drop the DVD still frame //
     2574                       if (ringBuffer->InCellWithDVDStillFrame())
     2575                           ret = avcodec_decode_video(context, &mpa_pic,
     2576                                                   &gotpicture, ptr, len);
     2577                    }
    25112578                    avcodeclock.unlock();
    25122579
    25132580                    if (ret < 0)
     
    26062673                    int gotSubtitles = 0;
    26072674                    AVSubtitle subtitle;
    26082675
    2609                     if (pkt->stream_index == subIdx)
     2676                    if (ringBuffer->IsInDVDMenu())
     2677                        ringBuffer->GetDVDMenuSPUPkt(ptr,len);
     2678                    else if (pkt->stream_index == subIdx)
    26102679                    {
    26112680                        QMutexLocker locker(&avcodeclock);
    26122681                        avcodec_decode_subtitle(curstream->codec,
  • decoderbase.h

     
    9090    // DVD public stuff
    9191    void ChangeDVDTrack(bool ffw);
    9292    long long DVDFindPosition(long long desiredFrame);
     93    long long DVDCurrentFrameNumber(void);
    9394
    9495  protected:
    9596    void FileChanged(void);
  • tv_play.cpp

     
    148148    REG_KEY("TV Playback", "PREVSUBTITLE", "Switch to the previous subtitle track", "");
    149149    REG_KEY("TV Playback", "JUMPPREV", "Jump to previously played recording", "");
    150150    REG_KEY("TV Playback", "SIGNALMON", "Monitor Signal Quality", "F7");
    151    
     151    REG_KEY("TV Playback", "JUMPTODVDMENU", "Jump to the DVD Root Menu", "");
     152
    152153    REG_KEY("TV Editing", "CLEARMAP", "Clear editing cut points", "C,Q,Home");
    153154    REG_KEY("TV Editing", "INVERTMAP", "Invert Begin/End cut points", "I");
    154155    REG_KEY("TV Editing", "LOADCOMMSKIP", "Load cut list from commercial skips",
     
    11551156void TV::StopStuff(bool stopRingBuffers, bool stopPlayers, bool stopRecorders)
    11561157{
    11571158    VERBOSE(VB_PLAYBACK, LOC + "StopStuff() -- begin");
     1159
     1160    if (prbuffer->isDVD())
     1161    {
     1162       VERBOSE(VB_PLAYBACK,LOC + " StopStuff() -- get dvd player out of still frame or wait status");
     1163       prbuffer->IgnoreDVDStillOrWait(true);
     1164    }
    11581165    if (stopRingBuffers)
    11591166    {
    11601167        VERBOSE(VB_PLAYBACK, LOC + "StopStuff(): stopping ring buffer[s]");
     
    21082115                AddKeyToInputQueue(0);
    21092116            }           
    21102117        }
    2111         else if (action == "SEEKFFWD")
     2118        else if (action == "SEEKFFWD" &&
     2119                   !prbuffer->IsInDVDMenu())
    21122120        {
    21132121            if (HasQueuedInput())
    21142122                DoArbSeek(ARBSEEK_FORWARD);
     
    21242132            else
    21252133                ChangeFFRew(1);
    21262134        }
    2127         else if (action == "FFWDSTICKY")
     2135        else if (action == "FFWDSTICKY" &&
     2136                   !prbuffer->IsInDVDMenu())
    21282137        {
    21292138            if (HasQueuedInput())
    21302139                DoArbSeek(ARBSEEK_END);
     
    21332142            else
    21342143                ChangeFFRew(1);
    21352144        }
    2136         else if (action == "SEEKRWND")
     2145        else if (action == "SEEKRWND" &&
     2146                   !prbuffer->IsInDVDMenu())
    21372147        {
    21382148            if (HasQueuedInput())
    21392149                DoArbSeek(ARBSEEK_REWIND);
     
    21482158            else
    21492159                ChangeFFRew(-1);
    21502160        }
    2151         else if (action == "RWNDSTICKY")
     2161        else if (action == "RWNDSTICKY" &&
     2162                   !prbuffer->IsInDVDMenu())
    21522163        {
    21532164            if (HasQueuedInput())
    21542165                DoArbSeek(ARBSEEK_SET);
     
    21612172        {
    21622173            if (prbuffer->isDVD())
    21632174            {
    2164                 nvp->ChangeDVDTrack(0);
    2165                 UpdateOSDSeekMessage(tr("Previous Chapter"),
    2166                                      osd_general_timeout);
     2175                if (prbuffer->NumPartsInDVDTitle() < 2)
     2176                {
     2177                    prbuffer->GoToDVDPreviousProgram();
     2178                    UpdateOSDSeekMessage(tr("Previous Title/Chapter"),
     2179                            osd_general_timeout);
     2180                }
     2181                else
     2182                {
     2183                    nvp->ChangeDVDTrack(0);
     2184                    UpdateOSDSeekMessage(tr("Previous Chapter"),
     2185                            osd_general_timeout);
     2186                }
    21672187            }
    21682188            else
    21692189            {
     
    21742194        {
    21752195            if (prbuffer->isDVD())
    21762196            {
    2177                 nvp->ChangeDVDTrack(1);
    2178                 UpdateOSDSeekMessage(tr("Next Chapter"), osd_general_timeout);
     2197                if (prbuffer->InCellWithDVDStillFrame())
     2198                {
     2199                    prbuffer->DVDSkipStillFrame();
     2200                    UpdateOSDSeekMessage(tr("Skip Still Frame"),
     2201                            osd_general_timeout);
     2202                }
     2203                else if (prbuffer->NumPartsInDVDTitle() > 2)
     2204                {
     2205                    nvp->ChangeDVDTrack(1);
     2206                    UpdateOSDSeekMessage(tr("Next Chapter"),
     2207                            osd_general_timeout);
     2208                }
     2209                else
     2210                {
     2211                   prbuffer->GoToDVDNextProgram();
     2212                   UpdateOSDSeekMessage(tr("Next Title"),
     2213                           osd_general_timeout);
     2214                }
    21792215            }
    21802216            else
    21812217            {
     
    24452481            QString action = actions[i];
    24462482            handled = true;
    24472483
    2448             if (action == "SELECT")
     2484            if (prbuffer->IsInDVDMenu())
    24492485            {
     2486               int nb_buttons = prbuffer->NumDVDMenuButtons();
     2487               if (nb_buttons > 0)
     2488               {
     2489                  if (action == "UP" || action == "CHANNELUP")
     2490                      prbuffer->MoveDVDButtonUp();
     2491                  else if (action == "DOWN" || action == "CHANNELDOWN")
     2492                      prbuffer->MoveDVDButtonDown();
     2493                  else if (action == "LEFT" || action == "SEEKRWND")
     2494                      prbuffer->MoveDVDButtonLeft();
     2495                  else if (action == "RIGHT" || action == "SEEKFFWD")
     2496                      prbuffer->MoveDVDButtonRight();
     2497                  else if (action == "SELECT")
     2498                      nvp->ActivateDVDButton();
     2499               }
     2500            }
     2501            else if (action == "SELECT")
     2502            {
    24502503                if (!was_doing_ff_rew)
    24512504                {
    24522505                    if (gContext->GetNumSetting("AltClearSavedPosition", 1)
     
    24682521                exitPlayer = true;
    24692522                wantsToQuit = true;
    24702523            }
     2524            else if (action == "JUMPTODVDMENU")
     2525            {
     2526                prbuffer->GoToDVDRootMenu();
     2527            }
    24712528            else if (action == "TOGGLEEDIT")
    24722529                DoEditMode();
    24732530            else if (action == "TOGGLEBROWSE")
    24742531                ShowOSDTreeMenu();
    24752532            else if (action == "CHANNELUP")
    24762533            {
    2477                 if (prbuffer->isDVD())
     2534                if (prbuffer->isDVD() &&
     2535                       !prbuffer->IsInDVDMenu())
    24782536                {
    2479                     nvp->ChangeDVDTrack(0);
    2480                     UpdateOSDSeekMessage(tr("Previous Chapter"),
    2481                                          osd_general_timeout);
     2537                   nvp->ChangeDVDTrack(0);
     2538                   UpdateOSDSeekMessage(tr("Previous Chapter"),
     2539                       osd_general_timeout);
    24822540                }
    24832541                else
    24842542                {
     
    24872545            }   
    24882546            else if (action == "CHANNELDOWN")
    24892547            {
    2490                 if (prbuffer->isDVD())
     2548                if (prbuffer->isDVD() &&
     2549                       !prbuffer->IsInDVDMenu())
    24912550                {
    2492                     nvp->ChangeDVDTrack(1);
    2493                     UpdateOSDSeekMessage(tr("Next Chapter"),
    2494                                          osd_general_timeout);
     2551                   nvp->ChangeDVDTrack(1);
     2552                   UpdateOSDSeekMessage(tr("Next Chapter"),
     2553                       osd_general_timeout);
    24952554                }
    24962555                else
    24972556                {
     
    29583017
    29593018void TV::DoPause(void)
    29603019{
     3020    if (prbuffer->IsInDVDMenu())
     3021       return;
     3022
    29613023    speed_index = 0;
    29623024    float time = 0.0;
    29633025
     
    53985460    }
    53995461    else if (StateIsPlaying(internalState))
    54005462    {
    5401         if (action == "TOGGLEEDIT")
     5463        if (action == "JUMPTODVDMENU")
     5464            prbuffer->GoToDVDRootMenu();
     5465        else if (action == "TOGGLEEDIT")
    54025466            DoEditMode();
    54035467        else if (action == "TOGGLEAUTOEXPIRE")
    54045468            ToggleAutoExpire();
     
    54895553    }
    54905554    else if (StateIsPlaying(internalState))
    54915555    {
     5556        if (prbuffer->isDVD() && !prbuffer->IsInDVDMenu())
     5557           item = new OSDGenericTree(treeMenu,tr("DVD Root Menu"), "JUMPTODVDMENU");
     5558
    54925559        item = new OSDGenericTree(treeMenu, tr("Edit Recording"), "TOGGLEEDIT");
    54935560
    54945561        if (lastProgram != NULL)
  • DVDRingBuffer.cpp

     
    2525      pgLength(0),      pgcLength(0),
    2626      cellStart(0),     pgStart(0),
    2727      lastNav(NULL),    part(0),
    28       title(0),         maxPart(0),
    29       mainTitle(0),     gotStop(false)
     28      title(0),         gotStop(false),
     29      cellHasStillFrame(false), dvdWaiting(false),
     30      titleLength(0),  spuchanged(false),
     31      menuBuflength(0),  buttonCoords(0),
     32      skipstillorwait(true), spuStreamLetterbox(false),
     33      titleChanged(false),cellstartPos(0)
    3034{
     35    dvdMenuButton = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect));
    3136}
    3237
    3338DVDRingBufferPriv::~DVDRingBufferPriv()
     
    8489
    8590        int numTitles  = 0;
    8691        int titleParts = 0;
    87         maxPart        = 0;
    88         mainTitle      = 0;
    8992        dvdnav_title_play(dvdnav, 0);
    9093        dvdRet = dvdnav_get_number_of_titles(dvdnav, &numTitles);
    9194        if (numTitles == 0 )
     
    113116                VERBOSE(VB_IMPORTANT,
    114117                        QString("There are title %1 has %2 parts.")
    115118                        .arg(curTitle).arg(titleParts));
    116                 if (titleParts > maxPart)
    117                 {
    118                     maxPart = titleParts;
    119                     mainTitle = curTitle;
    120                 }
    121119            }
    122             VERBOSE(VB_IMPORTANT, QString("%1 selected as the main title.")
    123                     .arg(mainTitle));
    124120        }               
    125121
    126         dvdnav_title_play(dvdnav, mainTitle);
    127122        dvdnav_current_title_info(dvdnav, &title, &part);
    128123        return true;
    129124    }
     
    140135    return pos * DVD_BLOCK_SIZE;
    141136}
    142137
    143 long long DVDRingBufferPriv::GetTotalReadPosition(void)
    144 {
    145     uint32_t pos;
    146     uint32_t length;
    147 
    148     if (dvdnav)       
    149         dvdnav_get_position(dvdnav, &pos, &length);
    150 
    151     return length * DVD_BLOCK_SIZE;
    152 }
    153 
    154138int DVDRingBufferPriv::safe_read(void *data, unsigned sz)
    155139{
    156140    dvdnav_status_t dvdStat;
     
    214198                        .arg(pgLength).arg(pgcLength)
    215199                        .arg(cellStart).arg(pgStart));
    216200
    217                 dvdnav_current_title_info(dvdnav, &title, &part);           
    218                 if (title == 0)
     201                if (dvdnav_get_next_still_flag(dvdnav) > 0)
    219202                {
    220                     pci_t* pci = dvdnav_get_current_nav_pci(dvdnav);
    221                     dvdnav_button_select(dvdnav, pci, 1);
     203                   if (dvdnav_get_next_still_flag(dvdnav) < 0xff)
     204                       stillFrameTimer.restart();
     205                   cellHasStillFrame = true;
    222206                }
     207                else
     208                   cellHasStillFrame = false;
    223209
     210                int tmptitle = 0;
     211                part = 0;
     212                titleParts = 0;
     213                dvdnav_current_title_info(dvdnav, &tmptitle, &part);
     214                dvdnav_get_number_of_parts(dvdnav, tmptitle, &titleParts);
     215
     216                if (tmptitle != title)
     217                  titleChanged = true;
     218               
     219                title = tmptitle;
     220
     221                uint32_t pos;
     222                uint32_t length;
     223                dvdnav_get_position(dvdnav, &pos, &length);
     224                titleLength = length *DVD_BLOCK_SIZE;
     225               
     226                         cellstartPos = GetReadPosition();
     227
    224228                if (blockBuf != dvdBlockWriteBuf)
    225229                {
    226230                    dvdnav_free_cache_block(dvdnav, blockBuf);
     
    228232            }
    229233            break;
    230234            case DVDNAV_SPU_CLUT_CHANGE:
     235                memcpy(clut,blockBuf, 16 * sizeof (uint32_t));
    231236                VERBOSE(VB_PLAYBACK, "DVDNAV_SPU_CLUT_CHANGE happened.");
    232237                break;
    233238                   
     
    241246                                "physical_pan_scan==%3, logical==%4")
    242247                        .arg(spu->physical_wide).arg(spu->physical_letterbox)
    243248                        .arg(spu->physical_pan_scan).arg(spu->logical));
    244                        
     249
     250                if (spu->physical_letterbox)
     251                   spuStreamLetterbox = true;
     252                else
     253                   spuStreamLetterbox = false;
     254                spuchanged = true;
     255                ClearMenuSPUParameters();
    245256                if (blockBuf != dvdBlockWriteBuf)
    246257                {
    247258                    dvdnav_free_cache_block(dvdnav, blockBuf);
     
    265276            break;
    266277            case DVDNAV_NAV_PACKET:
    267278                lastNav = (dvdnav_t *)blockBuf;
     279                if (IsInMenu() && NumMenuButtons() > 0)
     280                {
     281                   int32_t button;
     282                   pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     283                   dvdnav_get_current_highlight(dvdnav, &button);
     284
     285                   if (button > NumMenuButtons() || button < 1)
     286                       dvdnav_button_select(dvdnav, pci,1);
     287                   else
     288                       dvdnav_button_select(dvdnav, pci, button);
     289                   
     290                   spuchanged = false;
     291                }
     292                if (blockBuf != dvdBlockWriteBuf)
     293                {
     294                    dvdnav_free_cache_block(dvdnav, blockBuf);
     295                }       
    268296                break;
    269297            case DVDNAV_HOP_CHANNEL:
    270298                VERBOSE(VB_PLAYBACK, "DVDNAV_HOP_CHANNEL happened.");
     
    303331                    dvdnav_free_cache_block(dvdnav, blockBuf);
    304332                }                                                   
    305333
     334                if (DVDButtonUpdate(false))
     335                   DrawMenuButton(menuSpuPkt,menuBuflength);
    306336            }
    307337            break;
    308338            case DVDNAV_STILL_FRAME:
    309339            {
    310340                dvdnav_still_event_t* still =
    311341                    (dvdnav_still_event_t*)(blockBuf);
    312                 VERBOSE(VB_PLAYBACK, "DVDNAV_STILL_FRAME: " +
    313                         QString("needs displayed for %1 seconds")
    314                         .arg(still->length));
     342                if (skipstillorwait)
     343                    SkipStillFrame();
     344                else
     345                {
     346                   int elapsedTime = 0;
     347                   if (still->length  < 0xff)
     348                   {
     349                       elapsedTime = stillFrameTimer.elapsed() / 1000; // in seconds
     350                       if (elapsedTime < still->length)
     351                           usleep(10000);
     352                       else if (elapsedTime == still->length)
     353                           SkipStillFrame();
     354                   }
     355                }
    315356                if (blockBuf != dvdBlockWriteBuf)
    316357                {
    317358                    dvdnav_free_cache_block(dvdnav, blockBuf);
    318                 }                                                   
    319                        
    320                 dvdnav_still_skip(dvdnav);
     359                }
    321360            }
    322361            break;
    323362            case DVDNAV_WAIT:
    324                 VERBOSE(VB_PLAYBACK, "DVDNAV_WAIT recieved clearing it");
    325                 dvdnav_wait_skip(dvdnav);
     363                if (skipstillorwait)
     364                    DVDWaitSkip();
     365                else
     366                {
     367                    dvdWaiting = true;
     368                    usleep(10000);
     369                }
    326370                break;
    327371            case DVDNAV_STOP:
    328372                VERBOSE(VB_GENERAL, "DVDNAV_STOP");
     
    344388bool DVDRingBufferPriv::nextTrack(void)
    345389{
    346390    int newPart = part + 1;
    347     if (newPart < maxPart)
     391   
     392    if (newPart < titleParts)
    348393    {
    349394        dvdnav_part_play(dvdnav, title, newPart);
    350395        gotStop = false;
     
    374419    return cellStart / 90000;
    375420}
    376421
     422void DVDRingBufferPriv::SkipStillFrame(void)
     423{
     424   dvdnav_still_skip(dvdnav);
     425   cellHasStillFrame = false;
     426}
     427
     428void DVDRingBufferPriv::DVDWaitSkip(void)
     429{
     430   dvdnav_wait_skip(dvdnav);
     431   dvdWaiting = false;
     432}
     433
     434void DVDRingBufferPriv::GoToRootMenu(void)
     435{
     436    dvdnav_menu_call(dvdnav,DVD_MENU_Root);
     437}
     438
     439void DVDRingBufferPriv::GoToNextProgram(void)
     440{
     441   // if not in the menu feature, okay to skip allow to skip it.
     442   //  if (!dvdnav_is_domain_vts(dvdnav))
     443        dvdnav_next_pg_search(dvdnav);
     444}
     445
     446void DVDRingBufferPriv::GoToPreviousProgram(void)
     447{
     448    // if (!dvdnav_is_domain_vts(dvdnav))
     449        dvdnav_prev_pg_search(dvdnav);
     450}
     451
     452void DVDRingBufferPriv::MoveDVDButtonLeft(void)
     453{
     454    if (IsInMenu() && (NumMenuButtons() > 0))
     455    {
     456        pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     457        dvdnav_left_button_select(dvdnav, pci);
     458    }
     459}
     460
     461void DVDRingBufferPriv::MoveDVDButtonRight(void)
     462{
     463    if (IsInMenu() &&(NumMenuButtons() > 0) )
     464    {
     465        pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     466        dvdnav_right_button_select(dvdnav, pci);
     467    }
     468}
     469
     470void DVDRingBufferPriv::MoveDVDButtonUp(void)
     471{
     472    if (IsInMenu() && (NumMenuButtons() > 0))
     473    {
     474        pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     475        dvdnav_upper_button_select(dvdnav, pci);
     476    }
     477}
     478
     479void DVDRingBufferPriv::MoveDVDButtonDown(void)
     480{
     481    if (IsInMenu() && (NumMenuButtons() > 0))
     482    {
     483        pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     484        dvdnav_lower_button_select(dvdnav, pci);
     485    }
     486}
     487
     488void DVDRingBufferPriv::ActivateDVDButton(void)
     489{
     490    if (IsInMenu() && (NumMenuButtons() > 0))
     491    {
     492        pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     493        dvdnav_button_activate(dvdnav, pci);
     494    }
     495}
     496
     497void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size)
     498{   
     499    if (buf_size < 4)
     500        return;
     501    if (buf_size == menuBuflength)
     502        return;
     503    else if (spuStreamLetterbox)
     504    {
     505        if ((buf_size < menuBuflength) && menuBuflength > 0)
     506            return;
     507    }
     508    else
     509    {
     510        if ((buf_size > menuBuflength) && (menuBuflength > 0))
     511            return;
     512    }
     513    ClearMenuSPUParameters();
     514
     515    uint8_t *spu_pkt;
     516    spu_pkt = (uint8_t*)av_malloc(buf_size);
     517    memcpy(spu_pkt, buf, buf_size);
     518    menuSpuPkt = spu_pkt;
     519    menuBuflength = buf_size;
     520    buttonCoords = 0;
     521   
     522    if (DVDButtonUpdate(false))
     523        DrawMenuButton(menuSpuPkt,menuBuflength);
     524}
     525
     526AVSubtitleRect *DVDRingBufferPriv::GetMenuButton(void)
     527{
     528    if (MenuButtonChanged())
     529        return dvdMenuButton;
     530
     531    return NULL;
     532}
     533
     534
     535bool DVDRingBufferPriv::DrawMenuButton(uint8_t *spu_pkt, int buf_size)
     536{
     537    #define GETBE16(p) (((p)[0] << 8) | (p)[1])
     538
     539    int cmd_pos, pos,cmd,next_cmd_pos,offset1,offset2;
     540    int x1,x2,y1,y2;
     541    uint8_t alpha[4],palette[4];
     542
     543    x1 = x2 = y1 = y2 = 0;
     544
     545    if (!spu_pkt)
     546       return false;
     547
     548    for (int i = 0; i < 4 ; i++)
     549    {
     550       alpha[i]    = button_alpha[i];
     551       palette[i] = button_color[i];
     552    }
     553 
     554    if (buf_size < 4)
     555       return false;
     556
     557    cmd_pos = GETBE16(spu_pkt + 2);
     558    while ((cmd_pos + 4) < buf_size)
     559    {
     560       offset1 = -1;
     561       offset2 = -1;
     562       next_cmd_pos = GETBE16(spu_pkt + cmd_pos + 2);
     563       pos = cmd_pos + 4;
     564       while (pos < buf_size)
     565       {
     566            cmd = spu_pkt[pos++];
     567            switch(cmd)
     568            {
     569                case 0x00:
     570                    break; 
     571                case 0x01:
     572                    break;
     573                case 0x02:
     574                    break;
     575                case 0x03:
     576                {
     577                    if ((buf_size - pos) < 2)
     578                        goto fail;
     579                    pos +=2;
     580                }
     581                break;
     582                case 0x04:
     583                {
     584                    if ((buf_size - pos) < 2)
     585                        goto fail;
     586                    pos +=2;
     587                }
     588                break;
     589                case 0x05:
     590                {
     591                   if ((buf_size - pos) < 6)
     592                       goto fail;
     593                   x1 = (spu_pkt[pos] << 4) | (spu_pkt[pos + 1] >> 4);
     594                   x2 = ((spu_pkt[pos + 1] & 0x0f) << 8) | spu_pkt[pos + 2];
     595                   y1 = (spu_pkt[pos + 3] << 4) | (spu_pkt[pos + 4] >> 4);
     596                   y2 = ((spu_pkt[pos + 4] & 0x0f) << 8) | spu_pkt[pos + 5];
     597                   pos +=6;
     598                }
     599                break;
     600                case 0x06:
     601                {
     602                    if ((buf_size - pos) < 4)
     603                        goto fail;
     604                    offset1 = GETBE16(spu_pkt + pos);
     605                    offset2 = GETBE16(spu_pkt + pos + 2);
     606                    pos +=4;
     607                }
     608                break;
     609                case 0xff:
     610                default:
     611                    goto the_end;
     612            }
     613        }
     614        the_end:
     615            if (offset1 >= 0)
     616            {
     617                int w, h,total;
     618                uint8_t *bitmap;
     619                w = x2 - x1 + 1;
     620                if (w < 0)
     621                    w = 0;
     622                h = y2 - y1;
     623                if (h < 0)
     624                    h = 0;
     625                if (w > 0 && h > 0)
     626                {
     627                    bitmap = (uint8_t*) av_malloc(w * h);
     628                    dvdMenuButton->rgba_palette = (uint32_t*)av_malloc(4 *4);
     629                    decode_rle(bitmap, w * 2, w, h / 2,
     630                            spu_pkt, offset1 * 2, buf_size);
     631                    decode_rle(bitmap + w, w * 2, w, h / 2,
     632                            spu_pkt, offset2 * 2, buf_size);
     633                    guess_palette(dvdMenuButton->rgba_palette, palette, alpha);
     634                    total = ((hl_starty+hl_height)*w) + (hl_startx + hl_width);
     635                    dvdMenuButton->bitmap = bitmap;
     636                    dvdMenuButton->x = hl_startx - x1;
     637                    dvdMenuButton->y  = hl_starty - y1;
     638                    dvdMenuButton->w  = hl_width;
     639                    dvdMenuButton->h  = hl_height;
     640                    dvdMenuButton->nb_colors = 4;
     641                    dvdMenuButton->linesize = w;
     642                    return true;
     643                }
     644            }
     645            if (next_cmd_pos == cmd_pos)
     646                break;
     647            cmd_pos = next_cmd_pos;
     648    }
     649    fail:
     650        return false;
     651}
     652
     653bool DVDRingBufferPriv::DVDButtonUpdate(bool b_mode)
     654{
     655    int32_t button;
     656    pci_t *pci;
     657    dvdnav_highlight_area_t hl;
     658    dvdnav_get_current_highlight(dvdnav, &button);
     659
     660    pci = dvdnav_get_current_nav_pci(dvdnav);
     661    dvdnav_get_highlight_area(pci,button, b_mode, &hl);
     662
     663    for (int i = 0 ; i < 4 ; i++)
     664    {
     665       button_alpha[i] = 0xf & (hl.palette >> (4 * i ));
     666       button_color[i] = 0xf & (hl.palette >> (16+4 *i ));
     667    }
     668
     669    hl_startx = hl.sx;
     670    hl_width = hl.ex - hl.sx;
     671    hl_starty = hl.sy;
     672    hl_height  = hl.ey - hl.sy;
     673
     674    int total_start_pos = hl.sx + hl.sy;
     675    if ( total_start_pos == 0 || total_start_pos > (720 + 480 ))
     676        return false;
     677
     678    return true;
     679}
     680
     681void DVDRingBufferPriv::ClearMenuSPUParameters(void)
     682{
     683   if (menuBuflength == 0)
     684   return;
     685
     686   VERBOSE(VB_PLAYBACK,"Clearing Menu SPU Packet" );
     687   av_free(menuSpuPkt);
     688   menuBuflength = 0;
     689   dvdMenuButton->x = 0;
     690   dvdMenuButton->y = 0;
     691   hl_startx = hl_starty = 0;
     692   hl_width = hl_height = 0;
     693   buttonCoords = (720+480+100);
     694   av_free(dvdMenuButton->rgba_palette);
     695   av_free(dvdMenuButton->bitmap);
     696}
     697
     698bool DVDRingBufferPriv::MenuButtonChanged(void)
     699{
     700   if (menuBuflength < 4 || buttonCoords > (720+576))
     701       return false;
     702
     703    int x = dvdMenuButton->x;
     704    int y = dvdMenuButton->y;
     705    if (buttonCoords != (x+y))
     706    {
     707        buttonCoords = (x+y);
     708        return true;
     709    }
     710    return false;
     711}
     712
     713int DVDRingBufferPriv::NumMenuButtons(void)
     714{
     715    pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     716    int numButtons = pci->hli.hl_gi.btn_ns;
     717    if (numButtons > 0 && numButtons < 36)
     718       return  numButtons;
     719    else
     720       return 0;
     721}
     722
     723void DVDRingBufferPriv::HideMenuButton(bool hide)
     724{
     725    if (hide)
     726       buttonCoords = (720+480+100);
     727    else
     728       buttonCoords = 0;
     729}
     730uint DVDRingBufferPriv::GetCurrentTime(void)
     731{
     732    // Macro to convert Binary Coded Decimal to Decimal
     733   // Obtained from VLC Code.
     734    #define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
     735
     736    dsi_t *dvdnavDsi = dvdnav_get_current_nav_dsi(dvdnav);
     737    dvd_time_t timeFromCellStart = dvdnavDsi->dsi_gi.c_eltm;
     738    uint8_t hours = BCD2D(timeFromCellStart.hour);
     739    uint8_t minutes = BCD2D(timeFromCellStart.minute);
     740    uint8_t seconds = BCD2D(timeFromCellStart.second);
     741    uint currentTime = GetCellStart() + (hours * 3600) + (minutes * 60) + seconds;
     742    VERBOSE(VB_PLAYBACK,QString("cellStartTime == %1 current time: hours %2 minutes"
     743                      "%3 seconds %4 currenttime %5").arg(GetCellStart()).arg(hours).
     744                      arg(minutes).arg(seconds).arg(currentTime));
     745    return currentTime;
     746}
     747
     748void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette,
     749                                        uint8_t *alpha)
     750{
     751    int i,r,g,b,y,cr,cb;
     752    uint32_t yuv;
     753
     754    for(i = 0; i < 4; i++)
     755        rgba_palette[i] = 0;
     756
     757    for ( i=0 ; i < 4 ; i++)
     758    {
     759        yuv = clut[palette[i]];
     760        y = ((yuv >> 16) & 0xff);
     761        cr = ((yuv >> 8) & 0xff);
     762        cb = ((yuv >> 0) & 0xff);
     763        r  = int(y + 1.4022 * (cr - 128));
     764        b  = int(y + 1.7710 * (cb - 128));
     765        g  = int(1.7047 * y - (0.1952 * b) - (0.5647 * r)) ;
     766        if (r < 0) r = 0;
     767        if (g < 0) g = 0;
     768        if (b < 0) b = 0;
     769        if (r > 0xff) r = 0xff;
     770        if (g > 0xff) g = 0xff;
     771        if (b > 0xff) b = 0xff;
     772        rgba_palette[i] = ((alpha[i] * 17) << 24) | (r << 16 )| (g << 8) | b;
     773    }
     774}
     775
     776int DVDRingBufferPriv::decode_rle(uint8_t *bitmap, int linesize, int w, int h,
     777                                     const uint8_t *buf, int nibble_offset, int buf_size)
     778{
     779    unsigned int v;
     780    int x, y, len, color, nibble_end;
     781    uint8_t *d;
     782
     783    nibble_end = buf_size * 2;
     784    x = 0;
     785    y = 0;
     786    d = bitmap;
     787    for(;;) {
     788        if (nibble_offset >= nibble_end)
     789            return -1;
     790        v = get_nibble(buf, nibble_offset++);
     791        if (v < 0x4) {
     792            v = (v << 4) | get_nibble(buf, nibble_offset++);
     793            if (v < 0x10) {
     794                v = (v << 4) | get_nibble(buf, nibble_offset++);
     795                if (v < 0x040) {
     796                    v = (v << 4) | get_nibble(buf, nibble_offset++);
     797                    if (v < 4) {
     798                        v |= (w - x) << 2;
     799                    }
     800                }
     801            }
     802        }
     803        len = v >> 2;
     804        if (len > (w - x))
     805            len = (w - x);
     806        color = v & 0x03;
     807        memset(d + x, color, len);
     808        x += len;
     809        if (x >= w) {
     810            y++;
     811            if (y >= h)
     812                break;
     813            d += linesize;
     814            x = 0;
     815            /* byte align */
     816            nibble_offset += (nibble_offset & 1);
     817        }
     818    }
     819    return 0;
     820}
     821
     822int DVDRingBufferPriv::get_nibble(const uint8_t *buf, int nibble_offset)
     823{
     824    return (buf[nibble_offset >> 1] >> ((1 - (nibble_offset & 1)) << 2)) & 0xf;
     825}
     826
     827
    377828#endif // HAVE_DVDNAV
  • RingBuffer.h

     
    55#include <qwaitcondition.h>
    66#include <qmutex.h>
    77#include <pthread.h>
     8#include "avcodec.h"
    89
    910class RemoteFile;
    1011class RemoteEncoder;
     
    8283    uint GetTotalTimeOfTitle(void);
    8384    uint GetCellStart(void);
    8485    long long GetTotalReadPosition(void);
     86    bool InCellWithDVDStillFrame(void);
     87    void DVDSkipStillFrame(void);
     88    void DVDWaitSkip(void);
     89    bool IsDVDWaiting(void);
     90    bool IsInDVDMenu(void);
     91    void GoToDVDRootMenu(void);
     92    void GoToDVDNextProgram(void);
     93    void GoToDVDPreviousProgram(void);
     94    void MoveDVDButtonLeft(void);
     95    void MoveDVDButtonRight(void);
     96    void MoveDVDButtonUp(void);
     97    void MoveDVDButtonDown(void);
     98    void ActivateDVDButton(void);
     99    int  NumDVDMenuButtons(void);
     100    int NumPartsInDVDTitle(void);
     101    void GetDVDMenuSPUPkt(uint8_t *buf, int buf_size);
     102    AVSubtitleRect *GetDVDMenuButton(void);
     103    bool IgnoringDVDStillorWait(void);
     104    void IgnoreDVDStillOrWait(bool skip);
     105    uint GetDVDCurrentTime(void);
     106    bool HasDVDTitleChanged(void);
     107    void SetDVDTitleChanged(bool change);
     108    long long GetDVDCellStartPos(void);
     109    void HideDVDMenuButton(bool hide);
     110    uint DVDButtonPosX(void);
     111    uint DVDButtonPosY(void);
    85112
    86113    long long SetAdjustFilesize(void);
    87114   
  • decoderbase.cpp

     
    715715    return (long long)(desiredFrame * multiplier);
    716716}
    717717
     718long long DecoderBase::DVDCurrentFrameNumber(void)
     719{
     720   if (!ringBuffer->isDVD())
     721        return 0;
     722
     723   int size = m_positionMap.size() - 1;
     724   long long currentpos = ringBuffer->GetReadPosition();
     725   long long multiplier = (currentpos * m_positionMap[size].index);
     726   long long currentframe = multiplier / m_positionMap[size].pos;
     727   return currentframe;
     728}
     729
    718730/* vim: set expandtab tabstop=4 shiftwidth=4: */