Bug 1758789 - part5 : using a fake decoded data generator in the stream wrapper. r=jolin

Media engine would handle the decoded data inside its pipeline, so we can't access them. Return fakes data instead, which helps the format reader stops sending endless data for the media engine. (because the format reader expects getting output data)

Differential Revision: https://phabricator.services.mozilla.com/D145153
This commit is contained in:
alwu 2022-06-30 22:34:17 +00:00
Родитель e2b58de49a
Коммит 4bf2469bc0
3 изменённых файлов: 53 добавлений и 17 удалений

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

@ -223,11 +223,12 @@ MFMediaEngineStreamWrapper* MFMediaEngineParent::GetMediaEngineStream(
MOZ_ASSERT(mMediaSource);
if (aType == TrackType::kAudioTrack) {
auto* stream = mMediaSource->GetAudioStream();
return new MFMediaEngineStreamWrapper(stream, stream->GetTaskQueue());
return new MFMediaEngineStreamWrapper(stream, stream->GetTaskQueue(),
aParam);
}
MOZ_ASSERT(aType == TrackType::kVideoTrack);
auto* stream = mMediaSource->GetVideoStream();
return new MFMediaEngineStreamWrapper(stream, stream->GetTaskQueue());
return new MFMediaEngineStreamWrapper(stream, stream->GetTaskQueue(), aParam);
}
mozilla::ipc::IPCResult MFMediaEngineParent::RecvInitMediaEngine(

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

@ -51,19 +51,8 @@ RefPtr<MediaDataDecoder::DecodePromise> MFMediaEngineStreamWrapper::Decode(
// We don't return a real data, all data would be processed inside the media
// engine. We return an empty data back instead.
DecodedData samples;
if (mStream->TrackType() == TrackInfo::TrackType::kAudioTrack) {
AudioSampleBuffer data(nullptr, 0);
// TODO : use a null data for audio?
samples.AppendElement(MakeRefPtr<AudioData>(
aSample->mOffset, aSample->mTime, data.Forget(), 1, 1));
} else {
// Remote video decoder parant will transfer null data to a video data.
MOZ_ASSERT(mStream->TrackType() == TrackInfo::TrackType::kVideoTrack);
samples.AppendElement(MakeRefPtr<NullData>(aSample->mOffset, aSample->mTime,
aSample->mDuration));
}
return DecodePromise::CreateAndResolve(std::move(samples), __func__);
MOZ_ASSERT(mFakeDataCreator->Type() == mStream->TrackType());
return mFakeDataCreator->Decode(aSample);
}
RefPtr<MediaDataDecoder::DecodePromise> MFMediaEngineStreamWrapper::Drain() {
@ -84,6 +73,7 @@ RefPtr<MediaDataDecoder::FlushPromise> MFMediaEngineStreamWrapper::Flush() {
MediaResult(NS_ERROR_FAILURE, "MFMediaEngineStreamWrapper is shutdown"),
__func__);
}
mFakeDataCreator->Flush();
return InvokeAsync(mTaskQueue, mStream.Get(), __func__,
&MFMediaEngineStream::Flush);
}
@ -99,6 +89,7 @@ RefPtr<ShutdownPromise> MFMediaEngineStreamWrapper::Shutdown() {
}
mStream = nullptr;
mTaskQueue = nullptr;
mFakeDataCreator = nullptr;
return ShutdownPromise::CreateAndResolve(true, __func__);
}
@ -106,6 +97,27 @@ nsCString MFMediaEngineStreamWrapper::GetDescriptionName() const {
return mStream ? mStream->GetDescriptionName() : nsLiteralCString("none");
}
MFMediaEngineStreamWrapper::FakeDecodedDataCreator::FakeDecodedDataCreator(
const CreateDecoderParams& aParams) {
if (aParams.mConfig.IsVideo()) {
const VideoInfo& config = aParams.VideoConfig();
mDummyDecoder = new DummyMediaDataDecoder(
MakeUnique<BlankVideoDataCreator>(config.mDisplay.width,
config.mDisplay.height,
aParams.mImageContainer),
"blank video data decoder for media engine"_ns, aParams);
mType = TrackInfo::TrackType::kVideoTrack;
} else if (aParams.mConfig.IsAudio()) {
const AudioInfo& config = aParams.AudioConfig();
mDummyDecoder = new DummyMediaDataDecoder(
MakeUnique<BlankAudioDataCreator>(config.mChannels, config.mRate),
"blank audio data decoder for media engine"_ns, aParams);
mType = TrackInfo::TrackType::kAudioTrack;
} else {
MOZ_ASSERT_UNREACHABLE("unexpected config type");
}
}
MFMediaEngineStream::MFMediaEngineStream()
: mIsShutdown(false),
mIsSelected(false),

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

@ -10,6 +10,7 @@
#include <queue>
#include "BlankDecoderModule.h"
#include "MediaQueue.h"
#include "PlatformDecoderModule.h"
#include "mozilla/Atomics.h"
@ -152,10 +153,14 @@ class MFMediaEngineStream
class MFMediaEngineStreamWrapper : public MediaDataDecoder {
public:
MFMediaEngineStreamWrapper(MFMediaEngineStream* aStream,
TaskQueue* aTaskQueue)
: mStream(aStream), mTaskQueue(aTaskQueue) {
TaskQueue* aTaskQueue,
const CreateDecoderParams& aParams)
: mStream(aStream),
mTaskQueue(aTaskQueue),
mFakeDataCreator(new FakeDecodedDataCreator(aParams)) {
MOZ_ASSERT(mStream);
MOZ_ASSERT(mTaskQueue);
MOZ_ASSERT(mFakeDataCreator);
}
// Methods for MediaDataDecoder, they are all called on the remote
@ -169,7 +174,25 @@ class MFMediaEngineStreamWrapper : public MediaDataDecoder {
private:
Microsoft::WRL::ComPtr<MFMediaEngineStream> mStream;
// We use this to generate fake decoded outputs, as the real data is handled
// inside the media engine. Audio output is not possible to get, the video
// output would be output via DCOMP.
class FakeDecodedDataCreator final {
public:
explicit FakeDecodedDataCreator(const CreateDecoderParams& aParams);
RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample) {
return mDummyDecoder->Decode(aSample);
}
void Flush() { Unused << mDummyDecoder->Flush(); }
TrackInfo::TrackType Type() const { return mType; }
private:
RefPtr<MediaDataDecoder> mDummyDecoder;
TrackInfo::TrackType mType;
};
RefPtr<TaskQueue> mTaskQueue;
UniquePtr<FakeDecodedDataCreator> mFakeDataCreator;
};
} // namespace mozilla