Skip to content

Commit

Permalink
mediacodec: Use actual width/height to initialize
Browse files Browse the repository at this point in the history
Pass in the actual width and height from the container and use
it to initialize the MediaCodec.

This way, if there is no underlying codec available to handle the
given image, we will fail early.

PiperOrigin-RevId: 647459305
  • Loading branch information
vigneshvg authored and copybara-github committed Jul 9, 2024
1 parent e623f72 commit d4347d4
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 30 deletions.
15 changes: 10 additions & 5 deletions src/codecs/android_mediacodec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ fn get_i32_from_str(format: *mut AMediaFormat, key: &str) -> Option<i32> {
}

impl Decoder for MediaCodec {
fn initialize(&mut self, _operating_point: u8, _all_layers: bool) -> AvifResult<()> {
fn initialize(
&mut self,
_operating_point: u8,
_all_layers: bool,
width: u32,
height: u32,
) -> AvifResult<()> {
// Does not support operating point and all layers.
if self.codec.is_some() {
return Ok(()); // Already initialized.
Expand All @@ -77,9 +83,8 @@ impl Decoder for MediaCodec {
unsafe {
c_str!(mime_type, mime_type_tmp, "video/av01");
AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime_type);
// TODO: Set actual width and height?
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, 200);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, 200);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, i32_from_u32(width)?);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, i32_from_u32(height)?);

// https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities#COLOR_FormatYUV420Flexible
//AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, 2135033992);
Expand Down Expand Up @@ -112,7 +117,7 @@ impl Decoder for MediaCodec {
category: Category,
) -> AvifResult<()> {
if self.codec.is_none() {
self.initialize(0, true)?;
self.initialize(0, true, 0, 0)?;
}
let codec = self.codec.unwrap();
if self.output_buffer_index.is_some() {
Expand Down
10 changes: 8 additions & 2 deletions src/codecs/dav1d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ const DAV1D_EAGAIN: i32 = if libc::EPERM > 0 { -libc::EAGAIN } else { libc::EAGA
// So allow clippy to ignore unnecessary cast warnings.
#[allow(clippy::unnecessary_cast)]
impl Decoder for Dav1d {
fn initialize(&mut self, operating_point: u8, all_layers: bool) -> AvifResult<()> {
fn initialize(
&mut self,
operating_point: u8,
all_layers: bool,
_width: u32,
_height: u32,
) -> AvifResult<()> {
if self.context.is_some() {
return Ok(());
}
Expand Down Expand Up @@ -77,7 +83,7 @@ impl Decoder for Dav1d {
category: Category,
) -> AvifResult<()> {
if self.context.is_none() {
self.initialize(0, true)?;
self.initialize(0, true, 0, 0)?;
}
unsafe {
let mut data: Dav1dData = std::mem::zeroed();
Expand Down
10 changes: 8 additions & 2 deletions src/codecs/libgav1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ pub struct Libgav1 {
// unnecessary cast warnings.
#[allow(clippy::unnecessary_cast)]
impl Decoder for Libgav1 {
fn initialize(&mut self, operating_point: u8, all_layers: bool) -> AvifResult<()> {
fn initialize(
&mut self,
operating_point: u8,
all_layers: bool,
_width: u32,
_height: u32,
) -> AvifResult<()> {
if self.decoder.is_some() {
return Ok(()); // Already initialized.
}
Expand Down Expand Up @@ -68,7 +74,7 @@ impl Decoder for Libgav1 {
category: Category,
) -> AvifResult<()> {
if self.decoder.is_none() {
self.initialize(0, true)?;
self.initialize(0, true, 0, 0)?;
}
unsafe {
let ret = Libgav1DecoderEnqueueFrame(
Expand Down
8 changes: 7 additions & 1 deletion src/codecs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@ use crate::image::Image;
use crate::AvifResult;

pub trait Decoder {
fn initialize(&mut self, operating_point: u8, all_layers: bool) -> AvifResult<()>;
fn initialize(
&mut self,
operating_point: u8,
all_layers: bool,
width: u32,
height: u32,
) -> AvifResult<()>;
fn get_next_image(
&mut self,
av1_payload: &[u8],
Expand Down
36 changes: 16 additions & 20 deletions src/decoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,9 +1079,15 @@ impl Decoder {
Ok(true)
}

fn create_codec(&mut self, operating_point: u8, all_layers: bool) -> AvifResult<()> {
fn create_codec(&mut self, category: Category, tile_index: usize) -> AvifResult<()> {
let tile = &self.tiles[category.usize()][tile_index];
let mut codec: Codec = self.settings.codec_choice.get_codec()?;
codec.initialize(operating_point, all_layers)?;
codec.initialize(
tile.operating_point,
tile.input.all_layers,
tile.width,
tile.height,
)?;
self.codecs.push(codec);
Ok(())
}
Expand All @@ -1094,36 +1100,26 @@ impl Decoder {
// In this case, we will use at most two codec instances (one for the color planes and
// one for the alpha plane). Gain maps are not supported.
self.codecs = create_vec_exact(2)?;
self.create_codec(
self.tiles[Category::Color.usize()][0].operating_point,
self.tiles[Category::Color.usize()][0].input.all_layers,
)?;
self.create_codec(Category::Color, 0)?;
self.tiles[Category::Color.usize()][0].codec_index = 0;
if !self.tiles[Category::Alpha.usize()].is_empty() {
self.create_codec(
self.tiles[Category::Alpha.usize()][0].operating_point,
self.tiles[Category::Alpha.usize()][0].input.all_layers,
)?;
self.tiles[1][0].codec_index = 1;
self.create_codec(Category::Alpha, 0)?;
self.tiles[Category::Alpha.usize()][0].codec_index = 1;
}
} else if self.can_use_single_codec()? {
self.codecs = create_vec_exact(1)?;
self.create_codec(
self.tiles[Category::Color.usize()][0].operating_point,
self.tiles[Category::Color.usize()][0].input.all_layers,
)?;
self.create_codec(Category::Color, 0)?;
for tiles in &mut self.tiles {
for tile in tiles {
tile.codec_index = 0;
}
}
} else {
self.codecs = create_vec_exact(self.tiles.iter().map(|tiles| tiles.len()).sum())?;
for category in Category::ALL_USIZE {
for tile_index in 0..self.tiles[category].len() {
let tile = &self.tiles[category][tile_index];
self.create_codec(tile.operating_point, tile.input.all_layers)?;
self.tiles[category][tile_index].codec_index = self.codecs.len() - 1;
for category in Category::ALL {
for tile_index in 0..self.tiles[category.usize()].len() {
self.create_codec(category, tile_index)?;
self.tiles[category.usize()][tile_index].codec_index = self.codecs.len() - 1;
}
}
}
Expand Down

0 comments on commit d4347d4

Please sign in to comment.