perf: run GIF-to-MP4 conversion on Dispatchers.Default

The conversion pipeline is overwhelmingly CPU/GPU bound (Movie decode,
GL rendering, MediaCodec encode) and can run for several seconds on a
large GIF. Running it on Dispatchers.IO occupies a thread from the
large IO pool with no kernel wait, which can starve legitimate IO
coroutines when multiple uploads run in parallel.

Switching to Dispatchers.Default caps concurrent conversions to the
CPU count, which is also desirable given the hardware encoder
contention that multiple simultaneous MediaCodec instances would
cause.

convertInternal remains a plain (non-suspending) function, so EGL
thread-affinity is still preserved for the lifetime of the call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
davotoula
2026-04-09 09:21:30 +02:00
co-authored by Claude Opus 4.6
parent 564fedcac8
commit 58c30901e8
@@ -105,7 +105,13 @@ object GifToMp4Converter {
uri: Uri,
context: Context,
): MediaCompressorResult? =
withContext(Dispatchers.IO) {
// Dispatchers.Default: the bulk of this work is CPU/GPU bound
// (Movie decode, GL rendering, MediaCodec encode). Running on IO
// would occupy a thread from the large IO pool for several seconds
// with no kernel wait, risking starvation of real IO coroutines.
// The brief file read at the start and muxer writes are acceptable
// on Default — they're short relative to the encoding loop.
withContext(Dispatchers.Default) {
try {
convertInternal(uri, context)
} catch (e: CancellationException) {