MCPcopy Create free account
hub / github.com/AOMediaCodec/libavif / avifEncoderWriteMediaDataBox

Function avifEncoderWriteMediaDataBox

src/write.c:2179–2332  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2177}
2178
2179static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
2180 avifRWStream * s,
2181 avifEncoderItemReferenceArray * layeredColorItems,
2182 avifEncoderItemReferenceArray * layeredAlphaItems)
2183{
2184 encoder->ioStats.colorOBUSize = 0;
2185 encoder->ioStats.alphaOBUSize = 0;
2186 encoder->data->gainMapSizeBytes = 0;
2187
2188 avifBoxMarker mdat;
2189 AVIF_CHECKRES(avifRWStreamWriteBox(s, "mdat", AVIF_BOX_SIZE_TBD, &mdat));
2190 const size_t mdatStartOffset = avifRWStreamOffset(s);
2191 for (uint32_t itemPasses = 0; itemPasses < 3; ++itemPasses) {
2192 // Use multiple passes to pack in the following order:
2193 // * Pass 0: metadata (Exif/XMP/gain map metadata)
2194 // * Pass 1: alpha, gain map image (AV1)
2195 // * Pass 2: all other item data (AV1 color)
2196 //
2197 // See here for the discussion on alpha coming before color:
2198 // https://github.com/AOMediaCodec/libavif/issues/287
2199 //
2200 // Exif and XMP are packed first as they're required to be fully available
2201 // by avifDecoderParse() before it returns AVIF_RESULT_OK, unless ignoreXMP
2202 // and ignoreExif are enabled.
2203 //
2204 const avifBool metadataPass = (itemPasses == 0);
2205 const avifBool alphaAndGainMapPass = (itemPasses == 1);
2206
2207 for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
2208 avifEncoderItem * item = &encoder->data->items.item[itemIndex];
2209 if ((item->metadataPayload.size == 0) && (item->encodeOutput->samples.count == 0)) {
2210 // this item has nothing for the mdat box
2211 continue;
2212 }
2213 const avifBool isMetadata = !memcmp(item->type, "mime", 4) || !memcmp(item->type, "Exif", 4) ||
2214 !memcmp(item->type, "tmap", 4);
2215 if (metadataPass != isMetadata) {
2216 // only process metadata (XMP/Exif) payloads when metadataPass is true
2217 continue;
2218 }
2219 const avifBool isAlpha = avifIsAlpha(item->itemCategory);
2220 const avifBool isAlphaOrGainMap = isAlpha || item->itemCategory == AVIF_ITEM_GAIN_MAP;
2221 if (alphaAndGainMapPass != isAlphaOrGainMap) {
2222 // only process alpha payloads when alphaPass is true
2223 continue;
2224 }
2225
2226 if ((encoder->extraLayerCount > 0) && (item->encodeOutput->samples.count > 0)) {
2227 // Interleave - Pick out AV1 items and interleave them later.
2228 // We always interleave all AV1 items for layered images.
2229 AVIF_ASSERT_OR_RETURN(item->encodeOutput->samples.count == item->mdatFixups.count);
2230
2231 avifEncoderItemReference * ref =
2232 (avifEncoderItemReference *)avifArrayPush(isAlpha ? layeredAlphaItems : layeredColorItems);
2233 AVIF_CHECKERR(ref != NULL, AVIF_RESULT_OUT_OF_MEMORY);
2234 *ref = item;
2235 continue;
2236 }

Callers 1

avifEncoderFinishFunction · 0.85

Calls 9

avifRWStreamWriteBoxFunction · 0.85
avifRWStreamOffsetFunction · 0.85
avifIsAlphaFunction · 0.85
avifArrayPushFunction · 0.85
avifRWStreamWriteFunction · 0.85
avifRWStreamSetOffsetFunction · 0.85
avifRWStreamWriteU32Function · 0.85
avifRWStreamFinishBoxFunction · 0.85

Tested by

no test coverage detected