Logo Search packages:      
Sourcecode: vdr-plugin-dvd version File versions  Download package

void cDvdPlayer::Action ( void   ) [protected, virtual]

DEBUG_CONTROL("dvd: menu=%d, v:%u, a:%u, p:%d, stc:%8ums, blk_size=%3d, skipPlayV=%d, IframeCnt=%d, stillTimer=%8ums\n", IsInMenuDomain(), cntVidBlocksPlayed, cntAudBlocksPlayed, playedPacket, (unsigned int)(stcPTS/90U), blk_size, skipPlayVideo, IframeCnt, stillTimer/90U);

!! Skip Stillpicture

reset device only if video was played, else it would distrub audio playback in an menu&audio only environment

check if we should use the very fast forward mode

skip blocks .. if pos is not at the end

increment about fastWindFactor * 0.5 s

check is we should use any backward mode

special slomo handling

simple rewind: trickspeed-NORMAL_SPEED <= MAX_SPEEDS else fast rewind half a secound * fastWindFactor

increment about fastWindFactor * 0.5 s

jump back, if pos is not at the beginning

dont jump over the end .. 10s tolerance ..

update information

Definition at line 565 of file player-dvd.c.

References BlocksToPGCTicks(), playPacket(), and time_ticks().

                            {
    memset(event_buf, 0, sizeof(uint8_t)*4096);

    unsigned char *write_blk = NULL;
    int blk_size = 0;

    BitStreamOutActive  = false;
    HasBitStreamOut     = (cPluginManager::GetPlugin("bitstreamout") != NULL);

    SoftDeviceOutActive = false;
    HasSoftDeviceOut    = (cPluginManager::GetPlugin("xine") != NULL);

    cSetupLine *slBitStreamOutActive = NULL;
    if(HasBitStreamOut) {
          slBitStreamOutActive = cPluginDvd::GetSetupLine("active", "bitstreamout");
          if(slBitStreamOutActive!=NULL)
                BitStreamOutActive = atoi ( slBitStreamOutActive->Value() ) ? true: false ;
    }
    dsyslog("dvd-plugin: BitStreamOutActive=%d, HasBitStreamOut=%d (%d)", BitStreamOutActive, HasBitStreamOut, slBitStreamOutActive!=NULL);

    if(HasSoftDeviceOut) {
          SoftDeviceOutActive = true;
    }
    dsyslog("dvd-plugin: SoftDeviceOutActive=%d, HasSoftDeviceOut=%d", SoftDeviceOutActive, HasSoftDeviceOut);

    if (dvdnav_open(&nav, const_cast<char *>(cDVD::getDVD()->DeviceName())) != DVDNAV_STATUS_OK) {
        Skins.Message(mtError, tr("Error.DVD$Error opening DVD!"));
        esyslog("ERROR: dvd-plugin cannot open dvdnav device %s -> input thread ended (pid=%d) !", const_cast<char *>(cDVD::getDVD()->DeviceName()), getpid());
        active = running = false;
        nav=NULL;
        fflush(NULL);
        return;
    }
    dvdnav_set_readahead_flag(nav, DVDSetup.ReadAHead);
    if (DVDSetup.PlayerRCE != 0)
        dvdnav_set_region_mask(nav, 1 << (DVDSetup.PlayerRCE - 1));
    else
        dvdnav_set_region_mask(nav, 0xffff);
    dvdnav_menu_language_select(nav,  const_cast<char *>(ISO639code[DVDSetup.MenuLanguage]));
    dvdnav_audio_language_select(nav, const_cast<char *>(ISO639code[DVDSetup.AudioLanguage]));
    dvdnav_spu_language_select(nav,   const_cast<char *>(ISO639code[DVDSetup.SpuLanguage]));
    DEBUGDVD("Default-Langs: menu=%s, audio=%s, spu=%s\n",
          const_cast<char *>(ISO639code[DVDSetup.MenuLanguage]),
          const_cast<char *>(ISO639code[DVDSetup.AudioLanguage]),
          const_cast<char *>(ISO639code[DVDSetup.SpuLanguage]));
    if (IsAttached()) {
        SPUdecoder = cDevice::PrimaryDevice()->GetSpuDecoder();
        DEBUG_NAV("DVD NAV SPU clear & empty %s:%d\n", __FILE__, __LINE__);
        EmptySPU();
    }

    int slomoloop=0;
    uint64_t sleept = 0; // in ticks !
    uint64_t sleept_done = 0; // in ticks !
    bool trickMode = false;
    bool noAudio   = false;
    int PollTimeouts = 0;
    int playedPacket = pktNone;

    uint32_t cntVidBlocksSkipped  = 0;

    Empty(false);
//    IframeCnt = -1; // mark that we have to reset the device, before 1st PlayVideo ..

    running = true;
    eFrameType frameType=ftUnknown;

    bool firstClear = true;

    while( running && nav ) {

        if (!pframe) {
            pframe=ringBuffer->Get();
            if ( pframe ) {
                write_blk=pframe->Data();
                blk_size=pframe->Count();
                frameType=pframe->Type();
            }
        }

/*
        // clip PTS values ..
        if ( pktptsAudio<pktptsLastAudio )
              pktptsLastAudio=pktptsAudio;

        if ( stcPTSAudio<stcPTSLastAudio )
            stcPTSLastAudio=stcPTSAudio;

        if ( playedPacket==pktAudio ) {
            uint64_t sleept_trial = 0; // in ticks !

              // do extra sleep, if stream's pts of audio diffs
              // against dvb device's seen pts more/equal than 1 ms == 90 ticks !
            if ( pktptsAudio-pktptsLastAudio >= stcPTSAudio-stcPTSLastAudio+90 ) {
                  sleept_trial = (pktptsAudio-pktptsLastAudio) -
                                 (stcPTSAudio-stcPTSLastAudio) ;
                  if(sleept_trial>sleept) sleept=sleept_trial;
              }
        }
 */
/**
      DEBUG_CONTROL("dvd: menu=%d, v:%u, a:%u, p:%d, stc:%8ums, blk_size=%3d, skipPlayV=%d, IframeCnt=%d, stillTimer=%8ums\n",
        IsInMenuDomain(), cntVidBlocksPlayed, cntAudBlocksPlayed, playedPacket,
            (unsigned int)(stcPTS/90U),
            blk_size, skipPlayVideo, IframeCnt, stillTimer/90U);
 */

        sleept_done = 0;
        if (sleept) {
              if ( sleept/90U > 1000 )
                    DEBUG_PTS("\n***** WARNING >=1000ms sleep %llums\n", sleept/90U);
            sleept_done = delay_ticks(sleept);

            DEBUG_PTS2("dvd loop sleep=%5ut(%3ums)/%5ut(%3ums), blk_size=%3d, skipPlayV=%d, AudioBlock=%d IframeCnt=%d stillTimer=%u\n",
                    (unsigned int)sleept, (unsigned int)sleept/90U,
                    (unsigned int)sleept_done, (unsigned int)sleept_done/90U,
                    blk_size, skipPlayVideo,
                playedPacket==pktAudio,
                    IframeCnt, stillTimer/90U);
        }
        sleept = 0;
        if (playMode == pmPause || playMode == pmStill) {
              sleept = 10*90U;  // 10ms*90t/ms
              continue;
        }

        cPoller Poller;
        if (!DevicePoll(Poller, 100)) {
            PollTimeouts++;
            if (PollTimeouts == POLLTIMEOUTS_BEFORE_DEVICECLEAR) {
                  dsyslog("dvd-plugin: clearing device because of consecutive poll timeouts %d",
                        POLLTIMEOUTS_BEFORE_DEVICECLEAR);
                DEBUG_CONTROL("clearing device because of consecutive poll timeouts %d\n",
                        POLLTIMEOUTS_BEFORE_DEVICECLEAR);
                  DeviceReset();
                PollTimeouts = 0;
              }
                continue;
        }
        PollTimeouts = 0;

        LOCK_THREAD;

        trickMode = playMode == pmFast || (playMode == pmSlow && playDir == pdBackward) ;

        if (pframe) {
            int res = blk_size;
            if( !skipPlayVideo ) {
                if (firstClear && (frameType==ftDolby || frameType==ftAudio) && IframeCnt==0) {
                    DeviceReset();
                    firstClear=false;
                }
                if ( IframeCnt < 0 && frameType==ftVideo ) {
                    // we played an IFrame with DeviceStillPicture, or else -> reset !
                    DEBUG_CONTROL("clearing device because of IframeCnt < 0 && VideoFrame\n");
                    IframeCnt = 0;
                    while (!DeviceFlush(100));
                          if (!firstClear) DeviceReset();
                    }

                /** !! Skip Stillpicture **/
                res = (IframeCnt > 0 && frameType == ftVideo) ? blk_size : PlayPes(write_blk, blk_size);

                    if (trickMode) {
                        DEBUG_CONTROL("PLAYED  : todo=%d, written=%d\n", blk_size, res);
                    }
              }
#ifdef CTRLDEBUG
            else if (trickMode)
                    printf("SKIPPED : todo=%d\n", blk_size);
#endif

              if (res < 0) {
                  if (errno != EAGAIN && errno != EINTR) {
                        esyslog("ERROR: dvd-plugin PlayVideo, %s (workaround activ)", strerror(errno));
                        DEBUG_CONTROL("PlayVideo, %s (workaround activ)\n", strerror(errno));
                  }
                  DEBUG_CONTROL("PLAYED zero -> Clear/Play\n");
                  DeviceReset();
                  continue;
              }
              if (res > 0) {
                  blk_size -= res;
                write_blk += res;
              }

              if (blk_size > 0) {
//                sleept = 5*90U;  // 5ms*90t/ms
              } else {
                if ( frameType==ftVideo ) {
                        if(!skipPlayVideo) {
                          cntVidBlocksPlayed++;
                        } else {
                          cntVidBlocksSkipped++;
                        }
                  } else if ( frameType==ftAudio || frameType==ftDolby ) {
                        cntAudBlocksPlayed++;
                }

                playedPacket = pktNone;
                frameType = ftUnknown;
                ringBuffer->Drop(pframe);
                pframe = NULL;

              }
              continue;
        } else {
            if ( playedPacket==pktAudio ) {
                  cntAudBlocksPlayed++;
            }
            playedPacket = pktNone;
            frameType = ftUnknown;
        }

        if (IframeCnt > 0) {
              /**
               * reset device only if video was played,
               * else it would distrub audio playback in an
               * menu&audio only environment
               */
              if (cntVidBlocksPlayed > 0) {
                    DEBUG_CONTROL("clearing device because of IframeCnt > 0, vid %d, aud %d\n",
                      cntVidBlocksPlayed, cntAudBlocksPlayed);
                while (!DeviceFlush(100));
                  DeviceReset();
              }
            int iframeSize;
            unsigned char *iframe=iframeAssembler->Get(iframeSize);

            DEBUG_IFRAME("I-Frame: DeviceStillPicture: IframeCnt=%d->-1, iframe=%d, used=%d;\n",
            IframeCnt, iframe!=NULL, iframeSize);

            if ( iframe && iframeSize>0 ) {
#ifdef IFRAMEWRITE
                    static int ifnum = 0;
                    static char ifname[255];
                    snprintf(ifname, 255, "/tmp/dvd.iframe.%3.3d.asm.pes", ifnum++);
                  FILE *f = fopen(ifname, "wb");
                  fwrite(iframe, 1, iframeSize, f);
                  fclose(f);
#endif
                DeviceStillPicture(iframe, iframeSize);
                DEBUG_IFRAME("SEND; ");
                while (!DeviceFlush(100));
                DEBUG_IFRAME("FLUSH!\n");
              }
            iframeAssembler->Clear();
              IframeCnt = -1; // mark that we played an IFrame
            if (blk_size <= 0 && !skipPlayVideo)
                  sleept = 1*90U;  // 1ms*90t/ms

            DEBUG_IFRAME("I-Frame: DeviceStillPicture: stc=%8ums vpts=%8ums sleept=%llums\n",
                    (unsigned int)(stcPTS/90U),
                    (unsigned int)(VideoPts/90U), sleept/90U);
              continue;
        }

      /**
       * check if we should use the very fast forward mode
       */
      if (playDir == pdForward && playMode == pmFast &&
          skipPlayVideo && cntVidBlocksPlayed>0 && fastWindFactor>1)
      {
          uint32_t pos, len;
            int64_t pgcPosTicks = 0, pgcPosTicksIncr=0;

          /**
           * skip blocks .. if pos is not at the end
           */
          dvdnav_set_PGC_positioning_flag ( nav, 1);
          dvdnav_get_position ( nav, &pos, &len);

            pgcPosTicks = (int64_t)pos * pgcTicksPerBlock;

          /**
           * increment about fastWindFactor * 0.5 s
           */
            pgcPosTicksIncr = (int64_t) ((fastWindFactor * 90000L)/2L) ;

          if( pgcPosTicks+pgcPosTicksIncr < pgcTotalTicks )
          {
                  DEBUG_CONTROL("dvd %d %4.4u/%4.4u fwd get block: %4.4ldb %10.10ldt %lds\n",
                        playDir == pdBackward,
                        cntVidBlocksPlayed, cntVidBlocksSkipped,
                        (long)pos, (long)pgcPosTicks, (long)(pgcPosTicks/90000L));

                  DEBUG_CONTROL("dvd fwd set block: ts=%d, factor=%ds, %ldms+%ldms=%ldms, %4.4ldb+%4.4ldb=%4.4ldb, %10.10ldt+%10.10ldt=%10.10ldt\n",
                              trickSpeed, fastWindFactor/2,
                              (long)(pgcPosTicks/90L), (long)(pgcPosTicksIncr/90L),
                              (long)((pgcPosTicks+pgcPosTicksIncr)/90L),
                              (long)pos, (long)(pgcPosTicksIncr/pgcTicksPerBlock),
                              (long)((pgcPosTicks+pgcPosTicksIncr)/pgcTicksPerBlock),
                              (long)pgcPosTicks, (long)pgcPosTicksIncr, (long)pgcPosTicks+(long)pgcPosTicksIncr);

                  pos = (pgcPosTicks+pgcPosTicksIncr)/pgcTicksPerBlock;

                    if (dvdnav_sector_search( nav, pos, SEEK_SET) != DVDNAV_STATUS_OK)
                    esyslog("ERROR: dvd-plugin dvd error dvdnav_sector_search: %s", dvdnav_err_to_string(nav));
          }
          cntVidBlocksPlayed=0;
          cntVidBlocksSkipped=0;
      }

      /**
       * check is we should use any backward mode
       */
      else if (playDir == pdBackward && skipPlayVideo && cntVidBlocksPlayed>0 && fastWindFactor!=1)
      {
          uint32_t pos=0, posdiff=0, len=0;
            int64_t pgcPosTicks = 0;

            if(fastWindFactor<0)
            {
                /**
                 * special slomo handling
                 */
                if(slomoloop==0)
                {
                  slomoloop= abs(fastWindFactor);
                    cntVidBlocksPlayed++; // one more block back ..
                  posdiff = (uint32_t)(cntVidBlocksPlayed*2) ;
                  DEBUG_CONTROL("dvd slomo jump: d%ldb %dsl (%df)\n",
                        (long)posdiff, slomoloop, fastWindFactor);
                } else {
                  posdiff = (uint32_t)(cntVidBlocksPlayed) ;
                  DEBUG_CONTROL("dvd slomo loop: d%ldb %dsl (%df)\n",
                        (long)posdiff, slomoloop, fastWindFactor);
                    slomoloop--;
                }
            } else {
                /**
                 * simple rewind:
                 *            trickspeed-NORMAL_SPEED <= MAX_SPEEDS
                 * else fast rewind
                 *            half a secound * fastWindFactor
                 */
                if ( trickSpeed-NORMAL_SPEED <= MAX_SPEEDS )
                {
                      cntVidBlocksPlayed++; // one more block back ..
                      posdiff = cntVidBlocksPlayed*fastWindFactor ;
                } else {
                      int64_t pgcPosTicksDecr=0;

                      /**
                       * increment about fastWindFactor * 0.5 s
                       */
                      pgcPosTicksDecr = (int64_t) ((fastWindFactor * 90000L)/2L) ;
                      posdiff = (uint32_t) (pgcPosTicksDecr / pgcTicksPerBlock);
                }
          }

          /**
           * jump back, if pos is not at the beginning
           */
          dvdnav_set_PGC_positioning_flag ( nav, 1);
          if( dvdnav_get_position ( nav, &pos, &len) == DVDNAV_STATUS_OK &&
            pos>posdiff )
          {
                        pgcPosTicks = (int64_t)pos * pgcTicksPerBlock;
                  uint32_t forcedBlockPosition = pos-posdiff;
                  DEBUG_CONTROL("dvd %d %4.4u/%4.4u bwd get block: %4.4ldb %10.10ldt %lds\n",
                        playDir == pdBackward,
                        cntVidBlocksPlayed, cntVidBlocksSkipped,
                        (long)pos, (long)pgcPosTicks, (long)(pgcPosTicks/90000L));
                  DEBUG_CONTROL("dvd bwd set block: ts=%d, factor=%d, %ld-%ld=%ld, slo=%d\n",
                              trickSpeed, fastWindFactor,
                              (long)pos, (long)posdiff, (long)forcedBlockPosition,
                              slomoloop);
                    if (dvdnav_sector_search( nav, forcedBlockPosition, SEEK_SET) != DVDNAV_STATUS_OK)
                    esyslog("ERROR: dvd-plugin dvd error dvdnav_sector_search: %s", dvdnav_err_to_string(nav));
          } else {
                  DEBUG_CONTROL("dvd %d %4.4u/%4.4u bwd get block: %4.4ldb d%4.4ldb, slo=%d\n",
                        playDir == pdBackward,
                        cntVidBlocksPlayed, cntVidBlocksSkipped,
                        (long)pos, (long)posdiff, slomoloop);
          }
          cntVidBlocksPlayed=0;
          cntVidBlocksSkipped=0;
      }
      else if ( playMode == pmFast || playMode == pmSlow )
      {
          uint32_t pos, len;
            int64_t pgcPosTicks = 0;

          dvdnav_set_PGC_positioning_flag ( nav, 1);
          dvdnav_get_position ( nav, &pos, &len);

            pgcPosTicks = (int64_t)pos * pgcTicksPerBlock;

          DEBUG_CONTROL("dvd %d %4.4u/%4.4u any get block: %4.4ldb %10.10ldt %lds, sec=%d\n",
                  playDir == pdBackward,
                  cntVidBlocksPlayed, cntVidBlocksSkipped,
                  (long)pos, (long)pgcPosTicks, (long)(pgcPosTicks/90000L),
                  (int)(pgcPosTicks/90000L));

          /**
           * dont jump over the end .. 10s tolerance ..
           */
            if (playDir == pdForward && pos+1 == len && pgcPosTicks>90000L*10L && pgcTicksPerBlock>0) {
                    pgcPosTicks-=90000L*10L;
                    if (dvdnav_sector_search( nav, pgcPosTicks/pgcTicksPerBlock, SEEK_SET) != DVDNAV_STATUS_OK )
                    esyslog("ERROR: dvd-plugin dvd error dvdnav_sector_search: %s", dvdnav_err_to_string(nav));
              }
      }

      uint8_t *cache_ptr = event_buf;
      int32_t event;
      int32_t len;

      // from here on, continue is not allowed,
      // as it would bypass dvdnav_free_cache_block
      if (dvdnav_get_next_cache_block(nav, &cache_ptr, &event, &len) != DVDNAV_STATUS_OK) {
          Skins.Message(mtError, tr("Error.DVD$Error fetching data from DVD!"));
        running = false;
        break;
      }

      noAudio   = playMode != pmPlay ;

      switch (event) {
        case DVDNAV_BLOCK_OK:
            // DEBUG_NAV("%s:%d:NAV BLOCK OK\n", __FILE__, __LINE__);
#if 0
//FIXME:
            if ( cntVidBlocksPlayed==0 && cntAudBlocksPlayed==0 )
            {
                        DEBUG_CONTROL("play device because of zero played blocks v:%u, a:%u..\n",
                        cntVidBlocksPlayed, cntAudBlocksPlayed);
                  DevicePlay();
            }
#endif
            UpdateBlockInfo(); // TEST
              playedPacket = playPacket(cache_ptr, trickMode, noAudio);
            break;
        case DVDNAV_NOP:
            DEBUG_NAV("%s:%d:NAV NOP\n", __FILE__, __LINE__);
            break;
        case DVDNAV_STILL_FRAME: {
            uint64_t currentTicks = time_ticks();
            DEBUG_PTS2("%s:%d:NAV STILL FRAME (menu=%d), rem. stillTimer=%ut(%ums), currTicks=%llut(%llums)\n",
            __FILE__, __LINE__, IsInMenuDomain(),
                  stillTimer, stillTimer/90, currentTicks, currentTicks/90);
            dvdnav_still_event_t *still = (dvdnav_still_event_t *)cache_ptr;
            if (stillTimer != 0) {
                seenVPTS(0);
              if (stillTimer > currentTicks) {
                  sleept = 40*90U;  // 40ms*90t/ms
              } else {
                  StillSkip();
                  sleept = 0;
                  DEBUG_PTS("Still time clear\n");
              }
              DEBUG_PTS2("StillTimer->Sleep: %llut(%llums)\n", sleept, sleept/90);
            } else {
                    if(still->length == 0xff) {
                  stillTimer = INT_MAX;
                    DEBUG_PTS("Still time (max): %ut(%ums)\n", stillTimer, stillTimer/90);
              } else {
                  stillTimer = currentTicks + (uint64_t)(still->length) * 90000U;
                    DEBUG_PTS("Still time (set): %ut(%ums)\n", stillTimer, stillTimer/90);
              }
                SendIframe( true );
            }
            break;
        }

          case DVDNAV_WAIT:
            DEBUG_NAV("%s:%d:NAV WAIT\n", __FILE__, __LINE__);
            prev_e_ptm = 0;
            ptm_offs = 0;
            dvdnav_wait_skip(nav);
            break;

        case DVDNAV_SPU_STREAM_CHANGE: {
            DEBUG_NAV("%s:%d:NAV SPU STREAM CHANGE\n", __FILE__, __LINE__);
            dvdnav_spu_stream_change_event_t *ev = (dvdnav_spu_stream_change_event_t *)cache_ptr;
            DEBUG_SUBP_ID("SPU Streams: w:0x%X (%d), l:0x%X (%d), p:0x%X (%d), L:0x%X (%d), locked=%d/%d\n",
                ev->physical_wide, ev->physical_wide,
                ev->physical_letterbox, ev->physical_letterbox,
                ev->physical_pan_scan, ev->physical_pan_scan,
                ev->logical, ev->logical,
                  currentNavSubpStreamUsrLocked, !changeNavSubpStreamOnceInSameCell);

            if( IsInMenuDomain() || IsDvdNavigationForced() || !currentNavSubpStreamUsrLocked || changeNavSubpStreamOnceInSameCell ) {
                cSpuDecoder::eScaleMode mode = SPUdecoder ? SPUdecoder->getScaleMode() : cSpuDecoder::eSpuNormal;

                /* !!! Bit 7 set means hide, and only let Forced display show (see vm.c from libdvdnav) */
                    if (mode == cSpuDecoder::eSpuLetterBox ) {
                        // TV 4:3,  DVD 16:9
                    currentNavSubpStream = ev->physical_letterbox & (0x80 | SubpStreamMask);
                      DEBUG_SUBP_ID("dvd choosing letterbox SPU stream: curNavSpu=%d 0x%X\n",
                        currentNavSubpStream, currentNavSubpStream);
                } else if (mode == cSpuDecoder::eSpuPanAndScan ) {
                    // TV 4:3,  DVD 16:9
                    currentNavSubpStream = ev->physical_pan_scan & (0x80 | SubpStreamMask);
                    DEBUG_SUBP_ID("dvd choosing pan_scan SPU stream: curNavSpu=%d 0x%X\n",
                        currentNavSubpStream, currentNavSubpStream);
                    } else {
                    currentNavSubpStream = ev->physical_wide & (0x80 | SubpStreamMask);
                          DEBUG_SUBP_ID("dvd choosing wide SPU stream: curNavSpu=%d 0x%X\n",
                              currentNavSubpStream, currentNavSubpStream);
                    }
                currentNavSubpStreamLangCode = GetNavSubpStreamLangCode(currentNavSubpStream);
                    changeNavSubpStreamOnceInSameCell=false;
              } else {
                    DEBUG_SUBP_ID("DVDNAV_SPU_STREAM_CHANGE: ignore (locked=%d/%d|not enabled=%d), menu=%d, feature=%d \n",
                        currentNavSubpStreamUsrLocked, !changeNavSubpStreamOnceInSameCell,
                      DVDSetup.ShowSubtitles,
                    IsInMenuDomain(), isInFeature);
              }
              break;
          }
          case DVDNAV_AUDIO_STREAM_CHANGE: {
              DEBUG_NAV("%s:%d:NAV AUDIO STREAM CHANGE\n", __FILE__, __LINE__);
              dvdnav_audio_stream_change_event_t *ev;
              ev = (dvdnav_audio_stream_change_event_t *)cache_ptr;
              if(!currentNavAudioTrackUsrLocked) {
                    int id = dvdnav_get_active_audio_stream(nav);
                DEBUG_AUDIO_ID("dvd->SetCurrentAudioTrack DOLBY %02X\n", ttDolby + id);
                    if (Setup.UseDolbyDigital)
                              DeviceSetCurrentAudioTrack(eTrackType(ttDolby + id));
                        else
                              DeviceSetCurrentAudioTrack(eTrackType(ttAudio + id));
                currentNavAudioTrack = id;

                    DEBUG_AUDIO_ID("DVDNAV_AUDIO_STREAM_CHANGE: curNavAu=%d 0x%02X, phys=%d, 0x%X\n",
                      id, id, ev->physical, ev->physical);
                  SetCurrentNavAudioTrackUsrLocked(false);
              } else {
                    DEBUG_AUDIO_ID("DVDNAV_AUDIO_STREAM_CHANGE: ignore (locked) phys=%d, 0x%X\n",
                      ev->physical, ev->physical);
              }
//          firstClear=true;
              break;
        }
        case DVDNAV_VTS_CHANGE:
            DEBUG_NAV("%s:%d:NAV VTS CHANGE -> Empty, setAll-spu&audio \n", __FILE__, __LINE__);
            Empty(true);
            UpdateBlockInfo(); // TEST
              UpdateVTSInfo(); // TEST
            setAllSubpStreams();
              setAllAudioTracks();
            SetTitleInfoString();
            SetTitleString();
            SetAspectString();
            break;
        case DVDNAV_CELL_CHANGE: {
            DEBUG_NAV("%s:%d:NAV CELL CHANGE\n", __FILE__, __LINE__);

            /**
             * update information
             */
              memcpy(&lastCellEventInfo, cache_ptr, sizeof(dvdnav_cell_change_event_t));
            UpdateBlockInfo(); // TEST
              UpdateVTSInfo(); // TEST
            BlocksToPGCTicks( 1, pgcTicksPerBlock, pgcTotalTicks);
#ifdef CTRLDEBUG
            printCellInfo(lastCellEventInfo, pgcTicksPerBlock, pgcTotalTicks);
#endif
            //did the old cell end in a still frame?
            SendIframe( stillFrame & CELL_STILL );
            stillFrame = (dvdnav_get_next_still_flag(nav) != 0) ? CELL_STILL : 0;
            // cell change .. game over ..
            changeNavSubpStreamOnceInSameCell=false;
            SetTitleInfoString();
            break;
        }
        case DVDNAV_NAV_PACKET: {
            DEBUG_NAV0("%s:%d:NAV PACKET\n", __FILE__, __LINE__);
            dsi_t *dsi;
            current_pci = dvdnav_get_current_nav_pci(nav);
            DEBUG_NAV0("NAV: %x, prev_e_ptm: %8d, s_ptm: %8d, ", stillFrame, prev_e_ptm,
                 current_pci->pci_gi.vobu_s_ptm);
            if (prev_e_ptm)
                    ptm_offs += (prev_e_ptm - current_pci->pci_gi.vobu_s_ptm);
            DEBUG_NAV0("ptm_offs: %8d\n", ptm_offs);
            prev_e_ptm = current_pci->pci_gi.vobu_e_ptm;
            if (current_pci && (current_pci->hli.hl_gi.hli_ss & 0x03) == 1)
              UpdateButtonHighlight(NULL);
            dsi = dvdnav_get_current_nav_dsi(nav);
            SendIframe( stillFrame & NAV_STILL );
            if (dsi->vobu_sri.next_video == 0xbfffffff)
              stillFrame |= NAV_STILL;
            else
              stillFrame &= ~NAV_STILL;
            break;

        }
        case DVDNAV_STOP:
            DEBUG_NAV("%s:%d:NAV STOP\n", __FILE__, __LINE__);
            running = false;
            break;
        case DVDNAV_HIGHLIGHT:
        {
            DEBUG_NAV("%s:%d:NAV HIGHLIGHT\n", __FILE__, __LINE__);
            dvdnav_highlight_event_t *hlevt = (dvdnav_highlight_event_t *)cache_ptr;
            UpdateButtonHighlight(hlevt);
            break;
        }
        case DVDNAV_SPU_CLUT_CHANGE:
            DEBUG_NAV("%s:%d:NAV SPU CLUT CHANGE SPUdecoder=%d\n",
                  __FILE__, __LINE__, SPUdecoder!=NULL);
            if (SPUdecoder)
            {
              ClearButtonHighlight();
              SPUdecoder->setPalette((uint32_t *)cache_ptr);
            }
            break;
        case DVDNAV_HOP_CHANNEL:
            DEBUG_NAV("%s:%d:NAV HOP CHANNEL -> Empty\n", __FILE__, __LINE__);
              //Empty reset backward play!!!
              if ( !trickMode )
            {
              //if (playDir != pdBackward)
                  Empty(true);
            }
            UpdateBlockInfo(); // TEST
              UpdateVTSInfo(); // TEST
            break;
        default:
            DEBUG_NAV("%s:%d:NAV ???\n", __FILE__, __LINE__);
            break;
      }
#ifdef DVDDEBUG
      if ((event != DVDNAV_BLOCK_OK) &&
        (event != DVDNAV_NAV_PACKET) &&
        (event != DVDNAV_STILL_FRAME))
        DEBUGDVD("got event (%d)%s, len %d\n",
               event, dvd_ev[event], len);
#endif
      if (cache_ptr != 0 && cache_ptr != event_buf)
        dvdnav_free_cache_block(nav, cache_ptr);
  }

  DEBUG_NAV("%s:%d: empty\n", __FILE__, __LINE__);
  Empty();
  fflush(NULL);

  running = false;

  SPUdecoder=NULL;

  dvdnav_close(nav);
  nav=NULL;

  DEBUGDVD("%s:%d: input thread ended (pid=%d)\n", __FILE__, __LINE__, getpid());
  fflush(NULL);
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index