Ticket #7892: t7892_avchapter_support_v3.diff

File t7892_avchapter_support_v3.diff, 10.9 KB (added by taylor.ralph@…, 10 years ago)

final update (trunk 23210)

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    122122      transcoding(false),
    123123      hasFullPositionMap(false),    limitKeyRepeat(false),
    124124      errorMsg(QString::null),      errorType(kError_None),
     125      // Chapter stuff
     126      jumpchapter(0),
    125127      // Bookmark stuff
    126128      bookmarkseek(0),
    127129      // Seek
     
    31253127}
    31263128
    31273129
     3130void NuppelVideoPlayer::JumpChapter(int direction)
     3131{
     3132    if (jumpchapter == 0)
     3133        jumpchapter = direction;
     3134}
     3135
    31283136void NuppelVideoPlayer::SkipCommercials(int direction)
    31293137{
    31303138    if (skipcommercials == 0)
     
    34543462    }
    34553463
    34563464    rewindtime = fftime = 0;
     3465    jumpchapter = 0;
    34573466    skipcommercials = 0;
    34583467
    34593468    if (bookmarkseek > 30)
     
    36623671                RefreshPauseFrame();
    36633672                need_change_dvd_track = 0;
    36643673            }
     3674            else if (jumpchapter != 0)
     3675            {
     3676                DoJumpChapter(jumpchapter);
     3677                RefreshPauseFrame();
     3678                jumpchapter = 0;
     3679            }
    36653680            else if (player_ctx->tvchain && player_ctx->tvchain->NeedsToJump())
    36663681            {
    36673682                JumpToProgram();
     
    37243739            need_change_dvd_track = 0;
    37253740        }
    37263741
     3742        if (jumpchapter != 0)
     3743        {
     3744            QMutexLocker locker(&internalPauseLock);
     3745
     3746            PauseVideo(true);
     3747            DoJumpChapter(jumpchapter);
     3748            UnpauseVideo(true);
     3749
     3750            jumpchapter = 0;
     3751        }
     3752
    37273753        if (skipcommercials != 0 && ffrew_skip == 1)
    37283754        {
    37293755            QMutexLocker locker(&internalPauseLock);
     
    65806606    }
    65816607}
    65826608
     6609int NuppelVideoPlayer::GetNumChapters()
     6610{
     6611    return GetDecoder()->GetNumChapters();
     6612}
     6613
     6614bool NuppelVideoPlayer::DoJumpChapter(int direction)
     6615{
     6616  int desiredFrame = 0;
     6617
     6618  if (direction == -1)
     6619  {
     6620      desiredFrame = GetDecoder()->GetPrevChapter(framesPlayed);
     6621  }
     6622  else
     6623  {
     6624      desiredFrame = GetDecoder()->GetNextChapter(framesPlayed);
     6625  }
     6626
     6627  if (paused && !editmode)
     6628      GetDecoder()->setExactSeeks(true);
     6629  if (direction == -1)
     6630      GetDecoder()->DoRewind(desiredFrame);
     6631  else
     6632      GetDecoder()->DoFastForward(desiredFrame);
     6633  GetDecoder()->setExactSeeks(exactseeks);
     6634
     6635  // Note: The video output will be reset by what the the decoder
     6636  //       does, so we only need to reset the audio, subtitles, etc.
     6637  ClearAfterSeek(false);
     6638
     6639  lastSkipTime = time(NULL);
     6640  return true;
     6641}
     6642
    65836643bool NuppelVideoPlayer::DoSkipCommercials(int direction)
    65846644{
    65856645    if (!hascommbreaktable)
  • libs/libmythtv/avformatdecoder.cpp

     
    580580    return  ((lsb - base_ts)&mask);
    581581}
    582582
     583int AvFormatDecoder::GetNumChapters()
     584{
     585  return ic->nb_chapters;
     586}
     587
     588int AvFormatDecoder::GetPrevChapter(int framesPlayed)
     589{
     590    int framenum = 0;
     591    int prevframenum = framesPlayed;
     592    int prevchapter = 0;
     593    for (unsigned int i=0; i < ic->nb_chapters; i++)
     594    {
     595        int num = ic->chapters[i]->time_base.num;
     596        int den = ic->chapters[i]->time_base.den;
     597        int64_t start = ic->chapters[i]->start;
     598        long double total_secs = (long double)start * (long double)num / (long double)den;
     599        framenum = (int)(total_secs * fps);
     600        if (framenum > (framesPlayed - (int)(3.0f * fps)))
     601        {
     602            VERBOSE(VB_PLAYBACK, LOC +
     603                    QString("GetPrevChapter(selected chapter %1 framenum %2)")
     604                            .arg(prevchapter).arg(prevframenum));
     605            return prevframenum;
     606        }
     607        prevframenum = framenum;
     608        prevchapter = i;
     609    }
     610    return framenum;
     611}
     612
     613int AvFormatDecoder::GetNextChapter(int framesPlayed)
     614{
     615    int framenum = 0;
     616    for (unsigned int i=0; i < ic->nb_chapters; i++)
     617    {
     618        int num = ic->chapters[i]->time_base.num;
     619        int den = ic->chapters[i]->time_base.den;
     620        int64_t start = ic->chapters[i]->start;
     621        long double total_secs = (long double)start * (long double)num / (long double)den;
     622        framenum = (int)(total_secs * fps);
     623        if (framenum > framesPlayed)
     624        {
     625            VERBOSE(VB_IMPORTANT, LOC +
     626                    QString("GetNextChapter(selected chapter %1 framenum %2)")
     627                            .arg(i).arg(framenum));
     628            return framenum;
     629        }
     630    }
     631    return framesPlayed;
     632}
     633
    583634bool AvFormatDecoder::DoRewind(long long desiredFrame, bool discardFrames)
    584635{
    585636    VERBOSE(VB_PLAYBACK, LOC + "DoRewind("
     
    11001151            QString("Successfully opened decoder for file: "
    11011152                    "\"%1\". novideo(%2)").arg(filename).arg(novideo));
    11021153
     1154    // Print AVChapter information
     1155    for (unsigned int i=0; i < ic->nb_chapters; i++)
     1156    {
     1157        int num = ic->chapters[i]->time_base.num;
     1158        int den = ic->chapters[i]->time_base.den;
     1159        int64_t start = ic->chapters[i]->start;
     1160        long double total_secs = (long double)start * (long double)num / (long double)den;
     1161        int hours = (int)total_secs / 60 / 60;
     1162        int minutes = ((int)total_secs / 60) - (hours * 60);
     1163        double secs = (double)total_secs - (double)(hours * 60 * 60 + minutes * 60);
     1164        VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found @ [%2:%3:%4]")
     1165                .arg(QString().sprintf("%02d", i))
     1166                .arg(QString().sprintf("%02d", hours))
     1167                .arg(QString().sprintf("%02d", minutes))
     1168                .arg(QString().sprintf("%06.3f", secs)));
     1169    }
     1170
    11031171    // Return true if recording has position map
    11041172    return recordingHasPositionMap;
    11051173}
  • libs/libmythtv/decoderbase.h

     
    105105    virtual bool GetFrame(DecodeType) = 0;
    106106    NuppelVideoPlayer *GetNVP() { return m_parent; }
    107107
     108    virtual int GetNumChapters(void) { return 0; }
     109    virtual int GetNextChapter(int framesPlayed) { return framesPlayed; }
     110    virtual int GetPrevChapter(int framesPlayed) { return framesPlayed; }
    108111    virtual bool DoRewind(long long desiredFrame, bool doflush = true);
    109112    virtual bool DoFastForward(long long desiredFrame, bool doflush = true);
    110113
  • libs/libmythtv/tv_play.h

     
    442442    float StopFFRew(PlayerContext*);
    443443    void ChangeFFRew(PlayerContext*, int direction);
    444444    void SetFFRew(PlayerContext*, int index);
     445    int GetNumChapters(PlayerContext*);
     446    void DoJumpChapter(PlayerContext*, int direction);
    445447    void DoSkipCommercials(PlayerContext*, int direction);
    446448    void StartProgramEditMode(PlayerContext*);
    447449
  • libs/libmythtv/NuppelVideoPlayer.h

     
    250250    bool RebuildSeekTable(bool showPercentage = true, StatusCallback cb = NULL,
    251251                          void* cbData = NULL);
    252252
     253    // Chapter stuff
     254    void JumpChapter(int direction);
     255
    253256    // Commercial stuff
    254257    void SkipCommercials(int direction);
    255258    int FlagCommercials(bool showPercentage, bool fullSpeed,
     
    394397    void CheckTVChain();
    395398    void FileChangedCallback();
    396399
     400    // Chapter public stuff
     401    int GetNumChapters();
     402
    397403    // DVD public stuff
    398404    void ChangeDVDTrack(bool ffw);
    399405    void ActivateDVDButton(void);
     
    470476    void JumpToNetFrame(long long net) { JumpToFrame(framesPlayed + net); }
    471477    void RefreshPauseFrame(void);
    472478
     479    // Private chapter stuff
     480    bool DoJumpChapter(int direction);
     481
    473482    // Private commercial skipping
    474483    void SkipCommercialsByBlanks(void);
    475484    bool DoSkipCommercials(int direction);
     
    580589    mutable QString  errorMsg;   ///< Reason why NVP exited with a error
    581590    mutable int errorType;
    582591
     592    // Chapter stuff
     593    int jumpchapter;
     594
    583595    // Bookmark stuff
    584596    long long bookmarkseek;
    585597
  • libs/libmythtv/tv_play.cpp

     
    43024302    {
    43034303        if (isDVD)
    43044304            DVDJumpBack(ctx);
     4305        else if (GetNumChapters(ctx) > 0)
     4306            DoJumpChapter(ctx, -1);
    43054307        else
    43064308            DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"));
    43074309    }
     
    43094311    {
    43104312        if (isDVD)
    43114313            DVDJumpForward(ctx);
     4314        else if (GetNumChapters(ctx) > 0)
     4315            DoJumpChapter(ctx, 1);
    43124316        else
    43134317            DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"));
    43144318    }
     
    61926196    ctx->UnlockPlayingInfo(__FILE__, __LINE__);
    61936197}
    61946198
     6199int TV::GetNumChapters(PlayerContext *ctx)
     6200{
     6201    int num_chapters;
     6202    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6203    if (ctx->nvp)
     6204        num_chapters = ctx->nvp->GetNumChapters();
     6205    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6206
     6207    return num_chapters;
     6208}
     6209
     6210void TV::DoJumpChapter(PlayerContext *ctx, int direction)
     6211{
     6212    NormalSpeed(ctx);
     6213    StopFFRew(ctx);
     6214
     6215    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6216    bool muted = MuteChannelChange(ctx);
     6217    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6218
     6219    struct StatusPosInfo posInfo;
     6220    ctx->CalcNVPSliderPosition(posInfo);
     6221
     6222    bool slidertype = false;
     6223
     6224    OSD *osd = GetOSDLock(ctx);
     6225    if (osd)
     6226    {
     6227        posInfo.desc = tr("Searching...");
     6228        if (direction < 0)
     6229            osd->ShowStatus(posInfo, slidertype, tr("Previous Chapter"), 3);
     6230        else
     6231            osd->ShowStatus(posInfo, slidertype, tr("Next Chapter"), 3);
     6232        SetUpdateOSDPosition(true);
     6233    }
     6234    ReturnOSDLock(ctx, osd);
     6235
     6236    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6237    if (ctx->nvp)
     6238        ctx->nvp->JumpChapter(direction);
     6239    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6240
     6241    if (muted)
     6242        SetMuteTimer(ctx, kMuteTimeout);
     6243}
     6244
    61956245void TV::DoSkipCommercials(PlayerContext *ctx, int direction)
    61966246{
    61976247    NormalSpeed(ctx);
  • libs/libmythtv/avformatdecoder.h

     
    131131
    132132    int ScanStreams(bool novideo);
    133133
     134    virtual int GetNumChapters();
     135    virtual int GetPrevChapter(int framesPlayed);
     136    virtual int GetNextChapter(int framesPlayed);
    134137    virtual bool DoRewind(long long desiredFrame, bool doflush = true);
    135138    virtual bool DoFastForward(long long desiredFrame, bool doflush = true);
    136139