ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / video_packetizer.c
1 #include <VLIB/video_codec.h>
2 #include <VLIB/video_packetizer.h>
3 #include <VLIB/Platform/video_utils.h>
4 #include <VLIB/Platform/video_config.h>
5
6 #include <VP_Os/vp_os_malloc.h>
7
8 C_RESULT video_packetizer_init( video_controller_t* controller )
9 {
10   // Internal buffer configuration
11   controller->in_stream.bytes     = vp_os_malloc( DEFAULT_INTERNAL_STREAM_SIZE );
12   controller->in_stream.used      = 0;
13   controller->in_stream.size      = DEFAULT_INTERNAL_STREAM_SIZE;
14   controller->in_stream.index     = 0;
15   controller->in_stream.length    = 32;
16   controller->in_stream.code      = 0;
17   controller->in_stream.endianess = VIDEO_STREAM_LITTLE_ENDIAN;
18
19   return C_OK;
20 }
21
22 C_RESULT video_packetizer_close( video_controller_t* controller )
23 {
24   vp_os_free( controller->in_stream.bytes );
25
26   controller->in_stream.bytes   = NULL;
27   controller->in_stream.used    = 0;
28   controller->in_stream.size    = 0;
29   controller->in_stream.index   = 0;
30   controller->in_stream.length  = 0;
31   controller->in_stream.code    = 0;
32
33   return C_OK;
34 }
35
36 C_RESULT video_cache_stream( video_controller_t* controller, video_stream_t* in )
37 {
38   video_codec_t* video_codec = controller->video_codec;
39
40   return video_codec->cache_stream( controller, in );
41 }
42
43 #ifndef HAS_VIDEO_WRITE_DATA
44
45 // Fill stream->code from right to left with data in parameters (code & length)
46 // New bits are always always inserted at the rigth of stream->code (least significant bits)
47 // This way old bits are put in most significant bits
48 //            31  ....   0    (length-1)    ....    0
49 //  stream <= ------------ <= -----------------------
50 //            stream->bits            code
51 void video_write_data( video_stream_t* const stream, uint32_t code, int32_t length )
52 {
53   while( length > stream->length )
54   {
55     // code's length is bigger than number of our free bits
56     // we put as many bits in cache as possible
57     stream->code <<= stream->length;
58     stream->code  |= code >> (length - stream->length);
59
60     length -= stream->length;  // Compute number of bits left
61     code   &= (1 << length) - 1; // We keep only bits we didn't push in cache
62
63     stream->bytes[stream->index] = stream->code;
64     stream->index++;
65     stream->used += 4;
66
67     stream->code    = 0;
68     stream->length  = 32;
69   }
70
71   if( length > 0 )
72   {
73     // In this case, previous loop ended with case length < stream->length
74     stream->code   <<= length;
75     stream->code    |= code;
76
77     stream->length -= length;
78   }
79 }
80
81 #endif
82
83 C_RESULT video_stuff8( video_stream_t* const stream )
84 {
85   uint32_t length8;
86
87   length8  = (stream->length & ~7); // TODO: Check if generated code use bic on arm
88
89   stream->code    <<= ( stream->length - length8 );
90   stream->length    = length8;
91
92   return C_OK;
93 }
94
95 // Fill code from right to left with length bits from stream->code
96 // Next bits in stream->code to take are always at the left (most significant bits)
97 // This way new bits are put in least significant bits
98 //  (length-1)    ....    0    31  ....   0
99 //  ----------------------- <= ------------ <= stream
100 //         code                stream->bits 
101 C_RESULT video_read_data( video_stream_t* const stream, uint32_t* code, int32_t length )
102 {
103   uint32_t out_code = *code;
104
105   while( length > (32 - stream->length) )
106   {
107     /// We need more bits than available in current read bits
108
109     out_code = (out_code << (32 - stream->length)) | (stream->code >> stream->length);
110     length  -= (32 - stream->length);
111
112     stream->code    = stream->bytes[stream->index];
113     stream->length  = 0;
114     stream->index++;
115   }
116
117   if( length > 0 )
118   {
119     out_code  = (out_code << length) | (stream->code >> ( 32 - length ));
120
121     stream->code  <<= length;
122     stream->length += length;
123   }
124
125   *code = out_code;
126
127   return C_OK;
128 }
129
130 C_RESULT video_peek_data( const video_stream_t* const stream, uint32_t* code, int32_t length )
131 {
132   uint32_t out_code = *code;
133   uint32_t stream_code = stream->code;
134   uint32_t stream_length = stream->length;
135
136   while( length > (32 - (int32_t)stream_length) )
137   {
138     /// We need more bits than available in current read bits
139
140     out_code = (out_code << (32 - stream_length)) | (stream_code >> stream_length);
141     length  -= (32 - stream_length);
142
143     stream_code    = stream->bytes[stream->index];
144     stream_length  = 0;
145   }
146
147   if( length > 0 )
148   {
149     out_code  = (out_code << length) | (stream_code >> ( 32 - length ));
150   }
151
152   *code = out_code;
153
154   return C_OK;
155 }
156
157 C_RESULT video_align8( video_stream_t* const stream )
158 {
159   uint32_t length8, length = stream->length;
160
161   if( length > 0 )
162   {
163     // Do alignment only when stream->length > 0
164     length8  = ( length & ~7); // TODO: Check if generated code use bic on arm
165     if( length8 != length )
166     {
167       length8 += 0x08;
168       stream->code    <<= ( length8 - length );
169       stream->length    = length8;
170     }
171   }
172
173   return C_OK;
174 }