o
    ٷiv                     @  s   d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
ZddlZddlmZ d(ddZd)ddZd*ddZd+ddZd,ddZd-d!d"Zd.d&d'ZdS )/zE
Shared helper utilities for OpenAI-compatible video generation API.
    )annotationsN)BytesIO)Any)Imageinput_reference
str | Noneinput_reference_bytesbytes | NonereturnImage.Image | Nonec              
   C  s   | r|rt d|rtt|dS | rI| dr$| dd\}}n| }zt|}W n t	y> } zt d|d}~ww tt|dS dS )z;Decode image input from multipart bytes or base64/data URL.zBProvide input_reference either as file upload or base64, not both.RGBz
data:image,   zInvalid base64 input_reference.N)

ValueErrorr   openr   convert
startswithsplitbase64	b64decode	Exception)r   r   _b64_dataimage_bytesexc r   `/home/ubuntu/.local/lib/python3.10/site-packages/vllm_omni/entrypoints/openai/video_api_utils.pydecode_input_reference   s    

r   video_tensortorch.Tensor
np.ndarrayc                 C  s   |    } |  dkrtd|  dkr%| jd dv r%| dddd} |  r4| d	dd
 d
 } n| t	j
d } |  }t|S )zINormalize a torch video tensor into a numpy array of frames (F, H, W, C).   zBBatched video tensors are not supported for single-video encoding.   r      r"   r      r$         ?     o@)detachcpudimr   shapepermuteis_floating_pointclamptotorchfloat32numpy_normalize_single_video_array)r   video_arrayr   r   r   _normalize_video_tensor'   s   r6   r5   c                 C  s   | j dkr	td| j dkr7| jd dv r#| jd dvr#t| d} n| jd dv r7| jd dvr7t| d	} t| jtjrX|  d
k sK| 	 dkrVt
| ddd d } | S t| jtjrh| tjd } | S )z7Normalize a single video array into shape (F, H, W, C).r!   zABatched video arrays are not supported for single-video encoding.r"   r   r#   r&   )r   r%   r$   r   r   )r   r%   r$   r                 ?      r'   r(   )ndimr   r,   np	transpose
issubdtypedtypefloatingminmaxclipintegerastyper2   r5   r   r   r   r4   8   s   

r4   list[np.ndarray] | np.ndarrayc                   s.    j dkr fddt jd D S t S )zNormalize a numpy video array into shape (F, H, W, C).

    If a batch dimension is present, returns a list of per-video arrays.
    r!   c                   s   g | ]}t  | qS r   )r4   ).0irE   r   r   
<listcomp>R   s    z*_normalize_video_array.<locals>.<listcomp>r   )r:   ranger,   r4   rE   r   rE   r   _normalize_video_arrayL   s   
rK   frames	list[Any]list[np.ndarray]c                 C  s  g }| D ]}}t |tjr|   }nt |tjr!t|}nt |tj	r*|}n	t
dt| |jdkrL|jd dv rL|jd dvrLt|d}t|jtjrl| dk s`| dkrkt|d	dd
 d
 }nt|jtjr||tjd }|| q|S )zBNormalize a list of frames into numpy arrays with values in [0,1].zUnsupported frame type: r$   r   r#   r&   )r   r%   r   r7   r8   r9   r'   r(   )
isinstancer1   Tensorr)   r*   r3   r   r;   arrayndarrayr   typer:   r,   r<   r=   r>   r?   r@   rA   rB   rC   rD   r2   append)rL   
normalizedframeframe_arrayr   r   r   _normalize_framesV   s&   &rX   videor   c                 C  s   t | tjrt| }t|S t | tjr:t| }t |tr!td|j	dkr*t|S |j	dkr2|gS td|j
 t | tra| sCg S tdd | D r]tdd | D rYtdt| S td	td
t|  )zBConvert a video payload into a list of frames for export_to_video.z3Batched video arrays must be split before encoding.r"   r$   zUnsupported video array shape: c                 s  s&    | ]}t |tjtjtjfV  qd S )N)rO   r;   rR   r1   rP   r   rG   itemr   r   r   	<genexpr>   s   $ z*_coerce_video_to_frames.<locals>.<genexpr>c                 s  s$    | ]}t |d o|jdkV  qdS )r:   r"   N)hasattrr:   rZ   r   r   r   r\      s   " z<Expected a single video, got a list of video tensors/arrays.z,Unsupported list contents for video payload.z Unsupported video payload type: )rO   r1   rP   r6   listr;   rR   rK   r   r:   r,   allrX   rS   )rY   r5   r   r   r   _coerce_video_to_framesp   s*   



r`   fpsintstrc                 C  s   zddl m} W n ty } ztd|d}~ww t| }|s$tdtjddd}|  z<|||j|d	 t	|jd
}|
 }W d   n1 sMw   Y  t|dW zt|j W S  tyk   Y S w zt|j W w  ty}   Y w w )z3Encode a video (frames/array/tensor) to base64 MP4.r   )export_to_videoz*diffusers is required for export_to_video.NzNo frames found to encode.z.mp4F)suffixdelete)ra   rbzutf-8)diffusers.utilsrd   ImportErrorr`   r   tempfileNamedTemporaryFileclosenamer   readr   	b64encodedecodeosremoveOSError)rY   ra   rd   r   rL   tmp_filefvideo_bytesr   r   r   encode_video_base64   s6   

rw   )r   r   r   r	   r
   r   )r   r   r
   r    )r5   r    r
   r    )r5   r    r
   rF   )rL   rM   r
   rN   )rY   r   r
   rN   )rY   r   ra   rb   r
   rc   )__doc__
__future__r   r   rq   rj   ior   typingr   r3   r;   r1   PILr   r   r6   r4   rK   rX   r`   rw   r   r   r   r   <module>   s"   






