120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber//#define LOG_NDEBUG 0 18f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber#define LOG_TAG "ESDS" 19f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber#include <utils/Log.h> 20f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber 2146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar#include <media/stagefright/Utils.h> 2246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/ESDS.h" 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberESDS::ESDS(const void *data, size_t size) 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mData(new uint8_t[size]), 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSize(size), 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mInitCheck(NO_INIT), 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDecoderSpecificOffset(0), 3481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mDecoderSpecificLength(0), 3581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mObjectTypeIndication(0) { 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber memcpy(mData, data, size); 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mInitCheck = parse(); 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberESDS::~ESDS() { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mData; 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mData = NULL; 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::InitCheck() const { 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mInitCheck; 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5081f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huberstatus_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const { 5181f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber if (mInitCheck != OK) { 5281f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return mInitCheck; 5381f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber } 5481f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 5581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber *objectTypeIndication = mObjectTypeIndication; 5681f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 5781f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber return OK; 5881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber} 5981f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const { 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mInitCheck != OK) { 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mInitCheck; 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *data = &mData[mDecoderSpecificOffset]; 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *size = mDecoderSpecificLength; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::skipDescriptorHeader( 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset, size_t size, 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t *tag, size_t *data_offset, size_t *data_size) const { 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (size == 0) { 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *tag = mData[offset++]; 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --size; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *data_size = 0; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool more; 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber do { 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (size == 0) { 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t x = mData[offset++]; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --size; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *data_size = (*data_size << 7) | (x & 0x7f); 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber more = (x & 0x80) != 0; 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (more); 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("tag=0x%02x data_size=%zu", *tag, *data_size); 97f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (*data_size > size) { 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *data_offset = offset; 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::parse() { 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t tag; 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t data_offset; 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t data_size; 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size); 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (tag != kTag_ESDescriptor) { 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return parseESDescriptor(data_offset, data_size); 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::parseESDescriptor(size_t offset, size_t size) { 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (size < 3) { 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 2; // skip ES_ID 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size -= 2; 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned streamDependenceFlag = mData[offset] & 0x80; 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned URL_Flag = mData[offset] & 0x40; 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned OCRstreamFlag = mData[offset] & 0x20; 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++offset; 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --size; 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (streamDependenceFlag) { 14107c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake if (size < 2) 14207c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake return ERROR_MALFORMED; 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 2; 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size -= 2; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (URL_Flag) { 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset >= size) { 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber unsigned URLlength = mData[offset]; 15207c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake if (URLlength >= size) 15307c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake return ERROR_MALFORMED; 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += URLlength + 1; 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size -= URLlength + 1; 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (OCRstreamFlag) { 15907c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake if (size < 2) 16007c0f59d6c48874982d2b5c713487612e5af465aJoshua J. Drake return ERROR_MALFORMED; 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 2; 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size -= 2; 163f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber 164f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber if ((offset >= size || mData[offset] != kTag_DecoderConfigDescriptor) 165f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber && offset - 2 < size 166f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber && mData[offset - 2] == kTag_DecoderConfigDescriptor) { 167f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber // Content found "in the wild" had OCRstreamFlag set but was 168f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber // missing OCR_ES_Id, the decoder config descriptor immediately 169f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber // followed instead. 170f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber offset -= 2; 171f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber size += 2; 172f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber 1735ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Found malformed 'esds' atom, ignoring missing OCR_ES_Id."); 174f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber } 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 176f3dadf2204119eb7ef263535d53d36cd14b9bf47Andreas Huber 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset >= size) { 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t tag; 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sub_offset, sub_size; 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = skipDescriptorHeader( 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset, size, &tag, &sub_offset, &sub_size); 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (tag != kTag_DecoderConfigDescriptor) { 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber err = parseDecoderConfigDescriptor(sub_offset, sub_size); 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnarstatus_t ESDS::getBitRate(uint32_t *brateMax, uint32_t *brateAvg) const { 20046f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar if (mInitCheck != OK) { 20146f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return mInitCheck; 20246f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar } 20346f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 20446f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar *brateMax = mBitRateMax; 20546f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar *brateAvg = mBitRateAvg; 20646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 20746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar return OK; 20846f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar}; 20946f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) { 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (size < 13) { 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21581f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber mObjectTypeIndication = mData[offset]; 21646f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mBitRateMax = U32_AT(mData + offset + 5); 21746f80165c595d81dda68f8f3fea27f4fb04937ddLajos Molnar mBitRateAvg = U32_AT(mData + offset + 9); 21881f82c32459029bf0744e28c73f95a7f18cab5acAndreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 13; 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size -= 13; 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (size == 0) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDecoderSpecificOffset = 0; 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDecoderSpecificLength = 0; 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t tag; 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sub_offset, sub_size; 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = skipDescriptorHeader( 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset, size, &tag, &sub_offset, &sub_size); 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (tag != kTag_DecoderSpecificInfo) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDecoderSpecificOffset = sub_offset; 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDecoderSpecificLength = sub_size; 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 249