void HevcSampleEntry::parseBox(BitStream& bitstr) { VisualSampleEntryBox::parseBox(bitstr); while (bitstr.numBytesLeft() > 0) { // Extract contained box bitstream and type std::string boxType; BitStream subBitStream = bitstr.readSubBoxBitStream(boxType); // Handle this box based on the type if (boxType == "hvcC") { mHevcConfigurationBox.parseBox(subBitStream); } else if (boxType == "ccst") { mCodingConstraintsBox.parseBox(subBitStream); mIsCodingConstraintsPresent = true; } else { logWarning() << "Skipping unknown box of type '" << boxType << "' inside HevcSampleEntry" << std::endl; } } }
void ItemReferenceBox::parseBox(BitStream& bitstr) { parseFullBoxHeader(bitstr); while (bitstr.numBytesLeft() > 0) { SingleItemTypeReferenceBox singleRef; singleRef.parseBox(bitstr); addItemRef(singleRef); } }
void ItemPropertiesBox::parseBox(BitStream& input) { parseBoxHeader(input); std::string subBoxType; BitStream subBitStream = input.readSubBoxBitStream(subBoxType); mContainer.parseBox(subBitStream); subBitStream = input.readSubBoxBitStream(subBoxType); if (subBoxType != "ipma") { throw std::runtime_error("ItemPropertiesBox includes a box which is not ipma"); } // There could be several ItemPropertyAssociation boxes, but currently only one is supported. mAssociations.parseBox(subBitStream); if (input.numBytesLeft() > 0) { logWarning() << "ItemPropertiesBox::parseBox() supports currently only one ipma box, but there seems to be more." << std::endl; } }
void ElementaryStreamDescriptorBox::parseBox(BitStream& bitstr) { parseFullBoxHeader(bitstr); ////////////////////////////////////////////// // Fill in struct ES_Descriptor // ////////////////////////////////////////////// mES_Descriptor.ES_DescrTag = bitstr.read8Bits(); if (mES_Descriptor.ES_DescrTag != 3) // ES_DescrTag { throw RuntimeError("ElementaryStreamDescritorBox ES_Descriptor.ES_DescrTag not valid"); } /* Expandable class... need to find out size based on (from ISO/IEC 14496-1) * int sizeOfInstance = 0; * bit(1) nextByte; * bit(7) sizeOfInstance; * while(nextByte) { * bit(1) nextByte; * bit(7) sizeByte; * sizeOfInstance = sizeOfInstance<<7 | sizeByte; } */ std::uint8_t readByte = 0; std::uint32_t size = 0; do { readByte = bitstr.read8Bits(); std::uint8_t sizeByte = (readByte & 0x7F); size = (size << 7) | sizeByte; } while (readByte & 0x80); mES_Descriptor.size = size; mES_Descriptor.ES_ID = bitstr.read16Bits(); mES_Descriptor.flags = bitstr.read8Bits(); if (mES_Descriptor.flags & 0x80) // streamDependenceFlag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { mES_Descriptor.dependsOn_ES_ID = bitstr.read16Bits(); } if (mES_Descriptor.flags & 0x40) // URL_Flag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { mES_Descriptor.URLlength = bitstr.read8Bits(); if (mES_Descriptor.URLlength) { bitstr.readStringWithLen(mES_Descriptor.URLstring, mES_Descriptor.URLlength); } } if (mES_Descriptor.flags & 0x20) // OCRstreamFlag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { mES_Descriptor.OCR_ES_Id = bitstr.read16Bits(); } ////////////////////////////////////////////////////////////////// // Fill in struct ES_Descriptor.DecoderConfigDescriptor // ////////////////////////////////////////////////////////////////// mES_Descriptor.decConfigDescr.DecoderConfigDescrTag = bitstr.read8Bits(); if (mES_Descriptor.decConfigDescr.DecoderConfigDescrTag != 4) // DecoderConfigDescrTag { throw RuntimeError("ElementaryStreamDescritorBox DecoderConfigDescriptor.DecoderConfigDescrTag not valid"); } readByte = 0; size = 0; do { readByte = bitstr.read8Bits(); std::uint8_t sizeByte = (readByte & 0x7f); size = (size << 7) | sizeByte; } while (readByte & 0x80); mES_Descriptor.decConfigDescr.size = size; mES_Descriptor.decConfigDescr.objectTypeIndication = bitstr.read8Bits(); mES_Descriptor.decConfigDescr.streamType = (bitstr.read8Bits() >> 2); mES_Descriptor.decConfigDescr.bufferSizeDB = bitstr.read24Bits(); mES_Descriptor.decConfigDescr.maxBitrate = bitstr.read32Bits(); mES_Descriptor.decConfigDescr.avgBitrate = bitstr.read32Bits(); ///////////////////////////////////////////////////////////////////////////////////// // Fill in struct ES_Descriptor.DecoderConfigDescriptor.DecoderSpecificInfo // ///////////////////////////////////////////////////////////////////////////////////// while (bitstr.numBytesLeft()) // DecoderSpecificInfo is optional. { std::uint8_t tag = bitstr.read8Bits(); readByte = 0; size = 0; do { readByte = bitstr.read8Bits(); std::uint8_t sizeByte = (readByte & 0x7f); size = (size << 7) | sizeByte; } while (readByte & 0x80); DecoderSpecificInfo decSpecificInfo; decSpecificInfo.DecSpecificInfoTag = tag; decSpecificInfo.size = size; bitstr.read8BitsArray(decSpecificInfo.DecSpecificInfo, decSpecificInfo.size); if (tag == 5) // DecSpecificInfoTag { mES_Descriptor.decConfigDescr.decSpecificInfo = std::move(decSpecificInfo); } else { mOtherDecSpecificInfo.push_back(std::move(decSpecificInfo)); } } }
void SampleTableBox::parseBox(BitStream& bitstr) { // First parse the box header parseBoxHeader(bitstr); // if there a data available in the file while (bitstr.numBytesLeft() > 0) { // Extract contained box bitstream and type std::string boxType; BitStream subBitstr = bitstr.readSubBoxBitStream(boxType); // Handle this box based on the type if (boxType == "stsd") { mSampleDescriptionBox.parseBox(subBitstr); } else if (boxType == "stco" || boxType == "co64") // 'co64' is the 64-bit version { mChunkOffsetBox.parseBox(subBitstr); } else if (boxType == "stsz") { mSampleSizeBox.parseBox(subBitstr); } else if (boxType == "stts") { mTimeToSampleBox.parseBox(subBitstr); } else if (boxType == "stsc") { mSampleToChunkBox.parseBox(subBitstr); } else if (boxType == "stss") { mSyncSampleBox = std::make_shared<SyncSampleBox>(); mSyncSampleBox->parseBox(subBitstr); } else if (boxType == "sgpd") { auto sgdb = new SampleGroupDescriptionBox; sgdb->parseBox(subBitstr); mSampleGroupDescriptionBox.reset(sgdb); } else if (boxType == "sbgp") { SampleToGroupBox sampleToGroupBox; sampleToGroupBox.parseBox(subBitstr); mSampleToGroupBox.push_back(move(sampleToGroupBox)); } else if (boxType == "cslg") { mCompositionToDecodeBox = std::make_shared<CompositionToDecodeBox>(); mCompositionToDecodeBox->parseBox(subBitstr); } else if (boxType == "ctts") { mCompositionOffsetBox = std::make_shared<CompositionOffsetBox>(); mCompositionOffsetBox->parseBox(subBitstr); } else { logWarning() << "Skipping unknown box of type '" << boxType << "' inside SampleTableBox" << endl; } } // We need to update stsc decoded presentation of chunk entries. mSampleToChunkBox.decodeEntries(mChunkOffsetBox.getChunkOffsets().size()); }