On 2017/6/8 18:02, Mark Thompson wrote:
> On 08/06/17 01:29, Jun Zhao wrote:
>> V3: Clean the code logic base on Michael's review.
>> V2: Add Add set_ue_golomb_long() to support 32bits UE golomb and update the 
>> unit test.
>>
>> From 4de3e0c30af7bc1901562000eda018a6d6849292 Mon Sep 17 00:00:00 2001
>> From: Jun Zhao <jun.z...@intel.com>
>> Date: Fri, 2 Jun 2017 15:05:49 +0800
>> Subject: [PATCH V3] lavc/golomb: Fix UE golomb overwrite issue.
>>
>> put_bits just support write up to 31 bits, when write 32 bit in
>> put_bits, it's will overwrite the bit buffer, because the default
>> assert level is 0, the av_assert2(n <= 31 && value < (1U << n))
>> in put_bits can not be trigger runtime. Add set_ue_golomb_long()
>> to support 32bits UE golomb.
>>
>> Signed-off-by: Jun Zhao <jun.z...@intel.com>
>> ---
>>  libavcodec/golomb.h       | 17 ++++++++++++++++-
>>  libavcodec/put_bits.h     | 35 +++++++++++++++++++++++++++++++++++
>>  libavcodec/tests/golomb.c | 19 +++++++++++++++++++
>>  3 files changed, 70 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
>> index 0833aff468..cba4861b10 100644
>> --- a/libavcodec/golomb.h
>> +++ b/libavcodec/golomb.h
>> @@ -458,7 +458,7 @@ static inline int get_te(GetBitContext *s, int r, char 
>> *file, const char *func,
>>  #endif /* TRACE */
>>  
>>  /**
>> - * write unsigned exp golomb code.
>> + * write unsigned exp golomb code. 2^16-2 at most.
>>   */
>>  static inline void set_ue_golomb(PutBitContext *pb, int i)
>>  {
>> @@ -473,6 +473,21 @@ static inline void set_ue_golomb(PutBitContext *pb, int 
>> i)
>>  }
>>  
>>  /**
>> + * write unsigned exp golomb code. 2^32-2 at most.
>> + */
>> +static inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i)
>> +{
>> +    av_assert2(i <= (0xffffffff - 2));
> 
> That's not 2^32 - 2.  Maybe use UINT32_MAX - 1
Your are right, will fix in the next version.

>> +
>> +    if (i < 256)
>> +        put_bits(pb, ff_ue_golomb_len[i], i + 1);
>> +    else {
>> +        int e = av_log2(i + 1);
>> +        put_bits64(pb, 2 * e + 1, i + 1);
>> +    }
>> +}
> 
> Please don't add a new function, just extend the existing one.  
> set_ue_golomb() is not used in any place where minor ricing is of any value, 
> and having another function will only be confusing over which to use (or, 
> more likely, people will always use the long version in order to avoid 
> thinking about it just like they do with get_ue_golomb() - cf. "grep 
> get_ue_golomb libavcodec/hevc*").

We have get_ue_golomb/get_ue_golomb_long/get_ue_golomb_31/..., I think add new 
set_ue_golomb_long is Ok,
the caller need to make the decision base on the value range even 
set_ue_golomb_long can cover the set_ue_golomb.

> 
>> +
>> +/**
>>   * write truncated unsigned exp golomb code.
>>   */
>>  static inline void set_te_golomb(PutBitContext *pb, int i, int range)
>> diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
>> index 68ed391195..06f0ebbeba 100644
>> --- a/libavcodec/put_bits.h
>> +++ b/libavcodec/put_bits.h
>> @@ -221,6 +221,41 @@ static void av_unused put_bits32(PutBitContext *s, 
>> uint32_t value)
>>  }
>>  
>>  /**
>> + * Write up to 64 bits into a bitstream.
>> + */
>> +static inline void put_bits64(PutBitContext *s, int n, uint64_t value)
> 
> put_bits32() writes exactly 32 bits, so it sounds like put_bits64() will 
> write exactly 64 bits.  I'm not sure what the function should be called, but 
> not that.
> 

For the function name, I can't find other good name short time. :(
>> +{
>> +    av_assert2(n <= 64 && value < (1UL << n));
> 
> 1UL is 32-bit on ILP32 platforms, so 1 << n is zero for n > 31 and the assert 
> will always fail.
> 
> Maybe "av_assert2(n == 64 || (n < 64 && value < UINT64_C(1) << n))"?
> 

Thanks again.

>> +
>> +    if (n < 32)
>> +        put_bits(s, n, value);
>> +    else if (n == 32)
>> +        put_bits32(s, value);
>> +    else if (n < 64) {
>> +        uint32_t lo = value & 0xffffffff;
>> +        uint32_t hi = value >> 32;
>> +#ifdef BITSTREAM_WRITER_LE
>> +        put_bits32(s, lo);
>> +        put_bits(s, n - 32, hi);
>> +#else
>> +        put_bits(s, n - 32, hi);
>> +        put_bits32(s, lo);
>> +#endif
>> +    } else {
>> +        uint32_t lo = value & 0xffffffff;
>> +        uint32_t hi = value >> 32;
>> +#ifdef BITSTREAM_WRITER_LE
>> +        put_bits32(s, lo);
>> +        put_bits32(s, hi);
>> +#else
>> +        put_bits32(s, hi);
>> +        put_bits32(s, lo);
>> +#endif
>> +
>> +    }
>> +}
>> +
>> +/**
>>   * Return the pointer to the byte where the bitstream writer will put
>>   * the next bit.
>>   */
>> diff --git a/libavcodec/tests/golomb.c b/libavcodec/tests/golomb.c
>> index 965367b7be..85b8a9390b 100644
>> --- a/libavcodec/tests/golomb.c
>> +++ b/libavcodec/tests/golomb.c
>> @@ -21,6 +21,7 @@
>>  #include <stdint.h>
>>  #include <stdio.h>
>>  
>> +#include "libavutil/internal.h"
>>  #include "libavutil/mem.h"
>>  
>>  #include "libavcodec/get_bits.h"
>> @@ -76,6 +77,24 @@ int main(void)
>>          }
>>      }
>>  
>> +#define EXTEND_L(i) ((i) << 4 | (i) & 15)
>> +    init_put_bits(&pb, temp, SIZE);
>> +    for (i = 0; i < COUNT; i++)
>> +        set_ue_golomb_long(&pb, EXTEND_L(i));
>> +    flush_put_bits(&pb);
>> +
>> +    init_get_bits(&gb, temp, 8 * SIZE);
>> +    for (i = 0; i < COUNT; i++) {
>> +        int j, s = show_bits_long(&gb, 32);
>> +
>> +        j = get_ue_golomb_long(&gb);
>> +        if (j != EXTEND_L(i)) {
>> +            fprintf(stderr, "get_ue_golomb_long: expected %d, got %d. "
>> +                    "bits: %8x\n", EXTEND_L(i), j, s);
>> +            ret = 1;
>> +        }
>> +    }
>> +
>>      init_put_bits(&pb, temp, SIZE);
>>      for (i = 0; i < COUNT; i++)
>>          set_se_golomb(&pb, i - COUNT / 2);
>> -- 
>> 2.11.0
>>
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to