Bug 1840965 - Move Decode to template r=padenot

This patches renames the OutputVideoFrames to OutputDecodedData and add
a function to convert DecodedData to the output type defined by the
template inheritance.

Differential Revision: https://phabricator.services.mozilla.com/D189015
This commit is contained in:
Chun-Min Chang 2023-10-02 15:54:00 +00:00
Родитель f75a9dac7e
Коммит 6c5416a4a2
6 изменённых файлов: 57 добавлений и 40 удалений

Просмотреть файл

@ -188,6 +188,35 @@ void DecoderTemplate<DecoderType>::Configure(const ConfigType& aConfig,
ProcessControlMessageQueue();
}
template <typename DecoderType>
void DecoderTemplate<DecoderType>::Decode(InputType& aInput, ErrorResult& aRv) {
AssertIsOnOwningThread();
LOG("VideoDecoder %p, Decode", this);
if (mState != CodecState::Configured) {
aRv.ThrowInvalidStateError("Decoder must be configured first");
return;
}
if (mKeyChunkRequired) {
// TODO: Verify input's data is truly a key chunk
if (!DecoderType::IsKeyChunk(aInput)) {
aRv.ThrowDataError("VideoDecoder needs a key chunk");
return;
}
mKeyChunkRequired = false;
}
mDecodeQueueSize += 1;
mControlMessageQueue.emplace(UniquePtr<ControlMessage>(
new DecodeMessage(++mDecodeCounter, mLatestConfigureId,
DecoderType::CreateInputInternal(aInput))));
LOGV("VideoDecoder %p enqueues %s", this,
mControlMessageQueue.back()->ToString().get());
ProcessControlMessageQueue();
}
template <typename DecoderType>
void DecoderTemplate<DecoderType>::Reset(ErrorResult& aRv) {
AssertIsOnOwningThread();
@ -262,7 +291,7 @@ void DecoderTemplate<DecoderType>::ReportError(const nsresult& aResult) {
}
template <typename DecoderType>
void DecoderTemplate<DecoderType>::OutputVideoFrames(
void DecoderTemplate<DecoderType>::OutputDecodedData(
nsTArray<RefPtr<MediaData>>&& aData) {
AssertIsOnOwningThread();
MOZ_ASSERT(mState == CodecState::Configured);
@ -352,7 +381,7 @@ class DecoderTemplate<DecoderType>::OutputRunnable final
LOGV("VideoDecoder %p, yields %s-result for DecoderAgent #%d",
mVideoDecoder.get(), mLabel.get(), mAgentId);
RefPtr<Self> d = std::move(mVideoDecoder);
d->OutputVideoFrames(std::move(mData));
d->OutputDecodedData(std::move(mData));
return NS_OK;
}
@ -365,7 +394,7 @@ class DecoderTemplate<DecoderType>::OutputRunnable final
};
template <typename DecoderType>
void DecoderTemplate<DecoderType>::ScheduleOutputVideoFrames(
void DecoderTemplate<DecoderType>::ScheduleOutputDecodedData(
nsTArray<RefPtr<MediaData>>&& aData, const nsACString& aLabel) {
MOZ_ASSERT(mState == CodecState::Configured);
MOZ_ASSERT(mAgent);
@ -678,7 +707,7 @@ MessageProcessedResult DecoderTemplate<DecoderType>::ProcessDecodeMessage(
"VideoDecoder %p, schedule %zu decoded data output for "
"%s",
self.get(), data.Length(), msgStr.get());
self->ScheduleOutputVideoFrames(std::move(data), msgStr);
self->ScheduleOutputDecodedData(std::move(data), msgStr);
}
self->ProcessControlMessageQueue();
@ -775,7 +804,7 @@ MessageProcessedResult DecoderTemplate<DecoderType>::ProcessFlushMessage(
LOG("VideoDecoder %p, schedule %zu decoded data output for "
"%s",
self.get(), data.Length(), msgStr.get());
self->ScheduleOutputVideoFrames(std::move(data), msgStr);
self->ScheduleOutputDecodedData(std::move(data), msgStr);
}
self->SchedulePromiseResolveOrReject(msg->TakePromise(), NS_OK);

Просмотреть файл

@ -51,6 +51,7 @@ class DecoderTemplate : public DOMEventTargetHelper {
using Self = DecoderTemplate<DecoderType>;
using ConfigType = typename DecoderType::ConfigType;
using ConfigTypeInternal = typename DecoderType::ConfigTypeInternal;
using InputType = typename DecoderType::InputType;
using InputTypeInternal = typename DecoderType::InputTypeInternal;
using OutputType = typename DecoderType::OutputType;
using OutputCallbackType = typename DecoderType::OutputCallbackType;
@ -154,6 +155,8 @@ class DecoderTemplate : public DOMEventTargetHelper {
// TODO: Replace virtual with MOZ_EXPORT (visibility("default"))
virtual void Configure(const ConfigType& aConfig, ErrorResult& aRv);
virtual void Decode(InputType& aInput, ErrorResult& aRv);
virtual void Reset(ErrorResult& aRv);
virtual void Close(ErrorResult& aRv);
@ -178,14 +181,14 @@ class DecoderTemplate : public DOMEventTargetHelper {
Result<Ok, nsresult> CloseInternal(const nsresult& aResult);
MOZ_CAN_RUN_SCRIPT void ReportError(const nsresult& aResult);
MOZ_CAN_RUN_SCRIPT void OutputVideoFrames(
MOZ_CAN_RUN_SCRIPT void OutputDecodedData(
nsTArray<RefPtr<MediaData>>&& aData);
class ErrorRunnable;
void ScheduleReportError(const nsresult& aResult);
class OutputRunnable;
void ScheduleOutputVideoFrames(nsTArray<RefPtr<MediaData>>&& aData,
void ScheduleOutputDecodedData(nsTArray<RefPtr<MediaData>>&& aData,
const nsACString& aLabel);
void ScheduleClose(const nsresult& aResult);

Просмотреть файл

@ -61,7 +61,7 @@ EncodedVideoChunkData::EncodedVideoChunkData(
static_cast<size_t>(std::numeric_limits<uint32_t>::max()));
}
UniquePtr<EncodedVideoChunkData> EncodedVideoChunkData::Clone() {
UniquePtr<EncodedVideoChunkData> EncodedVideoChunkData::Clone() const {
if (!mBuffer) {
LOGE("No buffer in EncodedVideoChunkData %p to clone!", this);
return nullptr;

Просмотреть файл

@ -45,7 +45,7 @@ class EncodedVideoChunkData {
EncodedVideoChunkData(const EncodedVideoChunkData& aData) = default;
~EncodedVideoChunkData() = default;
UniquePtr<EncodedVideoChunkData> Clone();
UniquePtr<EncodedVideoChunkData> Clone() const;
already_AddRefed<MediaRawData> TakeData();
protected:

Просмотреть файл

@ -697,6 +697,17 @@ UniquePtr<VideoDecoderConfigInternal> VideoDecoderTraits::CreateConfigInternal(
return VideoDecoderConfigInternal::Create(aConfig);
}
/* static */
bool VideoDecoderTraits::IsKeyChunk(const EncodedVideoChunk& aInput) {
return aInput.Type() == EncodedVideoChunkType::Key;
}
/* static */
UniquePtr<EncodedVideoChunkData> VideoDecoderTraits::CreateInputInternal(
const EncodedVideoChunk& aInput) {
return aInput.Clone();
}
/*
* Below are VideoDecoder implementation
*/
@ -739,34 +750,6 @@ already_AddRefed<VideoDecoder> VideoDecoder::Constructor(
RefPtr<VideoFrameOutputCallback>(aInit.mOutput));
}
// https://w3c.github.io/webcodecs/#dom-videodecoder-decode
void VideoDecoder::Decode(EncodedVideoChunk& aChunk, ErrorResult& aRv) {
AssertIsOnOwningThread();
LOG("VideoDecoder %p, Decode", this);
if (mState != CodecState::Configured) {
aRv.ThrowInvalidStateError("Decoder must be configured first");
return;
}
if (mKeyChunkRequired) {
// TODO: Verify aChunk's data is truly a key chunk
if (aChunk.Type() != EncodedVideoChunkType::Key) {
aRv.ThrowDataError("VideoDecoder needs a key chunk");
return;
}
mKeyChunkRequired = false;
}
mDecodeQueueSize += 1;
mControlMessageQueue.emplace(UniquePtr<ControlMessage>(
new DecodeMessage(++mDecodeCounter, mLatestConfigureId, aChunk.Clone())));
LOGV("VideoDecoder %p enqueues %s", this,
mControlMessageQueue.back()->ToString().get());
ProcessControlMessageQueue();
}
// https://w3c.github.io/webcodecs/#dom-videodecoder-flush
already_AddRefed<Promise> VideoDecoder::Flush(ErrorResult& aRv) {
AssertIsOnOwningThread();
@ -844,8 +827,8 @@ already_AddRefed<Promise> VideoDecoder::IsConfigSupported(
already_AddRefed<MediaRawData> VideoDecoder::InputDataToMediaRawData(
UniquePtr<EncodedVideoChunkData>&& aData, TrackInfo& aInfo,
const VideoDecoderConfigInternal& aConfig) {
MOZ_ASSERT(aInfo.GetAsVideoInfo());
AssertIsOnOwningThread();
MOZ_ASSERT(aInfo.GetAsVideoInfo());
if (!aData) {
LOGE("No data for conversion");

Просмотреть файл

@ -53,6 +53,7 @@ class VideoDecoderTraits {
public:
using ConfigType = VideoDecoderConfig;
using ConfigTypeInternal = VideoDecoderConfigInternal;
using InputType = EncodedVideoChunk;
using InputTypeInternal = EncodedVideoChunkData;
using OutputType = VideoFrame;
using OutputCallbackType = VideoFrameOutputCallback;
@ -63,6 +64,9 @@ class VideoDecoderTraits {
static bool Validate(const ConfigType& aConfig);
static UniquePtr<ConfigTypeInternal> CreateConfigInternal(
const ConfigType& aConfig);
static bool IsKeyChunk(const InputType& aInput);
static UniquePtr<InputTypeInternal> CreateInputInternal(
const InputType& aInput);
};
class VideoDecoder final : public DecoderTemplate<VideoDecoderTraits> {
@ -86,8 +90,6 @@ class VideoDecoder final : public DecoderTemplate<VideoDecoderTraits> {
const GlobalObject& aGlobal, const VideoDecoderInit& aInit,
ErrorResult& aRv);
void Decode(EncodedVideoChunk& aChunk, ErrorResult& aRv);
already_AddRefed<Promise> Flush(ErrorResult& aRv);
static already_AddRefed<Promise> IsConfigSupported(