From 43d7c6118d64a8b2772e2d9e0c13413968e776f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Reimar=20D=C3=B6ffinger?= Date: Thu, 1 Oct 2009 15:40:29 +0000 Subject: [PATCH] put_bits can only reliably write up to 31 bit bits, above it relies on undefined shift behaviour. Document this, fix the assert and add a put_bits32 to handle writing 32 bits and use that where necessary. Originally committed as revision 20124 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/alacenc.c | 2 +- libavcodec/put_bits.h | 22 +++++++++++++++++++++- libavcodec/vorbis_enc.c | 16 ++++++++-------- libavformat/mpegenc.c | 4 ++-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index 5e8defb..691e6df 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -123,7 +123,7 @@ static void write_frame_header(AlacEncodeContext *s, int is_verbatim) put_bits(&s->pbctx, 1, 1); // Sample count is in the header put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim - put_bits(&s->pbctx, 32, s->avctx->frame_size); // No. of samples in the frame + put_bits32(&s->pbctx, s->avctx->frame_size); // No. of samples in the frame } static void calc_predictor_params(AlacEncodeContext *s, int ch) diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 4b4b3a8..b081c26 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -136,6 +136,10 @@ void ff_put_string(PutBitContext * pbc, const char *s, int terminate_string); */ void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); +/** + * Write up to 31 bits into a bitstream. + * Use put_bits32 to write 32 bits. + */ static inline void put_bits(PutBitContext *s, int n, unsigned int value) #ifndef ALT_BITSTREAM_WRITER { @@ -143,7 +147,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) int bit_left; // printf("put_bits=%d %x\n", n, value); - assert(n == 32 || value < (1U << n)); + assert(n <= 31 && value < (1U << n)); bit_buf = s->bit_buf; bit_left = s->bit_left; @@ -260,6 +264,22 @@ static inline void put_sbits(PutBitContext *pb, int bits, int32_t val) } /** + * Write exactly 32 bits into a bitstream + */ +static void av_unused put_bits32(PutBitContext *s, uint32_t value) +{ + int lo = value & 0xffff; + int hi = value >> 16; +#ifdef ALT_BITSTREAM_WRITER_LE + put_bits(s, 16, lo); + put_bits(s, 16, hi); +#else + put_bits(s, 16, hi); + put_bits(s, 16, lo); +#endif +} + +/** * Returns the pointer to the byte where the bitstream writer will put * the next bit. */ diff --git a/libavcodec/vorbis_enc.c b/libavcodec/vorbis_enc.c index 508a4f3..61f78b5 100644 --- a/libavcodec/vorbis_enc.c +++ b/libavcodec/vorbis_enc.c @@ -386,7 +386,7 @@ static void put_float(PutBitContext *pb, float f) mant = -mant; } res |= mant | (exp << 21); - put_bits(pb, 32, res); + put_bits32(pb, res); } static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb) @@ -531,12 +531,12 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) init_put_bits(&pb, p, buffer_len); put_bits(&pb, 8, 1); //magic ff_put_string(&pb, "vorbis", 0); - put_bits(&pb, 32, 0); // version + put_bits32(&pb, 0); // version put_bits(&pb, 8, venc->channels); - put_bits(&pb, 32, venc->sample_rate); - put_bits(&pb, 32, 0); // bitrate - put_bits(&pb, 32, 0); // bitrate - put_bits(&pb, 32, 0); // bitrate + put_bits32(&pb, venc->sample_rate); + put_bits32(&pb, 0); // bitrate + put_bits32(&pb, 0); // bitrate + put_bits32(&pb, 0); // bitrate put_bits(&pb, 4, venc->log2_blocksize[0]); put_bits(&pb, 4, venc->log2_blocksize[1]); put_bits(&pb, 1, 1); // framing @@ -550,8 +550,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) init_put_bits(&pb, p, buffer_len); put_bits(&pb, 8, 3); //magic ff_put_string(&pb, "vorbis", 0); - put_bits(&pb, 32, 0); // vendor length TODO - put_bits(&pb, 32, 0); // amount of comments + put_bits32(&pb, 0); // vendor length TODO + put_bits32(&pb, 0); // amount of comments put_bits(&pb, 1, 1); // framing flush_put_bits(&pb); diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c index df4c991..a471b38 100644 --- a/libavformat/mpegenc.c +++ b/libavformat/mpegenc.c @@ -89,7 +89,7 @@ static int put_pack_header(AVFormatContext *ctx, init_put_bits(&pb, buf, 128); - put_bits(&pb, 32, PACK_START_CODE); + put_bits32(&pb, PACK_START_CODE); if (s->is_mpeg2) { put_bits(&pb, 2, 0x1); } else { @@ -125,7 +125,7 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str init_put_bits(&pb, buf, 128); - put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); + put_bits32(&pb, SYSTEM_HEADER_START_CODE); put_bits(&pb, 16, 0); put_bits(&pb, 1, 1); -- 2.7.4