Exemple #1
0
def main():
    """
    """
    F = 'bqmall.bin'

    s = BitStream(filename=F)

    nals = list(s.findall('0x000001', bytealigned=True))
    size = [y - x for x, y in zip(nals, nals[1:])]

    for i, n in zip(nals, size):
        print
        print "!! Found NAL @ offset {0:d} ({0:#x})".format((i + 24) / 8)
        read_nal_unit(s, i, n / 8)  # bits to bytes
Exemple #2
0
class H26xParser:
    """
    H.264 extractor for Annex B streams.
    """

    START_CODE_PREFIX = "0x00000001"
    START_CODE_PREFIX_SHORT = "0x000001"
    VALID_CALLBACKS = [
        "sps",
        "pps",
        "slice",
        "aud",
        "nalu"
    ]

    def __init__(self, f, verbose=False, use_bitstream=None):
        """
        Create a new extractor for a .264/h264 file in Annex B format.

        f: input file
        use_bitstream: blob to use as bitstream (for testing)
        verbose: whether to print out NAL structure and fields
        """
        if use_bitstream:
            # testing the parser in a bitstream
            self.file = None
            self.stream = BitStream(use_bitstream)
        else:
            fn, ext = os.path.splitext(os.path.basename(f))
            valid_input_ext = ['.264', '.h264']
            # TODO: extend for H.265
            # valid_input_ext = ['.264', 'h264', '.265', '.h265']
            if not ext in valid_input_ext:
                raise RuntimeError("Valid input types: " + str(valid_input_ext))
            bitstream_file = f
            self.file = bitstream_file
            self.stream = BitStream(filename=bitstream_file)
        self.verbose = verbose
        self.callbacks = {}

    def set_callback(self, name, fun):
        """
        Set a callback function for raw data extracted. The function will be called with the raw
        bytes of the complete NALU. Valid callbacks are:

        - aud: for every AUD found
        - nalu: for every complete NAL unit found
        - sps: for every SPS NAL unit found
        - pps: for every PPS NAL unit found
        - slice: for every VCL NAL unit found with a slice in it (args: data, buffer_size, first_mb_in_slice)

        Raw data for all callbacks never includes the start code, but all the NAL headers, except
        for the "nalu" callback.
        """
        if name not in self.VALID_CALLBACKS:
            raise RuntimeError(name + " is not a valid callback. Choose one of " + str(self.VALID_CALLBACKS) + ".")
        if not callable(fun):
            raise RuntimeError(str(fun) + " is not a callable function")

        self.callbacks[name] = fun

    def __call(self, name, *args):
        """
        Calls a given callback, and silently skips if it is not implemented.

        name: name of the callback, e.g. "nalu", "aud", whatever
        args: will be expanded to the list of arguments, so you can call this with:
              self.__call("foo", arg1, arg2, ...)
        """
        if name not in self.VALID_CALLBACKS:
            return
        if name not in self.callbacks.keys():
            return
        else:
            self.callbacks[name](*args)

    def _get_nalu_positions(self):
        """
        Saves all the NALU positions as bit positions in self.nal_unit_positions
        """
        self.nal_unit_positions = list(self.stream.findall(self.START_CODE_PREFIX, bytealigned=True))
        self.short_nal_unit_positions = list(self.stream.findall(self.START_CODE_PREFIX_SHORT, bytealigned=True))

        if not self.nal_unit_positions and not self.short_nal_unit_positions:
            print("No NALUs found in stream")
            sys.exit(1)

        if not self.nal_unit_positions:
            self.nal_unit_positions = self.short_nal_unit_positions
        else:
            # if there were extraneous 3-byte NAL unit start codes, use them too
            extra_nal_unit_pos = set([max(s - 8, 0) for s in self.short_nal_unit_positions]) - set(self.nal_unit_positions)
            if len(extra_nal_unit_pos) and self.nal_unit_positions:
                if self.verbose:
                    print("Warning: 3-byte extra NAL unit start code found")
                self.nal_unit_positions.extend([s + 8 for s in extra_nal_unit_pos])
                self.nal_unit_positions = sorted(self.nal_unit_positions)

        self.end_of_stream = len(self.stream)
        self.nal_unit_positions.append(self.end_of_stream)
        return self.nal_unit_positions

    def _decode_nalu(self, nalu_bytes):
        """
        Returns nal_unit_type and RBSP payload from a NALU stream
        """
        if "0x" + nalu_bytes[0: 4*8].hex == self.START_CODE_PREFIX:
            start_code = nalu_bytes.read('bytes:4')
        else:
            start_code = nalu_bytes.read('bytes:3')
        forbidden_zero_bit = nalu_bytes.read(1)
        nal_ref_idc = nalu_bytes.read('uint:2')
        nal_unit_type = nalu_bytes.read('uint:5')
        nal_unit_payload = nalu_bytes[nalu_bytes.pos:]

        rbsp_payload = BitStream()
        for i in range(int(len(nal_unit_payload)/8)):
            if len(nal_unit_payload) - nal_unit_payload.pos >= 24 and \
               nal_unit_payload.peek('bits:24') == '0x000003':
                rbsp_payload.append(nal_unit_payload.read('bits:8'))
                rbsp_payload.append(nal_unit_payload.read('bits:8'))
                nal_unit_payload.read('bits:8')
            else:
                if nal_unit_payload.pos == len(nal_unit_payload):
                    continue
                rbsp_payload.append(nal_unit_payload.read('bits:8'))

        return nal_unit_type, rbsp_payload

    def parse(self):
        """
        Parse the bitstream and extract each NALU.
        Call the respective callbacks for each NALU type found.
        """

        self._get_nalu_positions()
        nalu_sps = None
        nalu_pps = None
        for current_nalu_pos, next_nalu_pos in zip(self.nal_unit_positions, islice(self.nal_unit_positions, 1, None)):
            current_nalu_bytepos = int(current_nalu_pos / 8)
            next_nalu_bytepos = int(next_nalu_pos / 8)
            nalu_bytes = self.stream[current_nalu_pos: next_nalu_pos]

            self.__call('nalu', nalu_bytes)

            if self.verbose:
                print("")
                print("========================================================================================================")
                print("")
                print("NALU bytepos:\t[" + str(current_nalu_bytepos) + ", " + str(next_nalu_bytepos - 1) + "]")
                print("NALU offset:\t" + str(current_nalu_bytepos) + " Bytes")
                print("NALU length:\t" + str(next_nalu_bytepos - current_nalu_bytepos) + " Bytes (including start code)")

            current_nalu_stream_segment = BitStream(self.stream[current_nalu_pos: next_nalu_pos])

            nal_unit_type, rbsp_payload = self._decode_nalu(current_nalu_stream_segment)

            if self.verbose:
                print("NALU type:\t" + str(nal_unit_type) + " (" + nalutypes.get_description(nal_unit_type) + ")")
                print("NALU bytes:\t" + str(nalu_bytes))
                print("NALU RBSP:\t" + str(rbsp_payload))
                print("")

            if nal_unit_type == nalutypes.NAL_UNIT_TYPE_SPS:
                nalu_sps = nalutypes.SPS(rbsp_payload, self.verbose)
                self.__call('sps', rbsp_payload)
            elif nal_unit_type == nalutypes.NAL_UNIT_TYPE_PPS:
                nalu_pps = nalutypes.PPS(rbsp_payload, self.verbose)
                self.__call('pps', rbsp_payload)
            elif nal_unit_type == nalutypes.NAL_UNIT_TYPE_AUD:
                aud = nalutypes.AUD(rbsp_payload, self.verbose)
                self.__call('aud', rbsp_payload)
            elif nal_unit_type == nalutypes.NAL_UNIT_TYPE_CODED_SLICE_NON_IDR:
                nalu_slice = nalutypes.CodedSliceNonIDR(rbsp_payload, nalu_sps, nalu_pps, self.verbose)
                self.__call('slice', rbsp_payload)
            elif nal_unit_type == nalutypes.NAL_UNIT_TYPE_CODED_SLICE_IDR:
                nalu_slice = nalutypes.CodedSliceIDR(rbsp_payload, nalu_sps, nalu_pps, self.verbose)
                self.__call('slice', rbsp_payload)
class GmoFile():
  def __init__(self, data = None, offset = 0, filename = None):
    self.data = None
    self.__gim_files = []
    
    self.gimconv = GimConverter()
    
    if not data == None:
      self.load_data(data, offset)
    elif not filename == None:
      self.load_file(filename)
  
  def load_file(self, filename):
    data = BitStream(filename = filename)
    self.load_data(data)
  
  def load_data(self, data, offset = 0):
    if not data[offset * 8 : offset * 8 + GMO_MAGIC.len] == GMO_MAGIC:
      _LOGGER.error("GMO header not found at 0x%04X." % offset)
      return
    
    data.bytepos = offset + GMO_SIZE_OFFSET
    gmo_size = data.read("uintle:32") + GMO_SIZE_DIFF
    
    self.data = BitStream(data[offset * 8 : (offset + gmo_size) * 8])
    
    self.__find_gims()
  
  def save(self, filename):
    with open(filename, "wb") as f:
      self.data.tofile(f)
  
  def __find_gims(self):
    if self.data == None:
      return
    
    self.__gim_files = []
    
    for gim_start in self.data.findall(GIM_MAGIC, bytealigned = True):
      gim_size_pos  = gim_start + (GIM_SIZE_OFFSET * 8) # Bit pos.
      gim_size      = self.data[gim_size_pos : gim_size_pos + 32].uintle + GIM_SIZE_DIFF
      
      # And turn it into a byte position.
      gim_start /= 8
      self.__gim_files.append((gim_start, gim_size))
  
  def gim_count(self):
    return len(self.__gim_files)
  
  def get_gim(self, gim_id):
    if gim_id >= self.gim_count():
      raise GimIndexError("Invalid GIM ID.")
    
    gim_start, gim_size = self.__gim_files[gim_id]
    gim_data = self.data[gim_start * 8 : (gim_start + gim_size) * 8]
    
    return gim_data
  
  def replace_png_file(self, gim_id, filename, quantize_to_fit = True):
  
    if quantize_to_fit:
      quantize_order = [QuantizeType.auto, QuantizeType.index8, QuantizeType.index4]
    else:
      quantize_order = [QuantizeType.auto]
    quantize_id = 0
    
    (fd, temp_gim) = tempfile.mkstemp(suffix = ".gim", prefix = "sdse-")
    os.close(fd) # Don't need the open file handle.
    
    while True:
      self.gimconv.png_to_gim(filename, temp_gim, quantize_order[quantize_id])
      
      try:
        self.replace_gim_file(gim_id, temp_gim)
      except GimSizeError:
        quantize_id += 1
      except GimIndexError:
        os.remove(temp_gim)
        raise
      else:
        # If we didn't except, that means we succeeded, so we can leave.
        _LOGGER.debug("Quantized PNG to %s" % quantize_order[quantize_id])
        break
      
      if quantize_id > len(quantize_order):
        _LOGGER.error("Unable to convert %s into a GIM small enough to insert." % filename)
        break
    
    os.remove(temp_gim)
  
  def replace_gim_file(self, gim_id, filename):
    gim_data = BitStream(filename = filename)
    self.replace_gim(gim_id, gim_data)
  
  def replace_gim(self, gim_id, gim_data):
    if gim_id >= self.gim_count():
      raise GimIndexError("Invalid GIM ID.")
    
    gim_start, gim_size = self.__gim_files[gim_id]
    
    if gim_data.len / 8 > gim_size:
      raise GimSizeError("GIM too large. %d bytes > %d bytes" % (gim_data.len / 8, gim_size))
      # return
    
    self.data.overwrite(gim_data, gim_start * 8)
    
    # Leave the length alone, though, because we know we have that much space
    # to work with from the original GIM file that was there, and there's no
    # point in shrinking that down if someone happens to want to re-replace
    # this GIM file without reloading the whole thing.
  
  def extract(self, directory, to_png = False):
    if not os.path.isdir(directory):
      os.makedirs(directory)
    
    for id in range(self.gim_count()):
      gim = self.get_gim(id)
      
      out_gim = os.path.join(directory, "%04d.gim" % id)
      out_png = os.path.join(directory, "%04d.png" % id)
      
      with open(out_gim, "wb") as f:
        gim.tofile(f)
      
      if to_png:
        self.gimconv.gim_to_png(out_gim, out_png)
        os.remove(out_gim)
Exemple #4
0
def main():
    """
    """

    if args.infile == args.outfile :
        print ('Error! Source and Destination can not be the same file!')
        sys.exit()

    if not os.path.exists(args.infile) :
        print ('Error! Given input file name not found! Please check path given in CMD or set in script code!')
        sys.exit()
    if md_arg_str :
        md = re.findall('\d+',md_arg_str)
        if len(md) != 10 :
            print ('Specified wrong "-masterdisplay" parameter! Please check!\n Example: G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1) or do not specify')
            sys.exit()

    if maxcll :
        mcll = re.findall('\d+',maxcll)
    sei_ok = 0 
    
    F = open (args.infile,'r+b')
    o = open (args.outfile,'wb')

    print ('Parsing the infile:')
    print ('')
    print ('==========================')
    print ('')
    print ('Prepending SEI data')
    s = BitStream(F.read(chunk))
    
    nals = list(s.findall('0x000001', bytealigned=True))
    sps_nals = list(s.findall('0x00000142', bytealigned=True))
    sei_pref_nals = list (s.findall('0x0000014e', bytealigned=True))
    size = [y - x for x,y in zip(nals,nals[1:])]
    sps_pos = list(set(nals).intersection(sps_nals))
    sei_pref_nals_pos = list(set(nals).intersection(sei_pref_nals))
    sps_size = size[nals.index(sps_nals[0])]
    if sei_pref_nals :
        sei_pref_nal_size = ( size[nals.index(sei_pref_nals[0])])
### MAXCLL & MAXFALL ###

    if args.maxcll or md_arg_str :
        sei_forbidden_zero_bit  = 0
        sei_nal_unit_type = 39
        sei_nuh_layer_id = 0
        sei_nuh_temporal_id_plus1 = 1
        new_sei_string = pack ('uint:1,2*uint:6,uint:3',sei_forbidden_zero_bit,sei_nal_unit_type,sei_nuh_layer_id,sei_nuh_temporal_id_plus1)
        print ('Starting new SEI NALu...')

        if maxcll :
            sei_last_payload_type_byte = 144
            sei_last_payload_size_byte = 4
            sei_max_content_light_level = int(mcll[0])
            sei_max_pic_average_light_level = int(mcll[1])
            new_sei_string += pack ('2*uint:8,2*uint:16',sei_last_payload_type_byte,sei_last_payload_size_byte,sei_max_content_light_level,sei_max_pic_average_light_level)
            print ('SEI message with MaxCLL=',sei_max_content_light_level,' and MaxFall=',sei_max_pic_average_light_level,' created in SEI NAL')

        if md_arg_str :
            md_sei_last_payload_type_byte = 137
            md_sei_last_payload_size_byte = 24
            #MD string ref
            #G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)
            new_sei_string += pack ('2*uint:8',md_sei_last_payload_type_byte,md_sei_last_payload_size_byte)
            for i in range (len(md)-2) :
                new_sei_string += pack ('uint:16',int(md[i]))

            new_sei_string += pack ('uint:32',int(md[8]))
            new_sei_string += pack ('uint:32',int(md[9]))

            new_sei_string.replace ('0x0000','0x000003',bytealigned=True)
            print ('SEI message Mastering Display Data',md_arg_str,'created in SEI NAL')     

        new_sei_string = '0x00000001' + new_sei_string + '0x00'
        sei_ok = True



### ------------------ ###   
    
    print ('Looking for SPS.........', sps_pos)
    print ('SPS_Nals_addresses', sps_pos)
    print ('SPS NAL Size', sps_size)
    print ('Starting reading SPS NAL contents')

    
    s.pos = sps_pos[0]
    t = s.peek(sps_size)

    t.pos = t.pos + 24

    forbidden_zero_bit  = t.read('uint:1')
    nal_unit_type = t.read('uint:6')
    nuh_layer_id = t.read('uint:6')
    nuh_temporal_id_plus1 = t.read('uint:3')
    nal_t = t[:]

# 7.3.1.1
    # Convert NAL data (Annex B format) to RBSP data

    t.tobytes()
    t.replace ('0x000003','0x0000')
    
    
# SPS parse block


    sps_video_parameter_set_id = t.read('uint:4')
    sps_max_sub_layers_minus1 = t.read('uint:3')
    sps_temporal_id_nesting_flag = t.read('uint:1')
    ptl = profile_tier_level(t, sps_max_sub_layers_minus1)
    sps_seq_parameter_set_id = t.read('ue')
    chroma_format_idc = t.read('ue')
    if chroma_format_idc == 3:
        separate_colour_plane_flag = t.read('uint:1')
    pic_width_in_luma_samples = t.read ('ue')
    pic_height_in_luma_samples = t.read ('ue')
    conformance_window_flag = t.read ('uint:1')
    if (conformance_window_flag) :
        conf_win_left_offset = t.read('ue')
        conf_win_right_offset = t.read('ue')
        conf_win_top_offset = t.read('ue')
        conf_win_bottom_offset = t.read('ue')
    bit_depth_luma_minus8 = t.read ('ue')
    bit_depth_chroma_minus8 = t.read ('ue')
    log2_max_pic_order_cnt_lsb_minus4 = t.read('ue')
    sps_sub_layer_ordering_info_present_flag = t.read('uint:1')
#   for (i = (sps_sub_layer_ordering_info_present_flag ? 0 : sps.max_sub_layers_minus1); i <= sps.max_sub_layers_minus1; i++)
    if sps_sub_layer_ordering_info_present_flag :
            sps_max_dec_pic_buffering_minus1 = t.read('ue')
            sps_max_num_reorder_pics = t.read('ue')
            sps_max_latency_increase_plus1 = t.read('ue')

    log2_min_luma_coding_block_size_minus3 = t.read ('ue')
    log2_diff_max_min_luma_coding_block_size = t.read ('ue')
    log2_min_luma_transform_block_size_minus2 = t.read ('ue')
    log2_diff_max_min_luma_transform_block_size = t.read ('ue')
    max_transform_hierarchy_depth_inter = t.read ('ue')
    max_transform_hierarchy_depth_intra = t.read ('ue')
    scaling_list_enabled_flag = t.read ('uint:1')
    """
    if( scaling_list_enabled_flag ) {
    sps_scaling_list_data_present_flag u(1)
    if( sps_scaling_list_data_present_flag )
    scaling_list_data( )
    }
    """
    amp_enabled_flag = t.read ('uint:1')
    sample_adaptive_offset_enabled_flag = t.read ('uint:1')
    pcm_enabled_flag = t.read ('uint:1')
    if pcm_enabled_flag :
        pcm_sample_bit_depth_luma_minus1 = t.read ('uint:4')
        pcm_sample_bit_depth_chroma_minus1 = t.read ('uint:4')
        log2_min_pcm_luma_coding_block_size_minus3  = t.read ('ue')
        log2_diff_max_min_pcm_luma_coding_block_size = t.read ('ue')
        pcm_loop_filter_disabled_flag = t.read ('uint:1')
    num_short_term_ref_pic_sets = t.read ('ue')
    if num_short_term_ref_pic_sets :
        for i in range (num_short_term_ref_pic_sets):
            if i != 0 :
                inter_ref_pic_set_prediction_flag = t.read ('uint:1')
        
            if not 'inter_ref_pic_set_prediction_flag' in globals() :
                """    
            
                if i == num_short_term_ref_pic_sets :
                    delta_idx_minus1 = t.read ('ue')
                if not 'delta_idx_minus1' in globals():
                    delta_idx_minus1 = 0
                delta_rps_sign = t.read ('uint:1')
                abs_delta_rps_minus1 = t.read ('ue')
                for j in range (NumDeltaPoc) :
                    used_by_curr_pic_flag[j] = t.read ('uint:1')
                if used_by_curr_pic_flag[j] :
                    use_delta_flag[j] = t.read ('uint:1')
        
             else:      
                """            
            
                num_negative_pics = t.read ('ue')
                num_positive_pics = t.read ('ue')
                delta_poc_s0_minus1 = [t.read ('ue') for _ in range (num_negative_pics)]
                used_by_curr_pic_s0_flag = [ t.read ('uint:1') for _ in range (num_negative_pics)]
                delta_poc_s1_minus1 = [t.read ('ue') for _ in range(num_positive_pics)]
                used_by_curr_pic_s1_flag = [t.read ('uint:1') for _ in range(num_positive_pics)]

          
    long_term_ref_pics_present_flag = t.read ('uint:1')
    if long_term_ref_pics_present_flag :
        num_long_term_ref_pics_sps = t.read ('ue')
        
        for i in range < (num_long_term_ref_pics_sps): 
            lt_ref_pic_poc_lsb_sps[i] = t.read ('ue')
            used_by_curr_pic_lt_sps_flag[i] = t.read ('uint:1')
       
    sps_temporal_mvp_enabled_flag = t.read ('uint:1')
    strong_intra_smoothing_enabled_flag = t.read ('uint:1')
    vui_parameters_present_flag = t.read ('uint:1')
    if vui_parameters_present_flag :
       vp = vui_parameters(t)
    sps_extension_present_flag = t.read ('uint:1')
    if sps_extension_present_flag :
        sps_range_extension_flag = t.read ('uint:1')
        sps_multilayer_extension_flag = t.read ('uint:1')
        sps_3d_extension_flag = t.read ('uint:1')
        sps_extension_5bits = t.read ('uint:1')
    tb = rbsp_trailing_bits(t,len(t))
    print ('Reading of SPS NAL finished. Read ',len(t),' of SPS NALu data.\n')
    
# print block
    """
    print ('sps_video_parameter_set_id', sps_video_parameter_set_id)
    print ('sps_max_sub_layers_minus1', sps_max_sub_layers_minus1)
    print ('sps_temporal_id_nesting_flag', sps_temporal_id_nesting_flag)
    ptl.show()
    print ('sps_seq_parameter_set_id', sps_seq_parameter_set_id)
    print ('chroma_format_idc', chroma_format_idc)
    if chroma_format_idc == 3:
        print ('separate_colour_plane_flag', separate_colour_plane_flag)
    print ('pic_width_in_luma_samples ', pic_width_in_luma_samples) #produces wrong number
    print ('pic_height_in_luma_samples', pic_height_in_luma_samples) #produces wrong number
    print ('conformance_window_flag', conformance_window_flag)
    print ('bit_depth_luma_minus8', bit_depth_luma_minus8)
    print ('bit_depth_chroma_minus8', bit_depth_chroma_minus8)
    print ('log2_max_pic_order_cnt_lsb_minus4', log2_max_pic_order_cnt_lsb_minus4)
    print ('sps_sub_layer_ordering_info_present_flag', sps_sub_layer_ordering_info_present_flag)

    if sps_sub_layer_ordering_info_present_flag :
       print ('sps_max_dec_pic_buffering_minus1', sps_max_dec_pic_buffering_minus1)
       print ('sps_max_num_reorder_pics', sps_max_num_reorder_pics)
       print ('sps_max_latency_increase_plus1', sps_max_latency_increase_plus1)
    
    print ('log2_min_luma_coding_block_size_minus3',log2_min_luma_coding_block_size_minus3)
    print ('log2_diff_max_min_luma_coding_block_size',log2_diff_max_min_luma_coding_block_size)
    print ('log2_min_luma_transform_block_size_minus2',log2_min_luma_transform_block_size_minus2)
    print ('log2_diff_max_min_luma_transform_block_size', log2_diff_max_min_luma_transform_block_size)
    print ('max_transform_hierarchy_depth_inter', max_transform_hierarchy_depth_inter)
    print ('max_transform_hierarchy_depth_intra', max_transform_hierarchy_depth_intra)
    print ('scaling_list_enabled_flag',scaling_list_enabled_flag)
    print ('amp_enabled_flag',amp_enabled_flag)
    print ('sample_adaptive_offset_enabled_flag',sample_adaptive_offset_enabled_flag)
    print ('pcm_enabled_flag',pcm_enabled_flag)
    if pcm_enabled_flag :
        print ('pcm_sample_bit_depth_luma_minus1',pcm_sample_bit_depth_luma_minus1)
        print ('pcm_sample_bit_depth_chroma_minus1',pcm_sample_bit_depth_chroma_minus1)
        print ('log2_min_pcm_luma_coding_block_size_minus3',log2_min_pcm_luma_coding_block_size_minus3)
        print ('log2_diff_max_min_pcm_luma_coding_block_size',log2_diff_max_min_pcm_luma_coding_block_size)
        print ('pcm_loop_filter_disabled_flag',pcm_loop_filter_disabled_flag)
    print ('num_short_term_ref_pic_sets',num_short_term_ref_pic_sets)
    print ('long_term_ref_pics_present_flag',long_term_ref_pics_present_flag)
    print ('sps_temporal_mvp_enabled_flag',sps_temporal_mvp_enabled_flag)
    print ('strong_intra_smoothing_enabled_flag',strong_intra_smoothing_enabled_flag)
    print ('vui_parameters_present_flag',vui_parameters_present_flag)
    if vui_parameters_present_flag :
        vp.show()
    print ('sps_extension_present_flag',sps_extension_present_flag)
    """
# New BS write Block
    print ('Making modified SPS NALu...')
    new_bs = BitStream()
    new_bs += pack('uint:4,uint:3,uint:1',sps_video_parameter_set_id,sps_max_sub_layers_minus1,sps_temporal_id_nesting_flag)
    new_bs += pack ('uint:2,uint:1,uint:5',ptl.general_profile_space, ptl.general_tier_flag,ptl.general_profile_idc)
    for i in range (32) :
        new_bs += pack('uint:1',int(ptl.general_profile_compatibility_flag[i]))
    new_bs += pack ('uint:1',ptl.general_progressive_source_flag)
    new_bs += pack ('uint:1',ptl.general_interlaced_source_flag)
    new_bs += pack ('uint:1',ptl.general_non_packed_constraint_flag)
    new_bs += pack ('uint:1',ptl.general_frame_only_constraint_flag)
    new_bs += pack ('uint:44',ptl.general_reserved_zero_44bits)
    new_bs += pack ('uint:8',ptl.general_level_idc)
    new_bs += pack ('ue',sps_seq_parameter_set_id)
    new_bs += pack ('ue',chroma_format_idc)
    if chroma_format_idc == 3:
        new_bs += pack ('uint:1',separate_colour_plane_flag)
    new_bs += pack ('ue',pic_width_in_luma_samples)
    new_bs += pack ('ue',pic_height_in_luma_samples)
    new_bs += pack ('uint:1',conformance_window_flag)
    if (conformance_window_flag) :
        new_bs += pack ('ue',conf_win_left_offset)
        new_bs += pack ('ue',conf_win_right_offset)
        new_bs += pack ('ue',conf_win_top_offset)
        new_bs += pack ('ue',conf_win_bottom_offset)
    new_bs += pack ('ue',bit_depth_luma_minus8)
    new_bs += pack ('ue',bit_depth_chroma_minus8)
    new_bs += pack ('ue',log2_max_pic_order_cnt_lsb_minus4)
    new_bs += pack ('uint:1',sps_sub_layer_ordering_info_present_flag)
#   for (i = (sps_sub_layer_ordering_info_present_flag ? 0 : sps.max_sub_layers_minus1); i <= sps.max_sub_layers_minus1; i++)
    if sps_sub_layer_ordering_info_present_flag :
            new_bs += pack ('ue',sps_max_dec_pic_buffering_minus1)
            new_bs += pack ('ue',sps_max_num_reorder_pics)
            new_bs += pack ('ue',sps_max_latency_increase_plus1)
    new_bs += pack ('ue',log2_min_luma_coding_block_size_minus3)
    new_bs += pack ('ue',log2_diff_max_min_luma_coding_block_size)
    new_bs += pack ('ue',log2_min_luma_transform_block_size_minus2)
    new_bs += pack ('ue',log2_diff_max_min_luma_transform_block_size)
    new_bs += pack ('ue',max_transform_hierarchy_depth_inter)
    new_bs += pack ('ue',max_transform_hierarchy_depth_intra)
    new_bs += pack ('uint:1',scaling_list_enabled_flag)
    #
    new_bs += pack ('uint:1',amp_enabled_flag)
    new_bs += pack ('uint:1',sample_adaptive_offset_enabled_flag)
    new_bs += pack ('uint:1',pcm_enabled_flag)
    if pcm_enabled_flag :
        new_bs += pack ('uint:4',pcm_sample_bit_depth_luma_minus1)
        new_bs += pack ('uint:4',pcm_sample_bit_depth_chroma_minus1)
        new_bs += pack ('ue',log2_min_pcm_luma_coding_block_size_minus3)
        new_bs += pack ('ue',log2_diff_max_min_pcm_luma_coding_block_size)
        new_bs += pack ('uint:1',pcm_loop_filter_disabled_flag)
    new_bs += pack ('ue',num_short_term_ref_pic_sets)


    if num_short_term_ref_pic_sets :
        for i in range (num_short_term_ref_pic_sets) :
            if i != 0 :
                new_bs += pack ('uint:1',inter_ref_pic_set_prediction_flag)

        
        
            if  not 'inter_ref_pic_set_prediction_flag' in globals() :
                """     
                if i == num_short_term_ref_pic_sets :
                    new_bs += pack ('ue',delta_idx_minus1)
                new_bs += pack ('uint:1', delta_rps_sign)
                new_bs += pack ('ue',abs_delta_rps_minus1)
                for j in range (NumDeltaPocs[i - (delta_idx_minus1 +1)]) :
                    new_bs += pack ('uint:1', used_by_curr_pic_flag[j])
                    if used_by_curr_pic_flag[j] :
                        new_bs += pack ('uint:1',use_delta_flag[j])
        
            else :
                """    
                new_bs += pack ('ue',num_negative_pics)
                new_bs += pack ('ue',num_positive_pics)
                new_bs += [pack ('ue',delta_poc_s0_minus1[_]) for _ in range (num_negative_pics)]
                new_bs += [pack ('uint:1',used_by_curr_pic_s0_flag[_]) for _ in range (num_negative_pics)]
                new_bs += [pack ('ue',delta_poc_s1_minus1[_]) for _ in range(num_positive_pics)]
                new_bs += [pack ('uint:1',used_by_curr_pic_s1_flag[_]) for _ in range(num_positive_pics)]
        

    new_bs += pack ('uint:1',long_term_ref_pics_present_flag)
    if long_term_ref_pics_present_flag :
        new_bs += pack ('ue',num_long_term_ref_pics_sps)
    new_bs += pack ('uint:1',sps_temporal_mvp_enabled_flag)
    new_bs += pack ('uint:1',strong_intra_smoothing_enabled_flag)
    new_bs += pack ('uint:1',vui_parameters_present_flag)
# VUI VP pack Section
    if vui_parameters_present_flag :
       new_bs += pack ('uint:1',vp.aspect_ratio_info_present_flag)
       if vp.aspect_ratio_info_present_flag :
            new_bs += pack ('uint:8',vp.aspect_ratio_idc)
            if vp.aspect_ratio_idc == 255 :
                new_bs += pack ('uint:16',vp.sar_width)
                new_bs += pack ('uint:16',vp.sar_height)
       new_bs += pack ('uint:1',vp.overscan_info_present_flag)
       if vp.overscan_info_present_flag :
           new_bs += pack ('uint:1',vp.overscan_appropriate_flag)
       new_bs += pack ('uint:1',vp.video_signal_type_present_flag)
       if vp.video_signal_type_present_flag :
           new_bs += pack ('uint:3',vp.video_format)
           new_bs += pack ('uint:1',vp.video_full_range_flag)
           new_bs += pack ('uint:1',vp.colour_description_present_flag)
           if vp.colour_description_present_flag :
               new_bs += pack ('uint:8',vp.colour_primaries)
               new_bs += pack ('uint:8',vp.transfer_characteristics)
               new_bs += pack ('uint:8',vp.matrix_coeffs)
       new_bs += pack ('uint:1',vp.chroma_loc_info_present_flag)
       if vp.chroma_loc_info_present_flag :
           new_bs += pack ('ue',vp.chroma_sample_loc_type_top_field)
           new_bs += pack ('ue',vp.chroma_sample_loc_type_bottom_field)
       new_bs += pack ('uint:1',vp.neutral_chroma_indication_flag)
       new_bs += pack ('uint:1',vp.field_seq_flag)
       new_bs += pack ('uint:1',vp.frame_field_info_present_flag)
       new_bs += pack ('uint:1',vp.default_display_window_flag)
       if vp.default_display_window_flag :
           new_bs += pack ('ue',vp.def_disp_win_left_offset)
           new_bs += pack ('ue',vp.def_disp_win_right_offset)
           new_bs += pack ('ue',vp.def_disp_win_top_offset)
           new_bs += pack ('ue',vp.def_disp_win_bottom_offset)
       new_bs += pack ('uint:1',vp.vui_timing_info_present_flag)
       if vp.vui_timing_info_present_flag :
           new_bs += pack ('uint:32',vp.vui_num_units_in_tick)
           new_bs += pack ('uint:32',vp.vui_time_scale)
           new_bs += pack ('uint:1',vp.vui_poc_proportional_to_timing_flag)
           if vp.vui_poc_proportional_to_timing_flag :
               new_bs += pack ('ue',vp.vui_num_ticks_poc_diff_one_minus1)
           new_bs += pack ('uint:1',vp.vui_hrd_parameters_present_flag)
           """
           if( vui_hrd_parameters_present_flag )
           hrd_parameters( 1, sps_max_sub_layers_minus1 )
           """
       new_bs += pack ('uint:1',vp.bitstream_restriction_flag)
       if vp. bitstream_restriction_flag :
           new_bs += pack ('uint:1',vp.tiles_fixed_structure_flag)
           new_bs += pack ('uint:1',vp.motion_vectors_over_pic_boundaries_flag)
           new_bs += pack ('uint:1',vp.restricted_ref_pic_lists_flag)
           new_bs += pack ('ue',vp.min_spatial_segmentation_idc)
           new_bs += pack ('ue',vp.max_bytes_per_pic_denom)
           new_bs += pack ('ue',vp.max_bits_per_min_cu_denom)
           new_bs += pack ('ue',vp.log2_max_mv_length_horizontal)
           new_bs += pack ('ue',vp.log2_max_mv_length_vertical)

    new_bs += pack ('uint:1',sps_extension_present_flag)
    if sps_extension_present_flag :
        new_bs += pack ('uint:1',sps_range_extension_flag)
        new_bs += pack ('uint:1',sps_multilayer_extension_flag)
        new_bs += pack ('uint:1',sps_3d_extension_flag)
        new_bs += pack ('uint:1',sps_extension_5bits)

    new_bs += pack ('uint:1',tb.rbsp_stop_one_bit)
    while len(new_bs) < t.pos :
        new_bs += pack ('uint:1',tb.rbsp_alignment_zero_bit)

#    self.sub_layer_profile_present_flag = []
#    self.sub_layer_level_present_flag = []
#    for i in range(maxNumSubLayersMinus1):
#        self.sub_layer_profile_present_flag.append(t.read('uint:1'))
#        self.sub_layer_level_present_flag.append(t.read('uint:1'))
    
    pre_new_bs = pack ('uint:1,2*uint:6,uint:3', forbidden_zero_bit,nal_unit_type,nuh_layer_id,nuh_temporal_id_plus1)
    new_bs.replace ('0x0000','0x000003',bytealigned=True)
    new_bs = pre_new_bs + new_bs + '0x00'
    nal_t_rep = nal_t[24:]
    repl = s.replace (nal_t_rep,new_bs, bytealigned=True)
    print ('Made modified SPS NALu - OK')
    if sei_ok :
        s.prepend (new_sei_string)
        print ('New SEI prepended')
    print ('Writing new stream...')
    s.tofile(o)
    progr = chunk
    while True:
        s = F.read(chunk)
        o.write(s)
        if progr < os.path.getsize(args.infile):
            print ('\rProgress ',int(round((progr/os.path.getsize(args.infile))*100)),'%',end='')
        progr = progr + chunk
        if not s:
            break
    o.close()
    F.close()
    print ('\rProgress: 100 %')
    print ('=====================')
    print ('Done!')
    print ('')
    print ('File ',args.outfile,' created.')
    sys.exit()
import sys
import bitstring
import shutil
import random
import pandas as pd
import subprocess

from bitstring import BitStream, BitArray, ConstBitStream, pack
name = str(sys.argv[1])
name = name.split('.')[0]
s = BitStream(filename=str(sys.argv[1]))  # take the file name
posu = None
if (len(sys.argv) == 3):
    posu = str(sys.argv[2])
pcksTOPs = list(
    s.findall('0x00000001',
              bytealigned=True))  # All frame headers includes VPS,SPS and PPS
pcks = list(s.findall(
    '0x000001',
    bytealigned=True))  # Find NAL for slices includes VPS,SPS,PPS and SEI
pcksAdj = [
    p + 8 for p in pcksTOPs
]  # +8 to bring the postion to first of 0x00'000001 from 0x'00000001) to compare positions found
b = set(pcksAdj)
allowedIDS = [i for i, item in enumerate(pcks) if item not in b]
del allowedIDS[0:12]  # exclude SEI NAL which has delimiter 0x000001


def conceal_p1(s, posi):
    #constants:
    NAL_header = 16
    NAL_delimiter = 24
Exemple #6
0
class GmoFile():
    def __init__(self, data=None, offset=0, filename=None):
        self.data = None
        self.__gim_files = []

        self.gimconv = GimConverter()

        if not data == None:
            self.load_data(data, offset)
        elif not filename == None:
            self.load_file(filename)

    def load_file(self, filename):
        data = BitStream(filename=filename)
        self.load_data(data)

    def load_data(self, data, offset=0):
        if not data[offset * 8:offset * 8 + GMO_MAGIC.len] == GMO_MAGIC:
            _LOGGER.error("GMO header not found at 0x%04X." % offset)
            return

        data.bytepos = offset + GMO_SIZE_OFFSET
        gmo_size = data.read("uintle:32") + GMO_SIZE_DIFF

        self.data = BitStream(data[offset * 8:(offset + gmo_size) * 8])

        self.__find_gims()

    def save(self, filename):
        with open(filename, "wb") as f:
            self.data.tofile(f)

    def __find_gims(self):
        if self.data == None:
            return

        self.__gim_files = []

        for gim_start in self.data.findall(GIM_MAGIC, bytealigned=True):
            gim_size_pos = gim_start + (GIM_SIZE_OFFSET * 8)  # Bit pos.
            gim_size = self.data[gim_size_pos:gim_size_pos +
                                 32].uintle + GIM_SIZE_DIFF

            # And turn it into a byte position.
            gim_start /= 8
            self.__gim_files.append((gim_start, gim_size))

    def gim_count(self):
        return len(self.__gim_files)

    def get_gim(self, gim_id):
        if gim_id >= self.gim_count():
            raise GimIndexError("Invalid GIM ID.")

        gim_start, gim_size = self.__gim_files[gim_id]
        gim_data = self.data[gim_start * 8:(gim_start + gim_size) * 8]

        return gim_data

    def replace_png_file(self, gim_id, filename, quantize_to_fit=True):

        if quantize_to_fit:
            quantize_order = [
                QuantizeType.auto, QuantizeType.index8, QuantizeType.index4
            ]
        else:
            quantize_order = [QuantizeType.auto]
        quantize_id = 0

        (fd, temp_gim) = tempfile.mkstemp(suffix=".gim", prefix="sdse-")
        os.close(fd)  # Don't need the open file handle.

        while True:
            self.gimconv.png_to_gim(filename, temp_gim,
                                    quantize_order[quantize_id])

            try:
                self.replace_gim_file(gim_id, temp_gim)
            except GimSizeError:
                quantize_id += 1
            except GimIndexError:
                os.remove(temp_gim)
                raise
            else:
                # If we didn't except, that means we succeeded, so we can leave.
                _LOGGER.debug("Quantized PNG to %s" %
                              quantize_order[quantize_id])
                break

            if quantize_id > len(quantize_order):
                _LOGGER.error(
                    "Unable to convert %s into a GIM small enough to insert." %
                    filename)
                break

        os.remove(temp_gim)

    def replace_gim_file(self, gim_id, filename):
        gim_data = BitStream(filename=filename)
        self.replace_gim(gim_id, gim_data)

    def replace_gim(self, gim_id, gim_data):
        if gim_id >= self.gim_count():
            raise GimIndexError("Invalid GIM ID.")

        gim_start, gim_size = self.__gim_files[gim_id]

        if gim_data.len / 8 > gim_size:
            raise GimSizeError("GIM too large. %d bytes > %d bytes" %
                               (gim_data.len / 8, gim_size))
            # return

        self.data.overwrite(gim_data, gim_start * 8)

        # Leave the length alone, though, because we know we have that much space
        # to work with from the original GIM file that was there, and there's no
        # point in shrinking that down if someone happens to want to re-replace
        # this GIM file without reloading the whole thing.

    def extract(self, directory, to_png=False):
        if not os.path.isdir(directory):
            os.makedirs(directory)

        for id in range(self.gim_count()):
            gim = self.get_gim(id)

            out_gim = os.path.join(directory, "%04d.gim" % id)
            out_png = os.path.join(directory, "%04d.png" % id)

            with open(out_gim, "wb") as f:
                gim.tofile(f)

            if to_png:
                self.gimconv.gim_to_png(out_gim, out_png)
                os.remove(out_gim)