1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "SimpleC2Interface"
19 #include <utils/Log.h>
20 
21 // use MediaDefs here vs. MediaCodecConstants as this is not MediaCodec specific/dependent
22 #include <media/stagefright/foundation/MediaDefs.h>
23 
24 #include <C2PlatformSupport.h>
25 #include <SimpleC2Interface.h>
26 
27 namespace android {
28 
29 /* SimpleInterface */
30 
BaseParams(const std::shared_ptr<C2ReflectorHelper> & reflector,C2String name,C2Component::kind_t kind,C2Component::domain_t domain,C2String mediaType,std::vector<C2String> aliases)31 SimpleInterface<void>::BaseParams::BaseParams(
32         const std::shared_ptr<C2ReflectorHelper> &reflector,
33         C2String name,
34         C2Component::kind_t kind,
35         C2Component::domain_t domain,
36         C2String mediaType,
37         std::vector<C2String> aliases)
38     : C2InterfaceHelper(reflector) {
39     setDerivedInstance(this);
40 
41     addParameter(
42             DefineParam(mApiFeatures, C2_PARAMKEY_API_FEATURES)
43             .withConstValue(new C2ApiFeaturesSetting(C2Config::api_feature_t(
44                     API_REFLECTION |
45                     API_VALUES |
46                     API_CURRENT_VALUES |
47                     API_DEPENDENCY |
48                     API_SAME_INPUT_BUFFER)))
49             .build());
50 
51     addParameter(
52             DefineParam(mName, C2_PARAMKEY_COMPONENT_NAME)
53             .withConstValue(AllocSharedString<C2ComponentNameSetting>(name.c_str()))
54             .build());
55 
56     if (aliases.size()) {
57         C2String joined;
58         for (const C2String &alias : aliases) {
59             if (joined.length()) {
60                 joined += ",";
61             }
62             joined += alias;
63         }
64         addParameter(
65                 DefineParam(mAliases, C2_PARAMKEY_COMPONENT_ALIASES)
66                 .withConstValue(AllocSharedString<C2ComponentAliasesSetting>(joined.c_str()))
67                 .build());
68     }
69 
70     addParameter(
71             DefineParam(mKind, C2_PARAMKEY_COMPONENT_KIND)
72             .withConstValue(new C2ComponentKindSetting(kind))
73             .build());
74 
75     addParameter(
76             DefineParam(mDomain, C2_PARAMKEY_COMPONENT_DOMAIN)
77             .withConstValue(new C2ComponentDomainSetting(domain))
78             .build());
79 
80     // simple interfaces have single streams
81     addParameter(
82             DefineParam(mInputStreamCount, C2_PARAMKEY_INPUT_STREAM_COUNT)
83             .withConstValue(new C2PortStreamCountTuning::input(1))
84             .build());
85 
86     addParameter(
87             DefineParam(mOutputStreamCount, C2_PARAMKEY_OUTPUT_STREAM_COUNT)
88             .withConstValue(new C2PortStreamCountTuning::output(1))
89             .build());
90 
91     // set up buffer formats and allocators
92 
93     // default to linear buffers and no media type
94     C2BufferData::type_t rawBufferType = C2BufferData::LINEAR;
95     C2String rawMediaType;
96     C2Allocator::id_t rawAllocator = C2AllocatorStore::DEFAULT_LINEAR;
97     C2BlockPool::local_id_t rawPoolId = C2BlockPool::BASIC_LINEAR;
98     C2BufferData::type_t codedBufferType = C2BufferData::LINEAR;
99     int poolMask = GetCodec2PoolMask();
100     C2Allocator::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask);
101     C2Allocator::id_t codedAllocator = preferredLinearId;
102     C2BlockPool::local_id_t codedPoolId = C2BlockPool::BASIC_LINEAR;
103 
104     switch (domain) {
105         case C2Component::DOMAIN_IMAGE: [[fallthrough]];
106         case C2Component::DOMAIN_VIDEO:
107             // TODO: should we define raw image? The only difference is timestamp handling
108             rawBufferType = C2BufferData::GRAPHIC;
109             rawMediaType = MEDIA_MIMETYPE_VIDEO_RAW;
110             rawAllocator = C2PlatformAllocatorStore::GRALLOC;
111             rawPoolId = C2BlockPool::BASIC_GRAPHIC;
112             break;
113         case C2Component::DOMAIN_AUDIO:
114             rawBufferType = C2BufferData::LINEAR;
115             rawMediaType = MEDIA_MIMETYPE_AUDIO_RAW;
116             rawAllocator = preferredLinearId;
117             rawPoolId = C2BlockPool::BASIC_LINEAR;
118             break;
119         default:
120             break;
121     }
122     bool isEncoder = kind == C2Component::KIND_ENCODER;
123 
124     // handle raw decoders
125     if (mediaType == rawMediaType) {
126         codedBufferType = rawBufferType;
127         codedAllocator = rawAllocator;
128         codedPoolId = rawPoolId;
129     }
130 
131     addParameter(
132             DefineParam(mInputFormat, C2_PARAMKEY_INPUT_STREAM_BUFFER_TYPE)
133             .withConstValue(new C2StreamBufferTypeSetting::input(
134                     0u, isEncoder ? rawBufferType : codedBufferType))
135             .build());
136 
137     addParameter(
138             DefineParam(mInputMediaType, C2_PARAMKEY_INPUT_MEDIA_TYPE)
139             .withConstValue(AllocSharedString<C2PortMediaTypeSetting::input>(
140                     isEncoder ? rawMediaType : mediaType))
141             .build());
142 
143     addParameter(
144             DefineParam(mOutputFormat, C2_PARAMKEY_OUTPUT_STREAM_BUFFER_TYPE)
145             .withConstValue(new C2StreamBufferTypeSetting::output(
146                     0u, isEncoder ? codedBufferType : rawBufferType))
147             .build());
148 
149     addParameter(
150             DefineParam(mOutputMediaType, C2_PARAMKEY_OUTPUT_MEDIA_TYPE)
151             .withConstValue(AllocSharedString<C2PortMediaTypeSetting::output>(
152                     isEncoder ? mediaType : rawMediaType))
153             .build());
154 
155     C2Allocator::id_t inputAllocators[1] = { isEncoder ? rawAllocator : codedAllocator };
156     C2Allocator::id_t outputAllocators[1] = { isEncoder ? codedAllocator : rawAllocator };
157     C2BlockPool::local_id_t outputPoolIds[1] = { isEncoder ? codedPoolId : rawPoolId };
158 
159     addParameter(
160             DefineParam(mInputAllocators, C2_PARAMKEY_INPUT_ALLOCATORS)
161             .withDefault(C2PortAllocatorsTuning::input::AllocShared(inputAllocators))
162             .withFields({ C2F(mInputAllocators, m.values[0]).any(),
163                           C2F(mInputAllocators, m.values).inRange(0, 1) })
164             .withSetter(Setter<C2PortAllocatorsTuning::input>::NonStrictValuesWithNoDeps)
165             .build());
166 
167     addParameter(
168             DefineParam(mOutputAllocators, C2_PARAMKEY_OUTPUT_ALLOCATORS)
169             .withDefault(C2PortAllocatorsTuning::output::AllocShared(outputAllocators))
170             .withFields({ C2F(mOutputAllocators, m.values[0]).any(),
171                           C2F(mOutputAllocators, m.values).inRange(0, 1) })
172             .withSetter(Setter<C2PortAllocatorsTuning::output>::NonStrictValuesWithNoDeps)
173             .build());
174 
175     addParameter(
176             DefineParam(mOutputPoolIds, C2_PARAMKEY_OUTPUT_BLOCK_POOLS)
177             .withDefault(C2PortBlockPoolsTuning::output::AllocShared(outputPoolIds))
178             .withFields({ C2F(mOutputPoolIds, m.values[0]).any(),
179                           C2F(mOutputPoolIds, m.values).inRange(0, 1) })
180             .withSetter(Setter<C2PortBlockPoolsTuning::output>::NonStrictValuesWithNoDeps)
181             .build());
182 
183     // add stateless params
184     addParameter(
185             DefineParam(mSubscribedParamIndices, C2_PARAMKEY_SUBSCRIBED_PARAM_INDICES)
186             .withDefault(C2SubscribedParamIndicesTuning::AllocShared(0u))
187             .withFields({ C2F(mSubscribedParamIndices, m.values[0]).any(),
188                           C2F(mSubscribedParamIndices, m.values).any() })
189             .withSetter(Setter<C2SubscribedParamIndicesTuning>::NonStrictValuesWithNoDeps)
190             .build());
191 
192     /* TODO
193 
194     addParameter(
195             DefineParam(mCurrentWorkOrdinal, C2_PARAMKEY_CURRENT_WORK)
196             .withDefault(new C2CurrentWorkTuning())
197             .withFields({ C2F(mCurrentWorkOrdinal, m.timeStamp).any(),
198                           C2F(mCurrentWorkOrdinal, m.frameIndex).any(),
199                           C2F(mCurrentWorkOrdinal, m.customOrdinal).any() })
200             .withSetter(Setter<C2CurrentWorkTuning>::NonStrictValuesWithNoDeps)
201             .build());
202 
203     addParameter(
204             DefineParam(mLastInputQueuedWorkOrdinal, C2_PARAMKEY_LAST_INPUT_QUEUED)
205             .withDefault(new C2LastWorkQueuedTuning::input())
206             .withFields({ C2F(mLastInputQueuedWorkOrdinal, m.timeStamp).any(),
207                           C2F(mLastInputQueuedWorkOrdinal, m.frameIndex).any(),
208                           C2F(mLastInputQueuedWorkOrdinal, m.customOrdinal).any() })
209             .withSetter(Setter<C2LastWorkQueuedTuning::input>::NonStrictValuesWithNoDeps)
210             .build());
211 
212     addParameter(
213             DefineParam(mLastOutputQueuedWorkOrdinal, C2_PARAMKEY_LAST_OUTPUT_QUEUED)
214             .withDefault(new C2LastWorkQueuedTuning::output())
215             .withFields({ C2F(mLastOutputQueuedWorkOrdinal, m.timeStamp).any(),
216                           C2F(mLastOutputQueuedWorkOrdinal, m.frameIndex).any(),
217                           C2F(mLastOutputQueuedWorkOrdinal, m.customOrdinal).any() })
218             .withSetter(Setter<C2LastWorkQueuedTuning::output>::NonStrictValuesWithNoDeps)
219             .build());
220 
221     std::shared_ptr<C2OutOfMemoryTuning> mOutOfMemory;
222 
223     std::shared_ptr<C2PortConfigCounterTuning::input> mInputConfigCounter;
224     std::shared_ptr<C2PortConfigCounterTuning::output> mOutputConfigCounter;
225     std::shared_ptr<C2ConfigCounterTuning> mDirectConfigCounter;
226 
227     */
228 }
229 
noInputLatency()230 void SimpleInterface<void>::BaseParams::noInputLatency() {
231     addParameter(
232             DefineParam(mRequestedInputDelay, C2_PARAMKEY_INPUT_DELAY_REQUEST)
233             .withConstValue(new C2PortRequestedDelayTuning::input(0u))
234             .build());
235 
236     addParameter(
237             DefineParam(mActualInputDelay, C2_PARAMKEY_INPUT_DELAY)
238             .withConstValue(new C2PortActualDelayTuning::input(0u))
239             .build());
240 }
241 
noOutputLatency()242 void SimpleInterface<void>::BaseParams::noOutputLatency() {
243     addParameter(
244             DefineParam(mRequestedOutputDelay, C2_PARAMKEY_OUTPUT_DELAY_REQUEST)
245             .withConstValue(new C2PortRequestedDelayTuning::output(0u))
246             .build());
247 
248     addParameter(
249             DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
250             .withConstValue(new C2PortActualDelayTuning::output(0u))
251             .build());
252 }
253 
noPipelineLatency()254 void SimpleInterface<void>::BaseParams::noPipelineLatency() {
255     addParameter(
256             DefineParam(mRequestedPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY_REQUEST)
257             .withConstValue(new C2RequestedPipelineDelayTuning(0u))
258             .build());
259 
260     addParameter(
261             DefineParam(mActualPipelineDelay, C2_PARAMKEY_PIPELINE_DELAY)
262             .withConstValue(new C2ActualPipelineDelayTuning(0u))
263             .build());
264 }
265 
noPrivateBuffers()266 void SimpleInterface<void>::BaseParams::noPrivateBuffers() {
267     addParameter(
268             DefineParam(mPrivateAllocators, C2_PARAMKEY_PRIVATE_ALLOCATORS)
269             .withConstValue(C2PrivateAllocatorsTuning::AllocShared(0u))
270             .build());
271 
272     addParameter(
273             DefineParam(mMaxPrivateBufferCount, C2_PARAMKEY_MAX_PRIVATE_BUFFER_COUNT)
274             .withConstValue(C2MaxPrivateBufferCountTuning::AllocShared(0u))
275             .build());
276 
277     addParameter(
278             DefineParam(mPrivatePoolIds, C2_PARAMKEY_PRIVATE_BLOCK_POOLS)
279             .withConstValue(C2PrivateBlockPoolsTuning::AllocShared(0u))
280             .build());
281 }
282 
noInputReferences()283 void SimpleInterface<void>::BaseParams::noInputReferences() {
284     addParameter(
285             DefineParam(mMaxInputReferenceAge, C2_PARAMKEY_INPUT_MAX_REFERENCE_AGE)
286             .withConstValue(new C2StreamMaxReferenceAgeTuning::input(0u))
287             .build());
288 
289     addParameter(
290             DefineParam(mMaxInputReferenceCount, C2_PARAMKEY_INPUT_MAX_REFERENCE_COUNT)
291             .withConstValue(new C2StreamMaxReferenceCountTuning::input(0u))
292             .build());
293 }
294 
noOutputReferences()295 void SimpleInterface<void>::BaseParams::noOutputReferences() {
296     addParameter(
297             DefineParam(mMaxOutputReferenceAge, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_AGE)
298             .withConstValue(new C2StreamMaxReferenceAgeTuning::output(0u))
299             .build());
300 
301     addParameter(
302             DefineParam(mMaxOutputReferenceCount, C2_PARAMKEY_OUTPUT_MAX_REFERENCE_COUNT)
303             .withConstValue(new C2StreamMaxReferenceCountTuning::output(0u))
304             .build());
305 }
306 
noTimeStretch()307 void SimpleInterface<void>::BaseParams::noTimeStretch() {
308     addParameter(
309             DefineParam(mTimeStretch, C2_PARAMKEY_TIME_STRETCH)
310             .withConstValue(new C2ComponentTimeStretchTuning(1.f))
311             .build());
312 }
313 
314 /*
315     Clients need to handle the following base params due to custom dependency.
316 
317     std::shared_ptr<C2ApiLevelSetting> mApiLevel;
318     std::shared_ptr<C2ComponentAttributesSetting> mAttrib;
319 
320     std::shared_ptr<C2PortSuggestedBufferCountTuning::input> mSuggestedInputBufferCount;
321     std::shared_ptr<C2PortSuggestedBufferCountTuning::output> mSuggestedOutputBufferCount;
322 
323     std::shared_ptr<C2TrippedTuning> mTripped;
324 
325 */
326 
327 } // namespace android
328