//------------------------------------------------------------------------// void MusicManager::OnSegmentStart() { FN("MusicManager::OnSegmentStart()"); ISegment* pCurrent; ISegment* pNext; AudioMgr()->GetCurrentSegment(pCurrent); if(m_pPlayingInterlude) { if(!m_pPlayingInterlude->GetTransition(m_pPreviousTheme, pCurrent, pNext)) { m_pPlayingInterlude = 0; if(!m_pPlayingTheme) return; m_pPlayingTheme->StartTheme(); if(!m_pPlayingTheme->GetTransition(m_pPreviousTheme, pCurrent, pNext)) return; } } else { if(!m_pPlayingTheme) return; if(!m_pPlayingTheme->GetTransition(m_pPreviousTheme, pCurrent, pNext)) return; } pNext->Play(); }
ISegment * SegmentInformation::getSegment(SegmentInfoType type, uint64_t pos) const { std::vector<ISegment *> retSegments; const size_t size = getSegments( type, retSegments ); if( size ) { if(size == 1 && retSegments[0]->isTemplate()) { MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]); if(!templ || templ->segmentTimeline.Get() == NULL || templ->segmentTimeline.Get()->maxElementNumber() > pos) return templ; } else { std::vector<ISegment *>::const_iterator it; for(it = retSegments.begin(); it != retSegments.end(); ++it) { ISegment *seg = *it; if(seg->getSequenceNumber() >= pos) { if(seg->getSequenceNumber() == pos) return seg; else return NULL; } } } } return NULL; }
Chunk * SegmentTracker::getNextChunk(StreamType type, bool switch_allowed) { BaseRepresentation *rep; ISegment *segment; if(!currentPeriod) return NULL; if( !switch_allowed || (prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) ) rep = prevRepresentation; else rep = logic->getCurrentRepresentation(type, currentPeriod); if ( rep == NULL ) return NULL; if(rep != prevRepresentation) { prevRepresentation = rep; initializing = true; } if(initializing) { initializing = false; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INIT); if(segment) return segment->toChunk(count, rep); } if(!indexed) { indexed = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INDEX); if(segment) return segment->toChunk(count, rep); } segment = rep->getSegment(BaseRepresentation::INFOTYPE_MEDIA, count); if(!segment) { currentPeriod = playlist->getNextPeriod(currentPeriod); resetCounter(); return getNextChunk(type, switch_allowed); } Chunk *chunk = segment->toChunk(count, rep); if(chunk) count++; return chunk; }
ISegment * SegmentList::getSegmentByNumber(uint64_t number) { std::vector<ISegment *>::const_iterator it = segments.begin(); for(it = segments.begin(); it != segments.end(); ++it) { ISegment *seg = *it; if(seg->getSequenceNumber() == number) { return seg; } else if (seg->getSequenceNumber() > number) { break; } } return NULL; }
void SegmentList::pruneBySegmentNumber(uint64_t tobelownum) { std::vector<ISegment *>::iterator it = segments.begin(); while(it != segments.end()) { ISegment *seg = *it; if(seg->getSequenceNumber() >= tobelownum) break; if(seg->chunksuse.Get()) /* can't prune from here, still in use */ break; delete *it; it = segments.erase(it); } }
/* Returns wanted segment, or next in sequence if not found */ ISegment * SegmentInformation::getNextSegment(SegmentInfoType type, uint64_t i_pos, uint64_t *pi_newpos, bool *pb_gap) const { *pb_gap = false; *pi_newpos = i_pos; if( type != INFOTYPE_MEDIA ) return NULL; std::vector<ISegment *> retSegments; const size_t size = getSegments( type, retSegments ); if( size ) { std::vector<ISegment *>::const_iterator it; for(it = retSegments.begin(); it != retSegments.end(); ++it) { ISegment *seg = *it; if(seg->isTemplate()) /* we don't care about seq number */ { /* Check if we don't exceed timeline */ MediaSegmentTemplate *templ = dynamic_cast<MediaSegmentTemplate*>(retSegments[0]); SegmentTimeline *timeline = (templ) ? templ->segmentTimeline.Get() : NULL; if(timeline) { *pi_newpos = std::max(timeline->minElementNumber(), i_pos); if(timeline->maxElementNumber() < i_pos) return NULL; } else { *pi_newpos = i_pos; /* start number */ *pi_newpos = std::max((uint64_t)templ->startNumber.Get(), i_pos); } return seg; } else if(seg->getSequenceNumber() >= i_pos) { *pi_newpos = seg->getSequenceNumber(); *pb_gap = (*pi_newpos != i_pos); return seg; } } } return NULL; }
static void insertIntoSegment(std::vector<ISegment *> &seglist, size_t start, size_t end, stime_t time) { std::vector<ISegment *>::iterator segIt; for(segIt = seglist.begin(); segIt < seglist.end(); ++segIt) { ISegment *segment = *segIt; if(segment->getClassId() == Segment::CLASSID_SEGMENT && (end == 0 || segment->contains(end))) { SubSegment *subsegment = new SubSegment(segment, start, (end != 0) ? end : 0); subsegment->startTime.Set(time); segment->addSubSegment(subsegment); break; } } }
//------------------------------------------------------------------------// bool MusicManager::LoadSegment(ScriptNode* pNode) { FN("MusicManager::LoadSegment()"); // We use string ids in this scripting system if(pNode->GetDataType() != Script::STRING) return Error::Handle("No id found for sound identifier"); // Make sure the segment ID doesn't already exist ISegmentMap::iterator itr = m_SegmentMap.find(pNode->GetString()); if(itr != m_SegmentMap.end()) return true; SegmentInit init; ScriptNode* pChildNode = pNode->GetChild(); init.m_pDLS = m_pCurrentDLS; while(pChildNode) { if(MUSMGR_STRCMP(pChildNode->GetName(), "FileName") == 0) init.m_sFileName = pChildNode->GetString(); else if(MUSMGR_STRCMP(pChildNode->GetName(), "Looping") == 0) init.m_bLooping = pChildNode->GetBool(); else if(MUSMGR_STRCMP(pChildNode->GetName(), "Music") == 0) init.m_bMusic = pChildNode->GetBool(); else if(MUSMGR_STRCMP(pChildNode->GetName(), "DLS") == 0) { IDLSMap::iterator itr = m_DLSMap.find(pChildNode->GetString()); if(itr != m_DLSMap.end()) init.m_pDLS = itr->second; } pChildNode = pChildNode->GetSibling(); } ISegment* pSegment; if(!AudioMgr()->CreateSegment(pSegment)) return false; if(!pSegment->Init(init)) return false; // Insert the segment into the map m_SegmentMap.insert(make_pair(pNode->GetString(), pSegment)); return true; }
void cut(const ISegment& seg, const char * const filePath) { ifstream ifile(filePath); vector<string> words; string line; string res; string s(filePath); s += ".seg"; ofstream outfile(s.c_str()); while(getline(ifile, line)) { if(!line.empty()) { words.clear(); seg.cut(line, words); join(words.begin(), words.end(), res, " "); //cout<< res <<endl; outfile << res; } } }
SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, HTTPConnectionManager *connManager) { BaseRepresentation *rep = NULL; ISegment *segment; if(!adaptationSet) return NULL; /* Ensure we don't keep chaining init/index without data */ if( initializing ) { if( prevRepresentation ) switch_allowed = false; else switch_allowed = true; } if( !switch_allowed || (prevRepresentation && prevRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) ) rep = prevRepresentation; else rep = logic->getNextRepresentation(adaptationSet, prevRepresentation); if ( rep == NULL ) return NULL; if(rep != prevRepresentation) { notify(SegmentTrackerEvent(prevRepresentation, rep)); prevRepresentation = rep; init_sent = false; index_sent = false; initializing = true; } /* Ensure ephemere content is updated/loaded */ if(rep->needsUpdate()) updateSelected(); if(!init_sent) { init_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INIT); if(segment) return segment->toChunk(count, rep, connManager); } if(!index_sent) { index_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INDEX); if(segment) return segment->toChunk(count, rep, connManager); } bool b_gap = false; segment = rep->getNextSegment(BaseRepresentation::INFOTYPE_MEDIA, count, &count, &b_gap); if(!segment) { reset(); return NULL; } /* stop initializing after 1st chunk */ initializing = false; SegmentChunk *chunk = segment->toChunk(count, rep, connManager); if(chunk) count++; /* We need to check segment/chunk format changes, as we can't rely on representation's (HLS)*/ if(format != chunk->getStreamFormat()) { format = chunk->getStreamFormat(); notify(SegmentTrackerEvent(&format)); } /* Handle both implicit and explicit discontinuities */ if( (b_gap && count) || (chunk && chunk->discontinuity) ) { notify(SegmentTrackerEvent(chunk)); } return chunk; }
SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, HTTPConnectionManager *connManager) { BaseRepresentation *rep = NULL, *prevRep = NULL; ISegment *segment; if(!adaptationSet) return NULL; /* Ensure we don't keep chaining init/index without data */ if( initializing ) { if( curRepresentation ) switch_allowed = false; else switch_allowed = true; } if( !switch_allowed || (curRepresentation && curRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) ) rep = curRepresentation; else rep = logic->getNextRepresentation(adaptationSet, curRepresentation); if ( rep == NULL ) return NULL; if(rep != curRepresentation) { notify(SegmentTrackerEvent(curRepresentation, rep)); prevRep = curRepresentation; curRepresentation = rep; init_sent = false; index_sent = false; initializing = true; } bool b_updated = false; /* Ensure ephemere content is updated/loaded */ if(rep->needsUpdate()) b_updated = rep->runLocalUpdates(getPlaybackTime(), curNumber, false); if(prevRep && !rep->consistentSegmentNumber()) { /* Convert our segment number */ next = rep->translateSegmentNumber(next, prevRep); } else if(first && rep->getPlaylist()->isLive()) { next = rep->getLiveStartSegmentNumber(next); first = false; } if(b_updated) { if(!rep->consistentSegmentNumber()) curRepresentation->pruneBySegmentNumber(curNumber); curRepresentation->scheduleNextUpdate(next); } if(!init_sent) { init_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INIT); if(segment) return segment->toChunk(next, rep, connManager); } if(!index_sent) { index_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INDEX); if(segment) return segment->toChunk(next, rep, connManager); } bool b_gap = false; segment = rep->getNextSegment(BaseRepresentation::INFOTYPE_MEDIA, next, &next, &b_gap); if(!segment) { reset(); return NULL; } if(initializing) { b_gap = false; /* stop initializing after 1st chunk */ initializing = false; } SegmentChunk *chunk = segment->toChunk(next, rep, connManager); /* We need to check segment/chunk format changes, as we can't rely on representation's (HLS)*/ if(chunk && format != chunk->getStreamFormat()) { format = chunk->getStreamFormat(); notify(SegmentTrackerEvent(&format)); } /* Handle both implicit and explicit discontinuities */ if( (b_gap && next) || (chunk && chunk->discontinuity) ) { notify(SegmentTrackerEvent(chunk)); } if(chunk) { curNumber = next; next++; } return chunk; }
SegmentChunk * SegmentTracker::getNextChunk(bool switch_allowed, AbstractConnectionManager *connManager) { /* LVP added, TFE DEBUG */ //msg_Info(NULL, "TFE DEBUG SegmentTracker getNextChunk, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker getNextChunk, " << mdate() << std::endl; BaseRepresentation *rep = NULL, *prevRep = NULL; ISegment *segment; if(!adaptationSet) { /* LVP added, TFE DEBUG */ //msg_Info(NULL, "TFE DEBUG SegmentTracker getNextChunk no adaptation set, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker getNextChunk no adaptation set, " << mdate() << std::endl; return NULL; } /* Ensure we don't keep chaining init/index without data */ if( initializing ) { if( curRepresentation ) switch_allowed = false; else switch_allowed = true; } if( !switch_allowed || (curRepresentation && curRepresentation->getSwitchPolicy() == SegmentInformation::SWITCH_UNAVAILABLE) ) rep = curRepresentation; else rep = logic->getNextRepresentation(adaptationSet, curRepresentation); if ( rep == NULL ) { /* LVP added, TFE DEBUG */ //msg_Info(NULL, "TFE DEBUG SegmentTracker no rep 1, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker no rep 1, " << mdate() << std::endl; return NULL; } if(rep != curRepresentation) { notify(SegmentTrackerEvent(curRepresentation, rep)); prevRep = curRepresentation; curRepresentation = rep; init_sent = false; index_sent = false; initializing = true; } bool b_updated = false; /* Ensure ephemere content is updated/loaded */ if(rep->needsUpdate()) b_updated = rep->runLocalUpdates(getPlaybackTime(), curNumber, false); if(prevRep && !rep->consistentSegmentNumber()) { /* Convert our segment number */ next = rep->translateSegmentNumber(next, prevRep); } else if(first && rep->getPlaylist()->isLive()) { next = rep->getLiveStartSegmentNumber(next); first = false; } if(b_updated) { if(!rep->consistentSegmentNumber()) curRepresentation->pruneBySegmentNumber(curNumber); curRepresentation->scheduleNextUpdate(next); } if(rep->getStreamFormat() != format) { /* Initial format ? */ if(format == StreamFormat(StreamFormat::UNSUPPORTED)) { format = rep->getStreamFormat(); } else { format = rep->getStreamFormat(); notify(SegmentTrackerEvent(&format)); /* Notify new demux format */ return NULL; /* Force current demux to end */ } } if(format == StreamFormat(StreamFormat::UNSUPPORTED)) { return NULL; /* Can't return chunk because no demux will be created */ } if(!init_sent) { init_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INIT); if(segment) { /* LVP added, TFE DEBUG */ std::cerr << "TFE DEBUG SegmentTracker getNextChunk no init sent but segment, " << mdate() << std::endl; //msg_Info(NULL, "TFE DEBUG SegmentTracker getNextChunk no init sent but segment, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker getNextChunk no init sent but segment, " << mdate() << std::endl; return segment->toChunk(next, rep, connManager); } } if(!index_sent) { index_sent = true; segment = rep->getSegment(BaseRepresentation::INFOTYPE_INDEX); if(segment) { /* LVP added, TFE DEBUG */ // happens after no init sent //msg_Info(NULL, "TFE DEBUG SegmentTracker getNextChunk no index sent but segment, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker getNextChunk no index sent but segment, " << mdate() << std::endl; return segment->toChunk(next, rep, connManager); } } bool b_gap = false; segment = rep->getNextSegment(BaseRepresentation::INFOTYPE_MEDIA, next, &next, &b_gap); if(!segment) { reset(); /* LVP added, TFE DEBUG */ // once at the end //msg_Info(NULL, "TFE DEBUG SegmentTracker getNextChunk no segment and reset, %" PRId64, mdate()); //std::cerr << "TFE DEBUG SegmentTracker getNextChunk no segment and reset, " << mdate() << std::endl; return NULL; } if(initializing) { b_gap = false; /* stop initializing after 1st chunk */ initializing = false; } SegmentChunk *chunk = segment->toChunk(next, rep, connManager); /* Notify new segment length for stats / logic */ if(chunk) { const Timescale timescale = rep->inheritTimescale(); notify(SegmentTrackerEvent(rep->getAdaptationSet()->getID(), timescale.ToTime(segment->duration.Get()))); } /* We need to check segment/chunk format changes, as we can't rely on representation's (HLS)*/ if(chunk && format != chunk->getStreamFormat()) { format = chunk->getStreamFormat(); notify(SegmentTrackerEvent(&format)); } /* Handle both implicit and explicit discontinuities */ if( (b_gap && next) || (chunk && chunk->discontinuity) ) { notify(SegmentTrackerEvent(chunk)); } if(chunk) { curNumber = next; next++; } /* LVP added, TFE */ //msg_Info(NULL, "TFE SegmentTracker getNextChunk done, %" PRId64 ", %" PRId64, mdate(), rep->getBandwidth()); //std::cerr << "TFE SegmentTracker getNextChunk done, " << mdate() << ", " << rep->getBandwidth() << std::endl; return chunk; }
//------------------------------------------------------------------------// void AudioManager::UpdateMusic() { FN("AudioManager::UpdateMusic()"); DMUS_NOTIFICATION_PMSG* pPmsg; while(true) { WaitForSingleObject(m_hMusicNotify, INFINITE); if(!m_bInitialized) { SetEvent(m_hTerm[MUSIC_EVENT]); return; } while (S_OK == m_pMusicPerformance->GetNotificationPMsg(&pPmsg)) { if(pPmsg->guidNotificationType == GUID_NOTIFICATION_MEASUREANDBEAT) { DebugOut(5, "Music notification: Beat = %d", pPmsg->dwField1); } else if(pPmsg->guidNotificationType == GUID_NOTIFICATION_PERFORMANCE) { if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_MUSICALMOSTEND) { DebugOut(5, "Music notification: Music almost at end"); if(!m_pCurrentSegment) break; if(m_pCurrentSegment->IsLooping() && !m_pNextSegment) { ISegment* pSeg = m_pCurrentSegment; m_pCurrentSegment = 0; m_pNextSegment = 0; pSeg->Play(); } else if(m_pNextSegment) { ISegment* pSeg = m_pNextSegment; m_pCurrentSegment = 0; m_pNextSegment = 0; pSeg->Play(); } } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_MUSICSTARTED) { DebugOut(5, "Music notification: Music started"); } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_MUSICSTOPPED) { DebugOut(5, "Music notification: Music stopped"); } } else if(pPmsg->guidNotificationType == GUID_NOTIFICATION_SEGMENT) { if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_SEGABORT) { DebugOut(5, "Music notification: Segment aborted"); } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_SEGALMOSTEND) { DebugOut(5, "Music notification: Segment almost at end"); } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_SEGEND) { DebugOut(5, "Music notification: Segment at end"); } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_SEGLOOP) { DebugOut(5, "Music notification: Segment has looped"); } else if(pPmsg->dwNotificationOption == DMUS_NOTIFICATION_SEGSTART) { DebugOut(5, "Music notification: Segment has started"); if(m_Init.m_pMusicCallback) m_Init.m_pMusicCallback->OnSegmentStart(); } } m_pMusicPerformance->FreePMsg((DMUS_PMSG*)pPmsg); } } }