| 7098 | } |
| 7099 | |
| 7100 | avifResult avifDecoderNthImage(avifDecoder * decoder, uint32_t frameIndex) |
| 7101 | { |
| 7102 | avifDiagnosticsClearError(&decoder->diag); |
| 7103 | |
| 7104 | if (!decoder->data) { |
| 7105 | // Nothing has been parsed yet |
| 7106 | return AVIF_RESULT_NO_CONTENT; |
| 7107 | } |
| 7108 | |
| 7109 | if ((frameIndex > INT_MAX) || ((int)frameIndex >= decoder->imageCount)) { |
| 7110 | // Impossible index |
| 7111 | return AVIF_RESULT_NO_IMAGES_REMAINING; |
| 7112 | } |
| 7113 | |
| 7114 | int requestedIndex = (int)frameIndex; |
| 7115 | if (requestedIndex == (decoder->imageIndex + 1)) { |
| 7116 | // It's just the next image (already partially decoded or not at all), nothing special here |
| 7117 | return avifDecoderNextImage(decoder); |
| 7118 | } |
| 7119 | |
| 7120 | if (requestedIndex == decoder->imageIndex) { |
| 7121 | if (avifDecoderDataFrameFullyDecoded(decoder->data)) { |
| 7122 | // The current fully decoded image (decoder->imageIndex) is requested, nothing to do |
| 7123 | return AVIF_RESULT_OK; |
| 7124 | } |
| 7125 | // The next image (decoder->imageIndex + 1) is partially decoded but |
| 7126 | // the previous image (decoder->imageIndex) is requested. |
| 7127 | // Fall through to resetting the decoder data and start decoding from |
| 7128 | // the nearest key frame. |
| 7129 | } |
| 7130 | |
| 7131 | int nearestKeyFrame = (int)avifDecoderNearestKeyframe(decoder, frameIndex); |
| 7132 | if ((nearestKeyFrame > (decoder->imageIndex + 1)) || (requestedIndex <= decoder->imageIndex)) { |
| 7133 | // If we get here, we need to start decoding from the nearest key frame. |
| 7134 | // So discard the unused decoder state and its previous frames. This |
| 7135 | // will force the setup of new AV1 decoder (avifCodec) instances in |
| 7136 | // avifDecoderNextImage(). |
| 7137 | decoder->imageIndex = nearestKeyFrame - 1; // prepare to read nearest keyframe |
| 7138 | avifDecoderDataResetCodec(decoder->data); |
| 7139 | } |
| 7140 | for (;;) { |
| 7141 | avifResult result = avifDecoderNextImage(decoder); |
| 7142 | if (result != AVIF_RESULT_OK) { |
| 7143 | return result; |
| 7144 | } |
| 7145 | |
| 7146 | if (requestedIndex == decoder->imageIndex) { |
| 7147 | break; |
| 7148 | } |
| 7149 | } |
| 7150 | return AVIF_RESULT_OK; |
| 7151 | } |
| 7152 | |
| 7153 | avifBool avifDecoderIsKeyframe(const avifDecoder * decoder, uint32_t frameIndex) |
| 7154 | { |