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

Support max_width/max_height options. #2490

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/api/config/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ pub struct EncoderConfig {
pub height: usize,
/// Sample aspect ratio (for anamorphic video).
pub sample_aspect_ratio: Rational,
/// Maximum width of the frames in pixels (for seq header)
/// 0 means to use the width setting instead.
/// Used for multiple renditions when switch frames are in use.
/// Set all renditions to have identical max_width / max_height.
pub max_width: usize,
/// Maximum height of the frames in pixels (for seq header)
pub max_height: usize,
/// Video time base.
pub time_base: Rational,

Expand Down Expand Up @@ -133,7 +140,8 @@ impl EncoderConfig {
height: 480,
sample_aspect_ratio: Rational { num: 1, den: 1 },
time_base: Rational { num: 1, den: 30 },

max_width: 0,
max_height: 0,
bit_depth: 8,
chroma_sampling: ChromaSampling::Cs420,
chroma_sample_position: ChromaSamplePosition::Unknown,
Expand Down
38 changes: 32 additions & 6 deletions src/api/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,21 @@ pub use crate::tiling::TilingInfo;
#[non_exhaustive]
pub enum InvalidConfig {
/// The width is invalid.
#[error("invalid width {0} (expected >= 16, <= 65535)")]
InvalidWidth(usize),
#[error("invalid width {actual} (expected >= 16, <= {max})")]
InvalidWidth {
/// The actual value.
actual: usize,
/// The maximal supported value.
max: usize,
},
/// The height is invalid.
#[error("invalid height {0} (expected >= 16, <= 65535)")]
InvalidHeight(usize),
#[error("invalid height {actual} (expected >= 16, <= {max})")]
InvalidHeight {
/// The actual value.
actual: usize,
/// The maximal supported value.
max: usize,
},
/// Aspect ratio numerator is invalid.
#[error("invalid aspect ratio numerator {0} (expected > 0)")]
InvalidAspectRatioNum(usize),
Expand Down Expand Up @@ -285,14 +295,30 @@ impl Config {
if (config.still_picture && config.width < 1)
|| (!config.still_picture && config.width < 16)
|| config.width > u16::max_value() as usize
|| (config.max_width != 0 && config.width > config.max_width)
{
return Err(InvalidWidth(config.width));
return Err(InvalidWidth {
actual: config.width,
max: if config.max_width != 0 {
config.max_width
} else {
u16::max_value() as usize
},
});
}
if (config.still_picture && config.height < 1)
|| (!config.still_picture && config.height < 16)
|| config.height > u16::max_value() as usize
|| (config.max_height != 0 && config.height > config.max_height)
{
return Err(InvalidHeight(config.height));
return Err(InvalidHeight {
actual: config.height,
max: if config.max_height != 0 {
config.max_height
} else {
u16::max_value() as usize
},
});
}

if config.sample_aspect_ratio.num == 0 {
Expand Down
4 changes: 4 additions & 0 deletions src/api/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,8 @@ fn log_q_exp_overflow() {
width: 16,
height: 16,
sample_aspect_ratio: Rational::new(1, 1),
max_width: 0,
max_height: 0,
bit_depth: 8,
chroma_sampling: ChromaSampling::Cs420,
chroma_sample_position: ChromaSamplePosition::Unknown,
Expand Down Expand Up @@ -1967,6 +1969,8 @@ fn guess_frame_subtypes_assert() {
width: 16,
height: 16,
sample_aspect_ratio: Rational::new(1, 1),
max_width: 0,
max_height: 0,
bit_depth: 8,
chroma_sampling: ChromaSampling::Cs420,
chroma_sample_position: ChromaSamplePosition::Unknown,
Expand Down
17 changes: 17 additions & 0 deletions src/bin/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,20 @@ pub fn parse_cli() -> Result<CliOptions, CliError> {
.takes_value(true)
.default_value("0")
)
.arg(
Arg::with_name("MAX_WIDTH")
.help("Maximum width coded in the sequence header. 0 uses the input video width.")
.long("max-width")
.takes_value(true)
.default_value("0")
)
.arg(
Arg::with_name("MAX_HEIGHT")
.help("Maximum height coded in the sequence header. 0 uses the input video width.")
.long("max-height")
.takes_value(true)
.default_value("0")
)
.arg(
Arg::with_name("TILES")
.help("Number of tiles. Tile-cols and tile-rows are overridden\n\
Expand Down Expand Up @@ -740,6 +754,9 @@ fn parse_config(matches: &ArgMatches<'_>) -> Result<EncoderConfig, CliError> {
cfg.tile_cols = matches.value_of("TILE_COLS").unwrap().parse().unwrap();
cfg.tile_rows = matches.value_of("TILE_ROWS").unwrap().parse().unwrap();

cfg.max_width = matches.value_of("MAX_WIDTH").unwrap().parse().unwrap();
cfg.max_height = matches.value_of("MAX_HEIGHT").unwrap().parse().unwrap();

tdaede marked this conversation as resolved.
Show resolved Hide resolved
cfg.tiles = matches.value_of("TILES").unwrap().parse().unwrap();

if cfg.tile_cols > 64 || cfg.tile_rows > 64 {
Expand Down
2 changes: 2 additions & 0 deletions src/capi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,8 @@ unsafe fn option_match(
match key {
"width" => enc.width = value.parse().map_err(|_| ())?,
"height" => enc.height = value.parse().map_err(|_| ())?,
"max_width" => enc.max_width = value.parse().map_err(|_| ())?,
"max_height" => enc.max_height = value.parse().map_err(|_| ())?,
"speed" => {
enc.speed_settings =
rav1e::SpeedSettings::from_preset(value.parse().map_err(|_| ())?)
Expand Down
12 changes: 8 additions & 4 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,12 @@ pub struct Sequence {

impl Sequence {
pub fn new(config: &EncoderConfig) -> Sequence {
let width_bits = 32 - (config.width as u32).leading_zeros();
let height_bits = 32 - (config.height as u32).leading_zeros();
let max_width =
if config.max_width > 0 { config.max_width } else { config.width };
let max_height =
if config.max_height > 0 { config.max_height } else { config.height };
let width_bits = 32 - (max_width as u32).leading_zeros();
let height_bits = 32 - (max_height as u32).leading_zeros();
tdaede marked this conversation as resolved.
Show resolved Hide resolved
assert!(width_bits <= 16);
assert!(height_bits <= 16);

Expand Down Expand Up @@ -277,8 +281,8 @@ impl Sequence {
color_description: config.color_description,
mastering_display: config.mastering_display,
content_light: config.content_light,
max_frame_width: config.width as u32,
max_frame_height: config.height as u32,
max_frame_width: max_width as u32,
max_frame_height: max_height as u32,
frame_id_numbers_present_flag: false,
frame_id_length: FRAME_ID_LENGTH,
delta_frame_id_length: DELTA_FRAME_ID_LENGTH,
Expand Down
2 changes: 2 additions & 0 deletions src/fuzzing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ impl Arbitrary for ArbitraryEncoder {
speed_settings: SpeedSettings::from_preset(u.int_in_range(0..=10)?),
width: u.int_in_range(1..=256)?,
height: u.int_in_range(1..=256)?,
max_width: 0,
max_height: 0,
still_picture: Arbitrary::arbitrary(u)?,
time_base: arbitrary_rational(u)?,
min_key_frame_interval: u.int_in_range(0..=3)?,
Expand Down
20 changes: 8 additions & 12 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -837,12 +837,10 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
fn write_max_frame_size<T: Pixel>(
&mut self, fi: &FrameInvariants<T>,
) -> io::Result<()> {
// width_bits and height_bits will have to be moved to the sequence header OBU
// when we add support for it.
let width = fi.width - 1;
let height = fi.height - 1;
let width_bits = log_in_base_2(width as u32) as u32 + 1;
let height_bits = log_in_base_2(height as u32) as u32 + 1;
let width = fi.sequence.max_frame_width - 1;
let height = fi.sequence.max_frame_height - 1;
let width_bits = fi.sequence.num_bits_width;
let height_bits = fi.sequence.num_bits_height;
tdaede marked this conversation as resolved.
Show resolved Hide resolved
assert!(width_bits <= 16);
assert!(height_bits <= 16);
self.write(4, width_bits - 1)?;
Expand All @@ -858,14 +856,12 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
// width_bits and height_bits will have to be moved to the sequence header OBU
// when we add support for it.
if fi.frame_size_override_flag {
let width = fi.width - 1;
let height = fi.height - 1;
let width_bits = log_in_base_2(width as u32) as u32 + 1;
let height_bits = log_in_base_2(height as u32) as u32 + 1;
let width_bits = fi.sequence.num_bits_width;
let height_bits = fi.sequence.num_bits_height;
assert!(width_bits <= 16);
assert!(height_bits <= 16);
self.write(width_bits, width as u16)?;
self.write(height_bits, height as u16)?;
self.write(width_bits, (fi.width - 1) as u16)?;
self.write(height_bits, (fi.height - 1) as u16)?;
}
if fi.sequence.enable_superres {
unimplemented!();
Expand Down