Merge "Fix: check cx_data buffer prior to write"
This commit is contained in:
commit
2c0b4a24b9
@ -221,7 +221,7 @@ extern "C"
|
||||
// receive a frames worth of data caller can assume that a copy of this frame is made
|
||||
// and not just a copy of the pointer..
|
||||
int vp8_receive_raw_frame(VP8_PTR comp, unsigned int frame_flags, YV12_BUFFER_CONFIG *sd, int64_t time_stamp, int64_t end_time_stamp);
|
||||
int vp8_get_compressed_data(VP8_PTR comp, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, int64_t *time_stamp, int64_t *time_end, int flush);
|
||||
int vp8_get_compressed_data(VP8_PTR comp, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, unsigned char *dest_end, int64_t *time_stamp, int64_t *time_end, int flush);
|
||||
int vp8_get_preview_raw_frame(VP8_PTR comp, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t *flags);
|
||||
|
||||
int vp8_use_as_reference(VP8_PTR comp, int ref_frame_flags);
|
||||
|
@ -358,11 +358,12 @@ static void write_partition_size(unsigned char *cx_data, int size)
|
||||
|
||||
}
|
||||
|
||||
static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, int num_part, int *size)
|
||||
static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data, unsigned char * cx_data_end, int num_part, int *size)
|
||||
{
|
||||
|
||||
int i;
|
||||
unsigned char *ptr = cx_data;
|
||||
unsigned char *ptr_end = cx_data_end;
|
||||
unsigned int shift;
|
||||
vp8_writer *w = &cpi->bc2;
|
||||
*size = 3 * (num_part - 1);
|
||||
@ -371,7 +372,7 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
|
||||
|
||||
for (i = 0; i < num_part; i++)
|
||||
{
|
||||
vp8_start_encode(w, ptr);
|
||||
vp8_start_encode(w, ptr, ptr_end);
|
||||
{
|
||||
unsigned int split;
|
||||
int count = w->count;
|
||||
@ -437,7 +438,13 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
|
||||
w->buffer[x] += 1;
|
||||
}
|
||||
|
||||
validate_buffer(w->buffer + w->pos,
|
||||
1,
|
||||
cx_data_end,
|
||||
&cpi->common.error);
|
||||
|
||||
w->buffer[w->pos++] = (lowvalue >> (24 - offset));
|
||||
|
||||
lowvalue <<= offset;
|
||||
shift = count;
|
||||
lowvalue &= 0xffffff;
|
||||
@ -497,7 +504,14 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
|
||||
w->buffer[x] += 1;
|
||||
}
|
||||
|
||||
w->buffer[w->pos++] = (lowvalue >> (24 - offset));
|
||||
validate_buffer(w->buffer + w->pos,
|
||||
1,
|
||||
cx_data_end,
|
||||
&cpi->common.error);
|
||||
|
||||
w->buffer[w->pos++] =
|
||||
(lowvalue >> (24 - offset));
|
||||
|
||||
lowvalue <<= offset;
|
||||
shift = count;
|
||||
lowvalue &= 0xffffff;
|
||||
@ -543,7 +557,13 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
|
||||
if (!++count)
|
||||
{
|
||||
count = -8;
|
||||
validate_buffer(w->buffer + w->pos,
|
||||
1,
|
||||
cx_data_end,
|
||||
&cpi->common.error);
|
||||
|
||||
w->buffer[w->pos++] = (lowvalue >> 24);
|
||||
|
||||
lowvalue &= 0xffffff;
|
||||
}
|
||||
}
|
||||
@ -1526,7 +1546,7 @@ static void put_delta_q(vp8_writer *bc, int delta_q)
|
||||
vp8_write_bit(bc, 0);
|
||||
}
|
||||
|
||||
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char * dest_end, unsigned long *size)
|
||||
{
|
||||
int i, j;
|
||||
VP8_HEADER oh;
|
||||
@ -1536,6 +1556,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
int extra_bytes_packed = 0;
|
||||
|
||||
unsigned char *cx_data = dest;
|
||||
unsigned char *cx_data_end = dest_end;
|
||||
const int *mb_feature_data_bits;
|
||||
|
||||
oh.show_frame = (int) pc->show_frame;
|
||||
@ -1544,6 +1565,8 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
oh.first_partition_length_in_bytes = 0;
|
||||
|
||||
mb_feature_data_bits = vp8_mb_feature_data_bits;
|
||||
|
||||
validate_buffer(cx_data, 3, cx_data_end, &cpi->common.error);
|
||||
cx_data += 3;
|
||||
|
||||
#if defined(SECTIONBITS_OUTPUT)
|
||||
@ -1560,6 +1583,8 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
{
|
||||
int v;
|
||||
|
||||
validate_buffer(cx_data, 7, cx_data_end, &cpi->common.error);
|
||||
|
||||
// Start / synch code
|
||||
cx_data[0] = 0x9D;
|
||||
cx_data[1] = 0x01;
|
||||
@ -1573,10 +1598,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
cx_data[5] = v;
|
||||
cx_data[6] = v >> 8;
|
||||
|
||||
|
||||
extra_bytes_packed = 7;
|
||||
cx_data += extra_bytes_packed ;
|
||||
|
||||
vp8_start_encode(bc, cx_data);
|
||||
vp8_start_encode(bc, cx_data, cx_data_end);
|
||||
|
||||
// signal clr type
|
||||
vp8_write_bit(bc, pc->clr_type);
|
||||
@ -1584,7 +1610,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
|
||||
}
|
||||
else
|
||||
vp8_start_encode(bc, cx_data);
|
||||
vp8_start_encode(bc, cx_data, cx_data_end);
|
||||
|
||||
|
||||
// Signal whether or not Segmentation is enabled
|
||||
@ -1841,13 +1867,13 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
|
||||
int asize;
|
||||
num_part = 1 << pc->multi_token_partition;
|
||||
|
||||
pack_tokens_into_partitions(cpi, cx_data + bc->pos, num_part, &asize);
|
||||
pack_tokens_into_partitions(cpi, cx_data + bc->pos, cx_data_end, num_part, &asize);
|
||||
|
||||
*size += asize;
|
||||
}
|
||||
else
|
||||
{
|
||||
vp8_start_encode(&cpi->bc2, cx_data + bc->pos);
|
||||
vp8_start_encode(&cpi->bc2, cx_data + bc->pos, cx_data_end);
|
||||
|
||||
#if CONFIG_MULTITHREAD
|
||||
if (cpi->b_multi_threaded)
|
||||
|
@ -27,13 +27,13 @@ void vp8cx_pack_mb_row_tokens_armv5(VP8_COMP *cpi, vp8_writer *w,
|
||||
const vp8_tree_index *);
|
||||
# define pack_tokens(a,b,c) \
|
||||
vp8cx_pack_tokens_armv5(a,b,c,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
|
||||
# define pack_tokens_into_partitions(a,b,c,d) \
|
||||
# define pack_tokens_into_partitions(a,b,unused,c,d) \
|
||||
vp8cx_pack_tokens_into_partitions_armv5(a,b,c,d,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
|
||||
# define pack_mb_row_tokens(a,b) \
|
||||
vp8cx_pack_mb_row_tokens_armv5(a,b,vp8_coef_encodings,vp8_extra_bits,vp8_coef_tree)
|
||||
#else
|
||||
# define pack_tokens(a,b,c) pack_tokens_c(a,b,c)
|
||||
# define pack_tokens_into_partitions(a,b,c,d) pack_tokens_into_partitions_c(a,b,c,d)
|
||||
# define pack_tokens_into_partitions(a,b,c,d,e) pack_tokens_into_partitions_c(a,b,c,d,e)
|
||||
# define pack_mb_row_tokens(a,b) pack_mb_row_tokens_c(a,b)
|
||||
#endif
|
||||
#endif
|
||||
|
@ -40,15 +40,16 @@ const unsigned int vp8_prob_cost[256] =
|
||||
22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 3, 1, 1
|
||||
};
|
||||
|
||||
void vp8_start_encode(BOOL_CODER *br, unsigned char *source)
|
||||
void vp8_start_encode(BOOL_CODER *br, unsigned char *source, unsigned char *source_end)
|
||||
{
|
||||
|
||||
br->lowvalue = 0;
|
||||
br->range = 255;
|
||||
br->value = 0;
|
||||
br->count = -24;
|
||||
br->buffer = source;
|
||||
br->pos = 0;
|
||||
br->lowvalue = 0;
|
||||
br->range = 255;
|
||||
br->value = 0;
|
||||
br->count = -24;
|
||||
br->buffer = source;
|
||||
br->buffer_end = source_end;
|
||||
br->pos = 0;
|
||||
}
|
||||
|
||||
void vp8_stop_encode(BOOL_CODER *br)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define __INC_BOOLHUFF_H
|
||||
|
||||
#include "vpx_ports/mem.h"
|
||||
#include "vpx/internal/vpx_codec_internal.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -29,13 +30,15 @@ typedef struct
|
||||
int count;
|
||||
unsigned int pos;
|
||||
unsigned char *buffer;
|
||||
unsigned char *buffer_end;
|
||||
struct vpx_internal_error_info *error;
|
||||
|
||||
// Variables used to track bit costs without outputing to the bitstream
|
||||
unsigned int measure_cost;
|
||||
unsigned long bit_counter;
|
||||
} BOOL_CODER;
|
||||
|
||||
extern void vp8_start_encode(BOOL_CODER *bc, unsigned char *buffer);
|
||||
extern void vp8_start_encode(BOOL_CODER *bc, unsigned char *buffer, unsigned char *buffer_end);
|
||||
|
||||
extern void vp8_encode_value(BOOL_CODER *br, int data, int bits);
|
||||
extern void vp8_stop_encode(BOOL_CODER *bc);
|
||||
@ -44,7 +47,19 @@ extern const unsigned int vp8_prob_cost[256];
|
||||
|
||||
DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
|
||||
|
||||
static int validate_buffer(const unsigned char *start,
|
||||
size_t len,
|
||||
const unsigned char *end,
|
||||
struct vpx_internal_error_info *error)
|
||||
{
|
||||
if (start + len > start && start + len < end)
|
||||
return 1;
|
||||
else
|
||||
vpx_internal_error(error, VPX_CODEC_CORRUPT_FRAME,
|
||||
"Truncated packet or corrupt partition ");
|
||||
|
||||
return 0;
|
||||
}
|
||||
static void vp8_encode_bool(BOOL_CODER *br, int bit, int probability)
|
||||
{
|
||||
unsigned int split;
|
||||
@ -96,7 +111,9 @@ static void vp8_encode_bool(BOOL_CODER *br, int bit, int probability)
|
||||
br->buffer[x] += 1;
|
||||
}
|
||||
|
||||
validate_buffer(br->buffer + br->pos, 1, br->buffer_end, br->error);
|
||||
br->buffer[br->pos++] = (lowvalue >> (24 - offset));
|
||||
|
||||
lowvalue <<= offset;
|
||||
shift = count;
|
||||
lowvalue &= 0xffffff;
|
||||
|
@ -3447,6 +3447,7 @@ static void encode_frame_to_data_rate
|
||||
VP8_COMP *cpi,
|
||||
unsigned long *size,
|
||||
unsigned char *dest,
|
||||
unsigned char* dest_end,
|
||||
unsigned int *frame_flags
|
||||
)
|
||||
{
|
||||
@ -4414,7 +4415,7 @@ static void encode_frame_to_data_rate
|
||||
#endif
|
||||
|
||||
// build the bitstream
|
||||
vp8_pack_bitstream(cpi, dest, size);
|
||||
vp8_pack_bitstream(cpi, dest, dest_end, size);
|
||||
|
||||
#if CONFIG_MULTITHREAD
|
||||
/* if PSNR packets are generated we have to wait for the lpf */
|
||||
@ -4827,13 +4828,13 @@ static void check_gf_quality(VP8_COMP *cpi)
|
||||
}
|
||||
|
||||
#if !(CONFIG_REALTIME_ONLY)
|
||||
static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags)
|
||||
static void Pass2Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned char * dest_end, unsigned int *frame_flags)
|
||||
{
|
||||
|
||||
if (!cpi->common.refresh_alt_ref_frame)
|
||||
vp8_second_pass(cpi);
|
||||
|
||||
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
||||
encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags);
|
||||
cpi->twopass.bits_left -= 8 * *size;
|
||||
|
||||
if (!cpi->common.refresh_alt_ref_frame)
|
||||
@ -4906,7 +4907,7 @@ static int frame_is_reference(const VP8_COMP *cpi)
|
||||
}
|
||||
|
||||
|
||||
int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, int64_t *time_stamp, int64_t *time_end, int flush)
|
||||
int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned long *size, unsigned char *dest, unsigned char *dest_end, int64_t *time_stamp, int64_t *time_end, int flush)
|
||||
{
|
||||
#if HAVE_ARMV7
|
||||
int64_t store_reg[8];
|
||||
@ -4921,6 +4922,14 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
if (!cpi)
|
||||
return -1;
|
||||
|
||||
if (setjmp(cpi->common.error.jmp)){
|
||||
cpi->common.error.setjmp = 0;
|
||||
return VPX_CODEC_CORRUPT_FRAME;
|
||||
}
|
||||
|
||||
cpi->bc.error = &cpi->common.error;
|
||||
cpi->common.error.setjmp = 1;
|
||||
|
||||
#if HAVE_ARMV7
|
||||
#if CONFIG_RUNTIME_CPU_DETECT
|
||||
if (cm->rtcd.flags & HAS_NEON)
|
||||
@ -5134,11 +5143,11 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
}
|
||||
else if (cpi->pass == 2)
|
||||
{
|
||||
Pass2Encode(cpi, size, dest, frame_flags);
|
||||
Pass2Encode(cpi, size, dest, dest_end, frame_flags);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
||||
encode_frame_to_data_rate(cpi, size, dest, dest_end, frame_flags);
|
||||
|
||||
if (cpi->compressor_speed == 2)
|
||||
{
|
||||
@ -5371,6 +5380,8 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
|
||||
}
|
||||
#endif
|
||||
|
||||
cpi->common.error.setjmp = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -683,7 +683,7 @@ void control_data_rate(VP8_COMP *cpi);
|
||||
|
||||
void vp8_encode_frame(VP8_COMP *cpi);
|
||||
|
||||
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size);
|
||||
void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned char *dest_end, unsigned long *size);
|
||||
|
||||
void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x);
|
||||
|
||||
|
@ -761,6 +761,8 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx,
|
||||
int64_t dst_time_stamp, dst_end_time_stamp;
|
||||
unsigned long size, cx_data_sz;
|
||||
unsigned char *cx_data;
|
||||
unsigned char *cx_data_end;
|
||||
int comp_data_state = 0;
|
||||
|
||||
/* Set up internal flags */
|
||||
if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
|
||||
@ -793,11 +795,25 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx,
|
||||
|
||||
cx_data = ctx->cx_data;
|
||||
cx_data_sz = ctx->cx_data_sz;
|
||||
cx_data_end = ctx->cx_data + cx_data_sz;
|
||||
lib_flags = 0;
|
||||
|
||||
while (cx_data_sz >= ctx->cx_data_sz / 2
|
||||
&& -1 != vp8_get_compressed_data(ctx->cpi, &lib_flags, &size, cx_data, &dst_time_stamp, &dst_end_time_stamp, !img))
|
||||
while (cx_data_sz >= ctx->cx_data_sz / 2)
|
||||
{
|
||||
comp_data_state = vp8_get_compressed_data(ctx->cpi,
|
||||
&lib_flags,
|
||||
&size,
|
||||
cx_data,
|
||||
cx_data_end,
|
||||
&dst_time_stamp,
|
||||
&dst_end_time_stamp,
|
||||
!img);
|
||||
|
||||
if(comp_data_state == VPX_CODEC_CORRUPT_FRAME)
|
||||
return VPX_CODEC_CORRUPT_FRAME;
|
||||
else if(comp_data_state == -1)
|
||||
break;
|
||||
|
||||
if (size)
|
||||
{
|
||||
vpx_codec_pts_t round, delta;
|
||||
|
Loading…
x
Reference in New Issue
Block a user