Files
palemoon27/dom/media/MediaDecoderReader.h
T
roytam1 74c60cb62d import changes from `dev' branch of rmottola/Arctic-Fox:
- Use CompositorWidgetProxy for dispatching vsync to the compositor. (bug 1269037 part 1, r=mchang) (c8b7a4240c)
- Remove unused null widget checks. (bug 1269037 part 2, r=mchang) (4f4cc9952b)
- Bug 1269422: Wrap Gonk widget in |CompositorWidgetProxyWrapper|. r=dvander (4513035cbf)
- Remove nsBaseWidget::NewCompositorBridgeParent. (bug 1272472 part 1, r=kats) (ca813c1f2b)
- Use IPDL to schedule composites on GTK. (bug 1272472 part 2, r=nical) (7402cf834e)
- Use IPC to schedule composites on Windows. (bug 1272472 part 3, r=jimm) (e5d7281dd7)
- Don't use nsIWidget to check APZ in LayerManagerComposite. (bug 1269653 part 1, r=kats) (79a1644111)
- Restrict SetDispAcquireFence's nsIWidget access to Gonk. (bug 1269653 part 2, r=kats) (72110b7bc7)
- Bug 1264764 - Move PTexture under PCompositorBridge r=nical,dvander (17e6ec7fc1)
- Move CompositorThreadHolder into its own file. (bug 1273017 part 1, r=mattwoodrow) (464ede8be1)
- Move CompositorBridgeParent::CompositorLoop to CompositorThreadHolder. (bug 1273017 part 2, r=mattwoodrow) (85708f3cde)
- Bug 1268313: Part 1 - Be explicit about which NewRunnableMethod callers want to be able to cancel. r=froydnj (faa07aa139)
- Bug 1268313: Part 2 - Replace some NewRunnableMethods with NS_NewNonOwningRunnableMethod. r=froydnj (010c43d000)
- Bug 1268313: Part 3 - Replace some NewCancelableRunnableMethod with NS_NewNonOwningCancelableRunnableMethod. r=froydnj (55018ef234)
- Bug 1268313: Part 4 - Replace NewCancelableRunnableMethod with NS_NewCancelableRunnableMethod. r=froydnj (c22711b35d)
- Bug 1268313: Part 5 - Make NS_NewRunnableMethod able to call const functions. r=froydnj (b0f60963a3)
- Bug 1268313: Part 6 - Replace NewRunnableMethod with NS_NewRunnableMethod. r=froydnj (18d40def2c)
- Bug 1260950 - Set mInitialSizeFound to true when the initial size id found. r=jesup, r=pehrsons a=kwierso (5d6abe57e0)
- Bug 1237176 - Notify synth start if we get a finished event without a blocking-changed event. r=roc (c1aebe903a)
- Bug 911546, use a runnable so that popups don't rollup during a grab, r=karlt (a06bd44e6c)
- Bug 1237617 - Call nsWindow::ForcePresent during going active r=bas.schouten (066cad8f89)
- Bug 1265420 - SetAndFetchFaviconForPage should return a cancelable object to allow aborting the fetch. r=Gijs (a3f7dc54b7)
- Bug 1268313: Part 7 - Move NS_NewRunnableMethod and friends to mozilla::NewRunnableMethod. r=froydnj (8b4bf34961)
- Bug 1266595: Followup to fix IPDL tests. r=billm (216f2dcff5)
- Bug 1268313: Fix up IPDL tests. r=billm (228348d642)
- Add WinCompositorWidgetProxy. (bug 1265975 part 1, r=jimm) (bfafe7a8e2)
- Implement WinCompositorWidgetProxy::GetClientSize. (bug 1265975 part 2, r=jimm) (a8710a3259)
- Move the WM_SETTEXT present lock to CompositorWidgetProxy. (bug 1265975 part 3, r=jimm) (297ce28c8a)
- Move transparency handling to WinCompositorWigetProxy. (bug 1265975 part 4, r=jimm) (46ba0c6d01)
- Remove Windows-specific compositor calls to nsIWidget. (bug 1265975 part 5, r=jimm) (3ef157c160)
- Remove plugin-related CompositorBridgeParent use of nsIWidget. (bug 1265975 part 6, r=jimm) (6d80cdd6fd)
- Hide top-level CompositorBridgeParents behind a new API. (bug 1272472 part 4, r=mattwoodrow,kats,gwagner) (228c0efdb7)
- Bug 1253424 - part 1 - add a already_AddRefed nsTransactionStack::Push overload; r=erahm (7059e20914)
- Bug 1253424 - part 2 - add nsTransactionStack::IsEmpty; r=erahm (7e9764a146)
- Bug 1254618 - modify nsTransactionStack to use nsDeque rather than std::deque; r=ehsan (5e47ea431e)
- Bug 1136857 - Make DOMStorageCache::mLoaded flag atomic to prevent potential races, r=nfroyd (39aaea1de3)
- Bug 1265408 - Add webidl for IIRFilterNode; r=smaug (040ce9aa43)
- Bug 1265408 - Implement IIRFilterNode; r=padenot (6bf569a412)
- Bug 1265408 - Import IIRFilter from blink; r=padenot (71b28c0ad2)
- Bug 1265408 - Use IIRFilter from blink; r=padenot (5d058d8568)
- Bug 1265408 - Add buffersAreZero to IIRFilter; r=karlt (45edba3e13)
- Bug 1265408 - Avoid subnormals in IIRFilter; r=karlt (0e1ae93f0b)
- Bug 1265408 - Add LogToDeveloperConsole to WebAudioUtils; r=padenot (88d5f0222a)
- Bug 1268984 - Store GMPStorage on GMPServiceParent so that it persists inside the same PB session. r=gerald (17d4d0abaf)
- Bug 1267905 - Replace uses of ScopedCERTCertList with UniqueCERTCertList. r=keeler (783bf11b2a)
- Bug 1270005 - Replace uses of ScopedPK11SlotInfo with UniquePK11SlotInfo in PSM. r=keeler (ea9a4011aa)
- Bug 1271501 - Remove unnecessary uses of reinterpret_cast in PSM. r=keeler (6be40f0a85)
- Bug 1271501 - Downgrade unnecessarily strong reinterpret_casts in PSM. r=keeler (95245f00ce)
- Bug 1082346 - 01. Convert PKCS12 password endian using copyAndSwapToBigEndian. r=keeler (9cc58fc550)
- Bug 1082346 - 02. Test case. r=keeler r=Cykesiopka (7fb0e8abc4)
- Bug 160122 - Stop using PR_smprintf in PSM. r=keeler (1e5b68819c)
- Bug 1271501 - Use mozilla::BitwiseCast instead of reinterpret_cast in PSM. r=keeler (894966a2ef)
- Bug 1273855: TraceLogger - Include PID in the log names in order to support browser with e10s, r=bbouvier (8cf2233db3)
- Bug 1274189. Part 1 - rename some functions to be consistent with other MediaDataDecoder sub-classes. r=jya. (4511b3d3f7)
- Bug 1274189. Part 2 - remove use of FlushableTaskQueue::Flush(). r=jya. (77e745fdd1)
- Bug 1274189. Part 3 - remove use of FlushableTaskQueue. r=jya (aac61dcd02)
- Bug 1269963. Part 1 - Add a SyncRunnable::DispatchToThread() overload for AbstractThread. r=bobbyholley. (839752aff4)
- Bug 1269672 - part1 : revert sampling rate changing of the bug1235612. (9015782e13)
- Bug 1270698 - check if we need to enter buffering periodically to ensure we start buffering when running out of decoded audio/video data. r=cpearce. (16734549b7)
- Bug 1271581 - use newCurrentTime, instead of GetMediaTime() to decide the nextState; r=jwwang (9c5075eada)
- Bug 1224973 - Part 1: Remove MediaDecoderOwner->IsHidden(). r=cpearce,jwwang (4fde3ede5a)
- Bug 1224973 - Part 2: Set MediaDecoder visibility via NotifyOwnerActivityChanged. r=cpearce,jwwang (be917202eb)
- Bug 1224973 - Part 3: Plumb element visibility into MDSM. r=jya,jwwang (9ec83fa243)
- Bug 1224973 - Part 4: Pref media.suspend-bkgnd-video.enabled. r=cpearce,jwwang (43413a025f)
- Bug 1269408: P1. Retry InternalSeek if previous attempt failed once more data is available. r=gerald (05db58dc7c)
- crude fix (0097068989)
- Bug 1269408: P2. Update mochitest. r=gerald (464b4c0724)
- Bug 1269408: P3. Ensure a new seek request will cancel the previous internal seek. r=gerald (6ed4b8dc95)
- Bug 1269408: P4. Ensure the decoders are flushed prior performing an internal seek. r=gerald (074234067b)
- Bug 1269408: P5. Only drop the seek target if it's exactly the seek target. r=gerald (88701eb05a)
- Bug 1269408: P6. Add debugging information, useful when a mochitest timeout. r=gerald (ef0270ab0d)
- Bug 1269408: P7. Start skip to next keyframe logic when resume point is behind current time. r=gerald (bd40ebf3bc)
- Bug 1269408: P8. Add debugging log. r=gerald (e6dbd1f0a6)
- Bug 1269408: P9. Move handling logic of skip to next keyframe to its own function. r=gerald (3c8039e417)
- Bug 1269408: P10. Reject promise early if in error state. r=me (8af54c574e)
- Bug 1224973 - Part 5: Implement suspend decoding for background video. r=cpearce,jwwang,jya (22081521e3)
- Bug 1242874 - part1 : create suspened types. r=baku (d3ac9548e5)
- Bug 1242874 - part2 : window's suspend attribute. r=baku, r=ehsan (1fd9dc2647)
- remove allowscirpted (39ab523036)
- Bug 1242874 - part3 : implement different suspended methods. r=baku, r=jwwang (25d1f27a03)
- Bug 1242874 - part4 : wrap the volume/mute/suspend for notifyStartedPlaying. r=baku (b8ba3238c2)
- bug 1242874 - part5 : add test. r=baku, r=ehsan (f840139b5a)
- Bug 1235612 - Part 1: Implement notify media-playback. r=baku (b5ec29da20)
- Bug 1235612 - Part 2: Notify audible state in NotifyStartedPlaying. r=baku (dc38583a62)
- Bug 1235612 - Part 3: Implement the logic of audible state notification for agent owners. r=baku (f65b3952fa)
- Bug 1235612 - Part 4: Modify check audible method. r=jwwang (73457e39eb)
- Bug 1269672 - part2 : move audible data checking from MDSM to DecodedAudioDataSink. (d2c3b6874c)
- Bug 1269936 - Introduce and call a runtime-wide servo initialization hook. r=heycam (d4d505d4c2)
- Bug 1263778 - Rename a bunch of low-level [[Prototype]] access methods to make their interactions with statically-known and dynamically-computed [[Prototype]]s clearer. r=efaust (66bbe8e7db)
- Bug 888969 - Permit a cyclic [[Prototype]] chain to be created through a Location object. r=bz, r=efaust (3e3b9cbb16)
- re-apply Bug 1054906 - Implement ES6 Symbol.hasInstance 2/2; r=jandem (8d5c7573ff)
- Bug 1054906 - Implement ES6 Symbol.hasInstance 1/2; r=evilpie,bz (a836904e5d)
- fix misspatch (54a5f2d708)
- Bug 1270349 part 1. Add IDL parser support for [LegacyUnenumerableNamedProperties]. r=peterv (8c836bc74a)
- Bug 1270349 part 2. Add [LegacyUnenumerableNamedProperties] to the interfaces that specify it in DOM and HTML. r=peterv (25d3cc1377)
- Bug 1270349 part 3. Add a way to ask an interface descriptor for a proxy whether its named props should be enumerable. r=peterv (0a9f804867)
- Bug 1270349 part 4. Use LegacyUnenumerableNamedProperties instead of NameIsEnumerable() calls to determine whether named props on DOM proxies should be enumerable. r=peterv (82f5158963)
- Bug 1270349 part 5. Use LegacyUnenumerableNamedProperties instead of passing flags to GetSupportedNames to determine whether named props on DOM proxies should be reflected in ownPropertyKeys. r=peterv (3984176834)
- Bug 1270349 followup to address a review comment. r=peterv (b49f4c5335)
2024-10-03 21:44:56 +08:00

443 lines
16 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MediaDecoderReader_h_)
#define MediaDecoderReader_h_
#include "mozilla/MozPromise.h"
#include "AbstractMediaDecoder.h"
#include "MediaInfo.h"
#include "MediaData.h"
#include "MediaMetadataManager.h"
#include "MediaQueue.h"
#include "MediaTimer.h"
#include "AudioCompactor.h"
#include "Intervals.h"
#include "TimeUnits.h"
#include "SeekTarget.h"
namespace mozilla {
class CDMProxy;
class MediaDecoderReader;
struct WaitForDataRejectValue
{
enum Reason {
SHUTDOWN,
CANCELED
};
WaitForDataRejectValue(MediaData::Type aType, Reason aReason)
:mType(aType), mReason(aReason) {}
MediaData::Type mType;
Reason mReason;
};
class MetadataHolder
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MetadataHolder)
MediaInfo mInfo;
nsAutoPtr<MetadataTags> mTags;
private:
virtual ~MetadataHolder() {}
};
enum class ReadMetadataFailureReason : int8_t
{
METADATA_ERROR
};
// Encapsulates the decoding and reading of media data. Reading can either
// synchronous and done on the calling "decode" thread, or asynchronous and
// performed on a background thread, with the result being returned by
// callback. Never hold the decoder monitor when calling into this class.
// Unless otherwise specified, methods and fields of this class can only
// be accessed on the decode task queue.
class MediaDecoderReader {
friend class ReRequestVideoWithSkipTask;
friend class ReRequestAudioTask;
static const bool IsExclusive = true;
public:
enum NotDecodedReason {
END_OF_STREAM,
DECODE_ERROR,
WAITING_FOR_DATA,
CANCELED
};
enum TargetQueues {
VIDEO_ONLY,
AUDIO_VIDEO
};
using MetadataPromise =
MozPromise<RefPtr<MetadataHolder>, ReadMetadataFailureReason, IsExclusive>;
using MediaDataPromise =
MozPromise<RefPtr<MediaData>, NotDecodedReason, IsExclusive>;
using SeekPromise = MozPromise<media::TimeUnit, nsresult, IsExclusive>;
// Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
// But in the current architecture it's only ever used exclusively (by MDSM),
// so we mark it that way to verify our assumptions. If you have a use-case
// for multiple WaitForData consumers, feel free to flip the exclusivity here.
using WaitForDataPromise =
MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
using BufferedUpdatePromise = MozPromise<bool, bool, IsExclusive>;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
// The caller must ensure that Shutdown() is called before aDecoder is
// destroyed.
explicit MediaDecoderReader(AbstractMediaDecoder* aDecoder);
// Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
// on failure.
virtual nsresult Init() { return NS_OK; }
// Release media resources they should be released in dormant state
// The reader can be made usable again by calling ReadMetadata().
virtual void ReleaseMediaResources() {}
// Destroys the decoding state. The reader cannot be made usable again.
// This is different from ReleaseMediaResources() as it is irreversable,
// whereas ReleaseMediaResources() is. Must be called on the decode
// thread.
virtual RefPtr<ShutdownPromise> Shutdown();
virtual bool OnTaskQueue() const
{
return OwnerThread()->IsCurrentThreadIn();
}
// Resets all state related to decoding, emptying all buffers etc.
// Cancels all pending Request*Data() request callbacks, rejects any
// outstanding seek promises, and flushes the decode pipeline. The
// decoder must not call any of the callbacks for outstanding
// Request*Data() calls after this is called. Calls to Request*Data()
// made after this should be processed as usual.
//
// Normally this call preceedes a Seek() call, or shutdown.
//
// The first samples of every stream produced after a ResetDecode() call
// *must* be marked as "discontinuities". If it's not, seeking work won't
// properly!
virtual nsresult ResetDecode(TargetQueues aQueues = AUDIO_VIDEO);
// Requests one audio sample from the reader.
//
// The decode should be performed asynchronously, and the promise should
// be resolved when it is complete. Don't hold the decoder
// monitor while calling this, as the implementation may try to wait
// on something that needs the monitor and deadlock.
virtual RefPtr<MediaDataPromise> RequestAudioData();
// Requests one video sample from the reader.
//
// Don't hold the decoder monitor while calling this, as the implementation
// may try to wait on something that needs the monitor and deadlock.
// If aSkipToKeyframe is true, the decode should skip ahead to the
// the next keyframe at or after aTimeThreshold microseconds.
virtual RefPtr<MediaDataPromise>
RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold);
// By default, the state machine polls the reader once per second when it's
// in buffering mode. Some readers support a promise-based mechanism by which
// they notify the state machine when the data arrives.
virtual bool IsWaitForDataSupported() const { return false; }
virtual RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType)
{
MOZ_CRASH();
}
// By default, the reader return the decoded data. Some readers support
// retuning demuxed data.
virtual bool IsDemuxOnlySupported() const { return false; }
// Configure the reader to return demuxed or decoded data
// upon calls to Request{Audio,Video}Data.
virtual void SetDemuxOnly(bool /*aDemuxedOnly*/) {}
// The default implementation of AsyncReadMetadata is implemented in terms of
// synchronous ReadMetadata() calls. Implementations may also
// override AsyncReadMetadata to create a more proper async implementation.
virtual RefPtr<MetadataPromise> AsyncReadMetadata();
// Fills aInfo with the latest cached data required to present the media,
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) {}
// Moves the decode head to aTime microseconds. aEndTime denotes the end
// time of the media in usecs. This is only needed for OggReader, and should
// probably be removed somehow.
virtual RefPtr<SeekPromise> Seek(SeekTarget aTarget, int64_t aEndTime) = 0;
// Called to move the reader into idle state. When the reader is
// created it is assumed to be active (i.e. not idle). When the media
// element is paused and we don't need to decode any more data, the state
// machine calls SetIdle() to inform the reader that its decoder won't be
// needed for a while. The reader can use these notifications to enter
// a low power state when the decoder isn't needed, if desired.
// This is most useful on mobile.
// Note: DecodeVideoFrame, DecodeAudioData, ReadMetadata and Seek should
// activate the decoder if necessary. The state machine only needs to know
// when to call SetIdle().
virtual void SetIdle() {}
#ifdef MOZ_EME
virtual void SetCDMProxy(CDMProxy* aProxy) {}
#endif
// Tell the reader that the data decoded are not for direct playback, so it
// can accept more files, in particular those which have more channels than
// available in the audio output.
void SetIgnoreAudioOutputFormat()
{
mIgnoreAudioOutputFormat = true;
}
// MediaSourceReader opts out of the start-time-guessing mechanism.
virtual bool ForceZeroStartTime() const { return false; }
// The MediaDecoderStateMachine uses various heuristics that assume that
// raw media data is arriving sequentially from a network channel. This
// makes sense in the <video src="foo"> case, but not for more advanced use
// cases like MSE.
virtual bool UseBufferingHeuristics() const { return true; }
// Returns the number of bytes of memory allocated by structures/frames in
// the video queue.
size_t SizeOfVideoQueueInBytes() const;
// Returns the number of bytes of memory allocated by structures/frames in
// the audio queue.
size_t SizeOfAudioQueueInBytes() const;
virtual size_t SizeOfVideoQueueInFrames();
virtual size_t SizeOfAudioQueueInFrames();
void NotifyDataArrived()
{
MOZ_ASSERT(OnTaskQueue());
NS_ENSURE_TRUE_VOID(!mShutdown);
NotifyDataArrivedInternal();
UpdateBuffered();
}
// Update the buffered ranges and upon doing so return a promise
// to indicate success. Overrides may need to do extra work to ensure
// buffered is up to date.
virtual RefPtr<BufferedUpdatePromise> UpdateBufferedWithPromise()
{
MOZ_ASSERT(OnTaskQueue());
UpdateBuffered();
return BufferedUpdatePromise::CreateAndResolve(true, __func__);
}
virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
AbstractCanonical<media::TimeIntervals>* CanonicalBuffered()
{
return &mBuffered;
}
void DispatchSetStartTime(int64_t aStartTime)
{
RefPtr<MediaDecoderReader> self = this;
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableFunction([self, aStartTime] () -> void
{
MOZ_ASSERT(self->OnTaskQueue());
MOZ_ASSERT(!self->HaveStartTime());
self->mStartTime.emplace(aStartTime);
self->UpdateBuffered();
});
OwnerThread()->Dispatch(r.forget());
}
TaskQueue* OwnerThread() const
{
return mTaskQueue;
}
// Returns true if the reader implements RequestAudioData()
// and RequestVideoData() asynchronously, rather than using the
// implementation in this class to adapt the old synchronous to
// the newer async model.
virtual bool IsAsync() const { return false; }
// Returns true if this decoder reader uses hardware accelerated video
// decoding.
virtual bool VideoIsHardwareAccelerated() const { return false; }
TimedMetadataEventSource& TimedMetadataEvent()
{
return mTimedMetadataEvent;
}
// Notified by the OggReader during playback when chained ogg is detected.
MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
protected:
virtual ~MediaDecoderReader();
// Populates aBuffered with the time ranges which are buffered. This may only
// be called on the decode task queue, and should only be used internally by
// UpdateBuffered - mBuffered (or mirrors of it) should be used for everything
// else.
//
// This base implementation in MediaDecoderReader estimates the time ranges
// buffered by interpolating the cached byte ranges with the duration
// of the media. Reader subclasses should override this method if they
// can quickly calculate the buffered ranges more accurately.
//
// The primary advantage of this implementation in the reader base class
// is that it's a fast approximation, which does not perform any I/O.
//
// The OggReader relies on this base implementation not performing I/O,
// since in FirefoxOS we can't do I/O on the main thread, where this is
// called.
virtual media::TimeIntervals GetBuffered();
RefPtr<MediaDataPromise> DecodeToFirstVideoData();
bool HaveStartTime()
{
MOZ_ASSERT(OnTaskQueue());
return mStartTime.isSome();
}
int64_t StartTime() { MOZ_ASSERT(HaveStartTime()); return mStartTime.ref(); }
// Queue of audio frames. This queue is threadsafe, and is accessed from
// the audio, decoder, state machine, and main threads.
MediaQueue<AudioData> mAudioQueue;
// Queue of video frames. This queue is threadsafe, and is accessed from
// the decoder, state machine, and main threads.
MediaQueue<VideoData> mVideoQueue;
// An adapter to the audio queue which first copies data to buffers with
// minimal allocation slop and then pushes them to the queue. This is
// useful for decoders working with formats that give awkward numbers of
// frames such as mp3.
AudioCompactor mAudioCompactor;
// Reference to the owning decoder object.
AbstractMediaDecoder* mDecoder;
// Decode task queue.
RefPtr<TaskQueue> mTaskQueue;
// State-watching manager.
WatchManager<MediaDecoderReader> mWatchManager;
// Buffered range.
Canonical<media::TimeIntervals> mBuffered;
// Stores presentation info required for playback.
MediaInfo mInfo;
// Duration, mirrored from the state machine task queue.
Mirror<media::NullableTimeUnit> mDuration;
// Whether we should accept media that we know we can't play
// directly, because they have a number of channel higher than
// what we support.
bool mIgnoreAudioOutputFormat;
// The start time of the media, in microseconds. This is the presentation
// time of the first frame decoded from the media. This is initialized to -1,
// and then set to a value >= by MediaDecoderStateMachine::SetStartTime(),
// after which point it never changes (though SetStartTime may be called
// multiple times with the same value).
//
// This is an ugly breach of abstractions - it's currently necessary for the
// readers to return the correct value of GetBuffered. We should refactor
// things such that all GetBuffered calls go through the MDSM, which would
// offset the range accordingly.
Maybe<int64_t> mStartTime;
// This is a quick-and-dirty way for DecodeAudioData implementations to
// communicate the presence of a decoding error to RequestAudioData. We should
// replace this with a promise-y mechanism as we make this stuff properly
// async.
bool mHitAudioDecodeError;
bool mShutdown;
// Used to send TimedMetadata to the listener.
TimedMetadataEventProducer mTimedMetadataEvent;
// Notify if this media is not seekable.
MediaEventProducer<void> mOnMediaNotSeekable;
private:
// Does any spinup that needs to happen on this task queue. This runs on a
// different thread than Init, and there should not be ordering dependencies
// between the two (even though in practice, Init will always run first right
// now thanks to the tail dispatcher).
void InitializationTask();
// Read header data for all bitstreams in the file. Fills aInfo with
// the data required to present the media, and optionally fills *aTags
// with tag metadata from the file.
// Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
virtual nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
{
MOZ_CRASH();
}
// Recomputes mBuffered.
virtual void UpdateBuffered();
virtual void VisibilityChanged();
virtual void NotifyDataArrivedInternal() {}
// Overrides of this function should decodes an unspecified amount of
// audio data, enqueuing the audio data in mAudioQueue. Returns true
// when there's more audio to decode, false if the audio is finished,
// end of file has been reached, or an un-recoverable read error has
// occured. This function blocks until the decode is complete.
virtual bool DecodeAudioData()
{
return false;
}
// Overrides of this function should read and decodes one video frame.
// Packets with a timestamp less than aTimeThreshold will be decoded
// (unless they're not keyframes and aKeyframeSkip is true), but will
// not be added to the queue. This function blocks until the decode
// is complete.
virtual bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold)
{
return false;
}
// Promises used only for the base-class (sync->async adapter) implementation
// of Request{Audio,Video}Data.
MozPromiseHolder<MediaDataPromise> mBaseAudioPromise;
MozPromiseHolder<MediaDataPromise> mBaseVideoPromise;
// Flags whether a the next audio/video sample comes after a "gap" or
// "discontinuity" in the stream. For example after a seek.
bool mAudioDiscontinuity;
bool mVideoDiscontinuity;
MediaEventListener mDataArrivedListener;
};
} // namespace mozilla
#endif