mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 1168456 - Remove NotifyWaitingForResourcesStatusChanged() call from MediaCodecReader r=bholley,bwu
This commit is contained in:
parent
c14569449f
commit
6a032542b6
@ -182,9 +182,6 @@ MediaDecoderReader::AsyncReadMetadata()
|
||||
mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
|
||||
DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");
|
||||
|
||||
// PreReadMetadata causes us to try to allocate various hardware and OS
|
||||
// resources, which may not be available at the moment.
|
||||
PreReadMetadata();
|
||||
if (IsWaitingMediaResources()) {
|
||||
return MetadataPromise::CreateAndReject(Reason::WAITING_FOR_RESOURCES, __func__);
|
||||
}
|
||||
|
@ -165,13 +165,10 @@ public:
|
||||
virtual bool HasVideo() = 0;
|
||||
|
||||
// The default implementation of AsyncReadMetadata is implemented in terms of
|
||||
// synchronous PreReadMetadata() / ReadMetadata() calls. Implementations may also
|
||||
// synchronous ReadMetadata() calls. Implementations may also
|
||||
// override AsyncReadMetadata to create a more proper async implementation.
|
||||
virtual nsRefPtr<MetadataPromise> AsyncReadMetadata();
|
||||
|
||||
// A function that is called before ReadMetadata() call.
|
||||
virtual void PreReadMetadata() {};
|
||||
|
||||
// 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.
|
||||
|
@ -486,6 +486,11 @@ MediaCodecProxy::resourceReserved()
|
||||
releaseCodec();
|
||||
if (!allocateCodec()) {
|
||||
SetMediaCodecFree();
|
||||
// Notification
|
||||
sp<CodecResourceListener> listener = mListener.promote();
|
||||
if (listener != nullptr) {
|
||||
listener->codecCanceled();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -501,6 +506,17 @@ MediaCodecProxy::resourceReserved()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaCodecProxy::resourceCanceled()
|
||||
{
|
||||
SetMediaCodecFree();
|
||||
// Notification
|
||||
sp<CodecResourceListener> listener = mListener.promote();
|
||||
if (listener != nullptr) {
|
||||
listener->codecCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
bool MediaCodecProxy::Prepare()
|
||||
{
|
||||
|
||||
|
@ -152,7 +152,7 @@ protected:
|
||||
// MediaResourceHandler::EventListener::resourceReserved()
|
||||
virtual void resourceReserved();
|
||||
// MediaResourceHandler::EventListener::resourceCanceled()
|
||||
virtual void resourceCanceled() {}
|
||||
virtual void resourceCanceled();
|
||||
|
||||
private:
|
||||
// Forbidden
|
||||
|
@ -268,7 +268,6 @@ MediaCodecReader::ProcessCachedDataTask::Run()
|
||||
MediaCodecReader::MediaCodecReader(AbstractMediaDecoder* aDecoder)
|
||||
: MediaOmxCommonReader(aDecoder)
|
||||
, mExtractor(nullptr)
|
||||
, mIsWaitingResources(false)
|
||||
, mTextureClientIndexesLock("MediaCodecReader::mTextureClientIndexesLock")
|
||||
, mColorConverterBufferSize(0)
|
||||
, mParserMonitor("MediaCodecReader::mParserMonitor")
|
||||
@ -289,19 +288,6 @@ MediaCodecReader::Init(MediaDecoderReader* aCloneDonor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaCodecReader::IsWaitingMediaResources()
|
||||
{
|
||||
return mIsWaitingResources;
|
||||
}
|
||||
|
||||
void
|
||||
MediaCodecReader::UpdateIsWaitingMediaResources()
|
||||
{
|
||||
mIsWaitingResources = (mVideoTrack.mCodec != nullptr) &&
|
||||
(!mVideoTrack.mCodec->allocated());
|
||||
}
|
||||
|
||||
void
|
||||
MediaCodecReader::ReleaseMediaResources()
|
||||
{
|
||||
@ -644,58 +630,66 @@ MediaCodecReader::ParseDataSegment(const char* aBuffer,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MediaCodecReader::PreReadMetadata()
|
||||
{
|
||||
UpdateIsWaitingMediaResources();
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
MediaCodecReader::ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags)
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise>
|
||||
MediaCodecReader::AsyncReadMetadata()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
if (!ReallocateResources()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!ReallocateExtractorResources()) {
|
||||
return MediaDecoderReader::MetadataPromise::CreateAndReject(
|
||||
ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
}
|
||||
|
||||
bool incrementalParserNeeded =
|
||||
mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
|
||||
if (incrementalParserNeeded && !TriggerIncrementalParser()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return MediaDecoderReader::MetadataPromise::CreateAndReject(
|
||||
ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
}
|
||||
|
||||
// Bug 1050667, both MediaDecoderStateMachine and MediaCodecReader
|
||||
// relies on IsWaitingMediaResources() function. And the waiting state will be
|
||||
// changed by binder thread, so we store the waiting state in a cache value to
|
||||
// make them in the same waiting state.
|
||||
UpdateIsWaitingMediaResources();
|
||||
if (IsWaitingMediaResources()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise> p = mMetadataPromise.Ensure(__func__);
|
||||
|
||||
nsRefPtr<MediaCodecReader> self = this;
|
||||
mMediaResourceRequest.Begin(CreateMediaCodecs()
|
||||
->RefableThen(GetTaskQueue(), __func__,
|
||||
[self] (bool) -> void {
|
||||
self->mMediaResourceRequest.Complete();
|
||||
self->HandleResourceAllocated();
|
||||
}, [self] (bool) -> void {
|
||||
self->mMediaResourceRequest.Complete();
|
||||
self->mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
}));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
MediaCodecReader::HandleResourceAllocated()
|
||||
{
|
||||
// Configure video codec after the codecReserved.
|
||||
if (mVideoTrack.mSource != nullptr) {
|
||||
if (!ConfigureMediaCodec(mVideoTrack)) {
|
||||
DestroyMediaCodec(mVideoTrack);
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: start streaming
|
||||
|
||||
if (!UpdateDuration()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateAudioInfo()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVideoInfo()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the total duration (the max of the audio and video track).
|
||||
@ -724,14 +718,15 @@ MediaCodecReader::ReadMetadata(MediaInfo* aInfo,
|
||||
mozilla::TimeStamp::Now());
|
||||
}
|
||||
|
||||
*aInfo = mInfo;
|
||||
*aTags = nullptr;
|
||||
nsRefPtr<MetadataHolder> metadata = new MetadataHolder();
|
||||
metadata->mInfo = mInfo;
|
||||
metadata->mTags = nullptr;
|
||||
|
||||
#ifdef MOZ_AUDIO_OFFLOAD
|
||||
CheckAudioOffload();
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
mMetadataPromise.Resolve(metadata, __func__);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1080,13 +1075,12 @@ MediaCodecReader::GetAudioOffloadTrack()
|
||||
}
|
||||
|
||||
bool
|
||||
MediaCodecReader::ReallocateResources()
|
||||
MediaCodecReader::ReallocateExtractorResources()
|
||||
{
|
||||
if (CreateLooper() &&
|
||||
CreateExtractor() &&
|
||||
CreateMediaSources() &&
|
||||
CreateTaskQueues() &&
|
||||
CreateMediaCodecs()) {
|
||||
CreateTaskQueues()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1097,6 +1091,10 @@ MediaCodecReader::ReallocateResources()
|
||||
void
|
||||
MediaCodecReader::ReleaseCriticalResources()
|
||||
{
|
||||
mMediaResourceRequest.DisconnectIfExists();
|
||||
mMediaResourcePromise.RejectIfExists(true, __func__);
|
||||
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
|
||||
|
||||
ResetDecode();
|
||||
// Before freeing a video codec, all video buffers needed to be released
|
||||
// even from graphics pipeline.
|
||||
@ -1292,21 +1290,35 @@ MediaCodecReader::CreateTaskQueues()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsRefPtr<MediaOmxCommonReader::MediaResourcePromise>
|
||||
MediaCodecReader::CreateMediaCodecs()
|
||||
{
|
||||
if (CreateMediaCodec(mLooper, mAudioTrack, false, nullptr) &&
|
||||
CreateMediaCodec(mLooper, mVideoTrack, true, mVideoListener)) {
|
||||
return true;
|
||||
bool isWaiting = false;
|
||||
nsRefPtr<MediaResourcePromise> p = mMediaResourcePromise.Ensure(__func__);
|
||||
|
||||
if (!CreateMediaCodec(mLooper, mAudioTrack, false, isWaiting, nullptr)) {
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (!CreateMediaCodec(mLooper, mVideoTrack, true, isWaiting, mVideoListener)) {
|
||||
mMediaResourcePromise.Reject(true, __func__);
|
||||
return p;
|
||||
}
|
||||
|
||||
if (!isWaiting) {
|
||||
// No MediaCodec allocation wait.
|
||||
mMediaResourcePromise.Resolve(true, __func__);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaCodecReader::CreateMediaCodec(sp<ALooper>& aLooper,
|
||||
Track& aTrack,
|
||||
bool aAsync,
|
||||
bool& aIsWaiting,
|
||||
wp<MediaCodecProxy::CodecResourceListener> aListener)
|
||||
{
|
||||
if (aTrack.mSource != nullptr && aTrack.mCodec == nullptr) {
|
||||
@ -1351,10 +1363,14 @@ MediaCodecReader::CreateMediaCodec(sp<ALooper>& aLooper,
|
||||
DestroyMediaCodec(aTrack);
|
||||
return false;
|
||||
}
|
||||
} else if (aAsync && !aTrack.mCodec->AsyncAskMediaCodec()) {
|
||||
NS_WARNING("Couldn't request MediaCodec asynchronously");
|
||||
DestroyMediaCodec(aTrack);
|
||||
return false;
|
||||
} else if (aAsync) {
|
||||
if (aTrack.mCodec->AsyncAskMediaCodec()) {
|
||||
aIsWaiting = true;
|
||||
} else {
|
||||
NS_WARNING("Couldn't request MediaCodec asynchronously");
|
||||
DestroyMediaCodec(aTrack);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1919,18 +1935,14 @@ MediaCodecReader::ClearColorConverterBuffer()
|
||||
void
|
||||
MediaCodecReader::VideoCodecReserved()
|
||||
{
|
||||
mDecoder->NotifyWaitingForResourcesStatusChanged();
|
||||
mMediaResourcePromise.ResolveIfExists(true, __func__);
|
||||
}
|
||||
|
||||
// Called on Binder thread.
|
||||
void
|
||||
MediaCodecReader::VideoCodecCanceled()
|
||||
{
|
||||
if (mVideoTrack.mTaskQueue) {
|
||||
RefPtr<nsIRunnable> task =
|
||||
NS_NewRunnableMethod(this, &MediaCodecReader::ReleaseCriticalResources);
|
||||
mVideoTrack.mTaskQueue->Dispatch(task.forget());
|
||||
}
|
||||
mMediaResourcePromise.RejectIfExists(true, __func__);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -52,6 +52,7 @@ class MediaCodecReader : public MediaOmxCommonReader
|
||||
{
|
||||
typedef mozilla::layers::TextureClient TextureClient;
|
||||
typedef mozilla::layers::FenceHandle FenceHandle;
|
||||
typedef MediaOmxCommonReader::MediaResourcePromise MediaResourcePromise;
|
||||
|
||||
public:
|
||||
MediaCodecReader(AbstractMediaDecoder* aDecoder);
|
||||
@ -61,9 +62,6 @@ public:
|
||||
// on failure.
|
||||
virtual nsresult Init(MediaDecoderReader* aCloneDonor);
|
||||
|
||||
// True if this reader is waiting media resource allocation
|
||||
virtual bool IsWaitingMediaResources();
|
||||
|
||||
// True when this reader need to become dormant state
|
||||
virtual bool IsDormantNeeded() { return true;}
|
||||
|
||||
@ -94,13 +92,7 @@ public:
|
||||
virtual bool HasAudio();
|
||||
virtual bool HasVideo();
|
||||
|
||||
virtual void PreReadMetadata() override;
|
||||
// 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);
|
||||
virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata() override;
|
||||
|
||||
// Moves the decode head to aTime microseconds. aStartTime and aEndTime
|
||||
// denote the start and end times of the media in usecs, and aCurrentTime
|
||||
@ -184,14 +176,14 @@ protected:
|
||||
|
||||
virtual bool CreateExtractor();
|
||||
|
||||
// Check the underlying HW resource is available and store the result in
|
||||
// mIsWaitingResources.
|
||||
void UpdateIsWaitingMediaResources();
|
||||
virtual void HandleResourceAllocated();
|
||||
|
||||
android::sp<android::MediaExtractor> mExtractor;
|
||||
// A cache value updated by UpdateIsWaitingMediaResources(), makes the
|
||||
// "waiting resources state" is synchronous to StateMachine.
|
||||
bool mIsWaitingResources;
|
||||
|
||||
MediaPromiseHolder<MediaDecoderReader::MetadataPromise> mMetadataPromise;
|
||||
// XXX Remove after bug 1168008 land.
|
||||
MediaPromiseConsumerHolder<MediaResourcePromise> mMediaResourceRequest;
|
||||
MediaPromiseHolder<MediaResourcePromise> mMediaResourcePromise;
|
||||
|
||||
private:
|
||||
|
||||
@ -339,7 +331,7 @@ private:
|
||||
MediaCodecReader() = delete;
|
||||
const MediaCodecReader& operator=(const MediaCodecReader& rhs) = delete;
|
||||
|
||||
bool ReallocateResources();
|
||||
bool ReallocateExtractorResources();
|
||||
void ReleaseCriticalResources();
|
||||
void ReleaseResources();
|
||||
|
||||
@ -351,10 +343,11 @@ private:
|
||||
bool CreateMediaSources();
|
||||
void DestroyMediaSources();
|
||||
|
||||
bool CreateMediaCodecs();
|
||||
nsRefPtr<MediaResourcePromise> CreateMediaCodecs();
|
||||
static bool CreateMediaCodec(android::sp<android::ALooper>& aLooper,
|
||||
Track& aTrack,
|
||||
bool aAsync,
|
||||
bool& aIsWaiting,
|
||||
android::wp<android::MediaCodecProxy::CodecResourceListener> aListener);
|
||||
static bool ConfigureMediaCodec(Track& aTrack);
|
||||
void DestroyMediaCodecs();
|
||||
|
@ -88,20 +88,28 @@ RtspMediaCodecReader::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
return MediaCodecReader::RequestVideoData(aSkipToNextKeyframe, aTimeThreshold);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RtspMediaCodecReader::ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags)
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise>
|
||||
RtspMediaCodecReader::AsyncReadMetadata()
|
||||
{
|
||||
mRtspResource->DisablePlayoutDelay();
|
||||
EnsureActive();
|
||||
nsresult rv = MediaCodecReader::ReadMetadata(aInfo, aTags);
|
||||
|
||||
nsRefPtr<MediaDecoderReader::MetadataPromise> p =
|
||||
MediaCodecReader::AsyncReadMetadata();
|
||||
|
||||
// Send a PAUSE to the RTSP server because the underlying media resource is
|
||||
// not ready.
|
||||
SetIdle();
|
||||
|
||||
if (rv == NS_OK && !IsWaitingMediaResources()) {
|
||||
mRtspResource->EnablePlayoutDelay();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
return rv;
|
||||
void
|
||||
RtspMediaCodecReader::HandleResourceAllocated()
|
||||
{
|
||||
EnsureActive();
|
||||
MediaCodecReader::HandleResourceAllocated();
|
||||
mRtspResource->EnablePlayoutDelay();;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -58,8 +58,10 @@ public:
|
||||
// Disptach a DecodeAudioDataTask to decode audio data.
|
||||
virtual nsRefPtr<AudioDataPromise> RequestAudioData() override;
|
||||
|
||||
virtual nsresult ReadMetadata(MediaInfo* aInfo,
|
||||
MetadataTags** aTags) override;
|
||||
virtual nsRefPtr<MediaDecoderReader::MetadataPromise> AsyncReadMetadata()
|
||||
override;
|
||||
|
||||
virtual void HandleResourceAllocated() override;
|
||||
|
||||
private:
|
||||
// A pointer to RtspMediaResource for calling the Rtsp specific function.
|
||||
|
Loading…
Reference in New Issue
Block a user