Skip to content

Commit 1944c13

Browse files
authored
image_reader: Add AImageReader_newWithDataSpace() from api-level-34 (#474)
Android 14 (U, API level 34) adds `DataSpace` support to `ImageReader` with a new constructor and a getter, and finally switches to the regular `HardwareBufferFormat` instead of the restricted `ImageFormat` enum to select the underlying buffer format. After all, an `AImage` can be turned into a `HardwareBuffer` which supports a wider range of formats. Also clean up and commonize some panics on pedantic `.try_from()` checks.
1 parent f964154 commit 1944c13

File tree

5 files changed

+56
-9
lines changed

5 files changed

+56
-9
lines changed

ndk/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
- image_reader: Add `ImageReader::new_with_data_space()` constructor and `ImageReader::data_space()` getter from API level 34. (#474)
4+
35
# 0.9.0 (2024-04-26)
46

57
- Move `MediaFormat` from `media::media_codec` to its own `media::media_format` module. (#442)

ndk/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rust-version = "1.66"
1414

1515
[features]
1616
default = ["rwh_06"]
17-
all = ["audio", "bitmap", "media", "nativewindow", "sync", "api-level-33", "rwh_04", "rwh_05", "rwh_06"]
17+
all = ["audio", "bitmap", "media", "nativewindow", "sync", "api-level-34", "rwh_04", "rwh_05", "rwh_06"]
1818

1919
audio = ["ffi/audio", "api-level-26"]
2020
bitmap = ["ffi/bitmap"]
@@ -33,6 +33,7 @@ api-level-30 = ["api-level-29"]
3333
api-level-31 = ["api-level-30"]
3434
api-level-32 = ["api-level-31"]
3535
api-level-33 = ["api-level-32"]
36+
api-level-34 = ["api-level-33"]
3637

3738
test = ["ffi/test", "jni", "all"]
3839

ndk/src/hardware_buffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl HardwareBufferDesc {
593593
layers: self.layers,
594594
format: i32::from(self.format)
595595
.try_into()
596-
.expect("i32->u32 overflow in HardwareBufferDesc::into_native()"),
596+
.expect("Unexpected sign bit in `format`"),
597597
usage: self.usage.bits(),
598598
stride: self.stride,
599599
rfu0: 0,

ndk/src/media/image_reader.rs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,25 @@
44
//! [`AImage`]: https://developer.android.com/ndk/reference/group/media#aimage
55
#![cfg(feature = "api-level-24")]
66

7-
use crate::media_error::{construct, construct_never_null, MediaError, Result};
8-
use crate::native_window::NativeWindow;
9-
use crate::utils::abort_on_panic;
10-
use num_enum::{FromPrimitive, IntoPrimitive};
11-
use std::{ffi::c_void, fmt, mem::MaybeUninit, ptr::NonNull};
12-
137
#[cfg(feature = "api-level-26")]
148
use std::os::fd::{FromRawFd, IntoRawFd, OwnedFd};
9+
use std::{ffi::c_void, fmt, mem::MaybeUninit, ptr::NonNull};
10+
11+
use num_enum::{FromPrimitive, IntoPrimitive};
1512

1613
#[cfg(feature = "api-level-26")]
1714
use crate::hardware_buffer::{HardwareBuffer, HardwareBufferUsage};
15+
use crate::media_error::{construct, construct_never_null, MediaError, Result};
16+
use crate::native_window::NativeWindow;
17+
use crate::utils::abort_on_panic;
18+
#[cfg(feature = "api-level-34")]
19+
use crate::{data_space::DataSpace, hardware_buffer_format::HardwareBufferFormat};
1820

1921
#[repr(i32)]
2022
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
2123
#[allow(non_camel_case_types)]
2224
#[non_exhaustive]
25+
#[doc(alias = "AIMAGE_FORMATS")]
2326
pub enum ImageFormat {
2427
RGBA_8888 = ffi::AIMAGE_FORMATS::AIMAGE_FORMAT_RGBA_8888.0 as i32,
2528
RGBX_8888 = ffi::AIMAGE_FORMATS::AIMAGE_FORMAT_RGBX_8888.0 as i32,
@@ -44,9 +47,13 @@ pub enum ImageFormat {
4447
__Unknown(i32),
4548
}
4649

50+
#[doc(alias = "AImageReader_ImageCallback")]
51+
#[doc(alias = "AImageReader_ImageListener")]
4752
pub type ImageListener = Box<dyn FnMut(&ImageReader) + Send>;
4853

4954
#[cfg(feature = "api-level-26")]
55+
#[doc(alias = "AImageReader_BufferRemovedCallback")]
56+
#[doc(alias = "AImageReader_BufferRemovedListener")]
5057
pub type BufferRemovedListener = Box<dyn FnMut(&ImageReader, &HardwareBuffer) + Send>;
5158

5259
/// Result returned by:
@@ -108,6 +115,7 @@ impl AcquireResult<Image> {
108115
/// A native [`AImageReader *`]
109116
///
110117
/// [`AImageReader *`]: https://developer.android.com/ndk/reference/group/media#aimagereader
118+
#[doc(alias = "AImageReader")]
111119
pub struct ImageReader {
112120
inner: NonNull<ffi::AImageReader>,
113121
image_cb: Option<Box<ImageListener>>,
@@ -144,6 +152,7 @@ impl ImageReader {
144152
self.inner.as_ptr()
145153
}
146154

155+
#[doc(alias = "AImageReader_new")]
147156
pub fn new(width: i32, height: i32, format: ImageFormat, max_images: i32) -> Result<Self> {
148157
let inner = construct_never_null(|res| unsafe {
149158
ffi::AImageReader_new(width, height, format.into(), max_images, res)
@@ -153,6 +162,7 @@ impl ImageReader {
153162
}
154163

155164
#[cfg(feature = "api-level-26")]
165+
#[doc(alias = "AImageReader_newWithUsage")]
156166
pub fn new_with_usage(
157167
width: i32,
158168
height: i32,
@@ -174,6 +184,33 @@ impl ImageReader {
174184
Ok(Self::from_ptr(inner))
175185
}
176186

187+
#[cfg(feature = "api-level-34")]
188+
#[doc(alias = "AImageReader_newWithDataSpace")]
189+
pub fn new_with_data_space(
190+
width: i32,
191+
height: i32,
192+
usage: HardwareBufferUsage,
193+
max_images: i32,
194+
format: HardwareBufferFormat,
195+
data_space: DataSpace,
196+
) -> Result<Self> {
197+
let inner = construct_never_null(|res| unsafe {
198+
ffi::AImageReader_newWithDataSpace(
199+
width,
200+
height,
201+
usage.bits(),
202+
max_images,
203+
i32::from(format)
204+
.try_into()
205+
.expect("Unexpected sign bit in `format`"),
206+
data_space.into(),
207+
res,
208+
)
209+
})?;
210+
211+
Ok(Self::from_ptr(inner))
212+
}
213+
177214
#[doc(alias = "AImageReader_setImageListener")]
178215
pub fn set_image_listener(&mut self, listener: ImageListener) -> Result<()> {
179216
let mut boxed = Box::new(listener);
@@ -444,6 +481,13 @@ impl Image {
444481
unsafe { ffi::AImage_deleteAsync(self.as_ptr(), release_fence_fd.into_raw_fd()) };
445482
std::mem::forget(self);
446483
}
484+
485+
#[cfg(feature = "api-level-34")]
486+
#[doc(alias = "AImage_getDataSpace")]
487+
pub fn data_space(&self) -> Result<DataSpace> {
488+
construct(|res| unsafe { ffi::AImage_getDataSpace(self.as_ptr(), res) })
489+
.map(DataSpace::from)
490+
}
447491
}
448492

449493
impl Drop for Image {

ndk/src/surface_texture.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl SurfaceTexture {
143143
Duration::from_nanos(
144144
unsafe { ffi::ASurfaceTexture_getTimestamp(self.ptr.as_ptr()) }
145145
.try_into()
146-
.unwrap(),
146+
.expect("Timestamp cannot be negative"),
147147
)
148148
}
149149

0 commit comments

Comments
 (0)