зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1749047 - harzar fix. CLOSED TREE
This patch uses RootedDictionary around `EncodedVideoChunkMetadata`, `VideoDecoderConfig` and `VideoColorSpaceInit` in `OutputEncodedData` to work around the JS hazard (unrooted) issues. Differential Revision: https://phabricator.services.mozilla.com/D197228
This commit is contained in:
Родитель
e07cea7e9d
Коммит
e6d0f178af
|
@ -43,6 +43,15 @@ class VideoDecoderConfigInternal {
|
|||
public:
|
||||
static UniquePtr<VideoDecoderConfigInternal> Create(
|
||||
const VideoDecoderConfig& aConfig);
|
||||
VideoDecoderConfigInternal(const nsAString& aCodec,
|
||||
Maybe<uint32_t>&& aCodedHeight,
|
||||
Maybe<uint32_t>&& aCodedWidth,
|
||||
Maybe<VideoColorSpaceInternal>&& aColorSpace,
|
||||
Maybe<RefPtr<MediaByteBuffer>>&& aDescription,
|
||||
Maybe<uint32_t>&& aDisplayAspectHeight,
|
||||
Maybe<uint32_t>&& aDisplayAspectWidth,
|
||||
const HardwareAcceleration& aHardwareAcceleration,
|
||||
Maybe<bool>&& aOptimizeForLatency);
|
||||
~VideoDecoderConfigInternal() = default;
|
||||
|
||||
nsString ToString() const;
|
||||
|
@ -79,17 +88,6 @@ class VideoDecoderConfigInternal {
|
|||
Maybe<uint32_t> mDisplayAspectWidth;
|
||||
HardwareAcceleration mHardwareAcceleration;
|
||||
Maybe<bool> mOptimizeForLatency;
|
||||
|
||||
private:
|
||||
VideoDecoderConfigInternal(const nsAString& aCodec,
|
||||
Maybe<uint32_t>&& aCodedHeight,
|
||||
Maybe<uint32_t>&& aCodedWidth,
|
||||
Maybe<VideoColorSpaceInternal>&& aColorSpace,
|
||||
Maybe<RefPtr<MediaByteBuffer>>&& aDescription,
|
||||
Maybe<uint32_t>&& aDisplayAspectHeight,
|
||||
Maybe<uint32_t>&& aDisplayAspectWidth,
|
||||
const HardwareAcceleration& aHardwareAcceleration,
|
||||
Maybe<bool>&& aOptimizeForLatency);
|
||||
};
|
||||
|
||||
class VideoDecoderTraits {
|
||||
|
|
|
@ -305,6 +305,14 @@ void EncoderTemplate<EncoderType>::OutputEncodedData(
|
|||
MOZ_ASSERT(mState == CodecState::Configured);
|
||||
MOZ_ASSERT(mActiveConfig);
|
||||
|
||||
// Get JSContext for RootedDictionary.
|
||||
// The EncoderType::MetadataType, VideoDecoderConfig, and VideoColorSpaceInit
|
||||
// below are rooted to work around the JS hazard issues.
|
||||
AutoJSAPI jsapi;
|
||||
DebugOnly<bool> ok =
|
||||
jsapi.Init(GetParentObject()); // TODO: check returned value?
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
RefPtr<typename EncoderType::OutputCallbackType> cb(mOutputCallback);
|
||||
for (auto& data : aData) {
|
||||
// It's possible to have reset() called in between this task having been
|
||||
|
@ -317,15 +325,69 @@ void EncoderTemplate<EncoderType>::OutputEncodedData(
|
|||
}
|
||||
RefPtr<typename EncoderType::OutputType> encodedData =
|
||||
EncodedDataToOutputType(GetParentObject(), data);
|
||||
typename EncoderType::MetadataType metadata;
|
||||
|
||||
RootedDictionary<typename EncoderType::MetadataType> metadata(cx);
|
||||
if (mOutputNewDecoderConfig) {
|
||||
metadata.mDecoderConfig.Construct(EncoderConfigToDecoderConfig(
|
||||
GetParentObject(), data, *mActiveConfig));
|
||||
VideoDecoderConfigInternal decoderConfigInternal =
|
||||
EncoderConfigToDecoderConfig(GetParentObject(), data, *mActiveConfig);
|
||||
|
||||
// Convert VideoDecoderConfigInternal to VideoDecoderConfig
|
||||
RootedDictionary<VideoDecoderConfig> decoderConfig(cx);
|
||||
decoderConfig.mCodec = decoderConfigInternal.mCodec;
|
||||
if (decoderConfigInternal.mCodedHeight) {
|
||||
decoderConfig.mCodedHeight.Construct(
|
||||
decoderConfigInternal.mCodedHeight.value());
|
||||
}
|
||||
if (decoderConfigInternal.mCodedWidth) {
|
||||
decoderConfig.mCodedWidth.Construct(
|
||||
decoderConfigInternal.mCodedWidth.value());
|
||||
}
|
||||
if (decoderConfigInternal.mColorSpace) {
|
||||
RootedDictionary<VideoColorSpaceInit> colorSpace(cx);
|
||||
colorSpace.mFullRange =
|
||||
MaybeToNullable(decoderConfigInternal.mColorSpace->mFullRange);
|
||||
colorSpace.mMatrix =
|
||||
MaybeToNullable(decoderConfigInternal.mColorSpace->mMatrix);
|
||||
colorSpace.mPrimaries =
|
||||
MaybeToNullable(decoderConfigInternal.mColorSpace->mPrimaries);
|
||||
colorSpace.mTransfer =
|
||||
MaybeToNullable(decoderConfigInternal.mColorSpace->mTransfer);
|
||||
decoderConfig.mColorSpace.Construct(std::move(colorSpace));
|
||||
}
|
||||
if (decoderConfigInternal.mDescription &&
|
||||
!decoderConfigInternal.mDescription.value()->IsEmpty()) {
|
||||
auto& abov = decoderConfig.mDescription.Construct();
|
||||
AutoEntryScript aes(GetParentObject(), "EncoderConfigToDecoderConfig");
|
||||
size_t lengthBytes =
|
||||
decoderConfigInternal.mDescription.value()->Length();
|
||||
UniquePtr<uint8_t[], JS::FreePolicy> extradata(
|
||||
new uint8_t[lengthBytes]);
|
||||
PodCopy(extradata.get(),
|
||||
decoderConfigInternal.mDescription.value()->Elements(),
|
||||
lengthBytes);
|
||||
JS::Rooted<JSObject*> description(
|
||||
aes.cx(), JS::NewArrayBufferWithContents(aes.cx(), lengthBytes,
|
||||
std::move(extradata)));
|
||||
JS::Rooted<JS::Value> value(aes.cx(), JS::ObjectValue(*description));
|
||||
DebugOnly<bool> rv = abov.Init(aes.cx(), value);
|
||||
}
|
||||
if (decoderConfigInternal.mDisplayAspectHeight) {
|
||||
decoderConfig.mDisplayAspectHeight.Construct(
|
||||
decoderConfigInternal.mDisplayAspectHeight.value());
|
||||
}
|
||||
if (decoderConfigInternal.mDisplayAspectWidth) {
|
||||
decoderConfig.mDisplayAspectWidth.Construct(
|
||||
decoderConfigInternal.mDisplayAspectWidth.value());
|
||||
}
|
||||
if (decoderConfigInternal.mOptimizeForLatency) {
|
||||
decoderConfig.mOptimizeForLatency.Construct(
|
||||
decoderConfigInternal.mOptimizeForLatency.value());
|
||||
}
|
||||
|
||||
metadata.mDecoderConfig.Construct(std::move(decoderConfig));
|
||||
mOutputNewDecoderConfig = false;
|
||||
LOGE("New config passed to output callback: %s",
|
||||
NS_ConvertUTF16toUTF8(ConfigToString(EncoderConfigToDecoderConfig(
|
||||
GetParentObject(), data, *mActiveConfig)))
|
||||
.get());
|
||||
NS_ConvertUTF16toUTF8(decoderConfigInternal.ToString()).get());
|
||||
}
|
||||
LOG("EncoderTemplate:: output callback (ts: % " PRId64 " ), %s",
|
||||
encodedData->Timestamp(),
|
||||
|
|
|
@ -77,7 +77,7 @@ class VideoEncoderTraits {
|
|||
using ConfigTypeInternal = VideoEncoderConfigInternal;
|
||||
using InputType = dom::VideoFrame;
|
||||
using InputTypeInternal = mozilla::VideoData;
|
||||
using OutputConfigType = mozilla::dom::VideoDecoderConfig;
|
||||
using OutputConfigType = mozilla::dom::VideoDecoderConfigInternal;
|
||||
using OutputType = EncodedVideoChunk;
|
||||
using OutputCallbackType = EncodedVideoChunkOutputCallback;
|
||||
using MetadataType = EncodedVideoChunkMetadata;
|
||||
|
|
|
@ -586,43 +586,29 @@ RefPtr<EncodedVideoChunk> VideoEncoder::EncodedDataToOutputType(
|
|||
return encodedVideoChunk;
|
||||
}
|
||||
|
||||
VideoDecoderConfig VideoEncoder::EncoderConfigToDecoderConfig(
|
||||
VideoDecoderConfigInternal VideoEncoder::EncoderConfigToDecoderConfig(
|
||||
nsIGlobalObject* aGlobal, const RefPtr<MediaRawData>& aRawData,
|
||||
const VideoEncoderConfigInternal& mOutputConfig) const {
|
||||
VideoDecoderConfig decoderConfig;
|
||||
decoderConfig.mCodec = mOutputConfig.mCodec;
|
||||
decoderConfig.mCodedWidth.Construct(mOutputConfig.mWidth);
|
||||
decoderConfig.mCodedHeight.Construct(mOutputConfig.mHeight);
|
||||
if (mOutputConfig.mDisplayWidth.isSome()) {
|
||||
MOZ_ASSERT(mOutputConfig.mDisplayHeight.isSome());
|
||||
decoderConfig.mDisplayAspectWidth.Construct(
|
||||
mOutputConfig.mDisplayWidth.value());
|
||||
decoderConfig.mDisplayAspectHeight.Construct(
|
||||
mOutputConfig.mDisplayHeight.value());
|
||||
}
|
||||
|
||||
// Colorspace is mandatory when outputing a decoder config after encode
|
||||
VideoColorSpaceInit init;
|
||||
init.mFullRange = false;
|
||||
init.mMatrix = VideoMatrixCoefficients::Bt709;
|
||||
init.mPrimaries = VideoColorPrimaries::Bt709;
|
||||
init.mTransfer = VideoTransferCharacteristics::Bt709;
|
||||
decoderConfig.mColorSpace.Construct(init);
|
||||
VideoColorSpaceInternal init;
|
||||
init.mFullRange.emplace(false);
|
||||
init.mMatrix.emplace(VideoMatrixCoefficients::Bt709);
|
||||
init.mPrimaries.emplace(VideoColorPrimaries::Bt709);
|
||||
init.mTransfer.emplace(VideoTransferCharacteristics::Bt709);
|
||||
|
||||
if (aRawData->mExtraData) {
|
||||
auto& abov = decoderConfig.mDescription.Construct();
|
||||
AutoEntryScript aes(aGlobal, "EncoderConfigToDecoderConfig");
|
||||
size_t lengthBytes = aRawData->mExtraData->Length();
|
||||
UniquePtr<uint8_t[], JS::FreePolicy> extradata(new uint8_t[lengthBytes]);
|
||||
PodCopy(extradata.get(), aRawData->mExtraData->Elements(), lengthBytes);
|
||||
JS::Rooted<JSObject*> description(
|
||||
aes.cx(), JS::NewArrayBufferWithContents(aes.cx(), lengthBytes,
|
||||
std::move(extradata)));
|
||||
JS::Rooted<JS::Value> value(aes.cx(), JS::ObjectValue(*description));
|
||||
DebugOnly<bool> rv = abov.Init(aes.cx(), value);
|
||||
}
|
||||
|
||||
return decoderConfig;
|
||||
return VideoDecoderConfigInternal(
|
||||
mOutputConfig.mCodec, /* aCodec */
|
||||
Some(mOutputConfig.mHeight), /* aCodedHeight */
|
||||
Some(mOutputConfig.mWidth), /* aCodedWidth */
|
||||
Some(init), /* aColorSpace */
|
||||
aRawData->mExtraData && !aRawData->mExtraData->IsEmpty()
|
||||
? Some(aRawData->mExtraData)
|
||||
: Nothing(), /* aDescription*/
|
||||
Maybe<uint32_t>(mOutputConfig.mDisplayHeight), /* aDisplayAspectHeight*/
|
||||
Maybe<uint32_t>(mOutputConfig.mDisplayWidth), /* aDisplayAspectWidth */
|
||||
mOutputConfig.mHardwareAcceleration, /* aHardwareAcceleration */
|
||||
Nothing() /* aOptimizeForLatency */
|
||||
);
|
||||
}
|
||||
|
||||
#undef LOG
|
||||
|
|
|
@ -67,8 +67,8 @@ class VideoEncoder final : public EncoderTemplate<VideoEncoderTraits> {
|
|||
virtual RefPtr<EncodedVideoChunk> EncodedDataToOutputType(
|
||||
nsIGlobalObject* aGlobal, RefPtr<MediaRawData>& aData) override;
|
||||
|
||||
virtual VideoDecoderConfig EncoderConfigToDecoderConfig(
|
||||
nsIGlobalObject* aGlobal,
|
||||
virtual VideoDecoderConfigInternal EncoderConfigToDecoderConfig(
|
||||
nsIGlobalObject* aGlobal /* TODO: delete */,
|
||||
const RefPtr<MediaRawData>& aRawData,
|
||||
const VideoEncoderConfigInternal& mOutputConfig) const override;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче