[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / cores / VideoPlayer / VideoPlayerSubtitle.cpp
blob982e95a2b617977c5bfdf05aa318d088ec07bb2e
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "VideoPlayerSubtitle.h"
11 #include "DVDCodecs/DVDFactoryCodec.h"
12 #include "DVDCodecs/Overlay/DVDOverlay.h"
13 #include "DVDCodecs/Overlay/DVDOverlayCodec.h"
14 #include "DVDCodecs/Overlay/DVDOverlaySpu.h"
15 #include "DVDSubtitles/DVDSubtitleParser.h"
16 #include "cores/VideoPlayer/Interface/DemuxPacket.h"
17 #include "cores/VideoPlayer/Interface/TimingConstants.h"
18 #include "utils/log.h"
20 #include <mutex>
22 CVideoPlayerSubtitle::CVideoPlayerSubtitle(CDVDOverlayContainer* pOverlayContainer, CProcessInfo &processInfo)
23 : IDVDStreamPlayer(processInfo)
25 m_pOverlayContainer = pOverlayContainer;
26 m_lastPts = DVD_NOPTS_VALUE;
29 CVideoPlayerSubtitle::~CVideoPlayerSubtitle()
31 CloseStream(true);
35 void CVideoPlayerSubtitle::Flush()
37 SendMessage(std::make_shared<CDVDMsg>(CDVDMsg::GENERAL_FLUSH), 0);
40 void CVideoPlayerSubtitle::SendMessage(std::shared_ptr<CDVDMsg> pMsg, int priority)
42 std::unique_lock<CCriticalSection> lock(m_section);
44 if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET))
46 auto pMsgDemuxerPacket = std::static_pointer_cast<CDVDMsgDemuxerPacket>(pMsg);
47 DemuxPacket* pPacket = pMsgDemuxerPacket->GetPacket();
49 if (m_pOverlayCodec)
51 OverlayMessage result = m_pOverlayCodec->Decode(pPacket);
53 if (result == OverlayMessage::OC_OVERLAY)
55 std::shared_ptr<CDVDOverlay> overlay;
57 while ((overlay = m_pOverlayCodec->GetOverlay()))
59 m_pOverlayContainer->ProcessAndAddOverlayIfValid(overlay);
63 else if (m_streaminfo.codec == AV_CODEC_ID_DVD_SUBTITLE)
65 std::shared_ptr<CDVDOverlaySpu> pSPUInfo =
66 m_dvdspus.AddData(pPacket->pData, pPacket->iSize, pPacket->pts);
67 if (pSPUInfo)
69 CLog::Log(LOGDEBUG, "CVideoPlayer::ProcessSubData: Got complete SPU packet");
70 m_pOverlayContainer->ProcessAndAddOverlayIfValid(pSPUInfo);
75 else if( pMsg->IsType(CDVDMsg::SUBTITLE_CLUTCHANGE) )
77 auto pData = std::static_pointer_cast<CDVDMsgSubtitleClutChange>(pMsg);
78 for (int i = 0; i < 16; i++)
80 uint8_t* color = m_dvdspus.m_clut[i];
81 uint8_t* t = (uint8_t*)pData->m_data[i];
83 // pData->m_data[i] points to an uint32_t
84 // Byte swapping is needed between big and little endian systems
85 #ifdef WORDS_BIGENDIAN
86 color[0] = t[1]; // Y
87 color[1] = t[2]; // Cr
88 color[2] = t[3]; // Cb
89 #else
90 color[0] = t[2]; // Y
91 color[1] = t[0]; // Cr
92 color[2] = t[1]; // Cb
93 #endif
95 m_dvdspus.m_bHasClut = true;
97 else if( pMsg->IsType(CDVDMsg::GENERAL_FLUSH)
98 || pMsg->IsType(CDVDMsg::GENERAL_RESET) )
100 m_dvdspus.Reset();
101 if (m_pSubtitleFileParser)
102 m_pSubtitleFileParser->Reset();
104 if (m_pOverlayCodec)
105 m_pOverlayCodec->Flush();
107 /* We must flush active overlays on flush or if we have a file
108 * parser since it will re-populate active items. */
109 if (pMsg->IsType(CDVDMsg::GENERAL_FLUSH) || m_pSubtitleFileParser)
110 m_pOverlayContainer->Flush();
112 m_lastPts = DVD_NOPTS_VALUE;
116 bool CVideoPlayerSubtitle::OpenStream(CDVDStreamInfo &hints, std::string &filename)
118 std::unique_lock<CCriticalSection> lock(m_section);
120 CloseStream(false);
121 m_streaminfo = hints;
123 // okey check if this is a filesubtitle
124 if(filename.size() && filename != "dvd" )
126 m_pSubtitleFileParser.reset(CDVDFactorySubtitle::CreateParser(filename));
127 if (!m_pSubtitleFileParser)
129 CLog::Log(LOGERROR, "{} - Unable to create subtitle parser", __FUNCTION__);
130 CloseStream(true);
131 return false;
134 CLog::Log(LOGDEBUG, "Created subtitles parser: {}", m_pSubtitleFileParser->GetName());
136 if (!m_pSubtitleFileParser->Open(hints))
138 CLog::Log(LOGERROR, "{} - Unable to init subtitle parser", __FUNCTION__);
139 CloseStream(true);
140 return false;
142 m_pSubtitleFileParser->Reset();
143 return true;
146 // dvd's use special subtitle decoder
147 if(hints.codec == AV_CODEC_ID_DVD_SUBTITLE && filename == "dvd")
148 return true;
150 m_pOverlayCodec = CDVDFactoryCodec::CreateOverlayCodec(hints);
151 if (m_pOverlayCodec)
153 CLog::Log(LOGDEBUG, "Created subtitles overlay codec: {}", m_pOverlayCodec->GetName());
154 return true;
157 CLog::Log(LOGERROR, "{} - Unable to init overlay codec", __FUNCTION__);
158 return false;
161 void CVideoPlayerSubtitle::CloseStream(bool bWaitForBuffers)
163 std::unique_lock<CCriticalSection> lock(m_section);
165 m_pSubtitleFileParser.reset();
166 m_pOverlayCodec.reset();
168 m_dvdspus.FlushCurrentPacket();
170 if (!bWaitForBuffers)
171 m_pOverlayContainer->Clear();
174 void CVideoPlayerSubtitle::Process(double pts, double offset)
176 std::unique_lock<CCriticalSection> lock(m_section);
178 if (m_pSubtitleFileParser)
180 if(pts == DVD_NOPTS_VALUE)
181 return;
183 if (pts + DVD_SEC_TO_TIME(1) < m_lastPts)
185 m_pOverlayContainer->Clear();
186 m_pSubtitleFileParser->Reset();
189 if(m_pOverlayContainer->GetSize() >= 5)
190 return;
192 std::shared_ptr<CDVDOverlay> pOverlay = m_pSubtitleFileParser->Parse(pts);
193 // add all overlays which fit the pts
194 while(pOverlay)
196 pOverlay->iPTSStartTime -= offset;
197 if(pOverlay->iPTSStopTime != 0.0)
198 pOverlay->iPTSStopTime -= offset;
200 m_pOverlayContainer->ProcessAndAddOverlayIfValid(pOverlay);
201 pOverlay = m_pSubtitleFileParser->Parse(pts);
204 m_lastPts = pts;
208 bool CVideoPlayerSubtitle::AcceptsData() const
210 // FIXME : This may still be causing problems + magic number :(
211 return m_pOverlayContainer->GetSize() < 5;