PDA

View Full Version : How to calculating max ref for level,....


Selur
13th November 2008, 17:24
Wanting to calculate the max number of refs allowed for a specific avc level I searched the forum and then based my calculation on http://forum.doom9.org/showthread.php?t=102048
which gave me
/***
* Restrictions:
* MaxMBPS >= width*height*fps. (w&h measured in macroblocks, i.e. pixels/16 round up in each dimension)
* MaxFS >= width*height
* sqrt(MaxFS*8) >= width
* sqrt(MaxFS*8) >= height
* MaxDPB >= (bytes in a frame) * min(16, ref + (pyramid ? 2 : bframes ? 1 : 0))
* MaxBR >= vbv_maxrate.
* MaxCPB >= vbv_bufsize.
* MaxVmvR >= max_mv_range.
* MaxMvsPer2Mb, MinLumaBiPredSize, direct_8x8_inference_flag : are not enforced by x264. The only way to ensure compliance is to disable p4x4 at level>=3.1, or at level>=3 w/ B-frames.
* MinCR : is not enforced by x264. Won't ever be an issue unless you use lossless.
* SliceRate : I don't know what this limits.latexxx once posted the values needed for these factors:
* VALUES FOR LEVEL: http://forum.doom9.org/showthread.php?t=101345
*
* LEGEND:
* MaxDPB = max decoded picture buffer
* MaxMBPS = max macroblocks per second
* MaxFS = max frame size
* MaxBR = max bitrate
* MaxCPB = max vbv buffer
* MaxVmvR = max motion vetor range
***/
so taking
MaxDPB >= (bytes in a frame) * min(16, ref + (pyramid ? 2 : bframes ? 1 : 0))
as basis I rearranged it to
Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
where:
maxDPB = 12582912 (for Level 4.1)
bytesPerFrame = (pixel width)*(pixel height)*1.5 (since x264 only support 4:2:0 atm) = 1920*1080*1.5
bframeModifier = 0 when no bframes are used, 1 when bframes are enabled and 2 when bframes&pyramid are enabled.

using this I get:

with bframes:
Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
maxDPB = 12582912
bytesPerFrame = 3110401
maxDPB/bytesPerFrame = 4
bframeModifier = 0
-> maxRef = 4

with bframes:
Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
maxDPB = 12582912
bytesPerFrame = 3110401
maxDPB/bytesPerFrame = 4
bframeModifier = 1
-> maxRef = 3

with bframes&pyramid:
Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
maxDPB = 12582912
bytesPerFrame = 3110401
maxDPB/bytesPerFrame = 4
bframeModifier = 2
-> maxRef = 2


Trahald&Co nutzen die Formel:
min( 1024 * MaxDPB/(PicWidthInMbs * FrameHeightInMbs * 384), 16)
1024 * (12288) / (120 * (( 2 – frame_mbs_only_flag ) * PicHeightInMapUnits) * 384)
maxDPB / (Width/16 * ( 2 – frame_mbs_only_flag ) * Height/16 * 384)
wobei frame_mbs_only_flag = 0 heißt man encoded interlaced

But looking at http://forum.doom9.org/showthread.php?t=136258 Trahald uses a different formula.
maxDPB / (PicWidth/16 * (( 2 – frame_mbs_only_flag ) * FrameHeight/16) * 384)
maxDPB = 12582912 (for Level 4.1)
and frame_mbs_only_flag = 1 assuming the material is progressive (iiirc frame_mbs_only_flag = 0 means material is interlaced)
1st thing about this formula that I registered was that:
a. it doesn't care about B-Frames
b. it cares about interlacing

Thanks for reading up to here. :)
Now here's my question/problem:

How does one calculate the maximum number of frames?
(I suspect that the 'real' formula is a mix of the two above. :))

:thanks:

Cu Selur

Manao
13th November 2008, 17:49
First of all, any formula will depend on the encoder. For example, without MMCOs (explicit picture reordering messages, not used by x264), B-pyramid requires a DPB of 4 frames if you want each frame to be able to use the closest reference frame (which is a good thing to want). MMCO would cut that number down to 3.

As for interlacing, MBAff doesn't change the DPB size (provided everything else is handled like in the progressive case). PAff does, if you want to have for each pair of fields the same available references, in addition to the cross field reference (the second field can reference the first field, which is a very good thing, but it adds one frame to the DPB).

Selur
13th November 2008, 18:23
First of all, any formula will depend on the encoder.
Okay, didn't know that.
I rephrase the question then:
How does one calculate the maximum number of frames for x264?

Cu Selur

Ps.: btw. for those who are wondering I'm working on a hobby-project which is linux&windows gui for x264 where I want to limit the number of references one can choose when a specific level is specified.

Manao
13th November 2008, 18:28
sps->vui.i_num_reorder_frames = param->b_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;
/* extra slot with pyramid so that we don't have to override the
* order of forgetting old pictures */
sps->vui.i_max_dec_frame_buffering =
sps->i_num_ref_frames = X264_MIN(16, X264_MAX(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames));

So it's your formula.

Selur
13th November 2008, 18:46
Thanks!

So encoding for level 4.1 with 1080p, bframes and pyramid would mean:
maxref = Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
= Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
= Min(12582912 / (1920*1080*1,5)
= Min(12582912/3110400 - 2, 16)
= Min(4 - 2, 16)
= 2

Thanks a lot for the help!

Cu Selur

Dark Shikari
13th November 2008, 18:54
So encoding for level 4.1 with 1080p, bframes and pyramid would mean:
maxref = Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
= Min(this->maxDPB(level)/bytesPerFrame - bframeModifier, 16)
= Min(12582912 / (1920*1080*1,5)
= Min(12582912/3110400 - 2, 16)
= Min(4 - 2, 16)
= 2Nope.

MIN(16,MAX(4,3)) is still 4.

Selur
13th November 2008, 18:56
Care to explain? Where did I go wrong?

Dark Shikari
13th November 2008, 18:56
Care to explain? Where did I go wrong?You subtracted "bframemodifier."

Selur
13th November 2008, 19:02
Okay, now I'm confused. What should I do with it when not subtract?

looking at the start point:
MaxDPB >= (bytes in a frame) * min(16, ref + (pyramid ? 2 : bframes ? 1 : 0))
for fixed a MaxDPB and fixed "bytes in a frame" ref should get smaller if pyramid and/or bframes are enabled. :)

Cu Selur

Dark Shikari
13th November 2008, 19:03
MaxDPB >= (bytes in a frame) * min(16, max(ref, 1 + (pyramid ? 2 : bframes ? 1 : 0)))

fixed

Selur
13th November 2008, 19:06
Okay, thanks. -> going to think about how to rearrange this to get maxRef :)
Doh, after thinking about it it's easier to do the max-brace after the calculation. :)

1. maxref = Min(this->maxDPB(level)/bytesPerFrame, 16)
2. if(maxref < bframeModifier+1) maxRef = bframeModifier+1;

Sergey A. Sablin
13th November 2008, 19:17
MaxDPB >= (bytes in a frame) * min(16, max(ref + (pyramid ? 1 : 0), 1 + (pyramid ? 2 : bframes ? 1 : 0)))

refixed for x264

Dark Shikari
13th November 2008, 19:33
refixed for x264Every time you complain about it is one more day before it gets patched.

And yes, there's already a patch to resolve it :p

Selur
13th November 2008, 19:36
MaxDPB >= (bytes in a frame) * min(16, max(ref + (pyramid ? 1 : 0), 1 + (pyramid ? 2 : bframes ? 1 : 0)))
which would result in:
maxref = Min(this->maxDPB(level)/bytesPerFrame, 16)
maxref = (pyramid) ? maxref-1 : maxref
if(maxref) < bframeModifier+1) maxref = bframeModifier+1

And yes, there's already a patch to resolve it
Nice, hopefully I won't forget to remove the 'maxref = (pyramid) ? maxref-1 : maxref'-line then.

Cu Selur

Sergey A. Sablin
13th November 2008, 19:49
Every time you complain about it is one more day before it gets patched.

the fact that you don't care about spec compliance doesn't change the spec.
and if you still didn't get it - I neither care about level compliance in x264, nor do I care about your humble opinion on this regard. I did answer original question and did it correctly, while x264 developer misinform x264 users (and seems did it knowingly):
And yes, there's already a patch to resolve it :p

so you better beg your pardon to the users for your mistake instead of making pointless comments.

Dark Shikari
13th November 2008, 19:53
the fact that you don't care about spec compliance doesn't change the spec.
and if you still didn't get it - I neither care about level compliance in x264, nor do I care about your humble opinion on this regard. I did answer original question and did it correctly, while x264 developer misinform x264 users (and seems did it knowingly):I am referring to the DPB value written to the bitstream per the code above. I am merely explaining the C code. What I said, with regard to the code, is correct.

What you are saying is that the DPB value written to the bitstream is wrong. This is completely separate. I am not "misleading anyone"; rather, you are misleading people by trying to make both of the following true at the same time:

1. You need to lower ref by 1 when using pyramid to make x264 level-compliant.
2. x264 is, technically, never actually spec-compliant when using pyramid.

In all the threads you have trolled off-topic with your posts on this matter, you seem unable to decide which of these it is. Now, the correct answer is 2), but that hasn't stopped you from coming out and saying 1 when it fit the thread better or happened to make x264 look worse.

If you don't care about x264's level-compliance, stop posting about it. The fact that every single thread that uses the words "pyramid" and "reference frame" gets trolled by you is clearly a signal that you care a hell of a lot. If you didn't care, you wouldn't post about it.

Sergey A. Sablin
13th November 2008, 22:46
I am not "misleading anyone"; rather, you are misleading people by trying to make both of the following true at the same time:

1. You need to lower ref by 1 when using pyramid to make x264 level-compliant.
2. x264 is, technically, never actually spec-compliant when using pyramid.


This simply can't be true at the same time, and don't try to put words in my mouth. The only true statement here is 2. And this is exactly why 1 simply can't be true at all. This is obvious, isn't it?
And no, there is no such a term as "level-compliant" - there is only spec compliant or not. Providing incorrect value about memory needed for decoding process is non compliant with spec, even if the maximum value for specified level is enough for correct decoding of this stream. To optimize memory usage, decoder may allocate as much memory as specified by encoder - not by maximum value for a level.

If you thinking that providing correct information is "trolling" and off-topic, or were done specifically to make x264 look worse, then there is definitely something wrong with you. I pointed to the hole and this shall lead to make x264 better, but no - you always complain that I try to make it look worse, nevertheless that encoder still produces incorrect bitstreams. Probably you think that your comment a-la "I don't care about DPB" make things better.

One would probably want say thank, for at least to be in the know about non-compliance and how to get rid of it.

PS. And once again - I didn't use x264, I don't use it, and most probably won't use it at all. My interest in video compression is far from making home videos, rips of any kind etc. That's - I don't care how compliant x264 is. But if somebody wants to know - I'll let him know. These two do not contradict at all.

shon3i
14th November 2008, 00:50
@Selur, why you make things so hard? when isn't

To calculate maximum references for choosen level you need to look into ITU-T Recommendation H.264 pdf document and Table A-1
http://img296.imageshack.us/img296/4319/91198638fs0.th.jpg (http://img296.imageshack.us/img296/4319/91198638fs0.jpg)

Use MaxDBP from table and use this simple formula to calculate ;)

numofrefs = int(MaxDPB * 1024 / 1.5 / (w * h))

Selur
14th November 2008, 11:32
you did read the rest of the thread didn't you?

shon3i
14th November 2008, 17:59
you did read the rest of the thread didn't you?
If i understood you correctly you want to calculate maximum number of reference frames for choosen level?

If yes, mine method, always give you maximum ref's for choosen level, but like Manao said everything depend on encoder, for example with Mainconcept, Ateme, you can count on this formula. With x264 because have broken b-pyramid, you must lower refs by one, and for totly safe encoding, turn b-pyramid completly off.