From 53313e1450c19fbb671f6b5512b6e7cca9463835 Mon Sep 17 00:00:00 2001 From: Memphiz Date: Sat, 22 Sep 2012 22:00:12 +0200 Subject: [dvdplayer/PGS-subs] - fix PGS Subtitles like ffmpeg did it in http://git.videolan.org/?p=ffmpeg.git;a=commit;h=2939e258f9d1fff89b3b68536beb931b54611585 - fixes #12074 --- .../DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp | 39 ++++++++++++++++++++-- .../DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h | 2 ++ xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp | 4 +-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp index 4028efb827..13eff26dde 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp @@ -33,6 +33,8 @@ CDVDOverlayCodecFFmpeg::CDVDOverlayCodecFFmpeg() : CDVDOverlayCodec("FFmpeg Subt m_SubtitleIndex = -1; m_width = 0; m_height = 0; + m_StartTime = 0.0; + m_StopTime = 0.0; memset(&m_Subtitle, 0, sizeof(m_Subtitle)); } @@ -60,6 +62,8 @@ bool CDVDOverlayCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &optio m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT; m_pCodecContext->sub_id = hints.identifier; m_pCodecContext->codec_tag = hints.codec_tag; + m_pCodecContext->time_base.num = 1; + m_pCodecContext->time_base.den = DVD_TIME_BASE; if( hints.extradata && hints.extrasize > 0 ) { @@ -142,6 +146,8 @@ void CDVDOverlayCodecFFmpeg::FreeSubtitle(AVSubtitle& sub) if(sub.rects) m_dllAvUtil.av_freep(&sub.rects); sub.num_rects = 0; + sub.start_display_time = 0; + sub.end_display_time = 0; } int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket) @@ -158,6 +164,15 @@ int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket) avpkt.data = pPacket->pData; avpkt.size = pPacket->iSize; + // for PGS subtitles we have to satisfy the assumptions of ffmpeg + // introduced here: + // http://git.videolan.org/?p=ffmpeg.git;a=commit;h=9dd82724315d651891f2a1ed733c4de06e9cb07a + // these are - valid packet pts + if (m_pCodecContext->codec_id == CODEC_ID_HDMV_PGS_SUBTITLE) + { + avpkt.pts = pPacket->pts; + } + len = m_dllAvCodec.avcodec_decode_subtitle2(m_pCodecContext, &m_Subtitle, &gotsub, &avpkt); if (len < 0) @@ -172,6 +187,24 @@ int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket) if (!gotsub) return OC_BUFFER; + m_StartTime = DVD_MSEC_TO_TIME(m_Subtitle.start_display_time); + m_StopTime = DVD_MSEC_TO_TIME(m_Subtitle.end_display_time); + + if (m_pCodecContext->codec_id == CODEC_ID_HDMV_PGS_SUBTITLE && m_Subtitle.format == 0) + { + // for pgs subtitles the packet pts of the end_segments are wrong + // instead use the subtitle pts to calc the offset here + // see http://git.videolan.org/?p=ffmpeg.git;a=commit;h=2939e258f9d1fff89b3b68536beb931b54611585 + if (m_Subtitle.pts != DVD_NOPTS_VALUE) + { + double pts_offset = m_Subtitle.pts - pPacket->pts; + m_StartTime = m_Subtitle.start_display_time + DVD_TIME_TO_MSEC(pts_offset); + m_StopTime = m_Subtitle.end_display_time + DVD_TIME_TO_MSEC(pts_offset); + m_StartTime = DVD_MSEC_TO_TIME(m_StartTime); + m_StopTime = DVD_MSEC_TO_TIME(m_StopTime); + } + } + m_SubtitleIndex = 0; return OC_OVERLAY; @@ -199,7 +232,7 @@ CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() { // we must add an empty overlay to replace the previous one CDVDOverlay* o = new CDVDOverlay(DVDOVERLAY_TYPE_NONE); - o->iPTSStartTime = 0; + o->iPTSStartTime = m_StartTime; o->iPTSStopTime = 0; o->replace = true; m_SubtitleIndex++; @@ -221,8 +254,8 @@ CDVDOverlay* CDVDOverlayCodecFFmpeg::GetOverlay() CDVDOverlayImage* overlay = new CDVDOverlayImage(); - overlay->iPTSStartTime = DVD_MSEC_TO_TIME(m_Subtitle.start_display_time); - overlay->iPTSStopTime = DVD_MSEC_TO_TIME(m_Subtitle.end_display_time); + overlay->iPTSStartTime = m_StartTime; + overlay->iPTSStopTime = m_StopTime; overlay->replace = true; overlay->linesize = rect.w; overlay->data = (BYTE*)malloc(rect.w * rect.h); diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h index d7611d1a0b..a267e6e638 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h @@ -45,6 +45,8 @@ private: AVCodecContext* m_pCodecContext; AVSubtitle m_Subtitle; int m_SubtitleIndex; + double m_StartTime; + double m_StopTime; int m_width; int m_height; diff --git a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp index c945e90f38..92d9e51c19 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp @@ -99,9 +99,9 @@ void CDVDPlayerSubtitle::SendMessage(CDVDMsg* pMsg) else pts = overlay->iPTSStartTime; - overlay->iPTSStartTime = pts; + overlay->iPTSStartTime += pts; if(duration) - overlay->iPTSStopTime = pts + duration; + overlay->iPTSStopTime += (pts + duration); else { overlay->iPTSStopTime = 0; -- cgit v1.2.3