MediaFormatReader.h (34103B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #if !defined(MediaFormatReader_h_) 8 # define MediaFormatReader_h_ 9 10 # include "FrameStatistics.h" 11 # include "MediaDataDemuxer.h" 12 # include "MediaEventSource.h" 13 # include "MediaMetadataManager.h" 14 # include "MediaPromiseDefs.h" 15 # include "PlatformDecoderModule.h" 16 # include "SeekTarget.h" 17 # include "mozilla/Atomics.h" 18 # include "mozilla/Maybe.h" 19 # include "mozilla/MozPromise.h" 20 # include "mozilla/Mutex.h" 21 # include "mozilla/StateMirroring.h" 22 # include "mozilla/StaticPrefs_media.h" 23 # include "mozilla/TaskQueue.h" 24 # include "mozilla/ThreadSafeWeakPtr.h" 25 # include "mozilla/TimeStamp.h" 26 # include "mozilla/dom/MediaDebugInfoBinding.h" 27 28 namespace mozilla { 29 30 class CDMProxy; 31 class GMPCrashHelper; 32 class MediaResource; 33 class VideoFrameContainer; 34 35 struct WaitForDataRejectValue { 36 enum Reason { SHUTDOWN, CANCELED }; 37 38 WaitForDataRejectValue(MediaData::Type aType, Reason aReason) 39 : mType(aType), mReason(aReason) {} 40 MediaData::Type mType; 41 Reason mReason; 42 }; 43 44 struct SeekRejectValue { 45 MOZ_IMPLICIT SeekRejectValue(const MediaResult& aError) 46 : mType(MediaData::Type::NULL_DATA), mError(aError) {} 47 MOZ_IMPLICIT SeekRejectValue(nsresult aResult) 48 : mType(MediaData::Type::NULL_DATA), mError(aResult) {} 49 SeekRejectValue(MediaData::Type aType, const MediaResult& aError) 50 : mType(aType), mError(aError) {} 51 MediaData::Type mType; 52 MediaResult mError; 53 }; 54 55 struct MetadataHolder { 56 UniquePtr<MediaInfo> mInfo; 57 UniquePtr<MetadataTags> mTags; 58 }; 59 60 using MediaDecoderOwnerID = void*; 61 62 struct MOZ_STACK_CLASS MediaFormatReaderInit { 63 MediaResource* mResource = nullptr; 64 VideoFrameContainer* mVideoFrameContainer = nullptr; 65 FrameStatistics* mFrameStats = nullptr; 66 already_AddRefed<layers::KnowsCompositor> mKnowsCompositor; 67 already_AddRefed<GMPCrashHelper> mCrashHelper; 68 // Used in bug 1393399 for temporary telemetry. 69 MediaDecoderOwnerID mMediaDecoderOwnerID = nullptr; 70 Maybe<TrackingId> mTrackingId; 71 }; 72 73 DDLoggedTypeDeclName(MediaFormatReader); 74 75 class MediaFormatReader final 76 : public SupportsThreadSafeWeakPtr<MediaFormatReader>, 77 public DecoderDoctorLifeLogger<MediaFormatReader> { 78 static const bool IsExclusive = true; 79 using TrackType = TrackInfo::TrackType; 80 using NotifyDataArrivedPromise = MozPromise<bool, MediaResult, IsExclusive>; 81 82 public: 83 MOZ_DECLARE_REFCOUNTED_TYPENAME(MediaFormatReader) 84 85 using TrackSet = EnumSet<TrackInfo::TrackType>; 86 using MetadataPromise = MozPromise<MetadataHolder, MediaResult, IsExclusive>; 87 88 template <typename Type> 89 using DataPromise = MozPromise<RefPtr<Type>, MediaResult, IsExclusive>; 90 using AudioDataPromise = DataPromise<AudioData>; 91 using VideoDataPromise = DataPromise<VideoData>; 92 93 using SeekPromise = MozPromise<media::TimeUnit, SeekRejectValue, IsExclusive>; 94 95 // Note that, conceptually, WaitForData makes sense in a non-exclusive sense. 96 // But in the current architecture it's only ever used exclusively (by MDSM), 97 // so we mark it that way to verify our assumptions. If you have a use-case 98 // for multiple WaitForData consumers, feel free to flip the exclusivity here. 99 using WaitForDataPromise = 100 MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>; 101 102 MediaFormatReader(MediaFormatReaderInit& aInit, MediaDataDemuxer* aDemuxer); 103 virtual ~MediaFormatReader(); 104 105 // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE 106 // on failure. 107 nsresult Init(); 108 109 size_t SizeOfVideoQueueInFrames(); 110 size_t SizeOfAudioQueueInFrames(); 111 112 // Requests one video sample from the reader. 113 RefPtr<VideoDataPromise> RequestVideoData( 114 const media::TimeUnit& aTimeThreshold, 115 bool aRequestNextVideoKeyFrame = false); 116 117 // Requests one audio sample from the reader. 118 // 119 // The decode should be performed asynchronously, and the promise should 120 // be resolved when it is complete. 121 RefPtr<AudioDataPromise> RequestAudioData(); 122 123 // The default implementation of AsyncReadMetadata is implemented in terms of 124 // synchronous ReadMetadata() calls. Implementations may also 125 // override AsyncReadMetadata to create a more proper async implementation. 126 RefPtr<MetadataPromise> AsyncReadMetadata(); 127 128 // Fills aInfo with the latest cached data required to present the media, 129 // ReadUpdatedMetadata will always be called once ReadMetadata has succeeded. 130 void ReadUpdatedMetadata(MediaInfo* aInfo); 131 132 RefPtr<SeekPromise> Seek(const SeekTarget& aTarget); 133 134 // Called once new data has been cached by the MediaResource. 135 // mBuffered should be recalculated and updated accordingly. 136 void NotifyDataArrived(); 137 138 // Update ID for the external playback engine. Currently it's only used on 139 // Windows when the media engine playback is enabled. 140 void UpdateMediaEngineId(uint64_t aMediaEngineId); 141 142 // This function will be called if the media key is set before playback 143 // starts, indicating the playback should be encrypted. 144 void SetEncryptedCustomIdent(); 145 146 bool IsEncryptedCustomIdent() const { return mEncryptedCustomIdent; } 147 148 protected: 149 // Recomputes mBuffered. 150 void UpdateBuffered(); 151 152 public: 153 // Called by MDSM in dormant state to release resources allocated by this 154 // reader. The reader can resume decoding by calling Seek() to a specific 155 // position. 156 void ReleaseResources(); 157 158 bool OnTaskQueue() const { return OwnerThread()->IsCurrentThreadIn(); } 159 160 // Resets all state related to decoding, emptying all buffers etc. 161 // Cancels all pending Request*Data() request callbacks, rejects any 162 // outstanding seek promises, and flushes the decode pipeline. The 163 // decoder must not call any of the callbacks for outstanding 164 // Request*Data() calls after this is called. Calls to Request*Data() 165 // made after this should be processed as usual. 166 // 167 // Normally this call preceedes a Seek() call, or shutdown. 168 // 169 // aParam is a set of TrackInfo::TrackType enums specifying which 170 // queues need to be reset, defaulting to both audio and video tracks. 171 nsresult ResetDecode(const TrackSet& aTracks); 172 173 // Destroys the decoding state. The reader cannot be made usable again. 174 // This is different from ReleaseMediaResources() as it is irreversable, 175 // whereas ReleaseMediaResources() is. Must be called on the decode 176 // thread. 177 RefPtr<ShutdownPromise> Shutdown(); 178 179 // Returns true if this decoder reader uses hardware accelerated video 180 // decoding. 181 bool VideoIsHardwareAccelerated() const; 182 183 // By default, the state machine polls the reader once per second when it's 184 // in buffering mode. Some readers support a promise-based mechanism by which 185 // they notify the state machine when the data arrives. 186 bool IsWaitForDataSupported() const { return true; } 187 188 RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType); 189 190 // The MediaDecoderStateMachine uses various heuristics that assume that 191 // raw media data is arriving sequentially from a network channel. This 192 // makes sense in the <video src="foo"> case, but not for more advanced use 193 // cases like MSE. 194 bool UseBufferingHeuristics() const { return mTrackDemuxersMayBlock; } 195 196 RefPtr<SetCDMPromise> SetCDMProxy(CDMProxy* aProxy); 197 198 // Requests that the MediaFormatReader populates aInfo with debug information. 199 // This may be done asynchronously, and aInfo should *not* be accessed by the 200 // caller until the returned promise is resolved or rejected. 201 RefPtr<GenericPromise> RequestDebugInfo( 202 dom::MediaFormatReaderDebugInfo& aInfo); 203 204 // Switch the video decoder to NullDecoderModule. It might takes effective 205 // since a few samples later depends on how much demuxed samples are already 206 // queued in the original video decoder. 207 void SetVideoNullDecode(bool aIsNullDecode); 208 209 void UpdateCompositor(already_AddRefed<layers::KnowsCompositor>); 210 211 void UpdateDuration(const media::TimeUnit& aDuration) { 212 MOZ_ASSERT(OnTaskQueue()); 213 UpdateBuffered(); 214 } 215 216 AbstractCanonical<media::TimeIntervals>* CanonicalBuffered() { 217 return &mBuffered; 218 } 219 220 TaskQueue* OwnerThread() const { return mTaskQueue; } 221 222 TimedMetadataEventSource& TimedMetadataEvent() { return mTimedMetadataEvent; } 223 224 // Notified by the OggDemuxer during playback when chained ogg is detected. 225 MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; } 226 227 TimedMetadataEventProducer& TimedMetadataProducer() { 228 return mTimedMetadataEvent; 229 } 230 231 MediaEventProducer<void>& MediaNotSeekableProducer() { 232 return mOnMediaNotSeekable; 233 } 234 235 // Notified if the reader can't decode a sample due to a missing decryption 236 // key. 237 MediaEventSource<TrackInfo::TrackType>& OnTrackWaitingForKey() { 238 return mOnTrackWaitingForKey; 239 } 240 241 MediaEventProducer<TrackInfo::TrackType>& OnTrackWaitingForKeyProducer() { 242 return mOnTrackWaitingForKey; 243 } 244 245 MediaEventSource<nsTArray<uint8_t>, nsString>& OnEncrypted() { 246 return mOnEncrypted; 247 } 248 249 MediaEventSource<void>& OnWaitingForKey() { return mOnWaitingForKey; } 250 251 MediaEventSource<MediaResult>& OnDecodeWarning() { return mOnDecodeWarning; } 252 253 MediaEventProducer<VideoInfo, AudioInfo>& OnTrackInfoUpdatedEvent() { 254 return mTrackInfoUpdatedEvent; 255 } 256 257 template <typename T> 258 friend struct DDLoggedTypeTraits; // For DecoderData 259 260 class VideoDecodeProperties final { 261 public: 262 void Load(RefPtr<MediaDataDecoder>& aDecoder); 263 void Clear() { 264 mMaxQueueSize.reset(); 265 mMinQueueSize.reset(); 266 mSendToCompositorSize.reset(); 267 } 268 269 Maybe<uint32_t> MaxQueueSize() { return mMaxQueueSize; } 270 Maybe<uint32_t> MinQueueSize() { return mMinQueueSize; } 271 Maybe<uint32_t> SendToCompositorSize() { return mSendToCompositorSize; } 272 273 private: 274 Maybe<uint32_t> mMaxQueueSize; 275 Maybe<uint32_t> mMinQueueSize; 276 Maybe<uint32_t> mSendToCompositorSize; 277 }; 278 279 VideoDecodeProperties& GetVideoDecodeProperties() { 280 MutexAutoLock lock(mVideo.mMutex); 281 return mVideo.mVideoDecodeProperties; 282 } 283 284 private: 285 bool HasVideo() const { return mVideo.mTrackDemuxer; } 286 bool HasAudio() const { return mAudio.mTrackDemuxer; } 287 288 bool IsWaitingOnCDMResource(); 289 290 bool InitDemuxer(); 291 // Notify the track demuxers that new data has been received. 292 void NotifyTrackDemuxers(); 293 void ReturnOutput(MediaData* aData, TrackType aTrack); 294 295 // Enqueues a task to call Update(aTrack) on the decoder task queue. 296 // Lock for corresponding track must be held. 297 void ScheduleUpdate(TrackType aTrack); 298 void Update(TrackType aTrack); 299 // Handle actions should more data be received. 300 // Returns true if no more action is required. 301 bool UpdateReceivedNewData(TrackType aTrack); 302 // Called when new samples need to be demuxed. 303 void RequestDemuxSamples(TrackType aTrack); 304 // Handle demuxed samples by the input behavior. 305 void HandleDemuxedSamples(TrackType aTrack, 306 FrameStatistics::AutoNotifyDecoded& aA); 307 // Decode any pending already demuxed samples. 308 void DecodeDemuxedSamples(TrackType aTrack, MediaRawData* aSample); 309 310 struct InternalSeekTarget { 311 InternalSeekTarget(const media::TimeInterval& aTime, bool aDropTarget) 312 : mTime(aTime), 313 mDropTarget(aDropTarget), 314 mWaiting(false), 315 mHasSeeked(false) {} 316 317 media::TimeUnit Time() const { return mTime.mStart; } 318 media::TimeUnit EndTime() const { return mTime.mEnd; } 319 bool Contains(const media::TimeUnit& aTime) const { 320 return mTime.Contains(aTime); 321 } 322 323 media::TimeInterval mTime; 324 bool mDropTarget; 325 // Whether known waiting for more raw packets, either for the random 326 // access point or dependent frames. 327 bool mWaiting; 328 // Whether `MediaTrackDemuxer::Seek()` has found the preceding random 329 // access point. 330 bool mHasSeeked; 331 }; 332 333 // Perform an internal seek to aTime. If aDropTarget is true then 334 // the first sample past the target will be dropped. 335 void InternalSeek(TrackType aTrack, const InternalSeekTarget& aTarget); 336 // Return the end time of the internal seek target if it exists. Otherwise, 337 // return infinity. 338 media::TimeUnit GetInternalSeekTargetEndTime() const; 339 340 // Drain the current decoder. 341 void DrainDecoder(TrackType aTrack); 342 void NotifyNewOutput(TrackType aTrack, 343 MediaDataDecoder::DecodedData&& aResults); 344 void NotifyError(TrackType aTrack, const MediaResult& aError); 345 void NotifyWaitingForData(TrackType aTrack); 346 void NotifyWaitingForKey(TrackType aTrack); 347 void NotifyEndOfStream(TrackType aTrack); 348 349 void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData); 350 351 // Initializes mLayersBackendType if possible. 352 void InitLayersBackendType(); 353 354 void Reset(TrackType aTrack); 355 void DropDecodedSamples(TrackType aTrack); 356 357 // Return a target timeunit which the reader should skip to, this would be 358 // either the timethreshold we pass, or the time of the next keyframe. Return 359 // nothing if we don't need to skip. 360 // @param aTimeThreshold 361 // The time that we expect the time of next video frame should be or go beyond 362 // @param aRequestNextVideoKeyFrame 363 // If true and the next keyframe's time is larger than aTimeThreshold, skip to 364 // the next keyframe time instead of aTimeThreshold. 365 Maybe<media::TimeUnit> ShouldSkip(media::TimeUnit aTimeThreshold, 366 bool aRequestNextVideoKeyFrame); 367 368 void SetVideoDecodeThreshold(); 369 370 size_t SizeOfQueue(TrackType aTrack); 371 372 void NotifyTrackInfoUpdated(); 373 374 enum class DrainState { 375 None, 376 DrainRequested, 377 Draining, 378 PartialDrainPending, 379 DrainCompleted, 380 DrainAborted, 381 }; 382 383 class SharedShutdownPromiseHolder : public MozPromiseHolder<ShutdownPromise> { 384 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedShutdownPromiseHolder) 385 private: 386 ~SharedShutdownPromiseHolder() = default; 387 }; 388 389 struct DecoderData { 390 DecoderData(MediaFormatReader* aOwner, MediaData::Type aType, 391 uint32_t aNumOfMaxError) 392 : mOwner(aOwner), 393 mType(aType), 394 mMutex("DecoderData"), 395 mDescription("uninitialized"), 396 mProcessName(""), 397 mCodecName(""), 398 mUpdateScheduled(false), 399 mDemuxEOS(false), 400 mWaitingForDataStartTime(Nothing()), 401 mWaitingForKey(false), 402 mReceivedNewData(false), 403 mFlushing(false), 404 mFlushed(true), 405 mDrainState(DrainState::None), 406 mNumOfConsecutiveDecodingError(0), 407 mMaxConsecutiveDecodingError(aNumOfMaxError), 408 mNumOfConsecutiveRDDOrGPUCrashes(0), 409 mMaxConsecutiveRDDOrGPUCrashes( 410 StaticPrefs::media_rdd_process_max_crashes()), 411 mNumOfConsecutiveUtilityCrashes(0), 412 mMaxConsecutiveUtilityCrashes( 413 StaticPrefs::media_utility_process_max_crashes()), 414 mFirstFrameTime(Some(media::TimeUnit::Zero())), 415 mNumSamplesInput(0), 416 mNumSamplesOutput(0), 417 mNumSamplesOutputTotal(0), 418 mNumSamplesSkippedTotal(0), 419 mSizeOfQueue(0), 420 mIsHardwareAccelerated(false), 421 mLastStreamSourceID(UINT32_MAX), 422 mIsNullDecode(false), 423 mHardwareDecodingDisabled(false) { 424 DecoderDoctorLogger::LogConstruction("MediaFormatReader::DecoderData", 425 this); 426 } 427 428 ~DecoderData() { 429 DecoderDoctorLogger::LogDestruction("MediaFormatReader::DecoderData", 430 this); 431 } 432 433 MediaFormatReader* mOwner; 434 // Disambiguate Audio vs Video. 435 MediaData::Type mType; 436 RefPtr<MediaTrackDemuxer> mTrackDemuxer; 437 // TaskQueue on which decoder can choose to decode. 438 // Only non-null up until the decoder is created. 439 RefPtr<TaskQueue> mTaskQueue; 440 441 // Mutex protecting mDescription, mDecoder, mTrackDemuxer, mWorkingInfo, 442 // mProcessName, mCodecName and mDecodeProperties as those can be read 443 // outside the TaskQueue. They are only written on the TaskQueue however, as 444 // such mMutex doesn't need to be held when those members are read on the 445 // TaskQueue. 446 Mutex mMutex MOZ_UNANNOTATED; 447 // The platform decoder. 448 RefPtr<MediaDataDecoder> mDecoder; 449 nsCString mDescription; 450 nsCString mProcessName; 451 nsCString mCodecName; 452 VideoDecodeProperties mVideoDecodeProperties; 453 454 void LoadDecodeProperties() { 455 MOZ_ASSERT(mOwner->OnTaskQueue()); 456 if (mType == MediaData::Type::VIDEO_DATA) { 457 mVideoDecodeProperties.Load(mDecoder); 458 } 459 } 460 461 void ShutdownDecoder(); 462 463 // Only accessed from reader's task queue. 464 bool mUpdateScheduled; 465 bool mDemuxEOS; 466 Maybe<TimeStamp> mWaitingForDataStartTime; 467 bool mWaitingForKey; 468 bool mReceivedNewData; 469 UniquePtr<PerformanceRecorderMulti<PlaybackStage>> mDecodePerfRecorder; 470 471 // Pending seek. 472 MozPromiseRequestHolder<MediaTrackDemuxer::SeekPromise> mSeekRequest; 473 474 // Queued demuxed samples waiting to be decoded. 475 nsTArray<RefPtr<MediaRawData>> mQueuedSamples; 476 MozPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest; 477 // A WaitingPromise is pending if the demuxer is waiting for data or 478 // if the decoder is waiting for a key. 479 MozPromiseHolder<WaitForDataPromise> mWaitingPromise; 480 bool HasWaitingPromise() const { 481 MOZ_ASSERT(mOwner->OnTaskQueue()); 482 return !mWaitingPromise.IsEmpty(); 483 } 484 485 bool IsWaitingForData() const { 486 MOZ_ASSERT(mOwner->OnTaskQueue()); 487 return !!mWaitingForDataStartTime; 488 } 489 490 bool IsWaitingForKey() const { 491 MOZ_ASSERT(mOwner->OnTaskQueue()); 492 return mWaitingForKey && mDecodeRequest.Exists(); 493 } 494 495 // MediaDataDecoder handler's variables. 496 MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDecodeRequest; 497 bool mFlushing; // True if flush is in action. 498 // Set to true if the last operation run on the decoder was a flush. 499 bool mFlushed; 500 RefPtr<SharedShutdownPromiseHolder> mShutdownPromise; 501 502 MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDrainRequest; 503 DrainState mDrainState; 504 bool HasPendingDrain() const { return mDrainState != DrainState::None; } 505 bool HasCompletedDrain() const { 506 return mDrainState == DrainState::DrainCompleted || 507 mDrainState == DrainState::DrainAborted; 508 } 509 void RequestDrain(); 510 511 void StartRecordDecodingPerf(const TrackType aTrack, 512 const MediaRawData* aSample); 513 514 // Track decoding error and fail when we hit the limit. 515 uint32_t mNumOfConsecutiveDecodingError; 516 uint32_t mMaxConsecutiveDecodingError; 517 518 // Track RDD or GPU process crashes and fail when we hit the limit. 519 uint32_t mNumOfConsecutiveRDDOrGPUCrashes; 520 uint32_t mMaxConsecutiveRDDOrGPUCrashes; 521 522 // Track Utility process crashes and fail when we hit the limit. 523 uint32_t mNumOfConsecutiveUtilityCrashes; 524 uint32_t mMaxConsecutiveUtilityCrashes; 525 526 // Set when we haven't yet decoded the first frame. 527 // Cleared once the first frame has been decoded. 528 // This is used to determine, upon error, if we should try again to decode 529 // the frame, or skip to the next keyframe. 530 Maybe<media::TimeUnit> mFirstFrameTime; 531 532 Maybe<MediaResult> mError; 533 bool HasFatalError() const { 534 if (!mError.isSome()) { 535 return false; 536 } 537 if (mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR) { 538 // Allow decode errors to be non-fatal, but give up 539 // if we have too many, or if warnings should be treated as errors. 540 return mNumOfConsecutiveDecodingError > mMaxConsecutiveDecodingError || 541 StaticPrefs::media_playback_warnings_as_errors(); 542 } 543 if (mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER) { 544 // If the caller asked for a new decoder we shouldn't treat 545 // it as fatal. 546 return false; 547 } 548 if (mError.ref() == NS_ERROR_DOM_MEDIA_REMOTE_CRASHED_RDD_OR_GPU_ERR) { 549 // Allow RDD crashes to be non-fatal, but give up 550 // if we have too many, or if warnings should be treated as errors. 551 return mNumOfConsecutiveRDDOrGPUCrashes > 552 mMaxConsecutiveRDDOrGPUCrashes || 553 StaticPrefs::media_playback_warnings_as_errors(); 554 } 555 if (mError.ref() == NS_ERROR_DOM_MEDIA_REMOTE_CRASHED_UTILITY_ERR) { 556 bool tooManyConsecutiveCrashes = 557 mNumOfConsecutiveUtilityCrashes > mMaxConsecutiveUtilityCrashes; 558 // TODO: Telemetry? 559 return tooManyConsecutiveCrashes || 560 StaticPrefs::media_playback_warnings_as_errors(); 561 } 562 if (mError.ref() == NS_ERROR_DOM_MEDIA_REMOTE_CRASHED_MF_CDM_ERR) { 563 return false; 564 } 565 // All other error types are fatal 566 return true; 567 } 568 569 // If set, all decoded samples prior mTimeThreshold will be dropped. 570 // Used for internal seeking when a change of stream is detected or when 571 // encountering data discontinuity. 572 Maybe<InternalSeekTarget> mTimeThreshold; 573 // Time of last decoded sample returned. 574 Maybe<media::TimeInterval> mLastDecodedSampleTime; 575 576 // Decoded samples returned my mDecoder awaiting being returned to 577 // state machine upon request. 578 nsTArray<RefPtr<MediaData>> mOutput; 579 uint64_t mNumSamplesInput; 580 uint64_t mNumSamplesOutput; 581 uint64_t mNumSamplesOutputTotal; 582 uint64_t mNumSamplesSkippedTotal; 583 584 // These get overridden in the templated concrete class. 585 // Indicate if we have a pending promise for decoded frame. 586 // Rejecting the promise will stop the reader from decoding ahead. 587 virtual bool HasPromise() const = 0; 588 virtual void RejectPromise(const MediaResult& aError, 589 StaticString aMethodName) = 0; 590 591 // Clear track demuxer related data. 592 void ResetDemuxer() { 593 mDemuxRequest.DisconnectIfExists(); 594 mSeekRequest.DisconnectIfExists(); 595 mTrackDemuxer->Reset(); 596 mQueuedSamples.Clear(); 597 } 598 599 // Flush the decoder if present and reset decoding related data. 600 // Following a flush, the decoder is ready to accept any new data. 601 void Flush(); 602 603 bool CancelWaitingForKey() { 604 if (!mWaitingForKey) { 605 return false; 606 } 607 mWaitingForKey = false; 608 if (IsWaitingForData() || !HasWaitingPromise()) { 609 return false; 610 } 611 mWaitingPromise.Resolve(mType, __func__); 612 return true; 613 } 614 615 // Reset the state of the DecoderData, clearing all queued frames 616 // (pending demuxed and decoded). 617 // The track demuxer is *not* reset. 618 void ResetState() { 619 MOZ_ASSERT(mOwner->OnTaskQueue()); 620 mDemuxEOS = false; 621 mWaitingForDataStartTime.reset(); 622 mQueuedSamples.Clear(); 623 mDecodeRequest.DisconnectIfExists(); 624 mDrainRequest.DisconnectIfExists(); 625 mDrainState = DrainState::None; 626 CancelWaitingForKey(); 627 mTimeThreshold.reset(); 628 mLastDecodedSampleTime.reset(); 629 mOutput.Clear(); 630 mNumSamplesInput = 0; 631 mNumSamplesOutput = 0; 632 mSizeOfQueue = 0; 633 mNextStreamSourceID.reset(); 634 if (!HasFatalError()) { 635 mError.reset(); 636 } 637 if (mType == MediaData::Type::VIDEO_DATA) { 638 mVideoDecodeProperties.Clear(); 639 } 640 } 641 642 // Return whether an InternalSeek() has been requested but has not yet 643 // seeked to the random access point preceding that target. 644 bool HasInternalSeekPending() const { 645 return mTimeThreshold && !mTimeThreshold.ref().mHasSeeked; 646 } 647 648 // Return the current TrackInfo in the stream. If the stream content never 649 // changed since AsyncReadMetadata was called then the TrackInfo used is 650 // mOriginalInfo, other it will be mInfo. The later case is only ever true 651 // with MSE or the WebMDemuxer. 652 const TrackInfo* GetCurrentInfo() const { 653 if (mInfo) { 654 return *mInfo; 655 } 656 return mOriginalInfo.get(); 657 } 658 // Return the current TrackInfo updated as per the decoder output. 659 // Typically for audio, the number of channels and/or sampling rate can vary 660 // between what was found in the metadata and what the decoder returned. 661 const TrackInfo* GetWorkingInfo() const { return mWorkingInfo.get(); } 662 bool IsEncrypted() const { return GetCurrentInfo()->mCrypto.IsEncrypted(); } 663 664 // Used by the MDSM for logging purposes. 665 Atomic<size_t> mSizeOfQueue; 666 // Used by the MDSM to determine if video decoding is hardware accelerated. 667 // This value is updated after a frame is successfully decoded. 668 Atomic<bool> mIsHardwareAccelerated; 669 // Sample format monitoring. 670 uint32_t mLastStreamSourceID; 671 Maybe<uint32_t> mNextStreamSourceID; 672 media::TimeIntervals mTimeRanges; 673 Maybe<media::TimeUnit> mLastTimeRangesEnd; 674 // TrackInfo as first discovered during ReadMetadata. 675 UniquePtr<TrackInfo> mOriginalInfo; 676 // Written exclusively on the TaskQueue, can be read on MDSM's TaskQueue. 677 // Must be read with parent's mutex held. 678 UniquePtr<TrackInfo> mWorkingInfo; 679 RefPtr<TrackInfoSharedPtr> mInfo; 680 Maybe<media::TimeUnit> mFirstDemuxedSampleTime; 681 // Use NullDecoderModule or not. 682 bool mIsNullDecode; 683 bool mHardwareDecodingDisabled; 684 // Whether we have reported hardware decoding support for video. Used only 685 // on reader's task queue, 686 bool mHasReportedVideoHardwareSupportTelemtry = false; 687 688 class { 689 public: 690 float Mean() const { return mMean; } 691 692 void Update(const media::TimeUnit& aValue) { 693 if (aValue == media::TimeUnit::Zero()) { 694 return; 695 } 696 mMean += static_cast<float>((1.0f / aValue.ToSeconds() - mMean) / 697 static_cast<double>(++mCount)); 698 } 699 700 void Reset() { 701 mMean = 0; 702 mCount = 0; 703 } 704 705 private: 706 float mMean = 0; 707 uint64_t mCount = 0; 708 } mMeanRate; 709 }; 710 711 template <typename Type> 712 class DecoderDataWithPromise : public DecoderData { 713 public: 714 DecoderDataWithPromise(MediaFormatReader* aOwner, MediaData::Type aType, 715 uint32_t aNumOfMaxError) 716 : DecoderData(aOwner, aType, aNumOfMaxError), mHasPromise(false) { 717 DecoderDoctorLogger::LogConstructionAndBase( 718 "MediaFormatReader::DecoderDataWithPromise", this, 719 "MediaFormatReader::DecoderData", 720 static_cast<const MediaFormatReader::DecoderData*>(this)); 721 } 722 723 ~DecoderDataWithPromise() { 724 DecoderDoctorLogger::LogDestruction( 725 "MediaFormatReader::DecoderDataWithPromise", this); 726 } 727 728 bool HasPromise() const override { return mHasPromise; } 729 730 RefPtr<DataPromise<Type>> EnsurePromise(StaticString aMethodName) { 731 MOZ_ASSERT(mOwner->OnTaskQueue()); 732 mHasPromise = true; 733 return mPromise.Ensure(aMethodName); 734 } 735 736 void ResolvePromise(Type* aData, StaticString aMethodName) { 737 MOZ_ASSERT(mOwner->OnTaskQueue()); 738 mPromise.Resolve(aData, aMethodName); 739 mHasPromise = false; 740 } 741 742 void RejectPromise(const MediaResult& aError, 743 StaticString aMethodName) override { 744 MOZ_ASSERT(mOwner->OnTaskQueue()); 745 mPromise.Reject(aError, aMethodName); 746 mHasPromise = false; 747 } 748 749 private: 750 MozPromiseHolder<DataPromise<Type>> mPromise; 751 Atomic<bool> mHasPromise; 752 }; 753 754 // Decode task queue. 755 RefPtr<TaskQueue> mTaskQueue; 756 757 DecoderDataWithPromise<AudioData> mAudio; 758 DecoderDataWithPromise<VideoData> mVideo; 759 760 Watchable<bool> mWorkingInfoChanged; 761 WatchManager<MediaFormatReader> mWatchManager; 762 bool mIsWatchingWorkingInfo; 763 764 // Returns true when the decoder for this track needs input. 765 bool NeedInput(DecoderData& aDecoder); 766 767 DecoderData& GetDecoderData(TrackType aTrack); 768 769 // Demuxer objects. 770 class DemuxerProxy; 771 UniquePtr<DemuxerProxy> mDemuxer; 772 bool mDemuxerInitDone; 773 void OnDemuxerInitDone(const MediaResult& aResult); 774 void OnDemuxerInitFailed(const MediaResult& aError); 775 MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest; 776 MozPromiseRequestHolder<NotifyDataArrivedPromise> mNotifyDataArrivedPromise; 777 bool mPendingNotifyDataArrived; 778 void OnDemuxFailed(TrackType aTrack, const MediaResult& aError); 779 780 void DoDemuxVideo(); 781 void OnVideoDemuxCompleted( 782 const RefPtr<MediaTrackDemuxer::SamplesHolder>& aSamples); 783 void OnVideoDemuxFailed(const MediaResult& aError) { 784 OnDemuxFailed(TrackType::kVideoTrack, aError); 785 } 786 787 void DoDemuxAudio(); 788 void OnAudioDemuxCompleted( 789 const RefPtr<MediaTrackDemuxer::SamplesHolder>& aSamples); 790 void OnAudioDemuxFailed(const MediaResult& aError) { 791 OnDemuxFailed(TrackType::kAudioTrack, aError); 792 } 793 794 void SkipVideoDemuxToNextKeyFrame(media::TimeUnit aTimeThreshold); 795 MozPromiseRequestHolder<MediaTrackDemuxer::SkipAccessPointPromise> 796 mSkipRequest; 797 void VideoSkipReset(uint32_t aSkipped); 798 void OnVideoSkipCompleted(uint32_t aSkipped); 799 void OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailure); 800 801 // The last number of decoded output frames that we've reported to 802 // MediaDecoder::NotifyDecoded(). We diff the number of output video 803 // frames every time that DecodeVideoData() is called, and report the 804 // delta there. 805 uint64_t mLastReportedNumDecodedFrames; 806 807 // Timestamp of the previous decoded video keyframe, in microseconds. 808 int64_t mPreviousDecodedKeyframeTime_us; 809 // Default mLastDecodedKeyframeTime_us value, must be bigger than anything. 810 static const int64_t sNoPreviousDecodedKeyframe = INT64_MAX; 811 812 RefPtr<layers::KnowsCompositor> mKnowsCompositor; 813 814 // Metadata objects 815 // True if we've read the streams' metadata. 816 bool mInitDone; 817 MozPromiseHolder<MetadataPromise> mMetadataPromise; 818 bool IsEncrypted() const; 819 820 // Set to true if any of our track buffers may be blocking. 821 bool mTrackDemuxersMayBlock; 822 823 // Seeking objects. 824 void SetSeekTarget(const SeekTarget& aTarget); 825 bool IsSeeking() const { return mPendingSeekTime.isSome(); } 826 bool IsVideoOnlySeeking() const { 827 return IsSeeking() && mOriginalSeekTarget.IsVideoOnly(); 828 } 829 bool IsAudioOnlySeeking() const { 830 return IsSeeking() && mOriginalSeekTarget.IsAudioOnly(); 831 } 832 void ScheduleSeek(); 833 void AttemptSeek(); 834 void OnSeekFailed(TrackType aTrack, const MediaResult& aError); 835 void DoVideoSeek(); 836 void OnVideoSeekCompleted(media::TimeUnit aTime); 837 void OnVideoSeekFailed(const MediaResult& aError); 838 bool mSeekScheduled; 839 840 void DoAudioSeek(); 841 void OnAudioSeekCompleted(media::TimeUnit aTime); 842 void OnAudioSeekFailed(const MediaResult& aError); 843 // The SeekTarget that was last given to Seek() 844 SeekTarget mOriginalSeekTarget; 845 // Temporary seek information while we wait for the data 846 Maybe<media::TimeUnit> mFallbackSeekTime; 847 Maybe<media::TimeUnit> mPendingSeekTime; 848 MozPromiseHolder<SeekPromise> mSeekPromise; 849 850 RefPtr<VideoFrameContainer> mVideoFrameContainer; 851 layers::ImageContainer* GetImageContainer(); 852 853 RefPtr<CDMProxy> mCDMProxy; 854 855 RefPtr<GMPCrashHelper> mCrashHelper; 856 857 void SetNullDecode(TrackType aTrack, bool aIsNullDecode); 858 859 class DecoderFactory; 860 UniquePtr<DecoderFactory> mDecoderFactory; 861 862 class ShutdownPromisePool; 863 UniquePtr<ShutdownPromisePool> mShutdownPromisePool; 864 865 MediaEventListener mOnTrackWaitingForKeyListener; 866 867 void OnFirstDemuxCompleted( 868 TrackInfo::TrackType aType, 869 const RefPtr<MediaTrackDemuxer::SamplesHolder>& aSamples); 870 871 void OnFirstDemuxFailed(TrackInfo::TrackType aType, 872 const MediaResult& aError); 873 874 void MaybeResolveMetadataPromise(); 875 876 // Stores presentation info required for playback. 877 MediaInfo mInfo; 878 879 UniquePtr<MetadataTags> mTags; 880 881 // A flag indicating if the start time is known or not. 882 bool mHasStartTime = false; 883 884 void ShutdownDecoder(TrackType aTrack); 885 RefPtr<ShutdownPromise> TearDownDecoders(); 886 887 bool mShutdown = false; 888 889 // Buffered range. 890 Canonical<media::TimeIntervals> mBuffered; 891 892 // Used to send TimedMetadata to the listener. 893 TimedMetadataEventProducer mTimedMetadataEvent; 894 895 // Notify if this media is not seekable. 896 MediaEventProducer<void> mOnMediaNotSeekable; 897 898 // Notify if we are waiting for a decryption key. 899 MediaEventProducer<TrackInfo::TrackType> mOnTrackWaitingForKey; 900 901 MediaEventProducer<nsTArray<uint8_t>, nsString> mOnEncrypted; 902 903 MediaEventProducer<void> mOnWaitingForKey; 904 905 MediaEventProducer<MediaResult> mOnDecodeWarning; 906 907 MediaEventProducer<VideoInfo, AudioInfo> mTrackInfoUpdatedEvent; 908 909 RefPtr<FrameStatistics> mFrameStats; 910 911 // Used in bug 1393399 for telemetry. 912 const MediaDecoderOwnerID mMediaDecoderOwnerID; 913 914 bool ResolveSetCDMPromiseIfDone(TrackType aTrack); 915 void PrepareToSetCDMForTrack(TrackType aTrack); 916 MozPromiseHolder<SetCDMPromise> mSetCDMPromise; 917 TrackSet mSetCDMForTracks{}; 918 bool IsDecoderWaitingForCDM(TrackType aTrack); 919 920 void GetDebugInfo(dom::MediaFormatReaderDebugInfo& aInfo); 921 922 // Only be used on Windows when the media engine playback is enabled. 923 Maybe<uint64_t> mMediaEngineId; 924 925 const Maybe<TrackingId> mTrackingId; 926 927 // The start time of reading the metdata and how long does it take. This 928 // measurement includes the time of downloading media resource over the 929 // internet. 930 Maybe<TimeStamp> mReadMetadataStartTime; 931 TimeDuration mReadMetaDataTime; 932 933 // The total amount of time we have been waiting for the video data due to 934 // lacking of data. 935 TimeDuration mTotalWaitingForVideoDataTime; 936 937 // https://github.com/w3c/encrypted-media/issues/251#issuecomment-819783073 938 // Treat playback as encrypted if the media key is set before playback starts, 939 // this allows websites to start with non-encrypted stream and switch to 940 // encrypted stream later. 941 Atomic<bool> mEncryptedCustomIdent; 942 }; 943 944 DDLoggedTypeCustomName(MediaFormatReader::DecoderData, DecoderData); 945 946 } // namespace mozilla 947 948 #endif