Files
palemoon27/dom/media/mediasource/SourceBufferDecoder.cpp
T
trav90 fde7400175 Stop updating playback position from Ogg seek and remove MediaDecoder::UpdatePlaybackPosition
The ogg reader makes two adjustments to the seek time - the first is to clamp it between start and end time, which MDSM already does. The second is to subtract SEEK_OPUS_PREROLL from the target. If we wanted to, we could return this as the resolve value in the seek promise and handle the update in the MDSM. But DropVideoUpToSeekTarget should actually handle this just fine.
2018-07-25 01:03:05 +08:00

287 lines
6.5 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaSourceUtils.h"
#include "SourceBufferDecoder.h"
#include "prlog.h"
#include "AbstractMediaDecoder.h"
#include "MediaDecoderReader.h"
#include "mozilla/dom/TimeRanges.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* GetMediaSourceLog();
/* Polyfill __func__ on MSVC to pass to the log. */
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
#define MSE_DEBUG(arg, ...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, ("SourceBufferDecoder(%p:%s)::%s: " arg, this, mResource->GetContentType().get(), __func__, ##__VA_ARGS__))
#else
#define MSE_DEBUG(...)
#endif
namespace mozilla {
class ReentrantMonitor;
namespace layers {
class ImageContainer;
} // namespace layers
NS_IMPL_ISUPPORTS0(SourceBufferDecoder)
SourceBufferDecoder::SourceBufferDecoder(MediaResource* aResource,
AbstractMediaDecoder* aParentDecoder,
int64_t aTimestampOffset)
: mResource(aResource)
, mParentDecoder(aParentDecoder)
, mReader(nullptr)
, mTimestampOffset(aTimestampOffset)
, mMediaDuration(-1)
, mRealMediaDuration(0)
, mTrimmedOffset(-1)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(SourceBufferDecoder);
}
SourceBufferDecoder::~SourceBufferDecoder()
{
MOZ_COUNT_DTOR(SourceBufferDecoder);
}
bool
SourceBufferDecoder::IsShutdown() const
{
// SourceBufferDecoder cannot be shut down.
MSE_DEBUG("UNIMPLEMENTED");
return false;
}
void
SourceBufferDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
{
MSE_DEBUG("UNIMPLEMENTED");
}
int64_t
SourceBufferDecoder::GetMediaDuration()
{
return mMediaDuration;
}
VideoFrameContainer*
SourceBufferDecoder::GetVideoFrameContainer()
{
MSE_DEBUG("UNIMPLEMENTED");
return nullptr;
}
bool
SourceBufferDecoder::IsTransportSeekable()
{
MSE_DEBUG("UNIMPLEMENTED");
return false;
}
bool
SourceBufferDecoder::IsMediaSeekable()
{
MSE_DEBUG("UNIMPLEMENTED");
return false;
}
void
SourceBufferDecoder::MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags,
MediaDecoderEventVisibility aEventVisibility)
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
MediaDecoderEventVisibility aEventVisibility)
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::QueueMetadata(int64_t aTime,
nsAutoPtr<MediaInfo> aInfo,
nsAutoPtr<MetadataTags> aTags)
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::RemoveMediaTracks()
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::SetMediaEndTime(int64_t aTime)
{
MSE_DEBUG("UNIMPLEMENTED");
}
bool
SourceBufferDecoder::HasInitializationData()
{
return true;
}
void
SourceBufferDecoder::OnReadMetadataCompleted()
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::NotifyWaitingForResourcesStatusChanged()
{
MSE_DEBUG("UNIMPLEMENTED");
}
ReentrantMonitor&
SourceBufferDecoder::GetReentrantMonitor()
{
return mParentDecoder->GetReentrantMonitor();
}
bool
SourceBufferDecoder::OnStateMachineThread() const
{
return mParentDecoder->OnStateMachineThread();
}
bool
SourceBufferDecoder::OnDecodeThread() const
{
// During initialization we run on our TrackBuffer's task queue.
if (mTaskQueue) {
return mTaskQueue->IsCurrentThreadIn();
}
return mParentDecoder->OnDecodeThread();
}
SourceBufferResource*
SourceBufferDecoder::GetResource() const
{
return static_cast<SourceBufferResource*>(mResource.get());
}
void
SourceBufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
uint32_t aDropped)
{
return mParentDecoder->NotifyDecodedFrames(aParsed, aDecoded, aDropped);
}
void
SourceBufferDecoder::SetMediaDuration(int64_t aDuration)
{
mMediaDuration = aDuration;
}
void
SourceBufferDecoder::SetRealMediaDuration(int64_t aDuration)
{
mRealMediaDuration = aDuration;
}
void
SourceBufferDecoder::Trim(int64_t aDuration)
{
mTrimmedOffset = (double)aDuration / USECS_PER_S;
}
void
SourceBufferDecoder::UpdateEstimatedMediaDuration(int64_t aDuration)
{
MSE_DEBUG("UNIMPLEMENTED");
}
void
SourceBufferDecoder::SetMediaSeekable(bool aMediaSeekable)
{
MSE_DEBUG("UNIMPLEMENTED");
}
layers::ImageContainer*
SourceBufferDecoder::GetImageContainer()
{
return mParentDecoder->GetImageContainer();
}
MediaDecoderOwner*
SourceBufferDecoder::GetOwner()
{
return mParentDecoder->GetOwner();
}
void
SourceBufferDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
{
mReader->NotifyDataArrived(aBuffer, aLength, aOffset);
// XXX: Params make no sense to parent decoder as it relates to a
// specific SourceBufferDecoder's data stream. Pass bogus values here to
// force parent decoder's state machine to recompute end time for
// infinite length media.
mParentDecoder->NotifyDataArrived(nullptr, 0, 0);
}
nsresult
SourceBufferDecoder::GetBuffered(dom::TimeRanges* aBuffered)
{
nsresult rv = mReader->GetBuffered(aBuffered);
if (NS_FAILED(rv)) {
return rv;
}
// Adjust buffered range according to timestamp offset.
aBuffered->Shift((double)mTimestampOffset / USECS_PER_S);
if (!WasTrimmed()) {
return NS_OK;
}
nsRefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
tr->Add(0, mTrimmedOffset);
aBuffered->Intersection(tr);
return NS_OK;
}
int64_t
SourceBufferDecoder::ConvertToByteOffset(double aTime)
{
int64_t readerOffset =
mReader->GetEvictionOffset(aTime - double(mTimestampOffset) / USECS_PER_S);
if (readerOffset >= 0) {
return readerOffset;
}
// Uses a conversion based on (aTime/duration) * length. For the
// purposes of eviction this should be adequate since we have the
// byte threshold as well to ensure data actually gets evicted and
// we ensure we don't evict before the current playable point.
if (mRealMediaDuration <= 0) {
return -1;
}
int64_t length = GetResource()->GetLength();
MOZ_ASSERT(length > 0);
int64_t offset =
((aTime - double(mTimestampOffset) / USECS_PER_S) /
(double(mRealMediaDuration) / USECS_PER_S)) * length;
return offset;
}
#undef MSE_DEBUG
} // namespace mozilla