void writeImageGrid(const ImageGrid& grid, BitStream& output) { bool write32BitFields = false; output.write8Bits(0); // version = 0 if ((grid.outputWidth > std::numeric_limits<std::uint16_t>::max()) && (grid.outputHeight > std::numeric_limits<std::uint16_t>::max())) { write32BitFields = true; } output.write8Bits(write32BitFields); // flags output.write8Bits(grid.rowsMinusOne); output.write8Bits(grid.columnsMinusOne); if (write32BitFields) { output.write32Bits(grid.outputWidth); output.write32Bits(grid.outputHeight); } else { output.write16Bits(static_cast<std::uint16_t>(grid.outputWidth)); output.write16Bits(static_cast<std::uint16_t>(grid.outputHeight)); } }
void writeImageOverlay(const ImageOverlay& iovl, BitStream& output) { bool write32BitFields = false; if ((iovl.outputWidth > std::numeric_limits<std::uint16_t>::max()) && (iovl.outputHeight > std::numeric_limits<std::uint16_t>::max())) { write32BitFields = true; } for (const auto& entry : iovl.offsets) { if ((entry.horizontalOffset > std::numeric_limits<std::int16_t>::max()) || (entry.verticalOffset > std::numeric_limits<std::int16_t>::max()) || (entry.horizontalOffset < std::numeric_limits<std::int16_t>::min()) || (entry.verticalOffset < std::numeric_limits<std::int16_t>::min())) { write32BitFields = true; break; } } output.write8Bits(0); // version output.write8Bits(write32BitFields); // flags output.write16Bits(iovl.canvasFillValueR); output.write16Bits(iovl.canvasFillValueG); output.write16Bits(iovl.canvasFillValueB); output.write16Bits(iovl.canvasFillValueA); if (write32BitFields) { output.write32Bits(iovl.outputWidth); output.write32Bits(iovl.outputHeight); } else { output.write16Bits(static_cast<std::uint16_t>(iovl.outputWidth)); output.write16Bits(static_cast<std::uint16_t>(iovl.outputHeight)); } for (const auto& entry : iovl.offsets) { if (write32BitFields) { output.write32Bits(static_cast<std::uint32_t>(entry.horizontalOffset)); output.write32Bits(static_cast<std::uint32_t>(entry.verticalOffset)); } else { output.write16Bits(static_cast<std::uint16_t>(entry.horizontalOffset)); output.write16Bits(static_cast<std::uint16_t>(entry.verticalOffset)); } } }
void ElementaryStreamDescriptorBox::writeBox(BitStream& bitstr) const { writeFullBoxHeader(bitstr); bitstr.write8Bits(mES_Descriptor.ES_DescrTag); bool esSizeConverged = false; std::uint64_t esSizeSize; std::uint32_t esDescriptorSize = mES_Descriptor.size; BitStream esBitstr; /* Write the whole stuff, then figure out if we wrote the correct * size for it (we allos mES_Descriptor to be incorrect); rewrite * everything with the correct size. However, this may increase * the size due to bigger size having been written and thus moving * the remaining of the data forward, so we may need to loop even * thrice. */ while (!esSizeConverged) { esBitstr.clear(); esSizeSize = writeSize(esBitstr, esDescriptorSize); esBitstr.write16Bits(mES_Descriptor.ES_ID); esBitstr.write8Bits(mES_Descriptor.flags); if (mES_Descriptor.flags & 0x80) // streamDependenceFlag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { esBitstr.write16Bits(mES_Descriptor.dependsOn_ES_ID); } if (mES_Descriptor.flags & 0x40) // URL_Flag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { esBitstr.write8Bits(mES_Descriptor.URLlength); if (mES_Descriptor.URLlength) { esBitstr.writeString(mES_Descriptor.URLstring); } } if (mES_Descriptor.flags & 0x20) // OCRstreamFlag as defined in 7.2.6.5.1 of ISO/IEC 14486-1:2010(E) { esBitstr.write16Bits(mES_Descriptor.OCR_ES_Id); } esBitstr.write8Bits(mES_Descriptor.decConfigDescr.DecoderConfigDescrTag); BitStream decConfigBitstr; std::uint64_t decConfigSize = mES_Descriptor.decConfigDescr.size; std::uint64_t decConfigSizeSize; bool decConfigSizeConverged = false; while (!decConfigSizeConverged) { decConfigBitstr.clear(); decConfigSizeSize = writeSize(decConfigBitstr, static_cast<uint32_t>(decConfigSize)); decConfigBitstr.write8Bits(mES_Descriptor.decConfigDescr.objectTypeIndication); decConfigBitstr.write8Bits((mES_Descriptor.decConfigDescr.streamType << 2) | 0x01); decConfigBitstr.write24Bits(mES_Descriptor.decConfigDescr.bufferSizeDB); decConfigBitstr.write32Bits(mES_Descriptor.decConfigDescr.maxBitrate); decConfigBitstr.write32Bits(mES_Descriptor.decConfigDescr.avgBitrate); if (mES_Descriptor.decConfigDescr.decSpecificInfo.DecSpecificInfoTag == 5) { writeDecoderSpecificInfo(decConfigBitstr, mES_Descriptor.decConfigDescr.decSpecificInfo); } for (const auto& decSpecificInfo : mOtherDecSpecificInfo) { writeDecoderSpecificInfo(decConfigBitstr, decSpecificInfo); } decConfigSizeConverged = decConfigBitstr.getSize() == std::uint64_t(decConfigSize) + decConfigSizeSize; if (!decConfigSizeConverged) { decConfigSize = decConfigBitstr.getSize() - decConfigSizeSize; } } esBitstr.writeBitStream(decConfigBitstr); esSizeConverged = esBitstr.getSize() == std::uint64_t(esDescriptorSize) + esSizeSize; if (!esSizeConverged) { esDescriptorSize = std::uint32_t(esBitstr.getSize() - esSizeSize); } } bitstr.writeBitStream(esBitstr); updateSize(bitstr); }