bool VideoDecoder::seekToFrame(uint frame) { if (!isSeekable()) return false; VideoTrack *track = 0; for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) { if ((*it)->getTrackType() == Track::kTrackTypeVideo) { // We only allow seeking by frame when one video track // is present if (track) return false; track = (VideoTrack *)*it; } } // If we didn't find a video track, we can't seek by frame (of course) if (!track) return false; Audio::Timestamp time = track->getFrameTime(frame); if (time < 0) return false; return seek(time); }
VideoTrack* VideoTrackList::getTrackById(const AtomicString& id) const { for (size_t i = 0; i < length(); ++i) { VideoTrack* track = toVideoTrack(m_inbandTracks[i].get()); if (track->id() == id) return track; } return 0; }
long VideoTrackList::selectedIndex() const { // 4.8.10.10.1 AudioTrackList and VideoTrackList objects // The VideoTrackList.selectedIndex attribute must return the index of the // currently selected track, if any. If the VideoTrackList object does not // currently represent any tracks, or if none of the tracks are selected, // it must instead return −1. for (size_t i = 0; i < length(); ++i) { VideoTrack* track = toVideoTrack(m_inbandTracks[i].get()); if (track->selected()) return i; } return -1; }
void VideoTrack::SetEnabledInternal(bool aEnabled, int aFlags) { if (aEnabled == mSelected) { return; } mSelected = aEnabled; // If this VideoTrack is no longer in its original VideoTrackList, then // whether it is selected or not has no effect on its original list. if (!mList) { return; } VideoTrackList& list = static_cast<VideoTrackList&>(*mList); if (mSelected) { uint32_t curIndex = 0; // Unselect all video tracks except the current one. for (uint32_t i = 0; i < list.Length(); ++i) { if (list[i] == this) { curIndex = i; continue; } VideoTrack* track = list[i]; track->SetSelected(false); } // Set the index of selected video track to the current's index. list.mSelectedIndex = curIndex; } else { list.mSelectedIndex = -1; } // Fire the change event at selection changes on this video track, shall // propose a spec change later. if (!(aFlags & MediaTrack::FIRE_NO_EVENTS)) { list.CreateAndDispatchChangeEvent(); HTMLMediaElement* element = mList->GetMediaElement(); if (element) { element->NotifyMediaTrackEnabled(this); } } }
VideoDecoder::VideoTrack *VideoDecoder::findNextVideoTrack() { _nextVideoTrack = 0; uint32 bestTime = 0xFFFFFFFF; for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) { if ((*it)->getTrackType() == Track::kTrackTypeVideo && !(*it)->endOfTrack()) { VideoTrack *track = (VideoTrack *)*it; uint32 time = track->getNextFrameStartTime(); if (time < bestTime) { bestTime = time; _nextVideoTrack = track; } } } return _nextVideoTrack; }
const Graphics::Surface *VideoDecoder::decodeNextFrame() { _needsUpdate = false; readNextPacket(); VideoTrack *track = findNextVideoTrack(); if (!track) return 0; const Graphics::Surface *frame = track->decodeNextFrame(); if (track->hasDirtyPalette()) { _palette = track->getPalette(); _dirtyPalette = true; } return frame; }
void VideoTrackList::append(PassRefPtr<VideoTrack> prpTrack) { RefPtr<VideoTrack> track = prpTrack; // Insert tracks in the media file order. size_t index = track->inbandTrackIndex(); size_t insertionIndex; for (insertionIndex = 0; insertionIndex < m_inbandTracks.size(); ++insertionIndex) { VideoTrack* otherTrack = static_cast<VideoTrack*>(m_inbandTracks[insertionIndex].get()); if (otherTrack->inbandTrackIndex() > index) break; } m_inbandTracks.insert(insertionIndex, track); ASSERT(!track->mediaElement() || track->mediaElement() == mediaElement()); track->setMediaElement(mediaElement()); scheduleAddTrackEvent(track.release()); }
void VideoDecoder::setEndFrame(uint frame) { VideoTrack *track = 0; for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) { if ((*it)->getTrackType() == Track::kTrackTypeVideo) { // We only allow this when one video track is present if (track) return; track = (VideoTrack *)*it; } } // If we didn't find a video track, we can't set the final frame (of course) if (!track) return; Audio::Timestamp time = track->getFrameTime(frame + 1); if (time < 0) return; setEndTime(time); }
void MediaSource::removeSourceBuffer(SourceBuffer& buffer, ExceptionCode& ec) { LOG(MediaSource, "MediaSource::removeSourceBuffer() %p", this); Ref<SourceBuffer> protect(buffer); // 2. If sourceBuffer specifies an object that is not in sourceBuffers then // throw a NOT_FOUND_ERR exception and abort these steps. if (!m_sourceBuffers->length() || !m_sourceBuffers->contains(buffer)) { ec = NOT_FOUND_ERR; return; } // 3. If the sourceBuffer.updating attribute equals true, then run the following steps: ... buffer.abortIfUpdating(); // 4. Let SourceBuffer audioTracks list equal the AudioTrackList object returned by sourceBuffer.audioTracks. RefPtr<AudioTrackList> audioTracks = buffer.audioTracks(); // 5. If the SourceBuffer audioTracks list is not empty, then run the following steps: if (audioTracks->length()) { // 5.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object returned by the audioTracks // attribute on the HTMLMediaElement. // 5.2 Let the removed enabled audio track flag equal false. bool removedEnabledAudioTrack = false; // 5.3 For each AudioTrack object in the SourceBuffer audioTracks list, run the following steps: while (audioTracks->length()) { AudioTrack* track = audioTracks->lastItem(); // 5.3.1 Set the sourceBuffer attribute on the AudioTrack object to null. track->setSourceBuffer(nullptr); // 5.3.2 If the enabled attribute on the AudioTrack object is true, then set the removed enabled // audio track flag to true. if (track->enabled()) removedEnabledAudioTrack = true; // 5.3.3 Remove the AudioTrack object from the HTMLMediaElement audioTracks list. // 5.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement audioTracks list. if (mediaElement()) mediaElement()->removeAudioTrack(track); // 5.3.5 Remove the AudioTrack object from the SourceBuffer audioTracks list. // 5.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the SourceBuffer audioTracks list. audioTracks->remove(track); } // 5.4 If the removed enabled audio track flag equals true, then queue a task to fire a simple event // named change at the HTMLMediaElement audioTracks list. if (removedEnabledAudioTrack) mediaElement()->audioTracks()->scheduleChangeEvent(); } // 6. Let SourceBuffer videoTracks list equal the VideoTrackList object returned by sourceBuffer.videoTracks. RefPtr<VideoTrackList> videoTracks = buffer.videoTracks(); // 7. If the SourceBuffer videoTracks list is not empty, then run the following steps: if (videoTracks->length()) { // 7.1 Let HTMLMediaElement videoTracks list equal the VideoTrackList object returned by the videoTracks // attribute on the HTMLMediaElement. // 7.2 Let the removed selected video track flag equal false. bool removedSelectedVideoTrack = false; // 7.3 For each VideoTrack object in the SourceBuffer videoTracks list, run the following steps: while (videoTracks->length()) { VideoTrack* track = videoTracks->lastItem(); // 7.3.1 Set the sourceBuffer attribute on the VideoTrack object to null. track->setSourceBuffer(nullptr); // 7.3.2 If the selected attribute on the VideoTrack object is true, then set the removed selected // video track flag to true. if (track->selected()) removedSelectedVideoTrack = true; // 7.3.3 Remove the VideoTrack object from the HTMLMediaElement videoTracks list. // 7.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement videoTracks list. if (mediaElement()) mediaElement()->removeVideoTrack(track); // 7.3.5 Remove the VideoTrack object from the SourceBuffer videoTracks list. // 7.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the SourceBuffer videoTracks list. videoTracks->remove(track); } // 7.4 If the removed selected video track flag equals true, then queue a task to fire a simple event // named change at the HTMLMediaElement videoTracks list. if (removedSelectedVideoTrack) mediaElement()->videoTracks()->scheduleChangeEvent(); } // 8. Let SourceBuffer textTracks list equal the TextTrackList object returned by sourceBuffer.textTracks. RefPtr<TextTrackList> textTracks = buffer.textTracks(); // 9. If the SourceBuffer textTracks list is not empty, then run the following steps: if (textTracks->length()) { // 9.1 Let HTMLMediaElement textTracks list equal the TextTrackList object returned by the textTracks // attribute on the HTMLMediaElement. // 9.2 Let the removed enabled text track flag equal false. bool removedEnabledTextTrack = false; // 9.3 For each TextTrack object in the SourceBuffer textTracks list, run the following steps: while (textTracks->length()) { TextTrack* track = textTracks->lastItem(); // 9.3.1 Set the sourceBuffer attribute on the TextTrack object to null. track->setSourceBuffer(nullptr); // 9.3.2 If the mode attribute on the TextTrack object is set to "showing" or "hidden", then // set the removed enabled text track flag to true. if (track->mode() == TextTrack::showingKeyword() || track->mode() == TextTrack::hiddenKeyword()) removedEnabledTextTrack = true; // 9.3.3 Remove the TextTrack object from the HTMLMediaElement textTracks list. // 9.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement textTracks list. if (mediaElement()) mediaElement()->removeTextTrack(track); // 9.3.5 Remove the TextTrack object from the SourceBuffer textTracks list. // 9.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not // cancelable, and that uses the TrackEvent interface, at the SourceBuffer textTracks list. textTracks->remove(track); } // 9.4 If the removed enabled text track flag equals true, then queue a task to fire a simple event // named change at the HTMLMediaElement textTracks list. if (removedEnabledTextTrack) mediaElement()->textTracks()->scheduleChangeEvent(); } // 10. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer from activeSourceBuffers ... m_activeSourceBuffers->remove(buffer); // 11. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer event // on that object. m_sourceBuffers->remove(buffer); // 12. Destroy all resources for sourceBuffer. buffer.removedFromMediaSource(); }
int main(int argc, char *argv[]) { if(argc != 2) { cout << "usage ./exec <video>.avi\n" <<endl; return -1; } cv::VideoCapture capture(argv[1]); if (!capture.isOpened()) { std::cout << "ERROR: capture is NULL \n"<<std::endl; return -1; } VideoTrack v; v.init_frames(capture); /* char send_data[1]; cout << "Type 1.1 to run problem set 1.1\n"<< "1.2 to run problem set 1.2\n"<< "2.1 to run problem set 2.1\n"<< "2.2 to run problem set 2.2\n"<< "3.1 to run problem set 3.1\n"<< "4.1 to run problem set 4.1\n"<< "5.1 to run problem set 5.1\n"<<endl; cin >>send_data; if ((strcmp(send_data , "1.1") == 0)) { } else if ((strcmp(send_data , "1.2") == 0)) { } else if ((strcmp(send_data , "2.1") == 0)) { } else if ((strcmp(send_data , "2.2") == 0)) { } else if ((strcmp(send_data , "3.1") == 0)) { } else cout << "I do not recognize that number"<<endl;*/ // wait for a key //cvWaitKey(0); return 0; }
std::vector<WebMediaPlayer::TrackId> SourceBuffer::initializationSegmentReceived(const std::vector<MediaTrackInfo>& newTracks) { WTF_LOG(Media, "SourceBuffer::initializationSegmentReceived %p tracks=%zu", this, newTracks.size()); ASSERT(m_source); ASSERT(m_source->mediaElement()); ASSERT(m_updating); // TODO(servolk): Implement proper 'initialization segment received' algorithm according to MSE spec: // https://w3c.github.io/media-source/#sourcebuffer-init-segment-received std::vector<WebMediaPlayer::TrackId> result; for (const auto& trackInfo : newTracks) { const auto& trackType = std::get<0>(trackInfo); const auto& id = std::get<1>(trackInfo); const auto& kind = std::get<2>(trackInfo); const auto& label = std::get<3>(trackInfo); const auto& language = std::get<4>(trackInfo); if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) { static WebMediaPlayer::TrackId nextTrackId = 0; result.push_back(++nextTrackId); continue; } const TrackBase* trackBase = nullptr; if (trackType == WebMediaPlayer::AudioTrack) { AudioTrack* audioTrack = nullptr; if (!m_firstInitializationSegmentReceived) { audioTrack = AudioTrack::create(id, kind, label, language, false); audioTracks().add(audioTrack); m_source->mediaElement()->audioTracks().add(audioTrack); } else { audioTrack = findExistingTrackById(audioTracks(), id); ASSERT(audioTrack); } trackBase = audioTrack; result.push_back(audioTrack->trackId()); } else if (trackType == WebMediaPlayer::VideoTrack) { VideoTrack* videoTrack = nullptr; if (!m_firstInitializationSegmentReceived) { videoTrack = VideoTrack::create(id, kind, label, language, false); videoTracks().add(videoTrack); m_source->mediaElement()->videoTracks().add(videoTrack); } else { videoTrack = findExistingTrackById(videoTracks(), id); ASSERT(videoTrack); } trackBase = videoTrack; result.push_back(videoTrack->trackId()); } else { NOTREACHED(); } (void)trackBase; #if !LOG_DISABLED const char* logActionStr = m_firstInitializationSegmentReceived ? "using existing" : "added"; const char* logTrackTypeStr = (trackType == WebMediaPlayer::AudioTrack) ? "audio" : "video"; WTF_LOG(Media, "Tracks (sb=%p): %s %sTrack %p trackId=%d id=%s label=%s lang=%s", this, logActionStr, logTrackTypeStr, trackBase, trackBase->trackId(), trackBase->id().utf8().data(), trackBase->label().utf8().data(), trackBase->language().utf8().data()); #endif } if (!m_firstInitializationSegmentReceived) { // 5. If active track flag equals true, then run the following steps: // 5.1. Add this SourceBuffer to activeSourceBuffers. // 5.2. Queue a task to fire a simple event named addsourcebuffer at // activesourcebuffers. m_source->setSourceBufferActive(this); // 6. Set first initialization segment received flag to true. m_firstInitializationSegmentReceived = true; } return result; }