зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1015985 - Set decoder seekable members outside of ReadMetadata by StateMachine. r=cpearce
This commit is contained in:
Родитель
dfd6c3f511
Коммит
297a9b2844
|
@ -2527,7 +2527,6 @@ nsresult HTMLMediaElement::InitializeDecoderAsClone(MediaDecoder* aOriginal)
|
|||
double duration = aOriginal->GetDuration();
|
||||
if (duration >= 0) {
|
||||
decoder->SetDuration(duration);
|
||||
decoder->SetTransportSeekable(aOriginal->IsTransportSeekable());
|
||||
decoder->SetMediaSeekable(aOriginal->IsMediaSeekable());
|
||||
}
|
||||
|
||||
|
|
|
@ -80,9 +80,6 @@ public:
|
|||
// Set the media as being seekable or not.
|
||||
virtual void SetMediaSeekable(bool aMediaSeekable) = 0;
|
||||
|
||||
// Set the transport level as being seekable or not.
|
||||
virtual void SetTransportSeekable(bool aTransportSeekable) = 0;
|
||||
|
||||
virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
|
||||
virtual mozilla::layers::ImageContainer* GetImageContainer() = 0;
|
||||
|
||||
|
|
|
@ -120,12 +120,6 @@ BufferDecoder::SetMediaSeekable(bool aMediaSeekable)
|
|||
// ignore
|
||||
}
|
||||
|
||||
void
|
||||
BufferDecoder::SetTransportSeekable(bool aTransportSeekable)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
VideoFrameContainer*
|
||||
BufferDecoder::GetVideoFrameContainer()
|
||||
{
|
||||
|
|
|
@ -54,8 +54,6 @@ public:
|
|||
|
||||
virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_OVERRIDE;
|
||||
|
||||
virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_OVERRIDE;
|
||||
virtual layers::ImageContainer* GetImageContainer() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -417,7 +417,6 @@ MediaDecoder::MediaDecoder() :
|
|||
mInitialPlaybackRate(1.0),
|
||||
mInitialPreservesPitch(true),
|
||||
mDuration(-1),
|
||||
mTransportSeekable(true),
|
||||
mMediaSeekable(true),
|
||||
mSameOriginMedia(false),
|
||||
mReentrantMonitor("media.decoder"),
|
||||
|
@ -551,8 +550,6 @@ nsresult MediaDecoder::InitializeStateMachine(MediaDecoder* aCloneDonor)
|
|||
}
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
mDecoderStateMachine->SetTransportSeekable(mTransportSeekable);
|
||||
mDecoderStateMachine->SetMediaSeekable(mMediaSeekable);
|
||||
mDecoderStateMachine->SetDuration(mDuration);
|
||||
mDecoderStateMachine->SetVolume(mInitialVolume);
|
||||
mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
|
||||
|
@ -1286,25 +1283,14 @@ void MediaDecoder::SetMediaSeekable(bool aMediaSeekable) {
|
|||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
MOZ_ASSERT(NS_IsMainThread() || OnDecodeThread());
|
||||
mMediaSeekable = aMediaSeekable;
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->SetMediaSeekable(aMediaSeekable);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::SetTransportSeekable(bool aTransportSeekable)
|
||||
bool
|
||||
MediaDecoder::IsTransportSeekable()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
MOZ_ASSERT(NS_IsMainThread() || OnDecodeThread());
|
||||
mTransportSeekable = aTransportSeekable;
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->SetTransportSeekable(aTransportSeekable);
|
||||
}
|
||||
}
|
||||
|
||||
bool MediaDecoder::IsTransportSeekable()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mTransportSeekable;
|
||||
MOZ_ASSERT(OnDecodeThread() || NS_IsMainThread());
|
||||
return GetResource()->IsTransportSeekable();
|
||||
}
|
||||
|
||||
bool MediaDecoder::IsMediaSeekable()
|
||||
|
|
|
@ -608,7 +608,7 @@ public:
|
|||
|
||||
// Set a flag indicating whether seeking is supported
|
||||
virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;
|
||||
virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// Returns true if this media supports seeking. False for example for WebM
|
||||
// files without an index and chained ogg files.
|
||||
virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
@ -1037,10 +1037,6 @@ protected:
|
|||
// True when playback should start with audio captured (not playing).
|
||||
bool mInitialAudioCaptured;
|
||||
|
||||
// True if the resource is seekable at a transport level (server supports byte
|
||||
// range requests, local file, etc.).
|
||||
bool mTransportSeekable;
|
||||
|
||||
// True if the media is seekable (i.e. supports random access).
|
||||
bool mMediaSeekable;
|
||||
|
||||
|
|
|
@ -173,6 +173,10 @@ public:
|
|||
|
||||
MediaInfo GetMediaInfo() { return mInfo; }
|
||||
|
||||
// Indicates if the media is seekable.
|
||||
// ReadMetada should be called before calling this method.
|
||||
virtual bool IsMediaSeekable() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~MediaDecoderReader();
|
||||
|
||||
|
|
|
@ -202,8 +202,6 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
mAudioRequestPending(false),
|
||||
mVideoRequestPending(false),
|
||||
mAudioCaptured(false),
|
||||
mTransportSeekable(true),
|
||||
mMediaSeekable(true),
|
||||
mPositionChangeQueued(false),
|
||||
mAudioCompleted(false),
|
||||
mGotDurationFromMetaData(false),
|
||||
|
@ -1602,23 +1600,6 @@ void MediaDecoderStateMachine::SetFragmentEndTime(int64_t aEndTime)
|
|||
mFragmentEndTime = aEndTime < 0 ? aEndTime : aEndTime + mStartTime;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SetTransportSeekable(bool aTransportSeekable)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(),
|
||||
"Should be on main thread or the decoder thread.");
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
mTransportSeekable = aTransportSeekable;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SetMediaSeekable(bool aMediaSeekable)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(),
|
||||
"Should be on main thread or the decoder thread.");
|
||||
|
||||
mMediaSeekable = aMediaSeekable;
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::IsDormantNeeded()
|
||||
{
|
||||
return mReader->IsDormantNeeded();
|
||||
|
@ -1775,7 +1756,8 @@ void MediaDecoderStateMachine::Seek(const SeekTarget& aTarget)
|
|||
|
||||
// We need to be able to seek both at a transport level and at a media level
|
||||
// to seek.
|
||||
if (!mMediaSeekable) {
|
||||
if (!mDecoder->IsMediaSeekable()) {
|
||||
NS_WARNING("Seek() function should not be called on a non-seekable state machine");
|
||||
return;
|
||||
}
|
||||
// MediaDecoder::mPlayState should be SEEKING while we seek, and
|
||||
|
@ -2186,15 +2168,21 @@ nsresult MediaDecoderStateMachine::DecodeMetadata()
|
|||
ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
|
||||
res = mReader->ReadMetadata(&info, getter_Transfers(mMetadataTags));
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
if (mState == DECODER_STATE_DECODING_METADATA &&
|
||||
mReader->IsWaitingMediaResources()) {
|
||||
// change state to DECODER_STATE_WAIT_FOR_RESOURCES
|
||||
StartWaitForResources();
|
||||
// affect values only if ReadMetadata succeeds
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
mDecoder->SetMediaSeekable(mReader->IsMediaSeekable());
|
||||
}
|
||||
|
||||
mInfo = info;
|
||||
|
||||
if (NS_FAILED(res) || (!info.HasValidMedia())) {
|
||||
|
@ -2266,13 +2254,16 @@ MediaDecoderStateMachine::FinishDecodeMetadata()
|
|||
|
||||
NS_ASSERTION(mStartTime != -1, "Must have start time");
|
||||
MOZ_ASSERT((!HasVideo() && !HasAudio()) ||
|
||||
!(mMediaSeekable && mTransportSeekable) || mEndTime != -1,
|
||||
"Active seekable media should have end time");
|
||||
MOZ_ASSERT(!(mMediaSeekable && mTransportSeekable) ||
|
||||
GetDuration() != -1, "Seekable media should have duration");
|
||||
!(mDecoder->IsMediaSeekable() && mDecoder->IsTransportSeekable()) ||
|
||||
mEndTime != -1,
|
||||
"Active seekable media should have end time");
|
||||
MOZ_ASSERT(!(mDecoder->IsMediaSeekable() && mDecoder->IsTransportSeekable()) ||
|
||||
GetDuration() != -1,
|
||||
"Seekable media should have duration");
|
||||
DECODER_LOG(PR_LOG_DEBUG, "Media goes from %lld to %lld (duration %lld) "
|
||||
"transportSeekable=%d, mediaSeekable=%d",
|
||||
mStartTime, mEndTime, GetDuration(), mTransportSeekable, mMediaSeekable);
|
||||
"transportSeekable=%d, mediaSeekable=%d",
|
||||
mStartTime, mEndTime, GetDuration(),
|
||||
mDecoder->IsTransportSeekable(), mDecoder->IsMediaSeekable());
|
||||
|
||||
if (HasAudio() && !HasVideo()) {
|
||||
// We're playing audio only. We don't need to worry about slow video
|
||||
|
|
|
@ -209,17 +209,6 @@ public:
|
|||
// be called with the decode monitor held.
|
||||
void ClearPositionChangeFlag();
|
||||
|
||||
// Called from the main thread or the decoder thread to set whether the media
|
||||
// resource can seek into unbuffered ranges. The decoder monitor must be
|
||||
// obtained before calling this.
|
||||
void SetTransportSeekable(bool aSeekable);
|
||||
|
||||
// Called from the main thread or the decoder thread to set whether the media
|
||||
// can seek to random location. This is not true for chained ogg and WebM
|
||||
// media without index. The decoder monitor must be obtained before calling
|
||||
// this.
|
||||
void SetMediaSeekable(bool aSeekable);
|
||||
|
||||
// Update the playback position. This can result in a timeupdate event
|
||||
// and an invalidate of the frame being dispatched asynchronously if
|
||||
// there is no such event currently queued.
|
||||
|
@ -290,16 +279,6 @@ public:
|
|||
return mEndTime;
|
||||
}
|
||||
|
||||
bool IsTransportSeekable() {
|
||||
AssertCurrentThreadInMonitor();
|
||||
return mTransportSeekable;
|
||||
}
|
||||
|
||||
bool IsMediaSeekable() {
|
||||
AssertCurrentThreadInMonitor();
|
||||
return mMediaSeekable;
|
||||
}
|
||||
|
||||
// Returns the shared state machine thread.
|
||||
nsIEventTarget* GetStateMachineThread();
|
||||
|
||||
|
@ -908,14 +887,6 @@ protected:
|
|||
// the audio thread will never start again after it has stopped.
|
||||
bool mAudioCaptured;
|
||||
|
||||
// True if the media resource can be seeked on a transport level. Accessed
|
||||
// from the state machine and main threads. Synchronised via decoder monitor.
|
||||
bool mTransportSeekable;
|
||||
|
||||
// True if the media can be seeked. Accessed from the state machine and main
|
||||
// threads. Synchronised via decoder monitor.
|
||||
bool mMediaSeekable;
|
||||
|
||||
// True if an event to notify about a change in the playback
|
||||
// position has been queued, but not yet run. It is set to false when
|
||||
// the event is run. This allows coalescing of these events as they can be
|
||||
|
|
|
@ -348,7 +348,6 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest)
|
|||
|
||||
mDecoder->SetInfinite(!dataIsBounded);
|
||||
}
|
||||
mDecoder->SetTransportSeekable(seekable);
|
||||
mCacheStream.SetTransportSeekable(seekable);
|
||||
|
||||
{
|
||||
|
|
|
@ -607,9 +607,7 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
|
|||
if (duration) {
|
||||
// Not live stream.
|
||||
mRealTime = false;
|
||||
bool seekable = true;
|
||||
mDecoder->SetInfinite(false);
|
||||
mDecoder->SetTransportSeekable(seekable);
|
||||
mDecoder->SetDuration(duration);
|
||||
} else {
|
||||
// Live stream.
|
||||
|
@ -624,7 +622,6 @@ RtspMediaResource::OnConnected(uint8_t aTrackIdx,
|
|||
mRealTime = true;
|
||||
bool seekable = false;
|
||||
mDecoder->SetInfinite(true);
|
||||
mDecoder->SetTransportSeekable(seekable);
|
||||
mDecoder->SetMediaSeekable(seekable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -329,6 +329,12 @@ AppleMP3Reader::HasVideo()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
AppleMP3Reader::IsMediaSeekable()
|
||||
{
|
||||
// not used
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the MP3 parser for a piece of metadata.
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
uint32_t aLength,
|
||||
int64_t aOffset) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
void SetupDecoder();
|
||||
nsresult Read(uint32_t *aNumBytes, char *aData);
|
||||
|
|
|
@ -211,10 +211,6 @@ DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
|||
|
||||
DWORD seekCaps = 0;
|
||||
hr = mMediaSeeking->GetCapabilities(&seekCaps);
|
||||
bool canSeek = ((AM_SEEKING_CanSeekAbsolute & seekCaps) == AM_SEEKING_CanSeekAbsolute);
|
||||
if (!canSeek) {
|
||||
mDecoder->SetMediaSeekable(false);
|
||||
}
|
||||
|
||||
int64_t duration = mMP3FrameParser.GetDuration();
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
@ -232,6 +228,15 @@ DirectShowReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
DirectShowReader::IsMediaSeekable()
|
||||
{
|
||||
DWORD seekCaps = 0;
|
||||
HRESULT hr = mMediaSeeking->GetCapabilities(&seekCaps);
|
||||
return ((AM_SEEKING_CanSeekAbsolute & seekCaps) ==
|
||||
AM_SEEKING_CanSeekAbsolute);
|
||||
}
|
||||
|
||||
inline float
|
||||
UnsignedByteToAudioSample(uint8_t aValue)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
uint32_t aLength,
|
||||
int64_t aOffset) MOZ_OVERRIDE;
|
||||
|
||||
bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
// Notifies the filter graph that playback is complete. aStatus is
|
||||
|
|
|
@ -243,11 +243,6 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
|
|||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->SetMediaDuration(duration);
|
||||
}
|
||||
// We can seek if we get a duration *and* the reader reports that it's
|
||||
// seekable.
|
||||
if (!mDecoder->GetResource()->IsTransportSeekable() || !mDemuxer->CanSeek()) {
|
||||
mDecoder->SetMediaSeekable(false);
|
||||
}
|
||||
|
||||
*aInfo = mInfo;
|
||||
*aTags = nullptr;
|
||||
|
@ -255,6 +250,14 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MP4Reader::IsMediaSeekable()
|
||||
{
|
||||
// We can seek if we get a duration *and* the reader reports that it's
|
||||
// seekable.
|
||||
return mDecoder->GetResource()->IsTransportSeekable() && mDemuxer->CanSeek();
|
||||
}
|
||||
|
||||
bool
|
||||
MP4Reader::HasAudio()
|
||||
{
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
// Destroys all decoder resources.
|
||||
|
|
|
@ -437,8 +437,6 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,
|
|||
LOG(PR_LOG_DEBUG, "have duration %" GST_TIME_FORMAT, GST_TIME_ARGS(duration));
|
||||
duration = GST_TIME_AS_USECONDS (duration);
|
||||
mDecoder->SetMediaDuration(duration);
|
||||
} else {
|
||||
mDecoder->SetMediaSeekable(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,6 +463,28 @@ nsresult GStreamerReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
GStreamerReader::IsMediaSeekable()
|
||||
{
|
||||
if (mUseParserDuration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
gint64 duration;
|
||||
#if GST_VERSION_MAJOR >= 1
|
||||
if (gst_element_query_duration(GST_ELEMENT(mPlayBin), GST_FORMAT_TIME,
|
||||
&duration)) {
|
||||
#else
|
||||
GstFormat format = GST_FORMAT_TIME;
|
||||
if (gst_element_query_duration(GST_ELEMENT(mPlayBin), &format, &duration) &&
|
||||
format == GST_FORMAT_TIME) {
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult GStreamerReader::CheckSupportedFormats()
|
||||
{
|
||||
bool done = false;
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
|
||||
layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); }
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
void ReadAndPushData(guint aLength);
|
||||
|
|
|
@ -143,6 +143,8 @@ public:
|
|||
return mInfo.HasAudio();
|
||||
}
|
||||
|
||||
bool IsMediaSeekable() { return true; }
|
||||
|
||||
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;
|
||||
nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
@ -513,9 +515,6 @@ MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
|
|||
nsresult
|
||||
MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
|
||||
{
|
||||
mDecoder->SetMediaSeekable(true);
|
||||
mDecoder->SetTransportSeekable(false);
|
||||
|
||||
MSE_DEBUG("%p: MSR::ReadMetadata pending=%u", this, mPendingDecoders.Length());
|
||||
|
||||
InitializePendingDecoders();
|
||||
|
|
|
@ -90,12 +90,6 @@ SubBufferDecoder::SetMediaSeekable(bool aMediaSeekable)
|
|||
//mParentDecoder->SetMediaSeekable(aMediaSeekable);
|
||||
}
|
||||
|
||||
void
|
||||
SubBufferDecoder::SetTransportSeekable(bool aTransportSeekable)
|
||||
{
|
||||
//mParentDecoder->SetTransportSeekable(aTransportSeekable);
|
||||
}
|
||||
|
||||
layers::ImageContainer*
|
||||
SubBufferDecoder::GetImageContainer()
|
||||
{
|
||||
|
|
|
@ -44,7 +44,6 @@ public:
|
|||
virtual void SetMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
|
||||
virtual void UpdateEstimatedMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
|
||||
virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;
|
||||
virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_OVERRIDE;
|
||||
virtual layers::ImageContainer* GetImageContainer() MOZ_OVERRIDE;
|
||||
virtual MediaDecoderOwner* GetOwner() MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -378,12 +378,6 @@ nsresult OggReader::ReadMetadata(MediaInfo* aInfo,
|
|||
LOG(PR_LOG_DEBUG, ("Got Ogg duration from seeking to end %lld", endTime));
|
||||
}
|
||||
mDecoder->GetResource()->EndSeekingForMetadata();
|
||||
} else if (mDecoder->GetMediaDuration() == -1) {
|
||||
// We don't have a duration, and we don't know enough about the resource
|
||||
// to try a seek. Abort trying to get a duration. This happens for example
|
||||
// when the server says it accepts range requests, but does not give us a
|
||||
// Content-Length.
|
||||
mDecoder->SetTransportSeekable(false);
|
||||
}
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -393,6 +387,15 @@ nsresult OggReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
OggReader::IsMediaSeekable()
|
||||
{
|
||||
if (mIsChained) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult OggReader::DecodeVorbis(ogg_packet* aPacket) {
|
||||
NS_ASSERTION(aPacket->granulepos != -1, "Must know vorbis granulepos!");
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// This monitor should be taken when reading or writing to mIsChained.
|
||||
ReentrantMonitor mMonitor;
|
||||
|
|
|
@ -161,9 +161,6 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||
mDecoder->SetMediaDuration(durationUs);
|
||||
}
|
||||
|
||||
// Check the MediaExtract flag if the source is seekable.
|
||||
mDecoder->SetMediaSeekable(mExtractor->flags() & MediaExtractor::CAN_SEEK);
|
||||
|
||||
if (mOmxDecoder->HasVideo()) {
|
||||
int32_t displayWidth, displayHeight, width, height;
|
||||
mOmxDecoder->GetVideoParameters(&displayWidth, &displayHeight,
|
||||
|
@ -204,6 +201,13 @@ nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaOmxReader::IsMediaSeekable()
|
||||
{
|
||||
// Check the MediaExtract flag if the source is seekable.
|
||||
return (mExtractor->flags() & MediaExtractor::CAN_SEEK);
|
||||
}
|
||||
|
||||
bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
int64_t aTimeThreshold)
|
||||
{
|
||||
|
|
|
@ -84,6 +84,8 @@ public:
|
|||
MetadataTags** aTags);
|
||||
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetIdle() MOZ_OVERRIDE;
|
||||
|
||||
virtual void Shutdown() MOZ_OVERRIDE;
|
||||
|
|
|
@ -61,6 +61,12 @@ public:
|
|||
return mHasVideo;
|
||||
}
|
||||
|
||||
virtual bool IsMediaSeekable()
|
||||
{
|
||||
// not used
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags);
|
||||
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
|
|
|
@ -112,6 +112,13 @@ nsresult RawReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
RawReader::IsMediaSeekable()
|
||||
{
|
||||
// not used
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawReader::DecodeAudioData()
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
|
||||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
bool ReadFromResource(MediaResource *aResource, uint8_t *aBuf, uint32_t aLength);
|
||||
|
||||
|
|
|
@ -158,6 +158,13 @@ nsresult WaveReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
WaveReader::IsMediaSeekable()
|
||||
{
|
||||
// not used
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> T UnsignedByteToAudioSample(uint8_t aValue);
|
||||
template <typename T> T SignedShortToAudioSample(int16_t aValue);
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
bool ReadAll(char* aBuf, int64_t aSize, int64_t* aBytesRead = nullptr);
|
||||
bool LoadRIFFChunk();
|
||||
|
|
|
@ -464,9 +464,6 @@ nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
|
|||
}
|
||||
}
|
||||
|
||||
// We can't seek in buffered regions if we have no cues.
|
||||
mDecoder->SetMediaSeekable(nestegg_has_cues(mContext) == 1);
|
||||
|
||||
*aInfo = mInfo;
|
||||
|
||||
*aTags = nullptr;
|
||||
|
@ -474,6 +471,12 @@ nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
WebMReader::IsMediaSeekable()
|
||||
{
|
||||
return mContext && nestegg_has_cues(mContext);
|
||||
}
|
||||
|
||||
#ifdef MOZ_OPUS
|
||||
bool WebMReader::InitOpusDecoder()
|
||||
{
|
||||
|
|
|
@ -135,6 +135,8 @@ public:
|
|||
virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
|
||||
|
||||
virtual bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
// Value passed to NextPacket to determine if we are reading a video or an
|
||||
// audio packet.
|
||||
|
|
|
@ -541,14 +541,6 @@ WMFReader::ReadMetadata(MediaInfo* aInfo,
|
|||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->SetMediaEndTime(duration);
|
||||
}
|
||||
// We can seek if we get a duration *and* the reader reports that it's
|
||||
// seekable.
|
||||
bool canSeek = false;
|
||||
if (FAILED(hr) ||
|
||||
FAILED(GetSourceReaderCanSeek(mSourceReader, canSeek)) ||
|
||||
!canSeek) {
|
||||
mDecoder->SetMediaSeekable(false);
|
||||
}
|
||||
|
||||
*aInfo = mInfo;
|
||||
*aTags = nullptr;
|
||||
|
@ -558,6 +550,22 @@ WMFReader::ReadMetadata(MediaInfo* aInfo,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
WMFReader::IsMediaSeekable()
|
||||
{
|
||||
// Get the duration
|
||||
int64_t duration = 0;
|
||||
HRESULT hr = GetSourceReaderDuration(mSourceReader, duration);
|
||||
// We can seek if we get a duration *and* the reader reports that it's
|
||||
// seekable.
|
||||
bool canSeek = false;
|
||||
if (FAILED(hr) || FAILED(GetSourceReaderCanSeek(mSourceReader, canSeek)) ||
|
||||
!canSeek) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WMFReader::DecodeAudioData()
|
||||
{
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
int64_t aStartTime,
|
||||
int64_t aEndTime,
|
||||
int64_t aCurrentTime) MOZ_OVERRIDE;
|
||||
|
||||
bool IsMediaSeekable() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
HRESULT CreateSourceReader();
|
||||
|
|
Загрузка…
Ссылка в новой задаче