| @@ -1463,24 +1463,90 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, · 1462 unmodified lines |
| 1463 | 1463 | } |
| 1464 | 1464 | |
| 1465 | 1465 | static int FUNC(frame_header_obu)(CodedBitstreamContext *ctx, RWContext *rw, |
| 1466 | | − AV1RawFrameHeader *current) |
| 1466 | + AV1RawFrameHeader *current, int redundant, |
| 1467 | + AVBufferRef *rw_buffer_ref) |
| 1467 | 1468 | { |
| 1468 | 1469 | CodedBitstreamAV1Context *priv = ctx->priv_data; |
| 1469 | | − int err; |
| 1470 | | − |
| 1471 | | − HEADER("Frame Header"); |
| 1470 | + int start_pos, fh_bits, fh_bytes, err; |
| 1471 | + uint8_t *fh_start; |
| 1472 | 1472 | |
| 1473 | 1473 | if (priv->seen_frame_header) { |
| 1474 | | − // Nothing to do. |
| 1474 | + if (!redundant) { |
| 1475 | + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid repeated " |
| 1476 | + "frame header OBU.\n"); |
| 1477 | + return AVERROR_INVALIDDATA; |
| 1478 | + } else { |
| 1479 | + GetBitContext fh; |
| 1480 | + size_t i, b; |
| 1481 | + uint32_t val; |
| 1482 | + |
| 1483 | + HEADER("Redundant Frame Header"); |
| 1484 | + |
| 1485 | + av_assert0(priv->frame_header_ref && priv->frame_header); |
| 1486 | + |
| 1487 | + init_get_bits(&fh, priv->frame_header, |
| 1488 | + priv->frame_header_size); |
| 1489 | + for (i = 0; i < priv->frame_header_size; i += 8) { |
| 1490 | + b = FFMIN(priv->frame_header_size - i, 8); |
| 1491 | + val = get_bits(&fh, b); |
| 1492 | + xf(b, frame_header_copy[i], |
| 1493 | + val, val, val, 1, i / 8); |
| 1494 | + } |
| 1495 | + } |
| 1475 | 1496 | } else { |
| 1497 | + if (redundant) |
| 1498 | + HEADER("Redundant Frame Header (used as Frame Header)"); |
| 1499 | + else |
| 1500 | + HEADER("Frame Header"); |
| 1501 | + |
| 1476 | 1502 | priv->seen_frame_header = 1; |
| 1477 | 1503 | |
| 1504 | +#ifdef READ |
| 1505 | + start_pos = get_bits_count(rw); |
| 1506 | +#else |
| 1507 | + start_pos = put_bits_count(rw); |
| 1508 | +#endif |
| 1509 | + |
| 1478 | 1510 | CHECK(FUNC(uncompressed_header)(ctx, rw, current)); |
| 1479 | 1511 | |
| 1480 | 1512 | if (current->show_existing_frame) { |
| 1481 | 1513 | priv->seen_frame_header = 0; |
| 1482 | 1514 | } else { |
| 1483 | 1515 | priv->seen_frame_header = 1; |
| 1516 | + |
| 1517 | + av_buffer_unref(&priv->frame_header_ref); |
| 1518 | + |
| 1519 | +#ifdef READ |
| 1520 | + fh_bits = get_bits_count(rw) - start_pos; |
| 1521 | + fh_start = (uint8_t*)rw->buffer + start_pos / 8; |
| 1522 | +#else |
| 1523 | + // Need to flush the bitwriter so that we can copy its output, |
| 1524 | + // but use a copy so we don't affect the caller's structure. |
| 1525 | + { |
| 1526 | + PutBitContext tmp = *rw; |
| 1527 | + flush_put_bits(&tmp); |
| 1528 | + } |
| 1529 | + |
| 1530 | + fh_bits = put_bits_count(rw) - start_pos; |
| 1531 | + fh_start = rw->buf + start_pos / 8; |
| 1532 | +#endif |
| 1533 | + fh_bytes = (fh_bits + 7) / 8; |
| 1534 | + |
| 1535 | + priv->frame_header_size = fh_bits; |
| 1536 | + |
| 1537 | + if (rw_buffer_ref) { |
| 1538 | + priv->frame_header_ref = av_buffer_ref(rw_buffer_ref); |
| 1539 | + if (!priv->frame_header_ref) |
| 1540 | + return AVERROR(ENOMEM); |
| 1541 | + priv->frame_header = fh_start; |
| 1542 | + } else { |
| 1543 | + priv->frame_header_ref = |
| 1544 | + av_buffer_alloc(fh_bytes + AV_INPUT_BUFFER_PADDING_SIZE); |
| 1545 | + if (!priv->frame_header_ref) |
| 1546 | + return AVERROR(ENOMEM); |
| 1547 | + priv->frame_header = priv->frame_header_ref->data; |
| 1548 | + memcpy(priv->frame_header, fh_start, fh_bytes); |
| 1549 | + } |
| 1484 | 1550 | } |
| 1485 | 1551 | } |
| 1486 | 1552 | |
| @@ -1524,11 +1590,13 @@ static int FUNC(tile_group_obu)(CodedBitstreamContext *ctx, RWContext *rw, · 37 unmodified lines |
| 1524 | 1590 | } |
| 1525 | 1591 | |
| 1526 | 1592 | static int FUNC(frame_obu)(CodedBitstreamContext *ctx, RWContext *rw, |
| 1527 | | − AV1RawFrame *current) |
| 1593 | + AV1RawFrame *current, |
| 1594 | + AVBufferRef *rw_buffer_ref) |
| 1528 | 1595 | { |
| 1529 | 1596 | int err; |
| 1530 | 1597 | |
| 1531 | | − CHECK(FUNC(frame_header_obu)(ctx, rw, ¤t->header)); |
| 1598 | + CHECK(FUNC(frame_header_obu)(ctx, rw, ¤t->header, |
| 1599 | + 0, rw_buffer_ref)); |
| 1532 | 1600 | |
| 1533 | 1601 | CHECK(FUNC(byte_alignment)(ctx, rw)); |
| 1534 | 1602 | |