void InbandTextTrackPrivateAVF::processCue(CFArrayRef attributedStrings, double time) { if (!client()) return; if (m_havePartialCue) { // Cues do not have an explicit duration, they are displayed until the next "cue" (which might be empty) is emitted. m_currentCueEndTime = time; if (m_currentCueEndTime >= m_currentCueStartTime) { for (size_t i = 0; i < m_cues.size(); i++) { GenericCueData* cueData = m_cues[i].get(); LOG(Media, "InbandTextTrackPrivateAVF::processCue flushing cue: start=%.2f, end=%.2f, content=\"%s\" \n", m_currentCueStartTime, m_currentCueEndTime, cueData->content().utf8().data()); if (!cueData->content().length()) continue; cueData->setStartTime(m_currentCueStartTime); cueData->setEndTime(m_currentCueEndTime); // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to // set CSS "left". if (cueData->position() >= 0 && cueData->size() > 0) cueData->setPosition(cueData->position() - cueData->size() / 2); LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position = %.2f, line = %.2f", this, cueData->startTime(), cueData->position(), cueData->line()); client()->addGenericCue(this, cueData); } } else LOG(Media, "InbandTextTrackPrivateAVF::processCue negative length cue(s) ignored: start=%.2f, end=%.2f\n", m_currentCueStartTime, m_currentCueEndTime); resetCueValues(); } if (!attributedStrings) return; CFIndex count = CFArrayGetCount(attributedStrings); if (!count) return; for (CFIndex i = 0; i < count; i++) { CFAttributedStringRef attributedString = static_cast<CFAttributedStringRef>(CFArrayGetValueAtIndex(attributedStrings, i)); if (!attributedString || !CFAttributedStringGetLength(attributedString)) continue; m_cues.append(adoptPtr(new GenericCueData)); processCueAttributes(attributedString, m_cues[i].get()); m_currentCueStartTime = time; m_havePartialCue = true; } }
void InbandTextTrackPrivateAVF::processCue(CFArrayRef attributedStrings, double time) { if (!client()) return; LOG(Media, "InbandTextTrackPrivateAVF::processCue - %li cues at time %.2f\n", attributedStrings ? CFArrayGetCount(attributedStrings) : 0, time); if (m_pendingCueStatus != None) { // Cues do not have an explicit duration, they are displayed until the next "cue" (which might be empty) is emitted. m_currentCueEndTime = time; if (m_currentCueEndTime >= m_currentCueStartTime) { for (size_t i = 0; i < m_cues.size(); i++) { GenericCueData* cueData = m_cues[i].get(); if (m_pendingCueStatus == Valid) { cueData->setEndTime(m_currentCueEndTime); cueData->setStatus(GenericCueData::Complete); LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - updating cue: start=%.2f, end=%.2f, content=\"%s\"", this, cueData->startTime(), m_currentCueEndTime, cueData->content().utf8().data()); client()->updateGenericCue(this, cueData); } else { // We have to assume that the implicit duration is invalid for cues delivered during a seek because the AVF decode pipeline may not // see every cue, so DO NOT update cue duration while seeking. LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - ignoring cue delivered during seek: start=%.2f, end=%.2f, content=\"%s\"", this, cueData->startTime(), m_currentCueEndTime, cueData->content().utf8().data()); } } } else LOG(Media, "InbandTextTrackPrivateAVF::processCue negative length cue(s) ignored: start=%.2f, end=%.2f\n", m_currentCueStartTime, m_currentCueEndTime); resetCueValues(); } if (!attributedStrings) return; CFIndex count = CFArrayGetCount(attributedStrings); if (!count) return; for (CFIndex i = 0; i < count; i++) { CFAttributedStringRef attributedString = static_cast<CFAttributedStringRef>(CFArrayGetValueAtIndex(attributedStrings, i)); if (!attributedString || !CFAttributedStringGetLength(attributedString)) continue; RefPtr<GenericCueData> cueData = GenericCueData::create(); processCueAttributes(attributedString, cueData.get()); if (!cueData->content().length()) continue; m_cues.append(cueData); m_currentCueStartTime = time; cueData->setStartTime(m_currentCueStartTime); cueData->setEndTime(numeric_limits<double>::infinity()); // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to // set CSS "left". if (cueData->position() >= 0 && cueData->size() > 0) cueData->setPosition(cueData->position() - cueData->size() / 2); LOG(Media, "InbandTextTrackPrivateAVF::processCue(%p) - adding cue for time = %.2f, position = %.2f, line = %.2f", this, cueData->startTime(), cueData->position(), cueData->line()); cueData->setStatus(GenericCueData::Partial); client()->addGenericCue(this, cueData.release()); m_pendingCueStatus = seeking() ? DeliveredDuringSeek : Valid; } }