#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  argparse 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  os 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  struct 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  enum  import  IntEnum 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  typing  import  Tuple 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  openpilot . tools . lib . filereader  import  FileReader 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								DEBUG  =  int ( os . getenv ( " DEBUG " ,  " 0 " ) ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# compare to ffmpeg parsing 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ffmpeg -i <input.hevc> -c copy -bsf:v trace_headers -f null - 2>&1 | grep -B4 -A32 '] 0 ' 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# H.265 specification 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.265-201802-S!!PDF-E&type=items 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NAL_UNIT_START_CODE  =  b " \x00 \x00 \x01 " 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NAL_UNIT_START_CODE_SIZE  =  len ( NAL_UNIT_START_CODE ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NAL_UNIT_HEADER_SIZE  =  2 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  HevcNalUnitType ( IntEnum ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  TRAIL_N  =  0          # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  TRAIL_R  =  1          # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  TSA_N  =  2            # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  TSA_R  =  3            # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  STSA_N  =  4           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  STSA_R  =  5           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RADL_N  =  6           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RADL_R  =  7           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RASL_N  =  8           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RASL_R  =  9           # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_N10  =  10 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_R11  =  11 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_N12  =  12 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_R13  =  13 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_N14  =  14 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL_R15  =  15 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  BLA_W_LP  =  16        # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  BLA_W_RADL  =  17      # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  BLA_N_LP  =  18        # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  IDR_W_RADL  =  19      # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  IDR_N_LP  =  20        # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  CRA_NUT  =  21         # RBSP structure: slice_segment_layer_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_IRAP_VCL22  =  22 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_IRAP_VCL23  =  23 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL24  =  24 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL25  =  25 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL26  =  26 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL27  =  27 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL28  =  28 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL29  =  29 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL30  =  30 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_VCL31  =  31 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  VPS_NUT  =  32         # RBSP structure: video_parameter_set_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SPS_NUT  =  33         # RBSP structure: seq_parameter_set_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PPS_NUT  =  34         # RBSP structure: pic_parameter_set_rbsp( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  AUD_NUT  =  35 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  EOS_NUT  =  36 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  EOB_NUT  =  37 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FD_NUT  =  38 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PREFIX_SEI_NUT  =  39 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SUFFIX_SEI_NUT  =  40 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL41  =  41 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL42  =  42 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL43  =  43 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL44  =  44 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL45  =  45 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL46  =  46 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  RSV_NVCL47  =  47 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC48  =  48 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC49  =  49 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC50  =  50 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC51  =  51 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC52  =  52 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC53  =  53 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC54  =  54 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC55  =  55 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC56  =  56 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC57  =  57 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC58  =  58 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC59  =  59 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC60  =  60 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC61  =  61 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC62  =  62 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNSPEC63  =  63 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# B.2.2 Byte stream NAL unit semantics 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# - The nal_unit_type within the nal_unit( ) syntax structure is equal to VPS_NUT, SPS_NUT or PPS_NUT. 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# - The byte stream NAL unit syntax structure contains the first NAL unit of an access unit in decoding 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#   order, as specified in clause 7.4.2.4.4. 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								HEVC_PARAMETER_SET_NAL_UNITS  =  ( 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . VPS_NUT , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . SPS_NUT , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . PPS_NUT , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 3.29 coded slice segment NAL unit: A NAL unit that has nal_unit_type in the range of TRAIL_N to RASL_R, 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# inclusive, or in the range of BLA_W_LP to RSV_IRAP_VCL23, inclusive, which indicates that the NAL unit 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# contains a coded slice segment 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								HEVC_CODED_SLICE_SEGMENT_NAL_UNITS  =  ( 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . TRAIL_N , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . TRAIL_R , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . TSA_N , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . TSA_R , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . STSA_N , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . STSA_R , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . RADL_N , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . RADL_R , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . RASL_N , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . RASL_R , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . BLA_W_LP , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . BLA_W_RADL , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . BLA_N_LP , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . IDR_W_RADL , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . IDR_N_LP , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  HevcNalUnitType . CRA_NUT , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  VideoFileInvalid ( Exception ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pass 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_ue ( dat :  bytes ,  start_idx :  int ,  skip_bits :  int )  - >  Tuple [ int ,  int ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  prefix_val  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  prefix_len  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suffix_val  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suffix_len  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  i  =  start_idx 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  i  <  len ( dat ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    j  =  7 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  j  > =  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  skip_bits  >  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        skip_bits  - =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elif  prefix_val  ==  0 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prefix_val  =  ( dat [ i ]  >>  j )  &  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prefix_len  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        suffix_val  =  ( suffix_val  <<  1 )  |  ( ( dat [ i ]  >>  j )  &  1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        suffix_len  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      j  - =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  prefix_val  ==  1  and  prefix_len  -  1  ==  suffix_len : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        val  =  2 * * ( prefix_len - 1 )  -  1  +  suffix_val 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size  =  prefix_len  +  suffix_len 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  val ,  size 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    i  + =  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  raise  VideoFileInvalid ( " invalid exponential-golomb code " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  require_nal_unit_start ( dat :  bytes ,  nal_unit_start :  int )  - >  None : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  nal_unit_start  <  1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  ValueError ( " start index must be greater than zero " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  dat [ nal_unit_start : nal_unit_start  +  NAL_UNIT_START_CODE_SIZE ]  !=  NAL_UNIT_START_CODE : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  VideoFileInvalid ( " data must begin with start code " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_hevc_nal_unit_length ( dat :  bytes ,  nal_unit_start :  int )  - >  int : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pos  =  dat . index ( NAL_UNIT_START_CODE ,  nal_unit_start  +  NAL_UNIT_START_CODE_SIZE ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  ValueError : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pos  =  - 1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # length of NAL unit is byte count up to next NAL unit start index 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nal_unit_len  =  ( pos  if  pos  !=  - 1  else  len ( dat ) )  -  nal_unit_start 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  DEBUG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( "   nal_unit_len: " ,  nal_unit_len ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  nal_unit_len 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_hevc_nal_unit_type ( dat :  bytes ,  nal_unit_start :  int )  - >  HevcNalUnitType : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.3.1.2 NAL unit header syntax 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # nal_unit_header( ) {    // descriptor 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   forbidden_zero_bit    f(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   nal_unit_type         u(6) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   nuh_layer_id          u(6) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   nuh_temporal_id_plus1 u(3) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header_start  =  nal_unit_start  +  NAL_UNIT_START_CODE_SIZE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nal_unit_header  =  dat [ header_start : header_start  +  NAL_UNIT_HEADER_SIZE ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  len ( nal_unit_header )  !=  2 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  VideoFileInvalid ( " data to short to contain nal unit header " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  nal_unit_type  =  HevcNalUnitType ( ( nal_unit_header [ 0 ]  >>  1 )  &  0x3F ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  DEBUG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( "   nal_unit_type: " ,  nal_unit_type . name ,  f " ( { nal_unit_type . value } ) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  nal_unit_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_hevc_slice_type ( dat :  bytes ,  nal_unit_start :  int ,  nal_unit_type :  HevcNalUnitType )  - >  Tuple [ int ,  bool ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.3.2.9 Slice segment layer RBSP syntax 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # slice_segment_layer_rbsp( ) { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   slice_segment_header( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   slice_segment_data( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   rbsp_slice_segment_trailing_bits( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # ... 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.3.6.1 General slice segment header syntax 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # slice_segment_header( ) {                                             // descriptor 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   first_slice_segment_in_pic_flag                                     u(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   if( nal_unit_type >= BLA_W_LP && nal_unit_type <= RSV_IRAP_VCL23 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     no_output_of_prior_pics_flag                                      u(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   slice_pic_parameter_set_id                                         ue(v) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   if( !first_slice_segment_in_pic_flag ) { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     if( dependent_slice_segments_enabled_flag ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #       dependent_slice_segment_flag                                    u(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     slice_segment_address                                             u(v) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #   if( !dependent_slice_segment_flag ) { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     for( i = 0; i < num_extra_slice_header_bits; i++ ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #       slice_reserved_flag[ i ]                                        u(1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     slice_type                                                       ue(v) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # ... 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  rbsp_start  =  nal_unit_start  +  NAL_UNIT_START_CODE_SIZE  +  NAL_UNIT_HEADER_SIZE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  skip_bits  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.4.7.1 General slice segment header semantics 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # first_slice_segment_in_pic_flag equal to 1 specifies that the slice segment is the first slice segment of the picture in 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # decoding order. first_slice_segment_in_pic_flag equal to 0 specifies that the slice segment is not the first slice segment 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # of the picture in decoding order. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  is_first_slice  =  dat [ rbsp_start ]  >>  7  &  1  ==  1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  not  is_first_slice : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # TODO: parse dependent_slice_segment_flag and slice_segment_address and get real slice_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # for now since we don't use it return -1 for slice_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ( - 1 ,  is_first_slice ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  skip_bits  + =  1  # skip past first_slice_segment_in_pic_flag 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  nal_unit_type  > =  HevcNalUnitType . BLA_W_LP  and  nal_unit_type  < =  HevcNalUnitType . RSV_IRAP_VCL23 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # 7.4.7.1 General slice segment header semantics 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # no_output_of_prior_pics_flag affects the output of previously-decoded pictures in the decoded picture buffer after the 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    # decoding of an IDR or a BLA picture that is not the first picture in the bitstream as specified in Annex C. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    skip_bits  + =  1  # skip past no_output_of_prior_pics_flag 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.4.7.1 General slice segment header semantics 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # slice_pic_parameter_set_id specifies the value of pps_pic_parameter_set_id for the PPS in use. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # The value of slice_pic_parameter_set_id shall be in the range of 0 to 63, inclusive. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  _ ,  size  =  get_ue ( dat ,  rbsp_start ,  skip_bits ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  skip_bits  + =  size  # skip past slice_pic_parameter_set_id 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.4.3.3.1 General picture parameter set RBSP semanal_unit_lenntics 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # num_extra_slice_header_bits specifies the number of extra slice header bits that are present in the slice header RBSP 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # for coded pictures referring to the PPS. The value of num_extra_slice_header_bits shall be in the range of 0 to 2, inclusive, 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # in bitstreams conforming to this version of this Specification. Other values for num_extra_slice_header_bits are reserved 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # for future use by ITU-T | ISO/IEC. However, decoders shall allow num_extra_slice_header_bits to have any value. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # TODO: get from PPS_NUT pic_parameter_set_rbsp( ) for corresponding slice_pic_parameter_set_id 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  num_extra_slice_header_bits  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  skip_bits  + =  num_extra_slice_header_bits 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # 7.4.7.1 General slice segment header semantics 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # slice_type specifies the coding type of the slice according to Table 7-7. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Table 7-7 - Name association to slice_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # slice_type | Name of slice_type 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     0      | B (B slice) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     1      | P (P slice) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  #     2      | I (I slice) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # unsigned integer 0-th order Exp-Golomb-coded syntax element with the left bit first 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  slice_type ,  _  =  get_ue ( dat ,  rbsp_start ,  skip_bits ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  DEBUG : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    print ( "   slice_type: " ,  slice_type ,  f " (first slice:  { is_first_slice } ) " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  slice_type  >  2 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  VideoFileInvalid ( " slice_type must be 0, 1, or 2 " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  slice_type ,  is_first_slice 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  hevc_index ( hevc_file_name :  str ,  allow_corrupt :  bool = False )  - >  Tuple [ list ,  int ,  bytes ] : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  FileReader ( hevc_file_name )  as  f : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dat  =  f . read ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  len ( dat )  <  NAL_UNIT_START_CODE_SIZE  +  1 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  VideoFileInvalid ( " data is too short " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  dat [ 0 ]  !=  0x00 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    raise  VideoFileInvalid ( " first byte must be 0x00 " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  prefix_dat  =  b " " 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  frame_types  =  list ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  i  =  1  # skip past first byte 0x00 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  i  <  len ( dat ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      require_nal_unit_start ( dat ,  i ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nal_unit_len  =  get_hevc_nal_unit_length ( dat ,  i ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nal_unit_type  =  get_hevc_nal_unit_type ( dat ,  i ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  nal_unit_type  in  HEVC_PARAMETER_SET_NAL_UNITS : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prefix_dat  + =  dat [ i : i + nal_unit_len ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      elif  nal_unit_type  in  HEVC_CODED_SLICE_SEGMENT_NAL_UNITS : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        slice_type ,  is_first_slice  =  get_hevc_slice_type ( dat ,  i ,  nal_unit_type ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  is_first_slice : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          frame_types . append ( ( slice_type ,  i ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      i  + =  nal_unit_len 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  except  Exception  as  e : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  allow_corrupt : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      raise 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    print ( f " ERROR: NAL unit skipped @  { i } \n " ,  str ( e ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  frame_types ,  len ( dat ) ,  prefix_dat 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  main ( )  - >  None : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser  =  argparse . ArgumentParser ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " input_file " ,  type = str ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " output_prefix_file " ,  type = str ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  parser . add_argument ( " output_index_file " ,  type = str ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  args  =  parser . parse_args ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  frame_types ,  dat_len ,  prefix_dat  =  hevc_index ( args . input_file ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  open ( args . output_prefix_file ,  " wb " )  as  f : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f . write ( prefix_dat ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  with  open ( args . output_index_file ,  " wb " )  as  f : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ft ,  fp  in  frame_types : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      f . write ( struct . pack ( " <II " ,  ft ,  fp ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    f . write ( struct . pack ( " <II " ,  0xFFFFFFFF ,  dat_len ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main ( )