+ while (cnt--) {
+ *dst = *src;
+ src += channel_stride;
+ dst += channel_stride;
+ }
+ }
+ }
+
+ *got_frame_ptr = 1;
+
+ return samplecount * bpp;
+}
+
+static void wavpack_decode_flush(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->fdec_num; i++)
+ wv_reset_saved_context(s->fdec[i]);
+}
+
+static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ WavpackContext *s = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int frame_size, ret, frame_flags;
+ int samplecount = 0;
+
+ s->block = 0;
+ s->ch_offset = 0;
+
+ /* determine number of samples */
+ if (s->mkv_mode) {
+ s->samples = AV_RL32(buf); buf += 4;
+ frame_flags = AV_RL32(buf);
+ } else {
+ if (s->multichannel) {
+ s->samples = AV_RL32(buf + 4);
+ frame_flags = AV_RL32(buf + 8);
+ } else {
+ s->samples = AV_RL32(buf);
+ frame_flags = AV_RL32(buf + 4);
+ }
+ }
+ if (s->samples <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
+ s->samples);
+ return AVERROR(EINVAL);
+ }
+
+ if (frame_flags & 0x80) {
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ } else if ((frame_flags & 0x03) <= 1) {
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ } else {
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = s->samples;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ while (buf_size > 0) {
+ if (!s->multichannel) {
+ frame_size = buf_size;
+ } else {
+ if (!s->mkv_mode) {
+ frame_size = AV_RL32(buf) - 12; buf += 4; buf_size -= 4;
+ } else {
+ if (buf_size < 12) //MKV files can have zero flags after last block
+ break;
+ frame_size = AV_RL32(buf + 8) + 12;