
    qi4                     r   d dl Z d dlmZ ddlmZ ddlmZ d dlmZm	Z	 ddl
mZmZ ddlmZmZ d d	lmZ  G d
 d      Zdedededej&                  j(                  fdZdej,                  j.                  dededefdZdedej,                  j.                  dededeej&                  j(                     f
dZy)    N)Union   )video_frame_pb2)ffi_pb2)ListOptional)	FfiClient	FfiHandle)_ensure_compatible_bufferget_address)Anyc                      e Zd ZdZdededej                  j                  dee	e
ef   ddf
dZedefd	       Zedefd
       Zedej                  j                  fd       Zedefd       Zedej&                  dd fd       Zdej*                  fdZdedee   fdZdddej                  j                  dedd fdZdefdZedefd       Zy)
VideoFramez
    Represents a video frame with associated metadata and pixel data.

    This class provides methods to access video frame properties such as width, height,
    and pixel format, as well as methods for manipulating and converting video frames.
    widthheighttypedatareturnNc                 R    t        |      }|| _        || _        || _        || _        y)a  
        Initializes a new VideoFrame instance.

        Args:
            width (int): The width of the video frame in pixels.
            height (int): The height of the video frame in pixels.
            type (proto_video.VideoBufferType.ValueType): The format type of the video frame data
                (e.g., RGBA, BGRA, RGB24, etc.).
            data (Union[bytes, bytearray, memoryview]): The raw pixel data for the video frame.
        N)r   _width_height_type_data)selfr   r   r   r   s        I/opt/pipecat/venv/lib/python3.12/site-packages/livekit/rtc/video_frame.py__init__zVideoFrame.__init__"   s*    " ).

    c                     | j                   S )z
        Returns the width of the video frame in pixels.

        Returns:
            int: The width of the video frame.
        )r   r   s    r   r   zVideoFrame.width:   s     {{r   c                     | j                   S z
        Returns the height of the video frame in pixels.

        Returns:
            int: The height of the video frame.
        )r   r   s    r   r   zVideoFrame.heightD   s     ||r   c                     | j                   S r!   )r   r   s    r   r   zVideoFrame.typeN   s     zzr   c                 ,    t        | j                        S )z
        Returns a memoryview of the raw pixel data for the video frame.

        Returns:
            memoryview: The raw pixel data of the video frame as a memoryview object.
        )
memoryviewr   r   s    r   r   zVideoFrame.dataX   s     $**%%r   
owned_infoc                    | j                   }t        |j                  |j                  |j                        }t
        j                  |z  j                  |j                        }t        |      }t        |j                  |j                  |j                  |      }t        | j                  j                        j                          |S )Nr   r   r   r   )info_get_plane_lengthr   r   r   ctypesc_uint8from_addressdata_ptr	bytearrayr   r
   handleiddispose)r%   r(   data_lencdatar   frames         r   _from_owned_infozVideoFrame._from_owned_infob   s    $TYY

DKKH(*88G**;;	
 	*##&&'//1r   c                    t        j                         }t        | j                        }|j                  j                  t        || j                  | j                  | j                               | j                  |_        | j                  |_	        | j                  |_        ||_
        d|_        | j                  t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j                   fv r| j                  dz  |_        |S | j                  t         j                  j"                  k(  r| j                  dz  |_        |S )Nr         )proto_videoVideoBufferInfor   r   
componentsextend_get_plane_infosr   r   r   r-   strideVideoBufferTypeARGBABGRRGBABGRARGB24)r   r(   addrs      r   _proto_infozVideoFrame._proto_infoq   s
   **,499%/diiT[[YZZZ
kkII	99'',,'',,'',,'',,	
 
 **q.DK  YY+55;;;**q.DKr   	plane_nthc                 *   t        t        | j                        | j                  | j                  | j
                        }|t        |      k\  ry||   }t        j                  |j                  z  j                  |j                        }t        |      S )a  
        Returns the memoryview of a specific plane in the video frame, based on its index.

        Some video formats (e.g., I420, NV12) contain multiple planes (Y, U, V channels).
        This method allows access to individual planes by index.

        Args:
            plane_nth (int): The index of the plane to retrieve (starting from 0).

        Returns:
            Optional[memoryview]: A memoryview of the specified plane's data, or None if
            the index is out of bounds for the format.
        N)r=   r   r   r   r   r   lenr*   r+   sizer,   r-   r$   )r   rG   plane_infos
plane_infor3   s        r   	get_planezVideoFrame.get_plane   st     '{499'=tyy$**VZVaVabK(( +
*//1??
@S@ST%  r   F)flip_yrN   c                   t        j                         }||j                  _        ||j                  _        |j                  j
                  j                  | j                                t        j                  j                  |      }|j                  j                  rt        |j                  j                        t        j                  |j                  j
                        S )aS  
        Converts the current video frame to a different format type, optionally flipping
        the frame vertically.

        Args:
            type (proto_video.VideoBufferType.ValueType): The target format type to convert to
                (e.g., RGBA, I420).
            flip_y (bool, optional): If True, the frame will be flipped vertically. Defaults to False.

        Returns:
            VideoFrame: A new VideoFrame object in the specified format.

        Raises:
            Exception: If the conversion isn't supported.

        Example:
            Convert a frame from RGBA to I420 format:

            >>> frame = VideoFrame(width=1920, height=1080, type=proto_video.VideoBufferType.RGBA, data=raw_data)
            >>> converted_frame = frame.convert(proto_video.VideoBufferType.I420)
            >>> print(converted_frame.type)
            VideoBufferType.I420

        Example:
            Convert a frame from BGRA to RGB24 format and flip it vertically:

            >>> frame = VideoFrame(width=1280, height=720, type=proto_video.VideoBufferType.BGRA, data=raw_data)
            >>> converted_frame = frame.convert(proto_video.VideoBufferType.RGB24, flip_y=True)
            >>> print(converted_frame.type)
            VideoBufferType.RGB24
            >>> print(converted_frame.width, converted_frame.height)
            1280 720
        )proto
FfiRequestvideo_convertrN   dst_typebufferCopyFromrF   r	   instancerequesterror	Exceptionr   r5   )r   r   rN   reqresps        r   convertzVideoFrame.convert   s    H  #) %)"  ))$*:*:*<=!!))#.##D..4455**4+=+=+D+DEEr   c                     d| j                    d| j                   dt        j                  j	                  | j
                         dS )Nzrtc.VideoFrame(width=z	, height=z, type=))r   r   r9   r?   Namer   r   s    r   __repr__zVideoFrame.__repr__   s@    &tzzl)DKK=P[PkPkPpPpquqzqzP{O||}~~r   _c                    ddl m} dd ldt        ddffd}|j	                  |j                  |j                  |j                  |j                               |j                  |j                               |j                  |j                               |j                  |j                               d      |j                  |      g      |j                  |      |j                  fd      	      S )
Nr   )core_schemavaluer   r   c           	         t        | t              r| S t        | t              r| d   } t        | t              rGt        | d   | d   t        j
                  j                  | d         j                  | d               S t        d      )Nr   r   r   r   r   r'   zInvalid type for VideoFrame)	
isinstancer   tupledictr9   r?   Value	b64decode	TypeError)rd   base64s    r   validate_video_framezEVideoFrame.__get_pydantic_core_schema__.<locals>.validate_video_frame   s    %,%'a%&!. ?$44::5=I))%-8	  9::r   r'   c                     | j                   | j                  t        j                  j	                  | j
                        j                  | j                        j                  d      dS )Nzutf-8r'   )	r   r   r9   r?   r_   r   	b64encoder   decode)rV   rl   s    r   <lambda>z9VideoFrame.__get_pydantic_core_schema__.<locals>.<lambda>   sM    %^^&oo'77<<X]]K",,X]];BB7K	" r   )json_schemapython_schemaserialization)pydantic_corerc   rl   r   json_or_python_schemachain_schemamodel_fields_schemamodel_field
int_schema
str_schema no_info_plain_validator_function$plain_serializer_function_ser_schema)clsra   rc   rm   rl   s       @r   __get_pydantic_core_schema__z'VideoFrame.__get_pydantic_core_schema__   s    -	; 	; 	;" 00#0033%0%<%<[=S=S=U%V&1&=&=k>T>T>V&W$/$;$;K<R<R<T$U$/$;$;K<R<R<T$U	  @@AUV
 &FFG[\%JJ 1 
 	
r   ) __name__
__module____qualname____doc__intr9   r?   	ValueTyper   bytesr.   r$   r   propertyr   r   r   r   staticmethodOwnedVideoBufferr5   r:   rF   r   rM   boolr\   strr`   classmethodr   r    r   r   r   r      s|     ))33	
 E9j01 
0 s      k11;;   &j & & [%A%A l  [88 ,!3 !8J+? !. NS,F//99,FFJ,F	,F\#  ,
c ,
 ,
r   r   r-   r>   rJ   r   c                 l    t         j                  j                         }| |_        ||_        ||_        |S )N)r9   r:   ComponentInfor-   r>   rJ   )r-   r>   rJ   cmpts       r   _component_infor      s2     &&446DDMDKDIKr   r   r   r   c                    | t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j
                  fv r||z  dz  S | t         j                  j                  k(  r||z  dz  S | t         j                  j                  k(  r|dz   dz  }|dz   dz  }||z  ||z  dz  z   S | t         j                  j                  k(  r|dz   dz  }||z  dz  ||z  dz  z   S | t         j                  j                  k(  r|dz   dz  }||z  ||z  dz  z   S | t         j                  j                  k(  r||z  dz  S | t         j                  j                  k(  r!|dz   dz  }|dz   dz  }||z  dz  ||z  dz  z   S | t         j                  j                  k(  r|dz   dz  }|dz   dz  }||z  ||z  dz  z   S t        d|        )zr
    Return the size in bytes of a participant video buffer type based on its size (This ignores the strides)
    r7   r8   r      zunsupported video buffer type: )r9   r?   r@   rA   rB   rC   rD   I420I420AI422I444I010NV12rY   )r   r   r   chroma_widthchroma_heights        r   r)   r)     s    ##((##((##((##((	  v~!!	,,22	2v~!!	,,11	1	a'!)v~} <q @@@	,,22	2	a'v~!L<$?!$CCC	,,11	1	a'v~v 5 999	,,11	1v~!!	,,11	1	a'!)v~!L=$@1$DDD	,,11	1	a'!)v~| ;a ???
5dV<
==r   rE   c                    |t         j                  j                  k(  rs|dz   dz  }|dz   dz  }t        | |||z        }t        |j                  |j
                  z   |||z        }t        |j                  |j
                  z   |||z        }|||gS |t         j                  j                  k(  r|dz   dz  }|dz   dz  }t        | |||z        }t        |j                  |j
                  z   |||z        }t        |j                  |j
                  z   |||z        }t        |j                  |j
                  z   |||z        }	||||	gS |t         j                  j                  k(  rx|dz   dz  }t        | |||z        }t        |j                  |j
                  z   |||z        }t        |j                  |j
                  z   |j
                  z   |||z        }|||gS |t         j                  j                  k(  rct        | |||z        }t        |j                  |j
                  z   |||z        }t        |j                  |j
                  z   |||z        }|||gS |t         j                  j                  k(  r|dz   dz  }|dz   dz  }t        | |dz  ||z  dz        }t        |j                  |j
                  z   |dz  ||z  dz        }t        |j                  |j
                  z   |dz  ||z  dz        }|||gS |t         j                  j                  k(  rQ|dz   dz  }|dz   dz  }t        | |||z        }t        |j                  |j
                  z   |dz  ||z  dz        }
||
gS g S )Nr   r   )r9   r?   r   r   r-   rJ   r   r   r   r   r   )rE   r   r   r   r   r   yuvauvs              r   r=   r=   -  sj    {**///	a'!)D%8AJJ/|m?[\AJJ/|m?[\1ay	,,22	2	a'!)D%8AJJ/|m?[\AJJ/|m?[\AJJ/G1a|	,,11	1	a'D%8AJJ/|f?TUAJJ/!&&8,W]H]^1ay	,,11	1D%8AJJ/GAJJ/G1ay	,,11	1	a'!)D%!)UV^a-?@AJJ/1A<R_C_bcCcdAJJ/1A<R_C_bcCcd1ay	,,11	1	a'!)D%8JJ!1<-3ORS3S
 2wIr   )r*   typingr   _protor   r9   r   rP   r   r   _ffi_clientr	   r
   _utilsr   r   r   r   r   r:   r   r   r?   r   r)   r=   r   r   r   <module>r      s      2 $ ! - : a
 a
H&)  ..">K77AA "># ">WZ ">_b ">J-
- 00::-CF-PS-	+
%
%
3
34-r   