<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Greetings -<div class=""><br class=""></div><div class="">I’m attempting to encode a sequence of frames with libx264. For testing, I’m using the sample code from <a href="http://www.imc-store.com.au/Articles.asp?ID=276" class="">http://www.imc-store.com.au/Articles.asp?ID=276</a>. This is all pretty vanilla FFmpeg API usage, and is similar to what one might write oneself. It produces correct output with libx264, however the bitrate I specify is not honored at all…</div><div class=""><br class=""></div><div class="">I can set the bitrate (m_AVIMOV_BPS) to whatever number I choose, and the actual bitrate used is some other value:</div><div class=""><span class="Apple-tab-span" style="color: rgb(195, 89, 0); font-family: 'Panic Sans'; white-space: pre;"> </span></div><div class=""><div style="margin: 0px;" class=""><div style="margin: 0px;" class=""><span style="font-family: Courier;" class=""><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="font-family: Courier; color: rgb(195, 89, 0);" class="">AVCodec</span><span style="font-family: Courier; color: rgb(88, 126, 168);" class=""> *m_video_codec </span><span style="font-family: Courier;" class="">= </span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">avcodec_find_encoder</span><span style="font-family: Courier;" class="">(</span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">m_fmt</span><span style="font-family: Courier;" class="">-></span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">video_codec</span><span style="font-family: Courier;" class="">);</span></div><div style="color: rgb(88, 126, 168); margin: 0px;" class=""><font face="Courier" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #35568a" class="">if</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> (!(</span>m_video_codec<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)) {</span></font></div><div style="color: rgb(53, 86, 138); margin: 0px;" class=""><font face="Courier" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><span class="Apple-tab-span" style="white-space:pre"> </span> </span>return<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">;</span></font></div><div style="color: rgb(195, 89, 0); margin: 0px;" class=""><font face="Courier" class=""><span class="Apple-tab-span" style="white-space:pre"> </span>}</font></div><div style="color: rgb(207, 135, 36); margin: 0px;" class=""><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="font-family: Courier; color: rgb(195, 89, 0);" class="">AVStream</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""> *st</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""> = </span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">avformat_new_stream</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">(</span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">m_oc</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">, </span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">m_video_codec</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">);</span></div><div style="color: rgb(207, 135, 36); margin: 0px;" class=""><span class="Apple-tab-span" style="font-family: Courier; color: rgb(195, 89, 0); white-space: pre;"> </span><span style="font-family: Courier; color: rgb(195, 89, 0);" class="">AVCodecContext</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""> *m_c</span><span style="font-family: Courier; color: rgb(195, 89, 0);" class=""> = st-></span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">codec</span><span style="font-family: Courier; color: rgb(195, 89, 0);" class="">;</span></div><p style="color: rgb(195, 89, 0); margin: 0px; min-height: 14px;" class=""><font face="Courier" class=""><span class="Apple-tab-span" style="white-space:pre"> </span><br class="webkit-block-placeholder"></font></p><div style="color: rgb(207, 135, 36); margin: 0px;" class=""><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""><span class="Apple-tab-span" style="white-space:pre"> </span></span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">m_c</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">-></span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">codec_id</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class=""> = </span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">m_fmt</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">-></span><span style="font-family: Courier; color: rgb(88, 126, 168);" class="">video_codec</span><span style="font-family: Courier; color: rgb(0, 0, 0);" class="">;</span></div><div style="color: rgb(88, 126, 168); margin: 0px;" class=""><font face="Courier" class=""><span style="color: rgb(0, 0, 0);" class=""><span class="Apple-tab-span" style="white-space:pre"> </span></span>m_c<span style="color: rgb(0, 0, 0);" class="">-></span>bit_rate<span style="color: rgb(0, 0, 0);" class=""> = </span>m_AVIMOV_BPS<span style="color: rgb(0, 0, 0);" class="">;</span><span style="color: rgb(207, 135, 36);" class=""> </span></font></div><div style="font-family: 'Panic Sans'; color: rgb(195, 89, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #cf8724" class=""><br class=""></span></div></div></div><div class=""><br class=""></div><div class=""><div class="">Googling this issue, I find that it’s the subject of a lot of discussion. Evidently, simply setting the bit rate in the context is not sufficient — I can set <font face="Courier" class="">m_AVIMOV_BPS</font> to 400 million, but the bitrate used in encoding ends up being something like 176 Kbps (using the info inspector in one of any number of players/utilities). As well, visually I see significant undersampling artifacts. I assume the effective bitrate used is computed by ffmpeg or the encoder itself, based on some other (default) parameters. But in any case, my value is being ignored, making the output useless to me.</div><div class=""><br class=""></div><div class="">One forum I post I found ( <a href="http://libav-users.943685.n4.nabble.com/Setting-libx264-bitrate-via-API-td4655453.html" class="">http://libav-users.943685.n4.nabble.com/Setting-libx264-bitrate-via-API-td4655453.html</a> ) suggests that the reason the encoder (or ffmpeg itself?) is ignoring the bit rate is because of the use of “pts” and “dts” in the encoder and output stream writer. Specifically, the encoder’s input should use, say, integer frame numbers, while the stream writer should use values in its own time base: </div></div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">My code was sending pictures into the encoder using a pts in the stream's </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">time_base of 1/90000 (e.g. 3003, 6006, 9009). The solution was to first </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">rescale the AVFrame's pts from the stream's time_base to the codec time_base </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">to get a simple frame number (e.g. 1, 2, 3). </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class=""><br style="font-size: 13px;" class=""></font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">pic->pts = av_rescale_q(pic->pts, ost->time_base, enc->time_base); </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">avcodec_encode_video2(enc, &newpkt, pic, &got_packet_ptr); </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class=""><br style="font-size: 13px;" class=""></font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">Then when a packet is received from the encoder, you need to rescale pts and </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">dts back to the stream time_base. </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class=""><br style="font-size: 13px;" class=""></font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">newpkt.pts = av_rescale_q(newpkt.pts, enc->time_base, ost->time_base); </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">newpkt.dts = av_rescale_q(newpkt.dts, enc->time_base, ost->time_base); </font></span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-size: 13px; background-color: rgb(255, 255, 255);" class=""><font face="Courier" class="">av_interleaved_write_frame(out, &newpkt); </font></span></div></blockquote></blockquote><div class=""><br class=""></div><div class="">However, this is not working for me. I suspect it may be due to other differences between my code and theirs.. :-(</div><div class=""><br class=""></div><div class="">In any case, surely someone out there has the understanding (and code snippets?) of how to get the libx264 encoder to honor the specified bitrate? Any help/pointers/advice/code would be greatly appreciated!</div><div class=""><br class=""></div><div class="">Thanks!</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>