Added avifEncoder and avifDecoder to match avifImage's pattern and allow for easier future parameterization
diff --git a/src/codec_aom.c b/src/codec_aom.c
index e05c186..97783bd 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -197,11 +197,16 @@
return fmt;
}
-static avifBool encodeOBU(avifImage * image, avifBool alphaOnly, int numThreads, int quality, avifRawData * outputOBU, avifCodecConfigurationBox * outputConfig)
+static avifBool encodeOBU(avifImage * image, avifBool alphaOnly, avifEncoder * encoder, avifRawData * outputOBU, avifCodecConfigurationBox * outputConfig)
{
avifBool success = AVIF_FALSE;
aom_codec_iface_t * encoder_interface = aom_codec_av1_cx();
- aom_codec_ctx_t encoder;
+ aom_codec_ctx_t aomEncoder;
+
+ int quality = encoder->quality;
+ if (alphaOnly) {
+ quality = AVIF_BEST_QUALITY;
+ }
memset(outputConfig, 0, sizeof(avifCodecConfigurationBox));
@@ -247,8 +252,8 @@
cfg.g_input_bit_depth = image->depth;
cfg.g_w = image->width;
cfg.g_h = image->height;
- if (numThreads > 1) {
- cfg.g_threads = numThreads;
+ if (encoder->maxThreads > 1) {
+ cfg.g_threads = encoder->maxThreads;
}
// TODO: Choose correct value from Annex A.3 table: https://aomediacodec.github.io/av1-spec/av1-spec.pdf
@@ -286,13 +291,13 @@
if (image->depth > 8) {
encoderFlags |= AOM_CODEC_USE_HIGHBITDEPTH;
}
- aom_codec_enc_init(&encoder, encoder_interface, &cfg, encoderFlags);
+ aom_codec_enc_init(&aomEncoder, encoder_interface, &cfg, encoderFlags);
if (lossless) {
- aom_codec_control(&encoder, AV1E_SET_LOSSLESS, 1);
+ aom_codec_control(&aomEncoder, AV1E_SET_LOSSLESS, 1);
}
- if (numThreads > 1) {
- aom_codec_control(&encoder, AV1E_SET_ROW_MT, 1);
+ if (encoder->maxThreads > 1) {
+ aom_codec_control(&aomEncoder, AV1E_SET_ROW_MT, 1);
}
int uvHeight = image->height >> yShift;
@@ -300,7 +305,7 @@
if (alphaOnly) {
aomImage->range = AOM_CR_FULL_RANGE; // Alpha is always full range
- aom_codec_control(&encoder, AV1E_SET_COLOR_RANGE, aomImage->range);
+ aom_codec_control(&aomEncoder, AV1E_SET_COLOR_RANGE, aomImage->range);
aomImage->monochrome = 1;
for (int j = 0; j < image->height; ++j) {
uint8_t * srcAlphaRow = &image->alphaPlane[j * image->alphaRowBytes];
@@ -315,7 +320,7 @@
}
} else {
aomImage->range = (image->yuvRange == AVIF_RANGE_FULL) ? AOM_CR_FULL_RANGE : AOM_CR_STUDIO_RANGE;
- aom_codec_control(&encoder, AV1E_SET_COLOR_RANGE, aomImage->range);
+ aom_codec_control(&aomEncoder, AV1E_SET_COLOR_RANGE, aomImage->range);
for (int yuvPlane = 0; yuvPlane < 3; ++yuvPlane) {
int aomPlaneIndex = yuvPlane;
int planeHeight = image->height;
@@ -335,12 +340,12 @@
}
}
- aom_codec_encode(&encoder, aomImage, 0, 1, 0);
- aom_codec_encode(&encoder, NULL, 0, 1, 0); // flush
+ aom_codec_encode(&aomEncoder, aomImage, 0, 1, 0);
+ aom_codec_encode(&aomEncoder, NULL, 0, 1, 0); // flush
aom_codec_iter_t iter = NULL;
for (;;) {
- const aom_codec_cx_pkt_t * pkt = aom_codec_get_cx_data(&encoder, &iter);
+ const aom_codec_cx_pkt_t * pkt = aom_codec_get_cx_data(&aomEncoder, &iter);
if (pkt == NULL)
break;
if (pkt->kind == AOM_CODEC_CX_FRAME_PKT) {
@@ -351,19 +356,19 @@
}
aom_img_free(aomImage);
- aom_codec_destroy(&encoder);
+ aom_codec_destroy(&aomEncoder);
return success;
}
-avifResult avifCodecEncodeImage(avifCodec * codec, avifImage * image, int numThreads, int colorQuality, avifRawData * colorOBU, avifRawData * alphaOBU)
+avifResult avifCodecEncodeImage(avifCodec * codec, avifImage * image, avifEncoder * encoder, avifRawData * colorOBU, avifRawData * alphaOBU)
{
if (colorOBU) {
- if (!encodeOBU(image, AVIF_FALSE, numThreads, colorQuality, colorOBU, &codec->internal->configs[AVIF_CODEC_PLANES_COLOR])) {
+ if (!encodeOBU(image, AVIF_FALSE, encoder, colorOBU, &codec->internal->configs[AVIF_CODEC_PLANES_COLOR])) {
return AVIF_RESULT_ENCODE_COLOR_FAILED;
}
}
if (alphaOBU) {
- if (!encodeOBU(image, AVIF_TRUE, numThreads, AVIF_BEST_QUALITY, alphaOBU, &codec->internal->configs[AVIF_CODEC_PLANES_ALPHA])) {
+ if (!encodeOBU(image, AVIF_TRUE, encoder, alphaOBU, &codec->internal->configs[AVIF_CODEC_PLANES_ALPHA])) {
return AVIF_RESULT_ENCODE_COLOR_FAILED;
}
}
diff --git a/src/read.c b/src/read.c
index 831af8f..a40bc6c 100644
--- a/src/read.c
+++ b/src/read.c
@@ -538,7 +538,19 @@
// ---------------------------------------------------------------------------
-avifResult avifImageRead(avifImage * image, avifRawData * input)
+avifDecoder * avifDecoderCreate(void)
+{
+ avifDecoder * decoder = (avifDecoder *)avifAlloc(sizeof(avifDecoder));
+ memset(decoder, 0, sizeof(avifDecoder));
+ return decoder;
+}
+
+void avifDecoderDestroy(avifDecoder * decoder)
+{
+ avifFree(decoder);
+}
+
+avifResult avifDecoderRead(avifDecoder * decoder, avifImage * image, avifRawData * input)
{
avifCodec * codec = NULL;
@@ -705,7 +717,7 @@
avifCodecDestroy(codec);
}
- image->ioStats.colorOBUSize = colorOBU.size;
- image->ioStats.alphaOBUSize = alphaOBU.size;
+ decoder->ioStats.colorOBUSize = colorOBU.size;
+ decoder->ioStats.alphaOBUSize = alphaOBU.size;
return AVIF_RESULT_OK;
}
diff --git a/src/write.c b/src/write.c
index 0d9eeab..354ef1a 100644
--- a/src/write.c
+++ b/src/write.c
@@ -23,7 +23,21 @@
static avifBool avifImageIsOpaque(avifImage * image);
static void writeConfigBox(avifStream * s, avifCodecConfigurationBox * cfg);
-avifResult avifImageWrite(avifImage * image, avifRawData * output, int numThreads, int quality)
+avifEncoder * avifEncoderCreate(void)
+{
+ avifEncoder * encoder = (avifEncoder *)avifAlloc(sizeof(avifEncoder));
+ memset(encoder, 0, sizeof(avifEncoder));
+ encoder->maxThreads = 1;
+ encoder->quality = AVIF_BEST_QUALITY;
+ return encoder;
+}
+
+void avifEncoderDestroy(avifEncoder * encoder)
+{
+ avifFree(encoder);
+}
+
+avifResult avifEncoderWrite(avifEncoder * encoder, avifImage * image, avifRawData * output)
{
if ((image->depth != 8) && (image->depth != 10) && (image->depth != 12)) {
return AVIF_RESULT_UNSUPPORTED_DEPTH;
@@ -67,7 +81,7 @@
alphaOBUPtr = NULL;
}
- avifResult encodeResult = avifCodecEncodeImage(codec, image, numThreads, quality, &colorOBU, alphaOBUPtr);
+ avifResult encodeResult = avifCodecEncodeImage(codec, image, encoder, &colorOBU, alphaOBUPtr);
if (encodeResult != AVIF_RESULT_OK) {
result = encodeResult;
goto writeCleanup;
@@ -319,13 +333,13 @@
// -----------------------------------------------------------------------
// IO stats
- image->ioStats.colorOBUSize = colorOBU.size;
- image->ioStats.alphaOBUSize = alphaOBU.size;
-
- result = AVIF_RESULT_OK;
+ encoder->ioStats.colorOBUSize = colorOBU.size;
+ encoder->ioStats.alphaOBUSize = alphaOBU.size;
// -----------------------------------------------------------------------
- // Cleanup
+ // Set result and cleanup
+
+ result = AVIF_RESULT_OK;
writeCleanup:
if (codec) {