The platform decoders, through the :mob_media_nif NIF linked into the app
by its native build.
- Android: the C NIF hands each job to the Kotlin
MobMediaBridge, which runs it on its own two-thread pool:MediaExtractor+MediaCodecfor PCM (downmixed and resampled in Kotlin, the same algorithm asMobMedia.PCM),MediaExtractor+MediaMetadataRetrieverfor info,MediaMetadataRetriever.getScaledFrameAtTimefor frames. - iOS: the Objective-C NIF runs each job on an
NSOperationQueue(two at a time):AVAssetReaderwith LinearPCM output settings at the requested rate and channels (Core Audio does the conversion),AVAssetImageGeneratorfor frames,AVURLAssetfor info.
No BEAM scheduler (normal or dirty) runs any decoding; a Mob app has one dirty CPU and one dirty IO scheduler and they're not ours to hold.
Synchronous errors on Android are {:error, {:jni, reason}}: :no_jenv,
:bridge_not_registered (MobMediaBridge.register() didn't run before the
BEAM started), :alloc or :call_failed (the bridge threw; it logs why
under the MobMedia logcat tag). On iOS the only one is {:error, :alloc}
(the job couldn't be allocated).