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) {