google/ExoPlayer · error · IllegalArgumentException

Failed to load bitmap.

Error message

Failed to load bitmap.

What it means

IllegalArgumentException thrown in TransformerActivity's input preview path when DataSourceBitmapLoader.loadBitmap(uri) completes exceptionally; future.get() wraps the failure in an ExecutionException (or the wait is interrupted). The demo only supports jpg inputs, so any decode/IO failure of the image surfaces as this error.

Source

Thrown at demos/transformer/src/main/java/com/google/android/exoplayer2/transformerdemo/TransformerActivity.java:716

    outputPlayerView.setPlayer(outputPlayer);
    outputPlayerView.setControllerAutoShow(false);
    outputPlayer.setMediaItem(outputMediaItem);
    outputPlayer.prepare();
    this.outputPlayer = outputPlayer;

    // Only support showing jpg images.
    if (uri.toString().endsWith("jpg")) {
      inputPlayerView.setVisibility(View.GONE);
      inputImageView.setVisibility(View.VISIBLE);
      inputTextView.setText(getString(R.string.input_image));

      BitmapLoader bitmapLoader = new DataSourceBitmapLoader(getApplicationContext());
      ListenableFuture<Bitmap> future = bitmapLoader.loadBitmap(uri);
      try {
        Bitmap bitmap = future.get();
        inputImageView.setImageBitmap(bitmap);
      } catch (ExecutionException | InterruptedException e) {
        throw new IllegalArgumentException("Failed to load bitmap.", e);
      }
    } else {
      inputPlayerView.setVisibility(View.VISIBLE);
      inputImageView.setVisibility(View.GONE);
      inputTextView.setText(getString(R.string.input_video_no_sound));

      ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
      inputPlayerView.setPlayer(inputPlayer);
      inputPlayerView.setControllerAutoShow(false);
      inputPlayerView.setOnClickListener(this::onClickingPlayerView);
      outputPlayerView.setOnClickListener(this::onClickingPlayerView);
      inputPlayer.setMediaItem(inputMediaItem);
      inputPlayer.prepare();
      this.inputPlayer = inputPlayer;
      inputPlayer.setVolume(0f);
      inputPlayer.play();
    }
    outputPlayer.play();

View on GitHub (pinned to dd430f7053)

Solutions

  1. Verify the URI is readable and the bytes are really JPEG before calling loadBitmap (check BitmapFactory.decodeBounds or the content resolver type)
  2. Catch ExecutionException separately and unwrap its cause for a specific message instead of a generic crash
  3. Restore the interrupted flag when catching InterruptedException so the thread state is preserved
  4. Support a broader set of image types or filter the picker to image/jpeg only

Example fix

// before
try {
  Bitmap bitmap = future.get();
  inputImageView.setImageBitmap(bitmap);
} catch (ExecutionException | InterruptedException e) {
  throw new IllegalArgumentException("Failed to load bitmap.", e);
}

// after: degrade gracefully instead of crashing
try {
  inputImageView.setImageBitmap(future.get());
} catch (ExecutionException e) {
  Log.e(TAG, "Failed to load bitmap", e.getCause());
  showToast(R.string.general_error); // keep the video preview path
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
}
Defensive patterns

Strategy: try-catch

Validate before calling

private boolean isDecodableJpg(Uri uri) {
  try (InputStream in = getContentResolver().openInputStream(uri)) {
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(in, null, opts);
    return opts.outWidth > 0; // header parsed -> decodable
  } catch (IOException | SecurityException e) {
    return false;
  }
}

Try / catch

ListenableFuture<Bitmap> future = bitmapLoader.loadBitmap(uri);
try {
  inputImageView.setImageBitmap(future.get());
} catch (ExecutionException e) {
  Log.e(TAG, "bitmap decode failed", e.getCause()); // degrade, do not crash
  inputImageView.setVisibility(View.GONE);
} catch (InterruptedException e) {
  Thread.currentThread().interrupt();
}

Prevention

When it happens

Trigger: Input URI ends with 'jpg' but the bytes are not a decodable JPEG (corrupt file, renamed png, unsupported variant like CMYK jpeg); URI unreadable (content provider revoked, file moved); loadBitmap future fails with a BitmapDecoderException; thread interrupted while waiting.

Common situations: User picks a non-jpg image with a .jpg extension; SAF grant expired; large image OOM inside the decoder; HEIC disguised as jpg.

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/1f8e861e0b701ce4. Report an issue: GitHub.