1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <string.h> |
|
21 #include "globals.h" |
|
22 #include "nrctyp32.h" |
|
23 #include "bitbuffer.h" |
|
24 |
|
25 #include "parameterset.h" |
|
26 |
|
27 |
|
28 /* |
|
29 * Static functions |
|
30 */ |
|
31 |
|
32 static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf); |
|
33 static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf); |
|
34 |
|
35 |
|
36 /* |
|
37 * |
|
38 * bibOpen: |
|
39 * |
|
40 * Parameters: |
|
41 * |
|
42 * Function: |
|
43 * Open bitbuffer |
|
44 * |
|
45 * Returns: |
|
46 * Pointer to bitbuffer object or NULL for allocation failure. |
|
47 * |
|
48 */ |
|
49 bitbuffer_s *bibOpen() |
|
50 { |
|
51 bitbuffer_s *bitbuf; |
|
52 |
|
53 bitbuf = (bitbuffer_s *)User::Alloc(sizeof(bitbuffer_s)); |
|
54 |
|
55 if (bitbuf != NULL) |
|
56 memset(bitbuf, 0, sizeof(bitbuffer_s)); |
|
57 |
|
58 return bitbuf; |
|
59 } |
|
60 |
|
61 |
|
62 /* |
|
63 * |
|
64 * bibInit: |
|
65 * |
|
66 * Parameters: |
|
67 * bitbuf Bitbuffer object |
|
68 * streamBytes Pointer to data |
|
69 * length Data length in bytes |
|
70 * |
|
71 * Function: |
|
72 * Initialize bitbuffer |
|
73 * |
|
74 * Returns: |
|
75 * BIB_ok for ok, BIB_ERROR for error |
|
76 * |
|
77 */ |
|
78 int bibInit(bitbuffer_s *bitbuf, u_int8 *streamBytes, int length) |
|
79 { |
|
80 bitbuf->data = streamBytes; |
|
81 bitbuf->dataLen = length; |
|
82 bitbuf->bytePos = 0; |
|
83 bitbuf->bitpos = 0; |
|
84 bitbuf->errorStatus = BIB_OK; |
|
85 |
|
86 #if ENCAPSULATED_NAL_PAYLOAD |
|
87 if (removeStartCodeEmulationBytes(bitbuf) < 0) |
|
88 return BIB_ERROR; |
|
89 #endif |
|
90 |
|
91 return BIB_OK; |
|
92 } |
|
93 |
|
94 |
|
95 /* |
|
96 * |
|
97 * bibClose: |
|
98 * |
|
99 * Parameters: |
|
100 * bitbuf Bitbuffer object |
|
101 * |
|
102 * Function: |
|
103 * Close bitbuffer |
|
104 * |
|
105 * Returns: |
|
106 * - |
|
107 * |
|
108 */ |
|
109 void bibClose(bitbuffer_s *bitbuf) |
|
110 { |
|
111 User::Free(bitbuf); |
|
112 } |
|
113 |
|
114 |
|
115 /* |
|
116 * |
|
117 * removeStartCodeEmulationBytes: |
|
118 * |
|
119 * Parameters: |
|
120 * bitbuf Bitbuffer object |
|
121 * |
|
122 * Function: |
|
123 * Remove start code emulation bytes from the bitbuffer |
|
124 * |
|
125 * Returns: |
|
126 * - |
|
127 * |
|
128 */ |
|
129 static int removeStartCodeEmulationBytes(bitbuffer_s *bitbuf) |
|
130 { |
|
131 TInt i; |
|
132 TInt j; |
|
133 TInt numZero; |
|
134 TInt32 lastBytes; |
|
135 |
|
136 |
|
137 // Skip the start code if it exists |
|
138 numZero = 0; |
|
139 i = 0; |
|
140 while (i < bitbuf->dataLen) |
|
141 { |
|
142 if (bitbuf->data[i] == 0) |
|
143 numZero++; |
|
144 else if (numZero > 1 && bitbuf->data[i] == 1) |
|
145 { |
|
146 // Start code found |
|
147 i++; |
|
148 break; |
|
149 } |
|
150 else |
|
151 { |
|
152 // No start code found |
|
153 i = 0; |
|
154 break; |
|
155 } |
|
156 i++; |
|
157 } |
|
158 |
|
159 // Convert EBSP to RBSP. Note that the nal head byte is kept within the buffer |
|
160 lastBytes = 0xffffffff; |
|
161 j = 0; |
|
162 while (i < bitbuf->dataLen) |
|
163 { |
|
164 lastBytes = (lastBytes << 8) | bitbuf->data[i]; |
|
165 if ((lastBytes & 0xffffff) != 0x000003) |
|
166 { |
|
167 bitbuf->data[j] = bitbuf->data[i]; |
|
168 j++; |
|
169 } |
|
170 i++; |
|
171 } |
|
172 |
|
173 // If bytes were removed, set as many bytes zero at the end of the buffer |
|
174 if (j < bitbuf->dataLen) |
|
175 { |
|
176 // Prevention bytes have been removed, set the last bytes to zero |
|
177 TInt removedBytes = bitbuf->dataLen - j; |
|
178 for (i=0; i<removedBytes; i++) |
|
179 { |
|
180 bitbuf->data[bitbuf->dataLen-1-i] = 0; |
|
181 } |
|
182 } |
|
183 |
|
184 // Adjust the bitbuffer dataLen |
|
185 bitbuf->dataLen = j; |
|
186 |
|
187 return BIB_OK; |
|
188 } |
|
189 |
|
190 |
|
191 /* |
|
192 * |
|
193 * bibGetBitFunc: |
|
194 * |
|
195 * Parameters: |
|
196 * bitbuf Bitbuffer object |
|
197 * |
|
198 * Function: |
|
199 * Get next bit from bitbuffer. |
|
200 * |
|
201 * Returns: |
|
202 * Next bit in bitbuffer or BIB_ERR_NO_BITS if no bits left. |
|
203 * |
|
204 */ |
|
205 int bibGetBitFunc(bitbuffer_s *bitbuf) |
|
206 { |
|
207 /* If there are no bits left in buffer return an error */ |
|
208 if (bitbuf->bitpos == 0 && bitbuf->bytePos >= bitbuf->dataLen) { |
|
209 bitbuf->errorStatus = BIB_ERR_NO_BITS; |
|
210 return 0; |
|
211 } |
|
212 |
|
213 /* Fill bitbuf->currentBits with bits */ |
|
214 while (bitbuf->bitpos <= 24 && bitbuf->bytePos < bitbuf->dataLen) { |
|
215 bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; |
|
216 bitbuf->bitpos += 8; |
|
217 } |
|
218 |
|
219 /* Return bit */ |
|
220 bitbuf->bitpos--; |
|
221 return (bitbuf->currentBits >> bitbuf->bitpos) & 1; |
|
222 } |
|
223 |
|
224 |
|
225 /* |
|
226 * |
|
227 * bibGetBitsFunc: |
|
228 * |
|
229 * Parameters: |
|
230 * bitbuf Bitbuffer object |
|
231 * n Number of bits requested |
|
232 * |
|
233 * Function: |
|
234 * Get next n bits from bitbuffer. |
|
235 * |
|
236 * NOTE: maximum of 24 bits can be fetched |
|
237 * |
|
238 * Returns: |
|
239 * Next n bits from bitbuffer |
|
240 * |
|
241 */ |
|
242 int32 bibGetBitsFunc(bitbuffer_s *bitbuf, int n) |
|
243 { |
|
244 /* Fill bitbuf->currentBits with bits */ |
|
245 while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { |
|
246 bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; |
|
247 bitbuf->bitpos += 8; |
|
248 } |
|
249 |
|
250 /* If there are not enought bits there was an error */ |
|
251 if (n > bitbuf->bitpos) { |
|
252 bitbuf->errorStatus = BIB_ERR_NO_BITS; |
|
253 return 0; |
|
254 } |
|
255 |
|
256 /* Return bits */ |
|
257 bitbuf->bitpos -= n; |
|
258 return (bitbuf->currentBits >> (bitbuf->bitpos)) & ~(((u_int32)-1)<<n); |
|
259 } |
|
260 |
|
261 |
|
262 /* |
|
263 * |
|
264 * bibShowBitsFunc: |
|
265 * |
|
266 * Parameters: |
|
267 * bitbuf Bitbuffer object |
|
268 * n Number of bits requested |
|
269 * |
|
270 * Function: |
|
271 * Get next n bits from bitbuffer without advancing bitbuffer pointer. |
|
272 * This function will not failt even if there are not enough bits in |
|
273 * the bitbuffer. |
|
274 * |
|
275 * NOTE: maximum of 24 bits can be fetched |
|
276 * |
|
277 * Returns: |
|
278 * Next n bits of bitbuffer |
|
279 * |
|
280 */ |
|
281 int32 bibShowBitsFunc(bitbuffer_s *bitbuf, int n) |
|
282 { |
|
283 /* Fill bitbuf->currentBits with bits */ |
|
284 while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { |
|
285 bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; |
|
286 bitbuf->bitpos += 8; |
|
287 } |
|
288 |
|
289 /* Check if there are enought bits in currentBits */ |
|
290 if (n <= bitbuf->bitpos) |
|
291 /* Return bits normally */ |
|
292 return (bitbuf->currentBits >> (bitbuf->bitpos-n)) & ~(((u_int32)-1)<<n); |
|
293 else |
|
294 /* Return bits padded with zero bits */ |
|
295 return (bitbuf->currentBits << (n-bitbuf->bitpos)) & ~(((u_int32)-1)<<n); |
|
296 } |
|
297 |
|
298 |
|
299 /* |
|
300 * |
|
301 * bibSkipBitsFunc: |
|
302 * |
|
303 * Parameters: |
|
304 * bitbuf Bitbuffer object |
|
305 * n Number of bits to skip |
|
306 * |
|
307 * Function: |
|
308 * Skip next n bits in the bitbuffer |
|
309 * |
|
310 * Returns: |
|
311 * BIB_OK for no error and BIB_ERR_NO_BITS for end of buffer. |
|
312 * |
|
313 */ |
|
314 int bibSkipBitsFunc(bitbuffer_s *bitbuf, int n) |
|
315 { |
|
316 /* Fill bitbuf->currentBits with bits */ |
|
317 while (n > bitbuf->bitpos && bitbuf->bytePos < bitbuf->dataLen) { |
|
318 bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; |
|
319 bitbuf->bitpos += 8; |
|
320 } |
|
321 |
|
322 bitbuf->bitpos -= n; |
|
323 |
|
324 /* Check for buffer underrun */ |
|
325 if (bitbuf->bitpos < 0) { |
|
326 bitbuf->errorStatus = BIB_ERR_NO_BITS; |
|
327 return BIB_ERR_NO_BITS; |
|
328 } |
|
329 |
|
330 return BIB_OK; |
|
331 } |
|
332 |
|
333 |
|
334 /* |
|
335 * |
|
336 * bibGetByte: |
|
337 * |
|
338 * Parameters: |
|
339 * bitbuf Bitbuffer object |
|
340 * byteRet Return pointer for byte |
|
341 * |
|
342 * Function: |
|
343 * Get next byte aligned byte from bitbuffer. |
|
344 * |
|
345 * Returns: |
|
346 * 1 for End Of Stream, 0 otherwise |
|
347 * |
|
348 */ |
|
349 int bibGetByte(bitbuffer_s *bitbuf, int *byteRet) |
|
350 { |
|
351 if (bitbuf->bitpos >= 8) { |
|
352 bitbuf->bitpos = bitbuf->bitpos & ~7; |
|
353 *byteRet = (bitbuf->currentBits >> (bitbuf->bitpos - 8)) & 0xff; |
|
354 bitbuf->bitpos -= 8; |
|
355 } |
|
356 else { |
|
357 bitbuf->bitpos = 0; |
|
358 |
|
359 if (bitbuf->bytePos >= bitbuf->dataLen) { |
|
360 return 1; |
|
361 } |
|
362 |
|
363 *byteRet = bitbuf->data[bitbuf->bytePos++]; |
|
364 } |
|
365 |
|
366 return 0; |
|
367 } |
|
368 |
|
369 |
|
370 /* |
|
371 * |
|
372 * bibByteAlign: |
|
373 * |
|
374 * Parameters: |
|
375 * bitbuf Bitbuffer object |
|
376 * |
|
377 * Function: |
|
378 * Set bitbuffer pointer to next byte aligned position. |
|
379 * |
|
380 * Returns: |
|
381 * Number of bits skipped as a result of aligning. |
|
382 * |
|
383 */ |
|
384 int bibByteAlign(bitbuffer_s *bitbuf) |
|
385 { |
|
386 int bitpos = bitbuf->bitpos; |
|
387 |
|
388 bitbuf->bitpos = bitbuf->bitpos & ~7; |
|
389 |
|
390 return (bitpos - bitbuf->bitpos); |
|
391 } |
|
392 |
|
393 |
|
394 /* |
|
395 * bibSkipTrailingBits: |
|
396 * |
|
397 * Parameters: |
|
398 * bitbuf Bitbuffer object |
|
399 * |
|
400 * Function: |
|
401 * Skip the trailing bits at the end of a NAL unit |
|
402 * |
|
403 * Returns: |
|
404 * The number of bits being skipped or <0 for error. |
|
405 */ |
|
406 int bibSkipTrailingBits(bitbuffer_s *bitbuf) |
|
407 { |
|
408 int ret; |
|
409 int len = 0; |
|
410 int bit = 0; |
|
411 |
|
412 bit = bibGetBitFunc(bitbuf); |
|
413 len++; |
|
414 |
|
415 ret = bibGetStatus(bitbuf); |
|
416 if (ret < 0) |
|
417 return ret; |
|
418 |
|
419 /* First we expect to receive 1 bit */ |
|
420 if (bit != 1) { |
|
421 bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT); |
|
422 return BIB_INCORRECT_TRAILING_BIT; |
|
423 } |
|
424 |
|
425 /* Remaining bits in current byte should be zero */ |
|
426 while ( bitbuf->bitpos % 8 != 0 ) { |
|
427 bibGetBit(bitbuf, &bit); |
|
428 len++; |
|
429 if (bit != 0) { |
|
430 bibRaiseError(bitbuf, BIB_INCORRECT_TRAILING_BIT); |
|
431 return BIB_INCORRECT_TRAILING_BIT; |
|
432 } |
|
433 } |
|
434 |
|
435 ret = bibGetStatus(bitbuf); |
|
436 if (ret < 0) |
|
437 return ret; |
|
438 |
|
439 return len; |
|
440 } |
|
441 |
|
442 |
|
443 /* |
|
444 * bibMoreRbspData: |
|
445 * |
|
446 * Parameters: |
|
447 * bitbuf Bitbuffer object |
|
448 * |
|
449 * Function: |
|
450 * Check if there is more RBSP data in the bitbuffer. |
|
451 * |
|
452 * Returns: |
|
453 * 0: no more rbsp data |
|
454 * 1: more rbsp data |
|
455 */ |
|
456 int bibMoreRbspData(bitbuffer_s *bitbuf) |
|
457 { |
|
458 int numBytesLeft; |
|
459 u_int32 lastBits; |
|
460 |
|
461 numBytesLeft = bitbuf->dataLen - bitbuf->bytePos; |
|
462 |
|
463 if (numBytesLeft >= 2 || (numBytesLeft*8 + bitbuf->bitpos >= 9)) |
|
464 /* If there are at least 9 bits left, it is certain to have more rbsp data */ |
|
465 return 1; |
|
466 |
|
467 if (numBytesLeft == 0 && bitbuf->bitpos == 0) |
|
468 /* Something may be wrong. Normally, there should be at least one bit left */ |
|
469 return 0; |
|
470 |
|
471 if (numBytesLeft == 1) { |
|
472 /* Insert last byte to currentBits */ |
|
473 bitbuf->currentBits = (bitbuf->currentBits << 8) | bitbuf->data[bitbuf->bytePos++]; |
|
474 bitbuf->bitpos += 8; |
|
475 } |
|
476 |
|
477 /* Copy the last bits into "lastBits", then compare it with 0x1..00 */ |
|
478 lastBits = bitbuf->currentBits & ~(((u_int32)-1)<<bitbuf->bitpos); |
|
479 |
|
480 if (lastBits == ((u_int32)1 << (bitbuf->bitpos-1))) |
|
481 return 0; |
|
482 else |
|
483 return 1; |
|
484 } |
|
485 |
|
486 |
|
487 /* |
|
488 * bibGetNumOfRemainingBits: |
|
489 * |
|
490 * Parameters: |
|
491 * bitbuf Bitbuffer object |
|
492 * |
|
493 * Function: |
|
494 * Return number of bits in bitbuffer. |
|
495 * |
|
496 * Returns: |
|
497 * Number of bits |
|
498 */ |
|
499 int32 bibGetNumRemainingBits(bitbuffer_s *bitbuf) |
|
500 { |
|
501 return bitbuf->bitpos + 8*(bitbuf->dataLen - bitbuf->bytePos); |
|
502 } |
|
503 |
|
504 |
|
505 // syncBitBufferBitpos |
|
506 // Synchronizes the input bit buffer's bit position to be between one and eight, |
|
507 // modifies the byte position and current bits if required. |
|
508 void syncBitBufferBitpos(bitbuffer_s *bitbuf) |
|
509 { |
|
510 // To be able to edit the bitbuffer, reset the bit position to be eight at the maximum |
|
511 while (bitbuf->bitpos > 8) |
|
512 { |
|
513 // If bit position is modified, then modify byte position and current bits accordingly |
|
514 bitbuf->bitpos -= 8; |
|
515 bitbuf->bytePos--; |
|
516 bitbuf->currentBits >>= 8; |
|
517 } |
|
518 } |
|
519 |
|
520 |
|
521 // addStartCodeEmulationBytes |
|
522 // Adds start code emulation bytes to the input bit buffer. |
|
523 static int addStartCodeEmulationBytes(bitbuffer_s *bitbuf) |
|
524 { |
|
525 TInt i = 0; |
|
526 TInt32 lastBytes; |
|
527 |
|
528 |
|
529 // Add prevention bytes that were removed for processing |
|
530 lastBytes = 0xffffffff; |
|
531 while (i < bitbuf->dataLen) |
|
532 { |
|
533 lastBytes = (lastBytes << 8) | bitbuf->data[i]; |
|
534 |
|
535 if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4)) |
|
536 { |
|
537 // Add byte(s) to the bit buffer |
|
538 TInt error = AddBytesToBuffer(bitbuf, 1); |
|
539 |
|
540 if (error != 0) |
|
541 return error; |
|
542 |
|
543 // Adjust data length |
|
544 bitbuf->dataLen++; |
|
545 |
|
546 // Make room for the emulation prevention byte 0x03 to the buffer |
|
547 for (TInt k=bitbuf->dataLen; k>i; k--) |
|
548 { |
|
549 bitbuf->data[k] = bitbuf->data[k-1]; |
|
550 } |
|
551 |
|
552 // Add the emulation prevention byte to the buffer |
|
553 bitbuf->data[i+1] = 0x03; |
|
554 } |
|
555 |
|
556 i++; |
|
557 } |
|
558 return KErrNone; |
|
559 } |
|
560 |
|
561 |
|
562 // bibEnd |
|
563 // Takes care of the bit buffer after the frame has been processed. |
|
564 int bibEnd(bitbuffer_s *bitbuf) |
|
565 { |
|
566 #if ENCAPSULATED_NAL_PAYLOAD |
|
567 return addStartCodeEmulationBytes(bitbuf); |
|
568 #endif |
|
569 } |
|
570 |
|
571 |
|
572 // addStartCodeEmulationBytesSlice |
|
573 // Adds start code emulation bytes to the input bit buffer. |
|
574 static void addStartCodeEmulationBytesSlice(bitbuffer_s *bitbuf) |
|
575 { |
|
576 TInt i = 0; |
|
577 TInt32 lastBytes; |
|
578 |
|
579 |
|
580 // Add prevention bytes that were removed for processing |
|
581 lastBytes = 0xffffffff; |
|
582 while (i < bitbuf->dataLen) |
|
583 { |
|
584 lastBytes = (lastBytes << 8) | bitbuf->data[i]; |
|
585 |
|
586 if(((lastBytes & 0xffff) == 0x0000) && ((i+1) < bitbuf->dataLen) && (bitbuf->data[i+1] < 4)) |
|
587 { |
|
588 // Make room for the emulation prevention byte 0x03 to the buffer |
|
589 for (TInt k=bitbuf->dataLen; k>i; k--) |
|
590 { |
|
591 bitbuf->data[k] = bitbuf->data[k-1]; |
|
592 } |
|
593 // Adjust data length |
|
594 bitbuf->dataLen++; |
|
595 |
|
596 // Add the emulation prevention byte to the buffer |
|
597 bitbuf->data[i+1] = 0x03; |
|
598 } |
|
599 |
|
600 i++; |
|
601 } |
|
602 } |
|
603 |
|
604 |
|
605 // bibEndSlice |
|
606 // Takes care of the bit buffer after the frame has been processed. |
|
607 void bibEndSlice(bitbuffer_s *bitbuf) |
|
608 { |
|
609 #if ENCAPSULATED_NAL_PAYLOAD |
|
610 addStartCodeEmulationBytesSlice(bitbuf); |
|
611 #endif |
|
612 } |
|
613 |
|