Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2024-10-01 10:28:33 +08:00
commit 687f52e183
9 changed files with 82 additions and 12 deletions

View file

@ -31,6 +31,7 @@ mozilla::LogModule* GetMediaSourceSamplesLog()
return sLogModule; return sLogModule;
} }
#define SAMPLE_DEBUG(arg, ...) MOZ_LOG(GetMediaSourceSamplesLog(), mozilla::LogLevel::Debug, ("TrackBuffersManager(%p)::%s: " arg, this, __func__, ##__VA_ARGS__)) #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 { namespace mozilla {
@ -708,7 +709,11 @@ TrackBuffersManager::SegmentParserLoop()
if (mNewMediaSegmentStarted) { if (mNewMediaSegmentStarted) {
if (NS_SUCCEEDED(newData) && mLastParsedEndTime.isSome() && if (NS_SUCCEEDED(newData) && mLastParsedEndTime.isSome() &&
start < mLastParsedEndTime.ref().ToMicroseconds()) { 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(); ResetDemuxingState();
return; return;
} }
@ -817,7 +822,15 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
mType.LowerCaseEqualsLiteral("video/x-matroska") || mType.LowerCaseEqualsLiteral("video/x-matroska") ||
mType.LowerCaseEqualsLiteral("audio/x-matroska") || mType.LowerCaseEqualsLiteral("audio/x-matroska") ||
mType.LowerCaseEqualsLiteral("audio/webm")) { 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; return;
} }
@ -825,6 +838,7 @@ TrackBuffersManager::CreateDemuxerforMIMEType()
if (mType.LowerCaseEqualsLiteral("video/mp4") || if (mType.LowerCaseEqualsLiteral("video/mp4") ||
mType.LowerCaseEqualsLiteral("audio/mp4")) { mType.LowerCaseEqualsLiteral("audio/mp4")) {
mInputDemuxer = new MP4Demuxer(mCurrentInputBuffer); mInputDemuxer = new MP4Demuxer(mCurrentInputBuffer);
mFrameEndTimeBeforeRecreateDemuxer.reset();
return; return;
} }
#endif #endif
@ -1229,9 +1243,11 @@ void
TrackBuffersManager::OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) TrackBuffersManager::OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{ {
MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(OnTaskQueue());
MSE_DEBUG("%d video samples demuxed", aSamples->mSamples.Length());
mVideoTracks.mDemuxRequest.Complete(); mVideoTracks.mDemuxRequest.Complete();
mVideoTracks.mQueuedSamples.AppendElements(aSamples->mSamples); mVideoTracks.mQueuedSamples.AppendElements(aSamples->mSamples);
MSE_DEBUG("%zu video samples demuxed, queued-sz=%zu",
aSamples->mSamples.Length(),
mVideoTracks.mQueuedSamples.Length());
DoDemuxAudio(); DoDemuxAudio();
} }
@ -1472,6 +1488,9 @@ TrackBuffersManager::ProcessFrames(TrackBuffer& aSamples, TrackData& aTrackData)
if (trackBuffer.mNeedRandomAccessPoint) { 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. // 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) { if (!sample->mKeyframe) {
SAMPLE_DEBUGV("skipping sample [%" PRId64 ",%" PRId64 "]",
sample->mTime,
sample->GetEndTime());
continue; continue;
} }
// 2. Set the need random access point flag on track buffer to false. // 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. // 3. Unset the last frame duration on all track buffers.
// 4. Unset the highest end timestamp 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. // 5. Set the need random access point flag on all track buffers to true.
MSE_DEBUG("Resetting append state");
track->ResetAppendState(); track->ResetAppendState();
} }
// 6. Jump to the Loop Top step above to restart processing of the current coded frame. // 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 // we can optimize this part. TODO
mParser = ContainerParser::CreateForMIMEType(mType); mParser = ContainerParser::CreateForMIMEType(mType);
if (aReuseInitData && mInitData) { if (aReuseInitData && mInitData) {
MSE_DEBUG("Using existing init data to reset parser");
int64_t start, end; int64_t start, end;
mParser->ParseStartAndEndTimestamps(mInitData, start, end); mParser->ParseStartAndEndTimestamps(mInitData, start, end);
mProcessedInput = mInitData->Length(); mProcessedInput = mInitData->Length();
} else { } else {
MSE_DEBUG("Resetting parser, not reusing init data");
mProcessedInput = 0; mProcessedInput = 0;
} }
} }

View file

@ -492,6 +492,8 @@ private:
media::TimeIntervals mAudioBufferedRanges; media::TimeIntervals mAudioBufferedRanges;
// MediaInfo of the first init segment read. // MediaInfo of the first init segment read.
MediaInfo mInfo; MediaInfo mInfo;
Maybe<int64_t> mFrameEndTimeBeforeRecreateDemuxer;
}; };
} // namespace mozilla } // namespace mozilla

View file

@ -22,10 +22,11 @@ public:
: mPacket(nullptr) : mPacket(nullptr)
, mOffset(-1) , mOffset(-1)
, mTimestamp(-1) , mTimestamp(-1)
, mDefaultDuration(-1)
, mDuration(-1) , mDuration(-1)
, mIsKeyframe(false) {} , 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; uint64_t timestamp_ns;
if (nestegg_packet_tstamp(aPacket, &timestamp_ns) == -1) { if (nestegg_packet_tstamp(aPacket, &timestamp_ns) == -1) {
@ -44,6 +45,9 @@ public:
if (!nestegg_packet_duration(aPacket, &duration_ns)) { if (!nestegg_packet_duration(aPacket, &duration_ns)) {
mDuration = duration_ns / 1000; mDuration = duration_ns / 1000;
} }
if (!nestegg_track_default_duration(aContext, mTrack, &duration_ns)) {
mDefaultDuration = duration_ns / 1000;
}
return true; return true;
} }
@ -51,6 +55,7 @@ public:
int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; } int64_t Offset() { MOZ_ASSERT(IsInitialized()); return mOffset; }
int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; } int64_t Timestamp() { MOZ_ASSERT(IsInitialized()); return mTimestamp; }
int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; } int64_t Duration() { MOZ_ASSERT(IsInitialized()); return mDuration; }
int64_t DefaultDuration() const { MOZ_ASSERT(IsInitialized()); return mDefaultDuration; }
unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; } unsigned Track() { MOZ_ASSERT(IsInitialized()); return mTrack; }
bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; } bool IsKeyframe() { MOZ_ASSERT(IsInitialized()); return mIsKeyframe; }
@ -60,7 +65,7 @@ private:
nestegg_free_packet(mPacket); nestegg_free_packet(mPacket);
} }
bool IsInitialized() { return mOffset >= 0; } bool IsInitialized() const { return mOffset >= 0; }
nestegg_packet* mPacket; nestegg_packet* mPacket;
@ -72,8 +77,13 @@ private:
int64_t mTimestamp; int64_t mTimestamp;
// Packet duration in microseconds; -1 if unknown or retrieval failed. // Packet duration in microseconds; -1 if unknown or retrieval failed.
// https://www.webmproject.org/docs/container/#BlockDuration
int64_t mDuration; 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. // Track ID.
unsigned mTrack; unsigned mTrack;

View file

@ -17,6 +17,7 @@
#include "gfx2DGlue.h" #include "gfx2DGlue.h"
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
#include "mozilla/EndianUtils.h" #include "mozilla/EndianUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/SharedThreadPool.h" #include "mozilla/SharedThreadPool.h"
#include "MediaDataDemuxer.h" #include "MediaDataDemuxer.h"
#include "nsAutoPtr.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<int64_t> aFrameEndTimeBeforeRecreateDemuxer)
: mVideoContext(this, aResource) : mVideoContext(this, aResource)
, mAudioContext(this, aResource) , mAudioContext(this, aResource)
, mBufferedState(nullptr) , mBufferedState(nullptr)
@ -174,6 +177,13 @@ WebMDemuxer::WebMDemuxer(MediaResource* aResource, bool aIsMediaSource)
, mLastWebMBlockOffset(-1) , mLastWebMBlockOffset(-1)
, mIsMediaSource(aIsMediaSource) , mIsMediaSource(aIsMediaSource)
{ {
MOZ_ASSERT_IF(!aIsMediaSource,
aFrameEndTimeBeforeRecreateDemuxer.isNothing());
if (aIsMediaSource && aFrameEndTimeBeforeRecreateDemuxer) {
mVideoFrameEndTimeBeforeReset = aFrameEndTimeBeforeRecreateDemuxer;
WEBM_DEBUG("Set mVideoFrameEndTimeBeforeReset=%" PRId64,
mVideoFrameEndTimeBeforeReset.value());
}
} }
WebMDemuxer::~WebMDemuxer() WebMDemuxer::~WebMDemuxer()
@ -592,6 +602,11 @@ WebMDemuxer::GetNextPacket(TrackInfo::TrackType aType, MediaRawDataQueue *aSampl
} }
int64_t tstamp = holder->Timestamp(); int64_t tstamp = holder->Timestamp();
int64_t duration = holder->Duration(); 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 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 // 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())) { (mIsMediaSource && mLastVideoFrameTime.isSome())) {
next_tstamp = tstamp; next_tstamp = tstamp;
next_tstamp += tstamp - mLastVideoFrameTime.refOr(0); 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 { } else {
PushVideoPacket(holder); PushVideoPacket(holder);
} }
@ -865,7 +886,7 @@ WebMDemuxer::DemuxPacket(TrackInfo::TrackType aType,
int64_t offset = Resource(aType).Tell(); int64_t offset = Resource(aType).Tell();
RefPtr<NesteggPacketHolder> holder = new NesteggPacketHolder(); RefPtr<NesteggPacketHolder> 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; return NS_ERROR_DOM_MEDIA_DEMUXER_ERR;
} }

View file

@ -92,7 +92,9 @@ public:
explicit WebMDemuxer(MediaResource* aResource); explicit WebMDemuxer(MediaResource* aResource);
// Indicate if the WebMDemuxer is to be used with MediaSource. In which // Indicate if the WebMDemuxer is to be used with MediaSource. In which
// case the demuxer will stop reads to the last known complete block. // case the demuxer will stop reads to the last known complete block.
WebMDemuxer(MediaResource* aResource, bool aIsMediaSource); WebMDemuxer(MediaResource* aResource,
bool aIsMediaSource,
Maybe<int64_t> aFrameEndTimeBeforeRecreateDemuxer = Nothing());
RefPtr<InitPromise> Init() override; RefPtr<InitPromise> Init() override;
@ -227,6 +229,8 @@ private:
Maybe<int64_t> mLastAudioFrameTime; Maybe<int64_t> mLastAudioFrameTime;
Maybe<int64_t> mLastVideoFrameTime; Maybe<int64_t> mLastVideoFrameTime;
Maybe<int64_t> mVideoFrameEndTimeBeforeReset;
// Codec ID of audio track // Codec ID of audio track
int mAudioCodec; int mAudioCodec;
// Codec ID of video track // Codec ID of video track

View file

@ -1307,9 +1307,8 @@ ScriptLoader::StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType,
// According to the spec, module scripts have different behaviour to classic // According to the spec, module scripts have different behaviour to classic
// scripts and always use CORS. // scripts and always use CORS.
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
if (aRequest->CORSMode() == CORS_NONE) { if (aRequest->CORSMode() == CORS_NONE ||
securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT; aRequest->CORSMode() == CORS_ANONYMOUS) {
} else if (aRequest->CORSMode() == CORS_ANONYMOUS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN; securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
} else { } else {
MOZ_ASSERT(aRequest->CORSMode() == CORS_USE_CREDENTIALS); MOZ_ASSERT(aRequest->CORSMode() == CORS_USE_CREDENTIALS);

View file

@ -27,6 +27,7 @@ nestegg_track_codec_data_count
nestegg_track_codec_id nestegg_track_codec_id
nestegg_track_content_enc_key_id nestegg_track_content_enc_key_id
nestegg_track_count nestegg_track_count
nestegg_track_default_duration
nestegg_get_cue_point nestegg_get_cue_point
nestegg_track_seek nestegg_track_seek
nestegg_track_type nestegg_track_type

View file

@ -245,7 +245,7 @@ elif CONFIG['CPU_ARCH'].startswith('ppc'):
'simd/powerpc/jsimd.c', 'simd/powerpc/jsimd.c',
] ]
for srcfile in ppc_vmx_sources: for srcfile in ppc_vmx_sources:
SOURCES[srcfile].flags += CONFIG['PPC_VMX_FLAGS'] SOURCES[srcfile].flags += ['-maltivec']
else: # No SIMD support? else: # No SIMD support?
SOURCES += [ SOURCES += [
'jsimd_none.c', 'jsimd_none.c',

View file

@ -38,6 +38,9 @@
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <machine/cpu.h> #include <machine/cpu.h>
#include <sys/auxv.h> #include <sys/auxv.h>
#elif defined(__NetBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#endif #endif
static unsigned int simd_support = ~0; static unsigned int simd_support = ~0;
@ -127,6 +130,9 @@ init_simd(void)
size_t len = sizeof(altivec); size_t len = sizeof(altivec);
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
unsigned long cpufeatures = 0; unsigned long cpufeatures = 0;
#elif defined(__NetBSD__)
int ret, av;
size_t len;
#endif #endif
if (simd_support != ~0U) if (simd_support != ~0U)
@ -149,6 +155,11 @@ init_simd(void)
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0) if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0)
simd_support |= JSIMD_ALTIVEC; 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__) #elif defined(__FreeBSD__)
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)); elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
if (cpufeatures & PPC_FEATURE_HAS_ALTIVEC) if (cpufeatures & PPC_FEATURE_HAS_ALTIVEC)