| 1421 | |
| 1422 | |
| 1423 | static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size) |
| 1424 | { |
| 1425 | MpegEncContext *s = &r->s; |
| 1426 | GetBitContext *const gb = &r->gb; |
| 1427 | int mb_pos, slice_type; |
| 1428 | int res; |
| 1429 | |
| 1430 | res = init_get_bits8(gb, buf, buf_size); |
| 1431 | if (res < 0) |
| 1432 | return res; |
| 1433 | res = r->parse_slice_header(r, gb, &r->si); |
| 1434 | if(res < 0){ |
| 1435 | av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n"); |
| 1436 | return -1; |
| 1437 | } |
| 1438 | |
| 1439 | slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; |
| 1440 | if (slice_type != s->pict_type) { |
| 1441 | av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); |
| 1442 | return AVERROR_INVALIDDATA; |
| 1443 | } |
| 1444 | if (s->width != r->si.width || s->height != r->si.height) { |
| 1445 | av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n"); |
| 1446 | return AVERROR_INVALIDDATA; |
| 1447 | } |
| 1448 | |
| 1449 | r->si.end = end; |
| 1450 | s->qscale = r->si.quant; |
| 1451 | r->mb_num_left = r->si.end - r->si.start; |
| 1452 | r->mb_skip_run = 0; |
| 1453 | |
| 1454 | mb_pos = s->mb_x + s->mb_y * s->mb_width; |
| 1455 | if(r->si.start != mb_pos){ |
| 1456 | av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos); |
| 1457 | s->mb_x = r->si.start % s->mb_width; |
| 1458 | s->mb_y = r->si.start / s->mb_width; |
| 1459 | } |
| 1460 | memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); |
| 1461 | s->first_slice_line = 1; |
| 1462 | s->resync_mb_x = s->mb_x; |
| 1463 | s->resync_mb_y = s->mb_y; |
| 1464 | |
| 1465 | ff_init_block_index(s); |
| 1466 | while(!check_slice_end(r, s)) { |
| 1467 | s->dest[0] += 16; |
| 1468 | s->dest[1] += 8; |
| 1469 | s->dest[2] += 8; |
| 1470 | |
| 1471 | if(r->si.type) |
| 1472 | res = rv34_decode_inter_macroblock(r, r->intra_types + s->mb_x * 4 + 4); |
| 1473 | else |
| 1474 | res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4); |
| 1475 | if(res < 0){ |
| 1476 | ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR); |
| 1477 | return -1; |
| 1478 | } |
| 1479 | if (++s->mb_x == s->mb_width) { |
| 1480 | s->mb_x = 0; |
no test coverage detected