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         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     uint32_t type;
    614     const void *data;
    615     size_t size;
    616     if (meta->findData(kKeyCASessionID, &type, &data, &size)) {
    617         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
    618         if (buffer.get() == NULL || buffer->base() == NULL) {
    619             return NO_MEMORY;
    620         }
    621 
    622         msg->setBuffer("ca-session-id", buffer);
    623         memcpy(buffer->data(), data, size);
    624     }
    625 
    626     int32_t systemId;
    627     if (meta->findInt32(kKeyCASystemID, &systemId)) {
    628         msg->setInt32("ca-system-id", systemId);
    629     }
    630 
    631     if (!strncasecmp("video/scrambled", mime, 15)
    632             || !strncasecmp("audio/scrambled", mime, 15)) {
    633 
    634         *format = msg;
    635         return OK;
    636     }
    637 
    638     int64_t durationUs;
    639     if (meta->findInt64(kKeyDuration, &durationUs)) {
    640         msg->setInt64("durationUs", durationUs);
    641     }
    642 
    643     int32_t avgBitRate = 0;
    644     if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
    645         msg->setInt32("bitrate", avgBitRate);
    646     }
    647 
    648     int32_t maxBitRate;
    649     if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
    650             && maxBitRate > 0 && maxBitRate >= avgBitRate) {
    651         msg->setInt32("max-bitrate", maxBitRate);
    652     }
    653 
    654     int32_t isSync;
    655     if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
    656         msg->setInt32("is-sync-frame", 1);
    657     }
    658 
    659     // this only needs to be translated from meta to message as it is an extractor key
    660     int32_t trackID;
    661     if (meta->findInt32(kKeyTrackID, &trackID)) {
    662         msg->setInt32("track-id", trackID);
    663     }
    664 
    665     const char *lang;
    666     if (meta->findCString(kKeyMediaLanguage, &lang)) {
    667         msg->setString("language", lang);
    668     }
    669 
    670     if (!strncasecmp("video/", mime, 6)) {
    671         int32_t width, height;
    672         if (!meta->findInt32(kKeyWidth, &width)
    673                 || !meta->findInt32(kKeyHeight, &height)) {
    674             return BAD_VALUE;
    675         }
    676 
    677         msg->setInt32("width", width);
    678         msg->setInt32("height", height);
    679 
    680         int32_t displayWidth, displayHeight;
    681         if (meta->findInt32(kKeyDisplayWidth, &displayWidth)
    682                 && meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
    683             msg->setInt32("display-width", displayWidth);
    684             msg->setInt32("display-height", displayHeight);
    685         }
    686 
    687         int32_t sarWidth, sarHeight;
    688         if (meta->findInt32(kKeySARWidth, &sarWidth)
    689                 && meta->findInt32(kKeySARHeight, &sarHeight)) {
    690             msg->setInt32("sar-width", sarWidth);
    691             msg->setInt32("sar-height", sarHeight);
    692         }
    693 
    694         int32_t colorFormat;
    695         if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
    696             msg->setInt32("color-format", colorFormat);
    697         }
    698 
    699         int32_t cropLeft, cropTop, cropRight, cropBottom;
    700         if (meta->findRect(kKeyCropRect,
    701                            &cropLeft,
    702                            &cropTop,
    703                            &cropRight,
    704                            &cropBottom)) {
    705             msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
    706         }
    707 
    708         int32_t rotationDegrees;
    709         if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
    710             msg->setInt32("rotation-degrees", rotationDegrees);
    711         }
    712 
    713         uint32_t type;
    714         const void *data;
    715         size_t size;
    716         if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
    717                 && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
    718             ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
    719         }
    720 
    721         convertMetaDataToMessageColorAspects(meta, msg);
    722     } else if (!strncasecmp("audio/", mime, 6)) {
    723         int32_t numChannels, sampleRate;
    724         if (!meta->findInt32(kKeyChannelCount, &numChannels)
    725                 || !meta->findInt32(kKeySampleRate, &sampleRate)) {
    726             return BAD_VALUE;
    727         }
    728 
    729         msg->setInt32("channel-count", numChannels);
    730         msg->setInt32("sample-rate", sampleRate);
    731 
    732         int32_t channelMask;
    733         if (meta->findInt32(kKeyChannelMask, &channelMask)) {
    734             msg->setInt32("channel-mask", channelMask);
    735         }
    736 
    737         int32_t delay = 0;
    738         if (meta->findInt32(kKeyEncoderDelay, &delay)) {
    739             msg->setInt32("encoder-delay", delay);
    740         }
    741         int32_t padding = 0;
    742         if (meta->findInt32(kKeyEncoderPadding, &padding)) {
    743             msg->setInt32("encoder-padding", padding);
    744         }
    745 
    746         int32_t isADTS;
    747         if (meta->findInt32(kKeyIsADTS, &isADTS)) {
    748             msg->setInt32("is-adts", isADTS);
    749         }
    750 
    751         int32_t aacProfile = -1;
    752         if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
    753             msg->setInt32("aac-profile", aacProfile);
    754         }
    755 
    756         int32_t pcmEncoding;
    757         if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
    758             msg->setInt32("pcm-encoding", pcmEncoding);
    759         }
    760     }
    761 
    762     int32_t maxInputSize;
    763     if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
    764         msg->setInt32("max-input-size", maxInputSize);
    765     }
    766 
    767     int32_t maxWidth;
    768     if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
    769         msg->setInt32("max-width", maxWidth);
    770     }
    771 
    772     int32_t maxHeight;
    773     if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
    774         msg->setInt32("max-height", maxHeight);
    775     }
    776 
    777     int32_t rotationDegrees;
    778     if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
    779         msg->setInt32("rotation-degrees", rotationDegrees);
    780     }
    781 
    782     int32_t fps;
    783     if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
    784         msg->setInt32("frame-rate", fps);
    785     }
    786 
    787     if (meta->findData(kKeyAVCC, &type, &data, &size)) {
    788         // Parse the AVCDecoderConfigurationRecord
    789 
    790         const uint8_t *ptr = (const uint8_t *)data;
    791 
    792         if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
    793             ALOGE("b/23680780");
    794             return BAD_VALUE;
    795         }
    796 
    797         parseAvcProfileLevelFromAvcc(ptr, size, msg);
    798 
    799         // There is decodable content out there that fails the following
    800         // assertion, let's be lenient for now...
    801         // CHECK((ptr[4] >> 2) == 0x3f);  // reserved
    802 
    803         size_t lengthSize __unused = 1 + (ptr[4] & 3);
    804 
    805         // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
    806         // violates it...
    807         // CHECK((ptr[5] >> 5) == 7);  // reserved
    808 
    809         size_t numSeqParameterSets = ptr[5] & 31;
    810 
    811         ptr += 6;
    812         size -= 6;
    813 
    814         sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
    815         if (buffer.get() == NULL || buffer->base() == NULL) {
    816             return NO_MEMORY;
    817         }
    818         buffer->setRange(0, 0);
    819 
    820         for (size_t i = 0; i < numSeqParameterSets; ++i) {
    821             if (size < 2) {
    822                 ALOGE("b/23680780");
    823                 return BAD_VALUE;
    824             }
    825             size_t length = U16_AT(ptr);
    826 
    827             ptr += 2;
    828             size -= 2;
    829 
    830             if (size < length) {
    831                 return BAD_VALUE;
    832             }
    833             status_t err = copyNALUToABuffer(&buffer, ptr, length);
    834             if (err != OK) {
    835                 return err;
    836             }
    837 
    838             ptr += length;
    839             size -= length;
    840         }
    841 
    842         buffer->meta()->setInt32("csd", true);
    843         buffer->meta()->setInt64("timeUs", 0);
    844 
    845         msg->setBuffer("csd-0", buffer);
    846 
    847         buffer = new (std::nothrow) ABuffer(1024);
    848         if (buffer.get() == NULL || buffer->base() == NULL) {
    849             return NO_MEMORY;
    850         }
    851         buffer->setRange(0, 0);
    852 
    853         if (size < 1) {
    854             ALOGE("b/23680780");
    855             return BAD_VALUE;
    856         }
    857         size_t numPictureParameterSets = *ptr;
    858         ++ptr;
    859         --size;
    860 
    861         for (size_t i = 0; i < numPictureParameterSets; ++i) {
    862             if (size < 2) {
    863                 ALOGE("b/23680780");
    864                 return BAD_VALUE;
    865             }
    866             size_t length = U16_AT(ptr);
    867 
    868             ptr += 2;
    869             size -= 2;
    870 
    871             if (size < length) {
    872                 return BAD_VALUE;
    873             }
    874             status_t err = copyNALUToABuffer(&buffer, ptr, length);
    875             if (err != OK) {
    876                 return err;
    877             }
    878 
    879             ptr += length;
    880             size -= length;
    881         }
    882 
    883         buffer->meta()->setInt32("csd", true);
    884         buffer->meta()->setInt64("timeUs", 0);
    885         msg->setBuffer("csd-1", buffer);
    886     } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
    887         const uint8_t *ptr = (const uint8_t *)data;
    888 
    889         if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
    890             ALOGE("b/23680780");
    891             return BAD_VALUE;
    892         }
    893 
    894         const size_t dataSize = size; // save for later
    895         ptr += 22;
    896         size -= 22;
    897 
    898         size_t numofArrays = (char)ptr[0];
    899         ptr += 1;
    900         size -= 1;
    901         size_t j = 0, i = 0;
    902 
    903         sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
    904         if (buffer.get() == NULL || buffer->base() == NULL) {
    905             return NO_MEMORY;
    906         }
    907         buffer->setRange(0, 0);
    908 
    909         HevcParameterSets hvcc;
    910 
    911         for (i = 0; i < numofArrays; i++) {
    912             if (size < 3) {
    913                 ALOGE("b/23680780");
    914                 return BAD_VALUE;
    915             }
    916             ptr += 1;
    917             size -= 1;
    918 
    919             //Num of nals
    920             size_t numofNals = U16_AT(ptr);
    921 
    922             ptr += 2;
    923             size -= 2;
    924 
    925             for (j = 0; j < numofNals; j++) {
    926                 if (size < 2) {
    927                     ALOGE("b/23680780");
    928                     return BAD_VALUE;
    929                 }
    930                 size_t length = U16_AT(ptr);
    931 
    932                 ptr += 2;
    933                 size -= 2;
    934 
    935                 if (size < length) {
    936                     return BAD_VALUE;
    937                 }
    938                 status_t err = copyNALUToABuffer(&buffer, ptr, length);
    939                 if (err != OK) {
    940                     return err;
    941                 }
    942                 (void)hvcc.addNalUnit(ptr, length);
    943 
    944                 ptr += length;
    945                 size -= length;
    946             }
    947         }
    948         buffer->meta()->setInt32("csd", true);
    949         buffer->meta()->setInt64("timeUs", 0);
    950         msg->setBuffer("csd-0", buffer);
    951 
    952         // if we saw VUI color information we know whether this is HDR because VUI trumps other
    953         // format parameters for HEVC.
    954         HevcParameterSets::Info info = hvcc.getInfo();
    955         if (info & hvcc.kInfoHasColorDescription) {
    956             msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
    957         }
    958 
    959         parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
    960     } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
    961         ESDS esds((const char *)data, size);
    962         if (esds.InitCheck() != (status_t)OK) {
    963             return BAD_VALUE;
    964         }
    965 
    966         const void *codec_specific_data;
    967         size_t codec_specific_data_size;
    968         esds.getCodecSpecificInfo(
    969                 &codec_specific_data, &codec_specific_data_size);
    970 
    971         sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
    972         if (buffer.get() == NULL || buffer->base() == NULL) {
    973             return NO_MEMORY;
    974         }
    975 
    976         memcpy(buffer->data(), codec_specific_data,
    977                codec_specific_data_size);
    978 
    979         buffer->meta()->setInt32("csd", true);
    980         buffer->meta()->setInt64("timeUs", 0);
    981         msg->setBuffer("csd-0", buffer);
    982 
    983         if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
    984             parseMpeg4ProfileLevelFromCsd(buffer, msg);
    985         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
    986             parseMpeg2ProfileLevelFromEsds(esds, msg);
    987             if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
    988                 parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
    989             }
    990         } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    991             parseAacProfileFromCsd(buffer, msg);
    992         }
    993 
    994         uint32_t maxBitrate, avgBitrate;
    995         if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
    996             if (!meta->hasData(kKeyBitRate)
    997                     && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
    998                 msg->setInt32("bitrate", (int32_t)avgBitrate);
    999             } else {
   1000                 (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
   1001             }
   1002             if (!meta->hasData(kKeyMaxBitRate)
   1003                     && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
   1004                 msg->setInt32("max-bitrate", (int32_t)maxBitrate);
   1005             }
   1006         }
   1007     } else if (meta->findData(kTypeD263, &type, &data, &size)) {
   1008         const uint8_t *ptr = (const uint8_t *)data;
   1009         parseH263ProfileLevelFromD263(ptr, size, msg);
   1010     } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
   1011         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1012         if (buffer.get() == NULL || buffer->base() == NULL) {
   1013             return NO_MEMORY;
   1014         }
   1015         memcpy(buffer->data(), data, size);
   1016 
   1017         buffer->meta()->setInt32("csd", true);
   1018         buffer->meta()->setInt64("timeUs", 0);
   1019         msg->setBuffer("csd-0", buffer);
   1020 
   1021         if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
   1022             return -EINVAL;
   1023         }
   1024 
   1025         buffer = new (std::nothrow) ABuffer(size);
   1026         if (buffer.get() == NULL || buffer->base() == NULL) {
   1027             return NO_MEMORY;
   1028         }
   1029         memcpy(buffer->data(), data, size);
   1030 
   1031         buffer->meta()->setInt32("csd", true);
   1032         buffer->meta()->setInt64("timeUs", 0);
   1033         msg->setBuffer("csd-1", buffer);
   1034     } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
   1035         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1036         if (buffer.get() == NULL || buffer->base() == NULL) {
   1037             return NO_MEMORY;
   1038         }
   1039         memcpy(buffer->data(), data, size);
   1040 
   1041         buffer->meta()->setInt32("csd", true);
   1042         buffer->meta()->setInt64("timeUs", 0);
   1043         msg->setBuffer("csd-0", buffer);
   1044 
   1045         if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
   1046             return -EINVAL;
   1047         }
   1048 
   1049         buffer = new (std::nothrow) ABuffer(size);
   1050         if (buffer.get() == NULL || buffer->base() == NULL) {
   1051             return NO_MEMORY;
   1052         }
   1053         memcpy(buffer->data(), data, size);
   1054 
   1055         buffer->meta()->setInt32("csd", true);
   1056         buffer->meta()->setInt64("timeUs", 0);
   1057         msg->setBuffer("csd-1", buffer);
   1058 
   1059         if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
   1060             return -EINVAL;
   1061         }
   1062 
   1063         buffer = new (std::nothrow) ABuffer(size);
   1064         if (buffer.get() == NULL || buffer->base() == NULL) {
   1065             return NO_MEMORY;
   1066         }
   1067         memcpy(buffer->data(), data, size);
   1068 
   1069         buffer->meta()->setInt32("csd", true);
   1070         buffer->meta()->setInt64("timeUs", 0);
   1071         msg->setBuffer("csd-2", buffer);
   1072     } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
   1073         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1074         if (buffer.get() == NULL || buffer->base() == NULL) {
   1075             return NO_MEMORY;
   1076         }
   1077         memcpy(buffer->data(), data, size);
   1078 
   1079         buffer->meta()->setInt32("csd", true);
   1080         buffer->meta()->setInt64("timeUs", 0);
   1081         msg->setBuffer("csd-0", buffer);
   1082 
   1083         parseVp9ProfileLevelFromCsd(buffer, msg);
   1084     }
   1085 
   1086     // TODO expose "crypto-key"/kKeyCryptoKey through public api
   1087     if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
   1088         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
   1089         msg->setBuffer("crypto-key", buffer);
   1090         memcpy(buffer->data(), data, size);
   1091     }
   1092 
   1093     *format = msg;
   1094 
   1095     return OK;
   1096 }
   1097 
   1098 const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
   1099     uint8_t *res = NULL;
   1100     if (length > 4) {
   1101         // minus 1 as to not match NAL start code at end
   1102         res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
   1103     }
   1104     return res != NULL && res < data + length - 4 ? res : &data[length];
   1105 }
   1106 
   1107 static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> &csd1, char *avcc) {
   1108     avcc[0] = 1;        // version
   1109     avcc[1] = 0x64;     // profile (default to high)
   1110     avcc[2] = 0;        // constraints (default to none)
   1111     avcc[3] = 0xd;      // level (default to 1.3)
   1112     avcc[4] = 0xff;     // reserved+size
   1113 
   1114     size_t i = 0;
   1115     int numparams = 0;
   1116     int lastparamoffset = 0;
   1117     int avccidx = 6;
   1118     do {
   1119         i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
   1120         ALOGV("block at %zu, last was %d", i, lastparamoffset);
   1121         if (lastparamoffset > 0) {
   1122             const uint8_t *lastparam = csd0->data() + lastparamoffset;
   1123             int size = i - lastparamoffset;
   1124             if (size > 3) {
   1125                 if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
   1126                     ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
   1127                             avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
   1128                 } else if (!numparams) {
   1129                     // fill in profile, constraints and level
   1130                     memcpy(avcc + 1, lastparam + 1, 3);
   1131                 }
   1132             }
   1133             avcc[avccidx++] = size >> 8;
   1134             avcc[avccidx++] = size & 0xff;
   1135             memcpy(avcc+avccidx, lastparam, size);
   1136             avccidx += size;
   1137             numparams++;
   1138         }
   1139         i += 4;
   1140         lastparamoffset = i;
   1141     } while(i < csd0->size());
   1142     ALOGV("csd0 contains %d params", numparams);
   1143 
   1144     avcc[5] = 0xe0 | numparams;
   1145     //and now csd-1
   1146     i = 0;
   1147     numparams = 0;
   1148     lastparamoffset = 0;
   1149     int numpicparamsoffset = avccidx;
   1150     avccidx++;
   1151     do {
   1152         i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
   1153         ALOGV("block at %zu, last was %d", i, lastparamoffset);
   1154         if (lastparamoffset > 0) {
   1155             int size = i - lastparamoffset;
   1156             avcc[avccidx++] = size >> 8;
   1157             avcc[avccidx++] = size & 0xff;
   1158             memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
   1159             avccidx += size;
   1160             numparams++;
   1161         }
   1162         i += 4;
   1163         lastparamoffset = i;
   1164     } while(i < csd1->size());
   1165     avcc[numpicparamsoffset] = numparams;
   1166     return avccidx;
   1167 }
   1168 
   1169 static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
   1170     int csd0size = csd0->size();
   1171     esds[0] = 3; // kTag_ESDescriptor;
   1172     int esdescriptorsize = 26 + csd0size;
   1173     CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
   1174     esds[1] = 0x80 | (esdescriptorsize >> 21);
   1175     esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
   1176     esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
   1177     esds[4] = (esdescriptorsize & 0x7f);
   1178     esds[5] = esds[6] = 0; // es id
   1179     esds[7] = 0; // flags
   1180     esds[8] = 4; // kTag_DecoderConfigDescriptor
   1181     int configdescriptorsize = 18 + csd0size;
   1182     esds[9] = 0x80 | (configdescriptorsize >> 21);
   1183     esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
   1184     esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
   1185     esds[12] = (configdescriptorsize & 0x7f);
   1186     esds[13] = 0x40; // objectTypeIndication
   1187     // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
   1188     esds[14] = 0x15; // streamType(5), upStream(0),
   1189     esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
   1190     esds[16] = 0x18;
   1191     esds[17] = 0x00;
   1192     esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
   1193     esds[19] = 0x00;
   1194     esds[20] = 0xfa;
   1195     esds[21] = 0x00;
   1196     esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
   1197     esds[23] = 0x00;
   1198     esds[24] = 0xfa;
   1199     esds[25] = 0x00;
   1200     esds[26] = 5; // kTag_DecoderSpecificInfo;
   1201     esds[27] = 0x80 | (csd0size >> 21);
   1202     esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
   1203     esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
   1204     esds[30] = (csd0size & 0x7f);
   1205     memcpy((void*)&esds[31], csd0->data(), csd0size);
   1206     // data following this is ignored, so don't bother appending it
   1207 }
   1208 
   1209 static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
   1210     HevcParameterSets paramSets;
   1211     uint8_t* data = csd0->data();
   1212     if (csd0->size() < 4) {
   1213         ALOGE("csd0 too small");
   1214         return 0;
   1215     }
   1216     if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
   1217         ALOGE("csd0 doesn't start with a start code");
   1218         return 0;
   1219     }
   1220     size_t prevNalOffset = 4;
   1221     status_t err = OK;
   1222     for (size_t i = 1; i < csd0->size() - 4; ++i) {
   1223         if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
   1224             continue;
   1225         }
   1226         err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
   1227         if (err != OK) {
   1228             return 0;
   1229         }
   1230         prevNalOffset = i + 4;
   1231     }
   1232     err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
   1233     if (err != OK) {
   1234         return 0;
   1235     }
   1236     size_t size = hvccSize;
   1237     err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
   1238     if (err != OK) {
   1239         return 0;
   1240     }
   1241     return size;
   1242 }
   1243 
   1244 #if 0
   1245 static void convertMessageToMetaDataInt32(
   1246         const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
   1247     int32_t value;
   1248     if (msg->findInt32(name, &value)) {
   1249         meta->setInt32(key, value);
   1250     }
   1251 }
   1252 #endif
   1253 
   1254 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
   1255     // 0 values are unspecified
   1256     int32_t range = 0, standard = 0, transfer = 0;
   1257     (void)msg->findInt32("color-range", &range);
   1258     (void)msg->findInt32("color-standard", &standard);
   1259     (void)msg->findInt32("color-transfer", &transfer);
   1260 
   1261     ColorAspects colorAspects;
   1262     memset(&colorAspects, 0, sizeof(colorAspects));
   1263     if (CodecBase::convertPlatformColorAspectsToCodecAspects(
   1264             range, standard, transfer, colorAspects) != OK) {
   1265         return;
   1266     }
   1267 
   1268     // save specified values to meta
   1269     if (colorAspects.mRange != 0) {
   1270         meta->setInt32(kKeyColorRange, colorAspects.mRange);
   1271     }
   1272     if (colorAspects.mPrimaries != 0) {
   1273         meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
   1274     }
   1275     if (colorAspects.mTransfer != 0) {
   1276         meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
   1277     }
   1278     if (colorAspects.mMatrixCoeffs != 0) {
   1279         meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
   1280     }
   1281 }
   1282 
   1283 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
   1284     AString mime;
   1285     if (msg->findString("mime", &mime)) {
   1286         meta->setCString(kKeyMIMEType, mime.c_str());
   1287     } else {
   1288         ALOGW("did not find mime type");
   1289     }
   1290 
   1291     int64_t durationUs;
   1292     if (msg->findInt64("durationUs", &durationUs)) {
   1293         meta->setInt64(kKeyDuration, durationUs);
   1294     }
   1295 
   1296     int32_t isSync;
   1297     if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
   1298         meta->setInt32(kKeyIsSyncFrame, 1);
   1299     }
   1300 
   1301     int32_t avgBitrate = 0;
   1302     int32_t maxBitrate;
   1303     if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
   1304         meta->setInt32(kKeyBitRate, avgBitrate);
   1305     }
   1306     if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
   1307         meta->setInt32(kKeyMaxBitRate, maxBitrate);
   1308     }
   1309 
   1310     AString lang;
   1311     if (msg->findString("language", &lang)) {
   1312         meta->setCString(kKeyMediaLanguage, lang.c_str());
   1313     }
   1314 
   1315     if (mime.startsWith("video/")) {
   1316         int32_t width;
   1317         int32_t height;
   1318         if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
   1319             meta->setInt32(kKeyWidth, width);
   1320             meta->setInt32(kKeyHeight, height);
   1321         } else {
   1322             ALOGW("did not find width and/or height");
   1323         }
   1324 
   1325         int32_t sarWidth, sarHeight;
   1326         if (msg->findInt32("sar-width", &sarWidth)
   1327                 && msg->findInt32("sar-height", &sarHeight)) {
   1328             meta->setInt32(kKeySARWidth, sarWidth);
   1329             meta->setInt32(kKeySARHeight, sarHeight);
   1330         }
   1331 
   1332         int32_t displayWidth, displayHeight;
   1333         if (msg->findInt32("display-width", &displayWidth)
   1334                 && msg->findInt32("display-height", &displayHeight)) {
   1335             meta->setInt32(kKeyDisplayWidth, displayWidth);
   1336             meta->setInt32(kKeyDisplayHeight, displayHeight);
   1337         }
   1338 
   1339         int32_t colorFormat;
   1340         if (msg->findInt32("color-format", &colorFormat)) {
   1341             meta->setInt32(kKeyColorFormat, colorFormat);
   1342         }
   1343 
   1344         int32_t cropLeft, cropTop, cropRight, cropBottom;
   1345         if (msg->findRect("crop",
   1346                           &cropLeft,
   1347                           &cropTop,
   1348                           &cropRight,
   1349                           &cropBottom)) {
   1350             meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
   1351         }
   1352 
   1353         int32_t rotationDegrees;
   1354         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
   1355             meta->setInt32(kKeyRotation, rotationDegrees);
   1356         }
   1357 
   1358         if (msg->contains("hdr-static-info")) {
   1359             HDRStaticInfo info;
   1360             if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
   1361                 meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
   1362             }
   1363         }
   1364 
   1365         convertMessageToMetaDataColorAspects(msg, meta);
   1366 
   1367         AString tsSchema;
   1368         if (msg->findString("ts-schema", &tsSchema)) {
   1369             unsigned int numLayers = 0;
   1370             unsigned int numBLayers = 0;
   1371             char dummy;
   1372             int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
   1373                     &numLayers, &dummy, &numBLayers, &dummy);
   1374             if ((tags == 1 || (tags == 3 && dummy == '+'))
   1375                     && numLayers > 0 && numLayers < UINT32_MAX - numBLayers
   1376                     && numLayers + numBLayers <= INT32_MAX) {
   1377                 meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
   1378             }
   1379         }
   1380     } else if (mime.startsWith("audio/")) {
   1381         int32_t numChannels;
   1382         if (msg->findInt32("channel-count", &numChannels)) {
   1383             meta->setInt32(kKeyChannelCount, numChannels);
   1384         }
   1385         int32_t sampleRate;
   1386         if (msg->findInt32("sample-rate", &sampleRate)) {
   1387             meta->setInt32(kKeySampleRate, sampleRate);
   1388         }
   1389         int32_t channelMask;
   1390         if (msg->findInt32("channel-mask", &channelMask)) {
   1391             meta->setInt32(kKeyChannelMask, channelMask);
   1392         }
   1393         int32_t delay = 0;
   1394         if (msg->findInt32("encoder-delay", &delay)) {
   1395             meta->setInt32(kKeyEncoderDelay, delay);
   1396         }
   1397         int32_t padding = 0;
   1398         if (msg->findInt32("encoder-padding", &padding)) {
   1399             meta->setInt32(kKeyEncoderPadding, padding);
   1400         }
   1401 
   1402         int32_t isADTS;
   1403         if (msg->findInt32("is-adts", &isADTS)) {
   1404             meta->setInt32(kKeyIsADTS, isADTS);
   1405         }
   1406 
   1407         int32_t pcmEncoding;
   1408         if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
   1409             meta->setInt32(kKeyPcmEncoding, pcmEncoding);
   1410         }
   1411     }
   1412 
   1413     int32_t maxInputSize;
   1414     if (msg->findInt32("max-input-size", &maxInputSize)) {
   1415         meta->setInt32(kKeyMaxInputSize, maxInputSize);
   1416     }
   1417 
   1418     int32_t maxWidth;
   1419     if (msg->findInt32("max-width", &maxWidth)) {
   1420         meta->setInt32(kKeyMaxWidth, maxWidth);
   1421     }
   1422 
   1423     int32_t maxHeight;
   1424     if (msg->findInt32("max-height", &maxHeight)) {
   1425         meta->setInt32(kKeyMaxHeight, maxHeight);
   1426     }
   1427 
   1428     int32_t fps;
   1429     float fpsFloat;
   1430     if (msg->findInt32("frame-rate", &fps) && fps > 0) {
   1431         meta->setInt32(kKeyFrameRate, fps);
   1432     } else if (msg->findFloat("frame-rate", &fpsFloat)
   1433             && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
   1434         // truncate values to distinguish between e.g. 24 vs 23.976 fps
   1435         meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
   1436     }
   1437 
   1438     // reassemble the csd data into its original form
   1439     sp<ABuffer> csd0, csd1, csd2;
   1440     if (msg->findBuffer("csd-0", &csd0)) {
   1441         int csd0size = csd0->size();
   1442         if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
   1443             sp<ABuffer> csd1;
   1444             if (msg->findBuffer("csd-1", &csd1)) {
   1445                 std::vector<char> avcc(csd0size + csd1->size() + 1024);
   1446                 size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
   1447                 meta->setData(kKeyAVCC, kKeyAVCC, avcc.data(), outsize);
   1448             }
   1449         } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
   1450             std::vector<char> esds(csd0size + 31);
   1451             // The written ESDS is actually for an audio stream, but it's enough
   1452             // for transporting the CSD to muxers.
   1453             reassembleESDS(csd0, esds.data());
   1454             meta->setData(kKeyESDS, kKeyESDS, esds.data(), esds.size());
   1455         } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
   1456             std::vector<uint8_t> hvcc(csd0size + 1024);
   1457             size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
   1458             meta->setData(kKeyHVCC, kKeyHVCC, hvcc.data(), outsize);
   1459         } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
   1460             meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
   1461         } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
   1462             meta->setData(kKeyOpusHeader, 0, csd0->data(), csd0->size());
   1463             if (msg->findBuffer("csd-1", &csd1)) {
   1464                 meta->setData(kKeyOpusCodecDelay, 0, csd1->data(), csd1->size());
   1465             }
   1466             if (msg->findBuffer("csd-2", &csd2)) {
   1467                 meta->setData(kKeyOpusSeekPreRoll, 0, csd2->data(), csd2->size());
   1468             }
   1469         } else if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
   1470             meta->setData(kKeyVorbisInfo, 0, csd0->data(), csd0->size());
   1471             if (msg->findBuffer("csd-1", &csd1)) {
   1472                 meta->setData(kKeyVorbisBooks, 0, csd1->data(), csd1->size());
   1473             }
   1474         }
   1475     }
   1476 
   1477     int32_t timeScale;
   1478     if (msg->findInt32("time-scale", &timeScale)) {
   1479         meta->setInt32(kKeyTimeScale, timeScale);
   1480     }
   1481 
   1482     // XXX TODO add whatever other keys there are
   1483 
   1484 #if 0
   1485     ALOGI("converted %s to:", msg->debugString(0).c_str());
   1486     meta->dumpToLog();
   1487 #endif
   1488 }
   1489 
   1490 AString MakeUserAgent() {
   1491     AString ua;
   1492     ua.append("stagefright/1.2 (Linux;Android ");
   1493 
   1494 #if (PROPERTY_VALUE_MAX < 8)
   1495 #error "PROPERTY_VALUE_MAX must be at least 8"
   1496 #endif
   1497 
   1498     char value[PROPERTY_VALUE_MAX];
   1499     property_get("ro.build.version.release", value, "Unknown");
   1500     ua.append(value);
   1501     ua.append(")");
   1502 
   1503     return ua;
   1504 }
   1505 
   1506 status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
   1507                            const sp<MetaData>& meta)
   1508 {
   1509     int32_t sampleRate = 0;
   1510     int32_t bitRate = 0;
   1511     int32_t channelMask = 0;
   1512     int32_t delaySamples = 0;
   1513     int32_t paddingSamples = 0;
   1514 
   1515     AudioParameter param = AudioParameter();
   1516 
   1517     if (meta->findInt32(kKeySampleRate, &sampleRate)) {
   1518         param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
   1519     }
   1520     if (meta->findInt32(kKeyChannelMask, &channelMask)) {
   1521         param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
   1522     }
   1523     if (meta->findInt32(kKeyBitRate, &bitRate)) {
   1524         param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
   1525     }
   1526     if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
   1527         param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
   1528     }
   1529     if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
   1530         param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
   1531     }
   1532 
   1533     ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
   1534           "delaySample %d, paddingSample %d", bitRate, sampleRate,
   1535           channelMask, delaySamples, paddingSamples);
   1536 
   1537     sink->setParameters(param.toString());
   1538     return OK;
   1539 }
   1540 
   1541 struct mime_conv_t {
   1542     const char* mime;
   1543     audio_format_t format;
   1544 };
   1545 
   1546 static const struct mime_conv_t mimeLookup[] = {
   1547     { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
   1548     { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
   1549     { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
   1550     { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
   1551     { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
   1552     { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
   1553     { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
   1554     { MEDIA_MIMETYPE_AUDIO_AC3,         AUDIO_FORMAT_AC3},
   1555     { 0, AUDIO_FORMAT_INVALID }
   1556 };
   1557 
   1558 status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
   1559 {
   1560 const struct mime_conv_t* p = &mimeLookup[0];
   1561     while (p->mime != NULL) {
   1562         if (0 == strcasecmp(mime, p->mime)) {
   1563             format = p->format;
   1564             return OK;
   1565         }
   1566         ++p;
   1567     }
   1568 
   1569     return BAD_VALUE;
   1570 }
   1571 
   1572 struct aac_format_conv_t {
   1573     OMX_AUDIO_AACPROFILETYPE eAacProfileType;
   1574     audio_format_t format;
   1575 };
   1576 
   1577 static const struct aac_format_conv_t profileLookup[] = {
   1578     { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
   1579     { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
   1580     { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
   1581     { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
   1582     { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
   1583     { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
   1584     { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
   1585     { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
   1586     { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
   1587     { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
   1588     { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
   1589 };
   1590 
   1591 void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
   1592 {
   1593 const struct aac_format_conv_t* p = &profileLookup[0];
   1594     while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
   1595         if (eAacProfile == p->eAacProfileType) {
   1596             format = p->format;
   1597             return;
   1598         }
   1599         ++p;
   1600     }
   1601     format = AUDIO_FORMAT_AAC;
   1602     return;
   1603 }
   1604 
   1605 bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
   1606                       bool isStreaming, audio_stream_type_t streamType)
   1607 {
   1608     const char *mime;
   1609     if (meta == NULL) {
   1610         return false;
   1611     }
   1612     CHECK(meta->findCString(kKeyMIMEType, &mime));
   1613 
   1614     audio_offload_info_t info = AUDIO_INFO_INITIALIZER;
   1615 
   1616     info.format = AUDIO_FORMAT_INVALID;
   1617     if (mapMimeToAudioFormat(info.format, mime) != OK) {
   1618         ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
   1619         return false;
   1620     } else {
   1621         ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
   1622     }
   1623 
   1624     if (AUDIO_FORMAT_INVALID == info.format) {
   1625         // can't offload if we don't know what the source format is
   1626         ALOGE("mime type \"%s\" not a known audio format", mime);
   1627         return false;
   1628     }
   1629 
   1630     // Redefine aac format according to its profile
   1631     // Offloading depends on audio DSP capabilities.
   1632     int32_t aacaot = -1;
   1633     if (meta->findInt32(kKeyAACAOT, &aacaot)) {
   1634         mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
   1635     }
   1636 
   1637     int32_t srate = -1;
   1638     if (!meta->findInt32(kKeySampleRate, &srate)) {
   1639         ALOGV("track of type '%s' does not publish sample rate", mime);
   1640     }
   1641     info.sample_rate = srate;
   1642 
   1643     int32_t cmask = 0;
   1644     if (!meta->findInt32(kKeyChannelMask, &cmask)) {
   1645         ALOGV("track of type '%s' does not publish channel mask", mime);
   1646 
   1647         // Try a channel count instead
   1648         int32_t channelCount;
   1649         if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
   1650             ALOGV("track of type '%s' does not publish channel count", mime);
   1651         } else {
   1652             cmask = audio_channel_out_mask_from_count(channelCount);
   1653         }
   1654     }
   1655     info.channel_mask = cmask;
   1656 
   1657     int64_t duration = 0;
   1658     if (!meta->findInt64(kKeyDuration, &duration)) {
   1659         ALOGV("track of type '%s' does not publish duration", mime);
   1660     }
   1661     info.duration_us = duration;
   1662 
   1663     int32_t brate = -1;
   1664     if (!meta->findInt32(kKeyBitRate, &brate)) {
   1665         ALOGV("track of type '%s' does not publish bitrate", mime);
   1666     }
   1667     info.bit_rate = brate;
   1668 
   1669 
   1670     info.stream_type = streamType;
   1671     info.has_video = hasVideo;
   1672     info.is_streaming = isStreaming;
   1673 
   1674     // Check if offload is possible for given format, stream type, sample rate,
   1675     // bit rate, duration, video and streaming
   1676     return AudioSystem::isOffloadSupported(info);
   1677 }
   1678 
   1679 AString uriDebugString(const AString &uri, bool incognito) {
   1680     if (incognito) {
   1681         return AString("<URI suppressed>");
   1682     }
   1683 
   1684     if (property_get_bool("media.stagefright.log-uri", false)) {
   1685         return uri;
   1686     }
   1687 
   1688     // find scheme
   1689     AString scheme;
   1690     const char *chars = uri.c_str();
   1691     for (size_t i = 0; i < uri.size(); i++) {
   1692         const char c = chars[i];
   1693         if (!isascii(c)) {
   1694             break;
   1695         } else if (isalpha(c)) {
   1696             continue;
   1697         } else if (i == 0) {
   1698             // first character must be a letter
   1699             break;
   1700         } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
   1701             continue;
   1702         } else if (c != ':') {
   1703             break;
   1704         }
   1705         scheme = AString(uri, 0, i);
   1706         scheme.append("://<suppressed>");
   1707         return scheme;
   1708     }
   1709     return AString("<no-scheme URI suppressed>");
   1710 }
   1711 
   1712 HLSTime::HLSTime(const sp<AMessage>& meta) :
   1713     mSeq(-1),
   1714     mTimeUs(-1ll),
   1715     mMeta(meta) {
   1716     if (meta != NULL) {
   1717         CHECK(meta->findInt32("discontinuitySeq", &mSeq));
   1718         CHECK(meta->findInt64("timeUs", &mTimeUs));
   1719     }
   1720 }
   1721 
   1722 int64_t HLSTime::getSegmentTimeUs() const {
   1723     int64_t segmentStartTimeUs = -1ll;
   1724     if (mMeta != NULL) {
   1725         CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));
   1726 
   1727         int64_t segmentFirstTimeUs;
   1728         if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
   1729             segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
   1730         }
   1731 
   1732         // adjust segment time by playlist age (for live streaming)
   1733         int64_t playlistTimeUs;
   1734         if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
   1735             int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;
   1736 
   1737             int64_t durationUs;
   1738             CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));
   1739 
   1740             // round to nearest whole segment
   1741             playlistAgeUs = (playlistAgeUs + durationUs / 2)
   1742                     / durationUs * durationUs;
   1743 
   1744             segmentStartTimeUs -= playlistAgeUs;
   1745             if (segmentStartTimeUs < 0) {
   1746                 segmentStartTimeUs = 0;
   1747             }
   1748         }
   1749     }
   1750     return segmentStartTimeUs;
   1751 }
   1752 
   1753 bool operator <(const HLSTime &t0, const HLSTime &t1) {
   1754     // we can only compare discontinuity sequence and timestamp.
   1755     // (mSegmentTimeUs is not reliable in live streaming case, it's the
   1756     // time starting from beginning of playlist but playlist could change.)
   1757     return t0.mSeq < t1.mSeq
   1758             || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
   1759 }
   1760 
   1761 void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate) {
   1762     msg->setFloat("speed", rate.mSpeed);
   1763     msg->setFloat("pitch", rate.mPitch);
   1764     msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
   1765     msg->setInt32("audio-stretch-mode", rate.mStretchMode);
   1766 }
   1767 
   1768 void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
   1769     *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
   1770     CHECK(msg->findFloat("speed", &rate->mSpeed));
   1771     CHECK(msg->findFloat("pitch", &rate->mPitch));
   1772     CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
   1773     CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
   1774 }
   1775 
   1776 void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint) {
   1777     msg->setInt32("sync-source", sync.mSource);
   1778     msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
   1779     msg->setFloat("tolerance", sync.mTolerance);
   1780     msg->setFloat("video-fps", videoFpsHint);
   1781 }
   1782 
   1783 void readFromAMessage(
   1784         const sp<AMessage> &msg,
   1785         AVSyncSettings *sync /* nonnull */,
   1786         float *videoFps /* nonnull */) {
   1787     AVSyncSettings settings;
   1788     CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
   1789     CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
   1790     CHECK(msg->findFloat("tolerance", &settings.mTolerance));
   1791     CHECK(msg->findFloat("video-fps", videoFps));
   1792     *sync = settings;
   1793 }
   1794 
   1795 void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering) {
   1796     msg->setInt32("init-mode", buffering.mInitialBufferingMode);
   1797     msg->setInt32("rebuffer-mode", buffering.mRebufferingMode);
   1798     msg->setInt32("init-ms", buffering.mInitialWatermarkMs);
   1799     msg->setInt32("init-kb", buffering.mInitialWatermarkKB);
   1800     msg->setInt32("rebuffer-low-ms", buffering.mRebufferingWatermarkLowMs);
   1801     msg->setInt32("rebuffer-high-ms", buffering.mRebufferingWatermarkHighMs);
   1802     msg->setInt32("rebuffer-low-kb", buffering.mRebufferingWatermarkLowKB);
   1803     msg->setInt32("rebuffer-high-kb", buffering.mRebufferingWatermarkHighKB);
   1804 }
   1805 
   1806 void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */) {
   1807     int32_t value;
   1808     if (msg->findInt32("init-mode", &value)) {
   1809         buffering->mInitialBufferingMode = (BufferingMode)value;
   1810     }
   1811     if (msg->findInt32("rebuffer-mode", &value)) {
   1812         buffering->mRebufferingMode = (BufferingMode)value;
   1813     }
   1814     if (msg->findInt32("init-ms", &value)) {
   1815         buffering->mInitialWatermarkMs = value;
   1816     }
   1817     if (msg->findInt32("init-kb", &value)) {
   1818         buffering->mInitialWatermarkKB = value;
   1819     }
   1820     if (msg->findInt32("rebuffer-low-ms", &value)) {
   1821         buffering->mRebufferingWatermarkLowMs = value;
   1822     }
   1823     if (msg->findInt32("rebuffer-high-ms", &value)) {
   1824         buffering->mRebufferingWatermarkHighMs = value;
   1825     }
   1826     if (msg->findInt32("rebuffer-low-kb", &value)) {
   1827         buffering->mRebufferingWatermarkLowKB = value;
   1828     }
   1829     if (msg->findInt32("rebuffer-high-kb", &value)) {
   1830         buffering->mRebufferingWatermarkHighKB = value;
   1831     }
   1832 }
   1833 
   1834 AString nameForFd(int fd) {
   1835     const size_t SIZE = 256;
   1836     char buffer[SIZE];
   1837     AString result;
   1838     snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
   1839     struct stat s;
   1840     if (lstat(buffer, &s) == 0) {
   1841         if ((s.st_mode & S_IFMT) == S_IFLNK) {
   1842             char linkto[256];
   1843             int len = readlink(buffer, linkto, sizeof(linkto));
   1844             if(len > 0) {
   1845                 if(len > 255) {
   1846                     linkto[252] = '.';
   1847                     linkto[253] = '.';
   1848                     linkto[254] = '.';
   1849                     linkto[255] = 0;
   1850                 } else {
   1851                     linkto[len] = 0;
   1852                 }
   1853                 result.append(linkto);
   1854             }
   1855         } else {
   1856             result.append("unexpected type for ");
   1857             result.append(buffer);
   1858         }
   1859     } else {
   1860         result.append("couldn't open ");
   1861         result.append(buffer);
   1862     }
   1863     return result;
   1864 }
   1865 
   1866 }  // namespace android
   1867 
   1868