Bug 1672072 - P7. Remove the guarantee that the TrackInfo reference will always be valid. r=mattwoodrow,bryce,padenot

Until now, it was up to the caller to ensure that the VideoInfo or AudioInfo passed to the PlatformDecoderModule would remain alive until the created decoder was shut down.
This was achieved by the MediaFormatReader through great care and complexity and ensuring that the MediaFormatReader would never complete its own shutdown unless the  decoder did the same.

Asynchronously creating the decoder add an even greater of complexity. We have to ensure that should the caller shut down while the decoder creation promise hasn't been resolved ; that it stays alive the entire time.

It could be achieved by making the TrackInfo object refcounted, or creating a cycle between the caller and the PDM/decoder.

Each of those options have their own downsides.

Either of those options add an unwarranted level of complexity, when we can just have each decoder copy the arguments it receives. This is simpler and more straightforward and the required copy isn't expensive.

Differential Revision: https://phabricator.services.mozilla.com/D96363
This commit is contained in:
Jean-Yves Avenard 2020-11-13 04:21:15 +00:00
Родитель d05265e239
Коммит 2dfb45a566
11 изменённых файлов: 16 добавлений и 27 удалений

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

@ -352,14 +352,11 @@ class PlatformDecoderModule {
// Creates a Video decoder. The layers backend is passed in so that
// decoders can determine whether hardware accelerated decoding can be used.
// Asynchronous decoding of video should be done in runnables dispatched
// to aVideoTaskQueue. If the task queue isn't needed, the decoder should
// not hold a reference to it.
// On Windows the task queue's threads in have MSCOM initialized with
// COINIT_MULTITHREADED.
// Returns nullptr if the decoder can't be created.
// It is safe to store a reference to aConfig.
// This is called on the decode task queue.
// It is not safe to store a reference to aParams or aParams.mConfig as the
// object isn't guaranteed to live after the call.
// CreateVideoDecoder may need to make additional checks if the
// CreateDecoderParams argument is actually supported and return nullptr if
// not to allow for fallback PDMs to be tried.
@ -367,14 +364,11 @@ class PlatformDecoderModule {
const CreateDecoderParams& aParams) = 0;
// Creates an Audio decoder with the specified properties.
// Asynchronous decoding of audio should be done in runnables dispatched to
// aAudioTaskQueue. If the task queue isn't needed, the decoder should
// not hold a reference to it.
// Returns nullptr if the decoder can't be created.
// On Windows the task queue's threads in have MSCOM initialized with
// COINIT_MULTITHREADED.
// It is safe to store a reference to aConfig.
// This is called on the decode task queue.
// It is not safe to store a reference to aParams or aParams.mConfig as the
// object isn't guaranteed to live after the call.
// CreateAudioDecoder may need to make additional checks if the
// CreateDecoderParams argument is actually supported and return nullptr if
// not to allow for fallback PDMs to be tried.
@ -401,10 +395,7 @@ DDLoggedTypeDeclName(MediaDataDecoder);
// Don't block inside these functions, unless it's explicitly noted that you
// should (like in Flush()).
//
// Decoding is done asynchronously. Any async work can be done on the
// TaskQueue passed into the PlatformDecoderModules's Create*Decoder()
// function. This may not be necessary for platforms with async APIs
// for decoding.
// Decoding is done asynchronously.
class MediaDataDecoder : public DecoderDoctorLifeLogger<MediaDataDecoder> {
protected:
virtual ~MediaDataDecoder() = default;
@ -421,7 +412,7 @@ class MediaDataDecoder : public DecoderDoctorLifeLogger<MediaDataDecoder> {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder)
// Initialize the decoder. The decoder should be ready to decode once
// promise resolves. The decoder should do any initialization here, rather
// the promise resolves. The decoder should do any initialization here, rather
// than in its constructor or PlatformDecoderModule::Create*Decoder(),
// so that if the MediaFormatReader needs to shutdown during initialization,
// it can call Shutdown() to cancel this operation. Any initialization

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

@ -50,7 +50,7 @@ class AOMDecoder : public MediaDataDecoder,
// AOM decoder state
aom_codec_ctx_t mCodec;
const VideoInfo& mInfo;
const VideoInfo mInfo;
};
} // namespace mozilla

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

@ -40,7 +40,7 @@ class DAV1DDecoder : public MediaDataDecoder,
Dav1dContext* mContext = nullptr;
const VideoInfo& mInfo;
const VideoInfo mInfo;
const RefPtr<TaskQueue> mTaskQueue;
const RefPtr<layers::ImageContainer> mImageContainer;
const RefPtr<layers::KnowsCompositor> mImageAllocator;

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

@ -47,7 +47,7 @@ class OpusDataDecoder : public MediaDataDecoder,
private:
nsresult DecodeHeader(const unsigned char* aData, size_t aLength);
const AudioInfo& mInfo;
const AudioInfo mInfo;
nsCOMPtr<nsISerialEventTarget> mThread;
// Opus decoder state

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

@ -51,7 +51,7 @@ class TheoraDecoder : public MediaDataDecoder,
th_dec_ctx* mTheoraDecoderContext;
int mPacketCount;
const VideoInfo& mInfo;
const VideoInfo mInfo;
};
} // namespace mozilla

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

@ -209,7 +209,7 @@ class VPXDecoder : public MediaDataDecoder,
// VPx alpha decoder state
vpx_codec_ctx_t mVPXAlpha;
const VideoInfo& mInfo;
const VideoInfo mInfo;
const Codec mCodec;
const bool mLowLatency;

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

@ -42,7 +42,7 @@ class VorbisDataDecoder : public MediaDataDecoder,
private:
nsresult DecodeHeader(const unsigned char* aData, size_t aLength);
const AudioInfo& mInfo;
const AudioInfo mInfo;
nsCOMPtr<nsISerialEventTarget> mThread;
// Vorbis decoder state

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

@ -31,7 +31,7 @@ class WaveDataDecoder : public MediaDataDecoder,
}
private:
const AudioInfo& mInfo;
const AudioInfo mInfo;
nsCOMPtr<nsISerialEventTarget> mThread;
};

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

@ -33,7 +33,6 @@ static bool IsOnGMPThread() {
GMPVideoDecoderParams::GMPVideoDecoderParams(const CreateDecoderParams& aParams)
: mConfig(aParams.VideoConfig()),
mImageContainer(aParams.mImageContainer),
mLayersBackend(aParams.GetLayersBackend()),
mCrashHelper(aParams.mCrashHelper) {}
void GMPVideoDecoder::Decoded(GMPVideoi420Frame* aDecodedFrame) {

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

@ -16,13 +16,12 @@
namespace mozilla {
struct GMPVideoDecoderParams {
struct MOZ_STACK_CLASS GMPVideoDecoderParams {
explicit GMPVideoDecoderParams(const CreateDecoderParams& aParams);
const VideoInfo& mConfig;
layers::ImageContainer* mImageContainer;
layers::LayersBackend mLayersBackend;
RefPtr<GMPCrashHelper> mCrashHelper;
GMPCrashHelper* mCrashHelper;
};
DDLoggedTypeDeclNameAndBase(GMPVideoDecoder, MediaDataDecoder);

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

@ -35,7 +35,7 @@ class AppleATDecoder : public MediaDataDecoder,
}
// Callbacks also need access to the config.
const AudioInfo& mConfig;
const AudioInfo mConfig;
// Use to extract magic cookie for HE-AAC detection.
nsTArray<uint8_t> mMagicCookie;