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