Formalize output struct sent to codecs during encode, in order to get sync sample bools and add more data in the future
diff --git a/src/write.c b/src/write.c
index c370d8c..67aec96 100644
--- a/src/write.c
+++ b/src/write.c
@@ -33,6 +33,33 @@
static avifResult avifEncoderWriteTracks(avifEncoder * encoder, avifRWData * output);
// ---------------------------------------------------------------------------
+// avifCodecEncodeOutput
+
+avifCodecEncodeOutput * avifCodecEncodeOutputCreate(void)
+{
+ avifCodecEncodeOutput * encodeOutput = (avifCodecEncodeOutput *)avifAlloc(sizeof(avifCodecEncodeOutput));
+ memset(encodeOutput, 0, sizeof(avifCodecEncodeOutput));
+ avifArrayCreate(&encodeOutput->samples, sizeof(avifEncodeSample), 1);
+ return encodeOutput;
+}
+
+void avifCodecEncodeOutputAddSample(avifCodecEncodeOutput * encodeOutput, const uint8_t * data, size_t len, avifBool sync)
+{
+ avifEncodeSample * sample = (avifEncodeSample *)avifArrayPushPtr(&encodeOutput->samples);
+ avifRWDataSet(&sample->data, data, len);
+ sample->sync = sync;
+}
+
+void avifCodecEncodeOutputDestroy(avifCodecEncodeOutput * encodeOutput)
+{
+ for (uint32_t sampleIndex = 0; sampleIndex < encodeOutput->samples.count; ++sampleIndex) {
+ avifRWDataFree(&encodeOutput->samples.sample[sampleIndex].data);
+ }
+ avifArrayDestroy(&encodeOutput->samples);
+ avifFree(encodeOutput);
+}
+
+// ---------------------------------------------------------------------------
// avifEncoderItem
// one "item" worth for encoder
@@ -40,9 +67,9 @@
{
uint16_t id;
uint8_t type[4];
- avifCodec * codec; // only present on type==av01
- avifRWDataArray samples; // AV1 sample data for image sequences
- avifRWData content; // OBU data on av01 items-based image, metadata payload for Exif/XMP
+ avifCodec * codec; // only present on type==av01
+ avifCodecEncodeOutput * encodeOutput; // AV1 sample data for image sequences
+ avifRWData content; // OBU data on av01 items-based image, metadata payload for Exif/XMP
avifBool alpha;
const char * infeName;
@@ -89,7 +116,7 @@
memcpy(item->type, type, sizeof(item->type));
item->infeName = infeName;
item->infeNameSize = infeNameSize;
- avifArrayCreate(&item->samples, sizeof(avifRWData), 1);
+ item->encodeOutput = avifCodecEncodeOutputCreate();
return item;
}
@@ -100,10 +127,7 @@
if (item->codec) {
avifCodecDestroy(item->codec);
}
- for (uint32_t sampleIndex = 0; sampleIndex < item->samples.count; ++sampleIndex) {
- avifRWDataFree(&item->samples.raw[sampleIndex]);
- }
- avifArrayDestroy(&item->samples);
+ avifCodecEncodeOutputDestroy(item->encodeOutput);
avifRWDataFree(&item->content);
}
avifImageDestroy(data->imageMetadata);
@@ -248,14 +272,9 @@
for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
avifEncoderItem * item = &encoder->data->items.item[itemIndex];
if (item->codec) {
- avifRWData tmpSampleData = AVIF_DATA_EMPTY;
- if (!item->codec->encodeImage(item->codec, image, encoder, item->alpha, &tmpSampleData)) {
+ if (!item->codec->encodeImage(item->codec, image, encoder, item->alpha, item->encodeOutput)) {
return item->alpha ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
}
- if (tmpSampleData.data && tmpSampleData.size) {
- avifRWData * sampleData = (avifRWData *)avifArrayPushPtr(&item->samples);
- memcpy(sampleData, &tmpSampleData, sizeof(avifRWData));
- }
}
}
@@ -275,22 +294,17 @@
for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
avifEncoderItem * item = &encoder->data->items.item[itemIndex];
if (item->codec) {
- avifRWData tmpSampleData = AVIF_DATA_EMPTY;
- if (!item->codec->encodeFinish(item->codec, &tmpSampleData)) {
+ if (!item->codec->encodeFinish(item->codec, item->encodeOutput)) {
return item->alpha ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
}
- if (tmpSampleData.data && tmpSampleData.size) {
- avifRWData * sampleData = (avifRWData *)avifArrayPushPtr(&item->samples);
- memcpy(sampleData, &tmpSampleData, sizeof(avifRWData));
- }
- if (item->samples.count != encoder->data->receivedFrameCount) {
+ if (item->encodeOutput->samples.count != encoder->data->receivedFrameCount) {
return item->alpha ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
}
size_t obuSize = 0;
- for (uint32_t sampleIndex = 0; sampleIndex < item->samples.count; ++sampleIndex) {
- obuSize += item->samples.raw[sampleIndex].size;
+ for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
+ obuSize += item->encodeOutput->samples.sample[sampleIndex].data.size;
}
if (item->alpha) {
encoder->ioStats.alphaOBUSize = obuSize;
@@ -298,12 +312,12 @@
encoder->ioStats.colorOBUSize = obuSize;
}
- if (item->samples.count == 1) {
+ if (item->encodeOutput->samples.count == 1) {
// Detected a single image (non-sequence). Hand over the only sample to item->content
// so that the image is encoded with items instead of tracks.
- memcpy(&item->content, &item->samples.raw[0], sizeof(avifRWData));
- memset(&item->samples.raw[0], 0, sizeof(avifRWData));
- item->samples.count = 0;
+ memcpy(&item->content, &item->encodeOutput->samples.sample[0].data, sizeof(avifRWData));
+ memset(&item->encodeOutput->samples.sample[0].data, 0, sizeof(avifRWData));
+ item->encodeOutput->samples.count = 0;
}
}
}