Mercurial > libavcodec.hg
comparison vp3.c @ 1272:777d4145cdfb libavcodec
fix subtle logic problem in block unpacker that leads to incorrect token
decoding which leads to segfaults
author | tmmm |
---|---|
date | Mon, 19 May 2003 01:22:46 +0000 |
parents | a02df1ba6c7f |
children | 8988af3ae1e8 |
comparison
equal
deleted
inserted
replaced
1271:42ea05e4a391 | 1272:777d4145cdfb |
---|---|
1130 int bit = 0; | 1130 int bit = 0; |
1131 int current_superblock = 0; | 1131 int current_superblock = 0; |
1132 int current_run = 0; | 1132 int current_run = 0; |
1133 int decode_fully_flags = 0; | 1133 int decode_fully_flags = 0; |
1134 int decode_partial_blocks = 0; | 1134 int decode_partial_blocks = 0; |
1135 int first_c_fragment_seen; | |
1135 | 1136 |
1136 int i, j; | 1137 int i, j; |
1137 int current_fragment; | 1138 int current_fragment; |
1138 | 1139 |
1139 debug_vp3(" vp3: unpacking superblock coding\n"); | 1140 debug_vp3(" vp3: unpacking superblock coding\n"); |
1221 /* figure out which fragments are coded; iterate through each | 1222 /* figure out which fragments are coded; iterate through each |
1222 * superblock (all planes) */ | 1223 * superblock (all planes) */ |
1223 s->coded_fragment_list_index = 0; | 1224 s->coded_fragment_list_index = 0; |
1224 s->first_coded_y_fragment = s->first_coded_c_fragment = 0; | 1225 s->first_coded_y_fragment = s->first_coded_c_fragment = 0; |
1225 s->last_coded_y_fragment = s->last_coded_c_fragment = -1; | 1226 s->last_coded_y_fragment = s->last_coded_c_fragment = -1; |
1227 first_c_fragment_seen = 0; | |
1226 memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); | 1228 memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); |
1227 for (i = 0; i < s->superblock_count; i++) { | 1229 for (i = 0; i < s->superblock_count; i++) { |
1228 | 1230 |
1229 /* iterate through all 16 fragments in a superblock */ | 1231 /* iterate through all 16 fragments in a superblock */ |
1230 for (j = 0; j < 16; j++) { | 1232 for (j = 0; j < 16; j++) { |
1251 bit ^= 1; | 1253 bit ^= 1; |
1252 current_run = get_fragment_run_length(gb); | 1254 current_run = get_fragment_run_length(gb); |
1253 } | 1255 } |
1254 | 1256 |
1255 if (bit) { | 1257 if (bit) { |
1256 /* mode will be decoded in the next phase */ | 1258 /* default mode; actual mode will be decoded in |
1259 * the next phase */ | |
1257 s->all_fragments[current_fragment].coding_method = | 1260 s->all_fragments[current_fragment].coding_method = |
1258 MODE_INTER_NO_MV; | 1261 MODE_INTER_NO_MV; |
1259 s->coded_fragment_list[s->coded_fragment_list_index] = | 1262 s->coded_fragment_list[s->coded_fragment_list_index] = |
1260 current_fragment; | 1263 current_fragment; |
1261 if ((current_fragment >= s->u_fragment_start) && | 1264 if ((current_fragment >= s->u_fragment_start) && |
1262 (s->last_coded_y_fragment == -1)) { | 1265 (s->last_coded_y_fragment == -1) && |
1266 (!first_c_fragment_seen)) { | |
1263 s->first_coded_c_fragment = s->coded_fragment_list_index; | 1267 s->first_coded_c_fragment = s->coded_fragment_list_index; |
1264 s->last_coded_y_fragment = s->first_coded_c_fragment - 1; | 1268 s->last_coded_y_fragment = s->first_coded_c_fragment - 1; |
1269 first_c_fragment_seen = 1; | |
1265 } | 1270 } |
1266 s->coded_fragment_list_index++; | 1271 s->coded_fragment_list_index++; |
1267 s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; | 1272 s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; |
1268 debug_block_coding(" superblock %d is partially coded, fragment %d is coded\n", | 1273 debug_block_coding(" superblock %d is partially coded, fragment %d is coded\n", |
1269 i, current_fragment); | 1274 i, current_fragment); |
1284 s->all_fragments[current_fragment].coding_method = | 1289 s->all_fragments[current_fragment].coding_method = |
1285 MODE_INTER_NO_MV; | 1290 MODE_INTER_NO_MV; |
1286 s->coded_fragment_list[s->coded_fragment_list_index] = | 1291 s->coded_fragment_list[s->coded_fragment_list_index] = |
1287 current_fragment; | 1292 current_fragment; |
1288 if ((current_fragment >= s->u_fragment_start) && | 1293 if ((current_fragment >= s->u_fragment_start) && |
1289 (s->last_coded_y_fragment == -1)) { | 1294 (s->last_coded_y_fragment == -1) && |
1295 (!first_c_fragment_seen)) { | |
1290 s->first_coded_c_fragment = s->coded_fragment_list_index; | 1296 s->first_coded_c_fragment = s->coded_fragment_list_index; |
1291 s->last_coded_y_fragment = s->first_coded_c_fragment - 1; | 1297 s->last_coded_y_fragment = s->first_coded_c_fragment - 1; |
1298 first_c_fragment_seen = 1; | |
1292 } | 1299 } |
1293 s->coded_fragment_list_index++; | 1300 s->coded_fragment_list_index++; |
1294 s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; | 1301 s->macroblock_coding[s->all_fragments[current_fragment].macroblock] = MODE_INTER_NO_MV; |
1295 debug_block_coding(" superblock %d is fully coded, fragment %d is coded\n", | 1302 debug_block_coding(" superblock %d is fully coded, fragment %d is coded\n", |
1296 i, current_fragment); | 1303 i, current_fragment); |
1297 } | 1304 } |
1298 } | 1305 } |
1299 } | 1306 } |
1300 } | 1307 } |
1301 | 1308 |
1302 if (s->first_coded_c_fragment == 0) | 1309 if (!first_c_fragment_seen) |
1303 /* no C fragments coded */ | 1310 /* only Y fragments coded in this frame */ |
1304 s->last_coded_y_fragment = s->coded_fragment_list_index - 1; | 1311 s->last_coded_y_fragment = s->coded_fragment_list_index - 1; |
1305 else | 1312 else |
1313 /* end the list of coded fragments */ | |
1306 s->last_coded_c_fragment = s->coded_fragment_list_index - 1; | 1314 s->last_coded_c_fragment = s->coded_fragment_list_index - 1; |
1315 | |
1307 debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", | 1316 debug_block_coding(" %d total coded fragments, y: %d -> %d, c: %d -> %d\n", |
1308 s->coded_fragment_list_index, | 1317 s->coded_fragment_list_index, |
1309 s->first_coded_y_fragment, | 1318 s->first_coded_y_fragment, |
1310 s->last_coded_y_fragment, | 1319 s->last_coded_y_fragment, |
1311 s->first_coded_c_fragment, | 1320 s->first_coded_c_fragment, |
1654 int token; | 1663 int token; |
1655 int zero_run; | 1664 int zero_run; |
1656 DCTELEM coeff; | 1665 DCTELEM coeff; |
1657 Vp3Fragment *fragment; | 1666 Vp3Fragment *fragment; |
1658 | 1667 |
1659 if ((first_fragment < 0) || | 1668 if ((first_fragment >= s->fragment_count) || |
1660 (first_fragment >= s->fragment_count) || | |
1661 (last_fragment < 0) || | |
1662 (last_fragment >= s->fragment_count)) { | 1669 (last_fragment >= s->fragment_count)) { |
1663 | 1670 |
1664 printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", | 1671 printf (" vp3:unpack_vlcs(): bad fragment number (%d -> %d ?)\n", |
1665 first_fragment, last_fragment); | 1672 first_fragment, last_fragment); |
1666 return 1; | 1673 return 0; |
1667 } | 1674 } |
1668 | 1675 |
1669 for (i = first_fragment; i <= last_fragment; i++) { | 1676 for (i = first_fragment; i <= last_fragment; i++) { |
1670 | 1677 |
1671 fragment = &s->all_fragments[s->coded_fragment_list[i]]; | 1678 fragment = &s->all_fragments[s->coded_fragment_list[i]]; |
2431 | 2438 |
2432 debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); | 2439 debug_vp3(" VP3 frame #%d: Q index = %d", counter, s->quality_index); |
2433 counter++; | 2440 counter++; |
2434 | 2441 |
2435 if (s->keyframe) { | 2442 if (s->keyframe) { |
2443 | |
2444 debug_vp3(", keyframe\n"); | |
2445 /* skip the other 2 header bytes for now */ | |
2446 skip_bits(&gb, 16); | |
2447 | |
2436 if (s->last_frame.data[0] == s->golden_frame.data[0]) { | 2448 if (s->last_frame.data[0] == s->golden_frame.data[0]) { |
2437 if (s->golden_frame.data[0]) | 2449 if (s->golden_frame.data[0]) |
2438 avctx->release_buffer(avctx, &s->golden_frame); | 2450 avctx->release_buffer(avctx, &s->golden_frame); |
2439 } else { | 2451 } else { |
2440 if (s->golden_frame.data[0]) | 2452 if (s->golden_frame.data[0]) |
2456 if (!s->pixel_addresses_inited) | 2468 if (!s->pixel_addresses_inited) |
2457 vp3_calculate_pixel_addresses(s); | 2469 vp3_calculate_pixel_addresses(s); |
2458 | 2470 |
2459 } else { | 2471 } else { |
2460 | 2472 |
2473 debug_vp3("\n"); | |
2474 | |
2461 /* allocate a new current frame */ | 2475 /* allocate a new current frame */ |
2462 s->current_frame.reference = 0; | 2476 s->current_frame.reference = 0; |
2463 if(avctx->get_buffer(avctx, &s->current_frame) < 0) { | 2477 if(avctx->get_buffer(avctx, &s->current_frame) < 0) { |
2464 printf("vp3: get_buffer() failed\n"); | 2478 printf("vp3: get_buffer() failed\n"); |
2465 return -1; | 2479 return -1; |
2466 } | 2480 } |
2467 | 2481 } |
2468 } | |
2469 | |
2470 if (s->keyframe) { | |
2471 debug_vp3(", keyframe\n"); | |
2472 /* skip the other 2 header bytes for now */ | |
2473 skip_bits(&gb, 16); | |
2474 } else | |
2475 debug_vp3("\n"); | |
2476 | 2482 |
2477 init_frame(s, &gb); | 2483 init_frame(s, &gb); |
2478 | 2484 |
2479 #if KEYFRAMES_ONLY | 2485 #if KEYFRAMES_ONLY |
2480 if (!s->keyframe) { | 2486 if (!s->keyframe) { |