[Bugfix] Emit a valid media type from encode_{audio,image,video}_url (#49056)

Signed-off-by: Vineeth Sai <vineethsai4444@gmail.com>

Vineeth Sai Varikuntla committed Aug 3, 2026 at 12:02 UTC 7f2e78ba4df2f7091c247155fc5aeecaa73a486d
2 files changed +21 -4
tests/multimodal/test_utils.py
+16 -1
@@ -2,6 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import pytest
4 import torch
5 +from PIL import Image
6
7 from vllm.multimodal.inputs import (
8 MultiModalBatchedField,
@@ -10,7 +11,11 @@ from vllm.multimodal.inputs import (
11 MultiModalSharedField,
12 PlaceholderRange,
13 )
13 -from vllm.multimodal.utils import argsort_mm_positions, group_and_batch_mm_items
14 +from vllm.multimodal.utils import (
15 + argsort_mm_positions,
16 + encode_image_url,
17 + group_and_batch_mm_items,
18 +)
19
20
21 @pytest.mark.parametrize(
@@ -224,6 +229,16 @@ def test_group_and_batch_mm_items_splits_shared_data_by_dtype():
229 assert [num_items for num_items, _ in res] == [1, 1, 1]
230
231
232 +def test_encode_image_url_uncommon_format_has_valid_mimetype():
233 + """A format missing from mimetypes.types_map must still produce a
234 + well-formed type/subtype media type, not a bare 'image'."""
235 + # ".tga" is not registered in mimetypes.types_map, so it exercises the
236 + # fallback path; Pillow can still encode it.
237 + url = encode_image_url(Image.new("RGB", (2, 2)), format="TGA")
238 + mimetype = url.removeprefix("data:").split(";", 1)[0]
239 + assert mimetype == "image/tga"
240 +
241 +
242 def test_group_and_batch_mm_items_split_by_shared_data():
243 elem1 = MultiModalFieldElem(
244 data=torch.zeros(1, dtype=torch.uint8),
vllm/multimodal/utils.py
+5 -3
@@ -57,7 +57,7 @@ def encode_audio_url(
57 ) -> str:
58 """Encode audio as a data URL."""
59 audio_b64 = encode_audio_base64(audio, sampling_rate, format=format)
60 - mimetype = mimetypes.types_map.get("." + format.lower(), "audio")
60 + mimetype = mimetypes.types_map.get("." + format.lower(), f"audio/{format.lower()}")
61 return f"data:{mimetype};base64,{audio_b64}"
62
63
@@ -90,7 +90,7 @@ def encode_image_url(
90 Pass `image_mode=None` to keep the original image mode.
91 """
92 image_b64 = encode_image_base64(image, image_mode=image_mode, format=format)
93 - mimetype = mimetypes.types_map.get("." + format.lower(), "image")
93 + mimetype = mimetypes.types_map.get("." + format.lower(), f"image/{format.lower()}")
94 return f"data:{mimetype};base64,{image_b64}"
95
96
@@ -114,7 +114,9 @@ def encode_video_url(
114 if format.lower() == "jpeg":
115 mimetype = "video/jpeg"
116 else:
117 - mimetype = mimetypes.types_map.get("." + format.lower(), "video")
117 + mimetype = mimetypes.types_map.get(
118 + "." + format.lower(), f"video/{format.lower()}"
119 + )
120
121 return f"data:{mimetype};base64,{video_b64}"
122