|  | /* | 
|  | * Copyright (C) 2017 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | //#define LOG_NDEBUG 0 | 
|  | #define LOG_TAG "SimpleC2Interface" | 
|  | #include <utils/Log.h> | 
|  |  | 
|  | // use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent | 
|  | #include <media/stagefright/foundation/MediaDefs.h> | 
|  |  | 
|  | #include <C2PlatformSupport.h> | 
|  | #include <SimpleC2Interface.h> | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | /* SimpleInterface */ | 
|  |  | 
|  | static C2R SubscribedParamIndicesSetter( | 
|  | bool mayBlock, C2InterfaceHelper::C2P<C2SubscribedParamIndicesTuning> &me) { | 
|  | (void)mayBlock; | 
|  | (void)me; | 
|  |  | 
|  | return C2R::Ok(); | 
|  | } | 
|  |  | 
|  | SimpleInterface<void>::BaseParams::BaseParams( | 
|  | const std::shared_ptr<C2ReflectorHelper> &reflector, | 
|  | C2String name, | 
|  | C2Component::kind_t kind, | 
|  | C2Component::domain_t domain, | 
|  | C2String mediaType, | 
|  | std::vector<C2String> aliases) | 
|  | : C2InterfaceHelper(reflector) { | 
|  | setDerivedInstance(this); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mApiFeatures, C2_PARAMKEY_API_FEATURES) | 
|  | .withConstValue(new C2ApiFeaturesSetting(C2Config::api_feature_t( | 
|  | API_REFLECTION | | 
|  | API_VALUES | | 
|  | API_CURRENT_VALUES | | 
|  | API_DEPENDENCY | | 
|  | API_SAME_INPUT_BUFFER))) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME) | 
|  | .withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str())) | 
|  | .build()); | 
|  |  | 
|  | if (aliases.size()) { | 
|  | C2String joined; | 
|  | for (const C2String &alias : aliases) { | 
|  | if (joined.length()) { | 
|  | joined += ","; | 
|  | } | 
|  | joined += alias; | 
|  | } | 
|  | addParameter( | 
|  | DefineParam(mAliases, C2_PARAMKEY_COMPONENT_ALIASES) | 
|  | .withConstValue(AllocSharedString<C2ComponentAliasesSetting>(joined.c_str())) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND) | 
|  | .withConstValue(new C2ComponentKindSetting(kind)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN) | 
|  | .withConstValue(new C2ComponentDomainSetting(domain)) | 
|  | .build()); | 
|  |  | 
|  | // simple interfaces have single streams | 
|  | addParameter( | 
|  | DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT) | 
|  | .withConstValue(new C2PortStreamCountTuning::input(1)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT) | 
|  | .withConstValue(new C2PortStreamCountTuning::output(1)) | 
|  | .build()); | 
|  |  | 
|  | // set up buffer formats and allocators | 
|  |  | 
|  | // default to linear buffers and no media type | 
|  | C2BufferData::type_t rawBufferType = C2BufferData::LINEAR; | 
|  | C2String rawMediaType; | 
|  | C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR; | 
|  | C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR; | 
|  | C2BufferData::type_t codedBufferType = C2BufferData::LINEAR; | 
|  | int poolMask = GetCodec2PoolMask(); | 
|  | C2Allocator::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask); | 
|  | C2Allocator::id_t codedAllocator = preferredLinearId; | 
|  | C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR; | 
|  |  | 
|  | switch (domain) { | 
|  | case C2Component::DOMAIN_IMAGE: [[fallthrough]]; | 
|  | case C2Component::DOMAIN_VIDEO: | 
|  | // TODO: should we define raw image? The only difference is timestamp handling | 
|  | rawBufferType = C2BufferData::GRAPHIC; | 
|  | rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW; | 
|  | rawAllocator = C2PlatformAllocatorStore::GRALLOC; | 
|  | rawPoolId = C2BlockPool::BASIC_GRAPHIC; | 
|  | break; | 
|  | case C2Component::DOMAIN_AUDIO: | 
|  | rawBufferType = C2BufferData::LINEAR; | 
|  | rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW; | 
|  | rawAllocator = preferredLinearId; | 
|  | rawPoolId = C2BlockPool::BASIC_LINEAR; | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | bool isEncoder = kind == C2Component::KIND_ENCODER; | 
|  |  | 
|  | // handle raw decoders | 
|  | if (mediaType == rawMediaType) { | 
|  | codedBufferType = rawBufferType; | 
|  | codedAllocator = rawAllocator; | 
|  | codedPoolId = rawPoolId; | 
|  | } | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE) | 
|  | .withConstValue(new C2StreamBufferTypeSetting::input( | 
|  | 0u, isEncoder ? rawBufferType : codedBufferType)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE) | 
|  | .withConstValue(AllocSharedString<C2PortMediaTypeSetting::input>( | 
|  | isEncoder ? rawMediaType : mediaType)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mOutputFormat, C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE) | 
|  | .withConstValue(new C2StreamBufferTypeSetting::output( | 
|  | 0u, isEncoder ? codedBufferType : rawBufferType)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE) | 
|  | .withConstValue(AllocSharedString<C2PortMediaTypeSetting::output>( | 
|  | isEncoder ? mediaType : rawMediaType)) | 
|  | .build()); | 
|  |  | 
|  | C2Allocator::id_t inputAllocators[1] = { isEncoder ? rawAllocator : codedAllocator }; | 
|  | C2Allocator::id_t outputAllocators[1] = { isEncoder ? codedAllocator : rawAllocator }; | 
|  | C2BlockPool::local_id_t outputPoolIds[1] = { isEncoder ? codedPoolId : rawPoolId }; | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mInputAllocators, C2_PARAMKEY_INPUT_ALLOCATORS) | 
|  | .withDefault(C2PortAllocatorsTuning::input::AllocShared(inputAllocators)) | 
|  | .withFields({ C2F(mInputAllocators, m.values[0]).any(), | 
|  | C2F(mInputAllocators, m.values).inRange(0, 1) }) | 
|  | .withSetter(Setter<C2PortAllocatorsTuning::input>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mOutputAllocators, C2_PARAMKEY_OUTPUT_ALLOCATORS) | 
|  | .withDefault(C2PortAllocatorsTuning::output::AllocShared(outputAllocators)) | 
|  | .withFields({ C2F(mOutputAllocators, m.values[0]).any(), | 
|  | C2F(mOutputAllocators, m.values).inRange(0, 1) }) | 
|  | .withSetter(Setter<C2PortAllocatorsTuning::output>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mOutputPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS) | 
|  | .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputPoolIds)) | 
|  | .withFields({ C2F(mOutputPoolIds, m.values[0]).any(), | 
|  | C2F(mOutputPoolIds, m.values).inRange(0, 1) }) | 
|  | .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | // add stateless params | 
|  | addParameter( | 
|  | DefineParam(mSubscribedParamIndices, C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES) | 
|  | .withDefault(C2SubscribedParamIndicesTuning::AllocShared(0u)) | 
|  | .withFields({ C2F(mSubscribedParamIndices, m.values[0]).any(), | 
|  | C2F(mSubscribedParamIndices, m.values).any() }) | 
|  | .withSetter(SubscribedParamIndicesSetter) | 
|  | .build()); | 
|  |  | 
|  | /* TODO | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mCurrentWorkOrdinal, C2_PARAMKEY_CURRENT_WORK) | 
|  | .withDefault(new C2CurrentWorkTuning()) | 
|  | .withFields({ C2F(mCurrentWorkOrdinal, m.timeStamp).any(), | 
|  | C2F(mCurrentWorkOrdinal, m.frameIndex).any(), | 
|  | C2F(mCurrentWorkOrdinal, m.customOrdinal).any() }) | 
|  | .withSetter(Setter<C2CurrentWorkTuning>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mLastInputQueuedWorkOrdinal, C2_PARAMKEY_LAST_INPUT_QUEUED) | 
|  | .withDefault(new C2LastWorkQueuedTuning::input()) | 
|  | .withFields({ C2F(mLastInputQueuedWorkOrdinal, m.timeStamp).any(), | 
|  | C2F(mLastInputQueuedWorkOrdinal, m.frameIndex).any(), | 
|  | C2F(mLastInputQueuedWorkOrdinal, m.customOrdinal).any() }) | 
|  | .withSetter(Setter<C2LastWorkQueuedTuning::input>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mLastOutputQueuedWorkOrdinal, C2_PARAMKEY_LAST_OUTPUT_QUEUED) | 
|  | .withDefault(new C2LastWorkQueuedTuning::output()) | 
|  | .withFields({ C2F(mLastOutputQueuedWorkOrdinal, m.timeStamp).any(), | 
|  | C2F(mLastOutputQueuedWorkOrdinal, m.frameIndex).any(), | 
|  | C2F(mLastOutputQueuedWorkOrdinal, m.customOrdinal).any() }) | 
|  | .withSetter(Setter<C2LastWorkQueuedTuning::output>::NonStrictValuesWithNoDeps) | 
|  | .build()); | 
|  |  | 
|  | std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory; | 
|  |  | 
|  | std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter; | 
|  | std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter; | 
|  | std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter; | 
|  |  | 
|  | */ | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noInputLatency() { | 
|  | addParameter( | 
|  | DefineParam(mRequestedInputDelay, C2_PARAMKEY_INPUT_DELAY_REQUEST) | 
|  | .withConstValue(new C2PortRequestedDelayTuning::input(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY) | 
|  | .withConstValue(new C2PortActualDelayTuning::input(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noOutputLatency() { | 
|  | addParameter( | 
|  | DefineParam(mRequestedOutputDelay, C2_PARAMKEY_OUTPUT_DELAY_REQUEST) | 
|  | .withConstValue(new C2PortRequestedDelayTuning::output(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY) | 
|  | .withConstValue(new C2PortActualDelayTuning::output(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noPipelineLatency() { | 
|  | addParameter( | 
|  | DefineParam(mRequestedPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY_REQUEST) | 
|  | .withConstValue(new C2RequestedPipelineDelayTuning(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mActualPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY) | 
|  | .withConstValue(new C2ActualPipelineDelayTuning(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noPrivateBuffers() { | 
|  | addParameter( | 
|  | DefineParam(mPrivateAllocators, C2_PARAMKEY_PRIVATE_ALLOCATORS) | 
|  | .withConstValue(C2PrivateAllocatorsTuning::AllocShared(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mMaxPrivateBufferCount, C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT) | 
|  | .withConstValue(C2MaxPrivateBufferCountTuning::AllocShared(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mPrivatePoolIds, C2_PARAMKEY_PRIVATE_BLOCK_POOLS) | 
|  | .withConstValue(C2PrivateBlockPoolsTuning::AllocShared(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noInputReferences() { | 
|  | addParameter( | 
|  | DefineParam(mMaxInputReferenceAge, C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE) | 
|  | .withConstValue(new C2StreamMaxReferenceAgeTuning::input(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mMaxInputReferenceCount, C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT) | 
|  | .withConstValue(new C2StreamMaxReferenceCountTuning::input(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noOutputReferences() { | 
|  | addParameter( | 
|  | DefineParam(mMaxOutputReferenceAge, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE) | 
|  | .withConstValue(new C2StreamMaxReferenceAgeTuning::output(0u)) | 
|  | .build()); | 
|  |  | 
|  | addParameter( | 
|  | DefineParam(mMaxOutputReferenceCount, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT) | 
|  | .withConstValue(new C2StreamMaxReferenceCountTuning::output(0u)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | void SimpleInterface<void>::BaseParams::noTimeStretch() { | 
|  | addParameter( | 
|  | DefineParam(mTimeStretch, C2_PARAMKEY_TIME_STRETCH) | 
|  | .withConstValue(new C2ComponentTimeStretchTuning(1.f)) | 
|  | .build()); | 
|  | } | 
|  |  | 
|  | /* | 
|  | Clients need to handle the following base params due to custom dependency. | 
|  |  | 
|  | std::shared_ptr<C2ApiLevelSetting> mApiLevel; | 
|  | std::shared_ptr<C2ComponentAttributesSetting> mAttrib; | 
|  |  | 
|  | std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount; | 
|  | std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount; | 
|  |  | 
|  | std::shared_ptr<C2TrippedTuning> mTripped; | 
|  |  | 
|  | */ | 
|  |  | 
|  | } // namespace android |