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

Treat avifenc --stdin as regular file input arg #2574

Merged
merged 4 commits into from
Jan 27, 2025

Conversation

y-guyon
Copy link
Collaborator

@y-guyon y-guyon commented Jan 17, 2025

Consider --stdin to be a positional argument as if it was the name of the y4m file path containing the y4m standard input contents.

Fixes #2572.

@y-guyon y-guyon force-pushed the stdin branch 9 times, most recently from 55e529c to 0d27263 Compare January 17, 2025 12:19
Consider --stdin to be a positional argument as if it was the name of
the y4m file path containing the y4m standard input contents.
@wantehchang
Copy link
Collaborator

@tongyuantongyu Yuan: Could you also take a look at this pull request if you have time? Thanks.

@@ -57,6 +57,7 @@ The changes are relative to the previous release, unless the baseline is specifi
avifCropRectFromCleanApertureBox() and avifCleanApertureBoxFromCropRect().
* Ignore descriptive properties associated after transformative ones.
* Reject non-essential transformative properties.
* Treat avifenc --stdin as a regular positional file path argument.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I haven't read the pull request. I have a question: where is the position of this fictitious file path argument?

Here is my expectation:

  • If the output file path is specified without using the -o option, the fictitious input file path argument is right before the output file path argument.
  • If the -o option is used, the fictitious input file path argument is at the end of the command line.

Is this what you implemented?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have now read the pull request. What you implemented is not exactly the same as what I expected in how the options with update suffix (i.e., pendingSettings) are handled. This is perfectly fine because there are several reasonable ways to handle this. Since people's expectations may be different from what is implemented, it would be good to document somewhere how we handle the options with update suffix when --stdin is specified.

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 makes no sense to use :u with --stdin because no other input is allowed. So how :u behaves with --stdin does not matter, as long as nothing is silently ignored.

I find it simpler to understand and to implement if --stdin can just be replaced with /path/to/in.y4m with identical behavior. I do not think it has to be mentioned in --help because there is no other input file name allowed, so it does not really matter where --stdin is.

Happy to revisit if needed though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that it's easier to understand if --stdin can be replaced with /path/to/in.y4m with identical behavior. This simple rule is only mentioned in the changelog. It would be good to document this in the help message.

Also, this rule needs to make an exception for the avifenc out.avif --stdin case. The exception might be worth documenting.

Copy link
Collaborator Author

@y-guyon y-guyon Jan 27, 2025

Choose a reason for hiding this comment

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

It would be good to document this in the help message.

I disagree. It does not provide any benefit as long as "No other input is allowed": since there is an ovious single input and a single output, the order of all arguments should not matter. The same behavior as if replaced by a file path is somewhat expected (besides the exception you mentioned), and if it is not the case, it does not really matter because there is a single input and a single output.
So describing that in the help message would just bring confusion in my opinion.

@tongyuantongyu
Copy link
Contributor

@tongyuantongyu Yuan: Could you also take a look at this pull request if you have time? Thanks.

LGTM, though I have a small question: while we are there, can we support - as an alias of --stdin?

Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks a lot for the fix.

@tongyuantongyu Yuan: Thank you for the review!

@@ -57,6 +57,7 @@ The changes are relative to the previous release, unless the baseline is specifi
avifCropRectFromCleanApertureBox() and avifCleanApertureBoxFromCropRect().
* Ignore descriptive properties associated after transformative ones.
* Reject non-essential transformative properties.
* Treat avifenc --stdin as a regular positional file path argument.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have now read the pull request. What you implemented is not exactly the same as what I expected in how the options with update suffix (i.e., pendingSettings) are handled. This is perfectly fine because there are several reasonable ways to handle this. Since people's expectations may be different from what is implemented, it would be good to document somewhere how we handle the options with update suffix when --stdin is specified.

apps/avifenc.c Outdated
@@ -215,7 +222,7 @@ static void syntaxLong(void)
printf(" For JPEG, auto honors the JPEG's internal format, if possible. For grayscale PNG, auto defaults to 400. For all other cases, auto defaults to 444\n");
printf(" -p,--premultiply : Premultiply color by the alpha channel and signal this in the AVIF\n");
printf(" --sharpyuv : Use sharp RGB to YUV420 conversion (if supported). Ignored for y4m or if output is not 420.\n");
printf(" --stdin : Read y4m frames from stdin instead of files; no input filenames allowed, must set before offering output filename\n");
printf(" --stdin : Read y4m frames from stdin instead of files; no input filenames allowed\n");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just wondering: why is "must set before offering output filename" removed?

The new code allows --stdin to be set after the output filename, so "must set before offering output filename" is incorrect for the new code. Does the original code also allow --stdin to be set after the output filename?

Note: When --stdin is treated as a regular positional file path argument, it seems cleaner if we disallow output.avif ... --stdin. But if the original code allows output.avif ... --stdin, the new code will need to allow it.

Copy link
Collaborator Author

@y-guyon y-guyon Jan 24, 2025

Choose a reason for hiding this comment

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

Just wondering: why is "must set before offering output filename" removed?

Because it is allowed.

The new code allows --stdin to be set after the output filename, so "must set before offering output filename" is incorrect for the new code. Does the original code also allow --stdin to be set after the output filename?

I did not try it but I do not see how it could detect that.
The only place where --stdin is parsed from the command line arguments just flips a boolean:

libavif/apps/avifenc.c

Lines 1475 to 1477 in 7ae69db

} else if (!strcmp(arg, "--stdin")) {
input.useStdin = AVIF_TRUE;
} else if (!strcmp(arg, "-o") || !strcmp(arg, "--output")) {

which is not checked until all other arguments were parsed.

Note: When --stdin is treated as a regular positional file path argument, it seems cleaner if we disallow output.avif ... --stdin. But if the original code allows output.avif ... --stdin, the new code will need to allow it.

I was thinking about these cases:

avifenc --stdin -o out.avif < in.y4m # Explicit
avifenc --stdin    out.avif < in.y4m # Expected
avifenc -o out.avif --stdin < in.y4m # Allowed
avifenc    out.avif --stdin < in.y4m # Why not? It keeps "--stdin" close to "< in.yam".

apps/avifenc.c Outdated Show resolved Hide resolved
apps/avifenc.c Show resolved Hide resolved
apps/avifenc.c Show resolved Hide resolved
apps/avifenc.c Show resolved Hide resolved
apps/avifenc.c Outdated Show resolved Hide resolved
apps/avifenc.c Outdated Show resolved Hide resolved
tests/test_cmd.sh Show resolved Hide resolved
tests/test_cmd_stdin.sh Outdated Show resolved Hide resolved
@y-guyon y-guyon merged commit 46a46aa into AOMediaCodec:main Jan 27, 2025
35 checks passed
@y-guyon y-guyon deleted the stdin branch January 27, 2025 12:16
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.

Multiple options are ignored with --stdin ("Trailing options with update suffix has no effect") using --output
3 participants