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