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