Commit 22493ab9 authored by Mike Melanson's avatar Mike Melanson

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
parent 6d71b382
......@@ -1132,6 +1132,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
int current_run = 0;
int decode_fully_flags = 0;
int decode_partial_blocks = 0;
int first_c_fragment_seen;
int i, j;
int current_fragment;
......@@ -1223,6 +1224,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
s->coded_fragment_list_index = 0;
s->first_coded_y_fragment = s->first_coded_c_fragment = 0;
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);
for (i = 0; i < s->superblock_count; i++) {
......@@ -1253,15 +1255,18 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
}
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 =
MODE_INTER_NO_MV;
s->coded_fragment_list[s->coded_fragment_list_index] =
current_fragment;
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->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
}
s->coded_fragment_list_index++;
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] =
current_fragment;
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->last_coded_y_fragment = s->first_coded_c_fragment - 1;
first_c_fragment_seen = 1;
}
s->coded_fragment_list_index++;
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)
/* no C fragments coded */
if (!first_c_fragment_seen)
/* only Y fragments coded in this frame */
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;
debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n",
s->coded_fragment_list_index,
s->first_coded_y_fragment,
......@@ -1656,14 +1665,12 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
DCTELEM coeff;
Vp3Fragment *fragment;
if ((first_fragment < 0) ||
(first_fragment >= s->fragment_count) ||
(last_fragment < 0) ||
if ((first_fragment >= s->fragment_count) ||
(last_fragment >= s->fragment_count)) {
printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n",
first_fragment, last_fragment);
return 1;
return 0;
}
for (i = first_fragment; i <= last_fragment; i++) {
......@@ -2433,6 +2440,11 @@ static int vp3_decode_frame(AVCodecContext *avctx,
counter++;
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->golden_frame.data[0])
avctx->release_buffer(avctx, &s->golden_frame);
......@@ -2458,22 +2470,16 @@ static int vp3_decode_frame(AVCodecContext *avctx,
} else {
debug_vp3("\n");
/* allocate a new current frame */
s->current_frame.reference = 0;
if(avctx->get_buffer(avctx, &s->current_frame) < 0) {
printf("vp3: get_buffer() failed\n");
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);
#if KEYFRAMES_ONLY
......
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