o
    ॵi                     @   s  d dl Z d dlZd dlZd dlZd dlmZmZmZ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mZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZ d dlm Z  dZ!e  Z"ej#dfddZ$ej%ej&ej&dG dd deZ'dS )    N)AnyDictOptionalUnion)	make_grid)	Pipelines)MSRResNetLiteModelRealBasicVSRNetForVideoSR)
OutputKeys)InputPipeline)	PIPELINES)VideoReader)Tasks)
get_logger).mp4z.mov)r      c              	   C   s  t | pt| totdd | D }|stdt|  t | r&| g} g }| D ]}|dd}| 	 
 j| }||d  |d |d   }| }|dkrxt|tt|ddd }t|g d	d
d
d
d
f d}n*|dkr| }t|g d	d
d
d
d
f d}n|dkr| }ntd| |tjkr|d  }||}|| q*t|dkr|d }|S |}|S )aQ  Convert torch Tensors into image numpy arrays.
    After clamping to (min, max), image values will be normalized to [0, 1].
    For different tensor shapes, this function will have different behaviors:
        1. 4D mini-batch Tensor of shape (N x 3/1 x H x W):
            Use `make_grid` to stitch images in the batch dimension, and then
            convert it to numpy array.
        2. 3D Tensor of shape (3/1 x H x W) and 2D Tensor of shape (H x W):
            Directly change to numpy array.
    Note that the image channel in input tensors should be RGB order. This
    function will convert it to cv2 convention, i.e., (H x W x C) with BGR
    order.
    Args:
        tensor (Tensor | list[Tensor]): Input tensors.
        out_type (numpy type): Output types. If ``np.uint8``, transform outputs
            to uint8 type with range [0, 255]; otherwise, float type with
            range [0, 1]. Default: ``np.uint8``.
        min_max (tuple): min and max values for clamp.
    Returns:
        (Tensor | list[Tensor]): 3D ndarray of shape (H x W x C) or 2D ndarray
        of shape (H x W).
    c                 s   s    | ]}t |V  qd S N)torch	is_tensor).0t r   k/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/pipelines/cv/video_super_resolution_pipeline.py	<genexpr>4   s    

ztensor2img.<locals>.<genexpr>z(tensor or list of tensors expected, got r   r      F)nrow	normalize)   r   r   N)r   r   r      r   z?Only support 4D, 3D or 2D tensor. But received with dimension:      o@)r   r   
isinstancelistall	TypeErrortypesqueezefloatdetachcpuclamp_dimr   intmathsqrtsizenumpynp	transpose
ValueErroruint8roundastypeappendlen)tensorout_typemin_max	conditionresult_tensorn_dimimg_npr   r   r   
tensor2img   sN   
$$


rA   )module_namec                       s   e Zd Z	ddeeeef f fddZdede	ee
f fddZde	ee
f de	ee
f fd	d
Zde	ee
f de	ee
f fddZ  ZS )VideoSuperResolutionPipelineNmodelc                    s^   t  jd||d| | j  | jj| _tj r"td| _	ntd| _	t
d d S )N)rD   preprocessorcudar)   z&load video super-resolution model doner   )super__init__rD   evalconfigr   rF   is_availabledevice_deviceloggerinfo)selfrD   rE   kwargs	__class__r   r   rH   `   s   


z%VideoSuperResolutionPipeline.__init__inputreturnc                 C   s   t |}g }|D ]}|tj|dd q|j}t|D ]\}}t|d ddd	 }|
d||< qtj|dd}||dS )Nr   )axisr    r   r   r+   )videofps)r   r7   r1   fliprY   	enumerater   
from_numpypermuter'   	unsqueezestack)rP   rT   video_readerinputsframerY   iimgr   r   r   
preprocessp   s   
z'VideoSuperResolutionPipeline.preprocessc              	   C   s   |d }t  d t| jjjtrUg }td|d| jjjD ]-}|d d ||| jjj d d d d d d f }|	| j
}|| j|d   qt j|dd}n|	| j
}| j|d  }W d    n1 sow   Y  ||d dS )NrX   r   r   outputrW   rY   )rf   rY   )r   no_gradr!   rJ   rD   max_seq_lenr,   ranger/   torM   r7   _inference_forwardr)   cat)rP   rT   ra   outputsrc   imgsr   r   r   forward~   s(   
"z$VideoSuperResolutionPipeline.forwardra   c              	   K   s   | dd }| dd}|d u rtjddj}|d jdd  \}}tjd }t|||d	 ||f}td
|d 	dD ] }	t
|d d d |	d d d d d d f }
||
tj q=|  |rtdd
ksoJ d|d d d }d| d| }tj|dd tj|iS tj|iS )Noutput_videodemo_serviceTr   )suffixrf   mp4vrY   r   r   zffmpeg -versionzaffmpeg is not installed correctly, please refer to https://trac.ffmpeg.org/wiki/CompilationGuide.z_web.mp4z
ffmpeg -i z -vcodec h264 -crf 5 )shell)gettempfileNamedTemporaryFilenameshapecv2VideoWriter_fourccVideoWriterri   r/   rA   writer6   r1   r4   releaseossystem
subprocesscallr
   OUTPUT_VIDEO)rP   ra   rQ   output_video_pathrq   hwfourccvideo_writerrc   rd   output_video_path_for_webconvert_cmdr   r   r   postprocess   s4   
*

z(VideoSuperResolutionPipeline.postprocessr   )__name__
__module____qualname__r   r	   r   strrH   r   r   r   re   ro   r   __classcell__r   r   rR   r   rC   \   s    "*rC   )(r-   r   r   rx   typingr   r   r   r   r|   r0   r1   r   torchvision.utilsr   modelscope.metainfor   +modelscope.models.cv.video_super_resolutionr   r	   modelscope.outputsr
   modelscope.pipelines.baser   r   modelscope.pipelines.builderr   modelscope.preprocessors.cvr   modelscope.utils.constantr   modelscope.utils.loggerr   VIDEO_EXTENSIONSrN   r4   rA   register_modulevideo_super_resolutionrC   r   r   r   r   <module>   s0   >