Home | History | Annotate | Download | only in examples
      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 #include <stdlib.h>
     18 #include <stdio.h>
     19 #include <string.h>
     20 #include <unistd.h>
     21 #include <sys/time.h>
     22 #include <fcntl.h>
     23 
     24 #include <OMXAL/OpenMAXAL.h>
     25 #include <OMXAL/OpenMAXAL_Android.h> // for VP8 definitions
     26 
     27 #define NUM_ENGINE_INTERFACES 1
     28 
     29 char unknown[50];
     30 
     31 //-----------------------------------------------------------------
     32 /* Exits the application if an error is encountered */
     33 #define ExitOnError(x) ExitOnErrorFunc(x,__LINE__)
     34 
     35 void ExitOnErrorFunc( XAresult result , int line)
     36 {
     37     if (XA_RESULT_SUCCESS != result) {
     38         fprintf(stderr, "Error %u encountered at line %d, exiting\n", result, line);
     39         exit(EXIT_FAILURE);
     40     }
     41 }
     42 
     43 const char* videoCodecIdToString(XAuint32 decoderId) {
     44     switch(decoderId) {
     45     case XA_VIDEOCODEC_MPEG2: return "XA_VIDEOCODEC_MPEG2"; break;
     46     case XA_VIDEOCODEC_H263: return "XA_VIDEOCODEC_H263"; break;
     47     case XA_VIDEOCODEC_MPEG4: return "XA_VIDEOCODEC_MPEG4"; break;
     48     case XA_VIDEOCODEC_AVC: return "XA_VIDEOCODEC_AVC"; break;
     49     case XA_VIDEOCODEC_VC1: return "XA_VIDEOCODEC_VC1"; break;
     50     case XA_ANDROID_VIDEOCODEC_VP8: return "XA_ANDROID_VIDEOCODEC_VP8"; break;
     51     default:
     52         sprintf(unknown, "Video codec %d unknown to OpenMAX AL", decoderId);
     53         return unknown;
     54     }
     55 }
     56 
     57 // Use a table of [integer, string] entries to map an integer to a string
     58 
     59 typedef struct {
     60     XAuint32 id;
     61     const char *string;
     62 } id_to_string_t;
     63 
     64 const char *id_to_string(XAuint32 id, const id_to_string_t *table, size_t numEntries)
     65 {
     66     size_t i;
     67     for (i = 0; i < numEntries; ++i) {
     68         if (id == table[i].id) {
     69             return table[i].string;
     70         }
     71     }
     72     return "Unknown";
     73 }
     74 
     75 // Use a table of [integer, table] entries to map a pair of integers to a string
     76 
     77 typedef struct {
     78     XAuint32 id1;
     79     const id_to_string_t *id2_table;
     80     size_t id2_numEntries;
     81 } id_pair_to_string_t;
     82 
     83 const char *id_pair_to_string(XAuint32 id1, XAuint32 id2, const id_pair_to_string_t *table,
     84         size_t numEntries)
     85 {
     86     size_t i;
     87     for (i = 0; i < numEntries; ++i) {
     88         if (id1 == table[i].id1) {
     89             return id_to_string(id2, table[i].id2_table, table[i].id2_numEntries);
     90         }
     91     }
     92     return "Unknown";
     93 }
     94 
     95 // Map a video codec and profile to string
     96 
     97 const char *videoProfileToString(XAuint32 codec, XAuint32 profile) {
     98     // http://en.wikipedia.org/wiki/H.262/MPEG-2_Part_2
     99     static const id_to_string_t MPEG2[] = {
    100         {XA_VIDEOPROFILE_MPEG2_SIMPLE,  "Simple"},
    101         {XA_VIDEOPROFILE_MPEG2_MAIN,    "Main"},
    102         {XA_VIDEOPROFILE_MPEG2_422,     "4:2:2"},
    103         {XA_VIDEOPROFILE_MPEG2_SNR,     "SNR Scalable"},
    104         {XA_VIDEOPROFILE_MPEG2_SPATIAL, "Spatially Scalable"},
    105         {XA_VIDEOPROFILE_MPEG2_HIGH,    "High"},
    106     }, H263[] = {
    107         {XA_VIDEOPROFILE_H263_BASELINE,           "baseline"},
    108         {XA_VIDEOPROFILE_H263_H320CODING,         "H320 coding"},
    109         {XA_VIDEOPROFILE_H263_BACKWARDCOMPATIBLE, "backwards compatible"},
    110         {XA_VIDEOPROFILE_H263_ISWV2,              "isw v2"},
    111         {XA_VIDEOPROFILE_H263_ISWV3,              "isw v3"},
    112         {XA_VIDEOPROFILE_H263_HIGHCOMPRESSION,    "high compression"},
    113         {XA_VIDEOPROFILE_H263_INTERNET,           "internet"},
    114         {XA_VIDEOPROFILE_H263_INTERLACE,          "interlace"},
    115         {XA_VIDEOPROFILE_H263_HIGHLATENCY,        "high latency"},
    116     }, MPEG4[] = {
    117         {XA_VIDEOPROFILE_MPEG4_SIMPLE,           "simple"},
    118         {XA_VIDEOPROFILE_MPEG4_SIMPLESCALABLE,   "simple scalable"},
    119         {XA_VIDEOPROFILE_MPEG4_CORE,             "core"},
    120         {XA_VIDEOPROFILE_MPEG4_MAIN,             "main"},
    121         {XA_VIDEOPROFILE_MPEG4_NBIT,             "nbit"},
    122         {XA_VIDEOPROFILE_MPEG4_SCALABLETEXTURE,  "scalable texture"},
    123         {XA_VIDEOPROFILE_MPEG4_SIMPLEFACE,       "simple face"},
    124         {XA_VIDEOPROFILE_MPEG4_SIMPLEFBA,        "simple fba"},
    125         {XA_VIDEOPROFILE_MPEG4_BASICANIMATED,    "basic animated"},
    126         {XA_VIDEOPROFILE_MPEG4_HYBRID,           "hybrid"},
    127         {XA_VIDEOPROFILE_MPEG4_ADVANCEDREALTIME, "advanced realtime"},
    128         {XA_VIDEOPROFILE_MPEG4_CORESCALABLE,     "core scalable"},
    129         {XA_VIDEOPROFILE_MPEG4_ADVANCEDCODING,   "advanced coding"},
    130         {XA_VIDEOPROFILE_MPEG4_ADVANCEDCORE,     "advanced core"},
    131         {XA_VIDEOPROFILE_MPEG4_ADVANCEDSCALABLE, "advanced scalable"},
    132         // FIXME OpenMAX AL is out-of-date with respect to OpenMAX IL
    133         {16,                                     "advanced simple"},
    134     }, AVC[] = {
    135         {XA_VIDEOPROFILE_AVC_BASELINE, "Baseline"},
    136         {XA_VIDEOPROFILE_AVC_MAIN,     "Main"},
    137         {XA_VIDEOPROFILE_AVC_EXTENDED, "Extended"},
    138         {XA_VIDEOPROFILE_AVC_HIGH,     "High"},
    139         {XA_VIDEOPROFILE_AVC_HIGH10,   "High 10"},
    140         {XA_VIDEOPROFILE_AVC_HIGH422,  "High 4:2:2"},
    141         {XA_VIDEOPROFILE_AVC_HIGH444,  "High 4:4:4"},
    142     }, VC1[] = {
    143         // FIXME sic should be XA_VIDEOPROFILE_*
    144         {XA_VIDEOLEVEL_VC1_SIMPLE,   "simple"},
    145         {XA_VIDEOLEVEL_VC1_MAIN,     "main"},
    146         {XA_VIDEOLEVEL_VC1_ADVANCED, "advanced"},
    147     };
    148     static const id_pair_to_string_t table[] = {
    149         {XA_VIDEOCODEC_MPEG2, MPEG2, sizeof(MPEG2) / sizeof(MPEG2[0])},
    150         {XA_VIDEOCODEC_H263,  H263,  sizeof(H263)  / sizeof(H263[0])},
    151         {XA_VIDEOCODEC_MPEG4, MPEG4, sizeof(MPEG4) / sizeof(MPEG4[0])},
    152         {XA_VIDEOCODEC_AVC,   AVC,   sizeof(AVC)   / sizeof(AVC[0])},
    153         {XA_VIDEOCODEC_VC1,   VC1,   sizeof(VC1)   / sizeof(VC1[0])},
    154     };
    155     return id_pair_to_string(codec, profile, table, sizeof(table) / sizeof(table[0]));
    156 }
    157 
    158 // Map a video codec and level to string
    159 
    160 const char* videoLevelToString(XAuint32 codec, XAuint32 level) {
    161     static const id_to_string_t MPEG2[] = {
    162         {XA_VIDEOLEVEL_MPEG2_LL,  "Low"},
    163         {XA_VIDEOLEVEL_MPEG2_ML,  "Main"},
    164         {XA_VIDEOLEVEL_MPEG2_H14, "H-14"},
    165         {XA_VIDEOLEVEL_MPEG2_HL,  "High"},
    166     }, H263[]= {
    167         {XA_VIDEOLEVEL_H263_10, "10"},
    168         {XA_VIDEOLEVEL_H263_20, "20"},
    169         {XA_VIDEOLEVEL_H263_30, "30"},
    170         {XA_VIDEOLEVEL_H263_40, "40"},
    171         {XA_VIDEOLEVEL_H263_45, "45"},
    172         {XA_VIDEOLEVEL_H263_50, "50"},
    173         {XA_VIDEOLEVEL_H263_60, "60"},
    174         {XA_VIDEOLEVEL_H263_70, "70"},
    175     }, MPEG4[] = {
    176         {XA_VIDEOLEVEL_MPEG4_0,  "0"},
    177         {XA_VIDEOLEVEL_MPEG4_0b, "0b"},
    178         {XA_VIDEOLEVEL_MPEG4_1,  "1"},
    179         {XA_VIDEOLEVEL_MPEG4_2,  "2"},
    180         {XA_VIDEOLEVEL_MPEG4_3,  "3"},
    181         {XA_VIDEOLEVEL_MPEG4_4,  "4"},
    182         {XA_VIDEOLEVEL_MPEG4_4a, "4a"},
    183         // FIXME OpenMAX AL is out-of-date with respect to OpenMAX IL
    184         {8,                      "5"},
    185     }, AVC[] = {
    186         {XA_VIDEOLEVEL_AVC_1,  "1"},
    187         {XA_VIDEOLEVEL_AVC_1B, "1B"},
    188         {XA_VIDEOLEVEL_AVC_11, "1.1"},
    189         {XA_VIDEOLEVEL_AVC_12, "1.2"},
    190         {XA_VIDEOLEVEL_AVC_13, "1.3"},
    191         {XA_VIDEOLEVEL_AVC_2,  "2"},
    192         {XA_VIDEOLEVEL_AVC_21, "2.1"},
    193         {XA_VIDEOLEVEL_AVC_22, "2.2"},
    194         {XA_VIDEOLEVEL_AVC_3,  "3"},
    195         {XA_VIDEOLEVEL_AVC_31, "3.1"},
    196         {XA_VIDEOLEVEL_AVC_32, "3.2"},
    197         {XA_VIDEOLEVEL_AVC_4,  "4"},
    198         {XA_VIDEOLEVEL_AVC_41, "4.1"},
    199         {XA_VIDEOLEVEL_AVC_42, "4.2"},
    200         {XA_VIDEOLEVEL_AVC_5,  "5"},
    201         {XA_VIDEOLEVEL_AVC_51, "5.1"},
    202     }, VC1[] = {
    203         {XA_VIDEOLEVEL_VC1_LOW,    "Low"},
    204         {XA_VIDEOLEVEL_VC1_MEDIUM, "Medium"},
    205         {XA_VIDEOLEVEL_VC1_HIGH,   "High"},
    206         {XA_VIDEOLEVEL_VC1_L0,     "L0"},
    207         {XA_VIDEOLEVEL_VC1_L1,     "L1"},
    208         {XA_VIDEOLEVEL_VC1_L2,     "L2"},
    209         {XA_VIDEOLEVEL_VC1_L3,     "L3"},
    210         {XA_VIDEOLEVEL_VC1_L4,     "L4"},
    211     };
    212     static const id_pair_to_string_t table[] = {
    213         {XA_VIDEOCODEC_MPEG2, MPEG2, sizeof(MPEG2) / sizeof(MPEG2[0])},
    214         {XA_VIDEOCODEC_H263,  H263,  sizeof(H263)  / sizeof(H263[0])},
    215         {XA_VIDEOCODEC_MPEG4, MPEG4, sizeof(MPEG4) / sizeof(MPEG4[0])},
    216         {XA_VIDEOCODEC_AVC,   AVC,   sizeof(AVC)   / sizeof(AVC[0])},
    217         {XA_VIDEOCODEC_VC1,   VC1,   sizeof(VC1)   / sizeof(VC1[0])},
    218     };
    219     return id_pair_to_string(codec, level, table, sizeof(table) / sizeof(table[0]));
    220 }
    221 
    222 //-----------------------------------------------------------------
    223 void TestVideoDecoderCapabilities() {
    224 
    225     XAObjectItf xa;
    226     XAresult res;
    227 
    228     /* parameters for the OpenMAX AL engine creation */
    229     XAEngineOption EngineOption[] = {
    230             {(XAuint32) XA_ENGINEOPTION_THREADSAFE, (XAuint32) XA_BOOLEAN_TRUE}
    231     };
    232     XAInterfaceID itfIidArray[NUM_ENGINE_INTERFACES] = { XA_IID_VIDEODECODERCAPABILITIES };
    233     XAboolean     itfRequired[NUM_ENGINE_INTERFACES] = { XA_BOOLEAN_TRUE };
    234 
    235     /* create OpenMAX AL engine */
    236     res = xaCreateEngine( &xa, 1, EngineOption, NUM_ENGINE_INTERFACES, itfIidArray, itfRequired);
    237     ExitOnError(res);
    238 
    239     /* realize the engine in synchronous mode. */
    240     res = (*xa)->Realize(xa, XA_BOOLEAN_FALSE); ExitOnError(res);
    241 
    242     /* Get the video decoder capabilities interface which was explicitly requested */
    243     XAVideoDecoderCapabilitiesItf decItf;
    244     res = (*xa)->GetInterface(xa, XA_IID_VIDEODECODERCAPABILITIES, (void*)&decItf);
    245     ExitOnError(res);
    246 
    247     /* Query the platform capabilities */
    248     XAuint32 numDecoders = 0;
    249     XAuint32 *decoderIds = NULL;
    250 
    251     /* -> Number of decoders */
    252     res = (*decItf)->GetVideoDecoders(decItf, &numDecoders, NULL); ExitOnError(res);
    253     fprintf(stdout, "Found %d video decoders\n", numDecoders);
    254     if (0 == numDecoders) {
    255         fprintf(stderr, "0 video decoders is not an acceptable number, exiting\n");
    256         goto destroyRes;
    257     }
    258 
    259     /* -> Decoder list */
    260     decoderIds = (XAuint32 *) malloc(numDecoders * sizeof(XAuint32));
    261     res = (*decItf)->GetVideoDecoders(decItf, &numDecoders, decoderIds); ExitOnError(res);
    262     fprintf(stdout, "Decoders:\n");
    263     for(XAuint32 i = 0 ; i < numDecoders ; i++) {
    264         fprintf(stdout, "decoder %d is %s\n", i, videoCodecIdToString(decoderIds[i]));
    265     }
    266 
    267     /* -> Decoder capabilities */
    268     /*       for each decoder  */
    269     for(XAuint32 i = 0 ; i < numDecoders ; i++) {
    270         XAuint32 nbCombinations = 0;
    271         /* get the number of profile / level combinations */
    272         res = (*decItf)->GetVideoDecoderCapabilities(decItf, decoderIds[i], &nbCombinations, NULL);
    273         ExitOnError(res);
    274         fprintf(stdout, "decoder %s has %d profile/level combinations:\n\t",
    275                 videoCodecIdToString(decoderIds[i]), nbCombinations);
    276         /* display the profile / level combinations */
    277         for(XAuint32 pl = 0 ; pl < nbCombinations ; pl++) {
    278             XAVideoCodecDescriptor decDescriptor;
    279             XAuint32 decoder = decoderIds[i];
    280             res = (*decItf)->GetVideoDecoderCapabilities(decItf, decoder, &pl, &decDescriptor);
    281             ExitOnError(res);
    282             XAuint32 profile = decDescriptor.profileSetting;
    283             XAuint32 level = decDescriptor.levelSetting;
    284             fprintf(stdout, "%u/%u ", profile, level);
    285             ExitOnError(res);
    286             printf("(%s/%s) ", videoProfileToString(decoder, profile),
    287                     videoLevelToString(decoder, level));
    288         }
    289         fprintf(stdout, "\n");
    290     }
    291 
    292 destroyRes:
    293     free(decoderIds);
    294 
    295     /* shutdown OpenMAX AL */
    296     (*xa)->Destroy(xa);
    297 }
    298 
    299 
    300 //-----------------------------------------------------------------
    301 int main(int argc, char* const argv[])
    302 {
    303     XAresult    result;
    304     XAObjectItf sl;
    305 
    306     fprintf(stdout, "OpenMAX AL test %s: exercises SLAudioDecoderCapabiltiesItf ", argv[0]);
    307     fprintf(stdout, "and displays the list of supported video decoders, and for each, lists the ");
    308     fprintf(stdout, "profile / levels combinations, that map to the constants defined in ");
    309     fprintf(stdout, "\"XA_VIDEOPROFILE and XA_VIDEOLEVEL\" section of the specification\n\n");
    310 
    311     TestVideoDecoderCapabilities();
    312 
    313     return EXIT_SUCCESS;
    314 }
    315