зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 6 changesets (bug 1288329) for wpt failures a=backout
Backed out changeset f33cb032cc9f (bug 1288329) Backed out changeset 49ea83d00a77 (bug 1288329) Backed out changeset 1406c14098f1 (bug 1288329) Backed out changeset 936b73eb37c6 (bug 1288329) Backed out changeset a1c4d9b9de32 (bug 1288329) Backed out changeset a76b6e559777 (bug 1288329) --HG-- extra : amend_source : 4e054fc4af62693934a4ae450a9595443b6a961d
This commit is contained in:
Родитель
b4c6cfd89b
Коммит
8f0a108b9a
|
@ -512,7 +512,6 @@ MediaRawData::Clone() const
|
||||||
s->mExtraData = mExtraData;
|
s->mExtraData = mExtraData;
|
||||||
s->mCryptoInternal = mCryptoInternal;
|
s->mCryptoInternal = mCryptoInternal;
|
||||||
s->mTrackInfo = mTrackInfo;
|
s->mTrackInfo = mTrackInfo;
|
||||||
s->mEOS = mEOS;
|
|
||||||
if (!s->mBuffer.Append(mBuffer.Data(), mBuffer.Length())) {
|
if (!s->mBuffer.Append(mBuffer.Data(), mBuffer.Length())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,10 +656,6 @@ public:
|
||||||
const CryptoSample& mCrypto;
|
const CryptoSample& mCrypto;
|
||||||
RefPtr<MediaByteBuffer> mExtraData;
|
RefPtr<MediaByteBuffer> mExtraData;
|
||||||
|
|
||||||
// Used by the Vorbis decoder and Ogg demuxer.
|
|
||||||
// Indicates that this is the last packet of the stream.
|
|
||||||
bool mEOS = false;
|
|
||||||
|
|
||||||
RefPtr<SharedTrackInfo> mTrackInfo;
|
RefPtr<SharedTrackInfo> mTrackInfo;
|
||||||
|
|
||||||
// Return a deep copy or nullptr if out of memory.
|
// Return a deep copy or nullptr if out of memory.
|
||||||
|
|
|
@ -291,16 +291,6 @@ public:
|
||||||
// Notified by the OggReader during playback when chained ogg is detected.
|
// Notified by the OggReader during playback when chained ogg is detected.
|
||||||
MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
|
MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
|
||||||
|
|
||||||
TimedMetadataEventProducer& TimedMetadataProducer()
|
|
||||||
{
|
|
||||||
return mTimedMetadataEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaEventProducer<void>& MediaNotSeekableProducer()
|
|
||||||
{
|
|
||||||
return mOnMediaNotSeekable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSuspended() const
|
bool IsSuspended() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
|
|
|
@ -247,7 +247,6 @@ OggCodecState::PacketOutAsMediaRawData()
|
||||||
sample->mTime = end_tstamp - duration;
|
sample->mTime = end_tstamp - duration;
|
||||||
sample->mDuration = duration;
|
sample->mDuration = duration;
|
||||||
sample->mKeyframe = IsKeyframe(packet);
|
sample->mKeyframe = IsKeyframe(packet);
|
||||||
sample->mEOS = packet->e_o_s;
|
|
||||||
|
|
||||||
ReleasePacket(packet);
|
ReleasePacket(packet);
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,9 @@ MediaDecoderStateMachine* OggDecoder::CreateStateMachine()
|
||||||
{
|
{
|
||||||
bool useFormatDecoder =
|
bool useFormatDecoder =
|
||||||
Preferences::GetBool("media.format-reader.ogg", true);
|
Preferences::GetBool("media.format-reader.ogg", true);
|
||||||
RefPtr<OggDemuxer> demuxer =
|
RefPtr<MediaDecoderReader> reader = useFormatDecoder ?
|
||||||
useFormatDecoder ? new OggDemuxer(GetResource()) : nullptr;
|
static_cast<MediaDecoderReader*>(new MediaFormatReader(this, new OggDemuxer(GetResource()), GetVideoFrameContainer())) :
|
||||||
RefPtr<MediaDecoderReader> reader = useFormatDecoder
|
new OggReader(this);
|
||||||
? static_cast<MediaDecoderReader*>(new MediaFormatReader(this, demuxer, GetVideoFrameContainer()))
|
|
||||||
: new OggReader(this);
|
|
||||||
if (useFormatDecoder) {
|
|
||||||
demuxer->SetChainingEvents(&reader->TimedMetadataProducer(),
|
|
||||||
&reader->MediaNotSeekableProducer());
|
|
||||||
}
|
|
||||||
return new MediaDecoderStateMachine(this, reader);
|
return new MediaDecoderStateMachine(this, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,7 @@ extern mozilla::LazyLogModule gMediaDemuxerLog;
|
||||||
#define SEEK_LOG(type, msg)
|
#define SEEK_LOG(type, msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace mozilla
|
namespace mozilla {
|
||||||
{
|
|
||||||
|
|
||||||
using media::TimeUnit;
|
using media::TimeUnit;
|
||||||
using media::TimeInterval;
|
using media::TimeInterval;
|
||||||
|
@ -49,8 +48,7 @@ static const uint32_t OGG_SEEK_FUZZ_USECS = 500000;
|
||||||
// The specification recommends 80 ms.
|
// The specification recommends 80 ms.
|
||||||
static const int64_t OGG_SEEK_OPUS_PREROLL = 80 * USECS_PER_MS;
|
static const int64_t OGG_SEEK_OPUS_PREROLL = 80 * USECS_PER_MS;
|
||||||
|
|
||||||
class OggHeaders
|
class OggHeaders {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
OggHeaders() {}
|
OggHeaders() {}
|
||||||
~OggHeaders()
|
~OggHeaders()
|
||||||
|
@ -135,8 +133,7 @@ OggDemuxer::OggDemuxer(MediaResource* aResource)
|
||||||
, mTheoraSerial(0)
|
, mTheoraSerial(0)
|
||||||
, mOpusPreSkip(0)
|
, mOpusPreSkip(0)
|
||||||
, mIsChained(false)
|
, mIsChained(false)
|
||||||
, mTimedMetadataEvent(nullptr)
|
, mDecodedAudioFrames(0)
|
||||||
, mOnSeekableEvent(nullptr)
|
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(OggDemuxer);
|
MOZ_COUNT_CTOR(OggDemuxer);
|
||||||
PodZero(&mTheoraInfo);
|
PodZero(&mTheoraInfo);
|
||||||
|
@ -159,15 +156,6 @@ OggDemuxer::~OggDemuxer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
OggDemuxer::SetChainingEvents(TimedMetadataEventProducer* aMetadataEvent,
|
|
||||||
MediaEventProducer<void>* aOnSeekableEvent)
|
|
||||||
{
|
|
||||||
mTimedMetadataEvent = aMetadataEvent;
|
|
||||||
mOnSeekableEvent = aOnSeekableEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OggDemuxer::HasAudio()
|
OggDemuxer::HasAudio()
|
||||||
const
|
const
|
||||||
|
@ -192,29 +180,32 @@ const
|
||||||
int64_t
|
int64_t
|
||||||
OggDemuxer::StartTime() const
|
OggDemuxer::StartTime() const
|
||||||
{
|
{
|
||||||
return mStartTime.refOr(0);
|
MOZ_ASSERT(HaveStartTime());
|
||||||
|
return mStartTime.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OggDemuxer::HaveStartTime(TrackInfo::TrackType aType)
|
OggDemuxer::HaveStartTime(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
return OggState(aType).mStartTime.isSome();
|
return (aType == TrackInfo::kAudioTrack ? mAudioOggState : mVideoOggState)
|
||||||
|
.mStartTime.isSome();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
OggDemuxer::StartTime(TrackInfo::TrackType aType)
|
OggDemuxer::StartTime(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
return OggState(aType).mStartTime.refOr(TimeUnit::FromMicroseconds(0)).ToMicroseconds();
|
return (aType == TrackInfo::kAudioTrack ? mAudioOggState : mVideoOggState)
|
||||||
|
.mStartTime.refOr(TimeUnit::FromMicroseconds(0)).ToMicroseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<OggDemuxer::InitPromise>
|
RefPtr<OggDemuxer::InitPromise>
|
||||||
OggDemuxer::Init()
|
OggDemuxer::Init()
|
||||||
{
|
{
|
||||||
int ret = ogg_sync_init(OggSyncState(TrackInfo::kAudioTrack));
|
int ret = ogg_sync_init(OggState(TrackInfo::kAudioTrack));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||||
}
|
}
|
||||||
ret = ogg_sync_init(OggSyncState(TrackInfo::kVideoTrack));
|
ret = ogg_sync_init(OggState(TrackInfo::kVideoTrack));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
return InitPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
|
||||||
}
|
}
|
||||||
|
@ -314,12 +305,11 @@ nsresult
|
||||||
OggDemuxer::Reset(TrackInfo::TrackType aType)
|
OggDemuxer::Reset(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
// Discard any previously buffered packets/pages.
|
// Discard any previously buffered packets/pages.
|
||||||
ogg_sync_reset(OggSyncState(aType));
|
ogg_sync_reset(OggState(aType));
|
||||||
OggCodecState* trackState = GetTrackCodecState(aType);
|
OggCodecState* trackState = GetTrackCodecState(aType);
|
||||||
if (trackState) {
|
if (trackState) {
|
||||||
return trackState->Reset();
|
return trackState->Reset();
|
||||||
}
|
}
|
||||||
OggState(aType).mNeedKeyframe = true;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,8 +666,9 @@ OggDemuxer::ReadMetadata()
|
||||||
if (HasAudio() || HasVideo()) {
|
if (HasAudio() || HasVideo()) {
|
||||||
int64_t startTime = -1;
|
int64_t startTime = -1;
|
||||||
FindStartTime(startTime);
|
FindStartTime(startTime);
|
||||||
|
NS_ASSERTION(startTime >= 0, "Must have a non-negative start time");
|
||||||
|
OGG_DEBUG("Detected stream start time %lld", startTime);
|
||||||
if (startTime >= 0) {
|
if (startTime >= 0) {
|
||||||
OGG_DEBUG("Detected stream start time %lld", startTime);
|
|
||||||
mStartTime.emplace(startTime);
|
mStartTime.emplace(startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,13 +715,12 @@ OggDemuxer::SetChained() {
|
||||||
}
|
}
|
||||||
mIsChained = true;
|
mIsChained = true;
|
||||||
}
|
}
|
||||||
if (mOnSeekableEvent) {
|
// @FIXME how can MediaDataDemuxer / MediaTrackDemuxer notify this has changed?
|
||||||
mOnSeekableEvent->Notify();
|
//mOnMediaNotSeekable.Notify();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime)
|
OggDemuxer::ReadOggChain()
|
||||||
{
|
{
|
||||||
bool chained = false;
|
bool chained = false;
|
||||||
OpusState* newOpusState = nullptr;
|
OpusState* newOpusState = nullptr;
|
||||||
|
@ -762,7 +752,8 @@ OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime)
|
||||||
newVorbisState = static_cast<VorbisState*>(codecState.get());
|
newVorbisState = static_cast<VorbisState*>(codecState.get());
|
||||||
} else if (mOpusState && (codecState->GetType() == OggCodecState::TYPE_OPUS)) {
|
} else if (mOpusState && (codecState->GetType() == OggCodecState::TYPE_OPUS)) {
|
||||||
newOpusState = static_cast<OpusState*>(codecState.get());
|
newOpusState = static_cast<OpusState*>(codecState.get());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,13 +814,15 @@ OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime)
|
||||||
|
|
||||||
if (chained) {
|
if (chained) {
|
||||||
SetChained();
|
SetChained();
|
||||||
mInfo.mMediaSeekable = false;
|
{
|
||||||
mDecodedAudioDuration += aLastEndTime;
|
// @FIXME notify this!
|
||||||
if (mTimedMetadataEvent) {
|
/*
|
||||||
mTimedMetadataEvent->Notify(
|
auto t = mDecodedAudioFrames * USECS_PER_S / mInfo.mAudio.mRate;
|
||||||
TimedMetadata(mDecodedAudioDuration,
|
mTimedMetadataEvent.Notify(
|
||||||
|
TimedMetadata(TimeUnit::FromMicroseconds(t),
|
||||||
Move(tags),
|
Move(tags),
|
||||||
nsAutoPtr<MediaInfo>(new MediaInfo(mInfo))));
|
nsAutoPtr<MediaInfo>(new MediaInfo(mInfo))));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -837,25 +830,22 @@ OggDemuxer::ReadOggChain(const media::TimeUnit& aLastEndTime)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OggDemuxer::OggStateContext&
|
ogg_sync_state*
|
||||||
OggDemuxer::OggState(TrackInfo::TrackType aType)
|
OggDemuxer::OggState(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
if (aType == TrackInfo::kVideoTrack) {
|
if (aType == TrackInfo::kVideoTrack) {
|
||||||
return mVideoOggState;
|
return &mVideoOggState.mOggState.mState;
|
||||||
}
|
}
|
||||||
return mAudioOggState;
|
return &mAudioOggState.mOggState.mState;
|
||||||
}
|
|
||||||
|
|
||||||
ogg_sync_state*
|
|
||||||
OggDemuxer::OggSyncState(TrackInfo::TrackType aType)
|
|
||||||
{
|
|
||||||
return &OggState(aType).mOggState.mState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaResourceIndex*
|
MediaResourceIndex*
|
||||||
OggDemuxer::Resource(TrackInfo::TrackType aType)
|
OggDemuxer::Resource(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
return &OggState(aType).mResource;
|
if (aType == TrackInfo::kVideoTrack) {
|
||||||
|
return &mVideoOggState.mResource;
|
||||||
|
}
|
||||||
|
return &mAudioOggState.mResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaResourceIndex*
|
MediaResourceIndex*
|
||||||
|
@ -868,7 +858,7 @@ bool
|
||||||
OggDemuxer::ReadOggPage(TrackInfo::TrackType aType, ogg_page* aPage)
|
OggDemuxer::ReadOggPage(TrackInfo::TrackType aType, ogg_page* aPage)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while((ret = ogg_sync_pageseek(OggSyncState(aType), aPage)) <= 0) {
|
while((ret = ogg_sync_pageseek(OggState(aType), aPage)) <= 0) {
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// Lost page sync, have to skip up to next page.
|
// Lost page sync, have to skip up to next page.
|
||||||
continue;
|
continue;
|
||||||
|
@ -876,7 +866,7 @@ OggDemuxer::ReadOggPage(TrackInfo::TrackType aType, ogg_page* aPage)
|
||||||
// Returns a buffer that can be written too
|
// Returns a buffer that can be written too
|
||||||
// with the given size. This buffer is stored
|
// with the given size. This buffer is stored
|
||||||
// in the ogg synchronisation structure.
|
// in the ogg synchronisation structure.
|
||||||
char* buffer = ogg_sync_buffer(OggSyncState(aType), 4096);
|
char* buffer = ogg_sync_buffer(OggState(aType), 4096);
|
||||||
NS_ASSERTION(buffer, "ogg_sync_buffer failed");
|
NS_ASSERTION(buffer, "ogg_sync_buffer failed");
|
||||||
|
|
||||||
// Read from the resource into the buffer
|
// Read from the resource into the buffer
|
||||||
|
@ -890,7 +880,7 @@ OggDemuxer::ReadOggPage(TrackInfo::TrackType aType, ogg_page* aPage)
|
||||||
|
|
||||||
// Update the synchronisation layer with the number
|
// Update the synchronisation layer with the number
|
||||||
// of bytes written to the buffer
|
// of bytes written to the buffer
|
||||||
ret = ogg_sync_wrote(OggSyncState(aType), bytesRead);
|
ret = ogg_sync_wrote(OggState(aType), bytesRead);
|
||||||
NS_ENSURE_TRUE(ret == 0, false);
|
NS_ENSURE_TRUE(ret == 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,27 +928,15 @@ OggDemuxer::GetNextPacket(TrackInfo::TrackType aType)
|
||||||
{
|
{
|
||||||
OggCodecState* state = GetTrackCodecState(aType);
|
OggCodecState* state = GetTrackCodecState(aType);
|
||||||
ogg_packet* packet = nullptr;
|
ogg_packet* packet = nullptr;
|
||||||
OggStateContext& context = OggState(aType);
|
|
||||||
|
|
||||||
while (true) {
|
do {
|
||||||
if (packet) {
|
if (packet) {
|
||||||
OggCodecState::ReleasePacket(state->PacketOut());
|
OggCodecState::ReleasePacket(state->PacketOut());
|
||||||
}
|
}
|
||||||
DemuxUntilPacketAvailable(aType, state);
|
DemuxUntilPacketAvailable(aType, state);
|
||||||
|
|
||||||
packet = state->PacketPeek();
|
packet = state->PacketPeek();
|
||||||
if (!packet) {
|
} while (packet && state->IsHeader(packet));
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (state->IsHeader(packet)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (context.mNeedKeyframe && !state->IsKeyframe(packet)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
context.mNeedKeyframe = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
@ -1151,9 +1129,9 @@ OggDemuxer::SeekInternal(TrackInfo::TrackType aType, const TimeUnit& aTarget)
|
||||||
adjustedTarget = std::max(startTime, target - OGG_SEEK_OPUS_PREROLL);
|
adjustedTarget = std::max(startTime, target - OGG_SEEK_OPUS_PREROLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HaveStartTime(aType) || adjustedTarget == startTime) {
|
if (adjustedTarget == startTime) {
|
||||||
// We've seeked to the media start or we can't seek.
|
// We've seeked to the media start. Just seek to the offset of the first
|
||||||
// Just seek to the offset of the first content page.
|
// content page.
|
||||||
res = Resource(aType)->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
res = Resource(aType)->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||||
NS_ENSURE_SUCCESS(res,res);
|
NS_ENSURE_SUCCESS(res,res);
|
||||||
|
|
||||||
|
@ -1257,7 +1235,8 @@ OggDemuxer::SeekToKeyframeUsingIndex(TrackInfo::TrackType aType, int64_t aTarget
|
||||||
SkeletonState::nsSeekTarget keyframe;
|
SkeletonState::nsSeekTarget keyframe;
|
||||||
if (NS_FAILED(mSkeletonState->IndexedSeekTarget(aTarget,
|
if (NS_FAILED(mSkeletonState->IndexedSeekTarget(aTarget,
|
||||||
tracks,
|
tracks,
|
||||||
keyframe))) {
|
keyframe)))
|
||||||
|
{
|
||||||
// Could not locate a keypoint for the target in the index.
|
// Could not locate a keypoint for the target in the index.
|
||||||
return SEEK_INDEX_FAIL;
|
return SEEK_INDEX_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1267,7 +1246,8 @@ OggDemuxer::SeekToKeyframeUsingIndex(TrackInfo::TrackType aType, int64_t aTarget
|
||||||
|
|
||||||
// Seek to the keypoint returned by the index.
|
// Seek to the keypoint returned by the index.
|
||||||
if (keyframe.mKeyPoint.mOffset > Resource(aType)->GetLength() ||
|
if (keyframe.mKeyPoint.mOffset > Resource(aType)->GetLength() ||
|
||||||
keyframe.mKeyPoint.mOffset < 0) {
|
keyframe.mKeyPoint.mOffset < 0)
|
||||||
|
{
|
||||||
// Index must be invalid.
|
// Index must be invalid.
|
||||||
return RollbackIndexedSeek(aType, tell);
|
return RollbackIndexedSeek(aType, tell);
|
||||||
}
|
}
|
||||||
|
@ -1286,7 +1266,7 @@ OggDemuxer::SeekToKeyframeUsingIndex(TrackInfo::TrackType aType, int64_t aTarget
|
||||||
ogg_page page;
|
ogg_page page;
|
||||||
int skippedBytes = 0;
|
int skippedBytes = 0;
|
||||||
PageSyncResult syncres = PageSync(Resource(aType),
|
PageSyncResult syncres = PageSync(Resource(aType),
|
||||||
OggSyncState(aType),
|
OggState(aType),
|
||||||
false,
|
false,
|
||||||
keyframe.mKeyPoint.mOffset,
|
keyframe.mKeyPoint.mOffset,
|
||||||
Resource(aType)->GetLength(),
|
Resource(aType)->GetLength(),
|
||||||
|
@ -1306,7 +1286,8 @@ OggDemuxer::SeekToKeyframeUsingIndex(TrackInfo::TrackType aType, int64_t aTarget
|
||||||
}
|
}
|
||||||
OggCodecState* codecState = mCodecStore.Get(serial);
|
OggCodecState* codecState = mCodecStore.Get(serial);
|
||||||
if (codecState && codecState->mActive &&
|
if (codecState && codecState->mActive &&
|
||||||
ogg_stream_pagein(&codecState->mState, &page) != 0) {
|
ogg_stream_pagein(&codecState->mState, &page) != 0)
|
||||||
|
{
|
||||||
// Couldn't insert page into the ogg resource, or somehow the resource
|
// Couldn't insert page into the ogg resource, or somehow the resource
|
||||||
// is no longer active.
|
// is no longer active.
|
||||||
return RollbackIndexedSeek(aType, tell);
|
return RollbackIndexedSeek(aType, tell);
|
||||||
|
@ -1443,7 +1424,7 @@ OggTrackDemuxer::NextSample()
|
||||||
if (eos) {
|
if (eos) {
|
||||||
// We've encountered an end of bitstream packet; check for a chained
|
// We've encountered an end of bitstream packet; check for a chained
|
||||||
// bitstream following this one.
|
// bitstream following this one.
|
||||||
mParent->ReadOggChain(TimeUnit::FromMicroseconds(data->GetEndTime()));
|
mParent->ReadOggChain();
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1507,10 @@ OggDemuxer::GetPageChecksum(ogg_page* page)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const unsigned char* p = page->header + 22;
|
const unsigned char* p = page->header + 22;
|
||||||
uint32_t c = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
|
uint32_t c = p[0] +
|
||||||
|
(p[1] << 8) +
|
||||||
|
(p[2] << 16) +
|
||||||
|
(p[3] << 24);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1543,14 +1527,11 @@ OggDemuxer::RangeStartTime(TrackInfo::TrackType aType, int64_t aOffset)
|
||||||
return startTime;
|
return startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nsDemuxerAutoOggSyncState
|
struct nsDemuxerAutoOggSyncState {
|
||||||
{
|
nsDemuxerAutoOggSyncState() {
|
||||||
nsDemuxerAutoOggSyncState()
|
|
||||||
{
|
|
||||||
ogg_sync_init(&mState);
|
ogg_sync_init(&mState);
|
||||||
}
|
}
|
||||||
~nsDemuxerAutoOggSyncState()
|
~nsDemuxerAutoOggSyncState() {
|
||||||
{
|
|
||||||
ogg_sync_clear(&mState);
|
ogg_sync_clear(&mState);
|
||||||
}
|
}
|
||||||
ogg_sync_state mState;
|
ogg_sync_state mState;
|
||||||
|
@ -1968,7 +1949,7 @@ OggDemuxer::SeekBisection(TrackInfo::TrackType aType,
|
||||||
// granule time of the audio and video bitstreams there. We can then
|
// granule time of the audio and video bitstreams there. We can then
|
||||||
// make a bisection decision based on our location in the media.
|
// make a bisection decision based on our location in the media.
|
||||||
PageSyncResult pageSyncResult = PageSync(Resource(aType),
|
PageSyncResult pageSyncResult = PageSync(Resource(aType),
|
||||||
OggSyncState(aType),
|
OggState(aType),
|
||||||
false,
|
false,
|
||||||
guess,
|
guess,
|
||||||
endOffset,
|
endOffset,
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "MediaDataDemuxer.h"
|
#include "MediaDataDemuxer.h"
|
||||||
#include "OggCodecState.h"
|
#include "OggCodecState.h"
|
||||||
#include "OggCodecStore.h"
|
#include "OggCodecStore.h"
|
||||||
#include "MediaMetadataManager.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -35,9 +34,6 @@ public:
|
||||||
|
|
||||||
UniquePtr<EncryptionInfo> GetCrypto() override;
|
UniquePtr<EncryptionInfo> GetCrypto() override;
|
||||||
|
|
||||||
// Set the events to notify when chaining is encountered.
|
|
||||||
void SetChainingEvents(TimedMetadataEventProducer* aMetadataEvent,
|
|
||||||
MediaEventProducer<void>* aOnSeekableEvent);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -61,8 +57,7 @@ private:
|
||||||
|
|
||||||
// Seeks to the keyframe preceding the target time using available
|
// Seeks to the keyframe preceding the target time using available
|
||||||
// keyframe indexes.
|
// keyframe indexes.
|
||||||
enum IndexedSeekResult
|
enum IndexedSeekResult {
|
||||||
{
|
|
||||||
SEEK_OK, // Success.
|
SEEK_OK, // Success.
|
||||||
SEEK_INDEX_FAIL, // Failure due to no index, or invalid index.
|
SEEK_INDEX_FAIL, // Failure due to no index, or invalid index.
|
||||||
SEEK_FATAL_ERROR // Error returned by a stream operation.
|
SEEK_FATAL_ERROR // Error returned by a stream operation.
|
||||||
|
@ -76,24 +71,23 @@ private:
|
||||||
// and the timestamps of the start and end of that range, that is cached.
|
// and the timestamps of the start and end of that range, that is cached.
|
||||||
// Used to denote the extremities of a range in which we can seek quickly
|
// Used to denote the extremities of a range in which we can seek quickly
|
||||||
// (because it's cached).
|
// (because it's cached).
|
||||||
class SeekRange
|
class SeekRange {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SeekRange()
|
SeekRange()
|
||||||
: mOffsetStart(0)
|
: mOffsetStart(0),
|
||||||
, mOffsetEnd(0)
|
mOffsetEnd(0),
|
||||||
, mTimeStart(0)
|
mTimeStart(0),
|
||||||
, mTimeEnd(0)
|
mTimeEnd(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SeekRange(int64_t aOffsetStart,
|
SeekRange(int64_t aOffsetStart,
|
||||||
int64_t aOffsetEnd,
|
int64_t aOffsetEnd,
|
||||||
int64_t aTimeStart,
|
int64_t aTimeStart,
|
||||||
int64_t aTimeEnd)
|
int64_t aTimeEnd)
|
||||||
: mOffsetStart(aOffsetStart)
|
: mOffsetStart(aOffsetStart),
|
||||||
, mOffsetEnd(aOffsetEnd)
|
mOffsetEnd(aOffsetEnd),
|
||||||
, mTimeStart(aTimeStart)
|
mTimeStart(aTimeStart),
|
||||||
, mTimeEnd(aTimeEnd)
|
mTimeEnd(aTimeEnd)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool IsNull() const {
|
bool IsNull() const {
|
||||||
|
@ -156,8 +150,7 @@ private:
|
||||||
// is about 4300 bytes, so we read the file in chunks larger than that.
|
// is about 4300 bytes, so we read the file in chunks larger than that.
|
||||||
static const int PAGE_STEP = 8192;
|
static const int PAGE_STEP = 8192;
|
||||||
|
|
||||||
enum PageSyncResult
|
enum PageSyncResult {
|
||||||
{
|
|
||||||
PAGE_SYNC_ERROR = 1,
|
PAGE_SYNC_ERROR = 1,
|
||||||
PAGE_SYNC_END_OF_RANGE= 2,
|
PAGE_SYNC_END_OF_RANGE= 2,
|
||||||
PAGE_SYNC_OK = 3
|
PAGE_SYNC_OK = 3
|
||||||
|
@ -206,7 +199,7 @@ private:
|
||||||
bool ReadHeaders(TrackInfo::TrackType aType, OggCodecState* aState, OggHeaders& aHeaders);
|
bool ReadHeaders(TrackInfo::TrackType aType, OggCodecState* aState, OggHeaders& aHeaders);
|
||||||
|
|
||||||
// Reads the next link in the chain.
|
// Reads the next link in the chain.
|
||||||
bool ReadOggChain(const media::TimeUnit& aLastEndTime);
|
bool ReadOggChain();
|
||||||
|
|
||||||
// Set this media as being a chain and notifies the state machine that the
|
// Set this media as being a chain and notifies the state machine that the
|
||||||
// media is no longer seekable.
|
// media is no longer seekable.
|
||||||
|
@ -248,6 +241,7 @@ private:
|
||||||
// started playback at aOffset.
|
// started playback at aOffset.
|
||||||
int64_t RangeStartTime(TrackInfo::TrackType aType, int64_t aOffset);
|
int64_t RangeStartTime(TrackInfo::TrackType aType, int64_t aOffset);
|
||||||
|
|
||||||
|
|
||||||
MediaInfo mInfo;
|
MediaInfo mInfo;
|
||||||
nsTArray<RefPtr<OggTrackDemuxer>> mDemuxers;
|
nsTArray<RefPtr<OggTrackDemuxer>> mDemuxers;
|
||||||
|
|
||||||
|
@ -276,18 +270,14 @@ private:
|
||||||
SkeletonState* mSkeletonState;
|
SkeletonState* mSkeletonState;
|
||||||
|
|
||||||
// Ogg decoding state.
|
// Ogg decoding state.
|
||||||
struct OggStateContext
|
struct OggStateContext {
|
||||||
{
|
explicit OggStateContext(MediaResource* aResource) : mResource(aResource) {}
|
||||||
explicit OggStateContext(MediaResource* aResource)
|
|
||||||
: mResource(aResource), mNeedKeyframe(true) {}
|
|
||||||
nsAutoOggSyncState mOggState;
|
nsAutoOggSyncState mOggState;
|
||||||
MediaResourceIndex mResource;
|
MediaResourceIndex mResource;
|
||||||
Maybe<media::TimeUnit> mStartTime;
|
Maybe<media::TimeUnit> mStartTime;
|
||||||
bool mNeedKeyframe;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
OggStateContext& OggState(TrackInfo::TrackType aType);
|
ogg_sync_state* OggState(TrackInfo::TrackType aType);
|
||||||
ogg_sync_state* OggSyncState(TrackInfo::TrackType aType);
|
|
||||||
MediaResourceIndex* Resource(TrackInfo::TrackType aType);
|
MediaResourceIndex* Resource(TrackInfo::TrackType aType);
|
||||||
MediaResourceIndex* CommonResource();
|
MediaResourceIndex* CommonResource();
|
||||||
OggStateContext mAudioOggState;
|
OggStateContext mAudioOggState;
|
||||||
|
@ -311,8 +301,7 @@ private:
|
||||||
// Booleans to indicate if we have audio and/or video data
|
// Booleans to indicate if we have audio and/or video data
|
||||||
bool HasVideo() const;
|
bool HasVideo() const;
|
||||||
bool HasAudio() const;
|
bool HasAudio() const;
|
||||||
bool HasSkeleton() const
|
bool HasSkeleton() const {
|
||||||
{
|
|
||||||
return mSkeletonState != 0 && mSkeletonState->mActive;
|
return mSkeletonState != 0 && mSkeletonState->mActive;
|
||||||
}
|
}
|
||||||
bool HaveStartTime () const;
|
bool HaveStartTime () const;
|
||||||
|
@ -327,12 +316,8 @@ private:
|
||||||
// True if we are decoding a chained ogg.
|
// True if we are decoding a chained ogg.
|
||||||
bool mIsChained;
|
bool mIsChained;
|
||||||
|
|
||||||
// Total audio duration played so far.
|
// Number of audio frames decoded so far.
|
||||||
media::TimeUnit mDecodedAudioDuration;
|
int64_t mDecodedAudioFrames;
|
||||||
|
|
||||||
// Events manager
|
|
||||||
TimedMetadataEventProducer* mTimedMetadataEvent;
|
|
||||||
MediaEventProducer<void>* mOnSeekableEvent;
|
|
||||||
|
|
||||||
friend class OggTrackDemuxer;
|
friend class OggTrackDemuxer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -167,8 +167,7 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
|
||||||
mLastFrameTime = Some(aSample->mTime);
|
mLastFrameTime = Some(aSample->mTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogg_packet pkt = InitVorbisPacket(aData, aLength, false, aSample->mEOS,
|
ogg_packet pkt = InitVorbisPacket(aData, aLength, false, false, -1, mPacketCount++);
|
||||||
aSample->mTimecode, mPacketCount++);
|
|
||||||
|
|
||||||
if (vorbis_synthesis(&mVorbisBlock, &pkt) != 0) {
|
if (vorbis_synthesis(&mVorbisBlock, &pkt) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -181,7 +181,7 @@ var gPlayTests = [
|
||||||
// Multiple audio streams.
|
// Multiple audio streams.
|
||||||
{ name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
|
{ name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
|
||||||
// oggz-chop with non-keyframe as first frame
|
// oggz-chop with non-keyframe as first frame
|
||||||
{ name:"bug556821.ogv", type:"video/ogg", duration:2.936 },
|
{ name:"bug556821.ogv", type:"video/ogg", duration:2.551 },
|
||||||
|
|
||||||
// Encoded with vorbis beta1, includes unusually sized codebooks
|
// Encoded with vorbis beta1, includes unusually sized codebooks
|
||||||
{ name:"beta-phrasebook.ogg", type:"audio/ogg", duration:4.01 },
|
{ name:"beta-phrasebook.ogg", type:"audio/ogg", duration:4.01 },
|
||||||
|
@ -198,9 +198,9 @@ var gPlayTests = [
|
||||||
{ name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
|
{ name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
|
||||||
{ name:"chain.ogv", type:"video/ogg", duration:Number.NaN },
|
{ name:"chain.ogv", type:"video/ogg", duration:Number.NaN },
|
||||||
{ name:"bug523816.ogv", type:"video/ogg", duration:0.766 },
|
{ name:"bug523816.ogv", type:"video/ogg", duration:0.533 },
|
||||||
{ name:"bug495129.ogv", type:"video/ogg", duration:2.41 },
|
{ name:"bug495129.ogv", type:"video/ogg", duration:2.41 },
|
||||||
{ name:"bug498380.ogv", type:"video/ogg", duration:0.7663 },
|
{ name:"bug498380.ogv", type:"video/ogg", duration:0.533 },
|
||||||
{ name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
|
{ name:"bug495794.ogg", type:"audio/ogg", duration:0.3 },
|
||||||
{ name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
|
{ name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
|
||||||
|
@ -294,16 +294,16 @@ var gSeekToNextFrameTests = [
|
||||||
// Multiple audio streams.
|
// Multiple audio streams.
|
||||||
{ name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
|
{ name:"bug516323.ogv", type:"video/ogg", duration:4.208 },
|
||||||
// oggz-chop with non-keyframe as first frame
|
// oggz-chop with non-keyframe as first frame
|
||||||
{ name:"bug556821.ogv", type:"video/ogg", duration:2.936 },
|
{ name:"bug556821.ogv", type:"video/ogg", duration:2.551 },
|
||||||
// Various weirdly formed Ogg files
|
// Various weirdly formed Ogg files
|
||||||
{ name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug498855-1.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug498855-2.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug498855-3.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
|
{ name:"bug504644.ogv", type:"video/ogg", duration:1.6 },
|
||||||
|
|
||||||
{ name:"bug523816.ogv", type:"video/ogg", duration:0.766 },
|
{ name:"bug523816.ogv", type:"video/ogg", duration:0.533 },
|
||||||
|
|
||||||
{ name:"bug498380.ogv", type:"video/ogg", duration:0.766 },
|
{ name:"bug498380.ogv", type:"video/ogg", duration:0.533 },
|
||||||
{ name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
|
{ name:"bug557094.ogv", type:"video/ogg", duration:0.24 },
|
||||||
{ name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
|
{ name:"multiple-bos.ogg", type:"video/ogg", duration:0.431 },
|
||||||
// Test playback/metadata work after a redirect
|
// Test playback/metadata work after a redirect
|
||||||
|
|
|
@ -544,7 +544,7 @@ pref("media.mediasource.webm.enabled", true);
|
||||||
pref("media.mediasource.webm.audio.enabled", true);
|
pref("media.mediasource.webm.audio.enabled", true);
|
||||||
|
|
||||||
// Use new MediaFormatReader architecture for plain ogg.
|
// Use new MediaFormatReader architecture for plain ogg.
|
||||||
pref("media.format-reader.ogg", true);
|
pref("media.format-reader.ogg", false);
|
||||||
|
|
||||||
pref("media.benchmark.vp9.threshold", 150);
|
pref("media.benchmark.vp9.threshold", 150);
|
||||||
pref("media.benchmark.frames", 300);
|
pref("media.benchmark.frames", 300);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче