summaryrefslogtreecommitdiff
path: root/apps/codecs/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/lib')
-rw-r--r--apps/codecs/lib/ffmpeg_bitstream.c8
-rw-r--r--apps/codecs/lib/ffmpeg_get_bits.h11
-rw-r--r--apps/codecs/lib/ffmpeg_intreadwrite.h484
-rw-r--r--apps/codecs/lib/ffmpeg_put_bits.h323
4 files changed, 813 insertions, 13 deletions
diff --git a/apps/codecs/lib/ffmpeg_bitstream.c b/apps/codecs/lib/ffmpeg_bitstream.c
index be0a3a11f6..542f2671e5 100644
--- a/apps/codecs/lib/ffmpeg_bitstream.c
+++ b/apps/codecs/lib/ffmpeg_bitstream.c
@@ -30,7 +30,8 @@
30 30
31//#include "avcodec.h" 31//#include "avcodec.h"
32#include "ffmpeg_get_bits.h" 32#include "ffmpeg_get_bits.h"
33//#include "put_bits.h" 33#include "ffmpeg_put_bits.h"
34#include "ffmpeg_intreadwrite.h"
34 35
35#define av_log(...) 36#define av_log(...)
36 37
@@ -65,6 +66,7 @@ void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
65 if(terminate_string) 66 if(terminate_string)
66 put_bits(pb, 8, 0); 67 put_bits(pb, 8, 0);
67} 68}
69#endif
68 70
69void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length) 71void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
70{ 72{
@@ -74,7 +76,7 @@ void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
74 76
75 if(length==0) return; 77 if(length==0) return;
76 78
77 if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){ 79 if(words < 16 || put_bits_count(pb)&7){
78 for(i=0; i<words; i++) put_bits(pb, 16, AV_RB16(src + 2*i)); 80 for(i=0; i<words; i++) put_bits(pb, 16, AV_RB16(src + 2*i));
79 }else{ 81 }else{
80 for(i=0; put_bits_count(pb)&31; i++) 82 for(i=0; put_bits_count(pb)&31; i++)
@@ -86,7 +88,7 @@ void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
86 88
87 put_bits(pb, bits, AV_RB16(src + 2*words)>>(16-bits)); 89 put_bits(pb, bits, AV_RB16(src + 2*words)>>(16-bits));
88} 90}
89#endif 91
90/* VLC decoding */ 92/* VLC decoding */
91 93
92//#define DEBUG_VLC 94//#define DEBUG_VLC
diff --git a/apps/codecs/lib/ffmpeg_get_bits.h b/apps/codecs/lib/ffmpeg_get_bits.h
index 1a461e9e25..8fce395a4d 100644
--- a/apps/codecs/lib/ffmpeg_get_bits.h
+++ b/apps/codecs/lib/ffmpeg_get_bits.h
@@ -28,6 +28,7 @@
28 28
29#include <stdint.h> 29#include <stdint.h>
30#include <stdlib.h> 30#include <stdlib.h>
31#include "ffmpeg_intreadwrite.h"
31//#include <assert.h> 32//#include <assert.h>
32//#include "libavutil/bswap.h" 33//#include "libavutil/bswap.h"
33//#include "libavutil/common.h" 34//#include "libavutil/common.h"
@@ -56,16 +57,6 @@
56#define av_const __attribute__((const)) 57#define av_const __attribute__((const))
57#define av_always_inline inline __attribute__((always_inline)) 58#define av_always_inline inline __attribute__((always_inline))
58 59
59/* Coldfire cpu's support unaligned long reads */
60#ifdef CPU_COLDFIRE
61#define AV_RB32(x) (*(const uint32_t*)(x))
62#else
63/* The following define is taken from libavutil/intreadwrite.h */
64#define AV_RB32(x) ((((const uint8_t*)(x))[0] << 24) | \
65 (((const uint8_t*)(x))[1] << 16) | \
66 (((const uint8_t*)(x))[2] << 8) | \
67 ((const uint8_t*)(x))[3])
68#endif
69/* The following is taken from mathops.h */ 60/* The following is taken from mathops.h */
70 61
71#ifndef sign_extend 62#ifndef sign_extend
diff --git a/apps/codecs/lib/ffmpeg_intreadwrite.h b/apps/codecs/lib/ffmpeg_intreadwrite.h
new file mode 100644
index 0000000000..ca718106d1
--- /dev/null
+++ b/apps/codecs/lib/ffmpeg_intreadwrite.h
@@ -0,0 +1,484 @@
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef AVUTIL_INTREADWRITE_H
20#define AVUTIL_INTREADWRITE_H
21
22#include <stdint.h>
23/*
24 * Arch-specific headers can provide any combination of
25 * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
26 * Preprocessor symbols must be defined, even if these are implemented
27 * as inline functions.
28 */
29
30/*
31 * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers.
32 */
33#define HAVE_BIGENDIAN 0
34#if HAVE_BIGENDIAN
35
36# if defined(AV_RN16) && !defined(AV_RB16)
37# define AV_RB16(p) AV_RN16(p)
38# elif !defined(AV_RN16) && defined(AV_RB16)
39# define AV_RN16(p) AV_RB16(p)
40# endif
41
42# if defined(AV_WN16) && !defined(AV_WB16)
43# define AV_WB16(p, v) AV_WN16(p, v)
44# elif !defined(AV_WN16) && defined(AV_WB16)
45# define AV_WN16(p, v) AV_WB16(p, v)
46# endif
47
48# if defined(AV_RN24) && !defined(AV_RB24)
49# define AV_RB24(p) AV_RN24(p)
50# elif !defined(AV_RN24) && defined(AV_RB24)
51# define AV_RN24(p) AV_RB24(p)
52# endif
53
54# if defined(AV_WN24) && !defined(AV_WB24)
55# define AV_WB24(p, v) AV_WN24(p, v)
56# elif !defined(AV_WN24) && defined(AV_WB24)
57# define AV_WN24(p, v) AV_WB24(p, v)
58# endif
59
60# if defined(AV_RN32) && !defined(AV_RB32)
61# define AV_RB32(p) AV_RN32(p)
62# elif !defined(AV_RN32) && defined(AV_RB32)
63# define AV_RN32(p) AV_RB32(p)
64# endif
65
66# if defined(AV_WN32) && !defined(AV_WB32)
67# define AV_WB32(p, v) AV_WN32(p, v)
68# elif !defined(AV_WN32) && defined(AV_WB32)
69# define AV_WN32(p, v) AV_WB32(p, v)
70# endif
71
72# if defined(AV_RN64) && !defined(AV_RB64)
73# define AV_RB64(p) AV_RN64(p)
74# elif !defined(AV_RN64) && defined(AV_RB64)
75# define AV_RN64(p) AV_RB64(p)
76# endif
77
78# if defined(AV_WN64) && !defined(AV_WB64)
79# define AV_WB64(p, v) AV_WN64(p, v)
80# elif !defined(AV_WN64) && defined(AV_WB64)
81# define AV_WN64(p, v) AV_WB64(p, v)
82# endif
83
84#else /* HAVE_BIGENDIAN */
85
86# if defined(AV_RN16) && !defined(AV_RL16)
87# define AV_RL16(p) AV_RN16(p)
88# elif !defined(AV_RN16) && defined(AV_RL16)
89# define AV_RN16(p) AV_RL16(p)
90# endif
91
92# if defined(AV_WN16) && !defined(AV_WL16)
93# define AV_WL16(p, v) AV_WN16(p, v)
94# elif !defined(AV_WN16) && defined(AV_WL16)
95# define AV_WN16(p, v) AV_WL16(p, v)
96# endif
97
98# if defined(AV_RN24) && !defined(AV_RL24)
99# define AV_RL24(p) AV_RN24(p)
100# elif !defined(AV_RN24) && defined(AV_RL24)
101# define AV_RN24(p) AV_RL24(p)
102# endif
103
104# if defined(AV_WN24) && !defined(AV_WL24)
105# define AV_WL24(p, v) AV_WN24(p, v)
106# elif !defined(AV_WN24) && defined(AV_WL24)
107# define AV_WN24(p, v) AV_WL24(p, v)
108# endif
109
110# if defined(AV_RN32) && !defined(AV_RL32)
111# define AV_RL32(p) AV_RN32(p)
112# elif !defined(AV_RN32) && defined(AV_RL32)
113# define AV_RN32(p) AV_RL32(p)
114# endif
115
116# if defined(AV_WN32) && !defined(AV_WL32)
117# define AV_WL32(p, v) AV_WN32(p, v)
118# elif !defined(AV_WN32) && defined(AV_WL32)
119# define AV_WN32(p, v) AV_WL32(p, v)
120# endif
121
122# if defined(AV_RN64) && !defined(AV_RL64)
123# define AV_RL64(p) AV_RN64(p)
124# elif !defined(AV_RN64) && defined(AV_RL64)
125# define AV_RN64(p) AV_RL64(p)
126# endif
127
128# if defined(AV_WN64) && !defined(AV_WL64)
129# define AV_WL64(p, v) AV_WN64(p, v)
130# elif !defined(AV_WN64) && defined(AV_WL64)
131# define AV_WN64(p, v) AV_WL64(p, v)
132# endif
133
134#endif /* !HAVE_BIGENDIAN */
135
136#define HAVE_ATTRIBUTE_PACKED 0
137#define HAVE_FAST_UNALIGNED 0
138/*
139 * Define AV_[RW]N helper macros to simplify definitions not provided
140 * by per-arch headers.
141 */
142
143#if HAVE_ATTRIBUTE_PACKED
144
145union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias;
146union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
147union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
148
149# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
150# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v))
151
152#elif defined(__DECC)
153
154# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
155# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
156
157#elif HAVE_FAST_UNALIGNED
158
159# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
160# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v))
161
162#else
163
164#ifndef AV_RB16
165# define AV_RB16(x) \
166 ((((const uint8_t*)(x))[0] << 8) | \
167 ((const uint8_t*)(x))[1])
168#endif
169#ifndef AV_WB16
170# define AV_WB16(p, d) do { \
171 ((uint8_t*)(p))[1] = (d); \
172 ((uint8_t*)(p))[0] = (d)>>8; \
173 } while(0)
174#endif
175
176#ifndef AV_RL16
177# define AV_RL16(x) \
178 ((((const uint8_t*)(x))[1] << 8) | \
179 ((const uint8_t*)(x))[0])
180#endif
181#ifndef AV_WL16
182# define AV_WL16(p, d) do { \
183 ((uint8_t*)(p))[0] = (d); \
184 ((uint8_t*)(p))[1] = (d)>>8; \
185 } while(0)
186#endif
187
188#ifndef AV_RB32
189/* Coldfire cpu's support unaligned long reads */
190#ifdef CPU_COLDFIRE
191#define AV_RB32(x) (*(const uint32_t*)(x))
192#else
193# define AV_RB32(x) \
194 ((((const uint8_t*)(x))[0] << 24) | \
195 (((const uint8_t*)(x))[1] << 16) | \
196 (((const uint8_t*)(x))[2] << 8) | \
197 ((const uint8_t*)(x))[3])
198#endif
199#endif
200#ifndef AV_WB32
201# define AV_WB32(p, d) do { \
202 ((uint8_t*)(p))[3] = (d); \
203 ((uint8_t*)(p))[2] = (d)>>8; \
204 ((uint8_t*)(p))[1] = (d)>>16; \
205 ((uint8_t*)(p))[0] = (d)>>24; \
206 } while(0)
207#endif
208
209#ifndef AV_RL32
210# define AV_RL32(x) \
211 ((((const uint8_t*)(x))[3] << 24) | \
212 (((const uint8_t*)(x))[2] << 16) | \
213 (((const uint8_t*)(x))[1] << 8) | \
214 ((const uint8_t*)(x))[0])
215#endif
216#ifndef AV_WL32
217# define AV_WL32(p, d) do { \
218 ((uint8_t*)(p))[0] = (d); \
219 ((uint8_t*)(p))[1] = (d)>>8; \
220 ((uint8_t*)(p))[2] = (d)>>16; \
221 ((uint8_t*)(p))[3] = (d)>>24; \
222 } while(0)
223#endif
224
225#ifndef AV_RB64
226# define AV_RB64(x) \
227 (((uint64_t)((const uint8_t*)(x))[0] << 56) | \
228 ((uint64_t)((const uint8_t*)(x))[1] << 48) | \
229 ((uint64_t)((const uint8_t*)(x))[2] << 40) | \
230 ((uint64_t)((const uint8_t*)(x))[3] << 32) | \
231 ((uint64_t)((const uint8_t*)(x))[4] << 24) | \
232 ((uint64_t)((const uint8_t*)(x))[5] << 16) | \
233 ((uint64_t)((const uint8_t*)(x))[6] << 8) | \
234 (uint64_t)((const uint8_t*)(x))[7])
235#endif
236#ifndef AV_WB64
237# define AV_WB64(p, d) do { \
238 ((uint8_t*)(p))[7] = (d); \
239 ((uint8_t*)(p))[6] = (d)>>8; \
240 ((uint8_t*)(p))[5] = (d)>>16; \
241 ((uint8_t*)(p))[4] = (d)>>24; \
242 ((uint8_t*)(p))[3] = (d)>>32; \
243 ((uint8_t*)(p))[2] = (d)>>40; \
244 ((uint8_t*)(p))[1] = (d)>>48; \
245 ((uint8_t*)(p))[0] = (d)>>56; \
246 } while(0)
247#endif
248
249#ifndef AV_RL64
250# define AV_RL64(x) \
251 (((uint64_t)((const uint8_t*)(x))[7] << 56) | \
252 ((uint64_t)((const uint8_t*)(x))[6] << 48) | \
253 ((uint64_t)((const uint8_t*)(x))[5] << 40) | \
254 ((uint64_t)((const uint8_t*)(x))[4] << 32) | \
255 ((uint64_t)((const uint8_t*)(x))[3] << 24) | \
256 ((uint64_t)((const uint8_t*)(x))[2] << 16) | \
257 ((uint64_t)((const uint8_t*)(x))[1] << 8) | \
258 (uint64_t)((const uint8_t*)(x))[0])
259#endif
260#ifndef AV_WL64
261# define AV_WL64(p, d) do { \
262 ((uint8_t*)(p))[0] = (d); \
263 ((uint8_t*)(p))[1] = (d)>>8; \
264 ((uint8_t*)(p))[2] = (d)>>16; \
265 ((uint8_t*)(p))[3] = (d)>>24; \
266 ((uint8_t*)(p))[4] = (d)>>32; \
267 ((uint8_t*)(p))[5] = (d)>>40; \
268 ((uint8_t*)(p))[6] = (d)>>48; \
269 ((uint8_t*)(p))[7] = (d)>>56; \
270 } while(0)
271#endif
272
273#if HAVE_BIGENDIAN
274# define AV_RN(s, p) AV_RB##s(p)
275# define AV_WN(s, p, v) AV_WB##s(p, v)
276#else
277# define AV_RN(s, p) AV_RL##s(p)
278# define AV_WN(s, p, v) AV_WL##s(p, v)
279#endif
280
281#endif /* HAVE_FAST_UNALIGNED */
282
283#ifndef AV_RN16
284# define AV_RN16(p) AV_RN(16, p)
285#endif
286
287#ifndef AV_RN32
288# define AV_RN32(p) AV_RN(32, p)
289#endif
290
291#ifndef AV_RN64
292# define AV_RN64(p) AV_RN(64, p)
293#endif
294
295#ifndef AV_WN16
296# define AV_WN16(p, v) AV_WN(16, p, v)
297#endif
298
299#ifndef AV_WN32
300# define AV_WN32(p, v) AV_WN(32, p, v)
301#endif
302
303#ifndef AV_WN64
304# define AV_WN64(p, v) AV_WN(64, p, v)
305#endif
306
307#if HAVE_BIGENDIAN
308# define AV_RB(s, p) AV_RN##s(p)
309# define AV_WB(s, p, v) AV_WN##s(p, v)
310# define AV_RL(s, p) bswap_##s(AV_RN##s(p))
311# define AV_WL(s, p, v) AV_WN##s(p, bswap_##s(v))
312#else
313# define AV_RB(s, p) bswap_##s(AV_RN##s(p))
314# define AV_WB(s, p, v) AV_WN##s(p, bswap_##s(v))
315# define AV_RL(s, p) AV_RN##s(p)
316# define AV_WL(s, p, v) AV_WN##s(p, v)
317#endif
318
319#define AV_RB8(x) (((const uint8_t*)(x))[0])
320#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0)
321
322#define AV_RL8(x) AV_RB8(x)
323#define AV_WL8(p, d) AV_WB8(p, d)
324
325#ifndef AV_RB16
326# define AV_RB16(p) AV_RB(16, p)
327#endif
328#ifndef AV_WB16
329# define AV_WB16(p, v) AV_WB(16, p, v)
330#endif
331
332#ifndef AV_RL16
333# define AV_RL16(p) AV_RL(16, p)
334#endif
335#ifndef AV_WL16
336# define AV_WL16(p, v) AV_WL(16, p, v)
337#endif
338
339#ifndef AV_RB32
340# define AV_RB32(p) AV_RB(32, p)
341#endif
342#ifndef AV_WB32
343# define AV_WB32(p, v) AV_WB(32, p, v)
344#endif
345
346#ifndef AV_RL32
347# define AV_RL32(p) AV_RL(32, p)
348#endif
349#ifndef AV_WL32
350# define AV_WL32(p, v) AV_WL(32, p, v)
351#endif
352
353#ifndef AV_RB64
354# define AV_RB64(p) AV_RB(64, p)
355#endif
356#ifndef AV_WB64
357# define AV_WB64(p, v) AV_WB(64, p, v)
358#endif
359
360#ifndef AV_RL64
361# define AV_RL64(p) AV_RL(64, p)
362#endif
363#ifndef AV_WL64
364# define AV_WL64(p, v) AV_WL(64, p, v)
365#endif
366
367#ifndef AV_RB24
368# define AV_RB24(x) \
369 ((((const uint8_t*)(x))[0] << 16) | \
370 (((const uint8_t*)(x))[1] << 8) | \
371 ((const uint8_t*)(x))[2])
372#endif
373#ifndef AV_WB24
374# define AV_WB24(p, d) do { \
375 ((uint8_t*)(p))[2] = (d); \
376 ((uint8_t*)(p))[1] = (d)>>8; \
377 ((uint8_t*)(p))[0] = (d)>>16; \
378 } while(0)
379#endif
380
381#ifndef AV_RL24
382# define AV_RL24(x) \
383 ((((const uint8_t*)(x))[2] << 16) | \
384 (((const uint8_t*)(x))[1] << 8) | \
385 ((const uint8_t*)(x))[0])
386#endif
387#ifndef AV_WL24
388# define AV_WL24(p, d) do { \
389 ((uint8_t*)(p))[0] = (d); \
390 ((uint8_t*)(p))[1] = (d)>>8; \
391 ((uint8_t*)(p))[2] = (d)>>16; \
392 } while(0)
393#endif
394
395/*
396 * The AV_[RW]NA macros access naturally aligned data
397 * in a type-safe way.
398 */
399
400#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s)
401#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v))
402
403#ifndef AV_RN16A
404# define AV_RN16A(p) AV_RNA(16, p)
405#endif
406
407#ifndef AV_RN32A
408# define AV_RN32A(p) AV_RNA(32, p)
409#endif
410
411#ifndef AV_RN64A
412# define AV_RN64A(p) AV_RNA(64, p)
413#endif
414
415#ifndef AV_WN16A
416# define AV_WN16A(p, v) AV_WNA(16, p, v)
417#endif
418
419#ifndef AV_WN32A
420# define AV_WN32A(p, v) AV_WNA(32, p, v)
421#endif
422
423#ifndef AV_WN64A
424# define AV_WN64A(p, v) AV_WNA(64, p, v)
425#endif
426
427/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
428 * naturally aligned. They may be implemented using MMX,
429 * so emms_c() must be called before using any float code
430 * afterwards.
431 */
432
433#define AV_COPY(n, d, s) \
434 (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n)
435
436#ifndef AV_COPY16
437# define AV_COPY16(d, s) AV_COPY(16, d, s)
438#endif
439
440#ifndef AV_COPY32
441# define AV_COPY32(d, s) AV_COPY(32, d, s)
442#endif
443
444#ifndef AV_COPY64
445# define AV_COPY64(d, s) AV_COPY(64, d, s)
446#endif
447
448#ifndef AV_COPY128
449# define AV_COPY128(d, s) \
450 do { \
451 AV_COPY64(d, s); \
452 AV_COPY64((char*)(d)+8, (char*)(s)+8); \
453 } while(0)
454#endif
455
456#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b))
457
458#ifndef AV_SWAP64
459# define AV_SWAP64(a, b) AV_SWAP(64, a, b)
460#endif
461
462#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0)
463
464#ifndef AV_ZERO16
465# define AV_ZERO16(d) AV_ZERO(16, d)
466#endif
467
468#ifndef AV_ZERO32
469# define AV_ZERO32(d) AV_ZERO(32, d)
470#endif
471
472#ifndef AV_ZERO64
473# define AV_ZERO64(d) AV_ZERO(64, d)
474#endif
475
476#ifndef AV_ZERO128
477# define AV_ZERO128(d) \
478 do { \
479 AV_ZERO64(d); \
480 AV_ZERO64((char*)(d)+8); \
481 } while(0)
482#endif
483
484#endif /* AVUTIL_INTREADWRITE_H */
diff --git a/apps/codecs/lib/ffmpeg_put_bits.h b/apps/codecs/lib/ffmpeg_put_bits.h
new file mode 100644
index 0000000000..38db55fe18
--- /dev/null
+++ b/apps/codecs/lib/ffmpeg_put_bits.h
@@ -0,0 +1,323 @@
1/*
2 * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file libavcodec/put_bits.h
23 * bitstream writer API
24 */
25
26#ifndef AVCODEC_PUT_BITS_H
27#define AVCODEC_PUT_BITS_H
28
29#include <stdint.h>
30#include <stdlib.h>
31#include "ffmpeg_bswap.h"
32#include "ffmpeg_intreadwrite.h"
33
34#define av_log(...)
35#define HAVE_FAST_UNALIGNED 0
36
37/* buf and buf_end must be present and used by every alternative writer. */
38typedef struct PutBitContext {
39#ifdef ALT_BITSTREAM_WRITER
40 uint8_t *buf, *buf_end;
41 int index;
42#else
43 uint32_t bit_buf;
44 int bit_left;
45 uint8_t *buf, *buf_ptr, *buf_end;
46#endif
47 int size_in_bits;
48} PutBitContext;
49
50/**
51 * Initializes the PutBitContext s.
52 *
53 * @param buffer the buffer where to put bits
54 * @param buffer_size the size in bytes of buffer
55 */
56static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
57{
58 if(buffer_size < 0) {
59 buffer_size = 0;
60 buffer = NULL;
61 }
62
63 s->size_in_bits= 8*buffer_size;
64 s->buf = buffer;
65 s->buf_end = s->buf + buffer_size;
66#ifdef ALT_BITSTREAM_WRITER
67 s->index=0;
68 ((uint32_t*)(s->buf))[0]=0;
69// memset(buffer, 0, buffer_size);
70#else
71 s->buf_ptr = s->buf;
72 s->bit_left=32;
73 s->bit_buf=0;
74#endif
75}
76
77/**
78 * Returns the total number of bits written to the bitstream.
79 */
80static inline int put_bits_count(PutBitContext *s)
81{
82#ifdef ALT_BITSTREAM_WRITER
83 return s->index;
84#else
85 return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left;
86#endif
87}
88
89/**
90 * Pads the end of the output stream with zeros.
91 */
92static inline void flush_put_bits(PutBitContext *s)
93{
94#ifdef ALT_BITSTREAM_WRITER
95 align_put_bits(s);
96#else
97#ifndef BITSTREAM_WRITER_LE
98 s->bit_buf<<= s->bit_left;
99#endif
100 while (s->bit_left < 32) {
101 /* XXX: should test end of buffer */
102#ifdef BITSTREAM_WRITER_LE
103 *s->buf_ptr++=s->bit_buf;
104 s->bit_buf>>=8;
105#else
106 *s->buf_ptr++=s->bit_buf >> 24;
107 s->bit_buf<<=8;
108#endif
109 s->bit_left+=8;
110 }
111 s->bit_left=32;
112 s->bit_buf=0;
113#endif
114}
115
116#if defined(ALT_BITSTREAM_WRITER) || defined(BITSTREAM_WRITER_LE)
117#define align_put_bits align_put_bits_unsupported_here
118#define ff_put_string ff_put_string_unsupported_here
119#define ff_copy_bits ff_copy_bits_unsupported_here
120#else
121/**
122 * Pads the bitstream with zeros up to the next byte boundary.
123 */
124void align_put_bits(PutBitContext *s);
125
126/**
127 * Puts the string string in the bitstream.
128 *
129 * @param terminate_string 0-terminates the written string if value is 1
130 */
131void ff_put_string(PutBitContext *pb, const char *string, int terminate_string);
132
133/**
134 * Copies the content of src to the bitstream.
135 *
136 * @param length the number of bits of src to copy
137 */
138void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length);
139#endif
140
141/**
142 * Writes up to 31 bits into a bitstream.
143 * Use put_bits32 to write 32 bits.
144 */
145static inline void put_bits(PutBitContext *s, int n, unsigned int value)
146#ifndef ALT_BITSTREAM_WRITER
147{
148 unsigned int bit_buf;
149 int bit_left;
150
151 // printf("put_bits=%d %x\n", n, value);
152 //assert(n <= 31 && value < (1U << n));
153
154 bit_buf = s->bit_buf;
155 bit_left = s->bit_left;
156
157 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
158 /* XXX: optimize */
159#ifdef BITSTREAM_WRITER_LE
160 bit_buf |= value << (32 - bit_left);
161 if (n >= bit_left) {
162#if !HAVE_FAST_UNALIGNED
163 if (3 & (intptr_t) s->buf_ptr) {
164 AV_WL32(s->buf_ptr, bit_buf);
165 } else
166#endif
167 *(uint32_t *)s->buf_ptr = le2me_32(bit_buf);
168 s->buf_ptr+=4;
169 bit_buf = (bit_left==32)?0:value >> bit_left;
170 bit_left+=32;
171 }
172 bit_left-=n;
173#else
174 if (n < bit_left) {
175 bit_buf = (bit_buf<<n) | value;
176 bit_left-=n;
177 } else {
178 bit_buf<<=bit_left;
179 bit_buf |= value >> (n - bit_left);
180#if !HAVE_FAST_UNALIGNED
181 if (3 & (intptr_t) s->buf_ptr) {
182 AV_WB32(s->buf_ptr, bit_buf);
183 } else
184#endif
185 *(uint32_t *)s->buf_ptr = be2me_32(bit_buf);
186 //printf("bitbuf = %08x\n", bit_buf);
187 s->buf_ptr+=4;
188 bit_left+=32 - n;
189 bit_buf = value;
190 }
191#endif
192
193 s->bit_buf = bit_buf;
194 s->bit_left = bit_left;
195}
196#else /* ALT_BITSTREAM_WRITER defined */
197{
198# ifdef ALIGNED_BITSTREAM_WRITER
199# if ARCH_X86
200 __asm__ volatile(
201 "movl %0, %%ecx \n\t"
202 "xorl %%eax, %%eax \n\t"
203 "shrdl %%cl, %1, %%eax \n\t"
204 "shrl %%cl, %1 \n\t"
205 "movl %0, %%ecx \n\t"
206 "shrl $3, %%ecx \n\t"
207 "andl $0xFFFFFFFC, %%ecx \n\t"
208 "bswapl %1 \n\t"
209 "orl %1, (%2, %%ecx) \n\t"
210 "bswapl %%eax \n\t"
211 "addl %3, %0 \n\t"
212 "movl %%eax, 4(%2, %%ecx) \n\t"
213 : "=&r" (s->index), "=&r" (value)
214 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n))
215 : "%eax", "%ecx"
216 );
217# else
218 int index= s->index;
219 uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5);
220
221 value<<= 32-n;
222
223 ptr[0] |= be2me_32(value>>(index&31));
224 ptr[1] = be2me_32(value<<(32-(index&31)));
225//if(n>24) printf("%d %d\n", n, value);
226 index+= n;
227 s->index= index;
228# endif
229# else //ALIGNED_BITSTREAM_WRITER
230# if ARCH_X86
231 __asm__ volatile(
232 "movl $7, %%ecx \n\t"
233 "andl %0, %%ecx \n\t"
234 "addl %3, %%ecx \n\t"
235 "negl %%ecx \n\t"
236 "shll %%cl, %1 \n\t"
237 "bswapl %1 \n\t"
238 "movl %0, %%ecx \n\t"
239 "shrl $3, %%ecx \n\t"
240 "orl %1, (%%ecx, %2) \n\t"
241 "addl %3, %0 \n\t"
242 "movl $0, 4(%%ecx, %2) \n\t"
243 : "=&r" (s->index), "=&r" (value)
244 : "r" (s->buf), "r" (n), "0" (s->index), "1" (value)
245 : "%ecx"
246 );
247# else
248 int index= s->index;
249 uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3));
250
251 ptr[0] |= be2me_32(value<<(32-n-(index&7) ));
252 ptr[1] = 0;
253//if(n>24) printf("%d %d\n", n, value);
254 index+= n;
255 s->index= index;
256# endif
257# endif //!ALIGNED_BITSTREAM_WRITER
258}
259#endif
260
261static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
262{
263 //assert(n >= 0 && n <= 31);
264
265 put_bits(pb, n, value & ((1<<n)-1));
266}
267
268/**
269 * Returns the pointer to the byte where the bitstream writer will put
270 * the next bit.
271 */
272static inline uint8_t* put_bits_ptr(PutBitContext *s)
273{
274#ifdef ALT_BITSTREAM_WRITER
275 return s->buf + (s->index>>3);
276#else
277 return s->buf_ptr;
278#endif
279}
280
281/**
282 * Skips the given number of bytes.
283 * PutBitContext must be flushed & aligned to a byte boundary before calling this.
284 */
285static inline void skip_put_bytes(PutBitContext *s, int n)
286{
287 //assert((put_bits_count(s)&7)==0);
288#ifdef ALT_BITSTREAM_WRITER
289 FIXME may need some cleaning of the buffer
290 s->index += n<<3;
291#else
292 //assert(s->bit_left==32);
293 s->buf_ptr += n;
294#endif
295}
296
297/**
298 * Skips the given number of bits.
299 * Must only be used if the actual values in the bitstream do not matter.
300 * If n is 0 the behavior is undefined.
301 */
302static inline void skip_put_bits(PutBitContext *s, int n)
303{
304#ifdef ALT_BITSTREAM_WRITER
305 s->index += n;
306#else
307 s->bit_left -= n;
308 s->buf_ptr-= 4*(s->bit_left>>5);
309 s->bit_left &= 31;
310#endif
311}
312
313/**
314 * Changes the end of the buffer.
315 *
316 * @param size the new size in bytes of the buffer where to put bits
317 */
318static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
319{
320 s->buf_end= s->buf + size;
321}
322
323#endif /* AVCODEC_PUT_BITS_H */