RefPtr<MediaDataDecoder::InitPromise> GonkVideoDecoderManager::Init() { nsIntSize displaySize(mDisplayWidth, mDisplayHeight); nsIntRect pictureRect(0, 0, mVideoWidth, mVideoHeight); uint32_t maxWidth, maxHeight; char propValue[PROPERTY_VALUE_MAX]; property_get("ro.moz.omx.hw.max_width", propValue, "-1"); maxWidth = -1 == atoi(propValue) ? MAX_VIDEO_WIDTH : atoi(propValue); property_get("ro.moz.omx.hw.max_height", propValue, "-1"); maxHeight = -1 == atoi(propValue) ? MAX_VIDEO_HEIGHT : atoi(propValue) ; if (mVideoWidth * mVideoHeight > maxWidth * maxHeight) { GVDM_LOG("Video resolution exceeds hw codec capability"); return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__); } // Validate the container-reported frame and pictureRect sizes. This ensures // that our video frame creation code doesn't overflow. nsIntSize frameSize(mVideoWidth, mVideoHeight); if (!IsValidVideoRegion(frameSize, pictureRect, displaySize)) { GVDM_LOG("It is not a valid region"); return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__); } mReaderTaskQueue = AbstractThread::GetCurrent()->AsTaskQueue(); MOZ_ASSERT(mReaderTaskQueue); if (mDecodeLooper.get() != nullptr) { return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__); } if (!InitLoopers(MediaData::VIDEO_DATA)) { return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__); } RefPtr<InitPromise> p = mInitPromise.Ensure(__func__); android::sp<GonkVideoDecoderManager> self = this; mVideoCodecRequest.Begin(mVideoListener->Init() ->Then(mReaderTaskQueue, __func__, [self] (bool) -> void { self->mVideoCodecRequest.Complete(); self->codecReserved(); }, [self] (bool) -> void { self->mVideoCodecRequest.Complete(); self->codecCanceled(); })); mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper, mMimeType.get(), false, mVideoListener); mDecoder->AsyncAskMediaCodec(); uint32_t capability = MediaCodecProxy::kEmptyCapability; if (mDecoder->getCapability(&capability) == OK && (capability & MediaCodecProxy::kCanExposeGraphicBuffer)) { mNativeWindow = new GonkNativeWindow(); } return p; }
bool GonkAudioDecoderManager::InitMediaCodecProxy() { status_t rv = OK; if (!InitLoopers(MediaData::AUDIO_DATA)) { return false; } mDecoder = MediaCodecProxy::CreateByType(mDecodeLooper, mMimeType.get(), false); if (!mDecoder.get()) { return false; } if (!mDecoder->AllocateAudioMediaCodec()) { mDecoder = nullptr; return false; } sp<AMessage> format = new AMessage; // Fixed values GADM_LOG("Configure audio mime type:%s, chan no:%d, sample-rate:%d, profile:%d", mMimeType.get(), mAudioChannels, mAudioRate, mAudioProfile); format->setString("mime", mMimeType.get()); format->setInt32("channel-count", mAudioChannels); format->setInt32("sample-rate", mAudioRate); format->setInt32("aac-profile", mAudioProfile); status_t err = mDecoder->configure(format, nullptr, nullptr, 0); if (err != OK || !mDecoder->Prepare()) { return false; } if (mMimeType.EqualsLiteral("audio/mp4a-latm")) { rv = mDecoder->Input(mCodecSpecificData->Elements(), mCodecSpecificData->Length(), 0, android::MediaCodec::BUFFER_FLAG_CODECCONFIG, CODECCONFIG_TIMEOUT_US); } if (rv == OK) { return true; } else { GADM_LOG("Failed to input codec specific data!"); return false; } }