• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
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  
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  
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  
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  
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  
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  
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  
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  
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