1 /*
2 * Copyright (C) 2011 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 /* StreamInformation implementation */
18
19 #include "sles_allinclusive.h"
20
IStreamInformation_QueryMediaContainerInformation(XAStreamInformationItf self,XAMediaContainerInformation * info)21 static XAresult IStreamInformation_QueryMediaContainerInformation( XAStreamInformationItf self,
22 XAMediaContainerInformation * info /* [out] */)
23 {
24 XA_ENTER_INTERFACE
25
26 if (NULL == info) {
27 result = XA_RESULT_PARAMETER_INVALID;
28 XA_LEAVE_INTERFACE
29 }
30
31 #ifdef ANDROID
32 IStreamInformation *thiz = (IStreamInformation *) self;
33 interface_lock_shared(thiz);
34 // always storing container info at index 0, as per spec
35 *info = thiz->mStreamInfoTable.itemAt(0).containerInfo;
36 interface_unlock_shared(thiz);
37 // even though the pointer to the media container info is returned, the values aren't set
38 // for the actual container in this version, they are simply initialized to defaults
39 // (see IStreamInformation_init)
40 result = XA_RESULT_SUCCESS;
41 #else
42 SL_LOGE("QueryMediaContainerInformation is unsupported");
43 memset(info, 0, sizeof(XAMediaContainerInformation));
44 result = XA_RESULT_FEATURE_UNSUPPORTED;
45 #endif
46
47 XA_LEAVE_INTERFACE
48 }
49
50
IStreamInformation_QueryStreamType(XAStreamInformationItf self,XAuint32 streamIndex,XAuint32 * domain)51 static XAresult IStreamInformation_QueryStreamType( XAStreamInformationItf self,
52 XAuint32 streamIndex, /* [in] */
53 XAuint32 *domain) /* [out] */
54 {
55 XA_ENTER_INTERFACE
56
57 if (NULL == domain) {
58 result = XA_RESULT_PARAMETER_INVALID;
59 XA_LEAVE_INTERFACE;
60 }
61
62 #ifndef ANDROID
63 *domain = XA_DOMAINTYPE_UNKNOWN;
64 #else
65 if (0 == streamIndex) {
66 // stream 0 is reserved for the container
67 result = XA_RESULT_PARAMETER_INVALID;
68 *domain = XA_DOMAINTYPE_UNKNOWN;
69 } else {
70 IStreamInformation *thiz = (IStreamInformation *) self;
71
72 interface_lock_shared(thiz);
73
74 XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
75 // streams in the container are numbered 1..nbStreams
76 if (streamIndex <= nbStreams) {
77 result = XA_RESULT_SUCCESS;
78 *domain = thiz->mStreamInfoTable.itemAt(streamIndex).domain;
79 } else {
80 SL_LOGE("Querying stream type for stream %d, only %d streams available",
81 streamIndex, nbStreams);
82 result = XA_RESULT_PARAMETER_INVALID;
83 }
84
85 interface_unlock_shared(thiz);
86 }
87 #endif
88
89 XA_LEAVE_INTERFACE
90 }
91
92
IStreamInformation_QueryStreamInformation(XAStreamInformationItf self,XAuint32 streamIndex,void * info)93 static XAresult IStreamInformation_QueryStreamInformation( XAStreamInformationItf self,
94 XAuint32 streamIndex, /* [in] */
95 void * info) /* [out] */
96 {
97 XA_ENTER_INTERFACE
98
99 if (NULL == info) {
100 result = XA_RESULT_PARAMETER_INVALID;
101 } else {
102
103 #ifndef ANDROID
104 result = XA_RESULT_FEATURE_UNSUPPORTED;
105 #else
106
107 IStreamInformation *thiz = (IStreamInformation *) self;
108
109 interface_lock_shared(thiz);
110
111 XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
112 // stream 0 is the container, and other streams in the container are numbered 1..nbStreams
113 if (streamIndex <= nbStreams) {
114 result = XA_RESULT_SUCCESS;
115 const StreamInfo& streamInfo = thiz->mStreamInfoTable.itemAt((size_t)streamIndex);
116
117 switch (streamInfo.domain) {
118 case XA_DOMAINTYPE_CONTAINER:
119 *(XAMediaContainerInformation *)info = streamInfo.containerInfo;
120 break;
121 case XA_DOMAINTYPE_AUDIO:
122 *(XAAudioStreamInformation *)info = streamInfo.audioInfo;
123 break;
124 case XA_DOMAINTYPE_VIDEO:
125 *(XAVideoStreamInformation *)info = streamInfo.videoInfo;
126 break;
127 case XA_DOMAINTYPE_IMAGE:
128 *(XAImageStreamInformation *)info = streamInfo.imageInfo;
129 break;
130 case XA_DOMAINTYPE_TIMEDTEXT:
131 *(XATimedTextStreamInformation *)info = streamInfo.textInfo;
132 break;
133 case XA_DOMAINTYPE_MIDI:
134 *(XAMIDIStreamInformation *)info = streamInfo.midiInfo;
135 break;
136 case XA_DOMAINTYPE_VENDOR:
137 *(XAVendorStreamInformation *)info = streamInfo.vendorInfo;
138 break;
139 default:
140 SL_LOGE("StreamInformation::QueryStreamInformation index %u has "
141 "unknown domain %u", streamIndex, streamInfo.domain);
142 result = XA_RESULT_INTERNAL_ERROR;
143 break;
144 }
145
146 } else {
147 SL_LOGE("Querying stream type for stream %d, only %d streams available",
148 streamIndex, nbStreams);
149 result = XA_RESULT_PARAMETER_INVALID;
150 }
151
152 interface_unlock_shared(thiz);
153 #endif
154
155 }
156
157 XA_LEAVE_INTERFACE
158 }
159
160
IStreamInformation_QueryStreamName(XAStreamInformationItf self,XAuint32 streamIndex,XAuint16 * pNameSize,XAchar * pName)161 static XAresult IStreamInformation_QueryStreamName( XAStreamInformationItf self,
162 XAuint32 streamIndex, /* [in] */
163 XAuint16 * pNameSize, /* [in/out] */
164 XAchar * pName) /* [out] */
165 {
166 XA_ENTER_INTERFACE
167
168 if (NULL == pNameSize || streamIndex == 0) {
169 result = XA_RESULT_PARAMETER_INVALID;
170 } else {
171 #ifdef ANDROID
172 IStreamInformation *thiz = (IStreamInformation *) self;
173 interface_lock_shared(thiz);
174
175 XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
176 // streams in the container are numbered 1..nbStreams
177 if (streamIndex <= nbStreams) {
178 char streamName[16]; // large enough for the fixed format in next line
179 snprintf(streamName, sizeof(streamName), "stream%u", streamIndex);
180 size_t actualNameLength = strlen(streamName);
181 if (NULL == pName) {
182 // application is querying the name length in order to allocate a buffer
183 result = XA_RESULT_SUCCESS;
184 } else {
185 SLuint16 availableNameLength = *pNameSize;
186 if (actualNameLength > availableNameLength) {
187 memcpy(pName, streamName, availableNameLength);
188 result = XA_RESULT_BUFFER_INSUFFICIENT;
189 } else if (actualNameLength == availableNameLength) {
190 memcpy(pName, streamName, availableNameLength);
191 result = XA_RESULT_SUCCESS;
192 } else { // actualNameLength < availableNameLength
193 memcpy(pName, streamName, actualNameLength + 1);
194 result = XA_RESULT_SUCCESS;
195 }
196 }
197 *pNameSize = actualNameLength;
198 } else {
199 result = XA_RESULT_PARAMETER_INVALID;
200 }
201
202 interface_unlock_shared(thiz);
203 #else
204 SL_LOGE("unsupported XAStreamInformationItf function");
205 result = XA_RESULT_FEATURE_UNSUPPORTED;
206 #endif
207 }
208
209 XA_LEAVE_INTERFACE
210 }
211
212
IStreamInformation_RegisterStreamChangeCallback(XAStreamInformationItf self,xaStreamEventChangeCallback callback,void * pContext)213 static XAresult IStreamInformation_RegisterStreamChangeCallback( XAStreamInformationItf self,
214 xaStreamEventChangeCallback callback, /* [in] */
215 void * pContext) /* [in] */
216 {
217 XA_ENTER_INTERFACE
218
219 IStreamInformation *thiz = (IStreamInformation *) self;
220
221 interface_lock_exclusive(thiz);
222
223 thiz->mCallback = callback;
224 thiz->mContext = pContext;
225 result = SL_RESULT_SUCCESS;
226
227 interface_unlock_exclusive(thiz);
228
229 XA_LEAVE_INTERFACE
230 }
231
232
IStreamInformation_QueryActiveStreams(XAStreamInformationItf self,XAuint32 * numStreams,XAboolean * activeStreams)233 static XAresult IStreamInformation_QueryActiveStreams( XAStreamInformationItf self,
234 XAuint32 *numStreams, /* [in/out] */
235 XAboolean *activeStreams) /* [out] */
236 {
237 XA_ENTER_INTERFACE
238
239 if (NULL == numStreams) {
240 result = XA_RESULT_PARAMETER_INVALID;
241 XA_LEAVE_INTERFACE;
242 }
243
244 #ifdef ANDROID
245 IStreamInformation *thiz = (IStreamInformation *) self;
246 interface_lock_shared(thiz);
247
248 result = XA_RESULT_SUCCESS;
249 *numStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
250 // FIXME not setting activeStreams
251
252 interface_unlock_shared(thiz);
253 #else
254 result = SL_RESULT_FEATURE_UNSUPPORTED;
255 #endif
256
257 XA_LEAVE_INTERFACE
258 }
259
260
IStreamInformation_SetActiveStream(XAStreamInformationItf self,XAuint32 streamNum,XAboolean active,XAboolean commitNow)261 static XAresult IStreamInformation_SetActiveStream( XAStreamInformationItf self,
262 XAuint32 streamNum, /* [in] */
263 XAboolean active, /* [in] */
264 XAboolean commitNow) /* [in] */
265 {
266 XA_ENTER_INTERFACE
267
268 SL_LOGE("unsupported XAStreamInformationItf function");
269 result = XA_RESULT_FEATURE_UNSUPPORTED;
270
271 XA_LEAVE_INTERFACE
272 }
273
274
275 static const struct XAStreamInformationItf_ IStreamInformation_Itf = {
276 IStreamInformation_QueryMediaContainerInformation,
277 IStreamInformation_QueryStreamType,
278 IStreamInformation_QueryStreamInformation,
279 IStreamInformation_QueryStreamName,
280 IStreamInformation_RegisterStreamChangeCallback,
281 IStreamInformation_QueryActiveStreams,
282 IStreamInformation_SetActiveStream
283 };
284
285
IStreamInformation_init(void * self)286 void IStreamInformation_init(void *self)
287 {
288 SL_LOGV("IStreamInformation_init\n");
289 IStreamInformation *thiz = (IStreamInformation *) self;
290 thiz->mItf = &IStreamInformation_Itf;
291
292 thiz->mCallback = NULL;
293 thiz->mContext = NULL;
294
295 for (int i=0 ; i < NB_SUPPORTED_STREAMS ; i++) {
296 thiz->mActiveStreams[i] = XA_BOOLEAN_FALSE;
297 }
298
299 #ifdef ANDROID
300 // placement new constructor for C++ field within C struct
301 (void) new (&thiz->mStreamInfoTable) android::Vector<StreamInfo>();
302 // initialize container info
303 StreamInfo contInf;
304 contInf.domain = XA_DOMAINTYPE_CONTAINER;
305 contInf.containerInfo.containerType = XA_CONTAINERTYPE_UNSPECIFIED;
306 contInf.containerInfo.mediaDuration = XA_TIME_UNKNOWN;
307 // FIXME shouldn't this be 1 ?
308 contInf.containerInfo.numStreams = 0;
309 // always storing container info at index 0, as per spec: here, the table was still empty
310 thiz->mStreamInfoTable.add(contInf);
311 #endif
312 }
313
314
IStreamInformation_deinit(void * self)315 void IStreamInformation_deinit(void *self) {
316 #ifdef ANDROID
317 IStreamInformation *thiz = (IStreamInformation *) self;
318 // explicit destructor
319 thiz->mStreamInfoTable.~Vector<StreamInfo>();
320 #endif
321 }
322