Ticket #1043: mythdvd_v6.patch

File mythdvd_v6.patch, 35.4 KB (added by skamithi@…, 20 years ago)

subtitle fixes.

  • libs/libmythtv/NuppelVideoPlayer.h

     
    318318    void ActivateDVDButton(void);
    319319    void GoToDVDMenu(QString str);
    320320    void GoToDVDProgram(bool direction);
     321    void HideDVDButton(bool hide) { hidedvdbutton = hide; }
     322    void SetSubtitleMode(bool setting) { subtitlesOn = setting; }
    321323
    322324  protected:
    323325    void DisplayPauseFrame(void);
     
    664666
    665667    // DVD
    666668    bool indvdstillframe;
     669    bool hidedvdbutton;
    667670
    668671    // Debugging variables
    669672    Jitterometer *output_jmeter;
  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    175175      // LiveTVChain stuff
    176176      livetvchain(NULL), m_tv(NULL),
    177177      // DVD stuff
    178       indvdstillframe(false),
     178      indvdstillframe(false), hidedvdbutton(true),
    179179      // Debugging variables
    180180      output_jmeter(NULL)
    181181{
     
    509509
    510510    ClearAfterSeek();
    511511
    512     if (ringBuffer->InDVDMenuOrStillFrame())
     512    if (ringBuffer->isDVD())
    513513        ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(), SEEK_SET);
    514514}
    515515
     
    967967void NuppelVideoPlayer::AddTextData(unsigned char *buffer, int len,
    968968                                    long long timecode, char type)
    969969{
    970     if (!ringBuffer->isDVD())
    971         WrapTimecode(timecode, TC_CC);
     970    WrapTimecode(timecode, TC_CC);
    972971
    973     if (subtitlesOn)
     972    if (subtitlesOn && !ringBuffer->isDVD())
    974973    {
    975974        if (!tbuffer_numfree())
    976975        {
     
    19541953    video_actually_paused = false;
    19551954    resetvideo = false;
    19561955
    1957     if (!ringBuffer->isDVD())
     1956    if (!ringBuffer->InDVDMenuOrStillFrame())
    19581957    {
    19591958        if (!PrebufferEnoughFrames())
    19601959            return;
     
    21042103                if (ringBuffer->DVD()->IsWaiting())
    21052104                {
    21062105                    ringBuffer->DVD()->WaitSkip();
    2107                     usleep(100000);
    21082106                    continue;
    21092107                }
     2108               
    21102109                if (ringBuffer->InDVDMenuOrStillFrame())
    21112110                {
    21122111                    if (nbframes == 0)
    21132112                    {
    2114                         // wait to confirm there is no other frames been decoded.
    2115                         usleep(100000);
    2116                         nbframes = videoOutput->ValidVideoFrames();
    2117                         if (nbframes == 0)
    2118                         {
    2119                             ringBuffer->Seek(ringBuffer->DVD()->GetCellStartPos(),SEEK_SET);
    2120                             continue;
    2121                         }
     2113                        if (pausevideo)
     2114                            UnpauseVideo();
     2115                        continue;
    21222116                    }
    2123                     indvdstillframe = true;
    21242117                    if (!pausevideo && nbframes == 1)
     2118                    {
     2119                        indvdstillframe = true;
    21252120                        PauseVideo(false);
     2121                    }
    21262122                }
    21272123            }
    21282124
    2129             // restart playing after skipping still frame
    21302125            if (indvdstillframe && nbframes > 1)
    21312126            {
    21322127                UnpauseVideo();
    21332128                indvdstillframe = false;
     2129                continue;
    21342130            }
    21352131        }
    21362132
     
    29252921
    29262922    int samples = len / samplesize;
    29272923
    2928     if (ringBuffer->isDVD())
     2924    if (ringBuffer->InDVDMenuOrStillFrame())
    29292925    {
    29302926        audioOutput->Pause(false);
    29312927        audioOutput->Drain();
    2932     }
     2928    } 
    29332929
    29342930    // If there is no warping, just send it to the audioOutput.
    29352931    if (!usevideotimebase)
     
    53175313    if (!ringBuffer->InDVDMenuOrStillFrame())
    53185314        return;
    53195315
    5320     long long spupts = ringBuffer->DVD()->MenuSpuPts();
    5321     long long ptslow = spupts - 1000;
    5322     long long ptshigh = spupts + 1000;
    53235316    VideoFrame *buffer = videoOutput->GetLastShownFrame();
    5324 
    5325     if (!osd->IsSetDisplaying("subtitles") &&
    5326         (buffer->timecode > 0) &&
    5327         ((buffer->timecode < ptslow) ||
    5328          (buffer->timecode > ptshigh)))
     5317    int numbuttons = ringBuffer->DVD()->NumMenuButtons();
     5318    bool osdshown = osd->IsSetDisplaying("subtitles");
     5319    long long menupktpts = ringBuffer->DVD()->GetMenuPktPts();
     5320   
     5321    if ((numbuttons == 0) ||
     5322            (osdshown) ||
     5323            ((!osdshown) && (hidedvdbutton) &&
     5324             (buffer->timecode > 0) && (menupktpts != buffer->timecode)))
    53295325    {
    5330         return; 
     5326        return;
    53315327    }
    53325328
     5329    hidedvdbutton = false;
    53335330    AVSubtitleRect *highlightButton;
    53345331    OSDSet *subtitleOSD = NULL;
    53355332    highlightButton = ringBuffer->DVD()->GetMenuButton();
     
    53795376    if (!ringBuffer->isDVD())
    53805377        return;
    53815378
    5382     if (videoOutput->ValidVideoFrames() > 20)
    5383         DiscardVideoFrames(true);
    53845379    ringBuffer->DVD()->ActivateButton();
    5385     ringBuffer->DVD()->HideMenuButton(true);
    53865380}
    53875381
    53885382void NuppelVideoPlayer::GoToDVDMenu(QString str)
     
    53905384    if (!ringBuffer->isDVD())
    53915385        return;
    53925386
    5393     if (videoOutput->ValidVideoFrames() > 20)
    5394         DiscardVideoFrames(true);
     5387    subtitlesOn = false;
    53955388    ringBuffer->DVD()->GoToMenu(str);
    53965389}
    53975390
     
    54025395{
    54035396    if (!ringBuffer->isDVD())
    54045397        return;
    5405  
    5406     if (videoOutput->ValidVideoFrames() > 20)
    5407         DiscardVideoFrames(true);
     5398
    54085399    if (direction == 0)
    54095400        ringBuffer->DVD()->GoToPreviousProgram();
    54105401    else
  • libs/libmythtv/DVDRingBuffer.h

     
    4545    bool InStillFrame(void) { return cellHasStillFrame; }
    4646    bool IsWaiting(void) { return dvdWaiting; }
    4747    int    NumPartsInTitle(void) { return titleParts; }
    48     void GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts);
     48    void GetMenuSPUPkt(uint8_t *buf, int len, int stream_id);
    4949    AVSubtitleRect *GetMenuButton(void);
    5050    bool IgnoringStillorWait(void) { return skipstillorwait; }
    51     long long GetCellStartPos(void) { return cellstartPos; }
    52     void HideMenuButton(bool hide);
     51    long long GetCellStartPos(void);
    5352    uint ButtonPosX(void) { return hl_startx; }
    5453    uint ButtonPosY(void) { return hl_starty; }
    5554    uint GetAudioLanguage(int id);
    5655    uint GetSubtitleLanguage(int id);
    57     long long MenuSpuPts(void) { return menuspupts; }
    58 
     56    void SetMenuPktPts(long long pts) { menupktpts = pts; }
     57    long long GetMenuPktPts(void) { return menupktpts; }
     58    bool DecodeSubtitles(AVSubtitle * sub, int * gotSubtitles,
     59                        const uint8_t * buf, int buf_size);
     60 
    5961    // commands
    6062    bool OpenFile(const QString &filename);
    6163    void close(void);
     
    7678    int NumMenuButtons(void);
    7779    void IgnoreStillOrWait(bool skip) { skipstillorwait = skip; }
    7880    uint GetCurrentTime(void);
    79    
     81    void  SetAudioTrack(void);
     82    void  SetSubtitleTrack(void);
     83    uint8_t GetNumAudioChannels(int id);
     84    void AutoSelectAudio(bool setting) { autoselectaudio = setting; }
     85    void AutoSelectSubtitle(bool setting) { autoselectsubtitle = setting; }
     86
    8087    void SetParent(NuppelVideoPlayer *p) { parent = p; }
    8188   
    8289  protected:
     
    106113    uint16_t       hl_width;
    107114    uint16_t       hl_starty;
    108115    uint16_t       hl_height;
    109     bool           spuchanged;
    110116    uint8_t       *menuSpuPkt;
    111117    int            menuBuflength;
    112118    uint8_t       *buttonBitmap;
    113     AVSubtitleRect *dvdMenuButton;
    114     int            buttonCoords;
     119    AVSubtitle     dvdMenuButton;
    115120    bool           skipstillorwait;
    116     bool           spuStreamLetterbox;
    117121    long long      cellstartPos;
    118122    bool           buttonSelected;
    119123    bool           buttonExists;
    120     long long      menuspupts;
    121 
     124    int            cellid;
     125    int            lastcellid;
     126    int            vobid;
     127    int            lastvobid;
     128    bool           cellRepeated;
     129    int            buttonstreamid;
     130    bool           gotoCellStart;
     131    long long      menupktpts;
     132    bool           autoselectaudio;
     133    bool           autoselectsubtitle;
     134   
    122135    NuppelVideoPlayer *parent;
    123136
    124137    bool DrawMenuButton(uint8_t *spu_pkt, int buf_size);
     
    126139    void ClearMenuSPUParameters(void);
    127140    bool MenuButtonChanged(void);
    128141    uint ConvertLangCode(uint16_t code); // converts 2char key to 3char key
     142    void SelectDefaultButton(void);
     143    void ClearSubtitlesOSD(void);
    129144   
    130145    /* copied from dvdsub.c from ffmpeg */
    131146    int get_nibble(const uint8_t *buf, int nibble_offset);
  • libs/libmythtv/avformatdecoder.cpp

     
    278278      // language preference
    279279      languagePreference(iso639_get_language_key_list()),
    280280      // DVD
    281       lastdvdtitle(0)
     281      lastdvdtitle(0), dvdmenupktseen(false)
    282282{
    283283    bzero(&params, sizeof(AVFormatParameters));
    284284    bzero(prvpkt, 3 * sizeof(char));
     
    431431void AvFormatDecoder::SeekReset(long long newKey, uint skipFrames,
    432432                                bool doflush, bool discardFrames)
    433433{
    434     if (ringBuffer->isDVD())
    435     {
    436         int totaltime = ringBuffer->DVD()->GetTotalTimeOfTitle();
    437         if (totaltime < 30 || ringBuffer->InDVDMenuOrStillFrame())
    438             return;
    439     }
    440 
     434    if (ringBuffer->InDVDMenuOrStillFrame())
     435        return;
     436       
    441437    VERBOSE(VB_PLAYBACK, LOC +
    442438            QString("SeekReset(%1, %2, %3 flush, %4 discard)")
    443439            .arg(newKey).arg(skipFrames)
     
    11941191                lang_indx = lang_sub_cnt[lang];
    11951192                lang_sub_cnt[lang]++;
    11961193            }
    1197             subtitleStreams.push_back(StreamInfo(i, lang, lang_indx));
     1194            subtitleStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id));
    11981195
    11991196            VERBOSE(VB_PLAYBACK, LOC + QString(
    12001197                        "Subtitle track #%1 is A/V stream #%2 "
     
    12131210                lang_indx = lang_aud_cnt[lang];
    12141211                lang_aud_cnt[lang]++;
    12151212            }
    1216             audioStreams.push_back(StreamInfo(i, lang, lang_indx));
    1217 
     1213            audioStreams.push_back(StreamInfo(i, lang, lang_indx,ic->streams[i]->id));
    12181214            VERBOSE(VB_AUDIO, LOC + QString(
    12191215                        "Audio Track #%1 is A/V stream #%2 "
    12201216                        "and has %3 channels in the %4 language(%5).")
     
    12351231    currentAudioTrack = -1;
    12361232    currentSubtitleTrack = -1;
    12371233
     1234    if (ringBuffer->isDVD())
     1235    {
     1236        if (audioStreams.size() > 1)
     1237        {
     1238            qBubbleSort(audioStreams);
     1239            ringBuffer->DVD()->SetAudioTrack();
     1240        }
     1241        if (subtitleStreams.size() > 1)
     1242        {
     1243            qBubbleSort(subtitleStreams);
     1244            ringBuffer->DVD()->SetSubtitleTrack();
     1245        }
     1246    }
     1247
    12381248    // We have to do this here to avoid the NVP getting stuck
    12391249    // waiting on audio.
    12401250    if (GetNVP()->HasAudioIn() && audioStreams.empty())
     
    19031913    {
    19041914        QString msg;
    19051915        if (ringBuffer->isDVD())
     1916        {
    19061917            msg = iso639_key_toName(ringBuffer->DVD()->GetAudioLanguage(i));
     1918            if (msg.compare("Unknown") == 0)
     1919                continue;
     1920        }
    19071921        else
    19081922            msg = iso639_key_toName(audioStreams[i].language);
     1923
    19091924        AVStream *s  = ic->streams[audioStreams[i].av_stream_index];
    19101925        if (s)
    19111926        {
     
    19141929            else
    19151930                msg += QString(" %1").arg(s->codec->codec->name).upper();
    19161931
    1917             if (!s->codec->channels)
    1918                 msg += QString(" ?ch");
    1919             else if ((s->codec->channels > 4) && !(s->codec->channels & 1))
    1920                 msg += QString(" %1.1ch").arg(s->codec->channels - 1);
     1932            int channels = 0;
     1933            if (ringBuffer->isDVD())
     1934                channels = ringBuffer->DVD()->GetNumAudioChannels(i);
     1935            else if (s->codec->channels)
     1936                channels = s->codec->channels;
     1937
     1938            if (channels == 0)
     1939                msg+= QString(" ?ch");
     1940            else if((channels > 4) && !(channels & 1))
     1941                msg += QString(" %1.1ch").arg(channels - 1);
    19211942            else
    1922                 msg += QString(" %1ch").arg(s->codec->channels);
    1923         }
     1943                msg += QString(" %1ch").arg(channels);
     1944        }   
    19241945        list += QString("%1: %2").arg(i+1).arg(msg);
    19251946    }
    19261947
     
    21502171    {
    21512172        QString msg;
    21522173        if (ringBuffer->isDVD())
     2174        {
    21532175            msg = iso639_key_toName(ringBuffer->DVD()->GetSubtitleLanguage(i));
     2176            if (msg.compare("Unknown") == 0)
     2177                continue;
     2178        }
    21542179        else
    21552180            msg  = iso639_key_toName(subtitleStreams[i].language);
    21562181        list += QString("%1: %2").arg(i+1).arg(msg);
     
    23012326                VERBOSE(VB_PLAYBACK,
    23022327                    QString(LOC + "DVD Title Changed. Update framesPlayed: %1 ")
    23032328                            .arg(framesPlayed));
     2329                ScanStreams(false);
    23042330            }
    23052331            lastdvdtitle = dvdtitle;
    23062332           
     
    23132339        if (gotvideo)
    23142340        {
    23152341            if (lowbuffers && onlyvideo == 0 && lastapts < lastvpts + 100 &&
    2316                 lastapts > lastvpts - 10000 && !ringBuffer->isDVD())
     2342                lastapts > lastvpts - 10000 && !ringBuffer->InDVDMenuOrStillFrame())
    23172343            {
    23182344                //cout << "behind: " << lastapts << " " << lastvpts << endl;
    23192345                storevideoframes = true;
     
    23252351            }
    23262352        }
    23272353
    2328         if (ringBuffer->isDVD() && ringBuffer->DVD()->InStillFrame() &&
    2329                 storedPackets.count() > 0)
     2354        if (ringBuffer->isDVD() &&
     2355                ringBuffer->DVD()->InStillFrame())
    23302356        {
    23312357            storevideoframes = false;
    23322358            dvdvideopause = true;
     
    27202746                    gotvideo = 1;
    27212747                    framesPlayed++;
    27222748
     2749                    if (dvdmenupktseen)
     2750                    {
     2751                        ringBuffer->DVD()->SetMenuPktPts(pts);
     2752                        dvdmenupktseen = false;
     2753                    }
     2754
    27232755                    lastvpts = temppts;
    27242756                    break;
    27252757                }
     
    27282760                    int gotSubtitles = 0;
    27292761                    AVSubtitle subtitle;
    27302762
    2731                     if (ringBuffer->isDVD() && ringBuffer->DVD()->IsInMenu())
    2732                         ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,pts);
     2763                    if (ringBuffer->isDVD())
     2764                    {
     2765                        if (ringBuffer->DVD()->IsInMenu())
     2766                        {
     2767                            dvdmenupktseen = true;
     2768                            ringBuffer->DVD()->GetMenuSPUPkt(ptr,len,curstream->id);
     2769                        }
     2770                        else
     2771                        {
     2772                            if (pkt->stream_index == subIdx)
     2773                                ringBuffer->DVD()->DecodeSubtitles(&subtitle, &gotSubtitles,
     2774                                        ptr,len);
     2775                        }
     2776                    }
    27332777                    else if (pkt->stream_index == subIdx)
    27342778                    {
    27352779                        QMutexLocker locker(&avcodeclock);
  • libs/libmythtv/tv_play.cpp

     
    23212321            if (prbuffer->isDVD())
    23222322            {
    23232323                if (prbuffer->InDVDMenuOrStillFrame())
    2324                     UpdateOSDSeekMessage(tr("Skipping Back Not Allowed"),
     2324                    UpdateOSDSeekMessage(tr("Skip Back Not Allowed"),
    23252325                                         osd_general_timeout);
    23262326                else if (prbuffer->DVD()->NumPartsInTitle() < 2)
    23272327                {
     
    61876187{
    61886188    if (activenvp)
    61896189    {
     6190        if (prbuffer->isDVD())
     6191            prbuffer->DVD()->AutoSelectAudio(false);
     6192
    61906193        activenvp->setCurrentAudioTrack(track - 1);
    61916194
    61926195        if (activenvp->getCurrentAudioTrack())
     
    62266229{
    62276230    if (activenvp)
    62286231    {
     6232        if (prbuffer->isDVD())
     6233            prbuffer->DVD()->AutoSelectSubtitle(false);
     6234
    62296235        activenvp->setCurrentSubtitleTrack(track - 1);
    62306236
    62316237        if (activenvp->getCurrentSubtitleTrack())
  • libs/libmythtv/DVDRingBuffer.cpp

     
    2929      lastNav(NULL),    part(0),
    3030      title(0),         gotStop(false),
    3131      cellHasStillFrame(false), dvdWaiting(false),
    32       titleLength(0),  spuchanged(false),
    33       menuBuflength(0),  buttonCoords(0),
    34       skipstillorwait(true), spuStreamLetterbox(false),
     32      titleLength(0), menuBuflength(0),
     33      skipstillorwait(true),
    3534      cellstartPos(0), buttonSelected(false),
    36       buttonExists(false), menuspupts(0),
    37       parent(0)
     35      buttonExists(false), cellid(0),
     36      lastcellid(0), vobid(0),
     37      lastvobid(0), cellRepeated(false),
     38      buttonstreamid(0), gotoCellStart(false),
     39      menupktpts(0), autoselectaudio(true),
     40      autoselectsubtitle(true), parent(0)
    3841{
    39     dvdMenuButton = (AVSubtitleRect*)av_mallocz(sizeof(AVSubtitleRect));
    4042}
    4143
    4244DVDRingBufferPriv::~DVDRingBufferPriv()
    4345{
    4446    close();
    45     av_free(dvdMenuButton);
     47    ClearMenuSPUParameters();
    4648}
    4749
    4850void DVDRingBufferPriv::close(void)
     
    119121            {
    120122                dvdnav_get_number_of_parts(dvdnav, curTitle, &titleParts);
    121123                VERBOSE(VB_IMPORTANT,
    122                         QString("There are title %1 has %2 parts.")
     124                        QString("Title %1 has %2 parts.")
    123125                        .arg(curTitle).arg(titleParts));
    124126            }
    125127        }
     
    222224                dvdnav_get_position(dvdnav, &pos, &length);
    223225                titleLength = length *DVD_BLOCK_SIZE;
    224226                cellstartPos = GetReadPosition();
    225                 buttonSelected = false;
    226 
    227                 if (parent && parent->GetOSD())
     227                buttonSelected = false;
     228                if (gotoCellStart)
    228229                {
    229                     parent->GetOSD()->HideSet("subtitles");
    230                     parent->GetOSD()->ClearAll("subtitles");
     230                    lastvobid = lastcellid = 0;
     231                    gotoCellStart = false;
    231232                }
     233                else
     234                {
     235                    lastvobid = vobid;
     236                    lastcellid = cellid;
     237                }
     238               
     239                vobid = 0;
     240                cellid = 0;
     241                cellRepeated = false;
     242                menupktpts = 0;
     243             
     244                if (parent && IsInMenu())
     245                {
     246                    parent->HideDVDButton(true);
     247                    parent->SetSubtitleMode(false);
     248                    autoselectaudio = true;
     249                    autoselectsubtitle = true;
     250                }
    232251
    233252                if (blockBuf != dvdBlockWriteBuf)
    234253                {
     
    253272                        .arg(spu->physical_wide).arg(spu->physical_letterbox)
    254273                        .arg(spu->physical_pan_scan).arg(spu->logical));
    255274
    256                 if (spu->physical_letterbox)
    257                     spuStreamLetterbox = true;
    258                 else
    259                     spuStreamLetterbox = false;
    260                 spuchanged = true;
    261275                ClearMenuSPUParameters();
     276                ClearSubtitlesOSD();
    262277
    263278                if (blockBuf != dvdBlockWriteBuf)
    264279                {
     
    284299            case DVDNAV_NAV_PACKET:
    285300            {
    286301                lastNav = (dvdnav_t *)blockBuf;
    287                 if (IsInMenu() && NumMenuButtons() > 0 &&
    288                         !buttonSelected)
     302                if (vobid == 0 && cellid == 0)
    289303                {
    290                     pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
    291 
    292                     uint8_t button = pci->hli.hl_gi.fosl_btnn;
    293                     if (button > 0)
    294                         dvdnav_button_select(dvdnav,pci,button);
    295                     else
    296                         dvdnav_button_select(dvdnav,pci,1);
    297 
    298                     buttonSelected = true;
    299                     spuchanged = false;
     304                    dsi_t *dsi = dvdnav_get_current_nav_dsi(dvdnav);
     305                    vobid  = dsi->dsi_gi.vobu_vob_idn;
     306                    cellid = dsi->dsi_gi.vobu_c_idn;
     307                    if ((lastvobid == vobid) && (lastcellid == cellid)
     308                            && IsInMenu())
     309                    {
     310                        cellRepeated = true;
     311                    }
    300312                }
    301313                if (blockBuf != dvdBlockWriteBuf)
    302314                {
     
    348360
    349361                if (DVDButtonUpdate(false))
    350362                    buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength);
    351 
     363                ClearSubtitlesOSD();
    352364                if (blockBuf != dvdBlockWriteBuf)
    353365                {
    354366                    dvdnav_free_cache_block(dvdnav, blockBuf);
     
    521533    }
    522534}
    523535
    524 void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size,long long pts)
    525 {   
     536void DVDRingBufferPriv::GetMenuSPUPkt(uint8_t *buf, int buf_size, int stream_id)
     537{
    526538    if (buf_size < 4)
    527539        return;
    528540
    529     menuspupts = pts;   
    530     if (buf_size == menuBuflength)
     541
     542    if ((buttonstreamid < stream_id) &&
     543        (buttonstreamid > 0))
    531544        return;
    532     else if (spuStreamLetterbox)
    533     {
    534         if ((buf_size < menuBuflength) && menuBuflength > 0)
    535             return;
    536     }
    537     else
    538     {
    539         if ((buf_size > menuBuflength) && (menuBuflength > 0))
    540             return;
    541     }
     545   
     546    buttonstreamid = stream_id;
    542547    ClearMenuSPUParameters();
    543548    uint8_t *spu_pkt;
    544549    spu_pkt = (uint8_t*)av_malloc(buf_size);
    545550    memcpy(spu_pkt, buf, buf_size);
    546551    menuSpuPkt = spu_pkt;
    547552    menuBuflength = buf_size;
    548     buttonCoords = 0;
     553    if (!buttonSelected)
     554    {
     555        SelectDefaultButton();
     556        buttonSelected = true;
     557    }
    549558    if (DVDButtonUpdate(false))
    550559        buttonExists = DrawMenuButton(menuSpuPkt,menuBuflength);
     560   
    551561}
    552562
    553563AVSubtitleRect *DVDRingBufferPriv::GetMenuButton(void)
    554564{
    555     if (MenuButtonChanged() && buttonExists)
    556         return dvdMenuButton;
     565    if ((menuBuflength > 4) && buttonExists)
     566        return &(dvdMenuButton.rects[0]);
    557567
    558568    return NULL;
    559569}
    560570
    561 
    562571bool DVDRingBufferPriv::DrawMenuButton(uint8_t *spu_pkt, int buf_size)
    563572{
     573    int gotbutton = 0;
     574    if (DecodeSubtitles(&dvdMenuButton,&gotbutton,spu_pkt,buf_size))
     575    {
     576        int x1, y1;
     577        x1 = dvdMenuButton.rects[0].x;
     578        y1 = dvdMenuButton.rects[0].y;
     579        dvdMenuButton.rects[0].w = hl_width;
     580        dvdMenuButton.rects[0].h = hl_height;
     581        if (hl_startx > x1)
     582            dvdMenuButton.rects[0].x = hl_startx - x1;
     583        else
     584            dvdMenuButton.rects[0].x = 0;
     585        if (hl_starty > y1)
     586            dvdMenuButton.rects[0].y  = hl_starty - y1;
     587        else
     588            dvdMenuButton.rects[0].y = 0;
     589    }
     590    return gotbutton;       
     591}
     592
     593bool DVDRingBufferPriv::DecodeSubtitles(AVSubtitle *sub, int *gotSubtitles,
     594                                    const uint8_t *spu_pkt, int buf_size)
     595{
    564596    #define GETBE16(p) (((p)[0] << 8) | (p)[1])
    565597
    566     int cmd_pos, pos,cmd,next_cmd_pos,offset1,offset2;
    567     int x1,x2,y1,y2;
    568     uint8_t alpha[4],palette[4];
    569 
    570     x1 = x2 = y1 = y2 = 0;
    571 
     598    int cmd_pos, pos, cmd, next_cmd_pos, offset1, offset2;
     599    int x1, x2, y1, y2;
     600    uint8_t alpha[4], palette[4];
     601    uint i;
     602    int date;
     603   
    572604    if (!spu_pkt)
    573605        return false;
    574606
    575     for (int i = 0; i < 4 ; i++)
    576     {
    577         alpha[i]   = button_alpha[i];
    578         palette[i] = button_color[i];
    579     }
    580 
    581607    if (buf_size < 4)
    582608        return false;
    583 
     609   
     610    sub->rects = NULL;
     611    sub->num_rects = 0;
     612    sub->start_display_time = 0;
     613    sub->end_display_time = 0;
     614   
    584615    cmd_pos = GETBE16(spu_pkt + 2);
    585616    while ((cmd_pos + 4) < buf_size)
    586617    {
    587618        offset1 = -1;
    588619        offset2 = -1;
     620        date = GETBE16(spu_pkt + cmd_pos);
    589621        next_cmd_pos = GETBE16(spu_pkt + cmd_pos + 2);
    590622        pos = cmd_pos + 4;
     623        x1 = x2 = y1 = y2 = 0;
    591624        while (pos < buf_size)
    592625        {
    593626            cmd = spu_pkt[pos++];
     
    596629                case 0x00:
    597630                break; 
    598631                case 0x01:
     632                    sub->start_display_time = (date << 10) / 90;
    599633                break;
    600634                case 0x02:
     635                    sub->end_display_time = (date << 10) / 90;
    601636                break;
    602637                case 0x03:
    603638                {
    604639                    if ((buf_size - pos) < 2)
    605640                        goto fail;
     641                    if (!IsInMenu())
     642                    {
     643                        palette[3] = spu_pkt[pos] >> 4;
     644                        palette[2] = spu_pkt[pos] & 0x0f;
     645                        palette[1] = spu_pkt[pos + 1] >> 4;
     646                        palette[0] = spu_pkt[pos + 1] & 0x0f;
     647                    }
    606648                    pos +=2;
    607649                }
    608650                break;
     
    610652                {
    611653                    if ((buf_size - pos) < 2)
    612654                        goto fail;
     655                    if (!IsInMenu())
     656                    {
     657                        alpha[3] = spu_pkt[pos] >> 4;
     658                        alpha[2] = spu_pkt[pos] & 0x0f;
     659                        alpha[1] = spu_pkt[pos + 1] >> 4;
     660                        alpha[0] = spu_pkt[pos + 1] >> 0x0f;
     661                    }
    613662                    pos +=2;
    614663                }
    615664                break;
     
    651700                h = 0;
    652701            if (w > 0 && h > 0)
    653702            {
     703                if (IsInMenu())
     704                {
     705                    for (int i = 0; i < 4 ; i++)
     706                    {
     707                        alpha[i]   = button_alpha[i];
     708                        palette[i] = button_color[i];
     709                    }
     710                }
     711                if (sub->rects != NULL)
     712                {
     713                    for (i = 0; i < sub->num_rects; i++)
     714                    {
     715                        av_free(sub->rects[i].bitmap);
     716                        av_free(sub->rects[i].rgba_palette);
     717                    }
     718                    av_freep(&sub->rects);
     719                    sub->num_rects = 0;
     720                }
    654721                bitmap = (uint8_t*) av_malloc(w * h);
    655                 dvdMenuButton->rgba_palette = (uint32_t*)av_malloc(4 *4);
     722                sub->rects = (AVSubtitleRect *)av_mallocz(sizeof(AVSubtitleRect));
     723                sub->num_rects = 1;
     724                sub->rects[0].rgba_palette = (uint32_t*)av_malloc(4 *4);
    656725                decode_rle(bitmap, w * 2, w, h / 2,
    657726                            spu_pkt, offset1 * 2, buf_size);
    658727                decode_rle(bitmap + w, w * 2, w, h / 2,
    659728                            spu_pkt, offset2 * 2, buf_size);
    660                 guess_palette(dvdMenuButton->rgba_palette, palette, alpha);
    661                 dvdMenuButton->bitmap = bitmap;
    662                 if (hl_startx > x1)
    663                     dvdMenuButton->x = hl_startx - x1;
    664                 else
    665                     dvdMenuButton->x = 0;
    666                 if (hl_starty > y1)
    667                     dvdMenuButton->y  = hl_starty - y1;
    668                 else
    669                     dvdMenuButton->y = 0;
    670                 dvdMenuButton->w  = hl_width;
    671                 dvdMenuButton->h  = hl_height;
    672                 dvdMenuButton->nb_colors = 4;
    673                 dvdMenuButton->linesize = w;
    674                 return true;
     729                guess_palette(sub->rects[0].rgba_palette, palette, alpha);
     730                sub->rects[0].bitmap = bitmap;
     731                sub->rects[0].x = x1;
     732                sub->rects[0].y = y1;
     733                sub->rects[0].w  = w;
     734                sub->rects[0].h = h;
     735                sub->rects[0].nb_colors = 4;
     736                sub->rects[0].linesize = w;
     737                *gotSubtitles = 1;
    675738            }
    676739        }
    677740        if (next_cmd_pos == cmd_pos)
    678741            break;
    679742        cmd_pos = next_cmd_pos;
    680743    }
    681     fail:
    682         return false;
     744    if (sub->num_rects > 0)
     745        return true;
     746fail:
     747    return false;
    683748}
    684749
    685750bool DVDRingBufferPriv::DVDButtonUpdate(bool b_mode)
    686751{
     752    if (!parent)
     753        return false;
     754    int videoheight = parent->GetVideoHeight();
     755    int videowidth = parent->GetVideoWidth();
    687756    int32_t button;
    688757    pci_t *pci;
    689758    dvdnav_highlight_area_t hl;
     
    702771    hl_starty = hl.sy;
    703772    hl_height  = hl.ey - hl.sy;
    704773
    705     int total_start_pos = hl.sx + hl.sy;
    706     if ( total_start_pos == 0 || total_start_pos > (720 + 576 ))
    707         return false;
     774    if (((hl.sx + hl.sy) > 0) &&
     775            (hl.sx < videowidth && hl.sy < videoheight))
     776        return true;
    708777
    709     return true;
     778    return false;
    710779}
    711780
    712781void DVDRingBufferPriv::ClearMenuSPUParameters(void)
     
    717786    VERBOSE(VB_PLAYBACK,LOC + "Clearing Menu SPU Packet" );
    718787    if (buttonExists)
    719788    {
    720         av_free(dvdMenuButton->rgba_palette);
    721         av_free(dvdMenuButton->bitmap);
     789        av_free(dvdMenuButton.rects[0].rgba_palette);
     790        av_free(dvdMenuButton.rects[0].bitmap);
     791        av_free(dvdMenuButton.rects);
    722792        buttonExists = false;
    723793    } 
    724794    av_free(menuSpuPkt);
    725795    menuBuflength = 0;
    726     dvdMenuButton->x = 0;
    727     dvdMenuButton->y = 0;
    728796    hl_startx = hl_starty = 0;
    729797    hl_width = hl_height = 0;
    730     buttonCoords = (720+480+100);
    731798}
    732799
    733 bool DVDRingBufferPriv::MenuButtonChanged(void)
    734 {
    735     if (menuBuflength < 4 || buttonCoords > (720+576))
    736         return false;
    737 
    738     int x = hl_startx;
    739     int y = hl_starty;
    740     if (buttonCoords != (x+y))
    741     {
    742         buttonCoords = (x+y);
    743         return true;
    744     }
    745     return false;
    746 }
    747 
    748800int DVDRingBufferPriv::NumMenuButtons(void)
    749801{
    750802    pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     
    755807        return 0;
    756808}
    757809
    758 void DVDRingBufferPriv::HideMenuButton(bool hide)
    759 {
    760     if (hide)
    761         buttonCoords = (720+480+100);
    762     else
    763         buttonCoords = 0;
    764 }
    765 
    766810uint DVDRingBufferPriv::GetCurrentTime(void)
    767811{
    768812    // Macro to convert Binary Coded Decimal to Decimal
     
    778822    return currentTime;
    779823}
    780824
     825long long DVDRingBufferPriv::GetCellStartPos(void)
     826{
     827    gotoCellStart = true;
     828    return cellstartPos;
     829}
     830
    781831uint DVDRingBufferPriv::GetAudioLanguage(int id)
    782832{
    783833    int8_t channel = dvdnav_get_audio_logical_stream(dvdnav,id);
     
    810860    return 0;
    811861}
    812862
     863void DVDRingBufferPriv::SelectDefaultButton(void)
     864{
     865    pci_t *pci = dvdnav_get_current_nav_pci(dvdnav);
     866    int button = pci->hli.hl_gi.fosl_btnn;
     867    if (button > 0 && !cellRepeated)
     868    {
     869        dvdnav_button_select(dvdnav,pci,button);
     870        return;
     871    }
     872    dvdnav_get_current_highlight(dvdnav,&button);
     873    if (button > 0 && button <= NumMenuButtons())
     874        dvdnav_button_select(dvdnav,pci,button);
     875    else
     876        dvdnav_button_select(dvdnav,pci,1);   
     877}
     878
     879void DVDRingBufferPriv::SetAudioTrack(void)
     880{
     881    if (!autoselectaudio)
     882        return;
     883   
     884    int track = dvdnav_get_active_audio_stream(dvdnav);
     885    if (parent)
     886        parent->setCurrentAudioTrack(track);
     887}
     888
     889void DVDRingBufferPriv::SetSubtitleTrack(void)
     890{
     891    if (!autoselectsubtitle)
     892        return;
     893
     894    int track = dvdnav_get_active_spu_stream(dvdnav);
     895    if (parent && track >=0 && !IsInMenu())
     896    {
     897        parent->setCurrentSubtitleTrack(track);
     898        parent->SetSubtitleMode(true);
     899    }
     900}
     901
     902uint8_t DVDRingBufferPriv::GetNumAudioChannels(int id)
     903{
     904    unsigned char channels = dvdnav_audio_get_channels(dvdnav,id);
     905    if (channels == 0xff)
     906        return 0;
     907    return (uint8_t)channels + 1;
     908}
     909
     910void DVDRingBufferPriv::ClearSubtitlesOSD(void)
     911{
     912    if (parent && parent->GetOSD())
     913    {
     914        parent->GetOSD()->HideSet("subtitles");
     915        parent->GetOSD()->ClearAll("subtitles");
     916    }
     917}
     918
    813919void DVDRingBufferPriv::guess_palette(uint32_t *rgba_palette,uint8_t *palette,
    814920                                        uint8_t *alpha)
    815921{
  • libs/libmythtv/avformatdecoder.h

     
    2727{
    2828  public:
    2929    StreamInfo() : av_stream_index(-1), language(-2), language_index(0) {}
    30     StreamInfo(int a, int b, uint c)
    31         : av_stream_index(a), language(b), language_index(c) {}
     30    StreamInfo(int a, int b, uint c, int d)
     31        : av_stream_index(a), language(b), language_index(c), stream_id(d) {}
    3232  public:
    3333    int  av_stream_index;
    3434    int  language; ///< ISO639 canonical language key
    3535    uint language_index;
     36    int  stream_id;
     37    bool operator<(const StreamInfo& b) { return (this->stream_id < b.stream_id) ; }
    3638};
    3739typedef vector<StreamInfo> sinfo_vec_t;
    3840
     
    266268
    267269    // DVD
    268270    int lastdvdtitle;
     271    bool dvdmenupktseen;
    269272};
    270273
    271274#endif
  • libs/libavformat/avformat.h

     
    276276#define AVFMTCTX_NOHEADER      0x0001 /* signal that no header is present
    277277                                         (streams are added dynamically) */
    278278
    279 #define MAX_STREAMS 20
     279#define MAX_STREAMS 40
    280280
    281281/* format I/O context */
    282282typedef struct AVFormatContext {
  • libs/libavcodec/mpeg12.c

     
    30333033        }
    30343034    }
    30353035
     3036    /* look for SEQ_END_CODE at the last data in this buffer*/
     3037    /* dvd's won't send the next frame start on still images*/
     3038    /* state should hold the last startcode if one was found above*/
     3039    /* i will point to the position after that startcode */
     3040    if(!pc->frame_start_found){
     3041        if(state == SEQ_END_CODE){
     3042            pc->state=-1;
     3043            return i;
     3044        }
     3045    }
     3046   
    30363047    if(pc->frame_start_found){
    30373048        /* EOF considered as end of frame */
    30383049        if (buf_size == 0)
  • libs/libmythdvdnav/dvdnav.c

     
    877877  return attr.lang_code;
    878878}
    879879
     880unsigned char dvdnav_audio_get_channels(dvdnav_t *this, uint8_t stream){
     881  audio_attr_t  attr;
     882
     883  if(!this) {
     884    printerr("Passed a NULL pointer.");
     885    return 0xff;
     886  }
     887  if(!this->started) {
     888    printerr("Virtual DVD machine not started.");
     889    return 0xff;
     890  }
     891
     892  pthread_mutex_lock(&this->vm_lock);
     893  attr = vm_get_audio_attr(this->vm, stream);
     894  pthread_mutex_unlock(&this->vm_lock);
     895
     896  return attr.channels;
     897             
     898}
     899
    880900uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) {
    881901  subp_attr_t  attr;
    882902 
  • libs/libmythdvdnav/dvdnav.h

     
    550550uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream);
    551551
    552552/*
     553 * Get number of audio channels.
     554 * (1 -> 2 channels , 5 -> 6 channels)
     555 * (returns 0xff if no such stream).
     556 */
     557unsigned char dvdnav_audio_get_channels(dvdnav_t *self, uint8_t stream);
     558
     559/*
    553560 * Converts a *logical* subpicture stream id into country code
    554561 * (returns 0xffff if no such stream).
    555562 */