Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avidec: output all frames of animations when passed --index all #2670

Merged
merged 3 commits into from
Mar 6, 2025

Conversation

maryla-uc
Copy link
Collaborator

@maryla-uc maryla-uc commented Mar 5, 2025

Also refactor avifdec.c to remove duplication between --info mode and normal mode.

#2634

`avifdec image.avif out.png` will write `out.png` containing the first frame as before,
and `out-xxx.png` files, one for each frame, including `out-000.png` containing
the first frame, which is therefore written twice.

If this behavior is not desired, `--index N` can still be used to specify the frame to decode.

Refactor avifdec.c to remove duplication between --info mode and normal mode.

AOMediaCodec#2634
@maryla-uc maryla-uc force-pushed the decanim branch 2 times, most recently from 4e7a476 to a660360 Compare March 5, 2025 15:56
By default, only the first frame is decoded. --index all must be used
explicitly to decode all frames. In that case, the first frame is no longer
written twice, only the -xxx files are written.
Use ten padding zeros for the frame number, to accomodate the max value of an int32.
A fixed number of leading zeros is easier for scripts to deal with.
@maryla-uc maryla-uc changed the title avidec: output all frames of animations by default avidec: output all frames of animations when passed --index all Mar 5, 2025
@maryla-uc maryla-uc requested a review from y-guyon March 5, 2025 16:27
Copy link
Collaborator

@y-guyon y-guyon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding the feature!

apps/avifdec.c Outdated
if (decodeAllFrames) {
result = AVIF_RESULT_OK;
} else {
fprintf(stderr, "ERROR: Frame at index %d requested but the file does not contain enough frames\n", frameIndex);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decoder->imageCount could be mentioned in this error

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I didn't add it originally was because in my understanding, we don't know if that numer matches the actual number of frames. But you're right that it's useful information in most cases.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code it seems to be equal to the number of track samples. I have no idea if that is equal to the number of frames in an AVIF image sequence.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that in theory they should be the same, but the actual movie data might end up having a different number of frames if non compliant? In --info mode we print "(XXX expected frames)" before actually decoding the frames. But this is just a corner case.

@maryla-uc
Copy link
Collaborator Author

Thanks for the thorough review!

@maryla-uc maryla-uc merged commit ad49114 into AOMediaCodec:main Mar 6, 2025
19 checks passed
@@ -38,7 +39,7 @@ static void syntax(void)
printf(" -u,--upsampling U : Chroma upsampling (for 420/422). One of 'automatic' (default), 'fastest', 'best', 'nearest', or 'bilinear'\n");
printf(" -r,--raw-color : Output raw RGB values instead of multiplying by alpha when saving to opaque formats\n");
printf(" (JPEG only; not applicable to y4m)\n");
printf(" --index I : When decoding an image sequence or progressive image, specify which frame index to decode (Default: 0)\n");
printf(" --index I : When decoding an image sequence or progressive image, specify which frame index to decode, where the first frame has index 0, or 'all' to decode all frames. (Default: 0)\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the changelog?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I forgot (again)

fprintf(stderr, "Warning: metadata dropped when saving to y4m.\n");
}
return y4mWrite(outputFilename, image);
} else if (outputFormat == AVIF_APP_FILE_FORMAT_JPEG) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elses after returns can be avoided

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can but I'm not sure it makes the code inhrently better? It's a code style preference, and there's nothing in the styleguide about this AFAIK. I prefer it this way, it's more compact and I find it clearer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as things are consistent. You're right, it's not in the style guide, but a clang-tidy warning.

// This cannot fail.
result = avifImageSetProfileICC(decoder->image, NULL, 0);
assert(result == AVIF_RESULT_OK);
const int isSequence = decoder->imageCount > 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avifBool?

char frameFilename[1024];
int res = snprintf(frameFilename,
sizeof(frameFilename),
"%.*s-%010d.%.*s",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ffmpeg allows for a format string like %03d in the input and output filenames, but this would require a little more validation. You could shorten this based on the max number of frames if that's available, but otherwise this seems OK.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could shorten this based on the max number of frames if that's available, but otherwise this seems OK.

I did that at first but we decided that having a predictible number of zeros (and therefore filename) would be easier for scripts. And that we could implement the "%03d" syntax if someone ever asked for it, but it really seems like a "nice to have".

jzern added a commit to jzern/libavif that referenced this pull request Mar 8, 2025
* main: (53 commits)
  Fix reading gray/color ICC profile from color/gray image in apps (AOMediaCodec#2675)
  Revert "Use SVT_LOG=0 in avifsvttest for SVT-AV1 3.0.0 (AOMediaCodec#2668)" (AOMediaCodec#2674)
  Fix monochrome ICC profile error message in apps (AOMediaCodec#2673)
  Add missing changelog for `avifdec --index all` (AOMediaCodec#2672)
  Specify target platform version in binary artifacts (AOMediaCodec#2652)
  avidec: output all frames of animations when passed `--index all` (AOMediaCodec#2670)
  Do not allow keeping the ICC when converting from RGB to gray (AOMediaCodec#2669)
  Update CHANGELOG (AOMediaCodec#2666)
  Use SVT_LOG=0 in avifsvttest for SVT-AV1 3.0.0 (AOMediaCodec#2668)
  read.c: fix empty struct initializers (AOMediaCodec#2661)
  avifutil.c: fix avifQueryCPUCount() empty param list (AOMediaCodec#2662)
  Add libyuv dependency to the README.md (AOMediaCodec#2664)
  fix: patch libyuv CMakeLists for compatibility with gcc 10 (AOMediaCodec#2660)
  Use default for tensorflow with libavm (AOMediaCodec#2624)
  Bump some Rust dependencies (AOMediaCodec#2658)
  Use C99 syntax to initialize avifFileType struct (AOMediaCodec#2657)
  Bump the github-actions group with 3 updates
  libargparse: use a git patch file instead of sed command (AOMediaCodec#2654)
  y4m: Remove some repeated code
  Remove fully static instructions (AOMediaCodec#2649)
  ...
y-guyon pushed a commit to y-guyon/libavif that referenced this pull request Mar 14, 2025
…MediaCodec#2670)

Also refactor avifdec.c to remove duplication between --info mode and normal mode.
y-guyon pushed a commit to y-guyon/libavif that referenced this pull request Mar 14, 2025
…MediaCodec#2670)

Also refactor avifdec.c to remove duplication between --info mode and normal mode.
y-guyon pushed a commit that referenced this pull request Mar 16, 2025
)

Also refactor avifdec.c to remove duplication between --info mode and normal mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants