16e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi/*
26e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
36e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi *
46e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
56e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * you may not use this file except in compliance with the License.
66e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * You may obtain a copy of the License at
76e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi *
86e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
96e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi *
106e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
116e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
126e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * See the License for the specific language governing permissions and
146e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi * limitations under the License.
156e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi */
166e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
176e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi/* VideoDecoderCapabilities implementation */
186e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
196e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#include "sles_allinclusive.h"
206e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
216e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#include "android/VideoCodec_to_android.h"
226e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
236e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
246e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
256e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivistatic XAresult IVideoDecoderCapabilities_GetVideoDecoders(XAVideoDecoderCapabilitiesItf self,
266e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XAuint32 *pNumDecoders, XAuint32 *pDecoderIds)
276e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi{
286e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XA_ENTER_INTERFACE
296e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
306e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    if (NULL == pNumDecoders) {
316e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        result = XA_RESULT_PARAMETER_INVALID;
326e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    } else {
336e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        if (NULL == pDecoderIds) {
346e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // If pDecoderIds is NULL, pNumDecoders returns the number of decoders available.
356e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
366e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            *pNumDecoders = android::android_videoCodec_getNbDecoders();
376e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#else
386e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            *pNumDecoders = kMaxVideoDecoders;
396e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
406e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
416e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        } else {
426e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // If pDecodersIds is non-NULL, as an input pNumDecoders specifies the size of the
436e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // pDecoderIds array and as an output it specifies the number of decoder IDs available
446e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // within the pDecoderIds array.
456e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            XAuint32 numDecoders = *pNumDecoders;
46df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten#ifdef ANDROID
476e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            const XAuint32 androidNbDecoders = android::android_videoCodec_getNbDecoders();
48df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            if (androidNbDecoders < numDecoders) {
496e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi                *pNumDecoders = numDecoders = androidNbDecoders;
506e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            }
516e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            android::android_videoCodec_getDecoderIds(numDecoders, pDecoderIds);
526e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#else
53df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            if (kMaxVideoDecoders < numDecoders) {
546e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi                *pNumDecoders = numDecoders = kMaxVideoDecoders;
556e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            }
566e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            memcpy(pDecoderIds, VideoDecoderIds, numDecoders * sizeof(XAuint32));
576e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
586e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        }
596e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        result = XA_RESULT_SUCCESS;
606e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    }
616e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
626e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XA_LEAVE_INTERFACE
636e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi}
646e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
656e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
666e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivistatic XAresult IVideoDecoderCapabilities_GetVideoDecoderCapabilities(
676e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XAVideoDecoderCapabilitiesItf self, XAuint32 decoderId, XAuint32 *pIndex,
686e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XAVideoCodecDescriptor *pDescriptor)
696e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi{
706e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XA_ENTER_INTERFACE
716e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
726e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    if (NULL == pIndex) {
736e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        result = XA_RESULT_PARAMETER_INVALID;
746e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    } else {
756e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        if (NULL == pDescriptor) {
766e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // pIndex returns the number of video decoders capability descriptions.
776e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
786e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            result = android::android_videoCodec_getProfileLevelCombinationNb(decoderId, pIndex);
796e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#else
80df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            // Generic implementation has zero profile/level combinations for all codecs,
81df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            // but this is not allowed per spec:
82df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            //    "Each decoder must support at least one profile/mode pair
83df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            //    and therefore have at least one Codec Descriptor."
84df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            *pIndex = 0;
856e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            SL_LOGE("Generic implementation has no video decoder capabilities");
866e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            result = XA_RESULT_PARAMETER_INVALID;
876e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
886e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        } else {
896e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            // pIndex is an incrementing value used to enumerate capability descriptions.
906e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
916e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            result = android::android_videoCodec_getProfileLevelCombination(decoderId, *pIndex,
926e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi                    pDescriptor);
936e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#else
94df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten            // For the generic implementation, any index >= 0 is out of range
95df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten#if 1   // not sure if this is needed, it's not being done for the Android case
966e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            pDescriptor->codecId = decoderId;
97df200f6a98da83bf2c1b14aff0ed356263dfb8b7Glenn Kasten#endif
986e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            SL_LOGE("Generic implementation has no video decoder capabilities");
996e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi            result = XA_RESULT_PARAMETER_INVALID;
1006e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
1016e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi        }
1026e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    }
1036e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1046e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    XA_LEAVE_INTERFACE
1056e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi}
1066e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1076e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1086e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivistatic const struct XAVideoDecoderCapabilitiesItf_ IVideoDecoderCapabilities_Itf = {
1096e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    IVideoDecoderCapabilities_GetVideoDecoders,
1106e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    IVideoDecoderCapabilities_GetVideoDecoderCapabilities
1116e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi};
1126e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1136e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivivoid IVideoDecoderCapabilities_init(void *self)
1146e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi{
1156e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    IVideoDecoderCapabilities *thiz = (IVideoDecoderCapabilities *) self;
1166e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    thiz->mItf = &IVideoDecoderCapabilities_Itf;
1176e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi}
1186e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1196e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1206e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivibool IVideoDecoderCapabilities_expose(void *self)
1216e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi{
1226e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
1236e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    // This is an Engine object interface, so we allocate the associated resources every time
1246e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    //   the interface is exposed on the Engine object and free them when the object is about
1256e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    //   to be destroyed (see IVideoDecoderCapabilities_deinit), not just once during the
1266e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    //   lifetime of the process.
1276e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    return android::android_videoCodec_expose();
1286e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#else
1296e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    return false;
1306e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
1316e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi}
1326e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1336e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi
1346e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivivoid IVideoDecoderCapabilities_deinit(void *self)
1356e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi{
136d7ecf117cfac5f2b90a0dc6c62b56dcce0715971Glenn Kasten    SL_LOGV("IVideoDecoderCapabilities_deinit()");
1376e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#ifdef ANDROID
1386e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi    android::android_videoCodec_deinit();
1396e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi#endif
1406e7e174807fc639c49125ced8962aa369370fbf0Jean-Michel Trivi}
141