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
Support arbitrary SAR anamorphic video #2505
Conversation
d4f02d4
to
45ce98c
Compare
5d5641f
to
c7f399b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be a bug that causes only the first frame to have its render width/height changed.
b418aeb
to
1f86153
Compare
This adds an aspect ratio input parameter to the Rust and C APIs, computes the render size by upscaling one dimension, and codes it in-bitstream, as well as in Y4M output. The default aspect ratio is parsed from Y4M input, or set to 1:1 if absent.
I'm now aware that 0:0 is a "valid" aspect ratio that should map to 1:1, so such samples are to-test and might be rejected with the current state of the branch. |
Thinking more about this, shouldn't it be per-frame? |
I think we can leave that as future work. |
@dwbuiten I moved the parameters to |
@rzumer I was indeed saying it should be per-frame in the API. Aspect ratio may change midstream, and should be supported either via frame properties, or via encoder-reconfig, I believe. |
Then as mentioned earlier I prefer it to be left as future work considering how rare of a use case it is, unless there is already a framework for setting parameters frame by frame (I can't see anything in the |
Maybe this should instead set frame_size_override_flag to 1 on inter frames and take the frame and render dimension values from one of the frames they reference in the ref_frame_idx[] array (The frame_size_with_refs() function defined in Section 5.9.7). That way you'll save 4 bytes per frame header used to code the same render dimension values. |
@jamrial That works as long as frame size is static. We can probably assume it is for now though. |
Afailk, it can also work for non static frame sizes by ensuring a given inter frame references a frame with the exact same values it would otherwise write. If none of the seven potential reference frames share the exact same values, then they are explicitly written instead. |
I see, I'll look into adding that. |
If you'd rather not bother looking at the values for each of the seven reference frame since for now the sizes are fixed, then it's a matter of setting frame_size_override_flag to 1 and implementing frame_size_with_refs() as a single bit found_ref to signal that the first reference frame should be used by the decoder to infer this frame's dimensions. |
After looking into it I don't think this frame_size_override has the same effect as overriding the render_size. Seems to me that frame size is related to the number of luma samples, while render size signals players to rescale the frame when displaying it. Unless this part of the spec is inconsistently written and poorly defined, and the aomdec behaviour matches what you're implying, I'd keep the current implementation. |
No, it doesn't have the same effect. frame_size_override_flag means that either frame dimensions, render dimensions, or both, may be coded in the frame or should be inferred from a reference frame. For this specific case, frame dimensions and render dimensions will be constant for the entire video sequence, so setting both frame_size_override_flag and render_and_frame_size_different to 1 and then taking the first reference frame's dimensions is the same as signaling only render_and_frame_size_different and coding the render dimensions in the frame, except it doesn't use four bytes for it. See the code below
|
I mean, I'm fine with this change but it seems like it should be separate from this PR. Isn't it applicable regardless of render size anyway since we currently assume a static frame size? |
Sure, i can send a PR for it after this one is merged. Also, here's a complex sample where frame dimensions vary between frames (But render dimensions are constant), and uses the frame_size_with_refs() logic to avoid coding the values in the bitstream when a reference frame shares the same values, if you're curious. https://code.videolan.org/videolan/dav1d/uploads/e41cf2423c6ae93e2a0a4fc9ae543730/resize.ivf |
I think it should be doable with an encoder reconfig API, so doing it eoncig level should be OK, I suppose. Color properties are done this way too. |
This adds an aspect ratio input parameter
to the Rust and C APIs, computes the render
size by upscaling one dimension, and codes
it in-bitstream, as well as in Y4M output.
The default aspect ratio is parsed from
Y4M input, or set to 1:1 if absent.
Note that neither aomdec nor dav1d will propagate the bitstream render size to the Y4M files they output.
It doesn't seem to be honored by ffmpeg with aomdec either, but it might be with dav1d (haven't tested it myself, but the code seems present). Reconstruction output is affected as well.
I think we can close #2504 with this, as it implements everything that should be needed for decoders/players to correctly output/display the encoded video.