19aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim/* 29aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * Copyright (C) 2015 The Android Open Source Project 39aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * 49aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * Licensed under the Apache License, Version 2.0 (the "License"); 59aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * you may not use this file except in compliance with the License. 69aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * You may obtain a copy of the License at 79aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * 89aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * http://www.apache.org/licenses/LICENSE-2.0 99aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * 109aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * Unless required by applicable law or agreed to in writing, software 119aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * distributed under the License is distributed on an "AS IS" BASIS, 129aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * See the License for the specific language governing permissions and 149aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim * limitations under the License. 159aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim */ 169aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 179aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim//#define LOG_NDEBUG 0 189aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#define LOG_TAG "HevcUtils" 199aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 209aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <cstring> 2172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar#include <utility> 229aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 239aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include "include/HevcUtils.h" 249aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include "include/avc_utils.h" 259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 269aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/foundation/ABitReader.h> 279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/foundation/ABuffer.h> 289aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/foundation/ADebug.h> 299aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/foundation/AMessage.h> 309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/MediaErrors.h> 319aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim#include <media/stagefright/Utils.h> 329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 339aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimnamespace android { 349aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 359aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic const uint8_t kHevcNalUnitTypes[5] = { 369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim kHevcNalUnitTypeVps, 379aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim kHevcNalUnitTypeSps, 389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim kHevcNalUnitTypePps, 399aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim kHevcNalUnitTypePrefixSei, 409aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim kHevcNalUnitTypeSuffixSei, 419aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim}; 429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 4372061e5ab52d12c17054aeffbb2299a002b6b53aLajos MolnarHevcParameterSets::HevcParameterSets() 4472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar : mInfo(kInfoNone) { 459aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatus_t HevcParameterSets::addNalUnit(const uint8_t* data, size_t size) { 48e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick if (size < 1) { 49e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick ALOGE("empty NAL b/35467107"); 50e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick return ERROR_MALFORMED; 51e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick } 529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t nalUnitType = (data[0] >> 1) & 0x3f; 539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim status_t err = OK; 549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim switch (nalUnitType) { 559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case 32: // VPS 56e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick if (size < 2) { 57e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick ALOGE("invalid NAL/VPS size b/35467107"); 58e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick return ERROR_MALFORMED; 59e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick } 609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim err = parseVps(data + 2, size - 2); 619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim break; 629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case 33: // SPS 63e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick if (size < 2) { 64e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick ALOGE("invalid NAL/SPS size b/35467107"); 65e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick return ERROR_MALFORMED; 66e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick } 679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim err = parseSps(data + 2, size - 2); 689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim break; 699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case 34: // PPS 70e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick if (size < 2) { 71e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick ALOGE("invalid NAL/PPS size b/35467107"); 72e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick return ERROR_MALFORMED; 73e0dcf097cc029d056926029a29419e1650cbdf1bRay Essick } 749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim err = parsePps(data + 2, size - 2); 759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim break; 769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case 39: // Prefix SEI 779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim case 40: // Suffix SEI 789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Ignore 799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim break; 809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim default: 819aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim ALOGE("Unrecognized NAL unit type."); 829aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return ERROR_MALFORMED; 839aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 849aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 859aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (err != OK) { 869aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return err; 879aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 889aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 899aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim sp<ABuffer> buffer = ABuffer::CreateAsCopy(data, size); 909aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim buffer->setInt32Data(nalUnitType); 919aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim mNalUnits.push(buffer); 929aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return OK; 939aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 949aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 959aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimtemplate <typename T> 969aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatic bool findParam(uint32_t key, T *param, 979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim KeyedVector<uint32_t, uint64_t> ¶ms) { 989aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim CHECK(param); 999aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (params.indexOfKey(key) < 0) { 1009aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return false; 1019aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 1029aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim *param = (T) params[key]; 1039aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return true; 1049aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1059aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1069aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimbool HevcParameterSets::findParam8(uint32_t key, uint8_t *param) { 1079aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return findParam(key, param, mParams); 1089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1099aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1109aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimbool HevcParameterSets::findParam16(uint32_t key, uint16_t *param) { 1119aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return findParam(key, param, mParams); 1129aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1139aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1149aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimbool HevcParameterSets::findParam32(uint32_t key, uint32_t *param) { 1159aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return findParam(key, param, mParams); 1169aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1179aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1189aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimbool HevcParameterSets::findParam64(uint32_t key, uint64_t *param) { 1199aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return findParam(key, param, mParams); 1209aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1219aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1229aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimsize_t HevcParameterSets::getNumNalUnitsOfType(uint8_t type) { 1239aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t num = 0; 1249aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (size_t i = 0; i < mNalUnits.size(); ++i) { 1259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (getType(i) == type) { 1269aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim ++num; 1279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 1289aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 1299aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return num; 1309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1319aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimuint8_t HevcParameterSets::getType(size_t index) { 1339aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim CHECK_LT(index, mNalUnits.size()); 1349aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return mNalUnits[index]->int32Data(); 1359aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1379aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimsize_t HevcParameterSets::getSize(size_t index) { 1389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim CHECK_LT(index, mNalUnits.size()); 1399aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return mNalUnits[index]->size(); 1409aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1419aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimbool HevcParameterSets::write(size_t index, uint8_t* dest, size_t size) { 1439aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim CHECK_LT(index, mNalUnits.size()); 1449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim const sp<ABuffer>& nalUnit = mNalUnits[index]; 1459aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (size < nalUnit->size()) { 1469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim ALOGE("dest buffer size too small: %zu vs. %zu to be written", 1479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size, nalUnit->size()); 1489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return false; 1499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 1509aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim memcpy(dest, nalUnit->data(), nalUnit->size()); 1519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return true; 1529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatus_t HevcParameterSets::parseVps(const uint8_t* data, size_t size) { 1559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // See Rec. ITU-T H.265 v3 (04/2015) Chapter 7.3.2.1 for reference 1569aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim NALBitReader reader(data, size); 1579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip vps_video_parameter_set_id 1589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(4); 1599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip vps_base_layer_internal_flag 1609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(1); 1619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip vps_base_layer_available_flag 1629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(1); 1639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip vps_max_layers_minus_1 1649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(6); 1659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip vps_temporal_id_nesting_flags 1669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(1); 1679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip reserved 1689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(16); 1699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 17005b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar if (reader.atLeastNumBitsLeft(96)) { 17105b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kGeneralProfileSpace, reader.getBits(2)); 17205b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kGeneralTierFlag, reader.getBits(1)); 17305b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kGeneralProfileIdc, reader.getBits(5)); 17405b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kGeneralProfileCompatibilityFlags, reader.getBits(32)); 17505b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add( 17605b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar kGeneralConstraintIndicatorFlags, 17705b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar ((uint64_t)reader.getBits(16) << 32) | reader.getBits(32)); 17805b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kGeneralLevelIdc, reader.getBits(8)); 17905b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar // 96 bits total for general profile. 18005b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar } else { 18105b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar reader.skipBits(96); 18205b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar } 1839aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 18405b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar return reader.overRead() ? ERROR_MALFORMED : OK; 1859aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 1869aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 1879aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatus_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) { 1889aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // See Rec. ITU-T H.265 v3 (04/2015) Chapter 7.3.2.2 for reference 1899aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim NALBitReader reader(data, size); 1909aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip sps_video_parameter_set_id 1919aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(4); 19205b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar uint8_t maxSubLayersMinus1 = reader.getBitsWithFallback(3, 0); 1939aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip sps_temporal_id_nesting_flag; 1949aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(1); 1959aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip general profile 1969aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(96); 1979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (maxSubLayersMinus1 > 0) { 1989aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim bool subLayerProfilePresentFlag[8]; 1999aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim bool subLayerLevelPresentFlag[8]; 2009aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (int i = 0; i < maxSubLayersMinus1; ++i) { 20105b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar subLayerProfilePresentFlag[i] = reader.getBitsWithFallback(1, 0); 20205b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar subLayerLevelPresentFlag[i] = reader.getBitsWithFallback(1, 0); 2039aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2049aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip reserved 2059aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(2 * (8 - maxSubLayersMinus1)); 2069aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (int i = 0; i < maxSubLayersMinus1; ++i) { 2079aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (subLayerProfilePresentFlag[i]) { 2089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip profile 2099aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(88); 2109aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2119aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (subLayerLevelPresentFlag[i]) { 2129aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip sub_layer_level_idc[i] 2139aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(8); 2149aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2159aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2169aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2179aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip sps_seq_parameter_set_id 21805b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 21905b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar uint8_t chromaFormatIdc = parseUEWithFallback(&reader, 0); 2209aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim mParams.add(kChromaFormatIdc, chromaFormatIdc); 2219aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (chromaFormatIdc == 3) { 2229aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip separate_colour_plane_flag 2239aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim reader.skipBits(1); 2249aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 2259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip pic_width_in_luma_samples 22605b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 2279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip pic_height_in_luma_samples 22805b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 22905b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar if (reader.getBitsWithFallback(1, 0) /* i.e. conformance_window_flag */) { 2309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip conf_win_left_offset 23105b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 2329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip conf_win_right_offset 23305b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 2349aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip conf_win_top_offset 23505b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 2369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // Skip conf_win_bottom_offset 23705b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar skipUE(&reader); 2389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 23905b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kBitDepthLumaMinus8, parseUEWithFallback(&reader, 0)); 24005b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar mParams.add(kBitDepthChromaMinus8, parseUEWithFallback(&reader, 0)); 2419aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 24272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar // log2_max_pic_order_cnt_lsb_minus4 24372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar size_t log2MaxPicOrderCntLsb = parseUEWithFallback(&reader, 0) + (size_t)4; 24472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar bool spsSubLayerOrderingInfoPresentFlag = reader.getBitsWithFallback(1, 0); 24572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t i = spsSubLayerOrderingInfoPresentFlag ? 0 : maxSubLayersMinus1; 24672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar i <= maxSubLayersMinus1; ++i) { 24772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // sps_max_dec_pic_buffering_minus1[i] 24872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // sps_max_num_reorder_pics[i] 24972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // sps_max_latency_increase_plus1[i] 25072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 25172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar 25272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_min_luma_coding_block_size_minus3 25372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_diff_max_min_luma_coding_block_size 25472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_min_luma_transform_block_size_minus2 25572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_diff_max_min_luma_transform_block_size 25672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // max_transform_hierarchy_depth_inter 25772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // max_transform_hierarchy_depth_intra 25872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // scaling_list_enabled_flag u(1) 25972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar // scaling_list_data 26072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // sps_scaling_list_data_present_flag 26172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t sizeId = 0; sizeId < 4; ++sizeId) { 26272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) { 26372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (!reader.getBitsWithFallback(1, 1)) { 26472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar // scaling_list_pred_mode_flag[sizeId][matrixId] 26572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // scaling_list_pred_matrix_id_delta[sizeId][matrixId] 26672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } else { 26772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t coefNum = std::min(64, (1 << (4 + (sizeId << 1)))); 26872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (sizeId > 1) { 26972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipSE(&reader); // scaling_list_dc_coef_minus8[sizeId − 2][matrixId] 27072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t i = 0; i < coefNum; ++i) { 27272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipSE(&reader); // scaling_list_delta_coef 27372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 27972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // amp_enabled_flag 28072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // sample_adaptive_offset_enabled_flag u(1) 28172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // pcm_enabled_flag 28272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(4); // pcm_sample_bit_depth_luma_minus1 28372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(4); // pcm_sample_bit_depth_chroma_minus1 u(4) 28472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_min_pcm_luma_coding_block_size_minus3 28572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // log2_diff_max_min_pcm_luma_coding_block_size 28672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // pcm_loop_filter_disabled_flag 28772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 28872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t numShortTermRefPicSets = parseUEWithFallback(&reader, 0); 28972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t numPics = 0; 29072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t i = 0; i < numShortTermRefPicSets; ++i) { 29172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar // st_ref_pic_set(i) 29272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (i != 0 && reader.getBitsWithFallback(1, 0)) { // inter_ref_pic_set_prediction_flag 29372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // delta_rps_sign 29472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // abs_delta_rps_minus1 29572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t nextNumPics = 0; 29672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t j = 0; j <= numPics; ++j) { 29772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0) // used_by_curr_pic_flag[j] 29872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar || reader.getBitsWithFallback(1, 0)) { // use_delta_flag[j] 29972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar ++nextNumPics; 30072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 30172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 30272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar numPics = nextNumPics; 30372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } else { 30472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t numNegativePics = parseUEWithFallback(&reader, 0); 30572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t numPositivePics = parseUEWithFallback(&reader, 0); 30672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (numNegativePics > UINT32_MAX - numPositivePics) { 30772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar return ERROR_MALFORMED; 30872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 30972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar numPics = numNegativePics + numPositivePics; 31072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t j = 0; j < numPics; ++j) { 31172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar skipUE(&reader); // delta_poc_s0|1_minus1[i] 31272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // used_by_curr_pic_s0|1_flag[i] 31372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 31472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 31572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 31672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // long_term_ref_pics_present_flag 31772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t numLongTermRefPicSps = parseUEWithFallback(&reader, 0); 31872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar for (uint32_t i = 0; i < numLongTermRefPicSps; ++i) { 31972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(log2MaxPicOrderCntLsb); // lt_ref_pic_poc_lsb_sps[i] 32072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // used_by_curr_pic_lt_sps_flag[i] 32172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 32272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 32372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // sps_temporal_mvp_enabled_flag 32472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // strong_intra_smoothing_enabled_flag 32572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // vui_parameters_present_flag 32672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // aspect_ratio_info_present_flag 32772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t aspectRatioIdc = reader.getBitsWithFallback(8, 0); 32872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (aspectRatioIdc == 0xFF /* EXTENDED_SAR */) { 32972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(16); // sar_width 33072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(16); // sar_height 33172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 33272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 33372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // overscan_info_present_flag 33472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(1); // overscan_appropriate_flag 33572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 33672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // video_signal_type_present_flag 33772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar reader.skipBits(3); // video_format 33872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t videoFullRangeFlag; 33972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsGraceful(1, &videoFullRangeFlag)) { 34072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mParams.add(kVideoFullRangeFlag, videoFullRangeFlag); 34172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 34272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsWithFallback(1, 0)) { // colour_description_present_flag 34372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mInfo = (Info)(mInfo | kInfoHasColorDescription); 34472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar uint32_t colourPrimaries, transferCharacteristics, matrixCoeffs; 34572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsGraceful(8, &colourPrimaries)) { 34672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mParams.add(kColourPrimaries, colourPrimaries); 34772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 34872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsGraceful(8, &transferCharacteristics)) { 34972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mParams.add(kTransferCharacteristics, transferCharacteristics); 35072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (transferCharacteristics == 16 /* ST 2084 */ 35172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar || transferCharacteristics == 18 /* ARIB STD-B67 HLG */) { 35272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mInfo = (Info)(mInfo | kInfoIsHdr); 35372061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 35472061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 35572061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar if (reader.getBitsGraceful(8, &matrixCoeffs)) { 35672061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar mParams.add(kMatrixCoeffs, matrixCoeffs); 35772061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 35872061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 35972061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar // skip rest of VUI 36072061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 36172061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar } 36272061e5ab52d12c17054aeffbb2299a002b6b53aLajos Molnar 36305b849ec0b585412aa0c23a5dad9ca5d9fb28888Lajos Molnar return reader.overRead() ? ERROR_MALFORMED : OK; 3649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 3659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 3669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatus_t HevcParameterSets::parsePps( 3679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim const uint8_t* data __unused, size_t size __unused) { 3689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return OK; 3699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 3709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 3719aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kimstatus_t HevcParameterSets::makeHvcc(uint8_t *hvcc, size_t *hvccSize, 3729aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t nalSizeLength) { 3739aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (hvcc == NULL || hvccSize == NULL 3749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || (nalSizeLength != 4 && nalSizeLength != 2)) { 3759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return BAD_VALUE; 3769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 3779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // ISO 14496-15: HEVC file format 3789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t size = 23; // 23 bytes in the header 3799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t numOfArrays = 0; 3809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim const size_t numNalUnits = getNumNalUnits(); 3819aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (size_t i = 0; i < ARRAY_SIZE(kHevcNalUnitTypes); ++i) { 3829aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t type = kHevcNalUnitTypes[i]; 3839aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t numNalus = getNumNalUnitsOfType(type); 3849aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (numNalus == 0) { 3859aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim continue; 3869aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 3879aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim ++numOfArrays; 3889aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size += 3; 3899aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (size_t j = 0; j < numNalUnits; ++j) { 3909aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (getType(j) != type) { 3919aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim continue; 3929aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 3939aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size += 2 + getSize(j); 3949aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 3959aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 3969aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t generalProfileSpace, generalTierFlag, generalProfileIdc; 3979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (!findParam8(kGeneralProfileSpace, &generalProfileSpace) 3989aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || !findParam8(kGeneralTierFlag, &generalTierFlag) 3999aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || !findParam8(kGeneralProfileIdc, &generalProfileIdc)) { 4009aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return ERROR_MALFORMED; 4019aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4029aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint32_t compatibilityFlags; 4039aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint64_t constraintIdcFlags; 4049aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (!findParam32(kGeneralProfileCompatibilityFlags, &compatibilityFlags) 4059aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || !findParam64(kGeneralConstraintIndicatorFlags, &constraintIdcFlags)) { 4069aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return ERROR_MALFORMED; 4079aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t generalLevelIdc; 4099aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (!findParam8(kGeneralLevelIdc, &generalLevelIdc)) { 4109aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return ERROR_MALFORMED; 4119aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4129aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t chromaFormatIdc, bitDepthLumaMinus8, bitDepthChromaMinus8; 4139aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (!findParam8(kChromaFormatIdc, &chromaFormatIdc) 4149aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || !findParam8(kBitDepthLumaMinus8, &bitDepthLumaMinus8) 4159aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim || !findParam8(kBitDepthChromaMinus8, &bitDepthChromaMinus8)) { 4169aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return ERROR_MALFORMED; 4179aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4189aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (size > *hvccSize) { 4199aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return NO_MEMORY; 4209aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4219aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim *hvccSize = size; 4229aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 4239aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t *header = hvcc; 4249aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[0] = 1; 4259aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[1] = (kGeneralProfileSpace << 6) | (kGeneralTierFlag << 5) | kGeneralProfileIdc; 4269aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[2] = (compatibilityFlags >> 24) & 0xff; 4279aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[3] = (compatibilityFlags >> 16) & 0xff; 4289aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[4] = (compatibilityFlags >> 8) & 0xff; 4299aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[5] = compatibilityFlags & 0xff; 4309aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[6] = (constraintIdcFlags >> 40) & 0xff; 4319aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[7] = (constraintIdcFlags >> 32) & 0xff; 4329aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[8] = (constraintIdcFlags >> 24) & 0xff; 4339aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[9] = (constraintIdcFlags >> 16) & 0xff; 4349aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[10] = (constraintIdcFlags >> 8) & 0xff; 4359aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[11] = constraintIdcFlags & 0xff; 4369aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[12] = generalLevelIdc; 4379aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // FIXME: parse min_spatial_segmentation_idc. 4389aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[13] = 0xf0; 4399aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[14] = 0; 4409aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // FIXME: derive parallelismType properly. 4419aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[15] = 0xfc; 4429aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[16] = 0xfc | chromaFormatIdc; 4439aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[17] = 0xf8 | bitDepthLumaMinus8; 4449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[18] = 0xf8 | bitDepthChromaMinus8; 4459aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // FIXME: derive avgFrameRate 4469aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[19] = 0; 4479aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[20] = 0; 4489aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // constantFrameRate, numTemporalLayers, temporalIdNested all set to 0. 4499aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[21] = nalSizeLength - 1; 4509aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[22] = numOfArrays; 4519aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header += 23; 4529aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (size_t i = 0; i < ARRAY_SIZE(kHevcNalUnitTypes); ++i) { 4539aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim uint8_t type = kHevcNalUnitTypes[i]; 4549aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim size_t numNalus = getNumNalUnitsOfType(type); 4559aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (numNalus == 0) { 4569aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim continue; 4579aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4589aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim // array_completeness set to 0. 4599aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[0] = type; 4609aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[1] = (numNalus >> 8) & 0xff; 4619aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[2] = numNalus & 0xff; 4629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header += 3; 4639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim for (size_t j = 0; j < numNalUnits; ++j) { 4649aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (getType(j) != type) { 4659aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim continue; 4669aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4679aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[0] = (getSize(j) >> 8) & 0xff; 4689aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header[1] = getSize(j) & 0xff; 4699aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim if (!write(j, header + 2, size - (header - (uint8_t *)hvcc))) { 4709aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return NO_MEMORY; 4719aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4729aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim header += (2 + getSize(j)); 4739aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4749aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim } 4759aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim CHECK_EQ(header - size, hvcc); 4769aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 4779aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim return OK; 4789aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} 4799aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim 4809aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim} // namespace android 481