xiph / rav1e

The fastest and safest AV1 encoder.
BSD 2-Clause "Simplified" License
3.72k stars 253 forks source link

Corrupt bitstream when bitrate is set too high #1719

Closed rzumer closed 5 years ago

rzumer commented 5 years ago

Tested with a 720p clip setting --bitrate 24000 (i.e. 24 Mbps).

I have been able to reproduce this with several different clips, and it seems (under investigation) that even setting a lower bitrate has a chance of generating a corrupt bitstream (presumably from spikes), though it is not as consistent.

command line:

cargo run --release -- 720.y4m --tile-rows 2 --tile-cols 2 -s 4 -l 120 --min-quantizer 20 --quantizer 170 --bitrate 24000 -o 720.ivf

mpv/ffmpeg output:

[ffmpeg/video] libaom-av1: Failed to decode frame: Bitstream not supported by this decoder
[ffmpeg/video] libaom-av1:   Additional information: Buffer -1 does not contain a decoded frame
[ffmpeg/video] libaom-av1: Failed to decode frame: Corrupt frame detected
[ffmpeg/video] libaom-av1:   Additional information: Reference frame containing this frame's initial frame context is unavailable.
[ffmpeg/video] libaom-av1: Failed to decode frame: Bitstream not supported by this decoder
[ffmpeg/video] libaom-av1:   Additional information: Buffer -1 does not contain a decoded frame
[ffmpeg/demuxer] ivf: Could not find codec parameters for stream 0 (Video: av1 (libaom-av1) (Main) (AV01 / 0x31305641), none, 1280x720): unspecified pixel format
[ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' and 'probesize' options
 (+) Video --vid=1 (av1 1280x720 25.000fps)
mpv: /build/aom-BDGUmS/aom-1.0.0.errata1/av1/decoder/decodemv.c:314: set_segment_id: Assertion `segment_id >= 0 && segment_id < MAX_SEGMENTS' failed.

With bitrate set to a reasonable 2400 instead (on my clip) I get corruption a few dozen frames in. The lower the bitrate, the longer it tends to take for corruption to occur, presumably because the quantizer is usually higher.

shssoichiro commented 5 years ago

This sounds very similar to https://github.com/xiph/rav1e/issues/1649 which should be fixed by https://github.com/xiph/rav1e/pull/1694

rzumer commented 5 years ago

You're right, I'll pull that branch and see if it solves it.

rzumer commented 5 years ago

That branch alone does not solve the issue, instead for the clip I am testing playback just freezes at the point where it was previously corrupted. The encoder behavior from what I saw seems to be that dozens of frames are encoded "at once" (the frame counter jumps to the end from several dozens behind).

rzumer commented 5 years ago

I updated my original comment with the input command line. Clearly min-quantizer is also relevant as even with @tdaede's branch the corruption only seems to occur when the quantizer is set very low. Changing the minimum to 40 with the same bitrate seems to fix it for the clip I tested, so it does seem related to #1649.

tdaede commented 5 years ago

Interesting. The latest version of my patch has an assert for the qidx = 0 case, so if you don't see it asserting then it's probably a different issue (or I screwed up).

rzumer commented 5 years ago

Sample: sample.tar.gz

Will be corrupted after a few frames when encoded with the command line above.

rzumer commented 5 years ago

First bad commit: 6f86711f197f2e54c8a1101054d4afda43ad1532

ycho commented 5 years ago

This sounds very similar to #1649 which should be fixed by #1694

Indeed, it looks to me coming from the same origin of #1649 in its nature.

rzumer commented 5 years ago

With @tdaede's branch and large LRU disabled, first bad commit is cc7c5f39aa7291ebe55cf039536ed2959bae22d6.

ycho commented 5 years ago

Note that, if speed 4 is used as reported, this issue should not be related because quant_rdo is only enabled at speed 0 and 1 since https://github.com/xiph/rav1e/pull/1709, which is committed on Sep 27, 45d7358c1953c05693f6a52f2487f384540fce80

So, as @rzumer stated, min-quantizer or others are related.

rzumer commented 5 years ago

Fixed by tdaede#1 (#1694).

ycho commented 5 years ago

Oh... " /// When disabled, the segment ID is chosen heuristically. pub quantizer_rdo: bool," I missed whole this. So, seg_id still works even if quantizer_rdo is disabled. Based on block importance?