avcodec/get_bits: Add get_bits_bytesize()

And use it to avoid accesses to GetBitContext.buffer_end.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt
2025-07-04 14:22:31 +02:00
parent d20a4ef93c
commit 367cf961ea
8 changed files with 38 additions and 11 deletions

View File

@@ -82,6 +82,7 @@
# define bits_init8 bits_init8_le
# define bits_tell bits_tell_le
# define bits_size bits_size_le
# define bits_bytesize bits_bytesize_le
# define bits_left bits_left_le
# define bits_read_bit bits_read_bit_le
# define bits_read_nz bits_read_nz_le
@@ -111,6 +112,7 @@
# define bits_init8 bits_init8_be
# define bits_tell bits_tell_be
# define bits_size bits_size_be
# define bits_bytesize bits_bytesize_be
# define bits_left bits_left_be
# define bits_read_bit bits_read_bit_be
# define bits_read_nz bits_read_nz_be

View File

@@ -156,6 +156,14 @@ static inline int BS_FUNC(size)(const BSCTX *bc)
return bc->size_in_bits;
}
/**
* Return buffer size in bytes.
*/
static inline int BS_FUNC(bytesize)(const BSCTX *bc, int round_up)
{
return (bc->size_in_bits + (round_up ? 7 : 0)) >> 3;
}
/**
* Return the number of the bits left in a buffer.
*/

View File

@@ -76,6 +76,7 @@
typedef BitstreamContext GetBitContext;
#define get_bits_count bits_tell
#define get_bits_bytesize bits_bytesize
#define get_bits_left bits_left
#define skip_bits_long bits_skip
#define skip_bits bits_skip
@@ -251,6 +252,20 @@ static inline int get_bits_count(const GetBitContext *s)
return s->index;
}
/**
* Get the size of the GetBitContext's buffer in bytes.
*
* @param s the GetBitContext
* @param round_up If set, the number of bits will be rounded up to full bytes;
* this does not matter if the number of bits is known to be
* a multiple of eight, e.g. if the GetBitContext has been
* initialized with init_get_bits8.
*/
static inline int get_bits_bytesize(const GetBitContext *s, int round_up)
{
return (s->size_in_bits + (round_up ? 7 : 0)) >> 3;
}
/**
* Skips the specified number of bits.
* @param n the number of bits to skip,

View File

@@ -208,7 +208,8 @@ static int decode_slice(H263DecContext *const h)
if (h->c.avctx->hwaccel) {
const uint8_t *start = h->gb.buffer + get_bits_count(&h->gb) / 8;
ret = FF_HW_CALL(h->c.avctx, decode_slice, start, h->gb.buffer_end - start);
ret = FF_HW_CALL(h->c.avctx, decode_slice, start,
get_bits_bytesize(&h->gb, 0) - get_bits_count(&h->gb) / 8);
// ensure we exit decode loop
h->c.mb_y = h->c.mb_height;
return ret;
@@ -372,7 +373,7 @@ static int decode_slice(H263DecContext *const h)
if (h->c.codec_id == AV_CODEC_ID_H263 &&
(h->c.workaround_bugs & FF_BUG_AUTODETECT) &&
get_bits_left(&h->gb) >= 64 &&
AV_RB64(h->gb.buffer_end - 8) == 0xCDCDCDCDFC7F0000) {
AV_RB64(h->gb.buffer + (get_bits_bytesize(&h->gb, 0) - 8)) == 0xCDCDCDCDFC7F0000) {
h->padding_bug_score += 32;
}
@@ -546,7 +547,7 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict,
if (avctx->hwaccel) {
ret = FF_HW_CALL(avctx, start_frame, NULL,
h->gb.buffer, h->gb.buffer_end - h->gb.buffer);
h->gb.buffer, get_bits_bytesize(&h->gb, 0));
if (ret < 0 )
return ret;
}

View File

@@ -294,7 +294,7 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
if (!sps)
return AVERROR(ENOMEM);
sps->data_size = gb->buffer_end - gb->buffer;
sps->data_size = get_bits_bytesize(gb, 1);
if (sps->data_size > sizeof(sps->data)) {
av_log(avctx, AV_LOG_DEBUG, "Truncating likely oversized SPS\n");
sps->data_size = sizeof(sps->data);
@@ -712,7 +712,7 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct
if (!pps)
return AVERROR(ENOMEM);
pps->data_size = gb->buffer_end - gb->buffer;
pps->data_size = get_bits_bytesize(gb, 1);
if (pps->data_size > sizeof(pps->data)) {
av_log(avctx, AV_LOG_DEBUG, "Truncating likely oversized PPS "
"(%"SIZE_SPECIFIER" > %"SIZE_SPECIFIER")\n",

View File

@@ -2752,7 +2752,7 @@ static int hls_decode_entry(HEVCContext *s, GetBitContext *gb)
const HEVCPPS *const pps = s->pps;
const HEVCSPS *const sps = pps->sps;
const uint8_t *slice_data = gb->buffer + s->sh.data_offset;
const size_t slice_size = gb->buffer_end - gb->buffer - s->sh.data_offset;
const size_t slice_size = get_bits_bytesize(gb, 1) - s->sh.data_offset;
int ctb_size = 1 << sps->log2_ctb_size;
int more_data = 1;
int x_ctb = 0;

View File

@@ -763,7 +763,7 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
{
int i;
int vps_id = get_bits(gb, 4);
ptrdiff_t nal_size = gb->buffer_end - gb->buffer;
ptrdiff_t nal_size = get_bits_bytesize(gb, 1);
int ret = AVERROR_INVALIDDATA;
uint64_t layer1_id_included = 0;
unsigned vps_base_layer_internal_flag, vps_base_layer_available_flag;
@@ -1710,7 +1710,7 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx,
av_log(avctx, AV_LOG_DEBUG, "Decoding SPS\n");
sps->data_size = gb->buffer_end - gb->buffer;
sps->data_size = get_bits_bytesize(gb, 1);
sps->data = av_memdup(gb->buffer, sps->data_size);
if (!sps->data) {
ret = AVERROR(ENOMEM);
@@ -2165,7 +2165,7 @@ int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
const HEVCSPS *sps = NULL;
const HEVCVPS *vps = NULL;
int i, ret = 0;
ptrdiff_t nal_size = gb->buffer_end - gb->buffer;
ptrdiff_t nal_size = get_bits_bytesize(gb, 1);
unsigned int pps_id = get_ue_golomb_long(gb);
unsigned log2_parallel_merge_level_minus2;
HEVCPPS *pps;

View File

@@ -1635,6 +1635,7 @@ static int slice_decode_thread(AVCodecContext *c, void *arg)
{
Mpeg12SliceContext *const s = *(void **) arg;
const uint8_t *buf = s->gb.buffer;
const uint8_t *end = buf + get_bits_bytesize(&s->gb, 0);
int mb_y = s->c.start_mb_y;
const int field_pic = s->c.picture_structure != PICT_FRAME;
@@ -1644,7 +1645,7 @@ static int slice_decode_thread(AVCodecContext *c, void *arg)
uint32_t start_code;
int ret;
ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
ret = mpeg_decode_slice(s, mb_y, &buf, end - buf);
emms_c();
ff_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
ret, s->c.resync_mb_x, s->c.resync_mb_y, s->c.mb_x, s->c.mb_y,
@@ -1666,7 +1667,7 @@ static int slice_decode_thread(AVCodecContext *c, void *arg)
return 0;
start_code = -1;
buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code);
buf = avpriv_find_start_code(buf, end, &start_code);
if (start_code < SLICE_MIN_START_CODE || start_code > SLICE_MAX_START_CODE)
return AVERROR_INVALIDDATA;
mb_y = start_code - SLICE_MIN_START_CODE;