66// complex going forward. Allow them to be unused when compiling with certain feature combinations.
77#![ allow( dead_code) ]
88
9- use std:: { convert :: TryInto , mem:: MaybeUninit , ptr:: NonNull } ;
9+ use std:: { fmt , mem:: MaybeUninit , ptr:: NonNull } ;
1010
11- use thiserror :: Error ;
11+ use num_enum :: { FromPrimitive , IntoPrimitive } ;
1212
1313pub type Result < T , E = MediaError > = std:: result:: Result < T , E > ;
1414
1515/// Media Status codes for [`media_status_t`](https://developer.android.com/ndk/reference/group/media#group___media_1ga009a49041fe39f7bdc6d8b5cddbe760c)
1616#[ repr( i32 ) ]
17- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
18- pub enum MediaStatus {
17+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , FromPrimitive , IntoPrimitive ) ]
18+ #[ non_exhaustive]
19+ pub enum MediaError {
1920 CodecErrorInsufficientResource = ffi:: media_status_t:: AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE . 0 ,
2021 CodecErrorReclaimed = ffi:: media_status_t:: AMEDIACODEC_ERROR_RECLAIMED . 0 ,
2122 ErrorUnknown = ffi:: media_status_t:: AMEDIA_ERROR_UNKNOWN . 0 ,
@@ -43,57 +44,29 @@ pub enum MediaStatus {
4344 ImgreaderCannotLockImage = ffi:: media_status_t:: AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE . 0 ,
4445 ImgreaderCannotUnlockImage = ffi:: media_status_t:: AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE . 0 ,
4546 ImgreaderImageNotLocked = ffi:: media_status_t:: AMEDIA_IMGREADER_IMAGE_NOT_LOCKED . 0 ,
47+ // Use the OK discriminant, assuming no-one calls `as i32` and only uses the generated `From` implementation via `IntoPrimitive`
48+ #[ num_enum( catch_all) ]
49+ Unknown ( i32 ) = 0 ,
4650}
4751
48- /// Media Status codes in [`MediaStatus`] or raw [`ffi::media_status_t`] if unknown.
49- #[ derive( Debug , Error ) ]
50- pub enum MediaError {
51- #[ error( "Media Status {0:?}" ) ]
52- MediaStatus ( MediaStatus ) ,
53- #[ error( "Unknown Media Status {0:?}" ) ]
54- UnknownStatus ( ffi:: media_status_t ) ,
52+ impl fmt:: Display for MediaError {
53+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
54+ write ! ( f, "{:?}" , self )
55+ }
5556}
5657
58+ impl std:: error:: Error for MediaError { }
59+
5760impl MediaError {
5861 /// Returns [`Ok`] on [`ffi::media_status_t::AMEDIA_OK`], [`Err`] otherwise (including positive
5962 /// values).
6063 ///
6164 /// Note that some known error codes (currently only for `AMediaCodec`) are positive.
6265 pub ( crate ) fn from_status ( status : ffi:: media_status_t ) -> Result < ( ) > {
63- use MediaStatus :: * ;
64- Err ( Self :: MediaStatus ( match status {
65- ffi:: media_status_t:: AMEDIA_OK => return Ok ( ( ) ) ,
66- ffi:: media_status_t:: AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE => {
67- CodecErrorInsufficientResource
68- }
69- ffi:: media_status_t:: AMEDIACODEC_ERROR_RECLAIMED => CodecErrorReclaimed ,
70- ffi:: media_status_t:: AMEDIA_ERROR_UNKNOWN => ErrorUnknown ,
71- ffi:: media_status_t:: AMEDIA_ERROR_MALFORMED => ErrorMalformed ,
72- ffi:: media_status_t:: AMEDIA_ERROR_UNSUPPORTED => ErrorUnsupported ,
73- ffi:: media_status_t:: AMEDIA_ERROR_INVALID_OBJECT => ErrorInvalidObject ,
74- ffi:: media_status_t:: AMEDIA_ERROR_INVALID_PARAMETER => ErrorInvalidParameter ,
75- ffi:: media_status_t:: AMEDIA_ERROR_INVALID_OPERATION => ErrorInvalidOperation ,
76- ffi:: media_status_t:: AMEDIA_ERROR_END_OF_STREAM => ErrorEndOfStream ,
77- ffi:: media_status_t:: AMEDIA_ERROR_IO => ErrorIo ,
78- ffi:: media_status_t:: AMEDIA_ERROR_WOULD_BLOCK => ErrorWouldBlock ,
79- ffi:: media_status_t:: AMEDIA_DRM_ERROR_BASE => DrmErrorBase ,
80- ffi:: media_status_t:: AMEDIA_DRM_NOT_PROVISIONED => DrmNotProvisioned ,
81- ffi:: media_status_t:: AMEDIA_DRM_RESOURCE_BUSY => DrmResourceBusy ,
82- ffi:: media_status_t:: AMEDIA_DRM_DEVICE_REVOKED => DrmDeviceRevoked ,
83- ffi:: media_status_t:: AMEDIA_DRM_SHORT_BUFFER => DrmShortBuffer ,
84- ffi:: media_status_t:: AMEDIA_DRM_SESSION_NOT_OPENED => DrmSessionNotOpened ,
85- ffi:: media_status_t:: AMEDIA_DRM_TAMPER_DETECTED => DrmTamperDetected ,
86- ffi:: media_status_t:: AMEDIA_DRM_VERIFY_FAILED => DrmVerifyFailed ,
87- ffi:: media_status_t:: AMEDIA_DRM_NEED_KEY => DrmNeedKey ,
88- ffi:: media_status_t:: AMEDIA_DRM_LICENSE_EXPIRED => DrmLicenseExpired ,
89- ffi:: media_status_t:: AMEDIA_IMGREADER_ERROR_BASE => ImgreaderErrorBase ,
90- ffi:: media_status_t:: AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE => ImgreaderNoBufferAvailable ,
91- ffi:: media_status_t:: AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED => ImgreaderMaxImagesAcquired ,
92- ffi:: media_status_t:: AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE => ImgreaderCannotLockImage ,
93- ffi:: media_status_t:: AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE => ImgreaderCannotUnlockImage ,
94- ffi:: media_status_t:: AMEDIA_IMGREADER_IMAGE_NOT_LOCKED => ImgreaderImageNotLocked ,
95- _ => return Err ( MediaError :: UnknownStatus ( status) ) ,
96- } ) )
66+ match status {
67+ ffi:: media_status_t:: AMEDIA_OK => Ok ( ( ) ) ,
68+ x => Err ( Self :: from ( x. 0 ) ) ,
69+ }
9770 }
9871
9972 /// Returns the original value in [`Ok`] if it is not negative, [`Err`] otherwise.
@@ -106,12 +79,9 @@ impl MediaError {
10679 if v >= 0 {
10780 Ok ( value)
10881 } else {
109- Err ( Self :: from_status ( ffi :: media_status_t (
110- v . try_into ( ) . expect ( "Error code out of bounds" ) ,
82+ Err ( Self :: from (
83+ i32 :: try_from ( v ) . expect ( "Error code out of bounds" ) ,
11184 ) )
112- // This panic should be unreachable: the only case where Ok is returned is in
113- // AMEDIA_OK=0 whose value is already handled above.
114- . unwrap_err ( ) )
11585 }
11686 }
11787}
0 commit comments