| /* |
| * 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 |