Commit a136554e authored by norvell's avatar norvell
Browse files

Merge branch 'rtp-updates-sa4-134-alternative-orientation' into 'rtp-updates-sa4-134'

Rtp updates sa4 134 alternative orientation

See merge request !2414
parents e93e1dd5 17ea1e5e
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@
#define RTP_SR_CODEC_FRAME_SIZE_IN_TOC_BYTE            /* CR for split rendering codec framesize signalling in Toc Byte*/
#define FIX_SPLIT_RENDERING_ON_DECODER_RESTART         /* Re-configure split rendering on decoder restart */
#define RTP_UPDATES_SA4_134                            /* Updates to RTP during SA4 134 */
#define COMPACT_ORIENTATION_PI_DATA

/* ################### Start BE switches ################################# */
/* only BE switches wrt selection floating point code */
+115 −1
Original line number Diff line number Diff line
@@ -106,6 +106,95 @@ static int16_t ivasPayload_convertToQ9( float value )
    return (int16_t) ( value );
}

#ifdef COMPACT_ORIENTATION_PI_DATA
static uint32_t packQuaternion( IVAS_QUATERNION orientation, uint8_t *buffer )
{
    uint32_t nBytes = 0;
    float q[4], q_max;
    uint16_t max_q_idx, n, k;
    uint32_t lWord;

    q[0] = orientation.w;
    q[1] = orientation.x;
    q[2] = orientation.y;
    q[3] = orientation.z;

    max_q_idx = 0;
    q_max = (float) fabs( q[0] );
    for ( n = 1; n < 4; n++ )
    {
        if ( (float) fabs( q[n] ) > q_max )
        {
            q_max = (float) fabs( q[n] );
            max_q_idx = n;
        }
    }

    if ( q[max_q_idx] < 0 )
    {
        for ( n = 0; n < 4; n++ )
        {
            q[n] = -q[n];
        }
    }
    lWord = max_q_idx << 30;

    k = 1;
    for ( n = 0; n < 4; n++ )
    {
        if ( n == max_q_idx )
        {
            continue;
        }
        lWord |= ( ( (int16_t) ( ( q[n] + 1 ) * 1023 * 0.5f ) & MASK_10BIT ) << ( 30 - k * 10 ) );
        k++;
    }

    buffer[nBytes++] = ( lWord >> 24 ) & MASK_8BIT;
    buffer[nBytes++] = ( lWord >> 16 ) & MASK_8BIT;
    buffer[nBytes++] = ( lWord >> 8 ) & MASK_8BIT;
    buffer[nBytes++] = (lWord) &MASK_8BIT;

    return nBytes;
}


static ivas_error unpackQuaternion( const uint8_t *buffer, IVAS_QUATERNION *orientation )
{
    uint32_t i, k, lWord;
    uint16_t max_q_idx, tmp;
    float q[4], qs;

    lWord = ( buffer[0] ) << 24;
    lWord |= ( buffer[1] ) << 16;
    lWord |= ( buffer[2] ) << 8;
    lWord |= buffer[3];

    max_q_idx = ( lWord >> 30 ) & MASK_2BIT;
    k = 1;
    qs = 0.0f;
    for ( i = 0; i < 4; i++ )
    {
        if ( i == max_q_idx )
        {
            continue;
        }
        tmp = ( lWord >> ( 30 - k * 10 ) ) & MASK_10BIT;
        q[i] = tmp / 1023.0f * 2.0f - 1;
        qs += q[i] * q[i];
        k++;
    }
    q[max_q_idx] = sqrtf( 1 - qs );
    orientation->w = q[0];
    orientation->x = q[1];
    orientation->y = q[2];
    orientation->z = q[3];

    return IVAS_ERR_OK;
}

#else

/*-----------------------------------------------------------------------*
 * ivasPayload_convertToQ7()
 *
@@ -119,6 +208,7 @@ static int16_t ivasPayload_convertToQ7( float value )
    return (int16_t) ( value );
}
#endif
#endif

static ivas_error packUnsupportedData( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten )
{
@@ -210,10 +300,14 @@ static ivas_error packOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *b
    buffer[nBytes++] = ( orientation->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */
#ifdef RTP_UPDATES_SA4_134
    buffer[nBytes++] = 4;
#ifdef COMPACT_ORIENTATION_PI_DATA
    nBytes += packQuaternion( orientation->orientation, &buffer[nBytes] );
#else
    buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.w );
    buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.x );
    buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.y );
    buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.z );
#endif
#else
    buffer[nBytes++] = 8;
    nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.w ) );
@@ -262,10 +356,14 @@ static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t
    buffer[nBytes++] = (uint8_t) orientation->numObjects * 4;
    for ( n = 0; n < orientation->numObjects; n++ )
    {
#ifdef COMPACT_ORIENTATION_PI_DATA
        nBytes += packQuaternion( orientation->orientation[n], &buffer[nBytes] );
#else
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].w );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].x );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].y );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].z );
#endif
    }
#else
    buffer[nBytes++] = (uint8_t) orientation->numObjects * 8;
@@ -294,10 +392,14 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte
    }

    piData->size = sizeof( IVAS_PIDATA_ORIENTATION );
#ifdef COMPACT_ORIENTATION_PI_DATA
    unpackQuaternion( buffer, &( orientation->orientation ) );
#else
    orientation->orientation.w = FLOAT_FROM_Q7( (int8_t) buffer[0] );
    orientation->orientation.x = FLOAT_FROM_Q7( (int8_t) buffer[1] );
    orientation->orientation.y = FLOAT_FROM_Q7( (int8_t) buffer[2] );
    orientation->orientation.z = FLOAT_FROM_Q7( (int8_t) buffer[3] );
#endif
#else
    /* Orientation data is 8 bytes */
    if ( numDataBytes != 8 )
@@ -306,12 +408,12 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte
    }

    piData->size = sizeof( IVAS_PIDATA_ORIENTATION );

    orientation->orientation.w = FLOAT_FROM_Q15( readInt16( &buffer[0] ) );
    orientation->orientation.x = FLOAT_FROM_Q15( readInt16( &buffer[2] ) );
    orientation->orientation.y = FLOAT_FROM_Q15( readInt16( &buffer[4] ) );
    orientation->orientation.z = FLOAT_FROM_Q15( readInt16( &buffer[6] ) );
#endif

    return IVAS_ERR_OK;
}

@@ -333,10 +435,14 @@ static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataB

    for ( n = 0; n < ism_orientation->numObjects; n++ )
    {
#ifdef COMPACT_ORIENTATION_PI_DATA
        unpackQuaternion( &buffer[4 * n], &( ism_orientation->orientation[n] ) );
#else
        ism_orientation->orientation[n].w = FLOAT_FROM_Q7( (int8_t) buffer[4 * n] );
        ism_orientation->orientation[n].x = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 1] );
        ism_orientation->orientation[n].y = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 2] );
        ism_orientation->orientation[n].z = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 3] );
#endif
    }
#else
    /* Orientation data is 8 bytes */
@@ -1036,10 +1142,14 @@ static ivas_error packAudioFocusCommon( const IVAS_PIDATA_GENERIC *piData, uint8
#ifdef RTP_UPDATES_SA4_134
    if ( packedSize == 5 || packedSize == 4 )
    {
#ifdef COMPACT_ORIENTATION_PI_DATA
        nBytes += packQuaternion( audioFocus->direction, &buffer[nBytes] );
#else
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.w );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.x );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.y );
        buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.z );
#endif
    }
    if ( packedSize == 5 || packedSize == 1 )
    {
@@ -1084,10 +1194,14 @@ static ivas_error unpackAudioFocusCommon( const uint8_t *buffer, uint32_t numDat
    }
    else
    {
#ifdef COMPACT_ORIENTATION_PI_DATA
        unpackQuaternion( buffer, &( audioFocus->direction ) );
#else
        audioFocus->direction.w = FLOAT_FROM_Q7( (int8_t) buffer[0] );
        audioFocus->direction.x = FLOAT_FROM_Q7( (int8_t) buffer[1] );
        audioFocus->direction.y = FLOAT_FROM_Q7( (int8_t) buffer[2] );
        audioFocus->direction.z = FLOAT_FROM_Q7( (int8_t) buffer[3] );
#endif

        if ( numDataBytes == 5 )
        {
+26 −8
Original line number Diff line number Diff line
@@ -761,11 +761,23 @@ def unpackOrientations(bitstrm: ConstBitStream, piSize: int) -> list[ORIENTATION
        piSize % 4
    ) == 0 and piSize <= 16, "Incorrect PI Data Size for list[ORIENTATION]"
    orientations = list()
    q = [(float)]*4
    qs = 0
    while piSize > 0:
        w = bitstrm.read(8).int / 128.0
        x = bitstrm.read(8).int / 128.0
        y = bitstrm.read(8).int / 128.0
        z = bitstrm.read(8).int / 128.0
        max_q_idx = bitstrm.read(2).uint
        for i in range(0,4):
            if i == max_q_idx:
                continue
            tmp = bitstrm.read(10).uint
            q[i] = (tmp / 1023.0) * 2.0 - 1.0
            qs = qs + q[i]**2
        
        q[max_q_idx] = (1 - qs)**0.5
            
        w = q[0]
        x = q[1]
        y = q[2]
        z = q[3]
        orientations.append(ORIENTATION(w, x, y, z))
        piSize -= 4
    return orientations
@@ -777,10 +789,16 @@ def packOrientations(bitstrm: BitStream, data: any):
        assert (
            type(orientation) == ORIENTATION
        ), "Orientation PI Data expects a data of type list[ORIENTATION]"
        bitstrm.append(f"intbe:8={q7(orientation.w)}")
        bitstrm.append(f"intbe:8={q7(orientation.x)}")
        bitstrm.append(f"intbe:8={q7(orientation.y)}")
        bitstrm.append(f"intbe:8={q7(orientation.z)}")
        q = [orientation.w, orientation.x, orientation.y, orientation.z]
        max_q = max(q, key=abs)
        max_q_idx = q.index(max_q)
        if max_q < 0:
            q = [-x for x in q]
        bitstrm.append(f"uint:2={max_q_idx}")
        for i in range(0,4):
            if i == max_q_idx:
                continue
            bitstrm.append(f"uint:10={(int)((q[i]+1)*1023*1/2)}")


def unpackPositions(bitstrm: ConstBitStream, piSize: int) -> list[POSITION]:
+22 −32
Original line number Diff line number Diff line
@@ -182,12 +182,17 @@ def generateRequests(startTs: int, endTs: int) -> dict:
def generatePiData(startTs: int, endTs: int) -> dict:
    data = dict()

    someOrientation = lambda: ORIENTATION(
        w=2 * random.random() - 1.0,
        x=2 * random.random() - 1.0,
        y=2 * random.random() - 1.0,
        z=2 * random.random() - 1.0,
    )
    def random_unit_quaternion():
        w = 2*random.random() - 1.0
        x = 2*random.random() - 1.0
        y = 2*random.random() - 1.0
        z = 2*random.random() - 1.0
        n = (w*w + x*x + y*y + z*z)**0.5
        if n == 0.0:
            return random_unit_quaternion()
        return ORIENTATION(w/n, x/n, y/n, z/n)

    someOrientation = lambda: random_unit_quaternion()
    somePosition = lambda: POSITION(
        x=random.randint(-32788, 32767) / 100.0,
        y=random.randint(-32788, 32767) / 100.0,
@@ -214,23 +219,8 @@ def generatePiData(startTs: int, endTs: int) -> dict:
    someDIG = lambda: DIEGETIC_TYPE(
        isDigetic=[bool(random.getrandbits(1)) for _ in range(random.randint(1, 5))]
    )
    someAuFocusDirLvl = lambda: AUDIO_FOCUS(
        ORIENTATION(
            w=2 * random.random() - 1.0,
            x=2 * random.random() - 1.0,
            y=2 * random.random() - 1.0,
            z=2 * random.random() - 1.0,
        ),
        level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)),
    )
    someAuFocusDir = lambda: AUDIO_FOCUS(
        ORIENTATION(
            w=2 * random.random() - 1.0,
            x=2 * random.random() - 1.0,
            y=2 * random.random() - 1.0,
            z=2 * random.random() - 1.0,
        )
    )
    someAuFocusDirLvl = lambda: AUDIO_FOCUS(random_unit_quaternion(),level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)),)
    someAuFocusDir = lambda: AUDIO_FOCUS(random_unit_quaternion())
    someAuFocusLvl = lambda: AUDIO_FOCUS(level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)))
    someAuFocusList = [someAuFocusDirLvl, someAuFocusDir, someAuFocusLvl]
    someLatency = lambda: PI_LATENCY(
@@ -278,7 +268,7 @@ def generatePiData(startTs: int, endTs: int) -> dict:
    someNumISM = lambda : ISM_NUM(num=random.randint(1, 4))
    someISMIds = lambda num_ism : ISM_ID(ids=[int(random.getrandbits(8)) for _ in range(num_ism)])
    someISMGains = lambda num_ism : ISM_GAIN(gains=[random.choice([int(random.randint(-24,12)), -128]) for _ in range(num_ism)]) # -128 corresponds to -Inf
    someISMOrientations = lambda num_ism : [ORIENTATION(w=2*random.random()-1.0, x=2*random.random()-1.0, y=2*random.random()-1.0, z=2*random.random()-1.0) for _ in range(num_ism)]
    someISMOrientations = lambda num_ism : [random_unit_quaternion() for _ in range(num_ism)]
    someISMPositions = lambda num_ism : [POSITION( x=random.randint(-32788, 32767)/100.0, y=random.randint(-32788, 32767)/100.0, z=random.randint(-32788, 32767)/100.0) for _ in range(num_ism)]
    someISMPositionsCompact = lambda num_ism : [POSITION( x=random.randint(-1024, 1023)/100.0, y=random.randint(-1024, 1023)/100.0, z=random.randint(-512, 511)/100.0) for _ in range(num_ism)]
    someISMDistanceAttenuations = lambda num_ism : [DISTANCE_ATTENUATION(ref_dist=random.randint(1,64)/10.0, max_dist=random.randint(1,64), roll_off=random.randint(0,40)/10.0) for _ in range(num_ism)]
@@ -330,10 +320,10 @@ def isEqualFrame(refFrame: bytes, dutFrame: bytes):


def isEqualOrientation(ref: ORIENTATION, dut: ORIENTATION):
    assert abs(ref.w - dut.w) < 0.0079, "Scene Orientation PI Data mismatch in w"
    assert abs(ref.x - dut.x) < 0.0079, "Scene Orientation PI Data mismatch in x"
    assert abs(ref.y - dut.y) < 0.0079, "Scene Orientation PI Data mismatch in y"
    assert abs(ref.z - dut.z) < 0.0079, "Scene Orientation PI Data mismatch in z"
    assert abs(abs(ref.w) - abs(dut.w)) < 0.01, "Scene Orientation PI Data mismatch in w"
    assert abs(abs(ref.x) - abs(dut.x)) < 0.01, "Scene Orientation PI Data mismatch in x"
    assert abs(abs(ref.y) - abs(dut.y)) < 0.01, "Scene Orientation PI Data mismatch in y"
    assert abs(abs(ref.z) - abs(dut.z)) < 0.01, "Scene Orientation PI Data mismatch in z"


def isEqualPosition(ref: POSITION, dut: POSITION):
@@ -400,16 +390,16 @@ def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS):
        assert dut.direction is not None, "Audio Focus PI Data missing direction"
    if ref.direction is not None and dut.direction is not None:
        assert (
            abs(ref.direction["w"] - dut.direction.w) < 0.0079
            abs(abs(ref.direction["w"]) - abs(dut.direction.w)) < 0.01
        ), "Audio Focus PI Data mismatch in direction w"
        assert (
            abs(ref.direction["x"] - dut.direction.x) < 0.0079
            abs(abs(ref.direction["x"]) - abs(dut.direction.x)) < 0.01
        ), "Audio Focus PI Data mismatch in direction x"
        assert (
            abs(ref.direction["y"] - dut.direction.y) < 0.0079
            abs(abs(ref.direction["y"]) - abs(dut.direction.y)) < 0.01
        ), "Audio Focus PI Data mismatch in direction y"
        assert (
            abs(ref.direction["z"] - dut.direction.z) < 0.0079
            abs(abs(ref.direction["z"]) - abs(dut.direction.z)) < 0.01
        ), "Audio Focus PI Data mismatch in direction z"
    assert ref.level == dut.level, "Audio Focus PI Data mismatch in level"