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