X-Git-Url: http://git.maemo.org/git/?p=mardrone;a=blobdiff_plain;f=mardrone%2FARDrone_SDK_Version_1_8_20110726%2FARDroneLib%2FVLIB%2FP264%2Fp264.c;fp=mardrone%2FARDrone_SDK_Version_1_8_20110726%2FARDroneLib%2FVLIB%2FP264%2Fp264.c;h=c5accad3ce8db9d9349307593d2f4b73c36ee117;hp=0000000000000000000000000000000000000000;hb=9ec9bc13b75d30bc45535c54a652934debfcea92;hpb=ae0a3c2dc0898400aca0dd6b439c5db8044db7b2 diff --git a/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VLIB/P264/p264.c b/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VLIB/P264/p264.c new file mode 100644 index 0000000..c5accad --- /dev/null +++ b/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VLIB/P264/p264.c @@ -0,0 +1,249 @@ +#include +#include + +#include + +#include + +#include + +#ifndef HAS_P264_ENCODE +//TODO: rename this file and this function (something like p264_entropic.c) + +#define PACK_BITS( bits_out, length_out, bits_in, length_in ) \ + bits_out <<= length_in; \ + length_out += length_in; \ + bits_out |= bits_in; + +void p264_encode_int(video_stream_t* const stream, int32_t code) +{ + int32_t sign, length, data, value_code, value_length; + + value_code = 0; + value_length = 0; + /// Encode level + data = code; + + if (data != 0) + { + // sign handling + sign = 0; + if( data < 0 ) + { + data = -data; + sign = 1; + } + + // TODO Check saturation & if level == -128 + length = 32 - clz(data); // number of bits used in level ( = length of level ) + if( length > 1 ) + { + data -= 1 << (length - 1); + length += 1; + } + + PACK_BITS( value_code, value_length, 1, length ); + + length -= 2; + if(length > 0) + { + PACK_BITS( value_code, value_length, data, length ); + } + + PACK_BITS( value_code, value_length, sign, 1 ); + + /// Write output + video_write_data( stream, value_code, value_length ); + } + else + { + video_write_data( stream, 0x01, 2 ); + } +} + +void p264_decode_int(video_stream_t* const stream, int32_t *code) +{ + uint32_t stream_code, stream_length; + int32_t r = 0, z, sign; + + stream_code = stream_length = 0; + + // Peek 32 bits from stream because we know our datas fit in + video_peek_data( stream, &stream_code, 32 ); + + /// Decode level / last + z = clz(stream_code); + + stream_code <<= z + 1; // Skip all zeros & 1 + stream_length += z + 1; + + if( z == 1 ) + { + *code = 0; + } + else + { + if( z == 0 ) + { + z = 1; + r = 1; + } + + stream_length += z; + + stream_code >>= (32 - z); + sign = stream_code & 1; + + if( z != 0 ) + { + r = stream_code >> 1; + r += 1 << (z-1); + } + + *code = sign ? -r : r; + } + + // Do the real Read in stream to consume what we used + video_read_data( stream, &stream_code, stream_length ); + +} + +void p264_encode( video_stream_t* const stream, int32_t level, int32_t run, int32_t not_last ) +{ + int32_t sign, length, data, value_code, value_length; + + /// Encode number of zeros + data = run; + + length = 0; + value_code = 1; + + if( data > 0 ) + { + length = 32 - clz(data); // compute number of bits used in run ( = length of run ) + data -= 1 << ( length - 1 ); // compute value of run + } + + value_length = length + 1; + + length -= 1; + if( length > 0 ) + { + PACK_BITS( value_code, value_length, data, length ); + } + + /// Encode level + data = level; + + // sign handling + sign = 0; + if( data < 0 ) + { + data = -data; + sign = 1; + } + + // TODO Check saturation & if level == -128 + length = 32 - clz(data); // number of bits used in level ( = length of level ) + if( length > 1 ) + { + data -= 1 << (length - 1); + length += 1; + } + + PACK_BITS( value_code, value_length, 1, length ); + + VP_OS_ASSERT( length != 2 ); + + length -= 2; + if(length > 0) + { + PACK_BITS( value_code, value_length, data, length ); + } + + PACK_BITS( value_code, value_length, sign, 1 ); + + /// Encode last + // add sequence for end of block if required + if( not_last == 0 ) + { + PACK_BITS( value_code, value_length, 0x5, 3 ); + } + + /// Write output + video_write_data( stream, value_code, value_length ); +} + +#endif // HAS_UVLC_ENCODE + +C_RESULT p264_decode( video_stream_t* const stream, int32_t* run, uint32_t* level, int32_t* last) +{ + uint32_t stream_code, stream_length; + int32_t r = 0, z, sign; + + stream_code = stream_length = 0; + + // Peek 32 bits from stream because we know our datas fit in + video_peek_data( stream, &stream_code, 32 ); + + + /// Decode number of zeros + z = clz(stream_code); + + stream_code <<= z + 1; // Skip all zeros & 1 + stream_length += z + 1; + + if( z > 1 ) + { + r = stream_code >> (32 - (z-1)); + + stream_code <<= (z-1); + stream_length += (z-1); + + *run = r + (1 << (z-1)); + } + else + { + *run = z; + } + + + /// Decode level / last + z = clz(stream_code); + + stream_code <<= z + 1; // Skip all zeros & 1 + stream_length += z + 1; + + if( z == 1 ) + { + *run = 0; + *last = 1; + } + else + { + if( z == 0 ) + { + z = 1; + r = 1; + } + + stream_length += z; + + stream_code >>= (32 - z); + sign = stream_code & 1; + + if( z != 0 ) + { + r = stream_code >> 1; + r += 1 << (z-1); + } + + *level = sign ? -r : r; + *last = 0; + } + + // Do the real Read in stream to consume what we used + video_read_data( stream, &stream_code, stream_length ); + + return C_OK; +}