1 /* ----------------------------------------------------------------------------- 2 The copyright in this software is being made available under the BSD 3 License, included below. No patent rights, trademark rights and/or 4 other Intellectual Property Rights other than the copyrights concerning 5 the Software are granted under this license. 6 7 For any license concerning other Intellectual Property rights than the software, 8 especially patent licenses, a separate Agreement needs to be closed. 9 For more information please contact: 10 11 Fraunhofer Heinrich Hertz Institute 12 Einsteinufer 37 13 10587 Berlin, Germany 14 www.hhi.fraunhofer.de/vvc 15 vvc@hhi.fraunhofer.de 16 17 Copyright (c) 2018-2021, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. 18 All rights reserved. 19 20 Redistribution and use in source and binary forms, with or without 21 modification, are permitted provided that the following conditions are met: 22 23 * Redistributions of source code must retain the above copyright notice, 24 this list of conditions and the following disclaimer. 25 * Redistributions in binary form must reproduce the above copyright notice, 26 this list of conditions and the following disclaimer in the documentation 27 and/or other materials provided with the distribution. 28 * Neither the name of Fraunhofer nor the names of its contributors may 29 be used to endorse or promote products derived from this software without 30 specific prior written permission. 31 32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 33 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 36 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 37 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 38 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 39 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 40 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 42 THE POSSIBILITY OF SUCH DAMAGE. 43 44 45 ------------------------------------------------------------------------------------------- */ 46 47 /** 48 \file AnnexBread.h 49 \brief reading functions for Annex B byte streams 50 */ 51 52 #pragma once 53 54 #include <stdint.h> 55 #include <istream> 56 #include <vector> 57 58 #include "CommonLib/CommonDef.h" 59 60 namespace vvdec 61 { 62 63 //! \ingroup DecoderLib 64 //! \{ 65 66 class InputByteStream 67 { 68 public: 69 /** 70 * Create a bytestream reader that will extract bytes from 71 * istream. 72 * 73 * NB, it isn't safe to access istream while in use by a 74 * InputByteStream. 75 * 76 * Side-effects: the exception mask of istream is set to eofbit 77 */ InputByteStream(std::istream & istream)78 InputByteStream(std::istream& istream) 79 : m_NumFutureBytes(0) 80 , m_FutureBytes(0) 81 , m_Input(istream) 82 { 83 istream.exceptions(std::istream::eofbit | std::istream::badbit); 84 } 85 86 /** 87 * Reset the internal state. Must be called if input stream is 88 * modified externally to this class 89 */ reset()90 void reset() 91 { 92 m_NumFutureBytes = 0; 93 m_FutureBytes = 0; 94 } 95 96 /** 97 * returns true if an EOF will be encountered within the next 98 * n bytes. 99 */ eofBeforeNBytes(uint32_t n)100 bool eofBeforeNBytes(uint32_t n) 101 { 102 CHECK(n > 4, "Unsupported look-ahead value"); 103 if (m_NumFutureBytes >= n) 104 { 105 return false; 106 } 107 108 n -= m_NumFutureBytes; 109 try 110 { 111 for (uint32_t i = 0; i < n; i++) 112 { 113 m_FutureBytes = (m_FutureBytes << 8) | m_Input.get(); 114 m_NumFutureBytes++; 115 } 116 } 117 catch (...) 118 { 119 return true; 120 } 121 return false; 122 } 123 124 /** 125 * return the next n bytes in the stream without advancing 126 * the stream pointer. 127 * 128 * Returns: an unsigned integer representing an n byte bigendian 129 * word. 130 * 131 * If an attempt is made to read past EOF, an n-byte word is 132 * returned, but the portion that required input bytes beyond EOF 133 * is undefined. 134 * 135 */ peekBytes(uint32_t n)136 uint32_t peekBytes(uint32_t n) 137 { 138 eofBeforeNBytes(n); 139 return m_FutureBytes >> 8*(m_NumFutureBytes - n); 140 } 141 142 /** 143 * consume and return one byte from the input. 144 * 145 * If bytestream is already at EOF prior to a call to readByte(), 146 * an exception std::ios_base::failure is thrown. 147 */ readByte()148 uint8_t readByte() 149 { 150 if (!m_NumFutureBytes) 151 { 152 uint8_t byte = m_Input.get(); 153 return byte; 154 } 155 m_NumFutureBytes--; 156 uint8_t wanted_byte = m_FutureBytes >> 8*m_NumFutureBytes; 157 m_FutureBytes &= ~(0xff << 8*m_NumFutureBytes); 158 return wanted_byte; 159 } 160 161 /** 162 * consume and return n bytes from the input. n bytes from 163 * bytestream are interpreted as bigendian when assembling 164 * the return value. 165 */ readBytes(uint32_t n)166 uint32_t readBytes(uint32_t n) 167 { 168 uint32_t val = 0; 169 for (uint32_t i = 0; i < n; i++) 170 { 171 val = (val << 8) | readByte(); 172 } 173 return val; 174 } 175 176 177 private: 178 uint32_t m_NumFutureBytes; /* number of valid bytes in m_FutureBytes */ 179 uint32_t m_FutureBytes; /* bytes that have been peeked */ 180 std::istream& m_Input; /* Input stream to read from */ 181 }; 182 183 /** 184 * Statistics associated with AnnexB bytestreams 185 */ 186 struct AnnexBStats 187 { 188 uint32_t m_numLeadingZero8BitsBytes = 0; 189 uint32_t m_numZeroByteBytes = 0; 190 uint32_t m_numStartCodePrefixBytes = 0; 191 uint32_t m_numBytesInNALUnit = 0; 192 uint32_t m_numTrailingZero8BitsBytes = 0; 193 194 AnnexBStats& operator+=(const AnnexBStats& rhs) 195 { 196 this->m_numLeadingZero8BitsBytes += rhs.m_numLeadingZero8BitsBytes; 197 this->m_numZeroByteBytes += rhs.m_numZeroByteBytes; 198 this->m_numStartCodePrefixBytes += rhs.m_numStartCodePrefixBytes; 199 this->m_numBytesInNALUnit += rhs.m_numBytesInNALUnit; 200 this->m_numTrailingZero8BitsBytes += rhs.m_numTrailingZero8BitsBytes; 201 return *this; 202 } 203 }; 204 205 bool byteStreamNALUnit(InputByteStream& bs, std::vector<uint8_t>& nalUnit, AnnexBStats& stats); 206 207 } 208