PDF::PDF(InputStream *pSource) { char str[40]; int i, j, n, nOffset; bool bFound; Trailer *pTrailer; const Object *pObj; m_pSource = new DataInputStream(pSource); *str = m_pSource->Read(); m_pSource->ReadStr(str + 1, sizeof(str) - 1); if (strncmp(str, "%PDF-", 5) != 0) { m_pVersion[0] = '\0'; delete m_pSource; m_pSource = NULL; return; } strcpy(m_pVersion, (const char *)str + 5); n = strlen("startxref"); bFound = false; m_pSource->Seek(-(int)sizeof(str), SEEK_END); for (i = 30; i > 0; --i) { m_pSource->Read(str, sizeof(str)); for (j = 0; j < sizeof(str) - n; ++j) if (strncmp(str + j, "startxref", n) == 0) { bFound = true; m_pSource->Seek(j - sizeof(str), SEEK_CUR); m_pSource->ReadStr(str, sizeof(str)); // startxref nOffset = m_pSource->ReadInt(); // offset of xref break; } if (bFound) break; m_pSource->Seek(n - sizeof(str) * 2, SEEK_CUR); } if (!bFound) // startxref is not found { m_pVersion[0] = '\0'; delete m_pSource; m_pSource = NULL; return; } m_pXref = new Xref(); m_pReader = new ObjReader(m_pSource, m_pXref); m_pTrailer = NULL; do { pTrailer = new Trailer; m_pSource->Seek(nOffset, SEEK_SET); m_pSource->ReadStr(str, sizeof(str)); if (strcmp(str, "xref") == 0) { m_pXref->Read(m_pSource); m_pSource->ReadStr(str, sizeof(str)); //trailer pTrailer->pStream = NULL; pTrailer->pDict = (const Dictionary *)m_pReader->ReadObj(); } else { m_pSource->ReadInt(); m_pSource->ReadStr(str, sizeof(str)); //obj pTrailer->pStream = (const Stream *)m_pReader->ReadObj(); //stream pTrailer->pDict = pTrailer->pStream->GetDictionary(); pSource = CreateInputStream(pTrailer->pStream); m_pXref->Read(pSource); delete pSource; } pTrailer->pPrev = NULL; if (m_pTrailer == NULL) m_pTrailer = pTrailer; else m_pTail->pPrev = pTrailer; m_pTail = pTrailer; pObj = pTrailer->pDict->GetValue("Prev"); if (pObj != NULL) nOffset = ((const Numeric *)pObj)->GetValue(); } while (pObj != NULL); m_nPageNum = 0; for (pTrailer = m_pTrailer; pTrailer != NULL; pTrailer = pTrailer->pPrev) { pObj = GetObject(pTrailer->pDict->GetValue("Root")); if (pObj != NULL) { m_pPages = (const Dictionary *)GetObject(((Dictionary *)pObj)->GetValue("Pages")); m_nPageNum = ((const Numeric *)GetObject(m_pPages->GetValue("Count")))->GetValue(); break; } } }
CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio) { std::string file = fileitem.GetPath(); if (scanforextaudio) { // find any available external audio tracks std::vector<std::string> filenames; filenames.push_back(file); CUtil::ScanForExternalAudio(file, filenames); CUtil::ScanForExternalDemuxSub(file, filenames); if (filenames.size() >= 2) { return CreateInputStream(pPlayer, fileitem, filenames); } } ADDON::VECADDONS addons; ADDON::CBinaryAddonCache &addonCache = CServiceBroker::GetBinaryAddonCache(); addonCache.GetAddons(addons, ADDON::ADDON_INPUTSTREAM); for (size_t i=0; i<addons.size(); ++i) { std::shared_ptr<ADDON::CInputStream> input(std::static_pointer_cast<ADDON::CInputStream>(addons[i])); if (input->Supports(fileitem)) { std::shared_ptr<ADDON::CInputStream> addon = input; if (!input->UseParent()) addon = std::shared_ptr<ADDON::CInputStream>(new ADDON::CInputStream(*input)); ADDON_STATUS status = addon->Create(); if (status == ADDON_STATUS_OK) { unsigned int videoWidth, videoHeight; pPlayer->GetVideoResolution(videoWidth, videoHeight); addon->SetVideoResolution(videoWidth, videoHeight); return new CInputStreamAddon(fileitem, addon); } } } if (fileitem.IsDiscImage()) { #ifdef HAVE_LIBBLURAY CURL url("udf://"); url.SetHostName(file); url.SetFileName("BDMV/index.bdmv"); if(XFILE::CFile::Exists(url.Get())) return new CDVDInputStreamBluray(pPlayer, fileitem); #endif return new CDVDInputStreamNavigator(pPlayer, fileitem); } #ifdef HAS_DVD_DRIVE if(file.compare(g_mediaManager.TranslateDevicePath("")) == 0) { #ifdef HAVE_LIBBLURAY if(XFILE::CFile::Exists(URIUtils::AddFileToFolder(file, "BDMV/index.bdmv"))) return new CDVDInputStreamBluray(pPlayer, fileitem); #endif return new CDVDInputStreamNavigator(pPlayer, fileitem); } #endif if (fileitem.IsDVDFile(false, true)) return (new CDVDInputStreamNavigator(pPlayer, fileitem)); else if(file.substr(0, 6) == "pvr://") return new CDVDInputStreamPVRManager(pPlayer, fileitem); #ifdef HAVE_LIBBLURAY else if (fileitem.IsType(".bdmv") || fileitem.IsType(".mpls") || file.substr(0, 7) == "bluray:") return new CDVDInputStreamBluray(pPlayer, fileitem); #endif else if(file.substr(0, 6) == "rtp://" || file.substr(0, 7) == "rtsp://" || file.substr(0, 6) == "sdp://" || file.substr(0, 6) == "udp://" || file.substr(0, 6) == "tcp://" || file.substr(0, 6) == "mms://" || file.substr(0, 7) == "mmst://" || file.substr(0, 7) == "mmsh://") return new CDVDInputStreamFFmpeg(fileitem); #ifdef ENABLE_DVDINPUTSTREAM_STACK else if(file.substr(0, 8) == "stack://") return new CDVDInputStreamStack(fileitem); #endif else if (fileitem.IsInternetStream()) { if (fileitem.IsType(".m3u8")) return new CDVDInputStreamFFmpeg(fileitem); if (fileitem.GetMimeType() == "application/vnd.apple.mpegurl") return new CDVDInputStreamFFmpeg(fileitem); } // our file interface handles all these types of streams return (new CDVDInputStreamFile(fileitem)); }
CDVDInputStream* CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, CFileItem fileitem, bool scanforextaudio) { std::string file = fileitem.GetPath(); if (scanforextaudio) { // find any available external audio tracks std::vector<std::string> filenames; filenames.push_back(file); CUtil::ScanForExternalAudio(file, filenames); if (filenames.size() >= 2) { return CreateInputStream(pPlayer, fileitem, filenames); } } ADDON::VECADDONS addons; g_application.m_binaryAddonCache.GetAddons(addons, ADDON::ADDON_INPUTSTREAM); for (size_t i=0; i<addons.size(); ++i) { std::shared_ptr<ADDON::CInputStream> input(std::static_pointer_cast<ADDON::CInputStream>(addons[i])); ADDON::CInputStream* clone = new ADDON::CInputStream(*input); ADDON_STATUS status = clone->Supports(fileitem) ? clone->Create() : ADDON_STATUS_PERMANENT_FAILURE; if (status == ADDON_STATUS_OK) { if (clone->Supports(fileitem)) { return new CInputStreamAddon(fileitem, clone); } } delete clone; } if (fileitem.IsDiscImage()) { #ifdef HAVE_LIBBLURAY CURL url("udf://"); url.SetHostName(file); url.SetFileName("BDMV/index.bdmv"); if(XFILE::CFile::Exists(url.Get())) return new CDVDInputStreamBluray(pPlayer, fileitem); #endif return new CDVDInputStreamNavigator(pPlayer, fileitem); } #ifdef HAS_DVD_DRIVE if(file.compare(g_mediaManager.TranslateDevicePath("")) == 0) { #ifdef HAVE_LIBBLURAY if(XFILE::CFile::Exists(URIUtils::AddFileToFolder(file, "BDMV/index.bdmv"))) return new CDVDInputStreamBluray(pPlayer, fileitem); #endif return new CDVDInputStreamNavigator(pPlayer, fileitem); } #endif if (fileitem.IsDVDFile(false, true)) return (new CDVDInputStreamNavigator(pPlayer, fileitem)); else if(file.substr(0, 6) == "pvr://") return new CDVDInputStreamPVRManager(pPlayer, fileitem); #ifdef HAVE_LIBBLURAY else if (fileitem.IsType(".bdmv") || fileitem.IsType(".mpls") || file.substr(0, 7) == "bluray:") return new CDVDInputStreamBluray(pPlayer, fileitem); #endif else if(file.substr(0, 6) == "rtp://" || file.substr(0, 7) == "rtsp://" || file.substr(0, 6) == "sdp://" || file.substr(0, 6) == "udp://" || file.substr(0, 6) == "tcp://" || file.substr(0, 6) == "mms://" || file.substr(0, 7) == "mmst://" || file.substr(0, 7) == "mmsh://") return new CDVDInputStreamFFmpeg(fileitem); #ifdef ENABLE_DVDINPUTSTREAM_STACK else if(file.substr(0, 8) == "stack://") return new CDVDInputStreamStack(fileitem); #endif #ifdef HAS_LIBRTMP else if(file.substr(0, 7) == "rtmp://" || file.substr(0, 8) == "rtmpt://" || file.substr(0, 8) == "rtmpe://" || file.substr(0, 9) == "rtmpte://" || file.substr(0, 8) == "rtmps://") return new CDVDInputStreamRTMP(fileitem); #endif else if (fileitem.IsInternetStream()) { if (fileitem.IsType(".m3u8")) return new CDVDInputStreamFFmpeg(fileitem); if (fileitem.ContentLookup()) { // request header fileitem.SetMimeType(""); fileitem.FillInMimeType(); } if (fileitem.GetMimeType() == "application/vnd.apple.mpegurl") return new CDVDInputStreamFFmpeg(fileitem); } // our file interface handles all these types of streams return (new CDVDInputStreamFile(fileitem)); }