<s> '''<STR_LIT>''' <EOL> __docformat__ = '<STR_LIT>' <EOL> __version__ = '<STR_LIT>' <EOL> import ctypes <EOL> import threading <EOL> import time <EOL> import pyglet <EOL> from pyglet import gl <EOL> from pyglet . gl import gl_info <EOL> from pyglet import image <EOL> import pyglet . lib <EOL> from pyglet . media import MediaFormatException , StreamingSource , VideoFormat , AudioFormat , AudioData , MediaEvent , WorkerThread , SourceInfo <EOL> av = pyglet . lib . load_library ( '<STR_LIT>' , <EOL> darwin = '<STR_LIT>' ) <EOL> AVBIN_RESULT_ERROR = - <NUM_LIT:1> <EOL> AVBIN_RESULT_OK = <NUM_LIT:0> <EOL> AVbinResult = ctypes . c_int <EOL> AVBIN_STREAM_TYPE_UNKNOWN = <NUM_LIT:0> <EOL> AVBIN_STREAM_TYPE_VIDEO = <NUM_LIT:1> <EOL> AVBIN_STREAM_TYPE_AUDIO = <NUM_LIT:2> <EOL> AVbinStreamType = ctypes . c_int <EOL> AVBIN_SAMPLE_FORMAT_U8 = <NUM_LIT:0> <EOL> AVBIN_SAMPLE_FORMAT_S16 = <NUM_LIT:1> <EOL> AVBIN_SAMPLE_FORMAT_S24 = <NUM_LIT:2> <EOL> AVBIN_SAMPLE_FORMAT_S32 = <NUM_LIT:3> <EOL> AVBIN_SAMPLE_FORMAT_FLOAT = <NUM_LIT:4> <EOL> AVbinSampleFormat = ctypes . c_int <EOL> AVBIN_LOG_QUIET = - <NUM_LIT:8> <EOL> AVBIN_LOG_PANIC = <NUM_LIT:0> <EOL> AVBIN_LOG_FATAL = <NUM_LIT:8> <EOL> AVBIN_LOG_ERROR = <NUM_LIT:16> <EOL> AVBIN_LOG_WARNING = <NUM_LIT> <EOL> AVBIN_LOG_INFO = <NUM_LIT:32> <EOL> AVBIN_LOG_VERBOSE = <NUM_LIT> <EOL> AVBIN_LOG_DEBUG = <NUM_LIT> <EOL> AVbinLogLevel = ctypes . c_int <EOL> AVbinFileP = ctypes . c_void_p <EOL> AVbinStreamP = ctypes . c_void_p <EOL> Timestamp = ctypes . c_int64 <EOL> class AVbinFileInfo ( ctypes . Structure ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT>' , ctypes . c_size_t ) , <EOL> ( '<STR_LIT>' , ctypes . c_int ) , <EOL> ( '<STR_LIT>' , Timestamp ) , <EOL> ( '<STR_LIT>' , Timestamp ) , <EOL> ( '<STR_LIT:title>' , ctypes . c_char * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , ctypes . c_char * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , ctypes . c_char * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , ctypes . c_char * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , ctypes . c_char * <NUM_LIT> ) , <EOL> ( '<STR_LIT>' , ctypes . c_int ) , <EOL> ( '<STR_LIT>' , ctypes . c_int ) , <EOL> ( '<STR_LIT>' , ctypes . c_char * <NUM_LIT:32> ) , <EOL> ] <EOL> class _AVbinStreamInfoVideo8 ( ctypes . Structure ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT:width>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ] <EOL> class _AVbinStreamInfoAudio8 ( ctypes . Structure ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT>' , ctypes . c_int ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ( '<STR_LIT>' , ctypes . c_uint ) , <EOL> ] <EOL> class _AVbinStreamInfoUnion8 ( ctypes . Union ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT>' , _AVbinStreamInfoVideo8 ) , <EOL> ( '<STR_LIT>' , _AVbinStreamInfoAudio8 ) , <EOL> ] <EOL> class AVbinStreamInfo8 ( ctypes . Structure ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT>' , ctypes . c_size_t ) , <EOL> ( '<STR_LIT:type>' , ctypes . c_int ) , <EOL> ( '<STR_LIT:u>' , _AVbinStreamInfoUnion8 ) <EOL> ] <EOL> class AVbinPacket ( ctypes . Structure ) : <EOL> _fields_ = [ <EOL> ( '<STR_LIT>' , ctypes . c_size_t ) , <EOL> ( '<STR_LIT>' , Timestamp ) , <EOL> ( '<STR_LIT>' , ctypes . c_int ) , <EOL> ( '<STR_LIT:data>' , ctypes . POINTER ( ctypes . c_uint8 ) ) , <EOL> ( '<STR_LIT:size>' , ctypes . c_size_t ) , <EOL> ] <EOL> AVbinLogCallback = ctypes . CFUNCTYPE ( None , <EOL> ctypes . c_char_p , ctypes . c_int , ctypes . c_char_p ) <EOL> av . avbin_get_version . restype = ctypes . c_int <EOL> av . avbin_get_ffmpeg_revision . restype = ctypes . c_int <EOL> av . avbin_get_audio_buffer_size . restype = ctypes . c_size_t <EOL> av . avbin_have_feature . restype = ctypes . c_int <EOL> av . avbin_have_feature . argtypes = [ ctypes . c_char_p ] <EOL> av . avbin_init . restype = AVbinResult <EOL> av . avbin_set_log_level . restype = AVbinResult <EOL> av . avbin_set_log_level . argtypes = [ AVbinLogLevel ] <EOL> av . avbin_set_log_callback . argtypes = [ AVbinLogCallback ] <EOL> av . avbin_open_filename . restype = AVbinFileP <EOL> av . avbin_open_filename . argtypes = [ ctypes . c_char_p ] <EOL> av . avbin_close_file . argtypes = [ AVbinFileP ] <EOL> av . avbin_seek_file . argtypes = [ AVbinFileP , Timestamp ] <EOL> av . avbin_file_info . argtypes = [ AVbinFileP , ctypes . POINTER ( AVbinFileInfo ) ] <EOL> av . avbin_stream_info . argtypes = [ AVbinFileP , ctypes . c_int , <EOL> ctypes . POINTER ( AVbinStreamInfo8 ) ] <EOL> av . avbin_open_stream . restype = ctypes . c_void_p <EOL> av . avbin_open_stream . argtypes = [ AVbinFileP , ctypes . c_int ] <EOL> av . avbin_close_stream . argtypes = [ AVbinStreamP ] <EOL> av . avbin_read . argtypes = [ AVbinFileP , ctypes . POINTER ( AVbinPacket ) ] <EOL> av . avbin_read . restype = AVbinResult <EOL> av . avbin_decode_audio . restype = ctypes . c_int <EOL> av . avbin_decode_audio . argtypes = [ AVbinStreamP , <EOL> ctypes . c_void_p , ctypes . c_size_t , <EOL> ctypes . c_void_p , ctypes . POINTER ( ctypes . c_int ) ] <EOL> av . avbin_decode_video . restype = ctypes . c_int <EOL> av . avbin_decode_video . argtypes = [ AVbinStreamP , <EOL> ctypes . c_void_p , ctypes . c_size_t , <EOL> ctypes . c_void_p ] <EOL> if True : <EOL> def synchronize ( func , lock ) : <EOL> def f ( * args ) : <EOL> lock . acquire ( ) <EOL> result = func ( * args ) <EOL> lock . release ( ) <EOL> return result <EOL> return f <EOL> _avbin_lock = threading . Lock ( ) <EOL> for name in dir ( av ) : <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> setattr ( av , name , synchronize ( getattr ( av , name ) , _avbin_lock ) ) <EOL> def get_version ( ) : <EOL> return av . avbin_get_version ( ) <EOL> class AVbinException ( MediaFormatException ) : <EOL> pass <EOL> def timestamp_from_avbin ( timestamp ) : <EOL> return float ( timestamp ) / <NUM_LIT> <EOL> def timestamp_to_avbin ( timestamp ) : <EOL> return int ( timestamp * <NUM_LIT> ) <EOL> class VideoPacket ( object ) : <EOL> _next_id = <NUM_LIT:0> <EOL> def __init__ ( self , packet ) : <EOL> self . timestamp = timestamp_from_avbin ( packet . timestamp ) <EOL> self . data = ( ctypes . c_uint8 * packet . size ) ( ) <EOL> self . size = packet . size <EOL> ctypes . memmove ( self . data , packet . data , self . size ) <EOL> self . image = <NUM_LIT:0> <EOL> self . id = self . _next_id <EOL> self . __class__ . _next_id += <NUM_LIT:1> <EOL> class AVbinSource ( StreamingSource ) : <EOL> def __init__ ( self , filename , file = None ) : <EOL> if file is not None : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> self . _file = av . avbin_open_filename ( filename ) <EOL> if not self . _file : <EOL> raise AVbinException ( '<STR_LIT>' % filename ) <EOL> self . _video_stream = None <EOL> self . _video_stream_index = - <NUM_LIT:1> <EOL> self . _audio_stream = None <EOL> self . _audio_stream_index = - <NUM_LIT:1> <EOL> file_info = AVbinFileInfo ( ) <EOL> file_info . structure_size = ctypes . sizeof ( file_info ) <EOL> av . avbin_file_info ( self . _file , ctypes . byref ( file_info ) ) <EOL> self . _duration = timestamp_from_avbin ( file_info . duration ) <EOL> self . info = SourceInfo ( ) <EOL> self . info . title = file_info . title <EOL> self . info . author = file_info . author <EOL> self . info . copyright = file_info . copyright <EOL> self . info . comment = file_info . comment <EOL> self . info . album = file_info . album <EOL> self . info . year = file_info . year <EOL> self . info . track = file_info . track <EOL> self . info . genre = file_info . genre <EOL> for i in range ( file_info . n_streams ) : <EOL> info = AVbinStreamInfo8 ( ) <EOL> info . structure_size = ctypes . sizeof ( info ) <EOL> av . avbin_stream_info ( self . _file , i , info ) <EOL> if ( info . type == AVBIN_STREAM_TYPE_VIDEO and <EOL> not self . _video_stream ) : <EOL> stream = av . avbin_open_stream ( self . _file , i ) <EOL> if not stream : <EOL> continue <EOL> self . video_format = VideoFormat ( <EOL> width = info . u . video . width , <EOL> height = info . u . video . height ) <EOL> if info . u . video . sample_aspect_num != <NUM_LIT:0> : <EOL> self . video_format . sample_aspect = ( <EOL> float ( info . u . video . sample_aspect_num ) / <EOL> info . u . video . sample_aspect_den ) <EOL> if _have_frame_rate : <EOL> self . video_format . frame_rate = ( <EOL> float ( info . u . video . frame_rate_num ) / <EOL> info . u . video . frame_rate_den ) <EOL> self . _video_stream = stream <EOL> self . _video_stream_index = i <EOL> elif ( info . type == AVBIN_STREAM_TYPE_AUDIO and <EOL> info . u . audio . sample_bits in ( <NUM_LIT:8> , <NUM_LIT:16> ) and <EOL> info . u . audio . channels in ( <NUM_LIT:1> , <NUM_LIT:2> ) and <EOL> not self . _audio_stream ) : <EOL> stream = av . avbin_open_stream ( self . _file , i ) <EOL> if not stream : <EOL> continue <EOL> self . audio_format = AudioFormat ( <EOL> channels = info . u . audio . channels , <EOL> sample_size = info . u . audio . sample_bits , <EOL> sample_rate = info . u . audio . sample_rate ) <EOL> self . _audio_stream = stream <EOL> self . _audio_stream_index = i <EOL> self . _packet = AVbinPacket ( ) <EOL> self . _packet . structure_size = ctypes . sizeof ( self . _packet ) <EOL> self . _packet . stream_index = - <NUM_LIT:1> <EOL> self . _events = [ ] <EOL> self . _video_timestamp = <NUM_LIT:0> <EOL> self . _buffered_audio_data = [ ] <EOL> if self . audio_format : <EOL> self . _audio_buffer = ( ctypes . c_uint8 * av . avbin_get_audio_buffer_size ( ) ) ( ) <EOL> if self . video_format : <EOL> self . _video_packets = [ ] <EOL> self . _decode_thread = WorkerThread ( ) <EOL> self . _decode_thread . start ( ) <EOL> self . _condition = threading . Condition ( ) <EOL> def __del__ ( self ) : <EOL> if _debug : <EOL> print '<STR_LIT>' <EOL> try : <EOL> if self . _video_stream : <EOL> av . avbin_close_stream ( self . _video_stream ) <EOL> if self . _audio_stream : <EOL> av . avbin_close_stream ( self . _audio_stream ) <EOL> av . avbin_close_file ( self . _file ) <EOL> except : <EOL> pass <EOL> def delete ( self ) : <EOL> if self . video_format : <EOL> self . _decode_thread . stop ( ) <EOL> def seek ( self , timestamp ) : <EOL> if _debug : <EOL> print '<STR_LIT>' , timestamp <EOL> av . avbin_seek_file ( self . _file , timestamp_to_avbin ( timestamp ) ) <EOL> self . _audio_packet_size = <NUM_LIT:0> <EOL> del self . _events [ : ] <EOL> del self . _buffered_audio_data [ : ] <EOL> if self . video_format : <EOL> self . _video_timestamp = <NUM_LIT:0> <EOL> self . _condition . acquire ( ) <EOL> for packet in self . _video_packets : <EOL> packet . image = None <EOL> self . _condition . notify ( ) <EOL> self . _condition . release ( ) <EOL> del self . _video_packets [ : ] <EOL> self . _decode_thread . clear_jobs ( ) <EOL> def _get_packet ( self ) : <EOL> return av . avbin_read ( self . _file , self . _packet ) == AVBIN_RESULT_OK <EOL> def _process_packet ( self ) : <EOL> if self . _packet . stream_index == self . _video_stream_index : <EOL> if self . _packet . timestamp < <NUM_LIT:0> : <EOL> return None , None <EOL> video_packet = VideoPacket ( self . _packet ) <EOL> if _debug : <EOL> print '<STR_LIT>' % ( video_packet . id , video_packet . timestamp ) <EOL> self . _video_timestamp = max ( self . _video_timestamp , <EOL> video_packet . timestamp ) <EOL> self . _video_packets . append ( video_packet ) <EOL> self . _decode_thread . put_job ( <EOL> lambda : self . _decode_video_packet ( video_packet ) ) <EOL> return '<STR_LIT>' , video_packet <EOL> elif self . _packet . stream_index == self . _audio_stream_index : <EOL> audio_data = self . _decode_audio_packet ( ) <EOL> if audio_data : <EOL> if _debug : <EOL> print '<STR_LIT>' , audio_data . timestamp <EOL> self . _buffered_audio_data . append ( audio_data ) <EOL> return '<STR_LIT>' , audio_data <EOL> return None , None <EOL> def get_audio_data ( self , bytes ) : <EOL> try : <EOL> audio_data = self . _buffered_audio_data . pop ( <NUM_LIT:0> ) <EOL> audio_data_timeend = audio_data . timestamp + audio_data . duration <EOL> except IndexError : <EOL> audio_data = None <EOL> audio_data_timeend = self . _video_timestamp + <NUM_LIT:1> <EOL> if _debug : <EOL> print '<STR_LIT>' <EOL> have_video_work = False <EOL> while not audio_data or ( <EOL> self . _video_stream and self . _video_timestamp < audio_data_timeend ) : <EOL> if not self . _get_packet ( ) : <EOL> break <EOL> packet_type , packet = self . _process_packet ( ) <EOL> if packet_type == '<STR_LIT>' : <EOL> have_video_work = True <EOL> elif not audio_data and packet_type == '<STR_LIT>' : <EOL> audio_data = self . _buffered_audio_data . pop ( <NUM_LIT:0> ) <EOL> if _debug : <EOL> print '<STR_LIT>' , audio_data . timestamp <EOL> audio_data_timeend = audio_data . timestamp + audio_data . duration <EOL> if have_video_work : <EOL> time . sleep ( <NUM_LIT:0> ) <EOL> if not audio_data : <EOL> if _debug : <EOL> print '<STR_LIT>' <EOL> return None <EOL> while self . _events and self . _events [ <NUM_LIT:0> ] . timestamp <= audio_data_timeend : <EOL> event = self . _events . pop ( <NUM_LIT:0> ) <EOL> if event . timestamp >= audio_data . timestamp : <EOL> event . timestamp -= audio_data . timestamp <EOL> audio_data . events . append ( event ) <EOL> if _debug : <EOL> print '<STR_LIT>' % audio_data . timestamp , audio_data . events <EOL> print '<STR_LIT>' , self . _events <EOL> return audio_data <EOL> def _decode_audio_packet ( self ) : <EOL> packet = self . _packet <EOL> size_out = ctypes . c_int ( len ( self . _audio_buffer ) ) <EOL> while True : <EOL> audio_packet_ptr = ctypes . cast ( packet . data , ctypes . c_void_p ) <EOL> audio_packet_size = packet . size <EOL> used = av . avbin_decode_audio ( self . _audio_stream , <EOL> audio_packet_ptr , audio_packet_size , <EOL> self . _audio_buffer , size_out ) <EOL> if used < <NUM_LIT:0> : <EOL> self . _audio_packet_size = <NUM_LIT:0> <EOL> break <EOL> audio_packet_ptr . value += used <EOL> audio_packet_size -= used <EOL> if size_out . value <= <NUM_LIT:0> : <EOL> continue <EOL> buffer = ctypes . create_string_buffer ( size_out . value ) <EOL> ctypes . memmove ( buffer , self . _audio_buffer , len ( buffer ) ) <EOL> buffer = buffer . raw <EOL> duration = float ( len ( buffer ) ) / self . audio_format . bytes_per_second <EOL> self . _audio_packet_timestamp = timestamp = timestamp_from_avbin ( packet . timestamp ) <EOL> return AudioData ( buffer , len ( buffer ) , timestamp , duration , [ ] ) <EOL> def _decode_video_packet ( self , packet ) : <EOL> width = self . video_format . width <EOL> height = self . video_format . height <EOL> pitch = width * <NUM_LIT:3> <EOL> buffer = ( ctypes . c_uint8 * ( pitch * height ) ) ( ) <EOL> result = av . avbin_decode_video ( self . _video_stream , <EOL> packet . data , packet . size , <EOL> buffer ) <EOL> if result < <NUM_LIT:0> : <EOL> image_data = None <EOL> else : <EOL> image_data = image . ImageData ( width , height , '<STR_LIT>' , buffer , pitch ) <EOL> packet . image = image_data <EOL> self . _condition . acquire ( ) <EOL> self . _condition . notify ( ) <EOL> self . _condition . release ( ) <EOL> def _ensure_video_packets ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . _video_packets : <EOL> if _debug : <EOL> print '<STR_LIT>' <EOL> self . _get_packet ( ) <EOL> packet_type , _ = self . _process_packet ( ) <EOL> while packet_type and packet_type != '<STR_LIT>' : <EOL> self . _get_packet ( ) <EOL> packet_type , _ = self . _process_packet ( ) <EOL> if not packet_type : <EOL> return False <EOL> if _debug : <EOL> print '<STR_LIT>' , _ <EOL> return True <EOL> def get_next_video_timestamp ( self ) : <EOL> if not self . video_format : <EOL> return <EOL> if self . _ensure_video_packets ( ) : <EOL> if _debug : <EOL> print '<STR_LIT>' , self . _video_packets [ <NUM_LIT:0> ] . timestamp <EOL> return self . _video_packets [ <NUM_LIT:0> ] . timestamp <EOL> def get_next_video_frame ( self ) : <EOL> if not self . video_format : <EOL> return <EOL> if self . _ensure_video_packets ( ) : <EOL> packet = self . _video_packets . pop ( <NUM_LIT:0> ) <EOL> if _debug : <EOL> print '<STR_LIT>' , packet <EOL> self . _condition . acquire ( ) <EOL> while packet . image == <NUM_LIT:0> : <EOL> self . _condition . wait ( ) <EOL> self . _condition . release ( ) <EOL> if _debug : <EOL> print '<STR_LIT>' , packet <EOL> return packet . image <EOL> av . avbin_init ( ) <EOL> if pyglet . options [ '<STR_LIT>' ] : <EOL> _debug = True <EOL> av . avbin_set_log_level ( AVBIN_LOG_DEBUG ) <EOL> else : <EOL> _debug = False <EOL> av . avbin_set_log_level ( AVBIN_LOG_QUIET ) <EOL> _have_frame_rate = av . avbin_have_feature ( '<STR_LIT>' ) </s>
