Home | History | Annotate | Download | only in itf
      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     activeStreams = thiz->mActiveStreams;
    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