diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index b552adf291..5e40a977d9 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -31,6 +31,7 @@ mozilla::LogModule* GetMediaSourceSamplesLog() return sLogModule; } #define SAMPLE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) +#define SAMPLE_DEBUGV(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Verbose, ("TrackBuffersManager(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) namespace mozilla { @@ -708,7 +709,11 @@ TrackBuffersManager::SegmentParserLoop() if (mNewMediaSegmentStarted) { if (NS_SUCCEEDED(newData) && mLastParsedEndTime.isSome() && start < mLastParsedEndTime.ref().ToMicroseconds()) { - MSE_DEBUG("Re-creating demuxer"); + MSE_DEBUG("Re-creating demuxer, new start (%" PRId64 + ") is smaller than last parsed end time (%" PRId64 ")", + start, + mLastParsedEndTime.value()); + mFrameEndTimeBeforeRecreateDemuxer = Some(end); ResetDemuxingState(); return; } @@ -817,7 +822,15 @@ TrackBuffersManager::CreateDemuxerforMIMEType() mType.LowerCaseEqualsLiteral("video/x-matroska") || mType.LowerCaseEqualsLiteral("audio/x-matroska") || mType.LowerCaseEqualsLiteral("audio/webm")) { - mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/ ); + if (mFrameEndTimeBeforeRecreateDemuxer) { + MSE_DEBUG( + "CreateDemuxerFromMimeType: " + "mFrameEndTimeBeforeRecreateDemuxer=%" PRId64, + mFrameEndTimeBeforeRecreateDemuxer.value()); + } + mInputDemuxer = new WebMDemuxer(mCurrentInputBuffer, true /* IsMediaSource*/, + mFrameEndTimeBeforeRecreateDemuxer); + mFrameEndTimeBeforeRecreateDemuxer.reset(); return; } @@ -825,6 +838,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType() if (mType.LowerCaseEqualsLiteral("video/mp4") || mType.LowerCaseEqualsLiteral("audio/mp4")) { mInputDemuxer = new MP4Demuxer(mCurrentInputBuffer); + mFrameEndTimeBeforeRecreateDemuxer.reset(); return; } #endif @@ -1229,9 +1243,11 @@ void TrackBuffersManager::OnVideoDemuxCompleted(RefPtr aSamples) { MOZ_ASSERT(OnTaskQueue()); - MSE_DEBUG("%d video samples demuxed", aSamples->mSamples.Length()); mVideoTracks.mDemuxRequest.Complete(); mVideoTracks.mQueuedSamples.AppendElements(aSamples->mSamples); + MSE_DEBUG("%zu video samples demuxed, queued-sz=%zu", + aSamples->mSamples.Length(), + mVideoTracks.mQueuedSamples.Length()); DoDemuxAudio(); } @@ -1472,6 +1488,9 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) if (trackBuffer.mNeedRandomAccessPoint) { // 1. If the coded frame is not a random access point, then drop the coded frame and jump to the top of the loop to start processing the next coded frame. if (!sample->mKeyframe) { + SAMPLE_DEBUGV("skipping sample [%" PRId64 ",%" PRId64 "]", + sample->mTime, + sample->GetEndTime()); continue; } // 2. Set the need random access point flag on track buffer to false. @@ -1532,6 +1551,7 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData) // 3. Unset the last frame duration on all track buffers. // 4. Unset the highest end timestamp on all track buffers. // 5. Set the need random access point flag on all track buffers to true. + MSE_DEBUG("Resetting append state"); track->ResetAppendState(); } // 6. Jump to the Loop Top step above to restart processing of the current coded frame. @@ -1930,10 +1950,12 @@ TrackBuffersManager::RecreateParser(bool aReuseInitData) // we can optimize this part. TODO mParser = ContainerParser::CreateForMIMEType(mType); if (aReuseInitData && mInitData) { + MSE_DEBUG("Using existing init data to reset parser"); int64_t start, end; mParser->ParseStartAndEndTimestamps(mInitData, start, end); mProcessedInput = mInitData->Length(); } else { + MSE_DEBUG("Resetting parser, not reusing init data"); mProcessedInput = 0; } } diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index 11bcb353ab..7bd2131bce 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -492,6 +492,8 @@ private: media::TimeIntervals mAudioBufferedRanges; // MediaInfo of the first init segment read. MediaInfo mInfo; + + Maybe mFrameEndTimeBeforeRecreateDemuxer; }; } // namespace mozilla diff --git a/dom/media/webm/NesteggPacketHolder.h b/dom/media/webm/NesteggPacketHolder.h index 00a7b12cfb..0f8f9b63ab 100644 --- a/dom/media/webm/NesteggPacketHolder.h +++ b/dom/media/webm/NesteggPacketHolder.h @@ -22,10 +22,11 @@ public: : mPacket(nullptr) , mOffset(-1) , mTimestamp(-1) + , mDefaultDuration(-1) , mDuration(-1) , mIsKeyframe(false) {} - bool Init(nestegg_packet* aPacket, int64_t aOffset, unsigned aTrack, bool aIsKeyframe) + bool Init(nestegg_packet* aPacket, nestegg* aContext, int64_t aOffset, unsigned aTrack, bool aIsKeyframe) { uint64_t timestamp_ns; if (nestegg_packet_tstamp(aPacket, ×tamp_ns) == -1) { @@ -44,6 +45,9 @@ public: if (!nestegg_packet_duration(aPacket, &duration_ns)) { mDuration = duration_ns / 1000; } + if (!nestegg_track_default_duration(aContext, mTrack, &duration_ns)) { + mDefaultDuration = duration_ns / 1000; + } return true; } @@ -51,6 +55,7 @@ public: int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; } int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; } int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; } + int64_t DefaultDuration() const { MOZ_ASSERT(IsInitialized()); return mDefaultDuration; } unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; } bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; } @@ -60,7 +65,7 @@ private: nestegg_free_packet(mPacket); } - bool IsInitialized() { return mOffset >= 0; } + bool IsInitialized() const { return mOffset >= 0; } nestegg_packet* mPacket; @@ -72,8 +77,13 @@ private: int64_t mTimestamp; // Packet duration in microseconds; -1 if unknown or retrieval failed. + // https://www.webmproject.org/docs/container/#BlockDuration int64_t mDuration; + // Default duration in microseconds; -1 if unknown or retrieval failed. + // https://www.webmproject.org/docs/container/#Duration + int64_t mDefaultDuration; + // Track ID. unsigned mTrack; diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp index 1009fedc69..fc98db4d77 100644 --- a/dom/media/webm/WebMDemuxer.cpp +++ b/dom/media/webm/WebMDemuxer.cpp @@ -17,6 +17,7 @@ #include "gfx2DGlue.h" #include "mozilla/Atomics.h" #include "mozilla/EndianUtils.h" +#include "mozilla/Maybe.h" #include "mozilla/SharedThreadPool.h" #include "MediaDataDemuxer.h" #include "nsAutoPtr.h" @@ -158,7 +159,9 @@ WebMDemuxer::WebMDemuxer(MediaResource* aResource) { } -WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource) +WebMDemuxer::WebMDemuxer(MediaResource* aResource, + bool aIsMediaSource, + Maybe aFrameEndTimeBeforeRecreateDemuxer) : mVideoContext(this, aResource) , mAudioContext(this, aResource) , mBufferedState(nullptr) @@ -174,6 +177,13 @@ WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource) , mLastWebMBlockOffset(-1) , mIsMediaSource(aIsMediaSource) { + MOZ_ASSERT_IF(!aIsMediaSource, + aFrameEndTimeBeforeRecreateDemuxer.isNothing()); + if (aIsMediaSource && aFrameEndTimeBeforeRecreateDemuxer) { + mVideoFrameEndTimeBeforeReset = aFrameEndTimeBeforeRecreateDemuxer; + WEBM_DEBUG("Set mVideoFrameEndTimeBeforeReset=%" PRId64, + mVideoFrameEndTimeBeforeReset.value()); + } } WebMDemuxer::~WebMDemuxer() @@ -592,6 +602,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl } int64_t tstamp = holder->Timestamp(); int64_t duration = holder->Duration(); + int64_t defaultDuration = holder->DefaultDuration(); + if (aType == TrackInfo::TrackType::kVideoTrack) { + WEBM_DEBUG("GetNextPacket(video): tstamp=%" PRId64 ", duration=%" PRId64, ", defaultDuration=%" PRId64, + tstamp, duration, defaultDuration); + } // The end time of this frame is the start time of the next frame. Fetch // the timestamp of the next packet for this track. If we've reached the @@ -632,6 +647,12 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl (mIsMediaSource && mLastVideoFrameTime.isSome())) { next_tstamp = tstamp; next_tstamp += tstamp - mLastVideoFrameTime.refOr(0); + } else if (defaultDuration >= 0) { + next_tstamp = tstamp + defaultDuration; + } else if (mVideoFrameEndTimeBeforeReset) { + WEBM_DEBUG("Setting next timestamp to be %" PRId64 " us", + mVideoFrameEndTimeBeforeReset.value()); + next_tstamp = mVideoFrameEndTimeBeforeReset.ref(); } else { PushVideoPacket(holder); } @@ -865,7 +886,7 @@ WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType, int64_t offset = Resource(aType).Tell(); RefPtr holder = new NesteggPacketHolder(); - if (!holder->Init(packet, offset, track, false)) { + if (!holder->Init(packet, Context(aType), offset, track, false)) { return NS_ERROR_DOM_MEDIA_DEMUXER_ERR; } diff --git a/dom/media/webm/WebMDemuxer.h b/dom/media/webm/WebMDemuxer.h index a0d2960d33..99d516b632 100644 --- a/dom/media/webm/WebMDemuxer.h +++ b/dom/media/webm/WebMDemuxer.h @@ -92,7 +92,9 @@ public: explicit WebMDemuxer(MediaResource* aResource); // Indicate if the WebMDemuxer is to be used with MediaSource. In which // case the demuxer will stop reads to the last known complete block. - WebMDemuxer(MediaResource* aResource, bool aIsMediaSource); + WebMDemuxer(MediaResource* aResource, + bool aIsMediaSource, + Maybe aFrameEndTimeBeforeRecreateDemuxer = Nothing()); RefPtr Init() override; @@ -227,6 +229,8 @@ private: Maybe mLastAudioFrameTime; Maybe mLastVideoFrameTime; + Maybe mVideoFrameEndTimeBeforeReset; + // Codec ID of audio track int mAudioCodec; // Codec ID of video track diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index a61ba92c23..cbe4265181 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -1307,9 +1307,8 @@ ScriptLoader::StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType, // According to the spec, module scripts have different behaviour to classic // scripts and always use CORS. securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; - if (aRequest->CORSMode() == CORS_NONE) { - securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT; - } else if (aRequest->CORSMode() == CORS_ANONYMOUS) { + if (aRequest->CORSMode() == CORS_NONE || + aRequest->CORSMode() == CORS_ANONYMOUS) { securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; } else { MOZ_ASSERT(aRequest->CORSMode() == CORS_USE_CREDENTIALS); diff --git a/layout/media/symbols.def.in b/layout/media/symbols.def.in index d81b199d05..101e98d6fd 100644 --- a/layout/media/symbols.def.in +++ b/layout/media/symbols.def.in @@ -27,6 +27,7 @@ nestegg_track_codec_data_count nestegg_track_codec_id nestegg_track_content_enc_key_id nestegg_track_count +nestegg_track_default_duration nestegg_get_cue_point nestegg_track_seek nestegg_track_type diff --git a/media/libjpeg/moz.build b/media/libjpeg/moz.build index f24b4fcf0f..1068e3f0ff 100644 --- a/media/libjpeg/moz.build +++ b/media/libjpeg/moz.build @@ -245,7 +245,7 @@ elif CONFIG['CPU_ARCH'].startswith('ppc'): 'simd/powerpc/jsimd.c', ] for srcfile in ppc_vmx_sources: - SOURCES[srcfile].flags += CONFIG['PPC_VMX_FLAGS'] + SOURCES[srcfile].flags += ['-maltivec'] else: # No SIMD support? SOURCES += [ 'jsimd_none.c', diff --git a/media/libjpeg/simd/powerpc/jsimd.c b/media/libjpeg/simd/powerpc/jsimd.c index b9e86dcfac..5ff3be48ac 100644 --- a/media/libjpeg/simd/powerpc/jsimd.c +++ b/media/libjpeg/simd/powerpc/jsimd.c @@ -38,6 +38,9 @@ #elif defined(__FreeBSD__) #include #include +#elif defined(__NetBSD__) +#include +#include #endif static unsigned int simd_support = ~0; @@ -127,6 +130,9 @@ init_simd(void) size_t len = sizeof(altivec); #elif defined(__FreeBSD__) unsigned long cpufeatures = 0; +#elif defined(__NetBSD__) + int ret, av; + size_t len; #endif if (simd_support != ~0U) @@ -149,6 +155,11 @@ init_simd(void) #elif defined(__OpenBSD__) if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0) simd_support |= JSIMD_ALTIVEC; +#elif defined(__NetBSD__) + len = sizeof(av); + ret = sysctlbyname("machdep.altivec", &av, &len, NULL, 0); + if (!ret && av) + simd_support |= JSIMD_ALTIVEC; #elif defined(__FreeBSD__) elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)); if (cpufeatures & PPC_FEATURE_HAS_ALTIVEC)