aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMemphiz <memphis@machzwo.de>2012-09-22 22:00:12 +0200
committerMemphiz <memphis@machzwo.de>2012-09-30 22:19:35 +0200
commit53313e1450c19fbb671f6b5512b6e7cca9463835 (patch)
tree6375e0ca2824aca58f3d981f9dce190948353c2c
parentef191ef14a9c6d4ccd70366363e1422359ecccef (diff)
[dvdplayer/PGS-subs] - fix PGS Subtitles like ffmpeg did it in http://git.videolan.org/?p=ffmpeg.git;a=commit;h=2939e258f9d1fff89b3b68536beb931b54611585
- fixes #12074
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp39
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h2
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp4
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;