Skip to content

Commit

Permalink
Optimize tile size bytes in bitstream
Browse files Browse the repository at this point in the history
The tile size may be encoded using 1, 2, 3 or 4 bytes. For simplicity,
it always used 4 bytes.

Instead, use the number of bytes required by the biggest tile.
  • Loading branch information
rom1v authored and tdaede committed Apr 20, 2019
1 parent ec82d80 commit 9a76ff0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
14 changes: 10 additions & 4 deletions src/encoder.rs
Expand Up @@ -418,6 +418,7 @@ pub struct FrameState<T: Pixel> {
pub rec: Frame<T>,
pub cdfs: CDFContext,
pub context_update_tile_id: usize, // tile id used for the CDFontext
pub max_tile_size_bytes: u32,
pub deblock: DeblockState,
pub segmentation: SegmentationState,
pub restoration: RestorationState,
Expand Down Expand Up @@ -447,6 +448,7 @@ impl<T: Pixel> FrameState<T> {
rec: Frame::new(luma_width, luma_height, fi.sequence.chroma_sampling),
cdfs: CDFContext::new(0),
context_update_tile_id: 0,
max_tile_size_bytes: 0,
deblock: Default::default(),
segmentation: Default::default(),
restoration: rs,
Expand Down Expand Up @@ -2144,7 +2146,7 @@ fn encode_tile_group<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>)
fs.t.print_code();
}

let (idx_max, _max_len) = raw_tiles
let (idx_max, max_len) = raw_tiles
.iter()
.map(Vec::len)
.enumerate()
Expand All @@ -2156,10 +2158,14 @@ fn encode_tile_group<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>)
fs.cdfs = cdfs[idx_max];
fs.cdfs.reset_counts();

build_raw_tile_group(ti, &raw_tiles)
let max_tile_size_bytes = ((max_len as u32).ilog() + 7) / 8;
debug_assert!(max_tile_size_bytes > 0 && max_tile_size_bytes <= 4);
fs.max_tile_size_bytes = max_tile_size_bytes;

build_raw_tile_group(ti, &raw_tiles, max_tile_size_bytes)
}

fn build_raw_tile_group(ti: &TilingInfo, raw_tiles: &[Vec<u8>]) -> Vec<u8> {
fn build_raw_tile_group(ti: &TilingInfo, raw_tiles: &[Vec<u8>], max_tile_size_bytes: u32) -> Vec<u8> {
// <https://aomediacodec.github.io/av1-spec/#general-tile-group-obu-syntax>
let mut raw = Vec::new();
let mut bw = BitWriter::endian(&mut raw, BigEndian);
Expand All @@ -2172,7 +2178,7 @@ fn build_raw_tile_group(ti: &TilingInfo, raw_tiles: &[Vec<u8>]) -> Vec<u8> {
let last = raw_tiles.len() - 1;
if i != last {
let tile_size_minus_1 = raw_tile.len() - 1;
bw.write_le(4, tile_size_minus_1 as u64).unwrap();
bw.write_le(max_tile_size_bytes, tile_size_minus_1 as u64).unwrap();
}
bw.write_bytes(&raw_tile).unwrap();
}
Expand Down
3 changes: 1 addition & 2 deletions src/header.rs
Expand Up @@ -645,8 +645,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
self.write(tiles_log2 as u32, fs.context_update_tile_id as u32)?;

// tile_size_bytes_minus_1
// force TileSizeBytes == 4, to be optimized using actual tile sizes
self.write(2, 3);
self.write(2, fs.max_tile_size_bytes - 1);
}

// quantization
Expand Down

0 comments on commit 9a76ff0

Please sign in to comment.