Skip to content

Commit

Permalink
ndk/media_format: Implement copy_to()/clear() fns since API level 29
Browse files Browse the repository at this point in the history
Also provide the typical `try_clone()` method, and add missing doc
aliases to all types and functions.
  • Loading branch information
MarijnS95 committed Nov 20, 2023
1 parent 341e4a2 commit 50f05bb
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
3 changes: 2 additions & 1 deletion ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased

- Move `MediaFormat` from `media::media_codec` to its own `media::media_format` module. (#442)
- Expose `MediaFormat::copy_to()` and `MediaFormat::clear()` from API level 29. (#449)

# 0.8.0 (2023-10-15)

Expand All @@ -9,7 +10,7 @@
- asset: Use entire asset length when mapping buffer. (#387)
- Bump MSRV to 1.66 for `raw-window-handle 0.5.1`, `num_enum`'s `catch_all` with arbitrary enum discriminants. (#388, #431)
- Bump optional `jni` dependency for doctest example from `0.19` to `0.21`. (#390)
- **Breaking:** Upgrade to [`ndk-sys 0.5.0`](../ndk-sys/CHANGELOG.md#050-TODO). (#370)
- **Breaking:** Upgrade to [`ndk-sys 0.5.0`](../ndk-sys/CHANGELOG.md#050-2023-10-15). (#370)
- **Breaking:** Upgrade `bitflags` crate from `1` to `2`. (#394)
- bitmap: Add `try_format()` to `AndroidBitmapInfo` to handle unexpected formats without panicking. (#395)
- Add `Font` bindings. (#397)
Expand Down
50 changes: 49 additions & 1 deletion ndk/src/media/media_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,28 @@ use std::{
slice,
};

use crate::media_error::MediaError;
use crate::media_error::{MediaError, Result};

/// A native [`AMediaFormat *`]
///
/// [`AMediaFormat *`]: https://developer.android.com/ndk/reference/group/media#amediaformat
#[derive(Debug)]
#[doc(alias = "AMediaFormat")]
pub struct MediaFormat {
inner: NonNull<ffi::AMediaFormat>,
}

impl fmt::Display for MediaFormat {
/// Human readable representation of the format.
#[doc(alias = "AMediaFormat_toString")]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c_str = unsafe { CStr::from_ptr(ffi::AMediaFormat_toString(self.as_ptr())) };
f.write_str(c_str.to_str().unwrap())
}
}

impl Default for MediaFormat {
#[doc(alias = "AMediaFormat_new")]
fn default() -> Self {
Self::new()
}
Expand All @@ -45,12 +49,14 @@ impl MediaFormat {
self.inner.as_ptr()
}

#[doc(alias = "AMediaFormat_new")]
pub fn new() -> Self {
Self {
inner: NonNull::new(unsafe { ffi::AMediaFormat_new() }).unwrap(),
}
}

#[doc(alias = "AMediaFormat_getInt32")]
pub fn i32(&self, key: &str) -> Option<i32> {
let name = CString::new(key).unwrap();
let mut out = 0;
Expand All @@ -61,6 +67,7 @@ impl MediaFormat {
}
}

#[doc(alias = "AMediaFormat_getInt64")]
pub fn i64(&self, key: &str) -> Option<i64> {
let name = CString::new(key).unwrap();
let mut out = 0;
Expand All @@ -71,6 +78,7 @@ impl MediaFormat {
}
}

#[doc(alias = "AMediaFormat_getFloat")]
pub fn f32(&self, key: &str) -> Option<f32> {
let name = CString::new(key).unwrap();
let mut out = 0.0;
Expand All @@ -81,6 +89,7 @@ impl MediaFormat {
}
}

#[doc(alias = "AMediaFormat_getSize")]
pub fn usize(&self, key: &str) -> Option<usize> {
let name = CString::new(key).unwrap();
let mut out = 0;
Expand All @@ -91,6 +100,7 @@ impl MediaFormat {
}
}

#[doc(alias = "AMediaFormat_getBuffer")]
pub fn buffer(&self, key: &str) -> Option<&[u8]> {
let name = CString::new(key).unwrap();
let mut out_buffer = ptr::null_mut();
Expand All @@ -106,34 +116,40 @@ impl MediaFormat {
.then(|| unsafe { slice::from_raw_parts(out_buffer.cast(), out_size) })
}

#[doc(alias = "AMediaFormat_getString")]
pub fn str(&self, key: &str) -> Option<&str> {
let name = CString::new(key).unwrap();
let mut out = ptr::null();
unsafe { ffi::AMediaFormat_getString(self.as_ptr(), name.as_ptr(), &mut out) }
.then(|| unsafe { CStr::from_ptr(out) }.to_str().unwrap())
}

#[doc(alias = "AMediaFormat_setInt32")]
pub fn set_i32(&self, key: &str, value: i32) {
let name = CString::new(key).unwrap();
unsafe { ffi::AMediaFormat_setInt32(self.as_ptr(), name.as_ptr(), value) };
}

#[doc(alias = "AMediaFormat_setInt64")]
pub fn set_i64(&self, key: &str, value: i64) {
let name = CString::new(key).unwrap();
unsafe { ffi::AMediaFormat_setInt64(self.as_ptr(), name.as_ptr(), value) };
}

#[doc(alias = "AMediaFormat_setFloat")]
pub fn set_f32(&self, key: &str, value: f32) {
let name = CString::new(key).unwrap();
unsafe { ffi::AMediaFormat_setFloat(self.as_ptr(), name.as_ptr(), value) };
}

#[doc(alias = "AMediaFormat_setString")]
pub fn set_str(&self, key: &str, value: &str) {
let name = CString::new(key).unwrap();
let c_string = CString::new(value).unwrap();
unsafe { ffi::AMediaFormat_setString(self.as_ptr(), name.as_ptr(), c_string.as_ptr()) };
}

#[doc(alias = "AMediaFormat_setBuffer")]
pub fn set_buffer(&self, key: &str, value: &[u8]) {
let name = CString::new(key).unwrap();
unsafe {
Expand All @@ -147,6 +163,7 @@ impl MediaFormat {
}

#[cfg(feature = "api-level-28")]
#[doc(alias = "AMediaFormat_getDouble")]
pub fn f64(&self, key: &str) -> Option<f64> {
let name = CString::new(key).unwrap();
let mut out = 0.0;
Expand All @@ -159,6 +176,7 @@ impl MediaFormat {

/// Returns (left, top, right, bottom)
#[cfg(feature = "api-level-28")]
#[doc(alias = "AMediaFormat_getRect")]
pub fn rect(&self, key: &str) -> Option<(i32, i32, i32, i32)> {
let name = CString::new(key).unwrap();
let mut left = 0;
Expand All @@ -182,12 +200,14 @@ impl MediaFormat {
}

#[cfg(feature = "api-level-28")]
#[doc(alias = "AMediaFormat_setDouble")]
pub fn set_f64(&self, key: &str, value: f64) {
let name = CString::new(key).unwrap();
unsafe { ffi::AMediaFormat_setDouble(self.as_ptr(), name.as_ptr(), value) };
}

#[cfg(feature = "api-level-28")]
#[doc(alias = "AMediaFormat_setRect")]
pub fn set_rect(&self, key: &str, left: i32, top: i32, right: i32, bottom: i32) {
let name = CString::new(key).unwrap();
unsafe {
Expand All @@ -196,13 +216,41 @@ impl MediaFormat {
}

#[cfg(feature = "api-level-28")]
#[doc(alias = "AMediaFormat_setSize")]
pub fn set_usize(&self, key: &str, value: usize) {
let name = CString::new(key).unwrap();
unsafe { ffi::AMediaFormat_setSize(self.as_ptr(), name.as_ptr(), value) };
}

/// Copy one [`MediaFormat`] to another.
#[cfg(feature = "api-level-29")]
#[doc(alias = "AMediaFormat_copy")]
pub fn copy_to(&self, other: &mut Self) -> Result<()> {
let status = unsafe { ffi::AMediaFormat_copy(self.as_ptr(), other.as_ptr()) };
MediaError::from_status(status)
}

/// Clones this [`MediaFormat`] into a [`MediaFormat::new()`] object using
/// [`MediaFormat::copy_to()`].
#[cfg(feature = "api-level-29")]
#[doc(alias = "AMediaFormat_new")]
#[doc(alias = "AMediaFormat_copy")]
pub fn try_clone(&self) -> Result<Self> {
let mut copy = Self::new();
self.copy_to(&mut copy)?;
Ok(copy)
}

/// Remove all key/value pairs from this [`MediaFormat`].
#[cfg(feature = "api-level-29")]
#[doc(alias = "AMediaFormat_clear")]
pub fn clear(&mut self) {
unsafe { ffi::AMediaFormat_clear(self.as_ptr()) }
}
}

impl Drop for MediaFormat {
#[doc(alias = "AMediaFormat_delete")]
fn drop(&mut self) {
let status = unsafe { ffi::AMediaFormat_delete(self.as_ptr()) };
MediaError::from_status(status).unwrap();
Expand Down

0 comments on commit 50f05bb

Please sign in to comment.