| 1 | /********** | 
|---|
| 2 | This library is free software; you can redistribute it and/or modify it under | 
|---|
| 3 | the terms of the GNU Lesser General Public License as published by the | 
|---|
| 4 | Free Software Foundation; either version 3 of the License, or (at your | 
|---|
| 5 | option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) | 
|---|
| 6 |  | 
|---|
| 7 | This library is distributed in the hope that it will be useful, but WITHOUT | 
|---|
| 8 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
|---|
| 9 | FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for | 
|---|
| 10 | more details. | 
|---|
| 11 |  | 
|---|
| 12 | You should have received a copy of the GNU Lesser General Public License | 
|---|
| 13 | along with this library; if not, write to the Free Software Foundation, Inc., | 
|---|
| 14 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA | 
|---|
| 15 | **********/ | 
|---|
| 16 | // "liveMedia" | 
|---|
| 17 | // Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved. | 
|---|
| 18 | // A filter that breaks up a H.264 or H.265 Video Elementary Stream into NAL units. | 
|---|
| 19 | // Implementation | 
|---|
| 20 |  | 
|---|
| 21 | #include "H264or5VideoStreamFramer.hh" | 
|---|
| 22 | #include "MPEGVideoStreamParser.hh" | 
|---|
| 23 | #include "BitVector.hh" | 
|---|
| 24 |  | 
|---|
| 25 | ////////// H264or5VideoStreamParser definition ////////// | 
|---|
| 26 |  | 
|---|
| 27 | class H264or5VideoStreamParser: public MPEGVideoStreamParser { | 
|---|
| 28 | public: | 
|---|
| 29 | H264or5VideoStreamParser(int hNumber, H264or5VideoStreamFramer* usingSource, | 
|---|
| 30 | FramedSource* inputSource, Boolean includeStartCodeInOutput); | 
|---|
| 31 | virtual ~H264or5VideoStreamParser(); | 
|---|
| 32 |  | 
|---|
| 33 | private: // redefined virtual functions: | 
|---|
| 34 | virtual void flushInput(); | 
|---|
| 35 | virtual unsigned parse(); | 
|---|
| 36 |  | 
|---|
| 37 | private: | 
|---|
| 38 | H264or5VideoStreamFramer* usingSource() { | 
|---|
| 39 | return (H264or5VideoStreamFramer*)fUsingSource; | 
|---|
| 40 | } | 
|---|
| 41 |  | 
|---|
| 42 | Boolean isVPS(u_int8_t nal_unit_type) { return usingSource()->isVPS(nal_unit_type); } | 
|---|
| 43 | Boolean isSPS(u_int8_t nal_unit_type) { return usingSource()->isSPS(nal_unit_type); } | 
|---|
| 44 | Boolean isPPS(u_int8_t nal_unit_type) { return usingSource()->isPPS(nal_unit_type); } | 
|---|
| 45 | Boolean isVCL(u_int8_t nal_unit_type) { return usingSource()->isVCL(nal_unit_type); } | 
|---|
| 46 | Boolean isSEI(u_int8_t nal_unit_type); | 
|---|
| 47 | Boolean isEOF(u_int8_t nal_unit_type); | 
|---|
| 48 | Boolean usuallyBeginsAccessUnit(u_int8_t nal_unit_type); | 
|---|
| 49 |  | 
|---|
| 50 | void removeEmulationBytes(u_int8_t* nalUnitCopy, unsigned maxSize, unsigned& nalUnitCopySize); | 
|---|
| 51 |  | 
|---|
| 52 | void analyze_video_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale); | 
|---|
| 53 | void analyze_seq_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale); | 
|---|
| 54 | void profile_tier_level(BitVector& bv, unsigned max_sub_layers_minus1); | 
|---|
| 55 | void analyze_vui_parameters(BitVector& bv, unsigned& num_units_in_tick, unsigned& time_scale); | 
|---|
| 56 | void analyze_hrd_parameters(BitVector& bv); | 
|---|
| 57 | void analyze_sei_data(u_int8_t nal_unit_type); | 
|---|
| 58 | void analyze_sei_payload(unsigned payloadType, unsigned payloadSize, u_int8_t* payload); | 
|---|
| 59 |  | 
|---|
| 60 | private: | 
|---|
| 61 | int fHNumber; // 264 or 265 | 
|---|
| 62 | unsigned fOutputStartCodeSize; | 
|---|
| 63 | Boolean fHaveSeenFirstStartCode, fHaveSeenFirstByteOfNALUnit; | 
|---|
| 64 | u_int8_t fFirstByteOfNALUnit; | 
|---|
| 65 | double fParsedFrameRate; | 
|---|
| 66 | // variables set & used in the specification: | 
|---|
| 67 | unsigned cpb_removal_delay_length_minus1, dpb_output_delay_length_minus1; | 
|---|
| 68 | Boolean CpbDpbDelaysPresentFlag, pic_struct_present_flag; | 
|---|
| 69 | double DeltaTfiDivisor; | 
|---|
| 70 | }; | 
|---|
| 71 |  | 
|---|
| 72 |  | 
|---|
| 73 | ////////// H264or5VideoStreamFramer implementation ////////// | 
|---|
| 74 |  | 
|---|
| 75 | H264or5VideoStreamFramer | 
|---|
| 76 | ::H264or5VideoStreamFramer(int hNumber, UsageEnvironment& env, FramedSource* inputSource, | 
|---|
| 77 | Boolean createParser, | 
|---|
| 78 | Boolean includeStartCodeInOutput, Boolean insertAccessUnitDelimiters) | 
|---|
| 79 | : MPEGVideoStreamFramer(env, inputSource), | 
|---|
| 80 | fHNumber(hNumber), fIncludeStartCodeInOutput(includeStartCodeInOutput), | 
|---|
| 81 | fInsertAccessUnitDelimiters(insertAccessUnitDelimiters), | 
|---|
| 82 | fLastSeenVPS(NULL), fLastSeenVPSSize(0), | 
|---|
| 83 | fLastSeenSPS(NULL), fLastSeenSPSSize(0), | 
|---|
| 84 | fLastSeenPPS(NULL), fLastSeenPPSSize(0) { | 
|---|
| 85 | fParser = createParser | 
|---|
| 86 | ? new H264or5VideoStreamParser(hNumber, this, inputSource, includeStartCodeInOutput) | 
|---|
| 87 | : NULL; | 
|---|
| 88 | fNextPresentationTime = fPresentationTimeBase; | 
|---|
| 89 | fFrameRate = 25.0; // We assume a frame rate of 25 fps, unless we learn otherwise (from parsing a VPS or SPS NAL unit) | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|
| 92 | H264or5VideoStreamFramer::~H264or5VideoStreamFramer() { | 
|---|
| 93 | delete[] fLastSeenPPS; | 
|---|
| 94 | delete[] fLastSeenSPS; | 
|---|
| 95 | delete[] fLastSeenVPS; | 
|---|
| 96 | } | 
|---|
| 97 |  | 
|---|
| 98 | #define VPS_MAX_SIZE 1000 // larger than the largest possible VPS (Video Parameter Set) NAL unit | 
|---|
| 99 |  | 
|---|
| 100 | void H264or5VideoStreamFramer::saveCopyOfVPS(u_int8_t* from, unsigned size) { | 
|---|
| 101 | if (from == NULL) return; | 
|---|
| 102 | delete[] fLastSeenVPS; | 
|---|
| 103 | fLastSeenVPS = new u_int8_t[size]; | 
|---|
| 104 | memmove(fLastSeenVPS, from, size); | 
|---|
| 105 |  | 
|---|
| 106 | fLastSeenVPSSize = size; | 
|---|
| 107 | } | 
|---|
| 108 |  | 
|---|
| 109 | #define SPS_MAX_SIZE 1000 // larger than the largest possible SPS (Sequence Parameter Set) NAL unit | 
|---|
| 110 |  | 
|---|
| 111 | void H264or5VideoStreamFramer::saveCopyOfSPS(u_int8_t* from, unsigned size) { | 
|---|
| 112 | if (from == NULL) return; | 
|---|
| 113 | delete[] fLastSeenSPS; | 
|---|
| 114 | fLastSeenSPS = new u_int8_t[size]; | 
|---|
| 115 | memmove(fLastSeenSPS, from, size); | 
|---|
| 116 |  | 
|---|
| 117 | fLastSeenSPSSize = size; | 
|---|
| 118 | } | 
|---|
| 119 |  | 
|---|
| 120 | void H264or5VideoStreamFramer::saveCopyOfPPS(u_int8_t* from, unsigned size) { | 
|---|
| 121 | if (from == NULL) return; | 
|---|
| 122 | delete[] fLastSeenPPS; | 
|---|
| 123 | fLastSeenPPS = new u_int8_t[size]; | 
|---|
| 124 | memmove(fLastSeenPPS, from, size); | 
|---|
| 125 |  | 
|---|
| 126 | fLastSeenPPSSize = size; | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | Boolean H264or5VideoStreamFramer::isVPS(u_int8_t nal_unit_type) { | 
|---|
| 130 | // VPS NAL units occur in H.265 only: | 
|---|
| 131 | return fHNumber == 265 && nal_unit_type == 32; | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | Boolean H264or5VideoStreamFramer::isSPS(u_int8_t nal_unit_type) { | 
|---|
| 135 | return fHNumber == 264 ? nal_unit_type == 7 : nal_unit_type == 33; | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | Boolean H264or5VideoStreamFramer::isPPS(u_int8_t nal_unit_type) { | 
|---|
| 139 | return fHNumber == 264 ? nal_unit_type == 8 : nal_unit_type == 34; | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | Boolean H264or5VideoStreamFramer::isVCL(u_int8_t nal_unit_type) { | 
|---|
| 143 | return fHNumber == 264 | 
|---|
| 144 | ? (nal_unit_type <= 5 && nal_unit_type > 0) | 
|---|
| 145 | : (nal_unit_type <= 31); | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | void H264or5VideoStreamFramer::doGetNextFrame() { | 
|---|
| 149 | if (fInsertAccessUnitDelimiters && pictureEndMarker()) { | 
|---|
| 150 | // Deliver an "access_unit_delimiter" NAL unit instead: | 
|---|
| 151 | unsigned const startCodeSize = fIncludeStartCodeInOutput ? 4: 0; | 
|---|
| 152 | unsigned const audNALSize = fHNumber == 264 ? 2 : 3; | 
|---|
| 153 |  | 
|---|
| 154 | fFrameSize = startCodeSize + audNALSize; | 
|---|
| 155 | if (fFrameSize > fMaxSize) { // there's no space | 
|---|
| 156 | fNumTruncatedBytes = fFrameSize - fMaxSize; | 
|---|
| 157 | fFrameSize = fMaxSize; | 
|---|
| 158 | handleClosure(); | 
|---|
| 159 | return; | 
|---|
| 160 | } | 
|---|
| 161 |  | 
|---|
| 162 | if (fIncludeStartCodeInOutput) { | 
|---|
| 163 | *fTo++ = 0x00; *fTo++ = 0x00; *fTo++ = 0x00; *fTo++ = 0x01; | 
|---|
| 164 | } | 
|---|
| 165 | if (fHNumber == 264) { | 
|---|
| 166 | *fTo++ = 9; // "Access unit delimiter" nal_unit_type | 
|---|
| 167 | *fTo++ = 0xF0; // "primary_pic_type" (7); "rbsp_trailing_bits()" | 
|---|
| 168 | } else { // H.265 | 
|---|
| 169 | *fTo++ = 35<<1; // "Access unit delimiter" nal_unit_type | 
|---|
| 170 | *fTo++ = 0; // "nuh_layer_id" (0); "nuh_temporal_id_plus1" (0) (Is this correct??) | 
|---|
| 171 | *fTo++ = 0x50; // "pic_type" (2); "rbsp_trailing_bits()" (Is this correct??) | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 | pictureEndMarker() = False; // for next time | 
|---|
| 175 | afterGetting(this); | 
|---|
| 176 | } else { | 
|---|
| 177 | // Do the normal delivery of a NAL unit from the parser: | 
|---|
| 178 | MPEGVideoStreamFramer::doGetNextFrame(); | 
|---|
| 179 | } | 
|---|
| 180 | } | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 | ////////// H264or5VideoStreamParser implementation ////////// | 
|---|
| 184 |  | 
|---|
| 185 | H264or5VideoStreamParser | 
|---|
| 186 | ::H264or5VideoStreamParser(int hNumber, H264or5VideoStreamFramer* usingSource, | 
|---|
| 187 | FramedSource* inputSource, Boolean includeStartCodeInOutput) | 
|---|
| 188 | : MPEGVideoStreamParser(usingSource, inputSource), | 
|---|
| 189 | fHNumber(hNumber), fOutputStartCodeSize(includeStartCodeInOutput ? 4 : 0), fHaveSeenFirstStartCode(False), fHaveSeenFirstByteOfNALUnit(False), fParsedFrameRate(0.0), | 
|---|
| 190 | cpb_removal_delay_length_minus1(23), dpb_output_delay_length_minus1(23), | 
|---|
| 191 | CpbDpbDelaysPresentFlag(0), pic_struct_present_flag(0), | 
|---|
| 192 | DeltaTfiDivisor(2.0) { | 
|---|
| 193 | } | 
|---|
| 194 |  | 
|---|
| 195 | H264or5VideoStreamParser::~H264or5VideoStreamParser() { | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | #define PREFIX_SEI_NUT 39 // for H.265 | 
|---|
| 199 | #define SUFFIX_SEI_NUT 40 // for H.265 | 
|---|
| 200 | Boolean H264or5VideoStreamParser::isSEI(u_int8_t nal_unit_type) { | 
|---|
| 201 | return fHNumber == 264 | 
|---|
| 202 | ? nal_unit_type == 6 | 
|---|
| 203 | : (nal_unit_type == PREFIX_SEI_NUT || nal_unit_type == SUFFIX_SEI_NUT); | 
|---|
| 204 | } | 
|---|
| 205 |  | 
|---|
| 206 | Boolean H264or5VideoStreamParser::isEOF(u_int8_t nal_unit_type) { | 
|---|
| 207 | // "end of sequence" or "end of (bit)stream" | 
|---|
| 208 | return fHNumber == 264 | 
|---|
| 209 | ? (nal_unit_type == 10 || nal_unit_type == 11) | 
|---|
| 210 | : (nal_unit_type == 36 || nal_unit_type == 37); | 
|---|
| 211 | } | 
|---|
| 212 |  | 
|---|
| 213 | Boolean H264or5VideoStreamParser::usuallyBeginsAccessUnit(u_int8_t nal_unit_type) { | 
|---|
| 214 | return fHNumber == 264 | 
|---|
| 215 | ? (nal_unit_type >= 6 && nal_unit_type <= 9) || (nal_unit_type >= 14 && nal_unit_type <= 18) | 
|---|
| 216 | : (nal_unit_type >= 32 && nal_unit_type <= 35) || (nal_unit_type == 39) | 
|---|
| 217 | || (nal_unit_type >= 41 && nal_unit_type <= 44) | 
|---|
| 218 | || (nal_unit_type >= 48 && nal_unit_type <= 55); | 
|---|
| 219 | } | 
|---|
| 220 |  | 
|---|
| 221 | void H264or5VideoStreamParser | 
|---|
| 222 | ::removeEmulationBytes(u_int8_t* nalUnitCopy, unsigned maxSize, unsigned& nalUnitCopySize) { | 
|---|
| 223 | u_int8_t const* nalUnitOrig = fStartOfFrame + fOutputStartCodeSize; | 
|---|
| 224 | unsigned const numBytesInNALunit = fTo - nalUnitOrig; | 
|---|
| 225 | nalUnitCopySize | 
|---|
| 226 | = removeH264or5EmulationBytes(nalUnitCopy, maxSize, nalUnitOrig, numBytesInNALunit); | 
|---|
| 227 | } | 
|---|
| 228 |  | 
|---|
| 229 | #ifdef DEBUG | 
|---|
| 230 | char const* nal_unit_type_description_h264[32] = { | 
|---|
| 231 | "Unspecified", //0 | 
|---|
| 232 | "Coded slice of a non-IDR picture", //1 | 
|---|
| 233 | "Coded slice data partition A", //2 | 
|---|
| 234 | "Coded slice data partition B", //3 | 
|---|
| 235 | "Coded slice data partition C", //4 | 
|---|
| 236 | "Coded slice of an IDR picture", //5 | 
|---|
| 237 | "Supplemental enhancement information (SEI)", //6 | 
|---|
| 238 | "Sequence parameter set", //7 | 
|---|
| 239 | "Picture parameter set", //8 | 
|---|
| 240 | "Access unit delimiter", //9 | 
|---|
| 241 | "End of sequence", //10 | 
|---|
| 242 | "End of stream", //11 | 
|---|
| 243 | "Filler data", //12 | 
|---|
| 244 | "Sequence parameter set extension", //13 | 
|---|
| 245 | "Prefix NAL unit", //14 | 
|---|
| 246 | "Subset sequence parameter set", //15 | 
|---|
| 247 | "Reserved", //16 | 
|---|
| 248 | "Reserved", //17 | 
|---|
| 249 | "Reserved", //18 | 
|---|
| 250 | "Coded slice of an auxiliary coded picture without partitioning", //19 | 
|---|
| 251 | "Coded slice extension", //20 | 
|---|
| 252 | "Reserved", //21 | 
|---|
| 253 | "Reserved", //22 | 
|---|
| 254 | "Reserved", //23 | 
|---|
| 255 | "Unspecified", //24 | 
|---|
| 256 | "Unspecified", //25 | 
|---|
| 257 | "Unspecified", //26 | 
|---|
| 258 | "Unspecified", //27 | 
|---|
| 259 | "Unspecified", //28 | 
|---|
| 260 | "Unspecified", //29 | 
|---|
| 261 | "Unspecified", //30 | 
|---|
| 262 | "Unspecified"//31 | 
|---|
| 263 | }; | 
|---|
| 264 | char const* nal_unit_type_description_h265[64] = { | 
|---|
| 265 | "Coded slice segment of a non-TSA, non-STSA trailing picture", //0 | 
|---|
| 266 | "Coded slice segment of a non-TSA, non-STSA trailing picture", //1 | 
|---|
| 267 | "Coded slice segment of a TSA picture", //2 | 
|---|
| 268 | "Coded slice segment of a TSA picture", //3 | 
|---|
| 269 | "Coded slice segment of a STSA picture", //4 | 
|---|
| 270 | "Coded slice segment of a STSA picture", //5 | 
|---|
| 271 | "Coded slice segment of a RADL picture", //6 | 
|---|
| 272 | "Coded slice segment of a RADL picture", //7 | 
|---|
| 273 | "Coded slice segment of a RASL picture", //8 | 
|---|
| 274 | "Coded slice segment of a RASL picture", //9 | 
|---|
| 275 | "Reserved", //10 | 
|---|
| 276 | "Reserved", //11 | 
|---|
| 277 | "Reserved", //12 | 
|---|
| 278 | "Reserved", //13 | 
|---|
| 279 | "Reserved", //14 | 
|---|
| 280 | "Reserved", //15 | 
|---|
| 281 | "Coded slice segment of a BLA picture", //16 | 
|---|
| 282 | "Coded slice segment of a BLA picture", //17 | 
|---|
| 283 | "Coded slice segment of a BLA picture", //18 | 
|---|
| 284 | "Coded slice segment of an IDR picture", //19 | 
|---|
| 285 | "Coded slice segment of an IDR picture", //20 | 
|---|
| 286 | "Coded slice segment of a CRA picture", //21 | 
|---|
| 287 | "Reserved", //22 | 
|---|
| 288 | "Reserved", //23 | 
|---|
| 289 | "Reserved", //24 | 
|---|
| 290 | "Reserved", //25 | 
|---|
| 291 | "Reserved", //26 | 
|---|
| 292 | "Reserved", //27 | 
|---|
| 293 | "Reserved", //28 | 
|---|
| 294 | "Reserved", //29 | 
|---|
| 295 | "Reserved", //30 | 
|---|
| 296 | "Reserved", //31 | 
|---|
| 297 | "Video parameter set", //32 | 
|---|
| 298 | "Sequence parameter set", //33 | 
|---|
| 299 | "Picture parameter set", //34 | 
|---|
| 300 | "Access unit delimiter", //35 | 
|---|
| 301 | "End of sequence", //36 | 
|---|
| 302 | "End of bitstream", //37 | 
|---|
| 303 | "Filler data", //38 | 
|---|
| 304 | "Supplemental enhancement information (SEI)", //39 | 
|---|
| 305 | "Supplemental enhancement information (SEI)", //40 | 
|---|
| 306 | "Reserved", //41 | 
|---|
| 307 | "Reserved", //42 | 
|---|
| 308 | "Reserved", //43 | 
|---|
| 309 | "Reserved", //44 | 
|---|
| 310 | "Reserved", //45 | 
|---|
| 311 | "Reserved", //46 | 
|---|
| 312 | "Reserved", //47 | 
|---|
| 313 | "Unspecified", //48 | 
|---|
| 314 | "Unspecified", //49 | 
|---|
| 315 | "Unspecified", //50 | 
|---|
| 316 | "Unspecified", //51 | 
|---|
| 317 | "Unspecified", //52 | 
|---|
| 318 | "Unspecified", //53 | 
|---|
| 319 | "Unspecified", //54 | 
|---|
| 320 | "Unspecified", //55 | 
|---|
| 321 | "Unspecified", //56 | 
|---|
| 322 | "Unspecified", //57 | 
|---|
| 323 | "Unspecified", //58 | 
|---|
| 324 | "Unspecified", //59 | 
|---|
| 325 | "Unspecified", //60 | 
|---|
| 326 | "Unspecified", //61 | 
|---|
| 327 | "Unspecified", //62 | 
|---|
| 328 | "Unspecified", //63 | 
|---|
| 329 | }; | 
|---|
| 330 | #endif | 
|---|
| 331 |  | 
|---|
| 332 | #ifdef DEBUG | 
|---|
| 333 | static unsigned numDebugTabs = 1; | 
|---|
| 334 | #define DEBUG_PRINT_TABS for (unsigned _i = 0; _i < numDebugTabs; ++_i) fprintf(stderr, "\t") | 
|---|
| 335 | #define DEBUG_PRINT(x) do { DEBUG_PRINT_TABS; fprintf(stderr, "%s: %d\n", #x, x); } while (0) | 
|---|
| 336 | #define DEBUG_STR(x) do { DEBUG_PRINT_TABS; fprintf(stderr, "%s\n", x); } while (0) | 
|---|
| 337 | class DebugTab { | 
|---|
| 338 | public: | 
|---|
| 339 | DebugTab() {++numDebugTabs;} | 
|---|
| 340 | ~DebugTab() {--numDebugTabs;} | 
|---|
| 341 | }; | 
|---|
| 342 | #define DEBUG_TAB DebugTab dummy | 
|---|
| 343 | #else | 
|---|
| 344 | #define DEBUG_PRINT(x) do {x = x;} while (0) | 
|---|
| 345 | // Note: the "x=x;" statement is intended to eliminate "unused variable" compiler warning messages | 
|---|
| 346 | #define DEBUG_STR(x) do {} while (0) | 
|---|
| 347 | #define DEBUG_TAB do {} while (0) | 
|---|
| 348 | #endif | 
|---|
| 349 |  | 
|---|
| 350 | void H264or5VideoStreamParser::profile_tier_level(BitVector& bv, unsigned max_sub_layers_minus1) { | 
|---|
| 351 | bv.skipBits(96); | 
|---|
| 352 |  | 
|---|
| 353 | unsigned i; | 
|---|
| 354 | Boolean sub_layer_profile_present_flag[7], sub_layer_level_present_flag[7]; | 
|---|
| 355 | for (i = 0; i < max_sub_layers_minus1; ++i) { | 
|---|
| 356 | sub_layer_profile_present_flag[i] = bv.get1BitBoolean(); | 
|---|
| 357 | sub_layer_level_present_flag[i] = bv.get1BitBoolean(); | 
|---|
| 358 | } | 
|---|
| 359 | if (max_sub_layers_minus1 > 0) { | 
|---|
| 360 | bv.skipBits(2*(8-max_sub_layers_minus1)); // reserved_zero_2bits | 
|---|
| 361 | } | 
|---|
| 362 | for (i = 0; i < max_sub_layers_minus1; ++i) { | 
|---|
| 363 | if (sub_layer_profile_present_flag[i]) { | 
|---|
| 364 | bv.skipBits(88); | 
|---|
| 365 | } | 
|---|
| 366 | if (sub_layer_level_present_flag[i]) { | 
|---|
| 367 | bv.skipBits(8); // sub_layer_level_idc[i] | 
|---|
| 368 | } | 
|---|
| 369 | } | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | void H264or5VideoStreamParser | 
|---|
| 373 | ::analyze_vui_parameters(BitVector& bv, | 
|---|
| 374 | unsigned& num_units_in_tick, unsigned& time_scale) { | 
|---|
| 375 | Boolean aspect_ratio_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 376 | DEBUG_PRINT(aspect_ratio_info_present_flag); | 
|---|
| 377 | if (aspect_ratio_info_present_flag) { | 
|---|
| 378 | DEBUG_TAB; | 
|---|
| 379 | unsigned aspect_ratio_idc = bv.getBits(8); | 
|---|
| 380 | DEBUG_PRINT(aspect_ratio_idc); | 
|---|
| 381 | if (aspect_ratio_idc == 255/*Extended_SAR*/) { | 
|---|
| 382 | bv.skipBits(32); // sar_width; sar_height | 
|---|
| 383 | } | 
|---|
| 384 | } | 
|---|
| 385 | Boolean overscan_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 386 | DEBUG_PRINT(overscan_info_present_flag); | 
|---|
| 387 | if (overscan_info_present_flag) { | 
|---|
| 388 | bv.skipBits(1); // overscan_appropriate_flag | 
|---|
| 389 | } | 
|---|
| 390 | Boolean video_signal_type_present_flag = bv.get1BitBoolean(); | 
|---|
| 391 | DEBUG_PRINT(video_signal_type_present_flag); | 
|---|
| 392 | if (video_signal_type_present_flag) { | 
|---|
| 393 | DEBUG_TAB; | 
|---|
| 394 | bv.skipBits(4); // video_format; video_full_range_flag | 
|---|
| 395 | Boolean colour_description_present_flag = bv.get1BitBoolean(); | 
|---|
| 396 | DEBUG_PRINT(colour_description_present_flag); | 
|---|
| 397 | if (colour_description_present_flag) { | 
|---|
| 398 | bv.skipBits(24); // colour_primaries; transfer_characteristics; matrix_coefficients | 
|---|
| 399 | } | 
|---|
| 400 | } | 
|---|
| 401 | Boolean chroma_loc_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 402 | DEBUG_PRINT(chroma_loc_info_present_flag); | 
|---|
| 403 | if (chroma_loc_info_present_flag) { | 
|---|
| 404 | (void)bv.get_expGolomb(); // chroma_sample_loc_type_top_field | 
|---|
| 405 | (void)bv.get_expGolomb(); // chroma_sample_loc_type_bottom_field | 
|---|
| 406 | } | 
|---|
| 407 | if (fHNumber == 265) { | 
|---|
| 408 | bv.skipBits(2); // neutral_chroma_indication_flag, field_seq_flag | 
|---|
| 409 | Boolean frame_field_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 410 | DEBUG_PRINT(frame_field_info_present_flag); | 
|---|
| 411 | pic_struct_present_flag = frame_field_info_present_flag; // hack to make H.265 like H.264 | 
|---|
| 412 | Boolean default_display_window_flag = bv.get1BitBoolean(); | 
|---|
| 413 | DEBUG_PRINT(default_display_window_flag); | 
|---|
| 414 | if (default_display_window_flag) { | 
|---|
| 415 | (void)bv.get_expGolomb(); // def_disp_win_left_offset | 
|---|
| 416 | (void)bv.get_expGolomb(); // def_disp_win_right_offset | 
|---|
| 417 | (void)bv.get_expGolomb(); // def_disp_win_top_offset | 
|---|
| 418 | (void)bv.get_expGolomb(); // def_disp_win_bottom_offset | 
|---|
| 419 | } | 
|---|
| 420 | } | 
|---|
| 421 | Boolean timing_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 422 | DEBUG_PRINT(timing_info_present_flag); | 
|---|
| 423 | if (timing_info_present_flag) { | 
|---|
| 424 | DEBUG_TAB; | 
|---|
| 425 | num_units_in_tick = bv.getBits(32); | 
|---|
| 426 | DEBUG_PRINT(num_units_in_tick); | 
|---|
| 427 | time_scale = bv.getBits(32); | 
|---|
| 428 | DEBUG_PRINT(time_scale); | 
|---|
| 429 | if (fHNumber == 264) { | 
|---|
| 430 | Boolean fixed_frame_rate_flag = bv.get1BitBoolean(); | 
|---|
| 431 | DEBUG_PRINT(fixed_frame_rate_flag); | 
|---|
| 432 | } else { // 265 | 
|---|
| 433 | Boolean vui_poc_proportional_to_timing_flag = bv.get1BitBoolean(); | 
|---|
| 434 | DEBUG_PRINT(vui_poc_proportional_to_timing_flag); | 
|---|
| 435 | if (vui_poc_proportional_to_timing_flag) { | 
|---|
| 436 | unsigned vui_num_ticks_poc_diff_one_minus1 = bv.get_expGolomb(); | 
|---|
| 437 | DEBUG_PRINT(vui_num_ticks_poc_diff_one_minus1); | 
|---|
| 438 | } | 
|---|
| 439 | return; // For H.265, don't bother parsing any more of this ##### | 
|---|
| 440 | } | 
|---|
| 441 | } | 
|---|
| 442 | // The following is H.264 only: ##### | 
|---|
| 443 | Boolean nal_hrd_parameters_present_flag = bv.get1BitBoolean(); | 
|---|
| 444 | DEBUG_PRINT(nal_hrd_parameters_present_flag); | 
|---|
| 445 | if (nal_hrd_parameters_present_flag) analyze_hrd_parameters(bv); | 
|---|
| 446 | Boolean vcl_hrd_parameters_present_flag = bv.get1BitBoolean(); | 
|---|
| 447 | DEBUG_PRINT(vcl_hrd_parameters_present_flag); | 
|---|
| 448 | if (vcl_hrd_parameters_present_flag) analyze_hrd_parameters(bv); | 
|---|
| 449 | CpbDpbDelaysPresentFlag = nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag; | 
|---|
| 450 | if (CpbDpbDelaysPresentFlag) { | 
|---|
| 451 | bv.skipBits(1); // low_delay_hrd_flag | 
|---|
| 452 | } | 
|---|
| 453 | pic_struct_present_flag = bv.get1BitBoolean(); | 
|---|
| 454 | DEBUG_PRINT(pic_struct_present_flag); | 
|---|
| 455 | } | 
|---|
| 456 |  | 
|---|
| 457 | void H264or5VideoStreamParser::analyze_hrd_parameters(BitVector& bv) { | 
|---|
| 458 | DEBUG_TAB; | 
|---|
| 459 | unsigned cpb_cnt_minus1 = bv.get_expGolomb(); | 
|---|
| 460 | DEBUG_PRINT(cpb_cnt_minus1); | 
|---|
| 461 | unsigned bit_rate_scale = bv.getBits(4); | 
|---|
| 462 | DEBUG_PRINT(bit_rate_scale); | 
|---|
| 463 | unsigned cpb_size_scale = bv.getBits(4); | 
|---|
| 464 | DEBUG_PRINT(cpb_size_scale); | 
|---|
| 465 | for (unsigned SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; ++SchedSelIdx) { | 
|---|
| 466 | DEBUG_TAB; | 
|---|
| 467 | DEBUG_PRINT(SchedSelIdx); | 
|---|
| 468 | unsigned bit_rate_value_minus1 = bv.get_expGolomb(); | 
|---|
| 469 | DEBUG_PRINT(bit_rate_value_minus1); | 
|---|
| 470 | unsigned cpb_size_value_minus1 = bv.get_expGolomb(); | 
|---|
| 471 | DEBUG_PRINT(cpb_size_value_minus1); | 
|---|
| 472 | Boolean cbr_flag = bv.get1BitBoolean(); | 
|---|
| 473 | DEBUG_PRINT(cbr_flag); | 
|---|
| 474 | } | 
|---|
| 475 | unsigned initial_cpb_removal_delay_length_minus1 = bv.getBits(5); | 
|---|
| 476 | DEBUG_PRINT(initial_cpb_removal_delay_length_minus1); | 
|---|
| 477 | cpb_removal_delay_length_minus1 = bv.getBits(5); | 
|---|
| 478 | DEBUG_PRINT(cpb_removal_delay_length_minus1); | 
|---|
| 479 | dpb_output_delay_length_minus1 = bv.getBits(5); | 
|---|
| 480 | DEBUG_PRINT(dpb_output_delay_length_minus1); | 
|---|
| 481 | unsigned time_offset_length = bv.getBits(5); | 
|---|
| 482 | DEBUG_PRINT(time_offset_length); | 
|---|
| 483 | } | 
|---|
| 484 |  | 
|---|
| 485 | void H264or5VideoStreamParser | 
|---|
| 486 | ::analyze_video_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale) { | 
|---|
| 487 | num_units_in_tick = time_scale = 0; // default values | 
|---|
| 488 |  | 
|---|
| 489 | // Begin by making a copy of the NAL unit data, removing any 'emulation prevention' bytes: | 
|---|
| 490 | u_int8_t vps[VPS_MAX_SIZE]; | 
|---|
| 491 | unsigned vpsSize; | 
|---|
| 492 | removeEmulationBytes(vps, sizeof vps, vpsSize); | 
|---|
| 493 |  | 
|---|
| 494 | BitVector bv(vps, 0, 8*vpsSize); | 
|---|
| 495 |  | 
|---|
| 496 | // Assert: fHNumber == 265 (because this function is called only when parsing H.265) | 
|---|
| 497 | unsigned i; | 
|---|
| 498 |  | 
|---|
| 499 | bv.skipBits(28); // nal_unit_header, vps_video_parameter_set_id, vps_reserved_three_2bits, vps_max_layers_minus1 | 
|---|
| 500 | unsigned vps_max_sub_layers_minus1 = bv.getBits(3); | 
|---|
| 501 | DEBUG_PRINT(vps_max_sub_layers_minus1); | 
|---|
| 502 | bv.skipBits(17); // vps_temporal_id_nesting_flag, vps_reserved_0xffff_16bits | 
|---|
| 503 | profile_tier_level(bv, vps_max_sub_layers_minus1); | 
|---|
| 504 | Boolean vps_sub_layer_ordering_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 505 | DEBUG_PRINT(vps_sub_layer_ordering_info_present_flag); | 
|---|
| 506 | for (i = vps_sub_layer_ordering_info_present_flag ? 0 : vps_max_sub_layers_minus1; | 
|---|
| 507 | i <= vps_max_sub_layers_minus1; ++i) { | 
|---|
| 508 | (void)bv.get_expGolomb(); // vps_max_dec_pic_buffering_minus1[i] | 
|---|
| 509 | (void)bv.get_expGolomb(); // vps_max_num_reorder_pics[i] | 
|---|
| 510 | (void)bv.get_expGolomb(); // vps_max_latency_increase_plus1[i] | 
|---|
| 511 | } | 
|---|
| 512 | unsigned vps_max_layer_id = bv.getBits(6); | 
|---|
| 513 | DEBUG_PRINT(vps_max_layer_id); | 
|---|
| 514 | unsigned vps_num_layer_sets_minus1 = bv.get_expGolomb(); | 
|---|
| 515 | DEBUG_PRINT(vps_num_layer_sets_minus1); | 
|---|
| 516 | for (i = 1; i <= vps_num_layer_sets_minus1; ++i) { | 
|---|
| 517 | bv.skipBits(vps_max_layer_id+1); // layer_id_included_flag[i][0..vps_max_layer_id] | 
|---|
| 518 | } | 
|---|
| 519 | Boolean vps_timing_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 520 | DEBUG_PRINT(vps_timing_info_present_flag); | 
|---|
| 521 | if (vps_timing_info_present_flag) { | 
|---|
| 522 | DEBUG_TAB; | 
|---|
| 523 | num_units_in_tick = bv.getBits(32); | 
|---|
| 524 | DEBUG_PRINT(num_units_in_tick); | 
|---|
| 525 | time_scale = bv.getBits(32); | 
|---|
| 526 | DEBUG_PRINT(time_scale); | 
|---|
| 527 | Boolean vps_poc_proportional_to_timing_flag = bv.get1BitBoolean(); | 
|---|
| 528 | DEBUG_PRINT(vps_poc_proportional_to_timing_flag); | 
|---|
| 529 | if (vps_poc_proportional_to_timing_flag) { | 
|---|
| 530 | unsigned vps_num_ticks_poc_diff_one_minus1 = bv.get_expGolomb(); | 
|---|
| 531 | DEBUG_PRINT(vps_num_ticks_poc_diff_one_minus1); | 
|---|
| 532 | } | 
|---|
| 533 | } | 
|---|
| 534 | Boolean vps_extension_flag = bv.get1BitBoolean(); | 
|---|
| 535 | DEBUG_PRINT(vps_extension_flag); | 
|---|
| 536 | } | 
|---|
| 537 |  | 
|---|
| 538 | void H264or5VideoStreamParser | 
|---|
| 539 | ::analyze_seq_parameter_set_data(unsigned& num_units_in_tick, unsigned& time_scale) { | 
|---|
| 540 | num_units_in_tick = time_scale = 0; // default values | 
|---|
| 541 |  | 
|---|
| 542 | // Begin by making a copy of the NAL unit data, removing any 'emulation prevention' bytes: | 
|---|
| 543 | u_int8_t sps[SPS_MAX_SIZE]; | 
|---|
| 544 | unsigned spsSize; | 
|---|
| 545 | removeEmulationBytes(sps, sizeof sps, spsSize); | 
|---|
| 546 |  | 
|---|
| 547 | BitVector bv(sps, 0, 8*spsSize); | 
|---|
| 548 |  | 
|---|
| 549 | if (fHNumber == 264) { | 
|---|
| 550 | bv.skipBits(8); // forbidden_zero_bit; nal_ref_idc; nal_unit_type | 
|---|
| 551 | unsigned profile_idc = bv.getBits(8); | 
|---|
| 552 | DEBUG_PRINT(profile_idc); | 
|---|
| 553 | unsigned constraint_setN_flag = bv.getBits(8); // also "reserved_zero_2bits" at end | 
|---|
| 554 | DEBUG_PRINT(constraint_setN_flag); | 
|---|
| 555 | unsigned level_idc = bv.getBits(8); | 
|---|
| 556 | DEBUG_PRINT(level_idc); | 
|---|
| 557 | unsigned seq_parameter_set_id = bv.get_expGolomb(); | 
|---|
| 558 | DEBUG_PRINT(seq_parameter_set_id); | 
|---|
| 559 | if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ) { | 
|---|
| 560 | DEBUG_TAB; | 
|---|
| 561 | unsigned chroma_format_idc = bv.get_expGolomb(); | 
|---|
| 562 | DEBUG_PRINT(chroma_format_idc); | 
|---|
| 563 | if (chroma_format_idc == 3) { | 
|---|
| 564 | DEBUG_TAB; | 
|---|
| 565 | Boolean separate_colour_plane_flag = bv.get1BitBoolean(); | 
|---|
| 566 | DEBUG_PRINT(separate_colour_plane_flag); | 
|---|
| 567 | } | 
|---|
| 568 | (void)bv.get_expGolomb(); // bit_depth_luma_minus8 | 
|---|
| 569 | (void)bv.get_expGolomb(); // bit_depth_chroma_minus8 | 
|---|
| 570 | bv.skipBits(1); // qpprime_y_zero_transform_bypass_flag | 
|---|
| 571 | Boolean seq_scaling_matrix_present_flag = bv.get1BitBoolean(); | 
|---|
| 572 | DEBUG_PRINT(seq_scaling_matrix_present_flag); | 
|---|
| 573 | if (seq_scaling_matrix_present_flag) { | 
|---|
| 574 | for (int i = 0; i < ((chroma_format_idc != 3) ? 8 : 12); ++i) { | 
|---|
| 575 | DEBUG_TAB; | 
|---|
| 576 | DEBUG_PRINT(i); | 
|---|
| 577 | Boolean seq_scaling_list_present_flag = bv.get1BitBoolean(); | 
|---|
| 578 | DEBUG_PRINT(seq_scaling_list_present_flag); | 
|---|
| 579 | if (seq_scaling_list_present_flag) { | 
|---|
| 580 | DEBUG_TAB; | 
|---|
| 581 | unsigned sizeOfScalingList = i < 6 ? 16 : 64; | 
|---|
| 582 | unsigned lastScale = 8; | 
|---|
| 583 | unsigned nextScale = 8; | 
|---|
| 584 | for (unsigned j = 0; j < sizeOfScalingList; ++j) { | 
|---|
| 585 | DEBUG_TAB; | 
|---|
| 586 | DEBUG_PRINT(j); | 
|---|
| 587 | DEBUG_PRINT(nextScale); | 
|---|
| 588 | if (nextScale != 0) { | 
|---|
| 589 | DEBUG_TAB; | 
|---|
| 590 | int delta_scale = bv.get_expGolombSigned(); | 
|---|
| 591 | DEBUG_PRINT(delta_scale); | 
|---|
| 592 | nextScale = (lastScale + delta_scale + 256) % 256; | 
|---|
| 593 | } | 
|---|
| 594 | lastScale = (nextScale == 0) ? lastScale : nextScale; | 
|---|
| 595 | DEBUG_PRINT(lastScale); | 
|---|
| 596 | } | 
|---|
| 597 | } | 
|---|
| 598 | } | 
|---|
| 599 | } | 
|---|
| 600 | } | 
|---|
| 601 | unsigned log2_max_frame_num_minus4 = bv.get_expGolomb(); | 
|---|
| 602 | DEBUG_PRINT(log2_max_frame_num_minus4); | 
|---|
| 603 | unsigned pic_order_cnt_type = bv.get_expGolomb(); | 
|---|
| 604 | DEBUG_PRINT(pic_order_cnt_type); | 
|---|
| 605 | if (pic_order_cnt_type == 0) { | 
|---|
| 606 | DEBUG_TAB; | 
|---|
| 607 | unsigned log2_max_pic_order_cnt_lsb_minus4 = bv.get_expGolomb(); | 
|---|
| 608 | DEBUG_PRINT(log2_max_pic_order_cnt_lsb_minus4); | 
|---|
| 609 | } else if (pic_order_cnt_type == 1) { | 
|---|
| 610 | DEBUG_TAB; | 
|---|
| 611 | bv.skipBits(1); // delta_pic_order_always_zero_flag | 
|---|
| 612 | (void)bv.get_expGolombSigned(); // offset_for_non_ref_pic | 
|---|
| 613 | (void)bv.get_expGolombSigned(); // offset_for_top_to_bottom_field | 
|---|
| 614 | unsigned num_ref_frames_in_pic_order_cnt_cycle = bv.get_expGolomb(); | 
|---|
| 615 | DEBUG_PRINT(num_ref_frames_in_pic_order_cnt_cycle); | 
|---|
| 616 | for (unsigned i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; ++i) { | 
|---|
| 617 | (void)bv.get_expGolombSigned(); // offset_for_ref_frame[i] | 
|---|
| 618 | } | 
|---|
| 619 | } | 
|---|
| 620 | unsigned max_num_ref_frames = bv.get_expGolomb(); | 
|---|
| 621 | DEBUG_PRINT(max_num_ref_frames); | 
|---|
| 622 | Boolean gaps_in_frame_num_value_allowed_flag = bv.get1BitBoolean(); | 
|---|
| 623 | DEBUG_PRINT(gaps_in_frame_num_value_allowed_flag); | 
|---|
| 624 | unsigned pic_width_in_mbs_minus1 = bv.get_expGolomb(); | 
|---|
| 625 | DEBUG_PRINT(pic_width_in_mbs_minus1); | 
|---|
| 626 | unsigned pic_height_in_map_units_minus1 = bv.get_expGolomb(); | 
|---|
| 627 | DEBUG_PRINT(pic_height_in_map_units_minus1); | 
|---|
| 628 | Boolean frame_mbs_only_flag = bv.get1BitBoolean(); | 
|---|
| 629 | DEBUG_PRINT(frame_mbs_only_flag); | 
|---|
| 630 | if (!frame_mbs_only_flag) { | 
|---|
| 631 | bv.skipBits(1); // mb_adaptive_frame_field_flag | 
|---|
| 632 | } | 
|---|
| 633 | bv.skipBits(1); // direct_8x8_inference_flag | 
|---|
| 634 | Boolean frame_cropping_flag = bv.get1BitBoolean(); | 
|---|
| 635 | DEBUG_PRINT(frame_cropping_flag); | 
|---|
| 636 | if (frame_cropping_flag) { | 
|---|
| 637 | (void)bv.get_expGolomb(); // frame_crop_left_offset | 
|---|
| 638 | (void)bv.get_expGolomb(); // frame_crop_right_offset | 
|---|
| 639 | (void)bv.get_expGolomb(); // frame_crop_top_offset | 
|---|
| 640 | (void)bv.get_expGolomb(); // frame_crop_bottom_offset | 
|---|
| 641 | } | 
|---|
| 642 | Boolean vui_parameters_present_flag = bv.get1BitBoolean(); | 
|---|
| 643 | DEBUG_PRINT(vui_parameters_present_flag); | 
|---|
| 644 | if (vui_parameters_present_flag) { | 
|---|
| 645 | DEBUG_TAB; | 
|---|
| 646 | analyze_vui_parameters(bv, num_units_in_tick, time_scale); | 
|---|
| 647 | } | 
|---|
| 648 | } else { // 265 | 
|---|
| 649 | unsigned i; | 
|---|
| 650 |  | 
|---|
| 651 | bv.skipBits(16); // nal_unit_header | 
|---|
| 652 | bv.skipBits(4); // sps_video_parameter_set_id | 
|---|
| 653 | unsigned sps_max_sub_layers_minus1 = bv.getBits(3); | 
|---|
| 654 | DEBUG_PRINT(sps_max_sub_layers_minus1); | 
|---|
| 655 | bv.skipBits(1); // sps_temporal_id_nesting_flag | 
|---|
| 656 | profile_tier_level(bv, sps_max_sub_layers_minus1); | 
|---|
| 657 | (void)bv.get_expGolomb(); // sps_seq_parameter_set_id | 
|---|
| 658 | unsigned chroma_format_idc = bv.get_expGolomb(); | 
|---|
| 659 | DEBUG_PRINT(chroma_format_idc); | 
|---|
| 660 | if (chroma_format_idc == 3) bv.skipBits(1); // separate_colour_plane_flag | 
|---|
| 661 | unsigned pic_width_in_luma_samples = bv.get_expGolomb(); | 
|---|
| 662 | DEBUG_PRINT(pic_width_in_luma_samples); | 
|---|
| 663 | unsigned pic_height_in_luma_samples = bv.get_expGolomb(); | 
|---|
| 664 | DEBUG_PRINT(pic_height_in_luma_samples); | 
|---|
| 665 | Boolean conformance_window_flag = bv.get1BitBoolean(); | 
|---|
| 666 | DEBUG_PRINT(conformance_window_flag); | 
|---|
| 667 | if (conformance_window_flag) { | 
|---|
| 668 | DEBUG_TAB; | 
|---|
| 669 | unsigned conf_win_left_offset = bv.get_expGolomb(); | 
|---|
| 670 | DEBUG_PRINT(conf_win_left_offset); | 
|---|
| 671 | unsigned conf_win_right_offset = bv.get_expGolomb(); | 
|---|
| 672 | DEBUG_PRINT(conf_win_right_offset); | 
|---|
| 673 | unsigned conf_win_top_offset = bv.get_expGolomb(); | 
|---|
| 674 | DEBUG_PRINT(conf_win_top_offset); | 
|---|
| 675 | unsigned conf_win_bottom_offset = bv.get_expGolomb(); | 
|---|
| 676 | DEBUG_PRINT(conf_win_bottom_offset); | 
|---|
| 677 | } | 
|---|
| 678 | (void)bv.get_expGolomb(); // bit_depth_luma_minus8 | 
|---|
| 679 | (void)bv.get_expGolomb(); // bit_depth_chroma_minus8 | 
|---|
| 680 | unsigned log2_max_pic_order_cnt_lsb_minus4 = bv.get_expGolomb(); | 
|---|
| 681 | Boolean sps_sub_layer_ordering_info_present_flag = bv.get1BitBoolean(); | 
|---|
| 682 | DEBUG_PRINT(sps_sub_layer_ordering_info_present_flag); | 
|---|
| 683 | for (i = (sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1); | 
|---|
| 684 | i <= sps_max_sub_layers_minus1; ++i) { | 
|---|
| 685 | (void)bv.get_expGolomb(); // sps_max_dec_pic_buffering_minus1[i] | 
|---|
| 686 | (void)bv.get_expGolomb(); // sps_max_num_reorder_pics[i] | 
|---|
| 687 | (void)bv.get_expGolomb(); // sps_max_latency_increase[i] | 
|---|
| 688 | } | 
|---|
| 689 | (void)bv.get_expGolomb(); // log2_min_luma_coding_block_size_minus3 | 
|---|
| 690 | (void)bv.get_expGolomb(); // log2_diff_max_min_luma_coding_block_size | 
|---|
| 691 | (void)bv.get_expGolomb(); // log2_min_transform_block_size_minus2 | 
|---|
| 692 | (void)bv.get_expGolomb(); // log2_diff_max_min_transform_block_size | 
|---|
| 693 | (void)bv.get_expGolomb(); // max_transform_hierarchy_depth_inter | 
|---|
| 694 | (void)bv.get_expGolomb(); // max_transform_hierarchy_depth_intra | 
|---|
| 695 | Boolean scaling_list_enabled_flag = bv.get1BitBoolean(); | 
|---|
| 696 | DEBUG_PRINT(scaling_list_enabled_flag); | 
|---|
| 697 | if (scaling_list_enabled_flag) { | 
|---|
| 698 | DEBUG_TAB; | 
|---|
| 699 | Boolean sps_scaling_list_data_present_flag = bv.get1BitBoolean(); | 
|---|
| 700 | DEBUG_PRINT(sps_scaling_list_data_present_flag); | 
|---|
| 701 | if (sps_scaling_list_data_present_flag) { | 
|---|
| 702 | // scaling_list_data() | 
|---|
| 703 | DEBUG_TAB; | 
|---|
| 704 | for (unsigned sizeId = 0; sizeId < 4; ++sizeId) { | 
|---|
| 705 | DEBUG_PRINT(sizeId); | 
|---|
| 706 | for (unsigned matrixId = 0; matrixId < (sizeId == 3 ? 2 : 6); ++matrixId) { | 
|---|
| 707 | DEBUG_TAB; | 
|---|
| 708 | DEBUG_PRINT(matrixId); | 
|---|
| 709 | Boolean scaling_list_pred_mode_flag = bv.get1BitBoolean(); | 
|---|
| 710 | DEBUG_PRINT(scaling_list_pred_mode_flag); | 
|---|
| 711 | if (!scaling_list_pred_mode_flag) { | 
|---|
| 712 | (void)bv.get_expGolomb(); // scaling_list_pred_matrix_id_delta[sizeId][matrixId] | 
|---|
| 713 | } else { | 
|---|
| 714 | unsigned const c = 1 << (4+(sizeId<<1)); | 
|---|
| 715 | unsigned coefNum = c < 64 ? c : 64; | 
|---|
| 716 | if (sizeId > 1) { | 
|---|
| 717 | (void)bv.get_expGolomb(); // scaling_list_dc_coef_minus8[sizeId][matrixId] | 
|---|
| 718 | } | 
|---|
| 719 | for (i = 0; i < coefNum; ++i) { | 
|---|
| 720 | (void)bv.get_expGolomb(); // scaling_list_delta_coef | 
|---|
| 721 | } | 
|---|
| 722 | } | 
|---|
| 723 | } | 
|---|
| 724 | } | 
|---|
| 725 | } | 
|---|
| 726 | } | 
|---|
| 727 | bv.skipBits(2); // amp_enabled_flag, sample_adaptive_offset_enabled_flag | 
|---|
| 728 | Boolean pcm_enabled_flag = bv.get1BitBoolean(); | 
|---|
| 729 | DEBUG_PRINT(pcm_enabled_flag); | 
|---|
| 730 | if (pcm_enabled_flag) { | 
|---|
| 731 | bv.skipBits(8); // pcm_sample_bit_depth_luma_minus1, pcm_sample_bit_depth_chroma_minus1 | 
|---|
| 732 | (void)bv.get_expGolomb(); // log2_min_pcm_luma_coding_block_size_minus3 | 
|---|
| 733 | (void)bv.get_expGolomb(); // log2_diff_max_min_pcm_luma_coding_block_size | 
|---|
| 734 | bv.skipBits(1); // pcm_loop_filter_disabled_flag | 
|---|
| 735 | } | 
|---|
| 736 | unsigned num_short_term_ref_pic_sets = bv.get_expGolomb(); | 
|---|
| 737 | DEBUG_PRINT(num_short_term_ref_pic_sets); | 
|---|
| 738 | unsigned num_negative_pics = 0, prev_num_negative_pics = 0; | 
|---|
| 739 | unsigned num_positive_pics = 0, prev_num_positive_pics = 0; | 
|---|
| 740 | for (i = 0; i < num_short_term_ref_pic_sets; ++i) { | 
|---|
| 741 | // short_term_ref_pic_set(i): | 
|---|
| 742 | DEBUG_TAB; | 
|---|
| 743 | DEBUG_PRINT(i); | 
|---|
| 744 | Boolean inter_ref_pic_set_prediction_flag = False; | 
|---|
| 745 | if (i != 0) { | 
|---|
| 746 | inter_ref_pic_set_prediction_flag = bv.get1BitBoolean(); | 
|---|
| 747 | } | 
|---|
| 748 | DEBUG_PRINT(inter_ref_pic_set_prediction_flag); | 
|---|
| 749 | if (inter_ref_pic_set_prediction_flag) { | 
|---|
| 750 | DEBUG_TAB; | 
|---|
| 751 | if (i == num_short_term_ref_pic_sets) { | 
|---|
| 752 | // This can't happen here, but it's in the spec, so we include it for completeness | 
|---|
| 753 | (void)bv.get_expGolomb(); // delta_idx_minus1 | 
|---|
| 754 | } | 
|---|
| 755 | bv.skipBits(1); // delta_rps_sign | 
|---|
| 756 | (void)bv.get_expGolomb(); // abs_delta_rps_minus1 | 
|---|
| 757 | unsigned NumDeltaPocs = prev_num_negative_pics + prev_num_positive_pics; // correct??? | 
|---|
| 758 | for (unsigned j = 0; j < NumDeltaPocs; ++j) { | 
|---|
| 759 | DEBUG_PRINT(j); | 
|---|
| 760 | Boolean used_by_curr_pic_flag = bv.get1BitBoolean(); | 
|---|
| 761 | DEBUG_PRINT(used_by_curr_pic_flag); | 
|---|
| 762 | if (!used_by_curr_pic_flag) bv.skipBits(1); // use_delta_flag[j] | 
|---|
| 763 | } | 
|---|
| 764 | } else { | 
|---|
| 765 | prev_num_negative_pics = num_negative_pics; | 
|---|
| 766 | num_negative_pics = bv.get_expGolomb(); | 
|---|
| 767 | DEBUG_PRINT(num_negative_pics); | 
|---|
| 768 | prev_num_positive_pics = num_positive_pics; | 
|---|
| 769 | num_positive_pics = bv.get_expGolomb(); | 
|---|
| 770 | DEBUG_PRINT(num_positive_pics); | 
|---|
| 771 | unsigned k; | 
|---|
| 772 | for (k = 0; k < num_negative_pics; ++k) { | 
|---|
| 773 | (void)bv.get_expGolomb(); // delta_poc_s0_minus1[k] | 
|---|
| 774 | bv.skipBits(1); // used_by_curr_pic_s0_flag[k] | 
|---|
| 775 | } | 
|---|
| 776 | for (k = 0; k < num_positive_pics; ++k) { | 
|---|
| 777 | (void)bv.get_expGolomb(); // delta_poc_s1_minus1[k] | 
|---|
| 778 | bv.skipBits(1); // used_by_curr_pic_s1_flag[k] | 
|---|
| 779 | } | 
|---|
| 780 | } | 
|---|
| 781 | } | 
|---|
| 782 | Boolean long_term_ref_pics_present_flag = bv.get1BitBoolean(); | 
|---|
| 783 | DEBUG_PRINT(long_term_ref_pics_present_flag); | 
|---|
| 784 | if (long_term_ref_pics_present_flag) { | 
|---|
| 785 | DEBUG_TAB; | 
|---|
| 786 | unsigned num_long_term_ref_pics_sps = bv.get_expGolomb(); | 
|---|
| 787 | DEBUG_PRINT(num_long_term_ref_pics_sps); | 
|---|
| 788 | for (i = 0; i < num_long_term_ref_pics_sps; ++i) { | 
|---|
| 789 | bv.skipBits(log2_max_pic_order_cnt_lsb_minus4); // lt_ref_pic_poc_lsb_sps[i] | 
|---|
| 790 | bv.skipBits(1); // used_by_curr_pic_lt_sps_flag[1] | 
|---|
| 791 | } | 
|---|
| 792 | } | 
|---|
| 793 | bv.skipBits(2); // sps_temporal_mvp_enabled_flag, strong_intra_smoothing_enabled_flag | 
|---|
| 794 | Boolean vui_parameters_present_flag = bv.get1BitBoolean(); | 
|---|
| 795 | DEBUG_PRINT(vui_parameters_present_flag); | 
|---|
| 796 | if (vui_parameters_present_flag) { | 
|---|
| 797 | DEBUG_TAB; | 
|---|
| 798 | analyze_vui_parameters(bv, num_units_in_tick, time_scale); | 
|---|
| 799 | } | 
|---|
| 800 | Boolean sps_extension_flag = bv.get1BitBoolean(); | 
|---|
| 801 | DEBUG_PRINT(sps_extension_flag); | 
|---|
| 802 | } | 
|---|
| 803 | } | 
|---|
| 804 |  | 
|---|
| 805 | #define SEI_MAX_SIZE 5000 // larger than the largest possible SEI NAL unit | 
|---|
| 806 |  | 
|---|
| 807 | #ifdef DEBUG | 
|---|
| 808 | #define MAX_SEI_PAYLOAD_TYPE_DESCRIPTION_H264 46 | 
|---|
| 809 | char const* sei_payloadType_description_h264[MAX_SEI_PAYLOAD_TYPE_DESCRIPTION_H264+1] = { | 
|---|
| 810 | "buffering_period", //0 | 
|---|
| 811 | "pic_timing", //1 | 
|---|
| 812 | "pan_scan_rect", //2 | 
|---|
| 813 | "filler_payload", //3 | 
|---|
| 814 | "user_data_registered_itu_t_t35", //4 | 
|---|
| 815 | "user_data_unregistered", //5 | 
|---|
| 816 | "recovery_point", //6 | 
|---|
| 817 | "dec_ref_pic_marking_repetition", //7 | 
|---|
| 818 | "spare_pic", //8 | 
|---|
| 819 | "scene_info", //9 | 
|---|
| 820 | "sub_seq_info", //10 | 
|---|
| 821 | "sub_seq_layer_characteristics", //11 | 
|---|
| 822 | "sub_seq_characteristics", //12 | 
|---|
| 823 | "full_frame_freeze", //13 | 
|---|
| 824 | "full_frame_freeze_release", //14 | 
|---|
| 825 | "full_frame_snapshot", //15 | 
|---|
| 826 | "progressive_refinement_segment_start", //16 | 
|---|
| 827 | "progressive_refinement_segment_end", //17 | 
|---|
| 828 | "motion_constrained_slice_group_set", //18 | 
|---|
| 829 | "film_grain_characteristics", //19 | 
|---|
| 830 | "deblocking_filter_display_preference", //20 | 
|---|
| 831 | "stereo_video_info", //21 | 
|---|
| 832 | "post_filter_hint", //22 | 
|---|
| 833 | "tone_mapping_info", //23 | 
|---|
| 834 | "scalability_info", //24 | 
|---|
| 835 | "sub_pic_scalable_layer", //25 | 
|---|
| 836 | "non_required_layer_rep", //26 | 
|---|
| 837 | "priority_layer_info", //27 | 
|---|
| 838 | "layers_not_present", //28 | 
|---|
| 839 | "layer_dependency_change", //29 | 
|---|
| 840 | "scalable_nesting", //30 | 
|---|
| 841 | "base_layer_temporal_hrd", //31 | 
|---|
| 842 | "quality_layer_integrity_check", //32 | 
|---|
| 843 | "redundant_pic_property", //33 | 
|---|
| 844 | "tl0_dep_rep_index", //34 | 
|---|
| 845 | "tl_switching_point", //35 | 
|---|
| 846 | "parallel_decoding_info", //36 | 
|---|
| 847 | "mvc_scalable_nesting", //37 | 
|---|
| 848 | "view_scalability_info", //38 | 
|---|
| 849 | "multiview_scene_info", //39 | 
|---|
| 850 | "multiview_acquisition_info", //40 | 
|---|
| 851 | "non_required_view_component", //41 | 
|---|
| 852 | "view_dependency_change", //42 | 
|---|
| 853 | "operation_points_not_present", //43 | 
|---|
| 854 | "base_view_temporal_hrd", //44 | 
|---|
| 855 | "frame_packing_arrangement", //45 | 
|---|
| 856 | "reserved_sei_message"// 46 or higher | 
|---|
| 857 | }; | 
|---|
| 858 | #endif | 
|---|
| 859 |  | 
|---|
| 860 | void H264or5VideoStreamParser::analyze_sei_data(u_int8_t nal_unit_type) { | 
|---|
| 861 | // Begin by making a copy of the NAL unit data, removing any 'emulation prevention' bytes: | 
|---|
| 862 | u_int8_t sei[SEI_MAX_SIZE]; | 
|---|
| 863 | unsigned seiSize; | 
|---|
| 864 | removeEmulationBytes(sei, sizeof sei, seiSize); | 
|---|
| 865 |  | 
|---|
| 866 | unsigned j = 1; // skip the initial byte (forbidden_zero_bit; nal_ref_idc; nal_unit_type); we've already seen it | 
|---|
| 867 | while (j < seiSize) { | 
|---|
| 868 | unsigned payloadType = 0; | 
|---|
| 869 | do { | 
|---|
| 870 | payloadType += sei[j]; | 
|---|
| 871 | } while (sei[j++] == 255 && j < seiSize); | 
|---|
| 872 | if (j >= seiSize) break; | 
|---|
| 873 |  | 
|---|
| 874 | unsigned payloadSize = 0; | 
|---|
| 875 | do { | 
|---|
| 876 | payloadSize += sei[j]; | 
|---|
| 877 | } while (sei[j++] == 255 && j < seiSize); | 
|---|
| 878 | if (j >= seiSize) break; | 
|---|
| 879 |  | 
|---|
| 880 | #ifdef DEBUG | 
|---|
| 881 | char const* description; | 
|---|
| 882 | if (fHNumber == 264) { | 
|---|
| 883 | unsigned descriptionNum = payloadType <= MAX_SEI_PAYLOAD_TYPE_DESCRIPTION_H264 | 
|---|
| 884 | ? payloadType : MAX_SEI_PAYLOAD_TYPE_DESCRIPTION_H264; | 
|---|
| 885 | description = sei_payloadType_description_h264[descriptionNum]; | 
|---|
| 886 | } else { // 265 | 
|---|
| 887 | description = | 
|---|
| 888 | payloadType == 3 ? "filler_payload": | 
|---|
| 889 | payloadType == 4 ? "user_data_registered_itu_t_t35": | 
|---|
| 890 | payloadType == 5 ? "user_data_unregistered": | 
|---|
| 891 | payloadType == 17 ? "progressive_refinement_segment_end": | 
|---|
| 892 | payloadType == 22 ? "post_filter_hint": | 
|---|
| 893 | (payloadType == 132 && nal_unit_type == SUFFIX_SEI_NUT) ? "decoded_picture_hash": | 
|---|
| 894 | nal_unit_type == SUFFIX_SEI_NUT ? "reserved_sei_message": | 
|---|
| 895 | payloadType == 0 ? "buffering_period": | 
|---|
| 896 | payloadType == 1 ? "pic_timing": | 
|---|
| 897 | payloadType == 2 ? "pan_scan_rect": | 
|---|
| 898 | payloadType == 6 ? "recovery_point": | 
|---|
| 899 | payloadType == 9 ? "scene_info": | 
|---|
| 900 | payloadType == 15 ? "picture_snapshot": | 
|---|
| 901 | payloadType == 16 ? "progressive_refinement_segment_start": | 
|---|
| 902 | payloadType == 19 ? "film_grain_characteristics": | 
|---|
| 903 | payloadType == 23 ? "tone_mapping_info": | 
|---|
| 904 | payloadType == 45 ? "frame_packing_arrangement": | 
|---|
| 905 | payloadType == 47 ? "display_orientation": | 
|---|
| 906 | payloadType == 128 ? "structure_of_pictures_info": | 
|---|
| 907 | payloadType == 129 ? "active_parameter_sets": | 
|---|
| 908 | payloadType == 130 ? "decoding_unit_info": | 
|---|
| 909 | payloadType == 131 ? "temporal_sub_layer_zero_index": | 
|---|
| 910 | payloadType == 133 ? "scalable_nesting": | 
|---|
| 911 | payloadType == 134 ? "region_refresh_info": "reserved_sei_message"; | 
|---|
| 912 | } | 
|---|
| 913 | fprintf(stderr, "\tpayloadType %d (\"%s\"); payloadSize %d\n", payloadType, description, payloadSize); | 
|---|
| 914 | #endif | 
|---|
| 915 |  | 
|---|
| 916 | analyze_sei_payload(payloadType, payloadSize, &sei[j]); | 
|---|
| 917 | j += payloadSize; | 
|---|
| 918 | } | 
|---|
| 919 | } | 
|---|
| 920 |  | 
|---|
| 921 | void H264or5VideoStreamParser | 
|---|
| 922 | ::analyze_sei_payload(unsigned payloadType, unsigned payloadSize, u_int8_t* payload) { | 
|---|
| 923 | if (payloadType == 1/* pic_timing, for both H.264 and H.265 */) { | 
|---|
| 924 | BitVector bv(payload, 0, 8*payloadSize); | 
|---|
| 925 |  | 
|---|
| 926 | DEBUG_TAB; | 
|---|
| 927 | if (CpbDpbDelaysPresentFlag) { | 
|---|
| 928 | unsigned cpb_removal_delay = bv.getBits(cpb_removal_delay_length_minus1 + 1); | 
|---|
| 929 | DEBUG_PRINT(cpb_removal_delay); | 
|---|
| 930 | unsigned dpb_output_delay = bv.getBits(dpb_output_delay_length_minus1 + 1); | 
|---|
| 931 | DEBUG_PRINT(dpb_output_delay); | 
|---|
| 932 | } | 
|---|
| 933 | double prevDeltaTfiDivisor = DeltaTfiDivisor; | 
|---|
| 934 | if (pic_struct_present_flag) { | 
|---|
| 935 | unsigned pic_struct = bv.getBits(4); | 
|---|
| 936 | DEBUG_PRINT(pic_struct); | 
|---|
| 937 | // Use this to set "DeltaTfiDivisor" (which is used to compute the frame rate): | 
|---|
| 938 | if (fHNumber == 264) { | 
|---|
| 939 | DeltaTfiDivisor = | 
|---|
| 940 | pic_struct == 0 ? 2.0 : | 
|---|
| 941 | pic_struct <= 2 ? 1.0 : | 
|---|
| 942 | pic_struct <= 4 ? 2.0 : | 
|---|
| 943 | pic_struct <= 6 ? 3.0 : | 
|---|
| 944 | pic_struct == 7 ? 4.0 : | 
|---|
| 945 | pic_struct == 8 ? 6.0 : | 
|---|
| 946 | 2.0; | 
|---|
| 947 | } else { // H.265 | 
|---|
| 948 | DeltaTfiDivisor = | 
|---|
| 949 | pic_struct == 0 ? 2.0 : | 
|---|
| 950 | pic_struct <= 2 ? 1.0 : | 
|---|
| 951 | pic_struct <= 4 ? 2.0 : | 
|---|
| 952 | pic_struct <= 6 ? 3.0 : | 
|---|
| 953 | pic_struct == 7 ? 2.0 : | 
|---|
| 954 | pic_struct == 8 ? 3.0 : | 
|---|
| 955 | pic_struct <= 12 ? 1.0 : | 
|---|
| 956 | 2.0; | 
|---|
| 957 | } | 
|---|
| 958 | } else { | 
|---|
| 959 | if (fHNumber == 264) { | 
|---|
| 960 | // Need to get field_pic_flag from slice_header to set this properly! ##### | 
|---|
| 961 | } else { // H.265 | 
|---|
| 962 | DeltaTfiDivisor = 1.0; | 
|---|
| 963 | } | 
|---|
| 964 | } | 
|---|
| 965 | // If "DeltaTfiDivisor" has changed, and we've already computed the frame rate, then | 
|---|
| 966 | // adjust it, based on the new value of "DeltaTfiDivisor": | 
|---|
| 967 | if (DeltaTfiDivisor != prevDeltaTfiDivisor && fParsedFrameRate != 0.0) { | 
|---|
| 968 | usingSource()->fFrameRate = fParsedFrameRate | 
|---|
| 969 | = fParsedFrameRate*(prevDeltaTfiDivisor/DeltaTfiDivisor); | 
|---|
| 970 | #ifdef DEBUG | 
|---|
| 971 | fprintf(stderr, "Changed frame rate to %f fps\n", usingSource()->fFrameRate); | 
|---|
| 972 | #endif | 
|---|
| 973 | } | 
|---|
| 974 | // Ignore the rest of the payload (timestamps) for now... ##### | 
|---|
| 975 | } | 
|---|
| 976 | } | 
|---|
| 977 |  | 
|---|
| 978 | void H264or5VideoStreamParser::flushInput() { | 
|---|
| 979 | fHaveSeenFirstStartCode = False; | 
|---|
| 980 | fHaveSeenFirstByteOfNALUnit = False; | 
|---|
| 981 |  | 
|---|
| 982 | StreamParser::flushInput(); | 
|---|
| 983 | } | 
|---|
| 984 |  | 
|---|
| 985 | unsigned H264or5VideoStreamParser::parse() { | 
|---|
| 986 | try { | 
|---|
| 987 | // The stream must start with a 0x00000001: | 
|---|
| 988 | if (!fHaveSeenFirstStartCode) { | 
|---|
| 989 | // Skip over any input bytes that precede the first 0x00000001: | 
|---|
| 990 | u_int32_t first4Bytes; | 
|---|
| 991 | while ((first4Bytes = test4Bytes()) != 0x00000001) { | 
|---|
| 992 | get1Byte(); setParseState(); // ensures that we progress over bad data | 
|---|
| 993 | } | 
|---|
| 994 | skipBytes(4); // skip this initial code | 
|---|
| 995 |  | 
|---|
| 996 | setParseState(); | 
|---|
| 997 | fHaveSeenFirstStartCode = True; // from now on | 
|---|
| 998 | } | 
|---|
| 999 |  | 
|---|
| 1000 | if (fOutputStartCodeSize > 0 && curFrameSize() == 0 && !haveSeenEOF()) { | 
|---|
| 1001 | // Include a start code in the output: | 
|---|
| 1002 | save4Bytes(0x00000001); | 
|---|
| 1003 | } | 
|---|
| 1004 |  | 
|---|
| 1005 | // Then save everything up until the next 0x00000001 (4 bytes) or 0x000001 (3 bytes), or we hit EOF. | 
|---|
| 1006 | // Also make note of the first byte, because it contains the "nal_unit_type": | 
|---|
| 1007 | if (haveSeenEOF()) { | 
|---|
| 1008 | // We hit EOF the last time that we tried to parse this data, so we know that any remaining unparsed data | 
|---|
| 1009 | // forms a complete NAL unit, and that there's no 'start code' at the end: | 
|---|
| 1010 | unsigned remainingDataSize = totNumValidBytes() - curOffset(); | 
|---|
| 1011 | #ifdef DEBUG | 
|---|
| 1012 | unsigned const trailingNALUnitSize = remainingDataSize; | 
|---|
| 1013 | #endif | 
|---|
| 1014 | while (remainingDataSize > 0) { | 
|---|
| 1015 | u_int8_t nextByte = get1Byte(); | 
|---|
| 1016 | if (!fHaveSeenFirstByteOfNALUnit) { | 
|---|
| 1017 | fFirstByteOfNALUnit = nextByte; | 
|---|
| 1018 | fHaveSeenFirstByteOfNALUnit = True; | 
|---|
| 1019 | } | 
|---|
| 1020 | saveByte(nextByte); | 
|---|
| 1021 | --remainingDataSize; | 
|---|
| 1022 | } | 
|---|
| 1023 |  | 
|---|
| 1024 | #ifdef DEBUG | 
|---|
| 1025 | if (fHNumber == 264) { | 
|---|
| 1026 | u_int8_t nal_ref_idc = (fFirstByteOfNALUnit&0x60)>>5; | 
|---|
| 1027 | u_int8_t nal_unit_type = fFirstByteOfNALUnit&0x1F; | 
|---|
| 1028 | fprintf(stderr, "Parsed trailing %d-byte NAL-unit (nal_ref_idc: %d, nal_unit_type: %d (\"%s\"))\n", | 
|---|
| 1029 | trailingNALUnitSize, nal_ref_idc, nal_unit_type, nal_unit_type_description_h264[nal_unit_type]); | 
|---|
| 1030 | } else { // 265 | 
|---|
| 1031 | u_int8_t nal_unit_type = (fFirstByteOfNALUnit&0x7E)>>1; | 
|---|
| 1032 | fprintf(stderr, "Parsed trailing %d-byte NAL-unit (nal_unit_type: %d (\"%s\"))\n", | 
|---|
| 1033 | trailingNALUnitSize, nal_unit_type, nal_unit_type_description_h265[nal_unit_type]); | 
|---|
| 1034 | } | 
|---|
| 1035 | #endif | 
|---|
| 1036 |  | 
|---|
| 1037 | (void)get1Byte(); // forces another read, which will cause EOF to get handled for real this time | 
|---|
| 1038 | return 0; | 
|---|
| 1039 | } else { | 
|---|
| 1040 | u_int32_t next4Bytes = test4Bytes(); | 
|---|
| 1041 | if (!fHaveSeenFirstByteOfNALUnit) { | 
|---|
| 1042 | fFirstByteOfNALUnit = next4Bytes>>24; | 
|---|
| 1043 | fHaveSeenFirstByteOfNALUnit = True; | 
|---|
| 1044 | } | 
|---|
| 1045 | while (next4Bytes != 0x00000001 && (next4Bytes&0xFFFFFF00) != 0x00000100) { | 
|---|
| 1046 | // We save at least some of "next4Bytes". | 
|---|
| 1047 | if ((unsigned)(next4Bytes&0xFF) > 1) { | 
|---|
| 1048 | // Common case: 0x00000001 or 0x000001 definitely doesn't begin anywhere in "next4Bytes", so we save all of it: | 
|---|
| 1049 | save4Bytes(next4Bytes); | 
|---|
| 1050 | skipBytes(4); | 
|---|
| 1051 | } else { | 
|---|
| 1052 | // Save the first byte, and continue testing the rest: | 
|---|
| 1053 | saveByte(next4Bytes>>24); | 
|---|
| 1054 | skipBytes(1); | 
|---|
| 1055 | } | 
|---|
| 1056 | setParseState(); // ensures forward progress | 
|---|
| 1057 | next4Bytes = test4Bytes(); | 
|---|
| 1058 | } | 
|---|
| 1059 | // Assert: next4Bytes starts with 0x00000001 or 0x000001, and we've saved all previous bytes (forming a complete NAL unit). | 
|---|
| 1060 | // Skip over these remaining bytes, up until the start of the next NAL unit: | 
|---|
| 1061 | if (next4Bytes == 0x00000001) { | 
|---|
| 1062 | skipBytes(4); | 
|---|
| 1063 | } else { | 
|---|
| 1064 | skipBytes(3); | 
|---|
| 1065 | } | 
|---|
| 1066 | } | 
|---|
| 1067 |  | 
|---|
| 1068 | fHaveSeenFirstByteOfNALUnit = False; // for the next NAL unit that we'll parse | 
|---|
| 1069 | u_int8_t nal_unit_type; | 
|---|
| 1070 | if (fHNumber == 264) { | 
|---|
| 1071 | nal_unit_type = fFirstByteOfNALUnit&0x1F; | 
|---|
| 1072 | #ifdef DEBUG | 
|---|
| 1073 | u_int8_t nal_ref_idc = (fFirstByteOfNALUnit&0x60)>>5; | 
|---|
| 1074 | fprintf(stderr, "Parsed %d-byte NAL-unit (nal_ref_idc: %d, nal_unit_type: %d (\"%s\"))\n", | 
|---|
| 1075 | curFrameSize()-fOutputStartCodeSize, nal_ref_idc, nal_unit_type, nal_unit_type_description_h264[nal_unit_type]); | 
|---|
| 1076 | #endif | 
|---|
| 1077 | } else { // 265 | 
|---|
| 1078 | nal_unit_type = (fFirstByteOfNALUnit&0x7E)>>1; | 
|---|
| 1079 | #ifdef DEBUG | 
|---|
| 1080 | fprintf(stderr, "Parsed %d-byte NAL-unit (nal_unit_type: %d (\"%s\"))\n", | 
|---|
| 1081 | curFrameSize()-fOutputStartCodeSize, nal_unit_type, nal_unit_type_description_h265[nal_unit_type]); | 
|---|
| 1082 | #endif | 
|---|
| 1083 | } | 
|---|
| 1084 |  | 
|---|
| 1085 | // Now that we have found (& copied) a NAL unit, process it if it's of special interest to us: | 
|---|
| 1086 | if (isVPS(nal_unit_type)) { // Video parameter set | 
|---|
| 1087 | // First, save a copy of this NAL unit, in case the downstream object wants to see it: | 
|---|
| 1088 | usingSource()->saveCopyOfVPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize); | 
|---|
| 1089 |  | 
|---|
| 1090 | if (fParsedFrameRate == 0.0) { | 
|---|
| 1091 | // We haven't yet parsed a frame rate from the stream. | 
|---|
| 1092 | // So parse this NAL unit to check whether frame rate information is present: | 
|---|
| 1093 | unsigned num_units_in_tick, time_scale; | 
|---|
| 1094 | analyze_video_parameter_set_data(num_units_in_tick, time_scale); | 
|---|
| 1095 | if (time_scale > 0 && num_units_in_tick > 0) { | 
|---|
| 1096 | usingSource()->fFrameRate = fParsedFrameRate | 
|---|
| 1097 | = time_scale/(DeltaTfiDivisor*num_units_in_tick); | 
|---|
| 1098 | #ifdef DEBUG | 
|---|
| 1099 | fprintf(stderr, "Set frame rate to %f fps\n", usingSource()->fFrameRate); | 
|---|
| 1100 | #endif | 
|---|
| 1101 | } else { | 
|---|
| 1102 | #ifdef DEBUG | 
|---|
| 1103 | fprintf(stderr, "\tThis \"Video Parameter Set\" NAL unit contained no frame rate information, so we use a default frame rate of %f fps\n", usingSource()->fFrameRate); | 
|---|
| 1104 | #endif | 
|---|
| 1105 | } | 
|---|
| 1106 | } | 
|---|
| 1107 | } else if (isSPS(nal_unit_type)) { // Sequence parameter set | 
|---|
| 1108 | // First, save a copy of this NAL unit, in case the downstream object wants to see it: | 
|---|
| 1109 | usingSource()->saveCopyOfSPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize); | 
|---|
| 1110 |  | 
|---|
| 1111 | if (fParsedFrameRate == 0.0) { | 
|---|
| 1112 | // We haven't yet parsed a frame rate from the stream. | 
|---|
| 1113 | // So parse this NAL unit to check whether frame rate information is present: | 
|---|
| 1114 | unsigned num_units_in_tick, time_scale; | 
|---|
| 1115 | analyze_seq_parameter_set_data(num_units_in_tick, time_scale); | 
|---|
| 1116 | if (time_scale > 0 && num_units_in_tick > 0) { | 
|---|
| 1117 | usingSource()->fFrameRate = fParsedFrameRate | 
|---|
| 1118 | = time_scale/(DeltaTfiDivisor*num_units_in_tick); | 
|---|
| 1119 | #ifdef DEBUG | 
|---|
| 1120 | fprintf(stderr, "Set frame rate to %f fps\n", usingSource()->fFrameRate); | 
|---|
| 1121 | #endif | 
|---|
| 1122 | } else { | 
|---|
| 1123 | #ifdef DEBUG | 
|---|
| 1124 | fprintf(stderr, "\tThis \"Sequence Parameter Set\" NAL unit contained no frame rate information, so we use a default frame rate of %f fps\n", usingSource()->fFrameRate); | 
|---|
| 1125 | #endif | 
|---|
| 1126 | } | 
|---|
| 1127 | } | 
|---|
| 1128 | } else if (isPPS(nal_unit_type)) { // Picture parameter set | 
|---|
| 1129 | // Save a copy of this NAL unit, in case the downstream object wants to see it: | 
|---|
| 1130 | usingSource()->saveCopyOfPPS(fStartOfFrame + fOutputStartCodeSize, curFrameSize() - fOutputStartCodeSize); | 
|---|
| 1131 | } else if (isSEI(nal_unit_type)) { // Supplemental enhancement information (SEI) | 
|---|
| 1132 | analyze_sei_data(nal_unit_type); | 
|---|
| 1133 | // Later, perhaps adjust "fPresentationTime" if we saw a "pic_timing" SEI payload??? ##### | 
|---|
| 1134 | } | 
|---|
| 1135 |  | 
|---|
| 1136 | usingSource()->setPresentationTime(); | 
|---|
| 1137 | #ifdef DEBUG | 
|---|
| 1138 | unsigned long secs = (unsigned long)usingSource()->fPresentationTime.tv_sec; | 
|---|
| 1139 | unsigned uSecs = (unsigned)usingSource()->fPresentationTime.tv_usec; | 
|---|
| 1140 | fprintf(stderr, "\tPresentation time: %lu.%06u\n", secs, uSecs); | 
|---|
| 1141 | #endif | 
|---|
| 1142 |  | 
|---|
| 1143 | // Now, check whether this NAL unit ends an 'access unit'. | 
|---|
| 1144 | // (RTP streamers need to know this in order to figure out whether or not to set the "M" bit.) | 
|---|
| 1145 | Boolean thisNALUnitEndsAccessUnit; | 
|---|
| 1146 | if (haveSeenEOF() || isEOF(nal_unit_type)) { | 
|---|
| 1147 | // There is no next NAL unit, so we assume that this one ends the current 'access unit': | 
|---|
| 1148 | thisNALUnitEndsAccessUnit = True; | 
|---|
| 1149 | } else if (usuallyBeginsAccessUnit(nal_unit_type)) { | 
|---|
| 1150 | // These NAL units usually *begin* an access unit, so assume that they don't end one here: | 
|---|
| 1151 | thisNALUnitEndsAccessUnit = False; | 
|---|
| 1152 | } else { | 
|---|
| 1153 | // We need to check the *next* NAL unit to figure out whether | 
|---|
| 1154 | // the current NAL unit ends an 'access unit': | 
|---|
| 1155 | u_int8_t firstBytesOfNextNALUnit[3]; | 
|---|
| 1156 | testBytes(firstBytesOfNextNALUnit, 3); | 
|---|
| 1157 |  | 
|---|
| 1158 | u_int8_t const& next_nal_unit_type = fHNumber == 264 | 
|---|
| 1159 | ? (firstBytesOfNextNALUnit[0]&0x1F) : ((firstBytesOfNextNALUnit[0]&0x7E)>>1); | 
|---|
| 1160 | if (isVCL(next_nal_unit_type)) { | 
|---|
| 1161 | // The high-order bit of the byte after the "nal_unit_header" tells us whether it's | 
|---|
| 1162 | // the start of a new 'access unit' (and thus the current NAL unit ends an 'access unit'): | 
|---|
| 1163 | u_int8_t const | 
|---|
| 1164 | = fHNumber == 264 ? firstBytesOfNextNALUnit[1] : firstBytesOfNextNALUnit[2]; | 
|---|
| 1165 | thisNALUnitEndsAccessUnit = (byteAfter_nal_unit_header&0x80) != 0; | 
|---|
| 1166 | } else if (usuallyBeginsAccessUnit(next_nal_unit_type)) { | 
|---|
| 1167 | // The next NAL unit's type is one that usually appears at the start of an 'access unit', | 
|---|
| 1168 | // so we assume that the current NAL unit ends an 'access unit': | 
|---|
| 1169 | thisNALUnitEndsAccessUnit = True; | 
|---|
| 1170 | } else { | 
|---|
| 1171 | // The next NAL unit definitely doesn't start a new 'access unit', | 
|---|
| 1172 | // which means that the current NAL unit doesn't end one: | 
|---|
| 1173 | thisNALUnitEndsAccessUnit = False; | 
|---|
| 1174 | } | 
|---|
| 1175 | } | 
|---|
| 1176 |  | 
|---|
| 1177 | if (thisNALUnitEndsAccessUnit) { | 
|---|
| 1178 | #ifdef DEBUG | 
|---|
| 1179 | fprintf(stderr, "*****This NAL unit ends the current access unit*****\n"); | 
|---|
| 1180 | #endif | 
|---|
| 1181 | usingSource()->fPictureEndMarker = True; | 
|---|
| 1182 | ++usingSource()->fPictureCount; | 
|---|
| 1183 |  | 
|---|
| 1184 | // Note that the presentation time for the next NAL unit will be different: | 
|---|
| 1185 | struct timeval& nextPT = usingSource()->fNextPresentationTime; // alias | 
|---|
| 1186 | nextPT = usingSource()->fPresentationTime; | 
|---|
| 1187 | double nextFraction = nextPT.tv_usec/1000000.0 + 1/usingSource()->fFrameRate; | 
|---|
| 1188 | unsigned nextSecsIncrement = (long)nextFraction; | 
|---|
| 1189 | nextPT.tv_sec += (long)nextSecsIncrement; | 
|---|
| 1190 | nextPT.tv_usec = (long)((nextFraction - nextSecsIncrement)*1000000); | 
|---|
| 1191 | } | 
|---|
| 1192 | setParseState(); | 
|---|
| 1193 |  | 
|---|
| 1194 | return curFrameSize(); | 
|---|
| 1195 | } catch (int /*e*/) { | 
|---|
| 1196 | #ifdef DEBUG | 
|---|
| 1197 | fprintf(stderr, "H264or5VideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n"); | 
|---|
| 1198 | #endif | 
|---|
| 1199 | return 0;  // the parsing got interrupted | 
|---|
| 1200 | } | 
|---|
| 1201 | } | 
|---|
| 1202 |  | 
|---|
| 1203 | unsigned removeH264or5EmulationBytes(u_int8_t* to, unsigned toMaxSize, | 
|---|
| 1204 | u_int8_t const* from, unsigned fromSize) { | 
|---|
| 1205 | unsigned toSize = 0; | 
|---|
| 1206 | unsigned i = 0; | 
|---|
| 1207 | while (i < fromSize && toSize+1 < toMaxSize) { | 
|---|
| 1208 | if (i+2 < fromSize && from[i] == 0 && from[i+1] == 0 && from[i+2] == 3) { | 
|---|
| 1209 | to[toSize] = to[toSize+1] = 0; | 
|---|
| 1210 | toSize += 2; | 
|---|
| 1211 | i += 3; | 
|---|
| 1212 | } else { | 
|---|
| 1213 | to[toSize] = from[i]; | 
|---|
| 1214 | toSize += 1; | 
|---|
| 1215 | i += 1; | 
|---|
| 1216 | } | 
|---|
| 1217 | } | 
|---|
| 1218 |  | 
|---|
| 1219 | return toSize; | 
|---|
| 1220 | } | 
|---|
| 1221 |  | 
|---|