From 0638c23631fee2ac19a0825cb098ea5364476211 Mon Sep 17 00:00:00 2001 From: Noemi Erli Date: Thu, 30 May 2024 04:03:57 +0300 Subject: [PATCH] Backed out 12 changesets (bug 1897481, bug 1897181) for causing failures in temporal-svc-encoding.https.any.html CLOSED TREE Backed out changeset 2e4e87506c23 (bug 1897481) Backed out changeset 412897e06226 (bug 1897481) Backed out changeset 4ca12a66de94 (bug 1897481) Backed out changeset 97b269d25105 (bug 1897481) Backed out changeset a91b229f4fad (bug 1897481) Backed out changeset 126b9ba6b909 (bug 1897481) Backed out changeset 702d8373d765 (bug 1897181) Backed out changeset 0fe2f70244ca (bug 1897181) Backed out changeset a1527c964edd (bug 1897181) Backed out changeset 069f83f502f6 (bug 1897181) Backed out changeset 38e91d70fc2e (bug 1897181) Backed out changeset 5f1417ad8c48 (bug 1897181) --- .../platforms/apple/AppleEncoderModule.cpp | 6 +- dom/media/platforms/apple/AppleVTEncoder.cpp | 138 +++--------------- dom/media/platforms/apple/AppleVTEncoder.h | 2 + dom/media/webcodecs/EncoderAgent.cpp | 1 - .../full-cycle-test.https.any.js.ini | 20 +-- .../reconfiguring-encoder.https.any.js.ini | 8 +- .../temporal-svc-encoding.https.any.js.ini | 21 +-- .../video-encoder-flush.https.any.js.ini | 8 +- ...eoFrame-createImageBitmap.https.any.js.ini | 4 +- 9 files changed, 44 insertions(+), 164 deletions(-) diff --git a/dom/media/platforms/apple/AppleEncoderModule.cpp b/dom/media/platforms/apple/AppleEncoderModule.cpp index f07f39f48cdb..6fa4a53ab5f5 100644 --- a/dom/media/platforms/apple/AppleEncoderModule.cpp +++ b/dom/media/platforms/apple/AppleEncoderModule.cpp @@ -8,7 +8,6 @@ #include "AppleVTEncoder.h" #include "VideoUtils.h" -#include "nsCocoaFeatures.h" namespace mozilla { @@ -28,10 +27,7 @@ bool AppleEncoderModule::Supports(const EncoderConfig& aConfig) const { if (!CanLikelyEncode(aConfig)) { return false; } - // Only two temporal layers supported, and only from 11.3 and more recent - if (aConfig.mScalabilityMode == ScalabilityMode::L1T3 || - (aConfig.mScalabilityMode != ScalabilityMode::None && - !nsCocoaFeatures::IsAtLeastVersion(11, 3, 0))) { + if (aConfig.mScalabilityMode != ScalabilityMode::None) { return false; } return aConfig.mCodec == CodecType::H264; diff --git a/dom/media/platforms/apple/AppleVTEncoder.cpp b/dom/media/platforms/apple/AppleVTEncoder.cpp index dfde3007e32c..c464ddd6f3ce 100644 --- a/dom/media/platforms/apple/AppleVTEncoder.cpp +++ b/dom/media/platforms/apple/AppleVTEncoder.cpp @@ -15,7 +15,6 @@ #include "H264.h" #include "AppleUtils.h" -#include "nsCocoaFeatures.h" namespace mozilla { extern LazyLogModule sPEMLog; @@ -26,23 +25,7 @@ extern LazyLogModule sPEMLog; MOZ_LOG(sPEMLog, mozilla::LogLevel::Debug, \ ("[AppleVTEncoder] %s: " fmt, __func__, ##__VA_ARGS__)) -static CFDictionaryRef BuildEncoderSpec(const bool aHardwareNotAllowed, - const bool aLowLatencyRateControl) { - if (__builtin_available(macos 11.3, *)) { - if (aLowLatencyRateControl) { - // If doing low-latency rate control, the hardware encoder is required. - const void* keys[] = { - kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, - kVTVideoEncoderSpecification_EnableLowLatencyRateControl}; - const void* values[] = {kCFBooleanTrue, kCFBooleanTrue}; - - static_assert(ArrayLength(keys) == ArrayLength(values), - "Non matching keys/values array size"); - return CFDictionaryCreate( - kCFAllocatorDefault, keys, values, ArrayLength(keys), - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - } - } +static CFDictionaryRef BuildEncoderSpec(const bool aHardwareNotAllowed) { const void* keys[] = { kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder}; const void* values[] = {aHardwareNotAllowed ? kCFBooleanFalse @@ -58,14 +41,12 @@ static CFDictionaryRef BuildEncoderSpec(const bool aHardwareNotAllowed, static void FrameCallback(void* aEncoder, void* aFrameRefCon, OSStatus aStatus, VTEncodeInfoFlags aInfoFlags, CMSampleBufferRef aSampleBuffer) { - if (aInfoFlags & kVTEncodeInfo_FrameDropped) { - LOGE("frame tagged as dropped"); - return; - } if (aStatus != noErr || !aSampleBuffer) { LOGE("VideoToolbox encoder returned no data status=%d sample=%p", aStatus, aSampleBuffer); aSampleBuffer = nullptr; + } else if (aInfoFlags & kVTEncodeInfo_FrameDropped) { + LOGE("frame tagged as dropped"); return; } (static_cast(aEncoder))->OutputFrame(aSampleBuffer); @@ -160,20 +141,7 @@ RefPtr AppleVTEncoder::Init() { return InitPromise::CreateAndReject(NS_ERROR_ILLEGAL_VALUE, __func__); } - if (mConfig.mScalabilityMode != ScalabilityMode::None && - !nsCocoaFeatures::IsAtLeastVersion(11, 3, 0)) { - LOGE("SVC only supported on macOS 11.3 and more recent"); - return InitPromise::CreateAndReject( - MediaResult(NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR, - "SVC only supported on macOS 11.3 and more recent"), - __func__); - } - - bool lowLatencyRateControl = - mConfig.mUsage == Usage::Realtime || - mConfig.mScalabilityMode != ScalabilityMode::None; - AutoCFRelease spec( - BuildEncoderSpec(mHardwareNotAllowed, lowLatencyRateControl)); + AutoCFRelease spec(BuildEncoderSpec(mHardwareNotAllowed)); AutoCFRelease srcBufferAttr( BuildSourceImageBufferAttributes()); if (!srcBufferAttr) { @@ -198,23 +166,15 @@ RefPtr AppleVTEncoder::Init() { } if (mConfig.mUsage == Usage::Realtime && !SetRealtime(mSession, true)) { - LOGE("fail to configure realtime properties"); + LOGE("fail to configurate realtime properties"); return InitPromise::CreateAndReject( MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - "fail to configure real-time"), + "fail to configurate average bitrate"), __func__); } if (mConfig.mBitrate) { - if (mConfig.mCodec == CodecType::H264 && - mConfig.mBitrateMode == BitrateMode::Constant) { - // Not supported, fall-back to VBR. - LOGD("H264 CBR not supported in VideoToolbox, falling back to VBR"); - mConfig.mBitrateMode = BitrateMode::Variable; - } - bool rv = - SetBitrateAndMode(mSession, mConfig.mBitrateMode, mConfig.mBitrate); - if (!rv) { + if (!SetBitrateAndMode(mSession, mConfig.mBitrateMode, mConfig.mBitrate)) { LOGE("failed to set bitrate to %d and mode to %s", mConfig.mBitrate, mConfig.mBitrateMode == BitrateMode::Constant ? "constant" : "variable"); @@ -225,60 +185,6 @@ RefPtr AppleVTEncoder::Init() { } } - if (mConfig.mScalabilityMode != ScalabilityMode::None) { - // A real-time encoder, with reordering disabled is required for SVC to - // work. - if (!SetRealtime(mSession, true)) { - LOGE("fail to configure real-time encoding for svc"); - return InitPromise::CreateAndReject( - MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - "fail to configure real-time encoding for svc"), - __func__); - } - - mConfig.mUsage = Usage::Realtime; - - if (__builtin_available(macos 11.3, *)) { - float baseLayerFPSRatio = 1.0f; - switch (mConfig.mScalabilityMode) { - case ScalabilityMode::L1T2: - baseLayerFPSRatio = 0.5; - break; - case ScalabilityMode::L1T3: - // Not supported in hw on macOS, but is accepted and errors out when - // encoding. Reject the configuration now. - LOGE("macOS only supports L1T2 h264 SVC"); - return InitPromise::CreateAndReject( - MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - nsPrintfCString("macOS only support L1T2 h264 SVC")), - __func__); - default: - MOZ_ASSERT_UNREACHABLE("Unhandled value"); - } - CFNumberRef baseLayerFPSRatioRef = CFNumberCreate( - kCFAllocatorDefault, kCFNumberFloatType, &baseLayerFPSRatio); - AutoCFRelease cf(CFNumberCreate( - kCFAllocatorDefault, kCFNumberFloatType, &baseLayerFPSRatio)); - if (VTSessionSetProperty( - mSession, kVTCompressionPropertyKey_BaseLayerFrameRateFraction, - baseLayerFPSRatioRef)) { - LOGE("Failed to set base layer framerate fraction to %f", - baseLayerFPSRatio); - return InitPromise::CreateAndReject( - MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - nsPrintfCString("fail to configure SVC (base ratio: %f", - baseLayerFPSRatio)), - __func__); - } - } else { - LOGE("MacOS version too old to enable SVC"); - return InitPromise::CreateAndReject( - MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, - "macOS version too old to enable SVC"), - __func__); - } - } - int64_t interval = mConfig.mKeyframeInterval > std::numeric_limits::max() ? std::numeric_limits::max() @@ -550,23 +456,12 @@ void AppleVTEncoder::OutputFrame(CMSampleBufferRef aBuffer) { LOGD("::OutputFrame"); RefPtr output(new MediaRawData()); - if (__builtin_available(macos 11.3, *)) { - if (mConfig.mScalabilityMode != ScalabilityMode::None) { - CFDictionaryRef dict = (CFDictionaryRef)(CFArrayGetValueAtIndex( - CMSampleBufferGetSampleAttachmentsArray(aBuffer, true), 0)); - CFBooleanRef isBaseLayerRef = (CFBooleanRef)CFDictionaryGetValue( - dict, (const void*)kCMSampleAttachmentKey_IsDependedOnByOthers); - Boolean isBaseLayer = CFBooleanGetValue(isBaseLayerRef); - output->mTemporalLayerId.emplace(isBaseLayer ? 0 : 1); - } - } - bool forceAvcc = false; if (mConfig.mCodecSpecific->is()) { forceAvcc = mConfig.mCodecSpecific->as().mFormat == H264BitStreamFormat::AVC; } - bool asAnnexB = !forceAvcc; + bool asAnnexB = mConfig.mUsage == Usage::Realtime && !forceAvcc; bool succeeded = WriteExtraData(output, aBuffer, asAnnexB) && WriteNALUs(output, aBuffer, asAnnexB); @@ -609,9 +504,9 @@ RefPtr AppleVTEncoder::Encode( RefPtr AppleVTEncoder::Reconfigure( const RefPtr& aConfigurationChanges) { - return InvokeAsync(mTaskQueue, this, __func__, - &AppleVTEncoder::ProcessReconfigure, - aConfigurationChanges); + return InvokeAsync&>( + mTaskQueue, this, __func__, &AppleVTEncoder::ProcessReconfigure, + aConfigurationChanges); } RefPtr AppleVTEncoder::ProcessEncode( @@ -660,10 +555,7 @@ AppleVTEncoder::ProcessReconfigure( const RefPtr& aConfigurationChanges) { bool ok = false; for (const auto& confChange : aConfigurationChanges->mChanges) { - // A reconfiguration on the fly succeeds if all changes can be applied - // successfuly. In case of failure, the encoder will be drained and - // recreated. - ok &= confChange.match( + ok |= confChange.match( // Not supported yet [&](const DimensionsChange& aChange) -> bool { return false; }, [&](const DisplayDimensionsChange& aChange) -> bool { return false; }, @@ -835,6 +727,11 @@ RefPtr AppleVTEncoder::ProcessDrain() { AssertOnTaskQueue(); MOZ_ASSERT(mSession); + if (mFramesCompleted) { + MOZ_DIAGNOSTIC_ASSERT(mEncodedData.IsEmpty()); + return EncodePromise::CreateAndResolve(EncodedData(), __func__); + } + OSStatus status = VTCompressionSessionCompleteFrames(mSession, kCMTimeIndefinite); if (status != noErr) { @@ -842,6 +739,7 @@ RefPtr AppleVTEncoder::ProcessDrain() { return EncodePromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__); } + mFramesCompleted = true; // VTCompressionSessionCompleteFrames() could have queued multiple tasks with // the new drained frames. Dispatch a task after them to resolve the promise // with those frames. diff --git a/dom/media/platforms/apple/AppleVTEncoder.h b/dom/media/platforms/apple/AppleVTEncoder.h index c8c5f691509b..b3a88e209848 100644 --- a/dom/media/platforms/apple/AppleVTEncoder.h +++ b/dom/media/platforms/apple/AppleVTEncoder.h @@ -28,6 +28,7 @@ class AppleVTEncoder final : public MediaDataEncoder { mTaskQueue(aTaskQueue), mHardwareNotAllowed(aConfig.mHardwarePreference == HardwarePreference::RequireSoftware), + mFramesCompleted(false), mError(NS_OK), mSession(nullptr) { MOZ_ASSERT(mConfig.mSize.width > 0 && mConfig.mSize.height > 0); @@ -73,6 +74,7 @@ class AppleVTEncoder final : public MediaDataEncoder { const bool mHardwareNotAllowed; // Access only in mTaskQueue. EncodedData mEncodedData; + bool mFramesCompleted; RefPtr mAvcc; // Stores latest avcC data. MediaResult mError; diff --git a/dom/media/webcodecs/EncoderAgent.cpp b/dom/media/webcodecs/EncoderAgent.cpp index bb02f1835fcc..e6af17a0be45 100644 --- a/dom/media/webcodecs/EncoderAgent.cpp +++ b/dom/media/webcodecs/EncoderAgent.cpp @@ -205,7 +205,6 @@ RefPtr EncoderAgent::Reconfigure( self->mReconfigurationRequest.Complete(); LOGE("EncoderAgent #%zu (%p) reconfigure success", self->mId, self.get()); - self->SetState(State::Configured); self->mReconfigurationPromise.Resolve(true, __func__); }, [self = RefPtr{this}](const MediaResult& aError) { diff --git a/testing/web-platform/meta/webcodecs/full-cycle-test.https.any.js.ini b/testing/web-platform/meta/webcodecs/full-cycle-test.https.any.js.ini index a67317af2adf..a90838a41773 100644 --- a/testing/web-platform/meta/webcodecs/full-cycle-test.https.any.js.ini +++ b/testing/web-platform/meta/webcodecs/full-cycle-test.https.any.js.ini @@ -1,6 +1,6 @@ [full-cycle-test.https.any.html?vp9_p2] disabled: - if (os == "android") or (bits == 32): not implemented + if (os == "mac") or (os == "android") or (bits == 32): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] @@ -13,7 +13,7 @@ [full-cycle-test.https.any.html?vp9_p0] disabled: - if (os == "android") or (bits == 32): not implemented + if (os == "mac") or (os == "android") or (bits == 32): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] @@ -26,7 +26,7 @@ [full-cycle-test.https.any.html?vp8] disabled: - if (os == "android") or (bits == 32): not implemented + if (os == "mac") or (os == "android") or (bits == 32): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] @@ -39,7 +39,7 @@ [full-cycle-test.https.any.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [full-cycle-test.https.any.html?av1] disabled: @@ -69,7 +69,7 @@ [full-cycle-test.https.any.worker.html?vp8] disabled: - if (os == "android") or (bits == 32): not implemented + if (os == "mac") or (os == "android") or (bits == 32): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] @@ -82,11 +82,11 @@ [full-cycle-test.https.any.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [full-cycle-test.https.any.worker.html?vp9_p0] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] @@ -99,15 +99,15 @@ [full-cycle-test.https.any.worker.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [full-cycle-test.https.any.worker.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [full-cycle-test.https.any.worker.html?vp9_p2] disabled: - if (os == "android") or (bits == 32): not implemented + if (os == "mac") or (os == "android") or (bits == 32): not implemented [Encoding and decoding cycle] expected: [PASS, FAIL] diff --git a/testing/web-platform/meta/webcodecs/reconfiguring-encoder.https.any.js.ini b/testing/web-platform/meta/webcodecs/reconfiguring-encoder.https.any.js.ini index 5f37771e1170..7371f71a20d8 100644 --- a/testing/web-platform/meta/webcodecs/reconfiguring-encoder.https.any.js.ini +++ b/testing/web-platform/meta/webcodecs/reconfiguring-encoder.https.any.js.ini @@ -1,6 +1,6 @@ [reconfiguring-encoder.https.any.worker.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [reconfiguring-encoder.https.any.html?av1] disabled: @@ -20,11 +20,11 @@ [reconfiguring-encoder.https.any.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [reconfiguring-encoder.https.any.worker.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [reconfiguring-encoder.https.any.html?vp9_p2] disabled: @@ -46,7 +46,7 @@ [reconfiguring-encoder.https.any.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [reconfiguring-encoder.https.any.html?vp8] disabled: diff --git a/testing/web-platform/meta/webcodecs/temporal-svc-encoding.https.any.js.ini b/testing/web-platform/meta/webcodecs/temporal-svc-encoding.https.any.js.ini index 48329d34de09..9b99c75bd6d1 100644 --- a/testing/web-platform/meta/webcodecs/temporal-svc-encoding.https.any.js.ini +++ b/testing/web-platform/meta/webcodecs/temporal-svc-encoding.https.any.js.ini @@ -10,15 +10,7 @@ if (os == "win") or (os == "android"): not implemented [temporal-svc-encoding.https.any.worker.html?h264] - disabled: - if (os == "win") or (os == "linux") or (os == "android"): not implemented - [SVC L1T2] - expected: - if (os == "mac") and (os_version == "10.15"): PRECONDITION_FAILED - PASS - [SVC L1T3] - expected: PRECONDITION_FAILED - + disabled: not implemented [temporal-svc-encoding.https.any.html?av1] disabled: not implemented @@ -28,16 +20,9 @@ if (os == "win") or (os == "android"): not implemented [temporal-svc-encoding.https.any.html?h264] - disabled: - if (os == "win") or (os == "linux") or (os == "android"): not implemented - [SVC L1T2] - expected: - if (os == "mac") and (os_version == "10.15"): PRECONDITION_FAILED - PASS - [SVC L1T3] - expected: PRECONDITION_FAILED - + disabled: not implemented [temporal-svc-encoding.https.any.html?vp9] disabled: if (os == "win") or (os == "android"): not implemented + diff --git a/testing/web-platform/meta/webcodecs/video-encoder-flush.https.any.js.ini b/testing/web-platform/meta/webcodecs/video-encoder-flush.https.any.js.ini index 9d3f5858d03e..baba28e119cd 100644 --- a/testing/web-platform/meta/webcodecs/video-encoder-flush.https.any.js.ini +++ b/testing/web-platform/meta/webcodecs/video-encoder-flush.https.any.js.ini @@ -8,11 +8,11 @@ [video-encoder-flush.https.any.worker.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [video-encoder-flush.https.any.html?h264_annexb] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [video-encoder-flush.https.any.worker.html?vp8] disabled: @@ -24,8 +24,8 @@ [video-encoder-flush.https.any.worker.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented [video-encoder-flush.https.any.html?h264_avc] disabled: - if (os == "android") or (version == "Ubuntu 18.04"): not implemented + if (os == "mac") or (os == "android") or (version == "Ubuntu 18.04"): not implemented diff --git a/testing/web-platform/meta/webcodecs/videoFrame-createImageBitmap.https.any.js.ini b/testing/web-platform/meta/webcodecs/videoFrame-createImageBitmap.https.any.js.ini index 5a2f40deec49..c96d63e442b4 100644 --- a/testing/web-platform/meta/webcodecs/videoFrame-createImageBitmap.https.any.js.ini +++ b/testing/web-platform/meta/webcodecs/videoFrame-createImageBitmap.https.any.js.ini @@ -1,13 +1,13 @@ [videoFrame-createImageBitmap.https.any.html] disabled: - if (os == "android"): not implemented + if (os == "macOS") or (os == "android"): not implemented [Create ImageBitmap for a VideoFrame from VP9 decoder.] expected: if (os == "win") and ccov: FAIL [videoFrame-createImageBitmap.https.any.worker.html] disabled: - if (os == "android"): not implemented + if (os == "macOS") or (os == "android"): not implemented [Create ImageBitmap for a VideoFrame from VP9 decoder.] expected: if (os == "win") and ccov: FAIL