fix subtle logic problem in block unpacker that leads to incorrect token

decoding which leads to segfaults

Originally committed as revision 1890 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Mike Melanson 2003-05-19 01:22:46 +00:00
parent 6d71b38207
commit 22493ab9cb

View File

@ -1132,6 +1132,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
int current_run = 0; int current_run = 0;
int decode_fully_flags = 0; int decode_fully_flags = 0;
int decode_partial_blocks = 0; int decode_partial_blocks = 0;
int first_c_fragment_seen;
int i, j; int i, j;
int current_fragment; int current_fragment;
@ -1223,6 +1224,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
s->coded_fragment_list_index = 0; s->coded_fragment_list_index = 0;
s->first_coded_y_fragment = s->first_coded_c_fragment = 0; s->first_coded_y_fragment = s->first_coded_c_fragment = 0;
s->last_coded_y_fragment = s->last_coded_c_fragment = -1; s->last_coded_y_fragment = s->last_coded_c_fragment = -1;
first_c_fragment_seen = 0;
memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);
for (i = 0; i < s->superblock_count; i++) { for (i = 0; i < s->superblock_count; i++) {
@ -1253,15 +1255,18 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
} }
if (bit) { if (bit) {
/* mode will be decoded in the next phase */ /* default mode; actual mode will be decoded in
* the next phase */
s->all_fragments[current_fragment].coding_method = s->all_fragments[current_fragment].coding_method =
MODE_INTER_NO_MV; MODE_INTER_NO_MV;
s->coded_fragment_list[s->coded_fragment_list_index] = s->coded_fragment_list[s->coded_fragment_list_index] =
current_fragment; current_fragment;
if ((current_fragment >= s->u_fragment_start) && if ((current_fragment >= s->u_fragment_start) &&
(s->last_coded_y_fragment == -1)) { (s->last_coded_y_fragment == -1) &&
(!first_c_fragment_seen)) {
s->first_coded_c_fragment = s->coded_fragment_list_index; s->first_coded_c_fragment = s->coded_fragment_list_index;
s->last_coded_y_fragment = s->first_coded_c_fragment - 1; s->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
} }
s->coded_fragment_list_index++; s->coded_fragment_list_index++;
s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV;
@ -1286,9 +1291,11 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
s->coded_fragment_list[s->coded_fragment_list_index] = s->coded_fragment_list[s->coded_fragment_list_index] =
current_fragment; current_fragment;
if ((current_fragment >= s->u_fragment_start) && if ((current_fragment >= s->u_fragment_start) &&
(s->last_coded_y_fragment == -1)) { (s->last_coded_y_fragment == -1) &&
(!first_c_fragment_seen)) {
s->first_coded_c_fragment = s->coded_fragment_list_index; s->first_coded_c_fragment = s->coded_fragment_list_index;
s->last_coded_y_fragment = s->first_coded_c_fragment - 1; s->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
} }
s->coded_fragment_list_index++; s->coded_fragment_list_index++;
s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV;
@ -1299,11 +1306,13 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
} }
} }
if (s->first_coded_c_fragment == 0) if (!first_c_fragment_seen)
/* no C fragments coded */ /* only Y fragments coded in this frame */
s->last_coded_y_fragment = s->coded_fragment_list_index - 1; s->last_coded_y_fragment = s->coded_fragment_list_index - 1;
else else
/* end the list of coded fragments */
s->last_coded_c_fragment = s->coded_fragment_list_index - 1; s->last_coded_c_fragment = s->coded_fragment_list_index - 1;
debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n",
s->coded_fragment_list_index, s->coded_fragment_list_index,
s->first_coded_y_fragment, s->first_coded_y_fragment,
@ -1656,14 +1665,12 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
DCTELEM coeff; DCTELEM coeff;
Vp3Fragment *fragment; Vp3Fragment *fragment;
if ((first_fragment < 0) || if ((first_fragment >= s->fragment_count) ||
(first_fragment >= s->fragment_count) ||
(last_fragment < 0) ||
(last_fragment >= s->fragment_count)) { (last_fragment >= s->fragment_count)) {
printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n",
first_fragment, last_fragment); first_fragment, last_fragment);
return 1; return 0;
} }
for (i = first_fragment; i <= last_fragment; i++) { for (i = first_fragment; i <= last_fragment; i++) {
@ -2433,6 +2440,11 @@ static int vp3_decode_frame(AVCodecContext *avctx,
counter++; counter++;
if (s->keyframe) { if (s->keyframe) {
debug_vp3(", keyframe\n");
/* skip the other 2 header bytes for now */
skip_bits(&gb, 16);
if (s->last_frame.data[0] == s->golden_frame.data[0]) { if (s->last_frame.data[0] == s->golden_frame.data[0]) {
if (s->golden_frame.data[0]) if (s->golden_frame.data[0])
avctx->release_buffer(avctx, &s->golden_frame); avctx->release_buffer(avctx, &s->golden_frame);
@ -2458,22 +2470,16 @@ static int vp3_decode_frame(AVCodecContext *avctx,
} else { } else {
debug_vp3("\n");
/* allocate a new current frame */ /* allocate a new current frame */
s->current_frame.reference = 0; s->current_frame.reference = 0;
if(avctx->get_buffer(avctx, &s->current_frame) < 0) { if(avctx->get_buffer(avctx, &s->current_frame) < 0) {
printf("vp3: get_buffer() failed\n"); printf("vp3: get_buffer() failed\n");
return -1; return -1;
} }
} }
if (s->keyframe) {
debug_vp3(", keyframe\n");
/* skip the other 2 header bytes for now */
skip_bits(&gb, 16);
} else
debug_vp3("\n");
init_frame(s, &gb); init_frame(s, &gb);
#if KEYFRAMES_ONLY #if KEYFRAMES_ONLY