""" RouteFrameReader indexes and reads frames across routes, by frameId or segment indices. """ 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  tools . lib . framereader  import  FrameReader 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  _FrameReaderDict ( dict ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  __init__ ( self ,  camera_paths ,  cache_paths ,  framereader_kwargs ,  * args ,  * * kwargs ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    super ( _FrameReaderDict ,  self ) . __init__ ( * args ,  * * kwargs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  cache_paths  is  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cache_paths  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  isinstance ( cache_paths ,  dict ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      cache_paths  =  dict ( enumerate ( cache_paths ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _camera_paths  =  camera_paths 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _cache_paths  =  cache_paths 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _framereader_kwargs  =  framereader_kwargs 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  __missing__ ( self ,  key ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  self . _camera_paths . get ( key ,  None )  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      frame_reader  =  FrameReader ( self . _camera_paths [ key ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                 self . _cache_paths . get ( key ) ,  * * self . _framereader_kwargs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self [ key ]  =  frame_reader 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  frame_reader 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      raise  KeyError ( " Segment index out of bounds:  {} " . format ( key ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  RouteFrameReader ( object ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  """ Reads frames across routes and route segments by frameId. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  __init__ ( self ,  camera_paths ,  cache_paths ,  frame_id_lookup ,  * * kwargs ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Create a route framereader. 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								       Inputs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TODO 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kwargs :  Forwarded  to  the  FrameReader  function .  If  cache_prefix  is  included ,  that  path 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                will  also  be  used  for  frame  position  indices . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  not  isinstance ( camera_paths ,  dict ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      camera_paths  =  { int ( k . split ( ' ? ' ) [ 0 ] . split ( ' / ' ) [ - 2 ] ) :  k  for  k  in  camera_paths  if  k  is  not  None } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . _first_camera_idx  =  min ( camera_paths . keys ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _frame_readers  =  _FrameReaderDict ( camera_paths ,  cache_paths ,  kwargs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _frame_id_lookup  =  frame_id_lookup 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  w ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Width of each frame in pixels. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . _frame_readers [ self . _first_camera_idx ] . w 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  @property 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  h ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Height of each frame in pixels. """ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . _frame_readers [ self . _first_camera_idx ] . h 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  get ( self ,  frame_id ,  * * kwargs ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Get a frame for a route based on frameId. 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								       Inputs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        frame_id :  The  frameId  of  the  returned  frame . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kwargs :  Forwarded  to  BaseFrameReader . get .  " count "  is  not  implemented . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    segment_num ,  segment_id  =  self . _frame_id_lookup . get ( frame_id ,  ( None ,  None ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  segment_num  is  None  or  segment_num  ==  - 1  or  segment_id  ==  - 1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  self . get_from_segment ( segment_num ,  segment_id ,  * * kwargs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  get_from_segment ( self ,  segment_num ,  segment_id ,  * * kwargs ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ Get a frame from a specific segment with a specific index in that segment (segment_id). 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								       Inputs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        segment_num :  The  number  of  the  segment . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        segment_id :  The  index  of  the  return  frame  within  that  segment . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        kwargs :  Forwarded  to  BaseFrameReader . get .  " count "  is  not  implemented . 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    """ 
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  " count "  in  kwargs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      raise  NotImplementedError ( " count " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self . _frame_readers [ segment_num ] . get ( segment_id ,  * * kwargs ) [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  close ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    frs  =  self . _frame_readers 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . _frame_readers . clear ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  fr  in  frs : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      fr . close ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  __enter__ ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  self 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  __exit__ ( self ,  exc_type ,  exc_value ,  traceback ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . close ( )