/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "Utils"
#include <utils/Log.h>
#include <ctype.h>
#include <stdio.h>
#include <sys/stat.h>

#include <utility>
#include <vector>

#include "include/ESDS.h"
#include "include/HevcUtils.h"

#include <arpa/inet.h>
#include <cutils/properties.h>
#include <media/openmax/OMX_Audio.h>
#include <media/openmax/OMX_Video.h>
#include <media/openmax/OMX_VideoExt.h>
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALookup.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDefs.h>
#include <media/AudioSystem.h>
#include <media/MediaPlayerInterface.h>
#include <hardware/audio.h>
#include <media/stagefright/Utils.h>
#include <media/AudioParameter.h>

namespace android {

uint16_t U16_AT(const uint8_t *ptr) {
    return ptr[0] << 8 | ptr[1];
}

uint32_t U32_AT(const uint8_t *ptr) {
    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
}

uint64_t U64_AT(const uint8_t *ptr) {
    return ((uint64_t)U32_AT(ptr)) << 32 | U32_AT(ptr + 4);
}

uint16_t U16LE_AT(const uint8_t *ptr) {
    return ptr[0] | (ptr[1] << 8);
}

uint32_t U32LE_AT(const uint8_t *ptr) {
    return ptr[3] << 24 | ptr[2] << 16 | ptr[1] << 8 | ptr[0];
}

uint64_t U64LE_AT(const uint8_t *ptr) {
    return ((uint64_t)U32LE_AT(ptr + 4)) << 32 | U32LE_AT(ptr);
}

// XXX warning: these won't work on big-endian host.
uint64_t ntoh64(uint64_t x) {
    return ((uint64_t)ntohl(x & 0xffffffff) << 32) | ntohl(x >> 32);
}

uint64_t hton64(uint64_t x) {
    return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
}

static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
    if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
        sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
        if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
        tmpBuffer->setRange(0, (*buffer)->size());
        (*buffer) = tmpBuffer;
    }

    memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
    memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
    (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
    return OK;
}

#if 0
static void convertMetaDataToMessageInt32(
        const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
    int32_t value;
    if (meta->findInt32(key, &value)) {
        msg->setInt32(name, value);
    }
}
#endif

static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
    // 0 values are unspecified
    int32_t range = 0;
    int32_t primaries = 0;
    int32_t transferFunction = 0;
    int32_t colorMatrix = 0;
    meta->findInt32(kKeyColorRange, &range);
    meta->findInt32(kKeyColorPrimaries, &primaries);
    meta->findInt32(kKeyTransferFunction, &transferFunction);
    meta->findInt32(kKeyColorMatrix, &colorMatrix);
    ColorAspects colorAspects;
    memset(&colorAspects, 0, sizeof(colorAspects));
    colorAspects.mRange = (ColorAspects::Range)range;
    colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
    colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
    colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;

    int32_t rangeMsg, standardMsg, transferMsg;
    if (CodecBase::convertCodecColorAspectsToPlatformAspects(
            colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
        return;
    }

    // save specified values to msg
    if (rangeMsg != 0) {
        msg->setInt32("color-range", rangeMsg);
    }
    if (standardMsg != 0) {
        msg->setInt32("color-standard", standardMsg);
    }
    if (transferMsg != 0) {
        msg->setInt32("color-transfer", transferMsg);
    }
}

static bool isHdr(const sp<AMessage> &format) {
    // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR
    // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key
    // in the format.
    int32_t isHdr;
    if (format->findInt32("android._is-hdr", &isHdr)) {
        return isHdr;
    }

    // if user/container supplied HDR static info without transfer set, assume true
    if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
        return true;
    }
    // otherwise, verify that an HDR transfer function is set
    int32_t transfer;
    if (format->findInt32("color-transfer", &transfer)) {
        return transfer == ColorUtils::kColorTransferST2084
                || transfer == ColorUtils::kColorTransferHLG;
    }
    return false;
}

static void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    if (csd->size() < 2) {
        return;
    }

    uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
    if ((audioObjectType & 0xF800) == 0xF800) {
        audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
    } else {
        audioObjectType >>= 11;
    }

    const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
        { 1,  OMX_AUDIO_AACObjectMain     },
        { 2,  OMX_AUDIO_AACObjectLC       },
        { 3,  OMX_AUDIO_AACObjectSSR      },
        { 4,  OMX_AUDIO_AACObjectLTP      },
        { 5,  OMX_AUDIO_AACObjectHE       },
        { 6,  OMX_AUDIO_AACObjectScalable },
        { 17, OMX_AUDIO_AACObjectERLC     },
        { 23, OMX_AUDIO_AACObjectLD       },
        { 29, OMX_AUDIO_AACObjectHE_PS    },
        { 39, OMX_AUDIO_AACObjectELD      },
    };

    OMX_AUDIO_AACPROFILETYPE profile;
    if (profiles.map(audioObjectType, &profile)) {
        format->setInt32("profile", profile);
    }
}

static void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    if (size < 4 || ptr[0] != 1) {  // configurationVersion == 1
        return;
    }
    const uint8_t profile = ptr[1];
    const uint8_t constraints = ptr[2];
    const uint8_t level = ptr[3];

    const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
        {  9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
        { 10, OMX_VIDEO_AVCLevel1  },
        { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
        { 11, OMX_VIDEO_AVCLevel1b },
        { 12, OMX_VIDEO_AVCLevel12 },
        { 13, OMX_VIDEO_AVCLevel13 },
        { 20, OMX_VIDEO_AVCLevel2  },
        { 21, OMX_VIDEO_AVCLevel21 },
        { 22, OMX_VIDEO_AVCLevel22 },
        { 30, OMX_VIDEO_AVCLevel3  },
        { 31, OMX_VIDEO_AVCLevel31 },
        { 32, OMX_VIDEO_AVCLevel32 },
        { 40, OMX_VIDEO_AVCLevel4  },
        { 41, OMX_VIDEO_AVCLevel41 },
        { 42, OMX_VIDEO_AVCLevel42 },
        { 50, OMX_VIDEO_AVCLevel5  },
        { 51, OMX_VIDEO_AVCLevel51 },
        { 52, OMX_VIDEO_AVCLevel52 },
    };
    const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
        { 66, OMX_VIDEO_AVCProfileBaseline },
        { 77, OMX_VIDEO_AVCProfileMain     },
        { 88, OMX_VIDEO_AVCProfileExtended },
        { 100, OMX_VIDEO_AVCProfileHigh    },
        { 110, OMX_VIDEO_AVCProfileHigh10  },
        { 122, OMX_VIDEO_AVCProfileHigh422 },
        { 244, OMX_VIDEO_AVCProfileHigh444 },
    };

    // set profile & level if they are recognized
    OMX_VIDEO_AVCPROFILETYPE codecProfile;
    OMX_VIDEO_AVCLEVELTYPE codecLevel;
    if (profiles.map(profile, &codecProfile)) {
        format->setInt32("profile", codecProfile);
        if (levels.map(level, &codecLevel)) {
            // for 9 && 11 decide level based on profile and constraint_set3 flag
            if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
                codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
            }
            format->setInt32("level", codecLevel);
        }
    }
}

static void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    if (size < 7) {
        return;
    }

    const uint8_t profile = ptr[6];
    const uint8_t level = ptr[5];

    const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
        { 0, OMX_VIDEO_H263ProfileBaseline },
        { 1, OMX_VIDEO_H263ProfileH320Coding },
        { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
        { 3, OMX_VIDEO_H263ProfileISWV2 },
        { 4, OMX_VIDEO_H263ProfileISWV3 },
        { 5, OMX_VIDEO_H263ProfileHighCompression },
        { 6, OMX_VIDEO_H263ProfileInternet },
        { 7, OMX_VIDEO_H263ProfileInterlace },
        { 8, OMX_VIDEO_H263ProfileHighLatency },
    };

    const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
        { 10, OMX_VIDEO_H263Level10 },
        { 20, OMX_VIDEO_H263Level20 },
        { 30, OMX_VIDEO_H263Level30 },
        { 40, OMX_VIDEO_H263Level40 },
        { 45, OMX_VIDEO_H263Level45 },
        { 50, OMX_VIDEO_H263Level50 },
        { 60, OMX_VIDEO_H263Level60 },
        { 70, OMX_VIDEO_H263Level70 },
    };

    // set profile & level if they are recognized
    OMX_VIDEO_H263PROFILETYPE codecProfile;
    OMX_VIDEO_H263LEVELTYPE codecLevel;
    if (profiles.map(profile, &codecProfile)) {
        format->setInt32("profile", codecProfile);
        if (levels.map(level, &codecLevel)) {
            format->setInt32("level", codecLevel);
        }
    }
}

static void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
    if (size < 13 || ptr[0] != 1) {  // configurationVersion == 1
        return;
    }

    const uint8_t profile = ptr[1] & 0x1F;
    const uint8_t tier = (ptr[1] & 0x20) >> 5;
    const uint8_t level = ptr[12];

    const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
        { { 0, 30  }, OMX_VIDEO_HEVCMainTierLevel1  },
        { { 0, 60  }, OMX_VIDEO_HEVCMainTierLevel2  },
        { { 0, 63  }, OMX_VIDEO_HEVCMainTierLevel21 },
        { { 0, 90  }, OMX_VIDEO_HEVCMainTierLevel3  },
        { { 0, 93  }, OMX_VIDEO_HEVCMainTierLevel31 },
        { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4  },
        { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
        { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5  },
        { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
        { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
        { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6  },
        { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
        { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
        { { 1, 30  }, OMX_VIDEO_HEVCHighTierLevel1  },
        { { 1, 60  }, OMX_VIDEO_HEVCHighTierLevel2  },
        { { 1, 63  }, OMX_VIDEO_HEVCHighTierLevel21 },
        { { 1, 90  }, OMX_VIDEO_HEVCHighTierLevel3  },
        { { 1, 93  }, OMX_VIDEO_HEVCHighTierLevel31 },
        { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4  },
        { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
        { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5  },
        { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
        { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
        { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6  },
        { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
        { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
    };

    const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
        { 1, OMX_VIDEO_HEVCProfileMain   },
        { 2, OMX_VIDEO_HEVCProfileMain10 },
    };

    // set profile & level if they are recognized
    OMX_VIDEO_HEVCPROFILETYPE codecProfile;
    OMX_VIDEO_HEVCLEVELTYPE codecLevel;
    if (!profiles.map(profile, &codecProfile)) {
        if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
            codecProfile = OMX_VIDEO_HEVCProfileMain;
        } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
            codecProfile = OMX_VIDEO_HEVCProfileMain10;
        } else {
            return;
        }
    }

    // bump to HDR profile
    if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) {
        codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
    }

    format->setInt32("profile", codecProfile);
    if (levels.map(std::make_pair(tier, level), &codecLevel)) {
        format->setInt32("level", codecLevel);
    }
}

static void parseMpeg2ProfileLevelFromHeader(
        const uint8_t *data, size_t size, sp<AMessage> &format) {
    // find sequence extension
    const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
    if (seq != NULL && seq + 5 < data + size) {
        const uint8_t start_code = seq[4] >> 4;
        if (start_code != 1 /* sequence extension ID */) {
            return;
        }
        const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);

        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
            { 0x50, OMX_VIDEO_MPEG2ProfileSimple  },
            { 0x40, OMX_VIDEO_MPEG2ProfileMain    },
            { 0x30, OMX_VIDEO_MPEG2ProfileSNR     },
            { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
            { 0x10, OMX_VIDEO_MPEG2ProfileHigh    },
        };

        const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
            { 0x0A, OMX_VIDEO_MPEG2LevelLL  },
            { 0x08, OMX_VIDEO_MPEG2LevelML  },
            { 0x06, OMX_VIDEO_MPEG2LevelH14 },
            { 0x04, OMX_VIDEO_MPEG2LevelHL  },
            { 0x02, OMX_VIDEO_MPEG2LevelHP  },
        };

        const static ALookup<uint8_t,
                std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
            /* unsupported
            { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL  } },
            { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML  } },
            { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
            { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL  } }, */
            { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML  } },
            { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL  } },
        };

        OMX_VIDEO_MPEG2PROFILETYPE profile;
        OMX_VIDEO_MPEG2LEVELTYPE level;
        std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
        if (escapes.map(indication, &profileLevel)) {
            format->setInt32("profile", profileLevel.first);
            format->setInt32("level", profileLevel.second);
        } else if (profiles.map(indication & 0x70, &profile)) {
            format->setInt32("profile", profile);
            if (levels.map(indication & 0xF, &level)) {
                format->setInt32("level", level);
            }
        }
    }
}

static void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
    // esds seems to only contain the profile for MPEG-2
    uint8_t objType;
    if (esds.getObjectTypeIndication(&objType) == OK) {
        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
            { 0x60, OMX_VIDEO_MPEG2ProfileSimple  },
            { 0x61, OMX_VIDEO_MPEG2ProfileMain    },
            { 0x62, OMX_VIDEO_MPEG2ProfileSNR     },
            { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
            { 0x64, OMX_VIDEO_MPEG2ProfileHigh    },
            { 0x65, OMX_VIDEO_MPEG2Profile422     },
        };

        OMX_VIDEO_MPEG2PROFILETYPE profile;
        if (profiles.map(objType, &profile)) {
            format->setInt32("profile", profile);
        }
    }
}

static void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    const uint8_t *data = csd->data();
    // find visual object sequence
    const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
    if (seq != NULL && seq + 4 < data + csd->size()) {
        const uint8_t indication = seq[4];

        const static ALookup<uint8_t,
                std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
            { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level1  } },
            { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level2  } },
            { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level3  } },
            { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level4a } },
            { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level5  } },
            { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level6  } },
            { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0  } },
            { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0b } },
            { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level0  } },
            { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level1  } },
            { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level2  } },
            /* unsupported
            { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level0  } },
            { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level1  } },
            { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level2  } }, */
            { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level1  } },
            { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level2  } },
            { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level2  } },
            { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level3  } },
            { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level4  } },
            /* deprecated
            { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit,              OMX_VIDEO_MPEG4Level2  } }, */
            { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture,   OMX_VIDEO_MPEG4Level1  } },
            { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level1  } },
            { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level2  } },
            { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level1  } },
            { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level2  } },
            { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level1  } },
            { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level2  } },
            { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level1  } },
            { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level2  } },
            { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level1  } },
            { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level2  } },
            { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level3  } },
            { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level4  } },
            { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level1  } },
            { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level2  } },
            { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level3  } },
            { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level1  } },
            { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level2  } },
            { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level3  } },
            { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level4  } },
            { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level1  } },
            { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level2  } },
            { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level1  } },
            { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level2  } },
            { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level3  } },
            /* unsupported
            { 0b11100001, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level1  } },
            { 0b11100010, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level2  } },
            { 0b11100011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level3  } },
            { 0b11100100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level4  } },
            { 0b11100101, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level1  } },
            { 0b11100110, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level2  } },
            { 0b11100111, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level3  } },
            { 0b11101000, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level4  } },
            { 0b11101011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level5  } },
            { 0b11101100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level6  } }, */
            { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level0  } },
            { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level1  } },
            { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level2  } },
            { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3  } },
            { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level4  } },
            { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level5  } },
            { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3b } },
            /* deprecated
            { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0  } },
            { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1  } },
            { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2  } },
            { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3  } },
            { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4  } },
            { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5  } }, */
        };

        std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
        if (table.map(indication, &profileLevel)) {
            format->setInt32("profile", profileLevel.first);
            format->setInt32("level", profileLevel.second);
        }
    }
}

static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
    const uint8_t *data = csd->data();
    size_t remaining = csd->size();

    while (remaining >= 2) {
        const uint8_t id = data[0];
        const uint8_t length = data[1];
        remaining -= 2;
        data += 2;
        if (length > remaining) {
            break;
        }
        switch (id) {
            case 1 /* profileId */:
                if (length >= 1) {
                    const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
                        { 0, OMX_VIDEO_VP9Profile0 },
                        { 1, OMX_VIDEO_VP9Profile1 },
                        { 2, OMX_VIDEO_VP9Profile2 },
                        { 3, OMX_VIDEO_VP9Profile3 },
                    };

                    const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr {
                        { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR },
                        { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR },
                    };

                    OMX_VIDEO_VP9PROFILETYPE profile;
                    if (profiles.map(data[0], &profile)) {
                        // convert to HDR profile
                        if (isHdr(format)) {
                            toHdr.lookup(profile, &profile);
                        }

                        format->setInt32("profile", profile);
                    }
                }
                break;
            case 2 /* levelId */:
                if (length >= 1) {
                    const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
                        { 10, OMX_VIDEO_VP9Level1  },
                        { 11, OMX_VIDEO_VP9Level11 },
                        { 20, OMX_VIDEO_VP9Level2  },
                        { 21, OMX_VIDEO_VP9Level21 },
                        { 30, OMX_VIDEO_VP9Level3  },
                        { 31, OMX_VIDEO_VP9Level31 },
                        { 40, OMX_VIDEO_VP9Level4  },
                        { 41, OMX_VIDEO_VP9Level41 },
                        { 50, OMX_VIDEO_VP9Level5  },
                        { 51, OMX_VIDEO_VP9Level51 },
                        { 52, OMX_VIDEO_VP9Level52 },
                        { 60, OMX_VIDEO_VP9Level6  },
                        { 61, OMX_VIDEO_VP9Level61 },
                        { 62, OMX_VIDEO_VP9Level62 },
                    };

                    OMX_VIDEO_VP9LEVELTYPE level;
                    if (levels.map(data[0], &level)) {
                        format->setInt32("level", level);
                    }
                }
                break;
            default:
                break;
        }
        remaining -= length;
        data += length;
    }
}

status_t convertMetaDataToMessage(
        const sp<MetaData> &meta, sp<AMessage> *format) {

    format->clear();

    if (meta == NULL) {
        ALOGE("convertMetaDataToMessage: NULL input");
        return BAD_VALUE;
    }

    const char *mime;
    if (!meta->findCString(kKeyMIMEType, &mime)) {
        return BAD_VALUE;
    }

    sp<AMessage> msg = new AMessage;
    msg->setString("mime", mime);

    int64_t durationUs;
    if (meta->findInt64(kKeyDuration, &durationUs)) {
        msg->setInt64("durationUs", durationUs);
    }

    int32_t avgBitRate = 0;
    if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
        msg->setInt32("bitrate", avgBitRate);
    }

    int32_t maxBitRate;
    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
            && maxBitRate > 0 && maxBitRate >= avgBitRate) {
        msg->setInt32("max-bitrate", maxBitRate);
    }

    int32_t isSync;
    if (meta->findInt32(kKeyIsSyncFrame, &isSync) && isSync != 0) {
        msg->setInt32("is-sync-frame", 1);
    }

    // this only needs to be translated from meta to message as it is an extractor key
    int32_t trackID;
    if (meta->findInt32(kKeyTrackID, &trackID)) {
        msg->setInt32("track-id", trackID);
    }

    if (!strncasecmp("video/", mime, 6)) {
        int32_t width, height;
        if (!meta->findInt32(kKeyWidth, &width)
                || !meta->findInt32(kKeyHeight, &height)) {
            return BAD_VALUE;
        }

        msg->setInt32("width", width);
        msg->setInt32("height", height);

        int32_t sarWidth, sarHeight;
        if (meta->findInt32(kKeySARWidth, &sarWidth)
                && meta->findInt32(kKeySARHeight, &sarHeight)) {
            msg->setInt32("sar-width", sarWidth);
            msg->setInt32("sar-height", sarHeight);
        }

        int32_t colorFormat;
        if (meta->findInt32(kKeyColorFormat, &colorFormat)) {
            msg->setInt32("color-format", colorFormat);
        }

        int32_t cropLeft, cropTop, cropRight, cropBottom;
        if (meta->findRect(kKeyCropRect,
                           &cropLeft,
                           &cropTop,
                           &cropRight,
                           &cropBottom)) {
            msg->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
        }

        int32_t rotationDegrees;
        if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
            msg->setInt32("rotation-degrees", rotationDegrees);
        }

        uint32_t type;
        const void *data;
        size_t size;
        if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
                && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
            ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
        }

        convertMetaDataToMessageColorAspects(meta, msg);
    } else if (!strncasecmp("audio/", mime, 6)) {
        int32_t numChannels, sampleRate;
        if (!meta->findInt32(kKeyChannelCount, &numChannels)
                || !meta->findInt32(kKeySampleRate, &sampleRate)) {
            return BAD_VALUE;
        }

        msg->setInt32("channel-count", numChannels);
        msg->setInt32("sample-rate", sampleRate);

        int32_t channelMask;
        if (meta->findInt32(kKeyChannelMask, &channelMask)) {
            msg->setInt32("channel-mask", channelMask);
        }

        int32_t delay = 0;
        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
            msg->setInt32("encoder-delay", delay);
        }
        int32_t padding = 0;
        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
            msg->setInt32("encoder-padding", padding);
        }

        int32_t isADTS;
        if (meta->findInt32(kKeyIsADTS, &isADTS)) {
            msg->setInt32("is-adts", isADTS);
        }

        int32_t aacProfile = -1;
        if (meta->findInt32(kKeyAACAOT, &aacProfile)) {
            msg->setInt32("aac-profile", aacProfile);
        }

        int32_t pcmEncoding;
        if (meta->findInt32(kKeyPcmEncoding, &pcmEncoding)) {
            msg->setInt32("pcm-encoding", pcmEncoding);
        }
    }

    int32_t maxInputSize;
    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
        msg->setInt32("max-input-size", maxInputSize);
    }

    int32_t maxWidth;
    if (meta->findInt32(kKeyMaxWidth, &maxWidth)) {
        msg->setInt32("max-width", maxWidth);
    }

    int32_t maxHeight;
    if (meta->findInt32(kKeyMaxHeight, &maxHeight)) {
        msg->setInt32("max-height", maxHeight);
    }

    int32_t rotationDegrees;
    if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
        msg->setInt32("rotation-degrees", rotationDegrees);
    }

    int32_t fps;
    if (meta->findInt32(kKeyFrameRate, &fps) && fps > 0) {
        msg->setInt32("frame-rate", fps);
    }

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        // Parse the AVCDecoderConfigurationRecord

        const uint8_t *ptr = (const uint8_t *)data;

        if (size < 7 || ptr[0] != 1) {  // configurationVersion == 1
            ALOGE("b/23680780");
            return BAD_VALUE;
        }

        parseAvcProfileLevelFromAvcc(ptr, size, msg);

        // There is decodable content out there that fails the following
        // assertion, let's be lenient for now...
        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved

        size_t lengthSize __unused = 1 + (ptr[4] & 3);

        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
        // violates it...
        // CHECK((ptr[5] >> 5) == 7);  // reserved

        size_t numSeqParameterSets = ptr[5] & 31;

        ptr += 6;
        size -= 6;

        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        buffer->setRange(0, 0);

        for (size_t i = 0; i < numSeqParameterSets; ++i) {
            if (size < 2) {
                ALOGE("b/23680780");
                return BAD_VALUE;
            }
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            if (size < length) {
                return BAD_VALUE;
            }
            status_t err = copyNALUToABuffer(&buffer, ptr, length);
            if (err != OK) {
                return err;
            }

            ptr += length;
            size -= length;
        }

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);

        msg->setBuffer("csd-0", buffer);

        buffer = new (std::nothrow) ABuffer(1024);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        buffer->setRange(0, 0);

        if (size < 1) {
            ALOGE("b/23680780");
            return BAD_VALUE;
        }
        size_t numPictureParameterSets = *ptr;
        ++ptr;
        --size;

        for (size_t i = 0; i < numPictureParameterSets; ++i) {
            if (size < 2) {
                ALOGE("b/23680780");
                return BAD_VALUE;
            }
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            if (size < length) {
                return BAD_VALUE;
            }
            status_t err = copyNALUToABuffer(&buffer, ptr, length);
            if (err != OK) {
                return err;
            }

            ptr += length;
            size -= length;
        }

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-1", buffer);
    } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
        const uint8_t *ptr = (const uint8_t *)data;

        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
            ALOGE("b/23680780");
            return BAD_VALUE;
        }

        const size_t dataSize = size; // save for later
        ptr += 22;
        size -= 22;

        size_t numofArrays = (char)ptr[0];
        ptr += 1;
        size -= 1;
        size_t j = 0, i = 0;

        sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        buffer->setRange(0, 0);

        HevcParameterSets hvcc;

        for (i = 0; i < numofArrays; i++) {
            if (size < 3) {
                ALOGE("b/23680780");
                return BAD_VALUE;
            }
            ptr += 1;
            size -= 1;

            //Num of nals
            size_t numofNals = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            for (j = 0; j < numofNals; j++) {
                if (size < 2) {
                    ALOGE("b/23680780");
                    return BAD_VALUE;
                }
                size_t length = U16_AT(ptr);

                ptr += 2;
                size -= 2;

                if (size < length) {
                    return BAD_VALUE;
                }
                status_t err = copyNALUToABuffer(&buffer, ptr, length);
                if (err != OK) {
                    return err;
                }
                (void)hvcc.addNalUnit(ptr, length);

                ptr += length;
                size -= length;
            }
        }
        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        // if we saw VUI color information we know whether this is HDR because VUI trumps other
        // format parameters for HEVC.
        HevcParameterSets::Info info = hvcc.getInfo();
        if (info & hvcc.kInfoHasColorDescription) {
            msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
        }

        parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const char *)data, size);
        if (esds.InitCheck() != (status_t)OK) {
            return BAD_VALUE;
        }

        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }

        memcpy(buffer->data(), codec_specific_data,
               codec_specific_data_size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
            parseMpeg4ProfileLevelFromCsd(buffer, msg);
        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
            parseMpeg2ProfileLevelFromEsds(esds, msg);
            if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
                parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
            }
        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
            parseAacProfileFromCsd(buffer, msg);
        }

        uint32_t maxBitrate, avgBitrate;
        if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
            if (!meta->hasData(kKeyBitRate)
                    && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
                msg->setInt32("bitrate", (int32_t)avgBitrate);
            } else {
                (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
            }
            if (!meta->hasData(kKeyMaxBitRate)
                    && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
            }
        }
    } else if (meta->findData(kTypeD263, &type, &data, &size)) {
        const uint8_t *ptr = (const uint8_t *)data;
        parseH263ProfileLevelFromD263(ptr, size, msg);
    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
            return -EINVAL;
        }

        buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-1", buffer);
    } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) {
        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        if (!meta->findData(kKeyOpusCodecDelay, &type, &data, &size)) {
            return -EINVAL;
        }

        buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-1", buffer);

        if (!meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)) {
            return -EINVAL;
        }

        buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-2", buffer);
    } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
        if (buffer.get() == NULL || buffer->base() == NULL) {
            return NO_MEMORY;
        }
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        buffer->meta()->setInt64("timeUs", 0);
        msg->setBuffer("csd-0", buffer);

        parseVp9ProfileLevelFromCsd(buffer, msg);
    }

    // TODO expose "crypto-key"/kKeyCryptoKey through public api
    if (meta->findData(kKeyCryptoKey, &type, &data, &size)) {
        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
        msg->setBuffer("crypto-key", buffer);
        memcpy(buffer->data(), data, size);
    }

    *format = msg;

    return OK;
}

const uint8_t *findNextNalStartCode(const uint8_t *data, size_t length) {
    uint8_t *res = NULL;
    if (length > 4) {
        // minus 1 as to not match NAL start code at end
        res = (uint8_t *)memmem(data, length - 1, "\x00\x00\x00\x01", 4);
    }
    return res != NULL && res < data + length - 4 ? res : &data[length];
}

static size_t reassembleAVCC(const sp<ABuffer> &csd0, const sp<ABuffer> &csd1, char *avcc) {
    avcc[0] = 1;        // version
    avcc[1] = 0x64;     // profile (default to high)
    avcc[2] = 0;        // constraints (default to none)
    avcc[3] = 0xd;      // level (default to 1.3)
    avcc[4] = 0xff;     // reserved+size

    size_t i = 0;
    int numparams = 0;
    int lastparamoffset = 0;
    int avccidx = 6;
    do {
        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
        ALOGV("block at %zu, last was %d", i, lastparamoffset);
        if (lastparamoffset > 0) {
            const uint8_t *lastparam = csd0->data() + lastparamoffset;
            int size = i - lastparamoffset;
            if (size > 3) {
                if (numparams && memcmp(avcc + 1, lastparam + 1, 3)) {
                    ALOGW("Inconsisted profile/level found in SPS: %x,%x,%x vs %x,%x,%x",
                            avcc[1], avcc[2], avcc[3], lastparam[1], lastparam[2], lastparam[3]);
                } else if (!numparams) {
                    // fill in profile, constraints and level
                    memcpy(avcc + 1, lastparam + 1, 3);
                }
            }
            avcc[avccidx++] = size >> 8;
            avcc[avccidx++] = size & 0xff;
            memcpy(avcc+avccidx, lastparam, size);
            avccidx += size;
            numparams++;
        }
        i += 4;
        lastparamoffset = i;
    } while(i < csd0->size());
    ALOGV("csd0 contains %d params", numparams);

    avcc[5] = 0xe0 | numparams;
    //and now csd-1
    i = 0;
    numparams = 0;
    lastparamoffset = 0;
    int numpicparamsoffset = avccidx;
    avccidx++;
    do {
        i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
        ALOGV("block at %zu, last was %d", i, lastparamoffset);
        if (lastparamoffset > 0) {
            int size = i - lastparamoffset;
            avcc[avccidx++] = size >> 8;
            avcc[avccidx++] = size & 0xff;
            memcpy(avcc+avccidx, csd1->data() + lastparamoffset, size);
            avccidx += size;
            numparams++;
        }
        i += 4;
        lastparamoffset = i;
    } while(i < csd1->size());
    avcc[numpicparamsoffset] = numparams;
    return avccidx;
}

static void reassembleESDS(const sp<ABuffer> &csd0, char *esds) {
    int csd0size = csd0->size();
    esds[0] = 3; // kTag_ESDescriptor;
    int esdescriptorsize = 26 + csd0size;
    CHECK(esdescriptorsize < 268435456); // 7 bits per byte, so max is 2^28-1
    esds[1] = 0x80 | (esdescriptorsize >> 21);
    esds[2] = 0x80 | ((esdescriptorsize >> 14) & 0x7f);
    esds[3] = 0x80 | ((esdescriptorsize >> 7) & 0x7f);
    esds[4] = (esdescriptorsize & 0x7f);
    esds[5] = esds[6] = 0; // es id
    esds[7] = 0; // flags
    esds[8] = 4; // kTag_DecoderConfigDescriptor
    int configdescriptorsize = 18 + csd0size;
    esds[9] = 0x80 | (configdescriptorsize >> 21);
    esds[10] = 0x80 | ((configdescriptorsize >> 14) & 0x7f);
    esds[11] = 0x80 | ((configdescriptorsize >> 7) & 0x7f);
    esds[12] = (configdescriptorsize & 0x7f);
    esds[13] = 0x40; // objectTypeIndication
    // bytes 14-25 are examples from a real file. they are unused/overwritten by muxers.
    esds[14] = 0x15; // streamType(5), upStream(0),
    esds[15] = 0x00; // 15-17: bufferSizeDB (6KB)
    esds[16] = 0x18;
    esds[17] = 0x00;
    esds[18] = 0x00; // 18-21: maxBitrate (64kbps)
    esds[19] = 0x00;
    esds[20] = 0xfa;
    esds[21] = 0x00;
    esds[22] = 0x00; // 22-25: avgBitrate (64kbps)
    esds[23] = 0x00;
    esds[24] = 0xfa;
    esds[25] = 0x00;
    esds[26] = 5; // kTag_DecoderSpecificInfo;
    esds[27] = 0x80 | (csd0size >> 21);
    esds[28] = 0x80 | ((csd0size >> 14) & 0x7f);
    esds[29] = 0x80 | ((csd0size >> 7) & 0x7f);
    esds[30] = (csd0size & 0x7f);
    memcpy((void*)&esds[31], csd0->data(), csd0size);
    // data following this is ignored, so don't bother appending it
}

static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvccSize, size_t nalSizeLength) {
    HevcParameterSets paramSets;
    uint8_t* data = csd0->data();
    if (csd0->size() < 4) {
        ALOGE("csd0 too small");
        return 0;
    }
    if (memcmp(data, "\x00\x00\x00\x01", 4) != 0) {
        ALOGE("csd0 doesn't start with a start code");
        return 0;
    }
    size_t prevNalOffset = 4;
    status_t err = OK;
    for (size_t i = 1; i < csd0->size() - 4; ++i) {
        if (memcmp(&data[i], "\x00\x00\x00\x01", 4) != 0) {
            continue;
        }
        err = paramSets.addNalUnit(&data[prevNalOffset], i - prevNalOffset);
        if (err != OK) {
            return 0;
        }
        prevNalOffset = i + 4;
    }
    err = paramSets.addNalUnit(&data[prevNalOffset], csd0->size() - prevNalOffset);
    if (err != OK) {
        return 0;
    }
    size_t size = hvccSize;
    err = paramSets.makeHvcc(hvcc, &size, nalSizeLength);
    if (err != OK) {
        return 0;
    }
    return size;
}

#if 0
static void convertMessageToMetaDataInt32(
        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
    int32_t value;
    if (msg->findInt32(name, &value)) {
        meta->setInt32(key, value);
    }
}
#endif

static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
    // 0 values are unspecified
    int32_t range = 0, standard = 0, transfer = 0;
    (void)msg->findInt32("color-range", &range);
    (void)msg->findInt32("color-standard", &standard);
    (void)msg->findInt32("color-transfer", &transfer);

    ColorAspects colorAspects;
    memset(&colorAspects, 0, sizeof(colorAspects));
    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
            range, standard, transfer, colorAspects) != OK) {
        return;
    }

    // save specified values to meta
    if (colorAspects.mRange != 0) {
        meta->setInt32(kKeyColorRange, colorAspects.mRange);
    }
    if (colorAspects.mPrimaries != 0) {
        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
    }
    if (colorAspects.mTransfer != 0) {
        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
    }
    if (colorAspects.mMatrixCoeffs != 0) {
        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
    }
}

void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
    AString mime;
    if (msg->findString("mime", &mime)) {
        meta->setCString(kKeyMIMEType, mime.c_str());
    } else {
        ALOGW("did not find mime type");
    }

    int64_t durationUs;
    if (msg->findInt64("durationUs", &durationUs)) {
        meta->setInt64(kKeyDuration, durationUs);
    }

    int32_t isSync;
    if (msg->findInt32("is-sync-frame", &isSync) && isSync != 0) {
        meta->setInt32(kKeyIsSyncFrame, 1);
    }

    int32_t avgBitrate = 0;
    int32_t maxBitrate;
    if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
        meta->setInt32(kKeyBitRate, avgBitrate);
    }
    if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
        meta->setInt32(kKeyMaxBitRate, maxBitrate);
    }

    if (mime.startsWith("video/")) {
        int32_t width;
        int32_t height;
        if (msg->findInt32("width", &width) && msg->findInt32("height", &height)) {
            meta->setInt32(kKeyWidth, width);
            meta->setInt32(kKeyHeight, height);
        } else {
            ALOGW("did not find width and/or height");
        }

        int32_t sarWidth, sarHeight;
        if (msg->findInt32("sar-width", &sarWidth)
                && msg->findInt32("sar-height", &sarHeight)) {
            meta->setInt32(kKeySARWidth, sarWidth);
            meta->setInt32(kKeySARHeight, sarHeight);
        }

        int32_t colorFormat;
        if (msg->findInt32("color-format", &colorFormat)) {
            meta->setInt32(kKeyColorFormat, colorFormat);
        }

        int32_t cropLeft, cropTop, cropRight, cropBottom;
        if (msg->findRect("crop",
                          &cropLeft,
                          &cropTop,
                          &cropRight,
                          &cropBottom)) {
            meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom);
        }

        int32_t rotationDegrees;
        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
            meta->setInt32(kKeyRotation, rotationDegrees);
        }

        if (msg->contains("hdr-static-info")) {
            HDRStaticInfo info;
            if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
                meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
            }
        }

        convertMessageToMetaDataColorAspects(msg, meta);

        AString tsSchema;
        if (msg->findString("ts-schema", &tsSchema)) {
            unsigned int numLayers = 0;
            unsigned int numBLayers = 0;
            char dummy;
            int tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
                    &numLayers, &dummy, &numBLayers, &dummy);
            if ((tags == 1 || (tags == 3 && dummy == '+'))
                    && numLayers > 0 && numLayers < UINT32_MAX - numBLayers
                    && numLayers + numBLayers <= INT32_MAX) {
                meta->setInt32(kKeyTemporalLayerCount, numLayers + numBLayers);
            }
        }
    } else if (mime.startsWith("audio/")) {
        int32_t numChannels;
        if (msg->findInt32("channel-count", &numChannels)) {
            meta->setInt32(kKeyChannelCount, numChannels);
        }
        int32_t sampleRate;
        if (msg->findInt32("sample-rate", &sampleRate)) {
            meta->setInt32(kKeySampleRate, sampleRate);
        }
        int32_t channelMask;
        if (msg->findInt32("channel-mask", &channelMask)) {
            meta->setInt32(kKeyChannelMask, channelMask);
        }
        int32_t delay = 0;
        if (msg->findInt32("encoder-delay", &delay)) {
            meta->setInt32(kKeyEncoderDelay, delay);
        }
        int32_t padding = 0;
        if (msg->findInt32("encoder-padding", &padding)) {
            meta->setInt32(kKeyEncoderPadding, padding);
        }

        int32_t isADTS;
        if (msg->findInt32("is-adts", &isADTS)) {
            meta->setInt32(kKeyIsADTS, isADTS);
        }

        int32_t pcmEncoding;
        if (msg->findInt32("pcm-encoding", &pcmEncoding)) {
            meta->setInt32(kKeyPcmEncoding, pcmEncoding);
        }
    }

    int32_t maxInputSize;
    if (msg->findInt32("max-input-size", &maxInputSize)) {
        meta->setInt32(kKeyMaxInputSize, maxInputSize);
    }

    int32_t maxWidth;
    if (msg->findInt32("max-width", &maxWidth)) {
        meta->setInt32(kKeyMaxWidth, maxWidth);
    }

    int32_t maxHeight;
    if (msg->findInt32("max-height", &maxHeight)) {
        meta->setInt32(kKeyMaxHeight, maxHeight);
    }

    int32_t fps;
    float fpsFloat;
    if (msg->findInt32("frame-rate", &fps) && fps > 0) {
        meta->setInt32(kKeyFrameRate, fps);
    } else if (msg->findFloat("frame-rate", &fpsFloat)
            && fpsFloat >= 1 && fpsFloat <= INT32_MAX) {
        // truncate values to distinguish between e.g. 24 vs 23.976 fps
        meta->setInt32(kKeyFrameRate, (int32_t)fpsFloat);
    }

    // reassemble the csd data into its original form
    sp<ABuffer> csd0, csd1, csd2;
    if (msg->findBuffer("csd-0", &csd0)) {
        int csd0size = csd0->size();
        if (mime == MEDIA_MIMETYPE_VIDEO_AVC) {
            sp<ABuffer> csd1;
            if (msg->findBuffer("csd-1", &csd1)) {
                std::vector<char> avcc(csd0size + csd1->size() + 1024);
                size_t outsize = reassembleAVCC(csd0, csd1, avcc.data());
                meta->setData(kKeyAVCC, kKeyAVCC, avcc.data(), outsize);
            }
        } else if (mime == MEDIA_MIMETYPE_AUDIO_AAC || mime == MEDIA_MIMETYPE_VIDEO_MPEG4) {
            std::vector<char> esds(csd0size + 31);
            // The written ESDS is actually for an audio stream, but it's enough
            // for transporting the CSD to muxers.
            reassembleESDS(csd0, esds.data());
            meta->setData(kKeyESDS, kKeyESDS, esds.data(), esds.size());
        } else if (mime == MEDIA_MIMETYPE_VIDEO_HEVC) {
            std::vector<uint8_t> hvcc(csd0size + 1024);
            size_t outsize = reassembleHVCC(csd0, hvcc.data(), hvcc.size(), 4);
            meta->setData(kKeyHVCC, kKeyHVCC, hvcc.data(), outsize);
        } else if (mime == MEDIA_MIMETYPE_VIDEO_VP9) {
            meta->setData(kKeyVp9CodecPrivate, 0, csd0->data(), csd0->size());
        } else if (mime == MEDIA_MIMETYPE_AUDIO_OPUS) {
            meta->setData(kKeyOpusHeader, 0, csd0->data(), csd0->size());
            if (msg->findBuffer("csd-1", &csd1)) {
                meta->setData(kKeyOpusCodecDelay, 0, csd1->data(), csd1->size());
            }
            if (msg->findBuffer("csd-2", &csd2)) {
                meta->setData(kKeyOpusSeekPreRoll, 0, csd2->data(), csd2->size());
            }
        } else if (mime == MEDIA_MIMETYPE_AUDIO_VORBIS) {
            meta->setData(kKeyVorbisInfo, 0, csd0->data(), csd0->size());
            if (msg->findBuffer("csd-1", &csd1)) {
                meta->setData(kKeyVorbisBooks, 0, csd1->data(), csd1->size());
            }
        }
    }

    int32_t timeScale;
    if (msg->findInt32("time-scale", &timeScale)) {
        meta->setInt32(kKeyTimeScale, timeScale);
    }

    // XXX TODO add whatever other keys there are

#if 0
    ALOGI("converted %s to:", msg->debugString(0).c_str());
    meta->dumpToLog();
#endif
}

AString MakeUserAgent() {
    AString ua;
    ua.append("stagefright/1.2 (Linux;Android ");

#if (PROPERTY_VALUE_MAX < 8)
#error "PROPERTY_VALUE_MAX must be at least 8"
#endif

    char value[PROPERTY_VALUE_MAX];
    property_get("ro.build.version.release", value, "Unknown");
    ua.append(value);
    ua.append(")");

    return ua;
}

status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink,
                           const sp<MetaData>& meta)
{
    int32_t sampleRate = 0;
    int32_t bitRate = 0;
    int32_t channelMask = 0;
    int32_t delaySamples = 0;
    int32_t paddingSamples = 0;

    AudioParameter param = AudioParameter();

    if (meta->findInt32(kKeySampleRate, &sampleRate)) {
        param.addInt(String8(AUDIO_OFFLOAD_CODEC_SAMPLE_RATE), sampleRate);
    }
    if (meta->findInt32(kKeyChannelMask, &channelMask)) {
        param.addInt(String8(AUDIO_OFFLOAD_CODEC_NUM_CHANNEL), channelMask);
    }
    if (meta->findInt32(kKeyBitRate, &bitRate)) {
        param.addInt(String8(AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE), bitRate);
    }
    if (meta->findInt32(kKeyEncoderDelay, &delaySamples)) {
        param.addInt(String8(AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES), delaySamples);
    }
    if (meta->findInt32(kKeyEncoderPadding, &paddingSamples)) {
        param.addInt(String8(AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES), paddingSamples);
    }

    ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d,"
          "delaySample %d, paddingSample %d", bitRate, sampleRate,
          channelMask, delaySamples, paddingSamples);

    sink->setParameters(param.toString());
    return OK;
}

struct mime_conv_t {
    const char* mime;
    audio_format_t format;
};

static const struct mime_conv_t mimeLookup[] = {
    { MEDIA_MIMETYPE_AUDIO_MPEG,        AUDIO_FORMAT_MP3 },
    { MEDIA_MIMETYPE_AUDIO_RAW,         AUDIO_FORMAT_PCM_16_BIT },
    { MEDIA_MIMETYPE_AUDIO_AMR_NB,      AUDIO_FORMAT_AMR_NB },
    { MEDIA_MIMETYPE_AUDIO_AMR_WB,      AUDIO_FORMAT_AMR_WB },
    { MEDIA_MIMETYPE_AUDIO_AAC,         AUDIO_FORMAT_AAC },
    { MEDIA_MIMETYPE_AUDIO_VORBIS,      AUDIO_FORMAT_VORBIS },
    { MEDIA_MIMETYPE_AUDIO_OPUS,        AUDIO_FORMAT_OPUS},
    { 0, AUDIO_FORMAT_INVALID }
};

status_t mapMimeToAudioFormat( audio_format_t& format, const char* mime )
{
const struct mime_conv_t* p = &mimeLookup[0];
    while (p->mime != NULL) {
        if (0 == strcasecmp(mime, p->mime)) {
            format = p->format;
            return OK;
        }
        ++p;
    }

    return BAD_VALUE;
}

struct aac_format_conv_t {
    OMX_AUDIO_AACPROFILETYPE eAacProfileType;
    audio_format_t format;
};

static const struct aac_format_conv_t profileLookup[] = {
    { OMX_AUDIO_AACObjectMain,        AUDIO_FORMAT_AAC_MAIN},
    { OMX_AUDIO_AACObjectLC,          AUDIO_FORMAT_AAC_LC},
    { OMX_AUDIO_AACObjectSSR,         AUDIO_FORMAT_AAC_SSR},
    { OMX_AUDIO_AACObjectLTP,         AUDIO_FORMAT_AAC_LTP},
    { OMX_AUDIO_AACObjectHE,          AUDIO_FORMAT_AAC_HE_V1},
    { OMX_AUDIO_AACObjectScalable,    AUDIO_FORMAT_AAC_SCALABLE},
    { OMX_AUDIO_AACObjectERLC,        AUDIO_FORMAT_AAC_ERLC},
    { OMX_AUDIO_AACObjectLD,          AUDIO_FORMAT_AAC_LD},
    { OMX_AUDIO_AACObjectHE_PS,       AUDIO_FORMAT_AAC_HE_V2},
    { OMX_AUDIO_AACObjectELD,         AUDIO_FORMAT_AAC_ELD},
    { OMX_AUDIO_AACObjectNull,        AUDIO_FORMAT_AAC},
};

void mapAACProfileToAudioFormat( audio_format_t& format, uint64_t eAacProfile)
{
const struct aac_format_conv_t* p = &profileLookup[0];
    while (p->eAacProfileType != OMX_AUDIO_AACObjectNull) {
        if (eAacProfile == p->eAacProfileType) {
            format = p->format;
            return;
        }
        ++p;
    }
    format = AUDIO_FORMAT_AAC;
    return;
}

bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
                      bool isStreaming, audio_stream_type_t streamType)
{
    const char *mime;
    if (meta == NULL) {
        return false;
    }
    CHECK(meta->findCString(kKeyMIMEType, &mime));

    audio_offload_info_t info = AUDIO_INFO_INITIALIZER;

    info.format = AUDIO_FORMAT_INVALID;
    if (mapMimeToAudioFormat(info.format, mime) != OK) {
        ALOGE(" Couldn't map mime type \"%s\" to a valid AudioSystem::audio_format !", mime);
        return false;
    } else {
        ALOGV("Mime type \"%s\" mapped to audio_format %d", mime, info.format);
    }

    if (AUDIO_FORMAT_INVALID == info.format) {
        // can't offload if we don't know what the source format is
        ALOGE("mime type \"%s\" not a known audio format", mime);
        return false;
    }

    // Redefine aac format according to its profile
    // Offloading depends on audio DSP capabilities.
    int32_t aacaot = -1;
    if (meta->findInt32(kKeyAACAOT, &aacaot)) {
        mapAACProfileToAudioFormat(info.format,(OMX_AUDIO_AACPROFILETYPE) aacaot);
    }

    int32_t srate = -1;
    if (!meta->findInt32(kKeySampleRate, &srate)) {
        ALOGV("track of type '%s' does not publish sample rate", mime);
    }
    info.sample_rate = srate;

    int32_t cmask = 0;
    if (!meta->findInt32(kKeyChannelMask, &cmask)) {
        ALOGV("track of type '%s' does not publish channel mask", mime);

        // Try a channel count instead
        int32_t channelCount;
        if (!meta->findInt32(kKeyChannelCount, &channelCount)) {
            ALOGV("track of type '%s' does not publish channel count", mime);
        } else {
            cmask = audio_channel_out_mask_from_count(channelCount);
        }
    }
    info.channel_mask = cmask;

    int64_t duration = 0;
    if (!meta->findInt64(kKeyDuration, &duration)) {
        ALOGV("track of type '%s' does not publish duration", mime);
    }
    info.duration_us = duration;

    int32_t brate = -1;
    if (!meta->findInt32(kKeyBitRate, &brate)) {
        ALOGV("track of type '%s' does not publish bitrate", mime);
    }
    info.bit_rate = brate;


    info.stream_type = streamType;
    info.has_video = hasVideo;
    info.is_streaming = isStreaming;

    // Check if offload is possible for given format, stream type, sample rate,
    // bit rate, duration, video and streaming
    return AudioSystem::isOffloadSupported(info);
}

AString uriDebugString(const AString &uri, bool incognito) {
    if (incognito) {
        return AString("<URI suppressed>");
    }

    char prop[PROPERTY_VALUE_MAX];
    if (property_get("media.stagefright.log-uri", prop, "false") &&
        (!strcmp(prop, "1") || !strcmp(prop, "true"))) {
        return uri;
    }

    // find scheme
    AString scheme;
    const char *chars = uri.c_str();
    for (size_t i = 0; i < uri.size(); i++) {
        const char c = chars[i];
        if (!isascii(c)) {
            break;
        } else if (isalpha(c)) {
            continue;
        } else if (i == 0) {
            // first character must be a letter
            break;
        } else if (isdigit(c) || c == '+' || c == '.' || c =='-') {
            continue;
        } else if (c != ':') {
            break;
        }
        scheme = AString(uri, 0, i);
        scheme.append("://<suppressed>");
        return scheme;
    }
    return AString("<no-scheme URI suppressed>");
}

HLSTime::HLSTime(const sp<AMessage>& meta) :
    mSeq(-1),
    mTimeUs(-1ll),
    mMeta(meta) {
    if (meta != NULL) {
        CHECK(meta->findInt32("discontinuitySeq", &mSeq));
        CHECK(meta->findInt64("timeUs", &mTimeUs));
    }
}

int64_t HLSTime::getSegmentTimeUs() const {
    int64_t segmentStartTimeUs = -1ll;
    if (mMeta != NULL) {
        CHECK(mMeta->findInt64("segmentStartTimeUs", &segmentStartTimeUs));

        int64_t segmentFirstTimeUs;
        if (mMeta->findInt64("segmentFirstTimeUs", &segmentFirstTimeUs)) {
            segmentStartTimeUs += mTimeUs - segmentFirstTimeUs;
        }

        // adjust segment time by playlist age (for live streaming)
        int64_t playlistTimeUs;
        if (mMeta->findInt64("playlistTimeUs", &playlistTimeUs)) {
            int64_t playlistAgeUs = ALooper::GetNowUs() - playlistTimeUs;

            int64_t durationUs;
            CHECK(mMeta->findInt64("segmentDurationUs", &durationUs));

            // round to nearest whole segment
            playlistAgeUs = (playlistAgeUs + durationUs / 2)
                    / durationUs * durationUs;

            segmentStartTimeUs -= playlistAgeUs;
            if (segmentStartTimeUs < 0) {
                segmentStartTimeUs = 0;
            }
        }
    }
    return segmentStartTimeUs;
}

bool operator <(const HLSTime &t0, const HLSTime &t1) {
    // we can only compare discontinuity sequence and timestamp.
    // (mSegmentTimeUs is not reliable in live streaming case, it's the
    // time starting from beginning of playlist but playlist could change.)
    return t0.mSeq < t1.mSeq
            || (t0.mSeq == t1.mSeq && t0.mTimeUs < t1.mTimeUs);
}

void writeToAMessage(const sp<AMessage> &msg, const AudioPlaybackRate &rate) {
    msg->setFloat("speed", rate.mSpeed);
    msg->setFloat("pitch", rate.mPitch);
    msg->setInt32("audio-fallback-mode", rate.mFallbackMode);
    msg->setInt32("audio-stretch-mode", rate.mStretchMode);
}

void readFromAMessage(const sp<AMessage> &msg, AudioPlaybackRate *rate /* nonnull */) {
    *rate = AUDIO_PLAYBACK_RATE_DEFAULT;
    CHECK(msg->findFloat("speed", &rate->mSpeed));
    CHECK(msg->findFloat("pitch", &rate->mPitch));
    CHECK(msg->findInt32("audio-fallback-mode", (int32_t *)&rate->mFallbackMode));
    CHECK(msg->findInt32("audio-stretch-mode", (int32_t *)&rate->mStretchMode));
}

void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float videoFpsHint) {
    msg->setInt32("sync-source", sync.mSource);
    msg->setInt32("audio-adjust-mode", sync.mAudioAdjustMode);
    msg->setFloat("tolerance", sync.mTolerance);
    msg->setFloat("video-fps", videoFpsHint);
}

void readFromAMessage(
        const sp<AMessage> &msg,
        AVSyncSettings *sync /* nonnull */,
        float *videoFps /* nonnull */) {
    AVSyncSettings settings;
    CHECK(msg->findInt32("sync-source", (int32_t *)&settings.mSource));
    CHECK(msg->findInt32("audio-adjust-mode", (int32_t *)&settings.mAudioAdjustMode));
    CHECK(msg->findFloat("tolerance", &settings.mTolerance));
    CHECK(msg->findFloat("video-fps", videoFps));
    *sync = settings;
}

AString nameForFd(int fd) {
    const size_t SIZE = 256;
    char buffer[SIZE];
    AString result;
    snprintf(buffer, SIZE, "/proc/%d/fd/%d", getpid(), fd);
    struct stat s;
    if (lstat(buffer, &s) == 0) {
        if ((s.st_mode & S_IFMT) == S_IFLNK) {
            char linkto[256];
            int len = readlink(buffer, linkto, sizeof(linkto));
            if(len > 0) {
                if(len > 255) {
                    linkto[252] = '.';
                    linkto[253] = '.';
                    linkto[254] = '.';
                    linkto[255] = 0;
                } else {
                    linkto[len] = 0;
                }
                result.append(linkto);
            }
        } else {
            result.append("unexpected type for ");
            result.append(buffer);
        }
    } else {
        result.append("couldn't open ");
        result.append(buffer);
    }
    return result;
}

}  // namespace android

