PDA

View Full Version : x264 Streaming Settings


MattKB
18th August 2008, 20:17
Hi,

I apologize ahead of time - I am trying to come up to speed with all of the intricacies of video encoding - so if my questions are very basic please excuse my lack of knowledge.

My goal: To use x264 to encode video to be streamed to flash.

My problem: I am having a hard time understanding the various rate control modes and how they operate. This has resulted in x264 producing streams that seem to follow a general average bit rate, but burst for long periods well about the target bit rate (Determined by using the -vstats option of FFMPEG).

Here are the settings I have been playing around with:

ffmpeg -i $1 -s $3 -y -an -pass 1 -vcodec libx264 \
-b 1024k -maxrate 1024k -bufsize 1024k -bt 1024k -flags +loop \
-cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me epzs -subq 1 -trellis 0 \
-refs 1 -bf 16 -b_strategy 1 -coder 1 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 \
-i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0 -qmin 10 -qmax 51 -qdiff 4 $2

ffmpeg -i $1 -s $3 -y -an -pass 2 -vcodec libx264 \
-b 1024k -maxrate 1024k -bufsize 1024k -bt 1024k \
-flags +loop -cmp +chroma -partitions +parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 \
-flags2 +brdo+dct8x8+wpred+bpyramid+mixed_refs \
-me umh -subq 7 -trellis 1 -refs 6 -bf 16 -directpred 3 -b_strategy 1 -bidir_refine 1 \
-coder 1 -me_range 16 -g 250 \
-keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -qcomp 0 \
-qmin 10 -qmax 51 -qdiff 4 $2

I have several questions about the above settings:

1) Should I be using 2 pass VBR to achieve my desired result (which is highest possible quality with temporal rate contraints)?

2) Setting buffer size is confusing. I have configured the flash client to buffer for 10 seconds prior to playback, but I'm not sure how I can probably determine what to set bufize at.

3) How does -bt play into this? I have tried different settings and it doesn't seem to alter how far above maxrate x264 goes.

4) I read in other posts that setting -qcomp to 0 allows the encoder to reduce quality to avoid buffer underflows. So I have set that here.

5) Am I on the right general track for good streaming encoding settings? Any help appreciated.

Thanks

Dark Shikari
18th August 2008, 20:34
My goal: To use x264 to encode video to be streamed to flash. Are you sure you're streaming, and not progressive download? Progressive download is much easier and more user-friendly, IMO. Plus, with progressive download, you don't need to restrict your quality so heavily with VBV restrictions.1) Should I be using 2 pass VBR to achieve my desired result (which is highest possible quality with temporal rate contraints)?Yes.
2) Setting buffer size is confusing. I have configured the flash client to buffer for 10 seconds prior to playback, but I'm not sure how I can probably determine what to set bufize at.Buffer size == max bitrate * time, so 10240k.3) How does -bt play into this? I have tried different settings and it doesn't seem to alter how far above maxrate x264 goes.-bt doesn't affect 2pass mode.4) I read in other posts that setting -qcomp to 0 allows the encoder to reduce quality to avoid buffer underflows. So I have set that here.No, not really.

MattKB
18th August 2008, 20:48
Are you sure you're streaming, and not progressive download? Progressive download is much easier and more user-friendly, IMO. Plus, with progressive download, you don't need to restrict your quality so heavily with VBV restrictions.

Yes I'm sure I am streaming. I control the entire system (server and client). For my application, we are doing several encodes and targetting a stream very close to the user's available BW, so streaming vs. progressive download doesn't matter as much regarding needing to come pretty close to a target BW.

Regarding -qcomp, would you then recommend that I set back to the default value of 0.6?

And finally, I want to make sure I understand the -vstat output. -vstat tells me my instantenous frame bit rate, as well as my cumulative average bit rate. Correct? So with the above settings, and changing -bufsize to 1024K*10, x264 guarentees that the buffer will never underflow with that size buffer, even though some of the instantenous rates might go well above 1024k. Correct?

Thanks!

Dark Shikari
18th August 2008, 21:13
Regarding -qcomp, would you then recommend that I set back to the default value of 0.6? Yes.And finally, I want to make sure I understand the -vstat output. -vstat tells me my instantenous frame bit rate, as well as my cumulative average bit rate. Correct? So with the above settings, and changing -bufsize to 1024K*10, x264 guarentees that the buffer will never underflow with that size buffer, even though some of the instantenous rates might go well above 1024k. Correct?Yes; it means that if you buffer 10 seconds at the start of the file, you will never have any underflows in the decoder.

MattKB
19th August 2008, 16:55
Sorry, one more thing is confusing me:

-bufsize is expressed in bits. However on the client, buffer is expressed in time. If the encoding where CBR, it wouldn't matter. However, since it's VBR, isn't there a unit mismatch? For example, let's say that the first 10 seconds of my content is static, so it encodes at a very low bit rate. If flash buffers the first 10 seconds of video, it wouldn't come close to buffering the 10Mb that the encoder expects to prevent underflow.

Does the encoder internally convert -bufsize to time before doing VBR/VBV calculations? If not, is there something I am missing that would prevent underflow at the client?

Thanks

Dark Shikari
19th August 2008, 16:58
Sorry, one more thing is confusing me:

-bufsize is expressed in bits. However on the client, buffer is expressed in time. If the encoding where CBR, it wouldn't matter. However, since it's VBR, isn't there a unit mismatch? For example, let's say that the first 10 seconds of my content is static, so it encodes at a very low bit rate. If flash buffers the first 10 seconds of video, it wouldn't come close to buffering the 10Mb that the encoder expects to prevent underflow.But the point is that you don't want to buffer 10 seconds of video--you want to buffer bufsize amount of video. That's how decoders are supposed to work.

MattKB
19th August 2008, 17:05
I realize that's the point, but unfortunately this is not how flash works. Flash expresses the amount of buffering in units of time, not data.

Since most internet video is currently displayed using flash, I wonder if anyone has any tips on how to handle (as best as possible) this mismatch.

Dark Shikari
19th August 2008, 17:24
I realize that's the point, but unfortunately this is not how flash works. Flash expresses the amount of buffering in units of time, not data.

Since most internet video is currently displayed using flash, I wonder if anyone has any tips on how to handle (as best as possible) this mismatch.VBV-init. This option allows you to specify how much of the buffer is "filled" at the start of the decoding process.

By default it is 0.9, meaning that the buffer is 90% full (so you have 9 seconds worth of max-bitrate video buffered). Instead, you could change it to 0.1, for example; this would make the encoder assume that the buffer only has 1 second worth to start, which would likely ensure that no problems occur.

Sergey A. Sablin
19th August 2008, 18:12
But the point is that you don't want to buffer 10 seconds of video--you want to buffer bufsize amount of video. That's how decoders are supposed to work.

it's your own assumption, cause you didn't read the spec on this subject - h.264 hrd model assumes 10 sec = 10 sec. whatever bitrate encoder outputs - will it be 0.0...01% of maxrate or 10...0%.

Dark Shikari
19th August 2008, 18:14
it's your own assumption, cause you didn't read the spec on this subject - h.264 hrd model assumes 10 sec = 10 sec. whatever bitrate encoder outputs - will it be 0.0...01% of maxrate or 10...0%.True, but if the encoder uses less than the maxrate, and the VBV overflows, that's just wasted bits; the encoder of course compensates for this.

MattKB
19th August 2008, 18:47
It seems like there is a feature request in here somewhere:

-buftime

It seems that the encoder should be able to do it's own optimal calculations if it knows that the client buffers X seconds of video before playback stars, and the maximum bitrate. Not that I am willing (or understand) how to program this, but I thought I would mention it. :)

Sharktooth
19th August 2008, 19:01
naa... not necessary. there are several more important things to think at...

Sergey A. Sablin
19th August 2008, 19:08
True, but if the encoder uses less than the maxrate, and the VBV overflows, that's just wasted bits; the encoder of course compensates for this.

Have no idea what are you talking about - CPB simply can't overflow in VBR case.

It seems like there is a feature request in here somewhere:

-buftime

It seems that the encoder should be able to do it's own optimal calculations if it knows that the client buffers X seconds of video before playback stars, and the maximum bitrate. Not that I am willing (or understand) how to program this, but I thought I would mention it.

it's actually how spec compliant h.264 encoder suppose to work - you set up buffer size, bitrate (actual channel rate), initial delay in seconds - and that's it. The best case is that encoder writes SEI message Buffering Period with initial delay information and Picture Timing SEI with timing information for each picture, so decoder (or user) don't need to guess which values were used at encoder side.

crypto
19th August 2008, 19:24
If you are going to stream H.264, I would also have a look at the container level. Many options are controlled by the MP4 container, like header optimization, MTU size, RTP payload size and hinting. When I worked through the mp4creator sources, I saw a lot stuff solely for streaming. No wonder since most of this comes from Cisco.

smok3
19th August 2008, 20:14
mattKB: not that i understand the entire story, but you are probably confusing player buffering and streaming buffering?, looking at my (dumbest possible) php streaming script, you can see:

while (!feof($fh)) { print(fread($fh, 1000)); }

where 2nd parameter of fread is in bytes.

http://si2.php.net/manual/en/function.fread.php

Sergey A. Sablin
19th August 2008, 20:43
mattKB: not that i understand the entire story, but you are probably confusing player buffering and streaming buffering?

those two are the same.

smok3
19th August 2008, 20:50
my point was: in my example when stream script is used then player related var for buffering is ignored. Player related var is indeed in sec.

Sergey A. Sablin
19th August 2008, 21:05
my point was: in my example when stream script is used then player related var for buffering is ignored. Player related var is indeed in sec.

there should not be such a thing as player buffering in ideal environment anyway - decoder has to use buffering information provided by encoder.
in case of network delays (which encoder can't control whatsoever) - player delay is supposed to get rid of network problems (in addition to provided information).

however this is all unrelated to OT.

smok3
20th August 2008, 09:00
the op is probably mixing the usage of decoder delay and network delay settings, so it is kinda related, isn't it?

MattKB
28th August 2008, 20:49
Sorry for some reason I stopped getting notices that there was reponses to this thread.

smok3 I don't understand what you are saying... The play buffers in seconds, not bytes. That is the point of this thread. I agree Sergey that the encoder should handle this case better.

crypto: I didn't know about the effects the container has on streaming.

1) Do you have any references I can look at?
2) Are any of these settings controllable using FFMPEG and/or x264?

Thanks