@@ -20,6 +20,14 @@ ISrsEncoder::~ISrsEncoder()
20
20
{
21
21
}
22
22
23
+ ISrsDecoder::ISrsDecoder ()
24
+ {
25
+ }
26
+
27
+ ISrsDecoder::~ISrsDecoder ()
28
+ {
29
+ }
30
+
23
31
ISrsCodec::ISrsCodec ()
24
32
{
25
33
}
@@ -468,14 +476,23 @@ srs_error_t SrsBitBuffer::read_bits_ue(uint32_t &v)
468
476
return srs_error_new (ERROR_HEVC_NALU_UEV, " empty stream" );
469
477
}
470
478
479
+ // Unsigned Exp-Golomb decoding algorithm from ITU-T H.265 specification
471
480
// ue(v) in 9.2 Parsing process for Exp-Golomb codes
472
481
// ITU-T-H.265-2021.pdf, page 221.
473
- // Syntax elements coded as ue(v), me(v), or se(v) are Exp-Golomb-coded.
474
- // leadingZeroBits = -1;
475
- // for( b = 0; !b; leadingZeroBits++ )
476
- // b = read_bits( 1 )
477
- // The variable codeNum is then assigned as follows:
478
- // codeNum = (2<<leadingZeroBits) - 1 + read_bits( leadingZeroBits )
482
+ //
483
+ // Algorithm:
484
+ // 1. Count leading zero bits until first '1' bit
485
+ // 2. Read the '1' bit (prefix)
486
+ // 3. Read leadingZeroBits more bits (suffix)
487
+ // 4. Calculate: codeNum = (2^leadingZeroBits) - 1 + suffix_value
488
+ //
489
+ // Examples:
490
+ // "1" -> leadingZeroBits=0, suffix=none -> value=0
491
+ // "010" -> leadingZeroBits=1, suffix=0 -> value=1
492
+ // "011" -> leadingZeroBits=1, suffix=1 -> value=2
493
+ // "00100" -> leadingZeroBits=2, suffix=00 -> value=3
494
+
495
+ // Step 1: Count leading zero bits
479
496
int leadingZeroBits = -1 ;
480
497
for (int8_t b = 0 ; !b && !empty (); leadingZeroBits++) {
481
498
b = read_bit ();
@@ -485,7 +502,10 @@ srs_error_t SrsBitBuffer::read_bits_ue(uint32_t &v)
485
502
return srs_error_new (ERROR_HEVC_NALU_UEV, " %dbits overflow 31bits" , leadingZeroBits);
486
503
}
487
504
505
+ // Step 2: Calculate base value: (2^leadingZeroBits) - 1
488
506
v = (1 << leadingZeroBits) - 1 ;
507
+
508
+ // Step 3: Read suffix bits and add to base value
489
509
for (int i = 0 ; i < (int )leadingZeroBits; i++) {
490
510
if (empty ()) {
491
511
return srs_error_new (ERROR_HEVC_NALU_UEV, " no bytes for leadingZeroBits=%d" , leadingZeroBits);
@@ -506,15 +526,30 @@ srs_error_t SrsBitBuffer::read_bits_se(int32_t &v)
506
526
return srs_error_new (ERROR_HEVC_NALU_SEV, " empty stream" );
507
527
}
508
528
509
- // ue(v) in 9.2.1 General Parsing process for Exp-Golomb codes
510
- // ITU-T-H.265-2021.pdf, page 221.
529
+ // Signed Exp-Golomb decoding algorithm from ITU-T H.265 specification
530
+ // se(v) in 9.2.2 Mapping process for signed Exp-Golomb codes
531
+ // ITU-T-H.265-2021.pdf, page 222.
532
+ //
533
+ // Algorithm:
534
+ // 1. First decode as unsigned Exp-Golomb to get codeNum
535
+ // 2. Map to signed value using alternating positive/negative pattern:
536
+ // - If codeNum is odd: se_value = (codeNum + 1) / 2
537
+ // - If codeNum is even: se_value = -(codeNum / 2)
538
+ //
539
+ // Mapping table:
540
+ // codeNum: 0 1 2 3 4 5 6 7 8 ...
541
+ // se(v): 0 1 -1 2 -2 3 -3 4 -4 ...
542
+ //
543
+ // This encoding efficiently represents signed integers with smaller
544
+ // absolute values using fewer bits.
545
+
546
+ // Step 1: Decode unsigned Exp-Golomb value
511
547
uint32_t val = 0 ;
512
548
if ((err = read_bits_ue (val)) != srs_success) {
513
549
return srs_error_wrap (err, " read uev" );
514
550
}
515
551
516
- // se(v) in 9.2.2 Mapping process for signed Exp-Golomb codes
517
- // ITU-T-H.265-2021.pdf, page 222.
552
+ // Step 2: Map unsigned code to signed value
518
553
if (val & 0x01 ) {
519
554
v = (val + 1 ) / 2 ;
520
555
} else {
0 commit comments