简体   繁体   中英

output mismatching when porting a python from python2 env to python3 env

I am porting a python code which was written in python2 into the latest python3.7. I made some minor changes in syntax without changing the main logic such that it could run in the python3 environment without error. Both codes running correctly giving outputs in "bytearray" but the outputs are not same in both cases.

This code try to create h264 Nal Unit for web streaming.The method is right, its is working in python2 but in python3 it is not working.

I thought I have made some mistakes that is why python3 code giving a different output. I have tried my best but I didn't find any mistake by myself.

I have posted below both python2 and python3 code. My humble request to please help me to find my error in python3 code.

The python2 code is

import json

capture_settings= [{"framerate": 30, "width": 1280, "height": 720, "bitrate": 17000000, "overlay": False, "gop_size": 30}]

SEI_UUID_CAMERA_SETTINGS = bytearray(b'\x08\x94\xfc\xa2\x58\xce\x45\x02\x8f\x18\xc0\x8c\x68\xe5\x32\x35')
#print(len(SEI_UUID_CAMERA_SETTINGS))
#""" encode values >= 255 as 0xff0xff..0xresidual """
def encode_multibyte_value(value):
    """ encode values >= 255 as 0xff0xff..0xresidual """

    encoded = bytearray()

    while (value >= 255):
        encoded += bytearray(chr(255))
        value -= 255

    encoded += bytearray(chr(value))

    return encoded

def escape_bytearray(input):
    """ escape 000 to 0030, 001 to 0031, 002 to 0032 and 003 to 0033 """
    output = bytearray()

    history1 = None
    history2 = None

    for b in input:
        if (history1==0) and (history2==0) and (b <= 3):
            output += chr(3)
            history1 = 3
            history2 = b
        else:
            history1 = history2
            history2 = b

        output += chr(b)    

    return output


def create_sei_nal_unit(uuid, payload_string):
    """ create a 'user data unregistered' SEI nal unit in a bytearray """

    assert(bytearray == type(uuid))
    print(uuid)

    uuid_length = len(uuid)
    assert(16 == uuid_length)   

    nal_unit_prefix = bytearray(b'\x00\x00\x00\x01')
    nal_unit_type = bytearray(chr(6))                   # 6 = SEI

    encoded_payload_type = encode_multibyte_value(5)    # 5 = 'user data unregistered'

    payload = bytearray(payload_string)

    encoded_payload_size = encode_multibyte_value(uuid_length + len(payload))
    print(uuid + payload)
    escaped_payload = escape_bytearray(uuid + payload)


    trailing_bits = bytearray(b'\x80')

    sei_nal_unit = ( nal_unit_prefix
                   + nal_unit_type
                   + encoded_payload_type
                   + encoded_payload_size
                   + escaped_payload
                   + trailing_bits )

    return sei_nal_unit

sei_nal_unit = create_sei_nal_unit(SEI_UUID_CAMERA_SETTINGS, json.dumps(capture_settings))
print(sei_nal_unit)
print(type(sei_nal_unit))

The output is

x���X�E���h�25[{"overlay": false, "gop_size": 30, "framerate": 30, "height": 720, "width": 1280, "bitrate": 17000000}]�

Python 3 code is

 import json


capture_settings= [{"framerate": 30, "width": 1280, "height": 720, "bitrate": 17000000, "overlay": False, "gop_size": 30}]

SEI_UUID_CAMERA_SETTINGS = b'\x08\x94\xfc\xa2\x58\xce\x45\x02\x8f\x18\xc0\x8c\x68\xe5\x32\x35'
#print(len(SEI_UUID_CAMERA_SETTINGS))
#""" encode values >= 255 as 0xff0xff..0xresidual """
def encode_multibyte_value(value):
    """ encode values >= 255 as 0xff0xff..0xresidual """

    encoded = bytes()

    while (value >= 255):
        encoded += bytes(chr(255).encode('utf-8'))
        value -= 255

    encoded += bytes(chr(value).encode('utf-8'))

    return encoded

def escape_bytearray(input):
    """ escape 000 to 0030, 001 to 0031, 002 to 0032 and 003 to 0033 """
    output = bytes()

    history1 = None
    history2 = None

    for b in input:
        if (history1==0) and (history2==0) and (b <= 3):
            output += b'\x03'
            history1 = 3
            history2 = b
        else:
            history1 = history2
            history2 = b

        output += chr(b).encode('utf-8')    

    return output


def create_sei_nal_unit(uuid, payload_string):
    """ create a 'user data unregistered' SEI nal unit in a bytearray """

    assert(bytes == type(uuid))

    uuid_length = len(uuid)
    assert(16 == uuid_length)   

    nal_unit_prefix = b'\x00\x00\x00\x01'
    nal_unit_type = b'\x06'                  # 6 = SEI
    encoded_payload_type = encode_multibyte_value(5)    # 5 = 'user data unregistered'

    payload = bytes(payload_string)

    encoded_payload_size = encode_multibyte_value(uuid_length + len(payload))
    escaped_payload = escape_bytearray(uuid + payload)


    trailing_bits = b'\x80'

    sei_nal_unit = ( nal_unit_prefix
                   + nal_unit_type
                   + encoded_payload_type
                   + encoded_payload_size
                   + escaped_payload
                   + trailing_bits )

    return sei_nal_unit

sei_nal_unit = create_sei_nal_unit(SEI_UUID_CAMERA_SETTINGS, json.dumps(capture_settings).encode('utf-8'))
print(sei_nal_unit)
print(type(sei_nal_unit)

Output is

b'\x00\x00\x00\x01\x06\x05x\x08\xc2\x94\xc3\xbc\xc2\xa2X\xc3\x8eE\x02\xc2\x8f\x18\xc3\x80\xc2\x8ch\xc3\xa525[{"framerate": 30, "width": 1280, "height": 720, "bitrate": 17000000, "overlay": false, "gop_size": 30}]\x80'

That is a bytestring, indicated by the b prefix. To decode it to a string literal, just use stringvar.decode('utf-8') .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM