Commit 43d7c611 authored by Reimar Döffinger's avatar Reimar Döffinger

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
parent ec656755
...@@ -123,7 +123,7 @@ static void write_frame_header(AlacEncodeContext *s, int is_verbatim) ...@@ -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, 1, 1); // Sample count is in the header
put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field 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, 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) static void calc_predictor_params(AlacEncodeContext *s, int ch)
......
...@@ -136,6 +136,10 @@ void ff_put_string(PutBitContext * pbc, const char *s, int terminate_string); ...@@ -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); 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) static inline void put_bits(PutBitContext *s, int n, unsigned int value)
#ifndef ALT_BITSTREAM_WRITER #ifndef ALT_BITSTREAM_WRITER
{ {
...@@ -143,7 +147,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) ...@@ -143,7 +147,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
int bit_left; int bit_left;
// printf("put_bits=%d %x\n", n, value); // 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_buf = s->bit_buf;
bit_left = s->bit_left; bit_left = s->bit_left;
...@@ -259,6 +263,22 @@ static inline void put_sbits(PutBitContext *pb, int bits, int32_t val) ...@@ -259,6 +263,22 @@ static inline void put_sbits(PutBitContext *pb, int bits, int32_t val)
put_bits(pb, bits, val & ((1<<bits)-1)); put_bits(pb, bits, val & ((1<<bits)-1));
} }
/**
* 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 * Returns the pointer to the byte where the bitstream writer will put
* the next bit. * the next bit.
......
...@@ -386,7 +386,7 @@ static void put_float(PutBitContext *pb, float f) ...@@ -386,7 +386,7 @@ static void put_float(PutBitContext *pb, float f)
mant = -mant; mant = -mant;
} }
res |= mant | (exp << 21); res |= mant | (exp << 21);
put_bits(pb, 32, res); put_bits32(pb, res);
} }
static void put_codebook_header(PutBitContext *pb, vorbis_enc_codebook *cb) 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) ...@@ -531,12 +531,12 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
init_put_bits(&pb, p, buffer_len); init_put_bits(&pb, p, buffer_len);
put_bits(&pb, 8, 1); //magic put_bits(&pb, 8, 1); //magic
ff_put_string(&pb, "vorbis", 0); 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, 8, venc->channels);
put_bits(&pb, 32, venc->sample_rate); put_bits32(&pb, venc->sample_rate);
put_bits(&pb, 32, 0); // bitrate put_bits32(&pb, 0); // bitrate
put_bits(&pb, 32, 0); // bitrate put_bits32(&pb, 0); // bitrate
put_bits(&pb, 32, 0); // bitrate put_bits32(&pb, 0); // bitrate
put_bits(&pb, 4, venc->log2_blocksize[0]); put_bits(&pb, 4, venc->log2_blocksize[0]);
put_bits(&pb, 4, venc->log2_blocksize[1]); put_bits(&pb, 4, venc->log2_blocksize[1]);
put_bits(&pb, 1, 1); // framing put_bits(&pb, 1, 1); // framing
...@@ -550,8 +550,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) ...@@ -550,8 +550,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out)
init_put_bits(&pb, p, buffer_len); init_put_bits(&pb, p, buffer_len);
put_bits(&pb, 8, 3); //magic put_bits(&pb, 8, 3); //magic
ff_put_string(&pb, "vorbis", 0); ff_put_string(&pb, "vorbis", 0);
put_bits(&pb, 32, 0); // vendor length TODO put_bits32(&pb, 0); // vendor length TODO
put_bits(&pb, 32, 0); // amount of comments put_bits32(&pb, 0); // amount of comments
put_bits(&pb, 1, 1); // framing put_bits(&pb, 1, 1); // framing
flush_put_bits(&pb); flush_put_bits(&pb);
......
...@@ -89,7 +89,7 @@ static int put_pack_header(AVFormatContext *ctx, ...@@ -89,7 +89,7 @@ static int put_pack_header(AVFormatContext *ctx,
init_put_bits(&pb, buf, 128); init_put_bits(&pb, buf, 128);
put_bits(&pb, 32, PACK_START_CODE); put_bits32(&pb, PACK_START_CODE);
if (s->is_mpeg2) { if (s->is_mpeg2) {
put_bits(&pb, 2, 0x1); put_bits(&pb, 2, 0x1);
} else { } else {
...@@ -125,7 +125,7 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str ...@@ -125,7 +125,7 @@ static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_str
init_put_bits(&pb, buf, 128); 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, 16, 0);
put_bits(&pb, 1, 1); put_bits(&pb, 1, 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment