nschlia / ffmpegfs

FUSE-based transcoding filesystem with video support from many formats to FLAC, MP4, TS, WebM, OGG, MP3, HLS, and others.
https://nschlia.github.io/ffmpegfs/
GNU General Public License v3.0
198 stars 14 forks source link

Bitrate too high for H264 files #46

Closed nschlia closed 4 years ago

nschlia commented 4 years ago

This is a new issue that came up with the #43 fix:

The selected bitrate is not properly respected, resulting files with a 1MBit rate end up between 900KBit (would be OK) and 5MBit (far too large), depending on the source. If transcoded from high bitrates, e.g. blurays, the resulting file's rate will also be higher.

This seems to be a known problem, see https://stackoverflow.com/questions/11466184/setting-video-bit-rate-through-ffmpeg-api-is-ignored-for-libx264-codec. A possible fix is mentioned in the answer:

We need to set the pts for the decoded/resized frames before they are fed to encoder. The person who found the solution has gone through ffmpeg.c source and was able to figure this out. We need to first rescale the AVFrame's pts from the stream's time_base to the codec time_base to get a simple frame number (e.g. 1, 2, 3).

pic->pts = av_rescale_q(pic->pts, ost->time_base, ovCodecCtx->time_base);

avcodec_encode_video2(ovCodecCtx, &newpkt, pic, &got_packet_ptr);

And when we receive back the encoded packet from the libx264 codec, we need to rescale the pts and dts of the encoded video packet to the stream time base

newpkt.pts = av_rescale_q(newpkt.pts, ovCodecCtx->time_base, ost->time_base);
newpkt.dts = av_rescale_q(newpkt.dts, ovCodecCtx->time_base, ost->time_base);

This fix is currently being evaluated. That's a FFmpeg API bug, if you ask me. But we'll have to bear with it anyway.

nschlia commented 4 years ago

Works properly now.