mkvmerge versions 6.2 to 40.0 had a bug that made it not propagate the WavPack extradata (containing the WavPack version) during remuxing from a Matroska file; currently our demuxer would treat every WavPack block encountered as invalid data (unless the WavPack stream is to be discarded (i.e. the streams discard is >= AVDISCARD_ALL)) and try to resync to the next level 1 element. Luckily, the WavPack version is currently not really important; so we fix this problem by assuming a version. David Bryant, the creator of WavPack, recommended using version 0x410 (the most recent version) for this. And this is what this commit does. A FATE-test for this has been added.
Unified · Split
| @@ -2613,6 +2613,14 @@ static int matroska_parse_tracks(AVFormatContext *s) · 2612 unmodified lines | ||
| 2613 | 2613 | ret = matroska_parse_flac(s, track, &extradata_offset); |
| 2614 | 2614 | if (ret < 0) |
| 2615 | 2615 | return ret; |
| 2616 | + } else if (codec_id == AV_CODEC_ID_WAVPACK && track->codec_priv.size < 2) { | |
| 2617 | + av_log(matroska->ctx, AV_LOG_INFO, "Assuming WavPack version 4.10 " | |
| 2618 | + "in absence of valid CodecPrivate.\n"); | |
| 2619 | + extradata_size = 2; | |
| 2620 | + extradata = av_mallocz(2 + AV_INPUT_BUFFER_PADDING_SIZE); | |
| 2621 | + if (!extradata) | |
| 2622 | + return AVERROR(ENOMEM); | |
| 2623 | + AV_WL16(extradata, 0x410); | |
| 2616 | 2624 | } else if (codec_id == AV_CODEC_ID_PRORES && track->codec_priv.size == 4) { |
| 2617 | 2625 | fourcc = AV_RL32(track->codec_priv.data); |
| 2618 | 2626 | } else if (codec_id == AV_CODEC_ID_VP9 && track->codec_priv.size) { |
| @@ -3165,9 +3173,10 @@ static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, · 546 unmodified lines | ||
| 3165 | 3173 | uint16_t ver; |
| 3166 | 3174 | int ret, offset = 0; |
| 3167 | 3175 | |
| 3168 | − if (srclen < 12 || track->stream->codecpar->extradata_size < 2) | |
| 3176 | + if (srclen < 12) | |
| 3169 | 3177 | return AVERROR_INVALIDDATA; |
| 3170 | 3178 | |
| 3179 | + av_assert1(track->stream->codecpar->extradata_size >= 2); | |
| 3171 | 3180 | ver = AV_RL16(track->stream->codecpar->extradata); |
| 3172 | 3181 | |
| 3173 | 3182 | samples = AV_RL32(src); |
| @@ -17,6 +17,11 @@ fate-matroska-remux: REF = 49a60ef91cf7302ab7276f9373f8a429 · 16 unmodified lines | ||
| 17 | 17 | FATE_MATROSKA-$(call ALLYES, MATROSKA_DEMUXER VORBIS_PARSER) += fate-matroska-xiph-lacing |
| 18 | 18 | fate-matroska-xiph-lacing: CMD = framecrc -i $(TARGET_SAMPLES)/mkv/xiph_lacing.mka -c:a copy |
| 19 | 19 | |
| 20 | +# This tests that the Matroska demuxer correctly demuxes WavPack | |
| 21 | +# without CodecPrivate; it also tests zlib compressed WavPack. | |
| 22 | +FATE_MATROSKA-$(call ALLYES, MATROSKA_DEMUXER ZLIB) += fate-matroska-wavpack-missing-codecprivate | |
| 23 | +fate-matroska-wavpack-missing-codecprivate: CMD = framecrc -i $(TARGET_SAMPLES)/mkv/wavpack_missing_codecprivate.mka -c copy | |
| 24 | + | |
| 20 | 25 | # This tests that the matroska demuxer supports decompressing |
| 21 | 26 | # zlib compressed tracks (both the CodecPrivate as well as the actual frames). |
| 22 | 27 | FATE_MATROSKA-$(call ALLYES, MATROSKA_DEMUXER ZLIB) += fate-matroska-zlib-decompression |
| @@ -0,0 +1,9 @@ | ||
| 1 | +#extradata 0: 2, 0x00240014 | |
| 2 | +#tb 0: 11337/500000000 | |
| 3 | +#media_type 0: audio | |
| 4 | +#codec_id 0: wavpack | |
| 5 | +#sample_rate 0: 44100 | |
| 6 | +#channel_layout 0: 3 | |
| 7 | +#channel_layout_name 0: stereo | |
| 8 | +0, 0, 0, 22051, 14778, 0x02819286 | |
| 9 | +0, 22051, 22051, 22052, 14756, 0x21976243 | |