Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 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 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "Utils"
     19 #include <utils/Log.h>
     20 #include <ctype.h>
     21 #include <stdio.h>
     22 #include <sys/stat.h>
     23 
     24 #include <utility>
     25 
     26 #include "include/ESDS.h"
     27 #include "include/HevcUtils.h"
     28 
     29 #include <arpa/inet.h>
     30 #include <cutils/properties.h>
     31 #include <media/openmax/OMX_Audio.h>
     32 #include <media/openmax/OMX_Video.h>
     33 #include <media/openmax/OMX_VideoExt.h>
     34 #include <media/stagefright/CodecBase.h>
     35 #include <media/stagefright/foundation/ABuffer.h>
     36 #include <media/stagefright/foundation/ADebug.h>
     37 #include <media/stagefright/foundation/ALookup.h>
     38 #include <media/stagefright/foundation/AMessage.h>
     39 #include <media/stagefright/MetaData.h>
     40 #include <media/stagefright/MediaDefs.h>
     41 #include <media/AudioSystem.h>
     42 #include <media/MediaPlayerInterface.h>
     43 #include <hardware/audio.h>
     44 #include <media/stagefright/Utils.h>
     45 #include <media/AudioParameter.h>
     46 
     47 namespace android {
     48 
     49 uint16_t U16_AT(const uint8_t *ptr) {
     50     return ptr[0] << 8 | ptr[1];
     51 }
     52 
     53 uint32_t U32_AT(const uint8_t *ptr) {
     54     return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
     55 }
     56 
     57 uint64_t U64_AT(const uint8_t *ptr) {
     58     return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
     59 }
     60 
     61 uint16_t U16LE_AT(const uint8_t *ptr) {
     62     return ptr[0] | (ptr[1] << 8);
     63 }
     64 
     65 uint32_t U32LE_AT(const uint8_t *ptr) {
     66     return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
     67 }
     68 
     69 uint64_t U64LE_AT(const uint8_t *ptr) {
     70     return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
     71 }
     72 
     73 // XXX warning: these won't work on big-endian host.
     74 uint64_t ntoh64(uint64_t x) {
     75     return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
     76 }
     77 
     78 uint64_t hton64(uint64_t x) {
     79     return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
     80 }
     81 
     82 static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
     83     if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
     84         sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
     85         if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
     86             return NO_MEMORY;
     87         }
     88         memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
     89         tmpBuffer->setRange(0, (*buffer)->size());
     90         (*buffer) = tmpBuffer;
     91     }
     92 
     93     memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
     94     memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
     95     (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
     96     return OK;
     97 }
     98 
     99 #if 0
    100 static void convertMetaDataToMessageInt32(
    101         const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
    102     int32_t value;
    103     if (meta->findInt32(key, &value)) {
    104         msg->setInt32(name, value);
    105     }
    106 }
    107 #endif
    108 
    109 static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
    110     // 0 values are unspecified
    111     int32_t range = 0;
    112     int32_t primaries = 0;
    113     int32_t transferFunction = 0;
    114     int32_t colorMatrix = 0;
    115     meta->findInt32(kKeyColorRange, &range);
    116     meta->findInt32(kKeyColorPrimaries, &primaries);
    117     meta->findInt32(kKeyTransferFunction, &transferFunction);
    118     meta->findInt32(kKeyColorMatrix, &colorMatrix);
    119     ColorAspects colorAspects;
    120     memset(&colorAspects, 0, sizeof(colorAspects));
    121     colorAspects.mRange = (ColorAspects::Range)range;
    122     colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
    123     colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
    124     colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
    125 
    126     int32_t rangeMsg, standardMsg, transferMsg;
    127     if (CodecBase::convertCodecColorAspectsToPlatformAspects(
    128             colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
    129         return;
    130     }
    131 
    132     // save specified values to msg
    133     if (rangeMsg != 0) {
    134         msg->setInt32("color-range", rangeMsg);
    135     }
    136     if (standardMsg != 0) {
    137         msg->setInt32("color-standard", standardMsg);
    138     }
    139     if (transferMsg != 0) {
    140         msg->setInt32("color-transfer", transferMsg);
    141     }
    142 }
    143 
    144 static bool isHdr(const sp<AMessage> &format) {
    145     // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR
    146     // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key
    147     // in the format.
    148     int32_t isHdr;
    149     if (format->findInt32("android._is-hdr", &isHdr)) {
    150         return isHdr;
    151     }
    152 
    153     // if user/container supplied HDR static info without transfer set, assume true
    154     if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
    155         return true;
    156     }
    157     // otherwise, verify that an HDR transfer function is set
    158     int32_t transfer;
    159     if (format->findInt32("color-transfer", &transfer)) {
    160         return transfer == ColorUtils::kColorTransferST2084
    161                 || transfer == ColorUtils::kColorTransferHLG;
    162     }
    163     return false;
    164 }
    165 
    166 static void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    167     if (csd->size() < 2) {
    168         return;
    169     }
    170 
    171     uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
    172     if ((audioObjectType & 0xF800) == 0xF800) {
    173         audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
    174     } else {
    175         audioObjectType >>= 11;
    176     }
    177 
    178     const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
    179         { 1,  OMX_AUDIO_AACObjectMain     },
    180         { 2,  OMX_AUDIO_AACObjectLC       },
    181         { 3,  OMX_AUDIO_AACObjectSSR      },
    182         { 4,  OMX_AUDIO_AACObjectLTP      },
    183         { 5,  OMX_AUDIO_AACObjectHE       },
    184         { 6,  OMX_AUDIO_AACObjectScalable },
    185         { 17, OMX_AUDIO_AACObjectERLC     },
    186         { 23, OMX_AUDIO_AACObjectLD       },
    187         { 29, OMX_AUDIO_AACObjectHE_PS    },
    188         { 39, OMX_AUDIO_AACObjectELD      },
    189     };
    190 
    191     OMX_AUDIO_AACPROFILETYPE profile;
    192     if (profiles.map(audioObjectType, &profile)) {
    193         format->setInt32("profile", profile);
    194     }
    195 }
    196 
    197 static void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    198     if (size < 4 || ptr[0] != 1) {  // configurationVersion == 1
    199         return;
    200     }
    201     const uint8_t profile = ptr[1];
    202     const uint8_t constraints = ptr[2];
    203     const uint8_t level = ptr[3];
    204 
    205     const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
    206         {  9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
    207         { 10, OMX_VIDEO_AVCLevel1  },
    208         { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
    209         { 11, OMX_VIDEO_AVCLevel1b },
    210         { 12, OMX_VIDEO_AVCLevel12 },
    211         { 13, OMX_VIDEO_AVCLevel13 },
    212         { 20, OMX_VIDEO_AVCLevel2  },
    213         { 21, OMX_VIDEO_AVCLevel21 },
    214         { 22, OMX_VIDEO_AVCLevel22 },
    215         { 30, OMX_VIDEO_AVCLevel3  },
    216         { 31, OMX_VIDEO_AVCLevel31 },
    217         { 32, OMX_VIDEO_AVCLevel32 },
    218         { 40, OMX_VIDEO_AVCLevel4  },
    219         { 41, OMX_VIDEO_AVCLevel41 },
    220         { 42, OMX_VIDEO_AVCLevel42 },
    221         { 50, OMX_VIDEO_AVCLevel5  },
    222         { 51, OMX_VIDEO_AVCLevel51 },
    223         { 52, OMX_VIDEO_AVCLevel52 },
    224     };
    225     const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
    226         { 66, OMX_VIDEO_AVCProfileBaseline },
    227         { 77, OMX_VIDEO_AVCProfileMain     },
    228         { 88, OMX_VIDEO_AVCProfileExtended },
    229         { 100, OMX_VIDEO_AVCProfileHigh    },
    230         { 110, OMX_VIDEO_AVCProfileHigh10  },
    231         { 122, OMX_VIDEO_AVCProfileHigh422 },
    232         { 244, OMX_VIDEO_AVCProfileHigh444 },
    233     };
    234 
    235     // set profile & level if they are recognized
    236     OMX_VIDEO_AVCPROFILETYPE codecProfile;
    237     OMX_VIDEO_AVCLEVELTYPE codecLevel;
    238     if (profiles.map(profile, &codecProfile)) {
    239         format->setInt32("profile", codecProfile);
    240         if (levels.map(level, &codecLevel)) {
    241             // for 9 && 11 decide level based on profile and constraint_set3 flag
    242             if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
    243                 codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
    244             }
    245             format->setInt32("level", codecLevel);
    246         }
    247     }
    248 }
    249 
    250 static void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    251     if (size < 7) {
    252         return;
    253     }
    254 
    255     const uint8_t profile = ptr[6];
    256     const uint8_t level = ptr[5];
    257 
    258     const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
    259         { 0, OMX_VIDEO_H263ProfileBaseline },
    260         { 1, OMX_VIDEO_H263ProfileH320Coding },
    261         { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
    262         { 3, OMX_VIDEO_H263ProfileISWV2 },
    263         { 4, OMX_VIDEO_H263ProfileISWV3 },
    264         { 5, OMX_VIDEO_H263ProfileHighCompression },
    265         { 6, OMX_VIDEO_H263ProfileInternet },
    266         { 7, OMX_VIDEO_H263ProfileInterlace },
    267         { 8, OMX_VIDEO_H263ProfileHighLatency },
    268     };
    269 
    270     const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
    271         { 10, OMX_VIDEO_H263Level10 },
    272         { 20, OMX_VIDEO_H263Level20 },
    273         { 30, OMX_VIDEO_H263Level30 },
    274         { 40, OMX_VIDEO_H263Level40 },
    275         { 45, OMX_VIDEO_H263Level45 },
    276         { 50, OMX_VIDEO_H263Level50 },
    277         { 60, OMX_VIDEO_H263Level60 },
    278         { 70, OMX_VIDEO_H263Level70 },
    279     };
    280 
    281     // set profile & level if they are recognized
    282     OMX_VIDEO_H263PROFILETYPE codecProfile;
    283     OMX_VIDEO_H263LEVELTYPE codecLevel;
    284     if (profiles.map(profile, &codecProfile)) {
    285         format->setInt32("profile", codecProfile);
    286         if (levels.map(level, &codecLevel)) {
    287             format->setInt32("level", codecLevel);
    288         }
    289     }
    290 }
    291 
    292 static void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    293     if (size < 13 || ptr[0] != 1) {  // configurationVersion == 1
    294         return;
    295     }
    296 
    297     const uint8_t profile = ptr[1] & 0x1F;
    298     const uint8_t tier = (ptr[1] & 0x20) >> 5;
    299     const uint8_t level = ptr[12];
    300 
    301     const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
    302         { { 0, 30  }, OMX_VIDEO_HEVCMainTierLevel1  },
    303         { { 0, 60  }, OMX_VIDEO_HEVCMainTierLevel2  },
    304         { { 0, 63  }, OMX_VIDEO_HEVCMainTierLevel21 },
    305         { { 0, 90  }, OMX_VIDEO_HEVCMainTierLevel3  },
    306         { { 0, 93  }, OMX_VIDEO_HEVCMainTierLevel31 },
    307         { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4  },
    308         { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
    309         { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5  },
    310         { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
    311         { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
    312         { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6  },
    313         { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
    314         { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
    315         { { 1, 30  }, OMX_VIDEO_HEVCHighTierLevel1  },
    316         { { 1, 60  }, OMX_VIDEO_HEVCHighTierLevel2  },
    317         { { 1, 63  }, OMX_VIDEO_HEVCHighTierLevel21 },
    318         { { 1, 90  }, OMX_VIDEO_HEVCHighTierLevel3  },
    319         { { 1, 93  }, OMX_VIDEO_HEVCHighTierLevel31 },
    320         { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4  },
    321         { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
    322         { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5  },
    323         { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
    324         { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
    325         { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6  },
    326         { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
    327         { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
    328     };
    329 
    330     const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
    331         { 1, OMX_VIDEO_HEVCProfileMain   },
    332         { 2, OMX_VIDEO_HEVCProfileMain10 },
    333     };
    334 
    335     // set profile & level if they are recognized
    336     OMX_VIDEO_HEVCPROFILETYPE codecProfile;
    337     OMX_VIDEO_HEVCLEVELTYPE codecLevel;
    338     if (!profiles.map(profile, &codecProfile)) {
    339         if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
    340             codecProfile = OMX_VIDEO_HEVCProfileMain;
    341         } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
    342             codecProfile = OMX_VIDEO_HEVCProfileMain10;
    343         } else {
    344             return;
    345         }
    346     }
    347 
    348     // bump to HDR profile
    349     if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) {
    350         codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
    351     }
    352 
    353     format->setInt32("profile", codecProfile);
    354     if (levels.map(std::make_pair(tier, level), &codecLevel)) {
    355         format->setInt32("level", codecLevel);
    356     }
    357 }
    358 
    359 static void parseMpeg2ProfileLevelFromHeader(
    360         const uint8_t *data, size_t size, sp<AMessage> &format) {
    361     // find sequence extension
    362     const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
    363     if (seq != NULL && seq + 5 < data + size) {
    364         const uint8_t start_code = seq[4] >> 4;
    365         if (start_code != 1 /* sequence extension ID */) {
    366             return;
    367         }
    368         const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);
    369 
    370         const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
    371             { 0x50, OMX_VIDEO_MPEG2ProfileSimple  },
    372             { 0x40, OMX_VIDEO_MPEG2ProfileMain    },
    373             { 0x30, OMX_VIDEO_MPEG2ProfileSNR     },
    374             { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
    375             { 0x10, OMX_VIDEO_MPEG2ProfileHigh    },
    376         };
    377 
    378         const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
    379             { 0x0A, OMX_VIDEO_MPEG2LevelLL  },
    380             { 0x08, OMX_VIDEO_MPEG2LevelML  },
    381             { 0x06, OMX_VIDEO_MPEG2LevelH14 },
    382             { 0x04, OMX_VIDEO_MPEG2LevelHL  },
    383             { 0x02, OMX_VIDEO_MPEG2LevelHP  },
    384         };
    385 
    386         const static ALookup<uint8_t,
    387                 std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
    388             /* unsupported
    389             { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL  } },
    390             { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML  } },
    391             { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
    392             { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL  } }, */
    393             { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML  } },
    394             { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL  } },
    395         };
    396 
    397         OMX_VIDEO_MPEG2PROFILETYPE profile;
    398         OMX_VIDEO_MPEG2LEVELTYPE level;
    399         std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
    400         if (escapes.map(indication, &profileLevel)) {
    401             format->setInt32("profile", profileLevel.first);
    402             format->setInt32("level", profileLevel.second);
    403         } else if (profiles.map(indication & 0x70, &profile)) {
    404             format->setInt32("profile", profile);
    405             if (levels.map(indication & 0xF, &level)) {
    406                 format->setInt32("level", level);
    407             }
    408         }
    409     }
    410 }
    411 
    412 static void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
    413     // esds seems to only contain the profile for MPEG-2
    414     uint8_t objType;
    415     if (esds.getObjectTypeIndication(&objType) == OK) {
    416         const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
    417             { 0x60, OMX_VIDEO_MPEG2ProfileSimple  },
    418             { 0x61, OMX_VIDEO_MPEG2ProfileMain    },
    419             { 0x62, OMX_VIDEO_MPEG2ProfileSNR     },
    420             { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
    421             { 0x64, OMX_VIDEO_MPEG2ProfileHigh    },
    422             { 0x65, OMX_VIDEO_MPEG2Profile422     },
    423         };
    424 
    425         OMX_VIDEO_MPEG2PROFILETYPE profile;
    426         if (profiles.map(objType, &profile)) {
    427             format->setInt32("profile", profile);
    428         }
    429     }
    430 }
    431 
    432 static void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    433     const uint8_t *data = csd->data();
    434     // find visual object sequence
    435     const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
    436     if (seq != NULL && seq + 4 < data + csd->size()) {
    437         const uint8_t indication = seq[4];
    438 
    439         const static ALookup<uint8_t,
    440                 std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
    441             { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level1  } },
    442             { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level2  } },
    443             { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level3  } },
    444             { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level4a } },
    445             { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level5  } },
    446             { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level6  } },
    447             { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0  } },
    448             { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0b } },
    449             { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level0  } },
    450             { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level1  } },
    451             { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level2  } },
    452             /* unsupported
    453             { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level0  } },
    454             { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level1  } },
    455             { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level2  } }, */
    456             { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level1  } },
    457             { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level2  } },
    458             { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level2  } },
    459             { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level3  } },
    460             { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level4  } },
    461             /* deprecated
    462             { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit,              OMX_VIDEO_MPEG4Level2  } }, */
    463             { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture,   OMX_VIDEO_MPEG4Level1  } },
    464             { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level1  } },
    465             { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level2  } },
    466             { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level1  } },
    467             { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level2  } },
    468             { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level1  } },
    469             { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level2  } },
    470             { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level1  } },
    471             { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level2  } },
    472             { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level1  } },
    473             { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level2  } },
    474             { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level3  } },
    475             { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level4  } },
    476             { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level1  } },
    477             { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level2  } },
    478             { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level3  } },
    479             { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level1  } },
    480             { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level2  } },
    481             { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level3  } },
    482             { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level4  } },
    483             { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level1  } },
    484             { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level2  } },
    485             { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level1  } },
    486             { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level2  } },
    487             { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level3  } },
    488             /* unsupported
    489             { 0b11100001, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level1  } },
    490             { 0b11100010, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level2  } },
    491             { 0b11100011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level3  } },
    492             { 0b11100100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level4  } },
    493             { 0b11100101, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level1  } },
    494             { 0b11100110, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level2  } },
    495             { 0b11100111, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level3  } },
    496             { 0b11101000, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level4  } },
    497             { 0b11101011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level5  } },
    498             { 0b11101100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level6  } }, */
    499             { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level0  } },
    500             { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level1  } },
    501             { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level2  } },
    502             { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3  } },
    503             { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level4  } },
    504             { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level5  } },
    505             { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3b } },
    506             /* deprecated
    507             { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0  } },
    508             { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1  } },
    509             { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2  } },
    510             { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3  } },
    511             { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4  } },
    512             { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5  } }, */
    513         };
    514 
    515         std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
    516         if (table.map(indication, &profileLevel)) {
    517             format->setInt32("profile", profileLevel.first);
    518             format->setInt32("level", profileLevel.second);
    519         }
    520     }
    521 }
    522 
    523 static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    524     const uint8_t *data = csd->data();
    525     size_t remaining = csd->size();
    526 
    527     while (remaining >= 2) {
    528         const uint8_t id = data[0];
    529         const uint8_t length = data[1];
    530         remaining -= 2;
    531         data += 2;
    532         if (length > remaining) {
    533             break;
    534         }
    535         switch (id) {
    536             case 1 /* profileId */:
    537                 if (length >= 1) {
    538                     const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
    539                         { 0, OMX_VIDEO_VP9Profile0 },
    540                         { 1, OMX_VIDEO_VP9Profile1 },
    541                         { 2, OMX_VIDEO_VP9Profile2 },
    542                         { 3, OMX_VIDEO_VP9Profile3 },
    543                     };
    544 
    545                     const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr {
    546                         { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR },
    547                         { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR },
    548                     };
    549 
    550                     OMX_VIDEO_VP9PROFILETYPE profile;
    551                     if (profiles.map(data[0], &profile)) {
    552                         // convert to HDR profile
    553                         if (isHdr(format)) {
    554                             toHdr.lookup(profile, &profile);
    555                         }
    556 
    557                         format->setInt32("profile", profile);
    558                     }
    559                 }
    560                 break;
    561             case 2 /* levelId */:
    562                 if (length >= 1) {
    563                     const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
    564                         { 10, OMX_VIDEO_VP9Level1  },
    565                         { 11, OMX_VIDEO_VP9Level11 },
    566                         { 20, OMX_VIDEO_VP9Level2  },
    567                         { 21, OMX_VIDEO_VP9Level21 },
    568                         { 30, OMX_VIDEO_VP9Level3  },
    569                         { 31, OMX_VIDEO_VP9Level31 },
    570                         { 40, OMX_VIDEO_VP9Level4  },
    571                         { 41, OMX_VIDEO_VP9Level41 },
    572                         { 50, OMX_VIDEO_VP9Level5  },
    573                         { 51, OMX_VIDEO_VP9Level51 },
    574                         { 52, OMX_VIDEO_VP9Level52 },
    575                         { 60, OMX_VIDEO_VP9Level6  },
    576                         { 61, OMX_VIDEO_VP9Level61 },
    577                         { 62, OMX_VIDEO_VP9Level62 },
    578                     };
    579 
    580                     OMX_VIDEO_VP9LEVELTYPE level;
    581                     if (levels.map(data[0], &level)) {
    582                         format->setInt32("level", level);
    583                     }
    584                 }
    585                 break;
    586             default:
    587                 break;
    588         }
    589         remaining -= length;
    590         data += length;
    591     }
    592 }
    593 
    594 status_t convertMetaDataToMessage(
    595         const sp<MetaData> &meta, sp<AMessage> *format) {
    596 
    597     format->clear();
    598 
    599     if (meta == NULL) {
    600         ALOGE("convertMetaDataToMessage: NULL input");
    601         return BAD_VALUE;
    602     }
    603 
    604     const char *mime;
    605     if (!meta->findCString(kKeyMIMEType, &mime)) {
    606         return BAD_VALUE;
    607     }
    608 
    609     sp<AMessage> msg = new AMessage;
    610     msg->setString("mime", mime);
    611 
    612     int64_t durationUs;
    613     if (meta->findInt64(kKeyDuration, &durationUs)) {
    614         msg->setInt64("durationUs", durationUs);
    615     }
    616 
    617     int32_t avgBitRate = 0;
    618     if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
    619         msg->setInt32("bitrate", avgBitRate);
    620     }
    621 
    622     int32_t maxBitRate;
    623     if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
    624             && maxBitRate > 0 && maxBitRate >= avgBitRate) {
    625         msg->setInt32("max-bitrate", maxBitRate);
    626     }
    627 
    628     int32_t isSync;
    629     if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
    630         msg->setInt32("is-sync-frame", 1);
    631     }
    632 
    633     // this only needs to be translated from meta to message as it is an extractor key
    634     int32_t trackID;
    635     if (meta->findInt32(kKeyTrackID, &trackID)) {
    636         msg->setInt32("track-id", trackID);
    637     }
    638 
    639     if (!strncasecmp("video/", mime, 6)) {
    640         int32_t width, height;
    641         if (!meta->findInt32(kKeyWidth, &width)
    642                 || !meta->findInt32(kKeyHeight, &height)) {
    643             return BAD_VALUE;
    644         }
    645 
    646         msg->setInt32("width", width);
    647         msg->setInt32("height", height);
    648 
    649         int32_t sarWidth, sarHeight;
    650         if (meta->findInt32(kKeySARWidth, &sarWidth)
    651                 && meta->findInt32(kKeySARHeight, &sarHeight)) {
    652             msg->setInt32("sar-width", sarWidth);
    653             msg->setInt32("sar-height", sarHeight);
    654         }
    655 
    656         int32_t colorFormat;
    657         if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
    658             msg->setInt32("color-format", colorFormat);
    659         }
    660 
    661         int32_t cropLeft, cropTop, cropRight, cropBottom;
    662         if (meta->findRect(kKeyCropRect,
    663                            &cropLeft,
    664                            &cropTop,
    665                            &cropRight,
    666                            &cropBottom)) {
    667             msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
    668         }
    669 
    670         int32_t rotationDegrees;
    671         if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
    672             msg->setInt32("rotation-degrees", rotationDegrees);
    673         }
    674 
    675         uint32_t type;
    676         const void *data;
    677         size_t size;
    678         if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
    679                 && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
    680             ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
    681         }
    682 
    683         convertMetaDataToMessageColorAspects(meta, msg);
    684     } else if (!strncasecmp("audio/", mime, 6)) {
    685         int32_t numChannels, sampleRate;
    686         if (!meta->findInt32(kKeyChannelCount, &numChannels)
    687                 || !meta->findInt32(kKeySampleRate, &sampleRate)) {
    688             return BAD_VALUE;
    689         }
    690 
    691         msg->setInt32("channel-count", numChannels);
    692         msg->setInt32("sample-rate", sampleRate);
    693 
    694         int32_t channelMask;
    695         if (meta->findInt32(kKeyChannelMask, &channelMask)) {
    696             msg->setInt32("channel-mask", channelMask);
    697         }
    698 
    699         int32_t delay = 0;
    700         if (meta->findInt32(kKeyEncoderDelay, &delay)) {
    701             msg->setInt32("encoder-delay", delay);
    702         }
    703         int32_t padding = 0;
    704         if (meta->findInt32(kKeyEncoderPadding, &padding)) {
    705             msg->setInt32("encoder-padding", padding);
    706         }
    707 
    708         int32_t isADTS;
    709         if (meta->findInt32(kKeyIsADTS, &isADTS)) {
    710             msg->setInt32("is-adts", isADTS);
    711         }
    712 
    713         int32_t aacProfile = -1;
    714         if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
    715             msg->setInt32("aac-profile", aacProfile);
    716         }
    717 
    718         int32_t pcmEncoding;
    719         if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
    720             msg->setInt32("pcm-encoding", pcmEncoding);
    721         }
    722     }
    723 
    724     int32_t maxInputSize;
    725     if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    726         msg->setInt32("max-input-size", maxInputSize);
    727     }
    728 
    729     int32_t maxWidth;
    730     if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
    731         msg->setInt32("max-width", maxWidth);
    732     }
    733 
    734     int32_t maxHeight;
    735     if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
    736         msg->setInt32("max-height", maxHeight);
    737     }
    738 
    739     int32_t rotationDegrees;
    740     if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
    741         msg->setInt32("rotation-degrees", rotationDegrees);
    742     }
    743 
    744     int32_t fps;
    745     if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
    746         msg->setInt32("frame-rate", fps);
    747     }
    748 
    749     uint32_t type;
    750     const void *data;
    751     size_t size;
    752     if (meta->findData(kKeyAVCC, &type, &data, &size)) {
    753         // Parse the AVCDecoderConfigurationRecord
    754 
    755         const uint8_t *ptr = (const uint8_t *)data;
    756 
    757         if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
    758             ALOGE("b/23680780");
    759             return BAD_VALUE;
    760         }
    761 
    762         parseAvcProfileLevelFromAvcc(ptr, size, msg);
    763 
    764         // There is decodable content out there that fails the following
    765         // assertion, let's be lenient for now...
    766         // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
    767 
    768         size_t lengthSize __unused = 1 + (ptr[4] & 3);
    769 
    770         // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
    771         // violates it...
    772         // CHECK((ptr[5] >> 5) == 7);  // reserved
    773 
    774         size_t numSeqParameterSets = ptr[5] & 31;
    775 
    776         ptr += 6;
    777         size -= 6;
    778 
    779         sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
    780         if (buffer.get() == NULL || buffer->base() == NULL) {
    781             return NO_MEMORY;
    782         }
    783         buffer->setRange(0, 0);
    784 
    785         for (size_t i = 0; i < numSeqParameterSets; ++i) {
    786             if (size < 2) {
    787                 ALOGE("b/23680780");
    788                 return BAD_VALUE;
    789             }
    790             size_t length = U16_AT(ptr);
    791 
    792             ptr += 2;
    793             size -= 2;
    794 
    795             if (size < length) {
    796                 return BAD_VALUE;
    797             }
    798             status_t err = copyNALUToABuffer(&buffer, ptr, length);
    799             if (err != OK) {
    800                 return err;
    801             }
    802 
    803             ptr += length;
    804             size -= length;
    805         }
    806 
    807         buffer->meta()->setInt32("csd", true);
    808         buffer->meta()->setInt64("timeUs", 0);
    809 
    810         msg->setBuffer("csd-0", buffer);
    811 
    812         buffer = new (std::nothrow) ABuffer(1024);
    813         if (buffer.get() == NULL || buffer->base() == NULL) {
    814             return NO_MEMORY;
    815         }
    816         buffer->setRange(0, 0);
    817 
    818         if (size < 1) {
    819             ALOGE("b/23680780");
    820             return BAD_VALUE;
    821         }
    822         size_t numPictureParameterSets = *ptr;
    823         ++ptr;
    824         --size;
    825 
    826         for (size_t i = 0; i < numPictureParameterSets; ++i) {
    827             if (size < 2) {
    828                 ALOGE("b/23680780");
    829                 return BAD_VALUE;
    830             }
    831             size_t length = U16_AT(ptr);
    832 
    833             ptr += 2;
    834             size -= 2;
    835 
    836             if (size < length) {
    837                 return BAD_VALUE;
    838             }
    839             status_t err = copyNALUToABuffer(&buffer, ptr, length);
    840             if (err != OK) {
    841                 return err;
    842             }
    843 
    844             ptr += length;
    845             size -= length;
    846         }
    847 
    848         buffer->meta()->setInt32("csd", true);
    849         buffer->meta()->setInt64("timeUs", 0);
    850         msg->setBuffer("csd-1", buffer);
    851     } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
    852         const uint8_t *ptr = (const uint8_t *)data;
    853 
    854         if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
    855             ALOGE("b/23680780");
    856             return BAD_VALUE;
    857         }
    858 
    859         const size_t dataSize = size; // save for later
    860         ptr += 22;
    861         size -= 22;
    862 
    863         size_t numofArrays = (char)ptr[0];
    864         ptr += 1;
    865         size -= 1;
    866         size_t j = 0, i = 0;
    867 
    868         sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
    869         if (buffer.get() == NULL || buffer->base() == NULL) {
    870             return NO_MEMORY;
    871         }
    872         buffer->setRange(0, 0);
    873 
    874         HevcParameterSets hvcc;
    875 
    876         for (i = 0; i < numofArrays; i++) {
    877             if (size < 3) {
    878                 ALOGE("b/23680780");
    879                 return BAD_VALUE;
    880             }
    881             ptr += 1;
    882             size -= 1;
    883 
    884             //Num of nals
    885             size_t numofNals = U16_AT(ptr);
    886 
    887             ptr += 2;
    888             size -= 2;
    889 
    890             for (j = 0; j < numofNals; j++) {
    891                 if (size < 2) {
    892                     ALOGE("b/23680780");
    893                     return BAD_VALUE;
    894                 }
    895                 size_t length = U16_AT(ptr);
    896 
    897                 ptr += 2;
    898                 size -= 2;
    899 
    900                 if (size < length) {
    901                     return BAD_VALUE;
    902                 }
    903                 status_t err = copyNALUToABuffer(&buffer, ptr, length);
    904                 if (err != OK) {
    905                     return err;
    906                 }
    907                 (void)hvcc.addNalUnit(ptr, length);
    908 
    909                 ptr += length;
    910                 size -= length;
    911             }
    912         }
    913         buffer->meta()->setInt32("csd", true);
    914         buffer->meta()->setInt64("timeUs", 0);
    915         msg->setBuffer("csd-0", buffer);
    916 
    917         // if we saw VUI color information we know whether this is HDR because VUI trumps other
    918         // format parameters for HEVC.
    919         HevcParameterSets::Info info = hvcc.getInfo();
    920         if (info & hvcc.kInfoHasColorDescription) {
    921             msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
    922         }
    923 
    924         parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
    925     } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
    926         ESDS esds((const char *)data, size);
    927         if (esds.InitCheck() != (status_t)OK) {
    928             return BAD_VALUE;
    929         }
    930 
    931         const void *codec_specific_data;
    932         size_t codec_specific_data_size;
    933         esds.getCodecSpecificInfo(
    934                 &codec_specific_data, &codec_specific_data_size);
    935 
    936         sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
    937         if (buffer.get() == NULL || buffer->base() == NULL) {
    938             return NO_MEMORY;
    939         }
    940 
    941         memcpy(buffer->data(), codec_specific_data,
    942                codec_specific_data_size);
    943 
    944         buffer->meta()->setInt32("csd", true);
    945         buffer->meta()->setInt64("timeUs", 0);
    946         msg->setBuffer("csd-0", buffer);
    947 
    948         if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
    949             parseMpeg4ProfileLevelFromCsd(buffer, msg);
    950         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
    951             parseMpeg2ProfileLevelFromEsds(esds, msg);
    952             if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
    953                 parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
    954             }
    955         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    956             parseAacProfileFromCsd(buffer, msg);
    957         }
    958 
    959         uint32_t maxBitrate, avgBitrate;
    960         if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
    961             if (!meta->hasData(kKeyBitRate)
    962                     && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
    963                 msg->setInt32("bitrate", (int32_t)avgBitrate);
    964             } else {
    965                 (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
    966             }
    967             if (!meta->hasData(kKeyMaxBitRate)
    968                     && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
    969                 msg->setInt32("max-bitrate", (int32_t)maxBitrate);
    970             }
    971         }
    972     } else if (meta->findData(kTypeD263, &type, &data, &size)) {
    973         const uint8_t *ptr = (const uint8_t *)data;
    974         parseH263ProfileLevelFromD263(ptr, size, msg);
    975     } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
    976         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
    977         if (buffer.get() == NULL || buffer->base() == NULL) {
    978             return NO_MEMORY;
    979         }
    980         memcpy(buffer->data(), data, size);
    981 
    982         buffer->meta()->setInt32("csd", true);
    983         buffer->meta()->setInt64("timeUs", 0);
    984         msg->setBuffer("csd-0", buffer);
    985 
    986         if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
    987             return -EINVAL;
    988         }
    989 
    990         buffer = new (std::nothrow) ABuffer(size);
    991         if (buffer.get() == NULL || buffer->base() == NULL) {
    992             return NO_MEMORY;
    993         }
    994         memcpy(buffer->data(), data, size);
    995 
    996         buffer->meta()->setInt32("csd", true);
    997         buffer->meta()->setInt64("timeUs", 0);
    998         msg->setBuffer("csd-1", buffer);
    999     } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
   1000         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1001         if (buffer.get() == NULL || buffer->base() == NULL) {
   1002             return NO_MEMORY;
   1003         }
   1004         memcpy(buffer->data(), data, size);
   1005 
   1006         buffer->meta()->setInt32("csd", true);
   1007         buffer->meta()->setInt64("timeUs", 0);
   1008         msg->setBuffer("csd-0", buffer);
   1009 
   1010         if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
   1011             return -EINVAL;
   1012         }
   1013 
   1014         buffer = new (std::nothrow) ABuffer(size);
   1015         if (buffer.get() == NULL || buffer->base() == NULL) {
   1016             return NO_MEMORY;
   1017         }
   1018         memcpy(buffer->data(), data, size);
   1019 
   1020         buffer->meta()->setInt32("csd", true);
   1021         buffer->meta()->setInt64("timeUs", 0);
   1022         msg->setBuffer("csd-1", buffer);
   1023 
   1024         if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
   1025             return -EINVAL;
   1026         }
   1027 
   1028         buffer = new (std::nothrow) ABuffer(size);
   1029         if (buffer.get() == NULL || buffer->base() == NULL) {
   1030             return NO_MEMORY;
   1031         }
   1032         memcpy(buffer->data(), data, size);
   1033 
   1034         buffer->meta()->setInt32("csd", true);
   1035         buffer->meta()->setInt64("timeUs", 0);
   1036         msg->setBuffer("csd-2", buffer);
   1037     } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
   1038         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1039         if (buffer.get() == NULL || buffer->base() == NULL) {
   1040             return NO_MEMORY;
   1041         }
   1042         memcpy(buffer->data(), data, size);
   1043 
   1044         buffer->meta()->setInt32("csd", true);
   1045         buffer->meta()->setInt64("timeUs", 0);
   1046         msg->setBuffer("csd-0", buffer);
   1047 
   1048         parseVp9ProfileLevelFromCsd(buffer, msg);
   1049     }
   1050 
   1051     // TODO expose "crypto-key"/kKeyCryptoKey through public api
   1052     if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
   1053         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1054         msg->setBuffer("crypto-key", buffer);
   1055         memcpy(buffer->data(), data, size);
   1056     }
   1057 
   1058     *format = msg;
   1059 
   1060     return OK;
   1061 }
   1062 
   1063 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
   1064     uint8_t *res = NULL;
   1065     if (length > 4) {
   1066         // minus 1 as to not match NAL start code at end
   1067         res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
   1068     }
   1069     return res != NULL && res < data + length - 4 ? res : &data[length];
   1070 }
   1071 
   1072 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> csd1, char *avcc) {
   1073     avcc[0] = 1;        // version
   1074     avcc[1] = 0x64;     // profile (default to high)
   1075     avcc[2] = 0;        // constraints (default to none)
   1076     avcc[3] = 0xd;      // level (default to 1.3)
   1077     avcc[4] = 0xff;     // reserved+size
   1078 
   1079     size_t i = 0;
   1080     int numparams = 0;
   1081     int lastparamoffset = 0;
   1082     int avccidx = 6;
   1083     do {
   1084         i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
   1085         ALOGV("block at %zu, last was %d", i, lastparamoffset);
   1086         if (lastparamoffset > 0) {
   1087             const uint8_t *lastparam = csd0->data() + lastparamoffset;
   1088             int size = i - lastparamoffset;
   1089             if (size > 3) {
   1090                 if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
   1091                     ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
   1092                             avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
   1093                 } else if (!numparams) {
   1094                     // fill in profile, constraints and level
   1095                     memcpy(avcc + 1, lastparam + 1, 3);
   1096                 }
   1097             }
   1098             avcc[avccidx++] = size >> 8;
   1099             avcc[avccidx++] = size & 0xff;
   1100             memcpy(avcc+avccidx, lastparam, size);
   1101             avccidx += size;
   1102             numparams++;
   1103         }
   1104         i += 4;
   1105         lastparamoffset = i;
   1106     } while(i < csd0->size());
   1107     ALOGV("csd0 contains %d params", numparams);
   1108 
   1109     avcc[5] = 0xe0 | numparams;
   1110     //and now csd-1
   1111     i = 0;
   1112     numparams = 0;
   1113     lastparamoffset = 0;
   1114     int numpicparamsoffset = avccidx;
   1115     avccidx++;
   1116     do {
   1117         i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
   1118         ALOGV("block at %zu, last was %d", i, lastparamoffset);
   1119         if (lastparamoffset > 0) {
   1120             int size = i - lastparamoffset;
   1121             avcc[avccidx++] = size >> 8;
   1122             avcc[avccidx++] = size & 0xff;
   1123             memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
   1124             avccidx += size;
   1125             numparams++;
   1126         }
   1127         i += 4;
   1128         lastparamoffset = i;
   1129     } while(i < csd1->size());
   1130     avcc[numpicparamsoffset] = numparams;
   1131     return avccidx;
   1132 }
   1133 
   1134 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
   1135     int csd0size = csd0->size();
   1136     esds[0] = 3; // kTag_ESDescriptor;
   1137     int esdescriptorsize = 26 + csd0size;
   1138     CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
   1139     esds[1] = 0x80 | (esdescriptorsize >> 21);
   1140     esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
   1141     esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
   1142     esds[4] = (esdescriptorsize & 0x7f);
   1143     esds[5] = esds[6] = 0; // es id
   1144     esds[7] = 0; // flags
   1145     esds[8] = 4; // kTag_DecoderConfigDescriptor
   1146     int configdescriptorsize = 18 + csd0size;
   1147     esds[9] = 0x80 | (configdescriptorsize >> 21);
   1148     esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
   1149     esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
   1150     esds[12] = (configdescriptorsize & 0x7f);
   1151     esds[13] = 0x40; // objectTypeIndication
   1152     // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
   1153     esds[14] = 0x15; // streamType(5), upStream(0),
   1154     esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
   1155     esds[16] = 0x18;
   1156     esds[17] = 0x00;
   1157     esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
   1158     esds[19] = 0x00;
   1159     esds[20] = 0xfa;
   1160     esds[21] = 0x00;
   1161     esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
   1162     esds[23] = 0x00;
   1163     esds[24] = 0xfa;
   1164     esds[25] = 0x00;
   1165     esds[26] = 5; // kTag_DecoderSpecificInfo;
   1166     esds[27] = 0x80 | (csd0size >> 21);
   1167     esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
   1168     esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
   1169     esds[30] = (csd0size & 0x7f);
   1170     memcpy((void*)&esds[31], csd0->data(), csd0size);
   1171     // data following this is ignored, so don't bother appending it
   1172 }
   1173 
   1174 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
   1175     HevcParameterSets paramSets;
   1176     uint8_t* data = csd0->data();
   1177     if (csd0->size() < 4) {
   1178         ALOGE("csd0 too small");
   1179         return 0;
   1180     }
   1181     if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
   1182         ALOGE("csd0 doesn't start with a start code");
   1183         return 0;
   1184     }
   1185     size_t prevNalOffset = 4;
   1186     status_t err = OK;
   1187     for (size_t i = 1; i < csd0->size() - 4; ++i) {
   1188         if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
   1189             continue;
   1190         }
   1191         err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
   1192         if (err != OK) {
   1193             return 0;
   1194         }
   1195         prevNalOffset = i + 4;
   1196     }
   1197     err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
   1198     if (err != OK) {
   1199         return 0;
   1200     }
   1201     size_t size = hvccSize;
   1202     err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
   1203     if (err != OK) {
   1204         return 0;
   1205     }
   1206     return size;
   1207 }
   1208 
   1209 #if 0
   1210 static void convertMessageToMetaDataInt32(
   1211         const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
   1212     int32_t value;
   1213     if (msg->findInt32(name, &value)) {
   1214         meta->setInt32(key, value);
   1215     }
   1216 }
   1217 #endif
   1218 
   1219 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
   1220     // 0 values are unspecified
   1221     int32_t range = 0, standard = 0, transfer = 0;
   1222     (void)msg->findInt32("color-range", &range);
   1223     (void)msg->findInt32("color-standard", &standard);
   1224     (void)msg->findInt32("color-transfer", &transfer);
   1225 
   1226     ColorAspects colorAspects;
   1227     memset(&colorAspects, 0, sizeof(colorAspects));
   1228     if (CodecBase::convertPlatformColorAspectsToCodecAspects(
   1229             range, standard, transfer, colorAspects) != OK) {
   1230         return;
   1231     }
   1232 
   1233     // save specified values to meta
   1234     if (colorAspects.mRange != 0) {
   1235         meta->setInt32(kKeyColorRange, colorAspects.mRange);
   1236     }
   1237     if (colorAspects.mPrimaries != 0) {
   1238         meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
   1239     }
   1240     if (colorAspects.mTransfer != 0) {
   1241         meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
   1242     }
   1243     if (colorAspects.mMatrixCoeffs != 0) {
   1244         meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
   1245     }
   1246 }
   1247 
   1248 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
   1249     AString mime;
   1250     if (msg->findString("mime", &mime)) {
   1251         meta->setCString(kKeyMIMEType, mime.c_str());
   1252     } else {
   1253         ALOGW("did not find mime type");
   1254     }
   1255 
   1256     int64_t durationUs;
   1257     if (msg->findInt64("durationUs", &durationUs)) {
   1258         meta->setInt64(kKeyDuration, durationUs);
   1259     }
   1260 
   1261     int32_t isSync;
   1262     if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
   1263         meta->setInt32(kKeyIsSyncFrame, 1);
   1264     }
   1265 
   1266     int32_t avgBitrate = 0;
   1267     int32_t maxBitrate;
   1268     if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
   1269         meta->setInt32(kKeyBitRate, avgBitrate);
   1270     }
   1271     if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
   1272         meta->setInt32(kKeyMaxBitRate, maxBitrate);
   1273     }
   1274 
   1275     if (mime.startsWith("video/")) {
   1276         int32_t width;
   1277         int32_t height;
   1278         if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
   1279             meta->setInt32(kKeyWidth, width);
   1280             meta->setInt32(kKeyHeight, height);
   1281         } else {
   1282             ALOGW("did not find width and/or height");
   1283         }
   1284 
   1285         int32_t sarWidth, sarHeight;
   1286         if (msg->findInt32("sar-width", &sarWidth)
   1287                 && msg->findInt32("sar-height", &sarHeight)) {
   1288             meta->setInt32(kKeySARWidth, sarWidth);
   1289             meta->setInt32(kKeySARHeight, sarHeight);
   1290         }
   1291 
   1292         int32_t colorFormat;
   1293         if (msg->findInt32("color-format", &colorFormat)) {
   1294             meta->setInt32(kKeyColorFormat, colorFormat);
   1295         }
   1296 
   1297         int32_t cropLeft, cropTop, cropRight, cropBottom;
   1298         if (msg->findRect("crop",
   1299                           &cropLeft,
   1300                           &cropTop,
   1301                           &cropRight,
   1302                           &cropBottom)) {
   1303             meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
   1304         }
   1305 
   1306         int32_t rotationDegrees;
   1307         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
   1308             meta->setInt32(kKeyRotation, rotationDegrees);
   1309         }
   1310 
   1311         if (msg->contains("hdr-static-info")) {
   1312             HDRStaticInfo info;
   1313             if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
   1314                 meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
   1315             }
   1316         }
   1317 
   1318         convertMessageToMetaDataColorAspects(msg, meta);
   1319     } else if (mime.startsWith("audio/")) {
   1320         int32_t numChannels;
   1321         if (msg->findInt32("channel-count", &numChannels)) {
   1322             meta->setInt32(kKeyChannelCount, numChannels);
   1323         }
   1324         int32_t sampleRate;
   1325         if (msg->findInt32("sample-rate", &sampleRate)) {
   1326             meta->setInt32(kKeySampleRate, sampleRate);
   1327         }
   1328         int32_t channelMask;
   1329         if (msg->findInt32("channel-mask", &channelMask)) {
   1330             meta->setInt32(kKeyChannelMask, channelMask);
   1331         }
   1332         int32_t delay = 0;
   1333         if (msg->findInt32("encoder-delay", &delay)) {
   1334             meta->setInt32(kKeyEncoderDelay, delay);
   1335         }
   1336         int32_t padding = 0;
   1337         if (msg->findInt32("encoder-padding", &padding)) {
   1338             meta->setInt32(kKeyEncoderPadding, padding);
   1339         }
   1340 
   1341         int32_t isADTS;
   1342         if (msg->findInt32("is-adts", &isADTS)) {
   1343             meta->setInt32(kKeyIsADTS, isADTS);
   1344         }
   1345 
   1346         int32_t pcmEncoding;
   1347         if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
   1348             meta->setInt32(kKeyPcmEncoding, pcmEncoding);
   1349         }
   1350     }
   1351 
   1352     int32_t maxInputSize;
   1353     if (msg->findInt32("max-input-size", &maxInputSize)) {
   1354         meta->setInt32(kKeyMaxInputSize, maxInputSize);
   1355     }
   1356 
   1357     int32_t maxWidth;
   1358     if (msg->findInt32("max-width", &maxWidth)) {
   1359         meta->setInt32(kKeyMaxWidth, maxWidth);
   1360     }
   1361 
   1362     int32_t maxHeight;
   1363     if (msg->findInt32("max-height", &maxHeight)) {
   1364         meta->setInt32(kKeyMaxHeight, maxHeight);
   1365     }
   1366 
   1367     int32_t fps;
   1368     float fpsFloat;
   1369     if (msg->findInt32("frame-rate", &fps) && fps > 0) {
   1370         meta->setInt32(kKeyFrameRate, fps);
   1371     } else if (msg->findFloat("frame-rate", &fpsFloat)
   1372             && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
   1373         // truncate values to distinguish between e.g. 24 vs 23.976 fps
   1374         meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
   1375     }
   1376 
   1377     // reassemble the csd data into its original form
   1378     sp<ABuffer> csd0, csd1, csd2;
   1379     if (msg->findBuffer("csd-0", &csd0)) {
   1380         if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
   1381             sp<ABuffer> csd1;
   1382             if (msg->findBuffer("csd-1", &csd1)) {
   1383                 char avcc[1024]; // that oughta be enough, right?
   1384                 size_t outsize = reassembleAVCC(csd0, csd1, avcc);
   1385                 meta->setData(kKeyAVCC, kKeyAVCC, avcc, outsize);
   1386             }
   1387         } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
   1388             int csd0size = csd0->size();
   1389             char esds[csd0size + 31];
   1390             // The written ESDS is actually for an audio stream, but it's enough
   1391             // for transporting the CSD to muxers.
   1392             reassembleESDS(csd0, esds);
   1393             meta->setData(kKeyESDS, kKeyESDS, esds, sizeof(esds));
   1394         } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
   1395             uint8_t hvcc[1024]; // that oughta be enough, right?
   1396             size_t outsize = reassembleHVCC(csd0, hvcc, 1024, 4);
   1397             meta->setData(kKeyHVCC, kKeyHVCC, hvcc, outsize);
   1398         } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
   1399             meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
   1400         } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
   1401             meta->setData(kKeyOpusHeader, 0, csd0->data(), csd0->size());
   1402             if (msg->findBuffer("csd-1", &csd1)) {
   1403                 meta->setData(kKeyOpusCodecDelay, 0, csd1->data(), csd1->size());
   1404             }
   1405             if (msg->findBuffer("csd-2", &csd2)) {
   1406                 meta->setData(kKeyOpusSeekPreRoll, 0, csd2->data(), csd2->size());
   1407             }
   1408         } else if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
   1409             meta->setData(kKeyVorbisInfo, 0, csd0->data(), csd0->size());
   1410             if (msg->findBuffer("csd-1", &csd1)) {
   1411                 meta->setData(kKeyVorbisBooks, 0, csd1->data(), csd1->size());
   1412             }
   1413         }
   1414     }
   1415 
   1416     int32_t timeScale;
   1417     if (msg->findInt32("time-scale", &timeScale)) {
   1418         meta->setInt32(kKeyTimeScale, timeScale);
   1419     }
   1420 
   1421     // XXX TODO add whatever other keys there are
   1422 
   1423 #if 0
   1424     ALOGI("converted %s to:", msg->debugString(0).c_str());
   1425     meta->dumpToLog();
   1426 #endif
   1427 }
   1428 
   1429 AString MakeUserAgent() {
   1430     AString ua;
   1431     ua.append("stagefright/1.2 (Linux;Android ");
   1432 
   1433 #if (PROPERTY_VALUE_MAX < 8)
   1434 #error "PROPERTY_VALUE_MAX must be at least 8"
   1435 #endif
   1436 
   1437     char value[PROPERTY_VALUE_MAX];
   1438     property_get("ro.build.version.release", value, "Unknown");
   1439     ua.append(value);
   1440     ua.append(")");
   1441 
   1442     return ua;
   1443 }
   1444 
   1445 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
   1446                            const sp<MetaData>& meta)
   1447 {
   1448     int32_t sampleRate = 0;
   1449     int32_t bitRate = 0;
   1450     int32_t channelMask = 0;
   1451     int32_t delaySamples = 0;
   1452     int32_t paddingSamples = 0;
   1453 
   1454     AudioParameter param = AudioParameter();
   1455 
   1456     if (meta->findInt32(kKeySampleRate, &sampleRate)) {
   1457         param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
   1458     }
   1459     if (meta->findInt32(kKeyChannelMask, &channelMask)) {
   1460         param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
   1461     }
   1462     if (meta->findInt32(kKeyBitRate, &bitRate)) {
   1463         param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
   1464     }
   1465     if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
   1466         param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
   1467     }
   1468     if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
   1469         param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
   1470     }
   1471 
   1472     ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
   1473           "delaySample %d, paddingSample %d", bitRate, sampleRate,
   1474           channelMask, delaySamples, paddingSamples);
   1475 
   1476     sink->setParameters(param.toString());
   1477     return OK;
   1478 }
   1479 
   1480 struct mime_conv_t {
   1481     const char* mime;
   1482     audio_format_t format;
   1483 };
   1484 
   1485 static const struct mime_conv_t mimeLookup[] = {
   1486     { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
   1487     { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
   1488     { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
   1489     { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
   1490     { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
   1491     { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
   1492     { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
   1493     { 0, AUDIO_FORMAT_INVALID }
   1494 };
   1495 
   1496 status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
   1497 {
   1498 const struct mime_conv_t* p = &mimeLookup[0];
   1499     while (p->mime != NULL) {
   1500         if (0 == strcasecmp(mime, p->mime)) {
   1501             format = p->format;
   1502             return OK;
   1503         }
   1504         ++p;
   1505     }
   1506 
   1507     return BAD_VALUE;
   1508 }
   1509 
   1510 struct aac_format_conv_t {
   1511     OMX_AUDIO_AACPROFILETYPE eAacProfileType;
   1512     audio_format_t format;
   1513 };
   1514 
   1515 static const struct aac_format_conv_t profileLookup[] = {
   1516     { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
   1517     { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
   1518     { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
   1519     { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
   1520     { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
   1521     { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
   1522     { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
   1523     { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
   1524     { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
   1525     { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
   1526     { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
   1527 };
   1528 
   1529 void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
   1530 {
   1531 const struct aac_format_conv_t* p = &profileLookup[0];
   1532     while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
   1533         if (eAacProfile == p->eAacProfileType) {
   1534             format = p->format;
   1535             return;
   1536         }
   1537         ++p;
   1538     }
   1539     format = AUDIO_FORMAT_AAC;
   1540     return;
   1541 }
   1542 
   1543 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
   1544                       bool isStreaming, audio_stream_type_t streamType)
   1545 {
   1546     const char *mime;
   1547     if (meta == NULL) {
   1548         return false;
   1549     }
   1550     CHECK(meta->findCString(kKeyMIMEType, &mime));
   1551 
   1552     audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
   1553 
   1554     info.format = AUDIO_FORMAT_INVALID;
   1555     if (mapMimeToAudioFormat(info.format, mime) != OK) {
   1556         ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
   1557         return false;
   1558     } else {
   1559         ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
   1560     }
   1561 
   1562     if (AUDIO_FORMAT_INVALID == info.format) {
   1563         // can't offload if we don't know what the source format is
   1564         ALOGE("mime type \"%s\" not a known audio format", mime);
   1565         return false;
   1566     }
   1567 
   1568     // Redefine aac format according to its profile
   1569     // Offloading depends on audio DSP capabilities.
   1570     int32_t aacaot = -1;
   1571     if (meta->findInt32(kKeyAACAOT, &aacaot)) {
   1572         mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
   1573     }
   1574 
   1575     int32_t srate = -1;
   1576     if (!meta->findInt32(kKeySampleRate, &srate)) {
   1577         ALOGV("track of type '%s' does not publish sample rate", mime);
   1578     }
   1579     info.sample_rate = srate;
   1580 
   1581     int32_t cmask = 0;
   1582     if (!meta->findInt32(kKeyChannelMask, &cmask)) {
   1583         ALOGV("track of type '%s' does not publish channel mask", mime);
   1584 
   1585         // Try a channel count instead
   1586         int32_t channelCount;
   1587         if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
   1588             ALOGV("track of type '%s' does not publish channel count", mime);
   1589         } else {
   1590             cmask = audio_channel_out_mask_from_count(channelCount);
   1591         }
   1592     }
   1593     info.channel_mask = cmask;
   1594 
   1595     int64_t duration = 0;
   1596     if (!meta->findInt64(kKeyDuration, &duration)) {
   1597         ALOGV("track of type '%s' does not publish duration", mime);
   1598     }
   1599     info.duration_us = duration;
   1600 
   1601     int32_t brate = -1;
   1602     if (!meta->findInt32(kKeyBitRate, &brate)) {
   1603         ALOGV("track of type '%s' does not publish bitrate", mime);
   1604     }
   1605     info.bit_rate = brate;
   1606 
   1607 
   1608     info.stream_type = streamType;
   1609     info.has_video = hasVideo;
   1610     info.is_streaming = isStreaming;
   1611 
   1612     // Check if offload is possible for given format, stream type, sample rate,
   1613     // bit rate, duration, video and streaming
   1614     return AudioSystem::isOffloadSupported(info);
   1615 }
   1616 
   1617 AString uriDebugString(const AString &uri, bool incognito) {
   1618     if (incognito) {
   1619         return AString("<URI suppressed>");
   1620     }
   1621 
   1622     char prop[PROPERTY_VALUE_MAX];
   1623     if (property_get("media.stagefright.log-uri", prop, "false") &&
   1624         (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
   1625         return uri;
   1626     }
   1627 
   1628     // find scheme
   1629     AString scheme;
   1630     const char *chars = uri.c_str();
   1631     for (size_t i = 0; i < uri.size(); i++) {
   1632         const char c = chars[i];
   1633         if (!isascii(c)) {
   1634             break;
   1635         } else if (isalpha(c)) {
   1636             continue;
   1637         } else if (i == 0) {
   1638             // first character must be a letter
   1639             break;
   1640         } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
   1641             continue;
   1642         } else if (c != ':') {
   1643             break;
   1644         }
   1645         scheme = AString(uri, 0, i);
   1646         scheme.append("://<suppressed>");
   1647         return scheme;
   1648     }
   1649     return AString("<no-scheme URI suppressed>");
   1650 }
   1651 
   1652 HLSTime::HLSTime(const sp<AMessage>& meta) :
   1653     mSeq(-1),
   1654     mTimeUs(-1ll),
   1655     mMeta(meta) {
   1656     if (meta != NULL) {
   1657         CHECK(meta->findInt32("discontinuitySeq", &mSeq));
   1658         CHECK(meta->findInt64("timeUs", &mTimeUs));
   1659     }
   1660 }
   1661 
   1662 int64_t HLSTime::getSegmentTimeUs() const {
   1663     int64_t segmentStartTimeUs = -1ll;
   1664     if (mMeta != NULL) {
   1665         CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
   1666 
   1667         int64_t segmentFirstTimeUs;
   1668         if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
   1669             segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
   1670         }
   1671 
   1672         // adjust segment time by playlist age (for live streaming)
   1673         int64_t playlistTimeUs;
   1674         if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
   1675             int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
   1676 
   1677             int64_t durationUs;
   1678             CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
   1679 
   1680             // round to nearest whole segment
   1681             playlistAgeUs = (playlistAgeUs + durationUs / 2)
   1682                     / durationUs * durationUs;
   1683 
   1684             segmentStartTimeUs -= playlistAgeUs;
   1685             if (segmentStartTimeUs < 0) {
   1686                 segmentStartTimeUs = 0;
   1687             }
   1688         }
   1689     }
   1690     return segmentStartTimeUs;
   1691 }
   1692 
   1693 bool operator <(const HLSTime &t0, const HLSTime &t1) {
   1694     // we can only compare discontinuity sequence and timestamp.
   1695     // (mSegmentTimeUs is not reliable in live streaming case, it's the
   1696     // time starting from beginning of playlist but playlist could change.)
   1697     return t0.mSeq < t1.mSeq
   1698             || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
   1699 }
   1700 
   1701 void writeToAMessage(sp<AMessage> msg, const AudioPlaybackRate &rate) {
   1702     msg->setFloat("speed", rate.mSpeed);
   1703     msg->setFloat("pitch", rate.mPitch);
   1704     msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
   1705     msg->setInt32("audio-stretch-mode", rate.mStretchMode);
   1706 }
   1707 
   1708 void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
   1709     *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
   1710     CHECK(msg->findFloat("speed", &rate->mSpeed));
   1711     CHECK(msg->findFloat("pitch", &rate->mPitch));
   1712     CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
   1713     CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
   1714 }
   1715 
   1716 void writeToAMessage(sp<AMessage> msg, const AVSyncSettings &sync, float videoFpsHint) {
   1717     msg->setInt32("sync-source", sync.mSource);
   1718     msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
   1719     msg->setFloat("tolerance", sync.mTolerance);
   1720     msg->setFloat("video-fps", videoFpsHint);
   1721 }
   1722 
   1723 void readFromAMessage(
   1724         const sp<AMessage> &msg,
   1725         AVSyncSettings *sync /* nonnull */,
   1726         float *videoFps /* nonnull */) {
   1727     AVSyncSettings settings;
   1728     CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
   1729     CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
   1730     CHECK(msg->findFloat("tolerance", &settings.mTolerance));
   1731     CHECK(msg->findFloat("video-fps", videoFps));
   1732     *sync = settings;
   1733 }
   1734 
   1735 AString nameForFd(int fd) {
   1736     const size_t SIZE = 256;
   1737     char buffer[SIZE];
   1738     AString result;
   1739     snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
   1740     struct stat s;
   1741     if (lstat(buffer, &s) == 0) {
   1742         if ((s.st_mode & S_IFMT) == S_IFLNK) {
   1743             char linkto[256];
   1744             int len = readlink(buffer, linkto, sizeof(linkto));
   1745             if(len > 0) {
   1746                 if(len > 255) {
   1747                     linkto[252] = '.';
   1748                     linkto[253] = '.';
   1749                     linkto[254] = '.';
   1750                     linkto[255] = 0;
   1751                 } else {
   1752                     linkto[len] = 0;
   1753                 }
   1754                 result.append(linkto);
   1755             }
   1756         } else {
   1757             result.append("unexpected type for ");
   1758             result.append(buffer);
   1759         }
   1760     } else {
   1761         result.append("couldn't open ");
   1762         result.append(buffer);
   1763     }
   1764     return result;
   1765 }
   1766 
   1767 }  // namespace android
   1768 
   1769