From 37827bc0c9affc4d9894ace7f12d5417d8b9afc3 Mon Sep 17 00:00:00 2001 From: Jim Stichnoth Date: Sat, 2 Feb 2013 09:46:36 -0800 Subject: [PATCH] Subtitles: Add manual synchronization of text subtitles. Adds an OSD dialog, similar to Adjust Audio Sync and Adjust Subtitle Zoom, to offset the presentation of text subtitles by a value between -5 and +5 seconds. --- mythtv/libs/libmythtv/osd.h | 3 +- mythtv/libs/libmythtv/subtitlescreen.cpp | 19 +++++- mythtv/libs/libmythtv/subtitlescreen.h | 6 +- mythtv/libs/libmythtv/tv_actions.h | 1 + mythtv/libs/libmythtv/tv_play.cpp | 77 ++++++++++++++++++++++++ mythtv/libs/libmythtv/tv_play.h | 4 ++ 6 files changed, 107 insertions(+), 3 deletions(-) diff --git a/mythtv/libs/libmythtv/osd.h b/mythtv/libs/libmythtv/osd.h index 2136fa25f4c..110205da5f3 100644 --- a/mythtv/libs/libmythtv/osd.h +++ b/mythtv/libs/libmythtv/osd.h @@ -43,7 +43,8 @@ enum OSDFunctionalType kOSDFunctionalType_SmartForward, kOSDFunctionalType_TimeStretchAdjust, kOSDFunctionalType_AudioSyncAdjust, - kOSDFunctionalType_SubtitleZoomAdjust + kOSDFunctionalType_SubtitleZoomAdjust, + kOSDFunctionalType_SubtitleDelayAdjust }; enum OSDTimeout diff --git a/mythtv/libs/libmythtv/subtitlescreen.cpp b/mythtv/libs/libmythtv/subtitlescreen.cpp index af796243d16..8c9b7a290c2 100644 --- a/mythtv/libs/libmythtv/subtitlescreen.cpp +++ b/mythtv/libs/libmythtv/subtitlescreen.cpp @@ -528,6 +528,7 @@ SubtitleScreen::SubtitleScreen(MythPlayer *player, const char * name, m_708reader(NULL), m_safeArea(QRect()), m_removeHTML(QRegExp("")), m_subtitleType(kDisplayNone), m_textFontZoom(100), m_textFontZoomPrev(100), + m_textFontDelayMs(0), m_textFontDelayMsPrev(0), m_refreshModified(false), m_refreshDeleted(false), m_fontStretch(fontStretch), m_format(new SubtitleFormat) @@ -594,6 +595,7 @@ void SubtitleScreen::EnableSubtitles(int type, bool forced_only) break; } m_textFontZoomPrev = m_textFontZoom; + m_textFontDelayMsPrev = m_textFontDelayMs; } void SubtitleScreen::DisableForcedSubtitles(void) @@ -641,6 +643,7 @@ void SubtitleScreen::Pulse(void) OptimiseDisplayedArea(); MythScreenType::Pulse(); m_textFontZoomPrev = m_textFontZoom; + m_textFontDelayMsPrev = m_textFontDelayMs; ResetElementState(); } @@ -1069,6 +1072,7 @@ void SubtitleScreen::DisplayTextSubtitles(void) return; bool changed = (m_textFontZoom != m_textFontZoomPrev); + changed |= (m_textFontDelayMs != m_textFontDelayMsPrev); VideoOutput *vo = m_player->GetVideoOutput(); if (!vo) return; @@ -1081,12 +1085,14 @@ void SubtitleScreen::DisplayTextSubtitles(void) TextSubtitles *subs = m_subreader->GetTextSubtitles(); subs->Lock(); uint64_t playPos = 0; + int playPosAdj = m_textFontDelayMs; if (subs->IsFrameBasedTiming()) { // frame based subtitles get out of synch after running mythcommflag // for the file, i.e., the following number is wrong and does not // match the subtitle frame numbers: playPos = currentFrame->frameNumber; + playPosAdj /= m_player->GetFrameRate(); } else { @@ -1104,6 +1110,7 @@ void SubtitleScreen::DisplayTextSubtitles(void) //else playPos = m_player->GetDecoder()->NormalizeVideoTimecode(currentFrame->timecode); } + playPos -= playPosAdj; if (playPos != 0) changed |= subs->HasSubtitleChanged(playPos); if (!changed) @@ -1451,11 +1458,21 @@ void SubtitleScreen::SetZoom(int percent) gCoreContext->SaveSetting("OSDCC708TextZoom", percent); } -int SubtitleScreen::GetZoom(void) +int SubtitleScreen::GetZoom(void) const { return m_textFontZoom; } +void SubtitleScreen::SetDelay(int ms) +{ + m_textFontDelayMs = ms; +} + +int SubtitleScreen::GetDelay(void) const +{ + return m_textFontDelayMs; +} + static QString srtColorString(QColor color) { return QString("#%1%2%3") diff --git a/mythtv/libs/libmythtv/subtitlescreen.h b/mythtv/libs/libmythtv/subtitlescreen.h index 5a4fda6bb44..32f1cb4668b 100644 --- a/mythtv/libs/libmythtv/subtitlescreen.h +++ b/mythtv/libs/libmythtv/subtitlescreen.h @@ -40,7 +40,9 @@ class SubtitleScreen : public MythScreenType void DisplayDVDButton(AVSubtitle* dvdButton, QRect &buttonPos); void SetZoom(int percent); - int GetZoom(void); + int GetZoom(void) const; + void SetDelay(int ms); + int GetDelay(void) const; QSize CalcTextSize(const QString &text, const CC708CharacterAttribute &format, @@ -95,6 +97,8 @@ class SubtitleScreen : public MythScreenType int m_fontSize; int m_textFontZoom; // valid for 708 & text subs int m_textFontZoomPrev; + int m_textFontDelayMs; // valid for text subs + int m_textFontDelayMsPrev; bool m_refreshModified; bool m_refreshDeleted; QHash > m_708imageCache; diff --git a/mythtv/libs/libmythtv/tv_actions.h b/mythtv/libs/libmythtv/tv_actions.h index 45a514a4611..b2ffe61cbfa 100644 --- a/mythtv/libs/libmythtv/tv_actions.h +++ b/mythtv/libs/libmythtv/tv_actions.h @@ -65,6 +65,7 @@ #define ACTION_ENABLEEXTTEXT "ENABLEEXTTEXT" #define ACTION_TOGGLEEXTTEXT "TOGGLETEXT" #define ACTION_TOGGLESUBTITLEZOOM "TOGGLESUBZOOM" +#define ACTION_TOGGLESUBTITLEDELAY "TOGGLESUBDELAY" /* Interactive Television keys */ #define ACTION_MENURED "MENURED" diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index e89d483c550..15af9ab57c7 100644 --- a/mythtv/libs/libmythtv/tv_play.cpp +++ b/mythtv/libs/libmythtv/tv_play.cpp @@ -981,6 +981,7 @@ TV::TV(void) stretchAdjustment(false), audiosyncAdjustment(false), subtitleZoomAdjustment(false), + subtitleDelayAdjustment(false), editmode(false), zoomMode(false), sigMonMode(false), endOfRecording(false), @@ -3860,6 +3861,7 @@ bool TV::ProcessKeypress(PlayerContext *actx, QKeyEvent *e) handled = handled || TimeStretchHandleAction(actx, actions); handled = handled || AudioSyncHandleAction(actx, actions); handled = handled || SubtitleZoomHandleAction(actx, actions); + handled = handled || SubtitleDelayHandleAction(actx, actions); handled = handled || DiscMenuHandleAction(actx, actions); handled = handled || ActiveHandleAction( actx, actions, isDVD, isMenuOrStill); @@ -4158,6 +4160,30 @@ bool TV::SubtitleZoomHandleAction(PlayerContext *ctx, return handled; } +bool TV::SubtitleDelayHandleAction(PlayerContext *ctx, + const QStringList &actions) +{ + if (!subtitleDelayAdjustment) + return false; + + bool handled = true; + + if (has_action(ACTION_LEFT, actions)) + ChangeSubtitleDelay(ctx, -1); + else if (has_action(ACTION_RIGHT, actions)) + ChangeSubtitleDelay(ctx, 1); + else if (has_action(ACTION_UP, actions)) + ChangeSubtitleDelay(ctx, -10); + else if (has_action(ACTION_DOWN, actions)) + ChangeSubtitleDelay(ctx, 10); + else if (has_action(ACTION_TOGGLESUBTITLEDELAY, actions)) + ClearOSD(ctx); + else + handled = false; + + return handled; +} + bool TV::DiscMenuHandleAction(PlayerContext *ctx, const QStringList &actions) { int64_t pts = 0; @@ -4531,6 +4557,8 @@ bool TV::ToggleHandleAction(PlayerContext *ctx, ChangeAudioSync(ctx, 0); // just display else if (has_action(ACTION_TOGGLESUBTITLEZOOM, actions)) ChangeSubtitleZoom(ctx, 0); // just display + else if (has_action(ACTION_TOGGLESUBTITLEDELAY, actions)) + ChangeSubtitleDelay(ctx, 0); // just display else if (has_action(ACTION_TOGGLEVISUALISATION, actions)) EnableVisualisation(ctx, false, true /*toggle*/); else if (has_action(ACTION_ENABLEVISUALISATION, actions)) @@ -8790,6 +8818,44 @@ void TV::ChangeSubtitleZoom(PlayerContext *ctx, int dir) } } +// dir in 10ms jumps +void TV::ChangeSubtitleDelay(PlayerContext *ctx, int dir) +{ + ctx->LockDeletePlayer(__FILE__, __LINE__); + if (!ctx->player) + { + ctx->UnlockDeletePlayer(__FILE__, __LINE__); + return; + } + + OSD *osd = GetOSDLock(ctx); + SubtitleScreen *subs = NULL; + if (osd) + subs = osd->InitSubtitles(); + ReturnOSDLock(ctx, osd); + subtitleDelayAdjustment = true; + uint capmode = ctx->player->GetCaptionMode(); + bool showing = ctx->player->GetCaptionsEnabled() && + (capmode == kDisplayRawTextSubtitle || + capmode == kDisplayTextSubtitle); + int newval = (subs ? subs->GetDelay() : 100) + dir * 10; + newval = max(-5000, newval); + newval = min(5000, newval); + ctx->UnlockDeletePlayer(__FILE__, __LINE__); + + if (showing && !browsehelper->IsBrowsing()) + { + // range of -5000ms..+5000ms, scale to 0..1000 + UpdateOSDStatus(ctx, tr("Adjust Subtitle Delay"), tr("Subtitle Delay"), + QString::number(newval), + kOSDFunctionalType_SubtitleDelayAdjust, + "ms", newval / 10 + 500, kOSDTimeout_Long); + SetUpdateOSDPosition(false); + if (subs) + subs->SetDelay(newval); + } +} + // dir in 10ms jumps void TV::ChangeAudioSync(PlayerContext *ctx, int dir, int newsync) { @@ -9703,6 +9769,9 @@ void TV::HandleOSDClosed(int osdType) case kOSDFunctionalType_SubtitleZoomAdjust: subtitleZoomAdjustment = false; break; + case kOSDFunctionalType_SubtitleDelayAdjust: + subtitleDelayAdjustment = false; + break; case kOSDFunctionalType_Default: break; } @@ -10632,6 +10701,8 @@ void TV::OSDDialogEvent(int result, QString text, QString action) ChangeAudioSync(actx, 0); else if (action == ACTION_TOGGLESUBTITLEZOOM) ChangeSubtitleZoom(actx, 0); + else if (action == ACTION_TOGGLESUBTITLEDELAY) + ChangeSubtitleDelay(actx, 0); else if (action == ACTION_TOGGLEVISUALISATION) EnableVisualisation(actx, false, true /*toggle*/); else if (action == ACTION_ENABLEVISUALISATION) @@ -11293,6 +11364,7 @@ void TV::FillOSDMenuSubtitles(const PlayerContext *ctx, OSD *osd, backaction = "MAIN"; currenttext = tr("Subtitles"); + uint capmode = ctx->player->GetCaptionMode(); if (have_subs && enabled) osd->DialogAddButton(tr("Disable Subtitles"), ACTION_DISABLESUBS); else if (have_subs && !enabled) @@ -11343,6 +11415,11 @@ void TV::FillOSDMenuSubtitles(const PlayerContext *ctx, OSD *osd, if (enabled) osd->DialogAddButton(tr("Adjust Subtitle Zoom"), ACTION_TOGGLESUBTITLEZOOM); + if (enabled && + (capmode == kDisplayRawTextSubtitle || + capmode == kDisplayTextSubtitle)) + osd->DialogAddButton(tr("Adjust Subtitle Delay"), + ACTION_TOGGLESUBTITLEDELAY); } else if (category == "AVSUBTITLES") { diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h index 6f408ef3268..1b8e05f0862 100644 --- a/mythtv/libs/libmythtv/tv_play.h +++ b/mythtv/libs/libmythtv/tv_play.h @@ -506,6 +506,9 @@ class MTV_PUBLIC TV : public QObject bool SubtitleZoomHandleAction(PlayerContext *ctx, const QStringList &actions); void ChangeSubtitleZoom(PlayerContext *ctx, int dir); + bool SubtitleDelayHandleAction(PlayerContext *ctx, + const QStringList &actions); + void ChangeSubtitleDelay(PlayerContext *ctx, int dir); // PxP handling bool CreatePBP(PlayerContext *lctx, const ProgramInfo *info); @@ -696,6 +699,7 @@ class MTV_PUBLIC TV : public QObject bool stretchAdjustment; ///< True if time stretch is turned on bool audiosyncAdjustment; ///< True if audiosync is turned on bool subtitleZoomAdjustment; ///< True if subtitle zoom is turned on + bool subtitleDelayAdjustment; ///< True if subtitle delay is turned on bool editmode; ///< Are we in video editing mode bool zoomMode; bool sigMonMode; ///< Are we in signal monitoring mode?