| 1631 | } |
| 1632 | |
| 1633 | static int wavpack_decode_frame(AVCodecContext *avctx, AVFrame *frame, |
| 1634 | int *got_frame_ptr, AVPacket *avpkt) |
| 1635 | { |
| 1636 | WavpackContext *s = avctx->priv_data; |
| 1637 | const uint8_t *buf = avpkt->data; |
| 1638 | int buf_size = avpkt->size; |
| 1639 | int frame_size, ret, frame_flags; |
| 1640 | int block = 0, new_progress = 0; |
| 1641 | |
| 1642 | av_assert1(!s->curr_progress || s->dsdctx); |
| 1643 | |
| 1644 | if (avpkt->size <= WV_HEADER_SIZE) |
| 1645 | return AVERROR_INVALIDDATA; |
| 1646 | |
| 1647 | s->ch_offset = 0; |
| 1648 | |
| 1649 | /* determine number of samples */ |
| 1650 | s->samples = AV_RL32(buf + 20); |
| 1651 | frame_flags = AV_RL32(buf + 24); |
| 1652 | if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) { |
| 1653 | av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", |
| 1654 | s->samples); |
| 1655 | return AVERROR_INVALIDDATA; |
| 1656 | } |
| 1657 | |
| 1658 | s->modulation = (frame_flags & WV_DSD_DATA) ? MODULATION_DSD : MODULATION_PCM; |
| 1659 | |
| 1660 | while (buf_size > WV_HEADER_SIZE) { |
| 1661 | frame_size = AV_RL32(buf + 4) - 12; |
| 1662 | buf += 20; |
| 1663 | buf_size -= 20; |
| 1664 | if (frame_size <= 0 || frame_size > buf_size) { |
| 1665 | av_log(avctx, AV_LOG_ERROR, |
| 1666 | "Block %d has invalid size (size %d vs. %d bytes left)\n", |
| 1667 | block, frame_size, buf_size); |
| 1668 | ret = AVERROR_INVALIDDATA; |
| 1669 | goto error; |
| 1670 | } |
| 1671 | ret = wavpack_decode_block(avctx, frame, block, buf, |
| 1672 | frame_size, &new_progress); |
| 1673 | if (ret < 0) |
| 1674 | goto error; |
| 1675 | block++; |
| 1676 | buf += frame_size; |
| 1677 | buf_size -= frame_size; |
| 1678 | } |
| 1679 | |
| 1680 | if (s->ch_offset != avctx->ch_layout.nb_channels) { |
| 1681 | av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n"); |
| 1682 | ret = AVERROR_INVALIDDATA; |
| 1683 | goto error; |
| 1684 | } |
| 1685 | |
| 1686 | if (s->dsdctx) { |
| 1687 | if (s->prev_progress) |
| 1688 | ff_thread_progress_await(s->prev_progress, INT_MAX); |
| 1689 | avctx->execute2(avctx, dsd_channel, frame, NULL, avctx->ch_layout.nb_channels); |
| 1690 | if (s->curr_progress) |
nothing calls this directly
no test coverage detected