LCOV - code coverage report
Current view: top level - media/libstagefright/frameworks/av/media/libstagefright - ESDS.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 111 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #undef LOG_TAG
      19             : #define LOG_TAG "ESDS"
      20             : #include <utils/Log.h>
      21             : 
      22             : #include "include/ESDS.h"
      23             : 
      24             : #include <string.h>
      25             : 
      26             : namespace stagefright {
      27             : 
      28           0 : ESDS::ESDS(const void *data, size_t size)
      29           0 :     : mData(new (mozilla::fallible) uint8_t[size]),
      30             :       mSize(size),
      31             :       mInitCheck(NO_INIT),
      32             :       mDecoderSpecificOffset(0),
      33             :       mDecoderSpecificLength(0),
      34           0 :       mObjectTypeIndication(0) {
      35           0 :     if (!mData) {
      36           0 :       mInitCheck = ERROR_BUFFER_TOO_SMALL;
      37           0 :       return;
      38             :     }
      39             : 
      40           0 :     memcpy(mData, data, size);
      41             : 
      42           0 :     mInitCheck = parse();
      43             : }
      44             : 
      45           0 : ESDS::~ESDS() {
      46           0 :     delete[] mData;
      47           0 :     mData = NULL;
      48           0 : }
      49             : 
      50           0 : status_t ESDS::InitCheck() const {
      51           0 :     return mInitCheck;
      52             : }
      53             : 
      54           0 : status_t ESDS::getObjectTypeIndication(uint8_t *objectTypeIndication) const {
      55           0 :     if (mInitCheck != OK) {
      56           0 :         return mInitCheck;
      57             :     }
      58             : 
      59           0 :     *objectTypeIndication = mObjectTypeIndication;
      60             : 
      61           0 :     return OK;
      62             : }
      63             : 
      64           0 : status_t ESDS::getCodecSpecificInfo(const void **data, size_t *size) const {
      65           0 :     if (mInitCheck != OK) {
      66           0 :         return mInitCheck;
      67             :     }
      68             : 
      69           0 :     *data = &mData[mDecoderSpecificOffset];
      70           0 :     *size = mDecoderSpecificLength;
      71             : 
      72           0 :     return OK;
      73             : }
      74             : 
      75           0 : status_t ESDS::skipDescriptorHeader(
      76             :         size_t offset, size_t size,
      77             :         uint8_t *tag, size_t *data_offset, size_t *data_size) const {
      78           0 :     if (size == 0) {
      79           0 :         return ERROR_MALFORMED;
      80             :     }
      81             : 
      82           0 :     *tag = mData[offset++];
      83           0 :     --size;
      84             : 
      85           0 :     *data_size = 0;
      86             :     bool more;
      87           0 :     do {
      88           0 :         if (size == 0) {
      89           0 :             return ERROR_MALFORMED;
      90             :         }
      91             : 
      92           0 :         uint8_t x = mData[offset++];
      93           0 :         --size;
      94             : 
      95           0 :         *data_size = (*data_size << 7) | (x & 0x7f);
      96           0 :         more = (x & 0x80) != 0;
      97             :     }
      98             :     while (more);
      99             : 
     100             :     ALOGV("tag=0x%02x data_size=%d", *tag, *data_size);
     101             : 
     102           0 :     if (*data_size > size) {
     103           0 :         return ERROR_MALFORMED;
     104             :     }
     105             : 
     106           0 :     *data_offset = offset;
     107             : 
     108           0 :     return OK;
     109             : }
     110             : 
     111           0 : status_t ESDS::parse() {
     112             :     uint8_t tag;
     113             :     size_t data_offset;
     114             :     size_t data_size;
     115             :     status_t err =
     116           0 :         skipDescriptorHeader(0, mSize, &tag, &data_offset, &data_size);
     117             : 
     118           0 :     if (err != OK) {
     119           0 :         return err;
     120             :     }
     121             : 
     122           0 :     if (tag != kTag_ESDescriptor) {
     123           0 :         return ERROR_MALFORMED;
     124             :     }
     125             : 
     126           0 :     return parseESDescriptor(data_offset, data_size);
     127             : }
     128             : 
     129           0 : status_t ESDS::parseESDescriptor(size_t offset, size_t size) {
     130           0 :     if (size < 3) {
     131           0 :         return ERROR_MALFORMED;
     132             :     }
     133             : 
     134           0 :     offset += 2;  // skip ES_ID
     135           0 :     size -= 2;
     136             : 
     137           0 :     unsigned streamDependenceFlag = mData[offset] & 0x80;
     138           0 :     unsigned URL_Flag = mData[offset] & 0x40;
     139           0 :     unsigned OCRstreamFlag = mData[offset] & 0x20;
     140             : 
     141           0 :     ++offset;
     142           0 :     --size;
     143             : 
     144           0 :     if (streamDependenceFlag) {
     145           0 :         offset += 2;
     146           0 :         if (size <= 2) {
     147           0 :             return ERROR_MALFORMED;
     148             :         }
     149           0 :         size -= 2;
     150             :     }
     151             : 
     152           0 :     if (URL_Flag) {
     153           0 :         if (offset >= size) {
     154           0 :             return ERROR_MALFORMED;
     155             :         }
     156           0 :         unsigned URLlength = mData[offset];
     157           0 :         offset += URLlength + 1;
     158           0 :         if (size <= URLlength + 1) {
     159           0 :             return ERROR_MALFORMED;
     160             :         }
     161           0 :         size -= URLlength + 1;
     162             :     }
     163             : 
     164           0 :     if (OCRstreamFlag) {
     165           0 :         offset += 2;
     166           0 :         if (size <= 2) {
     167           0 :             return ERROR_MALFORMED;
     168             :         }
     169           0 :         size -= 2;
     170             : 
     171           0 :         if ((offset >= size || mData[offset] != kTag_DecoderConfigDescriptor)
     172           0 :                 && offset >= 2
     173           0 :                 && offset - 2 < size
     174           0 :                 && mData[offset - 2] == kTag_DecoderConfigDescriptor) {
     175             :             // Content found "in the wild" had OCRstreamFlag set but was
     176             :             // missing OCR_ES_Id, the decoder config descriptor immediately
     177             :             // followed instead.
     178           0 :             offset -= 2;
     179           0 :             size += 2;
     180             : 
     181           0 :             ALOGW("Found malformed 'esds' atom, ignoring missing OCR_ES_Id.");
     182             :         }
     183             :     }
     184             : 
     185           0 :     if (offset >= size) {
     186           0 :         return ERROR_MALFORMED;
     187             :     }
     188             : 
     189             :     uint8_t tag;
     190             :     size_t sub_offset, sub_size;
     191             :     status_t err = skipDescriptorHeader(
     192           0 :             offset, size, &tag, &sub_offset, &sub_size);
     193             : 
     194           0 :     if (err != OK) {
     195           0 :         return err;
     196             :     }
     197             : 
     198           0 :     if (tag != kTag_DecoderConfigDescriptor) {
     199           0 :         return ERROR_MALFORMED;
     200             :     }
     201             : 
     202           0 :     err = parseDecoderConfigDescriptor(sub_offset, sub_size);
     203             : 
     204           0 :     return err;
     205             : }
     206             : 
     207           0 : status_t ESDS::parseDecoderConfigDescriptor(size_t offset, size_t size) {
     208           0 :     if (size < 13) {
     209           0 :         return ERROR_MALFORMED;
     210             :     }
     211             : 
     212           0 :     mObjectTypeIndication = mData[offset];
     213             : 
     214           0 :     offset += 13;
     215           0 :     size -= 13;
     216             : 
     217           0 :     if (size == 0) {
     218           0 :         mDecoderSpecificOffset = 0;
     219           0 :         mDecoderSpecificLength = 0;
     220           0 :         return OK;
     221             :     }
     222             : 
     223             :     uint8_t tag;
     224             :     size_t sub_offset, sub_size;
     225             :     status_t err = skipDescriptorHeader(
     226           0 :             offset, size, &tag, &sub_offset, &sub_size);
     227             : 
     228           0 :     if (err != OK) {
     229           0 :         return err;
     230             :     }
     231             : 
     232           0 :     if (tag != kTag_DecoderSpecificInfo) {
     233           0 :         return ERROR_MALFORMED;
     234             :     }
     235             : 
     236           0 :     mDecoderSpecificOffset = sub_offset;
     237           0 :     mDecoderSpecificLength = sub_size;
     238             : 
     239           0 :     return OK;
     240             : }
     241             : 
     242             : }  // namespace stagefright
     243             : 
     244             : #undef LOG_TAG

Generated by: LCOV version 1.13