void CPlayerSelectionRule::GetPlayers(const CFileItem& item, VECPLAYERCORES &vecCores) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: considering rule: %s", m_name.c_str()); if (m_bStreamDetails && !item.HasVideoInfoTag()) return; if (m_tAudio >= 0 && (m_tAudio > 0) != item.IsAudio()) return; if (m_tVideo >= 0 && (m_tVideo > 0) != item.IsVideo()) return; if (m_tInternetStream >= 0 && (m_tInternetStream > 0) != item.IsInternetStream()) return; if (m_tDVD >= 0 && (m_tDVD > 0) != item.IsDVD()) return; if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != item.IsDVDFile()) return; if (m_tDVDImage >= 0 && (m_tDVDImage > 0) != item.IsDVDImage()) return; CRegExp regExp; if (m_bStreamDetails) { if (!item.GetVideoInfoTag()->HasStreamDetails()) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: cannot check rule: %s, no StreamDetails", m_name.c_str()); return; } CStreamDetails streamDetails = item.GetVideoInfoTag()->m_streamDetails; if (CompileRegExp(m_audioCodec, regExp) && !MatchesRegExp(streamDetails.GetAudioCodec(), regExp)) return; if (CompileRegExp(m_videoCodec, regExp) && !MatchesRegExp(streamDetails.GetVideoCodec(), regExp)) return; if (CompileRegExp(m_videoResolution, regExp) && !MatchesRegExp(CStreamDetails::VideoDimsToResolutionDescription(streamDetails.GetVideoWidth(), streamDetails.GetVideoHeight()), regExp)) return; if (CompileRegExp(m_videoAspect, regExp) && !MatchesRegExp(CStreamDetails::VideoAspectToAspectDescription(streamDetails.GetVideoAspect()), regExp)) return; } CURL url(item.GetPath()); if (CompileRegExp(m_fileTypes, regExp) && !MatchesRegExp(url.GetFileType(), regExp)) return; if (CompileRegExp(m_protocols, regExp) && !MatchesRegExp(url.GetProtocol(), regExp)) return; if (CompileRegExp(m_mimeTypes, regExp) && !MatchesRegExp(item.GetMimeType(), regExp)) return; if (CompileRegExp(m_fileName, regExp) && !MatchesRegExp(item.GetPath(), regExp)) return; CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: matches rule: %s", m_name.c_str()); for (unsigned int i = 0; i < vecSubRules.size(); i++) vecSubRules[i]->GetPlayers(item, vecCores); PLAYERCOREID playerCoreId = GetPlayerCore(); if (playerCoreId != EPC_NONE) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: adding player: %s (%d) for rule: %s", m_playerName.c_str(), playerCoreId, m_name.c_str()); vecCores.push_back(GetPlayerCore()); } }
bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDemux *pDemuxer, const std::vector<CStreamDetailSubtitle> &subs, CStreamDetails &details) { bool result = DemuxerToStreamDetails(pInputStream, pDemuxer, details); for (unsigned int i = 0; i < subs.size(); i++) { CStreamDetailSubtitle* sub = new CStreamDetailSubtitle(); sub->m_strLanguage = subs[i].m_strLanguage; details.AddStream(sub); result = true; } return result; }
bool CDVDFileInfo::AddExternalSubtitleToDetails(const std::string &path, CStreamDetails &details, const std::string& filename, const std::string& subfilename) { std::string ext = URIUtils::GetExtension(filename); std::string vobsubfile = subfilename; if(ext == ".idx") { if (vobsubfile.empty()) vobsubfile = URIUtils::ReplaceExtension(filename, ".sub"); CDVDDemuxVobsub v; if (!v.Open(filename, STREAM_SOURCE_NONE, vobsubfile)) return false; int count = v.GetNrOfStreams(); for(int i = 0; i < count; i++) { CStreamDetailSubtitle *dsub = new CStreamDetailSubtitle(); CDemuxStream* stream = v.GetStream(i); std::string lang = stream->language; dsub->m_strLanguage = g_LangCodeExpander.ConvertToISO6392T(lang); details.AddStream(dsub); } return true; } if(ext == ".sub") { std::string strReplace(URIUtils::ReplaceExtension(filename,".idx")); if (XFILE::CFile::Exists(strReplace)) return false; } CStreamDetailSubtitle *dsub = new CStreamDetailSubtitle(); ExternalStreamInfo info; CUtil::GetExternalStreamDetailsFromFilename(path, filename, info); dsub->m_strLanguage = g_LangCodeExpander.ConvertToISO6392T(info.language); details.AddStream(dsub); return true; }
/* returns true if details have been added */ bool CDVDFileInfo::DemuxerToStreamDetails(CDVDInputStream *pInputStream, CDVDDemux *pDemux, CStreamDetails &details, const std::string &path) { bool retVal = false; details.Reset(); const CURL pathToUrl(path); for (int iStream=0; iStream<pDemux->GetNrOfStreams(); iStream++) { CDemuxStream *stream = pDemux->GetStream(iStream); if (stream->type == STREAM_VIDEO && !(stream->flags & AV_DISPOSITION_ATTACHED_PIC)) { CStreamDetailVideo *p = new CStreamDetailVideo(); p->m_iWidth = ((CDemuxStreamVideo *)stream)->iWidth; p->m_iHeight = ((CDemuxStreamVideo *)stream)->iHeight; p->m_fAspect = ((CDemuxStreamVideo *)stream)->fAspect; if (p->m_fAspect == 0.0f) p->m_fAspect = (float)p->m_iWidth / p->m_iHeight; pDemux->GetStreamCodecName(iStream, p->m_strCodec); p->m_iDuration = pDemux->GetStreamLength(); p->m_strStereoMode = ((CDemuxStreamVideo *)stream)->stereo_mode; // stack handling if (URIUtils::IsStack(path)) { CFileItemList files; XFILE::CStackDirectory stack; stack.GetDirectory(pathToUrl, files); // skip first path as we already know the duration for (int i = 1; i < files.Size(); i++) { int duration = 0; if (CDVDFileInfo::GetFileDuration(files[i]->GetPath(), duration)) p->m_iDuration = p->m_iDuration + duration; } } // finally, calculate seconds if (p->m_iDuration > 0) p->m_iDuration = p->m_iDuration / 1000; details.AddStream(p); retVal = true; } else if (stream->type == STREAM_AUDIO) { CStreamDetailAudio *p = new CStreamDetailAudio(); p->m_iChannels = ((CDemuxStreamAudio *)stream)->iChannels; p->m_strLanguage = stream->language; pDemux->GetStreamCodecName(iStream, p->m_strCodec); details.AddStream(p); retVal = true; } else if (stream->type == STREAM_SUBTITLE) { CStreamDetailSubtitle *p = new CStreamDetailSubtitle(); p->m_strLanguage = stream->language; details.AddStream(p); retVal = true; } } /* for iStream */ details.DetermineBestStreams(); #ifdef HAVE_LIBBLURAY // correct bluray runtime. we need the duration from the input stream, not the demuxer. if (pInputStream->IsStreamType(DVDSTREAM_TYPE_BLURAY)) { if(((CDVDInputStreamBluray*)pInputStream)->GetTotalTime() > 0) { CStreamDetailVideo* detailVideo = (CStreamDetailVideo*)details.GetNthStream(CStreamDetail::VIDEO, 0); if (detailVideo) detailVideo->m_iDuration = ((CDVDInputStreamBluray*)pInputStream)->GetTotalTime() / 1000; } } #endif return retVal; }
bool CVideoThumbLoader::LoadItem(CFileItem* pItem, bool bCanBlock) { if (pItem->m_bIsShareOrDrive) return false; bool retVal = false; if (pItem->IsVideoDb() && pItem->HasVideoInfoTag() && !pItem->HasThumbnail()) { if (pItem->m_bIsFolder && pItem->GetVideoInfoTag()->m_iSeason > -1) return false; CFileItem item(*pItem->GetVideoInfoTag()); bool bResult = LoadItem(&item, bCanBlock); if (bResult) { pItem->SetProperty("HasAutoThumb",item.GetProperty("HasAutoThumb")); pItem->SetProperty("AutoThumbImage",item.GetProperty("AutoThumbImage")); pItem->SetProperty("fanart_image",item.GetProperty("fanart_image")); pItem->SetThumbnailImage(item.GetThumbnailImage()); pItem->GetVideoInfoTag()->m_streamDetails = item.GetVideoInfoTag()->m_streamDetails; } return bResult; } CStdString cachedThumb(pItem->GetCachedVideoThumb()); CLog::Log(LOGDEBUG, "CVideoThumbLoader::LoadItem, strItemPath = %s, cachedThumb = %s (thumb)", pItem->m_strPath.c_str(), cachedThumb.c_str()); if (!pItem->HasThumbnail()) { if (CFile::Exists(cachedThumb)) { CLog::Log(LOGDEBUG, "CVideoThumbLoader::LoadItem, EXISTS, strItemPath = %s, cachedThumb = %s (thumb)", pItem->m_strPath.c_str(), cachedThumb.c_str()); pItem->SetCachedVideoThumb(); } else if (pItem->m_bIsFolder) pItem->SetUserVideoThumb(); else { CStdString strPath, strFileName; CUtil::Split(cachedThumb, strPath, strFileName); // create unique thumb for auto generated thumbs cachedThumb = strPath + "auto-" + strFileName; if (pItem->IsVideo() && !pItem->IsInternetStream() && !pItem->IsPlayList() && !CFile::Exists(cachedThumb) && !pItem->m_bIsFolder) { if (!bCanBlock) { // we should not retreive remote (e.g. SMB) thumbs if requested not to block return false; } CStreamDetails details; if (pItem->IsStack()) { CStackDirectory stack; CVideoThumbLoader::ExtractThumb(stack.GetFirstStackedFile(pItem->m_strPath), cachedThumb, &details); } else { CVideoThumbLoader::ExtractThumb(pItem->m_strPath, cachedThumb, &details); } if (details.HasItems() && m_pStreamDetailsObs) m_pStreamDetailsObs->OnStreamDetails(details, pItem->m_strPath, -1); } if (CFile::Exists(cachedThumb)) { pItem->SetProperty("HasAutoThumb", "1"); pItem->SetProperty("AutoThumbImage", cachedThumb); pItem->SetThumbnailImage(cachedThumb); retVal = true; } else pItem->SetThumbnailImage(""); } } else { // look for remote thumbs CStdString thumb(pItem->GetThumbnailImage()); if (!CURI::IsFileOnly(thumb) && !CUtil::IsHD(thumb)) { if (pItem->GetProperty("OriginalThumb").IsEmpty()) { //when the item is loaded from the database we don't want to overwrite the original thumb by mistake because the user might have his own thumb //related to http://jira.boxee.tv/browse/BOXEE-8488 pItem->SetProperty("OriginalThumb", thumb); } if(CFile::Exists(cachedThumb)) { pItem->SetThumbnailImage(cachedThumb); retVal = true; } else { if (!bCanBlock) { // we should not retreive remote thumbs if requested not to block return false; } if(CPicture::CreateThumbnail(thumb, cachedThumb)) pItem->SetThumbnailImage(cachedThumb); else pItem->SetThumbnailImage(""); } } else { if (!CFile::Exists(cachedThumb)) { // Thumb can not be found. Going to create the thumb by fetching the original thumb and save it in cache if (!bCanBlock) { if (pItem->GetProperty("OriginalThumb").IsEmpty()) { pItem->SetProperty("OriginalThumb", thumb); } return false; } CStdString originalThumb = pItem->GetProperty("OriginalThumb"); if (!pItem->GetThumbnailImage().IsEmpty() && (CUtil::IsHD(pItem->GetThumbnailImage()) || CUtil::IsSmb(pItem->GetThumbnailImage()) || CUtil::IsUPnP(pItem->GetThumbnailImage())) && CFile::Exists(pItem->GetThumbnailImage())) { //if the user has the thumb locally, use it originalThumb = pItem->GetThumbnailImage(); } CStdString newCachedThumb = pItem->GetCachedPictureThumb(); if(CPicture::CreateThumbnail(originalThumb, newCachedThumb,true )) { pItem->SetThumbnailImage(newCachedThumb); } else { pItem->SetThumbnailImage(""); } } } } if (!pItem->HasProperty("fanart_image") && bCanBlock) { pItem->CacheFanart(); if (CFile::Exists(pItem->GetCachedFanart())) { pItem->SetProperty("fanart_image",pItem->GetCachedFanart()); retVal = true; } } if (!pItem->m_bIsFolder && !pItem->IsInternetStream() && pItem->HasVideoInfoTag() && g_guiSettings.GetBool("myvideos.extractflags") && !pItem->GetVideoInfoTag()->HasStreamDetails()) { if (CDVDFileInfo::GetFileStreamDetails(pItem) && m_pStreamDetailsObs) { CVideoInfoTag *info = pItem->GetVideoInfoTag(); m_pStreamDetailsObs->OnStreamDetails(info->m_streamDetails, "", info->m_iFileId); pItem->SetInvalid(); retVal = true; } } // if (pItem->IsVideo() && !pItem->IsInternetStream()) // CDVDPlayer::GetFileMetaData(pItem->m_strPath, pItem); return retVal; }
void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::string>&validPlayers, std::vector<std::string>&players) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: considering rule: %s", m_name.c_str()); if (m_bStreamDetails && !item.HasVideoInfoTag()) return; if (m_tAudio >= 0 && (m_tAudio > 0) != item.IsAudio()) return; if (m_tVideo >= 0 && (m_tVideo > 0) != item.IsVideo()) return; if (m_tInternetStream >= 0 && (m_tInternetStream > 0) != item.IsInternetStream()) return; if (m_tRemote >= 0 && (m_tRemote > 0) != item.IsRemote()) return; if (m_tBD >= 0 && (m_tBD > 0) != (item.IsBDFile() && item.IsOnDVD())) return; if (m_tDVD >= 0 && (m_tDVD > 0) != item.IsDVD()) return; if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != item.IsDVDFile()) return; if (m_tDVDImage >= 0 && (m_tDVDImage > 0) != item.IsDiscImage()) return; CRegExp regExp(false, CRegExp::autoUtf8); if (m_bStreamDetails) { if (!item.GetVideoInfoTag()->HasStreamDetails()) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: cannot check rule: %s, no StreamDetails", m_name.c_str()); return; } CStreamDetails streamDetails = item.GetVideoInfoTag()->m_streamDetails; if (CompileRegExp(m_audioCodec, regExp) && !MatchesRegExp(streamDetails.GetAudioCodec(), regExp)) return; std::stringstream itoa; itoa << streamDetails.GetAudioChannels(); std::string audioChannelsstr = itoa.str(); if (CompileRegExp(m_audioChannels, regExp) && !MatchesRegExp(audioChannelsstr, regExp)) return; if (CompileRegExp(m_videoCodec, regExp) && !MatchesRegExp(streamDetails.GetVideoCodec(), regExp)) return; if (CompileRegExp(m_videoResolution, regExp) && !MatchesRegExp(CStreamDetails::VideoDimsToResolutionDescription(streamDetails.GetVideoWidth(), streamDetails.GetVideoHeight()), regExp)) return; if (CompileRegExp(m_videoAspect, regExp) && !MatchesRegExp(CStreamDetails::VideoAspectToAspectDescription(streamDetails.GetVideoAspect()), regExp)) return; } CURL url(item.GetPath()); if (CompileRegExp(m_fileTypes, regExp) && !MatchesRegExp(url.GetFileType(), regExp)) return; if (CompileRegExp(m_protocols, regExp) && !MatchesRegExp(url.GetProtocol(), regExp)) return; if (CompileRegExp(m_mimeTypes, regExp) && !MatchesRegExp(item.GetMimeType(), regExp)) return; if (CompileRegExp(m_fileName, regExp) && !MatchesRegExp(item.GetPath(), regExp)) return; CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: matches rule: %s", m_name.c_str()); for (unsigned int i = 0; i < vecSubRules.size(); i++) vecSubRules[i]->GetPlayers(item, validPlayers, players); if (std::find(validPlayers.begin(), validPlayers.end(), m_playerName) != validPlayers.end()) { CLog::Log(LOGDEBUG, "CPlayerSelectionRule::GetPlayers: adding player: %s for rule: %s", m_playerName.c_str(), m_name.c_str()); players.push_back(m_playerName); } }
TEST(TestStreamDetails, General) { CStreamDetails a; CStreamDetailVideo *video = new CStreamDetailVideo(); CStreamDetailAudio *audio = new CStreamDetailAudio(); CStreamDetailSubtitle *subtitle = new CStreamDetailSubtitle(); video->m_iWidth = 1920; video->m_iHeight = 1080; video->m_fAspect = 2.39f; video->m_iDuration = 30; video->m_strCodec = "h264"; audio->m_iChannels = 2; audio->m_strCodec = "aac"; audio->m_strLanguage = "eng"; subtitle->m_strLanguage = "eng"; a.AddStream(video); a.AddStream(audio); EXPECT_TRUE(a.HasItems()); EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::VIDEO)); EXPECT_EQ(1, a.GetVideoStreamCount()); EXPECT_STREQ("", a.GetVideoCodec().c_str()); EXPECT_EQ(0.0f, a.GetVideoAspect()); EXPECT_EQ(0, a.GetVideoWidth()); EXPECT_EQ(0, a.GetVideoHeight()); EXPECT_EQ(0, a.GetVideoDuration()); EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::AUDIO)); EXPECT_EQ(1, a.GetAudioStreamCount()); EXPECT_EQ(0, a.GetStreamCount(CStreamDetail::SUBTITLE)); EXPECT_EQ(0, a.GetSubtitleStreamCount()); a.AddStream(subtitle); EXPECT_EQ(1, a.GetStreamCount(CStreamDetail::SUBTITLE)); EXPECT_EQ(1, a.GetSubtitleStreamCount()); a.DetermineBestStreams(); EXPECT_STREQ("h264", a.GetVideoCodec().c_str()); EXPECT_EQ(2.39f, a.GetVideoAspect()); EXPECT_EQ(1920, a.GetVideoWidth()); EXPECT_EQ(1080, a.GetVideoHeight()); EXPECT_EQ(30, a.GetVideoDuration()); }