Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1458 from Memphiz/pgs

Fix for embedded PGS Subtitles
  • Loading branch information...
commit 0364761dcc5881ee7541a710cfd26bc1d32d6d42 2 parents acdd442 + 6070da3
@Memphiz Memphiz authored
Showing with 241 additions and 57 deletions.
  1. +4 −0 XBMC-ATV2.xcodeproj/project.pbxproj
  2. +4 −0 XBMC-IOS.xcodeproj/project.pbxproj
  3. +4 −0 XBMC.xcodeproj/project.pbxproj
  4. +8 −0 lib/ffmpeg/libavcodec/pgssubdec.c
  5. +3 −0  lib/ffmpeg/libavcodec/utils.c
  6. +64 −0 lib/ffmpeg/patches/0032-PGS-use-the-PTS-from-the-presentation-segment.patch
  7. +2 −1  project/VS2010Express/XBMC.vcxproj
  8. +4 −1 project/VS2010Express/XBMC.vcxproj.filters
  9. +54 −0 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodec.cpp
  10. +11 −1 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodec.h
  11. +7 −1 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecCC.cpp
  12. +1 −1  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecCC.h
  13. +35 −8 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.cpp
  14. +3 −1 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h
  15. +9 −1 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp
  16. +1 −1  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.h
  17. +6 −3 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecTX3G.cpp
  18. +1 −1  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecTX3G.h
  19. +9 −4 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.cpp
  20. +1 −1  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h
  21. +2 −1  xbmc/cores/dvdplayer/DVDCodecs/Overlay/Makefile.in
  22. +2 −30 xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp
  23. +6 −1 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
View
4 XBMC-ATV2.xcodeproj/project.pbxproj
@@ -141,6 +141,7 @@
DF93D8331444B88B007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D82F1444B88B007C6459 /* HDHomeRunDirectory.cpp */; };
DF93D8341444B88B007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D8311444B88B007C6459 /* HDHomeRunFile.cpp */; };
DF98D9A81434F4B400A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D9A61434F4B400A6EBE1 /* SkinVariable.cpp */; };
+ DFA0F9551618E1CD00611CBB /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA0F9541618E1CD00611CBB /* DVDOverlayCodec.cpp */; };
DFA6BE8713FED2A10048CC11 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE8513FED2A10048CC11 /* AirPlayServer.cpp */; };
DFA6BE8A13FED2B40048CC11 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE8813FED2B40048CC11 /* HttpParser.cpp */; };
DFAB04C113F8385F00B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB04BF13F8385F00B70BFB /* InertialScrollingHandler.cpp */; };
@@ -1332,6 +1333,7 @@
DF93D8321444B88B007C6459 /* HDHomeRunFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunFile.h; sourceTree = "<group>"; };
DF98D9A61434F4B400A6EBE1 /* SkinVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkinVariable.cpp; sourceTree = "<group>"; };
DF98D9A71434F4B400A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; };
+ DFA0F9541618E1CD00611CBB /* DVDOverlayCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodec.cpp; sourceTree = "<group>"; };
DFA6BE8513FED2A10048CC11 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; };
DFA6BE8613FED2A10048CC11 /* AirPlayServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirPlayServer.h; sourceTree = "<group>"; };
DFA6BE8813FED2B40048CC11 /* HttpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpParser.cpp; sourceTree = "<group>"; };
@@ -4303,6 +4305,7 @@
children = (
F56C727C131EC151000AD0F6 /* libspucc */,
F56C7271131EC151000AD0F6 /* DVDOverlay.h */,
+ DFA0F9541618E1CD00611CBB /* DVDOverlayCodec.cpp */,
F56C7272131EC151000AD0F6 /* DVDOverlayCodec.h */,
F56C7273131EC151000AD0F6 /* DVDOverlayCodecCC.cpp */,
F56C7274131EC151000AD0F6 /* DVDOverlayCodecCC.h */,
@@ -7580,6 +7583,7 @@
DFAB4C1015FCCB4300E1BAF6 /* TagLoaderTagLib.cpp in Sources */,
DFC0F8F51613A1960066D598 /* XLCDproc.cpp in Sources */,
DFC0F91C1613A3A00066D598 /* LCDFactory.cpp in Sources */,
+ DFA0F9551618E1CD00611CBB /* DVDOverlayCodec.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
4 XBMC-IOS.xcodeproj/project.pbxproj
@@ -142,6 +142,7 @@
DF93D81E1444B86B007C6459 /* HDHomeRunDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D81A1444B86B007C6459 /* HDHomeRunDirectory.cpp */; };
DF93D81F1444B86B007C6459 /* HDHomeRunFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF93D81C1444B86B007C6459 /* HDHomeRunFile.cpp */; };
DF98D9991434F49500A6EBE1 /* SkinVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF98D9971434F49500A6EBE1 /* SkinVariable.cpp */; };
+ DFA0F9291618E18A00611CBB /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA0F9281618E18A00611CBB /* DVDOverlayCodec.cpp */; };
DFA6BE4313FECA010048CC11 /* AirPlayServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE4113FECA010048CC11 /* AirPlayServer.cpp */; };
DFA6BE7713FED09C0048CC11 /* HttpParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFA6BE7513FED09C0048CC11 /* HttpParser.cpp */; };
DFAB04B013F8383300B70BFB /* InertialScrollingHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFAB04AE13F8383300B70BFB /* InertialScrollingHandler.cpp */; };
@@ -1337,6 +1338,7 @@
DF93D81D1444B86B007C6459 /* HDHomeRunFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDHomeRunFile.h; sourceTree = "<group>"; };
DF98D9971434F49500A6EBE1 /* SkinVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkinVariable.cpp; sourceTree = "<group>"; };
DF98D9981434F49500A6EBE1 /* SkinVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkinVariable.h; sourceTree = "<group>"; };
+ DFA0F9281618E18A00611CBB /* DVDOverlayCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodec.cpp; sourceTree = "<group>"; };
DFA6BE4113FECA010048CC11 /* AirPlayServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirPlayServer.cpp; sourceTree = "<group>"; };
DFA6BE4213FECA010048CC11 /* AirPlayServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirPlayServer.h; sourceTree = "<group>"; };
DFA6BE7513FED09C0048CC11 /* HttpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpParser.cpp; sourceTree = "<group>"; };
@@ -4652,6 +4654,7 @@
children = (
F56C8260131F42E7000AD0F6 /* libspucc */,
F56C8255131F42E6000AD0F6 /* DVDOverlay.h */,
+ DFA0F9281618E18A00611CBB /* DVDOverlayCodec.cpp */,
F56C8256131F42E6000AD0F6 /* DVDOverlayCodec.h */,
F56C8257131F42E6000AD0F6 /* DVDOverlayCodecCC.cpp */,
F56C8258131F42E6000AD0F6 /* DVDOverlayCodecCC.h */,
@@ -7615,6 +7618,7 @@
DFAB4BE715FCCA5000E1BAF6 /* TagLoaderTagLib.cpp in Sources */,
DFC0F8E71613A16F0066D598 /* XLCDproc.cpp in Sources */,
DFC0F90F1613A3810066D598 /* LCDFactory.cpp in Sources */,
+ DFA0F9291618E18A00611CBB /* DVDOverlayCodec.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
4 XBMC.xcodeproj/project.pbxproj
@@ -449,6 +449,7 @@
DFCA6AC9152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6ABF152245CD000BFAAE /* HTTPWebinterfaceAddonsHandler.cpp */; };
DFCA6ACA152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC1152245CD000BFAAE /* HTTPWebinterfaceHandler.cpp */; };
DFCA6ACB152245CD000BFAAE /* IHTTPRequestHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */; };
+ DFDA3153160E34230047A626 /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */; };
E306D12E0DDF7B590052C2AD /* XBMCHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */; };
E33206380D5070AA00435CE3 /* DVDDemuxVobsub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */; };
E33466A60D2E5103005A65EC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E33466A50D2E5103005A65EC /* IOKit.framework */; };
@@ -2010,6 +2011,7 @@
DFCA6AC2152245CD000BFAAE /* HTTPWebinterfaceHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPWebinterfaceHandler.h; sourceTree = "<group>"; };
DFCA6AC3152245CD000BFAAE /* IHTTPRequestHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IHTTPRequestHandler.cpp; sourceTree = "<group>"; };
DFCA6AC4152245CD000BFAAE /* IHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IHTTPRequestHandler.h; sourceTree = "<group>"; };
+ DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodec.cpp; sourceTree = "<group>"; };
E306D12C0DDF7B590052C2AD /* XBMCHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XBMCHelper.cpp; sourceTree = "<group>"; };
E306D12D0DDF7B590052C2AD /* XBMCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XBMCHelper.h; sourceTree = "<group>"; };
E33206370D5070AA00435CE3 /* DVDDemuxVobsub.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDDemuxVobsub.cpp; sourceTree = "<group>"; };
@@ -4979,6 +4981,7 @@
children = (
E38E15340D25F9F900618676 /* libspucc */,
E38E15290D25F9F900618676 /* DVDOverlay.h */,
+ DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */,
E38E152A0D25F9F900618676 /* DVDOverlayCodec.h */,
E38E152B0D25F9F900618676 /* DVDOverlayCodecCC.cpp */,
E38E152C0D25F9F900618676 /* DVDOverlayCodecCC.h */,
@@ -7648,6 +7651,7 @@
AEC0083115ACAC6E0099888C /* TagLoaderTagLib.cpp in Sources */,
DFC0F8CB16139DF10066D598 /* XLCDproc.cpp in Sources */,
DFC0F9021613A35E0066D598 /* LCDFactory.cpp in Sources */,
+ DFDA3153160E34230047A626 /* DVDOverlayCodec.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
8 lib/ffmpeg/libavcodec/pgssubdec.c
@@ -64,6 +64,7 @@ typedef struct PGSSubContext {
PGSSubPresentation presentation;
uint32_t clut[256];
PGSSubPicture pictures[UINT16_MAX];
+ int64_t pts;
} PGSSubContext;
static av_cold int init_decoder(AVCodecContext *avctx)
@@ -377,6 +378,7 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
{
AVSubtitle *sub = data;
PGSSubContext *ctx = avctx->priv_data;
+ int64_t pts;
uint16_t rect;
@@ -386,7 +388,10 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
* not been cleared by a subsequent empty display command.
*/
+ pts = ctx->pts != AV_NOPTS_VALUE ? ctx->pts : sub->pts;
memset(sub, 0, sizeof(*sub));
+ sub->pts = pts;
+ ctx->pts = AV_NOPTS_VALUE;
// Blank if last object_count was 0.
if (!ctx->presentation.object_count)
@@ -431,8 +436,10 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
static int decode(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
{
+ PGSSubContext *ctx = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
+ AVSubtitle *sub = data;
const uint8_t *buf_end;
uint8_t segment_type;
@@ -477,6 +484,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
break;
case PRESENTATION_SEGMENT:
parse_presentation_segment(avctx, buf, segment_length);
+ ctx->pts = sub->pts;
break;
case WINDOW_SEGMENT:
/*
View
3  lib/ffmpeg/libavcodec/utils.c
@@ -1396,6 +1396,9 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
avctx->pkt = avpkt;
*got_sub_ptr = 0;
avcodec_get_subtitle_defaults(sub);
+ if (avctx->time_base.den && avpkt->pts != AV_NOPTS_VALUE)
+ sub->pts = av_rescale_q(avpkt->pts,
+ avctx->time_base, AV_TIME_BASE_Q);
ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
if (*got_sub_ptr)
avctx->frame_number++;
View
64 lib/ffmpeg/patches/0032-PGS-use-the-PTS-from-the-presentation-segment.patch
@@ -0,0 +1,64 @@
+diff --git a/lib/ffmpeg/libavcodec/pgssubdec.c b/lib/ffmpeg/libavcodec/pgssubdec.c
+index 2785d25..02e650a 100644
+--- a/lib/ffmpeg/libavcodec/pgssubdec.c
++++ b/lib/ffmpeg/libavcodec/pgssubdec.c
+@@ -64,6 +64,7 @@ typedef struct PGSSubContext {
+ PGSSubPresentation presentation;
+ uint32_t clut[256];
+ PGSSubPicture pictures[UINT16_MAX];
++ int64_t pts;
+ } PGSSubContext;
+
+ static av_cold int init_decoder(AVCodecContext *avctx)
+@@ -377,6 +378,7 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
+ {
+ AVSubtitle *sub = data;
+ PGSSubContext *ctx = avctx->priv_data;
++ int64_t pts;
+
+ uint16_t rect;
+
+@@ -386,7 +388,10 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
+ * not been cleared by a subsequent empty display command.
+ */
+
++ pts = ctx->pts != AV_NOPTS_VALUE ? ctx->pts : sub->pts;
+ memset(sub, 0, sizeof(*sub));
++ sub->pts = pts;
++ ctx->pts = AV_NOPTS_VALUE;
+
+ // Blank if last object_count was 0.
+ if (!ctx->presentation.object_count)
+@@ -431,8 +436,10 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
+ static int decode(AVCodecContext *avctx, void *data, int *data_size,
+ AVPacket *avpkt)
+ {
++ PGSSubContext *ctx = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
++ AVSubtitle *sub = data;
+
+ const uint8_t *buf_end;
+ uint8_t segment_type;
+@@ -477,6 +484,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
+ break;
+ case PRESENTATION_SEGMENT:
+ parse_presentation_segment(avctx, buf, segment_length);
++ ctx->pts = sub->pts;
+ break;
+ case WINDOW_SEGMENT:
+ /*
+diff --git a/lib/ffmpeg/libavcodec/utils.c b/lib/ffmpeg/libavcodec/utils.c
+index 99bf27c..c1cde2c 100644
+--- a/lib/ffmpeg/libavcodec/utils.c
++++ b/lib/ffmpeg/libavcodec/utils.c
+@@ -1396,6 +1396,9 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+ avctx->pkt = avpkt;
+ *got_sub_ptr = 0;
+ avcodec_get_subtitle_defaults(sub);
++ if (avctx->time_base.den && avpkt->pts != AV_NOPTS_VALUE)
++ sub->pts = av_rescale_q(avpkt->pts,
++ avctx->time_base, AV_TIME_BASE_Q);
+ ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
+ if (*got_sub_ptr)
+ avctx->frame_number++;
View
3  project/VS2010Express/XBMC.vcxproj
@@ -1661,6 +1661,7 @@
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoCodecLibMpeg2.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DVDVideoPPFFmpeg.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.cpp" />
+ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodec.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecCC.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecFFmpeg.cpp" />
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecSSA.cpp" />
@@ -2918,4 +2919,4 @@
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\$(ProjectFileName).targets.user" Condition="Exists('$(SolutionDir)\$(ProjectFileName).targets.user')" />
-</Project>
+</Project>
View
5 project/VS2010Express/XBMC.vcxproj.filters
@@ -402,6 +402,9 @@
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Video\DXVA.cpp">
<Filter>cores\dvdplayer\DVDCodecs\Video</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodec.cpp">
+ <Filter>cores\dvdplayer\DVDCodecs\Overlay</Filter>
+ </ClCompile>
<ClCompile Include="..\..\xbmc\cores\dvdplayer\DVDCodecs\Overlay\DVDOverlayCodecCC.cpp">
<Filter>cores\dvdplayer\DVDCodecs\Overlay</Filter>
</ClCompile>
@@ -5768,4 +5771,4 @@
<Filter>interfaces\swig</Filter>
</None>
</ItemGroup>
-</Project>
+</Project>
View
54 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodec.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "DVDOverlayCodec.h"
+#include "cores/dvdplayer/DVDClock.h"
+
+void CDVDOverlayCodec::GetAbsoluteTimes(double &starttime, double &stoptime, DemuxPacket *pkt, bool &replace, double offset/* = 0.0*/)
+{
+ if (!pkt)
+ return;
+
+ double duration = 0.0;
+ double pts = starttime;
+
+ // we assume pts from packet is better than what
+ // decoder gives us, only take duration
+ // from decoder if available
+ if(stoptime > starttime)
+ duration = stoptime - starttime;
+ else if(pkt->duration != DVD_NOPTS_VALUE)
+ duration = pkt->duration;
+
+ if (pkt->pts != DVD_NOPTS_VALUE)
+ pts = pkt->pts;
+ else if(pkt->dts != DVD_NOPTS_VALUE)
+ pts = pkt->dts;
+
+ starttime = pts + offset;
+ if(duration)
+ {
+ stoptime = pts + duration + offset;
+ }
+ else
+ {
+ stoptime = 0;
+ replace = true;
+ }
+}
View
12 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodec.h
@@ -22,6 +22,7 @@
#include "DVDOverlay.h"
#include "PlatformDefs.h"
+#include "cores/dvdplayer/DVDDemuxers/DVDDemux.h"
#include <string>
@@ -59,7 +60,7 @@ class CDVDOverlayCodec
* returns one or a combination of VC_ messages
* pData and iSize can be NULL, this means we should flush the rest of the data.
*/
- virtual int Decode(BYTE* data, int size, double pts, double duration) = 0;
+ virtual int Decode(DemuxPacket *pPacket) = 0;
/*
* Reset the decoder.
@@ -83,6 +84,15 @@ class CDVDOverlayCodec
* return codecs name
*/
virtual const char* GetName() { return m_codecName.c_str(); }
+
+protected:
+ /*
+ * Adapts startTime, stopTIme from the subtitle stream (which is relative to stream pts)
+ * so that it returns the absolute start and stop timestamps.
+ * replace - will be set to true if the overlay should replace the former overlay
+ * offset - optional - offset will be added to start and stoptime
+ */
+ static void GetAbsoluteTimes(double &starttime, double &stoptime, DemuxPacket *pkt, bool &replace, double offset = 0.0);
private:
std::string m_codecName;
View
8 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecCC.cpp
@@ -55,8 +55,14 @@ int CDVDOverlayCodecCC::DecodeFieldData(BYTE* pData, int iSize)
}
*/
-int CDVDOverlayCodecCC::Decode(BYTE* pData, int iSize, double pts, double duration)
+int CDVDOverlayCodecCC::Decode(DemuxPacket *pPacket)
{
+ if (!pPacket)
+ return OC_ERROR;
+
+ BYTE *pData = pPacket->pData;
+ int iSize = pPacket->iSize;
+
// minimum amount of data is even more for cc
decode_cc(m_cc_decoder, pData, iSize);
View
2  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecCC.h
@@ -31,7 +31,7 @@ class CDVDOverlayCodecCC : public CDVDOverlayCodec
virtual ~CDVDOverlayCodecCC();
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose();
- virtual int Decode(BYTE* pData, int iSize, double pts, double duration);
+ virtual int Decode(DemuxPacket *pPacket);
virtual void Reset();
virtual void Flush();
virtual CDVDOverlay* GetOverlay();
View
43 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,11 +146,13 @@ 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(BYTE* data, int size, double pts, double duration)
+int CDVDOverlayCodecFFmpeg::Decode(DemuxPacket *pPacket)
{
- if (!m_pCodecContext)
+ if (!m_pCodecContext || !pPacket)
return 1;
int gotsub = 0, len = 0;
@@ -155,8 +161,10 @@ int CDVDOverlayCodecFFmpeg::Decode(BYTE* data, int size, double pts, double dura
AVPacket avpkt;
m_dllAvCodec.av_init_packet(&avpkt);
- avpkt.data = data;
- avpkt.size = size;
+ avpkt.data = pPacket->pData;
+ avpkt.size = pPacket->iSize;
+ avpkt.pts = pPacket->pts == DVD_NOPTS_VALUE ? AV_NOPTS_VALUE : (int64_t)pPacket->pts;
+ avpkt.dts = pPacket->dts == DVD_NOPTS_VALUE ? AV_NOPTS_VALUE : (int64_t)pPacket->dts;
len = m_dllAvCodec.avcodec_decode_subtitle2(m_pCodecContext, &m_Subtitle, &gotsub, &avpkt);
@@ -166,12 +174,31 @@ int CDVDOverlayCodecFFmpeg::Decode(BYTE* data, int size, double pts, double dura
return OC_ERROR;
}
- if (len != size)
+ if (len != avpkt.size)
CLog::Log(LOGWARNING, "%s - avcodec_decode_subtitle didn't consume the full packet", __FUNCTION__);
if (!gotsub)
return OC_BUFFER;
+ double pts_offset = 0.0;
+
+ 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)
+ {
+ pts_offset = m_Subtitle.pts - pPacket->pts ;
+ }
+ }
+
+ m_StartTime = DVD_MSEC_TO_TIME(m_Subtitle.start_display_time);
+ m_StopTime = DVD_MSEC_TO_TIME(m_Subtitle.end_display_time);
+
+ //adapt start and stop time to our packet pts
+ bool dummy = false;
+ CDVDOverlayCodec::GetAbsoluteTimes(m_StartTime, m_StopTime, pPacket, dummy, pts_offset);
m_SubtitleIndex = 0;
return OC_OVERLAY;
@@ -199,7 +226,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 +248,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);
View
4 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecFFmpeg.h
@@ -34,7 +34,7 @@ class CDVDOverlayCodecFFmpeg : public CDVDOverlayCodec
virtual ~CDVDOverlayCodecFFmpeg();
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose();
- virtual int Decode(BYTE* data, int size, double pts, double duration);
+ virtual int Decode(DemuxPacket *pPacket);
virtual void Reset();
virtual void Flush();
virtual CDVDOverlay* GetOverlay();
@@ -45,6 +45,8 @@ class CDVDOverlayCodecFFmpeg : public CDVDOverlayCodec
AVCodecContext* m_pCodecContext;
AVSubtitle m_Subtitle;
int m_SubtitleIndex;
+ double m_StartTime;
+ double m_StopTime;
int m_width;
int m_height;
View
10 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.cpp
@@ -62,10 +62,18 @@ void CDVDOverlayCodecSSA::Dispose()
SAFE_RELEASE(m_pOverlay);
}
-int CDVDOverlayCodecSSA::Decode(BYTE* data, int size, double pts, double duration)
+int CDVDOverlayCodecSSA::Decode(DemuxPacket *pPacket)
{
if(m_pOverlay)
SAFE_RELEASE(m_pOverlay);
+
+ if(!pPacket)
+ return OC_ERROR;
+
+ double pts = pPacket->dts != DVD_NOPTS_VALUE ? pPacket->dts : pPacket->pts;
+ BYTE *data = pPacket->pData;
+ int size = pPacket->iSize;
+ double duration = pPacket->duration;
if(strncmp((const char*)data, "Dialogue:", 9) == 0)
{
View
2  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecSSA.h
@@ -33,7 +33,7 @@ class CDVDOverlayCodecSSA : public CDVDOverlayCodec
virtual ~CDVDOverlayCodecSSA();
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose();
- virtual int Decode(BYTE* data, int size, double pts, double duration);
+ virtual int Decode(DemuxPacket *pPacket);
virtual void Reset();
virtual void Flush();
virtual CDVDOverlay* GetOverlay();
View
9 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecTX3G.cpp
@@ -19,6 +19,7 @@
*/
#include "system.h"
+#include "DVDClock.h"
#include "DVDOverlayCodecTX3G.h"
#include "DVDOverlayText.h"
#include "DVDStreamInfo.h"
@@ -85,14 +86,16 @@ void CDVDOverlayCodecTX3G::Dispose()
SAFE_RELEASE(m_pOverlay);
}
-int CDVDOverlayCodecTX3G::Decode(BYTE* data, int size, double pts, double duration)
+int CDVDOverlayCodecTX3G::Decode(DemuxPacket *pPacket)
{
if (m_pOverlay)
SAFE_RELEASE(m_pOverlay);
+ BYTE *data = pPacket->pData;
+ int size = pPacket->iSize;
+
m_pOverlay = new CDVDOverlayText();
- m_pOverlay->iPTSStartTime = pts;
- m_pOverlay->iPTSStopTime = pts + duration;
+ CDVDOverlayCodec::GetAbsoluteTimes(m_pOverlay->iPTSStartTime, m_pOverlay->iPTSStopTime, pPacket, m_pOverlay->replace);
// do not move this. READ_XXXX macros modify pos.
uint8_t *pos = data;
View
2  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecTX3G.h
@@ -31,7 +31,7 @@ class CDVDOverlayCodecTX3G : public CDVDOverlayCodec
virtual ~CDVDOverlayCodecTX3G();
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose();
- virtual int Decode(BYTE* data, int size, double pts, double duration);
+ virtual int Decode(DemuxPacket *pPacket);
virtual void Reset();
virtual void Flush();
virtual CDVDOverlay* GetOverlay();
View
13 xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.cpp
@@ -19,6 +19,7 @@
*/
#include "system.h"
+#include "DVDClock.h"
#include "DVDOverlayCodecText.h"
#include "DVDOverlayText.h"
#include "DVDStreamInfo.h"
@@ -52,15 +53,19 @@ void CDVDOverlayCodecText::Dispose()
SAFE_RELEASE(m_pOverlay);
}
-int CDVDOverlayCodecText::Decode(BYTE* data, int size, double pts, double duration)
+int CDVDOverlayCodecText::Decode(DemuxPacket *pPacket)
{
if(m_pOverlay)
SAFE_RELEASE(m_pOverlay);
+ if(!pPacket)
+ return OC_ERROR;
+
+ BYTE *data = pPacket->pData;
+ int size = pPacket->iSize;
+
m_pOverlay = new CDVDOverlayText();
- m_pOverlay->iPTSStartTime = 0;
- m_pOverlay->iPTSStopTime = 0;
-
+ CDVDOverlayCodec::GetAbsoluteTimes(m_pOverlay->iPTSStartTime, m_pOverlay->iPTSStopTime, pPacket, m_pOverlay->replace);
char *start, *end, *p;
start = (char*)data;
View
2  xbmc/cores/dvdplayer/DVDCodecs/Overlay/DVDOverlayCodecText.h
@@ -31,7 +31,7 @@ class CDVDOverlayCodecText : public CDVDOverlayCodec
virtual ~CDVDOverlayCodecText();
virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options);
virtual void Dispose();
- virtual int Decode(BYTE* data, int size, double pts, double duration);
+ virtual int Decode(DemuxPacket *pPacket);
virtual void Reset();
virtual void Flush();
virtual CDVDOverlay* GetOverlay();
View
3  xbmc/cores/dvdplayer/DVDCodecs/Overlay/Makefile.in
@@ -1,6 +1,7 @@
INCLUDES+=-I@abs_top_srcdir@/xbmc/cores/dvdplayer
-SRCS = DVDOverlayCodecCC.cpp
+SRCS = DVDOverlayCodec.cpp
+SRCS += DVDOverlayCodecCC.cpp
SRCS += DVDOverlayCodecFFmpeg.cpp
SRCS += DVDOverlayCodecSSA.cpp
SRCS += DVDOverlayCodecText.cpp
View
32 xbmc/cores/dvdplayer/DVDPlayerSubtitle.cpp
@@ -70,43 +70,15 @@ void CDVDPlayerSubtitle::SendMessage(CDVDMsg* pMsg)
if (m_pOverlayCodec)
{
- double pts = pPacket->dts != DVD_NOPTS_VALUE ? pPacket->dts : pPacket->pts;
- double duration = pPacket->duration;
- int result = m_pOverlayCodec->Decode(pPacket->pData, pPacket->iSize, pts, duration);
+ int result = m_pOverlayCodec->Decode(pPacket);
if(result == OC_OVERLAY)
{
CDVDOverlay* overlay;
+
while((overlay = m_pOverlayCodec->GetOverlay()) != NULL)
{
overlay->iGroupId = pPacket->iGroupId;
-
- // we assume pts is better than what
- // decoder gives us, only take duration
- // from decoder if available
- if(overlay->iPTSStopTime > overlay->iPTSStartTime)
- duration = overlay->iPTSStopTime - overlay->iPTSStartTime;
- else if(pPacket->duration != DVD_NOPTS_VALUE)
- duration = pPacket->duration;
- else
- duration = 0.0;
-
- if (pPacket->pts != DVD_NOPTS_VALUE)
- pts = pPacket->pts;
- else if(pPacket->dts != DVD_NOPTS_VALUE)
- pts = pPacket->dts;
- else
- pts = overlay->iPTSStartTime;
-
- overlay->iPTSStartTime = pts;
- if(duration)
- overlay->iPTSStopTime = pts + duration;
- else
- {
- overlay->iPTSStopTime = 0;
- overlay->replace = true;
- }
-
m_pOverlayContainer->Add(overlay);
overlay->Release();
}
View
7 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -805,7 +805,12 @@ void CDVDPlayerVideo::ProcessVideoUserData(DVDVideoUserData* pVideoUserData, dou
if (m_pOverlayCodecCC)
{
- m_pOverlayCodecCC->Decode(data, size, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
+ DemuxPacket packet;
+ packet.pData = data;
+ packet.iSize = size;
+ packet.pts = DVD_NOPTS_VALUE;
+ packet.dts = DVD_NOPTS_VALUE;
+ m_pOverlayCodecCC->Decode(&packet);
CDVDOverlay* overlay;
while((overlay = m_pOverlayCodecCC->GetOverlay()) != NULL)
Please sign in to comment.
Something went wrong with that request. Please try again.