| 433 | static avifBool avmCodecEncodeFinish(avifCodec * codec, avifCodecEncodeOutput * output); |
| 434 | |
| 435 | static avifResult avmCodecEncodeImage(avifCodec * codec, |
| 436 | avifEncoder * encoder, |
| 437 | const avifImage * image, |
| 438 | avifBool alpha, |
| 439 | int tileRowsLog2, |
| 440 | int tileColsLog2, |
| 441 | int quality, |
| 442 | avifEncoderChanges encoderChanges, |
| 443 | avifBool disableLaggedOutput, |
| 444 | avifAddImageFlags addImageFlags, |
| 445 | avifCodecEncodeOutput * output) |
| 446 | { |
| 447 | struct avm_codec_enc_cfg * cfg = &codec->internal->cfg; |
| 448 | avifBool quantizerUpdated = AVIF_FALSE; |
| 449 | const int quantizer = avmQualityToQuantizer(quality, image->depth); |
| 450 | |
| 451 | // For encoder->scalingMode.horizontal and encoder->scalingMode.vertical to take effect in AV2 |
| 452 | // encoder, config should be applied for each frame, so we don't care about changes on these |
| 453 | // two fields. |
| 454 | encoderChanges &= ~AVIF_ENCODER_CHANGE_SCALING_MODE; |
| 455 | |
| 456 | if (!codec->internal->encoderInitialized) { |
| 457 | int avmCpuUsed = -1; |
| 458 | if (encoder->speed != AVIF_SPEED_DEFAULT) { |
| 459 | avmCpuUsed = AVIF_CLAMP(encoder->speed, 0, 9); |
| 460 | } |
| 461 | |
| 462 | codec->internal->avmFormat = avifImageCalcAVMFmt(image, alpha); |
| 463 | if (codec->internal->avmFormat == AVM_IMG_FMT_NONE) { |
| 464 | return AVIF_RESULT_UNKNOWN_ERROR; |
| 465 | } |
| 466 | |
| 467 | avifGetPixelFormatInfo(image->yuvFormat, &codec->internal->formatInfo); |
| 468 | |
| 469 | avm_codec_iface_t * encoderInterface = avm_codec_av2_cx(); |
| 470 | avm_codec_err_t err = avm_codec_enc_config_default(encoderInterface, cfg, AVM_USAGE_GOOD_QUALITY); |
| 471 | if (err != AVM_CODEC_OK) { |
| 472 | avifDiagnosticsPrintf(codec->diag, "avm_codec_enc_config_default() failed: %s", avm_codec_err_to_string(err)); |
| 473 | return AVIF_RESULT_UNKNOWN_ERROR; |
| 474 | } |
| 475 | |
| 476 | // avm's default is AVM_VBR. Change the default to AVM_Q since we don't need to hit a certain target bit rate. |
| 477 | // It's easier to control the worst quality in Q mode. |
| 478 | cfg->rc_end_usage = AVM_Q; |
| 479 | |
| 480 | // Profile 0. 8-bit and 10-bit 4:2:0 and 4:0:0 only. |
| 481 | // Profile 1. 8-bit and 10-bit 4:4:4 |
| 482 | // Profile 2. 8-bit and 10-bit 4:2:2 |
| 483 | // 12-bit 4:0:0, 4:2:0, 4:2:2 and 4:4:4 |
| 484 | uint8_t seqProfile = 0; |
| 485 | if (image->depth != 8 && image->depth != 10) { |
| 486 | avifDiagnosticsPrintf(codec->diag, "%d-bit is not supported in AV2 encoder.", image->depth); |
| 487 | return AVIF_RESULT_INVALID_ARGUMENT; |
| 488 | } |
| 489 | // Based on AV2 spec Section A.3 Profiles. |
| 490 | if (alpha) { |
| 491 | seqProfile = 1; // Main_420_10_IP1 |
| 492 | } else { |
nothing calls this directly
no test coverage detected