From fddda40e9e95c33a3eb5d268c418d5422fddeecd Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 15 Jun 2023 16:43:51 +0200 Subject: [PATCH] ndk: Rework media error types - Clean up the names: we're already in the `ndk` crate so no need to repeat that in the type name; - Make the types available outside the `media` module, so that they can be used in `AMidi` bindings which are not located inside `libmediandk.so` (but `libamidi.so`); - Add documentation comments. --- ndk/CHANGELOG.md | 1 + ndk/src/lib.rs | 1 + ndk/src/media/image_reader.rs | 15 +++---- ndk/src/media/media_codec.rs | 38 ++++++++--------- ndk/src/media/mod.rs | 25 +---------- ndk/src/{media/error.rs => media_error.rs} | 49 ++++++++++++++++------ 6 files changed, 65 insertions(+), 64 deletions(-) rename ndk/src/{media/error.rs => media_error.rs} (76%) diff --git a/ndk/CHANGELOG.md b/ndk/CHANGELOG.md index 14b8202c..53139995 100644 --- a/ndk/CHANGELOG.md +++ b/ndk/CHANGELOG.md @@ -8,6 +8,7 @@ - **Breaking:** Upgrade to [`ndk-sys 0.5.0`](../ndk-sys/CHANGELOG.md#050-TODO). (#370) - **Breaking:** Upgrade `bitflags` crate from `1` to `2`. (#394) - **Breaking:** Upgrade `num_enum` crate from `0.5.1` to `0.6`. (#398) +- **Breaking:** Renamed and moved "`media`" error types and helpers to the always-available `media_error` module. (#399) # 0.7.0 (2022-07-24) diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 00a69da0..824f8d7f 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -16,6 +16,7 @@ pub mod hardware_buffer_format; pub mod input_queue; pub mod looper; pub mod media; +pub mod media_error; pub mod native_activity; pub mod native_window; pub mod surface_texture; diff --git a/ndk/src/media/image_reader.rs b/ndk/src/media/image_reader.rs index ce2daa1e..da92a24a 100644 --- a/ndk/src/media/image_reader.rs +++ b/ndk/src/media/image_reader.rs @@ -4,8 +4,7 @@ //! [`AImage`]: https://developer.android.com/ndk/reference/group/media#aimage #![cfg(feature = "api-level-24")] -use super::NdkMediaError; -use super::{construct, construct_never_null, error::MediaErrorResult, Result}; +use crate::media_error::{construct, construct_never_null, MediaError, MediaStatus, Result}; use crate::native_window::NativeWindow; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::{ @@ -140,7 +139,7 @@ impl ImageReader { onImageAvailable: Some(on_image_available), }; let status = unsafe { ffi::AImageReader_setImageListener(self.as_ptr(), &mut listener) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-26")] @@ -168,7 +167,7 @@ impl ImageReader { }; let status = unsafe { ffi::AImageReader_setBufferRemovedListener(self.as_ptr(), &mut listener) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn get_window(&self) -> Result { @@ -202,9 +201,7 @@ impl ImageReader { match res { Ok(inner) => Ok(Some(Image { inner })), - Err(NdkMediaError::ErrorResult(MediaErrorResult::ImgreaderNoBufferAvailable)) => { - Ok(None) - } + Err(MediaError::MediaStatus(MediaStatus::ImgreaderNoBufferAvailable)) => Ok(None), Err(e) => Err(e), } } @@ -232,7 +229,7 @@ impl ImageReader { ffi::AImageReader_acquireLatestImage(self.as_ptr(), res) }); - if let Err(NdkMediaError::ErrorResult(MediaErrorResult::ImgreaderNoBufferAvailable)) = res { + if let Err(MediaError::MediaStatus(MediaStatus::ImgreaderNoBufferAvailable)) = res { return Ok(None); } @@ -291,7 +288,7 @@ impl Image { ) }; - NdkMediaError::from_status(status).map(|()| unsafe { + MediaError::from_status(status).map(|()| unsafe { std::slice::from_raw_parts(result_ptr.assume_init(), result_len.assume_init() as _) }) } diff --git a/ndk/src/media/media_codec.rs b/ndk/src/media/media_codec.rs index 2911f500..31f23535 100644 --- a/ndk/src/media/media_codec.rs +++ b/ndk/src/media/media_codec.rs @@ -3,7 +3,7 @@ //! [`AMediaFormat`]: https://developer.android.com/ndk/reference/group/media#amediaformat //! [`AMediaCodec`]: https://developer.android.com/ndk/reference/group/media#amediacodec -use super::{get_unlikely_to_be_null, NdkMediaError, Result}; +use super::{get_unlikely_to_be_null, MediaError, Result}; use crate::native_window::NativeWindow; use std::{ convert::TryInto, @@ -206,7 +206,7 @@ impl MediaFormat { impl Drop for MediaFormat { fn drop(&mut self) { let status = unsafe { ffi::AMediaFormat_delete(self.as_ptr()) }; - NdkMediaError::from_status(status).unwrap(); + MediaError::from_status(status).unwrap(); } } @@ -267,12 +267,12 @@ impl MediaCodec { }, ) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-26")] pub fn create_input_surface(&self) -> Result { - use super::construct_never_null; + use crate::media_error::construct_never_null; unsafe { let ptr = construct_never_null(|res| { ffi::AMediaCodec_createInputSurface(self.as_ptr(), res) @@ -283,7 +283,7 @@ impl MediaCodec { #[cfg(feature = "api-level-26")] pub fn create_persistent_input_surface() -> Result { - use super::construct_never_null; + use crate::media_error::construct_never_null; unsafe { let ptr = construct_never_null(|res| ffi::AMediaCodec_createPersistentInputSurface(res))?; @@ -311,7 +311,7 @@ impl MediaCodec { index: result as usize, })) } else { - NdkMediaError::from_status(ffi::media_status_t(result as _)).map(|()| None) + MediaError::from_status(ffi::media_status_t(result as _)).map(|()| None) } } @@ -339,13 +339,13 @@ impl MediaCodec { info, })) } else { - NdkMediaError::from_status(ffi::media_status_t(result as _)).map(|()| None) + MediaError::from_status(ffi::media_status_t(result as _)).map(|()| None) } } pub fn flush(&self) -> Result<()> { let status = unsafe { ffi::AMediaCodec_flush(self.as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-28")] @@ -363,7 +363,7 @@ impl MediaCodec { #[cfg(feature = "api-level-28")] pub fn name(&self) -> Result { - use super::construct; + use crate::media_error::construct; unsafe { let name_ptr = construct(|name| ffi::AMediaCodec_getName(self.as_ptr(), name))?; let name = CStr::from_ptr(name_ptr).to_str().unwrap().to_owned(); @@ -391,13 +391,13 @@ impl MediaCodec { flags, ) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn release_output_buffer(&self, buffer: OutputBuffer, render: bool) -> Result<()> { let status = unsafe { ffi::AMediaCodec_releaseOutputBuffer(self.as_ptr(), buffer.index, render) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn release_output_buffer_at_time( @@ -408,49 +408,49 @@ impl MediaCodec { let status = unsafe { ffi::AMediaCodec_releaseOutputBufferAtTime(self.as_ptr(), buffer.index, timestamp_ns) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-26")] pub fn set_input_surface(&self, surface: &NativeWindow) -> Result<()> { let status = unsafe { ffi::AMediaCodec_setInputSurface(self.as_ptr(), surface.ptr().as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn set_output_surface(&self, surface: &NativeWindow) -> Result<()> { let status = unsafe { ffi::AMediaCodec_setOutputSurface(self.as_ptr(), surface.ptr().as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-26")] pub fn set_parameters(&self, params: MediaFormat) -> Result<()> { let status = unsafe { ffi::AMediaCodec_setParameters(self.as_ptr(), params.as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } #[cfg(feature = "api-level-26")] pub fn set_signal_end_of_input_stream(&self) -> Result<()> { let status = unsafe { ffi::AMediaCodec_signalEndOfInputStream(self.as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn start(&self) -> Result<()> { let status = unsafe { ffi::AMediaCodec_start(self.as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } pub fn stop(&self) -> Result<()> { let status = unsafe { ffi::AMediaCodec_stop(self.as_ptr()) }; - NdkMediaError::from_status(status) + MediaError::from_status(status) } } impl Drop for MediaCodec { fn drop(&mut self) { let status = unsafe { ffi::AMediaCodec_delete(self.as_ptr()) }; - NdkMediaError::from_status(status).unwrap(); + MediaError::from_status(status).unwrap(); } } diff --git a/ndk/src/media/mod.rs b/ndk/src/media/mod.rs index cf380e9d..6203b7c2 100644 --- a/ndk/src/media/mod.rs +++ b/ndk/src/media/mod.rs @@ -3,32 +3,11 @@ //! See also [the NDK docs](https://developer.android.com/ndk/reference/group/media) #![cfg(feature = "media")] -mod error; pub mod image_reader; pub mod media_codec; -pub use error::NdkMediaError; -use std::{mem::MaybeUninit, ptr::NonNull}; - -pub type Result = std::result::Result; - -fn construct(with_ptr: impl FnOnce(*mut T) -> ffi::media_status_t) -> Result { - let mut result = MaybeUninit::uninit(); - let status = with_ptr(result.as_mut_ptr()); - NdkMediaError::from_status(status).map(|()| unsafe { result.assume_init() }) -} - -fn construct_never_null( - with_ptr: impl FnOnce(*mut *mut T) -> ffi::media_status_t, -) -> Result> { - let result = construct(with_ptr)?; - let non_null = if cfg!(debug_assertions) { - NonNull::new(result).expect("result should never be null") - } else { - unsafe { NonNull::new_unchecked(result) } - }; - Ok(non_null) -} +use crate::media_error::{MediaError, Result}; +use std::ptr::NonNull; /// Function is not expected to ever return `null`, but this /// cannot be validated through the Android documentation. diff --git a/ndk/src/media/error.rs b/ndk/src/media_error.rs similarity index 76% rename from ndk/src/media/error.rs rename to ndk/src/media_error.rs index 05cff87e..cd2e3b82 100644 --- a/ndk/src/media/error.rs +++ b/ndk/src/media_error.rs @@ -1,9 +1,13 @@ -use super::Result; +use std::{mem::MaybeUninit, ptr::NonNull}; + use thiserror::Error; +pub type Result = std::result::Result; + +/// Media Status codes for [`media_status_t`](https://developer.android.com/ndk/reference/group/media#group___media_1ga009a49041fe39f7bdc6d8b5cddbe760c) #[repr(i32)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum MediaErrorResult { +pub enum MediaStatus { CodecErrorInsufficientResource = ffi::media_status_t::AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE.0, CodecErrorReclaimed = ffi::media_status_t::AMEDIACODEC_ERROR_RECLAIMED.0, ErrorUnknown = ffi::media_status_t::AMEDIA_ERROR_UNKNOWN.0, @@ -33,18 +37,20 @@ pub enum MediaErrorResult { ImgreaderImageNotLocked = ffi::media_status_t::AMEDIA_IMGREADER_IMAGE_NOT_LOCKED.0, } +/// Media Status codes in [`MediaStatus`] or raw [`ffi::media_status_t`] if unknown. #[derive(Debug, Error)] -pub enum NdkMediaError { - #[error("error Media result ({0:?})")] - ErrorResult(MediaErrorResult), - #[error("unknown Media error result ({0:?})")] - UnknownResult(ffi::media_status_t), +pub enum MediaError { + #[error("Media Status {0:?}")] + MediaStatus(MediaStatus), + #[error("Unknown Media Status {0:?}")] + UnknownStatus(ffi::media_status_t), } -impl NdkMediaError { +impl MediaError { + /// Returns [`Ok(())`] on [`ffi::media_status_t::AMEDIA_OK`] [`Err`] otherwise. pub(crate) fn from_status(status: ffi::media_status_t) -> Result<()> { - use MediaErrorResult::*; - let result = match status { + use MediaStatus::*; + Err(Self::MediaStatus(match status { ffi::media_status_t::AMEDIA_OK => return Ok(()), ffi::media_status_t::AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE => { CodecErrorInsufficientResource @@ -75,8 +81,25 @@ impl NdkMediaError { ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE => ImgreaderCannotLockImage, ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE => ImgreaderCannotUnlockImage, ffi::media_status_t::AMEDIA_IMGREADER_IMAGE_NOT_LOCKED => ImgreaderImageNotLocked, - _ => return Err(NdkMediaError::UnknownResult(status)), - }; - Err(NdkMediaError::ErrorResult(result)) + _ => return Err(MediaError::UnknownStatus(status)), + })) } } + +pub(crate) fn construct(with_ptr: impl FnOnce(*mut T) -> ffi::media_status_t) -> Result { + let mut result = MaybeUninit::uninit(); + let status = with_ptr(result.as_mut_ptr()); + MediaError::from_status(status).map(|()| unsafe { result.assume_init() }) +} + +pub(crate) fn construct_never_null( + with_ptr: impl FnOnce(*mut *mut T) -> ffi::media_status_t, +) -> Result> { + let result = construct(with_ptr)?; + let non_null = if cfg!(debug_assertions) { + NonNull::new(result).expect("result should never be null") + } else { + unsafe { NonNull::new_unchecked(result) } + }; + Ok(non_null) +}