tis 2024-01-23 klockan 11:33 +0300 skrev Victor Luchitz: > Re-posting the patch as an attachment. Sorry for the inconvenience! Yep, this one applies and also passes FATE. I notice ffplay_buffer whines a lot when playing RoQ files: > [swscaler @ 0x7fcb44043240] deprecated pixel format used, make sure you did set range correctly > [ffplay_buffer @ 0x7fcb44032fc0] filter context - w: 256 h: 256 fmt: 14 csp: unknown range: unknown, incoming frame - w: 256 h: 256 fmt: 14 csp: unknown range: pc pts_time: 0 > [ffplay_buffer @ 0x7fcb44032fc0] Changing video frame properties on the fly is not supported by all filters. I don't think this problem relates to this patch however. Anyway, using -b:v 100k causes the encoder to effectively become stuck on the first frame, being unable to go below 621 kbps and increasing qscale very slowly. But you mentioned this already of course. Perhaps there should be a faster "startup" phase? Subsequent frames being P- frames may lead to the average hitting the target bitrate. Even when using 1 Mbps the encoding is very slow: ./ffmpeg -r:v 30 -t 1 -f lavfi -i testsrc2 -s 256x256 -b:v 1000k -y foo-1000k.roq > [roqvideo @ 0x3112980] > Generated a frame too big for desired bit rate (1489 kbps), now switching to a bigger qscale value (257). > [roqvideo @ 0x3112980] > Generated a frame too big for desired bit rate (1489 kbps), now switching to a bigger qscale value (259). > [...] > Generated a frame too big for desired bit rate (1100 kbps), now switching to a bigger qscale value (196863). > [roqvideo @ 0x3112980] .0 size= 0kB time=N/A bitrate=N/A speed=N/A > Generated a frame too big for desired bit rate (1069 kbps), now switching to a bigger qscale value (262399). > [roqvideo @ 0x3112980] > Generated a frame too small for desired bit rate (601 kbps), reverting lambda and using smaller inc on qscale (196863). > [roqvideo @ 0x3112980] 0.0 size= 17kB time=00:00:00.16 bitrate= 812.7kbits/s speed=0.0476x > Generated a frame too small for desired bit rate (915 kbps), qscale value cannot be lowered any further (1). > [...] > [roqvideo @ 0x3112980] > Generated a frame too big for desired bit rate (1084 kbps), now switching to a bigger qscale value (327680). > [roqvideo @ 0x3112980] > Generated a frame too big for desired bit rate (1068 kbps), now switching to a bigger qscale value (393216). > [roqvideo @ 0x3112980] 0.0 size= 42kB time=00:00:00.40 bitrate= 866.5kbits/s speed=0.0667x > Generated a frame too small for desired bit rate (514 kbps), reverting lambda and using smaller inc on qscale (327680). > [roqvideo @ 0x3112980] 0.0 size= 62kB time=00:00:00.56 bitrate= 896.2kbits/s speed=0.0708x > Generated a frame too small for desired bit rate (901 kbps), qscale value cannot be lowered any further (1). This suggests an unstable regulation loop. It also makes the encoder slower than the Cinepak encoder, amazingly. 59.6 vs 21.57 seconds for encoding 90 frames of dimension 256x256. -bt should have a default of 0, and similar default logic as -b. The default of bitrate/20 also seems excessively small? If I change the default to be the same as the bitrate then the encoding time above shrinks to 11.7 seconds. There is an excessive newline visible here: > + "\nGenerated a frame too big for desired bit rate > (%d kbps), " And elsewhere. Using non-integer framerates causes the encoder to go bananas. For example 24000/1001 fps makes the ratecontrol think it's running at 24000 fps. An easy fix is to reject avctx->time_base.num != 1 on init. roq_write_header() rejects non-integer framerates. I'm also curious about this hunk: > - if (enc->lambda > 100000) { > + if (enc->lambda > 100000000) { > av_log(roq->logctx, AV_LOG_ERROR, "Cannot encode video in Quake compatible form\n"); > return AVERROR(EINVAL); > } Where in the Quake (3?) source code is this limitation? Seems rather that there should be a retry limit. There's probably no harm in keeping going so long as the packet doesn't end up above the limit. A quick logarithmic regression on bitrate vs qscale suggests it scales with somewhere between qscale^-0.2833 and qscale^-0.2842. Conversely, to hit a specific bitrate, try scaling qscale with the bitrate ratio raised to around 3.5. A more conservative exponent like 2 is probably also fine. See patch attached. A more systematic approach might be to do a binary search for qscale, with an initial guess per the formula above. /Tomas