зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1648309 - P3. Use ArrayOfRemoteMediaRawData inplace of an actual array. r=padenot,mjf
The reduce the amount of shmem allocations to 1 instead of 100 when used with webaudio. We also fix the AudioTrimmer for remote decoders as the trimming information was lost over the IPC serialization. Another issue corrected is that we no longer crash if the first MediaRawData decoded had an empty size. Differential Revision: https://phabricator.services.mozilla.com/D91538
This commit is contained in:
Родитель
2c63e2e5b0
Коммит
8f76bc3fd0
|
@ -18,16 +18,4 @@ struct MediaDataIPDL
|
|||
bool keyframe;
|
||||
};
|
||||
|
||||
// used for SendInput/RecvInput
|
||||
struct MediaRawDataIPDL
|
||||
{
|
||||
MediaDataIPDL base;
|
||||
bool eos;
|
||||
uint32_t discardPadding;
|
||||
// Pass along buffer size since we're using ShmemPool
|
||||
// and we can receive buffers larger than requested size.
|
||||
int64_t bufferSize;
|
||||
Shmem buffer;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -11,6 +11,7 @@ using mozilla::MediaDataDecoder::ConversionRequired from "PlatformDecoderModule.
|
|||
using mozilla::TrackInfo::TrackType from "MediaInfo.h";
|
||||
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
|
||||
using mozilla::MediaResult from "MediaResult.h";
|
||||
using refcounted class mozilla::ArrayOfRemoteMediaRawData from "mozilla/RemoteMediaData.h";
|
||||
using refcounted class mozilla::ArrayOfRemoteVideoData from "mozilla/RemoteMediaData.h";
|
||||
include PMediaDecoderParams;
|
||||
include LayersSurfaces;
|
||||
|
@ -72,7 +73,7 @@ parent:
|
|||
// frame. This SurfaceDescriptor can be used on the Layers IPDL protocol, but
|
||||
// must be released explicitly using DeallocateSurfaceDescriptorGPUVideo
|
||||
// on the manager protocol.
|
||||
async Decode(MediaRawDataIPDL[] data) returns (DecodeResultIPDL result);
|
||||
async Decode(ArrayOfRemoteMediaRawData data) returns (DecodeResultIPDL result);
|
||||
async Flush() returns (MediaResult error);
|
||||
async Drain() returns (DecodeResultIPDL result);
|
||||
async Shutdown() returns (bool unused);
|
||||
|
|
|
@ -100,62 +100,46 @@ RefPtr<MediaDataDecoder::DecodePromise> RemoteDecoderChild::Decode(
|
|||
const nsTArray<RefPtr<MediaRawData>>& aSamples) {
|
||||
AssertOnManagerThread();
|
||||
|
||||
nsTArray<MediaRawDataIPDL> samples;
|
||||
for (auto&& sample : aSamples) {
|
||||
// TODO: It would be nice to add an allocator method to
|
||||
// MediaDataDecoder so that the demuxer could write directly
|
||||
// into shmem rather than requiring a copy here.
|
||||
ShmemBuffer buffer = AllocateBuffer(sample->Size());
|
||||
if (!buffer.Valid()) {
|
||||
return MediaDataDecoder::DecodePromise::CreateAndReject(
|
||||
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
|
||||
}
|
||||
|
||||
memcpy(buffer.Get().get<uint8_t>(), sample->Data(), sample->Size());
|
||||
MediaRawDataIPDL rawSample(
|
||||
MediaDataIPDL(sample->mOffset, sample->mTime, sample->mTimecode,
|
||||
sample->mDuration, sample->mKeyframe),
|
||||
sample->mEOS, sample->mDiscardPadding, sample->Size(),
|
||||
std::move(buffer.Get()));
|
||||
samples.AppendElement(std::move(rawSample));
|
||||
auto samples = MakeRefPtr<ArrayOfRemoteMediaRawData>();
|
||||
if (!samples->Fill(aSamples,
|
||||
[&](size_t aSize) { return AllocateBuffer(aSize); })) {
|
||||
return MediaDataDecoder::DecodePromise::CreateAndReject(
|
||||
NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
}
|
||||
SendDecode(samples)->Then(
|
||||
mThread, __func__,
|
||||
[self = RefPtr{this}, this](
|
||||
PRemoteDecoderChild::DecodePromise::ResolveOrRejectValue&& aValue) {
|
||||
// We no longer need the samples as the data has been
|
||||
// processed by the parent.
|
||||
// If the parent died, the error being fatal will cause the
|
||||
// decoder to be torn down and all shmem in the pool will be
|
||||
// deallocated.
|
||||
ReleaseAllBuffers();
|
||||
|
||||
RefPtr<RemoteDecoderChild> self = this;
|
||||
SendDecode(std::move(samples))
|
||||
->Then(mThread, __func__,
|
||||
[self,
|
||||
this](PRemoteDecoderChild::DecodePromise::ResolveOrRejectValue&&
|
||||
aValue) {
|
||||
// We no longer need the samples as the data has been
|
||||
// processed by the parent.
|
||||
// If the parent died, the error being fatal will cause the
|
||||
// decoder to be torn down and all shmem in the pool will be
|
||||
// deallocated.
|
||||
ReleaseAllBuffers();
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
HandleRejectionError(
|
||||
aValue.RejectValue(), [self](const MediaResult& aError) {
|
||||
self->mDecodePromise.RejectIfExists(aError, __func__);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (mDecodePromise.IsEmpty()) {
|
||||
// We got flushed.
|
||||
return;
|
||||
}
|
||||
auto response = std::move(aValue.ResolveValue());
|
||||
if (response.type() == DecodeResultIPDL::TMediaResult &&
|
||||
NS_FAILED(response.get_MediaResult())) {
|
||||
mDecodePromise.Reject(response.get_MediaResult(), __func__);
|
||||
return;
|
||||
}
|
||||
if (response.type() == DecodeResultIPDL::TDecodedOutputIPDL) {
|
||||
ProcessOutput(std::move(response.get_DecodedOutputIPDL()));
|
||||
}
|
||||
mDecodePromise.Resolve(std::move(mDecodedData), __func__);
|
||||
mDecodedData = MediaDataDecoder::DecodedData();
|
||||
});
|
||||
if (aValue.IsReject()) {
|
||||
HandleRejectionError(
|
||||
aValue.RejectValue(), [self](const MediaResult& aError) {
|
||||
self->mDecodePromise.RejectIfExists(aError, __func__);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (mDecodePromise.IsEmpty()) {
|
||||
// We got flushed.
|
||||
return;
|
||||
}
|
||||
auto response = std::move(aValue.ResolveValue());
|
||||
if (response.type() == DecodeResultIPDL::TMediaResult &&
|
||||
NS_FAILED(response.get_MediaResult())) {
|
||||
mDecodePromise.Reject(response.get_MediaResult(), __func__);
|
||||
return;
|
||||
}
|
||||
if (response.type() == DecodeResultIPDL::TDecodedOutputIPDL) {
|
||||
ProcessOutput(std::move(response.get_DecodedOutputIPDL()));
|
||||
}
|
||||
mDecodePromise.Resolve(std::move(mDecodedData), __func__);
|
||||
mDecodedData = MediaDataDecoder::DecodedData();
|
||||
});
|
||||
|
||||
return mDecodePromise.Ensure(__func__);
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "RemoteDecoderParent.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "RemoteDecoderManagerParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -67,41 +66,27 @@ mozilla::ipc::IPCResult RemoteDecoderParent::RecvInit(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void RemoteDecoderParent::DecodeNextSample(nsTArray<MediaRawDataIPDL>&& aData,
|
||||
DecodedOutputIPDL&& aOutput,
|
||||
DecodeResolver&& aResolver) {
|
||||
if (aData.IsEmpty()) {
|
||||
void RemoteDecoderParent::DecodeNextSample(
|
||||
const RefPtr<ArrayOfRemoteMediaRawData>& aData, size_t aIndex,
|
||||
DecodedOutputIPDL&& aOutput, DecodeResolver&& aResolver) {
|
||||
MOZ_ASSERT(OnManagerThread());
|
||||
|
||||
if (aData->Count() == aIndex) {
|
||||
aResolver(std::move(aOutput));
|
||||
return;
|
||||
}
|
||||
|
||||
const MediaRawDataIPDL& rawData = aData[0];
|
||||
RefPtr<MediaRawData> data = new MediaRawData(
|
||||
rawData.buffer().get<uint8_t>(),
|
||||
std::min((unsigned long)rawData.bufferSize(),
|
||||
(unsigned long)rawData.buffer().Size<uint8_t>()));
|
||||
// if MediaRawData's size is less than the actual buffer size recorded
|
||||
// in MediaRawDataIPDL, consider it an OOM situation.
|
||||
if ((int64_t)data->Size() < rawData.bufferSize()) {
|
||||
RefPtr<MediaRawData> rawData = aData->ElementAt(aIndex);
|
||||
if (!rawData) {
|
||||
// OOM
|
||||
ReleaseAllBuffers();
|
||||
aResolver(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
|
||||
return;
|
||||
}
|
||||
data->mOffset = rawData.base().offset();
|
||||
data->mTime = rawData.base().time();
|
||||
data->mTimecode = rawData.base().timecode();
|
||||
data->mDuration = rawData.base().duration();
|
||||
data->mKeyframe = rawData.base().keyframe();
|
||||
data->mEOS = rawData.eos();
|
||||
data->mDiscardPadding = rawData.discardPadding();
|
||||
|
||||
aData.RemoveElementAt(0);
|
||||
|
||||
RefPtr<RemoteDecoderParent> self = this;
|
||||
mDecoder->Decode(data)->Then(
|
||||
mDecoder->Decode(rawData)->Then(
|
||||
mManagerThread, __func__,
|
||||
[self, this, aData = std::move(aData), output = std::move(aOutput),
|
||||
[self = RefPtr{this}, this, aData, aIndex, output = std::move(aOutput),
|
||||
resolver = std::move(aResolver)](
|
||||
MediaDataDecoder::DecodePromise::ResolveOrRejectValue&&
|
||||
aValue) mutable {
|
||||
|
@ -121,14 +106,14 @@ void RemoteDecoderParent::DecodeNextSample(nsTArray<MediaRawDataIPDL>&& aData,
|
|||
resolver(rv);
|
||||
} else {
|
||||
// Call again in case we have more data to decode.
|
||||
DecodeNextSample(std::move(aData), std::move(output),
|
||||
DecodeNextSample(aData, aIndex + 1, std::move(output),
|
||||
std::move(resolver));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RemoteDecoderParent::RecvDecode(
|
||||
nsTArray<MediaRawDataIPDL>&& aData, DecodeResolver&& aResolver) {
|
||||
ArrayOfRemoteMediaRawData* aData, DecodeResolver&& aResolver) {
|
||||
MOZ_ASSERT(OnManagerThread());
|
||||
// XXX: This copies the data into a buffer owned by the MediaRawData. Ideally
|
||||
// we'd just take ownership of the shmem.
|
||||
|
@ -140,7 +125,7 @@ mozilla::ipc::IPCResult RemoteDecoderParent::RecvDecode(
|
|||
// available again.
|
||||
ReleaseAllBuffers();
|
||||
DecodedOutputIPDL output;
|
||||
DecodeNextSample(std::move(aData), std::move(output), std::move(aResolver));
|
||||
DecodeNextSample(aData, 0, std::move(output), std::move(aResolver));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class RemoteDecoderParent : public ShmemRecycleAllocator<RemoteDecoderParent>,
|
|||
|
||||
// PRemoteDecoderParent
|
||||
IPCResult RecvInit(InitResolver&& aResolver);
|
||||
IPCResult RecvDecode(nsTArray<MediaRawDataIPDL>&& aData,
|
||||
IPCResult RecvDecode(ArrayOfRemoteMediaRawData* aData,
|
||||
DecodeResolver&& aResolver);
|
||||
IPCResult RecvFlush(FlushResolver&& aResolver);
|
||||
IPCResult RecvDrain(DrainResolver&& aResolver);
|
||||
|
@ -54,8 +54,8 @@ class RemoteDecoderParent : public ShmemRecycleAllocator<RemoteDecoderParent>,
|
|||
RefPtr<MediaDataDecoder> mDecoder;
|
||||
|
||||
private:
|
||||
void DecodeNextSample(nsTArray<MediaRawDataIPDL>&& aData,
|
||||
DecodedOutputIPDL&& aOutput,
|
||||
void DecodeNextSample(const RefPtr<ArrayOfRemoteMediaRawData>& aData,
|
||||
size_t aIndex, DecodedOutputIPDL&& aOutput,
|
||||
DecodeResolver&& aResolver);
|
||||
RefPtr<RemoteDecoderParent> mIPDLSelfRef;
|
||||
const RefPtr<nsISerialEventTarget> mManagerThread;
|
||||
|
|
Загрузка…
Ссылка в новой задаче