Ticket #7892: t7892_avchapter_support_v1.diff

File t7892_avchapter_support_v1.diff, 11.1 KB (added by tralph11@…, 11 years ago)

AVChapter support

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    169169      transcoding(false),
    170170      hasFullPositionMap(false),    limitKeyRepeat(false),
    171171      errorMsg(QString::null),      errorType(kError_None),
     172      // Chapter stuff
     173      jumpchapter(0),
    172174      // Bookmark stuff
    173175      bookmarkseek(0),              previewFromBookmark(false),
    174176      // Seek
     
    32483250}
    32493251
    32503252
     3253void NuppelVideoPlayer::JumpChapter(int direction)
     3254{
     3255    if (jumpchapter == 0)
     3256        jumpchapter = direction;
     3257}
     3258
    32513259void NuppelVideoPlayer::SkipCommercials(int direction)
    32523260{
    32533261    if (skipcommercials == 0)
     
    35763584    }
    35773585
    35783586    rewindtime = fftime = 0;
     3587    jumpchapter = 0;
    35793588    skipcommercials = 0;
    35803589
    35813590    if (bookmarkseek > 30)
     
    37823791                RefreshPauseFrame();
    37833792                need_change_dvd_track = 0;
    37843793            }
     3794            else if (jumpchapter != 0)
     3795            {
     3796                DoJumpChapter(jumpchapter);
     3797                RefreshPauseFrame();
     3798                jumpchapter = 0;
     3799            }
    37853800            else if (player_ctx->tvchain && player_ctx->tvchain->NeedsToJump())
    37863801            {
    37873802                JumpToProgram();
     
    38443859            need_change_dvd_track = 0;
    38453860        }
    38463861
     3862        if (jumpchapter != 0)
     3863        {
     3864            QMutexLocker locker(&internalPauseLock);
     3865
     3866            PauseVideo(true);
     3867            DoJumpChapter(jumpchapter);
     3868            UnpauseVideo(true);
     3869
     3870            jumpchapter = 0;
     3871        }
     3872
    38473873        if (skipcommercials != 0 && ffrew_skip == 1)
    38483874        {
    38493875            QMutexLocker locker(&internalPauseLock);
     
    66606686    }
    66616687}
    66626688
     6689int NuppelVideoPlayer::GetNumChapters()
     6690{
     6691    return GetDecoder()->GetNumChapters();
     6692}
     6693
     6694bool NuppelVideoPlayer::DoJumpChapter(int direction)
     6695{
     6696  int desiredFrame;
     6697
     6698  if (direction == -1)
     6699  {
     6700      desiredFrame = GetDecoder()->GetPrevChapter(framesPlayed);
     6701  }
     6702  else
     6703  {
     6704      desiredFrame = GetDecoder()->GetNextChapter(framesPlayed);
     6705  }
     6706
     6707  if (paused && !editmode)
     6708      GetDecoder()->setExactSeeks(true);
     6709  if (direction == -1)
     6710      GetDecoder()->DoRewind(desiredFrame);
     6711  else
     6712      GetDecoder()->DoFastForward(desiredFrame);
     6713  GetDecoder()->setExactSeeks(exactseeks);
     6714
     6715  // Note: The video output will be reset by what the the decoder
     6716  //       does, so we only need to reset the audio, subtitles, etc.
     6717  ClearAfterSeek(false);
     6718
     6719  lastSkipTime = time(NULL);
     6720  return true;
     6721}
     6722
    66636723bool NuppelVideoPlayer::DoSkipCommercials(int direction)
    66646724{
    66656725    if (!hascommbreaktable)
  • libs/libmythtv/decoderbase.h

     
    7878    virtual bool GetFrame(int onlyvideo) = 0;
    7979    NuppelVideoPlayer *GetNVP() { return m_parent; }
    8080
     81    virtual int GetNumChapters(void) { return 0; }
     82    virtual int GetNextChapter(int framesPlayed) { return framesPlayed; }
     83    virtual int GetPrevChapter(int framesPlayed) { return framesPlayed; }
    8184    virtual bool DoRewind(long long desiredFrame, bool doflush = true);
    8285    virtual bool DoFastForward(long long desiredFrame, bool doflush = true);
    8386
  • libs/libmythtv/avformatdecoder.cpp

     
    561561    return  ((lsb - base_ts)&mask);
    562562}
    563563
     564int AvFormatDecoder::GetNumChapters()
     565{
     566  return ic->nb_chapters;
     567}
     568
     569int AvFormatDecoder::GetPrevChapter(int framesPlayed)
     570{
     571    int framenum;
     572    int prevframenum = framesPlayed;
     573    int prevchapter = 0;
     574    for (int i=0; i < ic->nb_chapters; i++)
     575    {
     576        int num = ic->chapters[i]->time_base.num;
     577        int den = ic->chapters[i]->time_base.den;
     578        int64_t start = ic->chapters[i]->start;
     579        int64_t end = ic->chapters[i]->end;
     580        double total_secs = (double)((long double)start * (long double)num / (long double)den);
     581        framenum = (int)(total_secs * fps);
     582        if (framenum > (framesPlayed - (int)fps))
     583        {
     584            VERBOSE(VB_PLAYBACK, LOC +
     585                    QString("GetPrevChapter(selected chapter %1 framenum %2)")
     586                            .arg(prevchapter).arg(prevframenum));
     587            return prevframenum;
     588        }
     589        prevframenum = framenum;
     590        prevchapter = i;
     591    }
     592    return framenum;
     593}
     594
     595int AvFormatDecoder::GetNextChapter(int framesPlayed)
     596{
     597    int framenum;
     598    for (int i=0; i < ic->nb_chapters; i++)
     599    {
     600        int num = ic->chapters[i]->time_base.num;
     601        int den = ic->chapters[i]->time_base.den;
     602        int64_t start = ic->chapters[i]->start;
     603        int64_t end = ic->chapters[i]->end;
     604        double total_secs = (double)((long double)start * (long double)num / (long double)den);
     605        framenum = (int)(total_secs * fps);
     606        if (framenum > framesPlayed)
     607        {
     608            VERBOSE(VB_IMPORTANT, LOC +
     609                    QString("GetNextChapter(selected chapter %1 framenum %2)")
     610                            .arg(i).arg(framenum));
     611            return framenum;
     612        }
     613    }
     614    return framesPlayed;
     615}
     616
    564617bool AvFormatDecoder::DoRewind(long long desiredFrame, bool discardFrames)
    565618{
    566619    VERBOSE(VB_PLAYBACK, LOC + "DoRewind("
     
    10801133            QString("Successfully opened decoder for file: "
    10811134                    "\"%1\". novideo(%2)").arg(filename).arg(novideo));
    10821135
     1136    // Print AVContext chapter information
     1137    for (int i=0; i < ic->nb_chapters; i++)
     1138    {
     1139        int id = ic->chapters[i]->id;
     1140        int num = ic->chapters[i]->time_base.num;
     1141        int den = ic->chapters[i]->time_base.den;
     1142        int64_t start = ic->chapters[i]->start;
     1143        int64_t end = ic->chapters[i]->end;
     1144        double total_secs = (double)((long double)start * (long double)num / (long double)den);
     1145        int hours = (int)total_secs / 60 / 60;
     1146        int minutes = ((int)total_secs / 60) - (hours * 60);
     1147        double secs = total_secs - (double)((hours * 60 * 60) - (minutes * 60));
     1148        VERBOSE(VB_PLAYBACK, LOC + QString("Chapter %1 found %2:%3:%4")
     1149                .arg(QString().sprintf("%02d", i))
     1150                .arg(QString().sprintf("%02d", hours))
     1151                .arg(QString().sprintf("%02d", minutes))
     1152                .arg(QString().sprintf("%02.3f", secs)));
     1153    }
     1154
    10831155    // Return true if recording has position map
    10841156    return recordingHasPositionMap;
    10851157}
  • libs/libmythtv/tv_play.h

     
    436436    float StopFFRew(PlayerContext*);
    437437    void ChangeFFRew(PlayerContext*, int direction);
    438438    void SetFFRew(PlayerContext*, int index);
     439    int GetNumChapters(PlayerContext*);
     440    void DoJumpChapter(PlayerContext*, int direction);
    439441    void DoSkipCommercials(PlayerContext*, int direction);
    440442    void StartProgramEditMode(PlayerContext*);
    441443
  • libs/libmythtv/NuppelVideoPlayer.h

     
    265265    bool RebuildSeekTable(bool showPercentage = true, StatusCallback cb = NULL,
    266266                          void* cbData = NULL);
    267267
     268    // Chapter stuff
     269    void JumpChapter(int direction);
     270
    268271    // Commercial stuff
    269272    void SkipCommercials(int direction);
    270273    int FlagCommercials(bool showPercentage, bool fullSpeed,
     
    409412    void CheckTVChain();
    410413    void FileChangedCallback();
    411414
     415    // Chapter public stuff
     416    int GetNumChapters();
     417
    412418    // DVD public stuff
    413419    void ChangeDVDTrack(bool ffw);
    414420    void ActivateDVDButton(void);
     
    486492    void JumpToNetFrame(long long net) { JumpToFrame(framesPlayed + net); }
    487493    void RefreshPauseFrame(void);
    488494
     495    // Private chapter stuff
     496    bool DoJumpChapter(int direction);
     497
    489498    // Private commercial skipping
    490499    void SkipCommercialsByBlanks(void);
    491500    bool DoSkipCommercials(int direction);
     
    596605    mutable QString  errorMsg;   ///< Reason why NVP exited with a error
    597606    mutable int errorType;
    598607
     608    // Chapter stuff
     609    int jumpchapter;
     610
    599611    // Bookmark stuff
    600612    long long bookmarkseek;
    601613    bool      previewFromBookmark;
  • libs/libmythtv/tv_play.cpp

     
    42224222    {
    42234223        if (isDVD)
    42244224            DVDJumpBack(ctx);
     4225        else if (GetNumChapters(ctx) > 0)
     4226            DoJumpChapter(ctx, -1);
    42254227        else
    42264228            DoSeek(ctx, -ctx->jumptime * 60, tr("Jump Back"));
    42274229    }
     
    42294231    {
    42304232        if (isDVD)
    42314233            DVDJumpForward(ctx);
     4234        else if (GetNumChapters(ctx) > 0)
     4235            DoJumpChapter(ctx, 1);
    42324236        else
    42334237            DoSeek(ctx, ctx->jumptime * 60, tr("Jump Ahead"));
    42344238    }
     
    61066110    ctx->UnlockPlayingInfo(__FILE__, __LINE__);
    61076111}
    61086112
     6113int TV::GetNumChapters(PlayerContext *ctx)
     6114{
     6115    int num_chapters;
     6116    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6117    if (ctx->nvp)
     6118        num_chapters = ctx->nvp->GetNumChapters();
     6119    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6120
     6121    return num_chapters;
     6122}
     6123
     6124void TV::DoJumpChapter(PlayerContext *ctx, int direction)
     6125{
     6126    NormalSpeed(ctx);
     6127    StopFFRew(ctx);
     6128
     6129    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6130    bool muted = MuteChannelChange(ctx);
     6131    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6132
     6133    struct StatusPosInfo posInfo;
     6134    ctx->CalcNVPSliderPosition(posInfo);
     6135
     6136    bool slidertype = false;
     6137
     6138    OSD *osd = GetOSDLock(ctx);
     6139    if (osd)
     6140    {
     6141        posInfo.desc = tr("Searching...");
     6142        if (direction < 0)
     6143            osd->ShowStatus(posInfo, slidertype, tr("Previous Chapter"), 6);
     6144        else
     6145            osd->ShowStatus(posInfo, slidertype, tr("Next Chapter"), 6);
     6146        SetUpdateOSDPosition(true);
     6147    }
     6148    ReturnOSDLock(ctx, osd);
     6149
     6150    ctx->LockDeleteNVP(__FILE__, __LINE__);
     6151    if (ctx->nvp)
     6152        ctx->nvp->JumpChapter(direction);
     6153    ctx->UnlockDeleteNVP(__FILE__, __LINE__);
     6154
     6155    if (muted)
     6156        SetMuteTimer(ctx, kMuteTimeout);
     6157}
     6158
    61096159void TV::DoSkipCommercials(PlayerContext *ctx, int direction)
    61106160{
    61116161    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