<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.videolan.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=J+Darnley</id>
	<title>VideoLAN Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.videolan.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=J+Darnley"/>
	<link rel="alternate" type="text/html" href="https://wiki.videolan.org/Special:Contributions/J_Darnley/"/>
	<updated>2026-11-04T15:56:12Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20909</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20909"/>
		<updated>2011-12-17T22:52:43Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Remove unnecessary &amp;lt;br&amp;gt;s&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise. The original transcript can be found here: [[X264asm]] &lt;br /&gt;
&lt;br /&gt;
__TOC__ &lt;br /&gt;
&lt;br /&gt;
== Example 1: predict_4x4_dc  ==&lt;br /&gt;
&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]). This function does the following: &lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt; &lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What is FDEC_STRIDE? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride. It&#039;s faster that way, and better on cache. So for example, motion compensation will write to this buffer (or intra prediction). &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What&#039;s a stride? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm. &lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;quot;cglobal&amp;quot; declares a function accessible from outside of asm. The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added). The &amp;quot;1&amp;quot; means &amp;quot;we have one argument. Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, (that argument is uint8_t *src). If we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc. So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt; &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What tells the function that it&#039;s uint8_t? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line: &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free, &amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; That&#039;s x86inc.asm&#039;s doing right? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, but we aren&#039;t going into that. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, which is why you can&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps: &lt;br /&gt;
&lt;br /&gt;
#Sum up A through D &lt;br /&gt;
#Sum up E through H &lt;br /&gt;
#Do the math to get our final value &lt;br /&gt;
#Store it into the 16 output Xs&lt;br /&gt;
&lt;br /&gt;
So let&#039;s see how this asm implements these. &lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1 &lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register. &amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How do you tell how large a register is? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit. The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt; &lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0} &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Oh, and how do we know the mm* registers are free? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; They always are.&lt;br /&gt;
&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit). So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits. So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000. &amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in C-style. Hence why it points to ABCD. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Former&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt; &lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does: &lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt; &lt;br /&gt;
Parse that for a moment &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; where is the sum stored? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored. So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero! So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ... Or A+B+C+D. So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero. &lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt; &lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm. &lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H. Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way. So, now we&#039;re going to load E, F, G, H. Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands. &lt;br /&gt;
&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;. In C this would be: int r1d = r0[-1]; &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, [] is just a dereference of a pointer. *(r0-1) = r0[-1] = (r0-1)[0] &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; what is r0-1 in that ascii matrix? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; E.&lt;br /&gt;
&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs: &lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt; &lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Where is n stored? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It isn&#039;t. It&#039;s a preprocessor variable. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Oh, so it&#039;s like a macro? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It is a macro. Note the pre-processed code above. Everything starting with&amp;amp;nbsp;% in yasm syntax is a macro.&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8 &lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt; &lt;br /&gt;
First, let&#039;s go over x86 addressing. What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST]. A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays. E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20] &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, yasm sums up constants for you.&lt;br /&gt;
&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did. &amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add. So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4 &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Wait, how does that work? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first. &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it. It just calculates the result and stores it instead of going to memory. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; And it&#039;s faster than add? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It&#039;s just as fast except that you can do more with it.&lt;br /&gt;
&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;. But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op. &lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt; &lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are we shifting right? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; +4 for correct rounding, &amp;amp;gt;&amp;amp;gt; 3 to divide (&amp;amp;gt;&amp;amp;gt;3 = /(2^3) = /8).&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results. &lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt; &lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well. We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;amp;gt; AAAA &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; how does this work? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done. &lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us. &lt;br /&gt;
&lt;br /&gt;
== Example 2: pixel_sad  ==&lt;br /&gt;
&lt;br /&gt;
Ok, next. You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome. It does like 8 things in one. Whereas abs() is typically 4 instructions on x86. &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up. That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent). &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; why is abs() so slow? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; abs() isn&#039;t slow, there&#039;s just no instruction for it. The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;amp;gt;&amp;amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt; &lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences. So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]). Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]). This function is pretty simple. You should be able to see how it works. Look only at the C for now. &lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro. So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t. &lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two parameters. They are accessed as&amp;amp;nbsp;%1 and&amp;amp;nbsp;%2. We call the macro 7 times, one for each size. The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args) &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is SAD_INC_2x%1P another macro? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16. It picks the right one based on the width and it&amp;amp;nbsp;%reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work. Note mm0 is the accumulator which is why it&#039;s zeroed at the start. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; The order of args is the same as in the C function? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What does punpckldq do? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Good question! punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high. So punpckl__ ABCD, EFGH will use AB and EF. And punpbkh__ ABCD, EFGH will use CD and GH. &lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size. For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes). So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL. So in other words, it stuffs the two sets of 4 bytes we just loaded into one register &lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two. &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH. So it effectively concatenates mm1 and mm2 for us. If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds. We do this because the registers are width 8, but our sad is width 4. So we need to stuff sad information side by side to fill the whole reg. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; We&#039;re concatenating row 0 and row 1 of each input. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step? Doesn&#039;t it move r0 over 2*r1? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why is the lea out of order in SAD_INC_2x8P? By out of order i mean not next to each other. &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; No particular reason. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; So we rep the SAD for however many times so the 2x%1 is completed? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are strides not hardcoded btw? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; SAD can be called on a reference frame thus variable stride &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I don&#039;t really get it... &lt;br /&gt;
:A&amp;amp;lt;&amp;amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What? Why is it so much faster? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance. For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units. The first two are represented with notation like this: &amp;quot;3/1&amp;quot;. This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle. Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;. Between two registers it is 1/0.33, takes 1 cycle, and you can do 3 per clock. &lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier. Not all execution units can do all instructions. Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5 &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Wait, what is latency? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; time from start to finish, in clocks &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; and inverse throughput and execution units? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Inverse throughput is how many you can do per clock. Execution units are the things in the chip that do stuff.&lt;br /&gt;
&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5. &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three. &lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices. For example, if an execution unit is sitting around doing nothing for a whole function. &lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How about branching? I heard branching ruins things. &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause. We can get to a case of that later.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s just analyze SAD. Suppose we want to analyze the 8x8 SAD. In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead. 8 SADs: takes 8 cycles (inverse throughput of 1). 8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs. 16 loads: takes 16 cycles, and can run at the same time as the above. &lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck. This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function. Loads are a common example. In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time. The actual run-time of the function is about 22 clocks. Which is fitting for 16 + start + end + overhead. &lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you. How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is there anything that does this automatically for you? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Analysis? not really. There are Intel performance counters and such on the chip but they&#039;re not magic. It might be useful to have some kind of tool to analyze asm functions. In general though, intuition is a powerful tool.&lt;br /&gt;
&lt;br /&gt;
== Example 3: pixel_avg2_w16_sse2  ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s move onto something else. Open common/x86/mc-a.asm, pixel_avg2_w16_sse2 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/mc-a.asm;h=22fb8720c83b72bcd34b41553f4153bb62847462;hb=HEAD#l842 git link]). This function interpolates between two inputs, and outputs to an output. The interpolation is the simplest possible: (A+B+1)&amp;amp;gt;&amp;amp;gt;1 &lt;br /&gt;
&lt;br /&gt;
Look at the function signature above: &amp;lt;tt&amp;gt;void pixel_avg2_w4( uint8_t *dst, int dst_stride&amp;lt;/tt&amp;gt; etc. This function takes inputs from src1 and src2, averages them together, and writes to dst. src1 and src2 have src_stride and dst has dst_stride. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What&#039;s the height? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; How many lines to interpolate.&lt;br /&gt;
&lt;br /&gt;
Now this function uses xmm registers (128-bit) so it does 16 bytes at a time. All 128-bit loads must be aligned unless movdqu is used. Since our inputs are unaligned, this is a lot of movdqu. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What does movdqu do? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Loads 128 bits from an unaligned source. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What is the difference between movdqa and movdqu? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; movdqa is for aligned data, movdqu is for unaligned data. The output is always aligned, as we control it, whereas the input is an arbitrary pointer into a reference frame and so it could be anything. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why subtract r2 from r4? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Ah, now here&#039;s a fun trick. We need to increment three pointers, right? src1, src2, dst. But src1 and src2 have the same stride, so they&#039;re being incremented by the same amount. So we can take src2 and represent it as an offset from src1. Then we only have to increment src1. One lea removed per iteration, bam. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; And use r6 as the offset + stride? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes&lt;br /&gt;
&lt;br /&gt;
Look through that function and see if there&#039;s anything you don&#039;t know about and ask questions. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How do you keep track of which argument is which? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; You can copy the description from w4 and annotate it.&lt;br /&gt;
&amp;lt;pre&amp;gt;; void pixel_avg2_w4( uint8_t *dst (r0), int dst_stride (r1),&lt;br /&gt;
;                     uint8_t *src1 (r2), int src_stride (r3),&lt;br /&gt;
;                     uint8_t *src2 (r4), int height (r5) );&amp;lt;/pre&amp;gt; &lt;br /&gt;
:There is also a system that can be covered later which helps you keep track of registers or, well, makes it easier to. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; pavgb, I assume, does some sort of averaging? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, (A+B+1)&amp;amp;gt;&amp;amp;gt;1 for each pair of input pixels.&lt;br /&gt;
&lt;br /&gt;
Now we come to one of the many jumps that exists in x86, jump if greater than, so if r5d &amp;amp;gt; 0. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How does the jump work without a compare instruction? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; The sub sets the same flags as a cmp. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; So why subtract two? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It handles two rows at a time.&lt;br /&gt;
&lt;br /&gt;
Here is something to note. The REP_RET you might have been wondering about. In short, if you have a RET after a jump, use REP_RET. Blame AMD.&lt;br /&gt;
&lt;br /&gt;
== Helpful links ==&lt;br /&gt;
* http://agner.org/optimize/ - PDFs containing instruction timing and a couple of related guides (mentioned above)&lt;br /&gt;
* http://alien.dowling.edu/~rohit/nasmdocb.html - NASM manual, x86 instruction reference&lt;br /&gt;
* http://alien.dowling.edu/~rohit/nasmdoc0.html - NASM manual, contents page&lt;br /&gt;
* http://www.tortall.net/projects/yasm/manual/html/index.html - YASM manual, contents page (similar to the NASM manual)&lt;br /&gt;
* http://www.tommesani.com/Docs.html - Some visual representations of MMX instructions&lt;br /&gt;
* http://webster.cs.ucr.edu/AoA/Windows/HTML/TheMMXInstructionSeta2.html - More visual representations of instructions&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20908</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20908"/>
		<updated>2011-12-17T22:18:02Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Add links to other useful pages&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise. The original transcript can be found here: [[X264asm]] &lt;br /&gt;
&lt;br /&gt;
__TOC__ &lt;br /&gt;
&lt;br /&gt;
== Example 1: predict_4x4_dc  ==&lt;br /&gt;
&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]). This function does the following: &lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt; &lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What is FDEC_STRIDE? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride. It&#039;s faster that way, and better on cache. So for example, motion compensation will write to this buffer (or intra prediction). &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What&#039;s a stride? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Now that you understand what the function does, let&#039;s look at the asm. &lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;quot;cglobal&amp;quot; declares a function accessible from outside of asm. The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added). The &amp;quot;1&amp;quot; means &amp;quot;we have one argument. Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, (that argument is uint8_t *src). If we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc. So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt; &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What tells the function that it&#039;s uint8_t? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line: &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free, &amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; That&#039;s x86inc.asm&#039;s doing right? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, but we aren&#039;t going into that. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, which is why you can&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; So now, this function as you can see has 4 real steps: &lt;br /&gt;
&lt;br /&gt;
#Sum up A through D &lt;br /&gt;
#Sum up E through H &lt;br /&gt;
#Do the math to get our final value &lt;br /&gt;
#Store it into the 16 output Xs&lt;br /&gt;
&lt;br /&gt;
So let&#039;s see how this asm implements these. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; First, we&#039;ll look at step 1 &lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register. &amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How do you tell how large a register is? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit. The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt; &lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0} &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Oh, and how do we know the mm* registers are free? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; They always are.&lt;br /&gt;
&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit). So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits. So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000. &amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in C-style. Hence why it points to ABCD. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Former&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt; &lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does: &lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt; &lt;br /&gt;
Parse that for a moment &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; where is the sum stored? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored. So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero! So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ... Or A+B+C+D. So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero. &lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt; &lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Get moving with part 2 of the algorithm. &lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H. Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way. So, now we&#039;re going to load E, F, G, H. Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands. &lt;br /&gt;
&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt; &lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;. In C this would be: int r1d = r0[-1]; &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, [] is just a dereference of a pointer. *(r0-1) = r0[-1] = (r0-1)[0] &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; what is r0-1 in that ascii matrix? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; E.&lt;br /&gt;
&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs: &lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt; &lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Where is n stored? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It isn&#039;t. It&#039;s a preprocessor variable. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Oh, so it&#039;s like a macro? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It is a macro. Note the pre-processed code above. Everything starting with&amp;amp;nbsp;% in yasm syntax is a macro.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8 &lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt; &lt;br /&gt;
First, let&#039;s go over x86 addressing. What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST]. A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays. E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20] &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, yasm sums up constants for you.&lt;br /&gt;
&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did. &amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add. So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4 &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Wait, how does that work? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first. &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it. It just calculates the result and stores it instead of going to memory. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; And it&#039;s faster than add? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It&#039;s just as fast except that you can do more with it.&lt;br /&gt;
&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;. But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op. &lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt; &lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are we shifting right? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; +4 for correct rounding, &amp;amp;gt;&amp;amp;gt; 3 to divide (&amp;amp;gt;&amp;amp;gt;3 = /(2^3) = /8).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Now for the final part: storing the results. &lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt; &lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well. We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;amp;gt; AAAA &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; how does this work? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done. &lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us. &lt;br /&gt;
&lt;br /&gt;
== Example 2: pixel_sad  ==&lt;br /&gt;
&lt;br /&gt;
Ok, next. You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome. It does like 8 things in one. Whereas abs() is typically 4 instructions on x86. &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up. That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent). &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; why is abs() so slow? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; abs() isn&#039;t slow, there&#039;s just no instruction for it. The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;amp;gt;&amp;amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt; &lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences. So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]). Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]). This function is pretty simple. You should be able to see how it works. Look only at the C for now. &lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro. So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t. &lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two parameters. They are accessed as&amp;amp;nbsp;%1 and&amp;amp;nbsp;%2. We call the macro 7 times, one for each size. The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args) &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is SAD_INC_2x%1P another macro? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16. It picks the right one based on the width and it&amp;amp;nbsp;%reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work. Note mm0 is the accumulator which is why it&#039;s zeroed at the start. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; The order of args is the same as in the C function? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What does punpckldq do? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Good question! punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high. So punpckl__ ABCD, EFGH will use AB and EF. And punpbkh__ ABCD, EFGH will use CD and GH. &lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size. For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes). So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL. So in other words, it stuffs the two sets of 4 bytes we just loaded into one register &lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two. &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH. So it effectively concatenates mm1 and mm2 for us. If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds. We do this because the registers are width 8, but our sad is width 4. So we need to stuff sad information side by side to fill the whole reg. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; We&#039;re concatenating row 0 and row 1 of each input. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step? Doesn&#039;t it move r0 over 2*r1? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why is the lea out of order in SAD_INC_2x8P? By out of order i mean not next to each other. &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; No particular reason. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; So we rep the SAD for however many times so the 2x%1 is completed? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why are strides not hardcoded btw? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; SAD can be called on a reference frame thus variable stride &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; I don&#039;t really get it... &lt;br /&gt;
:A&amp;amp;lt;&amp;amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What? Why is it so much faster? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Now let&#039;s get a bit to how we measure performance. For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units. The first two are represented with notation like this: &amp;quot;3/1&amp;quot;. This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle. Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;. Between two registers it is 1/0.33, takes 1 cycle, and you can do 3 per clock. &lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier. Not all execution units can do all instructions. Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5 &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Wait, what is latency? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; time from start to finish, in clocks &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; and inverse throughput and execution units? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Inverse throughput is how many you can do per clock. Execution units are the things in the chip that do stuff.&lt;br /&gt;
&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5. &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three. &lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices. For example, if an execution unit is sitting around doing nothing for a whole function. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How about branching? I heard branching ruins things. &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause. We can get to a case of that later.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s just analyze SAD. Suppose we want to analyze the 8x8 SAD. In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead. 8 SADs: takes 8 cycles (inverse throughput of 1). 8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs. 16 loads: takes 16 cycles, and can run at the same time as the above. &lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck. This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function. Loads are a common example. In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time. The actual run-time of the function is about 22 clocks. Which is fitting for 16 + start + end + overhead. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; So that&#039;s some basic performance analysis for you. How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Is there anything that does this automatically for you? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Analysis? not really. There are Intel performance counters and such on the chip but they&#039;re not magic. It might be useful to have some kind of tool to analyze asm functions. In general though, intuition is a powerful tool.&lt;br /&gt;
&lt;br /&gt;
== Example 3: pixel_avg2_w16_sse2  ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s move onto something else. Open common/x86/mc-a.asm, pixel_avg2_w16_sse2 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/mc-a.asm;h=22fb8720c83b72bcd34b41553f4153bb62847462;hb=HEAD#l842 git link]). This function interpolates between two inputs, and outputs to an output. The interpolation is the simplest possible: (A+B+1)&amp;amp;gt;&amp;amp;gt;1 &lt;br /&gt;
&lt;br /&gt;
Look at the function signature above: &amp;lt;tt&amp;gt;void pixel_avg2_w4( uint8_t *dst, int dst_stride&amp;lt;/tt&amp;gt; etc. This function takes inputs from src1 and src2, averages them together, and writes to dst. src1 and src2 have src_stride and dst has dst_stride. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What&#039;s the height? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; How many lines to interpolate.&lt;br /&gt;
&lt;br /&gt;
Now this function uses xmm registers (128-bit) so it does 16 bytes at a time. All 128-bit loads must be aligned unless movdqu is used. Since our inputs are unaligned, this is a lot of movdqu. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What does movdqu do? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Loads 128 bits from an unaligned source. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; What is the difference between movdqa and movdqu? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; movdqa is for aligned data, movdqu is for unaligned data. The output is always aligned, as we control it, whereas the input is an arbitrary pointer into a reference frame and so it could be anything. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; Why subtract r2 from r4? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Ah, now here&#039;s a fun trick. We need to increment three pointers, right? src1, src2, dst. But src1 and src2 have the same stride, so they&#039;re being incremented by the same amount. So we can take src2 and represent it as an offset from src1. Then we only have to increment src1. One lea removed per iteration, bam. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; And use r6 as the offset + stride? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes&lt;br /&gt;
&lt;br /&gt;
Look through that function and see if there&#039;s anything you don&#039;t know about and ask questions. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How do you keep track of which argument is which? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; You can copy the description from w4 and annotate it.&lt;br /&gt;
&amp;lt;pre&amp;gt;; void pixel_avg2_w4( uint8_t *dst (r0), int dst_stride (r1),&lt;br /&gt;
;                     uint8_t *src1 (r2), int src_stride (r3),&lt;br /&gt;
;                     uint8_t *src2 (r4), int height (r5) );&amp;lt;/pre&amp;gt; &lt;br /&gt;
:There is also a system that can be covered later which helps you keep track of registers or, well, makes it easier to. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; pavgb, I assume, does some sort of averaging? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; Yes, (A+B+1)&amp;amp;gt;&amp;amp;gt;1 for each pair of input pixels.&lt;br /&gt;
&lt;br /&gt;
Now we come to one of the many jumps that exists in x86, jump if greater than, so if r5d &amp;amp;gt; 0. &lt;br /&gt;
&lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; How does the jump work without a compare instruction? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; The sub sets the same flags as a cmp. &lt;br /&gt;
:&amp;amp;lt;Q&amp;amp;gt; So why subtract two? &lt;br /&gt;
:&amp;amp;lt;A&amp;amp;gt; It handles two rows at a time.&lt;br /&gt;
&lt;br /&gt;
Here is something to note. The REP_RET you might have been wondering about. In short, if you have a RET after a jump, use REP_RET. Blame AMD.&lt;br /&gt;
&lt;br /&gt;
== Helpful links ==&lt;br /&gt;
* http://agner.org/optimize/ - PDFs containing instruction timing and a couple of related guides (mentioned above)&lt;br /&gt;
* http://alien.dowling.edu/~rohit/nasmdocb.html - NASM manual, x86 instruction reference&lt;br /&gt;
* http://alien.dowling.edu/~rohit/nasmdoc0.html - NASM manual, contents page&lt;br /&gt;
* http://www.tortall.net/projects/yasm/manual/html/index.html - YASM manual, contents page (similar to the NASM manual)&lt;br /&gt;
* http://www.tommesani.com/Docs.html - Some visual representations of MMX instructions&lt;br /&gt;
* http://webster.cs.ucr.edu/AoA/Windows/HTML/TheMMXInstructionSeta2.html - More visual representations of instructions&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20580</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=20580"/>
		<updated>2011-12-10T16:11:54Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Lets get a table of contents in here along with some better headings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise.  The original transcript can be found here: [[X264asm]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Example 1: predict_4x4_dc ==&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]).  This function does the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;quot;cglobal&amp;quot; declares a function accessible from outside of asm.  The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).  The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, (that argument is uint8_t *src).  If we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What tells the function that it&#039;s uint8_t?&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line: &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free, &amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use.&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&lt;br /&gt;
# Sum up A through D&lt;br /&gt;
# Sum up E through H&lt;br /&gt;
# Do the math to get our final value&lt;br /&gt;
# Store it into the 16 output Xs&lt;br /&gt;
So let&#039;s see how this asm implements these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.  &amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&lt;br /&gt;
&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit).  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits.  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000.  &amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.  So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.  Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&lt;br /&gt;
&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&lt;br /&gt;
&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs:&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST].  A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&lt;br /&gt;
&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.  &amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&lt;br /&gt;
&lt;br /&gt;
== Example 2: pixel_sad ==&lt;br /&gt;
Ok, next.  You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome.  It does like 8 things in one.  Whereas abs() is typically 4 instructions on x86.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up.  That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent).&lt;br /&gt;
:&amp;lt;Q&amp;gt; why is abs() so slow?&lt;br /&gt;
:&amp;lt;A&amp;gt; abs() isn&#039;t slow, there&#039;s just no instructin for it.  The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences.  So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]).  Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]).  This function is pretty simple.  You should be able to see how it works.  Look only at the C for now.&lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro.  So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two paremeters.  They are accessed as %1 and %2.  We call the macro 7 times, one for each size.  The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args)&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is SAD_INC_2x%1P another macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16.  It picks the right one based on the width and it %reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.  Note mm0 is the accumulator which is why it&#039;s zeroed at the start.&lt;br /&gt;
:&amp;lt;Q&amp;gt; The order of args is the same as in the C function?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does punpckldq do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Good question!  punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high.  So punpckl__ ABCD, EFGH will use AB and EF.  And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size.  For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes).  So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL.  So in other words, it stuffs the two sets of 4 bytes we just loaded into one register&lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two.  &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH.  So it effectively concatenates mm1 and mm2 for us.  If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.  We do this because the registers are width 8, but our sad is width 4.  So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re concatenating row 0 and row 1 of each input.&lt;br /&gt;
:&amp;lt;Q&amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step?  Doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why is the lea out of order in SAD_INC_2x8P?  By out of order i mean not next to each other.&lt;br /&gt;
:&amp;lt;A&amp;gt; No particular reason.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are strides not hardcoded btw?&lt;br /&gt;
:&amp;lt;A&amp;gt; SAD can be called on a reference frame thus variable stride&lt;br /&gt;
:&amp;lt;Q&amp;gt; I don&#039;t really get it...&lt;br /&gt;
:A&amp;lt;&amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What?  Why is it so much faster?&lt;br /&gt;
:&amp;lt;A&amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance.  For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units.  The first two are represented with notation like this: &amp;quot;3/1&amp;quot;.  This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle.  Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;.  Between two registers  it is 1/0.33, takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier.  Not all execution units can do all instructions.  Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, what is latency?&lt;br /&gt;
:&amp;lt;A&amp;gt; time from start to finish, in clocks&lt;br /&gt;
:&amp;lt;Q&amp;gt; and inverse throughput and execution units?&lt;br /&gt;
:&amp;lt;A&amp;gt; Inverse throughput is how many you can do per clock.  Execution units are the things in the chip that do stuff.&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three.&lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices.  For example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How about branching?  I heard branching ruins things.&lt;br /&gt;
:&amp;lt;A&amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause.  We can get to a case of that later.&lt;br /&gt;
Now, let&#039;s just analyze SAD.  Suppose we want to analyze the 8x8 SAD.  In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead.  8 SADs: takes 8 cycles (inverse throughput of 1).  8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs.  16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck.  This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.  Loads are a common example.  In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.  The actual runtime of the function is about 22 clocks.  Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you.  How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is there anything that does this automatically for you?&lt;br /&gt;
:&amp;lt;A&amp;gt; Analysis?  not really.  There are intel performance counters and such on the chip  but they&#039;re not magic.  It might be useful to have some kind of tool to analyze asm functions.  In general though, intuition is a powerful tool.&lt;br /&gt;
&lt;br /&gt;
== Example 3: pixel_avg2_w16_sse2 ==&lt;br /&gt;
Let&#039;s move onto something else.  Open common/x86/mc-a.asm, pixel_avg2_w16_sse2 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/mc-a.asm;h=22fb8720c83b72bcd34b41553f4153bb62847462;hb=HEAD#l842 git link]).  This function interpolates between two inputs, and outputs to an output.  The interpolation is the simplest possible: (A+B+1)&amp;gt;&amp;gt;1&lt;br /&gt;
&lt;br /&gt;
Look at the function signature above: &amp;lt;tt&amp;gt;void pixel_avg2_w4( uint8_t *dst, int dst_stride&amp;lt;/tt&amp;gt; etc.  This function takes inputs from src1 and src2, averages them together, and writes to dst.  src1 and src2 have src_stride and dst has dst_stride.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s the height?&lt;br /&gt;
:&amp;lt;A&amp;gt; How many lines to interpolate.&lt;br /&gt;
&lt;br /&gt;
Now this function uses xmm registers (128-bit) so it does 16 bytes at a time.  All 128-bit loads must be aligned unless movdqu is used.  Since our inputs are unaligned, this is a lot of movdqu.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does movdqu do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Loads 128 bits from an unaligned source.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is the difference between movdqa and movdqu?&lt;br /&gt;
:&amp;lt;A&amp;gt; movdqa is for aligned data, movdqu is for unaligned data.  The output is always aligned, as we control it, whereas the input is an arbitrary pointer into a reference frame and so it could be anything.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why subtract r2 from r4?&lt;br /&gt;
:&amp;lt;A&amp;gt; Ah, now here&#039;s a fun trick.  We need to increment three pointers, right?  src1, src2, dst.  But src1 and src2 have the same stride, so they&#039;re being incremented by the same amount.  So we can take src2 and represent it as an offset from src1.  Then we only have to increment src1.  One lea removed per iteration, bam.&lt;br /&gt;
:&amp;lt;Q&amp;gt; And use r6 as the offset + stride?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
&lt;br /&gt;
Look through that function and see if there&#039;s anything you don&#039;t know about and ask questions.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you keep track of which argument is which?&lt;br /&gt;
:&amp;lt;A&amp;gt; You can copy the description from w4 and annotate it.&lt;br /&gt;
&amp;lt;pre&amp;gt;; void pixel_avg2_w4( uint8_t *dst (r0), int dst_stride (r1),&lt;br /&gt;
;                     uint8_t *src1 (r2), int src_stride (r3),&lt;br /&gt;
;                     uint8_t *src2 (r4), int height (r5) );&amp;lt;/pre&amp;gt;&lt;br /&gt;
:There is also a system that can be covered later which helps you keep track of registers or, well, makes it easier to.&lt;br /&gt;
:&amp;lt;Q&amp;gt; pavgb, I assume, does some sort of averaging?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, (A+B+1)&amp;gt;&amp;gt;1 for each pair of input pixels.&lt;br /&gt;
&lt;br /&gt;
Now we come to one of the many jumps that exists in x86, jump if greater than, so if r5d &amp;gt; 0.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How does the jump work without a compare instruction?&lt;br /&gt;
:&amp;lt;A&amp;gt; The sub sets the same flags as a cmp.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So why subtract two?&lt;br /&gt;
:&amp;lt;A&amp;gt; It handles two rows at a time.&lt;br /&gt;
&lt;br /&gt;
Here is something to note.  The REP_RET you might have been wondering about.  In short, if you have a RET after a jump, use REP_RET.  Blame AMD.&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18090</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18090"/>
		<updated>2010-12-04T15:58:54Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: /* Two */ Add the third discussion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise.  The original transcript can be found here: [[X264asm]]&lt;br /&gt;
&lt;br /&gt;
== One ==&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]).  This function does the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;quot;cglobal&amp;quot; declares a function accessible from outside of asm.  The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).  The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, (that argument is uint8_t *src).  If we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What tells the function that it&#039;s uint8_t?&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line: &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free, &amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use.&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&lt;br /&gt;
# Sum up A through D&lt;br /&gt;
# Sum up E through H&lt;br /&gt;
# Do the math to get our final value&lt;br /&gt;
# Store it into the 16 output Xs&lt;br /&gt;
So let&#039;s see how this asm implements these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.  &amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&lt;br /&gt;
&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit).  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits.  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000.  &amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.  So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.  Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&lt;br /&gt;
&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&lt;br /&gt;
&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs:&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST].  A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&lt;br /&gt;
&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.  &amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&lt;br /&gt;
&lt;br /&gt;
== Two ==&lt;br /&gt;
Ok, next.  You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome.  It does like 8 things in one.  Whereas abs() is typically 4 instructions on x86.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up.  That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent).&lt;br /&gt;
:&amp;lt;Q&amp;gt; why is abs() so slow?&lt;br /&gt;
:&amp;lt;A&amp;gt; abs() isn&#039;t slow, there&#039;s just no instructin for it.  The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences.  So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]).  Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]).  This function is pretty simple.  You should be able to see how it works.  Look only at the C for now.&lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro.  So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two paremeters.  They are accessed as %1 and %2.  We call the macro 7 times, one for each size.  The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args)&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is SAD_INC_2x%1P another macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16.  It picks the right one based on the width and it %reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.  Note mm0 is the accumulator which is why it&#039;s zeroed at the start.&lt;br /&gt;
:&amp;lt;Q&amp;gt; The order of args is the same as in the C function?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does punpckldq do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Good question!  punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high.  So punpckl__ ABCD, EFGH will use AB and EF.  And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size.  For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes).  So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL.  So in other words, it stuffs the two sets of 4 bytes we just loaded into one register&lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two.  &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH.  So it effectively concatenates mm1 and mm2 for us.  If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.  We do this because the registers are width 8, but our sad is width 4.  So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re concatenating row 0 and row 1 of each input.&lt;br /&gt;
:&amp;lt;Q&amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step?  Doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why is the lea out of order in SAD_INC_2x8P?  By out of order i mean not next to each other.&lt;br /&gt;
:&amp;lt;A&amp;gt; No particular reason.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are strides not hardcoded btw?&lt;br /&gt;
:&amp;lt;A&amp;gt; SAD can be called on a reference frame thus variable stride&lt;br /&gt;
:&amp;lt;Q&amp;gt; I don&#039;t really get it...&lt;br /&gt;
:A&amp;lt;&amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What?  Why is it so much faster?&lt;br /&gt;
:&amp;lt;A&amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance.  For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units.  The first two are represented with notation like this: &amp;quot;3/1&amp;quot;.  This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle.  Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;.  Between two registers  it is 1/0.33, takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier.  Not all execution units can do all instructions.  Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, what is latency?&lt;br /&gt;
:&amp;lt;A&amp;gt; time from start to finish, in clocks&lt;br /&gt;
:&amp;lt;Q&amp;gt; and inverse throughput and execution units?&lt;br /&gt;
:&amp;lt;A&amp;gt; Inverse throughput is how many you can do per clock.  Execution units are the things in the chip that do stuff.&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three.&lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices.  For example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How about branching?  I heard branching ruins things.&lt;br /&gt;
:&amp;lt;A&amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause.  We can get to a case of that later.&lt;br /&gt;
Now, let&#039;s just analyze SAD.  Suppose we want to analyze the 8x8 SAD.  In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead.  8 SADs: takes 8 cycles (inverse throughput of 1).  8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs.  16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck.  This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.  Loads are a common example.  In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.  The actual runtime of the function is about 22 clocks.  Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you.  How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is there anything that does this automatically for you?&lt;br /&gt;
:&amp;lt;A&amp;gt; Analysis?  not really.  There are intel performance counters and such on the chip  but they&#039;re not magic.  It might be useful to have some kind of tool to analyze asm functions.  In general though, intuition is a powerful tool.&lt;br /&gt;
&lt;br /&gt;
== Three ==&lt;br /&gt;
Let&#039;s move onto something else.  Open common/x86/mc-a.asm, pixel_avg2_w16_sse2 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/mc-a.asm;h=22fb8720c83b72bcd34b41553f4153bb62847462;hb=HEAD#l842 git link]).  This function interpolates between two inputs, and outputs to an output.  The interpolation is the simplest possible: (A+B+1)&amp;gt;&amp;gt;1&lt;br /&gt;
&lt;br /&gt;
Look at the function signature above: &amp;lt;tt&amp;gt;void pixel_avg2_w4( uint8_t *dst, int dst_stride&amp;lt;/tt&amp;gt; etc.  This function takes inputs from src1 and src2, averages them together, and writes to dst.  src1 and src2 have src_stride and dst has dst_stride.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s the height?&lt;br /&gt;
:&amp;lt;A&amp;gt; How many lines to interpolate.&lt;br /&gt;
&lt;br /&gt;
Now this function uses xmm registers (128-bit) so it does 16 bytes at a time.  All 128-bit loads must be aligned unless movdqu is used.  Since our inputs are unaligned, this is a lot of movdqu.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does movdqu do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Loads 128 bits from an unaligned source.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is the difference between movdqa and movdqu?&lt;br /&gt;
:&amp;lt;A&amp;gt; movdqa is for aligned data, movdqu is for unaligned data.  The output is always aligned, as we control it, whereas the input is an arbitrary pointer into a reference frame and so it could be anything.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why subtract r2 from r4?&lt;br /&gt;
:&amp;lt;A&amp;gt; Ah, now here&#039;s a fun trick.  We need to increment three pointers, right?  src1, src2, dst.  But src1 and src2 have the same stride, so they&#039;re being incremented by the same amount.  So we can take src2 and represent it as an offset from src1.  Then we only have to increment src1.  One lea removed per iteration, bam.&lt;br /&gt;
:&amp;lt;Q&amp;gt; And use r6 as the offset + stride?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
&lt;br /&gt;
Look through that function and see if there&#039;s anything you don&#039;t know about and ask questions.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you keep track of which argument is which?&lt;br /&gt;
:&amp;lt;A&amp;gt; You can copy the description from w4 and annotate it.&lt;br /&gt;
&amp;lt;pre&amp;gt;; void pixel_avg2_w4( uint8_t *dst (r0), int dst_stride (r1),&lt;br /&gt;
;                     uint8_t *src1 (r2), int src_stride (r3),&lt;br /&gt;
;                     uint8_t *src2 (r4), int height (r5) );&amp;lt;/pre&amp;gt;&lt;br /&gt;
:There is also a system that can be covered later which helps you keep track of registers or, well, makes it easier to.&lt;br /&gt;
:&amp;lt;Q&amp;gt; pavgb, I assume, does some sort of averaging?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, (A+B+1)&amp;gt;&amp;gt;1 for each pair of input pixels.&lt;br /&gt;
&lt;br /&gt;
Now we come to one of the many jumps that exists in x86, jump if greater than, so if r5d &amp;gt; 0.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How does the jump work without a compare instruction?&lt;br /&gt;
:&amp;lt;A&amp;gt; The sub sets the same flags as a cmp.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So why subtract two?&lt;br /&gt;
:&amp;lt;A&amp;gt; It handles two rows at a time.&lt;br /&gt;
&lt;br /&gt;
Here is something to note.  The REP_RET you might have been wondering about.  In short, if you have a RET after a jump, use REP_RET.  Blame AMD.&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18089</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18089"/>
		<updated>2010-12-03T22:41:25Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: /* One */ Layout and markup changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise.  The original transcript can be found here: [[X264asm]]&lt;br /&gt;
&lt;br /&gt;
== One ==&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]).  This function does the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;quot;cglobal&amp;quot; declares a function accessible from outside of asm.  The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).  The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, (that argument is uint8_t *src).  If we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What tells the function that it&#039;s uint8_t?&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line: &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free, &amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use.&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&lt;br /&gt;
# Sum up A through D&lt;br /&gt;
# Sum up E through H&lt;br /&gt;
# Do the math to get our final value&lt;br /&gt;
# Store it into the 16 output Xs&lt;br /&gt;
So let&#039;s see how this asm implements these.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.  &amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&lt;br /&gt;
&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit).  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits.  So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000.  &amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.  So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&lt;br /&gt;
&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.  Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&lt;br /&gt;
&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&lt;br /&gt;
&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs:&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST].  A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&lt;br /&gt;
&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.  &amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&lt;br /&gt;
&lt;br /&gt;
== Two ==&lt;br /&gt;
Ok, next.  You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome.  It does like 8 things in one.  Whereas abs() is typically 4 instructions on x86.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up.  That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent).&lt;br /&gt;
:&amp;lt;Q&amp;gt; why is abs() so slow?&lt;br /&gt;
:&amp;lt;A&amp;gt; abs() isn&#039;t slow, there&#039;s just no instructin for it.  The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences.  So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]).  Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]).  This function is pretty simple.  You should be able to see how it works.  Look only at the C for now.&lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro.  So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two paremeters.  They are accessed as %1 and %2.  We call the macro 7 times, one for each size.  The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args)&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is SAD_INC_2x%1P another macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16.  It picks the right one based on the width and it %reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.  Note mm0 is the accumulator which is why it&#039;s zeroed at the start.&lt;br /&gt;
:&amp;lt;Q&amp;gt; The order of args is the same as in the C function?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does punpckldq do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Good question!  punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high.  So punpckl__ ABCD, EFGH will use AB and EF.  And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size.  For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes).  So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL.  So in other words, it stuffs the two sets of 4 bytes we just loaded into one register&lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two.  &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH.  So it effectively concatenates mm1 and mm2 for us.  If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.  We do this because the registers are width 8, but our sad is width 4.  So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re concatenating row 0 and row 1 of each input.&lt;br /&gt;
:&amp;lt;Q&amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step?  Doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why is the lea out of order in SAD_INC_2x8P?  By out of order i mean not next to each other.&lt;br /&gt;
:&amp;lt;A&amp;gt; No particular reason.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are strides not hardcoded btw?&lt;br /&gt;
:&amp;lt;A&amp;gt; SAD can be called on a reference frame thus variable stride&lt;br /&gt;
:&amp;lt;Q&amp;gt; I don&#039;t really get it...&lt;br /&gt;
:A&amp;lt;&amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What?  Why is it so much faster?&lt;br /&gt;
:&amp;lt;A&amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance.  For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units.  The first two are represented with notation like this: &amp;quot;3/1&amp;quot;.  This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle.  Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;.  Between two registers  it is 1/0.33, takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier.  Not all execution units can do all instructions.  Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, what is latency?&lt;br /&gt;
:&amp;lt;A&amp;gt; time from start to finish, in clocks&lt;br /&gt;
:&amp;lt;Q&amp;gt; and inverse throughput and execution units?&lt;br /&gt;
:&amp;lt;A&amp;gt; Inverse throughput is how many you can do per clock.  Execution units are the things in the chip that do stuff.&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three.&lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices.  For example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How about branching?  I heard branching ruins things.&lt;br /&gt;
:&amp;lt;A&amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause.  We can get to a case of that later.&lt;br /&gt;
Now, let&#039;s just analyze SAD.  Suppose we want to analyze the 8x8 SAD.  In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead.  8 SADs: takes 8 cycles (inverse throughput of 1).  8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs.  16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck.  This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.  Loads are a common example.  In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.  The actual runtime of the function is about 22 clocks.  Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you.  How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is there anything that does this automatically for you?&lt;br /&gt;
:&amp;lt;A&amp;gt; Analysis?  not really.  There are intel performance counters and such on the chip  but they&#039;re not magic.  It might be useful to have some kind of tool to analyze asm functions.  In general though, intuition is a powerful tool.&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264asm&amp;diff=18088</id>
		<title>X264asm</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264asm&amp;diff=18088"/>
		<updated>2010-12-03T22:06:33Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Add a link to the edited version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An edited version can be found here: [[X264 asm intro]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2010-11-22 00:35:03 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-22 00:35:09 &amp;lt; Dark_Shikari&amp;gt; open common/x86/predict-a.asm&lt;br /&gt;
2010-11-22 00:35:26 &amp;lt; Dark_Shikari&amp;gt; go to predict_4x4_dc_mmxext&lt;br /&gt;
2010-11-22 00:35:29 &amp;lt; Dark_Shikari&amp;gt; this function does the following&lt;br /&gt;
2010-11-22 00:35:32 &amp;lt; Dark_Shikari&amp;gt;   A B C D&lt;br /&gt;
2010-11-22 00:35:34 &amp;lt; Dark_Shikari&amp;gt; E X X X X&lt;br /&gt;
2010-11-22 00:35:36 &amp;lt; Dark_Shikari&amp;gt; F X X X X&lt;br /&gt;
2010-11-22 00:35:37 &amp;lt; Dark_Shikari&amp;gt; G X X X X&lt;br /&gt;
2010-11-22 00:35:40 &amp;lt; Dark_Shikari&amp;gt; H X X X X&lt;br /&gt;
2010-11-22 00:35:48 &amp;lt; Kovensky&amp;gt; ascii graphs :D&lt;br /&gt;
2010-11-22 00:35:51 &amp;lt; Dark_Shikari&amp;gt; It calculates (A+B+C+D+E+F+G+H+4)&amp;gt;&amp;gt;3, and sets all the Xs equal to that value.&lt;br /&gt;
2010-11-22 00:36:06 &amp;lt; Dark_Shikari&amp;gt; where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
2010-11-22 00:36:12 &amp;lt; Dark_Shikari&amp;gt; got that?  throw questions at any time&lt;br /&gt;
2010-11-22 00:36:19 &amp;lt; Jumpyshoes&amp;gt; actually, can you hold on for one minute?&lt;br /&gt;
2010-11-22 00:36:28 &amp;lt; Dark_Shikari&amp;gt; ok&lt;br /&gt;
2010-11-22 00:36:42 &amp;lt; Jumpyshoes&amp;gt; being a dumbass, i forgot x264 was on my other computer&lt;br /&gt;
2010-11-22 00:36:46 &amp;lt; Kovensky&amp;gt; durf, iTerm2 locked up&lt;br /&gt;
2010-11-22 00:38:54 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 00:38:56 &amp;lt; Jumpyshoes&amp;gt; ready now&lt;br /&gt;
2010-11-22 00:40:15  * Dark_Shikari waits for response&lt;br /&gt;
2010-11-22 00:40:33 &amp;lt; Jumpyshoes&amp;gt; i think i should look up the intel docs&lt;br /&gt;
2010-11-22 00:40:42 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-22 00:40:50 &amp;lt; Dark_Shikari&amp;gt; I asked you if you understood my explanation of what a function does.&lt;br /&gt;
2010-11-22 00:40:52 &amp;lt; Jumpyshoes&amp;gt; well, it&#039;s a bunch of assembly&lt;br /&gt;
2010-11-22 00:40:53 &amp;lt; Jumpyshoes&amp;gt; OH&lt;br /&gt;
2010-11-22 00:40:54 &amp;lt; Dark_Shikari&amp;gt; This has absolutely nothing to do with intel.&lt;br /&gt;
2010-11-22 00:40:59 &amp;lt; Jumpyshoes&amp;gt; yes, i understand what the function does&lt;br /&gt;
2010-11-22 00:41:19 &amp;lt; Dark_Shikari&amp;gt; ok, good&lt;br /&gt;
2010-11-22 00:41:42 &amp;lt; Jumpyshoes&amp;gt; actually, what is FDEC_STRIDE?&lt;br /&gt;
2010-11-22 00:41:54 &amp;lt; Dark_Shikari&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer&lt;br /&gt;
2010-11-22 00:41:59 &amp;lt; Dark_Shikari&amp;gt; of constant stride&lt;br /&gt;
2010-11-22 00:42:02 &amp;lt; Dark_Shikari&amp;gt; it&#039;s faster that way, and better on cache&lt;br /&gt;
2010-11-22 00:42:16 &amp;lt; Jumpyshoes&amp;gt; what&#039;s a stride? &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-22 00:42:16 &amp;lt; Dark_Shikari&amp;gt; so for example, motion compensation will write to this buffer&lt;br /&gt;
2010-11-22 00:42:18 &amp;lt; Dark_Shikari&amp;gt; or intra prediction&lt;br /&gt;
2010-11-22 00:42:26 &amp;lt; Kovensky&amp;gt; a stride is the distance from one line to the next IIRC&lt;br /&gt;
2010-11-22 00:42:43 &amp;lt; Dark_Shikari&amp;gt; stride is the distance between (x,y) and (x,y+1)&lt;br /&gt;
2010-11-22 00:43:07 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 00:43:36 &amp;lt; Dark_Shikari&amp;gt; so to get from one row to the next&lt;br /&gt;
2010-11-22 00:43:51 &amp;lt; Dark_Shikari&amp;gt; now that you understand what the function does, let&#039;s look at the asm&lt;br /&gt;
2010-11-22 00:43:54 &amp;lt; Dark_Shikari&amp;gt; cglobal predict_4x4_dc_mmxext, 1,4&lt;br /&gt;
2010-11-22 00:44:01 &amp;lt; Kovensky&amp;gt; yay, asm class&lt;br /&gt;
2010-11-22 00:44:02  * Kovensky watches&lt;br /&gt;
2010-11-22 00:44:12 &amp;lt; Dark_Shikari&amp;gt; cglobal: declares a function accessible from outside of asm&lt;br /&gt;
2010-11-22 00:44:20 &amp;lt; Dark_Shikari&amp;gt; the function&#039;s name is x264_predict_4x4_dc_mmxext&lt;br /&gt;
2010-11-22 00:44:24 &amp;lt; Dark_Shikari&amp;gt; the x264_ is auto-added.&lt;br /&gt;
2010-11-22 00:44:33 &amp;lt; Dark_Shikari&amp;gt; the &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in r0.&amp;quot;&lt;br /&gt;
2010-11-22 00:44:36 &amp;lt; Dark_Shikari&amp;gt; that argument is uint8_t *src&lt;br /&gt;
2010-11-22 00:44:46 &amp;lt; Dark_Shikari&amp;gt; if we had a second argument, we&#039;d say &amp;quot;2&amp;quot; and the second one would go in r1.&lt;br /&gt;
2010-11-22 00:44:50 &amp;lt; Dark_Shikari&amp;gt; and if we had a third, it&#039;d go in r2.&lt;br /&gt;
2010-11-22 00:44:51 &amp;lt; Dark_Shikari&amp;gt; etc&lt;br /&gt;
2010-11-22 00:44:53 &amp;lt; Dark_Shikari&amp;gt; got that?&lt;br /&gt;
2010-11-22 00:45:04 &amp;lt; Dark_Shikari&amp;gt; so at the start of the function, r0 contains uint8_t *src.&lt;br /&gt;
2010-11-22 00:45:04 &amp;lt; Jumpyshoes&amp;gt; that argument is uint8_t *src &amp;lt;-- what does this mean?&lt;br /&gt;
2010-11-22 00:45:09 &amp;lt; Dark_Shikari&amp;gt; ; void predict_4x4_dc( uint8_t *src )&lt;br /&gt;
2010-11-22 00:45:11 &amp;lt; Dark_Shikari&amp;gt; hurr hurr&lt;br /&gt;
2010-11-22 00:45:15 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 00:45:16 &amp;lt; Dark_Shikari&amp;gt; it&#039;s a function argument&lt;br /&gt;
2010-11-22 00:45:16 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 00:45:36 &amp;lt; Jumpyshoes&amp;gt; what tells the function that it&#039;s uint8_t?&lt;br /&gt;
2010-11-22 00:45:39 &amp;lt; Dark_Shikari&amp;gt; Nothing.&lt;br /&gt;
2010-11-22 00:45:42 &amp;lt; Dark_Shikari&amp;gt; It doesn&#039;t need to know.&lt;br /&gt;
2010-11-22 00:45:44 &amp;lt; Dark_Shikari&amp;gt; types are a Cism&lt;br /&gt;
2010-11-22 00:45:58 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 00:45:59 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-22 00:46:03 &amp;lt; Dark_Shikari&amp;gt; the &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use.&lt;br /&gt;
2010-11-22 00:46:05 &amp;lt; Dark_Shikari&amp;gt; r0, r1, r2, r3.&lt;br /&gt;
2010-11-22 00:46:10 &amp;lt; Dark_Shikari&amp;gt; This, of course, includes the r0 used for the parameter.&lt;br /&gt;
2010-11-22 00:46:17 &amp;lt; Dark_Shikari&amp;gt; So in short, after the first line:&lt;br /&gt;
2010-11-22 00:46:19 &amp;lt; Dark_Shikari&amp;gt; r0 = src&lt;br /&gt;
2010-11-22 00:46:22 &amp;lt; Dark_Shikari&amp;gt; r1/r2/r3 = free&lt;br /&gt;
2010-11-22 00:46:26 &amp;lt; Dark_Shikari&amp;gt; r5 and up: can&#039;t use.&lt;br /&gt;
2010-11-22 00:46:37 &amp;lt; Kovensky&amp;gt; that&#039;s x86inc.asm&#039;s doing right?&lt;br /&gt;
2010-11-22 00:46:42 &amp;lt; Dark_Shikari&amp;gt; yes, but we aren&#039;t going into that&lt;br /&gt;
2010-11-22 00:46:58 &amp;lt; Jumpyshoes&amp;gt; i assume it means we can use, but if you do, it&#039;ll screw around with something you don&#039;t want to?&lt;br /&gt;
2010-11-22 00:47:14 &amp;lt; Kovensky&amp;gt; which is why you can&#039;t use it&lt;br /&gt;
2010-11-22 00:47:19 &amp;lt; Dark_Shikari&amp;gt; ^&lt;br /&gt;
2010-11-22 00:47:23 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-22 00:47:31 &amp;lt; Dark_Shikari&amp;gt; So now, this function as you can see has 4 real steps&lt;br /&gt;
2010-11-22 00:47:36 &amp;lt; Dark_Shikari&amp;gt; 1) Sum up A through D&lt;br /&gt;
2010-11-22 00:47:39 &amp;lt; Dark_Shikari&amp;gt; 2) Sum up E through H&lt;br /&gt;
2010-11-22 00:47:46 &amp;lt; Dark_Shikari&amp;gt; 3) Do the math to get our final value&lt;br /&gt;
2010-11-22 00:47:50 &amp;lt; Dark_Shikari&amp;gt; 4) Store it into the 16 output Xs&lt;br /&gt;
2010-11-22 00:47:59 &amp;lt; Dark_Shikari&amp;gt; so let&#039;s see how this asm implements these.&lt;br /&gt;
2010-11-22 00:48:22 &amp;lt; Dark_Shikari&amp;gt; First, we&#039;ll look at step 1)&lt;br /&gt;
2010-11-22 00:48:27 &amp;lt; Dark_Shikari&amp;gt; pxor mm7, mm7: mm7 is now zeroed.&lt;br /&gt;
2010-11-22 00:48:31 &amp;lt; Dark_Shikari&amp;gt; mm7 is a 64-bit register.&lt;br /&gt;
2010-11-22 00:48:36 &amp;lt; Dark_Shikari&amp;gt; xor, as you might know, is a nice way to zero things.&lt;br /&gt;
2010-11-22 00:48:40 &amp;lt; Jumpyshoes&amp;gt; how do you tell how large a register is?&lt;br /&gt;
2010-11-22 00:48:51 &amp;lt; Dark_Shikari&amp;gt; mm* is 64-bit&lt;br /&gt;
2010-11-22 00:48:54 &amp;lt; Dark_Shikari&amp;gt; xmm* is 128-bit&lt;br /&gt;
2010-11-22 00:48:55 &amp;lt; Kovensky&amp;gt; the mm registers have a fixed size&lt;br /&gt;
2010-11-22 00:48:58 &amp;lt; Jumpyshoes&amp;gt; ah, okay&lt;br /&gt;
2010-11-22 00:49:09 &amp;lt; Dark_Shikari&amp;gt; stop me at any point if you are missing something.&lt;br /&gt;
2010-11-22 00:49:13 &amp;lt; Dark_Shikari&amp;gt; so, now mm7 is zero.&lt;br /&gt;
2010-11-22 00:49:20 &amp;lt; Dark_Shikari&amp;gt; movd mm0, [r0-FDEC_STRIDE]&lt;br /&gt;
2010-11-22 00:49:24 &amp;lt; Kovensky&amp;gt; only the general purpose registers are wordsize-dependant on x86&lt;br /&gt;
2010-11-22 00:49:31 &amp;lt; Dark_Shikari&amp;gt; this sets mm0 equal to {A,B,C,D,0,0,0,0}&lt;br /&gt;
2010-11-22 00:49:42 &amp;lt; Jumpyshoes&amp;gt; oh, and how do we know the mm* registers are free?&lt;br /&gt;
2010-11-22 00:49:45 &amp;lt; Dark_Shikari&amp;gt; They always are.&lt;br /&gt;
2010-11-22 00:49:48 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 00:49:50 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-22 00:49:59 &amp;lt; Dark_Shikari&amp;gt; in x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit)&lt;br /&gt;
2010-11-22 00:50:04 &amp;lt; Dark_Shikari&amp;gt; so movd = move doubleword&lt;br /&gt;
2010-11-22 00:50:05 &amp;lt; Dark_Shikari&amp;gt; = move 32 bits&lt;br /&gt;
2010-11-22 00:50:14 &amp;lt; Dark_Shikari&amp;gt; so movd to mm0 will load data to the first 4 bytes&lt;br /&gt;
2010-11-22 00:50:16 &amp;lt; Dark_Shikari&amp;gt; and zero the rest.&lt;br /&gt;
2010-11-22 00:50:20 &amp;lt; Dark_Shikari&amp;gt; thus mm0 is now ABCD0000&lt;br /&gt;
2010-11-22 00:50:32 &amp;lt; Dark_Shikari&amp;gt; [r0-FDEC_STRIDE] is equivalent to *(src-FDEC_STRIDE)&lt;br /&gt;
2010-11-22 00:50:35 &amp;lt; Dark_Shikari&amp;gt; in Cstyle&lt;br /&gt;
2010-11-22 00:50:43 &amp;lt; Dark_Shikari&amp;gt; Hence why it points to ABCD.&lt;br /&gt;
2010-11-22 00:50:56 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-22 00:51:08 &amp;lt; Dark_Shikari&amp;gt; got it so far?&lt;br /&gt;
2010-11-22 00:51:11 &amp;lt; Jumpyshoes&amp;gt; yup&lt;br /&gt;
2010-11-22 00:51:24 &amp;lt; Jumpyshoes&amp;gt; i tried to dabble in asm at some point in time&lt;br /&gt;
2010-11-22 00:51:28 &amp;lt; Jumpyshoes&amp;gt; then got frustrated and gave up&lt;br /&gt;
2010-11-22 00:51:31 &amp;lt; Jumpyshoes&amp;gt; &amp;lt;-- lazy ass&lt;br /&gt;
2010-11-22 00:51:48 &amp;lt; Kovensky&amp;gt; 21:35.33 Dark_Shikari:  A B C D&lt;br /&gt;
2010-11-22 00:51:48 &amp;lt; Kovensky&amp;gt; 21:35.35 Dark_Shikari: E X X X X&lt;br /&gt;
2010-11-22 00:51:48 &amp;lt; Kovensky&amp;gt; are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;&lt;br /&gt;
2010-11-22 00:51:55 &amp;lt; Dark_Shikari&amp;gt; former&lt;br /&gt;
2010-11-22 00:51:58 &amp;lt; Dark_Shikari&amp;gt; your IRC client sucks&lt;br /&gt;
2010-11-22 00:52:00 &amp;lt; Dark_Shikari&amp;gt; your spacing is wrong&lt;br /&gt;
2010-11-22 00:52:11 &amp;lt; jarod&amp;gt; nothing wrong here&lt;br /&gt;
2010-11-22 00:52:13 &amp;lt; Dark_Shikari&amp;gt; use a monospaced font&lt;br /&gt;
2010-11-22 00:52:18 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: next&lt;br /&gt;
2010-11-22 00:52:18 &amp;lt; Kovensky&amp;gt; I&#039;m using osaka-mono&lt;br /&gt;
2010-11-22 00:52:20 &amp;lt; Kovensky&amp;gt; well, whatever&lt;br /&gt;
2010-11-22 00:52:22 &amp;lt; Dark_Shikari&amp;gt; uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
2010-11-22 00:52:23 &amp;lt; Dark_Shikari&amp;gt; {&lt;br /&gt;
2010-11-22 00:52:23 &amp;lt; Dark_Shikari&amp;gt; 	uint16_t sum = 0;&lt;br /&gt;
2010-11-22 00:52:23 &amp;lt; Dark_Shikari&amp;gt; 	for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
2010-11-22 00:52:23 &amp;lt; Dark_Shikari&amp;gt; 		sum += abs(in[i]-out[i]);&lt;br /&gt;
2010-11-22 00:52:25 &amp;lt; Dark_Shikari&amp;gt; 	return sum;&lt;br /&gt;
2010-11-22 00:52:27 &amp;lt; Dark_Shikari&amp;gt; }&lt;br /&gt;
2010-11-22 00:52:33 &amp;lt; Dark_Shikari&amp;gt; that&#039;s what psadbw does&lt;br /&gt;
2010-11-22 00:52:45 &amp;lt; Dark_Shikari&amp;gt; parse that for a moment, and tell me when you&#039;re ready&lt;br /&gt;
2010-11-22 00:53:02 &amp;lt; Jumpyshoes&amp;gt; where is the sum stored?&lt;br /&gt;
2010-11-22 00:53:14 &amp;lt; Kovensky&amp;gt; packed SAD byte words?&lt;br /&gt;
2010-11-22 00:53:26 &amp;lt; Dark_Shikari&amp;gt; psadbw X, Y&lt;br /&gt;
2010-11-22 00:53:30 &amp;lt; Dark_Shikari&amp;gt; X is where the output is stored.&lt;br /&gt;
2010-11-22 00:53:37 &amp;lt; Dark_Shikari&amp;gt; So X is overwritten.&lt;br /&gt;
2010-11-22 00:53:40 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 00:53:43 &amp;lt; Dark_Shikari&amp;gt; so it&#039;s stored in the low 16 bits of X.&lt;br /&gt;
2010-11-22 00:53:59 &amp;lt; Dark_Shikari&amp;gt; now, of course, mm7 is zero!&lt;br /&gt;
2010-11-22 00:54:13 &amp;lt; Dark_Shikari&amp;gt; so we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...&lt;br /&gt;
2010-11-22 00:54:16 &amp;lt; Dark_Shikari&amp;gt; or A+B+C+D.&lt;br /&gt;
2010-11-22 00:54:28 &amp;lt; Dark_Shikari&amp;gt; So after psadbw mm0, mm7, mm0 is A+B+C+D and mm7 is still zero.&lt;br /&gt;
2010-11-22 00:54:30 &amp;lt; Dark_Shikari&amp;gt; Got that?&lt;br /&gt;
2010-11-22 00:54:31 &amp;lt; Jumpyshoes&amp;gt; wow, in three commands&lt;br /&gt;
2010-11-22 00:54:36 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-22 00:54:46 &amp;lt; Kovensky&amp;gt; nice trick&lt;br /&gt;
2010-11-22 00:54:46 &amp;lt; Dark_Shikari&amp;gt; Now, we move the result to &amp;quot;r3d&amp;quot;, a general purpose register&lt;br /&gt;
2010-11-22 00:54:54 &amp;lt; Dark_Shikari&amp;gt; and get moving with part 2) of the algorithm.&lt;br /&gt;
2010-11-22 00:55:03 &amp;lt; Dark_Shikari&amp;gt; Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&lt;br /&gt;
2010-11-22 00:55:13 &amp;lt; Jumpyshoes&amp;gt; is r3d one of the things that come with the 4 registers that are free&amp;gt;.&lt;br /&gt;
2010-11-22 00:55:14 &amp;lt; Jumpyshoes&amp;gt; ?&lt;br /&gt;
2010-11-22 00:55:15 &amp;lt; Dark_Shikari&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes.&lt;br /&gt;
2010-11-22 00:55:20 &amp;lt; Dark_Shikari&amp;gt; So it&#039;s really just r3.&lt;br /&gt;
2010-11-22 00:55:24 &amp;lt; Dark_Shikari&amp;gt; r0, r1, r2, r3 are the 4 that are free.&lt;br /&gt;
2010-11-22 00:55:27 &amp;lt; Dark_Shikari&amp;gt; So we&#039;re using r3.&lt;br /&gt;
2010-11-22 00:55:31 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-22 00:55:36 &amp;lt; Dark_Shikari&amp;gt; So now r0 has our source pointer, and r3 has A+B+C+D.&lt;br /&gt;
2010-11-22 00:55:49 &amp;lt; Dark_Shikari&amp;gt; Now, while the CPU is busy doing that, we&#039;ll go and do part 2), the E+F+G+H.&lt;br /&gt;
2010-11-22 00:55:53 &amp;lt; Kovensky&amp;gt; what does the movzx do?&lt;br /&gt;
2010-11-22 00:55:59 &amp;lt; Dark_Shikari&amp;gt; we&#039;ll get to that&lt;br /&gt;
2010-11-22 00:56:01 &amp;lt; Dark_Shikari&amp;gt; Unfortunately, these bytes aren&#039;t in a straight line.&lt;br /&gt;
2010-11-22 00:56:07 &amp;lt; Dark_Shikari&amp;gt; So we can&#039;t just load EFGH and sad them.&lt;br /&gt;
2010-11-22 00:56:15 &amp;lt; Dark_Shikari&amp;gt; We&#039;ll have to do it the naive/slow way.&lt;br /&gt;
2010-11-22 00:56:26 &amp;lt; Dark_Shikari&amp;gt; well, s/straight line/adjacent in memory/&lt;br /&gt;
2010-11-22 00:56:34 &amp;lt; Kovensky&amp;gt; oh, so %rep is a looping macro&lt;br /&gt;
2010-11-22 00:56:43 &amp;lt; Dark_Shikari&amp;gt; so, now we&#039;re going to load E, F, G, H&lt;br /&gt;
2010-11-22 00:56:48 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 00:56:50 &amp;lt; Dark_Shikari&amp;gt; now you might notice some preprocessor commands here.&lt;br /&gt;
2010-11-22 00:56:57 &amp;lt; Dark_Shikari&amp;gt; %assign, %rep, etc are preprocessor commands&lt;br /&gt;
2010-11-22 00:57:04 &amp;lt; Dark_Shikari&amp;gt; so, first step: load E into r1d&lt;br /&gt;
2010-11-22 00:57:09 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;movzx&amp;quot; means &amp;quot;move, with zero extend&amp;quot;&lt;br /&gt;
2010-11-22 00:57:15 &amp;lt; Dark_Shikari&amp;gt; movzx r1d, byte [r0-1]&lt;br /&gt;
2010-11-22 00:57:20 &amp;lt; Dark_Shikari&amp;gt; in C this would be:&lt;br /&gt;
2010-11-22 00:57:25 &amp;lt; Dark_Shikari&amp;gt; int r1d = r0[-1];&lt;br /&gt;
2010-11-22 00:58:00 &amp;lt; Jumpyshoes&amp;gt; my C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&lt;br /&gt;
2010-11-22 00:58:01 &amp;lt; Dark_Shikari&amp;gt; got that?&lt;br /&gt;
2010-11-22 00:58:07 &amp;lt; Dark_Shikari&amp;gt; *(r0-1)&lt;br /&gt;
2010-11-22 00:58:08 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 00:58:14 &amp;lt; Dark_Shikari&amp;gt; [] is just a dereference of a pointer&lt;br /&gt;
2010-11-22 00:58:23 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 00:58:24 &amp;lt; Dark_Shikari&amp;gt; *(r0-1) = r0[-1] = (r0-1)[0]&lt;br /&gt;
2010-11-22 00:58:51 &amp;lt; Dark_Shikari&amp;gt; So, here&#039;s what these 7 lines look like after the macro runs&lt;br /&gt;
2010-11-22 00:58:53 &amp;lt; Kovensky&amp;gt; what is r0-1 in that ascii matrix?&lt;br /&gt;
2010-11-22 00:59:09 &amp;lt; Dark_Shikari&amp;gt; E.&lt;br /&gt;
2010-11-22 00:59:19 &amp;lt; Dark_Shikari&amp;gt;     movzx  r1d, byte [r0-1]&lt;br /&gt;
2010-11-22 00:59:19 &amp;lt; Dark_Shikari&amp;gt;     movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
2010-11-22 00:59:19 &amp;lt; Dark_Shikari&amp;gt;     add    r1d, r2d&lt;br /&gt;
2010-11-22 00:59:19 &amp;lt; Dark_Shikari&amp;gt;     movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
2010-11-22 00:59:19 &amp;lt; Dark_Shikari&amp;gt;     add    r1d, r2d&lt;br /&gt;
2010-11-22 00:59:21 &amp;lt; Dark_Shikari&amp;gt;     movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
2010-11-22 00:59:24 &amp;lt; Dark_Shikari&amp;gt;     add    r1d, r2d&lt;br /&gt;
2010-11-22 00:59:26 &amp;lt; Dark_Shikari&amp;gt; in order:&lt;br /&gt;
2010-11-22 00:59:29 &amp;lt; Dark_Shikari&amp;gt; load E&lt;br /&gt;
2010-11-22 00:59:31 &amp;lt; Dark_Shikari&amp;gt; load F&lt;br /&gt;
2010-11-22 00:59:34 &amp;lt; Dark_Shikari&amp;gt; add F to E&lt;br /&gt;
2010-11-22 00:59:36 &amp;lt; Dark_Shikari&amp;gt; load G&lt;br /&gt;
2010-11-22 00:59:39 &amp;lt; Dark_Shikari&amp;gt; add G to E&lt;br /&gt;
2010-11-22 00:59:41 &amp;lt; Dark_Shikari&amp;gt; load H&lt;br /&gt;
2010-11-22 00:59:44 &amp;lt; Dark_Shikari&amp;gt; add H to E&lt;br /&gt;
2010-11-22 00:59:47 &amp;lt; Dark_Shikari&amp;gt; any questions about that?&lt;br /&gt;
2010-11-22 01:00:01 &amp;lt; Dark_Shikari&amp;gt; by the way, feel free to ask questions about WHY the code is like that, too, not just why it&#039;s correct.&lt;br /&gt;
2010-11-22 01:00:23 &amp;lt; Jumpyshoes&amp;gt; i&#039;m good so far&lt;br /&gt;
2010-11-22 01:00:29 &amp;lt; Dark_Shikari&amp;gt; ok, now we have to do step 3&lt;br /&gt;
2010-11-22 01:00:36 &amp;lt; Dark_Shikari&amp;gt; calculating A+B+C+D+E+F+G+H+4 &amp;gt;&amp;gt; 3&lt;br /&gt;
2010-11-22 01:00:36 &amp;lt; Jumpyshoes&amp;gt; actually&lt;br /&gt;
2010-11-22 01:00:42 &amp;lt; Jumpyshoes&amp;gt; where is n stored?&lt;br /&gt;
2010-11-22 01:00:46 &amp;lt; Dark_Shikari&amp;gt; it isn&#039;t.&lt;br /&gt;
2010-11-22 01:00:49 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 01:00:53 &amp;lt; Dark_Shikari&amp;gt; It&#039;s a preprocessor variable.&lt;br /&gt;
2010-11-22 01:00:56 &amp;lt; Jumpyshoes&amp;gt; oh, so it&#039;s like a macro?&lt;br /&gt;
2010-11-22 01:00:58 &amp;lt; Dark_Shikari&amp;gt; Yes&lt;br /&gt;
2010-11-22 01:00:59 &amp;lt; Dark_Shikari&amp;gt; It is a macro&lt;br /&gt;
2010-11-22 01:01:00 &amp;lt; Kovensky&amp;gt; yes, it&#039;s a macro&lt;br /&gt;
2010-11-22 01:01:06 &amp;lt; Jumpyshoes&amp;gt; that is handy&lt;br /&gt;
2010-11-22 01:01:07 &amp;lt; Dark_Shikari&amp;gt; Note how I pasted the after-preprocessor code above.&lt;br /&gt;
2010-11-22 01:01:11 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-22 01:01:13 &amp;lt; Jumpyshoes&amp;gt; now i see&lt;br /&gt;
2010-11-22 01:01:14 &amp;lt; Kovensky&amp;gt; everything starting with % in yasm syntax is a macro&lt;br /&gt;
2010-11-22 01:01:14 &amp;lt; Dark_Shikari&amp;gt; No n left.&lt;br /&gt;
2010-11-22 01:01:24 &amp;lt; Dark_Shikari&amp;gt; Now, so let&#039;s do step 3.&lt;br /&gt;
2010-11-22 01:01:31 &amp;lt; Dark_Shikari&amp;gt; lea is the best non-simd opcode in x86&lt;br /&gt;
2010-11-22 01:01:41 &amp;lt; Dark_Shikari&amp;gt; first, let&#039;s go over x86 addressing&lt;br /&gt;
2010-11-22 01:01:45 &amp;lt; Dark_Shikari&amp;gt; what you can put inside the brackets is not infinite.&lt;br /&gt;
2010-11-22 01:01:50 &amp;lt; Dark_Shikari&amp;gt; Here&#039;s the capabilities, specifically:&lt;br /&gt;
2010-11-22 01:02:00 &amp;lt; Dark_Shikari&amp;gt; [REG1 + REG2 * {1,2,4,8} + CONST]&lt;br /&gt;
2010-11-22 01:02:12 &amp;lt; Dark_Shikari&amp;gt; a register, plus another register * 1/2/4/8, plus a constant (positive or negative).&lt;br /&gt;
2010-11-22 01:02:23 &amp;lt; Dark_Shikari&amp;gt; As you might note, this is pretty useful for accessing things like arrays&lt;br /&gt;
2010-11-22 01:02:40 &amp;lt; Dark_Shikari&amp;gt; e.g. array[n+5], where array is an int array, would be&lt;br /&gt;
2010-11-22 01:02:45 &amp;lt; Dark_Shikari&amp;gt; [array + n*4 + 20]&lt;br /&gt;
2010-11-22 01:02:49 &amp;lt; Kovensky&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&lt;br /&gt;
2010-11-22 01:02:49 &amp;lt; Dark_Shikari&amp;gt; got that?&lt;br /&gt;
2010-11-22 01:02:53 &amp;lt; Dark_Shikari&amp;gt; Kovensky: yes&lt;br /&gt;
2010-11-22 01:02:58 &amp;lt; Dark_Shikari&amp;gt; yasm sums up constants for you.&lt;br /&gt;
2010-11-22 01:03:00 &amp;lt; Jumpyshoes&amp;gt; yea, that&#039;s nice&lt;br /&gt;
2010-11-22 01:03:10 &amp;lt; Dark_Shikari&amp;gt; so, as you might note, that&#039;s a pretty powerful addressing system.&lt;br /&gt;
2010-11-22 01:03:16 &amp;lt; Dark_Shikari&amp;gt; That&#039;s more powerful than, say... &amp;quot;add&amp;quot;.&lt;br /&gt;
2010-11-22 01:03:24 &amp;lt; Dark_Shikari&amp;gt; So why not expose it in an instruction to let us use it for math?&lt;br /&gt;
2010-11-22 01:03:26 &amp;lt; Dark_Shikari&amp;gt; So Intel did.&lt;br /&gt;
2010-11-22 01:03:39 &amp;lt; Dark_Shikari&amp;gt; lea X, [expr] sets X equal to the value of expr.&lt;br /&gt;
2010-11-22 01:03:42 &amp;lt; Dark_Shikari&amp;gt; just as fast as add.&lt;br /&gt;
2010-11-22 01:03:55 &amp;lt; Dark_Shikari&amp;gt; so that lea does r1d = r1 + r3 + 4&lt;br /&gt;
2010-11-22 01:04:07 &amp;lt; Jumpyshoes&amp;gt; wait, how does that work?&lt;br /&gt;
2010-11-22 01:04:11 &amp;lt; Dark_Shikari&amp;gt; how does what work&lt;br /&gt;
2010-11-22 01:04:23 &amp;lt; Jumpyshoes&amp;gt; so [] is addressing&lt;br /&gt;
2010-11-22 01:04:28 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 01:04:31 &amp;lt; Kovensky&amp;gt; lea runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first&lt;br /&gt;
2010-11-22 01:04:31 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 01:04:33 &amp;lt; Dark_Shikari&amp;gt; lea doesn&#039;t actually address it&lt;br /&gt;
2010-11-22 01:04:37 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 01:04:40 &amp;lt; Dark_Shikari&amp;gt; It just calculates the result and stores it&lt;br /&gt;
2010-11-22 01:04:42 &amp;lt; Dark_Shikari&amp;gt; instead of going to memory.&lt;br /&gt;
2010-11-22 01:04:46 &amp;lt; Jumpyshoes&amp;gt; and it&#039;s faster than add?&lt;br /&gt;
2010-11-22 01:04:50 &amp;lt; Dark_Shikari&amp;gt; It&#039;s just as fast&lt;br /&gt;
2010-11-22 01:04:53 &amp;lt; Dark_Shikari&amp;gt; Except that you can do more with it.&lt;br /&gt;
2010-11-22 01:04:58 &amp;lt; Kovensky&amp;gt; faster since you&#039;re doing 3 sums in one&lt;br /&gt;
2010-11-22 01:05:02 &amp;lt; Kovensky&amp;gt; if you look it that way&lt;br /&gt;
2010-11-22 01:05:04 &amp;lt; Jumpyshoes&amp;gt; o&lt;br /&gt;
2010-11-22 01:05:05 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-22 01:05:06 &amp;lt; Kovensky&amp;gt; but cyclewise it&#039;s the same speed&lt;br /&gt;
2010-11-22 01:05:06 &amp;lt; Dark_Shikari&amp;gt; now, technically, you can do more adds per cycle than lea, so you shouldn&#039;t go replacing all your adds with lea&lt;br /&gt;
2010-11-22 01:05:14 &amp;lt; Kovensky&amp;gt; hm&lt;br /&gt;
2010-11-22 01:05:17 &amp;lt; Dark_Shikari&amp;gt; But if you can use it to do more than one thing at a time, it&#039;s a big win.&lt;br /&gt;
2010-11-22 01:05:26 &amp;lt; Dark_Shikari&amp;gt; So this lets us add r3, and add 4, in one op.&lt;br /&gt;
2010-11-22 01:05:31 &amp;lt; Dark_Shikari&amp;gt; Got that&lt;br /&gt;
2010-11-22 01:05:31 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-22 01:05:33 &amp;lt; Jumpyshoes&amp;gt; yup&lt;br /&gt;
2010-11-22 01:05:43 &amp;lt; Dark_Shikari&amp;gt; now shr r1d, 3: there&#039;s one that you can probably figure out yourself ;)&lt;br /&gt;
2010-11-22 01:06:01 &amp;lt; Sean_McG&amp;gt; hm, shift halfword right?&lt;br /&gt;
2010-11-22 01:06:05 &amp;lt; Dark_Shikari&amp;gt; just shift right&lt;br /&gt;
2010-11-22 01:06:14 &amp;lt; Jumpyshoes&amp;gt; handy&lt;br /&gt;
2010-11-22 01:06:18 &amp;lt; Jumpyshoes&amp;gt; why are we doing this?&lt;br /&gt;
2010-11-22 01:06:25 &amp;lt; Dark_Shikari&amp;gt; doing what&lt;br /&gt;
2010-11-22 01:06:28 &amp;lt; Jumpyshoes&amp;gt; shifting right&lt;br /&gt;
2010-11-22 01:06:32 &amp;lt; Kovensky&amp;gt; it&#039;s part of the &amp;gt;&amp;gt;3 in the equation he gave during the description&lt;br /&gt;
2010-11-22 01:06:37 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 01:06:39 &amp;lt; Kovensky&amp;gt; &amp;gt;&amp;gt;3 = /(2^3) = /8&lt;br /&gt;
2010-11-22 01:06:50 &amp;lt; Dark_Shikari&amp;gt; DC prediction consists of averaging the pixels surrounding the block&lt;br /&gt;
2010-11-22 01:06:52 &amp;lt; Dark_Shikari&amp;gt; using correct rounding&lt;br /&gt;
2010-11-22 01:06:57 &amp;lt; Dark_Shikari&amp;gt; and then filling in the block with the result&lt;br /&gt;
2010-11-22 01:07:04 &amp;lt; Dark_Shikari&amp;gt; hence A+B+C+D+E+F+G+H+4 &amp;gt;&amp;gt; 3&lt;br /&gt;
2010-11-22 01:07:08 &amp;lt; Dark_Shikari&amp;gt; +4 for correct rounding&lt;br /&gt;
2010-11-22 01:07:10 &amp;lt; Dark_Shikari&amp;gt;  &amp;gt;&amp;gt; 3 to divide&lt;br /&gt;
2010-11-22 01:07:17 &amp;lt; Jumpyshoes&amp;gt; smart&lt;br /&gt;
2010-11-22 01:07:25 &amp;lt; Dark_Shikari&amp;gt; now for the final part: storing the results&lt;br /&gt;
2010-11-22 01:07:28 &amp;lt; Kovensky&amp;gt; the same trick as adding +0.5 to a float so you get it rounded when you cast to integer&lt;br /&gt;
2010-11-22 01:07:37 &amp;lt; Dark_Shikari&amp;gt; imul r1d, 0x01010101&lt;br /&gt;
2010-11-22 01:07:42 &amp;lt; Dark_Shikari&amp;gt; this is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well&lt;br /&gt;
2010-11-22 01:07:48 &amp;lt; Kovensky&amp;gt; splat? lol&lt;br /&gt;
2010-11-22 01:07:48 &amp;lt; Dark_Shikari&amp;gt; we&#039;re turning an 8-bit value into 4x that value&lt;br /&gt;
2010-11-22 01:07:51 &amp;lt; Dark_Shikari&amp;gt; e.g. A -&amp;gt; AAAAA&lt;br /&gt;
2010-11-22 01:07:55 &amp;lt; Dark_Shikari&amp;gt; er, AAAA&lt;br /&gt;
2010-11-22 01:07:58 &amp;lt; Jumpyshoes&amp;gt; i have never seen this before&lt;br /&gt;
2010-11-22 01:08:08 &amp;lt; Jumpyshoes&amp;gt; how does this work?&lt;br /&gt;
2010-11-22 01:08:09 &amp;lt; Dark_Shikari&amp;gt; so now we have a 32-bit register (r1d) with one copy of A in each 8-bit nibble of that register.&lt;br /&gt;
2010-11-22 01:08:15 &amp;lt; Jumpyshoes&amp;gt; oh nevermind, i get it&lt;br /&gt;
2010-11-22 01:08:17 &amp;lt; Dark_Shikari&amp;gt; A * 0x01010101 = A A A A&lt;br /&gt;
2010-11-22 01:08:30 &amp;lt; Dark_Shikari&amp;gt; Now we go ahead and store this 4 times.&lt;br /&gt;
2010-11-22 01:08:35 &amp;lt; Dark_Shikari&amp;gt; And we&#039;re done.&lt;br /&gt;
2010-11-22 01:08:47 &amp;lt; Jumpyshoes&amp;gt; woah&lt;br /&gt;
2010-11-22 01:08:51 &amp;lt; Dark_Shikari&amp;gt; Finally, we RET: x264 will automatically clean up after us.&lt;br /&gt;
2010-11-22 01:09:03 &amp;lt; Kovensky&amp;gt; emms is only needed on sse code, right?&lt;br /&gt;
2010-11-22 01:09:04 &amp;lt; Jumpyshoes&amp;gt; how much faster is this in asm than C?&lt;br /&gt;
2010-11-22 01:09:10 &amp;lt; Dark_Shikari&amp;gt; Not much.&lt;br /&gt;
2010-11-22 01:09:14 &amp;lt; Dark_Shikari&amp;gt; The only reason it&#039;s faster is psadbw.&lt;br /&gt;
2010-11-22 01:09:23 &amp;lt; Dark_Shikari&amp;gt; Everything else is something GCC can do with properly written C.&lt;br /&gt;
2010-11-22 01:09:34 &amp;lt; Dark_Shikari&amp;gt; I use it as an example because it&#039;s simple, and it mixes a lot of ideas in one function.&lt;br /&gt;
2010-11-22 01:09:38 &amp;lt; Dark_Shikari&amp;gt; well, as a first example.&lt;br /&gt;
2010-11-22 01:09:44 &amp;lt; Jumpyshoes&amp;gt; it does&lt;br /&gt;
2010-11-22 01:09:57 &amp;lt; Jumpyshoes&amp;gt; so what&#039;s the point of having it in asm if it&#039;s only slightly faster?&lt;br /&gt;
2010-11-22 01:09:57 &amp;lt; Dark_Shikari&amp;gt; It&#039;s probably 2-3 clocks faster at most.&lt;br /&gt;
2010-11-22 01:10:00 &amp;lt; Dark_Shikari&amp;gt; Because we can.&lt;br /&gt;
2010-11-22 01:10:02 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-22 01:10:06 &amp;lt; Jumpyshoes&amp;gt; of course&lt;br /&gt;
2010-11-22 01:10:09 &amp;lt; Jumpyshoes&amp;gt; this is open source&lt;br /&gt;
2010-11-22 01:10:12 &amp;lt; Dark_Shikari&amp;gt; Because it probably took 5 minutes to write.&lt;br /&gt;
2010-11-22 01:10:17 &amp;lt; Kovensky&amp;gt; isn&#039;t that a function that&#039;s called multiple times per frame too?&lt;br /&gt;
2010-11-22 01:10:22 &amp;lt; Dark_Shikari&amp;gt; Kovensky: understatement&lt;br /&gt;
2010-11-22 01:10:29 &amp;lt; Dark_Shikari&amp;gt; and this function only takes like 10 clocks&lt;br /&gt;
2010-11-22 01:10:33 &amp;lt; Dark_Shikari&amp;gt; so saving 2 clocks is kind of meaningful there&lt;br /&gt;
2010-11-22 01:10:34 &amp;lt; Dark_Shikari&amp;gt; (relatively)&lt;br /&gt;
2010-11-22 01:10:42 &amp;lt; Kovensky&amp;gt; then yea, I guess 3 clocks per MB on a really hot function is worth it =p&lt;br /&gt;
2010-11-22 01:10:53 &amp;lt; Dark_Shikari&amp;gt; anyways, that&#039;s a simple one.  Let&#039;s go on to some other concepts.&lt;br /&gt;
2010-11-22 01:11:06 &amp;lt; Dark_Shikari&amp;gt; Throw any questions you ahve at me about this before we go.&lt;br /&gt;
2010-11-22 01:11:34 &amp;lt; Jumpyshoes&amp;gt; are the preprocessor marcos in yasm or x264?&lt;br /&gt;
2010-11-22 01:11:43 &amp;lt; Jumpyshoes&amp;gt; (also brb 1 minute)&lt;br /&gt;
2010-11-22 01:11:49 &amp;lt; Dark_Shikari&amp;gt; x264 has its own macro system written in yasm&lt;br /&gt;
2010-11-22 01:11:49 &amp;lt; Kovensky&amp;gt; they&#039;re in yasm&lt;br /&gt;
2010-11-22 01:11:56 &amp;lt; Dark_Shikari&amp;gt; which handles stuff like arguments, pushing and popping of registers&lt;br /&gt;
2010-11-22 01:12:00 &amp;lt; Dark_Shikari&amp;gt; and many more things which we will see soon&lt;br /&gt;
2010-11-22 01:12:03 &amp;lt; Dark_Shikari&amp;gt; we call this &amp;quot;x264asm&amp;quot;&lt;br /&gt;
2010-11-22 01:12:07 &amp;lt; Dark_Shikari&amp;gt; ffmpeg also uses this.&lt;br /&gt;
2010-11-22 01:12:14 &amp;lt; Kovensky&amp;gt; wasn&#039;t it &amp;quot;pengvado asm&amp;quot;? :&amp;gt;&lt;br /&gt;
2010-11-22 01:12:19 &amp;lt; Dark_Shikari&amp;gt; It&#039;s under a BSD license, so anyone in any project can and should use it to make their life less painful.&lt;br /&gt;
2010-11-22 01:12:34 &amp;lt; Kovensky&amp;gt; or did you rename to &amp;quot;x264asm&amp;quot; after &amp;quot;pasm&amp;quot; was already taken? :p&lt;br /&gt;
2010-11-22 01:12:47 &amp;lt; Dark_Shikari&amp;gt; bugmaster also wrote some of it&lt;br /&gt;
2010-11-22 01:13:12 &amp;lt; Dark_Shikari&amp;gt; ok brb I&#039;m grabbing some food&lt;br /&gt;
2010-11-22 01:13:18 &amp;lt; Kovensky&amp;gt; right, the win64 part&lt;br /&gt;
2010-11-22 01:14:12 &amp;lt; Jumpyshoes&amp;gt; okay back&lt;br /&gt;
2010-11-22 01:14:15 &amp;lt; Jumpyshoes&amp;gt; whenever you&#039;re ready&lt;br /&gt;
2010-11-22 01:15:13 &amp;lt; Jumpyshoes&amp;gt; i wonder how much of this i will retain&lt;br /&gt;
2010-11-22 01:15:35 &amp;lt; j0sh&amp;gt; is this room logged somewhere?&lt;br /&gt;
2010-11-22 01:15:44 &amp;lt; Jumpyshoes&amp;gt; well, my hard drive&lt;br /&gt;
2010-11-22 01:15:59 &amp;lt; Kovensky&amp;gt; I have logs since ~2008 I think&lt;br /&gt;
2010-11-22 01:18:43 &amp;lt; Dark_Shikari&amp;gt; pengvado logs this&lt;br /&gt;
2010-11-22 01:18:52 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: you don&#039;t need to retain individual instructions etc, you can look those up&lt;br /&gt;
2010-11-22 01:18:59 &amp;lt; Dark_Shikari&amp;gt; ok, next&lt;br /&gt;
2010-11-22 01:19:03 &amp;lt; Dark_Shikari&amp;gt; you may have noticed that psadbw is fucking awesome.&lt;br /&gt;
2010-11-22 01:19:18 &amp;lt; Jumpyshoes&amp;gt; it does like 8 things in one&lt;br /&gt;
2010-11-22 01:19:22 &amp;lt; Dark_Shikari&amp;gt; abs() is typically 4 instructions on x86&lt;br /&gt;
2010-11-22 01:19:24 &amp;lt; Kovensky&amp;gt; 22:18.52 Dark_Shikari: Jumpyshoes: you don&#039;t need to retain individual instructions etc, you can look those up &amp;lt;-- indeed; you just need to know they exist so you know to look them up =p&lt;br /&gt;
2010-11-22 01:19:33 &amp;lt; Dark_Shikari&amp;gt; psadbw does 8 subtracts&lt;br /&gt;
2010-11-22 01:19:34 &amp;lt; Jumpyshoes&amp;gt; o&lt;br /&gt;
2010-11-22 01:19:36 &amp;lt; Dark_Shikari&amp;gt; 8 absolute values on those results&lt;br /&gt;
2010-11-22 01:19:40 &amp;lt; Dark_Shikari&amp;gt; and then adds them up&lt;br /&gt;
2010-11-22 01:19:45 &amp;lt; Dark_Shikari&amp;gt; that&#039;s 8 + 32 + 7&lt;br /&gt;
2010-11-22 01:19:46 &amp;lt; Jumpyshoes&amp;gt; that&#039;s a lot&lt;br /&gt;
2010-11-22 01:19:48 &amp;lt; Dark_Shikari&amp;gt; 47 instructions in one&lt;br /&gt;
2010-11-22 01:19:51 &amp;lt; Jumpyshoes&amp;gt; why is abs so slow?&lt;br /&gt;
2010-11-22 01:19:51 &amp;lt; Dark_Shikari&amp;gt; (at least, 47 equivalent)&lt;br /&gt;
2010-11-22 01:19:57 &amp;lt; Dark_Shikari&amp;gt; abs isn&#039;t slow, there&#039;s just no instructin for it&lt;br /&gt;
2010-11-22 01:20:00 &amp;lt; Dark_Shikari&amp;gt; the typical algorithm is&lt;br /&gt;
2010-11-22 01:20:03 &amp;lt; Dark_Shikari&amp;gt; int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
2010-11-22 01:20:14 &amp;lt; Dark_Shikari&amp;gt; (x ^ sign) - sign;&lt;br /&gt;
2010-11-22 01:20:20 &amp;lt; Dark_Shikari&amp;gt; this needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
2010-11-22 01:20:33 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 01:20:46 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 01:20:47 &amp;lt; Dark_Shikari&amp;gt; So psadbw is pretty awesome.&lt;br /&gt;
2010-11-22 01:20:52 &amp;lt; Jumpyshoes&amp;gt; indeed&lt;br /&gt;
2010-11-22 01:20:53 &amp;lt; Dark_Shikari&amp;gt; It&#039;s very awesome for doing what its name implies you should do with it&lt;br /&gt;
2010-11-22 01:20:56 &amp;lt; Dark_Shikari&amp;gt; That is -- SADs&lt;br /&gt;
2010-11-22 01:20:58 &amp;lt; Dark_Shikari&amp;gt; sum of absolute differences&lt;br /&gt;
2010-11-22 01:21:05 &amp;lt; Dark_Shikari&amp;gt; so let&#039;s open sad-a.asm and hop down to line 95&lt;br /&gt;
2010-11-22 01:21:17 &amp;lt; Dark_Shikari&amp;gt; also open common/pixel.c and look at the first function: SAD&lt;br /&gt;
2010-11-22 01:21:23 &amp;lt; Dark_Shikari&amp;gt; This function is pretty simple.  You should be able to see how it works.&lt;br /&gt;
2010-11-22 01:21:29 &amp;lt; Dark_Shikari&amp;gt; If you have any questions about its details, ask (the C, not the asm)&lt;br /&gt;
2010-11-22 01:21:36 &amp;lt; Dark_Shikari&amp;gt; look only at the C for now.&lt;br /&gt;
2010-11-22 01:21:51 &amp;lt; Jumpyshoes&amp;gt; pixel_sad_%1x%2_mmxext &amp;lt;-- you can have % in function names?&lt;br /&gt;
2010-11-22 01:21:57 &amp;lt; Dark_Shikari&amp;gt; We&#039;ll get to that.&lt;br /&gt;
2010-11-22 01:22:35 &amp;lt; Dark_Shikari&amp;gt; so as you&#039;ll notice, the C SAD has 7 different versions&lt;br /&gt;
2010-11-22 01:22:40 &amp;lt; Dark_Shikari&amp;gt; for 16x16, 16x8, 8x16...&lt;br /&gt;
2010-11-22 01:22:45 &amp;lt; Dark_Shikari&amp;gt; and it&#039;s instantiated via a macro.&lt;br /&gt;
2010-11-22 01:23:18 &amp;lt; Jumpyshoes&amp;gt; okay, so for the C function&lt;br /&gt;
2010-11-22 01:23:25 &amp;lt; Jumpyshoes&amp;gt; how do you pass the pix1 and i_stride_pix1 arguments?&lt;br /&gt;
2010-11-22 01:23:33 &amp;lt; Dark_Shikari&amp;gt; One&#039;s a pointer, one&#039;s the stride.&lt;br /&gt;
2010-11-22 01:23:35 &amp;lt; Dark_Shikari&amp;gt; They&#039;re just normal params.&lt;br /&gt;
2010-11-22 01:23:52 &amp;lt; Dark_Shikari&amp;gt; the function has 4 parameters: two sources, two strides.&lt;br /&gt;
2010-11-22 01:23:59 &amp;lt; Jumpyshoes&amp;gt; i mean, the define only has 3 parameters&lt;br /&gt;
2010-11-22 01:24:03 &amp;lt; Kovensky&amp;gt; they come from image data&lt;br /&gt;
2010-11-22 01:24:08 &amp;lt; Dark_Shikari&amp;gt; The define is defining things that ARENT parameters.&lt;br /&gt;
2010-11-22 01:24:21 &amp;lt; Dark_Shikari&amp;gt; the name of the function&lt;br /&gt;
2010-11-22 01:24:23 &amp;lt; Dark_Shikari&amp;gt; the width, and the height&lt;br /&gt;
2010-11-22 01:24:25 &amp;lt; Kovensky&amp;gt; yes, the define just defines the name and the length of the sad&lt;br /&gt;
2010-11-22 01:24:27 &amp;lt; Dark_Shikari&amp;gt; all those are HARDCODED upon compile time&lt;br /&gt;
2010-11-22 01:24:34 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 01:24:35 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 01:24:36 &amp;lt; Dark_Shikari&amp;gt; into 7 different versions of the function&lt;br /&gt;
2010-11-22 01:24:38 &amp;lt; Dark_Shikari&amp;gt; with 7 different names.&lt;br /&gt;
2010-11-22 01:24:50 &amp;lt; Jumpyshoes&amp;gt; right, i see&lt;br /&gt;
2010-11-22 01:25:06 &amp;lt; Dark_Shikari&amp;gt; so, for our asm, we also need 7 versions&lt;br /&gt;
2010-11-22 01:25:07 &amp;lt; Jumpyshoes&amp;gt; i haven&#039;t used defines extensively before, so you might get more stupid questions&lt;br /&gt;
2010-11-22 01:25:13 &amp;lt; Dark_Shikari&amp;gt; that&#039;s fine, no such thing as stupid questions&lt;br /&gt;
2010-11-22 01:25:19 &amp;lt; Dark_Shikari&amp;gt; and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
2010-11-22 01:25:21 &amp;lt; j0sh&amp;gt; only stupid mistakes :)&lt;br /&gt;
2010-11-22 01:25:28 &amp;lt; Dark_Shikari&amp;gt; so in the asm, we define a macro&lt;br /&gt;
2010-11-22 01:25:30 &amp;lt; Dark_Shikari&amp;gt; %macro SAD 2&lt;br /&gt;
2010-11-22 01:25:30 &amp;lt; Kovensky&amp;gt; better than not ask and misunderstand everything&lt;br /&gt;
2010-11-22 01:25:35 &amp;lt; Dark_Shikari&amp;gt; that means this macro has two paremeters.&lt;br /&gt;
2010-11-22 01:25:43 &amp;lt; Jumpyshoes&amp;gt; oh, %1 and %2?&lt;br /&gt;
2010-11-22 01:25:45 &amp;lt; Dark_Shikari&amp;gt; They are accessed as %1 and %2.&lt;br /&gt;
2010-11-22 01:25:53 &amp;lt; Dark_Shikari&amp;gt; we call the macro 7 times, one for each size.&lt;br /&gt;
2010-11-22 01:26:33 &amp;lt; Dark_Shikari&amp;gt; the function takes 4 args (as you&#039;d expect)&lt;br /&gt;
2010-11-22 01:26:36 &amp;lt; Dark_Shikari&amp;gt; and needs 4 regs (just the args)&lt;br /&gt;
2010-11-22 01:26:41 &amp;lt; Jumpyshoes&amp;gt; and SAD_INC_2x%1P is another macro?&lt;br /&gt;
2010-11-22 01:26:46 &amp;lt; Dark_Shikari&amp;gt; Yes, it&#039;s one of three macros&lt;br /&gt;
2010-11-22 01:26:47 &amp;lt; Dark_Shikari&amp;gt; look above&lt;br /&gt;
2010-11-22 01:26:53 &amp;lt; Dark_Shikari&amp;gt; each one does 2 rows worth of SAD&lt;br /&gt;
2010-11-22 01:26:56 &amp;lt; Jumpyshoes&amp;gt; oh, cool&lt;br /&gt;
2010-11-22 01:26:57 &amp;lt; Dark_Shikari&amp;gt; for width 4, width 8, and width 16.&lt;br /&gt;
2010-11-22 01:27:02 &amp;lt; Dark_Shikari&amp;gt; so it picks the right one based on the width&lt;br /&gt;
2010-11-22 01:27:07 &amp;lt; Dark_Shikari&amp;gt; and it %reps it based on the height&lt;br /&gt;
2010-11-22 01:27:10 &amp;lt; Kovensky&amp;gt; punpckldq &amp;lt;-- cute instruction name&lt;br /&gt;
2010-11-22 01:27:34 &amp;lt; Dark_Shikari&amp;gt; now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.&lt;br /&gt;
2010-11-22 01:27:37 &amp;lt; Dark_Shikari&amp;gt; ask questions.&lt;br /&gt;
2010-11-22 01:27:53 &amp;lt; Dark_Shikari&amp;gt; note mm0 is the accumulator&lt;br /&gt;
2010-11-22 01:27:56 &amp;lt; Dark_Shikari&amp;gt; which is why it&#039;s zeroed at the start.&lt;br /&gt;
2010-11-22 01:27:58 &amp;lt; Jumpyshoes&amp;gt; the order of args is the same as in the C function?&lt;br /&gt;
2010-11-22 01:28:01 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 01:28:04 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-22 01:28:20 &amp;lt; Jumpyshoes&amp;gt; what does punpckldq do?&lt;br /&gt;
2010-11-22 01:28:24 &amp;lt; Kovensky&amp;gt; ^&lt;br /&gt;
2010-11-22 01:28:30 &amp;lt; Dark_Shikari&amp;gt; good question!&lt;br /&gt;
2010-11-22 01:28:39 &amp;lt; Dark_Shikari&amp;gt; punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
2010-11-22 01:28:47 &amp;lt; Dark_Shikari&amp;gt; to start with, it can be l or h&lt;br /&gt;
2010-11-22 01:28:48 &amp;lt; Dark_Shikari&amp;gt; low or high&lt;br /&gt;
2010-11-22 01:29:01 &amp;lt; Dark_Shikari&amp;gt; so punpckl__ ABCD, EFGH will use AB and EF.&lt;br /&gt;
2010-11-22 01:29:07 &amp;lt; Dark_Shikari&amp;gt; And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
2010-11-22 01:29:19 &amp;lt; Kovensky&amp;gt; hurf, little endian&lt;br /&gt;
2010-11-22 01:29:20 &amp;lt; Dark_Shikari&amp;gt; the next two letters are the source size, and destination size.&lt;br /&gt;
2010-11-22 01:29:26 &amp;lt; Dark_Shikari&amp;gt; for example, punpcklbw interleaves bytes, to create words.&lt;br /&gt;
2010-11-22 01:29:36 &amp;lt; Dark_Shikari&amp;gt; So punpcklbw ABCD, EFGH gives you AEBF.&lt;br /&gt;
2010-11-22 01:29:51 &amp;lt; Jumpyshoes&amp;gt; oh, okay&lt;br /&gt;
2010-11-22 01:29:53 &amp;lt; Dark_Shikari&amp;gt; if the letters are bytes.&lt;br /&gt;
2010-11-22 01:30:07 &amp;lt; Dark_Shikari&amp;gt; so punpckldq ABCDEFGH, IJKLMNOP&lt;br /&gt;
2010-11-22 01:30:12 &amp;lt; Dark_Shikari&amp;gt; gives us ABCDIJKL&lt;br /&gt;
2010-11-22 01:30:23 &amp;lt; Dark_Shikari&amp;gt; so in other words, it stuffs the two sets of 4 bytes we just loaded into one register.&lt;br /&gt;
2010-11-22 01:30:26 &amp;lt; Dark_Shikari&amp;gt; So we can do only one SAD, instead of two.&lt;br /&gt;
2010-11-22 01:30:43 &amp;lt; Dark_Shikari&amp;gt; punpcklbw ABCD0000, EFGH0000 --&amp;gt; ABCDEFGH&lt;br /&gt;
2010-11-22 01:30:47 &amp;lt; Dark_Shikari&amp;gt; er, punpckldq&lt;br /&gt;
2010-11-22 01:31:02 &amp;lt; Dark_Shikari&amp;gt; so it effectively concatenates mm1 and mm2 for us.&lt;br /&gt;
2010-11-22 01:31:16 &amp;lt; Dark_Shikari&amp;gt; if we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.&lt;br /&gt;
2010-11-22 01:31:42 &amp;lt; Dark_Shikari&amp;gt; we do this because the registers are width 8, but our sad is width 4.&lt;br /&gt;
2010-11-22 01:31:50 &amp;lt; Dark_Shikari&amp;gt; So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
2010-11-22 01:32:31 &amp;lt; Jumpyshoes&amp;gt; why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
2010-11-22 01:32:41 &amp;lt; Jumpyshoes&amp;gt; oh wait, nevermind&lt;br /&gt;
2010-11-22 01:32:59 &amp;lt; Dark_Shikari&amp;gt; we&#039;re concatenating row 0 and row 1&lt;br /&gt;
2010-11-22 01:33:02 &amp;lt; Dark_Shikari&amp;gt; of each input.&lt;br /&gt;
2010-11-22 01:33:06 &amp;lt; Kovensky&amp;gt; so the punpckldq does mm1 = mm1 &amp;amp; 0xFFFF&amp;lt;&amp;lt;16 | [src+stride]&amp;gt;&amp;gt;16?&lt;br /&gt;
2010-11-22 01:33:30 &amp;lt; Dark_Shikari&amp;gt; no, each input is 32 bits&lt;br /&gt;
2010-11-22 01:33:30 &amp;lt; Dark_Shikari&amp;gt; not 16&lt;br /&gt;
2010-11-22 01:33:38 &amp;lt; Kovensky&amp;gt; orz&lt;br /&gt;
2010-11-22 01:33:40 &amp;lt; Dark_Shikari&amp;gt; low 32 of src1, low 32 of src2, combine to make 64 bit output&lt;br /&gt;
2010-11-22 01:33:44 &amp;lt; Kovensky&amp;gt; it&#039;s the same idea though right?&lt;br /&gt;
2010-11-22 01:33:59 &amp;lt; Dark_Shikari&amp;gt; not really, it doesn&#039;t right shift anything&lt;br /&gt;
2010-11-22 01:34:14 &amp;lt; Kovensky&amp;gt; hm&lt;br /&gt;
2010-11-22 01:34:18 &amp;lt; Kovensky&amp;gt; me failing at bit math here&lt;br /&gt;
2010-11-22 01:34:28 &amp;lt; Jumpyshoes&amp;gt; lea     r0,     [r0+2*r1] &amp;lt;-- why are we doing this step?&lt;br /&gt;
2010-11-22 01:34:42 &amp;lt; Jumpyshoes&amp;gt; doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
2010-11-22 01:34:49 &amp;lt; Dark_Shikari&amp;gt; btw Jumpyshoes http://alien.dowling.edu/~rohit/nasmdocb.html&lt;br /&gt;
2010-11-22 01:34:59 &amp;lt; Jumpyshoes&amp;gt; and change the arg?&lt;br /&gt;
2010-11-22 01:34:59 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: we&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
2010-11-22 01:35:12 &amp;lt; Jumpyshoes&amp;gt; does the C code do that?&lt;br /&gt;
2010-11-22 01:35:13 &amp;lt; Kovensky&amp;gt; you can do whatever you want with the arc&lt;br /&gt;
2010-11-22 01:35:14 &amp;lt; Kovensky&amp;gt; arg*&lt;br /&gt;
2010-11-22 01:35:21 &amp;lt; Jumpyshoes&amp;gt; oh, the rep&lt;br /&gt;
2010-11-22 01:36:02 &amp;lt; Jumpyshoes&amp;gt; okay, i get what SAD_INC_2x4P&lt;br /&gt;
2010-11-22 01:36:03 &amp;lt; Jumpyshoes&amp;gt; woohoo&lt;br /&gt;
2010-11-22 01:36:11 &amp;lt; Dark_Shikari&amp;gt; the others work similarly&lt;br /&gt;
2010-11-22 01:36:15 &amp;lt; Dark_Shikari&amp;gt; except without the punpck magic&lt;br /&gt;
2010-11-22 01:36:17 &amp;lt; Dark_Shikari&amp;gt; because they don&#039;t need it.&lt;br /&gt;
2010-11-22 01:36:35 &amp;lt; Jumpyshoes&amp;gt; wait, why is the lea out of order in SAD_INC_2x8P?&lt;br /&gt;
2010-11-22 01:36:43 &amp;lt; Jumpyshoes&amp;gt; by out of order i mean not next to each other&lt;br /&gt;
2010-11-22 01:36:44 &amp;lt; Kovensky&amp;gt; I&#039;m still finishing 2x4...&lt;br /&gt;
2010-11-22 01:36:46 &amp;lt; Dark_Shikari&amp;gt; No particular reason.&lt;br /&gt;
2010-11-22 01:36:50 &amp;lt; Kovensky&amp;gt; k, got it&lt;br /&gt;
2010-11-22 01:36:52 &amp;lt; Jumpyshoes&amp;gt; oh, okay&lt;br /&gt;
2010-11-22 01:38:10 &amp;lt; Dark_Shikari&amp;gt; http://alien.dowling.edu/~rohit/nasmdocb.html have this open in another window for reference&lt;br /&gt;
2010-11-22 01:38:13 &amp;lt; Dark_Shikari&amp;gt; very very useful&lt;br /&gt;
2010-11-22 01:38:19 &amp;lt; Jumpyshoes&amp;gt; yea, have it open&lt;br /&gt;
2010-11-22 01:38:37 &amp;lt; Jumpyshoes&amp;gt; so we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
2010-11-22 01:39:03 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 01:39:03 &amp;lt; Kovensky&amp;gt; well, the SADs work in two rows at a time&lt;br /&gt;
2010-11-22 01:39:08 &amp;lt; Dark_Shikari&amp;gt; so if it&#039;s height 8&lt;br /&gt;
2010-11-22 01:39:10 &amp;lt; Dark_Shikari&amp;gt; we rep it 4 times&lt;br /&gt;
2010-11-22 01:39:12 &amp;lt; Dark_Shikari&amp;gt; 4*2 = 8&lt;br /&gt;
2010-11-22 01:39:13 &amp;lt; Kovensky&amp;gt; so you just need to do for rows/2 times&lt;br /&gt;
2010-11-22 01:39:24 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 01:39:40 &amp;lt; Kovensky&amp;gt; I dunno if I understood 2x8 / 2x16 or not; I have no questions about them but I also doubt that I&#039;ll remember this after a day&lt;br /&gt;
2010-11-22 01:39:51 &amp;lt; Jumpyshoes&amp;gt; movq    mm2,    [r0+8] &amp;lt;-- why are we adding the 8?&lt;br /&gt;
2010-11-22 01:40:03 &amp;lt; Jumpyshoes&amp;gt; if it&#039;s movq&lt;br /&gt;
2010-11-22 01:40:20 &amp;lt; Kovensky&amp;gt; Jumpyshoes: because it&#039;s working now on 2 &amp;quot;columns&amp;quot; of 8 bytes each&lt;br /&gt;
2010-11-22 01:40:31 &amp;lt; Jumpyshoes&amp;gt; oh, right&lt;br /&gt;
2010-11-22 01:40:37 &amp;lt; Kovensky&amp;gt; Dark_Shikari: why are strides not hardcoded btw?&lt;br /&gt;
2010-11-22 01:41:05 &amp;lt; Dark_Shikari&amp;gt; Kovensky: SAD can be called on a reference frame&lt;br /&gt;
2010-11-22 01:41:08 &amp;lt; Dark_Shikari&amp;gt; thus variable stride&lt;br /&gt;
2010-11-22 01:41:37 &amp;lt; Kovensky&amp;gt; I don&#039;t really get it but then I&#039;d have to study more of x264 to know the reference frame memory layout&lt;br /&gt;
2010-11-22 01:41:47 &amp;lt; Kovensky&amp;gt; oh wait&lt;br /&gt;
2010-11-22 01:41:50 &amp;lt; Kovensky&amp;gt; I got it now lol&lt;br /&gt;
2010-11-22 01:41:54 &amp;lt; Dark_Shikari&amp;gt; it&#039;s called on frames, as opposed to some temporary block of memory =p&lt;br /&gt;
2010-11-22 01:42:26 &amp;lt; Jumpyshoes&amp;gt; okay, i think i understand the SAD_INC_* functions now&lt;br /&gt;
2010-11-22 01:42:31 &amp;lt; Dark_Shikari&amp;gt; now, for the kicker&lt;br /&gt;
2010-11-22 01:42:33 &amp;lt; Jumpyshoes&amp;gt; and the SAD&lt;br /&gt;
2010-11-22 01:42:41 &amp;lt; Dark_Shikari&amp;gt; the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
2010-11-22 01:42:45 &amp;lt; Jumpyshoes&amp;gt; wat&lt;br /&gt;
2010-11-22 01:43:13 &amp;lt; Jumpyshoes&amp;gt; why is it so much faster?&lt;br /&gt;
2010-11-22 01:43:18 &amp;lt; Dark_Shikari&amp;gt; psadbw&lt;br /&gt;
2010-11-22 01:43:33 &amp;lt; Jumpyshoes&amp;gt; oh, because you&#039;re doing the abs in the C function&lt;br /&gt;
2010-11-22 01:44:24 &amp;lt; Jumpyshoes&amp;gt; okay, that is pretty awesome&lt;br /&gt;
2010-11-22 01:44:40 &amp;lt; Dark_Shikari&amp;gt; now let&#039;s get a bit to how we measure performance&lt;br /&gt;
2010-11-22 01:44:46 &amp;lt; Dark_Shikari&amp;gt; for any asm instruction, there are three things that matter&lt;br /&gt;
2010-11-22 01:44:56 &amp;lt; Dark_Shikari&amp;gt; latency, inverse throughput, and execution units&lt;br /&gt;
2010-11-22 01:45:05 &amp;lt; Dark_Shikari&amp;gt; the first two are represented like this&lt;br /&gt;
2010-11-22 01:45:06 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;3/1&amp;quot;&lt;br /&gt;
2010-11-22 01:45:07 &amp;lt; Kovensky&amp;gt; inverse throughput?&lt;br /&gt;
2010-11-22 01:45:15 &amp;lt; Dark_Shikari&amp;gt; this means a psadbw takes 3 clocks to finish from when it&#039;s started&lt;br /&gt;
2010-11-22 01:45:19 &amp;lt; Dark_Shikari&amp;gt; and you can do one of them per cycle.&lt;br /&gt;
2010-11-22 01:45:30 &amp;lt; Jumpyshoes&amp;gt; okay, what are all three? &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-22 01:45:41 &amp;lt; Dark_Shikari&amp;gt; another example is &amp;quot;mov&amp;quot;&lt;br /&gt;
2010-11-22 01:45:48 &amp;lt; Dark_Shikari&amp;gt; mov between two registers is 1/0.33&lt;br /&gt;
2010-11-22 01:45:53 &amp;lt; Dark_Shikari&amp;gt; takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
2010-11-22 01:45:56 &amp;lt; Dark_Shikari&amp;gt; execution unit usage is a bit trickier.&lt;br /&gt;
2010-11-22 01:46:03 &amp;lt; Dark_Shikari&amp;gt; Not all execution units can do all instructions.&lt;br /&gt;
2010-11-22 01:46:11 &amp;lt; Dark_Shikari&amp;gt; Intel chips have 6 execution units:&lt;br /&gt;
2010-11-22 01:46:14 &amp;lt; Dark_Shikari&amp;gt; p0, p1, p2, p3, p4, p5&lt;br /&gt;
2010-11-22 01:46:15 &amp;lt; Jumpyshoes&amp;gt; wait, what is latency?&lt;br /&gt;
2010-11-22 01:46:20 &amp;lt; Dark_Shikari&amp;gt; time from start to finish, in clocks&lt;br /&gt;
2010-11-22 01:46:24 &amp;lt; Jumpyshoes&amp;gt; and inverse throughput and execution units&lt;br /&gt;
2010-11-22 01:46:33 &amp;lt; Dark_Shikari&amp;gt; inverse throughput is how many you can do per clock.&lt;br /&gt;
2010-11-22 01:46:41 &amp;lt; Dark_Shikari&amp;gt; execution units are the things in the chip that do stuff.&lt;br /&gt;
2010-11-22 01:46:41 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 01:46:53 &amp;lt; Dark_Shikari&amp;gt; of these 6 execution units, three can do math: p0, p1, p5.&lt;br /&gt;
2010-11-22 01:47:02 &amp;lt; Dark_Shikari&amp;gt; psadbw, for example, can only use one of these (p1)&lt;br /&gt;
2010-11-22 01:47:06 &amp;lt; Dark_Shikari&amp;gt; pxor can use all three&lt;br /&gt;
2010-11-22 01:47:08 &amp;lt; Dark_Shikari&amp;gt; and so forth&lt;br /&gt;
2010-11-22 01:47:18 &amp;lt; Dark_Shikari&amp;gt; generally execution units aren&#039;t important until you get into serious optimizing&lt;br /&gt;
2010-11-22 01:47:24 &amp;lt; Dark_Shikari&amp;gt; but they can often affect the best instruction choices&lt;br /&gt;
2010-11-22 01:47:31 &amp;lt; Dark_Shikari&amp;gt; for example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
2010-11-22 01:47:48 &amp;lt; Dark_Shikari&amp;gt; the instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput&lt;br /&gt;
2010-11-22 01:47:52 &amp;lt; Dark_Shikari&amp;gt; for a wide variety of CPUs&lt;br /&gt;
2010-11-22 01:48:26 &amp;lt; Kovensky&amp;gt; I suppose AMD are roughly the same, for compatibility?&lt;br /&gt;
2010-11-22 01:48:28 &amp;lt; Jumpyshoes&amp;gt; how about branching? i heard branching fucks you&lt;br /&gt;
2010-11-22 01:48:35 &amp;lt; Dark_Shikari&amp;gt; not generally unless it&#039;s unpredictable&lt;br /&gt;
2010-11-22 01:48:41 &amp;lt; Kovensky&amp;gt; branch mispredictions do&lt;br /&gt;
2010-11-22 01:48:45 &amp;lt; Dark_Shikari&amp;gt; we can get to a case of that later if you want.&lt;br /&gt;
2010-11-22 01:48:51 &amp;lt; Dark_Shikari&amp;gt; now, let&#039;s just analyze SAD.&lt;br /&gt;
2010-11-22 01:48:57 &amp;lt; Dark_Shikari&amp;gt; suppose we want to analyze the 8x8 SAD&lt;br /&gt;
2010-11-22 01:49:02 &amp;lt; Dark_Shikari&amp;gt; in this function we do:&lt;br /&gt;
2010-11-22 01:49:03 &amp;lt; Dark_Shikari&amp;gt; 8 SADs&lt;br /&gt;
2010-11-22 01:49:07 &amp;lt; Dark_Shikari&amp;gt; 8 adds (accumulates)&lt;br /&gt;
2010-11-22 01:49:09 &amp;lt; Dark_Shikari&amp;gt; 16 loads&lt;br /&gt;
2010-11-22 01:49:34 &amp;lt; Dark_Shikari&amp;gt; plus the start, end, and calling overhead&lt;br /&gt;
2010-11-22 01:49:44 &amp;lt; Dark_Shikari&amp;gt; 8 SADs: takes 8 cycles (inverse throughput of 1)&lt;br /&gt;
2010-11-22 01:49:54 &amp;lt; Dark_Shikari&amp;gt; 8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs&lt;br /&gt;
2010-11-22 01:50:01 &amp;lt; Dark_Shikari&amp;gt; 16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
2010-11-22 01:50:04 &amp;lt; Dark_Shikari&amp;gt; So the loads are the bottleneck.&lt;br /&gt;
2010-11-22 01:50:13 &amp;lt; Dark_Shikari&amp;gt; This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.&lt;br /&gt;
2010-11-22 01:50:19 &amp;lt; Dark_Shikari&amp;gt; Loads are a common example.&lt;br /&gt;
2010-11-22 01:50:34 &amp;lt; Dark_Shikari&amp;gt; In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.&lt;br /&gt;
2010-11-22 01:50:47 &amp;lt; Jumpyshoes&amp;gt; oh.&lt;br /&gt;
2010-11-22 01:50:56 &amp;lt; Dark_Shikari&amp;gt; the actual runtime of the function is about 22 clocks.&lt;br /&gt;
2010-11-22 01:51:02 &amp;lt; Dark_Shikari&amp;gt; Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
2010-11-22 01:51:20 &amp;lt; Dark_Shikari&amp;gt; so that&#039;s some basic performance analysis for you.&lt;br /&gt;
2010-11-22 01:51:29 &amp;lt; Jumpyshoes&amp;gt; is there anything that does this automatically for you?&lt;br /&gt;
2010-11-22 01:51:30 &amp;lt; Dark_Shikari&amp;gt; How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
2010-11-22 01:51:36 &amp;lt; Dark_Shikari&amp;gt; analysis?  not really.&lt;br /&gt;
2010-11-22 01:51:43 &amp;lt; Dark_Shikari&amp;gt; There are intel performance counters and such on the chip&lt;br /&gt;
2010-11-22 01:51:46 &amp;lt; Dark_Shikari&amp;gt; but they&#039;re not magic&lt;br /&gt;
2010-11-22 01:51:53 &amp;lt; Dark_Shikari&amp;gt; It might be useful to have some kind of tool to analyze asm functions&lt;br /&gt;
2010-11-22 01:52:08 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 01:52:25 &amp;lt; Dark_Shikari&amp;gt; in general though, intuition is a powerful tool.&lt;br /&gt;
2010-11-22 01:53:02 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 01:53:15 &amp;lt; Dark_Shikari&amp;gt; so let&#039;s move on to some examples of powerful x264 macros.&lt;br /&gt;
2010-11-22 01:53:45 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-22 01:53:46 &amp;lt; Dark_Shikari&amp;gt; actualyl, let&#039;s start with something simpler&lt;br /&gt;
2010-11-22 01:53:49 &amp;lt; Dark_Shikari&amp;gt; pixel_avg2_w16_sse2&lt;br /&gt;
2010-11-22 01:53:51 &amp;lt; Dark_Shikari&amp;gt; mc-a.asm&lt;br /&gt;
2010-11-22 01:53:54 &amp;lt; Dark_Shikari&amp;gt; find it, ping me when you have&lt;br /&gt;
2010-11-22 01:54:19  * Kovensky found it&lt;br /&gt;
2010-11-22 01:54:27 &amp;lt; Jumpyshoes&amp;gt; found it&lt;br /&gt;
2010-11-22 01:55:20 &amp;lt; Dark_Shikari&amp;gt; ok, so this function interpolates between two inputs, and outputs to an output&lt;br /&gt;
2010-11-22 01:55:31 &amp;lt; Dark_Shikari&amp;gt; the interpolation is the simplest possible&lt;br /&gt;
2010-11-22 01:55:33 &amp;lt; Dark_Shikari&amp;gt; (A+B+1)&amp;gt;&amp;gt;1&lt;br /&gt;
2010-11-22 01:55:56 &amp;lt; Dark_Shikari&amp;gt; look at the function signature above&lt;br /&gt;
2010-11-22 01:55:59 &amp;lt; Dark_Shikari&amp;gt; ; void pixel_avg2_w4( uint8_t *dst, int dst_stride,&lt;br /&gt;
2010-11-22 01:55:59 &amp;lt; Dark_Shikari&amp;gt; etc&lt;br /&gt;
2010-11-22 01:56:12 &amp;lt; Dark_Shikari&amp;gt; so this function takes inputs from src1 and src2, averages them together, and writes to dst&lt;br /&gt;
2010-11-22 01:56:16 &amp;lt; Dark_Shikari&amp;gt; src1 and src2 have src_stride&lt;br /&gt;
2010-11-22 01:56:19 &amp;lt; Dark_Shikari&amp;gt; and dst has dst_stride.&lt;br /&gt;
2010-11-22 01:56:20 &amp;lt; Dark_Shikari&amp;gt; got it?&lt;br /&gt;
2010-11-22 01:56:50 &amp;lt; Jumpyshoes&amp;gt; what&#039;s the height?&lt;br /&gt;
2010-11-22 01:57:12 &amp;lt; Dark_Shikari&amp;gt; how many lines to interpolate.&lt;br /&gt;
2010-11-22 01:57:17 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 01:58:29 &amp;lt; Dark_Shikari&amp;gt; now this function uses xmm registers (128-bit)&lt;br /&gt;
2010-11-22 01:58:31 &amp;lt; Dark_Shikari&amp;gt; so it does 16 bytes at a time&lt;br /&gt;
2010-11-22 01:58:44 &amp;lt; Dark_Shikari&amp;gt; all 128-bit loads must be aligned unless movdqu is used.&lt;br /&gt;
2010-11-22 01:58:50 &amp;lt; Dark_Shikari&amp;gt; since our inputs are aligned, this is a lot of movdqu.&lt;br /&gt;
2010-11-22 01:58:54 &amp;lt; Dark_Shikari&amp;gt; er, are unaligned&lt;br /&gt;
2010-11-22 01:59:05 &amp;lt; Jumpyshoes&amp;gt; and what does movdqu do?&lt;br /&gt;
2010-11-22 01:59:18 &amp;lt; Dark_Shikari&amp;gt; loads 128 bits from an unaligned source&lt;br /&gt;
2010-11-22 01:59:28 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 01:59:33 &amp;lt; Kovensky&amp;gt; why sub r2 from r4?&lt;br /&gt;
2010-11-22 01:59:40 &amp;lt; Dark_Shikari&amp;gt; ah, now here&#039;s a fun trick&lt;br /&gt;
2010-11-22 01:59:47 &amp;lt; Dark_Shikari&amp;gt; we need to increment three pointers, right?&lt;br /&gt;
2010-11-22 01:59:50 &amp;lt; Jumpyshoes&amp;gt; yea, aren&#039;t you subtracting addressses?&lt;br /&gt;
2010-11-22 01:59:51 &amp;lt; Dark_Shikari&amp;gt; src1, src2, dst&lt;br /&gt;
2010-11-22 01:59:58 &amp;lt; Dark_Shikari&amp;gt; But src1 and src2 have the same stride.&lt;br /&gt;
2010-11-22 02:00:03 &amp;lt; Dark_Shikari&amp;gt; So they&#039;re being incremented by the same amount.&lt;br /&gt;
2010-11-22 02:00:11 &amp;lt; Dark_Shikari&amp;gt; So we can take src2 and represent it as an offset from src1.&lt;br /&gt;
2010-11-22 02:00:14 &amp;lt; Dark_Shikari&amp;gt; Then we only have to increment src1.&lt;br /&gt;
2010-11-22 02:00:18 &amp;lt; Dark_Shikari&amp;gt; One lea removed per iteration, bam.&lt;br /&gt;
2010-11-22 02:00:28 &amp;lt; Kovensky&amp;gt; and use r6 as the offset + stride?&lt;br /&gt;
2010-11-22 02:00:47 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 02:01:31 &amp;lt; Jumpyshoes&amp;gt; that is a nice trick&lt;br /&gt;
2010-11-22 02:01:52 &amp;lt; Dark_Shikari&amp;gt; so look through that function and see if there&#039;s anything you don&#039;t know about&lt;br /&gt;
2010-11-22 02:01:53 &amp;lt; Dark_Shikari&amp;gt; and ask questions.&lt;br /&gt;
2010-11-22 02:02:16 &amp;lt; Jumpyshoes&amp;gt; god how do you keep track of which argument is which&lt;br /&gt;
2010-11-22 02:02:33 &amp;lt; Kovensky&amp;gt; I copied the description from w4&lt;br /&gt;
2010-11-22 02:02:37 &amp;lt; Kovensky&amp;gt; and annotated it&lt;br /&gt;
2010-11-22 02:02:45 &amp;lt; Kovensky&amp;gt; ; void pixel_avg2_w4( uint8_t *dst (r0), int dst_stride (r1),&lt;br /&gt;
2010-11-22 02:02:48 &amp;lt; Kovensky&amp;gt; ;                     uint8_t *src1 (r2), int src_stride (r3),&lt;br /&gt;
2010-11-22 02:02:51 &amp;lt; Kovensky&amp;gt; ;                     uint8_t *src2 (r4), int height (r5) );&lt;br /&gt;
2010-11-22 02:02:55 &amp;lt; Jumpyshoes&amp;gt; good idea&lt;br /&gt;
2010-11-22 02:03:04 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: we have a system I&#039;ll show you later that helps you keep track of registers.&lt;br /&gt;
2010-11-22 02:03:13 &amp;lt; Dark_Shikari&amp;gt; or, well, makes it easier to.&lt;br /&gt;
2010-11-22 02:03:41 &amp;lt; Jumpyshoes&amp;gt; pavgb i assume does some sort of averagiing?&lt;br /&gt;
2010-11-22 02:04:04 &amp;lt; Dark_Shikari&amp;gt; yes, (A+B+1)&amp;gt;&amp;gt;1 for each pair of input pixels&lt;br /&gt;
2010-11-22 02:04:26 &amp;lt; Jumpyshoes&amp;gt; http://www.tommesani.com/SSEPrimer.html ooh this has pretty diagrams&lt;br /&gt;
2010-11-22 02:04:43 &amp;lt; Kovensky&amp;gt; that one was easy to read, but I didn&#039;t bother much about u vs a&lt;br /&gt;
2010-11-22 02:04:55 &amp;lt; Jumpyshoes&amp;gt; movdqa - mov dq to aligned?&lt;br /&gt;
2010-11-22 02:05:13 &amp;lt; Dark_Shikari&amp;gt; same as movdqu, except for aligned&lt;br /&gt;
2010-11-22 02:05:36 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 02:05:46 &amp;lt; Dark_Shikari&amp;gt; the output is always aligned, as we control it&lt;br /&gt;
2010-11-22 02:05:52 &amp;lt; Dark_Shikari&amp;gt; the input is an arbitrary pointer into a reference frame&lt;br /&gt;
2010-11-22 02:05:54 &amp;lt; Dark_Shikari&amp;gt; and so it could be anything.&lt;br /&gt;
2010-11-22 02:05:56 &amp;lt; Jumpyshoes&amp;gt; hoho one of the four billion jumps that exists in x86&lt;br /&gt;
2010-11-22 02:06:04 &amp;lt; Dark_Shikari&amp;gt; jump if greater than&lt;br /&gt;
2010-11-22 02:06:07 &amp;lt; Jumpyshoes&amp;gt; jump greater?&lt;br /&gt;
2010-11-22 02:06:16 &amp;lt; Dark_Shikari&amp;gt; so if r5d &amp;gt; 0&lt;br /&gt;
2010-11-22 02:06:18 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 02:06:35 &amp;lt; Jumpyshoes&amp;gt; so why two?&lt;br /&gt;
2010-11-22 02:06:44 &amp;lt; Dark_Shikari&amp;gt; it handles two rows at a time.&lt;br /&gt;
2010-11-22 02:06:46 &amp;lt; Jumpyshoes&amp;gt; oh, right&lt;br /&gt;
2010-11-22 02:07:04 &amp;lt; Kovensky&amp;gt; hm&lt;br /&gt;
2010-11-22 02:07:14 &amp;lt; Kovensky&amp;gt; movdq moves doublequads&lt;br /&gt;
2010-11-22 02:07:21 &amp;lt; Kovensky&amp;gt; but the registers are only quads&lt;br /&gt;
2010-11-22 02:07:28 &amp;lt; Kovensky&amp;gt; unless on 64bit&lt;br /&gt;
2010-11-22 02:07:32 &amp;lt; Kovensky&amp;gt; so what does it do&lt;br /&gt;
2010-11-22 02:07:36 &amp;lt; Jumpyshoes&amp;gt; xmm2 is 128, isn&#039;t it?&lt;br /&gt;
2010-11-22 02:07:37 &amp;lt; Kovensky&amp;gt; oh wait, not registers, memory addresses&lt;br /&gt;
2010-11-22 02:07:43 &amp;lt; Kovensky&amp;gt; failed there&lt;br /&gt;
2010-11-22 02:07:52 &amp;lt; Jumpyshoes&amp;gt; i thought it pads 0s&lt;br /&gt;
2010-11-22 02:07:58 &amp;lt; Dark_Shikari&amp;gt; all the moves here are 128-bit&lt;br /&gt;
2010-11-22 02:07:59 &amp;lt; Dark_Shikari&amp;gt; so there&#039;s no padding&lt;br /&gt;
2010-11-22 02:08:11 &amp;lt; Kovensky&amp;gt; no, it moves 128bits from wherever the registers point to xmm / viceversa&lt;br /&gt;
2010-11-22 02:08:24 &amp;lt; Jumpyshoes&amp;gt; ah, right&lt;br /&gt;
2010-11-22 02:08:29 &amp;lt; Kovensky&amp;gt; I was failing just now and reading as if it was moving the register contents to xmm&lt;br /&gt;
2010-11-22 02:09:20 &amp;lt; Jumpyshoes&amp;gt; okay, this is pretty awesome&lt;br /&gt;
2010-11-22 02:09:26 &amp;lt; Jumpyshoes&amp;gt; except i have a headache now&lt;br /&gt;
2010-11-22 02:09:37 &amp;lt; wipple&amp;gt; Dark_Shikari: i fixed configure --&amp;gt; http://cccp.project357.com/p/f1860e321&lt;br /&gt;
2010-11-22 02:09:46 &amp;lt; wipple&amp;gt; any other good way to fix?&lt;br /&gt;
2010-11-22 02:10:13 &amp;lt; Dark_Shikari&amp;gt; wipple: if it works, I&#039;m fine with it.  you want to package that with an updated version of your other patch?&lt;br /&gt;
2010-11-22 02:10:38 &amp;lt; wipple&amp;gt; Dark_Shikari: http://cccp.project357.com/p/f3c6e06e4&lt;br /&gt;
2010-11-22 02:11:04 &amp;lt; Kovensky&amp;gt; Dark_Shikari: how faster is the SSE2 version of this func compared to C&lt;br /&gt;
2010-11-22 02:11:53 &amp;lt; Dark_Shikari&amp;gt; wipple: applied&lt;br /&gt;
2010-11-22 02:12:03 &amp;lt; Dark_Shikari&amp;gt; Kovensky: about 11 times faster&lt;br /&gt;
2010-11-22 02:12:20 &amp;lt; Jumpyshoes&amp;gt; holy crap&lt;br /&gt;
2010-11-22 02:12:59 &amp;lt; Jumpyshoes&amp;gt; okay, i think i get it&lt;br /&gt;
2010-11-22 02:13:27 &amp;lt; Dark_Shikari&amp;gt; also, the REP_RET  you might have been wondering about&lt;br /&gt;
2010-11-22 02:13:33 &amp;lt; Dark_Shikari&amp;gt; in short, if you have a RET after a jump, use REP_RET.&lt;br /&gt;
2010-11-22 02:13:36 &amp;lt; Dark_Shikari&amp;gt; Blame AMD.&lt;br /&gt;
2010-11-22 02:13:51 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 02:13:54 &amp;lt; Kovensky&amp;gt; REP_RET is one of x86inc&#039;s macros I suppose&lt;br /&gt;
2010-11-22 02:14:35 &amp;lt; Jumpyshoes&amp;gt; i sure hope these GCI tasks are easy&lt;br /&gt;
2010-11-22 02:14:48 &amp;lt; Jumpyshoes&amp;gt; but in other news, this is pretty cool&lt;br /&gt;
2010-11-22 02:14:50 &amp;lt; Kovensky&amp;gt; they are once you get the hang of it&lt;br /&gt;
2010-11-22 02:14:54 &amp;lt; Jumpyshoes&amp;gt; how optimized this can get&lt;br /&gt;
2010-11-22 02:14:58 &amp;lt; Kovensky&amp;gt; since you just need to take any silly function&lt;br /&gt;
2010-11-22 02:15:00 &amp;lt; Kovensky&amp;gt; and write asm for it&lt;br /&gt;
2010-11-22 02:15:11 &amp;lt; Kovensky&amp;gt; if I had merged x264-audio already, you could write asm for my resampler lol&lt;br /&gt;
2010-11-22 02:15:18 &amp;lt; Kovensky&amp;gt; atm it&#039;s pure C&lt;br /&gt;
2010-11-22 02:15:24 &amp;lt; Kovensky&amp;gt; er&lt;br /&gt;
2010-11-22 02:15:31 &amp;lt; Kovensky&amp;gt; s/resample/sample format converter/&lt;br /&gt;
2010-11-22 02:15:38 &amp;lt; Dark_Shikari&amp;gt; so, now let&#039;s look at some horrible macro abuse&lt;br /&gt;
2010-11-22 02:15:38 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 02:15:38 &amp;lt; Kovensky&amp;gt; +r&lt;br /&gt;
2010-11-22 02:15:41 &amp;lt; Jumpyshoes&amp;gt; derp&lt;br /&gt;
2010-11-22 02:15:56 &amp;lt; Dark_Shikari&amp;gt; dct-a.asm&lt;br /&gt;
2010-11-22 02:15:59 &amp;lt; Dark_Shikari&amp;gt; cglobal add4x4_idct_mmx, 2,2&lt;br /&gt;
2010-11-22 02:16:02 &amp;lt; Dark_Shikari&amp;gt; this does an inverse DCT&lt;br /&gt;
2010-11-22 02:16:09 &amp;lt; Dark_Shikari&amp;gt; steps:&lt;br /&gt;
2010-11-22 02:16:12 &amp;lt; Dark_Shikari&amp;gt; 1.  Load dct coeffs.&lt;br /&gt;
2010-11-22 02:16:14 &amp;lt; Dark_Shikari&amp;gt; 2.  1D IDCT.&lt;br /&gt;
2010-11-22 02:16:17 &amp;lt; Dark_Shikari&amp;gt; 2.  Transpose.&lt;br /&gt;
2010-11-22 02:16:19 &amp;lt; Dark_Shikari&amp;gt; *3.&lt;br /&gt;
2010-11-22 02:16:22 &amp;lt; Dark_Shikari&amp;gt; 4.  1D IDCT.&lt;br /&gt;
2010-11-22 02:16:33 &amp;lt; Dark_Shikari&amp;gt; 5.  Load pixels, add idct output, clamp, store.&lt;br /&gt;
2010-11-22 02:16:44 &amp;lt; Dark_Shikari&amp;gt; You might notice that this function looks curiously simple!&lt;br /&gt;
2010-11-22 02:16:47 &amp;lt; Kovensky&amp;gt; the IDCT macro itself is probably cute&lt;br /&gt;
2010-11-22 02:16:54 &amp;lt; Jumpyshoes&amp;gt; what does transpose do?&lt;br /&gt;
2010-11-22 02:17:05 &amp;lt; Dark_Shikari&amp;gt; Exactly what you think it does.&lt;br /&gt;
2010-11-22 02:17:06 &amp;lt; Kovensky&amp;gt; just a regular matrix transpose&lt;br /&gt;
2010-11-22 02:17:19 &amp;lt; Jumpyshoes&amp;gt; isn&#039;t it 1D though?&lt;br /&gt;
2010-11-22 02:17:27 &amp;lt; Kovensky&amp;gt; no, the source is 2D&lt;br /&gt;
2010-11-22 02:17:32 &amp;lt; Kovensky&amp;gt; but the IDCT is 1D&lt;br /&gt;
2010-11-22 02:17:34 &amp;lt; Jumpyshoes&amp;gt; oh, it is&lt;br /&gt;
2010-11-22 02:17:52 &amp;lt; Kovensky&amp;gt; however, if you do it on the matrix on both orientations, it works like a 2D IDCT... somehow...&lt;br /&gt;
2010-11-22 02:17:58 &amp;lt; Kovensky&amp;gt; idk the maths behind it lol&lt;br /&gt;
2010-11-22 02:18:00 &amp;lt; Dark_Shikari&amp;gt; it&#039;s called a &amp;quot;separable transform&amp;quot;&lt;br /&gt;
2010-11-22 02:18:08 &amp;lt; Dark_Shikari&amp;gt; it means you can do a 2D transform by doing two 1D transforms&lt;br /&gt;
2010-11-22 02:18:09 &amp;lt; Dark_Shikari&amp;gt; one in each direction&lt;br /&gt;
2010-11-22 02:18:12 &amp;lt; Dark_Shikari&amp;gt; the transform is designed that way.&lt;br /&gt;
2010-11-22 02:18:24 &amp;lt; Jumpyshoes&amp;gt; right, works like the DCT derp derp&lt;br /&gt;
2010-11-22 02:18:29 &amp;lt; Kovensky&amp;gt; is that specific of the HCT or has always been part of the DCT&lt;br /&gt;
2010-11-22 02:18:40 &amp;lt; Jumpyshoes&amp;gt; concentrates the energy and shit woohoo&lt;br /&gt;
2010-11-22 02:18:47 &amp;lt; Dark_Shikari&amp;gt; now notice how simple it is.&lt;br /&gt;
2010-11-22 02:18:57 &amp;lt; Kovensky&amp;gt; I know nothing about the DCT, and I&#039;ve read the wikipedia page like 5 times ._.&lt;br /&gt;
2010-11-22 02:18:57 &amp;lt; Dark_Shikari&amp;gt; Macros hide all the complexity in little manageable chunks.&lt;br /&gt;
2010-11-22 02:19:03 &amp;lt; Jumpyshoes&amp;gt; well, you&#039;re calling IDCT4_1D&lt;br /&gt;
2010-11-22 02:19:06 &amp;lt; Dark_Shikari&amp;gt; Which can be edited separately.&lt;br /&gt;
2010-11-22 02:19:16 &amp;lt; Kovensky&amp;gt; ,skip_prologue?&lt;br /&gt;
2010-11-22 02:19:27 &amp;lt; Dark_Shikari&amp;gt; Kovensky: there are functions that call this, and have already set up the registers&lt;br /&gt;
2010-11-22 02:19:30 &amp;lt; Dark_Shikari&amp;gt; so they jump directly to the start&lt;br /&gt;
2010-11-22 02:19:34 &amp;lt; Dark_Shikari&amp;gt; instead of the init part&lt;br /&gt;
2010-11-22 02:19:42 &amp;lt; Dark_Shikari&amp;gt; *asm functions that call this&lt;br /&gt;
2010-11-22 02:19:49 &amp;lt; Kovensky&amp;gt; I see&lt;br /&gt;
2010-11-22 02:19:53 &amp;lt; Dark_Shikari&amp;gt; Now, here&#039;s the fun part&lt;br /&gt;
2010-11-22 02:19:53 &amp;lt; Kovensky&amp;gt; cheaters&lt;br /&gt;
2010-11-22 02:19:54 &amp;lt; Kovensky&amp;gt; :P&lt;br /&gt;
2010-11-22 02:20:07 &amp;lt; Dark_Shikari&amp;gt; IDCT and transpose are both composed of submacros and so on&lt;br /&gt;
2010-11-22 02:20:12 &amp;lt; Jumpyshoes&amp;gt; oh god&lt;br /&gt;
2010-11-22 02:20:17 &amp;lt; Dark_Shikari&amp;gt; for example&lt;br /&gt;
2010-11-22 02:20:21 &amp;lt; Dark_Shikari&amp;gt; a transpose is a series of BUTTERFLY operations&lt;br /&gt;
2010-11-22 02:20:23 &amp;lt; Dark_Shikari&amp;gt; see x86util.asm&lt;br /&gt;
2010-11-22 02:20:26 &amp;lt; Dark_Shikari&amp;gt; it&#039;s actually pretty simple&lt;br /&gt;
2010-11-22 02:20:33 &amp;lt; Kovensky&amp;gt; BUTTERFLY?&lt;br /&gt;
2010-11-22 02:21:02 &amp;lt; Dark_Shikari&amp;gt; the catch is that in many cases, these macros output to different registers than they input from&lt;br /&gt;
2010-11-22 02:21:11 &amp;lt; Dark_Shikari&amp;gt; so, in a crappy asm language, yo&#039;ud have to track every single register manually&lt;br /&gt;
2010-11-22 02:21:15 &amp;lt; Dark_Shikari&amp;gt; which would make you go batshit insane&lt;br /&gt;
2010-11-22 02:21:16 &amp;lt; Jumpyshoes&amp;gt; argh&lt;br /&gt;
2010-11-22 02:21:30 &amp;lt; Jumpyshoes&amp;gt; i hope there&#039;s a way around this&lt;br /&gt;
2010-11-22 02:21:52 &amp;lt; Kovensky&amp;gt; why is the butterfly named butterfly&lt;br /&gt;
2010-11-22 02:21:59 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: But...&lt;br /&gt;
2010-11-22 02:21:59 &amp;lt; Jumpyshoes&amp;gt; that too&lt;br /&gt;
2010-11-22 02:22:09 &amp;lt; Dark_Shikari&amp;gt; in x264asm, you can do this:&lt;br /&gt;
2010-11-22 02:22:12 &amp;lt; Dark_Shikari&amp;gt; SWAP 2,3&lt;br /&gt;
2010-11-22 02:22:15 &amp;lt; Dark_Shikari&amp;gt; now m2 and m3 are swapped.&lt;br /&gt;
2010-11-22 02:22:16 &amp;lt; Dark_Shikari&amp;gt; From now on.&lt;br /&gt;
2010-11-22 02:22:22 &amp;lt; Dark_Shikari&amp;gt; It&#039;s the same as exchanging those registers&#039; values.&lt;br /&gt;
2010-11-22 02:22:25 &amp;lt; Dark_Shikari&amp;gt; But done without any ops.&lt;br /&gt;
2010-11-22 02:22:30 &amp;lt; Dark_Shikari&amp;gt; Because it swaps all future uses of those registers.&lt;br /&gt;
2010-11-22 02:22:41 &amp;lt; Dark_Shikari&amp;gt; Thus you offload the task of tracking registers to the assembler.&lt;br /&gt;
2010-11-22 02:22:42 &amp;lt; Kovensky&amp;gt; now that&#039;s evil macro usage&lt;br /&gt;
2010-11-22 02:22:50 &amp;lt; j0sh&amp;gt; Kovensky: because the swaps look like a butterfly https://secure.wikimedia.org/wikipedia/en/wiki/Butterfly_diagram&lt;br /&gt;
2010-11-22 02:22:50 &amp;lt; Jumpyshoes&amp;gt; that is awesome&lt;br /&gt;
2010-11-22 02:22:59 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;m0, m1, m2&amp;quot; are aliased to mm0, mm1, mm2 etc if INIT_MMX is set&lt;br /&gt;
2010-11-22 02:23:07 &amp;lt; Dark_Shikari&amp;gt; and xmm0, xmm1, xmm2... if INIT_XMM is set.&lt;br /&gt;
2010-11-22 02:23:15 &amp;lt; Dark_Shikari&amp;gt; and mmsize is 8 in the former case, 16 in the latter.&lt;br /&gt;
2010-11-22 02:23:19 &amp;lt; Kovensky&amp;gt; yeah, was about to ask what the m%d were&lt;br /&gt;
2010-11-22 02:23:20 &amp;lt; Dark_Shikari&amp;gt; So you can declare a single function&lt;br /&gt;
2010-11-22 02:23:27 &amp;lt; Dark_Shikari&amp;gt; then initialize it for both mmx and sse!&lt;br /&gt;
2010-11-22 02:23:28 &amp;lt; Dark_Shikari&amp;gt; in one go!&lt;br /&gt;
2010-11-22 02:23:58 &amp;lt; Dark_Shikari&amp;gt; here&#039;s a simple example: denoise, in quant-.asm&lt;br /&gt;
2010-11-22 02:24:01 &amp;lt; Dark_Shikari&amp;gt; line 748&lt;br /&gt;
2010-11-22 02:24:09 &amp;lt; Dark_Shikari&amp;gt; it loops over the coefficients in a dct block and denoises them&lt;br /&gt;
2010-11-22 02:24:13 &amp;lt; Kovensky&amp;gt; why are the movqs in a weird order?&lt;br /&gt;
2010-11-22 02:24:19 &amp;lt; Dark_Shikari&amp;gt; it&#039;s initted for both mmx and sse trivially&lt;br /&gt;
2010-11-22 02:24:20 &amp;lt; Kovensky&amp;gt; on add4x4_idct&lt;br /&gt;
2010-11-22 02:24:22 &amp;lt; Jumpyshoes&amp;gt; wait, where is it?&lt;br /&gt;
2010-11-22 02:24:41 &amp;lt; Dark_Shikari&amp;gt; quant-a.asm&lt;br /&gt;
2010-11-22 02:24:47 &amp;lt; Dark_Shikari&amp;gt; Kovensky: that&#039;s the order they&#039;re used&lt;br /&gt;
2010-11-22 02:24:52 &amp;lt; Dark_Shikari&amp;gt; so it&#039;s a bit faster to do it that way&lt;br /&gt;
2010-11-22 02:25:16 &amp;lt; Kovensky&amp;gt; so it&#039;s about the execution unit optimization I guess&lt;br /&gt;
2010-11-22 02:25:20 &amp;lt; Dark_Shikari&amp;gt; no, just ordering&lt;br /&gt;
2010-11-22 02:25:29 &amp;lt; Dark_Shikari&amp;gt; the cpu generally doesn&#039;t reorder loads/stores that much&lt;br /&gt;
2010-11-22 02:25:29 &amp;lt; Jumpyshoes&amp;gt; oh, is there an updated version of x264?&lt;br /&gt;
2010-11-22 02:25:36 &amp;lt; Dark_Shikari&amp;gt; git pull&lt;br /&gt;
2010-11-22 02:25:37 &amp;lt; Jumpyshoes&amp;gt; cause 748 for me is     bsf   ecx, r3&lt;br /&gt;
2010-11-22 02:25:38 &amp;lt; Dark_Shikari&amp;gt; now you have the latest&lt;br /&gt;
2010-11-22 02:25:59 &amp;lt; Dark_Shikari&amp;gt; btw, add_idct_mmx 4x4 is about ~5.8x faster than c&lt;br /&gt;
2010-11-22 02:26:17 &amp;lt; Kovensky&amp;gt; 748 is on zigzag_scan for me...&lt;br /&gt;
2010-11-22 02:26:19  * Kovensky goes pull&lt;br /&gt;
2010-11-22 02:26:47 &amp;lt; Dark_Shikari&amp;gt; 788-798 is were we init three copies of this function&lt;br /&gt;
2010-11-22 02:26:50 &amp;lt; Dark_Shikari&amp;gt; mmx, sse2, and ssse3.&lt;br /&gt;
2010-11-22 02:26:58 &amp;lt; Dark_Shikari&amp;gt; for mmx vs sse2, we just change from INIT_MMX to INIT_XMM&lt;br /&gt;
2010-11-22 02:27:09 &amp;lt; Dark_Shikari&amp;gt; for sse2 vs ssse3, we change PABSW and PSIGNW to use the pabsw and psignw instructions, instead of emulations thereof.&lt;br /&gt;
2010-11-22 02:27:20 &amp;lt; Dark_Shikari&amp;gt; (SSSE3 adds a &amp;quot;sign restore&amp;quot; and &amp;quot;absolute value&amp;quot; instruction)&lt;br /&gt;
2010-11-22 02:27:27 &amp;lt; Dark_Shikari&amp;gt; which are really really useful.&lt;br /&gt;
2010-11-22 02:27:47 &amp;lt; Jumpyshoes&amp;gt; okaaaaaay, so&lt;br /&gt;
2010-11-22 02:27:51 &amp;lt; Jumpyshoes&amp;gt; finally caught up&lt;br /&gt;
2010-11-22 02:28:02 &amp;lt; Jumpyshoes&amp;gt; why are some asm instructions capitalized?&lt;br /&gt;
2010-11-22 02:28:47 &amp;lt; Jumpyshoes&amp;gt; like PSIGNW&lt;br /&gt;
2010-11-22 02:29:27 &amp;lt; Jumpyshoes&amp;gt; i mean, why is it capitalized while other instructions aren&#039;t?&lt;br /&gt;
2010-11-22 02:29:28 &amp;lt; Dark_Shikari&amp;gt; PSIGNW isn&#039;t an instruction, it&#039;s a macro&lt;br /&gt;
2010-11-22 02:29:43 &amp;lt; Jumpyshoes&amp;gt; o&lt;br /&gt;
2010-11-22 02:29:43 &amp;lt; Dark_Shikari&amp;gt; we %define it to PSIGNW_MMX for the mmx implementation&lt;br /&gt;
2010-11-22 02:29:48 &amp;lt; Dark_Shikari&amp;gt; and when we make the ssse3 version&lt;br /&gt;
2010-11-22 02:29:53 &amp;lt; Dark_Shikari&amp;gt; we %define it to PSIGNW_SSSE3&lt;br /&gt;
2010-11-22 02:29:57 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 02:30:10 &amp;lt; Dark_Shikari&amp;gt; the latter of which... is just psignw.&lt;br /&gt;
2010-11-22 02:30:20 &amp;lt; Kovensky&amp;gt; so I heard you like instructions so we put instructions on your instructions so you can...&lt;br /&gt;
2010-11-22 02:30:30 &amp;lt; Dark_Shikari&amp;gt; by the way&lt;br /&gt;
2010-11-22 02:30:32 &amp;lt; Dark_Shikari&amp;gt; in INIT_XMM&lt;br /&gt;
2010-11-22 02:30:33 &amp;lt; Dark_Shikari&amp;gt; mova == movdqa&lt;br /&gt;
2010-11-22 02:30:35 &amp;lt; Dark_Shikari&amp;gt; movh == movq&lt;br /&gt;
2010-11-22 02:30:38 &amp;lt; Dark_Shikari&amp;gt; movu == movdqu&lt;br /&gt;
2010-11-22 02:30:42 &amp;lt; Dark_Shikari&amp;gt; init INIT_MMX&lt;br /&gt;
2010-11-22 02:30:43 &amp;lt; Dark_Shikari&amp;gt; mova == movq&lt;br /&gt;
2010-11-22 02:30:45 &amp;lt; Dark_Shikari&amp;gt; movh == movd&lt;br /&gt;
2010-11-22 02:30:46 &amp;lt; Dark_Shikari&amp;gt; movu == movq&lt;br /&gt;
2010-11-22 02:30:51 &amp;lt; Dark_Shikari&amp;gt; mova == move aligned&lt;br /&gt;
2010-11-22 02:30:53 &amp;lt; Dark_Shikari&amp;gt; movh == move half&lt;br /&gt;
2010-11-22 02:30:56 &amp;lt; Dark_Shikari&amp;gt; movu == move unaligned&lt;br /&gt;
2010-11-22 02:31:55 &amp;lt; Jumpyshoes&amp;gt; oh boy&lt;br /&gt;
2010-11-22 02:32:28 &amp;lt; Jumpyshoes&amp;gt; should i try to take a look at this denoise function?&lt;br /&gt;
2010-11-22 02:32:37 &amp;lt; Dark_Shikari&amp;gt; Yes, feel free to look at the C.&lt;br /&gt;
2010-11-22 02:32:39 &amp;lt; Dark_Shikari&amp;gt; It&#039;s not very complicated.&lt;br /&gt;
2010-11-22 02:32:48 &amp;lt; Jumpyshoes&amp;gt; where can i find the C?C&lt;br /&gt;
2010-11-22 02:32:51 &amp;lt; Dark_Shikari&amp;gt; C is in common/quant.c&lt;br /&gt;
2010-11-22 02:32:53 &amp;lt; Dark_Shikari&amp;gt; as you might expect.&lt;br /&gt;
2010-11-22 02:33:47 &amp;lt; Jumpyshoes&amp;gt; wait, so why is the macro 1-2?&lt;br /&gt;
2010-11-22 02:33:52 &amp;lt; Jumpyshoes&amp;gt; DENOISE_DCT 1-2&lt;br /&gt;
2010-11-22 02:33:59 &amp;lt; Dark_Shikari&amp;gt; variable number of arguments&lt;br /&gt;
2010-11-22 02:34:03 &amp;lt; Dark_Shikari&amp;gt; Ah, I forgot the third number.&lt;br /&gt;
2010-11-22 02:34:08 &amp;lt; Dark_Shikari&amp;gt; cglobal name, X, Y, Z&lt;br /&gt;
2010-11-22 02:34:11 &amp;lt; Dark_Shikari&amp;gt; We only covered the X and Y.&lt;br /&gt;
2010-11-22 02:34:29 &amp;lt; Dark_Shikari&amp;gt; on win64, xmmregs 6-15 need to be saved.&lt;br /&gt;
2010-11-22 02:34:44 &amp;lt; Dark_Shikari&amp;gt; so if we use more than 6 xmmregs, we need to tell x264 about it&lt;br /&gt;
2010-11-22 02:34:48 &amp;lt; Dark_Shikari&amp;gt; the last number is the number of xmmregs used.&lt;br /&gt;
2010-11-22 02:34:49 &amp;lt; Dark_Shikari&amp;gt; It&#039;s optional.&lt;br /&gt;
2010-11-22 02:34:55 &amp;lt; Dark_Shikari&amp;gt; So if we are using mmx, we don&#039;t bother setting it.&lt;br /&gt;
2010-11-22 02:34:58 &amp;lt; Dark_Shikari&amp;gt; and it defaults to 0.&lt;br /&gt;
2010-11-22 02:35:47 &amp;lt; Jumpyshoes&amp;gt; why is the C so simple and why is the asm so long&lt;br /&gt;
2010-11-22 02:35:56 &amp;lt; Dark_Shikari&amp;gt; 1) C is more expressive than asm&lt;br /&gt;
2010-11-22 02:36:03 &amp;lt; Dark_Shikari&amp;gt; 2) the asm is unrolled, doing more iterations per loop than the C&lt;br /&gt;
2010-11-22 02:36:10 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 02:37:25 &amp;lt; Dark_Shikari&amp;gt; asm is almost always longer than C.&lt;br /&gt;
2010-11-22 02:37:44 &amp;lt; Kovensky&amp;gt; what does pabsw do&lt;br /&gt;
2010-11-22 02:37:47 &amp;lt; Dark_Shikari&amp;gt; absolute value&lt;br /&gt;
2010-11-22 02:37:53 &amp;lt; Kovensky&amp;gt; it isn&#039;t in that nasm reference :(&lt;br /&gt;
2010-11-22 02:38:16 &amp;lt; Dark_Shikari&amp;gt; sure, because it&#039;s newer than sse2&lt;br /&gt;
2010-11-22 02:38:37 &amp;lt; Kovensky&amp;gt; so pabsw dst, src strips the signs from src and stores result on dst?&lt;br /&gt;
2010-11-22 02:38:43 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 02:40:35 &amp;lt; Kovensky&amp;gt; and psignw?&lt;br /&gt;
2010-11-22 02:43:03 &amp;lt; Jumpyshoes&amp;gt; you know what blows my mind? there&#039;s no xor or shr in the asm code&lt;br /&gt;
2010-11-22 02:43:06 &amp;lt; Dark_Shikari&amp;gt; Kovensky: restores sign&lt;br /&gt;
2010-11-22 02:43:24 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: the c code is optimized&lt;br /&gt;
2010-11-22 02:43:26 &amp;lt; Kovensky&amp;gt; I&#039;m atm parsing the bunch of punpck&lt;br /&gt;
2010-11-22 02:43:34 &amp;lt; Dark_Shikari&amp;gt; it&#039;s really more optimized than it needs to be&lt;br /&gt;
2010-11-22 02:43:41 &amp;lt; Dark_Shikari&amp;gt; the +/^ is just abs&lt;br /&gt;
2010-11-22 02:43:46 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 02:43:47 &amp;lt; Dark_Shikari&amp;gt; and a sign restore at the end&lt;br /&gt;
2010-11-22 02:43:54 &amp;lt; Dark_Shikari&amp;gt; the C was effectively rewritten to be more like the asm&lt;br /&gt;
2010-11-22 02:44:26 &amp;lt; Kovensky&amp;gt; actually, I lost track of the registers already lol&lt;br /&gt;
2010-11-22 02:44:42 &amp;lt; Jumpyshoes&amp;gt; soooooooo did i&lt;br /&gt;
2010-11-22 02:45:18 &amp;lt; Dark_Shikari&amp;gt; add comments next to them or give them names if you need to&lt;br /&gt;
2010-11-22 02:45:21 &amp;lt; Kovensky&amp;gt; why is m6 only read from&lt;br /&gt;
2010-11-22 02:45:27 &amp;lt; Dark_Shikari&amp;gt; m6 is a zero register&lt;br /&gt;
2010-11-22 02:45:31 &amp;lt; Dark_Shikari&amp;gt; it&#039;s initted at the start&lt;br /&gt;
2010-11-22 02:45:45 &amp;lt; Jumpyshoes&amp;gt; it interleaves 0s?&lt;br /&gt;
2010-11-22 02:45:51 &amp;lt; Kovensky&amp;gt; so it just supplies 0s to the punpcks&lt;br /&gt;
2010-11-22 02:46:08 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 02:46:13 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: to convert from 16-bit to 32-bit&lt;br /&gt;
2010-11-22 02:46:15 &amp;lt; Dark_Shikari&amp;gt; you add zeroes&lt;br /&gt;
2010-11-22 02:46:22 &amp;lt; Kovensky&amp;gt; I actually should go sleep right now, finals week start tomorrow and it&#039;s 14 minutes to tomorrow =p&lt;br /&gt;
2010-11-22 02:46:32 &amp;lt; Jumpyshoes&amp;gt; you know what my OCD self hates?&lt;br /&gt;
2010-11-22 02:46:36 &amp;lt; Jumpyshoes&amp;gt; &amp;gt;paddd     m4, [r1+r3*4+0*mmsize]&lt;br /&gt;
2010-11-22 02:46:40 &amp;lt; Jumpyshoes&amp;gt; f-f-f-f-f-fuck&lt;br /&gt;
2010-11-22 02:46:47 &amp;lt; Dark_Shikari&amp;gt; what&lt;br /&gt;
2010-11-22 02:46:52 &amp;lt; Jumpyshoes&amp;gt; m4 goes with 0&lt;br /&gt;
2010-11-22 02:46:58 &amp;lt; Dark_Shikari&amp;gt; oh&lt;br /&gt;
2010-11-22 02:46:58 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-22 02:47:08 &amp;lt; Dark_Shikari&amp;gt; those were just regs I ended up with at the end&lt;br /&gt;
2010-11-22 02:47:11 &amp;lt; Dark_Shikari&amp;gt; that&#039;s how you write these things&lt;br /&gt;
2010-11-22 02:47:12 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-22 02:48:36 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 02:48:40 &amp;lt; Jumpyshoes&amp;gt; i get the gist of this function&lt;br /&gt;
2010-11-22 02:49:08 &amp;lt; Kovensky&amp;gt; gl Jumpyshoes, I&#039;ll read the backlog later&lt;br /&gt;
2010-11-22 02:49:08 &amp;lt; Dark_Shikari&amp;gt; it subtracts a value from each dct coeff&lt;br /&gt;
2010-11-22 02:49:16  * Kovensky sleeps&lt;br /&gt;
2010-11-22 02:49:20 &amp;lt; Jumpyshoes&amp;gt; yea, from the offsets?&lt;br /&gt;
2010-11-22 02:49:22 &amp;lt; Dark_Shikari&amp;gt; (limiting it to zero, so they don&#039;t go negative)&lt;br /&gt;
2010-11-22 02:49:22 &amp;lt; Jumpyshoes&amp;gt; cya Kovensky&lt;br /&gt;
2010-11-22 02:49:25 &amp;lt; Dark_Shikari&amp;gt; it subtractss the offsets&lt;br /&gt;
2010-11-22 02:49:31 &amp;lt; Dark_Shikari&amp;gt; then it adds the amounts subtracted to the accumulators&lt;br /&gt;
2010-11-22 02:49:40 &amp;lt; Dark_Shikari&amp;gt; which are then used later in x264 to create new offsets.&lt;br /&gt;
2010-11-22 02:50:17 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 02:50:47 &amp;lt; Jumpyshoes&amp;gt; wait, now what&#039;s the conditions on this loop from breaking?&lt;br /&gt;
2010-11-22 02:51:01 &amp;lt; Jumpyshoes&amp;gt; OH&lt;br /&gt;
2010-11-22 02:51:02 &amp;lt; Jumpyshoes&amp;gt; the sub&lt;br /&gt;
2010-11-22 02:51:05 &amp;lt; Jumpyshoes&amp;gt; WAY UP TOP&lt;br /&gt;
2010-11-22 02:51:23 &amp;lt; Dark_Shikari&amp;gt; yeah, it kind of went walkabout&lt;br /&gt;
2010-11-22 02:52:02 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 02:52:05 &amp;lt; Jumpyshoes&amp;gt; now i think i understand&lt;br /&gt;
2010-11-22 02:52:48 &amp;lt; Jumpyshoes&amp;gt; understanding 15 lines of asm takes me 30 minutes&lt;br /&gt;
2010-11-22 02:52:50 &amp;lt; Jumpyshoes&amp;gt; woohoo&lt;br /&gt;
2010-11-22 02:52:52 &amp;lt; Dark_Shikari&amp;gt; That&#039;s normal&lt;br /&gt;
2010-11-22 02:53:12 &amp;lt; Dark_Shikari&amp;gt; for a newbie, writing is often easier than reading.&lt;br /&gt;
2010-11-22 02:53:18 &amp;lt; Dark_Shikari&amp;gt; because when writing, you already know what youw ant&lt;br /&gt;
2010-11-22 02:53:19 &amp;lt; Dark_Shikari&amp;gt; *want&lt;br /&gt;
2010-11-22 02:53:20 &amp;lt; Jumpyshoes&amp;gt; are you serious?&lt;br /&gt;
2010-11-22 02:53:23 &amp;lt; Dark_Shikari&amp;gt; when reading, you have to figure out what someone else wanted.&lt;br /&gt;
2010-11-22 02:53:38 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-22 02:53:43 &amp;lt; Dark_Shikari&amp;gt; And you can pattern your functions on others&lt;br /&gt;
2010-11-22 02:53:50 &amp;lt; Dark_Shikari&amp;gt; for example, like 1/3 of the functions in x264 are looping over some pixel input&lt;br /&gt;
2010-11-22 02:53:57 &amp;lt; Dark_Shikari&amp;gt; using the same basic template.&lt;br /&gt;
2010-11-22 02:54:04 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 02:54:12 &amp;lt; Jumpyshoes&amp;gt; i have a feeling GCI is gonna kick my ass&lt;br /&gt;
2010-11-22 02:54:15 &amp;lt; Dark_Shikari&amp;gt; in general, it&#039;s not as hard as you think.&lt;br /&gt;
2010-11-22 02:54:17 &amp;lt; Jumpyshoes&amp;gt; but that&#039;s not the point&lt;br /&gt;
2010-11-22 02:54:28 &amp;lt; Dark_Shikari&amp;gt; Actually, let&#039;s do that.  Let&#039;s write a function&lt;br /&gt;
2010-11-22 02:54:29 &amp;lt; Jumpyshoes&amp;gt; do all asm functions have a C equivalent?&lt;br /&gt;
2010-11-22 02:54:32 &amp;lt; Dark_Shikari&amp;gt; Yes&lt;br /&gt;
2010-11-22 02:54:41 &amp;lt; kierank&amp;gt; [02:53] Dark_Shikari: when reading, you have to figure out what someone else wanted. --&amp;gt; or if it&#039;s compiler created asm who knows what you have to figure out&lt;br /&gt;
2010-11-22 02:54:48 &amp;lt; Jumpyshoes&amp;gt; oh god, i&#039;m gonna get my ass kicked&lt;br /&gt;
2010-11-22 02:54:48 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-22 02:55:51 &amp;lt; Jumpyshoes&amp;gt; well, at least there&#039;s c&lt;br /&gt;
2010-11-22 02:55:53 &amp;lt; Jumpyshoes&amp;gt; to help me&lt;br /&gt;
2010-11-22 02:55:57 &amp;lt; Jumpyshoes&amp;gt; read this&lt;br /&gt;
2010-11-22 02:56:17 &amp;lt; Dark_Shikari&amp;gt; void foo( int16_t *dst, int16_t *src1, int16_t *src2 )&lt;br /&gt;
2010-11-22 02:56:17 &amp;lt; Dark_Shikari&amp;gt; {&lt;br /&gt;
2010-11-22 02:56:17 &amp;lt; Dark_Shikari&amp;gt;     for( int i = 0; i &amp;lt; 64; i++ )&lt;br /&gt;
2010-11-22 02:56:17 &amp;lt; Dark_Shikari&amp;gt;         dst[i] = src1[i] - src2[i];&lt;br /&gt;
2010-11-22 02:56:18 &amp;lt; Dark_Shikari&amp;gt; }&lt;br /&gt;
2010-11-22 02:56:20 &amp;lt; Dark_Shikari&amp;gt; implement this.&lt;br /&gt;
2010-11-22 02:56:25 &amp;lt; Dark_Shikari&amp;gt; ask questions as you go&lt;br /&gt;
2010-11-22 02:56:25 &amp;lt; Jumpyshoes&amp;gt; ooooh boy&lt;br /&gt;
2010-11-22 02:56:28 &amp;lt; Jumpyshoes&amp;gt; very well&lt;br /&gt;
2010-11-22 02:56:39 &amp;lt; Dark_Shikari&amp;gt; cglobal foo_mmxext, 3,3&lt;br /&gt;
2010-11-22 02:56:41 &amp;lt; Dark_Shikari&amp;gt; or sse2, take your pick&lt;br /&gt;
2010-11-22 02:57:14 &amp;lt; Jumpyshoes&amp;gt; i hope you don&#039;t expect it to be optimized&lt;br /&gt;
2010-11-22 02:57:54 &amp;lt; Dark_Shikari&amp;gt; I expect it to be reasonably fast, i.e. using SIMD&lt;br /&gt;
2010-11-22 02:58:07 &amp;lt; Dark_Shikari&amp;gt; feel free to stop at any point and ask any question about anything&lt;br /&gt;
2010-11-22 02:58:28 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-22 03:03:32 &amp;lt; Jumpyshoes&amp;gt; wait, so a qw is 128bits?&lt;br /&gt;
2010-11-22 03:03:42 &amp;lt; Dark_Shikari&amp;gt; no, quadword is 64&lt;br /&gt;
2010-11-22 03:03:44 &amp;lt; Dark_Shikari&amp;gt; double quadword is 128&lt;br /&gt;
2010-11-22 03:03:47 &amp;lt; Jumpyshoes&amp;gt; er&lt;br /&gt;
2010-11-22 03:03:49 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-22 03:03:49 &amp;lt; Dark_Shikari&amp;gt; word is 16&lt;br /&gt;
2010-11-22 03:03:53 &amp;lt; Dark_Shikari&amp;gt; quad... 4*...&lt;br /&gt;
2010-11-22 03:05:17 &amp;lt; darkbringer&amp;gt; what about overflows?&lt;br /&gt;
2010-11-22 03:05:27 &amp;lt; Jumpyshoes&amp;gt; oh, yes &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-22 03:06:10 &amp;lt; Dark_Shikari&amp;gt; not possible as far as I see&lt;br /&gt;
2010-11-22 03:06:14 &amp;lt; Dark_Shikari&amp;gt; they&#039;re all int16_t&lt;br /&gt;
2010-11-22 03:06:29 &amp;lt; Dark_Shikari&amp;gt; I mean, they could happen, but whatever, you won&#039;t have to care about them&lt;br /&gt;
2010-11-22 03:08:09 &amp;lt; Jumpyshoes&amp;gt; okay, i think this is horribly wrong&lt;br /&gt;
2010-11-22 03:08:17 &amp;lt; Dark_Shikari&amp;gt; use pastebin btw instead of pasting tons of shit&lt;br /&gt;
2010-11-22 03:08:42 &amp;lt; Jumpyshoes&amp;gt; this is going to be wrong and i will be laughed at &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-22 03:09:02 &amp;lt; Jumpyshoes&amp;gt; well whatever&lt;br /&gt;
2010-11-22 03:09:05 &amp;lt; Jumpyshoes&amp;gt; i&#039;m used to looking dumb&lt;br /&gt;
2010-11-22 03:10:28 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/2JCFdD4R&lt;br /&gt;
2010-11-22 03:11:30 &amp;lt; Dark_Shikari&amp;gt; psubw should be lowercase, it&#039;s an instruction&lt;br /&gt;
2010-11-22 03:11:41 &amp;lt; Dark_Shikari&amp;gt; your function has no stores&lt;br /&gt;
2010-11-22 03:11:41 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 03:11:59 &amp;lt; Jumpyshoes&amp;gt; stores?&lt;br /&gt;
2010-11-22 03:12:05 &amp;lt; Dark_Shikari&amp;gt; you know, storing your output&lt;br /&gt;
2010-11-22 03:12:14 &amp;lt; Jumpyshoes&amp;gt; oops&lt;br /&gt;
2010-11-22 03:12:17 &amp;lt; Dark_Shikari&amp;gt; also, n*8, because each iteration handles 8 bytes.&lt;br /&gt;
2010-11-22 03:12:27 &amp;lt; Dark_Shikari&amp;gt; also, can you make that a loop instead of %rep?&lt;br /&gt;
2010-11-22 03:12:57 &amp;lt; Jumpyshoes&amp;gt; grah, 8 * 8 = 64&lt;br /&gt;
2010-11-22 03:13:21 &amp;lt; Jumpyshoes&amp;gt; wouldn&#039;t i need another variable for a loop?&lt;br /&gt;
2010-11-22 03:13:52 &amp;lt; Dark_Shikari&amp;gt; Yes.&lt;br /&gt;
2010-11-22 03:13:54 &amp;lt; Dark_Shikari&amp;gt; you could do something like&lt;br /&gt;
2010-11-22 03:13:59 &amp;lt; Dark_Shikari&amp;gt; mov r3d, 8&lt;br /&gt;
2010-11-22 03:14:03 &amp;lt; Dark_Shikari&amp;gt; the dec r3d on each iteration&lt;br /&gt;
2010-11-22 03:14:17 &amp;lt; Jumpyshoes&amp;gt; then wouldn&#039;t i need another variable declared in the func?&lt;br /&gt;
2010-11-22 03:14:24 &amp;lt; Dark_Shikari&amp;gt; yes, you&#039;d have to do 3,4 instead of 3,3&lt;br /&gt;
2010-11-22 03:14:35 &amp;lt; Jumpyshoes&amp;gt; oh, okay&lt;br /&gt;
2010-11-22 03:14:52 &amp;lt; Dark_Shikari&amp;gt; also, psubw can take input from memory&lt;br /&gt;
2010-11-22 03:14:54 &amp;lt; Dark_Shikari&amp;gt; so you only need one load&lt;br /&gt;
2010-11-22 03:14:55 &amp;lt; Dark_Shikari&amp;gt; i.e.&lt;br /&gt;
2010-11-22 03:14:57 &amp;lt; Dark_Shikari&amp;gt; movq mm0, blah&lt;br /&gt;
2010-11-22 03:15:00 &amp;lt; Dark_Shikari&amp;gt; psubw mm0, blah2&lt;br /&gt;
2010-11-22 03:15:19 &amp;lt; Jumpyshoes&amp;gt; ooh&lt;br /&gt;
2010-11-22 03:15:46 &amp;lt; Jumpyshoes&amp;gt; that is nice&lt;br /&gt;
2010-11-22 03:15:59 &amp;lt; Dark_Shikari&amp;gt; all instructions can access memory in their second argument.&lt;br /&gt;
2010-11-22 03:16:05 &amp;lt; Dark_Shikari&amp;gt; well, almost all.&lt;br /&gt;
2010-11-22 03:16:27 &amp;lt; Jumpyshoes&amp;gt; what was the command for subtracting 1, dec?&lt;br /&gt;
2010-11-22 03:16:47 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 03:16:50 &amp;lt; Dark_Shikari&amp;gt; it&#039;s like sub val, 1&lt;br /&gt;
2010-11-22 03:16:54 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 03:16:58 &amp;lt; Dark_Shikari&amp;gt; decrement&lt;br /&gt;
2010-11-22 03:17:23 &amp;lt; Jumpyshoes&amp;gt; oh, and do i need a ret?&lt;br /&gt;
2010-11-22 03:18:33 &amp;lt; Dark_Shikari&amp;gt; yes, at the end&lt;br /&gt;
2010-11-22 03:18:41 &amp;lt; Dark_Shikari&amp;gt; just like in c&lt;br /&gt;
2010-11-22 03:21:06 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/HLCed9Jv&lt;br /&gt;
2010-11-22 03:21:32 &amp;lt; Dark_Shikari&amp;gt; .loop should have a :&lt;br /&gt;
2010-11-22 03:21:42 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 03:21:47 &amp;lt; Dark_Shikari&amp;gt; in address expressions, you have to use native sizes&lt;br /&gt;
2010-11-22 03:21:50 &amp;lt; Dark_Shikari&amp;gt; so inside the [], no d&lt;br /&gt;
2010-11-22 03:22:01 &amp;lt; Dark_Shikari&amp;gt; other than that, you&#039;re done!&lt;br /&gt;
2010-11-22 03:22:19 &amp;lt; Jumpyshoes&amp;gt; woah, that only took three revisions&lt;br /&gt;
2010-11-22 03:22:37 &amp;lt; Jumpyshoes&amp;gt; actually wait&lt;br /&gt;
2010-11-22 03:22:51 &amp;lt; Jumpyshoes&amp;gt; i&#039;m dealing with int16, and looping 64 times&lt;br /&gt;
2010-11-22 03:23:05 &amp;lt; Jumpyshoes&amp;gt; wouldn&#039;t i need to do more than 8 loops? since mm is 64 bits&lt;br /&gt;
2010-11-22 03:23:27 &amp;lt; Dark_Shikari&amp;gt; ah yes, you&#039;ll have to do 16 loops.&lt;br /&gt;
2010-11-22 03:23:41 &amp;lt; Dark_Shikari&amp;gt; now, btw, here&#039;s the big nice part about writing x264 asm&lt;br /&gt;
2010-11-22 03:23:44 &amp;lt; Dark_Shikari&amp;gt; make checkasm;./checkasm&lt;br /&gt;
2010-11-22 03:24:02 &amp;lt; Jumpyshoes&amp;gt; where do i do that?&lt;br /&gt;
2010-11-22 03:24:26 &amp;lt; Dark_Shikari&amp;gt; in your terminal&lt;br /&gt;
2010-11-22 03:24:44 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 03:25:00 &amp;lt; Jumpyshoes&amp;gt; lots of warnings thar&lt;br /&gt;
2010-11-22 03:25:37 &amp;lt; Jumpyshoes&amp;gt; oh and there&#039;s an error&lt;br /&gt;
2010-11-22 03:25:43 &amp;lt; Dark_Shikari&amp;gt; error?  what&#039;d you do&lt;br /&gt;
2010-11-22 03:25:50 &amp;lt; Jumpyshoes&amp;gt; i have no clue&lt;br /&gt;
2010-11-22 03:26:08 &amp;lt; Jumpyshoes&amp;gt; common/x86/const-a.asm:50: error: undefined symbol `BIT_DEPTH&#039; (first use)&lt;br /&gt;
2010-11-22 03:26:09 &amp;lt; Jumpyshoes&amp;gt; common/x86/const-a.asm:50: error:  (Each undefined symbol is reported only once.)&lt;br /&gt;
2010-11-22 03:26:14 &amp;lt; Dark_Shikari&amp;gt; you need to reconfigure&lt;br /&gt;
2010-11-22 03:26:14 &amp;lt; darkbringer&amp;gt; ./configure&lt;br /&gt;
2010-11-22 03:26:17 &amp;lt; Jumpyshoes&amp;gt; oh right&lt;br /&gt;
2010-11-22 03:26:18 &amp;lt; Jumpyshoes&amp;gt; since i pulled it&lt;br /&gt;
2010-11-22 03:28:04 &amp;lt; Jumpyshoes&amp;gt; x264: All tests passed Yeah :)&lt;br /&gt;
2010-11-22 03:28:22 &amp;lt; Dark_Shikari&amp;gt; you just ran unit tests on every asm function in x264.&lt;br /&gt;
2010-11-22 03:28:27 &amp;lt; Jumpyshoes&amp;gt; woah that is cool&lt;br /&gt;
2010-11-22 03:28:40 &amp;lt; Jumpyshoes&amp;gt; so i can test my func&lt;br /&gt;
2010-11-22 03:28:41 &amp;lt; Jumpyshoes&amp;gt; by adding it?&lt;br /&gt;
2010-11-22 03:28:58 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 03:29:02 &amp;lt; Dark_Shikari&amp;gt; well, I mean&lt;br /&gt;
2010-11-22 03:29:06 &amp;lt; Dark_Shikari&amp;gt; your function doesn&#039;t have a C equivalent in x264&lt;br /&gt;
2010-11-22 03:29:07 &amp;lt; Dark_Shikari&amp;gt; so not really&lt;br /&gt;
2010-11-22 03:29:09 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 03:29:10 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-22 03:29:12 &amp;lt; Dark_Shikari&amp;gt; but for anything with a C equivalent, it can test it&lt;br /&gt;
2010-11-22 03:29:17 &amp;lt; Jumpyshoes&amp;gt; sexy&lt;br /&gt;
2010-11-22 03:29:17 &amp;lt; Dark_Shikari&amp;gt; it of course needs unit test code in checkasm.c&lt;br /&gt;
2010-11-22 03:29:24 &amp;lt; Dark_Shikari&amp;gt; but for  all existing C functions, there&#039;s unit test code&lt;br /&gt;
2010-11-22 03:29:59 &amp;lt; Jumpyshoes&amp;gt; nice&lt;br /&gt;
2010-11-22 03:32:01 &amp;lt; Dark_Shikari&amp;gt; also&lt;br /&gt;
2010-11-22 03:32:03 &amp;lt; Dark_Shikari&amp;gt; ./checkasm --bench&lt;br /&gt;
2010-11-22 03:33:22 &amp;lt; Jumpyshoes&amp;gt; is that the number of clock cycles?&lt;br /&gt;
2010-11-22 03:33:32 &amp;lt; Dark_Shikari&amp;gt; 10ths of a clock cycle&lt;br /&gt;
2010-11-22 03:33:48 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 03:33:51 &amp;lt; Jumpyshoes&amp;gt; crazy&lt;br /&gt;
2010-11-22 03:33:56 &amp;lt; Dark_Shikari&amp;gt; note not all benches are quite accurate, particularly in the case of functions heavily bound by branch mispredictions&lt;br /&gt;
2010-11-22 03:34:07 &amp;lt; Jumpyshoes&amp;gt; add4x4_idct is like&lt;br /&gt;
2010-11-22 03:34:09 &amp;lt; Dark_Shikari&amp;gt; most commonly where C is branchy&lt;br /&gt;
2010-11-22 03:34:11 &amp;lt; Dark_Shikari&amp;gt; and asm isn&#039;t&lt;br /&gt;
2010-11-22 03:34:14 &amp;lt; Dark_Shikari&amp;gt; but most aren&#039;t like that.&lt;br /&gt;
2010-11-22 03:34:16 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 03:34:27 &amp;lt; Jumpyshoes&amp;gt; when do GCI tasks come out?&lt;br /&gt;
2010-11-22 03:34:34 &amp;lt; Dark_Shikari&amp;gt; probably tomorrow&lt;br /&gt;
2010-11-22 03:34:38 &amp;lt; Dark_Shikari&amp;gt; I really need to get to writing up the rest of them&lt;br /&gt;
2010-11-22 03:34:40 &amp;lt; Dark_Shikari&amp;gt; we only have 5&lt;br /&gt;
2010-11-22 03:34:42 &amp;lt; Dark_Shikari&amp;gt; I need more :/&lt;br /&gt;
2010-11-22 03:35:03 &amp;lt; Jumpyshoes&amp;gt; can you add stuff as the contest progresses?&lt;br /&gt;
2010-11-22 03:35:13 &amp;lt; Dark_Shikari&amp;gt; I hope so&lt;br /&gt;
2010-11-22 03:35:18 &amp;lt; Dark_Shikari&amp;gt; according to them I think yes&lt;br /&gt;
2010-11-22 03:35:27 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-22 03:35:28 &amp;lt; Dark_Shikari&amp;gt; as they said you can have a repeatable task just by re-adding it after someone takes it&lt;br /&gt;
2010-11-22 03:36:42 &amp;lt; Jumpyshoes&amp;gt; how hard are these tasks?&lt;br /&gt;
2010-11-22 03:37:10 &amp;lt; Dark_Shikari&amp;gt; http://wiki.videolan.org/X264_GCodeIn_Ideas&lt;br /&gt;
2010-11-22 03:38:37 &amp;lt; Jumpyshoes&amp;gt; interesting&lt;br /&gt;
2010-11-22 03:42:49 &amp;lt; ps-auxw&amp;gt; Dark_Shikari: Just wondering, is there a reason that PIXEL_SAD_C has a separate name argument, instead of constructing the function name using lx/ly and ## concatenation operator?&lt;br /&gt;
2010-11-22 03:42:59 &amp;lt; Dark_Shikari&amp;gt; ps-auxw: nobody did it 5 years ago when it was written&lt;br /&gt;
2010-11-22 03:43:01 &amp;lt; Dark_Shikari&amp;gt; and it hasn&#039;t bee modified since&lt;br /&gt;
2010-11-22 03:43:05 &amp;lt; Dark_Shikari&amp;gt; *been&lt;br /&gt;
2010-11-22 03:43:07 &amp;lt; ps-auxw&amp;gt; I see.&lt;br /&gt;
2010-11-22 03:53:46 &amp;lt; ps-auxw&amp;gt; Would a patch be welcome? ;)&lt;br /&gt;
2010-11-22 03:55:30 &amp;lt; Dark_Shikari&amp;gt; not relaly, kind of a waste of a patch =p&lt;br /&gt;
2010-11-22 03:55:50 &amp;lt; ps-auxw&amp;gt; True, true.&lt;br /&gt;
2010-11-22 08:42:15 &amp;lt; xxthink&amp;gt; &amp;lt; Dark_Shikari&amp;gt; x264 at crf 18 is &amp;quot;almost lossless&amp;quot; too&lt;br /&gt;
2010-11-22 08:42:42 &amp;lt; xxthink&amp;gt; what&#039;s the recommend GOP structure that x264 should use to save the video content?&lt;br /&gt;
2010-11-22 08:42:46 &amp;lt; xxthink&amp;gt; all I frames?&lt;br /&gt;
2010-11-22 08:43:20 &amp;lt; xxthink&amp;gt; sorry, wrong channel&lt;br /&gt;
2010-11-22 08:45:09 &amp;lt; rfw&amp;gt; so, i heard you guys have GCI tasks :D&lt;br /&gt;
2010-11-22 08:45:17 &amp;lt; rfw&amp;gt; hurt me if people have been here about this before me&lt;br /&gt;
2010-11-22 08:47:20 &amp;lt; dj_tjerk&amp;gt; you can check the logs anytime ;)&lt;br /&gt;
2010-11-22 08:47:49 &amp;lt; rfw&amp;gt; heh&lt;br /&gt;
2010-11-22 08:47:54 &amp;lt; rfw&amp;gt; the google site is still being lol :(&lt;br /&gt;
2010-11-22 08:48:25 &amp;lt; dj_tjerk&amp;gt; http://wiki.videolan.org/X264_GCodeIn_Ideas &amp;lt;-- just some ideas, D_S will make an official list tomorrow/today (timezones)&lt;br /&gt;
2010-11-22 08:48:36 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 08:48:43 &amp;lt; rfw&amp;gt; yeah i looked at that&lt;br /&gt;
2010-11-22 08:48:51 &amp;lt; rfw&amp;gt; the regression testing tool looks fun&lt;br /&gt;
2010-11-22 08:48:58 &amp;lt; dj_tjerk&amp;gt; but if you check the logs (see topic) you see D_S giving his awesome asm explanation&lt;br /&gt;
2010-11-22 08:49:20 &amp;lt; rfw&amp;gt; 4MB of bzipped logs&lt;br /&gt;
2010-11-22 08:49:31 &amp;lt; rfw&amp;gt; how big is that uncompressed&lt;br /&gt;
2010-11-22 08:49:33 &amp;lt; dj_tjerk&amp;gt; log*&lt;br /&gt;
2010-11-22 08:49:35 &amp;lt; dj_tjerk&amp;gt; 17MB&lt;br /&gt;
2010-11-22 08:49:40 &amp;lt; rfw&amp;gt; derp&lt;br /&gt;
2010-11-22 08:51:18 &amp;lt; rfw&amp;gt; --- Log opened Thu Jul 24 01:08:59 2008&lt;br /&gt;
2010-11-22 08:51:26 &amp;lt; rfw&amp;gt; this is going to be fun to page through&lt;br /&gt;
2010-11-22 08:51:31 &amp;lt; dj_tjerk&amp;gt; yeh.. you might wanna start reading from the bottom ;)&lt;br /&gt;
2010-11-22 08:51:43 &amp;lt; dj_tjerk&amp;gt; and then scroll up to wherever his awesome asm explanation starts&lt;br /&gt;
2010-11-22 08:53:42 &amp;lt; rfw&amp;gt; reading uncolored logs really isn&#039;t fun&lt;br /&gt;
2010-11-22 08:54:05 &amp;lt; rfw&amp;gt; &amp;quot;I asked you if you understood my explanation of what a function does.&amp;quot;&lt;br /&gt;
2010-11-22 08:54:08 &amp;lt; rfw&amp;gt; somewhere near here?&lt;br /&gt;
2010-11-22 08:54:44 &amp;lt; Kovensky&amp;gt; just a bit more above&lt;br /&gt;
2010-11-22 08:54:49 &amp;lt; rfw&amp;gt; ohi Kovensky&lt;br /&gt;
2010-11-22 08:56:02 &amp;lt; rfw&amp;gt; god i can&#039;t be bothered with this today&lt;br /&gt;
2010-11-22 08:56:13 &amp;lt; rfw&amp;gt; it&#039;s probably going to be like this for another half a day&lt;br /&gt;
2010-11-22 09:01:34 &amp;lt; rfw&amp;gt; bah, i&#039;m not really having much luck at all&lt;br /&gt;
2010-11-22 09:01:41 &amp;lt; rfw&amp;gt; i guess i&#039;ll be around tomorrow then&lt;br /&gt;
2010-11-22 09:01:51 &amp;lt; dj_tjerk&amp;gt; :?&lt;br /&gt;
2010-11-22 09:01:51 &amp;lt; rfw&amp;gt; night&lt;br /&gt;
2010-11-22 09:02:04 &amp;lt; rfw&amp;gt; the gci website is still giving me 500 errors&lt;br /&gt;
2010-11-22 09:02:09 &amp;lt; dj_tjerk&amp;gt; oh.. :|&lt;br /&gt;
2010-11-22 09:02:12 &amp;lt; rfw&amp;gt; yeah :|&lt;br /&gt;
2010-11-22 09:02:27 &amp;lt; rfw&amp;gt; probably from all the other high school kids ddosing google&lt;br /&gt;
2010-11-22 09:04:21 &amp;lt; rfw&amp;gt; tomorrow then :(&lt;br /&gt;
2010-11-22 09:04:22 &amp;lt; rfw&amp;gt; night&lt;br /&gt;
2010-11-22 09:08:16 &amp;lt; Kovensky&amp;gt; http://pastebin.ca/1998693 &amp;lt;-- my version of that for loop (SSE2)&lt;br /&gt;
2010-11-22 09:09:18 &amp;lt; Kovensky&amp;gt; though it&#039;s pretty much the same as the mmext, but with movdqu and xmm instead of movq and mm ._.&lt;br /&gt;
2010-11-22 09:23:09 &amp;lt; Kovensky&amp;gt; http://pastebin.ca/1998700 &amp;lt;-- uh, moving the sub up, fixes out of bounds read / writes&lt;br /&gt;
2010-11-22 09:58:34 &amp;lt; koda|work&amp;gt; hi all&lt;br /&gt;
2010-11-22 09:59:21 &amp;lt; koda|work&amp;gt; is anyone experiencing&lt;br /&gt;
2010-11-22 09:59:24 &amp;lt; koda|work&amp;gt; common/x86/const-a.asm:50: error: undefined symbol `BIT_DEPTH&#039; (first use)&lt;br /&gt;
2010-11-22 09:59:24 &amp;lt; koda|work&amp;gt; ?&lt;br /&gt;
2010-11-22 10:00:44 &amp;lt; koda|work&amp;gt; oh nevermind i forgot to configure cleanly&lt;br /&gt;
2010-11-22 10:06:12 &amp;lt; Dark_Shikari&amp;gt; hah&lt;br /&gt;
2010-11-22 10:24:39 &amp;lt; wipple&amp;gt; Dark_Shikari: sorry, i found a mistake in my first patch&lt;br /&gt;
2010-11-22 10:25:06 &amp;lt; wipple&amp;gt; line 207 should be +if [ &amp;quot;armv6&amp;quot; = &amp;quot;yes&amp;quot; ]; then&lt;br /&gt;
2010-11-22 10:26:01 &amp;lt; Dark_Shikari&amp;gt; applied&lt;br /&gt;
2010-11-22 10:26:12 &amp;lt; wipple&amp;gt; thx&lt;br /&gt;
2010-11-22 10:34:34 &amp;lt; Kovensky&amp;gt; Dark_Shikari: is my loop there correct? (as in, do I need to do it by subing 2 at a time?)&lt;br /&gt;
2010-11-22 10:34:46 &amp;lt; Kovensky&amp;gt; also, is it common for asm code to work backwards through memory?&lt;br /&gt;
2010-11-22 10:35:01 &amp;lt; Dark_Shikari&amp;gt; link?&lt;br /&gt;
2010-11-22 10:35:11 &amp;lt; Dark_Shikari&amp;gt; it&#039;s common to work backwards to avoid the &amp;quot;cmp&amp;quot; before the jump.&lt;br /&gt;
2010-11-22 10:35:12 &amp;lt; Kovensky&amp;gt; http://pastebin.ca/1998700&lt;br /&gt;
2010-11-22 10:35:30 &amp;lt; Dark_Shikari&amp;gt; should be mov r3d, 16 to start, not 8&lt;br /&gt;
2010-11-22 10:36:10 &amp;lt; Dark_Shikari&amp;gt; also if your source is aligned&lt;br /&gt;
2010-11-22 10:36:13 &amp;lt; Dark_Shikari&amp;gt; er, unaligned&lt;br /&gt;
2010-11-22 10:36:19 &amp;lt; Dark_Shikari&amp;gt; you can&#039;t use memory arguments for psubw&lt;br /&gt;
2010-11-22 10:36:29 &amp;lt; Kovensky&amp;gt; I see&lt;br /&gt;
2010-11-22 10:36:50 &amp;lt; Kovensky&amp;gt; so then I either assume the whole thing is aligned and use movdqa, or use two movdqus before the psubw&lt;br /&gt;
2010-11-22 10:37:04 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 10:38:06 &amp;lt; Kovensky&amp;gt; I think the 8 was left there from when I tried using *16 on the addressing (which ofc failed to assemble)&lt;br /&gt;
2010-11-22 10:38:35 &amp;lt; Dark_Shikari&amp;gt; the only purpose of the * is to save instruction space by using &amp;quot;dec&amp;quot;&lt;br /&gt;
2010-11-22 10:38:36 &amp;lt; Dark_Shikari&amp;gt; instead of sub&lt;br /&gt;
2010-11-22 10:38:43 &amp;lt; Dark_Shikari&amp;gt; so for clarity in your case you might as well just mov r3d, 128&lt;br /&gt;
2010-11-22 10:38:45 &amp;lt; Dark_Shikari&amp;gt; and sub 16 on each iteration&lt;br /&gt;
2010-11-22 10:38:54 &amp;lt; Kovensky&amp;gt; http://pastebin.ca/1998753 &amp;lt;-- unaligned, http://pastebin.ca/1998756 &amp;lt;-- aligned&lt;br /&gt;
2010-11-22 10:38:58 &amp;lt; Kovensky&amp;gt; Dark_Shikari: ok&lt;br /&gt;
2010-11-22 10:40:24 &amp;lt; Kovensky&amp;gt; http://pastebin.ca/1998759&lt;br /&gt;
2010-11-22 10:40:49 &amp;lt; Dark_Shikari&amp;gt; I&#039;d put the sub above the jg, and mov 112 instead of 128.&lt;br /&gt;
2010-11-22 10:40:55 &amp;lt; Dark_Shikari&amp;gt; to reduce data dependencies.&lt;br /&gt;
2010-11-22 10:41:19 &amp;lt; Dark_Shikari&amp;gt; and do jge instead of jg&lt;br /&gt;
2010-11-22 10:41:39 &amp;lt; Dark_Shikari&amp;gt; http://pastebin.ca/1998761&lt;br /&gt;
2010-11-22 10:42:04 &amp;lt; Kovensky&amp;gt; feels more natural, except for starting at 112&lt;br /&gt;
2010-11-22 10:45:39 &amp;lt; Dark_Shikari&amp;gt; lololol, in the vp8 experimental branch they removed the low pass filtering from the H and V predictions&lt;br /&gt;
2010-11-22 10:45:45 &amp;lt; Dark_Shikari&amp;gt; .... making them the same as h264&#039;s&lt;br /&gt;
2010-11-22 10:48:08 &amp;lt; Kovensky&amp;gt; lol&lt;br /&gt;
2010-11-22 10:52:01 &amp;lt; koda|work&amp;gt; hey Dark_Shikari, i once found a patch that brought speedbuffering to x264&lt;br /&gt;
2010-11-22 10:52:12 &amp;lt; koda|work&amp;gt; is there any plan to implement it?&lt;br /&gt;
2010-11-22 10:52:37 &amp;lt; Dark_Shikari&amp;gt; it can be done outside of x264&lt;br /&gt;
2010-11-22 10:52:55 &amp;lt; Dark_Shikari&amp;gt; with the presets it should be easy to do now&lt;br /&gt;
2010-11-22 10:53:24 &amp;lt; koda|work&amp;gt; that is a &#039;no&#039;? :p&lt;br /&gt;
2010-11-22 10:53:39 &amp;lt; Dark_Shikari&amp;gt; Probably not given that you can do it outside x264 in just a few lines of code&lt;br /&gt;
2010-11-22 10:54:39 &amp;lt; koda|work&amp;gt; but how would you that like in vlc?&lt;br /&gt;
2010-11-22 10:54:52 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-22 10:57:04 &amp;lt; koda|work&amp;gt; i mean, i patched x264 to have speed and speed-buffer options and then i use them from vlc when i&#039;m transcoding the video and send it on the net&lt;br /&gt;
2010-11-22 10:57:29 &amp;lt; koda|work&amp;gt; without speed and speed-buffer the decoded video would not appear fluid&lt;br /&gt;
2010-11-22 10:57:58 &amp;lt; Dark_Shikari&amp;gt; speed is for the encoder, not the decoder&lt;br /&gt;
2010-11-22 10:58:12 &amp;lt; Dark_Shikari&amp;gt; it&#039;s only &amp;quot;not fluid&amp;quot; if you try to use really slow settings when you can&#039;t handle them&lt;br /&gt;
2010-11-22 10:58:44 &amp;lt; Dark_Shikari&amp;gt; in VLC you could pretty easily add speed buffer code&lt;br /&gt;
2010-11-22 10:58:50 &amp;lt; Dark_Shikari&amp;gt; e.g. adjust encoding speed settings based on how far behind you are&lt;br /&gt;
2010-11-22 10:59:28 &amp;lt; koda|work&amp;gt; i see...&lt;br /&gt;
2010-11-22 10:59:40 &amp;lt; koda|work&amp;gt; i&#039;ll do more testing then&lt;br /&gt;
2010-11-22 10:59:52 &amp;lt; Dark_Shikari&amp;gt; speedcontrol is useful so that you can _always_ use the _slowest_ settings possible&lt;br /&gt;
2010-11-22 11:05:40 &amp;lt; Alex_W&amp;gt; Dark_Shikari: do you know if professionally encoded blu-rays use explicit wpred?&lt;br /&gt;
2010-11-22 11:06:14 &amp;lt; Dark_Shikari&amp;gt; I think so&lt;br /&gt;
2010-11-22 11:06:19 &amp;lt; Dark_Shikari&amp;gt; prolly depends on the encoder&lt;br /&gt;
2010-11-22 11:07:56 &amp;lt; Alex_W&amp;gt; so i wonder if they do it differently to x264 for compatibility reasons, i guess they don&#039;t use dupes at all...&lt;br /&gt;
2010-11-22 11:08:13 &amp;lt; Dark_Shikari&amp;gt; most encoders don&#039;t&lt;br /&gt;
2010-11-22 11:08:53 &amp;lt; Dark_Shikari&amp;gt; so quick, GCI starts today&lt;br /&gt;
2010-11-22 11:09:02 &amp;lt; Dark_Shikari&amp;gt; we need more tasks&lt;br /&gt;
2010-11-22 11:10:01 &amp;lt; Alex_W&amp;gt; then i wonder if it would be possible to have a blu-ray compatible weightp option in x264? ( i mean one that doesn&#039;t break on mediatek chipsets)&lt;br /&gt;
2010-11-22 11:10:11 &amp;lt; Alex_W&amp;gt; what kind of tasks are you looking for?&lt;br /&gt;
2010-11-22 11:10:18 &amp;lt; Dark_Shikari&amp;gt; http://wiki.videolan.org/X264_GCodeIn_Ideas&lt;br /&gt;
2010-11-22 11:10:23 &amp;lt; Dark_Shikari&amp;gt; anything no harder than these&lt;br /&gt;
2010-11-22 11:11:26 &amp;lt; Alex_W&amp;gt; maybe some psy testing?&lt;br /&gt;
2010-11-22 11:11:39 &amp;lt; Dark_Shikari&amp;gt; we would need some psy things to test.&lt;br /&gt;
2010-11-22 11:11:48 &amp;lt; Alex_W&amp;gt; aq-mode 1 vs 2&lt;br /&gt;
2010-11-22 11:12:08 &amp;lt; Dark_Shikari&amp;gt; if you want to create a psy curve for someone to test, feel free&lt;br /&gt;
2010-11-22 11:12:11 &amp;lt; Dark_Shikari&amp;gt; e.g. by adjusting AQ, etc, etc&lt;br /&gt;
2010-11-22 11:12:39 &amp;lt; Dark_Shikari&amp;gt; but I think we need to have something available to test&lt;br /&gt;
2010-11-22 11:12:42 &amp;lt; Dark_Shikari&amp;gt; as opposed to making htem write it&lt;br /&gt;
2010-11-22 11:15:21 &amp;lt; Dark_Shikari&amp;gt; import ideas from http://wiki.videolan.org/X264_TODO etc&lt;br /&gt;
2010-11-22 11:19:58 &amp;lt; Dark_Shikari&amp;gt; Alex_W: tl;dr this is a chance to test stuff&lt;br /&gt;
2010-11-22 11:20:02 &amp;lt; Dark_Shikari&amp;gt; prepare stuff to be tested.&lt;br /&gt;
2010-11-22 11:20:12 &amp;lt; Alex_W&amp;gt; well i&#039;m already testing a different AQ curve at low variances, though i think the one i&#039;m using atm is probably too aggressive&lt;br /&gt;
2010-11-22 11:23:10 &amp;lt; Alex_W&amp;gt; unfortunately it seems like preserving low variance dark areas is going to take a lot of bits, at least based on testing with an elevated black level&lt;br /&gt;
2010-11-22 11:25:59 &amp;lt; Alex_W&amp;gt; also i think RD bskip might be a problem for these areas as well&lt;br /&gt;
2010-11-22 11:30:18 &amp;lt; Alex_W&amp;gt; anyway here&#039;s my current change to aq-mode 1 at low variances: http://pastebin.com/UVfMCC5p&lt;br /&gt;
2010-11-22 11:38:36 &amp;lt; Dark_Shikari&amp;gt; I wonder if we can calculate the theoretically &amp;quot;correct&amp;quot; value?&lt;br /&gt;
2010-11-22 11:38:41 &amp;lt; Dark_Shikari&amp;gt; i.e. considering the effect of BIT_DEPTH&lt;br /&gt;
2010-11-22 11:38:49 &amp;lt; Dark_Shikari&amp;gt; er, correct curve&lt;br /&gt;
2010-11-22 11:39:02 &amp;lt; Dark_Shikari&amp;gt; in other words, there are two contributors to variance-related quality:&lt;br /&gt;
2010-11-22 11:39:06 &amp;lt; Dark_Shikari&amp;gt; 1) the normal effect&lt;br /&gt;
2010-11-22 11:39:08 &amp;lt; Dark_Shikari&amp;gt; 2) truncation&lt;br /&gt;
2010-11-22 11:39:17 &amp;lt; Dark_Shikari&amp;gt; at lower variance, the effect of 2) rises and the effect of 1) drops&lt;br /&gt;
2010-11-22 11:39:22 &amp;lt; Dark_Shikari&amp;gt; well, the relative effect of 1) drops&lt;br /&gt;
2010-11-22 11:50:10 &amp;lt; Alex_W&amp;gt; well i&#039;m certainly open to any suggestions on how to improve this&lt;br /&gt;
2010-11-22 11:52:11 &amp;lt; Alex_W&amp;gt; how low should the maximum negative QP offset be anyway? (i mean for variance=1)&lt;br /&gt;
2010-11-22 11:52:25 &amp;lt; Dark_Shikari&amp;gt; -20?&lt;br /&gt;
2010-11-22 11:52:44 &amp;lt; Dark_Shikari&amp;gt; -15?&lt;br /&gt;
2010-11-22 11:53:26 &amp;lt; Alex_W&amp;gt; right now it&#039;s approximately the same as the one that was originally used in aq-mode 1 which was around -14.4&lt;br /&gt;
2010-11-22 11:54:30 &amp;lt; Alex_W&amp;gt; and the difference between variance 512 and variance 1 is around -9 atm with my new curve&lt;br /&gt;
2010-11-22 11:54:37 &amp;lt; Dark_Shikari&amp;gt; what did it used to be?&lt;br /&gt;
2010-11-22 11:55:25 &amp;lt; Alex_W&amp;gt; the difference between 512 and 1 or the maximum negative offset for variance 1?&lt;br /&gt;
2010-11-22 11:55:32 &amp;lt; Dark_Shikari&amp;gt; former&lt;br /&gt;
2010-11-22 11:55:38 &amp;lt; Alex_W&amp;gt; lemme check&lt;br /&gt;
2010-11-22 11:56:15 &amp;lt; Dark_Shikari&amp;gt; ok, I added a psy test task&lt;br /&gt;
2010-11-22 11:56:16 &amp;lt; Dark_Shikari&amp;gt; what else&lt;br /&gt;
2010-11-22 11:56:19 &amp;lt; Dark_Shikari&amp;gt; up to 6 tasks&lt;br /&gt;
2010-11-22 11:57:37 &amp;lt; Alex_W&amp;gt; actually the difference in QPs is about the same but the shape of the curve between those two points is much different now&lt;br /&gt;
2010-11-22 11:57:47 &amp;lt; Dark_Shikari&amp;gt; ah.&lt;br /&gt;
2010-11-22 11:59:15 &amp;lt; Alex_W&amp;gt; but this new curve will likely increase bitrate quite a lot on clips with lots of low variance areas at the same crf&lt;br /&gt;
2010-11-22 12:00:48 &amp;lt; Alex_W&amp;gt; but i really wonder if there could be a better way to deal with these areas than just throwing huge amounts of bits at them to exactly preserve their noise/dither&lt;br /&gt;
2010-11-22 12:05:37 &amp;lt; Alex_W&amp;gt; Dark_Shikari: btw do you have any test content that shows noticeable banding/blocking in low variance areas even at reasonably high bitrates with the current aq-mode 1?&lt;br /&gt;
2010-11-22 12:06:08 &amp;lt; Dark_Shikari&amp;gt; dunno.  you could just create an artificial gradient&lt;br /&gt;
2010-11-22 12:06:30 &amp;lt; Dark_Shikari&amp;gt; possible solution: quantization-aware dither&lt;br /&gt;
2010-11-22 12:06:40 &amp;lt; Alex_W&amp;gt; yeah i was thinking about doing that&lt;br /&gt;
2010-11-22 12:06:55 &amp;lt; Alex_W&amp;gt; explain?&lt;br /&gt;
2010-11-22 12:07:15 &amp;lt; Dark_Shikari&amp;gt; i.e. just make dither patterns consisting of basis functions&lt;br /&gt;
2010-11-22 12:07:43 &amp;lt; Dark_Shikari&amp;gt; not sure how you would get that, but it&#039;s a desired result&lt;br /&gt;
2010-11-22 12:07:48 &amp;lt; Alex_W&amp;gt; yes but how do you decide which basis functions to use&lt;br /&gt;
2010-11-22 12:08:00 &amp;lt; Dark_Shikari&amp;gt; the highest frequency one.&lt;br /&gt;
2010-11-22 12:08:24 &amp;lt; Dark_Shikari&amp;gt; to misquote gmaxwell (I think it was), &amp;quot;blur it out, then cover it up with ants&amp;quot;&lt;br /&gt;
2010-11-22 12:08:31 &amp;lt; Alex_W&amp;gt; so [7][7] in the 8x8 transform?&lt;br /&gt;
2010-11-22 12:08:34 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 12:08:57 &amp;lt; Alex_W&amp;gt; just one basis function or a combination of a few different ones?&lt;br /&gt;
2010-11-22 12:08:57 &amp;lt; Dark_Shikari&amp;gt; This might naturally happen if we did floyd-steinberg in the dct&lt;br /&gt;
2010-11-22 12:09:07 &amp;lt; Dark_Shikari&amp;gt; or some other batching of nearby coeffs&lt;br /&gt;
2010-11-22 12:09:45 &amp;lt; Alex_W&amp;gt; well this is really what psy-trellis would do ideally&lt;br /&gt;
2010-11-22 12:11:08 &amp;lt; Alex_W&amp;gt; but yes if the noise has a low enough magnitude i think it could definitely be worthwhile to just remove it and then replace it with some that looks similar but costs a lot less bits&lt;br /&gt;
2010-11-22 12:11:28 &amp;lt; Dark_Shikari&amp;gt; I wasn&#039;t thinking of that&lt;br /&gt;
2010-11-22 12:11:32 &amp;lt; Dark_Shikari&amp;gt; I was thinking of e.g. 10-bit input&lt;br /&gt;
2010-11-22 12:11:38 &amp;lt; Dark_Shikari&amp;gt; and then dithering internally to x264 somehow&lt;br /&gt;
2010-11-22 12:11:42 &amp;lt; Dark_Shikari&amp;gt; not necessarily literally that&lt;br /&gt;
2010-11-22 12:11:54 &amp;lt; Dark_Shikari&amp;gt; but rather doing something AS A DITHER&lt;br /&gt;
2010-11-22 12:11:57 &amp;lt; Dark_Shikari&amp;gt; not as REPLACING NOISE&lt;br /&gt;
2010-11-22 12:14:58 &amp;lt; Alex_W&amp;gt; well either way i think this would be much better than having to code some MBs as low as QP 6 just to stop the damn blocking/banding&lt;br /&gt;
2010-11-22 12:15:18 &amp;lt; Dark_Shikari&amp;gt; if you had a quantizer that actually retained HF energy you wouldn&#039;t really need qp 6&lt;br /&gt;
2010-11-22 12:15:54 &amp;lt; jenny`&amp;gt; hey dark - i figured out the issues i was having (if you are curious)&lt;br /&gt;
2010-11-22 12:15:58 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-22 12:16:19 &amp;lt; jenny`&amp;gt; the server was sending compressed frames at 30 Hz but the client wasnt able to keep up&lt;br /&gt;
2010-11-22 12:16:37 &amp;lt; Dark_Shikari&amp;gt; common problem in systems with no client feedback for saying &amp;quot;I&#039;m too slow&amp;quot;&lt;br /&gt;
2010-11-22 12:16:57 &amp;lt; jenny`&amp;gt; decode was taking too long, and it indeed was buffering @ the network level&lt;br /&gt;
2010-11-22 12:17:18 &amp;lt; jenny`&amp;gt; yep yep&lt;br /&gt;
2010-11-22 12:19:45 &amp;lt; horlicks&amp;gt; thanks for the correction DS :p&lt;br /&gt;
2010-11-22 12:20:45 &amp;lt; Dark_Shikari&amp;gt; weightp is an explicit weighting applied to one input&lt;br /&gt;
2010-11-22 12:20:56 &amp;lt; Dark_Shikari&amp;gt; weightb is an implicit (or, optionally, explicit) weighting applied to two inputs&lt;br /&gt;
2010-11-22 12:21:24 &amp;lt; horlicks&amp;gt; yeah I understand, seems kinda obvious now&lt;br /&gt;
2010-11-22 12:22:02 &amp;lt; horlicks&amp;gt; maybe that&#039;s something I can do after mbaff :)&lt;br /&gt;
2010-11-22 12:22:18 &amp;lt; Dark_Shikari&amp;gt; what is &amp;quot;that&amp;quot;&lt;br /&gt;
2010-11-22 12:22:39 &amp;lt; horlicks&amp;gt; one sec&lt;br /&gt;
2010-11-22 12:23:09 &amp;lt; horlicks&amp;gt; &amp;quot;Make weightp work with interlacing. Preferably abuse reference duplication to make it useful for MBAFF.&amp;quot;&lt;br /&gt;
2010-11-22 12:23:16 &amp;lt; Dark_Shikari&amp;gt; ah yes&lt;br /&gt;
2010-11-22 12:23:36 &amp;lt; horlicks&amp;gt; anyway, I&#039;m off&lt;br /&gt;
2010-11-22 12:23:48 &amp;lt; Dark_Shikari&amp;gt; \o&lt;br /&gt;
2010-11-22 12:31:54 &amp;lt; Alex_W&amp;gt; &amp;lt;Dark_Shikari&amp;gt; I wonder if we can calculate the theoretically &amp;quot;correct&amp;quot; curve? &amp;lt;-- how would you go about doing this anyway?&lt;br /&gt;
2010-11-22 12:32:08 &amp;lt; Dark_Shikari&amp;gt; calculate the effect of truncation on quality loss&lt;br /&gt;
2010-11-22 12:32:26 &amp;lt; Dark_Shikari&amp;gt; that is:&lt;br /&gt;
2010-11-22 12:32:33 &amp;lt; Dark_Shikari&amp;gt; 1) Assume a Laplace distribution of coefficients.&lt;br /&gt;
2010-11-22 12:33:05 &amp;lt; Dark_Shikari&amp;gt; 2) Calculate quality loss due to the quantization process&lt;br /&gt;
2010-11-22 12:33:11 &amp;lt; Dark_Shikari&amp;gt; 3) Calculate quality loss due to truncation upon idct&lt;br /&gt;
2010-11-22 12:33:24 &amp;lt; Dark_Shikari&amp;gt; 4) create a curve by combining the two&lt;br /&gt;
2010-11-22 12:34:36 &amp;lt; Alex_W&amp;gt; i see, i doubt that the distribution would be laplacian for noise/dither in these cases though&lt;br /&gt;
2010-11-22 12:34:48 &amp;lt; Dark_Shikari&amp;gt; why not?&lt;br /&gt;
2010-11-22 12:36:56 &amp;lt; Alex_W&amp;gt; well if it&#039;s laplacian then bitrate should probably double every 4 - 6 QPs right? from what i&#039;ve seen so far it doubles much quicker than that&lt;br /&gt;
2010-11-22 12:37:50 &amp;lt; Dark_Shikari&amp;gt; it does once you get to the smooth domain of the curve&lt;br /&gt;
2010-11-22 12:38:03 &amp;lt; Dark_Shikari&amp;gt; the reason it doesn&#039;t seem to do that is because there&#039;s a threshold beyond which everything is zeroed&lt;br /&gt;
2010-11-22 12:38:07 &amp;lt; Dark_Shikari&amp;gt; because the magnitude of the noise is so low&lt;br /&gt;
2010-11-22 12:38:20 &amp;lt; Dark_Shikari&amp;gt; so you need to get beyond the discontinuous part of the curve&lt;br /&gt;
2010-11-22 12:38:23 &amp;lt; Dark_Shikari&amp;gt; then it&#039;s smooth and laplacian&lt;br /&gt;
2010-11-22 12:40:48 &amp;lt; Alex_W&amp;gt; also because the idct always rounds up should we try to compensate for this by adding small negative offsets to the DC coeff or would that be useless?&lt;br /&gt;
2010-11-22 12:41:00 &amp;lt; Dark_Shikari&amp;gt; probably useless&lt;br /&gt;
2010-11-22 14:34:52 &amp;lt; Dark_Shikari&amp;gt; pengvado: ping&lt;br /&gt;
2010-11-22 14:35:28 &amp;lt; Dark_Shikari&amp;gt; of the patches at http://pastebin.com/rW4dsM9J , which can I commit now?&lt;br /&gt;
2010-11-22 14:41:42 &amp;lt; Dark_Shikari&amp;gt; I will push them all today if you don&#039;t complain&lt;br /&gt;
2010-11-22 14:52:50 &amp;lt; jarod&amp;gt; so that patch&lt;br /&gt;
2010-11-22 14:52:53 &amp;lt; jarod&amp;gt; --version&lt;br /&gt;
2010-11-22 14:53:07 &amp;lt; jarod&amp;gt; is such inaccurate info useful?&lt;br /&gt;
2010-11-22 14:53:53 &amp;lt; Dark_Shikari&amp;gt; go away troll&lt;br /&gt;
2010-11-22 14:54:07 &amp;lt; jarod&amp;gt; its not to troll&lt;br /&gt;
2010-11-22 14:54:23 &amp;lt; jarod&amp;gt; just saying one revision can make a huge difference&lt;br /&gt;
2010-11-22 14:54:38 &amp;lt; jarod&amp;gt; unless you meant kierank&lt;br /&gt;
2010-11-22 14:55:37 &amp;lt; jarod&amp;gt; but if you want troll&lt;br /&gt;
2010-11-22 14:55:48 &amp;lt; jarod&amp;gt; allow me to &amp;lt;?php header(&#039;Location: http://www.webmproject.org/tools/vp8-sdk/&#039;); ?&amp;gt;&lt;br /&gt;
2010-11-22 14:57:52 &amp;lt; jarod&amp;gt; your mood swings are worst than a 8 month pregnant female&lt;br /&gt;
2010-11-22 14:59:05 &amp;lt; pengvado&amp;gt; which one revision is inaccurate?&lt;br /&gt;
2010-11-22 14:59:48 &amp;lt; pengvado&amp;gt; Dark_Shikari: 1,3,4,6,7,8 ok&lt;br /&gt;
2010-11-22 15:00:00 &amp;lt; pengvado&amp;gt; 2: I agree with mru&#039;s comments regarding nulls&lt;br /&gt;
2010-11-22 15:00:37 &amp;lt; pengvado&amp;gt; 5: that&#039;s a lot of repitions of that if/else block. sounds like a job for a macro.&lt;br /&gt;
2010-11-22 15:00:52 &amp;lt; kierank&amp;gt; oh dear. one of the replicated x264 blu-rays has a problem&lt;br /&gt;
2010-11-22 15:00:57 &amp;lt; Dark_Shikari&amp;gt; oh no&lt;br /&gt;
2010-11-22 15:01:08 &amp;lt; Dark_Shikari&amp;gt; do we know what the issue is?&lt;br /&gt;
2010-11-22 15:01:10 &amp;lt; Dark_Shikari&amp;gt; and if it&#039;s x264&#039;s problem?&lt;br /&gt;
2010-11-22 15:01:20 &amp;lt; kierank&amp;gt; &amp;quot;We&#039;ve tested the disc extensively without bumping into any problems, however after replication the customer is complaining the disc is pixelating at a certain scene in the movie.&amp;quot;&lt;br /&gt;
2010-11-22 15:01:52 &amp;lt; Dark_Shikari&amp;gt; :&amp;gt;&lt;br /&gt;
2010-11-22 15:01:56 &amp;lt; Dark_Shikari&amp;gt; Do we have a sample?&lt;br /&gt;
2010-11-22 15:02:12 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: ^&lt;br /&gt;
2010-11-22 15:02:38 &amp;lt; Dark_Shikari&amp;gt; what does &amp;quot;replicated&amp;quot; mean -- they&#039;ve already printed all the blu-rays?&lt;br /&gt;
2010-11-22 15:02:58 &amp;lt; kierank&amp;gt; I fear that&#039;s exactly what it means.&lt;br /&gt;
2010-11-22 15:03:43 &amp;lt; Dark_Shikari&amp;gt; what could cause that, a problem on a particular Blu-ray player that they didn&#039;t test on?&lt;br /&gt;
2010-11-22 15:03:58 &amp;lt; jarod&amp;gt; not testing and showing results @ devs ftf.... fuck commercialism, i hope its my fault&lt;br /&gt;
2010-11-22 15:04:03 &amp;lt; kierank&amp;gt; I guess&lt;br /&gt;
2010-11-22 15:05:49 &amp;lt; Dark_Shikari&amp;gt; kierank: can we get them to give a sample or something under NDA?&lt;br /&gt;
2010-11-22 15:05:50 &amp;lt; Dark_Shikari&amp;gt; or whatnot&lt;br /&gt;
2010-11-22 15:06:05 &amp;lt; kierank&amp;gt; yes i will ask&lt;br /&gt;
2010-11-22 15:06:10 &amp;lt; Dark_Shikari&amp;gt; so we can see if we have to commit sepukku or not&lt;br /&gt;
2010-11-22 15:06:19 &amp;lt; tjoener&amp;gt; I know there is a problem in x264 with dark scenes (bedroom scene with ellie and carl in up)&lt;br /&gt;
2010-11-22 15:06:27 &amp;lt; tjoener&amp;gt; it gets quite pixelated&lt;br /&gt;
2010-11-22 15:06:32 &amp;lt; Dark_Shikari&amp;gt; tjoener: that&#039;s not what they mean&lt;br /&gt;
2010-11-22 15:06:40 &amp;lt; Dark_Shikari&amp;gt; that isn&#039;t a &amp;quot;problem in x264&amp;quot;&lt;br /&gt;
2010-11-22 15:06:43 &amp;lt; tjoener&amp;gt; could be&lt;br /&gt;
2010-11-22 15:06:43 &amp;lt; Dark_Shikari&amp;gt; that&#039;s &amp;quot;you not using enough bitrate&amp;quot; =p&lt;br /&gt;
2010-11-22 15:06:48 &amp;lt; tjoener&amp;gt; haha&lt;br /&gt;
2010-11-22 15:06:51 &amp;lt; CIA-98&amp;gt; x264: James Darnley  master * r8eaf8a66d5 x264/filters/video/resize.c: Fix resize filter rounding code&lt;br /&gt;
2010-11-22 15:06:53 &amp;lt; tjoener&amp;gt; well its only in dark scenes&lt;br /&gt;
2010-11-22 15:06:54 &amp;lt; Dark_Shikari&amp;gt; at blu-ray bitrates, such a thing is basically meaningless&lt;br /&gt;
2010-11-22 15:06:59 &amp;lt; Dark_Shikari&amp;gt; or more accurately&lt;br /&gt;
2010-11-22 15:07:02 &amp;lt; tjoener&amp;gt; bright scenes are very VERY nice&lt;br /&gt;
2010-11-22 15:07:02 &amp;lt; Dark_Shikari&amp;gt; your monitor is very badly calibrated&lt;br /&gt;
2010-11-22 15:07:03 &amp;lt; CIA-98&amp;gt; x264: Anton Mitrofanov  master * raf1a7413af x264/encoder/ (encoder.c slicetype.c):&lt;br /&gt;
2010-11-22 15:07:03 &amp;lt; CIA-98&amp;gt; x264: Fix regression in chroma weightp&lt;br /&gt;
2010-11-22 15:07:03 &amp;lt; CIA-98&amp;gt; x264: Missing cache calls could cause artifacts, encoder/decoder desync.&lt;br /&gt;
2010-11-22 15:07:11 &amp;lt; Dark_Shikari&amp;gt; x264 assumes your monitor is calibrated correctly&lt;br /&gt;
2010-11-22 15:07:12 &amp;lt; tjoener&amp;gt; well ok&lt;br /&gt;
2010-11-22 15:07:13 &amp;lt; Dark_Shikari&amp;gt; i.e. blacks are black&lt;br /&gt;
2010-11-22 15:07:19 &amp;lt; tjoener&amp;gt; my monitor could be the issue&lt;br /&gt;
2010-11-22 15:07:19 &amp;lt; Dark_Shikari&amp;gt; if blacks are not black, the results will look very bad&lt;br /&gt;
2010-11-22 15:07:27 &amp;lt; tjoener&amp;gt; monitors nowadays are quite crappy&lt;br /&gt;
2010-11-22 15:07:42 &amp;lt; tjoener&amp;gt; havent had the time to look into it yet&lt;br /&gt;
2010-11-22 15:08:01 &amp;lt; tjoener&amp;gt; Ive got a second one though, old acer flatscreen with far better colours as the new one&lt;br /&gt;
2010-11-22 15:08:39 &amp;lt; Dark_Shikari&amp;gt; kierank: you can tell them that I can investigate it to see if there&#039;s anything weird about it that could cause problems in broken players, etc&lt;br /&gt;
2010-11-22 15:08:44 &amp;lt; Dark_Shikari&amp;gt; i.e. any &amp;quot;common bug triggers&amp;quot;&lt;br /&gt;
2010-11-22 15:09:40 &amp;lt; Dark_Shikari&amp;gt; I have a hunch, but I can&#039;t say what it is until I get a sample.&lt;br /&gt;
2010-11-22 15:10:21 &amp;lt; tjoener&amp;gt; weightp (like flash?)&lt;br /&gt;
2010-11-22 15:10:35 &amp;lt; Dark_Shikari&amp;gt; no&lt;br /&gt;
2010-11-22 15:25:08 &amp;lt; Dark_Shikari&amp;gt; kierank: well, if this sinks everything, I&#039;d like to know&lt;br /&gt;
2010-11-22 15:26:45 &amp;lt; kierank&amp;gt; ok&lt;br /&gt;
2010-11-22 16:11:58 &amp;lt; Jumpyshoes&amp;gt; hey Dark_Shikari, would it be too much if i took on the GCI task of writing an assembly function?&lt;br /&gt;
2010-11-22 16:12:20 &amp;lt; Dark_Shikari&amp;gt; Of course not.&lt;br /&gt;
2010-11-22 16:12:23 &amp;lt; Dark_Shikari&amp;gt; That&#039;s a repeatable task.&lt;br /&gt;
2010-11-22 16:12:28 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-22 16:12:29 &amp;lt; Dark_Shikari&amp;gt; If you take it, we&#039;ll add it in again&lt;br /&gt;
2010-11-22 16:12:33 &amp;lt; Jumpyshoes&amp;gt; i think i will then&lt;br /&gt;
2010-11-22 16:12:33 &amp;lt; holger_&amp;gt; Jumpyshoes:  do you have something specific on your mind?&lt;br /&gt;
2010-11-22 16:12:40 &amp;lt; Dark_Shikari&amp;gt; Yeah, come up with something first&lt;br /&gt;
2010-11-22 16:12:42 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 16:12:45 &amp;lt; Jumpyshoes&amp;gt; i&#039;ll need to do that at home&lt;br /&gt;
2010-11-22 16:12:51 &amp;lt; Dark_Shikari&amp;gt; keep in mind, almost all new opportunities in asm functions are in the category of &amp;quot;high bit depth&amp;quot;&lt;br /&gt;
2010-11-22 16:12:52 &amp;lt; Jumpyshoes&amp;gt; and look for a simple function&lt;br /&gt;
2010-11-22 16:12:59 &amp;lt; Dark_Shikari&amp;gt; as, before high bit depth, we had everything done basically (for x86, at least)&lt;br /&gt;
2010-11-22 16:13:08 &amp;lt; Dark_Shikari&amp;gt; but now with high bit depth, there&#039;s tons of missing functions&lt;br /&gt;
2010-11-22 16:13:12 &amp;lt; Dark_Shikari&amp;gt; for example, dequant.&lt;br /&gt;
2010-11-22 16:13:23 &amp;lt; Jumpyshoes&amp;gt; so, for example, 10-bit?&lt;br /&gt;
2010-11-22 16:13:32 &amp;lt; Dark_Shikari&amp;gt; high bit depth encompasses &amp;gt;8-bit&lt;br /&gt;
2010-11-22 16:13:38 &amp;lt; Dark_Shikari&amp;gt; the thing that makes it different is:&lt;br /&gt;
2010-11-22 16:13:41 &amp;lt; Dark_Shikari&amp;gt; 1) pixels are 16-bit instead of 8-bit&lt;br /&gt;
2010-11-22 16:13:45 &amp;lt; Dark_Shikari&amp;gt; 2) dct coeffs are 32-bit instead of 16-bit&lt;br /&gt;
2010-11-22 16:13:48 &amp;lt; Dark_Shikari&amp;gt; thus all the asm is different.&lt;br /&gt;
2010-11-22 16:14:06 &amp;lt; Jumpyshoes&amp;gt; but, the same algorithms apply, no?&lt;br /&gt;
2010-11-22 16:14:09 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 16:14:18 &amp;lt; holger_&amp;gt; 3) some things can now overflow that couldn&#039;t before&lt;br /&gt;
2010-11-22 16:14:25 &amp;lt; Dark_Shikari&amp;gt; 4) some things that could overflow before, now can&#039;t&lt;br /&gt;
2010-11-22 16:14:37 &amp;lt; Dark_Shikari&amp;gt; e.g. in 8-bit, they overflowed, but in 16-bit, since all our inputs are no more than 10-bit, don&#039;t&lt;br /&gt;
2010-11-22 16:15:08 &amp;lt; Dark_Shikari&amp;gt; e.g. in dequant, previously, we had two dequant branches, based on whether or not it needed 32-bit or 16-bit intermediate precision to work&lt;br /&gt;
2010-11-22 16:15:08 &amp;lt; Jumpyshoes&amp;gt; isn&#039;t that easier to take care of then?&lt;br /&gt;
2010-11-22 16:15:12 &amp;lt; Dark_Shikari&amp;gt; but now.... we can just do 32-bit&lt;br /&gt;
2010-11-22 16:15:16 &amp;lt; Dark_Shikari&amp;gt; and have no branch&lt;br /&gt;
2010-11-22 16:15:26 &amp;lt; Dark_Shikari&amp;gt; some things are easier, some are harder.&lt;br /&gt;
2010-11-22 16:15:38 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 16:16:17 &amp;lt; Jumpyshoes&amp;gt; is the high bit stuff in the same location in the code?&lt;br /&gt;
2010-11-22 16:17:42 &amp;lt; holger_&amp;gt; pretty much, yeah. look for ifdef HIGH_BIT_DEPTH&lt;br /&gt;
2010-11-22 16:18:27 &amp;lt; Jumpyshoes&amp;gt; thanks&lt;br /&gt;
2010-11-22 16:18:29 &amp;lt; holger_&amp;gt; to see which functions are missing you could probably just run checkasm with and without high bit depth and compare the output&lt;br /&gt;
2010-11-22 16:18:41 &amp;lt; holger_&amp;gt; erm. checkasm --bench of course ;)&lt;br /&gt;
2010-11-22 16:21:46 &amp;lt; Jumpyshoes&amp;gt; how do i run checkasm w/ high bit depth?&lt;br /&gt;
2010-11-22 16:22:04 &amp;lt; holger_&amp;gt; you configure for high bit depth, checkasm gets built accordingly&lt;br /&gt;
2010-11-22 16:22:08 &amp;lt; BugMaster|work&amp;gt; compile it with high bit depth&lt;br /&gt;
2010-11-22 16:22:12 &amp;lt; BugMaster|work&amp;gt; configure --bit-depth=10&lt;br /&gt;
2010-11-22 16:22:26 &amp;lt; Jumpyshoes&amp;gt; ah, okay, thanks&lt;br /&gt;
2010-11-22 16:23:22 &amp;lt; kierank&amp;gt; ^^ first gci person!!!&lt;br /&gt;
2010-11-22 16:23:37 &amp;lt; holger_&amp;gt; we often have more than one asm function btw. _mmx, _sse2, _ssse3, _sse4 are selfexplaining. then there is _sse2_misalign (amd k10 allows misaligned data loads), _c32/_c64 (cacheline split optimized versions), _fastshuffle (denotes somewhat decent ssse3, excludes conroe and atom)&lt;br /&gt;
2010-11-22 16:23:55 &amp;lt; Jumpyshoes&amp;gt; kierank: i&#039;m a dumbass so don&#039;t expect much&lt;br /&gt;
2010-11-22 16:27:14 &amp;lt; holger_&amp;gt; asm isn&#039;t that hard in itself. i see dark_shikari already gave you his crash course. you just need to visualize what you&#039;re doing (or if you&#039;re bad at that, waste a lot of paper documenting what you think you&#039;re doing ;)&lt;br /&gt;
2010-11-22 16:27:49 &amp;lt; callahanafk&amp;gt; Just pick one and make a bad attempt.  Then DK&#039;s head will explode and he&#039;ll fix it for you.&lt;br /&gt;
2010-11-22 16:27:51 &amp;lt; Jumpyshoes&amp;gt; well, it takes me a while to get used to stuff&lt;br /&gt;
2010-11-22 16:28:00 &amp;lt; Jumpyshoes&amp;gt; haha, my initials are actually DK&lt;br /&gt;
2010-11-22 16:28:07 &amp;lt; callahan&amp;gt; DS rather&lt;br /&gt;
2010-11-22 16:28:45 &amp;lt; Jumpyshoes&amp;gt; hopefully it isn&#039;t too bad&lt;br /&gt;
2010-11-22 16:28:54 &amp;lt; Jumpyshoes&amp;gt; it only took me three tries to write a three line C function!&lt;br /&gt;
2010-11-22 16:30:01 &amp;lt; holger_&amp;gt; the harder part is debugging asm if it doesn&#039;t work. so you need to think before you code. even more than in any other language.&lt;br /&gt;
2010-11-22 16:30:12 &amp;lt; Jumpyshoes&amp;gt; i&#039;m bad at thinking&lt;br /&gt;
2010-11-22 16:30:22 &amp;lt; Jumpyshoes&amp;gt; this will be interesting&lt;br /&gt;
2010-11-22 16:32:04 &amp;lt; Dark_Shikari&amp;gt; so anyways, if more GCI people come on and I&#039;m not here&lt;br /&gt;
2010-11-22 16:32:08 &amp;lt; Dark_Shikari&amp;gt; and nobody else is here to help them&lt;br /&gt;
2010-11-22 16:32:12 &amp;lt; Dark_Shikari&amp;gt; advise them to wait for me&lt;br /&gt;
2010-11-22 16:32:16 &amp;lt; holger_&amp;gt; (visualize: have a mental picture of which register holds what, which values go where, etc. write it down if you have to)&lt;br /&gt;
2010-11-22 16:33:02 &amp;lt; callahan&amp;gt; Meh, just pick one and do it, then fix it 10 times until it&#039;s right.&lt;br /&gt;
2010-11-22 16:33:21 &amp;lt; Jumpyshoes&amp;gt; (more like 400 for me)&lt;br /&gt;
2010-11-22 16:33:38 &amp;lt; Dark_Shikari&amp;gt; stop underestimating yourself&lt;br /&gt;
2010-11-22 16:33:47 &amp;lt; callahan&amp;gt; If that&#039;s what it takes, start sooner rather than later :)&lt;br /&gt;
2010-11-22 16:34:03 &amp;lt; Jumpyshoes&amp;gt; good thing i have two months&lt;br /&gt;
2010-11-22 16:35:17 &amp;lt; Jumpyshoes&amp;gt; i have the lowbit and highbit functions if anyone wants them&lt;br /&gt;
2010-11-22 16:36:01 &amp;lt; holger_&amp;gt; Jumpyshoes:  there is another task you can do to get your feet wet. (not a gci task though, because we can&#039;t seriously expect anyone to succeed) pick any asm function, try to modify it (do things differently, think outside the box) and keep it working. if you manage to get anything faster *g* we&#039;ll gladly add a gci task for you to submit your results and get credit&lt;br /&gt;
2010-11-22 16:36:11 &amp;lt; Dark_Shikari&amp;gt; What holger_ said.&lt;br /&gt;
2010-11-22 16:36:37 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-22 16:36:57 &amp;lt; Jumpyshoes&amp;gt; that sounds more viable&lt;br /&gt;
2010-11-22 16:37:04 &amp;lt; Dark_Shikari&amp;gt; no, I&#039;d say it&#039;s harder&lt;br /&gt;
2010-11-22 16:37:09 &amp;lt; Jumpyshoes&amp;gt; oh really?&lt;br /&gt;
2010-11-22 16:37:19 &amp;lt; Dark_Shikari&amp;gt; making an asm function faster than C is easy&lt;br /&gt;
2010-11-22 16:37:27 &amp;lt; Dark_Shikari&amp;gt; making an asm function faster than holger_&#039;s is lunatic-mode&lt;br /&gt;
2010-11-22 16:37:36 &amp;lt; Jumpyshoes&amp;gt; ._.&lt;br /&gt;
2010-11-22 16:37:49 &amp;lt; Dark_Shikari&amp;gt; of course, not all the asm functions are by holger, so it&#039;s not that hard!&lt;br /&gt;
2010-11-22 16:38:06 &amp;lt; Dark_Shikari&amp;gt; In general though, it&#039;s a good thing to do so that you learn why code is written like it is&lt;br /&gt;
2010-11-22 16:38:12 &amp;lt; Dark_Shikari&amp;gt; which is a very fast way to learn&lt;br /&gt;
2010-11-22 16:38:27 &amp;lt; Dark_Shikari&amp;gt; if you learn why function A is written with instructions B, C, and D, you&#039;ll know when to use them yourself, ec.&lt;br /&gt;
2010-11-22 16:38:30 &amp;lt; Dark_Shikari&amp;gt; etc&lt;br /&gt;
2010-11-22 16:38:44 &amp;lt; Jumpyshoes&amp;gt; i needa go, ttyl&lt;br /&gt;
2010-11-22 16:53:29 &amp;lt; Kovensky&amp;gt; &amp;lt; Dark_Shikari&amp;gt; making an asm function faster than holger_&#039;s is lunatic-mode &amp;lt;-- you mean extra stage ^ 3&lt;br /&gt;
2010-11-22 16:56:40 &amp;lt; holger_&amp;gt; the cheat mode being &amp;quot;do it on k10&amp;quot;&lt;br /&gt;
2010-11-22 16:56:58 &amp;lt; holger_&amp;gt; because we haven&#039;t been doing much k10-specific opts yet&lt;br /&gt;
2010-11-22 17:47:46 &amp;lt; bgm0&amp;gt; if anyone insterested there are some good read material here: http://www.stanford.edu/class/ee368b/handouts.html&lt;br /&gt;
2010-11-22 18:16:48 &amp;lt; rfw&amp;gt; mornin&#039; #x264dev&lt;br /&gt;
2010-11-22 18:17:32 &amp;lt; rfw&amp;gt; just stating my interest for doing the GCI regression test tool task&lt;br /&gt;
2010-11-22 18:18:10 &amp;lt; Kovensky&amp;gt; hi rofflwaffls&lt;br /&gt;
2010-11-22 18:18:17 &amp;lt; rfw&amp;gt; hi brazilian&lt;br /&gt;
2010-11-22 18:18:28 &amp;lt; Kovensky&amp;gt; you kiwi :&amp;lt;&lt;br /&gt;
2010-11-22 18:18:28 &amp;lt; rfw&amp;gt; You have requested to claim this task and the request is pending. Please don&#039;t submit any work until the request is approved.&lt;br /&gt;
2010-11-22 18:18:29 &amp;lt; rfw&amp;gt; :&amp;lt;&lt;br /&gt;
2010-11-22 18:18:31 &amp;lt; Kovensky&amp;gt; ok, back to topic&lt;br /&gt;
2010-11-22 18:18:32 &amp;lt; Kovensky&amp;gt; lol&lt;br /&gt;
2010-11-22 18:19:26 &amp;lt; rfw&amp;gt; i&#039;m not totally sure how regression testing works though&lt;br /&gt;
2010-11-22 18:19:36 &amp;lt; rfw&amp;gt; is it like unit testing but not unit testing&lt;br /&gt;
2010-11-22 18:19:42 &amp;lt; JEEB&amp;gt; っ the FATE system in ffmpeg&lt;br /&gt;
2010-11-22 18:20:29 &amp;lt; rfw&amp;gt; so, you have the basic tests, like building and configuring&lt;br /&gt;
2010-11-22 18:20:47 &amp;lt; rfw&amp;gt; then you have a few tests that don&#039;t have pass or fail&lt;br /&gt;
2010-11-22 18:20:53 &amp;lt; rfw&amp;gt; you just store the results of them&lt;br /&gt;
2010-11-22 18:20:59 &amp;lt; rfw&amp;gt; then you compare those from version to version?&lt;br /&gt;
2010-11-22 18:22:50 &amp;lt; kierank&amp;gt; rfw: for x264 it will be things like major filesize changes or major changes in psnr/ssim that are unexpected&lt;br /&gt;
2010-11-22 18:22:57 &amp;lt; Kovensky&amp;gt; well&lt;br /&gt;
2010-11-22 18:22:59 &amp;lt; kierank&amp;gt; or perhaps things like vbv uderflows&lt;br /&gt;
2010-11-22 18:23:04 &amp;lt; kierank&amp;gt; underflows*&lt;br /&gt;
2010-11-22 18:23:19 &amp;lt; rfw&amp;gt; you&#039;re going to tell me what those are, right&lt;br /&gt;
2010-11-22 18:23:21 &amp;lt; kierank&amp;gt; segfaults too&lt;br /&gt;
2010-11-22 18:23:25 &amp;lt; Kovensky&amp;gt; IIRC all what kierank said&lt;br /&gt;
2010-11-22 18:23:33 &amp;lt; rfw&amp;gt; because i have no clue ;_;&lt;br /&gt;
2010-11-22 18:23:34 &amp;lt; Kovensky&amp;gt; I&#039;m epic lagging here so whatever I type is only appearing 20 seconds later D:&lt;br /&gt;
2010-11-22 18:24:03 &amp;lt; kierank&amp;gt; rfw: well for example if you try to encode at 1000kbps and new commits are pushed. The next version ends up creating a file at 1500kbps that&#039;s a regression&lt;br /&gt;
2010-11-22 18:24:15 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 18:24:22 &amp;lt; JEEB&amp;gt; and x264 outputs PSNR/SSIM data too&lt;br /&gt;
2010-11-22 18:24:27 &amp;lt; rfw&amp;gt; no i meant the pnsr/ssim part&lt;br /&gt;
2010-11-22 18:24:28 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-22 18:24:34 &amp;lt; JEEB&amp;gt; so you can check that and compare to before&lt;br /&gt;
2010-11-22 18:24:43 &amp;lt; kierank&amp;gt; psnr/ssim is a mathematical measurement of the closeness to the source&lt;br /&gt;
2010-11-22 18:24:56 &amp;lt; kierank&amp;gt; if there&#039;s a major drop in that it&#039;s likely that something went wrong&lt;br /&gt;
2010-11-22 18:25:04 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 18:25:07 &amp;lt; rfw&amp;gt; got it&lt;br /&gt;
2010-11-22 18:25:09 &amp;lt; kierank&amp;gt; ideally the regression tool will do a git bisect and find out what patch caused it&lt;br /&gt;
2010-11-22 18:25:14 &amp;lt; kierank&amp;gt; caused the regression i mean&lt;br /&gt;
2010-11-22 18:25:14 &amp;lt; Kovensky&amp;gt; it can be off, but by a max deviation&lt;br /&gt;
2010-11-22 18:25:24 &amp;lt; rfw&amp;gt; so basically, all you need is a tool stores the data of each revision&lt;br /&gt;
2010-11-22 18:25:31 &amp;lt; rfw&amp;gt; then compares it with other revisions?&lt;br /&gt;
2010-11-22 18:25:44 &amp;lt; Kovensky&amp;gt; hurf, I should just stop writing since anything I say is already answered before it appears &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-22 18:25:54  * rfw pats Kovensky&lt;br /&gt;
2010-11-22 18:26:04 &amp;lt; kierank&amp;gt; rfw: yes something like that&lt;br /&gt;
2010-11-22 18:26:16 &amp;lt; rfw&amp;gt; seems fun to do&lt;br /&gt;
2010-11-22 18:26:52 &amp;lt; Kovensky&amp;gt; and have a cute and fluffy web interface for people to see&lt;br /&gt;
2010-11-22 18:27:05 &amp;lt; kierank&amp;gt; Kovensky: not necessarily&lt;br /&gt;
2010-11-22 18:27:07 &amp;lt; Kovensky&amp;gt; well, disregard the &amp;quot;cute and fluffy&amp;quot; part, unless you really want to :&amp;quot;&amp;gt;&lt;br /&gt;
2010-11-22 18:27:31 &amp;lt; Kovensky&amp;gt; well true, not necessary&lt;br /&gt;
2010-11-22 18:27:39 &amp;lt; Kovensky&amp;gt; I&#039;m just borrowing from FATE at this point&lt;br /&gt;
2010-11-22 18:27:46 &amp;lt; Kovensky&amp;gt; but a simple tool to run locally is already p. good&lt;br /&gt;
2010-11-22 18:28:11 &amp;lt; Kovensky&amp;gt; s/but //&lt;br /&gt;
2010-11-22 18:31:56 &amp;lt; rfw&amp;gt; can i just have cute and fluffy cli output&lt;br /&gt;
2010-11-22 18:31:58 &amp;lt; rfw&amp;gt; with colors&lt;br /&gt;
2010-11-22 18:32:44 &amp;lt; holger_&amp;gt; rfw: speed regressions are interesting too. and obviously you&#039;d want quite a diverse selection of videos, not just one.&lt;br /&gt;
2010-11-22 18:33:17 &amp;lt; rfw&amp;gt; well, i&#039;m probably going for a unit-testing fixtures approach&lt;br /&gt;
2010-11-22 18:33:53 &amp;lt; rfw&amp;gt; so i guess that could be easily done&lt;br /&gt;
2010-11-22 18:34:16 &amp;lt; holger_&amp;gt; it&#039;s quite possible for every single routine to become faster while x264 overall becomes slower.&lt;br /&gt;
2010-11-22 18:34:37 &amp;lt; holger_&amp;gt; we&#039;d probably see that if we unrolled everything&lt;br /&gt;
2010-11-22 18:35:28 &amp;lt; rfw&amp;gt; heh&lt;br /&gt;
2010-11-22 18:35:30 &amp;lt; rfw&amp;gt; isn&#039;t that always the case&lt;br /&gt;
2010-11-22 18:35:32 &amp;lt; nattofriends&amp;gt; funroll loops !&lt;br /&gt;
2010-11-22 18:36:35 &amp;lt; callahan&amp;gt; I always read that as fun roll&lt;br /&gt;
2010-11-22 18:36:39 &amp;lt; holger_&amp;gt; just an example of something unit testing wouldn&#039;t catch&lt;br /&gt;
2010-11-22 18:37:54  * microchip_ rollin&#039;&lt;br /&gt;
2010-11-22 18:37:59 &amp;lt; nattofriends&amp;gt; callahan: exactly&lt;br /&gt;
2010-11-22 19:23:37 &amp;lt; rfw&amp;gt; so Kovensky&lt;br /&gt;
2010-11-22 19:23:41 &amp;lt; rfw&amp;gt; where is Dark_Shikari :(&lt;br /&gt;
2010-11-22 19:24:42 &amp;lt; Kovensky&amp;gt; somewhere in california&lt;br /&gt;
2010-11-22 19:26:45 &amp;lt; rfw&amp;gt; no i mean&lt;br /&gt;
2010-11-22 19:27:00 &amp;lt; rfw&amp;gt; didn&#039;t you say he was always here&lt;br /&gt;
2010-11-22 19:27:15 &amp;lt; Kovensky&amp;gt; :P&lt;br /&gt;
2010-11-22 19:27:26 &amp;lt; astrange&amp;gt; can&#039;t always be awake&lt;br /&gt;
2010-11-22 19:27:41 &amp;lt; JEEB&amp;gt; he sleeps 2-3h at random times of the day and he will look through his pings as he gets back to his keyboard&lt;br /&gt;
2010-11-22 19:27:44 &amp;lt; JEEB&amp;gt; just stay on the channel&lt;br /&gt;
2010-11-22 19:27:46 &amp;lt; BugMaster_&amp;gt; sometimes he pretend to sleep&lt;br /&gt;
2010-11-22 19:27:48 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-22 19:29:23 &amp;lt; rfw&amp;gt; writing python at 8am doesn&#039;t seem to be an agreeable experience&lt;br /&gt;
2010-11-22 19:29:38  * Kovensky flames with perl&lt;br /&gt;
2010-11-22 19:29:53 &amp;lt; rfw&amp;gt; TOO BAD YOU&#039;RE GETTING YOUR REGRESSION TESITNG TOOL IN PYTHON&lt;br /&gt;
2010-11-22 19:30:18 &amp;lt; Kovensky&amp;gt; nuu ;_;&lt;br /&gt;
2010-11-22 19:30:31 &amp;lt; JEEB&amp;gt; python is mighty fine&lt;br /&gt;
2010-11-22 19:30:32 &amp;lt; rfw&amp;gt; :D&lt;br /&gt;
2010-11-22 19:31:35 &amp;lt; tjoener&amp;gt; indeed&lt;br /&gt;
2010-11-22 19:31:39 &amp;lt; tjoener&amp;gt; I like Python&lt;br /&gt;
2010-11-22 19:31:41 &amp;lt; tjoener&amp;gt; got a book&lt;br /&gt;
2010-11-22 19:32:30 &amp;lt; rfw&amp;gt; i hope it&#039;s not an orly book&lt;br /&gt;
2010-11-22 19:32:36 &amp;lt; komisar&amp;gt; tjoener: .chm from python distibution is fine&lt;br /&gt;
2010-11-22 19:32:39 &amp;lt; komisar&amp;gt; :)&lt;br /&gt;
2010-11-22 19:32:44 &amp;lt; tjoener&amp;gt; heh, I know&lt;br /&gt;
2010-11-22 19:32:53 &amp;lt; tjoener&amp;gt; ive been reading the online documentation&lt;br /&gt;
2010-11-22 19:33:05 &amp;lt; tjoener&amp;gt; but I dont know of anything to make with it&lt;br /&gt;
2010-11-22 19:33:12 &amp;lt; tjoener&amp;gt; so I&#039;m kind of letting it be&lt;br /&gt;
2010-11-22 19:33:51 &amp;lt; komisar&amp;gt; very simple and powerfull script-language&lt;br /&gt;
2010-11-22 19:34:08 &amp;lt; holger_&amp;gt; python makes everything seem so easy. and sometimes it does. in which case your problem was either a) really easy or b) didn&#039;t need much performance&lt;br /&gt;
2010-11-22 19:34:37 &amp;lt; tjoener&amp;gt; well yeah&lt;br /&gt;
2010-11-22 19:34:40 &amp;lt; tjoener&amp;gt; thats my idea too&lt;br /&gt;
2010-11-22 19:34:49 &amp;lt; tjoener&amp;gt; I never find a good use for a scripting language&lt;br /&gt;
2010-11-22 19:35:09 &amp;lt; tjoener&amp;gt; except for maybe batch/shell scripts, for which there are batch/shell scripts&lt;br /&gt;
2010-11-22 19:35:18 &amp;lt; elenril&amp;gt; python isn&#039;t just scripting&lt;br /&gt;
2010-11-22 19:35:30 &amp;lt; JEEB&amp;gt; &amp;gt; batch scripts&lt;br /&gt;
2010-11-22 19:35:31  * elenril wrote an mpd client in it&lt;br /&gt;
2010-11-22 19:35:31 &amp;lt; JEEB&amp;gt; eww&lt;br /&gt;
2010-11-22 19:35:35 &amp;lt; tjoener&amp;gt; yeah I know&lt;br /&gt;
2010-11-22 19:35:36 &amp;lt; djahandarie&amp;gt; I use Haskell for most everything I need&lt;br /&gt;
2010-11-22 19:35:54 &amp;lt; Kovensky&amp;gt; tjoener: do you seriously consider batch scripts for stuff? D:&lt;br /&gt;
2010-11-22 19:35:57 &amp;lt; Kovensky&amp;gt; plz2use perl&lt;br /&gt;
2010-11-22 19:36:15 &amp;lt; tjoener&amp;gt; naah, mostly ridiculously evil stuff&lt;br /&gt;
2010-11-22 19:36:24 &amp;lt; tjoener&amp;gt; running a few programes on a file&lt;br /&gt;
2010-11-22 19:36:28 &amp;lt; tjoener&amp;gt; not much else&lt;br /&gt;
2010-11-22 19:36:31 &amp;lt; Kovensky&amp;gt; though if you need good internationalization support you&#039;re better off with python3, assuming they did the win32 part right&lt;br /&gt;
2010-11-22 19:37:00 &amp;lt; elenril&amp;gt; &amp;gt;implying anybody uses python3&lt;br /&gt;
2010-11-22 19:37:12 &amp;lt; tjoener&amp;gt; whats wrong with python 3?&lt;br /&gt;
2010-11-22 19:37:17 &amp;lt; tjoener&amp;gt; except for print()&lt;br /&gt;
2010-11-22 19:37:42 &amp;lt; elenril&amp;gt; not enough support&lt;br /&gt;
2010-11-22 19:37:51 &amp;lt; tjoener&amp;gt; ah&lt;br /&gt;
2010-11-22 19:38:01  * elenril can&#039;t port his client to py3 because qt4 in debian only supports py2&lt;br /&gt;
2010-11-22 19:38:18 &amp;lt; elenril&amp;gt; also scipy/numpy only support py2 iirc&lt;br /&gt;
2010-11-22 19:38:19 &amp;lt; tjoener&amp;gt; hmmm&lt;br /&gt;
2010-11-22 19:38:26 &amp;lt; tjoener&amp;gt; numpy is nice&lt;br /&gt;
2010-11-22 19:39:46 &amp;lt; Kovensky&amp;gt; what is numpy&lt;br /&gt;
2010-11-22 19:39:48 &amp;lt; Kovensky&amp;gt; numbers for python? :P&lt;br /&gt;
2010-11-22 19:39:54  * elenril wishes they taught physicists how2write readable/maintainable code&lt;br /&gt;
2010-11-22 19:40:10 &amp;lt; elenril&amp;gt; Kovensky: http://numpy.scipy.org/ =p&lt;br /&gt;
2010-11-22 19:40:25 &amp;lt; komisar&amp;gt; py3/py2 usefull for self-made script/program... in mingw/*nix/windows... :)&lt;br /&gt;
2010-11-22 19:40:30 &amp;lt; tjoener&amp;gt; http://www.boingboing.net/2010/11/22/howto-make-a-stupend.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+boingboing%2FiBag+%28Boing+Boing%29&amp;amp;utm_content=Google+Reader&lt;br /&gt;
2010-11-22 19:40:35 &amp;lt; tjoener&amp;gt; lol&lt;br /&gt;
2010-11-22 19:40:36 &amp;lt; tjoener&amp;gt; loved those when I was a kid&lt;br /&gt;
2010-11-22 19:41:13 &amp;lt; tjoener&amp;gt; I&#039;m thinking of skipping python and looking at something functional&lt;br /&gt;
2010-11-22 19:41:21 &amp;lt; rfw&amp;gt; [08:39:47] &amp;lt;Kovensky&amp;gt; numbers for python? :P &amp;lt;-- o u&lt;br /&gt;
2010-11-22 19:41:25 &amp;lt; tjoener&amp;gt; like lisp or scheme or ...&lt;br /&gt;
2010-11-22 19:41:34  * Kovensky votes for common lisp&lt;br /&gt;
2010-11-22 19:42:23 &amp;lt; tjoener&amp;gt; yeah&lt;br /&gt;
2010-11-22 19:42:32 &amp;lt; tjoener&amp;gt; lisp isnt that bad&lt;br /&gt;
2010-11-22 19:42:35 &amp;lt; tjoener&amp;gt; F#? :)&lt;br /&gt;
2010-11-22 19:42:42 &amp;lt; Kovensky&amp;gt; idk about F#&lt;br /&gt;
2010-11-22 19:43:15 &amp;lt; tjoener&amp;gt; naah&lt;br /&gt;
2010-11-22 19:43:21 &amp;lt; tjoener&amp;gt; I&#039;m to addicted to .NET allready&lt;br /&gt;
2010-11-22 19:43:26 &amp;lt; tjoener&amp;gt; should learn something else&lt;br /&gt;
2010-11-22 19:43:34 &amp;lt; elenril&amp;gt; &amp;gt;.net&lt;br /&gt;
2010-11-22 19:43:39  * elenril runs away screaming&lt;br /&gt;
2010-11-22 19:43:52 &amp;lt; tjoener&amp;gt; elenril: It&#039;s frikkin nice&lt;br /&gt;
2010-11-22 19:44:28 &amp;lt; elenril&amp;gt; &amp;lt;a reply bashing microsoft&amp;gt;&lt;br /&gt;
2010-11-22 19:45:32 &amp;lt; tjoener&amp;gt; and what about Mono?&lt;br /&gt;
2010-11-22 19:45:50 &amp;lt; Kovensky&amp;gt; reply bashing novell?&lt;br /&gt;
2010-11-22 19:45:58 &amp;lt; tjoener&amp;gt; lol :D&lt;br /&gt;
2010-11-22 19:46:19 &amp;lt; tjoener&amp;gt; Kovensky: whats the most used common lisp interpreter/compiler/runtime?&lt;br /&gt;
2010-11-22 19:46:40 &amp;lt; tjoener&amp;gt; I dont know what&#039;s with all the people bashing .NET and Mono&lt;br /&gt;
2010-11-22 19:46:54 &amp;lt; komisar&amp;gt; .net -- suks&lt;br /&gt;
2010-11-22 19:46:54 &amp;lt; tjoener&amp;gt; What did that language ever do to you? :)&lt;br /&gt;
2010-11-22 19:47:05 &amp;lt; elenril&amp;gt; didn&#039;t novel get bought my microsoft sometime today?&lt;br /&gt;
2010-11-22 19:49:36 &amp;lt; astrange&amp;gt; the most common free one is sbcl&lt;br /&gt;
2010-11-22 19:49:48 &amp;lt; tjoener&amp;gt; lets see&lt;br /&gt;
2010-11-22 19:51:37 &amp;lt; BugMaster&amp;gt; -&amp;gt; #x264 or anywhere else&lt;br /&gt;
2010-11-22 19:52:21 &amp;lt; BugMaster&amp;gt; or this is for google project?&lt;br /&gt;
2010-11-22 19:52:25 &amp;lt; tjoener&amp;gt; sorry BugMaster&lt;br /&gt;
2010-11-22 19:55:21 &amp;lt; rfw&amp;gt; well then, that&#039;s a basic unit testing framework done&lt;br /&gt;
2010-11-22 19:55:44 &amp;lt; astrange&amp;gt; unit or regression testing?&lt;br /&gt;
2010-11-22 19:55:49 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-22 19:55:56 &amp;lt; rfw&amp;gt; i&#039;m starting with a unit testing framework&lt;br /&gt;
2010-11-22 19:56:01 &amp;lt; rfw&amp;gt; then adding regression testing to it&lt;br /&gt;
2010-11-22 19:56:11 &amp;lt; rfw&amp;gt; since regression testing has most aspects of unit testing&lt;br /&gt;
2010-11-22 19:56:44 &amp;lt; astrange&amp;gt; not necessarily, running the entire system and making sure it has the same outputs (when you want it to have the same outputs) is an effective regression test&lt;br /&gt;
2010-11-22 19:57:11 &amp;lt; rfw&amp;gt; well, i have classes that encapsulate results that compare values from revision to revision&lt;br /&gt;
2010-11-22 19:57:33 &amp;lt; rfw&amp;gt; the whole thing is horrendously extensible&lt;br /&gt;
2010-11-22 19:59:49 &amp;lt; holger_&amp;gt; rfw: we already have unit testing. for comparing asm implementations of functions to their c reference.&lt;br /&gt;
2010-11-22 20:00:16 &amp;lt; rfw&amp;gt; i know&lt;br /&gt;
2010-11-22 20:00:25 &amp;lt; rfw&amp;gt; but unit tests only have pass/fail results, right?&lt;br /&gt;
2010-11-22 20:06:29 &amp;lt; BugMaster&amp;gt; and now the funny/sad fact. after fixing weight-p bug results of gcc 4.4.5 build and gcc 4.5.2 builds still differ: http://privatepaste.com/b4380671ef&lt;br /&gt;
2010-11-22 20:06:29 &amp;lt; BugMaster&amp;gt; no artifacts and encoder/decoder desync, but wieght-p is used more and chroma psnr higher in *gcc 4.5.2* build&lt;br /&gt;
2010-11-22 20:06:29 &amp;lt; BugMaster&amp;gt; so it seems like miscompilation in *gcc 4.4.5* which probably also prevent previous bug to occur in this version&lt;br /&gt;
2010-11-22 20:06:29 &amp;lt; BugMaster&amp;gt; Dark_Shikari: ^&lt;br /&gt;
2010-11-22 20:08:17 &amp;lt; BugMaster&amp;gt; or strange miscompilation in 4.5.2 which increase quality&lt;br /&gt;
2010-11-22 20:08:33 &amp;lt; nattofriends&amp;gt; ^ i like this idea&lt;br /&gt;
2010-11-22 20:09:44 &amp;lt; Kovensky&amp;gt; why&lt;br /&gt;
2010-11-22 20:09:52 &amp;lt; tjoener&amp;gt; just compile it all with -S and see what the asm does :)&lt;br /&gt;
2010-11-22 20:09:56 &amp;lt; Kovensky&amp;gt; it means that gcc provides better results while broken than when working properly&lt;br /&gt;
2010-11-22 20:09:57 &amp;lt; BugMaster&amp;gt; --asm and --no-asm version identical for the same build. so this time it is not asm&lt;br /&gt;
2010-11-22 20:11:44 &amp;lt; tjoener&amp;gt; and no-asm on both versions?&lt;br /&gt;
2010-11-22 20:12:01 &amp;lt; BugMaster&amp;gt; no-asm between version differ&lt;br /&gt;
2010-11-22 20:13:15 &amp;lt; tjoener&amp;gt; stupid gcc&lt;br /&gt;
2010-11-22 20:13:36 &amp;lt; tjoener&amp;gt; I dont understand why they cant make a program compile right under different MINOR versions&lt;br /&gt;
2010-11-22 20:13:55 &amp;lt; tjoener&amp;gt; Isnt that the whole point of a compiler?&lt;br /&gt;
2010-11-22 20:15:27 &amp;lt; dj_tjerk&amp;gt; someone test with icc ;)&lt;br /&gt;
2010-11-22 20:15:30 &amp;lt; BugMaster&amp;gt; hm. gcc 4.5.2 with -O0 same result as 4.4.5&lt;br /&gt;
2010-11-22 20:15:49 &amp;lt; JEEB&amp;gt; interesting&lt;br /&gt;
2010-11-22 20:16:03 &amp;lt; BugMaster&amp;gt; so now I more think about &amp;quot;or strange miscompilation in 4.5.2 which increase quality&amp;quot;&lt;br /&gt;
2010-11-22 20:16:30 &amp;lt; BugMaster&amp;gt; that mean we missed some way to improve weight-p :-D&lt;br /&gt;
2010-11-22 20:16:35 &amp;lt; JEEB&amp;gt; law&lt;br /&gt;
2010-11-22 20:16:37 &amp;lt; JEEB&amp;gt; l&lt;br /&gt;
2010-11-22 20:16:39 &amp;lt; Dark_Shikari&amp;gt; BugMaster: lolwhat&lt;br /&gt;
2010-11-22 20:16:57 &amp;lt; Dark_Shikari&amp;gt; rfw: we already have unit tests&lt;br /&gt;
2010-11-22 20:17:01 &amp;lt; Gramner&amp;gt; it means gcc has gained artificial intelligence and is able to improve the algorithms&lt;br /&gt;
2010-11-22 20:17:02 &amp;lt; Dark_Shikari&amp;gt; we don&#039;t need more of it&lt;br /&gt;
2010-11-22 20:17:06 &amp;lt; rfw&amp;gt; i know&lt;br /&gt;
2010-11-22 20:17:11 &amp;lt; rfw&amp;gt; but what i mean&lt;br /&gt;
2010-11-22 20:17:29 &amp;lt; rfw&amp;gt; is you have test cases that return results which can be compared from one revision to another&lt;br /&gt;
2010-11-22 20:18:06 &amp;lt; Dark_Shikari&amp;gt; explicit test cases are a bad idea, it should test permutations&lt;br /&gt;
2010-11-22 20:18:20 &amp;lt; rfw&amp;gt; what do you mean exactly&lt;br /&gt;
2010-11-22 20:18:41 &amp;lt; tjoener&amp;gt; BugMaster: what about the different tests like those in fprofiled?&lt;br /&gt;
2010-11-22 20:19:15 &amp;lt; BugMaster&amp;gt; &amp;quot;we missed some way to improve weight-p&amp;quot; &amp;lt;- probably use weight-p on chroma without weighted lume. because currently we not analyse it as I understand if we don&#039;t have luma weight&lt;br /&gt;
2010-11-22 20:19:19 &amp;lt; tjoener&amp;gt; isnt that something that can narrow down what function gcc likes to change&lt;br /&gt;
2010-11-22 20:19:20 &amp;lt; tjoener&amp;gt; ?&lt;br /&gt;
2010-11-22 20:20:00 &amp;lt; Dark_Shikari&amp;gt; BugMaster: I tested that&lt;br /&gt;
2010-11-22 20:20:12 &amp;lt; Dark_Shikari&amp;gt; useless to run when luma isn&#039;t weighted&lt;br /&gt;
2010-11-22 20:20:14 &amp;lt; Dark_Shikari&amp;gt; and it saves a ton of time&lt;br /&gt;
2010-11-22 20:20:40 &amp;lt; Dark_Shikari&amp;gt; rfw: see my regresion teest sript&lt;br /&gt;
2010-11-22 20:20:43 &amp;lt; Dark_Shikari&amp;gt; http://pastebin.com/sHkmCak5&lt;br /&gt;
2010-11-22 20:20:49 &amp;lt; Dark_Shikari&amp;gt; it works via permutations&lt;br /&gt;
2010-11-22 20:20:59 &amp;lt; Dark_Shikari&amp;gt; whenever I find a case that my script missed, I make it 2x slower, lol&lt;br /&gt;
2010-11-22 20:21:04 &amp;lt; Dark_Shikari&amp;gt; by adding another loop&lt;br /&gt;
2010-11-22 20:21:13 &amp;lt; BugMaster&amp;gt; dunno. but this is the only thing what I think can be miscompiled and gain quality&lt;br /&gt;
2010-11-22 20:21:23 &amp;lt; rfw&amp;gt; i wish i could read that lol&lt;br /&gt;
2010-11-22 20:21:36 &amp;lt; Dark_Shikari&amp;gt; rfw: didn&#039;t the regression test task specifically tell you to look at mine? =p&lt;br /&gt;
2010-11-22 20:21:37 &amp;lt; JEEB&amp;gt; it has lots of for loops&lt;br /&gt;
2010-11-22 20:21:44 &amp;lt; Dark_Shikari&amp;gt; anyways my script is 2 minutes of work and shit&lt;br /&gt;
2010-11-22 20:21:50 &amp;lt; Dark_Shikari&amp;gt; I&#039;d rather randomly test than permutation-test&lt;br /&gt;
2010-11-22 20:21:52 &amp;lt; Dark_Shikari&amp;gt; permutation test is too slow&lt;br /&gt;
2010-11-22 20:22:12 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;random&amp;quot; being rather pseudo, so it&#039;s replicable&lt;br /&gt;
2010-11-22 20:22:25 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-22 20:22:33 &amp;lt; rfw&amp;gt; can&#039;t you just do permutations in a single test case&lt;br /&gt;
2010-11-22 20:22:35 &amp;lt; Amit&amp;gt; hi, i&#039;d like to start working on the assembly task from the Google Code In contest, it says there that i should come here&lt;br /&gt;
2010-11-22 20:22:40 &amp;lt; Dark_Shikari&amp;gt; welcome!&lt;br /&gt;
2010-11-22 20:22:58 &amp;lt; Dark_Shikari&amp;gt; rfw: permutations define 2^N tests instead of N tests&lt;br /&gt;
2010-11-22 20:23:05 &amp;lt; Dark_Shikari&amp;gt; where N is the number of test cases you&#039;ve written&lt;br /&gt;
2010-11-22 20:23:29 &amp;lt; Dark_Shikari&amp;gt; er, ok&lt;br /&gt;
2010-11-22 20:23:37 &amp;lt; Dark_Shikari&amp;gt; Amit: yes, you&#039;re in the right place&lt;br /&gt;
2010-11-22 20:23:42 &amp;lt; Amit&amp;gt; great&lt;br /&gt;
2010-11-22 20:23:50 &amp;lt; Amit&amp;gt; what do i need to do now?&lt;br /&gt;
2010-11-22 20:24:02 &amp;lt; rfw&amp;gt; i&#039;m still kinda confused&lt;br /&gt;
2010-11-22 20:24:04 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-22 20:24:11 &amp;lt; rfw&amp;gt; how does that work&lt;br /&gt;
2010-11-22 20:24:17 &amp;lt; Dark_Shikari&amp;gt; rfw: ok, suppose I have 5 options, each of which can be 0 or 1&lt;br /&gt;
2010-11-22 20:24:18 &amp;lt; rfw&amp;gt; how are the tests comparable to each other?&lt;br /&gt;
2010-11-22 20:24:26 &amp;lt; Dark_Shikari&amp;gt; that involves 32 tests.&lt;br /&gt;
2010-11-22 20:24:31 &amp;lt; Dark_Shikari&amp;gt; A0 B0 C0 D0 E0&lt;br /&gt;
2010-11-22 20:24:34 &amp;lt; Dark_Shikari&amp;gt; A0 B0 C0 D0 E1...&lt;br /&gt;
2010-11-22 20:24:36 &amp;lt; Dark_Shikari&amp;gt; etc&lt;br /&gt;
2010-11-22 20:24:53 &amp;lt; rfw&amp;gt; so you&#039;re comparing each test against another?&lt;br /&gt;
2010-11-22 20:24:55 &amp;lt; Dark_Shikari&amp;gt; Amit: ok, you&#039;ll need to check out a copy of x264&lt;br /&gt;
2010-11-22 20:24:56 &amp;lt; Dark_Shikari&amp;gt; rfw: no&lt;br /&gt;
2010-11-22 20:25:04 &amp;lt; Dark_Shikari&amp;gt; the regression test makes sure that JM decodes the file in the same way x264 thinks it should.&lt;br /&gt;
2010-11-22 20:25:14 &amp;lt; Dark_Shikari&amp;gt; This is the simplest and easiest form of regression test.&lt;br /&gt;
2010-11-22 20:25:17 &amp;lt; Dark_Shikari&amp;gt; It does not find all bugs.&lt;br /&gt;
2010-11-22 20:25:21 &amp;lt; Dark_Shikari&amp;gt; But it finds most really really bad bugs&lt;br /&gt;
2010-11-22 20:25:34 &amp;lt; Dark_Shikari&amp;gt; Amit: sorry, even my typing speed is limited here&lt;br /&gt;
2010-11-22 20:25:35 &amp;lt; rfw&amp;gt; so you compare one set of results&lt;br /&gt;
2010-11-22 20:25:38 &amp;lt; rfw&amp;gt; to another&lt;br /&gt;
2010-11-22 20:25:39 &amp;lt; dj_tjerk&amp;gt; --dump-yuv?&lt;br /&gt;
2010-11-22 20:25:42 &amp;lt; Dark_Shikari&amp;gt; rfw: --dump-yuv&lt;br /&gt;
2010-11-22 20:25:45 &amp;lt; Amit&amp;gt; no probs :P help him first&lt;br /&gt;
2010-11-22 20:25:50 &amp;lt; Dark_Shikari&amp;gt; it dumps x264&#039;s internal representation of the video&lt;br /&gt;
2010-11-22 20:25:55 &amp;lt; Dark_Shikari&amp;gt; with that, you can compare to what the decoder sees&lt;br /&gt;
2010-11-22 20:26:02 &amp;lt; Dark_Shikari&amp;gt; if it doesn&#039;t match bit-exact, it&#039;s wrong&lt;br /&gt;
2010-11-22 20:26:05 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 20:26:19 &amp;lt; Dark_Shikari&amp;gt; This is exacerbated by the fact that the decoder is not always 100% trustworthy ;) ;)&lt;br /&gt;
2010-11-22 20:26:25 &amp;lt; Dark_Shikari&amp;gt; That is, JM has bugs.&lt;br /&gt;
2010-11-22 20:26:34 &amp;lt; Dark_Shikari&amp;gt; Amit: so, have you done asm before?&lt;br /&gt;
2010-11-22 20:26:34 &amp;lt; rfw&amp;gt; that seems more of a unit test though&lt;br /&gt;
2010-11-22 20:26:40 &amp;lt; Amit&amp;gt; yes&lt;br /&gt;
2010-11-22 20:26:52 &amp;lt; pengvado&amp;gt; the whole encoder isn&#039;t a &amp;quot;unit&amp;quot;&lt;br /&gt;
2010-11-22 20:27:05 &amp;lt; Dark_Shikari&amp;gt; unit test usually means test one function&lt;br /&gt;
2010-11-22 20:27:17 &amp;lt; Dark_Shikari&amp;gt; which usually means you&#039;ve gone so batshit crazy on your OO that you should be thrown into a fire&lt;br /&gt;
2010-11-22 20:27:24 &amp;lt; Dark_Shikari&amp;gt; Amit: x86, altivec, or neon?&lt;br /&gt;
2010-11-22 20:27:29 &amp;lt; Amit&amp;gt; x86&lt;br /&gt;
2010-11-22 20:27:38 &amp;lt; Dark_Shikari&amp;gt; ok great, have you done mmx or sse?&lt;br /&gt;
2010-11-22 20:28:43 &amp;lt; Dark_Shikari&amp;gt; (not required, obviously you can just use your friendly neighborhood nasm manual and instruction table to look things up if you haven&#039;t)&lt;br /&gt;
2010-11-22 20:29:54 &amp;lt; Amit&amp;gt; i think that i haven&#039;t done any of them&lt;br /&gt;
2010-11-22 20:29:55 &amp;lt; pengvado&amp;gt; well, it would be nice if we could unit test everything. but asm is the only case where it&#039;s easy.&lt;br /&gt;
2010-11-22 20:30:04 &amp;lt; Dark_Shikari&amp;gt; yeah.&lt;br /&gt;
2010-11-22 20:30:06 &amp;lt; Amit&amp;gt; i studied the language but haven&#039;t yet worked on a real project&lt;br /&gt;
2010-11-22 20:30:32 &amp;lt; Dark_Shikari&amp;gt; you will have to do some learning, as x264 uses its own set of yasm macros to make asm coding easier&lt;br /&gt;
2010-11-22 20:30:37 &amp;lt; Dark_Shikari&amp;gt; i.e. to do things like popping, pushing, etc for you&lt;br /&gt;
2010-11-22 20:30:41 &amp;lt; Dark_Shikari&amp;gt; to track the stack&lt;br /&gt;
2010-11-22 20:30:52 &amp;lt; Dark_Shikari&amp;gt; but of course, those are intended to make it easier, not harder.&lt;br /&gt;
2010-11-22 20:31:04 &amp;lt; Amit&amp;gt; ok&lt;br /&gt;
2010-11-22 20:31:06 &amp;lt; Dark_Shikari&amp;gt; so your tasks in order:&lt;br /&gt;
2010-11-22 20:31:08 &amp;lt; Dark_Shikari&amp;gt; 1) check out x264&lt;br /&gt;
2010-11-22 20:31:10 &amp;lt; Dark_Shikari&amp;gt; 2) build x264&lt;br /&gt;
2010-11-22 20:31:14 &amp;lt; Dark_Shikari&amp;gt; 3) make checkasm&lt;br /&gt;
2010-11-22 20:31:17 &amp;lt; Dark_Shikari&amp;gt; 4) run checkasm&lt;br /&gt;
2010-11-22 20:31:27 &amp;lt; Dark_Shikari&amp;gt; you&#039;ve now run the x264 asm unit tester, which automatically checks all enabled asm functions in x264 for errors.&lt;br /&gt;
2010-11-22 20:31:40 &amp;lt; Dark_Shikari&amp;gt; once you have that, you can go to pick a function to write.&lt;br /&gt;
2010-11-22 20:32:05 &amp;lt; tjoener&amp;gt; its that easy?&lt;br /&gt;
2010-11-22 20:32:16 &amp;lt; Dark_Shikari&amp;gt; No, the writing is harder ;)&lt;br /&gt;
2010-11-22 20:32:23 &amp;lt; Dark_Shikari&amp;gt; the number 1 rule of any of this: ask questions.  it is better to ask a dumb question than to get stuck in confusion.&lt;br /&gt;
2010-11-22 20:32:23 &amp;lt; tjoener&amp;gt; hmmm, maybe I&#039;ll look into the asm then :)&lt;br /&gt;
2010-11-22 20:32:36 &amp;lt; Dark_Shikari&amp;gt; also, there are no stupid questions, just stupid people.&lt;br /&gt;
2010-11-22 20:32:37 &amp;lt; tjoener&amp;gt; used some intrinsics, so I know my way around SSE abit&lt;br /&gt;
2010-11-22 20:32:52 &amp;lt; Dark_Shikari&amp;gt; btw, also, the asm tasks are unlimited&lt;br /&gt;
2010-11-22 20:33:00 &amp;lt; Dark_Shikari&amp;gt; i.e. if we run out on GCI interface we can add more later&lt;br /&gt;
2010-11-22 20:33:07 &amp;lt; Dark_Shikari&amp;gt; so don&#039;t worry if there aren&#039;t any left at any pointl.&lt;br /&gt;
2010-11-22 20:33:20 &amp;lt; Dark_Shikari&amp;gt; well, I mean, they are limited by how much is available to complete, but I&#039;m pretty sure we won&#039;t run out of that.&lt;br /&gt;
2010-11-22 20:34:06 &amp;lt; Amit&amp;gt; where do i find which functions should be rewritten?&lt;br /&gt;
2010-11-22 20:34:19 &amp;lt; tjoener&amp;gt; maybe some MPSADBW ?&lt;br /&gt;
2010-11-22 20:34:46 &amp;lt; Dark_Shikari&amp;gt; Amit: well let&#039;s give an introduction to the situation first&lt;br /&gt;
2010-11-22 20:34:58 &amp;lt; Dark_Shikari&amp;gt; In normal bit depth mode, pixels are 8-bit values (uint8_t)&lt;br /&gt;
2010-11-22 20:35:04 &amp;lt; Dark_Shikari&amp;gt; and dct coefficients are 16-bit values (int16_t)&lt;br /&gt;
2010-11-22 20:35:19 &amp;lt; Dark_Shikari&amp;gt; for this case, nearly all possible x86 asm is written and reasonably well-optimized.&lt;br /&gt;
2010-11-22 20:35:26 &amp;lt; Dark_Shikari&amp;gt; High bit depth is new.&lt;br /&gt;
2010-11-22 20:35:31 &amp;lt; Dark_Shikari&amp;gt; In high bit depth, pixels are uint16_t.&lt;br /&gt;
2010-11-22 20:35:36 &amp;lt; Dark_Shikari&amp;gt; and dct coeffs are int32_t.&lt;br /&gt;
2010-11-22 20:35:43 &amp;lt; Dark_Shikari&amp;gt; There&#039;s less asm in this mode; many critical functions are missing.&lt;br /&gt;
2010-11-22 20:35:57 &amp;lt; Dark_Shikari&amp;gt; You can see this by running checkasm normally, then reconfiguring with --bit-depth=10, rebuilding checkasm, and running again.&lt;br /&gt;
2010-11-22 20:36:24 &amp;lt; Dark_Shikari&amp;gt; By the way, if you decide you can optimize an existing asm function -- and you succeed -- I&#039;ll give you a GCI task-equivalent for that too.&lt;br /&gt;
2010-11-22 20:37:36 &amp;lt; Amit&amp;gt; ok&lt;br /&gt;
2010-11-22 20:37:58 &amp;lt; Dark_Shikari&amp;gt; Now, of course, you&#039;re expected to ask questions as we go through this&lt;br /&gt;
2010-11-22 20:38:09 &amp;lt; Dark_Shikari&amp;gt; steps to adding a new asm function, or version of an asm function:&lt;br /&gt;
2010-11-22 20:38:28 &amp;lt; Dark_Shikari&amp;gt; 1) All C code equivalents for asm functions is in common/X.c, where X is the name of the function category&lt;br /&gt;
2010-11-22 20:38:37 &amp;lt; Dark_Shikari&amp;gt; so for example DCT code is in common/dct.c&lt;br /&gt;
2010-11-22 20:39:07 &amp;lt; Dark_Shikari&amp;gt; 2) You&#039;ll find functions in those files that load function pointers for all the asm functions which exist.  Add yours there under the appropriate place (MMX, SSE, etc)&lt;br /&gt;
2010-11-22 20:39:16 &amp;lt; Dark_Shikari&amp;gt; 3) Add your function declaration next to all the others in the appropriate .h file in common/x86/*&lt;br /&gt;
2010-11-22 20:39:23 &amp;lt; Dark_Shikari&amp;gt; 4) Find the appropriate asm file in common/x86/*.asm&lt;br /&gt;
2010-11-22 20:39:42 &amp;lt; Dark_Shikari&amp;gt; 5) Find the existing 8-bit code for the function, and figure out how it works, preferably by asking questions in addition to staring at it&lt;br /&gt;
2010-11-22 20:39:55 &amp;lt; Dark_Shikari&amp;gt; (while keeping the C code as a reference)&lt;br /&gt;
2010-11-22 20:40:15 &amp;lt; Dark_Shikari&amp;gt; 6) write your version of the high bit-depth version.&lt;br /&gt;
2010-11-22 20:40:28 &amp;lt; Dark_Shikari&amp;gt; So for example, one that&#039;s missing is dequant, in quant-a.asm, with quant.c for the C stuff.&lt;br /&gt;
2010-11-22 20:40:59 &amp;lt; Dark_Shikari&amp;gt; The C version of this function is about 10 lines and should be pretty easy to read.&lt;br /&gt;
2010-11-22 20:42:03 &amp;lt; Dark_Shikari&amp;gt; don&#039;t worry too much about optimization when first writing the function: I can make comments on it later.&lt;br /&gt;
2010-11-22 20:42:25 &amp;lt; Dark_Shikari&amp;gt; a good way to spot missing functions is to run ./checkasm --bench with and without --bit-depth=10 in configure.&lt;br /&gt;
2010-11-22 20:42:37 &amp;lt; Dark_Shikari&amp;gt; it does a benchmark of *all* asm functions and nicely lists them for you.&lt;br /&gt;
2010-11-22 20:45:56 &amp;lt; callahan&amp;gt; Dark_Shikari: Emergency mode works well so far.  You should commit it...&lt;br /&gt;
2010-11-22 20:46:18 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll get to it, maybe this week or next&lt;br /&gt;
2010-11-22 20:46:22 &amp;lt; Dark_Shikari&amp;gt; I have a few other changes I have to make&lt;br /&gt;
2010-11-22 20:46:23 &amp;lt; Dark_Shikari&amp;gt; and I&#039;m busy&lt;br /&gt;
2010-11-22 20:46:30 &amp;lt; nattofriends&amp;gt; emergency mode?&lt;br /&gt;
2010-11-22 20:46:40 &amp;lt; nattofriends&amp;gt; does that give x264 big red flashing lights?&lt;br /&gt;
2010-11-22 20:46:41 &amp;lt; callahan&amp;gt; Yeah, GCI craziness&lt;br /&gt;
2010-11-22 20:46:46 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-22 20:46:55 &amp;lt; Dark_Shikari&amp;gt; it makes x264 not die when you throw /dev/random at it&lt;br /&gt;
2010-11-22 20:47:54 &amp;lt; rfw&amp;gt; Dark_Shikari: can i ask more dumb questions about regression testing&lt;br /&gt;
2010-11-22 20:48:06 &amp;lt; rfw&amp;gt; since i still don&#039;t seem to be 100% clear about it&lt;br /&gt;
2010-11-22 20:48:08 &amp;lt; Dark_Shikari&amp;gt; Don&#039;t ask to ask&lt;br /&gt;
2010-11-22 20:48:12 &amp;lt; komisar&amp;gt; Dark_Shikari: what about auto-levels patch?&lt;br /&gt;
2010-11-22 20:48:13 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-22 20:48:13 &amp;lt; Dark_Shikari&amp;gt; just ask&lt;br /&gt;
2010-11-22 20:48:19 &amp;lt; rfw&amp;gt; i still don&#039;t get what you mean by permutations&lt;br /&gt;
2010-11-22 20:48:19 &amp;lt; Dark_Shikari&amp;gt; komisar: oh, that should be higher priority, I&#039;ll get it in next&lt;br /&gt;
2010-11-22 20:49:00 &amp;lt; Dark_Shikari&amp;gt; Suppose I have options A, B, and C.&lt;br /&gt;
2010-11-22 20:49:03 &amp;lt; rfw&amp;gt; oh, i get it now&lt;br /&gt;
2010-11-22 20:49:09 &amp;lt; Dark_Shikari&amp;gt; I can test with no options&lt;br /&gt;
2010-11-22 20:49:09 &amp;lt; rfw&amp;gt; replacing ; with ;\n helped a lot&lt;br /&gt;
2010-11-22 20:49:10 &amp;lt; Dark_Shikari&amp;gt; just A&lt;br /&gt;
2010-11-22 20:49:12 &amp;lt; Dark_Shikari&amp;gt; just B&lt;br /&gt;
2010-11-22 20:49:12 &amp;lt; Dark_Shikari&amp;gt; just C&lt;br /&gt;
2010-11-22 20:49:15 &amp;lt; Dark_Shikari&amp;gt; A and B&lt;br /&gt;
2010-11-22 20:49:17 &amp;lt; Dark_Shikari&amp;gt; B and C&lt;br /&gt;
2010-11-22 20:49:20 &amp;lt; Dark_Shikari&amp;gt; A, B and C&lt;br /&gt;
2010-11-22 20:49:20 &amp;lt; rfw&amp;gt; yeah i understand&lt;br /&gt;
2010-11-22 20:49:23 &amp;lt; Dark_Shikari&amp;gt; ok, so combinations, not permutations&lt;br /&gt;
2010-11-22 20:49:25 &amp;lt; Dark_Shikari&amp;gt; but whatever! ;)&lt;br /&gt;
2010-11-22 20:49:35 &amp;lt; rfw&amp;gt; cartesian product actually :)&lt;br /&gt;
2010-11-22 20:50:23 &amp;lt; Gramner&amp;gt; you missed &amp;quot;A and C&amp;quot;!&lt;br /&gt;
2010-11-22 20:50:30 &amp;lt; Dark_Shikari&amp;gt; ah yes.&lt;br /&gt;
2010-11-22 20:56:41 &amp;lt; tjoener&amp;gt; damnit&lt;br /&gt;
2010-11-22 20:56:47 &amp;lt; tjoener&amp;gt; terminal locked my alt keys :@&lt;br /&gt;
2010-11-22 20:58:12 &amp;lt; j-b&amp;gt; Dark_Shikari: http://www.google-melange.com/gci/task/show/google/gci2010/videolan/t128908283186 and http://www.google-melange.com/gci/task/show/google/gci2010/videolan/t128908435924&lt;br /&gt;
2010-11-22 20:58:38 &amp;lt; Dark_Shikari&amp;gt; I know&lt;br /&gt;
2010-11-22 20:58:41 &amp;lt; Dark_Shikari&amp;gt; they&#039;ve already shown up here&lt;br /&gt;
2010-11-22 21:13:52 &amp;lt; j-b&amp;gt; Dark_Shikari: so you need to approve at some point, I guess&lt;br /&gt;
2010-11-22 21:14:40 &amp;lt; Dark_Shikari&amp;gt; oh I do?&lt;br /&gt;
2010-11-22 21:16:02 &amp;lt; Dark_Shikari&amp;gt; done&lt;br /&gt;
2010-11-22 21:45:54 &amp;lt; rfw&amp;gt; i think i&#039;m taking too much time to time to make a test suite than to actually make the tests&lt;br /&gt;
2010-11-22 21:46:05 &amp;lt; rfw&amp;gt; and wow that sentence was badly formed&lt;br /&gt;
2010-11-22 21:47:16 &amp;lt; Dark_Shikari&amp;gt; rfw: the tests are easy&lt;br /&gt;
2010-11-22 21:47:19 &amp;lt; Dark_Shikari&amp;gt; the hard part is interpreting them&lt;br /&gt;
2010-11-22 21:47:26 &amp;lt; Dark_Shikari&amp;gt; that is, for example&lt;br /&gt;
2010-11-22 21:47:28 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 21:47:33 &amp;lt; Dark_Shikari&amp;gt; really easy interpretation: compare yuvs, see if encoder matches decoder&lt;br /&gt;
2010-11-22 21:47:38 &amp;lt; Dark_Shikari&amp;gt; that&#039;s trivial: a binary decision&lt;br /&gt;
2010-11-22 21:47:39 &amp;lt; Dark_Shikari&amp;gt; 1 or 0&lt;br /&gt;
2010-11-22 21:47:42 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-22 21:47:43 &amp;lt; Dark_Shikari&amp;gt; is it right or not.&lt;br /&gt;
2010-11-22 21:47:52 &amp;lt; Dark_Shikari&amp;gt; But of course, we might also want to know what frame it&#039;s wrong on, if it failed.&lt;br /&gt;
2010-11-22 21:47:57 &amp;lt; Dark_Shikari&amp;gt; Or if the decoder failed to output all the frames.&lt;br /&gt;
2010-11-22 21:47:59 &amp;lt; Dark_Shikari&amp;gt; i.e. if it crashed, etc.&lt;br /&gt;
2010-11-22 21:48:07 &amp;lt; Dark_Shikari&amp;gt; And what macroblock it&#039;s wrong on (i.e. where in the frame)&lt;br /&gt;
2010-11-22 21:48:17 &amp;lt; Dark_Shikari&amp;gt; And then, we might want to investigate more complex things&lt;br /&gt;
2010-11-22 21:48:21 &amp;lt; Dark_Shikari&amp;gt; like for example, compare PSNR between two revisions&lt;br /&gt;
2010-11-22 21:48:27 &amp;lt; rfw&amp;gt; do you have examples testing for macroblocks&lt;br /&gt;
2010-11-22 21:48:37 &amp;lt; Dark_Shikari&amp;gt; well that&#039;s very easy, you just have to do the math&lt;br /&gt;
2010-11-22 21:48:40 &amp;lt; rfw&amp;gt; since i have no idea about how YUV data works&lt;br /&gt;
2010-11-22 21:48:46 &amp;lt; Dark_Shikari&amp;gt; each frame is layed out as follows:&lt;br /&gt;
2010-11-22 21:49:05 &amp;lt; Dark_Shikari&amp;gt; a 2D array of width WIDTH and height HEIGHT, containing Y&lt;br /&gt;
2010-11-22 21:49:12 &amp;lt; Dark_Shikari&amp;gt; a 2D array of width WIDTH/2 and height HEIGHT/2, containing U&lt;br /&gt;
2010-11-22 21:49:13 &amp;lt; Dark_Shikari&amp;gt; a 2D array of width WIDTH/2 and height HEIGHT/2, containing V&lt;br /&gt;
2010-11-22 21:49:17 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 21:49:20 &amp;lt; Dark_Shikari&amp;gt; so the total size is 1.5 * WIDTH * HEIGHT&lt;br /&gt;
2010-11-22 21:49:26 &amp;lt; rfw&amp;gt; so i just spew out the part where it mismatches?&lt;br /&gt;
2010-11-22 21:49:28 &amp;lt; Dark_Shikari&amp;gt; so knowing the size of each frame, you can figure out from any offset in the file&lt;br /&gt;
2010-11-22 21:49:31 &amp;lt; Dark_Shikari&amp;gt; a) what frame it&#039;s in&lt;br /&gt;
2010-11-22 21:49:34 &amp;lt; Dark_Shikari&amp;gt; b) what macroblock it&#039;s in&lt;br /&gt;
2010-11-22 21:49:42 &amp;lt; rfw&amp;gt; how is a macroblock defined&lt;br /&gt;
2010-11-22 21:49:51 &amp;lt; Dark_Shikari&amp;gt; the frame is split into 16x16 blocks&lt;br /&gt;
2010-11-22 21:49:59 &amp;lt; Dark_Shikari&amp;gt; (well, 16x16 of luma, obviously each 16x16 of Y is 8x8 of U and V)&lt;br /&gt;
2010-11-22 21:50:04 &amp;lt; Dark_Shikari&amp;gt; since U and V are half size&lt;br /&gt;
2010-11-22 21:50:08 &amp;lt; Dark_Shikari&amp;gt; these are arranged in raster order&lt;br /&gt;
2010-11-22 21:50:11 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 21:50:15 &amp;lt; Dark_Shikari&amp;gt; so for example, frame 57 might be bad at macroblock (5,17)&lt;br /&gt;
2010-11-22 21:50:38 &amp;lt; rfw&amp;gt; i see, so&lt;br /&gt;
2010-11-22 21:50:44 &amp;lt; rfw&amp;gt; for a rudimentary comparison of two outputs&lt;br /&gt;
2010-11-22 21:50:47 &amp;lt; rfw&amp;gt; i could just checksum them&lt;br /&gt;
2010-11-22 21:50:51 &amp;lt; rfw&amp;gt; then if they mismatch&lt;br /&gt;
2010-11-22 21:50:57 &amp;lt; rfw&amp;gt; i compare frames, then macroblocks?&lt;br /&gt;
2010-11-22 21:52:01 &amp;lt; Dark_Shikari&amp;gt; no&lt;br /&gt;
2010-11-22 21:52:12 &amp;lt; Dark_Shikari&amp;gt; first you check to see the filesize are the same&lt;br /&gt;
2010-11-22 21:52:14 &amp;lt; Dark_Shikari&amp;gt; if not, report an error&lt;br /&gt;
2010-11-22 21:52:28 &amp;lt; Dark_Shikari&amp;gt; second, you find the first byte in the two files that differs&lt;br /&gt;
2010-11-22 21:52:33 &amp;lt; Dark_Shikari&amp;gt; then you calculate which frame and MB it belongs to.&lt;br /&gt;
2010-11-22 21:52:58 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-22 21:53:05 &amp;lt; rfw&amp;gt; this sounded so much easier before&lt;br /&gt;
2010-11-22 21:54:04 &amp;lt; Dark_Shikari&amp;gt; the more fancy part of the tool is wrapping around this comparison&lt;br /&gt;
2010-11-22 21:54:05 &amp;lt; Dark_Shikari&amp;gt; for example&lt;br /&gt;
2010-11-22 21:54:13 &amp;lt; Dark_Shikari&amp;gt; suppose I know the latest x264 is broken&lt;br /&gt;
2010-11-22 21:54:16 &amp;lt; Dark_Shikari&amp;gt; and I want to know what broke it&lt;br /&gt;
2010-11-22 21:54:28 &amp;lt; Dark_Shikari&amp;gt; your script could run git bisect using your comparison script&lt;br /&gt;
2010-11-22 21:54:35 &amp;lt; Dark_Shikari&amp;gt; so in effect, it&#039;s modular:&lt;br /&gt;
2010-11-22 21:54:37 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-22 21:54:47 &amp;lt; Dark_Shikari&amp;gt; 1) Comparison: comparing two revisions in some way (whether it be via yuv dump, psnr, etc)&lt;br /&gt;
2010-11-22 21:54:53 &amp;lt; rfw&amp;gt; but i&#039;m decoupling the scm from the core so i can&#039;t really run git bisect&lt;br /&gt;
2010-11-22 21:54:58 &amp;lt; Dark_Shikari&amp;gt; 2) How we use those comparisons (checking multiple revisions, etc)&lt;br /&gt;
2010-11-22 21:55:32 &amp;lt; rfw&amp;gt; well, what my idea is is to create a couple of fixtures which can be used to test every revision&lt;br /&gt;
2010-11-22 21:55:40 &amp;lt; rfw&amp;gt; which generates a dump of the results&lt;br /&gt;
2010-11-22 21:55:49 &amp;lt; rfw&amp;gt; then those can be compared with the tool from revision to revision&lt;br /&gt;
2010-11-22 21:56:39 &amp;lt; Dark_Shikari&amp;gt; well, keep in mind that whatever yours does, it must do more than my crappy script&lt;br /&gt;
2010-11-22 21:56:42 &amp;lt; Dark_Shikari&amp;gt; ;)&lt;br /&gt;
2010-11-22 21:56:44 &amp;lt; Dark_Shikari&amp;gt; i.e. enough to make it worthwhile&lt;br /&gt;
2010-11-22 21:56:49 &amp;lt; rfw&amp;gt; oh it already does more&lt;br /&gt;
2010-11-22 21:56:50 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-22 21:56:52 &amp;lt; Dark_Shikari&amp;gt; it should also be self-contained and not require really fancy other libs&lt;br /&gt;
2010-11-22 21:56:55 &amp;lt; Dark_Shikari&amp;gt; if possible&lt;br /&gt;
2010-11-22 21:57:02 &amp;lt; Dark_Shikari&amp;gt; though that&#039;s not required if you gt a big benefit from some other lib&lt;br /&gt;
2010-11-22 21:57:09 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-22 21:57:10 &amp;lt; Dark_Shikari&amp;gt; just don&#039;t cover it in boost or something&lt;br /&gt;
2010-11-22 21:57:14 &amp;lt; rfw&amp;gt; oh it&#039;s python&lt;br /&gt;
2010-11-22 21:57:15 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-22 21:57:17 &amp;lt; Dark_Shikari&amp;gt; good&lt;br /&gt;
2010-11-22 21:57:17 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-22 21:57:25 &amp;lt; rfw&amp;gt; boost gives me nightmares&lt;br /&gt;
2010-11-22 21:57:32 &amp;lt; Dark_Shikari&amp;gt; you&#039;re not the only one&lt;br /&gt;
2010-11-22 21:57:48 &amp;lt; Dark_Shikari&amp;gt; when I worked at facebook, one of my coworkers attempted to use almost every single boost feature in every project&lt;br /&gt;
2010-11-22 21:58:17 &amp;lt; rfw&amp;gt; how many screens of template errors does that make&lt;br /&gt;
2010-11-22 21:58:34 &amp;lt; Dark_Shikari&amp;gt; I&#039;ve seen a single *symbol* in a C++ program that was over 30 kilobytes&lt;br /&gt;
2010-11-22 21:59:25 &amp;lt; Jumpyshoes&amp;gt; hey Dark_Shikari, i&#039;m taking a look at some functions, and some call macros (like TRANSPOSE4x4w), does the higher bit depth have an equivalent of these, or do i need to check on a case by case basis?&lt;br /&gt;
2010-11-22 21:59:29 &amp;lt; checkers&amp;gt; I thought facebook used PHP? Do they write some stuff in C++?&lt;br /&gt;
2010-11-22 21:59:39 &amp;lt; Dark_Shikari&amp;gt; flvtool++ is C++&lt;br /&gt;
2010-11-22 21:59:42 &amp;lt; Dark_Shikari&amp;gt; along with lots of other internal tools&lt;br /&gt;
2010-11-22 21:59:43 &amp;lt; djahandarie&amp;gt; Facebook uses all sorts of languages, but yeah mainly PHP&lt;br /&gt;
2010-11-22 21:59:53 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: If there isn&#039;t one, you&#039;ll have to write it!&lt;br /&gt;
2010-11-22 22:00:05 &amp;lt; Dark_Shikari&amp;gt; A good start is to look at functions that use TRANSPOSE4x4W&lt;br /&gt;
2010-11-22 22:00:19 &amp;lt; Dark_Shikari&amp;gt; if there&#039;s a high bit depth version, the high bit depth version likely calls the high bit depth version of TRANSPOSE4x4W&lt;br /&gt;
2010-11-22 22:01:11 &amp;lt; Jumpyshoes&amp;gt; let&#039;s see&lt;br /&gt;
2010-11-22 22:01:14 &amp;lt; Dark_Shikari&amp;gt; since the normal and high bit depth do the same thing, just with different data types.&lt;br /&gt;
2010-11-22 22:01:26 &amp;lt; Jumpyshoes&amp;gt; TRANSPOSE4x4W calls other macros haha&lt;br /&gt;
2010-11-22 22:02:12 &amp;lt; Dark_Shikari&amp;gt; yup, SBUTTERFLY&lt;br /&gt;
2010-11-22 22:02:15 &amp;lt; Dark_Shikari&amp;gt; a transpose is a series of butterflies&lt;br /&gt;
2010-11-22 22:02:23 &amp;lt; Dark_Shikari&amp;gt; see &amp;quot;butterfly diagram&amp;quot; on wikipedia&lt;br /&gt;
2010-11-22 22:02:42 &amp;lt; Jumpyshoes&amp;gt; would i need to write that too?&lt;br /&gt;
2010-11-22 22:03:37 &amp;lt; Dark_Shikari&amp;gt; no, a butterfly is a generic operation&lt;br /&gt;
2010-11-22 22:03:44 &amp;lt; Dark_Shikari&amp;gt; not restrained to any data type&lt;br /&gt;
2010-11-22 22:03:49 &amp;lt; Dark_Shikari&amp;gt; that is, you tell it the data type to take&lt;br /&gt;
2010-11-22 22:03:51 &amp;lt; Dark_Shikari&amp;gt; it&#039;s a three line macro anyways!&lt;br /&gt;
2010-11-22 22:04:00 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-22 22:04:36 &amp;lt; Jumpyshoes&amp;gt; TRANSPOSE4x4W &amp;lt;-- what does the W at the end signify?&lt;br /&gt;
2010-11-22 22:05:11 &amp;lt; Dark_Shikari&amp;gt; words&lt;br /&gt;
2010-11-22 22:05:13 &amp;lt; Dark_Shikari&amp;gt; 16-bit&lt;br /&gt;
2010-11-22 22:05:27 &amp;lt; Dark_Shikari&amp;gt; so if the low bit depth function uses 16-bit intermediate data&lt;br /&gt;
2010-11-22 22:05:35 &amp;lt; Dark_Shikari&amp;gt; and you decide to use 32-bit intermediates instead for high bit depth&lt;br /&gt;
2010-11-22 22:05:38 &amp;lt; Dark_Shikari&amp;gt; you&#039;ll need TRANSPOSE4x4D&lt;br /&gt;
2010-11-22 22:05:53 &amp;lt; Jumpyshoes&amp;gt; ah, i see&lt;br /&gt;
2010-11-22 22:07:33 &amp;lt; Dark_Shikari&amp;gt; so transpose doesn&#039;t have a native &amp;quot;bit depth&amp;quot;&lt;br /&gt;
2010-11-22 22:07:37 &amp;lt; Dark_Shikari&amp;gt; rather it has a size of element it operates on&lt;br /&gt;
2010-11-22 22:07:42 &amp;lt; Dark_Shikari&amp;gt; and that may or may not be the size you need.&lt;br /&gt;
2010-11-22 22:08:32 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 22:08:54 &amp;lt; Dark_Shikari&amp;gt; note that intermediate sizes aren&#039;t always higher in high bit depth&lt;br /&gt;
2010-11-22 22:09:02 &amp;lt; Dark_Shikari&amp;gt; for example, in satd, you can still get away with 16-bit intermediates with 10-bit input&lt;br /&gt;
2010-11-22 22:09:05 &amp;lt; Dark_Shikari&amp;gt; this was a huge boon for speed&lt;br /&gt;
2010-11-22 22:09:40 &amp;lt; Dark_Shikari&amp;gt; (satd is one of those that&#039;s done, since it&#039;s the most important asm function in x264)&lt;br /&gt;
2010-11-22 22:10:03 &amp;lt; Jumpyshoes&amp;gt; out of curiosity, why do the sse* asm functions seem to be longer and more complicated then the mmx ones?&lt;br /&gt;
2010-11-22 22:10:50 &amp;lt; Dark_Shikari&amp;gt; depends, which ones are you looking at?&lt;br /&gt;
2010-11-22 22:11:10 &amp;lt; Jumpyshoes&amp;gt; add4x4_idct&lt;br /&gt;
2010-11-22 22:11:17 &amp;lt; Dark_Shikari&amp;gt; that&#039;s a special case&lt;br /&gt;
2010-11-22 22:11:24 &amp;lt; Dark_Shikari&amp;gt; a 4x4 idct needs, at most, 64 bits worth of register&lt;br /&gt;
2010-11-22 22:11:28 &amp;lt; Dark_Shikari&amp;gt; i.e. 4 16-bit values&lt;br /&gt;
2010-11-22 22:11:31 &amp;lt; Dark_Shikari&amp;gt; because, well, it&#039;s 4 wide&lt;br /&gt;
2010-11-22 22:11:33 &amp;lt; Dark_Shikari&amp;gt; and the values are 16-bit&lt;br /&gt;
2010-11-22 22:11:35 &amp;lt; Dark_Shikari&amp;gt; so, naturally&lt;br /&gt;
2010-11-22 22:11:48 &amp;lt; Dark_Shikari&amp;gt; So, if you want to take advantage of SSE, you do multiple idcts at a time&lt;br /&gt;
2010-11-22 22:11:55 &amp;lt; Dark_Shikari&amp;gt; as is done in the larger ones&lt;br /&gt;
2010-11-22 22:11:57 &amp;lt; Dark_Shikari&amp;gt; But...&lt;br /&gt;
2010-11-22 22:12:09 &amp;lt; Dark_Shikari&amp;gt; in some places in x264, we can only do a 4x4 idct for technical reasons, i.e. we can only do one at a time&lt;br /&gt;
2010-11-22 22:12:27 &amp;lt; Dark_Shikari&amp;gt; So, for the fun of it and the challenge, holger wrote an SSE4 implementation that tries to take advantage of the extra register space&lt;br /&gt;
2010-11-22 22:12:30 &amp;lt; Dark_Shikari&amp;gt; through horrible horrible munging&lt;br /&gt;
2010-11-22 22:12:40 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-22 22:12:42 &amp;lt; Dark_Shikari&amp;gt; It&#039;s a decent bit faster.&lt;br /&gt;
2010-11-22 22:12:53 &amp;lt; Dark_Shikari&amp;gt; But it&#039;s far more complicated and harder to read because it&#039;s doing things in a completely nonintutive, ugly way.&lt;br /&gt;
2010-11-22 22:12:57 &amp;lt; Dark_Shikari&amp;gt; In order to stuff more values into one register.&lt;br /&gt;
2010-11-22 22:13:22 &amp;lt; Jumpyshoes&amp;gt; yea, it sure looks harder to read&lt;br /&gt;
2010-11-22 22:13:51 &amp;lt; Dark_Shikari&amp;gt; remember width 4 SAD?&lt;br /&gt;
2010-11-22 22:13:53 &amp;lt; Dark_Shikari&amp;gt; with the punpckldq?&lt;br /&gt;
2010-11-22 22:14:01 &amp;lt; Dark_Shikari&amp;gt; that&#039;s an example of munging to take advantage of a register wider than your data.&lt;br /&gt;
2010-11-22 22:14:11 &amp;lt; Dark_Shikari&amp;gt; sse4 idct 4x4 is another one.&lt;br /&gt;
2010-11-22 22:14:41 &amp;lt; Jumpyshoes&amp;gt; aahh&lt;br /&gt;
2010-11-22 22:14:42 &amp;lt; Dark_Shikari&amp;gt; In general, in high bit depth, you&#039;ll almost never have this problem, since high bit depth has much larger data types.&lt;br /&gt;
2010-11-22 22:14:53 &amp;lt; Dark_Shikari&amp;gt; 4x4 idct, btw, I think has no high bit depth implementation.&lt;br /&gt;
2010-11-22 22:15:02 &amp;lt; Dark_Shikari&amp;gt; so that could be a good starting point&lt;br /&gt;
2010-11-22 22:15:03 &amp;lt; Jumpyshoes&amp;gt; yea, as far as i can tell, it doesn&#039;t&lt;br /&gt;
2010-11-22 22:15:07 &amp;lt; Jumpyshoes&amp;gt; which is why i was looking at it&lt;br /&gt;
2010-11-22 22:15:12 &amp;lt; Dark_Shikari&amp;gt; Yeah, that would be a good one&lt;br /&gt;
2010-11-22 22:15:22 &amp;lt; Dark_Shikari&amp;gt; Not too complex, pretty straightforward&lt;br /&gt;
2010-11-22 22:15:24 &amp;lt; Jumpyshoes&amp;gt; do you have a link that actually explains h264&#039;s DCT?&lt;br /&gt;
2010-11-22 22:15:31 &amp;lt; Dark_Shikari&amp;gt; As long as you stay very very far away from the sse4 oen&lt;br /&gt;
2010-11-22 22:15:37 &amp;lt; Dark_Shikari&amp;gt; how much do you know about DCTs?&lt;br /&gt;
2010-11-22 22:15:46 &amp;lt; Jumpyshoes&amp;gt; i know JPEG&#039;s DCT&lt;br /&gt;
2010-11-22 22:16:04 &amp;lt; Jumpyshoes&amp;gt; performs a seperable transformation which compacts energy&lt;br /&gt;
2010-11-22 22:16:09 &amp;lt; Jumpyshoes&amp;gt; to the top coefficients&lt;br /&gt;
2010-11-22 22:16:17 &amp;lt; Jumpyshoes&amp;gt; so you can effectively 0 out the lower ones&lt;br /&gt;
2010-11-22 22:16:19 &amp;lt; Jumpyshoes&amp;gt; w/ quantization&lt;br /&gt;
2010-11-22 22:16:35 &amp;lt; Dark_Shikari&amp;gt; JPEG&#039;s is just *THE* DCT&lt;br /&gt;
2010-11-22 22:16:40 &amp;lt; Dark_Shikari&amp;gt; that is what a dct is&lt;br /&gt;
2010-11-22 22:16:51 &amp;lt; Dark_Shikari&amp;gt; H.264&#039;s transform is often colloquially known as the HCT (H.264 Cosine Transform) as it isn&#039;t the DCT.&lt;br /&gt;
2010-11-22 22:16:56 &amp;lt; Dark_Shikari&amp;gt; It&#039;s a very very rough approximation.&lt;br /&gt;
2010-11-22 22:16:58 &amp;lt; Jumpyshoes&amp;gt; i heard h264&#039;s only used integer arithmetic?&lt;br /&gt;
2010-11-22 22:17:03 &amp;lt; Dark_Shikari&amp;gt; More than just that&lt;br /&gt;
2010-11-22 22:17:09 &amp;lt; Dark_Shikari&amp;gt; all real implementations of DCTs are integer-only&lt;br /&gt;
2010-11-22 22:17:22 &amp;lt; Dark_Shikari&amp;gt; and all modern video ones (VC-1, H.264, VP8, RV40, etc) are bit-exact, too.&lt;br /&gt;
2010-11-22 22:17:26 &amp;lt; Dark_Shikari&amp;gt; But H.264&#039;s is extra-special&lt;br /&gt;
2010-11-22 22:17:37 &amp;lt; Dark_Shikari&amp;gt; It requires nothing more than shifts and adds.&lt;br /&gt;
2010-11-22 22:17:41 &amp;lt; Dark_Shikari&amp;gt; and subtracts, I guess.&lt;br /&gt;
2010-11-22 22:17:51 &amp;lt; Dark_Shikari&amp;gt; The 4x4 dct in particular requires no shifts larger than 1.&lt;br /&gt;
2010-11-22 22:18:00 &amp;lt; Dark_Shikari&amp;gt; this makes it more like a Hadamard transform than a DCT.&lt;br /&gt;
2010-11-22 22:18:13 &amp;lt; Dark_Shikari&amp;gt; It&#039;s slightly less compression-efficient (~1%) than the ideal DCT, but way way way way way faster.&lt;br /&gt;
2010-11-22 22:18:21 &amp;lt; Dark_Shikari&amp;gt; Now, here&#039;s the catch with this&lt;br /&gt;
2010-11-22 22:18:51 &amp;lt; Dark_Shikari&amp;gt; if you analyse this DCT, you&#039;ll find out that it isn&#039;t properly normalized, i.e. the values outputted by the DCT and inputted to the iDCT are scaled differently per coefficient&lt;br /&gt;
2010-11-22 22:18:58 &amp;lt; Dark_Shikari&amp;gt; this is one of the consequences of the extremely simple implementation.&lt;br /&gt;
2010-11-22 22:19:09 &amp;lt; Dark_Shikari&amp;gt; So what they did... they rolled these numbers into the quantization scaling factors.&lt;br /&gt;
2010-11-22 22:19:16 &amp;lt; Dark_Shikari&amp;gt; Thus making multiplying by them cost nothing.&lt;br /&gt;
2010-11-22 22:19:23 &amp;lt; Dark_Shikari&amp;gt; Since you&#039;re already multiplying for quantization.&lt;br /&gt;
2010-11-22 22:19:40 &amp;lt; Dark_Shikari&amp;gt; so dct -&amp;gt; quant -&amp;gt; dequant -&amp;gt; idct&lt;br /&gt;
2010-11-22 22:19:48 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;quant&amp;quot; adds in the scaling factors for the dct&lt;br /&gt;
2010-11-22 22:19:53 &amp;lt; Dark_Shikari&amp;gt; and &amp;quot;dequant&amp;quot; adds in the scaling factors for the idct.&lt;br /&gt;
2010-11-22 22:19:58 &amp;lt; Dark_Shikari&amp;gt; (in addition to doing what they normally do)&lt;br /&gt;
2010-11-22 22:20:01 &amp;lt; Jumpyshoes&amp;gt; huh, i see&lt;br /&gt;
2010-11-22 22:20:12 &amp;lt; Dark_Shikari&amp;gt; You don&#039;t have to know about this when implementing a dct or idct, but it explains how it works.&lt;br /&gt;
2010-11-22 22:20:41 &amp;lt; Jumpyshoes&amp;gt; well, i need to figure out what the C code does&lt;br /&gt;
2010-11-22 22:20:52 &amp;lt; Dark_Shikari&amp;gt; This isn&#039;t involved in figuring out what it does.&lt;br /&gt;
2010-11-22 22:20:59 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-22 22:21:00 &amp;lt; Dark_Shikari&amp;gt; The C code just does a 1D transform in each direction.&lt;br /&gt;
2010-11-22 22:21:13 &amp;lt; Dark_Shikari&amp;gt; and the transform is rather obvious and simple, the challenge is if you want to figure out why it works.&lt;br /&gt;
2010-11-22 22:21:20 &amp;lt; Dark_Shikari&amp;gt; Which you don&#039;t have to, of course.&lt;br /&gt;
2010-11-22 22:21:26 &amp;lt; Dark_Shikari&amp;gt; since that&#039;s math and math is hard&lt;br /&gt;
2010-11-22 22:21:37 &amp;lt; Jumpyshoes&amp;gt; what does x264_clip_pixel do?&lt;br /&gt;
2010-11-22 22:22:05 &amp;lt; Dark_Shikari&amp;gt; It clips a pixel to within the valid range.&lt;br /&gt;
2010-11-22 22:22:10 &amp;lt; Dark_Shikari&amp;gt; 0-255 for 8-bit&lt;br /&gt;
2010-11-22 22:22:13 &amp;lt; Dark_Shikari&amp;gt; 0-511 for 9-bit&lt;br /&gt;
2010-11-22 22:22:13 &amp;lt; Dark_Shikari&amp;gt; etc etc&lt;br /&gt;
2010-11-22 22:22:28 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 22:22:30 &amp;lt; Dark_Shikari&amp;gt; This is because, after an idct, pixel values can go outside the valid range.&lt;br /&gt;
2010-11-22 22:22:33 &amp;lt; Dark_Shikari&amp;gt; the idct is required to clamp its output.&lt;br /&gt;
2010-11-22 22:22:41 &amp;lt; Dark_Shikari&amp;gt; to avoid overflow&lt;br /&gt;
2010-11-22 22:23:13 &amp;lt; Jumpyshoes&amp;gt; i see&lt;br /&gt;
2010-11-22 22:24:50 &amp;lt; Dark_Shikari&amp;gt; this is trickier for high bit depth&lt;br /&gt;
2010-11-22 22:24:57 &amp;lt; Jumpyshoes&amp;gt; does IDCT4_1D depend on the input size?&lt;br /&gt;
2010-11-22 22:25:01 &amp;lt; Dark_Shikari&amp;gt; if our pixels are 8-bit, we can just do packusbw&lt;br /&gt;
2010-11-22 22:25:04 &amp;lt; Dark_Shikari&amp;gt; which automatically saturates&lt;br /&gt;
2010-11-22 22:25:17 &amp;lt; Dark_Shikari&amp;gt; but for larger values we can&#039;t.&lt;br /&gt;
2010-11-22 22:25:22 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: yes, go look at it&lt;br /&gt;
2010-11-22 22:25:26 &amp;lt; Dark_Shikari&amp;gt; it probably uses word math (paddw, etc)&lt;br /&gt;
2010-11-22 22:26:02 &amp;lt; Jumpyshoes&amp;gt; it calls a bunch of SUMSUBD2_AB and stuff&lt;br /&gt;
2010-11-22 22:26:31 &amp;lt; Dark_Shikari&amp;gt; go look at what those do&lt;br /&gt;
2010-11-22 22:26:35 &amp;lt; Dark_Shikari&amp;gt; they&#039;re pretty trivial&lt;br /&gt;
2010-11-22 22:26:40 &amp;lt; Dark_Shikari&amp;gt; a SUMSUB calculates A+B and A-B&lt;br /&gt;
2010-11-22 22:26:42 &amp;lt; Dark_Shikari&amp;gt; for inputs A and B&lt;br /&gt;
2010-11-22 22:26:44 &amp;lt; Dark_Shikari&amp;gt; (surprise!)&lt;br /&gt;
2010-11-22 22:27:40 &amp;lt; Jumpyshoes&amp;gt; ah, so it does depend on the bit depth&lt;br /&gt;
2010-11-22 22:28:19 &amp;lt; Dark_Shikari&amp;gt; You could modify SUMSUB to take an argument for the data element size&lt;br /&gt;
2010-11-22 22:28:24 &amp;lt; Dark_Shikari&amp;gt; e.g. &amp;quot;w&amp;quot; for 16-bit, &amp;quot;d&amp;quot; for 32-bit&lt;br /&gt;
2010-11-22 22:28:30 &amp;lt; Dark_Shikari&amp;gt; then go around and find all existing calls to SUMSUB and add that&lt;br /&gt;
2010-11-22 22:28:33 &amp;lt; Dark_Shikari&amp;gt; make sure it still works&lt;br /&gt;
2010-11-22 22:28:39 &amp;lt; Dark_Shikari&amp;gt; then write your own passing &amp;quot;d&amp;quot; instead of &amp;quot;w&amp;quot;&lt;br /&gt;
2010-11-22 22:28:45 &amp;lt; Dark_Shikari&amp;gt; so for example&lt;br /&gt;
2010-11-22 22:28:57 &amp;lt; Dark_Shikari&amp;gt; SUMSUB mm0, mm1 would become SUMSUB w, mm0, mm1&lt;br /&gt;
2010-11-22 22:29:00 &amp;lt; Dark_Shikari&amp;gt; or similar&lt;br /&gt;
2010-11-22 22:29:13 &amp;lt; Jumpyshoes&amp;gt; wouldn&#039;t i need to replace it in every SUMSUB then?&lt;br /&gt;
2010-11-22 22:30:14 &amp;lt; Dark_Shikari&amp;gt; yes, you&#039;d have to add the &amp;quot;w&amp;quot; argument to every SUMSUB&lt;br /&gt;
2010-11-22 22:30:19 &amp;lt; Dark_Shikari&amp;gt; There aren&#039;t that many calls though&lt;br /&gt;
2010-11-22 22:30:27 &amp;lt; Dark_Shikari&amp;gt; most SUMSUB calls are in util&lt;br /&gt;
2010-11-22 22:30:30 &amp;lt; Dark_Shikari&amp;gt; i.e. as part of other things&lt;br /&gt;
2010-11-22 22:30:31 &amp;lt; Dark_Shikari&amp;gt; like transforms&lt;br /&gt;
2010-11-22 22:30:40 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-22 22:30:44 &amp;lt; Dark_Shikari&amp;gt; i.e. few functions call sumsub directly, they call it through macros&lt;br /&gt;
2010-11-22 22:30:48 &amp;lt; Dark_Shikari&amp;gt; like IDCT4_1D&lt;br /&gt;
2010-11-22 22:31:20 &amp;lt; Jumpyshoes&amp;gt; okay, time to try this out&lt;br /&gt;
2010-11-22 22:33:00 &amp;lt; Jumpyshoes&amp;gt; what is passed if i have &amp;quot;w&amp;quot; as an argument?&lt;br /&gt;
2010-11-22 22:33:11 &amp;lt; Jumpyshoes&amp;gt; is it just &amp;quot;w&amp;quot; in %0?&lt;br /&gt;
2010-11-22 22:33:20 &amp;lt; Jumpyshoes&amp;gt; er, %1&lt;br /&gt;
2010-11-22 22:33:43 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-22 22:33:44 &amp;lt; Dark_Shikari&amp;gt; so for example&lt;br /&gt;
2010-11-22 22:33:46 &amp;lt; Dark_Shikari&amp;gt; paddw becomes padd%1&lt;br /&gt;
2010-11-22 22:33:50 &amp;lt; Dark_Shikari&amp;gt; cool, eh?&lt;br /&gt;
2010-11-22 22:33:54 &amp;lt; Jumpyshoes&amp;gt; indeed&lt;br /&gt;
2010-11-22 22:34:02 &amp;lt; Dark_Shikari&amp;gt; also, on an unrelated note, %0 is the number of macro parameters.&lt;br /&gt;
2010-11-22 22:34:08 &amp;lt; Dark_Shikari&amp;gt; This is useful when making variadic macros.&lt;br /&gt;
2010-11-22 22:34:49 &amp;lt; Jumpyshoes&amp;gt; yasm is pretty handy&lt;br /&gt;
2010-11-22 22:35:30 &amp;lt; Dark_Shikari&amp;gt; yasm&#039;s preprocess is basically what C&#039;s should have been.&lt;br /&gt;
2010-11-22 22:35:33 &amp;lt; Dark_Shikari&amp;gt; *preprocessor&lt;br /&gt;
2010-11-22 22:37:15 &amp;lt; Jumpyshoes&amp;gt; what does mova do?&lt;br /&gt;
2010-11-22 22:37:36 &amp;lt; Dark_Shikari&amp;gt; as mentioned yesterday, it&#039;s part of the templating system&lt;br /&gt;
2010-11-22 22:37:39 &amp;lt; Dark_Shikari&amp;gt; if INIT_MMX is used, it&#039;s movq&lt;br /&gt;
2010-11-22 22:37:43 &amp;lt; Dark_Shikari&amp;gt; if INIT_XMM is used, it&#039;a movdqa&lt;br /&gt;
2010-11-22 22:37:44 &amp;lt; Jumpyshoes&amp;gt; er, right&lt;br /&gt;
2010-11-22 22:37:44 &amp;lt; Dark_Shikari&amp;gt; *it&#039;s&lt;br /&gt;
2010-11-22 22:37:49 &amp;lt; Dark_Shikari&amp;gt; in short, &amp;quot;move a whole register, aligned&amp;quot;&lt;br /&gt;
2010-11-22 22:37:59 &amp;lt; Dark_Shikari&amp;gt; in that macro it&#039;s just a register-to-register move.&lt;br /&gt;
2010-11-22 22:38:02 &amp;lt; Dark_Shikari&amp;gt; iirc&lt;br /&gt;
2010-11-22 22:44:55 &amp;lt; Sean_McG&amp;gt; 10:02 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: ^ &amp;lt;-- what was this all about, it&#039;s scrolled off&lt;br /&gt;
2010-11-22 22:45:41 &amp;lt; Dark_Shikari&amp;gt; pengvado had a comment for you&lt;br /&gt;
2010-11-22 22:45:43 &amp;lt; Dark_Shikari&amp;gt; grab the log and read it&lt;br /&gt;
2010-11-22 22:45:46 &amp;lt; Dark_Shikari&amp;gt; it&#039;s why I didn&#039;t commit your fix&lt;br /&gt;
2010-11-22 22:47:44 &amp;lt; Sean_McG&amp;gt; oh regarding Mans note about &#039;strings&#039;? Yeah, I understand... not sure how to fix it anymore though.&lt;br /&gt;
2010-11-22 22:48:51 &amp;lt; Sean_McG&amp;gt; not discarding the whole commit though, are we? can we just roll back the change to configure?&lt;br /&gt;
2010-11-22 22:49:38 &amp;lt; Sean_McG&amp;gt; back later -- meeting a co-worker for dinner&lt;br /&gt;
2010-11-22 23:09:09 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: I just discarded it for now&lt;br /&gt;
2010-11-22 23:09:12 &amp;lt; Dark_Shikari&amp;gt; it&#039;ll be in the next commit spree if you fix it&lt;br /&gt;
2010-11-22 23:16:42 &amp;lt; rfw&amp;gt; i should probably make my output easier to read&lt;br /&gt;
2010-11-22 23:17:36 &amp;lt; rfw&amp;gt; Dark_Shikari: http://pastebin.com/g58FejEe is this painful in any way to read&lt;br /&gt;
2010-11-22 23:18:33 &amp;lt; Dark_Shikari&amp;gt; It probably shouldn&#039;t use 4chan terminology.&lt;br /&gt;
2010-11-22 23:18:47 &amp;lt; rfw&amp;gt; oh those are just my half-assed commit messages&lt;br /&gt;
2010-11-22 23:18:48 &amp;lt; Dark_Shikari&amp;gt; Also most of that should be omitted in non-verbose mode&lt;br /&gt;
2010-11-22 23:18:58 &amp;lt; rfw&amp;gt; from my testing repo&lt;br /&gt;
2010-11-22 23:19:00 &amp;lt; rfw&amp;gt; don&#039;t mind that lol&lt;br /&gt;
2010-11-22 23:19:01 &amp;lt; Dark_Shikari&amp;gt; in non-verbose mode, it should tell me just what I want to know&lt;br /&gt;
2010-11-22 23:19:06 &amp;lt; Dark_Shikari&amp;gt; i.e. &amp;quot;X is broken, Y works&amp;quot;&lt;br /&gt;
2010-11-22 23:19:11 &amp;lt; Dark_Shikari&amp;gt; not all the things it did to discover that.&lt;br /&gt;
2010-11-22 23:19:14 &amp;lt; Dark_Shikari&amp;gt; in verbose mode it can tell me that&lt;br /&gt;
2010-11-22 23:58:13 &amp;lt; kemuri-_9&amp;gt; what is the purpose of that large configure change for the 1/0 vs 1/undef in the preprocessor vars?&lt;br /&gt;
--- Day changed Tue Nov 23 2010&lt;br /&gt;
2010-11-23 00:00:58 &amp;lt; holger_&amp;gt; &amp;lt;Dark_Shikari&amp;gt; But it&#039;s far more complicated and harder to read because it&#039;s doing things in a completely nonintutive, ugly way. &amp;lt;-- mostly due to the fact that this actually was an exercise in optimizing for atom. you only took the sse4 version, so it&#039;s not entirely obvious anymore ;)&lt;br /&gt;
2010-11-23 00:02:04 &amp;lt; Kovensky&amp;gt; kemuri-_9: being able to just use #if instead of having to use #ifdef&lt;br /&gt;
2010-11-23 00:02:28 &amp;lt; kemuri-_9&amp;gt; the preprocessor defaults undef to 0 though&lt;br /&gt;
2010-11-23 00:02:41 &amp;lt; Kovensky&amp;gt; and complains about it&lt;br /&gt;
2010-11-23 00:02:47 &amp;lt; kemuri-_9&amp;gt; what compiler?&lt;br /&gt;
2010-11-23 00:03:28 &amp;lt; Kovensky&amp;gt; gcc&lt;br /&gt;
2010-11-23 00:04:02 &amp;lt; pengvado&amp;gt; #if works on undef, but any other forms of conditionals don&#039;t&lt;br /&gt;
2010-11-23 00:04:27 &amp;lt; pengvado&amp;gt; ?:, &amp;amp;&amp;amp;, if(), ...&lt;br /&gt;
2010-11-23 00:04:32 &amp;lt; kemuri-_9&amp;gt; do we use any other conditionals on those values?&lt;br /&gt;
2010-11-23 00:04:49 &amp;lt; pengvado&amp;gt; not yet&lt;br /&gt;
2010-11-23 00:05:41 &amp;lt; kemuri-_9&amp;gt; it would probably be easier to check at the end of the ./configure to see which values are missing from the config.h than if (x=yes) define x 1 else define x 0&lt;br /&gt;
2010-11-23 00:05:50 &amp;lt; kemuri-_9&amp;gt; which is being splattered everywhere&lt;br /&gt;
2010-11-23 00:06:44 &amp;lt; Kovensky&amp;gt; that&#039;s... awfully verbose&lt;br /&gt;
2010-11-23 00:06:55 &amp;lt; Kovensky&amp;gt; just define x $(x=yes)&lt;br /&gt;
2010-11-23 00:08:13 &amp;lt; pengvado&amp;gt; Kovensky: what language is that? not bash&lt;br /&gt;
2010-11-23 00:08:47 &amp;lt; kemuri-_9&amp;gt; define x [ $x = yes ]  &amp;lt;--- would this not be what he was trying to do?&lt;br /&gt;
2010-11-23 00:08:50 &amp;lt; Kovensky&amp;gt; it isn&#039;t, I&#039;m just copying his pseudocode&lt;br /&gt;
2010-11-23 00:09:10 &amp;lt; Kovensky&amp;gt; define x $([ $x = yes ] &amp;amp;&amp;amp; echo 1 || echo 0)&lt;br /&gt;
2010-11-23 00:09:17 &amp;lt; Kovensky&amp;gt; er&lt;br /&gt;
2010-11-23 00:09:32 &amp;lt; Kovensky&amp;gt; hm nvm, that&#039;s correct&lt;br /&gt;
2010-11-23 00:09:36 &amp;lt; Kovensky&amp;gt; $? would give wrong results&lt;br /&gt;
2010-11-23 00:11:22 &amp;lt; kemuri-_9&amp;gt; and why all the changes to the makefile/config.mak? changing them to findstring x 1  from findstring x  works doesn&#039;t it?&lt;br /&gt;
2010-11-23 00:11:30 &amp;lt; rfw&amp;gt; time for lunch then more regression testing&lt;br /&gt;
2010-11-23 00:27:06 &amp;lt; Sean_McG&amp;gt; DS: both my submissions?&lt;br /&gt;
2010-11-23 00:27:55 &amp;lt; rfw&amp;gt; there, that&#039;s the testing framework done&lt;br /&gt;
2010-11-23 00:28:02 &amp;lt; rfw&amp;gt; what regression tests am i required to implement?&lt;br /&gt;
2010-11-23 00:29:53 &amp;lt; Sean_McG&amp;gt; DS: my 2nd submission regarding the VIS asm is still OK, yes?&lt;br /&gt;
2010-11-23 00:32:56 &amp;lt; Sean_McG&amp;gt; DS: for the &#039;configure&#039; change... is it acceptable if we just extend the length of the array and manually terminate the string?&lt;br /&gt;
2010-11-23 00:33:14 &amp;lt; Sean_McG&amp;gt; DS: and no one has been able to provide me with a platform to test where that breaks either.&lt;br /&gt;
2010-11-23 00:40:23 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: I don&#039;t care about configure.&lt;br /&gt;
2010-11-23 00:40:27 &amp;lt; Dark_Shikari&amp;gt; All that matters is that pengvado is satisfied&lt;br /&gt;
2010-11-23 00:40:36 &amp;lt; jarod&amp;gt; and the wife&lt;br /&gt;
2010-11-23 00:40:37 &amp;lt; Dark_Shikari&amp;gt; rfw: ok, the most basic is the two dump yuv tests&lt;br /&gt;
2010-11-23 00:40:38 &amp;lt; Sean_McG&amp;gt; OK... I&#039;ll try again&lt;br /&gt;
2010-11-23 00:40:41 &amp;lt; Dark_Shikari&amp;gt; compare vs JM and ffmpeg&lt;br /&gt;
2010-11-23 00:40:51 &amp;lt; Dark_Shikari&amp;gt; ffmpeg has some known decoding bugs, so JM is more important&lt;br /&gt;
2010-11-23 00:40:54 &amp;lt; Dark_Shikari&amp;gt; but they work in the same way&lt;br /&gt;
2010-11-23 00:41:00 &amp;lt; Dark_Shikari&amp;gt; for JM, just run ldecod -i inputfile&lt;br /&gt;
2010-11-23 00:41:00 &amp;lt; rfw&amp;gt; ah so&lt;br /&gt;
2010-11-23 00:41:02 &amp;lt; Dark_Shikari&amp;gt; it&#039;ll output to test_dec.yuv&lt;br /&gt;
2010-11-23 00:41:07 &amp;lt; rfw&amp;gt; i get JM and ffmpeg&lt;br /&gt;
2010-11-23 00:41:07 &amp;lt; Sean_McG&amp;gt; also, does r1789 fix the same artifacting issue BugMaster was talking about yesterday, with gcc 4.5.x?&lt;br /&gt;
2010-11-23 00:41:14 &amp;lt; rfw&amp;gt; and get x264 to dump a yuv&lt;br /&gt;
2010-11-23 00:41:15 &amp;lt; Dark_Shikari&amp;gt; for ffmpeg, do ffmpeg -i input -pix_fmt yuv420p -f rawvideo output.yuv&lt;br /&gt;
2010-11-23 00:41:20 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: yes&lt;br /&gt;
2010-11-23 00:41:22 &amp;lt; rfw&amp;gt; yeah i know how to use ffmpeg&lt;br /&gt;
2010-11-23 00:41:23 &amp;lt; Sean_McG&amp;gt; OK cool&lt;br /&gt;
2010-11-23 00:41:29  * Sean_McG rebuilds&lt;br /&gt;
2010-11-23 00:43:20 &amp;lt; rfw&amp;gt; time to get my msbuild ou&lt;br /&gt;
2010-11-23 00:43:20 &amp;lt; rfw&amp;gt; t&lt;br /&gt;
2010-11-23 00:44:01 &amp;lt; Dark_Shikari&amp;gt; msbuild?&lt;br /&gt;
2010-11-23 00:45:46 &amp;lt; rfw&amp;gt; yeah, to buidl the JM solution&lt;br /&gt;
2010-11-23 00:45:53 &amp;lt; Sean_McG&amp;gt; DS: can I revert my patch in my local tree without mucking with the commits I did afterwards? (I admit I&#039;m so used to cvs and svn that I still don&#039;t fully grok how git workflows are supposed to be done)&lt;br /&gt;
2010-11-23 00:46:04 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;revert&amp;quot;?&lt;br /&gt;
2010-11-23 00:46:10 &amp;lt; rfw&amp;gt; c:\users\tony\downloads\jm17.2\jm\lcommon\inc\win32.h(39): fatal error C1083: Cannot open include file: &#039;omp.h&#039;: No such file or directory [C:\Users\Tony\Downloads\jm17.2\JM\jm_vc9.sln]&lt;br /&gt;
2010-11-23 00:46:10 &amp;lt; rfw&amp;gt;  118 Error(s)&lt;br /&gt;
2010-11-23 00:46:15 &amp;lt; rfw&amp;gt; tihs isn&#039;t going very well&lt;br /&gt;
2010-11-23 00:46:20 &amp;lt; Sean_McG&amp;gt; DS: pull it out so I can edit it and recommit later&lt;br /&gt;
2010-11-23 00:46:27 &amp;lt; Dark_Shikari&amp;gt; git rebase -i&lt;br /&gt;
2010-11-23 00:46:36 &amp;lt; Dark_Shikari&amp;gt; rfw: compile in cygwin/mingw&lt;br /&gt;
2010-11-23 00:46:38 &amp;lt; Sean_McG&amp;gt; what does that do, cherry pick?&lt;br /&gt;
2010-11-23 00:46:44 &amp;lt; Dark_Shikari&amp;gt; it lets you edit any past commit&lt;br /&gt;
2010-11-23 00:46:50 &amp;lt; Dark_Shikari&amp;gt; just replace the word &amp;quot;pick&amp;quot; with the word &amp;quot;edit&amp;quot;&lt;br /&gt;
2010-11-23 00:46:53 &amp;lt; Dark_Shikari&amp;gt; for the commit you want&lt;br /&gt;
2010-11-23 00:47:01 &amp;lt; Dark_Shikari&amp;gt; and then when you&#039;re done, amend it and git rebase --continue&lt;br /&gt;
2010-11-23 00:47:24 &amp;lt; kemuri-_9&amp;gt; http://kemuri9.net/dev/misc/jm/jm17.2.rar  &amp;lt;--- i built this a while back for someone else in msvc, can use it if you want&lt;br /&gt;
2010-11-23 00:47:35 &amp;lt; Dark_Shikari&amp;gt; I just use cygwin, works fine here :&amp;gt;&lt;br /&gt;
2010-11-23 00:47:42 &amp;lt; rfw&amp;gt; but i just finied building with cygwin :&amp;lt;&lt;br /&gt;
2010-11-23 00:48:04 &amp;lt; kemuri-_9&amp;gt; pengvado: what do you think of http://pastebin.com/ZAb3crs1 ?&lt;br /&gt;
2010-11-23 00:48:09 &amp;lt; Dark_Shikari&amp;gt; that doesn&#039;t look like an error from cygwin&lt;br /&gt;
2010-11-23 00:48:26 &amp;lt; rfw&amp;gt; no i mean&lt;br /&gt;
2010-11-23 00:48:32 &amp;lt; rfw&amp;gt; i just built it with cygwin&lt;br /&gt;
2010-11-23 00:48:36 &amp;lt; rfw&amp;gt; (successfully)&lt;br /&gt;
2010-11-23 00:48:46 &amp;lt; rfw&amp;gt; that was from vs2010 before&lt;br /&gt;
2010-11-23 00:50:52 &amp;lt; Dark_Shikari&amp;gt; well that&#039;s what you get for trying to use vs2010&lt;br /&gt;
2010-11-23 00:51:09 &amp;lt; rfw&amp;gt; :&amp;lt;&lt;br /&gt;
2010-11-23 00:51:11 &amp;lt; kemuri-_9&amp;gt; lol&lt;br /&gt;
2010-11-23 00:51:52 &amp;lt; kemuri-_9&amp;gt; speaking of which i should reinstall vs2008 and icl so i can mess with that crap again&lt;br /&gt;
2010-11-23 00:56:07 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari: so i fell asleep, but would this work for SUMSUB_BA: http://pastebin.com/6Fms1SAB ?&lt;br /&gt;
2010-11-23 00:57:09 &amp;lt; Dark_Shikari&amp;gt; no&lt;br /&gt;
2010-11-23 00:57:44 &amp;lt; rfw&amp;gt; Dark_Shikari: how do i make x264 output raw YUV again?&lt;br /&gt;
2010-11-23 00:57:59 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: you probably want something like http://pastebin.com/xewaKQPt&lt;br /&gt;
2010-11-23 00:58:05 &amp;lt; checkers&amp;gt; -o file.yuv&lt;br /&gt;
2010-11-23 00:58:05 &amp;lt; Dark_Shikari&amp;gt; rfw: --dump-yuv file.yuv&lt;br /&gt;
2010-11-23 00:58:09 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 00:58:50 &amp;lt; rfw&amp;gt; ah okay&lt;br /&gt;
2010-11-23 00:58:51 &amp;lt; Jumpyshoes&amp;gt; thanks&lt;br /&gt;
2010-11-23 00:59:53 &amp;lt; rfw&amp;gt; Dark_Shikari: do you have any specific file or anything to test it on&lt;br /&gt;
2010-11-23 00:59:58 &amp;lt; rfw&amp;gt; or do i just grab one of my videos&lt;br /&gt;
2010-11-23 01:00:48 &amp;lt; Dark_Shikari&amp;gt; rfw: http://media.xiph.org/video/derf/ pick one&lt;br /&gt;
2010-11-23 01:00:59 &amp;lt; Dark_Shikari&amp;gt; if you want to test breaking x264 to see if your tool detects it&lt;br /&gt;
2010-11-23 01:01:13 &amp;lt; Dark_Shikari&amp;gt; in common/mc.c, find pixel_avg_wxh&lt;br /&gt;
2010-11-23 01:01:14 &amp;lt; Dark_Shikari&amp;gt; remove the +1&lt;br /&gt;
2010-11-23 01:01:23 &amp;lt; Dark_Shikari&amp;gt; then recompile and run x264 with --no-asm&lt;br /&gt;
2010-11-23 01:01:29 &amp;lt; Dark_Shikari&amp;gt; it will fail all tests on the first b-frame&lt;br /&gt;
2010-11-23 01:01:34 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 01:02:34 &amp;lt; Dark_Shikari&amp;gt; I chose that function because I and P-frames will still work&lt;br /&gt;
2010-11-23 01:02:38 &amp;lt; Dark_Shikari&amp;gt; so it doesn&#039;t completely break things&lt;br /&gt;
2010-11-23 01:02:41 &amp;lt; Dark_Shikari&amp;gt; allowing more meaningful testing&lt;br /&gt;
2010-11-23 01:08:21 &amp;lt; Sean_McG&amp;gt; alright, I guess I need someone who gives a rip about this endian test... doesn&#039;t mean anything to Windows people. Does pengvado use Windows or Linux or..?&lt;br /&gt;
2010-11-23 01:08:52 &amp;lt; Sean_McG&amp;gt; there *is* an autoconf macro: AC_C_BIGENDIAN... should I just adapt that?&lt;br /&gt;
2010-11-23 01:09:39 &amp;lt; rfw&amp;gt; Fixture result: PASS, took 6.9245 seconds.&lt;br /&gt;
2010-11-23 01:09:39 &amp;lt; rfw&amp;gt; Project result: PASS, took 6.9245 seconds.&lt;br /&gt;
2010-11-23 01:09:40 &amp;lt; rfw&amp;gt; \o/&lt;br /&gt;
2010-11-23 01:09:52 &amp;lt; Dark_Shikari&amp;gt; \o/&lt;br /&gt;
2010-11-23 01:10:57 &amp;lt; rfw&amp;gt; Fixture result: FAIL.&lt;br /&gt;
2010-11-23 01:10:58 &amp;lt; rfw&amp;gt; Project result: FAIL.&lt;br /&gt;
2010-11-23 01:11:00 &amp;lt; rfw&amp;gt; it can fail too \o/&lt;br /&gt;
2010-11-23 01:11:11 &amp;lt; Dark_Shikari&amp;gt; Now we just have to make that more descriptive.&lt;br /&gt;
2010-11-23 01:11:18 &amp;lt; rfw&amp;gt; yup&lt;br /&gt;
2010-11-23 01:11:35 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari http://pastebin.com/T0jbAwwv would this work for the rest?&lt;br /&gt;
2010-11-23 01:11:39  * Dark_Shikari very much likes finding high school students who can python better than he can&lt;br /&gt;
2010-11-23 01:11:48 &amp;lt; Dark_Shikari&amp;gt; also python is now a verb&lt;br /&gt;
2010-11-23 01:11:54 &amp;lt; rfw&amp;gt; http://pastebin.com/GF1czXrr&lt;br /&gt;
2010-11-23 01:12:02 &amp;lt; rfw&amp;gt; this probably would be much better suited for python projects, lol&lt;br /&gt;
2010-11-23 01:12:15 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: lgtm, you now have to modify the rest of x264 asm to call these correctly&lt;br /&gt;
2010-11-23 01:12:18 &amp;lt; Dark_Shikari&amp;gt; i.e. grep for them, add ws&lt;br /&gt;
2010-11-23 01:12:27 &amp;lt; Dark_Shikari&amp;gt; once you&#039;re done, compile in bit-depth 8 mode, and checkasm&lt;br /&gt;
2010-11-23 01:12:31 &amp;lt; Dark_Shikari&amp;gt; and fix until it works&lt;br /&gt;
2010-11-23 01:12:38 &amp;lt; Jumpyshoes&amp;gt; ws?&lt;br /&gt;
2010-11-23 01:13:14 &amp;lt; Dark_Shikari&amp;gt; plural w&lt;br /&gt;
2010-11-23 01:13:25 &amp;lt; Jumpyshoes&amp;gt; oh right&lt;br /&gt;
2010-11-23 01:13:57 &amp;lt; Jumpyshoes&amp;gt; there&#039;s like 3 pages of SUMSUBs, is there any way to replace them in all files?&lt;br /&gt;
2010-11-23 01:14:06 &amp;lt; Dark_Shikari&amp;gt; find/replace&lt;br /&gt;
2010-11-23 01:14:13 &amp;lt; Dark_Shikari&amp;gt; SUMSUB -&amp;gt; SUMSUMB w,&lt;br /&gt;
2010-11-23 01:14:22 &amp;lt; Jumpyshoes&amp;gt; can i ignore spacing for now?&lt;br /&gt;
2010-11-23 01:14:29 &amp;lt; Dark_Shikari&amp;gt; find/replace should be able to handle spacing.&lt;br /&gt;
2010-11-23 01:14:33 &amp;lt; Dark_Shikari&amp;gt; Anyways, it&#039;s just 15 minutes of work =p&lt;br /&gt;
2010-11-23 01:14:34 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-23 01:14:42 &amp;lt; Jumpyshoes&amp;gt; &amp;lt;-- lazy butt&lt;br /&gt;
2010-11-23 01:15:08 &amp;lt; Dark_Shikari&amp;gt; welcome to the club&lt;br /&gt;
2010-11-23 01:15:20 &amp;lt; kierank&amp;gt; [01:15] Jumpyshoes: &amp;lt;-- lazy butt --&amp;gt; you&#039;ll fit right in&lt;br /&gt;
2010-11-23 01:15:34 &amp;lt; Dark_Shikari&amp;gt; pretty much&lt;br /&gt;
2010-11-23 01:15:47 &amp;lt; Dark_Shikari&amp;gt; like the other day when I spent 2 hours to finish chroma weightp.&lt;br /&gt;
2010-11-23 01:15:47 &amp;lt; Jumpyshoes&amp;gt; oh excellent&lt;br /&gt;
2010-11-23 01:15:49 &amp;lt; Dark_Shikari&amp;gt; wait -- you say -- that&#039;s work!&lt;br /&gt;
2010-11-23 01:15:57 &amp;lt; Dark_Shikari&amp;gt; But it took one full year for me to get around to doing it&lt;br /&gt;
2010-11-23 01:16:03 &amp;lt; Jumpyshoes&amp;gt; LOL&lt;br /&gt;
2010-11-23 01:16:08 &amp;lt; Jumpyshoes&amp;gt; you sound exactly like one of my friends&lt;br /&gt;
2010-11-23 01:16:19 &amp;lt; Dark_Shikari&amp;gt; and I only did it on a dare from boiled_sugar&lt;br /&gt;
2010-11-23 01:17:07 &amp;lt; kemuri-_9&amp;gt; so dares are useful motivation?&lt;br /&gt;
2010-11-23 01:17:25 &amp;lt; Kovensky&amp;gt; 22:16.19 Dark_Shikari: and I only did it on a dare from boiled_sugar &amp;lt;-- lol&lt;br /&gt;
2010-11-23 01:17:26 &amp;lt; Kovensky&amp;gt; what was it&lt;br /&gt;
2010-11-23 01:18:03 &amp;lt; Dark_Shikari&amp;gt; he kept yelling at me to do chroma weightp&lt;br /&gt;
2010-11-23 01:18:07 &amp;lt; Dark_Shikari&amp;gt; so I said I&#039;d do it that weekend&lt;br /&gt;
2010-11-23 01:18:08 &amp;lt; Dark_Shikari&amp;gt; so I did&lt;br /&gt;
2010-11-23 01:18:40 &amp;lt; Jumpyshoes&amp;gt; haha, 97 of the SUMSUBs are arm&lt;br /&gt;
2010-11-23 01:18:47 &amp;lt; Jumpyshoes&amp;gt; that&#039;s half my work done!&lt;br /&gt;
2010-11-23 01:18:49 &amp;lt; Dark_Shikari&amp;gt; saves you some time eh!&lt;br /&gt;
2010-11-23 01:18:50 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 01:25:51 &amp;lt; rfw&amp;gt; Running test yuv_compare... failed, due to x264-output.yuv is not the same as jm-output.yuv (69076e2a5a9a76d5b483abe953b4a6ce vs 19becfba7cf53d773756095d8a355938)&lt;br /&gt;
2010-11-23 01:26:04 &amp;lt; rfw&amp;gt; there&#039;s some more verbosity&lt;br /&gt;
2010-11-23 01:26:06 &amp;lt; Dark_Shikari&amp;gt; don&#039;t need to hash imo&lt;br /&gt;
2010-11-23 01:26:08 &amp;lt; Dark_Shikari&amp;gt; waste of time&lt;br /&gt;
2010-11-23 01:26:16 &amp;lt; rfw&amp;gt; yeah but i haven&#039;t implemented all the macroblocking&lt;br /&gt;
2010-11-23 01:26:17 &amp;lt; rfw&amp;gt; and stuff&lt;br /&gt;
2010-11-23 01:26:24 &amp;lt; rfw&amp;gt; so i&#039;m just doing that for now&lt;br /&gt;
2010-11-23 01:27:14 &amp;lt; Dark_Shikari&amp;gt; you could just give a file offset&lt;br /&gt;
2010-11-23 01:27:17 &amp;lt; Dark_Shikari&amp;gt; like diff does&lt;br /&gt;
2010-11-23 01:27:27 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 01:27:34 &amp;lt; Dark_Shikari&amp;gt; btw, you should test your thing on files larger than ram&lt;br /&gt;
2010-11-23 01:27:38 &amp;lt; Dark_Shikari&amp;gt; i.e. you should not rely on O(N) ram usage&lt;br /&gt;
2010-11-23 01:27:44 &amp;lt; Dark_Shikari&amp;gt; because yuv files get really fucking huge.&lt;br /&gt;
2010-11-23 01:28:44 &amp;lt; rfw&amp;gt; yeah i know&lt;br /&gt;
2010-11-23 01:28:55 &amp;lt; rfw&amp;gt; i&#039;m reading it into a buffer and then puking it out again&lt;br /&gt;
2010-11-23 01:29:13 &amp;lt; Dark_Shikari&amp;gt; yeah, don&#039;t do that&lt;br /&gt;
2010-11-23 01:29:24 &amp;lt; rfw&amp;gt; what?&lt;br /&gt;
2010-11-23 01:29:30 &amp;lt; Dark_Shikari&amp;gt; I mean, don&#039;t read the whole file into a buffer&lt;br /&gt;
2010-11-23 01:29:35 &amp;lt; rfw&amp;gt; no i&#039;m not doing that&lt;br /&gt;
2010-11-23 01:29:35 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 01:29:36 &amp;lt; Dark_Shikari&amp;gt; oh ok&lt;br /&gt;
2010-11-23 01:29:37 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 01:29:41 &amp;lt; rfw&amp;gt; i&#039;m reading 8k bytes at a time&lt;br /&gt;
2010-11-23 01:29:46 &amp;lt; Dark_Shikari&amp;gt; good, so you&#039;re not like the author of flvtool2&lt;br /&gt;
2010-11-23 01:29:49 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 01:29:58 &amp;lt; Dark_Shikari&amp;gt; aka &amp;quot;ruby programmers&amp;quot;&lt;br /&gt;
2010-11-23 01:30:10 &amp;lt; rfw&amp;gt; i could never get into ruby&lt;br /&gt;
2010-11-23 01:30:11 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 01:30:54 &amp;lt; Dark_Shikari&amp;gt; btw, remember that your script will have to pass through pengvado&lt;br /&gt;
2010-11-23 01:30:59 &amp;lt; Dark_Shikari&amp;gt; think of him as gandalf, and you as the balrog&lt;br /&gt;
2010-11-23 01:31:21 &amp;lt; rfw&amp;gt; it&#039;s not so much a script as a huge python library&lt;br /&gt;
2010-11-23 01:31:36 &amp;lt; kemuri-_9&amp;gt; lol @ that analogy&lt;br /&gt;
2010-11-23 01:31:44 &amp;lt; rfw&amp;gt; wait a minute, doesn&#039;t that mean i lose&lt;br /&gt;
2010-11-23 01:33:22 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 01:33:30 &amp;lt; Dark_Shikari&amp;gt; it&#039;s a great analogy for professors&lt;br /&gt;
2010-11-23 01:33:33 &amp;lt; Dark_Shikari&amp;gt; YOU SHALL NOT PASS etc&lt;br /&gt;
2010-11-23 01:33:46 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;huge python library&amp;quot;?&lt;br /&gt;
2010-11-23 01:34:00 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 01:34:12 &amp;lt; rfw&amp;gt; http://pastebin.com/GF1czXrr&lt;br /&gt;
2010-11-23 01:34:35 &amp;lt; Dark_Shikari&amp;gt; what&#039;s digress?&lt;br /&gt;
2010-11-23 01:34:43 &amp;lt; rfw&amp;gt; what i called it&lt;br /&gt;
2010-11-23 01:34:49 &amp;lt; Dark_Shikari&amp;gt; Oh, and where will we get that?&lt;br /&gt;
2010-11-23 01:34:59 &amp;lt; rfw&amp;gt; i haven&#039;t finished writing it you know&lt;br /&gt;
2010-11-23 01:34:59 &amp;lt; rfw&amp;gt; :3&lt;br /&gt;
2010-11-23 01:35:01 &amp;lt; Dark_Shikari&amp;gt; will it be included in the source tree or just a lib the regtest tool requires?&lt;br /&gt;
2010-11-23 01:35:04 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 01:35:07 &amp;lt; Dark_Shikari&amp;gt; hahaha&lt;br /&gt;
2010-11-23 01:35:14 &amp;lt; Dark_Shikari&amp;gt; works for me as long as it works =p&lt;br /&gt;
2010-11-23 01:36:55 &amp;lt; Dark_Shikari&amp;gt; the main issue being that since your tool isn&#039;t part of x264, dependency issues aren&#039;t as big a deal&lt;br /&gt;
2010-11-23 01:37:03 &amp;lt; Dark_Shikari&amp;gt; for x264 itself, we make a big deal about not requiring external dependencies&lt;br /&gt;
2010-11-23 01:37:07 &amp;lt; Dark_Shikari&amp;gt; but for dev tools, whateva&lt;br /&gt;
2010-11-23 01:37:36 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 01:37:39 &amp;lt; rfw&amp;gt; it only depends on python&lt;br /&gt;
2010-11-23 01:38:05 &amp;lt; rfw&amp;gt; i guess you could include my package that&#039;s more or less standalone in the source tree&lt;br /&gt;
2010-11-23 01:38:23 &amp;lt; rfw&amp;gt; (i sorta wanted to use it for my own projects in future too :P)&lt;br /&gt;
2010-11-23 01:38:32 &amp;lt; Dark_Shikari&amp;gt; we could put it in extras/&lt;br /&gt;
2010-11-23 01:38:50 &amp;lt; Dark_Shikari&amp;gt; like we put the avisynth C header there, and getopt, and other system-dependent imports that not everyone has&lt;br /&gt;
2010-11-23 01:39:22 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 01:47:49 &amp;lt; rfw&amp;gt; alright Dark_Shikari&lt;br /&gt;
2010-11-23 01:47:51 &amp;lt; rfw&amp;gt; that&#039;s that done&lt;br /&gt;
2010-11-23 01:47:53 &amp;lt; rfw&amp;gt; what else do i need&lt;br /&gt;
2010-11-23 01:48:10 &amp;lt; Jumpyshoes&amp;gt; hey Dark_Shikari, i&#039;m getting the error: undefined symbol `w&#039; in preprocessor, how do i set it to be a word again? bw is in other places in the code, is it that?&lt;br /&gt;
2010-11-23 01:48:46 &amp;lt; Dark_Shikari&amp;gt; where do you get this error?&lt;br /&gt;
2010-11-23 01:48:53 &amp;lt; Dark_Shikari&amp;gt; you will only get that error if you attempt to use it as a symbol&lt;br /&gt;
2010-11-23 01:48:55 &amp;lt; Dark_Shikari&amp;gt; which you shouldn&#039;t&lt;br /&gt;
2010-11-23 01:49:16 &amp;lt; Jumpyshoes&amp;gt; common/x86/dct-a.asm:178: error: (SUMSUBD2_AB:3) undefined symbol `w&#039; in preprocessor&lt;br /&gt;
2010-11-23 01:49:58 &amp;lt; Dark_Shikari&amp;gt; what&#039;s the third line of SUMSUBd@_AB?&lt;br /&gt;
2010-11-23 01:50:18 &amp;lt; Dark_Shikari&amp;gt; Ah, 79-85 in your paste is wrong&lt;br /&gt;
2010-11-23 01:50:21 &amp;lt; Dark_Shikari&amp;gt; it should be psra%1&lt;br /&gt;
2010-11-23 01:50:24 &amp;lt; Dark_Shikari&amp;gt; like in the other cases&lt;br /&gt;
2010-11-23 01:51:09 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 01:51:20 &amp;lt; Dark_Shikari&amp;gt; if you want to do a comparison, you&#039;d do&lt;br /&gt;
2010-11-23 01:51:22 &amp;lt; Dark_Shikari&amp;gt; %ifidn %1, w&lt;br /&gt;
2010-11-23 01:51:26 &amp;lt; Dark_Shikari&amp;gt; But you don&#039;t need to.&lt;br /&gt;
2010-11-23 01:51:40 &amp;lt; Jumpyshoes&amp;gt; google lied to me ;-;&lt;br /&gt;
2010-11-23 01:52:09 &amp;lt; Jumpyshoes&amp;gt; no it didn&#039;t&lt;br /&gt;
2010-11-23 01:52:11 &amp;lt; Jumpyshoes&amp;gt; i&#039;m just a dumbass&lt;br /&gt;
2010-11-23 01:52:23 &amp;lt; rfw&amp;gt; you know if google lied to us this competition could all be a lie&lt;br /&gt;
2010-11-23 01:52:24 &amp;lt; rfw&amp;gt; !!&lt;br /&gt;
2010-11-23 01:52:44 &amp;lt; Jumpyshoes&amp;gt; oh shit&lt;br /&gt;
2010-11-23 01:52:52 &amp;lt; Jumpyshoes&amp;gt; are you also a high school student?&lt;br /&gt;
2010-11-23 01:52:55 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 01:52:57 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 01:53:11 &amp;lt; rfw&amp;gt; i don&#039;t know shit about asm though&lt;br /&gt;
2010-11-23 01:53:15 &amp;lt; Jumpyshoes&amp;gt; where are you from?&lt;br /&gt;
2010-11-23 01:53:21 &amp;lt; rfw&amp;gt; new zealand&lt;br /&gt;
2010-11-23 01:53:23 &amp;lt; Dark_Shikari&amp;gt; google lied to you?&lt;br /&gt;
2010-11-23 01:53:24 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 01:53:39 &amp;lt; Jumpyshoes&amp;gt; i googled the instruction&lt;br /&gt;
2010-11-23 01:53:41 &amp;lt; Dark_Shikari&amp;gt; GOOGLE LIED, PEOPLE DIED&lt;br /&gt;
2010-11-23 01:53:43 &amp;lt; Jumpyshoes&amp;gt; and uh&lt;br /&gt;
2010-11-23 01:53:50 &amp;lt; Jumpyshoes&amp;gt; missed the instruction in the pages that came up&lt;br /&gt;
2010-11-23 01:53:51 &amp;lt; Jumpyshoes&amp;gt; somehow&lt;br /&gt;
2010-11-23 01:53:55 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-23 01:54:09 &amp;lt; rfw&amp;gt; where are you from, Jumpyshoes&lt;br /&gt;
2010-11-23 01:54:27 &amp;lt; rfw&amp;gt; washdc.fios.verizon.net lolnevermind&lt;br /&gt;
2010-11-23 01:54:30 &amp;lt; Jumpyshoes&amp;gt; yup&lt;br /&gt;
2010-11-23 01:54:43 &amp;lt; Jumpyshoes&amp;gt; i googled PSRAD but somehow thought it didn&#039;t exist&lt;br /&gt;
2010-11-23 01:54:48 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: google lies&lt;br /&gt;
2010-11-23 01:54:51 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-23 01:55:07 &amp;lt; Dark_Shikari&amp;gt; psrad is too rad for google&lt;br /&gt;
2010-11-23 01:55:29 &amp;lt; Jumpyshoes&amp;gt; well, it did show up&lt;br /&gt;
2010-11-23 01:55:36 &amp;lt; Jumpyshoes&amp;gt; i just somehow missed every page that came up&lt;br /&gt;
2010-11-23 01:55:38 &amp;lt; Jumpyshoes&amp;gt; or something&lt;br /&gt;
2010-11-23 01:56:13 &amp;lt; pengvado&amp;gt; Sean_McG: AC_C_BIGENDIAN is implemented by 200 lines of m4. if by &amp;quot;adapt&amp;quot; you mean &amp;quot;throw out everything except the grep that&#039;s just like the one we already have&amp;quot;, ok.&lt;br /&gt;
2010-11-23 01:56:26 &amp;lt; pengvado&amp;gt; null-termination is good enough for me&lt;br /&gt;
2010-11-23 01:57:21 &amp;lt; Sean_McG&amp;gt; pengvado: how do you &amp;quot;null terminate&amp;quot; an int?&lt;br /&gt;
2010-11-23 01:57:58 &amp;lt; pengvado&amp;gt; int i[2] = {0x42494745,0};&lt;br /&gt;
2010-11-23 01:58:20 &amp;lt; Sean_McG&amp;gt; and those are guaranteed to be sequential and fix the issue that Mans was pointing out?&lt;br /&gt;
2010-11-23 01:58:24 &amp;lt; pengvado&amp;gt; yes&lt;br /&gt;
2010-11-23 01:58:44 &amp;lt; Sean_McG&amp;gt; hmmm, OK. I&#039;ll fix and resend my patch as soon as 1790 is built&lt;br /&gt;
2010-11-23 01:59:24 &amp;lt; pengvado&amp;gt; mru is right that clang&#039;s intermediate representation isn&#039;t real asm and thus still breaks, but since I don&#039;t know of any method that *would* work there, sucks to be clang&lt;br /&gt;
2010-11-23 01:59:35 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 01:59:40 &amp;lt; Sean_McG&amp;gt; aye, that was my thought too&lt;br /&gt;
2010-11-23 02:00:18 &amp;lt; Sean_McG&amp;gt; the endian test would have to be &amp;quot;if { not building with clang }&amp;quot;&lt;br /&gt;
2010-11-23 02:01:20 &amp;lt; Sean_McG&amp;gt; and here we go... fprofiled just finished on my Sol10 VM. just need to package it up and post it on my webserver&lt;br /&gt;
2010-11-23 02:01:41 &amp;lt; Jumpyshoes&amp;gt; okay Dark_Shikari&lt;br /&gt;
2010-11-23 02:01:43 &amp;lt; Jumpyshoes&amp;gt; i think i am done&lt;br /&gt;
2010-11-23 02:02:18 &amp;lt; Dark_Shikari&amp;gt; does it pass checkasm?&lt;br /&gt;
2010-11-23 02:02:21 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 02:02:27 &amp;lt; Dark_Shikari&amp;gt; in 8 and 10-bit?&lt;br /&gt;
2010-11-23 02:02:30 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 02:02:34 &amp;lt; Jumpyshoes&amp;gt; haven&#039;t tested 10bit&lt;br /&gt;
2010-11-23 02:02:39 &amp;lt; Dark_Shikari&amp;gt; just check to make sure you didn&#039;t break it&lt;br /&gt;
2010-11-23 02:02:49 &amp;lt; Dark_Shikari&amp;gt; Once you&#039;re done with that, you can write your IDCT_1D high bit depth version&lt;br /&gt;
2010-11-23 02:02:50 &amp;lt; Dark_Shikari&amp;gt; or, even better...&lt;br /&gt;
2010-11-23 02:02:56 &amp;lt; Dark_Shikari&amp;gt; make IDCT4_1D take a w or d :) :)&lt;br /&gt;
2010-11-23 02:03:04 &amp;lt; Jumpyshoes&amp;gt; i actually have a geo quiz tomorrow&lt;br /&gt;
2010-11-23 02:03:07 &amp;lt; Jumpyshoes&amp;gt; that everyone failed&lt;br /&gt;
2010-11-23 02:03:10 &amp;lt; Jumpyshoes&amp;gt; even though it&#039;s GEO&lt;br /&gt;
2010-11-23 02:03:16 &amp;lt; Jumpyshoes&amp;gt; so i actually need to study for that&lt;br /&gt;
2010-11-23 02:03:22 &amp;lt; pengvado&amp;gt; kemuri-_9: `[ ... ]` fails, because [ sets an exit code whereas `` captures stdout&lt;br /&gt;
2010-11-23 02:03:25 &amp;lt; rfw&amp;gt; how old are you Jumpyshoes, out of interest&lt;br /&gt;
2010-11-23 02:03:27 &amp;lt; Jumpyshoes&amp;gt; 17&lt;br /&gt;
2010-11-23 02:03:31 &amp;lt; Jumpyshoes&amp;gt; you?&lt;br /&gt;
2010-11-23 02:03:32 &amp;lt; pengvado&amp;gt; just let the !GPL case be handled by the same loop as everything else&lt;br /&gt;
2010-11-23 02:03:33 &amp;lt; rfw&amp;gt; 16&lt;br /&gt;
2010-11-23 02:03:39 &amp;lt; kemuri-_9&amp;gt; ok&lt;br /&gt;
2010-11-23 02:03:40 &amp;lt; Jumpyshoes&amp;gt; &amp;lt;-- 12th grade&lt;br /&gt;
2010-11-23 02:03:40 &amp;lt; Dark_Shikari&amp;gt; I was 17 when I started on x264&lt;br /&gt;
2010-11-23 02:03:50 &amp;lt; Jumpyshoes&amp;gt; i can&#039;t wait for that point in school&lt;br /&gt;
2010-11-23 02:03:55 &amp;lt; Jumpyshoes&amp;gt; where i can just give up&lt;br /&gt;
2010-11-23 02:03:55  * Sean_McG is... not that young :(&lt;br /&gt;
2010-11-23 02:03:56 &amp;lt; rfw&amp;gt; &amp;lt;-- some wacky new zealand schooling level&lt;br /&gt;
2010-11-23 02:03:58 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: the &amp;quot;I got accepted to college, now I can slack&amp;quot;&lt;br /&gt;
2010-11-23 02:04:04 &amp;lt; Jumpyshoes&amp;gt; yes.&lt;br /&gt;
2010-11-23 02:04:12 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;senioritis&amp;quot;&lt;br /&gt;
2010-11-23 02:04:13 &amp;lt; rfw&amp;gt; heh i&#039;m applying for university&lt;br /&gt;
2010-11-23 02:04:16 &amp;lt; Jumpyshoes&amp;gt; same&lt;br /&gt;
2010-11-23 02:04:33 &amp;lt; rfw&amp;gt; well not so much applying as having my parents tell me i can then i can&#039;t then i can&lt;br /&gt;
2010-11-23 02:05:24 &amp;lt; rfw&amp;gt; anyway Dark_Shikari&lt;br /&gt;
2010-11-23 02:05:28 &amp;lt; rfw&amp;gt; what are all the tests i need to implement/&lt;br /&gt;
2010-11-23 02:05:40 &amp;lt; Dark_Shikari&amp;gt; it&#039;s less so need and moreso want&lt;br /&gt;
2010-11-23 02:05:47 &amp;lt; Dark_Shikari&amp;gt; But there are a few basic tests:&lt;br /&gt;
2010-11-23 02:05:48 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 02:05:51 &amp;lt; Dark_Shikari&amp;gt; 1) Compare YUV: JM&lt;br /&gt;
2010-11-23 02:05:54 &amp;lt; rfw&amp;gt; done&lt;br /&gt;
2010-11-23 02:05:55 &amp;lt; Dark_Shikari&amp;gt; 2) Compare YUV: ffmpeg&lt;br /&gt;
2010-11-23 02:06:07 &amp;lt; Dark_Shikari&amp;gt; 3) test PSNR: just run x264 and grab the Global PSNR value&lt;br /&gt;
2010-11-23 02:06:13 &amp;lt; Dark_Shikari&amp;gt; 4) test SSIM: same, except grab the SSIM value&lt;br /&gt;
2010-11-23 02:06:13 &amp;lt; Jumpyshoes&amp;gt; okay, i think i broke something&lt;br /&gt;
2010-11-23 02:06:15 &amp;lt; Jumpyshoes&amp;gt; checkasm isn&#039;t compile&lt;br /&gt;
2010-11-23 02:06:20 &amp;lt; Jumpyshoes&amp;gt; compiling&lt;br /&gt;
2010-11-23 02:06:21 &amp;lt; rfw&amp;gt; is that all?&lt;br /&gt;
2010-11-23 02:06:27 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: ?&lt;br /&gt;
2010-11-23 02:06:39 &amp;lt; Dark_Shikari&amp;gt; rfw: well, then you have to implement something to let it do useful things with git&lt;br /&gt;
2010-11-23 02:06:42 &amp;lt; Dark_Shikari&amp;gt; like tell me where things broke.&lt;br /&gt;
2010-11-23 02:06:48 &amp;lt; Dark_Shikari&amp;gt; and finally, you have to test multiple x264 options, that&#039;s the main thing&lt;br /&gt;
2010-11-23 02:06:48 &amp;lt; rfw&amp;gt; i have bisection integration already&lt;br /&gt;
2010-11-23 02:06:57 &amp;lt; Dark_Shikari&amp;gt; i.e. be able to run test 1) with different x264 options, automatically&lt;br /&gt;
2010-11-23 02:07:00 &amp;lt; Dark_Shikari&amp;gt; to attempt to find various bugs&lt;br /&gt;
2010-11-23 02:07:00 &amp;lt; kemuri-_9&amp;gt; pengvado: care for any particular order in the HAVE list?&lt;br /&gt;
2010-11-23 02:07:08 &amp;lt; Dark_Shikari&amp;gt; that&#039;s the most important part&lt;br /&gt;
2010-11-23 02:07:11 &amp;lt; Dark_Shikari&amp;gt; testing one set of options isn&#039;t helpful&lt;br /&gt;
2010-11-23 02:07:15 &amp;lt; Dark_Shikari&amp;gt; testing a ton is useful&lt;br /&gt;
2010-11-23 02:07:48 &amp;lt; Jumpyshoes&amp;gt; for some reason, i think trying to compile 8-bit, and then 10-bit breaks gcc until i restart cygwin&lt;br /&gt;
2010-11-23 02:08:19 &amp;lt; Dark_Shikari&amp;gt; make distclean&lt;br /&gt;
2010-11-23 02:08:27 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 02:08:31 &amp;lt; Jumpyshoes&amp;gt; that will probably solve things&lt;br /&gt;
2010-11-23 02:08:43 &amp;lt; Sean_McG&amp;gt; aye, you have to do that because HIGH_BIT_DEPTH is in config.mak&lt;br /&gt;
2010-11-23 02:10:18 &amp;lt; rfw&amp;gt; Running test ffmpeg... failed: x264-output.yuv is not the same size as ffmpeg-output.yuv (11404800 vs 9542016)&lt;br /&gt;
2010-11-23 02:10:21 &amp;lt; rfw&amp;gt; lol i think my ffmpeg is broken&lt;br /&gt;
2010-11-23 02:12:08 &amp;lt; Jumpyshoes&amp;gt; sexy, checkasm passed&lt;br /&gt;
2010-11-23 02:12:18 &amp;lt; Dark_Shikari&amp;gt; rfw: ffmpeg commandline?&lt;br /&gt;
2010-11-23 02:12:29 &amp;lt; rfw&amp;gt; [ &amp;quot;ffmpeg&amp;quot;, &amp;quot;-i&amp;quot;, &amp;quot;akiyo_qcif.264&amp;quot;, &amp;quot;-pix_fmt&amp;quot;, &amp;quot;yuv420p&amp;quot;, &amp;quot;-f&amp;quot;, &amp;quot;rawvideo&amp;quot;, &amp;quot;ffmpeg-output.yuv&amp;quot; ]&lt;br /&gt;
2010-11-23 02:12:33 &amp;lt; pengvado&amp;gt; kemuri-_9: no preference&lt;br /&gt;
2010-11-23 02:12:58 &amp;lt; rfw&amp;gt; actually&lt;br /&gt;
2010-11-23 02:13:03 &amp;lt; rfw&amp;gt; i probably don&#039;t need all those params&lt;br /&gt;
2010-11-23 02:13:26 &amp;lt; Dark_Shikari&amp;gt; none of those should affect file length, hmmph&lt;br /&gt;
2010-11-23 02:14:03 &amp;lt; rfw&amp;gt; maybe my ffmpeg just sucks&lt;br /&gt;
2010-11-23 02:14:04 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 02:14:56 &amp;lt; Dark_Shikari&amp;gt; you could look at the output of ffmpeg&lt;br /&gt;
2010-11-23 02:15:19 &amp;lt; rfw&amp;gt; hold on&lt;br /&gt;
2010-11-23 02:15:22 &amp;lt; rfw&amp;gt; let me just ignore filesize&lt;br /&gt;
2010-11-23 02:15:58 &amp;lt; rfw&amp;gt; Running test ffmpeg... failed: x264-output.yuv is not the same as ffmpeg-output.yuv (offset 269008)&lt;br /&gt;
2010-11-23 02:16:14 &amp;lt; Dark_Shikari&amp;gt; check the ffmpeg output on stderr&lt;br /&gt;
2010-11-23 02:16:15 &amp;lt; Jumpyshoes&amp;gt; does SWAP care about whether it&#039;s w, or d? i don&#039;t think so&lt;br /&gt;
2010-11-23 02:16:39 &amp;lt; Dark_Shikari&amp;gt; nope&lt;br /&gt;
2010-11-23 02:16:42 &amp;lt; Dark_Shikari&amp;gt; SWAP just swaps registers&lt;br /&gt;
2010-11-23 02:17:00 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-23 02:17:04 &amp;lt; rfw&amp;gt; oh also is there a flag to stop ffmpeg telling me if i want to overwrite&lt;br /&gt;
2010-11-23 02:17:19 &amp;lt; Jumpyshoes&amp;gt; can i claim IDCT4_1D, even though it isn&#039;t actually a function?&lt;br /&gt;
2010-11-23 02:17:42 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;claim&amp;quot;?&lt;br /&gt;
2010-11-23 02:17:54 &amp;lt; Dark_Shikari&amp;gt; I mean, you&#039;ll have to write a function using it at some point!&lt;br /&gt;
2010-11-23 02:17:57 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-23 02:17:58 &amp;lt; Dark_Shikari&amp;gt; even if it&#039;s nigh-identical to the mmx&lt;br /&gt;
2010-11-23 02:18:01 &amp;lt; Jumpyshoes&amp;gt; okay, might as well do it&lt;br /&gt;
2010-11-23 02:18:19 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;writing a function&amp;quot; just means creating a new function really&lt;br /&gt;
2010-11-23 02:18:25 &amp;lt; Dark_Shikari&amp;gt; whether or not it involved writing&lt;br /&gt;
2010-11-23 02:18:47 &amp;lt; rfw&amp;gt; video:9318kB audio:0kB global headers:0kB muxing overhead 0.000000%&lt;br /&gt;
2010-11-23 02:18:57 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 02:18:57 &amp;lt; rfw&amp;gt; Seems stream 0 codec frame rate differs from container frame rate: 29.97 (30000/1001) -&amp;gt; 25.00 (25/1)&lt;br /&gt;
2010-11-23 02:19:11 &amp;lt; rfw&amp;gt; that&#039;s probably it, then?&lt;br /&gt;
2010-11-23 02:19:12 &amp;lt; Jumpyshoes&amp;gt; i forgot the fricking function i was planning to write in the first place&lt;br /&gt;
2010-11-23 02:19:44 &amp;lt; espes&amp;gt; Dark_Shikari: For the GCI task, off the top of your head do you know any basic candidates for neon-ing?&lt;br /&gt;
2010-11-23 02:20:32 &amp;lt; Dark_Shikari&amp;gt; Tons of stuff&lt;br /&gt;
2010-11-23 02:20:36 &amp;lt; Dark_Shikari&amp;gt; oh you mean easy ones?&lt;br /&gt;
2010-11-23 02:20:44 &amp;lt; Dark_Shikari&amp;gt; I mean, x264 has tons and tons of functions that are missing neon&lt;br /&gt;
2010-11-23 02:20:48 &amp;lt; Dark_Shikari&amp;gt; including many simple ones, like variance&lt;br /&gt;
2010-11-23 02:20:55 &amp;lt; Dark_Shikari&amp;gt; and chroma mc needs to be updated&lt;br /&gt;
2010-11-23 02:21:08 &amp;lt; Dark_Shikari&amp;gt; your best bet is to just run a profile and look at all the C dsp functions high on the list :)&lt;br /&gt;
2010-11-23 02:21:23 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: idct 4x4&lt;br /&gt;
2010-11-23 02:21:25 &amp;lt; espes&amp;gt; Dark_Shikari: I&#039;ll have a look, thanks.&lt;br /&gt;
2010-11-23 02:21:35 &amp;lt; Jumpyshoes&amp;gt; i thought that was a macro?&lt;br /&gt;
2010-11-23 02:21:51 &amp;lt; Dark_Shikari&amp;gt; add_idct4_mmx?  no, that&#039;s a function&lt;br /&gt;
2010-11-23 02:21:52 &amp;lt; Dark_Shikari&amp;gt; or whatever it&#039;s called&lt;br /&gt;
2010-11-23 02:22:15 &amp;lt; Jumpyshoes&amp;gt; oh, add4x4_idct_mmx i believe&lt;br /&gt;
2010-11-23 02:22:38 &amp;lt; rfw&amp;gt; where is the psnr data in the x264 output?&lt;br /&gt;
2010-11-23 02:22:39 &amp;lt; Sean_McG&amp;gt; sweet... can confirm that 1789 fixes the corruption here too&lt;br /&gt;
2010-11-23 02:23:58 &amp;lt; pengvado&amp;gt; rfw: did you enable the --psnr option?&lt;br /&gt;
2010-11-23 02:24:12 &amp;lt; rfw&amp;gt; oh that makes more sense&lt;br /&gt;
2010-11-23 02:24:12 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 02:24:25 &amp;lt; rfw&amp;gt; thanks&lt;br /&gt;
2010-11-23 02:27:37 &amp;lt; kemuri-_9&amp;gt; Dark_Shikari: http://pastebin.com/99HiveUE instead of the patch you have currently&lt;br /&gt;
2010-11-23 02:29:50 &amp;lt; rfw&amp;gt; alright, that&#039;s the psnr done&lt;br /&gt;
2010-11-23 02:30:09 &amp;lt; rfw&amp;gt; i hope you don&#039;t mind regular expressions&lt;br /&gt;
2010-11-23 02:31:53 &amp;lt; Dark_Shikari&amp;gt; kemuri-_9: done&lt;br /&gt;
2010-11-23 02:32:34 &amp;lt; rfw&amp;gt; x264 [[]info[]]: PSNR Mean Y:\d+[.]\d+ U:\d+[.]\d+ V:\d+[.]\d+ Avg:\d+[.]\d+ Global:(\d+[.]\d+) kb/s:\d+[.]\d+&lt;br /&gt;
2010-11-23 02:32:37 &amp;lt; rfw&amp;gt; this should be fine, right&lt;br /&gt;
2010-11-23 02:33:14 &amp;lt; Jumpyshoes&amp;gt; hrm, 16*4 fits in an mm*, so isn&#039;t changing IDCT4_1D really easy?&lt;br /&gt;
2010-11-23 02:33:24 &amp;lt; Dark_Shikari&amp;gt; 32*4 doesn&#039;t&lt;br /&gt;
2010-11-23 02:33:30 &amp;lt; Dark_Shikari&amp;gt; Of course, if you convert the function to use SSE instead of MMX&lt;br /&gt;
2010-11-23 02:33:32 &amp;lt; Dark_Shikari&amp;gt; it&#039;s DEAD simple&lt;br /&gt;
2010-11-23 02:33:36 &amp;lt; Dark_Shikari&amp;gt; i.e. nothing whatsoever changes&lt;br /&gt;
2010-11-23 02:33:41 &amp;lt; Dark_Shikari&amp;gt; since 4x32 is the same as 4x16&lt;br /&gt;
2010-11-23 02:34:06 &amp;lt; Jumpyshoes&amp;gt; oh right, these are DCT coefficients&lt;br /&gt;
2010-11-23 02:34:39 &amp;lt; Jumpyshoes&amp;gt; oh gosh, that&#039;s kinda annoying in mmx&lt;br /&gt;
2010-11-23 02:34:43 &amp;lt; Dark_Shikari&amp;gt; You just do it twice.&lt;br /&gt;
2010-11-23 02:34:50 &amp;lt; Dark_Shikari&amp;gt; OK, so the transpose will get a bit tricky, that&#039;s it.&lt;br /&gt;
2010-11-23 02:34:52 &amp;lt; Dark_Shikari&amp;gt; But do the SSE version first.&lt;br /&gt;
2010-11-23 02:34:58 &amp;lt; Dark_Shikari&amp;gt; Since the SSE version is going to be mindnumbingly trivial&lt;br /&gt;
2010-11-23 02:35:04 &amp;lt; Dark_Shikari&amp;gt; i.e. swap w for d, swap mm for xmm, done&lt;br /&gt;
2010-11-23 02:35:06 &amp;lt; Dark_Shikari&amp;gt; in fact&lt;br /&gt;
2010-11-23 02:35:08 &amp;lt; Dark_Shikari&amp;gt; you could just template it&lt;br /&gt;
2010-11-23 02:35:23 &amp;lt; Jumpyshoes&amp;gt; template it?&lt;br /&gt;
2010-11-23 02:35:48 &amp;lt; Sean_McG&amp;gt; DS: is my HIGH_BIT_DEPTH fix going to be pushed next commit storm, or was there an issue with that too?&lt;br /&gt;
2010-11-23 02:36:39 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: I think that&#039;s fine.&lt;br /&gt;
2010-11-23 02:36:42 &amp;lt; Sean_McG&amp;gt; OK&lt;br /&gt;
2010-11-23 02:36:43 &amp;lt; Dark_Shikari&amp;gt; pengvado only had issues with two patches.&lt;br /&gt;
2010-11-23 02:36:45 &amp;lt; Dark_Shikari&amp;gt; Only one was yours.&lt;br /&gt;
2010-11-23 02:36:58 &amp;lt; Sean_McG&amp;gt; I&#039;ll be sending a new one RSN&lt;br /&gt;
2010-11-23 02:37:44 &amp;lt; Jumpyshoes&amp;gt; wait Dark_Shikari, IDCT4_1D uses the aliases already&lt;br /&gt;
2010-11-23 02:37:53 &amp;lt; Jumpyshoes&amp;gt; so m%* already&lt;br /&gt;
2010-11-23 02:38:00 &amp;lt; Jumpyshoes&amp;gt; isn&#039;t it basically set for SSE?&lt;br /&gt;
2010-11-23 02:40:05 &amp;lt; Dark_Shikari&amp;gt; Yup&lt;br /&gt;
2010-11-23 02:40:08 &amp;lt; Dark_Shikari&amp;gt; All you have to do is template the function&lt;br /&gt;
2010-11-23 02:40:10 &amp;lt; Dark_Shikari&amp;gt; i.e.&lt;br /&gt;
2010-11-23 02:40:18 &amp;lt; Dark_Shikari&amp;gt; %macro MY_MACRO_NAME 1&lt;br /&gt;
2010-11-23 02:40:25 &amp;lt; Dark_Shikari&amp;gt; cglobal function_name_%1&lt;br /&gt;
2010-11-23 02:40:26 &amp;lt; Dark_Shikari&amp;gt; ...&lt;br /&gt;
2010-11-23 02:40:28 &amp;lt; Dark_Shikari&amp;gt; %endmacro&lt;br /&gt;
2010-11-23 02:40:28 &amp;lt; Dark_Shikari&amp;gt; then&lt;br /&gt;
2010-11-23 02:40:40 &amp;lt; Dark_Shikari&amp;gt; INIT_MMX&lt;br /&gt;
2010-11-23 02:40:42 &amp;lt; Dark_Shikari&amp;gt; MY_MACRO_NAME mmx&lt;br /&gt;
2010-11-23 02:40:44 &amp;lt; Dark_Shikari&amp;gt; INIT_XMM&lt;br /&gt;
2010-11-23 02:40:47 &amp;lt; Dark_Shikari&amp;gt; MY_MACRO_NAME sse2&lt;br /&gt;
2010-11-23 02:40:55 &amp;lt; Dark_Shikari&amp;gt; though of course you&#039;ll have to intersperse the aprpopriate high bit depth ifdefs&lt;br /&gt;
2010-11-23 02:41:10 &amp;lt; Jumpyshoes&amp;gt; and i would need to redo the transpose&lt;br /&gt;
2010-11-23 02:41:15 &amp;lt; Jumpyshoes&amp;gt; oh boy&lt;br /&gt;
2010-11-23 02:41:26 &amp;lt; Jumpyshoes&amp;gt; wait&lt;br /&gt;
2010-11-23 02:41:33 &amp;lt; Jumpyshoes&amp;gt; there&#039;s no transpose in the IDCT4_1D&lt;br /&gt;
2010-11-23 02:41:34 &amp;lt; Jumpyshoes&amp;gt; yay&lt;br /&gt;
2010-11-23 02:42:11 &amp;lt; Dark_Shikari&amp;gt; You&#039;ll need a TRANSPOSE_4x4D, yes&lt;br /&gt;
2010-11-23 02:42:14 &amp;lt; Dark_Shikari&amp;gt; I think there already is one though&lt;br /&gt;
2010-11-23 02:42:22 &amp;lt; Jumpyshoes&amp;gt; yea, there is&lt;br /&gt;
2010-11-23 02:53:22 &amp;lt; rfw&amp;gt; Dark_Shikari: http://pastebin.com/GuM6bSXZ&lt;br /&gt;
2010-11-23 02:54:32 &amp;lt; Dark_Shikari&amp;gt; nice&lt;br /&gt;
2010-11-23 02:55:15 &amp;lt; rfw&amp;gt; i think my thresholds are a bit too high&lt;br /&gt;
2010-11-23 02:55:25 &amp;lt; rfw&amp;gt; by how much do psnr and ssim differ?&lt;br /&gt;
2010-11-23 02:55:28 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;thresholds&amp;quot;?&lt;br /&gt;
2010-11-23 02:55:35 &amp;lt; rfw&amp;gt; you know&lt;br /&gt;
2010-11-23 02:55:42 &amp;lt; rfw&amp;gt; floating point arithmetic&lt;br /&gt;
2010-11-23 02:55:50 &amp;lt; rfw&amp;gt; or should i just take the value as it is&lt;br /&gt;
2010-11-23 02:55:59 &amp;lt; rfw&amp;gt; without converting it to a double&lt;br /&gt;
2010-11-23 02:56:51 &amp;lt; Dark_Shikari&amp;gt; I&#039;m not sure what you&#039;re talking about&lt;br /&gt;
2010-11-23 02:56:58 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 02:57:02 &amp;lt; rfw&amp;gt; they&#039;re floating point numbers, right&lt;br /&gt;
2010-11-23 02:57:06 &amp;lt; Dark_Shikari&amp;gt; yeah&lt;br /&gt;
2010-11-23 02:57:12 &amp;lt; rfw&amp;gt; so you can&#039;t perform direct comparisons&lt;br /&gt;
2010-11-23 02:57:20 &amp;lt; rfw&amp;gt; so how much allowance should i give the values of psnr and ssim&lt;br /&gt;
2010-11-23 02:57:25 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;allowance&amp;quot;?&lt;br /&gt;
2010-11-23 02:57:28 &amp;lt; Dark_Shikari&amp;gt; this isn&#039;t for a regression test&lt;br /&gt;
2010-11-23 02:57:30 &amp;lt; Dark_Shikari&amp;gt; at least, not directly&lt;br /&gt;
2010-11-23 02:57:33 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 02:57:36 &amp;lt; Dark_Shikari&amp;gt; this is so we can see change in psnr and ssim over time at a given setting&lt;br /&gt;
2010-11-23 02:57:39 &amp;lt; Dark_Shikari&amp;gt; e.g. to make a graph&lt;br /&gt;
2010-11-23 02:57:42 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 02:57:47 &amp;lt; rfw&amp;gt; ah oh&lt;br /&gt;
2010-11-23 02:58:01 &amp;lt; rfw&amp;gt; i need to stop thinking of this as a unit test&lt;br /&gt;
2010-11-23 02:58:07 &amp;lt; Dark_Shikari&amp;gt; yeah&lt;br /&gt;
2010-11-23 02:58:53 &amp;lt; nattofriends&amp;gt; LIFE AS UNIT TEST&lt;br /&gt;
2010-11-23 03:01:01 &amp;lt; Dark_Shikari&amp;gt; Also, you script should be able to catch things like crashes&lt;br /&gt;
2010-11-23 03:01:04 &amp;lt; Dark_Shikari&amp;gt; i.e. say &amp;quot;x264 crashed&amp;quot;&lt;br /&gt;
2010-11-23 03:01:10 &amp;lt; Dark_Shikari&amp;gt; or, more usefully, SIGSEGV etc&lt;br /&gt;
2010-11-23 03:01:14 &amp;lt; Dark_Shikari&amp;gt; *your script&lt;br /&gt;
2010-11-23 03:01:21 &amp;lt; Dark_Shikari&amp;gt; As that&#039;s important to know too.&lt;br /&gt;
2010-11-23 03:01:21 &amp;lt; Jumpyshoes&amp;gt; oh hi nattofriends&lt;br /&gt;
2010-11-23 03:01:29 &amp;lt; Sean_McG&amp;gt; not using dejagnu for unit tests? ;)&lt;br /&gt;
2010-11-23 03:01:33 &amp;lt; Dark_Shikari&amp;gt; another TJ resident?&lt;br /&gt;
2010-11-23 03:01:34 &amp;lt; nattofriends&amp;gt; hi Jumpyshoes&lt;br /&gt;
2010-11-23 03:01:41 &amp;lt; Jumpyshoes&amp;gt; nope&lt;br /&gt;
2010-11-23 03:01:47 &amp;lt; Jumpyshoes&amp;gt; know him from elsewhere&lt;br /&gt;
2010-11-23 03:01:54 &amp;lt; Dark_Shikari&amp;gt; the story of my life&lt;br /&gt;
2010-11-23 03:02:18 &amp;lt; rfw&amp;gt; i swear i&#039;ve seen nattofriends somewhere else too&lt;br /&gt;
2010-11-23 03:02:26 &amp;lt; nattofriends&amp;gt; darkhold?&lt;br /&gt;
2010-11-23 03:02:31 &amp;lt; rfw&amp;gt; oh probably&lt;br /&gt;
2010-11-23 03:02:47 &amp;lt; rfw&amp;gt; i&#039;ve probably seen everyone there is on that terrible network&lt;br /&gt;
2010-11-23 03:03:42 &amp;lt; rfw&amp;gt; time to compile a program that segfaults&lt;br /&gt;
2010-11-23 03:03:43 &amp;lt; kierank&amp;gt; [03:02] Dark_Shikari: the story of my life --&amp;gt; lol&lt;br /&gt;
2010-11-23 03:04:03 &amp;lt; kierank&amp;gt; are you the Dark_Shikari from eve-online...&lt;br /&gt;
2010-11-23 03:04:28 &amp;lt; Dark_Shikari&amp;gt; hurr hurr yes&lt;br /&gt;
2010-11-23 03:04:30 &amp;lt; Dark_Shikari&amp;gt; exactly&lt;br /&gt;
2010-11-23 03:05:27 &amp;lt; rfw&amp;gt; int main() { int *a = 0; int b = *a; }&lt;br /&gt;
2010-11-23 03:05:34 &amp;lt; rfw&amp;gt; let&#039;s see what happens when i replace x264.exe with this&lt;br /&gt;
2010-11-23 03:05:41 &amp;lt; Dark_Shikari&amp;gt; you could just add a 1/0&lt;br /&gt;
2010-11-23 03:06:22 &amp;lt; rfw&amp;gt; heh it just gives me the windows blah blah has stopped working dialog&lt;br /&gt;
2010-11-23 03:06:36 &amp;lt; Jumpyshoes&amp;gt; wait Dark_Shikari, can you macro on macros? basically can i template IDCT4_1D even if it&#039;s a macro?&lt;br /&gt;
2010-11-23 03:06:53 &amp;lt; rfw&amp;gt; not sure how to handle segfaults in subprocesses&lt;br /&gt;
2010-11-23 03:07:29 &amp;lt; Sean_McG&amp;gt; OK... I&#039;mma go watch Panty &amp;amp; Stocking&lt;br /&gt;
2010-11-23 03:08:56 &amp;lt; rfw&amp;gt; how do you even detect a segfault in a subprocess&lt;br /&gt;
2010-11-23 03:09:16 &amp;lt; Sean_McG&amp;gt; you can&#039;t&lt;br /&gt;
2010-11-23 03:09:26 &amp;lt; rfw&amp;gt; herp&lt;br /&gt;
2010-11-23 03:09:37 &amp;lt; Sean_McG&amp;gt; other than grep the return text&lt;br /&gt;
2010-11-23 03:09:50 &amp;lt; rfw&amp;gt; well i already dump the output to the terminal&lt;br /&gt;
2010-11-23 03:09:53 &amp;lt; rfw&amp;gt; so i guess that&#039;s fine&lt;br /&gt;
2010-11-23 03:10:37 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: just make the size a parameter&lt;br /&gt;
2010-11-23 03:10:41 &amp;lt; Dark_Shikari&amp;gt; IDCT4_1D w, blah, blah, blah&lt;br /&gt;
2010-11-23 03:10:44 &amp;lt; Dark_Shikari&amp;gt; or d, blah, blah, blah&lt;br /&gt;
2010-11-23 03:10:54 &amp;lt; Jumpyshoes&amp;gt; ah, okay&lt;br /&gt;
2010-11-23 03:12:30 &amp;lt; Jumpyshoes&amp;gt; so when i reference variables, does it reset inside the inner macro?&lt;br /&gt;
2010-11-23 03:12:35 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-23 03:12:56 &amp;lt; Jumpyshoes&amp;gt; so i have something like&lt;br /&gt;
2010-11-23 03:13:02 &amp;lt; Jumpyshoes&amp;gt; %macro IDCT 2&lt;br /&gt;
2010-11-23 03:13:02 &amp;lt; Jumpyshoes&amp;gt; %macro IDCT4_1D_%1 %2 5-6&lt;br /&gt;
2010-11-23 03:13:03 &amp;lt; Jumpyshoes&amp;gt; i guess&lt;br /&gt;
2010-11-23 03:13:14 &amp;lt; Dark_Shikari&amp;gt; No&lt;br /&gt;
2010-11-23 03:13:16 &amp;lt; Dark_Shikari&amp;gt; don&#039;t do that&lt;br /&gt;
2010-11-23 03:13:18 &amp;lt; Dark_Shikari&amp;gt; there&#039;s no reason to&lt;br /&gt;
2010-11-23 03:13:45 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 03:16:37 &amp;lt; rfw&amp;gt; time to clone the git repo and build it o9k times&lt;br /&gt;
2010-11-23 03:17:34 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: you get a faster respons eif you post things here&lt;br /&gt;
2010-11-23 03:18:25 &amp;lt; Sean_McG&amp;gt; DS: I like a record, but I can pastebin it if you like?&lt;br /&gt;
2010-11-23 03:19:18 &amp;lt; rfw&amp;gt;       0 [main] python 5232 C:\cygwin\bin\python.exe: *** fatal error - unable to remap \\?\C:\cygwin\lib\python2.6\lib-dynload\select.dll to same address as parent: 0x360000 != 0x3F0000&lt;br /&gt;
2010-11-23 03:19:22 &amp;lt; rfw&amp;gt; wtf cygwin ;_;&lt;br /&gt;
2010-11-23 03:20:13 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: sure&lt;br /&gt;
2010-11-23 03:20:22 &amp;lt; Dark_Shikari&amp;gt; rfw: I think I&#039;ve seen that before lol&lt;br /&gt;
2010-11-23 03:20:54 &amp;lt; rfw&amp;gt; oh i have to rebaseall&lt;br /&gt;
2010-11-23 03:22:34 &amp;lt; Sean_McG&amp;gt; http://www.pastebin.ca/1999626&lt;br /&gt;
2010-11-23 03:24:06 &amp;lt; Dark_Shikari&amp;gt; Sean_McG: applied&lt;br /&gt;
2010-11-23 03:24:11 &amp;lt; Sean_McG&amp;gt; thank you&lt;br /&gt;
2010-11-23 03:24:21 &amp;lt; Sean_McG&amp;gt; OK, I go watch anime now ^^;&lt;br /&gt;
2010-11-23 03:29:22 &amp;lt; rfw&amp;gt; Dark_Shikari: Running test ffmpeg... passed, took 2.7280 seconds (True)&lt;br /&gt;
2010-11-23 03:29:28 &amp;lt; rfw&amp;gt; i think my x264 was just broken&lt;br /&gt;
2010-11-23 03:29:28 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 03:29:34 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 03:29:55 &amp;lt; Dark_Shikari&amp;gt; it might be useful to automatically check if ffmpeg or jm or similar is installed&lt;br /&gt;
2010-11-23 03:29:59 &amp;lt; Dark_Shikari&amp;gt; and tell the user if it isn&#039;t, and don&#039;t run the test&lt;br /&gt;
2010-11-23 03:30:06 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 03:30:06 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 03:30:19 &amp;lt; rfw&amp;gt; i just check if it&#039;s the path?&lt;br /&gt;
2010-11-23 03:30:34 &amp;lt; Dark_Shikari&amp;gt; I guess?&lt;br /&gt;
2010-11-23 03:30:38 &amp;lt; Dark_Shikari&amp;gt; you could add an option to specify paths&lt;br /&gt;
2010-11-23 03:31:50 &amp;lt; Dark_Shikari&amp;gt; also, one issue we have is that there are some known decoding issues in JM&lt;br /&gt;
2010-11-23 03:31:54 &amp;lt; Dark_Shikari&amp;gt; particularly, it doesn&#039;t support x264&#039;s lossless mode&lt;br /&gt;
2010-11-23 03:32:07 &amp;lt; Dark_Shikari&amp;gt; so if we e.g. just randomly tried parameters, we&#039;d get some spurious failures&lt;br /&gt;
2010-11-23 03:33:00 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 03:33:09 &amp;lt; rfw&amp;gt; Running test ffmpeg... failed: x264-output.yuv is not the same size as ffmpeg-output.yuv (11404800 vs 9542016)&lt;br /&gt;
2010-11-23 03:33:13 &amp;lt; rfw&amp;gt; never mind it is my ffmpeg&lt;br /&gt;
2010-11-23 03:33:19 &amp;lt; rfw&amp;gt; why do i have so many ffmpegs installed&lt;br /&gt;
2010-11-23 03:35:05 &amp;lt; Dark_Shikari&amp;gt; they&#039;re like gremlins&lt;br /&gt;
2010-11-23 03:35:09 &amp;lt; Dark_Shikari&amp;gt; don&#039;t feed them video after midnight&lt;br /&gt;
2010-11-23 03:36:06 &amp;lt; rfw&amp;gt; ahaha i keep deleting folders that are opne in explorer&lt;br /&gt;
2010-11-23 03:36:09 &amp;lt; rfw&amp;gt; causing it to crash&lt;br /&gt;
2010-11-23 03:40:15 &amp;lt; rfw&amp;gt; Dark_Shikari: are there any revisions that don&#039;t compile?&lt;br /&gt;
2010-11-23 03:43:22 &amp;lt; kemuri-_9&amp;gt; revisions of x264?&lt;br /&gt;
2010-11-23 03:44:27 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 03:48:59 &amp;lt; kemuri-_9&amp;gt; hmm... i think there have a been a few, they&#039;re usually fairly rare (well it depends on the architecture, x86 being the primary - others are usually broken on a major change until someone coughs up a patch)&lt;br /&gt;
2010-11-23 03:49:27 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 03:49:33 &amp;lt; rfw&amp;gt; i&#039;m just looking to test my automatic bisection&lt;br /&gt;
2010-11-23 03:53:17 &amp;lt; Dark_Shikari&amp;gt; probably nothing won&#039;t compile on x86 on gcc 3.4.5&lt;br /&gt;
2010-11-23 03:53:20 &amp;lt; Dark_Shikari&amp;gt; i.e. what I compile on&lt;br /&gt;
2010-11-23 03:53:23 &amp;lt; Dark_Shikari&amp;gt; you could easily test it though!&lt;br /&gt;
2010-11-23 03:53:24 &amp;lt; Dark_Shikari&amp;gt; make a local commit!&lt;br /&gt;
2010-11-23 03:53:25 &amp;lt; Dark_Shikari&amp;gt; :)&lt;br /&gt;
2010-11-23 04:02:00 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 04:10:05 &amp;lt; rfw&amp;gt; Bisecting between 8eaf8a (good) and HEAD (bad)...&lt;br /&gt;
2010-11-23 04:10:17 &amp;lt; rfw&amp;gt; let&#039;s hope this works&lt;br /&gt;
2010-11-23 04:11:51 &amp;lt; Dark_Shikari&amp;gt; also, GCI students, feel free to hang out in #x264&lt;br /&gt;
2010-11-23 04:12:06 &amp;lt; Dark_Shikari&amp;gt; where we discuss a wide variety of topics that are, in fact, totally x264-related&lt;br /&gt;
2010-11-23 04:12:12 &amp;lt; Dark_Shikari&amp;gt; like touhou and starcraft&lt;br /&gt;
2010-11-23 04:17:03 &amp;lt; rfw&amp;gt; coincidentally i have touhou music on&lt;br /&gt;
2010-11-23 04:17:39 &amp;lt; Dark_Shikari&amp;gt; I would if I wasn&#039;t watching the gomtv live starcraft stream&lt;br /&gt;
2010-11-23 04:17:56 &amp;lt; Dark_Shikari&amp;gt; what&#039;s with this high correlation between &amp;quot;working on x264&amp;quot; and &amp;quot;touhou&amp;quot;&lt;br /&gt;
2010-11-23 04:18:36 &amp;lt; rfw&amp;gt; :P&lt;br /&gt;
2010-11-23 04:18:46 &amp;lt; saintdev&amp;gt; sadly touhou is not such a good candidate for ffaac hacking :(&lt;br /&gt;
2010-11-23 04:19:09 &amp;lt; Dark_Shikari&amp;gt; why not&lt;br /&gt;
2010-11-23 04:19:13 &amp;lt; Dark_Shikari&amp;gt; there&#039;s touhou music for every genre&lt;br /&gt;
2010-11-23 04:19:46 &amp;lt; rfw&amp;gt; Project result: FAILED, took 5.0750 seconds.&lt;br /&gt;
2010-11-23 04:19:46 &amp;lt; rfw&amp;gt; No tests failed on 85d4e2df22e8a894b3746f9a5ead33bfdbee9566; revision is good.&lt;br /&gt;
2010-11-23 04:19:52 &amp;lt; rfw&amp;gt; wtf i definitely broke something here&lt;br /&gt;
2010-11-23 04:20:05 &amp;lt; Dark_Shikari&amp;gt; also can you make it take revision numbers instead of git hashes?&lt;br /&gt;
2010-11-23 04:20:07 &amp;lt; Dark_Shikari&amp;gt; see version.sh&lt;br /&gt;
2010-11-23 04:20:19 &amp;lt; rfw&amp;gt; let me fix this first lol&lt;br /&gt;
2010-11-23 04:20:31 &amp;lt; Dark_Shikari&amp;gt; well, both would be good too&lt;br /&gt;
2010-11-23 04:20:32 &amp;lt; Dark_Shikari&amp;gt; and yeah&lt;br /&gt;
2010-11-23 04:24:05 &amp;lt; rfw&amp;gt; 8f95149b2a1943930968f098c904d84ef4b33555 determined to be bad.&lt;br /&gt;
2010-11-23 04:24:06 &amp;lt; rfw&amp;gt; 8f95149b2a1943930968f098c904d84ef4b33555 eye am broken!&lt;br /&gt;
2010-11-23 04:24:08 &amp;lt; rfw&amp;gt; hoory&lt;br /&gt;
2010-11-23 04:24:11 &amp;lt; rfw&amp;gt; +a&lt;br /&gt;
2010-11-23 04:25:21 &amp;lt; Dark_Shikari&amp;gt; the strongest revision?&lt;br /&gt;
2010-11-23 04:26:16 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 04:26:21 &amp;lt; rfw&amp;gt; glad you get the reference&lt;br /&gt;
2010-11-23 04:26:43 &amp;lt; Dark_Shikari&amp;gt; I get references, even really really stupid ones&lt;br /&gt;
2010-11-23 04:26:52 &amp;lt; Dark_Shikari&amp;gt; pun (fortunately) not intended&lt;br /&gt;
2010-11-23 04:26:59 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 04:31:37 &amp;lt; saintdev&amp;gt; &amp;lt;fozzy bear&amp;gt;baka baka baka&amp;lt;/fozzy&amp;gt;&lt;br /&gt;
2010-11-23 04:54:34 &amp;lt; Alex_W&amp;gt; so any news on the problem with the replicated blu-ray that kierank mentioned yesterday?&lt;br /&gt;
2010-11-23 04:57:21 &amp;lt; Dark_Shikari&amp;gt; ask him&lt;br /&gt;
2010-11-23 04:57:30 &amp;lt; Dark_Shikari&amp;gt; he had an interesting quote on it but I can&#039;t give it to you&lt;br /&gt;
2010-11-23 04:57:34 &amp;lt; Dark_Shikari&amp;gt; without ok from him&lt;br /&gt;
2010-11-23 04:57:45 &amp;lt; Dark_Shikari&amp;gt; (tl;dr: they don&#039;t think its x264&#039;s problem)&lt;br /&gt;
2010-11-23 05:02:39 &amp;lt; Alex_W&amp;gt; i see, so there are no known issues with the revision they&#039;re using that could cause any compatibility problems?&lt;br /&gt;
2010-11-23 05:03:52 &amp;lt; Dark_Shikari&amp;gt; don&#039;t know what revision&lt;br /&gt;
2010-11-23 05:03:57 &amp;lt; Dark_Shikari&amp;gt; but that&#039;s doubtufl&lt;br /&gt;
2010-11-23 05:04:00 &amp;lt; Dark_Shikari&amp;gt; they did massive testing&lt;br /&gt;
2010-11-23 05:04:03 &amp;lt; Dark_Shikari&amp;gt; on tons of boxes&lt;br /&gt;
2010-11-23 05:04:10 &amp;lt; Dark_Shikari&amp;gt; and the box that&#039;s having problems is also having subtitle issues&lt;br /&gt;
2010-11-23 05:04:14 &amp;lt; Dark_Shikari&amp;gt; so they think it isn&#039;t x264-related&lt;br /&gt;
2010-11-23 05:05:27 &amp;lt; Alex_W&amp;gt; right, so it could just be a faulty box&lt;br /&gt;
2010-11-23 05:09:53 &amp;lt; rfw&amp;gt; Dark_Shikari: http://pastebin.com/JxgRJ0kh&lt;br /&gt;
2010-11-23 05:10:02 &amp;lt; rfw&amp;gt; looking for something like this?&lt;br /&gt;
2010-11-23 05:11:40 &amp;lt; Dark_Shikari&amp;gt; except with revision #s, that looks really awesome&lt;br /&gt;
2010-11-23 05:11:46 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 05:13:03 &amp;lt; Dark_Shikari&amp;gt; psnr test should use --tune psnr&lt;br /&gt;
2010-11-23 05:13:05 &amp;lt; Dark_Shikari&amp;gt; ssim test should use --tune ssim&lt;br /&gt;
2010-11-23 05:13:14 &amp;lt; Dark_Shikari&amp;gt; and we&#039;ll need some way to integrate &amp;quot;trying lots of options&amp;quot; into this&lt;br /&gt;
2010-11-23 05:15:41 &amp;lt; rfw&amp;gt; --tune psnr in the regression tester/&lt;br /&gt;
2010-11-23 05:15:44 &amp;lt; rfw&amp;gt; ?&lt;br /&gt;
2010-11-23 05:16:11 &amp;lt; Dark_Shikari&amp;gt; in the x264 options&lt;br /&gt;
2010-11-23 05:16:15 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 05:16:20 &amp;lt; Dark_Shikari&amp;gt; when measuring psnr we use tune psnr (to tell x264 to optimize for psnr)&lt;br /&gt;
2010-11-23 05:16:27 &amp;lt; Dark_Shikari&amp;gt; psnr values aren&#039;t very useful if the encoder isn&#039;t optimizing for it&lt;br /&gt;
2010-11-23 05:17:29 &amp;lt; rfw&amp;gt; oh goddammit notepad++&lt;br /&gt;
2010-11-23 05:17:32 &amp;lt; rfw&amp;gt; clicked the wrong button&lt;br /&gt;
2010-11-23 05:18:15 &amp;lt; Dark_Shikari&amp;gt; hmm, there is one thing that bugs me&lt;br /&gt;
2010-11-23 05:18:19 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;PSNR&amp;quot; is generally tested with a single set of settings&lt;br /&gt;
2010-11-23 05:18:27 &amp;lt; Dark_Shikari&amp;gt; i.e. I want to know &amp;quot;how psnr has changed over time given some set of settings&amp;quot;&lt;br /&gt;
2010-11-23 05:18:29 &amp;lt; Dark_Shikari&amp;gt; But...&lt;br /&gt;
2010-11-23 05:18:40 &amp;lt; Dark_Shikari&amp;gt; for regressions, we really just want to know whether it&#039;s working or not.&lt;br /&gt;
2010-11-23 05:18:49 &amp;lt; Dark_Shikari&amp;gt; so regressions conceptually cover all settings&lt;br /&gt;
2010-11-23 05:18:54 &amp;lt; Dark_Shikari&amp;gt; while a psnr or ssim test covers just one.,&lt;br /&gt;
2010-11-23 05:41:22 &amp;lt; wipple&amp;gt; Dark_Shikari: my first patch was replaced by kemuri-_9&#039;s?&lt;br /&gt;
2010-11-23 05:41:27 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 05:41:51 &amp;lt; wipple&amp;gt; ic&lt;br /&gt;
2010-11-23 05:42:03 &amp;lt; Dark_Shikari&amp;gt; your second one, the one that actually affects output, is still in =p&lt;br /&gt;
2010-11-23 05:43:39 &amp;lt; wipple&amp;gt; i have to fix second patch&lt;br /&gt;
2010-11-23 05:44:00 &amp;lt; Dark_Shikari&amp;gt; ah ok&lt;br /&gt;
2010-11-23 05:44:08 &amp;lt; Dark_Shikari&amp;gt; give me the new version and I&#039;ll update it&lt;br /&gt;
2010-11-23 05:55:43 &amp;lt; Jumpyshoes&amp;gt; hey Dark_Shikari, i thought about it some more, and wouldn&#039;t add4x4_idct basically need to be rewritten from scratch for mmx? mmx can only hold 64bits, so you need to have all the registers used to store all the data (if coef are 32bit)&lt;br /&gt;
2010-11-23 05:55:50 &amp;lt; Dark_Shikari&amp;gt; Yes&lt;br /&gt;
2010-11-23 05:55:55 &amp;lt; Dark_Shikari&amp;gt; It wouldn&#039;t be very *difficult*&lt;br /&gt;
2010-11-23 05:56:07 &amp;lt; Dark_Shikari&amp;gt; the approach would generally be the same&lt;br /&gt;
2010-11-23 05:56:12 &amp;lt; Dark_Shikari&amp;gt; but you certainly can&#039;t just template it outright&lt;br /&gt;
2010-11-23 05:56:16 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-23 05:56:20 &amp;lt; Dark_Shikari&amp;gt; If you want to make that your second asm function, you could&lt;br /&gt;
2010-11-23 05:56:23 &amp;lt; Jumpyshoes&amp;gt; i think i can for SSE though&lt;br /&gt;
2010-11-23 05:56:28 &amp;lt; Dark_Shikari&amp;gt; for the first, do see&lt;br /&gt;
2010-11-23 05:56:29 &amp;lt; Dark_Shikari&amp;gt; *sse&lt;br /&gt;
2010-11-23 05:56:40 &amp;lt; Jumpyshoes&amp;gt; okay&lt;br /&gt;
2010-11-23 06:00:59 &amp;lt; Jumpyshoes&amp;gt; what is pw_32?&lt;br /&gt;
2010-11-23 06:01:39 &amp;lt; Dark_Shikari&amp;gt; {32, 32, 32, 32...}&lt;br /&gt;
2010-11-23 06:01:43 &amp;lt; Dark_Shikari&amp;gt; words&lt;br /&gt;
2010-11-23 06:01:45 &amp;lt; Dark_Shikari&amp;gt; packed word 32&lt;br /&gt;
2010-11-23 06:01:48 &amp;lt; Dark_Shikari&amp;gt; see const-a.asm&lt;br /&gt;
2010-11-23 06:01:50 &amp;lt; Dark_Shikari&amp;gt; where they&#039;re declared&lt;br /&gt;
2010-11-23 06:01:53 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-23 06:06:15 &amp;lt; rfw&amp;gt; class factories -- ah the miracles of python metaprogramming&lt;br /&gt;
2010-11-23 06:06:43 &amp;lt; Dark_Shikari&amp;gt; factoryfactoryfactory&lt;br /&gt;
2010-11-23 06:07:40 &amp;lt; rfw&amp;gt; time to turn implement your clusterfuck permutations&lt;br /&gt;
2010-11-23 06:07:44 &amp;lt; rfw&amp;gt; :3&lt;br /&gt;
2010-11-23 06:07:59 &amp;lt; saintdev&amp;gt; just write it in brainfuck&lt;br /&gt;
2010-11-23 06:08:03 &amp;lt; rfw&amp;gt; this isn&#039;t going to look pretty though&lt;br /&gt;
2010-11-23 06:12:34 &amp;lt; nattofriends&amp;gt; SingletonFactorySingleton&lt;br /&gt;
2010-11-23 06:13:22 &amp;lt; rfw&amp;gt; that doesn&#039;t even make sense!&lt;br /&gt;
2010-11-23 06:13:49 &amp;lt; Jumpyshoes&amp;gt; error: instruction expected after label &amp;lt;-- what does this error mean?&lt;br /&gt;
2010-11-23 06:14:05 &amp;lt; Dark_Shikari&amp;gt; syntax error&lt;br /&gt;
2010-11-23 06:14:11 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 06:14:12 &amp;lt; Jumpyshoes&amp;gt; bleh&lt;br /&gt;
2010-11-23 06:14:41 &amp;lt; rfw&amp;gt; http://pastebin.com/X3x7Fb57&lt;br /&gt;
2010-11-23 06:15:16 &amp;lt; Dark_Shikari&amp;gt; rfw: it might be nicer to try to cover more options than mine, but without as exhaustive a search&lt;br /&gt;
2010-11-23 06:15:22 &amp;lt; Dark_Shikari&amp;gt; mine for example only tests CRF ratecontrol mode&lt;br /&gt;
2010-11-23 06:15:25 &amp;lt; Dark_Shikari&amp;gt; not ABR, CBR, 2-pass, etc&lt;br /&gt;
2010-11-23 06:16:04 &amp;lt; Dark_Shikari&amp;gt; for example, you can use a pseudorandom combination of options&lt;br /&gt;
2010-11-23 06:16:13 &amp;lt; rfw&amp;gt; TypeError: unbound method run() must be called with YUVOutputComparison_film___ultrafast instance as first argument (got nothing instead)&lt;br /&gt;
2010-11-23 06:16:14 &amp;lt; rfw&amp;gt; blah wtf&lt;br /&gt;
2010-11-23 06:16:38 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 06:16:42 &amp;lt; rfw&amp;gt; forgot to instantiate the class&lt;br /&gt;
2010-11-23 06:16:43 &amp;lt; rfw&amp;gt; hurr hurr&lt;br /&gt;
2010-11-23 06:20:41 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, if i write an implementation of an asm function, how do i test it?&lt;br /&gt;
2010-11-23 06:20:49 &amp;lt; Dark_Shikari&amp;gt; 1) declare it in the appropriate C header file&lt;br /&gt;
2010-11-23 06:20:58 &amp;lt; Dark_Shikari&amp;gt; 2) assign it to the appropriate function pointer (in your case, in common/dct.c)&lt;br /&gt;
2010-11-23 06:21:02 &amp;lt; Dark_Shikari&amp;gt; there&#039;s a big init function&lt;br /&gt;
2010-11-23 06:21:10 &amp;lt; Dark_Shikari&amp;gt; with stuff like dctf-&amp;gt;myfunc = myfuncname_sse2;&lt;br /&gt;
2010-11-23 06:21:16 &amp;lt; Dark_Shikari&amp;gt; put it in the right place based on its type (sse2, etc)&lt;br /&gt;
2010-11-23 06:21:21 &amp;lt; Dark_Shikari&amp;gt; 3) make checkasm;./checkasm&lt;br /&gt;
2010-11-23 06:21:27 &amp;lt; Dark_Shikari&amp;gt; if yours is high bit depth, of course, make sure that:&lt;br /&gt;
2010-11-23 06:21:40 &amp;lt; Dark_Shikari&amp;gt; a) it&#039;s assigned under the #if high bit depth in common/dct.c&lt;br /&gt;
2010-11-23 06:21:44 &amp;lt; Dark_Shikari&amp;gt; b) you configured with high bit depth&lt;br /&gt;
2010-11-23 06:22:40 &amp;lt; Jumpyshoes&amp;gt; k&lt;br /&gt;
2010-11-23 06:32:40 &amp;lt; Jumpyshoes&amp;gt; oh wow, it compiled&lt;br /&gt;
2010-11-23 06:32:44 &amp;lt; Jumpyshoes&amp;gt; off to a good start&lt;br /&gt;
2010-11-23 06:32:54 &amp;lt; Jumpyshoes&amp;gt; segfault!&lt;br /&gt;
2010-11-23 06:32:58 &amp;lt; Jumpyshoes&amp;gt; lovel&lt;br /&gt;
2010-11-23 06:32:59 &amp;lt; Jumpyshoes&amp;gt; y&lt;br /&gt;
2010-11-23 06:38:51 &amp;lt; wipple&amp;gt; Dark_Shikari: i misunderstood, don&#039;t need to fix my second patch.&lt;br /&gt;
2010-11-23 06:38:56 &amp;lt; Dark_Shikari&amp;gt; ah ok&lt;br /&gt;
2010-11-23 06:39:40 &amp;lt; wipple&amp;gt; it might be better to fix commit message? i replaced avformat_license() with swscale_license()&lt;br /&gt;
2010-11-23 06:39:49 &amp;lt; wipple&amp;gt; but there in no mention&lt;br /&gt;
2010-11-23 06:39:53 &amp;lt; wipple&amp;gt; about it&lt;br /&gt;
2010-11-23 06:42:08 &amp;lt; Jumpyshoes&amp;gt; yay, no more segfaulting&lt;br /&gt;
2010-11-23 06:43:23 &amp;lt; wipple&amp;gt; *there _is_ no mention&lt;br /&gt;
2010-11-23 06:44:04 &amp;lt; Jumpyshoes&amp;gt; wait, why can i see pw_32, but not pw_64?&lt;br /&gt;
2010-11-23 06:45:29 &amp;lt; rfw&amp;gt; Dark_Shikari: cartesian product regression testing sure takes lolforever&lt;br /&gt;
2010-11-23 06:45:45 &amp;lt; rfw&amp;gt; i better implement that pseudorandom thing&lt;br /&gt;
2010-11-23 06:47:15 &amp;lt; Dark_Shikari&amp;gt; rfw: yeah, my thought is to define a massive set of parameters and some sane ranges&lt;br /&gt;
2010-11-23 06:47:27 &amp;lt; Dark_Shikari&amp;gt; and make your script take a seed + a number of tests&lt;br /&gt;
2010-11-23 06:47:31 &amp;lt; Dark_Shikari&amp;gt; and it randomly picks combinations thereof&lt;br /&gt;
2010-11-23 06:50:04 &amp;lt; rfw&amp;gt;     if randint(0, 4):&lt;br /&gt;
2010-11-23 06:50:04 &amp;lt; rfw&amp;gt;         YUVOutputComparison.test_jm = disabled(&amp;quot;randomly disabled&amp;quot;)(YUVOutputComparison.test_jm)&lt;br /&gt;
2010-11-23 06:50:05 &amp;lt; rfw&amp;gt;         YUVOutputComparison.test_ffmpeg = disabled(&amp;quot;randomly disabled&amp;quot;)(YUVOutputComparison.test_ffmpeg)&lt;br /&gt;
2010-11-23 06:50:05 &amp;lt; rfw&amp;gt; :3&lt;br /&gt;
2010-11-23 06:50:21 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t mean random choice of tests&lt;br /&gt;
2010-11-23 06:50:24 &amp;lt; Dark_Shikari&amp;gt; I mean random choice of parameters =p&lt;br /&gt;
2010-11-23 06:50:30 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 06:50:34 &amp;lt; rfw&amp;gt; it is a random choice of parameters&lt;br /&gt;
2010-11-23 06:50:52 &amp;lt; Dark_Shikari&amp;gt; btw, the parameter array (and sane ranges) should be easily editable by us&lt;br /&gt;
2010-11-23 06:50:54 &amp;lt; Dark_Shikari&amp;gt; so we can change it later&lt;br /&gt;
2010-11-23 06:51:01 &amp;lt; rfw&amp;gt; http://pastebin.com/FRdfXbpp&lt;br /&gt;
2010-11-23 06:51:03 &amp;lt; Dark_Shikari&amp;gt; i.e. with new params, etc&lt;br /&gt;
2010-11-23 06:51:05 &amp;lt; rfw&amp;gt; it&#039;s sorta editable&lt;br /&gt;
2010-11-23 06:51:05 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 06:51:20 &amp;lt; Dark_Shikari&amp;gt; It will need to be about 100 lines longer than that&lt;br /&gt;
2010-11-23 06:51:27 &amp;lt; Dark_Shikari&amp;gt; so that format will probably not be very readable&lt;br /&gt;
2010-11-23 06:51:34 &amp;lt; Dark_Shikari&amp;gt; i.e. you&#039;ll have to mentally match up the for index with the line number&lt;br /&gt;
2010-11-23 06:51:49 &amp;lt; Dark_Shikari&amp;gt; so if this was C, I&#039;d want something like this&lt;br /&gt;
2010-11-23 06:51:52 &amp;lt; rfw&amp;gt; derp&lt;br /&gt;
2010-11-23 06:51:59 &amp;lt; Dark_Shikari&amp;gt; {&amp;quot;subme&amp;quot;, 0, 10}&lt;br /&gt;
2010-11-23 06:52:09 &amp;lt; Dark_Shikari&amp;gt; makes sense?&lt;br /&gt;
2010-11-23 06:52:38 &amp;lt; rfw&amp;gt; not really no&lt;br /&gt;
2010-11-23 06:52:40 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 06:52:53 &amp;lt; Dark_Shikari&amp;gt; in order to generate a commandline, for each of N parameters, you pick one of M values&lt;br /&gt;
2010-11-23 06:53:03 &amp;lt; Dark_Shikari&amp;gt; so for example, if your parameters are A and B&lt;br /&gt;
2010-11-23 06:53:06 &amp;lt; Dark_Shikari&amp;gt; and their min values are 0 and max are 10&lt;br /&gt;
2010-11-23 06:53:10 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 06:53:10 &amp;lt; Dark_Shikari&amp;gt; you might do --A 5 --B 7&lt;br /&gt;
2010-11-23 06:53:13 &amp;lt; rfw&amp;gt; ah i get you&lt;br /&gt;
2010-11-23 06:53:14 &amp;lt; Dark_Shikari&amp;gt; or --A 2 --B 9&lt;br /&gt;
2010-11-23 06:53:37 &amp;lt; rfw&amp;gt; you&#039;re not giving those 4 points away that easily are you ;__;&lt;br /&gt;
2010-11-23 06:53:48 &amp;lt; Dark_Shikari&amp;gt; This isn&#039;t actually that hard, I imagine it&#039;s just a big array that you iterate over.&lt;br /&gt;
2010-11-23 06:54:08 &amp;lt; Dark_Shikari&amp;gt; If you make it extensible, you don&#039;t have to write the whole thing&lt;br /&gt;
2010-11-23 06:54:10 &amp;lt; Dark_Shikari&amp;gt; We can add it later.&lt;br /&gt;
2010-11-23 06:54:13 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 06:54:17 &amp;lt; rfw&amp;gt; it is extensible&lt;br /&gt;
2010-11-23 06:54:17 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 06:54:21 &amp;lt; rfw&amp;gt; to the point it&#039;s silly&lt;br /&gt;
2010-11-23 06:54:30 &amp;lt; Dark_Shikari&amp;gt; A for loop like that is not very readable with 100 options&lt;br /&gt;
2010-11-23 06:54:45 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 06:54:46 &amp;lt; rfw&amp;gt; it is&lt;br /&gt;
2010-11-23 06:54:50 &amp;lt; rfw&amp;gt; you just add more elements to the array&lt;br /&gt;
2010-11-23 06:54:56 &amp;lt; rfw&amp;gt; i flattened your nested loop&lt;br /&gt;
2010-11-23 06:54:58 &amp;lt; rfw&amp;gt; into one loop&lt;br /&gt;
2010-11-23 06:55:07 &amp;lt; Dark_Shikari&amp;gt; for option in A,C,Q,Y,X,D,I,S,B,W,C&lt;br /&gt;
2010-11-23 06:55:08 &amp;lt; Dark_Shikari&amp;gt; 1&lt;br /&gt;
2010-11-23 06:55:08 &amp;lt; Dark_Shikari&amp;gt; 2&lt;br /&gt;
2010-11-23 06:55:08 &amp;lt; Dark_Shikari&amp;gt; 3&lt;br /&gt;
2010-11-23 06:55:08 &amp;lt; Dark_Shikari&amp;gt; 4&lt;br /&gt;
2010-11-23 06:55:11 &amp;lt; Dark_Shikari&amp;gt; 5&lt;br /&gt;
2010-11-23 06:55:13 &amp;lt; Dark_Shikari&amp;gt; 6&lt;br /&gt;
2010-11-23 06:55:16 &amp;lt; Dark_Shikari&amp;gt; 7&lt;br /&gt;
2010-11-23 06:55:18 &amp;lt; Dark_Shikari&amp;gt; 8&lt;br /&gt;
2010-11-23 06:55:21 &amp;lt; Dark_Shikari&amp;gt; 9&lt;br /&gt;
2010-11-23 06:55:24 &amp;lt; Dark_Shikari&amp;gt; which option goes with which line?&lt;br /&gt;
2010-11-23 06:55:26 &amp;lt; Dark_Shikari&amp;gt; fucked if I know!&lt;br /&gt;
2010-11-23 06:55:30 &amp;lt; rfw&amp;gt; um&lt;br /&gt;
2010-11-23 06:55:31 &amp;lt; rfw&amp;gt; what?&lt;br /&gt;
2010-11-23 06:55:35 &amp;lt; rfw&amp;gt; YUVOutputComparison.options = filter(None, reduce(operator.add, [ opt.split(&amp;quot; &amp;quot;) for opt in options ]))&lt;br /&gt;
2010-11-23 06:55:36 &amp;lt; Dark_Shikari&amp;gt; your for loop has all your option names on one line&lt;br /&gt;
2010-11-23 06:55:40 &amp;lt; Dark_Shikari&amp;gt; the one you pasted&lt;br /&gt;
2010-11-23 06:55:43 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 06:55:44 &amp;lt; rfw&amp;gt; whoops&lt;br /&gt;
2010-11-23 06:55:46 &amp;lt; Dark_Shikari&amp;gt; and then it has one line for each option&lt;br /&gt;
2010-11-23 06:55:53 &amp;lt; Dark_Shikari&amp;gt; and mapping the two to each other is difficult visually&lt;br /&gt;
2010-11-23 06:56:00 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 06:56:02 &amp;lt; rfw&amp;gt; it&#039;s fixed now :p&lt;br /&gt;
2010-11-23 06:56:13 &amp;lt; Dark_Shikari&amp;gt; good =&lt;br /&gt;
2010-11-23 06:56:14 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-23 06:56:16 &amp;lt; rfw&amp;gt; http://pastebin.com/G0qeRJqZ&lt;br /&gt;
2010-11-23 06:56:32 &amp;lt; rfw&amp;gt; just add more parameters to the product function&lt;br /&gt;
2010-11-23 06:56:33 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 06:56:53 &amp;lt; Dark_Shikari&amp;gt; ah, sweet&lt;br /&gt;
2010-11-23 06:57:03 &amp;lt; Dark_Shikari&amp;gt; what&#039;s the randint 0,4 for?&lt;br /&gt;
2010-11-23 06:57:07 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 06:57:10 &amp;lt; rfw&amp;gt; random test selection&lt;br /&gt;
2010-11-23 06:57:14 &amp;lt; rfw&amp;gt; so you don&#039;t run all of them&lt;br /&gt;
2010-11-23 06:58:09 &amp;lt; Dark_Shikari&amp;gt; huh?&lt;br /&gt;
2010-11-23 06:58:27 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 06:58:38 &amp;lt; rfw&amp;gt; it generates a random number from 0-4&lt;br /&gt;
2010-11-23 06:58:48 &amp;lt; rfw&amp;gt; so there&#039;s a 1 in 5 chance of a test running&lt;br /&gt;
2010-11-23 06:59:01 &amp;lt; rfw&amp;gt; you can seed it of course&lt;br /&gt;
2010-11-23 06:59:03 &amp;lt; Dark_Shikari&amp;gt; ?  I don&#039;t see how that applies to the algorithm I mentioned&lt;br /&gt;
2010-11-23 06:59:04 &amp;lt; rfw&amp;gt; so it&#039;s consistent&lt;br /&gt;
2010-11-23 06:59:13 &amp;lt; Dark_Shikari&amp;gt; for any given test, you should randomly assemble a commandline&lt;br /&gt;
2010-11-23 06:59:13 &amp;lt; rfw&amp;gt; wait&lt;br /&gt;
2010-11-23 06:59:18 &amp;lt; Dark_Shikari&amp;gt; at no point in there is a &amp;quot;random chance of running a test&amp;quot;&lt;br /&gt;
2010-11-23 06:59:18 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 06:59:30 &amp;lt; rfw&amp;gt; isn&#039;t this more or less the same thing&lt;br /&gt;
2010-11-23 06:59:32 &amp;lt; Dark_Shikari&amp;gt; If you&#039;re going to iterate over all possible commandlines&lt;br /&gt;
2010-11-23 06:59:34 &amp;lt; Dark_Shikari&amp;gt; and only run some of them&lt;br /&gt;
2010-11-23 06:59:40 &amp;lt; Dark_Shikari&amp;gt; well, good luck when there are 10^100 possible commandlines&lt;br /&gt;
2010-11-23 06:59:50 &amp;lt; rfw&amp;gt; wait what&lt;br /&gt;
2010-11-23 06:59:52 &amp;lt; rfw&amp;gt; i&#039;m confused now&lt;br /&gt;
2010-11-23 07:00:00 &amp;lt; Dark_Shikari&amp;gt; You will run N tests.&lt;br /&gt;
2010-11-23 07:00:07 &amp;lt; Dark_Shikari&amp;gt; In each test, you will randomly assemble a commandline.&lt;br /&gt;
2010-11-23 07:00:13 &amp;lt; Dark_Shikari&amp;gt; And test it.&lt;br /&gt;
2010-11-23 07:00:21 &amp;lt; Dark_Shikari&amp;gt; The randomness will be based on a user-supplied seed.&lt;br /&gt;
2010-11-23 07:00:25 &amp;lt; Dark_Shikari&amp;gt; The N will be user-supplied.&lt;br /&gt;
2010-11-23 07:00:30 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari: are there different constants for high bit?&lt;br /&gt;
2010-11-23 07:00:31 &amp;lt; rfw&amp;gt; but aren&#039;t i randomly assembling a command here&lt;br /&gt;
2010-11-23 07:00:38 &amp;lt; Dark_Shikari&amp;gt; No, you&#039;re iterating over all possible commandlines&lt;br /&gt;
2010-11-23 07:00:41 &amp;lt; Dark_Shikari&amp;gt; and only running some of them&lt;br /&gt;
2010-11-23 07:00:42 &amp;lt; Dark_Shikari&amp;gt; right?&lt;br /&gt;
2010-11-23 07:00:45 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 07:00:46 &amp;lt; rfw&amp;gt; isn&#039;t that&lt;br /&gt;
2010-11-23 07:00:50 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: if you need a new one, make it&lt;br /&gt;
2010-11-23 07:00:51 &amp;lt; rfw&amp;gt; functionally equivalent?&lt;br /&gt;
2010-11-23 07:00:53 &amp;lt; Dark_Shikari&amp;gt; NO!&lt;br /&gt;
2010-11-23 07:00:56 &amp;lt; rfw&amp;gt; :(&lt;br /&gt;
2010-11-23 07:00:57 &amp;lt; Dark_Shikari&amp;gt; If there are 10^100 possible commandlines&lt;br /&gt;
2010-11-23 07:00:58 &amp;lt; Dark_Shikari&amp;gt; and I want 100 of them&lt;br /&gt;
2010-11-23 07:01:03 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 07:01:06 &amp;lt; Dark_Shikari&amp;gt; your solution will take longer than the life of the universe!&lt;br /&gt;
2010-11-23 07:01:19 &amp;lt; rfw&amp;gt; derp&lt;br /&gt;
2010-11-23 07:01:27 &amp;lt; Jumpyshoes&amp;gt; i made one in the const-a.asm file&lt;br /&gt;
2010-11-23 07:01:33 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: make sure there isn&#039;t already one&lt;br /&gt;
2010-11-23 07:01:35 &amp;lt; Dark_Shikari&amp;gt; there might be a pd_32&lt;br /&gt;
2010-11-23 07:01:38 &amp;lt; Jumpyshoes&amp;gt; but yasm can&#039;t see it for some reason&lt;br /&gt;
2010-11-23 07:01:39 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 07:01:46 &amp;lt; Dark_Shikari&amp;gt; you have to add it in your file&lt;br /&gt;
2010-11-23 07:01:48 &amp;lt; Dark_Shikari&amp;gt; extern pd_32&lt;br /&gt;
2010-11-23 07:01:53 &amp;lt; Dark_Shikari&amp;gt; see the top of your file&lt;br /&gt;
2010-11-23 07:01:56 &amp;lt; Jumpyshoes&amp;gt; aah&lt;br /&gt;
2010-11-23 07:02:07 &amp;lt; rfw&amp;gt; actually Dark_Shikari i don&#039;t see how&lt;br /&gt;
2010-11-23 07:02:10 &amp;lt; rfw&amp;gt; if i just randomized the options&lt;br /&gt;
2010-11-23 07:02:17 &amp;lt; rfw&amp;gt; then picked the first 100&lt;br /&gt;
2010-11-23 07:02:19 &amp;lt; Dark_Shikari&amp;gt; No&lt;br /&gt;
2010-11-23 07:02:24 &amp;lt; Dark_Shikari&amp;gt; that isn&#039;t what I asked for&lt;br /&gt;
2010-11-23 07:02:26 &amp;lt; Dark_Shikari&amp;gt; read what I said again&lt;br /&gt;
2010-11-23 07:02:30 &amp;lt; Dark_Shikari&amp;gt; let me write it in C, ok?&lt;br /&gt;
2010-11-23 07:02:34 &amp;lt; rfw&amp;gt; um okay&lt;br /&gt;
2010-11-23 07:02:37 &amp;lt; Dark_Shikari&amp;gt; for(int i = 0; i &amp;lt; numruns; i++) {&lt;br /&gt;
2010-11-23 07:02:55 &amp;lt; Dark_Shikari&amp;gt; String commandline = randomCommandline();&lt;br /&gt;
2010-11-23 07:03:02 &amp;lt; Dark_Shikari&amp;gt; test(commandline);&lt;br /&gt;
2010-11-23 07:03:03 &amp;lt; Dark_Shikari&amp;gt; }&lt;br /&gt;
2010-11-23 07:03:11 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;randomcommandline&amp;quot; generates one, exactly one, random commandline.&lt;br /&gt;
2010-11-23 07:03:14 &amp;lt; Dark_Shikari&amp;gt; just one.  not zero, not two, one.&lt;br /&gt;
2010-11-23 07:03:50 &amp;lt; Dark_Shikari&amp;gt; you aren&#039;t shuffling all possible commandlines&lt;br /&gt;
2010-11-23 07:03:55 &amp;lt; Dark_Shikari&amp;gt; you are just generating one random one&lt;br /&gt;
2010-11-23 07:04:02 &amp;lt; Dark_Shikari&amp;gt; randomCommandline is as follows:&lt;br /&gt;
2010-11-23 07:04:07 &amp;lt; rfw&amp;gt; yes i get what you mean&lt;br /&gt;
2010-11-23 07:04:09 &amp;lt; Dark_Shikari&amp;gt; for all options in optionArray:&lt;br /&gt;
2010-11-23 07:04:26 &amp;lt; rfw&amp;gt; but what i&#039;m saying is shuffle the individual subcommands&lt;br /&gt;
2010-11-23 07:04:28 &amp;lt; Dark_Shikari&amp;gt;     optionValue = random option in optionArray[option]&lt;br /&gt;
2010-11-23 07:04:30 &amp;lt; rfw&amp;gt; like [ &amp;quot;--tune %s&amp;quot; % t for t in (&amp;quot;film&amp;quot;, &amp;quot;zerolatency&amp;quot;) ]&lt;br /&gt;
2010-11-23 07:04:38 &amp;lt; rfw&amp;gt; wait never mind i&#039;m being silly&lt;br /&gt;
2010-11-23 07:04:51 &amp;lt; rfw&amp;gt; yeah i see what you mean&lt;br /&gt;
2010-11-23 07:05:07 &amp;lt; rfw&amp;gt; i feel kinda dumb now ._.&lt;br /&gt;
2010-11-23 07:05:36 &amp;lt; Dark_Shikari&amp;gt; feeling dumb is fine, happens all the time&lt;br /&gt;
2010-11-23 07:05:41 &amp;lt; Dark_Shikari&amp;gt; just grep the commit logs for &amp;quot;10L&amp;quot;&lt;br /&gt;
2010-11-23 07:06:26 &amp;lt; Dark_Shikari&amp;gt; well, 1[0]*[l|L]&lt;br /&gt;
2010-11-23 07:12:23 &amp;lt; Dark_Shikari&amp;gt; so in terms of committing this regression tester of yours&lt;br /&gt;
2010-11-23 07:12:29 &amp;lt; Dark_Shikari&amp;gt; what about the actual lib it depends on which you said isn&#039;t finished?&lt;br /&gt;
2010-11-23 07:23:18 &amp;lt; rfw&amp;gt; it&#039;s part of my regression tester&lt;br /&gt;
2010-11-23 07:23:27 &amp;lt; rfw&amp;gt; sorry, had to do something&lt;br /&gt;
2010-11-23 07:24:27 &amp;lt; Dark_Shikari&amp;gt; no worries, not going to push you or anything&lt;br /&gt;
2010-11-23 07:27:08 &amp;lt; rfw&amp;gt; Dark_Shikari: http://pastebin.com/vybYV0VR&lt;br /&gt;
2010-11-23 07:27:16 &amp;lt; rfw&amp;gt; is this more along the lines of what you were looking for?&lt;br /&gt;
2010-11-23 07:27:30 &amp;lt; Dark_Shikari&amp;gt; yup, exactly&lt;br /&gt;
2010-11-23 07:27:33 &amp;lt; rfw&amp;gt; :D&lt;br /&gt;
2010-11-23 07:27:38 &amp;lt; Dark_Shikari&amp;gt; fyi I can&#039;t really read python very well&lt;br /&gt;
2010-11-23 07:27:42 &amp;lt; Dark_Shikari&amp;gt; I haven&#039;t used it in like 5 years&lt;br /&gt;
2010-11-23 07:27:42 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 07:27:52 &amp;lt; Dark_Shikari&amp;gt; I last used python seriously for AI class in high school&lt;br /&gt;
2010-11-23 07:27:52 &amp;lt; rfw&amp;gt; it&#039;s more readable than perl&lt;br /&gt;
2010-11-23 07:28:05 &amp;lt; rfw&amp;gt; you know, the old elbows on keyboard joke&lt;br /&gt;
2010-11-23 07:28:36 &amp;lt; Dark_Shikari&amp;gt; yes yes&lt;br /&gt;
2010-11-23 07:29:39 &amp;lt; rfw&amp;gt; also, version numbers instead of commit hashes?&lt;br /&gt;
2010-11-23 07:29:47 &amp;lt; Dark_Shikari&amp;gt; see version.sh&lt;br /&gt;
2010-11-23 07:29:57 &amp;lt; Dark_Shikari&amp;gt; since x264 uses a completely linear git tree, version numbers are more usable than hashes&lt;br /&gt;
2010-11-23 07:30:09 &amp;lt; rfw&amp;gt; why did i just try to run it in cmd&lt;br /&gt;
2010-11-23 07:30:14 &amp;lt; Dark_Shikari&amp;gt; e.g. the current x264 is r1790&lt;br /&gt;
2010-11-23 07:32:30 &amp;lt; rfw&amp;gt; oh god i can&#039;t read bash&lt;br /&gt;
2010-11-23 07:33:46 &amp;lt; Dark_Shikari&amp;gt; You don&#039;t have to&lt;br /&gt;
2010-11-23 07:33:49 &amp;lt; Dark_Shikari&amp;gt; It just basically counts commits.&lt;br /&gt;
2010-11-23 07:33:49 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 07:34:01 &amp;lt; Dark_Shikari&amp;gt; pengvado could explain it though.&lt;br /&gt;
2010-11-23 07:34:13 &amp;lt; rfw&amp;gt; so why not just&lt;br /&gt;
2010-11-23 07:34:15 &amp;lt; rfw&amp;gt; git log --format=oneline | wc -l&lt;br /&gt;
2010-11-23 07:34:16 &amp;lt; rfw&amp;gt; :|&lt;br /&gt;
2010-11-23 07:34:36 &amp;lt; rfw&amp;gt; why the git rev-list origin/master | sort | join config.git-hash - | wc -l | awk &#039;{print $1}&#039;&lt;br /&gt;
2010-11-23 07:35:24 &amp;lt; Dark_Shikari&amp;gt; Because it does a bit of extra magic&lt;br /&gt;
2010-11-23 07:35:28 &amp;lt; Dark_Shikari&amp;gt; specifically, it does the following&lt;br /&gt;
2010-11-23 07:35:33 &amp;lt; Dark_Shikari&amp;gt; suppose latest x264 is 1790&lt;br /&gt;
2010-11-23 07:35:33 &amp;lt; dj_tjerk&amp;gt; origin/master doesn&#039;t make any sense if you do local regression testing does it?&lt;br /&gt;
2010-11-23 07:35:36 &amp;lt; Dark_Shikari&amp;gt; suppose I have 5 local commits&lt;br /&gt;
2010-11-23 07:35:41 &amp;lt; Dark_Shikari&amp;gt; it&#039;ll show my version as 1790+5&lt;br /&gt;
2010-11-23 07:35:47 &amp;lt; Dark_Shikari&amp;gt; suppose I also have a modified local tree when I do it&lt;br /&gt;
2010-11-23 07:35:50 &amp;lt; Dark_Shikari&amp;gt; it&#039;ll show my version as 1790+5M&lt;br /&gt;
2010-11-23 07:35:53 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 07:35:53 &amp;lt; Dark_Shikari&amp;gt; or something like that&lt;br /&gt;
2010-11-23 07:35:58 &amp;lt; rfw&amp;gt; i see&lt;br /&gt;
2010-11-23 07:36:43 &amp;lt; Dark_Shikari&amp;gt; in your case, it might be useful to distinguish between local and otherwise&lt;br /&gt;
2010-11-23 07:36:52 &amp;lt; Dark_Shikari&amp;gt; e.g. if my bug is in revision 1790+4&lt;br /&gt;
2010-11-23 07:36:55 &amp;lt; Dark_Shikari&amp;gt; as opposed to 1794&lt;br /&gt;
2010-11-23 07:37:08 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 07:37:10 &amp;lt; Dark_Shikari&amp;gt; but the latter might be fine too.&lt;br /&gt;
2010-11-23 07:39:13 &amp;lt; rfw&amp;gt; is there any reason why the bash script does a sort&lt;br /&gt;
2010-11-23 07:39:23 &amp;lt; rfw&amp;gt; oh nvm&lt;br /&gt;
2010-11-23 07:40:37 &amp;lt; Dark_Shikari&amp;gt; You&#039;ll probably want to cache these revision numbers at the start to avoid recalculating them repeatedly.&lt;br /&gt;
2010-11-23 07:40:43 &amp;lt; Dark_Shikari&amp;gt; i.e. the mapping of hash to revnum&lt;br /&gt;
2010-11-23 07:40:45 &amp;lt; Dark_Shikari&amp;gt; or similar&lt;br /&gt;
2010-11-23 07:40:51 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 07:53:22 &amp;lt; rfw&amp;gt; welp, now to write a routine to  convert it the other way&lt;br /&gt;
2010-11-23 07:58:19 &amp;lt; rfw&amp;gt; Testing project x264 at revision 1790+4M...&lt;br /&gt;
2010-11-23 08:01:43 &amp;lt; Dark_Shikari&amp;gt; You could just internally use hashes&lt;br /&gt;
2010-11-23 08:01:46 &amp;lt; Dark_Shikari&amp;gt; and convert only for display purposes&lt;br /&gt;
2010-11-23 08:01:49 &amp;lt; rfw&amp;gt; i do&lt;br /&gt;
2010-11-23 08:01:55 &amp;lt; Dark_Shikari&amp;gt; though I geuss you need to convert the other way for user input&lt;br /&gt;
2010-11-23 08:01:59 &amp;lt; Dark_Shikari&amp;gt; i.e. &amp;quot;I want to test revision X through Y&amp;quot;&lt;br /&gt;
2010-11-23 08:02:05 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 08:02:14 &amp;lt; Dark_Shikari&amp;gt; Though the most common thing for that isn&#039;t revision numbers&lt;br /&gt;
2010-11-23 08:02:17 &amp;lt; Dark_Shikari&amp;gt; but rather something like&lt;br /&gt;
2010-11-23 08:02:19 &amp;lt; Dark_Shikari&amp;gt; HEAD~10&lt;br /&gt;
2010-11-23 08:02:22 &amp;lt; Dark_Shikari&amp;gt; like in git parlance&lt;br /&gt;
2010-11-23 08:02:26 &amp;lt; Dark_Shikari&amp;gt; i.e. &amp;quot;I want to test the last 10 revisions&amp;quot;&lt;br /&gt;
2010-11-23 08:02:28 &amp;lt; rfw&amp;gt; safsagdshasd&lt;br /&gt;
2010-11-23 08:02:35 &amp;lt; rfw&amp;gt; TIME TO FIX&lt;br /&gt;
2010-11-23 08:02:46 &amp;lt; Dark_Shikari&amp;gt; anyways, let&#039;s get down how this interface will work&lt;br /&gt;
2010-11-23 08:02:57 &amp;lt; Dark_Shikari&amp;gt; so you don&#039;t keep changing things&lt;br /&gt;
2010-11-23 08:02:59 &amp;lt; Dark_Shikari&amp;gt; and doing unnecessary work&lt;br /&gt;
2010-11-23 08:03:05 &amp;lt; Dark_Shikari&amp;gt; if you have to use hashes, that&#039;s ok&lt;br /&gt;
2010-11-23 08:03:10 &amp;lt; rfw&amp;gt; nah it&#039;s fine&lt;br /&gt;
2010-11-23 08:03:24 &amp;lt; rfw&amp;gt; i&#039;m just checking if ~ is in revnumber&lt;br /&gt;
2010-11-23 08:03:31 &amp;lt; rfw&amp;gt; though&lt;br /&gt;
2010-11-23 08:03:42 &amp;lt; rfw&amp;gt; then what if somebody tries to 1780+4~3&lt;br /&gt;
2010-11-23 08:03:57 &amp;lt; rfw&amp;gt; can i just assume nobody&#039;s going to do that&lt;br /&gt;
2010-11-23 08:05:19 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 08:05:20 &amp;lt; Dark_Shikari&amp;gt; probably&lt;br /&gt;
2010-11-23 08:05:24 &amp;lt; Dark_Shikari&amp;gt; yes you can assume people are not stupid&lt;br /&gt;
2010-11-23 08:05:41 &amp;lt; rfw&amp;gt; \o/&lt;br /&gt;
2010-11-23 08:06:44 &amp;lt; Dark_Shikari&amp;gt; this is for devs, not users&lt;br /&gt;
2010-11-23 08:06:48 &amp;lt; Dark_Shikari&amp;gt; it can have less tolerance for bad input&lt;br /&gt;
2010-11-23 08:07:01 &amp;lt; Dark_Shikari&amp;gt; though it should at least error out cleanly if you give it stupid shit&lt;br /&gt;
2010-11-23 08:07:29 &amp;lt; rfw&amp;gt; why the hell is windows not letting me delete the x264 folder&lt;br /&gt;
2010-11-23 08:07:44 &amp;lt; rfw&amp;gt; &amp;quot;you need the computer administrator&#039;s permissions to change this folder&amp;quot;&lt;br /&gt;
2010-11-23 08:07:49 &amp;lt; rfw&amp;gt; but i am the computer administrator :(&lt;br /&gt;
2010-11-23 08:11:06 &amp;lt; Dark_Shikari&amp;gt; try not having it open in a cygwin window&lt;br /&gt;
2010-11-23 08:11:37 &amp;lt; rfw&amp;gt; i don&#039;t&lt;br /&gt;
2010-11-23 08:11:42 &amp;lt; rfw&amp;gt; i don&#039;t even have ownership of the folder&lt;br /&gt;
2010-11-23 08:11:50 &amp;lt; rfw&amp;gt; wtf&lt;br /&gt;
2010-11-23 08:12:10 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 08:12:16 &amp;lt; Dark_Shikari&amp;gt; try removing it in cygwin&lt;br /&gt;
2010-11-23 08:12:31 &amp;lt; rfw&amp;gt; nothing&lt;br /&gt;
2010-11-23 08:12:43 &amp;lt; rfw&amp;gt; $ cd x264&lt;br /&gt;
2010-11-23 08:12:44 &amp;lt; rfw&amp;gt; bash: cd: x264: Permission denied&lt;br /&gt;
2010-11-23 08:12:45 &amp;lt; rfw&amp;gt; :(&lt;br /&gt;
2010-11-23 08:12:49 &amp;lt; rfw&amp;gt; can&#039;t even enter it&lt;br /&gt;
2010-11-23 08:13:08 &amp;lt; rfw&amp;gt; drwxr-x---  1 ????????       ????????    0 2010-11-23 21:05 x264&lt;br /&gt;
2010-11-23 08:13:39 &amp;lt; rfw&amp;gt; i can&#039;t even get group/owner information&lt;br /&gt;
2010-11-23 08:14:22 &amp;lt; nattofriends&amp;gt; restart! restart!&lt;br /&gt;
2010-11-23 08:14:44 &amp;lt; rfw&amp;gt; nevar!&lt;br /&gt;
2010-11-23 08:16:59 &amp;lt; Dark_Shikari&amp;gt; o.0&lt;br /&gt;
2010-11-23 08:20:51 &amp;lt; Rodeo&amp;gt; Dark_Shikari: FWIW, http://paste.handbrake.fr/pastebin.php?show=1883&lt;br /&gt;
2010-11-23 08:22:46 &amp;lt; Rodeo&amp;gt; not that the current behavior bother me (on the contrary), but if this the correct behavior, then you have a patch&lt;br /&gt;
2010-11-23 08:24:49 &amp;lt; Dark_Shikari&amp;gt; I dunno if that&#039;ll work&lt;br /&gt;
2010-11-23 08:25:09 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t think the cplxr_sum stuff is used in 2-pass&lt;br /&gt;
2010-11-23 08:26:51 &amp;lt; Rodeo&amp;gt; well, without the patch, I get the final ratefactor for ./x264 infile -o outfile --pass 1 bitrate b&lt;br /&gt;
2010-11-23 08:26:57 &amp;lt; Rodeo&amp;gt; with the patch, it&#039;s not printed&lt;br /&gt;
2010-11-23 08:27:02 &amp;lt; Dark_Shikari&amp;gt; Is it *accurate*?&lt;br /&gt;
2010-11-23 08:27:03 &amp;lt; rfw&amp;gt; wow, the gci rankings haven&#039;t changed at all&lt;br /&gt;
2010-11-23 08:27:26 &amp;lt; Dark_Shikari&amp;gt; Rodeo: wait I&#039;m confused&lt;br /&gt;
2010-11-23 08:27:29 &amp;lt; Dark_Shikari&amp;gt; what does your patch do?&lt;br /&gt;
2010-11-23 08:27:33 &amp;lt; Dark_Shikari&amp;gt; are you trying to print it in 2-pass mode?&lt;br /&gt;
2010-11-23 08:27:36 &amp;lt; Dark_Shikari&amp;gt; on the second pass?&lt;br /&gt;
2010-11-23 08:27:37 &amp;lt; Dark_Shikari&amp;gt; or what&lt;br /&gt;
2010-11-23 08:27:52 &amp;lt; Dark_Shikari&amp;gt; rfw: what, trying to win the grand prize? =p&lt;br /&gt;
2010-11-23 08:27:56 &amp;lt; Rodeo&amp;gt; currently, it&#039;s printed in the first pass of a 2-pass encode&lt;br /&gt;
2010-11-23 08:28:04 &amp;lt; Rodeo&amp;gt; with that patch, this no longer happens&lt;br /&gt;
2010-11-23 08:28:07 &amp;lt; rfw&amp;gt; i&#039;m allowed to be ambitious, no :p&lt;br /&gt;
2010-11-23 08:28:19 &amp;lt; Dark_Shikari&amp;gt; Rodeo: er, that&#039;s removing a feature&lt;br /&gt;
2010-11-23 08:28:45 &amp;lt; Dark_Shikari&amp;gt; rfw: I assume the grand prize will be won by a very very dedicated nerd in a very small basement, taking massive numbers of overrated tasks.&lt;br /&gt;
2010-11-23 08:28:49 &amp;lt; Rodeo&amp;gt; OK, I thought that it wasn&#039;t supposed to do this&lt;br /&gt;
2010-11-23 08:28:52 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 08:28:52 &amp;lt; Dark_Shikari&amp;gt; No, it is.&lt;br /&gt;
2010-11-23 08:28:57 &amp;lt; Rodeo&amp;gt; but if current behavior is OK, then ignore my patch&lt;br /&gt;
2010-11-23 08:29:05 &amp;lt; Dark_Shikari&amp;gt; Rodeo: I thought you wanted it in the second pass&lt;br /&gt;
2010-11-23 08:29:07 &amp;lt; Dark_Shikari&amp;gt; _that_ would be cool.&lt;br /&gt;
2010-11-23 08:29:08 &amp;lt; rfw&amp;gt; i don&#039;t want to make surveys or posters&lt;br /&gt;
2010-11-23 08:29:16 &amp;lt; Dark_Shikari&amp;gt; rfw: I lol at those tasks&lt;br /&gt;
2010-11-23 08:29:20 &amp;lt; Dark_Shikari&amp;gt; MAKE A POSTER FOR MY PROJECT&lt;br /&gt;
2010-11-23 08:29:24 &amp;lt; Dark_Shikari&amp;gt; Actually, here&#039;s an idea&lt;br /&gt;
2010-11-23 08:29:25 &amp;lt; Rodeo&amp;gt; gotta go, I&#039;ll see what I can do about the altter later&lt;br /&gt;
2010-11-23 08:29:25 &amp;lt; rfw&amp;gt; lolol&lt;br /&gt;
2010-11-23 08:29:28 &amp;lt; Dark_Shikari&amp;gt; outsource&lt;br /&gt;
2010-11-23 08:29:36 &amp;lt; Dark_Shikari&amp;gt; find the easiest projects which can be done for like $5&lt;br /&gt;
2010-11-23 08:29:38 &amp;lt; Dark_Shikari&amp;gt; and outsource them&lt;br /&gt;
2010-11-23 08:29:46 &amp;lt; Dark_Shikari&amp;gt; through some mechanical turk like website&lt;br /&gt;
2010-11-23 08:29:54 &amp;lt; Dark_Shikari&amp;gt; 2) ???&lt;br /&gt;
2010-11-23 08:29:55 &amp;lt; Dark_Shikari&amp;gt; 3) profit&lt;br /&gt;
2010-11-23 08:30:33 &amp;lt; rfw&amp;gt; oh god, i have to rethink my side-by-side comparison output&lt;br /&gt;
2010-11-23 08:30:38 &amp;lt; rfw&amp;gt; because of the lol fixtures&lt;br /&gt;
2010-11-23 08:31:07 &amp;lt; Dark_Shikari&amp;gt; I feel sorry for people trying to game GCI&lt;br /&gt;
2010-11-23 08:31:23 &amp;lt; Dark_Shikari&amp;gt; it&#039;s just so extraordinarily silly&lt;br /&gt;
2010-11-23 08:33:51 &amp;lt; Dark_Shikari&amp;gt; Let&#039;s hope pengvado can read python to review your code =p&lt;br /&gt;
2010-11-23 08:34:38 &amp;lt; rfw&amp;gt; is there no more ./configure?&lt;br /&gt;
2010-11-23 08:35:12 &amp;lt; rfw&amp;gt; either that or something is very wrong&lt;br /&gt;
2010-11-23 08:35:15 &amp;lt; Dark_Shikari&amp;gt; o.0&lt;br /&gt;
2010-11-23 08:35:30 &amp;lt; rfw&amp;gt; where did it go&lt;br /&gt;
2010-11-23 08:36:58 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 08:37:01 &amp;lt; rfw&amp;gt; there we go&lt;br /&gt;
2010-11-23 08:37:52 &amp;lt; rfw&amp;gt; i had my revision list upside down&lt;br /&gt;
2010-11-23 08:48:41 &amp;lt; Kovensky&amp;gt; 05:13.39 rfw: i can&#039;t even get group/owner information &amp;lt;-- broken ACLs?&lt;br /&gt;
2010-11-23 08:48:55 &amp;lt; rfw&amp;gt; Kovensky: looks like it&lt;br /&gt;
2010-11-23 08:48:59 &amp;lt; rfw&amp;gt; super-broken ACLs&lt;br /&gt;
2010-11-23 08:49:10 &amp;lt; Kovensky&amp;gt; try chown yourusername:Administrator -R /path/to/folder &amp;amp;&amp;amp; chmod 777 -R /path/to/folder&lt;br /&gt;
2010-11-23 08:49:25 &amp;lt; Kovensky&amp;gt; if that doesn&#039;t work, you may need to chkdsk&lt;br /&gt;
2010-11-23 08:49:31 &amp;lt; nattofriends&amp;gt; takeown&lt;br /&gt;
2010-11-23 08:49:35 &amp;lt; Kovensky&amp;gt; Administrators*&lt;br /&gt;
2010-11-23 08:49:36 &amp;lt; rfw&amp;gt; nattofriends: did that&lt;br /&gt;
2010-11-23 08:49:44 &amp;lt; rfw&amp;gt; chown: cannot read directory `../x264&#039;: Permission denied&lt;br /&gt;
2010-11-23 08:49:51 &amp;lt; rfw&amp;gt; ;_;&lt;br /&gt;
2010-11-23 08:49:58 &amp;lt; nattofriends&amp;gt; can copy folder?&lt;br /&gt;
2010-11-23 08:50:01 &amp;lt; rfw&amp;gt; nope&lt;br /&gt;
2010-11-23 08:50:26 &amp;lt; nattofriends&amp;gt; drop to a bootcd with ntfs mounting, try copying it to FAT&lt;br /&gt;
2010-11-23 08:50:34 &amp;lt; nattofriends&amp;gt; then reboot and copy elsewhere?&lt;br /&gt;
2010-11-23 08:51:09 &amp;lt; Kovensky&amp;gt; the bootcd will just give more errors&lt;br /&gt;
2010-11-23 08:51:20 &amp;lt; Kovensky&amp;gt; run a chkdsk on readonly mode, if it whines you found your culprit&lt;br /&gt;
2010-11-23 08:51:29 &amp;lt; Dark_Shikari&amp;gt; Aren&#039;t there windows tools to override ACLs?&lt;br /&gt;
2010-11-23 08:52:09 &amp;lt; Kovensky&amp;gt; Dark_Shikari: they&#039;re not working&lt;br /&gt;
2010-11-23 08:52:21 &amp;lt; Kovensky&amp;gt; which is why I assume the ACLs are completely broken there&lt;br /&gt;
2010-11-23 09:09:55 &amp;lt; rfw&amp;gt; well then, i think i&#039;ve finished&lt;br /&gt;
2010-11-23 09:10:02 &amp;lt; rfw&amp;gt; oh wait&lt;br /&gt;
2010-11-23 09:10:09 &amp;lt; rfw&amp;gt; still haven&#039;t done that macroblock frame calculation thing&lt;br /&gt;
2010-11-23 09:10:10 &amp;lt; rfw&amp;gt; hnngh&lt;br /&gt;
2010-11-23 09:10:15 &amp;lt; Dark_Shikari&amp;gt; that&#039;s not too hard =p&lt;br /&gt;
2010-11-23 09:10:17 &amp;lt; Dark_Shikari&amp;gt; that&#039;s like 3 lines of code&lt;br /&gt;
2010-11-23 09:10:23 &amp;lt; Dark_Shikari&amp;gt; though you have to know the video width and height to do that.&lt;br /&gt;
2010-11-23 09:10:31 &amp;lt; rfw&amp;gt; but i&#039;m tired&lt;br /&gt;
2010-11-23 09:10:31 &amp;lt; rfw&amp;gt; D:&lt;br /&gt;
2010-11-23 09:10:46 &amp;lt; rfw&amp;gt; also do you mind if i commit my library to github&lt;br /&gt;
2010-11-23 09:10:57 &amp;lt; rfw&amp;gt; since i&#039;m paranoid&lt;br /&gt;
2010-11-23 09:11:02 &amp;lt; rfw&amp;gt; about my computer exploding&lt;br /&gt;
2010-11-23 09:11:04 &amp;lt; rfw&amp;gt; while i sleep&lt;br /&gt;
2010-11-23 09:25:20 &amp;lt; J_Darnley&amp;gt; What a lot of discussion where was overnight.  It nearly ran off the top of my buffer&lt;br /&gt;
2010-11-23 09:25:31 &amp;lt; tjoener&amp;gt; indeed J_Darnley&lt;br /&gt;
2010-11-23 09:25:34 &amp;lt; tjoener&amp;gt; just read them too&lt;br /&gt;
2010-11-23 09:26:22 &amp;lt; Kovensky&amp;gt; means your buffer is too small :&amp;gt;&lt;br /&gt;
2010-11-23 09:27:28 &amp;lt; Dark_Shikari&amp;gt; pengvado: can you explain cbr_decay?&lt;br /&gt;
2010-11-23 09:28:11 &amp;lt; Dark_Shikari&amp;gt; and specifically the formula used to calculate it&lt;br /&gt;
2010-11-23 09:28:18 &amp;lt; Dark_Shikari&amp;gt; and what &amp;quot;1.0&amp;quot; vs &amp;quot;0.0&amp;quot; etc would mean&lt;br /&gt;
2010-11-23 09:29:46 &amp;lt; Dark_Shikari&amp;gt; and why is printing of ratefactor disabled with high cbr decay?&lt;br /&gt;
2010-11-23 09:29:59 &amp;lt; Dark_Shikari&amp;gt; high cbr decay can happen with e.g. --vbv-bufsize 30000 --vbv-maxrate 40000 --bitrate 4000&lt;br /&gt;
2010-11-23 09:32:35 &amp;lt; Rodeo&amp;gt; and low cbr decay when vbv maxrate and/or bufsize are closer to the avg. bitrate&lt;br /&gt;
2010-11-23 09:33:25 &amp;lt; Rodeo&amp;gt; I used these high values in my test, but I think I&#039;d have gotten the same results with no vbv at all&lt;br /&gt;
2010-11-23 09:37:31 &amp;lt; Dark_Shikari&amp;gt; Oh, I see&lt;br /&gt;
2010-11-23 09:37:40 &amp;lt; Dark_Shikari&amp;gt; 1.0 --&amp;gt; no cbr decay&lt;br /&gt;
2010-11-23 09:37:47 &amp;lt; Dark_Shikari&amp;gt; less than 1.0 --&amp;gt; lots of cbr decay&lt;br /&gt;
2010-11-23 09:38:01 &amp;lt; Dark_Shikari&amp;gt; ratefactor is only printed if there&#039;s no cbr decay, or nearso&lt;br /&gt;
2010-11-23 09:38:23 &amp;lt; Dark_Shikari&amp;gt; there&#039;s no cbr decay in my example (1.0) because vbv is much larger than bitrate.&lt;br /&gt;
2010-11-23 09:44:31 &amp;lt; Rodeo&amp;gt; that was my guess&lt;br /&gt;
2010-11-23 09:44:58 &amp;lt; Rodeo&amp;gt; doesn&#039;t explain what cbr decay actually is though&lt;br /&gt;
2010-11-23 09:45:09 &amp;lt; Rodeo&amp;gt; though it probably makes more sense to you&lt;br /&gt;
2010-11-23 09:45:15 &amp;lt; Dark_Shikari&amp;gt; rc-&amp;gt;cplxr_sum *= rc-&amp;gt;cbr_decay;&lt;br /&gt;
2010-11-23 09:45:17 &amp;lt; Dark_Shikari&amp;gt; rc-&amp;gt;wanted_bits_window *= rc-&amp;gt;cbr_decay;&lt;br /&gt;
2010-11-23 09:45:24 &amp;lt; Dark_Shikari&amp;gt; it&#039;s how fast the ABR state decays over time&lt;br /&gt;
2010-11-23 09:45:26 &amp;lt; Dark_Shikari&amp;gt; 1.0 has no effect&lt;br /&gt;
2010-11-23 09:45:30 &amp;lt; Dark_Shikari&amp;gt; 0.0 means it immediately decays&lt;br /&gt;
2010-11-23 09:45:36 &amp;lt; Dark_Shikari&amp;gt; in CBR, you want it to decay fast&lt;br /&gt;
2010-11-23 09:45:44 &amp;lt; Dark_Shikari&amp;gt; in ABR with no VBV, you don&#039;t want it to decay at all&lt;br /&gt;
2010-11-23 09:45:52 &amp;lt; Dark_Shikari&amp;gt; so its a measure of a guess at the effect of CBR on the ABR algorithm&lt;br /&gt;
2010-11-23 09:48:13 &amp;lt; Rodeo&amp;gt; so there&#039;s no issue then&lt;br /&gt;
2010-11-23 09:48:35 &amp;lt; Dark_Shikari&amp;gt; well, it might be useful to have ratefactor if cbr_decay is &amp;lt; 1&lt;br /&gt;
2010-11-23 09:48:39 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t know if it&#039;d be meaningful or not&lt;br /&gt;
2010-11-23 11:47:46 &amp;lt; Alex_W&amp;gt; Dark_Shikari: I just saw your post on doom9 about using weightp with 1 ref for blu-ray compatibility, is it confirmed then that dupes are the problem on mediatek chipsets?&lt;br /&gt;
2010-11-23 12:01:31 &amp;lt; j-b&amp;gt; Dark_Shikari: http://socghop.appspot.com/gci/task/show/google/gci2010/videolan/t129045717568&lt;br /&gt;
2010-11-23 12:02:46 &amp;lt; kierank&amp;gt; j-b: that guy already failed ;)&lt;br /&gt;
2010-11-23 12:06:13 &amp;lt; kierank&amp;gt; melange is awful&lt;br /&gt;
2010-11-23 12:11:45 &amp;lt; Dark_Shikari&amp;gt; Alex_W: yes&lt;br /&gt;
2010-11-23 12:11:56 &amp;lt; Dark_Shikari&amp;gt; j-b: what?&lt;br /&gt;
2010-11-23 12:12:04 &amp;lt; Dark_Shikari&amp;gt; 4032 hours lol?&lt;br /&gt;
2010-11-23 12:13:07 &amp;lt; Alex_W&amp;gt; ok, then would you accept a patch that disables dupes? maybe something like --weightp bluray?&lt;br /&gt;
2010-11-23 12:13:37 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t like the idea of actively supporting broken players&lt;br /&gt;
2010-11-23 12:13:42 &amp;lt; Dark_Shikari&amp;gt; it creates more fragmentation&lt;br /&gt;
2010-11-23 12:13:58 &amp;lt; JEEB&amp;gt; Alex_W, wipple wrote something similar IIRC&lt;br /&gt;
2010-11-23 12:14:09 &amp;lt; JEEB&amp;gt; but yeah, gotta go by D_S&#039;s opinion here&lt;br /&gt;
2010-11-23 12:14:15 &amp;lt; Dark_Shikari&amp;gt; I think we could have a patch, maybe&lt;br /&gt;
2010-11-23 12:14:20 &amp;lt; Dark_Shikari&amp;gt; but committed?  probably not&lt;br /&gt;
2010-11-23 12:15:12 &amp;lt; Alex_W&amp;gt; the problem is that replicators probably won&#039;t use weightp at all because of this, imo a slightly less useful weightp without dupes is better than no weightp at all...&lt;br /&gt;
2010-11-23 12:15:47 &amp;lt; Alex_W&amp;gt; also we already have an --open-gop bluray, how is this any different?&lt;br /&gt;
2010-11-23 12:16:25 &amp;lt; JEEB&amp;gt; because it&#039;s in the spec :|&lt;br /&gt;
2010-11-23 12:16:56 &amp;lt; JEEB&amp;gt; normal weightp is completely within the spec and most players play it fine&lt;br /&gt;
2010-11-23 12:17:09 &amp;lt; JEEB&amp;gt; (as it is in the spec AFAICS)&lt;br /&gt;
2010-11-23 12:18:02 &amp;lt; wipple&amp;gt; i wrote this patch before ---&amp;gt; http://cccp.project357.com/p/f3b5731a7&lt;br /&gt;
2010-11-23 12:18:14 &amp;lt; Dark_Shikari&amp;gt; Alex_W: also, at very low quants, weightp is less useful&lt;br /&gt;
2010-11-23 12:18:17 &amp;lt; wipple&amp;gt; and rejected by Dark_Shikari&lt;br /&gt;
2010-11-23 12:18:40 &amp;lt; Alex_W&amp;gt; the problem is that the spec probably doesn&#039;t really matter to replicators, the only thing that&#039;s going to matter to them is whether real world players will actually play the discs without any problems&lt;br /&gt;
2010-11-23 12:18:55 &amp;lt; j-b&amp;gt; Dark_Shikari: I believe you should approve it&lt;br /&gt;
2010-11-23 12:19:17 &amp;lt; Dark_Shikari&amp;gt; j-b: really, for someone who didn&#039;t follow instructions ands how up?&lt;br /&gt;
2010-11-23 12:19:20 &amp;lt; Dark_Shikari&amp;gt; I guess I can hope they do after.&lt;br /&gt;
2010-11-23 12:19:44 &amp;lt; j-b&amp;gt; Dark_Shikari: then reject it&lt;br /&gt;
2010-11-23 12:19:53 &amp;lt; Dark_Shikari&amp;gt; well, they might be waiting for acceptance&lt;br /&gt;
2010-11-23 12:19:55 &amp;lt; Dark_Shikari&amp;gt; and then show up&lt;br /&gt;
2010-11-23 12:19:59 &amp;lt; Dark_Shikari&amp;gt; so whatever I&#039;ll accept can&#039;t hurt&lt;br /&gt;
2010-11-23 12:20:06 &amp;lt; j-b&amp;gt; melange is awful&lt;br /&gt;
2010-11-23 12:22:47 &amp;lt; Alex_W&amp;gt; Dark_Shikari: wipple&#039;s patch seems like it should be fine to me, it could be interesting to be able to disable dupes in ordinary encodes anyway&lt;br /&gt;
2010-11-23 12:23:37 &amp;lt; Dark_Shikari&amp;gt; dunno&lt;br /&gt;
2010-11-23 12:24:07 &amp;lt; Dark_Shikari&amp;gt; we could add a b_bluray mode to enable stupid blu-ray hacks&lt;br /&gt;
2010-11-23 12:24:07 &amp;lt; JEEB&amp;gt; is it explicitly dupes that all of those players have/had problems with?&lt;br /&gt;
2010-11-23 12:24:16 &amp;lt; Dark_Shikari&amp;gt; there&#039;s only one chipset with a bug&lt;br /&gt;
2010-11-23 12:24:17 &amp;lt; Dark_Shikari&amp;gt; mediatek&lt;br /&gt;
2010-11-23 12:24:20 &amp;lt; Dark_Shikari&amp;gt; and it&#039;s fixed in a firmware update&lt;br /&gt;
2010-11-23 12:24:46 &amp;lt; Alex_W&amp;gt; b_bluray would be the same as --device bluray right?&lt;br /&gt;
2010-11-23 12:25:41 &amp;lt; Dark_Shikari&amp;gt; no&lt;br /&gt;
2010-11-23 12:25:55 &amp;lt; Dark_Shikari&amp;gt; it&#039;d be for stupid shit like the max frame size limitation we stuck in&lt;br /&gt;
2010-11-23 12:26:00 &amp;lt; Dark_Shikari&amp;gt; it&#039;s currently under if( hrd &amp;amp;&amp;amp; level 4.1)&lt;br /&gt;
2010-11-23 12:26:22 &amp;lt; Alex_W&amp;gt; what frame size limitation is that?&lt;br /&gt;
2010-11-23 12:26:37 &amp;lt; Dark_Shikari&amp;gt; mincr&lt;br /&gt;
2010-11-23 12:26:41 &amp;lt; Dark_Shikari&amp;gt;         /* Blu-ray requires this */&lt;br /&gt;
2010-11-23 12:26:41 &amp;lt; Dark_Shikari&amp;gt;         if( l-&amp;gt;level_idc == 41 &amp;amp;&amp;amp; h-&amp;gt;param.i_nal_hrd )&lt;br /&gt;
2010-11-23 12:26:41 &amp;lt; Dark_Shikari&amp;gt;             mincr = 4;&lt;br /&gt;
2010-11-23 12:26:58 &amp;lt; Kovensky&amp;gt; 09:13.37 Dark_Shikari: I don&#039;t like the idea of actively supporting broken players &amp;lt;-- shifting the blame? :)&lt;br /&gt;
2010-11-23 12:27:14 &amp;lt; JEEB&amp;gt; So that problem was with dupes? I still don&#039;t get it, I get it&#039;s a single chipset but was the problem explicitly with dupes regarding weightp?&lt;br /&gt;
2010-11-23 12:27:15 &amp;lt; Dark_Shikari&amp;gt; it&#039;s my fault that mediatek fucked up?&lt;br /&gt;
2010-11-23 12:27:18 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 12:27:21 &amp;lt; Dark_Shikari&amp;gt; it&#039;s a single chipset&lt;br /&gt;
2010-11-23 12:27:22 &amp;lt; JEEB&amp;gt; ok&lt;br /&gt;
2010-11-23 12:27:25 &amp;lt; Dark_Shikari&amp;gt; which has ALREADY BEEN FIXED&lt;br /&gt;
2010-11-23 12:27:29 &amp;lt; JEEB&amp;gt; :)&lt;br /&gt;
2010-11-23 12:27:29 &amp;lt; Dark_Shikari&amp;gt; and which people need to stop bitching about&lt;br /&gt;
2010-11-23 12:27:34 &amp;lt; JEEB&amp;gt; Indeed&lt;br /&gt;
2010-11-23 12:28:00 &amp;lt; Alex_W&amp;gt; it&#039;s only fixed if people actually bother to update their firmware though :/&lt;br /&gt;
2010-11-23 12:28:10 &amp;lt; JEEB&amp;gt; I wish you could update the firmware through blu-ray discs&lt;br /&gt;
2010-11-23 12:28:23 &amp;lt; JEEB&amp;gt; &amp;quot;To watch this movie you need to update your player bleh bleh bleh&amp;quot;&lt;br /&gt;
2010-11-23 12:28:41 &amp;lt; Kovensky&amp;gt; &amp;quot;And if the power fail or otherwise stuff goes wrong you&#039;ll have yourself a heavy brick&amp;quot;&lt;br /&gt;
2010-11-23 12:28:42 &amp;lt; kierank&amp;gt; JEEB: well that implies they have a decent internet connection at hand&lt;br /&gt;
2010-11-23 12:28:43 &amp;lt; Dark_Shikari&amp;gt; Alex_W: discs already come with instructions on how to upgrade firmware&lt;br /&gt;
2010-11-23 12:28:45 &amp;lt; Kovensky&amp;gt; +s&lt;br /&gt;
2010-11-23 12:28:52 &amp;lt; Alex_W&amp;gt; ok, so apart from the mincr thing and dupes are there any other stupid hacks that blu-ray requires?&lt;br /&gt;
2010-11-23 12:29:10 &amp;lt; Dark_Shikari&amp;gt; not that aren&#039;t encapsulated in other options&lt;br /&gt;
2010-11-23 12:29:20 &amp;lt; JEEB&amp;gt; kierank, I mean having the updates for those crappy pieces of shit on the disc... :| But I guess that&#039;s impossible.&lt;br /&gt;
2010-11-23 12:29:41 &amp;lt; Kovensky&amp;gt; Dark_Shikari: the opengop one? I mean, the bluray suboption is specifically a bluray hack, isn&#039;t it&lt;br /&gt;
2010-11-23 12:29:46 &amp;lt; Dark_Shikari&amp;gt; oh, that&#039;s true.&lt;br /&gt;
2010-11-23 12:29:59 &amp;lt; Alex_W&amp;gt; ok so that too then&lt;br /&gt;
2010-11-23 12:30:14 &amp;lt; Dark_Shikari&amp;gt; ok, proposal&lt;br /&gt;
2010-11-23 12:30:22 &amp;lt; Dark_Shikari&amp;gt; replace weightp 1 with weightp without dupes.&lt;br /&gt;
2010-11-23 12:30:32 &amp;lt; Dark_Shikari&amp;gt; that is, 1 becomes SMART minus dupes&lt;br /&gt;
2010-11-23 12:30:38 &amp;lt; Dark_Shikari&amp;gt; instead of SMART minus analysis&lt;br /&gt;
2010-11-23 12:30:45 &amp;lt; JEEB&amp;gt; sounds good &#039;nuff&lt;br /&gt;
2010-11-23 12:30:46 &amp;lt; Dark_Shikari&amp;gt; I will commit that patch&lt;br /&gt;
2010-11-23 12:31:25 &amp;lt; Alex_W&amp;gt; ok that sounds reasonable&lt;br /&gt;
2010-11-23 12:31:42 &amp;lt; Dark_Shikari&amp;gt; this is in part because analysis is really faster than we expected it to be&lt;br /&gt;
2010-11-23 12:31:50 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll have to retune the presets but that&#039;s not too hard&lt;br /&gt;
2010-11-23 12:31:53 &amp;lt; Dark_Shikari&amp;gt; just give me a patch and I&#039;ll do the rest&lt;br /&gt;
2010-11-23 12:32:18  * Alex_W goes to look at the code&lt;br /&gt;
2010-11-23 12:32:38 &amp;lt; Dark_Shikari&amp;gt; NB: grep for all places where we check against WEIGHTP_SMART&lt;br /&gt;
2010-11-23 12:32:43 &amp;lt; Dark_Shikari&amp;gt; most of those, we&#039;ll have to just check for weightp&lt;br /&gt;
2010-11-23 12:32:49 &amp;lt; Dark_Shikari&amp;gt; also note WEIGHTP_FAKE as an internal value&lt;br /&gt;
2010-11-23 12:32:53 &amp;lt; Dark_Shikari&amp;gt; (for psy + weightp = 0)&lt;br /&gt;
2010-11-23 12:33:08 &amp;lt; Dark_Shikari&amp;gt; and we can replace BLIND with WEIGHTP_SIMPLE or something&lt;br /&gt;
2010-11-23 12:37:49 &amp;lt; Alex_W&amp;gt; so WEIGHTP_SIMPLE would be weightp without dupes and WEIGHTP_SMART would be weightp + dupes?&lt;br /&gt;
2010-11-23 12:38:13 &amp;lt; pengvado&amp;gt; Dark_Shikari: you got your explanation of cbr_decay?&lt;br /&gt;
2010-11-23 12:38:14 &amp;lt; pengvado&amp;gt; we don&#039;t print rate_factor in cbr mode, because it would be the rate_factor of just the last few seconds of the movie&lt;br /&gt;
2010-11-23 12:39:05 &amp;lt; Dark_Shikari&amp;gt; what about ABR with some VBV?&lt;br /&gt;
2010-11-23 12:39:31 &amp;lt; Dark_Shikari&amp;gt; I guess given how cbr_decay works, it wouldn&#039;t work.&lt;br /&gt;
2010-11-23 12:39:34 &amp;lt; Dark_Shikari&amp;gt; you&#039;d have to somehow recalculate it.&lt;br /&gt;
2010-11-23 12:39:39 &amp;lt; Dark_Shikari&amp;gt; sorta makes sense.&lt;br /&gt;
2010-11-23 12:40:41 &amp;lt; pengvado&amp;gt; the soft threshold of &amp;quot;cbr mode is when vbv-maxrate &amp;lt; 1.5*bitrate&amp;quot; is not at all tested, but yes&lt;br /&gt;
2010-11-23 12:46:48 &amp;lt; Alex_W&amp;gt; why does WEIGHTP_SMART add 2 dupes atm?&lt;br /&gt;
2010-11-23 12:47:10 &amp;lt; Dark_Shikari&amp;gt; the normal blind dupe, plus the smart dupe&lt;br /&gt;
2010-11-23 12:47:23 &amp;lt; Dark_Shikari&amp;gt; that is, there are three copies of a given frame:&lt;br /&gt;
2010-11-23 12:47:28 &amp;lt; Dark_Shikari&amp;gt; OPTIMAL (optimal weight)&lt;br /&gt;
2010-11-23 12:47:32 &amp;lt; Dark_Shikari&amp;gt; OPTIMAL-1 (blind dupe of optimal)&lt;br /&gt;
2010-11-23 12:47:35 &amp;lt; Dark_Shikari&amp;gt; ORIGINAL (original frame)&lt;br /&gt;
2010-11-23 12:47:43 &amp;lt; Dark_Shikari&amp;gt; if OPTIMAL and ORIGINAL are the same, ORIGINAL is omitted.&lt;br /&gt;
2010-11-23 12:47:46 &amp;lt; Dark_Shikari&amp;gt; i.e. if there&#039;s no weight&lt;br /&gt;
2010-11-23 12:47:58 &amp;lt; Dark_Shikari&amp;gt; having both optimal and original is very useful if part of the frame isn&#039;t fading in&lt;br /&gt;
2010-11-23 12:48:04 &amp;lt; Dark_Shikari&amp;gt; or is otherwise useful unweighted&lt;br /&gt;
2010-11-23 12:49:01 &amp;lt; Alex_W&amp;gt; well i&#039;ll have to change that so that optimal replaces original for the new weightp 1 right?&lt;br /&gt;
2010-11-23 12:49:13 &amp;lt; Dark_Shikari&amp;gt; no, ORIGINAL is a dupe&lt;br /&gt;
2010-11-23 12:49:16 &amp;lt; Dark_Shikari&amp;gt; optimal already does replace original&lt;br /&gt;
2010-11-23 12:49:18 &amp;lt; Dark_Shikari&amp;gt; i.e. ref0 is optimal&lt;br /&gt;
2010-11-23 12:49:23 &amp;lt; Dark_Shikari&amp;gt; all you have to do is _stop_ the creation of dupes&lt;br /&gt;
2010-11-23 12:49:26 &amp;lt; Alex_W&amp;gt; ah&lt;br /&gt;
2010-11-23 12:49:29 &amp;lt; Dark_Shikari&amp;gt; there&#039;s no new code to be added&lt;br /&gt;
2010-11-23 12:51:28 &amp;lt; Alex_W&amp;gt; lines 242 and 243 in common/macroblock.c can be removed then right since WEIGHTP_SIMPLE won&#039;t add any dupes?&lt;br /&gt;
2010-11-23 12:51:54 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 12:52:00 &amp;lt; Alex_W&amp;gt; k&lt;br /&gt;
2010-11-23 12:52:20 &amp;lt; Dark_Shikari&amp;gt; also we could just rename them&lt;br /&gt;
2010-11-23 12:52:22 &amp;lt; Dark_Shikari&amp;gt; to 0, 1, 2, 3&lt;br /&gt;
2010-11-23 12:52:24 &amp;lt; Dark_Shikari&amp;gt; 1 == fast&lt;br /&gt;
2010-11-23 12:52:25 &amp;lt; Dark_Shikari&amp;gt; 2 == medium&lt;br /&gt;
2010-11-23 12:52:28 &amp;lt; Dark_Shikari&amp;gt; 3 == slow (I&#039;l do this)&lt;br /&gt;
2010-11-23 12:52:35 &amp;lt; Dark_Shikari&amp;gt; anyways, for now, just do your part and I&#039;ll futz with the rest later&lt;br /&gt;
2010-11-23 12:52:41 &amp;lt; Dark_Shikari&amp;gt; brb sleep&lt;br /&gt;
2010-11-23 12:53:16 &amp;lt; Alex_W&amp;gt; what about &amp;gt; 8 bit, do we want dupes in WEIGHTP_SMART?&lt;br /&gt;
2010-11-23 12:54:22 &amp;lt; Dark_Shikari&amp;gt; not the -1 dupe&lt;br /&gt;
2010-11-23 12:54:25 &amp;lt; Dark_Shikari&amp;gt; yes the original vs optimal&lt;br /&gt;
2010-11-23 12:54:45 &amp;lt; Alex_W&amp;gt; k&lt;br /&gt;
2010-11-23 15:27:56  * koda|work pings Dark_Shikari&lt;br /&gt;
2010-11-23 17:39:47 &amp;lt; reid_&amp;gt; Is this the channel for Google Code-In?&lt;br /&gt;
2010-11-23 17:41:16 &amp;lt; kierank&amp;gt; yes&lt;br /&gt;
2010-11-23 17:41:31 &amp;lt; kierank&amp;gt; reid_: yes&lt;br /&gt;
2010-11-23 17:42:48 &amp;lt; reid_&amp;gt; I am looking at completing one of the &#039;C to assembly function&#039; problems and it said to come here first&lt;br /&gt;
2010-11-23 17:45:31 &amp;lt; kierank&amp;gt; reid_: how much assembly do you know?&lt;br /&gt;
2010-11-23 17:48:58 &amp;lt; reid_&amp;gt; I know how the language works, but I would  have to look up most commands. I wanted to look at the code before making a decision to see If it was out of my skill level.&lt;br /&gt;
2010-11-23 17:49:49 &amp;lt; reid_&amp;gt; Is there a link to the specific methods in question?&lt;br /&gt;
2010-11-23 17:51:31 &amp;lt; kierank&amp;gt; reid_: Dark_Shikari will teach you when he wakes up&lt;br /&gt;
2010-11-23 17:52:06 &amp;lt; callahan&amp;gt; reid_: Basically they are the 10 bit functions that are slow when you run the checkasm program.&lt;br /&gt;
2010-11-23 17:52:22 &amp;lt; callahan&amp;gt; Although I couldn&#039;t tell you which ones other people are working on.&lt;br /&gt;
2010-11-23 17:52:57 &amp;lt; callahan&amp;gt; Or that it matters.  Step 1 would be to get the code and compile it for 10 bit, then run checkasm.&lt;br /&gt;
2010-11-23 17:53:08 &amp;lt; callahan&amp;gt; While you wait for D_S.&lt;br /&gt;
2010-11-23 17:54:43 &amp;lt; reid_&amp;gt; where is the code? There is no reference to it on the task page.&lt;br /&gt;
2010-11-23 17:55:17 &amp;lt; callahan&amp;gt; git clone git://git.videolan.org/x264.git&lt;br /&gt;
2010-11-23 17:55:56 &amp;lt; callahan&amp;gt; Will check you out a copy, assuming that you have the git program installed.&lt;br /&gt;
2010-11-23 17:56:10 &amp;lt; callahan&amp;gt; If not start by googling up and installing git.&lt;br /&gt;
2010-11-23 17:56:27 &amp;lt; jarod&amp;gt; what is the main x264 google code in website?&lt;br /&gt;
2010-11-23 17:57:07 &amp;lt; reid_&amp;gt; is it an x86 instruction set?&lt;br /&gt;
2010-11-23 17:57:30 &amp;lt; callahan&amp;gt; git is a revision control system&lt;br /&gt;
2010-11-23 17:57:37 &amp;lt; callahan&amp;gt; for managing code bases&lt;br /&gt;
2010-11-23 17:59:04 &amp;lt; jarod&amp;gt; reid_ what link did you use to get here? :P&lt;br /&gt;
2010-11-23 18:01:07 &amp;lt; reid_&amp;gt; From the GCI task list on google-melange.com, it said it is required to come here before claiming the task.&lt;br /&gt;
2010-11-23 18:01:35 &amp;lt; kierank&amp;gt; reid_: what OS are you on?&lt;br /&gt;
2010-11-23 18:01:41 &amp;lt; jarod&amp;gt; yes that good, i just couldn&#039;t mind it :)&lt;br /&gt;
2010-11-23 18:03:30 &amp;lt; reid_&amp;gt; Right now i&#039;m on an Ubuntu variant.&lt;br /&gt;
2010-11-23 18:05:13 &amp;lt; kierank&amp;gt; reid_: then download the git package, open a terminal and run the command callahan posted&lt;br /&gt;
2010-11-23 18:08:27 &amp;lt; reid_&amp;gt; Ok it completed.&lt;br /&gt;
2010-11-23 18:09:56 &amp;lt; callahan&amp;gt; the source will be in the x264 directory&lt;br /&gt;
2010-11-23 18:10:18 &amp;lt; holger_&amp;gt; and the asm will be in x264/common/x86&lt;br /&gt;
2010-11-23 18:11:10 &amp;lt; callahan&amp;gt; I&#039;m not sure what the configure command is to get checkasm and 10 bit going.  Anyone else?&lt;br /&gt;
2010-11-23 18:12:14 &amp;lt; holger_&amp;gt; ./configure --bit-depth=10 ; make ; make checkasm&lt;br /&gt;
2010-11-23 18:12:32 &amp;lt; callahan&amp;gt; Yeah that, except use &amp;amp;&amp;amp; instead of ;&lt;br /&gt;
2010-11-23 18:12:39 &amp;lt; callahan&amp;gt; in case one fails :)&lt;br /&gt;
2010-11-23 18:12:46 &amp;lt; jarod&amp;gt; \doc&lt;br /&gt;
2010-11-23 18:12:47 &amp;lt; jarod&amp;gt; regression_test.txt&lt;br /&gt;
2010-11-23 18:12:52 &amp;lt; jarod&amp;gt; svn co svn://svn.videolan.org/x264/trunk x264&lt;br /&gt;
2010-11-23 18:12:54 &amp;lt; jarod&amp;gt; =)&lt;br /&gt;
2010-11-23 18:14:49 &amp;lt; callahan&amp;gt; reid_: anyway, do the holger_ commands to compile it.&lt;br /&gt;
2010-11-23 18:14:53 &amp;lt; holger_&amp;gt; i&#039;m currently wondering which of the .asm files would be the least scary for a noob to look at. can&#039;t decide. they all seem to have parts that are going to be way over the head for someone who&#039;s pretty new to asm.&lt;br /&gt;
2010-11-23 18:15:36 &amp;lt; reid_&amp;gt; so what exactly am I doing with this code?&lt;br /&gt;
2010-11-23 18:15:52 &amp;lt; callahan&amp;gt; Shikari has been recommending people try either one of two things.  Pick a missing 10 bit asm function and implement it, or make random changes to an existing function and see if it&#039;s faster.&lt;br /&gt;
2010-11-23 18:16:10 &amp;lt; reid_&amp;gt; Am I just translating a few functions into c?&lt;br /&gt;
2010-11-23 18:16:19 &amp;lt; callahan&amp;gt; reid_: You&#039;re making it faster, either by implementing a missing function or making one of the existing ones faster.&lt;br /&gt;
2010-11-23 18:17:03 &amp;lt; holger_&amp;gt; erm. you&#039;re going to translate c into asm. or optimize existing asm.&lt;br /&gt;
2010-11-23 18:17:34 &amp;lt; callahan&amp;gt; reid_: Best would be to get it to compile and poke around while you wait for Dark_Shikari to get back.&lt;br /&gt;
2010-11-23 18:17:43 &amp;lt; irock&amp;gt; personally I though sad was easiest to understand and write; it was the first code I implemented for high depth&lt;br /&gt;
2010-11-23 18:18:49 &amp;lt; callahan&amp;gt; get checkasm running first, that gives you a profile of the existing asm functions.&lt;br /&gt;
2010-11-23 18:20:56 &amp;lt; holger_&amp;gt; configure for 10 bit, build, run ./checkasm --bench. configure for 8 bit, do the same. compare the output. the differences tell you what&#039;s missing.&lt;br /&gt;
2010-11-23 18:22:22 &amp;lt; reid_&amp;gt; so checkasm will tell you how efficient your code is?&lt;br /&gt;
2010-11-23 18:22:53 &amp;lt; callahan&amp;gt; A good estimate, yes&lt;br /&gt;
2010-11-23 18:22:56 &amp;lt; holger_&amp;gt; it measures runtime. for the c reference and the asm routines (often there is more than one, for different instruction sets)&lt;br /&gt;
2010-11-23 18:23:39 &amp;lt; holger_&amp;gt; so pick a routine that exists for 8 bit but not 10 bit, look it up in the source and see if you can understand how it works.&lt;br /&gt;
2010-11-23 18:25:08 &amp;lt; reid_&amp;gt; where can I get checkasm. Do I need a specific repository?&lt;br /&gt;
2010-11-23 18:25:23 &amp;lt; holger_&amp;gt; you already have it. it&#039;s in the tools directory. make checkasm builds it.&lt;br /&gt;
2010-11-23 18:25:54 &amp;lt; callahan&amp;gt; It&#039;s an x264 specific regression test.&lt;br /&gt;
2010-11-23 18:26:20 &amp;lt; reid_&amp;gt; Oh wow sorry, I thought it was a tool.&lt;br /&gt;
2010-11-23 18:26:27 &amp;lt; holger_&amp;gt; yup that too. if you work on optimizing asm, it&#039;s good to have a way of telling if you broke it.&lt;br /&gt;
2010-11-23 18:29:13 &amp;lt; reid_&amp;gt; Am I supposed to get tons of errors?&lt;br /&gt;
2010-11-23 18:29:16 &amp;lt; callahan&amp;gt; no&lt;br /&gt;
2010-11-23 18:29:17 &amp;lt; irock&amp;gt; no&lt;br /&gt;
2010-11-23 18:29:21 &amp;lt; holger_&amp;gt; if you get stuck trying to understand the asm, dark_shikari is probably happy to give you his crash course to x264 asm.&lt;br /&gt;
2010-11-23 18:29:55 &amp;lt; irock&amp;gt; reid_: make sure do a make clean before/after you reconfigure for another bit depth.&lt;br /&gt;
2010-11-23 18:30:30 &amp;lt; reid_&amp;gt; I pointed my terminal over to /x264/tools and ran &#039;make checkasm&#039;&lt;br /&gt;
2010-11-23 18:30:30 &amp;lt; holger_&amp;gt; oh and you want to install yasm if you don&#039;t have it already&lt;br /&gt;
2010-11-23 18:30:45 &amp;lt; irock&amp;gt; you should be standing in x264 root&lt;br /&gt;
2010-11-23 18:30:45 &amp;lt; callahan&amp;gt; nah, make checkasm from the x264 directory&lt;br /&gt;
2010-11-23 18:31:00 &amp;lt; callahan&amp;gt; also make sure you ran the configure command listed above first&lt;br /&gt;
2010-11-23 18:31:17 &amp;lt; callahan&amp;gt; ./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make checkasm&lt;br /&gt;
2010-11-23 18:31:21 &amp;lt; callahan&amp;gt; will get you the 8 bit code&lt;br /&gt;
2010-11-23 18:37:28 &amp;lt; reid_&amp;gt; Ok I got it. did that just compile the whole project?&lt;br /&gt;
2010-11-23 18:37:34 &amp;lt; irock&amp;gt; yep&lt;br /&gt;
2010-11-23 18:38:10 &amp;lt; irock&amp;gt; now you have two binaries, x264 and checkasm&lt;br /&gt;
2010-11-23 18:38:28 &amp;lt; reid_&amp;gt; This is true.&lt;br /&gt;
2010-11-23 18:38:30 &amp;lt; irock&amp;gt; if you run ./checkasm --bench the aforementioned benchmark will be created&lt;br /&gt;
2010-11-23 18:39:03 &amp;lt; irock&amp;gt; tip: pipe it to a file for review&lt;br /&gt;
2010-11-23 18:42:55 &amp;lt; reid_&amp;gt; It gave me a big long list of what I assume to be the ASM method name followed by a number representing how long it took?&lt;br /&gt;
2010-11-23 18:43:04 &amp;lt; irock&amp;gt; correct&lt;br /&gt;
2010-11-23 18:43:30 &amp;lt; irock&amp;gt; the measured number of cycles it took to be exact iirc&lt;br /&gt;
2010-11-23 18:44:01 &amp;lt; irock&amp;gt; as you can see, the mxx/sse2/ssse3/... are faster than their C equivalents&lt;br /&gt;
2010-11-23 18:45:15 &amp;lt; irock&amp;gt; now, if you run `make clean &amp;amp;&amp;amp; ./configure --bit-depth=10 &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make checkasm` you end up with two new binaries&lt;br /&gt;
2010-11-23 18:46:51 &amp;lt; reid_&amp;gt; Ok it&#039;s running.&lt;br /&gt;
2010-11-23 18:47:17 &amp;lt; reid_&amp;gt; So what are you looking for to consider the task completed?&lt;br /&gt;
2010-11-23 18:48:24 &amp;lt; irock&amp;gt; if you compare the output from 8-bit (first run) checkasm and the output of 10-bit (second run) checkasm you&#039;ll see that there are missing some functions in 10-bit mode&lt;br /&gt;
2010-11-23 18:48:49 &amp;lt; irock&amp;gt; quite a lot of asm optimized functions actually&lt;br /&gt;
2010-11-23 18:49:24 &amp;lt; irock&amp;gt; so what we&#039;re looking for is you creating one function that doesn&#039;t exist yet for 10-bit&lt;br /&gt;
2010-11-23 18:50:00 &amp;lt; irock&amp;gt; OR rewrite an existing one for either 8-bit or 10-bit to make it faster&lt;br /&gt;
2010-11-23 18:50:00 &amp;lt; reid_&amp;gt; A method that exists in c but not in asm, for 10 bet mode?&lt;br /&gt;
2010-11-23 18:50:06 &amp;lt; irock&amp;gt; yes&lt;br /&gt;
2010-11-23 18:51:30 &amp;lt; irock&amp;gt; but, rewriting a 8-bit asm function is probably very hard, 10-bit version maybe not so (I wrote that, and I started learning asm in july)&lt;br /&gt;
2010-11-23 18:52:13 &amp;lt; reid_&amp;gt; So once I complete my method do I upload the source file containing the method I added/optimized and tell you which one it is?&lt;br /&gt;
2010-11-23 18:52:56 &amp;lt; irock&amp;gt; well, I think we could help you get started if you choose one and let us know to begin with&lt;br /&gt;
2010-11-23 18:54:12 &amp;lt; irock&amp;gt; however, I suggest that you wait an hour or two for Dark_Shikari to wake up. he&#039;ll teach you the basics of x264 asm&lt;br /&gt;
2010-11-23 18:54:55 &amp;lt; reid_&amp;gt; Ok I&#039;ll monitor the channel.&lt;br /&gt;
2010-11-23 18:56:04 &amp;lt; reid_&amp;gt; I just requested the task, thanks for all the help guys.&lt;br /&gt;
2010-11-23 19:03:16 &amp;lt; lnandor&amp;gt; hello everyone!&lt;br /&gt;
2010-11-23 19:45:44 &amp;lt; rfw&amp;gt; i think i&#039;m done&lt;br /&gt;
2010-11-23 19:45:47 &amp;lt; rfw&amp;gt; who do i give this to&lt;br /&gt;
2010-11-23 19:49:00 &amp;lt; reid_&amp;gt; Is anyone from VideoLAN on here?&lt;br /&gt;
2010-11-23 19:50:19 &amp;lt; BugMaster&amp;gt; reid_: try ping j-b&lt;br /&gt;
2010-11-23 19:50:49 &amp;lt; dj_tjerk&amp;gt; pastebin for review?&lt;br /&gt;
2010-11-23 19:50:58 &amp;lt; reid_&amp;gt; ping j-b&lt;br /&gt;
2010-11-23 19:51:46 &amp;lt; reid_&amp;gt; Who is in charge of accepting a claim request?&lt;br /&gt;
2010-11-23 19:52:06 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari as far as i&#039;m aware&lt;br /&gt;
2010-11-23 19:52:17 &amp;lt; reid_&amp;gt; Is he up yet?&lt;br /&gt;
2010-11-23 19:54:22 &amp;lt; reid_&amp;gt; Jumpyshoes, are you part of the videoLAN team?&lt;br /&gt;
2010-11-23 19:54:25 &amp;lt; nattofriends&amp;gt; does Dark_Shikari sleep?&lt;br /&gt;
2010-11-23 19:54:35 &amp;lt; Jumpyshoes&amp;gt; reid_: no&lt;br /&gt;
2010-11-23 19:55:00 &amp;lt; rfw&amp;gt; sure is GCI in here&lt;br /&gt;
2010-11-23 19:55:30 &amp;lt; Jumpyshoes&amp;gt; i actually need to talk to Dark_Shikari myself&lt;br /&gt;
2010-11-23 19:55:34 &amp;lt; reid_&amp;gt; I think it&#039;s pretty much only GCI in here.&lt;br /&gt;
2010-11-23 19:55:34 &amp;lt; Jumpyshoes&amp;gt; since i&#039;m failing at this asm thing&lt;br /&gt;
2010-11-23 19:55:40 &amp;lt; rfw&amp;gt; &amp;lt;-- GCI&lt;br /&gt;
2010-11-23 19:55:43 &amp;lt; rfw&amp;gt; so is Jumpyshoes&lt;br /&gt;
2010-11-23 19:55:44 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-23 19:55:58 &amp;lt; reid_&amp;gt; jumpyshoes, yea me too.&lt;br /&gt;
2010-11-23 19:56:09 &amp;lt; mferrell&amp;gt; are you guys doing the code-in thing?&lt;br /&gt;
2010-11-23 19:56:13 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 19:56:37 &amp;lt; reid_&amp;gt; Jumpyshoes, are you writing the 10 bit asm functions?&lt;br /&gt;
2010-11-23 19:56:47 &amp;lt; Jumpyshoes&amp;gt; yes&lt;br /&gt;
2010-11-23 19:56:49 &amp;lt; Jumpyshoes&amp;gt; i&#039;ve gotten a few macros down&lt;br /&gt;
2010-11-23 19:56:58 &amp;lt; rfw&amp;gt; this makes me glad i didn&#039;t choose to do the ASM thing&lt;br /&gt;
2010-11-23 19:57:20 &amp;lt; Jumpyshoes&amp;gt; it&#039;s fucking with my mind&lt;br /&gt;
2010-11-23 19:57:42 &amp;lt; reid_&amp;gt; I havent found any that are written only in c and not asm.&lt;br /&gt;
2010-11-23 19:58:12 &amp;lt; irock&amp;gt; Jumpyshoes: what function are you working on?&lt;br /&gt;
2010-11-23 19:58:31 &amp;lt; Jumpyshoes&amp;gt; add4x4_idct or w/e&lt;br /&gt;
2010-11-23 19:58:41 &amp;lt; Jumpyshoes&amp;gt; add4x4_idct, yea&lt;br /&gt;
2010-11-23 19:58:51 &amp;lt; Jumpyshoes&amp;gt; which comes along with 15 different macros&lt;br /&gt;
2010-11-23 19:59:03 &amp;lt; reid_&amp;gt; where are you looking?&lt;br /&gt;
2010-11-23 19:59:18 &amp;lt; Jumpyshoes&amp;gt; what do you mean by that?&lt;br /&gt;
2010-11-23 19:59:43 &amp;lt; reid_&amp;gt; are you using checkasm?&lt;br /&gt;
2010-11-23 20:00:00 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 20:00:33 &amp;lt; irock&amp;gt; Jumpyshoes: do you have a paste of your current work?&lt;br /&gt;
2010-11-23 20:00:49 &amp;lt; reid_&amp;gt; are you looking through the list it dumps out?&lt;br /&gt;
2010-11-23 20:00:56 &amp;lt; Jumpyshoes&amp;gt; my current work spans across about 5 files, but i have the current ASM function i&#039;m working on&lt;br /&gt;
2010-11-23 20:01:07 &amp;lt; Jumpyshoes&amp;gt; i can also point out what the problem is (probably)&lt;br /&gt;
2010-11-23 20:01:26 &amp;lt; irock&amp;gt; Jumpyshoes: or run git diff&lt;br /&gt;
2010-11-23 20:01:43 &amp;lt; Jumpyshoes&amp;gt; currently, the code is a mess though, since i&#039;ve been mucking around with it&lt;br /&gt;
2010-11-23 20:01:54 &amp;lt; irock&amp;gt; ok, I remember that :) np&lt;br /&gt;
2010-11-23 20:02:14 &amp;lt; Jumpyshoes&amp;gt; hrm?&lt;br /&gt;
2010-11-23 20:02:54 &amp;lt; irock&amp;gt; I remember how it was when I wrote my first asm this summer&lt;br /&gt;
2010-11-23 20:03:10 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 20:03:14 &amp;lt; Jumpyshoes&amp;gt; it&#039;s terrible&lt;br /&gt;
2010-11-23 20:03:32 &amp;lt; Jumpyshoes&amp;gt; i&#039;m not actually sure what something in the original function is doing&lt;br /&gt;
2010-11-23 20:03:39 &amp;lt; Jumpyshoes&amp;gt; so i was planning on asking someone about it&lt;br /&gt;
2010-11-23 20:03:44 &amp;lt; irock&amp;gt; good idea&lt;br /&gt;
2010-11-23 20:06:25 &amp;lt; irock&amp;gt; well, start asking is good to begin with&lt;br /&gt;
2010-11-23 20:06:45 &amp;lt; Jumpyshoes&amp;gt; i was planning on waiting till D_S got back&lt;br /&gt;
2010-11-23 20:07:21 &amp;lt; irock&amp;gt; alright&lt;br /&gt;
2010-11-23 20:07:24 &amp;lt; Jumpyshoes&amp;gt; unless you feel like helping me&lt;br /&gt;
2010-11-23 20:07:53 &amp;lt; rfw&amp;gt; Jumpyshoes: what&#039;s your task rated&lt;br /&gt;
2010-11-23 20:08:06 &amp;lt; Jumpyshoes&amp;gt; not sure, whatever the code a function in assembly is&lt;br /&gt;
2010-11-23 20:08:15 &amp;lt; irock&amp;gt; Jumpyshoes: I might be able to help, but I need a question first&lt;br /&gt;
2010-11-23 20:08:21 &amp;lt; Jumpyshoes&amp;gt; google&#039;s awesome open source tool to list projects crashes my browser, so i can&#039;t tell&lt;br /&gt;
2010-11-23 20:08:22 &amp;lt; rfw&amp;gt; i would check but the list tasks page takes fucking forever to load&lt;br /&gt;
2010-11-23 20:08:27 &amp;lt; rfw&amp;gt; haha&lt;br /&gt;
2010-11-23 20:08:30 &amp;lt; reid_&amp;gt; dificult&lt;br /&gt;
2010-11-23 20:08:34 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-23 20:08:44 &amp;lt; kierank&amp;gt; yes melange is completely useless&lt;br /&gt;
2010-11-23 20:08:50 &amp;lt; reid_&amp;gt; yes they list crashes all my browsers.&lt;br /&gt;
2010-11-23 20:08:58 &amp;lt; irock&amp;gt; yep, the lists particularly&lt;br /&gt;
2010-11-23 20:08:59 &amp;lt; Jumpyshoes&amp;gt; irock: http://pastebin.com/jyhm0z4w reid_&lt;br /&gt;
2010-11-23 20:09:04 &amp;lt; Jumpyshoes&amp;gt; oops, fail tab completion&lt;br /&gt;
2010-11-23 20:09:13 &amp;lt; rfw&amp;gt; i think i&#039;m going to go for plone next&lt;br /&gt;
2010-11-23 20:09:18 &amp;lt; Jumpyshoes&amp;gt; FDEC_STRIDE = 32&lt;br /&gt;
2010-11-23 20:09:27 &amp;lt; Jumpyshoes&amp;gt; i don&#039;t understand what the STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE] is doing&lt;br /&gt;
2010-11-23 20:09:30 &amp;lt; Jumpyshoes&amp;gt; (etc.)&lt;br /&gt;
2010-11-23 20:09:35 &amp;lt; Jumpyshoes&amp;gt; since it&#039;s moving up by 32 each time&lt;br /&gt;
2010-11-23 20:09:54 &amp;lt; Jumpyshoes&amp;gt; and that&#039;s a lot of bytes&lt;br /&gt;
2010-11-23 20:11:53 &amp;lt; irock&amp;gt; actually you need to double FDEC_STRIDE for high depth&lt;br /&gt;
2010-11-23 20:12:18 &amp;lt; irock&amp;gt; check sub4x4_dct_mmx e.g&lt;br /&gt;
2010-11-23 20:12:25 &amp;lt; Jumpyshoes&amp;gt; yea, but that&#039;s secondary&lt;br /&gt;
2010-11-23 20:13:06 &amp;lt; reid_&amp;gt; Jumpyshoes: has you request been accepted yet?&lt;br /&gt;
2010-11-23 20:13:07 &amp;lt; Jumpyshoes&amp;gt; doesn&#039;t that go beyond a 4x4 array of bytes&lt;br /&gt;
2010-11-23 20:13:19 &amp;lt; Jumpyshoes&amp;gt; reid_: nope&lt;br /&gt;
2010-11-23 20:13:42 &amp;lt; Jumpyshoes&amp;gt; i mean, i didn&#039;t file for one&lt;br /&gt;
2010-11-23 20:13:44 &amp;lt; Jumpyshoes&amp;gt; but D_S knows&lt;br /&gt;
2010-11-23 20:14:19 &amp;lt; irock&amp;gt; well, it&#039;s not a 4x4 array of bytes in high depth, it&#039;s an 4x4 array of uint16_t.&lt;br /&gt;
2010-11-23 20:14:32 &amp;lt; Jumpyshoes&amp;gt; i mean, i&#039;m just talking about 8 bit for now&lt;br /&gt;
2010-11-23 20:14:46 &amp;lt; irock&amp;gt; ah, ok&lt;br /&gt;
2010-11-23 20:15:02 &amp;lt; Jumpyshoes&amp;gt; doesn&#039;t 32 go over the 1x4 row?&lt;br /&gt;
2010-11-23 20:15:36 &amp;lt; rfw&amp;gt; oh god&lt;br /&gt;
2010-11-23 20:15:39 &amp;lt; rfw&amp;gt; melange is broken&lt;br /&gt;
2010-11-23 20:15:43 &amp;lt; rfw&amp;gt; Time to complete:	 6 mins&lt;br /&gt;
2010-11-23 20:15:54 &amp;lt; rfw&amp;gt; I HAVE 6 MINUTES TO COMPLETE THIS 7 DAY TASK I STARTED YESTERDAY&lt;br /&gt;
2010-11-23 20:15:59 &amp;lt; Jumpyshoes&amp;gt; LOL&lt;br /&gt;
2010-11-23 20:16:12 &amp;lt; rfw&amp;gt; Time to complete:	 59 mins&lt;br /&gt;
2010-11-23 20:16:16 &amp;lt; rfw&amp;gt; slightly better!&lt;br /&gt;
2010-11-23 20:16:20 &amp;lt; reid_&amp;gt; to be fair, melange never really worked to begin with.&lt;br /&gt;
2010-11-23 20:16:28 &amp;lt; Jumpyshoes&amp;gt; interesting how they use crappy open source software to promote open source&lt;br /&gt;
2010-11-23 20:17:32 &amp;lt; rfw&amp;gt; i think i should join #melange&lt;br /&gt;
2010-11-23 20:17:37 &amp;lt; irock&amp;gt; Jumpyshoes: take a look at the C code&lt;br /&gt;
2010-11-23 20:17:41 &amp;lt; rfw&amp;gt; and ask why the fuck i have 58 minutes left&lt;br /&gt;
2010-11-23 20:17:50 &amp;lt; reid_&amp;gt; rf&lt;br /&gt;
2010-11-23 20:18:00 &amp;lt; Jumpyshoes&amp;gt; yea, what about it?&lt;br /&gt;
2010-11-23 20:18:04 &amp;lt; irock&amp;gt; we&#039;re writing 4 pixels first, then we add the stride, write 4 more pixels, and so on&lt;br /&gt;
2010-11-23 20:18:33 &amp;lt; Jumpyshoes&amp;gt; OH MY GOD&lt;br /&gt;
2010-11-23 20:18:37 &amp;lt; BugMaster&amp;gt; Dark_Shikari: http://privatepaste.com/8b80558011&lt;br /&gt;
2010-11-23 20:18:37 &amp;lt; BugMaster&amp;gt; For information. It fix non critical difference between gcc 4.4.5 and gcc 4.5.2, which was due different processing of division by zero (early termination doesn&#039;t work in gcc 4.5.2 with division by zero).&lt;br /&gt;
2010-11-23 20:18:37 &amp;lt; BugMaster&amp;gt; Removed one weight_cache which was really needed only due the absent of luma weights initialization (which can be set in lookahead)&lt;br /&gt;
2010-11-23 20:18:40 &amp;lt; Jumpyshoes&amp;gt; i&#039;ve had this file open for AGES&lt;br /&gt;
2010-11-23 20:18:49 &amp;lt; Jumpyshoes&amp;gt; and i haven&#039;t noticed that&lt;br /&gt;
2010-11-23 20:18:51 &amp;lt; Jumpyshoes&amp;gt; thank you irock&lt;br /&gt;
2010-11-23 20:19:13 &amp;lt; irock&amp;gt; Jumpyshoes: just ask :)&lt;br /&gt;
2010-11-23 20:19:15 &amp;lt; tjoener&amp;gt; Jumpyshoes: Microsoft used Windows to promote themselves&lt;br /&gt;
2010-11-23 20:19:26 &amp;lt; tjoener&amp;gt; just use crappy software and youre rich :)&lt;br /&gt;
2010-11-23 20:19:46 &amp;lt; Jumpyshoes&amp;gt; i&#039;m on windows 7 and i like it&lt;br /&gt;
2010-11-23 20:19:52 &amp;lt; Jumpyshoes&amp;gt; DON&#039;T BE HATIN&#039;&lt;br /&gt;
2010-11-23 20:19:55  * JEEBsv high-fives BugMaster &lt;br /&gt;
2010-11-23 20:20:02 &amp;lt; tjoener&amp;gt; Ive got win7too&lt;br /&gt;
2010-11-23 20:20:03 &amp;lt; rfw&amp;gt; Jumpyshoes: me too, but not the liking part&lt;br /&gt;
2010-11-23 20:20:05 &amp;lt; JEEBsv&amp;gt; great, so I guess that problem is mostly behind us the?&lt;br /&gt;
2010-11-23 20:20:06 &amp;lt; JEEBsv&amp;gt; *then&lt;br /&gt;
2010-11-23 20:20:14 &amp;lt; tjoener&amp;gt; I meant in the old days&lt;br /&gt;
2010-11-23 20:20:56 &amp;lt; reid_&amp;gt; can we port c methods from 8bit to 10 bit or do they have to be the asm ones?&lt;br /&gt;
2010-11-23 20:21:08 &amp;lt; Jumpyshoes&amp;gt; ask Dark_Shikari&lt;br /&gt;
2010-11-23 20:21:21 &amp;lt; irock&amp;gt; reid_: the C functions are already working for high depth (10-bit)&lt;br /&gt;
2010-11-23 20:21:24 &amp;lt; reid_&amp;gt; where is he?&lt;br /&gt;
2010-11-23 20:21:32 &amp;lt; reid_&amp;gt; is he still sleeping!&lt;br /&gt;
2010-11-23 20:21:35 &amp;lt; Jumpyshoes&amp;gt; he&#039;s probably sleeping or something&lt;br /&gt;
2010-11-23 20:21:42 &amp;lt; tjoener&amp;gt; sleeping?&lt;br /&gt;
2010-11-23 20:21:49 &amp;lt; tjoener&amp;gt; DS does not need sleep!&lt;br /&gt;
2010-11-23 20:21:53 &amp;lt; tjoener&amp;gt; He&#039;s undead&lt;br /&gt;
2010-11-23 20:21:55 &amp;lt; Jumpyshoes&amp;gt; no clue, out with hot girls or something else&lt;br /&gt;
2010-11-23 20:21:55 &amp;lt; tjoener&amp;gt; or immortal&lt;br /&gt;
2010-11-23 20:21:57 &amp;lt; tjoener&amp;gt; or whatever&lt;br /&gt;
2010-11-23 20:22:09 &amp;lt; tjoener&amp;gt; now THAT would be the only reason to get away :)&lt;br /&gt;
2010-11-23 20:22:32 &amp;lt; irock&amp;gt; reid_: if you can&#039;t wait for a live tutorial, you can check the logs a few days back&lt;br /&gt;
2010-11-23 20:22:48 &amp;lt; Jumpyshoes&amp;gt; oh yea, D_S gave me a crash course on asm&lt;br /&gt;
2010-11-23 20:22:49 &amp;lt; irock&amp;gt; I think Jumpyshoes and someone more has done the tutorial quite recently&lt;br /&gt;
2010-11-23 20:23:02 &amp;lt; irock&amp;gt; check topic for the logs&lt;br /&gt;
2010-11-23 20:23:32 &amp;lt; reid_&amp;gt; irock: the c functions are not showing up on checkasm&lt;br /&gt;
2010-11-23 20:23:46 &amp;lt; reid_&amp;gt; at least not all of them.&lt;br /&gt;
2010-11-23 20:23:51 &amp;lt; irock&amp;gt; reid_: they are only showing up if there&#039;s an asm equivalent&lt;br /&gt;
2010-11-23 20:23:55 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 20:24:03 &amp;lt; reid_&amp;gt; oh&lt;br /&gt;
2010-11-23 20:25:57 &amp;lt; reid_&amp;gt; is there an easy way to tell where the function are located?&lt;br /&gt;
2010-11-23 20:26:21 &amp;lt; irock&amp;gt; ~all x86 asm functions are located in common/x86&lt;br /&gt;
2010-11-23 20:26:58 &amp;lt; irock&amp;gt; sometimes it&#039;s quite easy to guess from the name, otherwise you could ask or grep&lt;br /&gt;
2010-11-23 20:27:11 &amp;lt; reid_&amp;gt; I know, I was wondering if there was a way so i dont have to go hunting for them.&lt;br /&gt;
2010-11-23 20:27:30 &amp;lt; reid_&amp;gt; I&#039;m about to write a java app to do it for me.&lt;br /&gt;
2010-11-23 20:28:05 &amp;lt; irock&amp;gt; that&#039;s overkill&lt;br /&gt;
2010-11-23 20:28:37 &amp;lt; reid_&amp;gt; yea, bit it will take my mind off of asm.&lt;br /&gt;
2010-11-23 20:29:50 &amp;lt; kierank&amp;gt; ctags?&lt;br /&gt;
2010-11-23 20:30:36 &amp;lt; Gramner&amp;gt; &amp;gt;java&lt;br /&gt;
2010-11-23 20:30:41 &amp;lt; Gramner&amp;gt; blasphemy&lt;br /&gt;
2010-11-23 20:32:06 &amp;lt; Dark_Shikari&amp;gt; reid_: /me is now here&lt;br /&gt;
2010-11-23 20:33:06 &amp;lt; Dark_Shikari&amp;gt; rfw: keep in mind that if melange sucks and randomly steals all your time, I&#039;m happy to re-issue the tasks.&lt;br /&gt;
2010-11-23 20:33:13 &amp;lt; rfw&amp;gt; :D&lt;br /&gt;
2010-11-23 20:33:24 &amp;lt; rfw&amp;gt; apparently they know about it, though&lt;br /&gt;
2010-11-23 20:33:44 &amp;lt; Dark_Shikari&amp;gt; BugMaster: applied&lt;br /&gt;
2010-11-23 20:34:09 &amp;lt; rfw&amp;gt; Dark_Shikari: so do i have to wait for pengvado to look at my script?&lt;br /&gt;
2010-11-23 20:34:19 &amp;lt; Dark_Shikari&amp;gt; When you think you&#039;re done, post a git format-patch.&lt;br /&gt;
2010-11-23 20:34:32 &amp;lt; Dark_Shikari&amp;gt; And then the other devs here can try it out!&lt;br /&gt;
2010-11-23 20:34:44 &amp;lt; rfw&amp;gt; put it in extra?&lt;br /&gt;
2010-11-23 20:35:08 &amp;lt; Dark_Shikari&amp;gt; tools/&lt;br /&gt;
2010-11-23 20:35:10 &amp;lt; Dark_Shikari&amp;gt; like checkasm&lt;br /&gt;
2010-11-23 20:35:34 &amp;lt; reid_&amp;gt; are the 10 bit methods compiled when HIGH_BIT_DEPTH is defined and 8 bit methods compiled when it is not?&lt;br /&gt;
2010-11-23 20:35:48 &amp;lt; Dark_Shikari&amp;gt; Yup&lt;br /&gt;
2010-11-23 20:36:01 &amp;lt; Dark_Shikari&amp;gt; The primary difference between 8-bit and 10-bit, for the asm:&lt;br /&gt;
2010-11-23 20:36:03 &amp;lt; Dark_Shikari&amp;gt; for 8-bit&lt;br /&gt;
2010-11-23 20:36:13 &amp;lt; Dark_Shikari&amp;gt; pixels are uint8_t, and dct coeffs are int16_t&lt;br /&gt;
2010-11-23 20:36:15 &amp;lt; Dark_Shikari&amp;gt; for 10-bit&lt;br /&gt;
2010-11-23 20:36:21 &amp;lt; Dark_Shikari&amp;gt; pixels are uint16_t, and dct coeffs are int32_t&lt;br /&gt;
2010-11-23 20:36:27 &amp;lt; Dark_Shikari&amp;gt; (of course, the pixels can&#039;t exceed 1023 in that case)&lt;br /&gt;
2010-11-23 20:36:51 &amp;lt; Dark_Shikari&amp;gt; Some functions may need more internal precision than they did with 8-bit.&lt;br /&gt;
2010-11-23 20:36:53 &amp;lt; Dark_Shikari&amp;gt; Others might not.&lt;br /&gt;
2010-11-23 20:37:01 &amp;lt; JEEBsv&amp;gt; rfw: what kind of a script did you do?&lt;br /&gt;
2010-11-23 20:37:18 &amp;lt; Dark_Shikari&amp;gt; regression tester&lt;br /&gt;
2010-11-23 20:37:20 &amp;lt; Dark_Shikari&amp;gt; that does magic&lt;br /&gt;
2010-11-23 20:37:25 &amp;lt; reid_&amp;gt; So All I have to do is change the data types and make sure nothing overflows and what not?&lt;br /&gt;
2010-11-23 20:38:31 &amp;lt; Dark_Shikari&amp;gt; of course, this involves writing new asm&lt;br /&gt;
2010-11-23 20:38:37 &amp;lt; rfw&amp;gt; JEEBsv: python&lt;br /&gt;
2010-11-23 20:38:39 &amp;lt; Dark_Shikari&amp;gt; you can&#039;t just &amp;quot;&lt;br /&gt;
2010-11-23 20:38:44 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;change the data types&amp;quot; -- at least not usually&lt;br /&gt;
2010-11-23 20:38:47 &amp;lt; Dark_Shikari&amp;gt; of course, sometimes you can&lt;br /&gt;
2010-11-23 20:38:48 &amp;lt; rfw&amp;gt; JEEBsv: a whole pile of python... :V&lt;br /&gt;
2010-11-23 20:39:01 &amp;lt; Dark_Shikari&amp;gt; for example, in Jumpyshoes&#039; case, he found a function that could be converted from MMX 8-bit to SSE 10-bit with almost no changes&lt;br /&gt;
2010-11-23 20:39:09 &amp;lt; Dark_Shikari&amp;gt; as in MMX 8-bit, it worked on 4x16-bit values&lt;br /&gt;
2010-11-23 20:39:09 &amp;lt; JEEBsv&amp;gt; rfw: I&#039;ll be looking forward to it&lt;br /&gt;
2010-11-23 20:39:15 &amp;lt; Dark_Shikari&amp;gt; and in SSE 10-bit, it&#039;ll work on 4x32-bit values&lt;br /&gt;
2010-11-23 20:39:26 &amp;lt; rfw&amp;gt; JEEBsv: that sounds ominous&lt;br /&gt;
2010-11-23 20:39:26 &amp;lt; Dark_Shikari&amp;gt; so the basic structure stayed identical&lt;br /&gt;
2010-11-23 20:40:11 &amp;lt; Jumpyshoes&amp;gt; except i&#039;m failing at life&lt;br /&gt;
2010-11-23 20:40:35 &amp;lt; reid_&amp;gt; what are dct&#039;s?&lt;br /&gt;
2010-11-23 20:40:37 &amp;lt; Dark_Shikari&amp;gt; s/failing at life/not asking questions and posting your code/&lt;br /&gt;
2010-11-23 20:40:44 &amp;lt; Jumpyshoes&amp;gt; well&lt;br /&gt;
2010-11-23 20:40:49 &amp;lt; Jumpyshoes&amp;gt; i need to go in 10 minutes&lt;br /&gt;
2010-11-23 20:40:53 &amp;lt; Jumpyshoes&amp;gt; school being over and all&lt;br /&gt;
2010-11-23 20:40:59 &amp;lt; Jumpyshoes&amp;gt; so i will be doing that when i get back home&lt;br /&gt;
2010-11-23 20:41:02 &amp;lt; Dark_Shikari&amp;gt;  ok =p&lt;br /&gt;
2010-11-23 20:41:13 &amp;lt; Dark_Shikari&amp;gt; reid_: a DCT is a discrete cosine transform.  You don&#039;t have to understand how/why it works, just that there&#039;s nice pretty C code for it in common/dct.c&lt;br /&gt;
2010-11-23 20:41:53 &amp;lt; reid_&amp;gt; so all I have to worry about is pixel depth?&lt;br /&gt;
2010-11-23 20:42:38 &amp;lt; Dark_Shikari&amp;gt; and all consequences thereof&lt;br /&gt;
2010-11-23 20:42:45 &amp;lt; Dark_Shikari&amp;gt; and learning to write asm in x264&lt;br /&gt;
2010-11-23 20:43:19 &amp;lt; reid_&amp;gt; what is x264? what architecture is that?&lt;br /&gt;
2010-11-23 20:43:31 &amp;lt; Dark_Shikari&amp;gt; x264 is the program you&#039;re planning to work on&lt;br /&gt;
2010-11-23 20:43:47 &amp;lt; Dark_Shikari&amp;gt; the architectures to pick from are x86 (MMX/SSE), PPC (Altivec), and ARM (NEON)&lt;br /&gt;
2010-11-23 20:44:53 &amp;lt; rfw&amp;gt; fuck&lt;br /&gt;
2010-11-23 20:44:54 &amp;lt; rfw&amp;gt; fuuuuuuuuck&lt;br /&gt;
2010-11-23 20:45:02 &amp;lt; reid_&amp;gt; all I see is MMX/SSE&lt;br /&gt;
2010-11-23 20:45:08 &amp;lt; Dark_Shikari&amp;gt; NEON would be in common/arm&lt;br /&gt;
2010-11-23 20:45:10 &amp;lt; rfw&amp;gt; i just deleted&lt;br /&gt;
2010-11-23 20:45:12 &amp;lt; rfw&amp;gt; fuuuuuuuuck&lt;br /&gt;
2010-11-23 20:45:13 &amp;lt; Dark_Shikari&amp;gt; altivec would be in common/ppc&lt;br /&gt;
2010-11-23 20:45:18 &amp;lt; Jumpyshoes&amp;gt; reid_: change directory!&lt;br /&gt;
2010-11-23 20:45:22 &amp;lt; Dark_Shikari&amp;gt; rfw: stop.  stop right now.&lt;br /&gt;
2010-11-23 20:45:25 &amp;lt; Dark_Shikari&amp;gt; don&#039;t do anything else&lt;br /&gt;
2010-11-23 20:45:28 &amp;lt; rfw&amp;gt; too late&lt;br /&gt;
2010-11-23 20:45:31 &amp;lt; Dark_Shikari&amp;gt; Go get a data recovery tool&lt;br /&gt;
2010-11-23 20:45:34 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 20:45:55 &amp;lt; irock&amp;gt; rfw: what file system are you using?&lt;br /&gt;
2010-11-23 20:45:57 &amp;lt; rfw&amp;gt; ntfs&lt;br /&gt;
2010-11-23 20:46:00 &amp;lt; Dark_Shikari&amp;gt; By the way, this is why you POST YOUR SHIT&lt;br /&gt;
2010-11-23 20:46:10 &amp;lt; irock&amp;gt; ah, then it&#039;s probably np&lt;br /&gt;
2010-11-23 20:46:15 &amp;lt; rfw&amp;gt; okay, i have testdisk&lt;br /&gt;
2010-11-23 20:46:17 &amp;lt; Dark_Shikari&amp;gt; Do not write to any other files&lt;br /&gt;
2010-11-23 20:46:24 &amp;lt; reid_&amp;gt; i&#039;m in the root.&lt;br /&gt;
2010-11-23 20:46:35 &amp;lt; Jumpyshoes&amp;gt; okay going home&lt;br /&gt;
2010-11-23 20:46:40 &amp;lt; Jumpyshoes&amp;gt; i shall bug you with questions later&lt;br /&gt;
2010-11-23 20:46:54 &amp;lt; reid_&amp;gt; but it doesn&#039;t matter i&#039;m only working on x86&lt;br /&gt;
2010-11-23 20:47:02 &amp;lt; Dark_Shikari&amp;gt; rfw: http://www.officerecovery.com/index.htm#freeundelete&lt;br /&gt;
2010-11-23 20:47:27 &amp;lt; Dark_Shikari&amp;gt; This fact also dictates the following procedure for using FreeUndelete:&lt;br /&gt;
2010-11-23 20:47:27 &amp;lt; Dark_Shikari&amp;gt;    1. Stop any activity on the disk you are going to undelete files from! Remember that writing to that disk can damage the contents of the deleted files. Examples of disastrous activity include: copying files to the disk, installing programs there or running programs that use the disk as their swap media.&lt;br /&gt;
2010-11-23 20:47:32 &amp;lt; Dark_Shikari&amp;gt;    2. Download and install FreeUndelete. Whenever possible, save the setup executable and install the program to a disk that does not hold files you need to undelete.&lt;br /&gt;
2010-11-23 20:47:36 &amp;lt; Dark_Shikari&amp;gt;    3. Run and use FreeUndelete.&lt;br /&gt;
2010-11-23 20:47:36 &amp;lt; Dark_Shikari&amp;gt; I&#039;ve used it before.&lt;br /&gt;
2010-11-23 20:47:47 &amp;lt; Dark_Shikari&amp;gt; Now go grab a flash drive, stick it in, install freeundelete on it, and get your files back&lt;br /&gt;
2010-11-23 20:47:50 &amp;lt; Dark_Shikari&amp;gt; and next time, learn to post your shit.&lt;br /&gt;
2010-11-23 20:47:53 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 20:47:59 &amp;lt; Dark_Shikari&amp;gt; because stuff on the internet can&#039;t be deleted.&lt;br /&gt;
2010-11-23 20:48:00 &amp;lt; rfw&amp;gt; i&#039;m so silly&lt;br /&gt;
2010-11-23 20:48:14 &amp;lt; irock&amp;gt; (or learn to do regular backups)&lt;br /&gt;
2010-11-23 20:48:22 &amp;lt; JEEBsv&amp;gt; A true (9) you are, aren&#039;t you rfw :3&lt;br /&gt;
2010-11-23 20:48:36 &amp;lt; rfw&amp;gt; 天才&lt;br /&gt;
2010-11-23 20:48:45 &amp;lt; Dark_Shikari&amp;gt; Or just use a revision control system&lt;br /&gt;
2010-11-23 20:48:46 &amp;lt; Dark_Shikari&amp;gt; like git&lt;br /&gt;
2010-11-23 20:48:48 &amp;lt; Dark_Shikari&amp;gt; which saves your shit&lt;br /&gt;
2010-11-23 20:48:50 &amp;lt; JEEBsv&amp;gt; yeah&lt;br /&gt;
2010-11-23 20:48:52 &amp;lt; reid_&amp;gt; who backs up hourly?&lt;br /&gt;
2010-11-23 20:48:57 &amp;lt; Dark_Shikari&amp;gt; Someone who uses git&lt;br /&gt;
2010-11-23 20:48:58 &amp;lt; rfw&amp;gt; i did but&lt;br /&gt;
2010-11-23 20:49:01 &amp;lt; irock&amp;gt; reid_: I do&lt;br /&gt;
2010-11-23 20:49:06 &amp;lt; JEEBsv&amp;gt; you rm -rf&#039;d the whole folder?&lt;br /&gt;
2010-11-23 20:49:08 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 20:49:09 &amp;lt; rfw&amp;gt; &amp;gt;_&amp;gt;&lt;br /&gt;
2010-11-23 20:49:14 &amp;lt; rfw&amp;gt; need to learn to look&lt;br /&gt;
2010-11-23 20:49:15 &amp;lt; rfw&amp;gt; when i type&lt;br /&gt;
2010-11-23 20:51:54 &amp;lt; rfw&amp;gt; Dark_Shikari: not there D:&lt;br /&gt;
2010-11-23 20:52:04 &amp;lt; rfw&amp;gt; it&#039;s not reading the Users folder&lt;br /&gt;
2010-11-23 20:52:12 &amp;lt; Dark_Shikari&amp;gt; I highly doubt you&#039;ve managed to run the entire program on your entire drive already.&lt;br /&gt;
2010-11-23 20:52:18 &amp;lt; Dark_Shikari&amp;gt; It is much slower than that.&lt;br /&gt;
2010-11-23 20:52:30 &amp;lt; rfw&amp;gt; i scanned C&lt;br /&gt;
2010-11-23 20:52:34 &amp;lt; rfw&amp;gt; and it finished&lt;br /&gt;
2010-11-23 20:52:45 &amp;lt; Dark_Shikari&amp;gt; Did you check stuff like the unnamed folders and files and such?&lt;br /&gt;
2010-11-23 20:52:50 &amp;lt; Dark_Shikari&amp;gt; i.e. the stuff with no metadata?&lt;br /&gt;
2010-11-23 20:52:58 &amp;lt; rfw&amp;gt; hm, where?&lt;br /&gt;
2010-11-23 20:53:02 &amp;lt; rfw&amp;gt; it only shows 3 folders&lt;br /&gt;
2010-11-23 20:53:08 &amp;lt; Dark_Shikari&amp;gt; Open them.&lt;br /&gt;
2010-11-23 20:53:11 &amp;lt; rfw&amp;gt; programdat, program files and config.msi&lt;br /&gt;
2010-11-23 20:53:40 &amp;lt; Dark_Shikari&amp;gt; Also, don&#039;t you still have your editor open?&lt;br /&gt;
2010-11-23 20:53:49 &amp;lt; rfw&amp;gt; no&lt;br /&gt;
2010-11-23 20:53:55 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 20:53:59 &amp;lt; rfw&amp;gt; i only have test_x264.py open&lt;br /&gt;
2010-11-23 20:54:26 &amp;lt; Dark_Shikari&amp;gt; well then you&#039;re good aren&#039;t you?&lt;br /&gt;
2010-11-23 20:55:15 &amp;lt; rfw&amp;gt; no&lt;br /&gt;
2010-11-23 20:55:25 &amp;lt; rfw&amp;gt; since all of digress is gone&lt;br /&gt;
2010-11-23 20:55:49 &amp;lt; Dark_Shikari&amp;gt; er... you were making a library&lt;br /&gt;
2010-11-23 20:55:51 &amp;lt; Dark_Shikari&amp;gt; and you never put it on github?&lt;br /&gt;
2010-11-23 20:56:07 &amp;lt; Dark_Shikari&amp;gt; you never copied it into the x264 directory, instead you _moved_ it?&lt;br /&gt;
2010-11-23 20:56:10 &amp;lt; Dark_Shikari&amp;gt; leaving no original?&lt;br /&gt;
2010-11-23 20:56:24 &amp;lt; Dark_Shikari&amp;gt; what kind of crack are you on?&lt;br /&gt;
2010-11-23 20:56:30 &amp;lt; rfw&amp;gt; i don&#039;t know&lt;br /&gt;
2010-11-23 20:56:32 &amp;lt; rfw&amp;gt; it&#039;s 9a,&lt;br /&gt;
2010-11-23 20:56:33 &amp;lt; rfw&amp;gt; 9am&lt;br /&gt;
2010-11-23 20:56:36 &amp;lt; rfw&amp;gt; i don&#039;t think clearly&lt;br /&gt;
2010-11-23 20:56:50 &amp;lt; Dark_Shikari&amp;gt; er... this means you&#039;ve been actively stupid for the past couple months you&#039;ve been working on this &amp;quot;digress&amp;quot; thing&lt;br /&gt;
2010-11-23 20:56:59 &amp;lt; rfw&amp;gt; er no&lt;br /&gt;
2010-11-23 20:57:03 &amp;lt; rfw&amp;gt; i just started yesterday&lt;br /&gt;
2010-11-23 20:57:08 &amp;lt; rfw&amp;gt; i wrote a library first, then the tests&lt;br /&gt;
2010-11-23 20:57:12 &amp;lt; rfw&amp;gt; as part of the whole thing&lt;br /&gt;
2010-11-23 20:57:20 &amp;lt; rfw&amp;gt; i don&#039;t write a regression testing suite for no reason, you know&lt;br /&gt;
2010-11-23 20:57:34 &amp;lt; Dark_Shikari&amp;gt; maybe you can regression-test your brain first?&lt;br /&gt;
2010-11-23 20:57:48 &amp;lt; rfw&amp;gt; i probably need to D:&lt;br /&gt;
2010-11-23 20:58:13 &amp;lt; Dark_Shikari&amp;gt; check your editor temp files or something&lt;br /&gt;
2010-11-23 20:58:18 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-23 20:58:20 &amp;lt; rfw&amp;gt; recuva works&lt;br /&gt;
2010-11-23 20:58:36 &amp;lt; JEEBsv&amp;gt; &#039;grats&lt;br /&gt;
2010-11-23 20:58:38 &amp;lt; Dark_Shikari&amp;gt; Now, once you recover this&lt;br /&gt;
2010-11-23 20:58:40 &amp;lt; Dark_Shikari&amp;gt; make a repository on github&lt;br /&gt;
2010-11-23 20:58:43 &amp;lt; Dark_Shikari&amp;gt; and commit your shit.&lt;br /&gt;
2010-11-23 20:58:52 &amp;lt; Dark_Shikari&amp;gt; and don&#039;t ever do that again.&lt;br /&gt;
2010-11-23 20:59:08 &amp;lt; rfw&amp;gt; yes sir&lt;br /&gt;
2010-11-23 20:59:13 &amp;lt; tjoener&amp;gt; yeah rfw recuva helped me out a tight spot a few times (read thesis)&lt;br /&gt;
2010-11-23 20:59:20 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 20:59:22 &amp;lt; JEEBsv&amp;gt; lol&lt;br /&gt;
2010-11-23 20:59:24 &amp;lt; Dark_Shikari&amp;gt; &amp;gt;thesis oh god&lt;br /&gt;
2010-11-23 20:59:30 &amp;lt; JEEBsv&amp;gt; it helped me get back some rare&#039;ish files&lt;br /&gt;
2010-11-23 20:59:40 &amp;lt; JEEBsv&amp;gt; although I think I wasn&#039;t using recuva then, but that other open source app&lt;br /&gt;
2010-11-23 21:00:17 &amp;lt; holger_&amp;gt; as Dark_Shikari said: that was pretty lucky. at least you got your stuff back. also note we do not accept the &amp;quot;dog ate my homework&amp;quot; excuse, so you better recover your work from the dog erm disk ;) ;)&lt;br /&gt;
2010-11-23 21:00:36 &amp;lt; Dark_Shikari&amp;gt; github ---&amp;gt; your closest friend&lt;br /&gt;
2010-11-23 21:00:38 &amp;lt; Dark_Shikari&amp;gt; or gitosis or whatever&lt;br /&gt;
2010-11-23 21:00:48 &amp;lt; rfw&amp;gt; &amp;gt;estimated time left 7 hours&lt;br /&gt;
2010-11-23 21:01:01 &amp;lt; koda&amp;gt; umh would there be any hope of having this http://forum.doom9.org/showthread.php?t=154606 included in the stable branch?&lt;br /&gt;
2010-11-23 21:01:06 &amp;lt; tjoener&amp;gt; Ive got a public git repo, if someone wants to post some code for backup I could probably arrange something easy&lt;br /&gt;
2010-11-23 21:01:23 &amp;lt; tjoener&amp;gt; a few extra ssh keys or whatnot&lt;br /&gt;
2010-11-23 21:01:34 &amp;lt; koda&amp;gt; this patch to be more precise http://pastebin.com/ErL2eAW8&lt;br /&gt;
2010-11-23 21:01:56 &amp;lt; reid_&amp;gt; how do we submit our code?&lt;br /&gt;
2010-11-23 21:02:08 &amp;lt; JEEBsv&amp;gt; git format-patch&lt;br /&gt;
2010-11-23 21:02:12 &amp;lt; Dark_Shikari&amp;gt; you make a local commit&lt;br /&gt;
2010-11-23 21:02:14 &amp;lt; Dark_Shikari&amp;gt; you use git format-patch&lt;br /&gt;
2010-11-23 21:02:17 &amp;lt; Dark_Shikari&amp;gt; and then we review it!&lt;br /&gt;
2010-11-23 21:02:20 &amp;lt; Dark_Shikari&amp;gt; You should do this obvious&lt;br /&gt;
2010-11-23 21:02:21 &amp;lt; Dark_Shikari&amp;gt; er, often&lt;br /&gt;
2010-11-23 21:02:26 &amp;lt; Dark_Shikari&amp;gt; preferably, before it&#039;s even working!&lt;br /&gt;
2010-11-23 21:02:34 &amp;lt; Dark_Shikari&amp;gt; Because when things are broken, we may be able to help you figure out what&#039;s wrong&lt;br /&gt;
2010-11-23 21:02:47 &amp;lt; Dark_Shikari&amp;gt; git format-patch -&amp;gt; pastebin&lt;br /&gt;
2010-11-23 21:02:59 &amp;lt; Dark_Shikari&amp;gt; pastebin.com, pastebin.ca, etc&lt;br /&gt;
2010-11-23 21:03:28 &amp;lt; reid_&amp;gt; im using gitg&lt;br /&gt;
2010-11-23 21:04:25 &amp;lt; rfw&amp;gt; haha yes&lt;br /&gt;
2010-11-23 21:04:28 &amp;lt; rfw&amp;gt; got them all back&lt;br /&gt;
2010-11-23 21:04:29 &amp;lt; rfw&amp;gt; now&lt;br /&gt;
2010-11-23 21:04:31 &amp;lt; rfw&amp;gt; time to not be stupid&lt;br /&gt;
2010-11-23 21:04:43 &amp;lt; JEEBsv&amp;gt; time to add, commit and push to something non-local&lt;br /&gt;
2010-11-23 21:04:51 &amp;lt; rfw&amp;gt; oh wait&lt;br /&gt;
2010-11-23 21:04:55 &amp;lt; rfw&amp;gt; &amp;gt;.pyc&lt;br /&gt;
2010-11-23 21:04:59 &amp;lt; rfw&amp;gt; &amp;gt;_&amp;gt;&lt;br /&gt;
2010-11-23 21:05:00 &amp;lt; holger_&amp;gt; and it&#039;s always a good idea to sync your work directory to another machine, locally or even remote, if you have one. on linux you could set up a cron job running rsync for that&lt;br /&gt;
2010-11-23 21:05:10 &amp;lt; rfw&amp;gt; well, that was half-helpful&lt;br /&gt;
2010-11-23 21:07:20 &amp;lt; reid_&amp;gt; you want all the source?&lt;br /&gt;
2010-11-23 21:07:44  * koda pings Dark_Shikari with http://pastebin.com/ErL2eAW8&lt;br /&gt;
2010-11-23 21:08:19 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 21:09:00 &amp;lt; kierank&amp;gt; koda: the plan is to get it into the main branch&lt;br /&gt;
2010-11-23 21:09:02 &amp;lt; kierank&amp;gt; but it needs some work&lt;br /&gt;
2010-11-23 21:09:19 &amp;lt; Dark_Shikari&amp;gt; koda: there&#039;s no way that will get into trunk in its current state&lt;br /&gt;
2010-11-23 21:09:31 &amp;lt; Dark_Shikari&amp;gt; and really IMO speedcontrol should be outside libx264&lt;br /&gt;
2010-11-23 21:09:42 &amp;lt; Dark_Shikari&amp;gt; the only justification for it being _in_ x264 is to stop people from having to implement it themselves&lt;br /&gt;
2010-11-23 21:10:03 &amp;lt; koda&amp;gt; Dark_Shikari: it&#039;s just so convenient to have it all in one tool&lt;br /&gt;
2010-11-23 21:10:05 &amp;lt; Dark_Shikari&amp;gt; rfw: you can decompile python&lt;br /&gt;
2010-11-23 21:10:11 &amp;lt; koda&amp;gt; kierank: how can i help in the process?&lt;br /&gt;
2010-11-23 21:10:17 &amp;lt; rfw&amp;gt; Dark_Shikari: not very well&lt;br /&gt;
2010-11-23 21:10:26 &amp;lt; Dark_Shikari&amp;gt; at least it&#039;s not .pyo&lt;br /&gt;
2010-11-23 21:10:44 &amp;lt; irock&amp;gt; .pyc even have comments, no?&lt;br /&gt;
2010-11-23 21:19:26 &amp;lt; tjoener&amp;gt; I&#039;m off&lt;br /&gt;
2010-11-23 21:19:27 &amp;lt; tjoener&amp;gt; taa&lt;br /&gt;
2010-11-23 21:21:41 &amp;lt; rfw&amp;gt; YES&lt;br /&gt;
2010-11-23 21:21:44 &amp;lt; rfw&amp;gt; THANK YOU UNPYC&lt;br /&gt;
2010-11-23 21:22:08 &amp;lt; reid_&amp;gt; what are you using python for?&lt;br /&gt;
2010-11-23 21:22:17 &amp;lt; rfw&amp;gt; regression testing thing&lt;br /&gt;
2010-11-23 21:23:39 &amp;lt; dj_tjerk&amp;gt; pastebin nao&lt;br /&gt;
2010-11-23 21:24:19 &amp;lt; rfw&amp;gt; oh, it failed on my more complex files&lt;br /&gt;
2010-11-23 21:24:46 &amp;lt; rfw&amp;gt; sigh&lt;br /&gt;
2010-11-23 21:24:51 &amp;lt; rfw&amp;gt; at this rate i&#039;m going to have to withdraw&lt;br /&gt;
2010-11-23 21:25:35 &amp;lt; reid_&amp;gt; seriously melange&lt;br /&gt;
2010-11-23 21:29:11 &amp;lt; checkers&amp;gt; the worst part about stupid backup stories is nobody learns from them except the protagonist&lt;br /&gt;
2010-11-23 21:31:58 &amp;lt; dj_tjerk&amp;gt; rfw &amp;gt; writing python doesn&#039;t take that much time does it?&lt;br /&gt;
2010-11-23 21:32:26 &amp;lt; checkers&amp;gt; 0/10&lt;br /&gt;
2010-11-23 21:32:27 &amp;lt; rfw&amp;gt; i suppose not but&lt;br /&gt;
2010-11-23 21:32:34 &amp;lt; rfw&amp;gt; :(&lt;br /&gt;
2010-11-23 21:33:57 &amp;lt; checkers&amp;gt; ps use dropbox&lt;br /&gt;
2010-11-23 21:34:47 &amp;lt; checkers&amp;gt; also it&#039;s probably worth trying another undelete tool&lt;br /&gt;
2010-11-23 21:35:08 &amp;lt; checkers&amp;gt; http://ntfsundelete.com/ &amp;lt;-- I generally use this one&lt;br /&gt;
2010-11-23 21:36:44 &amp;lt; rfw&amp;gt; everything just froze&lt;br /&gt;
2010-11-23 21:36:47 &amp;lt; rfw&amp;gt; argh not having a good day&lt;br /&gt;
2010-11-23 21:44:03 &amp;lt; callahan&amp;gt; Sounds like you&#039;re learning alot :)&lt;br /&gt;
2010-11-23 22:00:25 &amp;lt; doron&amp;gt; Hi, I Registered your assembly task in the Google Code In competition. Can you please confirm me and explain to me what I need to do?&lt;br /&gt;
2010-11-23 22:01:00 &amp;lt; JEEBsv&amp;gt; one thing: keep on the channel, devs will talk to you eventually&lt;br /&gt;
2010-11-23 22:01:53 &amp;lt; doron&amp;gt; ah thank&lt;br /&gt;
2010-11-23 22:02:04 &amp;lt; reid_&amp;gt; doron:  do you know assembly?&lt;br /&gt;
2010-11-23 22:02:16 &amp;lt; rfw&amp;gt; i guess i&#039;m going to have to go with plan B&lt;br /&gt;
2010-11-23 22:02:22 &amp;lt; doron&amp;gt; yes&lt;br /&gt;
2010-11-23 22:07:29 &amp;lt; Dark_Shikari&amp;gt; rfw: it took you a day&lt;br /&gt;
2010-11-23 22:07:33 &amp;lt; Dark_Shikari&amp;gt; surely couldn&#039;t take that long to rewrite parts of it =p&lt;br /&gt;
2010-11-23 22:07:42 &amp;lt; Dark_Shikari&amp;gt; doron: will get to you in a moment, busy in class atm&lt;br /&gt;
2010-11-23 22:08:00 &amp;lt; Dark_Shikari&amp;gt; in the meantime you can check the log in the topic and see above where all previous students asked the same question ;)&lt;br /&gt;
2010-11-23 22:15:22 &amp;lt; checkers&amp;gt; back at college?&lt;br /&gt;
2010-11-23 22:15:31 &amp;lt; checkers&amp;gt; I thought you had a big break over christmas?&lt;br /&gt;
2010-11-23 22:15:43 &amp;lt; Dark_Shikari&amp;gt; is it christmas yet?&lt;br /&gt;
2010-11-23 22:15:45 &amp;lt; checkers&amp;gt; oh, you have that during your summer, dont you&lt;br /&gt;
2010-11-23 22:15:57 &amp;lt; Dark_Shikari&amp;gt; no...&lt;br /&gt;
2010-11-23 22:15:59 &amp;lt; astrange&amp;gt; it&#039;s not even thanksgiving break yet&lt;br /&gt;
2010-11-23 22:16:09 &amp;lt; Dark_Shikari&amp;gt; the stores seem to think it&#039;s already christmas&lt;br /&gt;
2010-11-23 22:16:11 &amp;lt; Dark_Shikari&amp;gt; but nobody else does&lt;br /&gt;
2010-11-23 22:16:12 &amp;lt; checkers&amp;gt; uni people here got out a few weeks ago&lt;br /&gt;
2010-11-23 22:16:12 &amp;lt; astrange&amp;gt; actually i think it is at every GA school except this one&lt;br /&gt;
2010-11-23 22:16:20 &amp;lt; checkers&amp;gt; so they have a break from mid-november to march 1&lt;br /&gt;
2010-11-23 22:16:50 &amp;lt; rfw&amp;gt; Dark_Shikari: i think i might withdraw from this&lt;br /&gt;
2010-11-23 22:16:54 &amp;lt; rfw&amp;gt; i&#039;m sorry :(&lt;br /&gt;
2010-11-23 22:16:59 &amp;lt; Dark_Shikari&amp;gt; rfw: but you had such a cool script!&lt;br /&gt;
2010-11-23 22:17:03 &amp;lt; rfw&amp;gt; i know!&lt;br /&gt;
2010-11-23 22:17:08 &amp;lt; rfw&amp;gt; i can&#039;t believe how fucking stupid i am&lt;br /&gt;
2010-11-23 22:17:10 &amp;lt; Dark_Shikari&amp;gt; get a better python decompiler&lt;br /&gt;
2010-11-23 22:17:14 &amp;lt; rfw&amp;gt; i tried everything&lt;br /&gt;
2010-11-23 22:17:26 &amp;lt; Dark_Shikari&amp;gt; go put in three hours and rewrite it, it&#039;s easier when you&#039;ve done it before&lt;br /&gt;
2010-11-23 22:18:03 &amp;lt; rfw&amp;gt; time to figure out all the classes i had&lt;br /&gt;
2010-11-23 22:19:36 &amp;lt; rfw&amp;gt; or i could make it&lt;br /&gt;
2010-11-23 22:19:37 &amp;lt; rfw&amp;gt; um&lt;br /&gt;
2010-11-23 22:19:46 &amp;lt; rfw&amp;gt; better, stronger and faster&lt;br /&gt;
2010-11-23 22:19:49 &amp;lt; Dark_Shikari&amp;gt; rewriting is great, it means you can fix all the stupid things you did the first time&lt;br /&gt;
2010-11-23 22:19:52 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 22:20:01 &amp;lt; rfw&amp;gt; yeah&lt;br /&gt;
2010-11-23 22:20:06 &amp;lt; rfw&amp;gt; but that&#039;s one day wasyed&lt;br /&gt;
2010-11-23 22:20:08 &amp;lt; rfw&amp;gt; wasted&lt;br /&gt;
2010-11-23 22:20:13 &amp;lt; rfw&amp;gt; well&lt;br /&gt;
2010-11-23 22:20:15 &amp;lt; checkers&amp;gt; I believe you mean harder, better, faster, stronger&lt;br /&gt;
2010-11-23 22:20:16 &amp;lt; rfw&amp;gt; i guess i get the experience&lt;br /&gt;
2010-11-23 22:20:20 &amp;lt; Dark_Shikari&amp;gt; no it isn&#039;t, because most of the day was spent figuring out how to do things&lt;br /&gt;
2010-11-23 22:20:22 &amp;lt; Dark_Shikari&amp;gt; and what needed to be done&lt;br /&gt;
2010-11-23 22:20:24 &amp;lt; rfw&amp;gt; yup&lt;br /&gt;
2010-11-23 22:20:32 &amp;lt; Dark_Shikari&amp;gt; you&#039;re actually more than half done at this point.&lt;br /&gt;
2010-11-23 22:20:41 &amp;lt; Dark_Shikari&amp;gt; This time around, do it with git, and make commits often&lt;br /&gt;
2010-11-23 22:20:42 &amp;lt; rfw&amp;gt; checkers: are you going to throw a longer and thicker in there too&lt;br /&gt;
2010-11-23 22:21:04 &amp;lt; Dark_Shikari&amp;gt; rfw: more than after hour never&lt;br /&gt;
2010-11-23 22:21:09 &amp;lt; Dark_Shikari&amp;gt; our work is never over (oh wait)&lt;br /&gt;
2010-11-23 22:53:17 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari: http://pastebin.com/hyNZL78m here&#039;s the code that wasn&#039;t working for me&lt;br /&gt;
2010-11-23 22:54:29 &amp;lt; Jumpyshoes&amp;gt; i changed the mov to move double quadwords, transpose/idct to d, pw --&amp;gt; pd, and used the updated version of STORE_DIFF&lt;br /&gt;
2010-11-23 22:54:33 &amp;lt; Jumpyshoes&amp;gt; isn&#039;t working though&lt;br /&gt;
2010-11-23 22:55:08 &amp;lt; Dark_Shikari&amp;gt; 1) is pd_32 times 4 or times 2?&lt;br /&gt;
2010-11-23 22:55:13 &amp;lt; Dark_Shikari&amp;gt; i.e. is it 4 values or 2?  check that, it should b4&lt;br /&gt;
2010-11-23 22:55:37 &amp;lt; Jumpyshoes&amp;gt; let&#039;s see&lt;br /&gt;
2010-11-23 22:55:38 &amp;lt; Jumpyshoes&amp;gt; const pw_32,       times 8 dw 32&lt;br /&gt;
2010-11-23 22:55:41 &amp;lt; Jumpyshoes&amp;gt; const pd_32,       times 8 dd 32&lt;br /&gt;
2010-11-23 22:55:46 &amp;lt; Dark_Shikari&amp;gt; it should be times 4 unless you didn&#039;t create it&lt;br /&gt;
2010-11-23 22:55:54 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 22:55:56 &amp;lt; Jumpyshoes&amp;gt; i created it&lt;br /&gt;
2010-11-23 22:55:57 &amp;lt; Dark_Shikari&amp;gt; that won&#039;t affect it though&lt;br /&gt;
2010-11-23 22:56:00 &amp;lt; Dark_Shikari&amp;gt; 8 is obviously enough&lt;br /&gt;
2010-11-23 22:56:06 &amp;lt; Dark_Shikari&amp;gt; where&#039;s your updated store_diff, how about posting the whole patch?&lt;br /&gt;
2010-11-23 22:56:14 &amp;lt; Dark_Shikari&amp;gt; you mean checkasm fails, right?&lt;br /&gt;
2010-11-23 22:56:20 &amp;lt; Jumpyshoes&amp;gt; yea, checkasm fails&lt;br /&gt;
2010-11-23 22:56:30 &amp;lt; Jumpyshoes&amp;gt; and store_diff was already written&lt;br /&gt;
2010-11-23 22:56:39 &amp;lt; Jumpyshoes&amp;gt; how do i post a whole patch?&lt;br /&gt;
2010-11-23 22:56:50 &amp;lt; Dark_Shikari&amp;gt; STORE_DIFF was written for high bit dept?h&lt;br /&gt;
2010-11-23 22:56:52 &amp;lt; Dark_Shikari&amp;gt; git diff&lt;br /&gt;
2010-11-23 22:56:56 &amp;lt; Jumpyshoes&amp;gt; yea, it was&lt;br /&gt;
2010-11-23 22:57:27 &amp;lt; Jumpyshoes&amp;gt; git diff prints to the terminal, how do i get it to a file? pipe?&lt;br /&gt;
2010-11-23 22:57:48 &amp;lt; dj_tjerk&amp;gt; &amp;gt; test.diff&lt;br /&gt;
2010-11-23 22:58:25 &amp;lt; dj_tjerk&amp;gt; if you didn&#039;t tinker with color settings, it should be fine (i think you can set it to always output color, and not check if it&#039;s outputting to a file or stdout)&lt;br /&gt;
2010-11-23 22:59:08 &amp;lt; Jumpyshoes&amp;gt; and i just pastebin it?&lt;br /&gt;
2010-11-23 23:00:38 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:00:50 &amp;lt; Dark_Shikari&amp;gt; also, you can add printfs to the checkasm unit test&lt;br /&gt;
2010-11-23 23:00:54 &amp;lt; Dark_Shikari&amp;gt; to look at the output and try to see what might be wrong&lt;br /&gt;
2010-11-23 23:01:03 &amp;lt; Jumpyshoes&amp;gt; how do i do that?&lt;br /&gt;
2010-11-23 23:01:24 &amp;lt; Dark_Shikari&amp;gt; by editing checkasm.c&lt;br /&gt;
2010-11-23 23:01:26 &amp;lt; Dark_Shikari&amp;gt; and adding printfs&lt;br /&gt;
2010-11-23 23:01:28 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/6r91qxH0 i did a bunch of mucking around&lt;br /&gt;
2010-11-23 23:01:28 &amp;lt; Dark_Shikari&amp;gt; assuming you know basic C&lt;br /&gt;
2010-11-23 23:01:41 &amp;lt; Jumpyshoes&amp;gt; why on earth would i try to learn asm before C ._.&lt;br /&gt;
2010-11-23 23:01:44 &amp;lt; Dark_Shikari&amp;gt; you should use &amp;quot;diff&amp;quot; highlighting for your pastebinsd&lt;br /&gt;
2010-11-23 23:01:55 &amp;lt; Jumpyshoes&amp;gt; oops, sorry&lt;br /&gt;
2010-11-23 23:02:41 &amp;lt; Dark_Shikari&amp;gt; aha.&lt;br /&gt;
2010-11-23 23:02:48 &amp;lt; Dark_Shikari&amp;gt; Your idct needs to clamp!&lt;br /&gt;
2010-11-23 23:03:08 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 23:03:15 &amp;lt; Jumpyshoes&amp;gt; lesse&lt;br /&gt;
2010-11-23 23:03:20 &amp;lt; Jumpyshoes&amp;gt; does the clamp happen after the IDCT?&lt;br /&gt;
2010-11-23 23:03:31 &amp;lt; Jumpyshoes&amp;gt; seems like it does&lt;br /&gt;
2010-11-23 23:03:35 &amp;lt; Dark_Shikari&amp;gt; ok, so here&#039;s how it works&lt;br /&gt;
2010-11-23 23:03:37 &amp;lt; Dark_Shikari&amp;gt; look at how STORE_DIFF works&lt;br /&gt;
2010-11-23 23:03:59 &amp;lt; Dark_Shikari&amp;gt; actually.  wait a minute.  where is store_diff actually used?&lt;br /&gt;
2010-11-23 23:04:12 &amp;lt; Jumpyshoes&amp;gt;     STORE_DIFF m0, m4, m5, [r0+0*FDEC_STRIDE], [r0+1*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:04:14 &amp;lt; Jumpyshoes&amp;gt; ...&lt;br /&gt;
2010-11-23 23:04:16 &amp;lt; Jumpyshoes&amp;gt;     STORE_DIFF m3, m4, m5, [r0+6*FDEC_STRIDE], [r0+7*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:04:32 &amp;lt; Dark_Shikari&amp;gt; .... oh god&lt;br /&gt;
2010-11-23 23:04:33 &amp;lt; Dark_Shikari&amp;gt; irock: !&lt;br /&gt;
2010-11-23 23:04:35 &amp;lt; Dark_Shikari&amp;gt; come on&lt;br /&gt;
2010-11-23 23:04:44 &amp;lt; Dark_Shikari&amp;gt; your STORE_DIFF doesn&#039;t do a STORE_DIFF, it&#039;s used for a completely unrelated purpose&lt;br /&gt;
2010-11-23 23:04:47 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-23 23:04:51 &amp;lt; Jumpyshoes&amp;gt; :(&lt;br /&gt;
2010-11-23 23:04:59 &amp;lt; Jumpyshoes&amp;gt; why is it called the same thing&lt;br /&gt;
2010-11-23 23:05:03 &amp;lt; Dark_Shikari&amp;gt; irock&lt;br /&gt;
2010-11-23 23:05:04 &amp;lt; Dark_Shikari&amp;gt; blame him&lt;br /&gt;
2010-11-23 23:05:09 &amp;lt; Dark_Shikari&amp;gt; anyways, for now, make your own macro that does it&lt;br /&gt;
2010-11-23 23:05:13 &amp;lt; Dark_Shikari&amp;gt; first start by copying the low bit depth STORE_DIFF&lt;br /&gt;
2010-11-23 23:05:21 &amp;lt; Dark_Shikari&amp;gt; second, you&#039;ll need to change it around a bit&lt;br /&gt;
2010-11-23 23:05:26 &amp;lt; Jumpyshoes&amp;gt; well, i can&#039;t exactly delete his&lt;br /&gt;
2010-11-23 23:05:26 &amp;lt; Dark_Shikari&amp;gt; punpcklbw will become punpcklwd&lt;br /&gt;
2010-11-23 23:05:31 &amp;lt; Dark_Shikari&amp;gt; No, just call yours STORE_DIFF2&lt;br /&gt;
2010-11-23 23:05:35 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll fix it later.&lt;br /&gt;
2010-11-23 23:05:41 &amp;lt; Jumpyshoes&amp;gt; oh, kk&lt;br /&gt;
2010-11-23 23:05:42 &amp;lt; Dark_Shikari&amp;gt; so:&lt;br /&gt;
2010-11-23 23:05:44 &amp;lt; Dark_Shikari&amp;gt;     movh       %2, %4&lt;br /&gt;
2010-11-23 23:05:44 &amp;lt; Dark_Shikari&amp;gt;     punpcklbw  %2, %3&lt;br /&gt;
2010-11-23 23:05:44 &amp;lt; Dark_Shikari&amp;gt;     psraw      %1, 6&lt;br /&gt;
2010-11-23 23:05:44 &amp;lt; Dark_Shikari&amp;gt;     paddsw     %1, %2&lt;br /&gt;
2010-11-23 23:05:47 &amp;lt; Dark_Shikari&amp;gt;     packuswb   %1, %1&lt;br /&gt;
2010-11-23 23:05:49 &amp;lt; Dark_Shikari&amp;gt;     movh       %4, %1&lt;br /&gt;
2010-11-23 23:05:54 &amp;lt; Dark_Shikari&amp;gt; we need to modify this for high bit depth and add clamping.&lt;br /&gt;
2010-11-23 23:06:01 &amp;lt; Dark_Shikari&amp;gt; punpcklbw -&amp;gt; punpcklwd (since the data type is 16-bit)&lt;br /&gt;
2010-11-23 23:06:15 &amp;lt; Dark_Shikari&amp;gt; psraw -&amp;gt; psrad&lt;br /&gt;
2010-11-23 23:06:22 &amp;lt; pengvado&amp;gt; how about pack first, then add?&lt;br /&gt;
2010-11-23 23:06:27 &amp;lt; Dark_Shikari&amp;gt; Oh, you could do that too&lt;br /&gt;
2010-11-23 23:06:32 &amp;lt; Dark_Shikari&amp;gt; yeah, that&#039;d better, you can pack before adding&lt;br /&gt;
2010-11-23 23:06:41 &amp;lt; Jumpyshoes&amp;gt; what?&lt;br /&gt;
2010-11-23 23:06:49 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: remember, the formula is&lt;br /&gt;
2010-11-23 23:07:02 &amp;lt; Dark_Shikari&amp;gt; pix + ((dctcoeff + 32) &amp;gt;&amp;gt; 6)&lt;br /&gt;
2010-11-23 23:07:08 &amp;lt; Dark_Shikari&amp;gt; the above code does that&lt;br /&gt;
2010-11-23 23:07:18 &amp;lt; Dark_Shikari&amp;gt; so we could do something like this:&lt;br /&gt;
2010-11-23 23:07:33 &amp;lt; Dark_Shikari&amp;gt; oh, but remember the 32 is already handled inside the idct above, so you don&#039;t have to worry about that&lt;br /&gt;
2010-11-23 23:07:37 &amp;lt; Dark_Shikari&amp;gt; so we&#039;re really doing&lt;br /&gt;
2010-11-23 23:07:38 &amp;lt; Dark_Shikari&amp;gt; pix + (dctcoeff &amp;gt;&amp;gt; 6)&lt;br /&gt;
2010-11-23 23:07:47 &amp;lt; Dark_Shikari&amp;gt; the pd_32 is the adding of the 32.&lt;br /&gt;
2010-11-23 23:07:53 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 23:07:53 &amp;lt; Dark_Shikari&amp;gt; so, here&#039;s what we do:&lt;br /&gt;
2010-11-23 23:07:59 &amp;lt; Dark_Shikari&amp;gt; 1) dctcoeff &amp;gt;&amp;gt;= 6&lt;br /&gt;
2010-11-23 23:08:03 &amp;lt; Dark_Shikari&amp;gt; 2) pack dctcoeff from 32-bit to 16-bit&lt;br /&gt;
2010-11-23 23:08:07 &amp;lt; Dark_Shikari&amp;gt; 3) add dctcoeff to pix&lt;br /&gt;
2010-11-23 23:08:24 &amp;lt; Dark_Shikari&amp;gt; 4) clamp pix to [0,(1&amp;lt;&amp;lt;BIT_DEPTH)-1]&lt;br /&gt;
2010-11-23 23:08:28 &amp;lt; Dark_Shikari&amp;gt; 5) store&lt;br /&gt;
2010-11-23 23:08:38 &amp;lt; Dark_Shikari&amp;gt; so, right here in chat, write out the instructions you&#039;d use to do each step&lt;br /&gt;
2010-11-23 23:08:47 &amp;lt; Jumpyshoes&amp;gt; in that order?&lt;br /&gt;
2010-11-23 23:08:50 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:09:11 &amp;lt; Jumpyshoes&amp;gt; i assume pack means (in C talk) to cast?&lt;br /&gt;
2010-11-23 23:11:46 &amp;lt; Dark_Shikari&amp;gt; not quite, you&#039;re rearranging the data values&lt;br /&gt;
2010-11-23 23:11:51 &amp;lt; Dark_Shikari&amp;gt; e.g. 4x32-bit -&amp;gt; 4x16-bit&lt;br /&gt;
2010-11-23 23:11:58 &amp;lt; Dark_Shikari&amp;gt; this clearly involves modifying the data in the register&lt;br /&gt;
2010-11-23 23:12:33 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-23 23:13:18 &amp;lt; Jumpyshoes&amp;gt; 1) dctcoeff &amp;gt;&amp;gt;= 6: psrad      %1, 6&lt;br /&gt;
2010-11-23 23:13:41 &amp;lt; Dark_Shikari&amp;gt; just use variables in your asm for now&lt;br /&gt;
2010-11-23 23:13:45 &amp;lt; Dark_Shikari&amp;gt; e.g. psrad dctcoeff, 6&lt;br /&gt;
2010-11-23 23:13:48 &amp;lt; Dark_Shikari&amp;gt; consider it pseudocode&lt;br /&gt;
2010-11-23 23:13:50 &amp;lt; Jumpyshoes&amp;gt; ah okay&lt;br /&gt;
2010-11-23 23:14:18 &amp;lt; Jumpyshoes&amp;gt; i have no idea how to pack data, unless you can do it by shifting like crazy&lt;br /&gt;
2010-11-23 23:14:53 &amp;lt; Dark_Shikari&amp;gt; using the pack instruction&lt;br /&gt;
2010-11-23 23:14:54 &amp;lt; Dark_Shikari&amp;gt; duh&lt;br /&gt;
2010-11-23 23:15:10 &amp;lt; Dark_Shikari&amp;gt; use your manual&lt;br /&gt;
2010-11-23 23:15:12 &amp;lt; Dark_Shikari&amp;gt; packssdw&lt;br /&gt;
2010-11-23 23:15:34 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-23 23:15:40 &amp;lt; Jumpyshoes&amp;gt; bleh, i need to get better at looking stuff up&lt;br /&gt;
2010-11-23 23:16:44 &amp;lt; Jumpyshoes&amp;gt; 2) pack dctcoeff from 32-bit to 16-bit: packssdw tmp1, dctcoeff&lt;br /&gt;
2010-11-23 23:16:55 &amp;lt; Dark_Shikari&amp;gt; no&lt;br /&gt;
2010-11-23 23:17:01 &amp;lt; Dark_Shikari&amp;gt; go read what packssdw does&lt;br /&gt;
2010-11-23 23:17:46 &amp;lt; Jumpyshoes&amp;gt; oh derp&lt;br /&gt;
2010-11-23 23:17:49 &amp;lt; Dark_Shikari&amp;gt; and look at how it&#039;s used in the existing STORE_DIFF&lt;br /&gt;
2010-11-23 23:18:06 &amp;lt; rfw&amp;gt; Dark_Shikari: it is better \o/&lt;br /&gt;
2010-11-23 23:18:18 &amp;lt; rfw&amp;gt; though i still have to rewrite all that fucking bisection code&lt;br /&gt;
2010-11-23 23:18:37 &amp;lt; Jumpyshoes&amp;gt; wait, how can you tell if an instruction can be used on the same register?&lt;br /&gt;
2010-11-23 23:18:40 &amp;lt; Jumpyshoes&amp;gt; PACKSSDW xmm1,&lt;br /&gt;
2010-11-23 23:18:41 &amp;lt; Jumpyshoes&amp;gt; xmm2/m128&lt;br /&gt;
2010-11-23 23:18:57 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: does it exist?  if so, it can be used on the same register&lt;br /&gt;
2010-11-23 23:19:04 &amp;lt; Jumpyshoes&amp;gt; oh &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-23 23:19:19 &amp;lt; Dark_Shikari&amp;gt; irock: I am copmletely lost with regadrs to the end of your dct mmx functions.  why do we need 32-bit dct coeff precision if your dct function can&#039;t even generate that?&lt;br /&gt;
2010-11-23 23:19:31 &amp;lt; Jumpyshoes&amp;gt; then, 2) pack dctcoeff from 32-bit to 16-bit: packssdw dctcoeff, dctcoeff ?&lt;br /&gt;
2010-11-23 23:19:58 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:23:16 &amp;lt; pengvado&amp;gt; that works, but you probably want to pack 2 regs together. no sense in wasting half the throughput.&lt;br /&gt;
2010-11-23 23:23:29 &amp;lt; Dark_Shikari&amp;gt; and what pengvado said&lt;br /&gt;
2010-11-23 23:23:31 &amp;lt; Dark_Shikari&amp;gt; so you can do something like&lt;br /&gt;
2010-11-23 23:23:39 &amp;lt; Dark_Shikari&amp;gt; psrad dctcoeffreg1, 6&lt;br /&gt;
2010-11-23 23:23:41 &amp;lt; Dark_Shikari&amp;gt; psrad dctcoeffreg2, 6&lt;br /&gt;
2010-11-23 23:23:50 &amp;lt; Dark_Shikari&amp;gt; packssdw dctcoeffreg1, dctcoeffreg2&lt;br /&gt;
2010-11-23 23:25:14 &amp;lt; Jumpyshoes&amp;gt; wouldn&#039;t i need to modify the storediff? i thought only one set of dctcoeff were passed at a time&lt;br /&gt;
2010-11-23 23:25:23 &amp;lt; Dark_Shikari&amp;gt; you&#039;re writing your own&lt;br /&gt;
2010-11-23 23:25:29 &amp;lt; Dark_Shikari&amp;gt; if you want, start by not even making it a macro&lt;br /&gt;
2010-11-23 23:25:31 &amp;lt; Dark_Shikari&amp;gt; you can macroize it later&lt;br /&gt;
2010-11-23 23:25:34 &amp;lt; Dark_Shikari&amp;gt; just write out the instructions&lt;br /&gt;
2010-11-23 23:25:42 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-23 23:27:40 &amp;lt; Dark_Shikari&amp;gt;  so do 1) and 2) for all your dct coeff registers&lt;br /&gt;
2010-11-23 23:28:53 &amp;lt; Jumpyshoes&amp;gt; psrad dctcoeffreg1, 6&lt;br /&gt;
2010-11-23 23:28:53 &amp;lt; Jumpyshoes&amp;gt; psrad dctcoeffreg2, 6&lt;br /&gt;
2010-11-23 23:28:53 &amp;lt; Jumpyshoes&amp;gt; packssdw dctcoeffreg1, dctcoeffreg2&lt;br /&gt;
2010-11-23 23:28:53 &amp;lt; Jumpyshoes&amp;gt; psrad dctcoeffreg3, 6&lt;br /&gt;
2010-11-23 23:28:53 &amp;lt; Jumpyshoes&amp;gt; psrad dctcoeffreg4, 6&lt;br /&gt;
2010-11-23 23:28:54 &amp;lt; Jumpyshoes&amp;gt; packssdw dctcoeffreg3, dctcoeffreg4&lt;br /&gt;
2010-11-23 23:28:58 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:29:13 &amp;lt; Jumpyshoes&amp;gt; oh, and now they&#039;re 16bit&lt;br /&gt;
2010-11-23 23:29:19 &amp;lt; Dark_Shikari&amp;gt; now load up your pixels, which are also 16-bit, and add them&lt;br /&gt;
2010-11-23 23:29:28 &amp;lt; Jumpyshoes&amp;gt; right&lt;br /&gt;
2010-11-23 23:29:29 &amp;lt; Dark_Shikari&amp;gt; so e.g.&lt;br /&gt;
2010-11-23 23:29:36 &amp;lt; Dark_Shikari&amp;gt; movq tmp1, [r0+0*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:29:41 &amp;lt; Dark_Shikari&amp;gt; movq tmp2, [r0+1*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:29:44 &amp;lt; Dark_Shikari&amp;gt; punpcklqdq tmp1, tmp2&lt;br /&gt;
2010-11-23 23:29:50 &amp;lt; Dark_Shikari&amp;gt; which gives you two rows of pixels in &amp;quot;tmp1&amp;quot;&lt;br /&gt;
2010-11-23 23:30:01 &amp;lt; Dark_Shikari&amp;gt; which is what you want, as you have two rows of dct coeffs in &amp;quot;dctcoeffreg1&amp;quot;&lt;br /&gt;
2010-11-23 23:30:03 &amp;lt; rfw&amp;gt; To git@github.com:rofflwaffls/digress.git&lt;br /&gt;
2010-11-23 23:30:03 &amp;lt; rfw&amp;gt;  * [new branch]      master -&amp;gt; master&lt;br /&gt;
2010-11-23 23:30:09 &amp;lt; rfw&amp;gt; there&lt;br /&gt;
2010-11-23 23:30:12 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 23:30:37 &amp;lt; Dark_Shikari&amp;gt; actually, better yet&lt;br /&gt;
2010-11-23 23:30:38 &amp;lt; Dark_Shikari&amp;gt; do&lt;br /&gt;
2010-11-23 23:30:41 &amp;lt; Dark_Shikari&amp;gt; movq tmp1, [r0+0*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:30:46 &amp;lt; Dark_Shikari&amp;gt; movhps tmp1, [r0+1*FDEC_STRIDE]&lt;br /&gt;
2010-11-23 23:30:51 &amp;lt; Dark_Shikari&amp;gt; same thing, two instructions instead of three.&lt;br /&gt;
2010-11-23 23:30:57 &amp;lt; Dark_Shikari&amp;gt; movhps --&amp;gt; move to the high half&lt;br /&gt;
2010-11-23 23:31:09 &amp;lt; Jumpyshoes&amp;gt; oh, isn&#039;t that for floating point though?&lt;br /&gt;
2010-11-23 23:31:15 &amp;lt; Dark_Shikari&amp;gt; It&#039;s a move, do you think the cpu cares? =p&lt;br /&gt;
2010-11-23 23:31:24 &amp;lt; Jumpyshoes&amp;gt; true&lt;br /&gt;
2010-11-23 23:31:40 &amp;lt; Jumpyshoes&amp;gt; now i need to add these&lt;br /&gt;
2010-11-23 23:33:23 &amp;lt; Jumpyshoes&amp;gt; paddsw dctcoeffreg1, tmp1&lt;br /&gt;
2010-11-23 23:33:23 &amp;lt; Jumpyshoes&amp;gt; paddsw dctcoeffreg3, tmp2&lt;br /&gt;
2010-11-23 23:33:23 &amp;lt; Jumpyshoes&amp;gt; ?&lt;br /&gt;
2010-11-23 23:35:12 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:36:32 &amp;lt; Jumpyshoes&amp;gt; can i use PACKSSDW or something similar to clamp? or will that not work&lt;br /&gt;
2010-11-23 23:37:09 &amp;lt; Dark_Shikari&amp;gt; ah, now here comes in the problem&lt;br /&gt;
2010-11-23 23:37:18 &amp;lt; Dark_Shikari&amp;gt; you&#039;re clamping to between, for example&lt;br /&gt;
2010-11-23 23:37:19 &amp;lt; Dark_Shikari&amp;gt; 0 and 1023&lt;br /&gt;
2010-11-23 23:37:22 &amp;lt; Dark_Shikari&amp;gt; there&#039;s no magic way to do that?&lt;br /&gt;
2010-11-23 23:37:24 &amp;lt; Dark_Shikari&amp;gt; *that!&lt;br /&gt;
2010-11-23 23:37:28 &amp;lt; Dark_Shikari&amp;gt; because they&#039;re not data type sizes&lt;br /&gt;
2010-11-23 23:37:34 &amp;lt; Dark_Shikari&amp;gt; i.e. it&#039;s not 0 and 65535&lt;br /&gt;
2010-11-23 23:37:35 &amp;lt; Dark_Shikari&amp;gt; or 0 and 255&lt;br /&gt;
2010-11-23 23:37:50 &amp;lt; Dark_Shikari&amp;gt; so here&#039;s what you do&lt;br /&gt;
2010-11-23 23:37:58 &amp;lt; Jumpyshoes&amp;gt; bleh, true&lt;br /&gt;
2010-11-23 23:38:05 &amp;lt; Dark_Shikari&amp;gt; pmaxsw myval, {0}&lt;br /&gt;
2010-11-23 23:38:13 &amp;lt; Dark_Shikari&amp;gt; pminsw myval, {MAX_PIXEL}&lt;br /&gt;
2010-11-23 23:38:17 &amp;lt; Dark_Shikari&amp;gt; where {0} is pw_0&lt;br /&gt;
2010-11-23 23:38:23 &amp;lt; Dark_Shikari&amp;gt; and max_pixel is pw_max&lt;br /&gt;
2010-11-23 23:38:33 &amp;lt; Dark_Shikari&amp;gt; which is defined as times 8 ((BIT_DEPTH&amp;lt;&amp;lt;1)-1)&lt;br /&gt;
2010-11-23 23:38:37 &amp;lt; Dark_Shikari&amp;gt; or pw_pixelmax&lt;br /&gt;
2010-11-23 23:38:39 &amp;lt; Dark_Shikari&amp;gt; or something descriptive&lt;br /&gt;
2010-11-23 23:39:00 &amp;lt; Dark_Shikari&amp;gt; also, pb_0 will (obviously) serve as a good pw_0/.&lt;br /&gt;
2010-11-23 23:39:06 &amp;lt; Jumpyshoes&amp;gt; there&#039;s already a pw_pixel_max, but it&#039;s times 8&lt;br /&gt;
2010-11-23 23:39:11 &amp;lt; Dark_Shikari&amp;gt; That&#039;s what you need&lt;br /&gt;
2010-11-23 23:39:16 &amp;lt; Dark_Shikari&amp;gt; use it&lt;br /&gt;
2010-11-23 23:39:17 &amp;lt; Jumpyshoes&amp;gt; oh right, i have 8 of them&lt;br /&gt;
2010-11-23 23:39:31 &amp;lt; pengvado&amp;gt; there&#039;as also a macro CLIPW&lt;br /&gt;
2010-11-23 23:39:37 &amp;lt; Dark_Shikari&amp;gt; Oh, nice&lt;br /&gt;
2010-11-23 23:39:38 &amp;lt; Jumpyshoes&amp;gt; o, can i use that?&lt;br /&gt;
2010-11-23 23:39:57 &amp;lt; Dark_Shikari&amp;gt; pengvado: so, why do we need 32-bit dct coefficients for 10-bit?  I just did a dct between min pixel value and max pixel value, and checkasm still passed&lt;br /&gt;
2010-11-23 23:40:03 &amp;lt; Dark_Shikari&amp;gt; Or is it because of idct scaling factors?&lt;br /&gt;
2010-11-23 23:40:15 &amp;lt; Dark_Shikari&amp;gt; i.e. I assume I&#039;m missing sometihng&lt;br /&gt;
2010-11-23 23:40:16 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: go check it out&lt;br /&gt;
2010-11-23 23:40:23 &amp;lt; Dark_Shikari&amp;gt; it&#039;s probably already used for exactly this purpose!&lt;br /&gt;
2010-11-23 23:40:53 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-23 23:41:02 &amp;lt; Jumpyshoes&amp;gt; does exactly what you pasted&lt;br /&gt;
2010-11-23 23:41:33 &amp;lt; Jumpyshoes&amp;gt; should i use pb_0 or can i just use 0?&lt;br /&gt;
2010-11-23 23:41:57 &amp;lt; Jumpyshoes&amp;gt; or i guess i could define a pw_pixel_min&lt;br /&gt;
2010-11-23 23:41:58 &amp;lt; Dark_Shikari&amp;gt; if you already have a zero register, use it&lt;br /&gt;
2010-11-23 23:42:05 &amp;lt; Dark_Shikari&amp;gt; guess what, you do&lt;br /&gt;
2010-11-23 23:42:18 &amp;lt; Dark_Shikari&amp;gt; m7&lt;br /&gt;
2010-11-23 23:42:24 &amp;lt; Jumpyshoes&amp;gt; right, xor&#039;d it up top&lt;br /&gt;
2010-11-23 23:42:40 &amp;lt; Jumpyshoes&amp;gt; CLIPW dctcoeffreg1, m7, pw_pixel_max ;m7 = 0&lt;br /&gt;
2010-11-23 23:42:40 &amp;lt; Jumpyshoes&amp;gt; CLIPW dctcoeffreg3, m7, pw_pixel_max&lt;br /&gt;
2010-11-23 23:42:50 &amp;lt; Dark_Shikari&amp;gt; load pw_pixel_max into a register to avoid loading it twice&lt;br /&gt;
2010-11-23 23:43:42 &amp;lt; Jumpyshoes&amp;gt; movq tmp1, pw_pixel_max&lt;br /&gt;
2010-11-23 23:43:43 &amp;lt; Jumpyshoes&amp;gt; CLIPW dctcoeffreg1, m7, tmp1 ;m7 = 0&lt;br /&gt;
2010-11-23 23:43:43 &amp;lt; Jumpyshoes&amp;gt; CLIPW dctcoeffreg3, m7, tmp1&lt;br /&gt;
2010-11-23 23:44:00 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-23 23:44:25 &amp;lt; Jumpyshoes&amp;gt; okay, now i need to store it&lt;br /&gt;
2010-11-23 23:44:50 &amp;lt; Dark_Shikari&amp;gt; movq outputrow1, dctcoeffreg1&lt;br /&gt;
2010-11-23 23:44:54 &amp;lt; Dark_Shikari&amp;gt; movhps outputrow1, dctcoeffreg1&lt;br /&gt;
2010-11-23 23:44:56 &amp;lt; Dark_Shikari&amp;gt; etc&lt;br /&gt;
2010-11-23 23:44:58 &amp;lt; Dark_Shikari&amp;gt; er&lt;br /&gt;
2010-11-23 23:45:01 &amp;lt; Dark_Shikari&amp;gt; movhps outputrow2, dctcoeffreg1&lt;br /&gt;
2010-11-23 23:45:06 &amp;lt; Dark_Shikari&amp;gt; where outputrow1 is a memory pointer, etc&lt;br /&gt;
2010-11-23 23:45:45 &amp;lt; Jumpyshoes&amp;gt; oh, that is handy&lt;br /&gt;
2010-11-23 23:45:53 &amp;lt; Dark_Shikari&amp;gt; movq and movhps work in both directions&lt;br /&gt;
2010-11-23 23:45:54 &amp;lt; Dark_Shikari&amp;gt; loading and storing&lt;br /&gt;
2010-11-23 23:46:01 &amp;lt; j-b&amp;gt; reid_: pong&lt;br /&gt;
2010-11-23 23:46:50 &amp;lt; Jumpyshoes&amp;gt; movq [r0+0*FDEC_STRIDE], dctcoeffreg1&lt;br /&gt;
2010-11-23 23:46:50 &amp;lt; Jumpyshoes&amp;gt; movhps [r0+4*FDEC_STRIDE], dctcoeffreg1&lt;br /&gt;
2010-11-23 23:46:50 &amp;lt; Jumpyshoes&amp;gt; movq [r0+8*FDEC_STRIDE], dctcoeffreg3&lt;br /&gt;
2010-11-23 23:46:50 &amp;lt; Jumpyshoes&amp;gt; movhps [r0+12*FDEC_STRIDE], dctcoeffreg3&lt;br /&gt;
2010-11-23 23:46:59 &amp;lt; Dark_Shikari&amp;gt; think about where you&#039;re outputting&lt;br /&gt;
2010-11-23 23:47:08 &amp;lt; Dark_Shikari&amp;gt; and look at the low bit depth version.&lt;br /&gt;
2010-11-23 23:47:35 &amp;lt; Jumpyshoes&amp;gt; oh right, you&#039;re adding the FDEC_STRIDE&lt;br /&gt;
2010-11-23 23:47:54 &amp;lt; Jumpyshoes&amp;gt; bleh, dinner, bbl&lt;br /&gt;
2010-11-23 23:48:00 &amp;lt; Dark_Shikari&amp;gt; damn east coasters&lt;br /&gt;
2010-11-23 23:48:12 &amp;lt; Jumpyshoes&amp;gt; but i just need to change it to 0,1,2,3?&lt;br /&gt;
2010-11-23 23:53:06 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
--- Day changed Wed Nov 24 2010&lt;br /&gt;
2010-11-24 00:02:55 &amp;lt; pengvado&amp;gt; Dark_Shikari: I don&#039;t know why your test passes.&lt;br /&gt;
2010-11-24 00:03:42 &amp;lt; pengvado&amp;gt; fdct8&#039;s dc is the sum of 2^6 samples, each of which is an 11 bit different between two pixels. total: 17 bits.&lt;br /&gt;
2010-11-24 00:04:00 &amp;lt; pengvado&amp;gt; and I think some of the ac coefs have another bit of expansion.&lt;br /&gt;
2010-11-24 00:04:55 &amp;lt; pengvado&amp;gt; do we need to generate some maximal edge cases, like we do for hadamard?&lt;br /&gt;
2010-11-24 00:05:03 &amp;lt; Dark_Shikari&amp;gt; I think that would be a good idea&lt;br /&gt;
2010-11-24 00:06:51 &amp;lt; pengvado&amp;gt; btw, some of the butterfly passes could still be 16bit&lt;br /&gt;
2010-11-24 00:07:36 &amp;lt; Dark_Shikari&amp;gt; yeah probably&lt;br /&gt;
2010-11-24 00:17:24 &amp;lt; Dark_Shikari&amp;gt; (patches welcome)&lt;br /&gt;
2010-11-24 00:22:08 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: does it pass checkasm yet? =p&lt;br /&gt;
2010-11-24 00:22:44 &amp;lt; rfw&amp;gt; Dark_Shikari: i&#039;m sorta not regretting deleting everything now&lt;br /&gt;
2010-11-24 00:22:49 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 00:22:59 &amp;lt; rfw&amp;gt; fixed all the weird ass conventions i had before&lt;br /&gt;
2010-11-24 00:23:07 &amp;lt; Dark_Shikari&amp;gt; &amp;quot;I told you so&amp;quot;&lt;br /&gt;
2010-11-24 00:23:10 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-24 00:23:16 &amp;lt; rfw&amp;gt; should i delete it again when i finish this :D&lt;br /&gt;
2010-11-24 00:23:18 &amp;lt; Dark_Shikari&amp;gt; Now commit early and often!&lt;br /&gt;
2010-11-24 00:23:20 &amp;lt; Dark_Shikari&amp;gt; and push too&lt;br /&gt;
2010-11-24 00:23:25 &amp;lt; rfw&amp;gt; Total 14 (delta 6), reused 0 (delta 0)&lt;br /&gt;
2010-11-24 00:23:26 &amp;lt; rfw&amp;gt; To git@github.com:rofflwaffls/digress.git&lt;br /&gt;
2010-11-24 00:23:26 &amp;lt; rfw&amp;gt;    2ee921b..12af40a  master -&amp;gt; master&lt;br /&gt;
2010-11-24 00:23:28 &amp;lt; rfw&amp;gt; :D&lt;br /&gt;
2010-11-24 00:23:56 &amp;lt; Dark_Shikari&amp;gt; I have saved another poor soul from data loss despair with github!&lt;br /&gt;
2010-11-24 00:24:11 &amp;lt; rfw&amp;gt; i usually do commit everything to github&lt;br /&gt;
2010-11-24 00:24:14 &amp;lt; rfw&amp;gt; not sure why i didn&#039;t with this&lt;br /&gt;
2010-11-24 00:26:39 &amp;lt; espes&amp;gt; Dark_Shikari: So like, I requested that GCI task.&lt;br /&gt;
2010-11-24 00:26:46 &amp;lt; Dark_Shikari&amp;gt; which one?&lt;br /&gt;
2010-11-24 00:26:51 &amp;lt; espes&amp;gt; Dark_Shikari: filter.&lt;br /&gt;
2010-11-24 00:26:57 &amp;lt; Dark_Shikari&amp;gt; That task is repeatable&lt;br /&gt;
2010-11-24 00:27:08 &amp;lt; Dark_Shikari&amp;gt; i.e. if you say you want to do it, you can go do it, no problem&lt;br /&gt;
2010-11-24 00:27:22 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll go accept you, which filter do you want to do?&lt;br /&gt;
2010-11-24 00:27:48 &amp;lt; Dark_Shikari&amp;gt; j-b: please approve my added duplicates of the filter task&lt;br /&gt;
2010-11-24 00:28:00 &amp;lt; espes&amp;gt; Dark_Shikari: I was thinking something basic. 2xsai maybe.&lt;br /&gt;
2010-11-24 00:28:31 &amp;lt; Dark_Shikari&amp;gt; we already have a resizer, though &amp;quot;interesting&amp;quot; resizing algorithms might be, well, interesting&lt;br /&gt;
2010-11-24 00:28:53 &amp;lt; espes&amp;gt; Dark_Shikari: The justification is that you do have tasvideos linked from your homepage :P&lt;br /&gt;
2010-11-24 00:28:53 &amp;lt; Dark_Shikari&amp;gt; hq2x/3x/4x might be interesting, though if I recall correctly those are written in pure asm and thus extremely scary&lt;br /&gt;
2010-11-24 00:28:58 &amp;lt; Dark_Shikari&amp;gt; tasvideos?&lt;br /&gt;
2010-11-24 00:29:13 &amp;lt; Dark_Shikari&amp;gt; Oh, wow, that list hasn&#039;t been updated in a mlilion years&lt;br /&gt;
2010-11-24 00:29:14 &amp;lt; espes&amp;gt; Dark_Shikari: Video game speed runs.&lt;br /&gt;
2010-11-24 00:29:15 &amp;lt; Dark_Shikari&amp;gt; I guess they are listed&lt;br /&gt;
2010-11-24 00:29:40 &amp;lt; Dark_Shikari&amp;gt; well, it is fitting, considering that my x264 demos page consists almost entirely of video game clips&lt;br /&gt;
2010-11-24 00:29:43 &amp;lt; Dark_Shikari&amp;gt; e.g. http://x264.nl/developers/Dark_Shikari/Flash/extra.html&lt;br /&gt;
2010-11-24 00:30:52 &amp;lt; espes&amp;gt; Dark_Shikari: besides, it&#039;s easy enough to rip 2xsai out of mplayer.&lt;br /&gt;
2010-11-24 00:31:16 &amp;lt; Dark_Shikari&amp;gt; didn&#039;t even know mplayer did&lt;br /&gt;
2010-11-24 00:31:37 &amp;lt; Dark_Shikari&amp;gt; sounds cool enough, I&#039;ll go for that&lt;br /&gt;
2010-11-24 00:31:45 &amp;lt; espes&amp;gt; Dark_Shikari: sweet.&lt;br /&gt;
2010-11-24 00:31:48 &amp;lt; Dark_Shikari&amp;gt; just keep in mind...&lt;br /&gt;
2010-11-24 00:31:55 &amp;lt; Dark_Shikari&amp;gt; all x264 tasks must go through pengvado&lt;br /&gt;
2010-11-24 00:31:59 &amp;lt; Dark_Shikari&amp;gt; that is, he must approve your code&lt;br /&gt;
2010-11-24 00:32:10 &amp;lt; Dark_Shikari&amp;gt; which means you must pass the code review =p&lt;br /&gt;
2010-11-24 00:32:37 &amp;lt; pengvado&amp;gt; and pengvado generally disapproves of forking libavfilter&lt;br /&gt;
2010-11-24 00:33:18 &amp;lt; Dark_Shikari&amp;gt; good point.&lt;br /&gt;
2010-11-24 00:33:35 &amp;lt; kemuri-_9&amp;gt; hmm someone&#039;s doing a filter?&lt;br /&gt;
2010-11-24 00:33:36 &amp;lt; Dark_Shikari&amp;gt; actually, pengvado, why didn&#039;t you say that earlier? =p&lt;br /&gt;
2010-11-24 00:33:56 &amp;lt; pengvado&amp;gt; didn&#039;t I say it enough times, whenever anyone has proposed to add any filter to x264?&lt;br /&gt;
2010-11-24 00:34:06 &amp;lt; Dark_Shikari&amp;gt; You never reviewed any filters.&lt;br /&gt;
2010-11-24 00:34:14 &amp;lt; Dark_Shikari&amp;gt; pad, hqdn3d, etc are sitting around unreviewed&lt;br /&gt;
2010-11-24 00:34:36 &amp;lt; Dark_Shikari&amp;gt; I&#039;d be fine with 2xsai being ported to libavfilter though!&lt;br /&gt;
2010-11-24 00:34:48 &amp;lt; Dark_Shikari&amp;gt; as long as someone writes an interface to transparently access libavfilter filters in x264&lt;br /&gt;
2010-11-24 00:34:52 &amp;lt; Dark_Shikari&amp;gt; but someone can do that later&lt;br /&gt;
2010-11-24 00:35:27 &amp;lt; Dark_Shikari&amp;gt; pengvado: I&#039;d really like you to say something certain here on this topic&lt;br /&gt;
2010-11-24 00:35:33 &amp;lt; pengvado&amp;gt; ok, so I only complained about yadif and h1dn3d&lt;br /&gt;
2010-11-24 00:35:44 &amp;lt; Dark_Shikari&amp;gt; like &amp;quot;I don&#039;t want any more filters in x264&amp;quot;&lt;br /&gt;
2010-11-24 00:35:50 &amp;lt; Dark_Shikari&amp;gt; or &amp;quot;I won&#039;t review any more filters in x264, but you can commit them&amp;quot;&lt;br /&gt;
2010-11-24 00:35:59 &amp;lt; Dark_Shikari&amp;gt; or &amp;quot;let&#039;s just stuff everything in libavfilter and dump the ones in x264&amp;quot;&lt;br /&gt;
2010-11-24 00:36:13 &amp;lt; pengvado&amp;gt; let&#039;s just stuff everything in libavfilter&lt;br /&gt;
2010-11-24 00:36:16 &amp;lt; Dark_Shikari&amp;gt; for espes, it doesn&#039;t really matter -- x264 or libavfilter are both easy enough&lt;br /&gt;
2010-11-24 00:36:40 &amp;lt; kemuri-_9&amp;gt; &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-24 00:36:41 &amp;lt; Dark_Shikari&amp;gt; ok, good, we&#039;ll swap the tasks over to libavfilter then&lt;br /&gt;
2010-11-24 00:36:48 &amp;lt; Dark_Shikari&amp;gt; Should have said this 6 months ago, slowpoke.&lt;br /&gt;
2010-11-24 00:37:32 &amp;lt; Dark_Shikari&amp;gt; now, pengvado, are you going to volunteer to do that?&lt;br /&gt;
2010-11-24 00:37:36 &amp;lt; Dark_Shikari&amp;gt; because nobody else wants to.&lt;br /&gt;
2010-11-24 00:37:49 &amp;lt; Dark_Shikari&amp;gt; that is, we have one primary problem: there is no depth filter in libavfilter&lt;br /&gt;
2010-11-24 00:37:51 &amp;lt; Dark_Shikari&amp;gt; and will probably never be&lt;br /&gt;
2010-11-24 00:37:56 &amp;lt; Dark_Shikari&amp;gt; and we need that filter no matter what&lt;br /&gt;
2010-11-24 00:38:25 &amp;lt; Dark_Shikari&amp;gt; so we need at least some of the x264 filter chain at some point.&lt;br /&gt;
2010-11-24 00:38:44 &amp;lt; pengvado&amp;gt; never will be because libav* doesn&#039;t support anything other than 8 and 16bit?&lt;br /&gt;
2010-11-24 00:38:51 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-24 00:39:06 &amp;lt; Dark_Shikari&amp;gt; and there are 100 bikesheds between here and that being reality&lt;br /&gt;
2010-11-24 00:39:11  * checkers waits for &amp;quot;I wrote a patch for that in 2006&amp;quot;&lt;br /&gt;
2010-11-24 00:39:38 &amp;lt; kierank&amp;gt; ffmpeg - &amp;quot;there&#039;s a patch for that&amp;quot;&lt;br /&gt;
2010-11-24 00:40:07 &amp;lt; rfw&amp;gt; http://code.google.com/p/soc/source/detail?r=57762a491b i don&#039;t think i trust google any more&lt;br /&gt;
2010-11-24 00:40:08 &amp;lt; Dark_Shikari&amp;gt; so I&#039;d like a straightforward statement of what you want us to do, and what part you&#039;ll take in it&lt;br /&gt;
2010-11-24 00:40:14 &amp;lt; kemuri-_9&amp;gt; so what all filters are there for libavfilter atm?&lt;br /&gt;
2010-11-24 00:40:19 &amp;lt; Dark_Shikari&amp;gt; kemuri-_9: a lot&lt;br /&gt;
2010-11-24 00:40:28 &amp;lt; Dark_Shikari&amp;gt; rfw: OH GOD&lt;br /&gt;
2010-11-24 00:40:32 &amp;lt; Dark_Shikari&amp;gt; homebrew time/date code&lt;br /&gt;
2010-11-24 00:40:33 &amp;lt; Dark_Shikari&amp;gt; AGHAGHAHSDLFKJASDLFKJ&lt;br /&gt;
2010-11-24 00:40:46 &amp;lt; kierank&amp;gt; and they say google is nih?&lt;br /&gt;
2010-11-24 00:41:03 &amp;lt; rfw&amp;gt; lolol&lt;br /&gt;
2010-11-24 00:41:32 &amp;lt; rfw&amp;gt; god i think i should go out for a walk&lt;br /&gt;
2010-11-24 00:41:35 &amp;lt; kierank&amp;gt; there was something from google where they accidently used memset instead of memcpy&lt;br /&gt;
2010-11-24 00:41:41 &amp;lt; Dark_Shikari&amp;gt; lol what&lt;br /&gt;
2010-11-24 00:41:52 &amp;lt; pengvado&amp;gt; bleh, so keep the depth filter, and anything else that can&#039;t be merged into libavfilter short of really forking it.&lt;br /&gt;
2010-11-24 00:42:19 &amp;lt; Jumpyshoes&amp;gt; bleh, still doesn&#039;t pass checkasm&lt;br /&gt;
2010-11-24 00:42:19 &amp;lt; pengvado&amp;gt; any filter that *is* already in libavfilter, or could be developed there instead of here, gets a wrapper instead of a paste&lt;br /&gt;
2010-11-24 00:42:27 &amp;lt; Dark_Shikari&amp;gt; pengvado: wait wait&lt;br /&gt;
2010-11-24 00:42:30 &amp;lt; Dark_Shikari&amp;gt; should we wrap INDIVIDUAL filters&lt;br /&gt;
2010-11-24 00:42:31 &amp;lt; Dark_Shikari&amp;gt; or LIBAVFILTER?&lt;br /&gt;
2010-11-24 00:42:49 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: pastebin the code&lt;br /&gt;
2010-11-24 00:43:47 &amp;lt; Jumpyshoes&amp;gt; &amp;gt;We are currently upgrading our software, we will return in a few minutes.&lt;br /&gt;
2010-11-24 00:43:49 &amp;lt; Jumpyshoes&amp;gt; hohohoho&lt;br /&gt;
2010-11-24 00:43:57 &amp;lt; Dark_Shikari&amp;gt; use a different pastebin&lt;br /&gt;
2010-11-24 00:44:14 &amp;lt; pengvado&amp;gt; you mean because if we use libavfilter&#039;s filterchain generation code, then it would support only libavfilter?&lt;br /&gt;
2010-11-24 00:44:30 &amp;lt; Dark_Shikari&amp;gt; no I&#039;m just asking whether or not we should keep our filterchain code.&lt;br /&gt;
2010-11-24 00:44:36 &amp;lt; espes&amp;gt; Jumpyshoes: codepad&lt;br /&gt;
2010-11-24 00:44:37 &amp;lt; Dark_Shikari&amp;gt; or whether we should wrap each filter separately&lt;br /&gt;
2010-11-24 00:44:57 &amp;lt; pengvado&amp;gt; does ours do anything that libavfilter doesn&#039;t and won&#039;t?&lt;br /&gt;
2010-11-24 00:45:03 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t know.&lt;br /&gt;
2010-11-24 00:45:06 &amp;lt; Dark_Shikari&amp;gt; Ask kemuri-_9&lt;br /&gt;
2010-11-24 00:45:25 &amp;lt; kemuri-_9&amp;gt; i don&#039;t know enough about libavfilter to say anything on that&lt;br /&gt;
2010-11-24 00:46:01 &amp;lt; Kovensky&amp;gt; though when the filtering system thing was started libavfilter was still vaporware&lt;br /&gt;
2010-11-24 00:46:07 &amp;lt; Kovensky&amp;gt; isn&#039;t it still vaporware, or is it getting somewhere now?&lt;br /&gt;
2010-11-24 00:46:13 &amp;lt; Dark_Shikari&amp;gt; no, it works&lt;br /&gt;
2010-11-24 00:46:19 &amp;lt; Jumpyshoes&amp;gt; http://privatepaste.com/2ebbfd4a33&lt;br /&gt;
2010-11-24 00:46:46 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: 1) replace m7 with m6&lt;br /&gt;
2010-11-24 00:46:49 &amp;lt; Dark_Shikari&amp;gt; 2) replace 2,2 with 2,2,7&lt;br /&gt;
2010-11-24 00:47:18 &amp;lt; Jumpyshoes&amp;gt; should i xor out m6 too then?&lt;br /&gt;
2010-11-24 00:47:24 &amp;lt; Dark_Shikari&amp;gt; yes, I mean replace all instances&lt;br /&gt;
2010-11-24 00:47:29 &amp;lt; Dark_Shikari&amp;gt; this won&#039;t affect correctness&lt;br /&gt;
2010-11-24 00:47:30 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-24 00:48:09 &amp;lt; bcoudurier&amp;gt; hi guys&lt;br /&gt;
2010-11-24 00:48:10 &amp;lt; pengvado&amp;gt; verdict: getting rid of duplicate code is good, but O(1) code for filterchain generation is less important than all of the individual filters&lt;br /&gt;
2010-11-24 00:48:11  * Dark_Shikari summons bcoudurier &lt;br /&gt;
2010-11-24 00:48:41 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: looks largely right.  this means it&#039;s debugging time ;)&lt;br /&gt;
2010-11-24 00:48:58 &amp;lt; Jumpyshoes&amp;gt; sigh&lt;br /&gt;
2010-11-24 00:49:09 &amp;lt; Dark_Shikari&amp;gt; see TEST_IDCT in checkasm.c&lt;br /&gt;
2010-11-24 00:49:16 &amp;lt; Dark_Shikari&amp;gt;         if( memcmp( pbuf3, pbuf4, 32*32 * sizeof(pixel) ) ) \&lt;br /&gt;
2010-11-24 00:49:22 &amp;lt; Dark_Shikari&amp;gt; before that line, print out the contents of pbuf3 and pbuf4, and compare&lt;br /&gt;
2010-11-24 00:49:42 &amp;lt; Dark_Shikari&amp;gt; this will help you find your ug&lt;br /&gt;
2010-11-24 00:49:45 &amp;lt; Dark_Shikari&amp;gt; *bug&lt;br /&gt;
2010-11-24 00:49:46 &amp;lt; Jumpyshoes&amp;gt; what are pbuf3 and pbuf4?&lt;br /&gt;
2010-11-24 00:49:56 &amp;lt; Jumpyshoes&amp;gt; strings?&lt;br /&gt;
2010-11-24 00:50:02 &amp;lt; Dark_Shikari&amp;gt; pixel buffers&lt;br /&gt;
2010-11-24 00:50:04 &amp;lt; Dark_Shikari&amp;gt; just memory.&lt;br /&gt;
2010-11-24 00:50:07 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-24 00:50:28 &amp;lt; Jumpyshoes&amp;gt; how do i print just a block of memory?&lt;br /&gt;
2010-11-24 00:50:35 &amp;lt; Dark_Shikari&amp;gt; pengvado: so this means....&lt;br /&gt;
2010-11-24 00:50:37 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes:&lt;br /&gt;
2010-11-24 00:50:49 &amp;lt; Dark_Shikari&amp;gt; oh yeah, and you should print this inside the if where it fails&lt;br /&gt;
2010-11-24 00:50:52 &amp;lt; Dark_Shikari&amp;gt; so it only prints for the broken one&lt;br /&gt;
2010-11-24 00:50:55 &amp;lt; Dark_Shikari&amp;gt; for( int y = 0; y &amp;lt; 4; y++ )&lt;br /&gt;
2010-11-24 00:51:01 &amp;lt; Dark_Shikari&amp;gt; for( int x = 0; x &amp;lt; 4; x++ )&lt;br /&gt;
2010-11-24 00:51:08  * kemuri-_9 sees a vf_scale and looks&lt;br /&gt;
2010-11-24 00:51:23 &amp;lt; Dark_Shikari&amp;gt; printf(&amp;quot;%d &amp;quot;,pbuf3[x+y*FEC_STRIDE])&lt;br /&gt;
2010-11-24 00:51:25 &amp;lt; Dark_Shikari&amp;gt; *FDEC_STRIDE&lt;br /&gt;
2010-11-24 00:51:28 &amp;lt; Dark_Shikari&amp;gt; plus whatever line breaks you need&lt;br /&gt;
2010-11-24 00:53:37 &amp;lt; pengvado&amp;gt; if there is something that libavfilter&#039;s framework doesn&#039;t support, and bikeshedding prevents patching libavfilter, and I can&#039;t just commit it to libavfilter anyway, then I&#039;ll tolerate a duplicate filterchain generator&lt;br /&gt;
2010-11-24 00:54:20 &amp;lt; Dark_Shikari&amp;gt; wrappers allows us to make the syntax less retarded while avoiding duplicating internal code&lt;br /&gt;
2010-11-24 00:54:29 &amp;lt; Dark_Shikari&amp;gt; now, the real problem here is just one of getting people to implement things&lt;br /&gt;
2010-11-24 00:54:36 &amp;lt; Dark_Shikari&amp;gt; without someone willing to do it, it won&#039;t happen&lt;br /&gt;
2010-11-24 00:54:46 &amp;lt; Dark_Shikari&amp;gt; and I don&#039;t want to sit around for 1 year with a half-completed filter system&lt;br /&gt;
2010-11-24 00:54:50 &amp;lt; Dark_Shikari&amp;gt; that half-duplicates half-code&lt;br /&gt;
2010-11-24 00:54:52 &amp;lt; Dark_Shikari&amp;gt; in a half-assed manner&lt;br /&gt;
2010-11-24 00:55:05 &amp;lt; Jumpyshoes&amp;gt; hrm, so the first row is right, everything from there dies&lt;br /&gt;
2010-11-24 00:55:32 &amp;lt; Dark_Shikari&amp;gt; the exact way in which it&#039;s wrong is often useful.&lt;br /&gt;
2010-11-24 00:55:46 &amp;lt; Dark_Shikari&amp;gt; *useful to know&lt;br /&gt;
2010-11-24 00:56:05 &amp;lt; bcoudurier&amp;gt; pengvado, I&#039;ll personally fight against any bikeshedding&lt;br /&gt;
2010-11-24 00:56:29 &amp;lt; Dark_Shikari&amp;gt; kemuri-_9 / J_Darnley since you&#039;re the people actually writing this stuff, I&#039;d like to know your thoughts&lt;br /&gt;
2010-11-24 00:56:39 &amp;lt; Dark_Shikari&amp;gt; you can get the 16-bit hqdn3d committed to libavfilter&lt;br /&gt;
2010-11-24 00:56:51 &amp;lt; Jumpyshoes&amp;gt; http://privatepaste.com/b452d32e20 first row seems right, everything else seems to be random&lt;br /&gt;
2010-11-24 00:57:08 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: oh duh&lt;br /&gt;
2010-11-24 00:57:11 &amp;lt; Dark_Shikari&amp;gt; 0*FDEC_STRIDE&lt;br /&gt;
2010-11-24 00:57:13 &amp;lt; Dark_Shikari&amp;gt; 2*FDEC_STRIDE&lt;br /&gt;
2010-11-24 00:57:14 &amp;lt; Dark_Shikari&amp;gt; 4*FDEC_STRIDE&lt;br /&gt;
2010-11-24 00:57:16 &amp;lt; Dark_Shikari&amp;gt; not 0/1/2/3&lt;br /&gt;
2010-11-24 00:57:20 &amp;lt; Dark_Shikari&amp;gt; because the pixels are 2 bytes each&lt;br /&gt;
2010-11-24 00:57:24 &amp;lt; Jumpyshoes&amp;gt; derp&lt;br /&gt;
2010-11-24 00:57:30 &amp;lt; Dark_Shikari&amp;gt; I should have caught that dmanit.&lt;br /&gt;
2010-11-24 00:57:39 &amp;lt; Jumpyshoes&amp;gt; i shoulda too&lt;br /&gt;
2010-11-24 00:57:45 &amp;lt; Jumpyshoes&amp;gt; i considered that for a very long time&lt;br /&gt;
2010-11-24 00:57:51 &amp;lt; Jumpyshoes&amp;gt; when i was using the wrong STORE_DIFF&lt;br /&gt;
2010-11-24 00:58:12 &amp;lt; Jumpyshoes&amp;gt; x264: All tests passed Yeah :)&lt;br /&gt;
2010-11-24 00:58:19 &amp;lt; kemuri-_9&amp;gt; &amp;quot;AVFilterPad type. Only video supported now, hopefully someone will add audio in the future.&amp;quot; &amp;lt;--- lol, this concept looks familiar&lt;br /&gt;
2010-11-24 00:58:38 &amp;lt; pengvado&amp;gt; I didn&#039;t comment on it because I thought Dark_Shikari noticed the error and was socratically questioning Jumpyshoes&lt;br /&gt;
2010-11-24 00:58:56 &amp;lt; Jumpyshoes&amp;gt; ;-;&lt;br /&gt;
2010-11-24 00:59:13 &amp;lt; Dark_Shikari&amp;gt; LOL&lt;br /&gt;
2010-11-24 00:59:16 &amp;lt; Kovensky&amp;gt; lol&lt;br /&gt;
2010-11-24 00:59:34 &amp;lt; Kovensky&amp;gt; Dark_Shikari: loren.html?&lt;br /&gt;
2010-11-24 00:59:42 &amp;lt; Dark_Shikari&amp;gt; ohdear.jpg&lt;br /&gt;
2010-11-24 00:59:46 &amp;lt; Jumpyshoes&amp;gt; okay, should i macro-ize this, or leave it as is?&lt;br /&gt;
2010-11-24 00:59:59 &amp;lt; Jumpyshoes&amp;gt; i feel like if i mess with it, it&#039;ll blow up beyond all repair and i will be sad&lt;br /&gt;
2010-11-24 01:00:30 &amp;lt; Dark_Shikari&amp;gt; make a macro right above your function&lt;br /&gt;
2010-11-24 01:00:32 &amp;lt; Dark_Shikari&amp;gt; called STORE_DIFFx2&lt;br /&gt;
2010-11-24 01:00:45 &amp;lt; Dark_Shikari&amp;gt; it should do two rows worth&lt;br /&gt;
2010-11-24 01:00:50 &amp;lt; Dark_Shikari&amp;gt; so then call it twice.&lt;br /&gt;
2010-11-24 01:01:05 &amp;lt; Jumpyshoes&amp;gt; sigh, very well&lt;br /&gt;
2010-11-24 01:01:13 &amp;lt; Dark_Shikari&amp;gt; You&#039;ll be writing your first macro!&lt;br /&gt;
2010-11-24 01:01:36 &amp;lt; Jumpyshoes&amp;gt; i will!&lt;br /&gt;
2010-11-24 01:02:48 &amp;lt; bcoudurier&amp;gt; kemuri-_9 audio is added right now&lt;br /&gt;
2010-11-24 01:04:10 &amp;lt; kemuri-_9&amp;gt; I have no current problems with focusing filtering into libavfilter, it&#039;s just more difficult for me as i wrote the current filtering system for x264cli and now i have to learn a completely different one.&lt;br /&gt;
2010-11-24 01:05:21 &amp;lt; Dark_Shikari&amp;gt; kemuri-_9: if you want we can keep the x264 filter chain and just outsource individual filters&lt;br /&gt;
2010-11-24 01:05:25 &amp;lt; Dark_Shikari&amp;gt; the main issue is:&lt;br /&gt;
2010-11-24 01:05:29 &amp;lt; Dark_Shikari&amp;gt; a) libavfilter is getting lots of free development with cool filters&lt;br /&gt;
2010-11-24 01:05:41 &amp;lt; Dark_Shikari&amp;gt; b) bcoudurier has been yelling at me like a chicken with its head cut off&lt;br /&gt;
2010-11-24 01:05:44 &amp;lt; Dark_Shikari&amp;gt; c) pengvado has spoken&lt;br /&gt;
2010-11-24 01:06:12 &amp;lt; kierank&amp;gt; the downside is all the bikeshedding&lt;br /&gt;
2010-11-24 01:06:43 &amp;lt; bcoudurier&amp;gt; I hear you&lt;br /&gt;
2010-11-24 01:07:09 &amp;lt; bcoudurier&amp;gt; bikeshedding is terrible, I&#039;ll do something about it&lt;br /&gt;
2010-11-24 01:07:20 &amp;lt; kemuri-_9&amp;gt; at the bare minimum i agree with using what&#039;s available in libavfilter in some form or fashion (whether we ditch the current system or wrap it), we&#039;ll have to discuss putting new filters into libavfilter as they come along and see if libavfilter will accept them or say &#039;gtfo&#039;&lt;br /&gt;
2010-11-24 01:07:49 &amp;lt; Dark_Shikari&amp;gt; so, bcoudurier, you can get people to help mentor for libavfilter?&lt;br /&gt;
2010-11-24 01:07:54 &amp;lt; Dark_Shikari&amp;gt; if so, we&#039;ll also need them to mentor kemuri-_9 =p&lt;br /&gt;
2010-11-24 01:08:01 &amp;lt; kemuri-_9&amp;gt; :&amp;lt;&lt;br /&gt;
2010-11-24 01:08:05 &amp;lt; kemuri-_9&amp;gt; sadly&lt;br /&gt;
2010-11-24 01:08:08 &amp;lt; kierank&amp;gt; and can the bitdepth problem be sorted out ;)&lt;br /&gt;
2010-11-24 01:08:35 &amp;lt; Dark_Shikari&amp;gt; we&#039;re keeping the depth filter for now&lt;br /&gt;
2010-11-24 01:08:40 &amp;lt; kierank&amp;gt; the advantage to the x264 filter system was it didn&#039;t try to be a jack of all trades&lt;br /&gt;
2010-11-24 01:08:43 &amp;lt; Dark_Shikari&amp;gt; i.e. libavfilter will still do 8-bit and 16-bit&lt;br /&gt;
2010-11-24 01:08:46 &amp;lt; Dark_Shikari&amp;gt; and not 10-bit&lt;br /&gt;
2010-11-24 01:08:51 &amp;lt; Dark_Shikari&amp;gt; and the depth filter will convert for us&lt;br /&gt;
2010-11-24 01:08:59 &amp;lt; Dark_Shikari&amp;gt; kierank: we can keep doing that, actually&lt;br /&gt;
2010-11-24 01:09:02 &amp;lt; Dark_Shikari&amp;gt; if we just wrap filters&lt;br /&gt;
2010-11-24 01:09:07 &amp;lt; Dark_Shikari&amp;gt; then the filters will only do what we let them do&lt;br /&gt;
2010-11-24 01:09:50 &amp;lt; bcoudurier&amp;gt; yes, I can mentor as well, and we&#039;ll be glad to do so&lt;br /&gt;
2010-11-24 01:09:59 &amp;lt; bcoudurier&amp;gt; kemuri, ask me any question&lt;br /&gt;
2010-11-24 01:11:07 &amp;lt; kemuri-_9&amp;gt; the only current problem i see immediately is the csp difference between libavfilter and the x264cli filter system, e.g. x264cli recognizes some csps that libavfilter does not (and technically vice versa)&lt;br /&gt;
2010-11-24 01:12:23 &amp;lt; kemuri-_9&amp;gt; bcoudurier: thanks i&#039;ll ask when the time comes, which is not largely now, i have other things i want to get done for x264 before really messing with libavfilter&lt;br /&gt;
2010-11-24 01:12:41 &amp;lt; Dark_Shikari&amp;gt; bcoudurier: we do want to smuggle students into ffmpeg for GCI though&lt;br /&gt;
2010-11-24 01:12:43 &amp;lt; Dark_Shikari&amp;gt; and that&#039;s really near term&lt;br /&gt;
2010-11-24 01:12:48 &amp;lt; Dark_Shikari&amp;gt; GCI literally just started and I got fucking flooded today&lt;br /&gt;
2010-11-24 01:13:37 &amp;lt; kemuri-_9&amp;gt; how&#039;s that going to work, ffmpeg didn&#039;t get accepted by GCI right?&lt;br /&gt;
2010-11-24 01:13:52 &amp;lt; Dark_Shikari&amp;gt; exactly&lt;br /&gt;
2010-11-24 01:13:56 &amp;lt; Dark_Shikari&amp;gt; and we want video filters in x264&lt;br /&gt;
2010-11-24 01:13:56 &amp;lt; rfw&amp;gt; i assume it&#039;s something like &amp;quot;hay kid wanna work in ffmpeg&amp;quot;&lt;br /&gt;
2010-11-24 01:14:06 &amp;lt; Dark_Shikari&amp;gt; so everyone who &amp;quot;does a filter&amp;quot; for x264&lt;br /&gt;
2010-11-24 01:14:09 &amp;lt; Dark_Shikari&amp;gt; will instead port to libavfilter!&lt;br /&gt;
2010-11-24 01:14:11 &amp;lt; Dark_Shikari&amp;gt; problem solved.&lt;br /&gt;
2010-11-24 01:14:19 &amp;lt; Dark_Shikari&amp;gt; trivial.&lt;br /&gt;
2010-11-24 01:14:34 &amp;lt; Dark_Shikari&amp;gt; We intended to do this from the start -- the instant ffmpeg wasn&#039;t accepted, we were going to add Videolan/x264 tasks that were just to work on ffmpeg.&lt;br /&gt;
2010-11-24 01:14:37 &amp;lt; Dark_Shikari&amp;gt; It&#039;s perfectly legit =p&lt;br /&gt;
2010-11-24 01:14:49 &amp;lt; rfw&amp;gt; apart from the fact it&#039;s not videolan? :D&lt;br /&gt;
2010-11-24 01:14:51 &amp;lt; kemuri-_9&amp;gt; seems like cheating the system but not like i a real voice in the issue&lt;br /&gt;
2010-11-24 01:14:58 &amp;lt; kemuri-_9&amp;gt; i have a*&lt;br /&gt;
2010-11-24 01:15:00 &amp;lt; kierank&amp;gt; boo hoo&lt;br /&gt;
2010-11-24 01:15:02 &amp;lt; kierank&amp;gt; google is so sad&lt;br /&gt;
2010-11-24 01:15:04 &amp;lt; Dark_Shikari&amp;gt; videolan uses ffmpeg&lt;br /&gt;
2010-11-24 01:15:04 &amp;lt; kierank&amp;gt; ;)&lt;br /&gt;
2010-11-24 01:15:06 &amp;lt; Dark_Shikari&amp;gt; x264 uses ffmpeg&lt;br /&gt;
2010-11-24 01:15:08 &amp;lt; Dark_Shikari&amp;gt; I think it&#039;s legit&lt;br /&gt;
2010-11-24 01:15:09 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-24 01:15:14 &amp;lt; rfw&amp;gt; yes but ffmpeg isn&#039;t part of videolan :3&lt;br /&gt;
2010-11-24 01:15:28 &amp;lt; Dark_Shikari&amp;gt; It might as well be, videolan is going to host ffmpeg&#039;s source now&lt;br /&gt;
2010-11-24 01:15:29 &amp;lt; kierank&amp;gt; Dark_Shikari: I think it&#039;s legit&lt;br /&gt;
2010-11-24 01:15:34 &amp;lt; kierank&amp;gt; x264 needs filters&lt;br /&gt;
2010-11-24 01:15:35 &amp;lt; Dark_Shikari&amp;gt; they&#039;re moving to git, and videolan will host it&lt;br /&gt;
2010-11-24 01:15:41 &amp;lt; rfw&amp;gt; ah&lt;br /&gt;
2010-11-24 01:15:49 &amp;lt; kierank&amp;gt; we decide that we&#039;re going to use libavfilter because of duplicated work&lt;br /&gt;
2010-11-24 01:15:50 &amp;lt; rfw&amp;gt; all hail git \o/&lt;br /&gt;
2010-11-24 01:15:52 &amp;lt; kierank&amp;gt; that&#039;s it&lt;br /&gt;
2010-11-24 01:15:53 &amp;lt; Dark_Shikari&amp;gt; kierank: yup&lt;br /&gt;
2010-11-24 01:16:03 &amp;lt; Dark_Shikari&amp;gt; seems fine to me.&lt;br /&gt;
2010-11-24 01:17:36 &amp;lt; rfw&amp;gt; after writing so many finally clauses i think i see why people use finally&lt;br /&gt;
2010-11-24 01:17:51 &amp;lt; Dark_Shikari&amp;gt; you should have started that sentence with &amp;quot;finally&amp;quot;&lt;br /&gt;
2010-11-24 01:18:04 &amp;lt; rfw&amp;gt; s/after/finally after/&lt;br /&gt;
2010-11-24 01:18:09 &amp;lt; rfw&amp;gt; problem solved&lt;br /&gt;
2010-11-24 01:18:50 &amp;lt; rfw&amp;gt; now how did i do my bisection again&lt;br /&gt;
2010-11-24 01:18:55 &amp;lt; Dark_Shikari&amp;gt; magic&lt;br /&gt;
2010-11-24 01:19:09 &amp;lt; rfw&amp;gt; i hate magic :(&lt;br /&gt;
2010-11-24 01:20:16 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, I AM DONE&lt;br /&gt;
2010-11-24 01:20:30 &amp;lt; Dark_Shikari&amp;gt; woohoooo&lt;br /&gt;
2010-11-24 01:20:35 &amp;lt; Dark_Shikari&amp;gt; now I just have to harass irock to fix his shit&lt;br /&gt;
2010-11-24 01:20:40 &amp;lt; JEEBsv&amp;gt; lol&lt;br /&gt;
2010-11-24 01:20:43 &amp;lt; Jumpyshoes&amp;gt; now what do i do&lt;br /&gt;
2010-11-24 01:20:46 &amp;lt; Dark_Shikari&amp;gt; and harass pengvado to make a checkasm test that demosntrates that irock&#039;s shit is broken&lt;br /&gt;
2010-11-24 01:20:50 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: post your patch!&lt;br /&gt;
2010-11-24 01:21:00 &amp;lt; Jumpyshoes&amp;gt; do a diff?&lt;br /&gt;
2010-11-24 01:21:07 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-24 01:21:17 &amp;lt; Dark_Shikari&amp;gt; then I will need from you three things!&lt;br /&gt;
2010-11-24 01:21:49 &amp;lt; Jumpyshoes&amp;gt; ?&lt;br /&gt;
2010-11-24 01:21:50 &amp;lt; Dark_Shikari&amp;gt; Your name, your email, and a response to the thing I send you via email!&lt;br /&gt;
2010-11-24 01:22:18 &amp;lt; kemuri-_9&amp;gt; CLA powar&lt;br /&gt;
2010-11-24 01:22:24 &amp;lt; Jumpyshoes&amp;gt; i should probably test the 8-bit&lt;br /&gt;
2010-11-24 01:22:31 &amp;lt; Jumpyshoes&amp;gt; to make sure i didn&#039;t massively f something else up&lt;br /&gt;
2010-11-24 01:22:49 &amp;lt; Dark_Shikari&amp;gt; Yup, of course&lt;br /&gt;
2010-11-24 01:22:52 &amp;lt; Dark_Shikari&amp;gt; and post the patch so I can review it!&lt;br /&gt;
2010-11-24 01:22:57 &amp;lt; Dark_Shikari&amp;gt; I will nitpick it in minor ways!&lt;br /&gt;
2010-11-24 01:23:01 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 01:24:07 &amp;lt; Jumpyshoes&amp;gt; after i test 8-bit i&#039;ll post&lt;br /&gt;
2010-11-24 01:25:15 &amp;lt; Jumpyshoes&amp;gt; great&lt;br /&gt;
2010-11-24 01:25:27 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/nzybLAmG inb4 i get my ass handed to me&lt;br /&gt;
2010-11-24 01:26:11 &amp;lt; Dark_Shikari&amp;gt; email sent&lt;br /&gt;
2010-11-24 01:26:17 &amp;lt; Dark_Shikari&amp;gt; now for review!&lt;br /&gt;
2010-11-24 01:26:51 &amp;lt; Dark_Shikari&amp;gt; 266/269/271: drop the extra spaces&lt;br /&gt;
2010-11-24 01:27:03 &amp;lt; Dark_Shikari&amp;gt; in that whole macro, align everything so that the commas are aligned&lt;br /&gt;
2010-11-24 01:27:08 &amp;lt; Dark_Shikari&amp;gt; 272: extra spaces, etc&lt;br /&gt;
2010-11-24 01:27:14 &amp;lt; Dark_Shikari&amp;gt; 293 has extra spaces too&lt;br /&gt;
2010-11-24 01:27:23 &amp;lt; Dark_Shikari&amp;gt; does your editor have weird tabbing or something?&lt;br /&gt;
2010-11-24 01:27:27 &amp;lt; Dark_Shikari&amp;gt; fyi we use 4-space tabs&lt;br /&gt;
2010-11-24 01:27:30 &amp;lt; Jumpyshoes&amp;gt; oh, yea&lt;br /&gt;
2010-11-24 01:27:31 &amp;lt; Dark_Shikari&amp;gt; 306-307: pointless change&lt;br /&gt;
2010-11-24 01:27:33 &amp;lt; Jumpyshoes&amp;gt; notepad++ defaults to single tab&lt;br /&gt;
2010-11-24 01:27:47 &amp;lt; Dark_Shikari&amp;gt; fix that, and find all your tabs and fix them&lt;br /&gt;
2010-11-24 01:27:51 &amp;lt; Dark_Shikari&amp;gt; 595: pointless change&lt;br /&gt;
2010-11-24 01:27:55 &amp;lt; Dark_Shikari&amp;gt; ok, first pass done.&lt;br /&gt;
2010-11-24 01:27:57 &amp;lt; Dark_Shikari&amp;gt; fix those and post it again&lt;br /&gt;
2010-11-24 01:28:00 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-24 01:28:50 &amp;lt; Jumpyshoes&amp;gt; oh btw&lt;br /&gt;
2010-11-24 01:28:52 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-24 01:28:54 &amp;lt; Jumpyshoes&amp;gt; i don&#039;t think this is an updated verion of x264&lt;br /&gt;
2010-11-24 01:29:00 &amp;lt; Dark_Shikari&amp;gt; what do you mean&lt;br /&gt;
2010-11-24 01:29:00 &amp;lt; espes&amp;gt; Dark_Shikari: so, what, am I still writing an x264 filter?&lt;br /&gt;
2010-11-24 01:29:05 &amp;lt; Jumpyshoes&amp;gt; since i pulled 17xx and didn&#039;t bother to pull again&lt;br /&gt;
2010-11-24 01:29:10 &amp;lt; Dark_Shikari&amp;gt; espes: you&#039;ll be writing a libavfilter filter -- much the same thing&lt;br /&gt;
2010-11-24 01:29:14 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: ok, here&#039;s how you do this&lt;br /&gt;
2010-11-24 01:29:16 &amp;lt; espes&amp;gt; Dark_Shikari: right.&lt;br /&gt;
2010-11-24 01:29:17 &amp;lt; Dark_Shikari&amp;gt; git commit -a&lt;br /&gt;
2010-11-24 01:29:21 &amp;lt; Dark_Shikari&amp;gt; &amp;lt;type in your commit message, etc, etc&amp;gt;&lt;br /&gt;
2010-11-24 01:29:24 &amp;lt; Dark_Shikari&amp;gt; git pull --rebase&lt;br /&gt;
2010-11-24 01:29:26 &amp;lt; Dark_Shikari&amp;gt; now you have the latest version&lt;br /&gt;
2010-11-24 01:29:33 &amp;lt; Dark_Shikari&amp;gt; then, to modify your commit, git commit -a --amend&lt;br /&gt;
2010-11-24 01:29:37 &amp;lt; Dark_Shikari&amp;gt; to make a diff&lt;br /&gt;
2010-11-24 01:29:41 &amp;lt; Dark_Shikari&amp;gt; git format-patch HEAD~1 --stdout &amp;gt; file.&lt;br /&gt;
2010-11-24 01:29:48 &amp;lt; Dark_Shikari&amp;gt; you can also add your authorship to the patch&lt;br /&gt;
2010-11-24 01:30:05 &amp;lt; Dark_Shikari&amp;gt; by adding --author=&amp;quot;My Name &amp;lt;myemail@email.com&amp;gt;&amp;quot; to git commit&lt;br /&gt;
2010-11-24 01:30:10 &amp;lt; Dark_Shikari&amp;gt; which will list your name on it&lt;br /&gt;
2010-11-24 01:30:41 &amp;lt; Dark_Shikari&amp;gt; espes: bcoudurier here is responsible for getting someone to help you with this.  he&#039;s a cool french dude.&lt;br /&gt;
2010-11-24 01:31:03 &amp;lt; espes&amp;gt; Dark_Shikari: ehh, I think libavfilter already supports loading libmpcodec filters, so it&#039;ll already be available. :\&lt;br /&gt;
2010-11-24 01:31:24 &amp;lt; astrange&amp;gt; it doesn&#039;t&lt;br /&gt;
2010-11-24 01:31:39 &amp;lt; Jumpyshoes&amp;gt; out of curiosity, why is ftp://ftp.videolan.org/pub/videolan/x264/snapshots/ dead?&lt;br /&gt;
2010-11-24 01:32:15 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: blame j-b&lt;br /&gt;
2010-11-24 01:32:16 &amp;lt; Dark_Shikari&amp;gt; it&#039;s all j-b&#039;s fault&lt;br /&gt;
2010-11-24 01:32:22 &amp;lt; astrange&amp;gt; a lot of libmpcodec filters are a mess anyway (timestamps are broken, only x86 is supported properly, no code reviews since forever)&lt;br /&gt;
2010-11-24 01:32:32 &amp;lt; Dark_Shikari&amp;gt; Yeah, we want to move libmpcodecs into libavfilter anyways&lt;br /&gt;
2010-11-24 01:32:38 &amp;lt; Dark_Shikari&amp;gt; libmpcodecs is part of mplayer and therefore rather dead&lt;br /&gt;
2010-11-24 01:32:46 &amp;lt; Jumpyshoes&amp;gt; i don&#039;t actually know what i did in the useless changes&lt;br /&gt;
2010-11-24 01:32:56 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: shit happens, we do it too&lt;br /&gt;
2010-11-24 01:33:09 &amp;lt; espes&amp;gt; Ok, so I move the filter from libmpcodec to libavfilter and make the code not suck.&lt;br /&gt;
2010-11-24 01:33:14 &amp;lt; Dark_Shikari&amp;gt; Basically that&#039;s it.&lt;br /&gt;
2010-11-24 01:33:20 &amp;lt; Dark_Shikari&amp;gt; And 4 points per filter.&lt;br /&gt;
2010-11-24 01:33:40 &amp;lt; Dark_Shikari&amp;gt; Pick your favorites.&lt;br /&gt;
2010-11-24 01:40:07 &amp;lt; Jumpyshoes&amp;gt; oh damn, my diff doesn&#039;t show anything anymor&lt;br /&gt;
2010-11-24 01:40:07 &amp;lt; Jumpyshoes&amp;gt; e&lt;br /&gt;
2010-11-24 01:40:51 &amp;lt; JEEBsv&amp;gt; you committed it?&lt;br /&gt;
2010-11-24 01:41:05 &amp;lt; JEEBsv&amp;gt; then git format-patch HEAD~1 if it&#039;s just one commit&lt;br /&gt;
2010-11-24 01:41:57 &amp;lt; Dark_Shikari&amp;gt; brb, I&#039;m going to grab dinner&lt;br /&gt;
2010-11-24 01:42:00 &amp;lt; Jumpyshoes&amp;gt; i mean, all my changes are committed already, so diff isn&#039;t finding anything &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-24 01:42:06 &amp;lt; Jumpyshoes&amp;gt; or something&lt;br /&gt;
2010-11-24 01:42:10 &amp;lt; astrange&amp;gt; http://pastebin.com/EdLuGCN7 those are the useful filters, i think&lt;br /&gt;
2010-11-24 01:42:12 &amp;lt; Dark_Shikari&amp;gt; use format-patch&lt;br /&gt;
2010-11-24 01:42:15 &amp;lt; Dark_Shikari&amp;gt; espes: ^&lt;br /&gt;
2010-11-24 01:42:27 &amp;lt; astrange&amp;gt; actually ass is the most useful filter. but i don&#039;t think you could do that one&lt;br /&gt;
2010-11-24 01:42:31 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 01:42:31 &amp;lt; JEEBsv&amp;gt; Jumpyshoes: point on HEAD~1 (or other number depending on how many commits)&lt;br /&gt;
2010-11-24 01:43:01 &amp;lt; JEEBsv&amp;gt; thus, git format-patch HEAD~1 will produce you one patch :3 (or the stdout way)&lt;br /&gt;
2010-11-24 01:43:13 &amp;lt; JEEBsv&amp;gt; if you have more commits, f.ex. three -- HEAD~3&lt;br /&gt;
2010-11-24 01:43:33 &amp;lt; espes&amp;gt; astrange: I&#039;m told gradfun doesn&#039;t really work as a preprocessing filter...&lt;br /&gt;
2010-11-24 01:43:44 &amp;lt; espes&amp;gt; (At least that&#039;s the note in the mplayer&#039;s implementation)&lt;br /&gt;
2010-11-24 01:43:47 &amp;lt; Jumpyshoes&amp;gt; oh, so i actually have two commits&lt;br /&gt;
2010-11-24 01:44:00 &amp;lt; Jumpyshoes&amp;gt; how do i compare my current with two commits ago?&lt;br /&gt;
2010-11-24 01:44:19 &amp;lt; astrange&amp;gt; it sometimes works on bad inputs that spp/pp leave blocks on, but yes&lt;br /&gt;
2010-11-24 01:44:22 &amp;lt; JEEBsv&amp;gt; git diff HEAD~2 ?&lt;br /&gt;
2010-11-24 01:44:31 &amp;lt; Jumpyshoes&amp;gt; that gives 2 patches&lt;br /&gt;
2010-11-24 01:44:38 &amp;lt; Jumpyshoes&amp;gt; so D_S can&#039;t see my changes&lt;br /&gt;
2010-11-24 01:44:53 &amp;lt; JEEBsv&amp;gt; use the stdout way of format-patch&lt;br /&gt;
2010-11-24 01:45:02 &amp;lt; JEEBsv&amp;gt; and thus concat it into one&lt;br /&gt;
2010-11-24 01:45:10 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-24 01:45:15 &amp;lt; Jumpyshoes&amp;gt; thanks&lt;br /&gt;
2010-11-24 01:46:27 &amp;lt; espes&amp;gt; astrange: isn&#039;t colorspace conversion already done by the scale filter?&lt;br /&gt;
2010-11-24 01:47:12 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari: http://pastebin.com/YASKQLHV&lt;br /&gt;
2010-11-24 01:47:32 &amp;lt; espes&amp;gt; But if you think shelling out to swscale isn&#039;t really optimal :\&lt;br /&gt;
2010-11-24 01:48:10 &amp;lt; astrange&amp;gt; nope, the issue is ignored. but that wouldn&#039;t be a bad idea&lt;br /&gt;
2010-11-24 01:51:22 &amp;lt; JEEBsv&amp;gt; espes: gradfun has its uses even before encoding :) Just that it indeed needs more bits. Thus if the player can fix the banding, it&#039;s better of course.&lt;br /&gt;
2010-11-24 01:53:39 &amp;lt; Jumpyshoes&amp;gt; speaking of filters&lt;br /&gt;
2010-11-24 01:53:49 &amp;lt; Jumpyshoes&amp;gt; whatever happened to halomaker3000deluxe&lt;br /&gt;
2010-11-24 01:54:14 &amp;lt; JEEBsv&amp;gt; lol&lt;br /&gt;
2010-11-24 01:54:42 &amp;lt; rfw&amp;gt; python&#039;s documentation is quite questionable in places&lt;br /&gt;
2010-11-24 01:54:47 &amp;lt; rfw&amp;gt; parser.add_option(&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;,&lt;br /&gt;
2010-11-24 01:54:47 &amp;lt; rfw&amp;gt;                   action=&amp;quot;store_false&amp;quot;, dest=&amp;quot;verbose&amp;quot;,&lt;br /&gt;
2010-11-24 01:54:47 &amp;lt; rfw&amp;gt;                   help=&amp;quot;be vewwy quiet (I&#039;m hunting wabbits)&amp;quot;)&lt;br /&gt;
2010-11-24 01:54:52 &amp;lt; rfw&amp;gt; i mean, what.&lt;br /&gt;
2010-11-24 01:55:23 &amp;lt; Jumpyshoes&amp;gt; i eat rabbits&lt;br /&gt;
2010-11-24 01:55:58 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-24 01:56:07 &amp;lt; Jumpyshoes&amp;gt; i have actually eaten a rabbit before&lt;br /&gt;
2010-11-24 01:56:19 &amp;lt; rfw&amp;gt; same&lt;br /&gt;
2010-11-24 01:56:48 &amp;lt; rfw&amp;gt; Dark_Shikari: i think i&#039;m finished (lolagain)&lt;br /&gt;
2010-11-24 01:56:55 &amp;lt; rfw&amp;gt; do i have to implement linear revisions again&lt;br /&gt;
2010-11-24 01:57:45 &amp;lt; JEEBsv&amp;gt; Jumpyshoes: I think they made a new filter adding pretty fabulous rainbows on #darkhold IIRC&lt;br /&gt;
2010-11-24 01:58:06 &amp;lt; Jumpyshoes&amp;gt; what&lt;br /&gt;
2010-11-24 01:58:14 &amp;lt; Jumpyshoes&amp;gt; HM3KD WITH RAINBOWS?&lt;br /&gt;
2010-11-24 01:58:18 &amp;lt; Jumpyshoes&amp;gt; WHERE THE FUCK CAN I FIND THIS?&lt;br /&gt;
2010-11-24 01:58:32 &amp;lt; rfw&amp;gt; i wrote an hlsl shader that rainbowed everything&lt;br /&gt;
2010-11-24 01:58:41 &amp;lt; JEEBsv&amp;gt; You&#039;ll have to ask on #darkhold , I don&#039;t remember who wrote it atm&lt;br /&gt;
2010-11-24 01:58:59 &amp;lt; Jumpyshoes&amp;gt; darn&lt;br /&gt;
2010-11-24 01:59:00 &amp;lt; Jumpyshoes&amp;gt; this rizon?&lt;br /&gt;
2010-11-24 01:59:07 &amp;lt; JEEBsv&amp;gt; yah, rizon&lt;br /&gt;
2010-11-24 01:59:08 &amp;lt; rfw&amp;gt; why are we all on rizon&lt;br /&gt;
2010-11-24 01:59:25 &amp;lt; rfw&amp;gt; half of this channel is on rizon&lt;br /&gt;
2010-11-24 01:59:27 &amp;lt; rfw&amp;gt; :(&lt;br /&gt;
2010-11-24 02:05:21 &amp;lt; Dark_Shikari&amp;gt; espes: gradfun2db WOULD be useful as a preprocessing filter with x264&#039;s 10-bit&lt;br /&gt;
2010-11-24 02:05:36 &amp;lt; Dark_Shikari&amp;gt; testing has shown this&lt;br /&gt;
2010-11-24 02:05:54 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: you need to merge your patches&lt;br /&gt;
2010-11-24 02:05:59 &amp;lt; Dark_Shikari&amp;gt; you inadvertantly made two local commits instead of one&lt;br /&gt;
2010-11-24 02:06:01 &amp;lt; Jumpyshoes&amp;gt; how do i do that?&lt;br /&gt;
2010-11-24 02:06:04 &amp;lt; Dark_Shikari&amp;gt; if you do git rebase -i HEAD~2&lt;br /&gt;
2010-11-24 02:06:06 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-24 02:06:10 &amp;lt; Dark_Shikari&amp;gt; you can change one of your commits to &amp;quot;squash&amp;quot; from &amp;quot;pick&amp;quot;&lt;br /&gt;
2010-11-24 02:06:15 &amp;lt; Dark_Shikari&amp;gt; and it will squash the commits together&lt;br /&gt;
2010-11-24 02:06:22 &amp;lt; Dark_Shikari&amp;gt; remember, to edit a commit, use --amend&lt;br /&gt;
2010-11-24 02:06:56 &amp;lt; rfw&amp;gt; almost rm -rf&#039;d digress there&lt;br /&gt;
2010-11-24 02:06:57 &amp;lt; rfw&amp;gt; whoops&lt;br /&gt;
2010-11-24 02:07:17 &amp;lt; Dark_Shikari&amp;gt; you should be banned from using rm&lt;br /&gt;
2010-11-24 02:07:27 &amp;lt; rfw&amp;gt; lol&lt;br /&gt;
2010-11-24 02:07:30 &amp;lt; rfw&amp;gt; well i&#039;m on windows&lt;br /&gt;
2010-11-24 02:07:34 &amp;lt; rfw&amp;gt; so del /s /q works too&lt;br /&gt;
2010-11-24 02:07:44 &amp;lt; Dark_Shikari&amp;gt; don&#039;t use that either&lt;br /&gt;
2010-11-24 02:08:02 &amp;lt; rfw&amp;gt; well i think i&#039;m done&lt;br /&gt;
2010-11-24 02:08:07 &amp;lt; JEEBsv&amp;gt;  /s /q isn&#039;t even easy to write :/&lt;br /&gt;
2010-11-24 02:08:12 &amp;lt; Dark_Shikari&amp;gt; linear revisions? =p&lt;br /&gt;
2010-11-24 02:08:16 &amp;lt; rfw&amp;gt; do i have to&lt;br /&gt;
2010-11-24 02:08:17 &amp;lt; rfw&amp;gt; ;_;&lt;br /&gt;
2010-11-24 02:08:23 &amp;lt; Dark_Shikari&amp;gt; ok then don&#039;t&lt;br /&gt;
2010-11-24 02:08:28 &amp;lt; rfw&amp;gt; \o/&lt;br /&gt;
2010-11-24 02:08:29 &amp;lt; Dark_Shikari&amp;gt; format-patch please :)&lt;br /&gt;
2010-11-24 02:08:33 &amp;lt; Dark_Shikari&amp;gt; don&#039;t forget to git add&lt;br /&gt;
2010-11-24 02:08:57 &amp;lt; rfw&amp;gt; hold on&lt;br /&gt;
2010-11-24 02:09:01 &amp;lt; rfw&amp;gt; let me write a setuptools package&lt;br /&gt;
2010-11-24 02:09:26 &amp;lt; Jumpyshoes&amp;gt; wait, how do i merge commits?&lt;br /&gt;
2010-11-24 02:09:31 &amp;lt; rfw&amp;gt; git merge?&lt;br /&gt;
2010-11-24 02:09:33 &amp;lt; Dark_Shikari&amp;gt; use git rebase -i as I said&lt;br /&gt;
2010-11-24 02:09:38 &amp;lt; Dark_Shikari&amp;gt; and replace &amp;quot;pick&amp;quot; for one with &amp;quot;squash&amp;quot;&lt;br /&gt;
2010-11-24 02:09:41 &amp;lt; Dark_Shikari&amp;gt; read the info it gives you&lt;br /&gt;
2010-11-24 02:09:43 &amp;lt; Dark_Shikari&amp;gt; also, git help is your friend&lt;br /&gt;
2010-11-24 02:09:52 &amp;lt; Dark_Shikari&amp;gt; git rebase -i HEAD~2 will let you modify the last 2 commits&lt;br /&gt;
2010-11-24 02:09:56 &amp;lt; Dark_Shikari&amp;gt; one of the ways to modify them is squashing&lt;br /&gt;
2010-11-24 02:10:01 &amp;lt; rfw&amp;gt; my git --help launches a help browser, except it doesn&#039;t&lt;br /&gt;
2010-11-24 02:10:22 &amp;lt; Dark_Shikari&amp;gt; git help commandname&lt;br /&gt;
2010-11-24 02:10:24 &amp;lt; Dark_Shikari&amp;gt; git help rebase&lt;br /&gt;
2010-11-24 02:10:29 &amp;lt; Dark_Shikari&amp;gt; git help help&lt;br /&gt;
2010-11-24 02:13:33 &amp;lt; rfw&amp;gt; whoops&lt;br /&gt;
2010-11-24 02:13:38 &amp;lt; rfw&amp;gt; i filled my directory with .patch files&lt;br /&gt;
2010-11-24 02:13:45 &amp;lt; rfw&amp;gt; there we go&lt;br /&gt;
2010-11-24 02:13:48 &amp;lt; rfw&amp;gt; where do i submit this?&lt;br /&gt;
2010-11-24 02:13:59 &amp;lt; Dark_Shikari&amp;gt; pastebin&lt;br /&gt;
2010-11-24 02:14:11 &amp;lt; rfw&amp;gt; oh you wanted it in tools, right?&lt;br /&gt;
2010-11-24 02:14:15 &amp;lt; Dark_Shikari&amp;gt; yes&lt;br /&gt;
2010-11-24 02:14:22 &amp;lt; rfw&amp;gt; ah let me fix that&lt;br /&gt;
2010-11-24 02:15:49 &amp;lt; Jumpyshoes&amp;gt; how do i resume an interactive git rebase?&lt;br /&gt;
2010-11-24 02:16:21 &amp;lt; kemuri-_9&amp;gt; git rebase --continue&lt;br /&gt;
2010-11-24 02:16:49 &amp;lt; rfw&amp;gt; http://pastebin.com/zLbbE2KL&lt;br /&gt;
2010-11-24 02:17:27 &amp;lt; Dark_Shikari&amp;gt; rfw: does that include digress?&lt;br /&gt;
2010-11-24 02:17:30 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-24 02:17:30 &amp;lt; rfw&amp;gt; no&lt;br /&gt;
2010-11-24 02:17:36 &amp;lt; rfw&amp;gt; but that&#039;s on my github repo&lt;br /&gt;
2010-11-24 02:17:36 &amp;lt; Dark_Shikari&amp;gt; well it won&#039;t run without it, will it?&lt;br /&gt;
2010-11-24 02:17:41 &amp;lt; JEEBsv&amp;gt; lol&lt;br /&gt;
2010-11-24 02:17:42 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-24 02:17:45 &amp;lt; rfw&amp;gt; so&lt;br /&gt;
2010-11-24 02:17:48 &amp;lt; rfw&amp;gt; put that in tools too?&lt;br /&gt;
2010-11-24 02:17:50 &amp;lt; Dark_Shikari&amp;gt; I guess?&lt;br /&gt;
2010-11-24 02:17:54 &amp;lt; rfw&amp;gt; heh&lt;br /&gt;
2010-11-24 02:18:01 &amp;lt; rfw&amp;gt; am i going to have to include python&lt;br /&gt;
2010-11-24 02:18:05 &amp;lt; rfw&amp;gt; and glibc :p&lt;br /&gt;
2010-11-24 02:18:54 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 02:18:59 &amp;lt; Dark_Shikari&amp;gt; digress isn&#039;t something you can install with apt-get =p&lt;br /&gt;
2010-11-24 02:19:30 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/GBSUtExQ&lt;br /&gt;
2010-11-24 02:20:37 &amp;lt; rfw&amp;gt; maybe i should do a debian task next&lt;br /&gt;
2010-11-24 02:20:41 &amp;lt; rfw&amp;gt; and include it in their apt repositories&lt;br /&gt;
2010-11-24 02:20:42 &amp;lt; rfw&amp;gt; :D&lt;br /&gt;
2010-11-24 02:21:14 &amp;lt; rfw&amp;gt; http://pastebin.com/Atb7j4DV&lt;br /&gt;
2010-11-24 02:22:05 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: in your STORE_DIFFx2, the , should all be vertically aligned&lt;br /&gt;
2010-11-24 02:22:07 &amp;lt; Dark_Shikari&amp;gt; the first , in each line, that is&lt;br /&gt;
2010-11-24 02:22:15 &amp;lt; Dark_Shikari&amp;gt; so add spaces as necessary&lt;br /&gt;
2010-11-24 02:22:16 &amp;lt; Dark_Shikari&amp;gt; e.g.&lt;br /&gt;
2010-11-24 02:22:21 &amp;lt; Dark_Shikari&amp;gt; packssdw %1, %2&lt;br /&gt;
2010-11-24 02:22:24 &amp;lt; Jumpyshoes&amp;gt; oh right&lt;br /&gt;
2010-11-24 02:22:26 &amp;lt; Dark_Shikari&amp;gt; movq     %3, %4&lt;br /&gt;
2010-11-24 02:22:46 &amp;lt; Dark_Shikari&amp;gt; junk spaces are still around on line 306&lt;br /&gt;
2010-11-24 02:22:57 &amp;lt; Dark_Shikari&amp;gt; 304 line break is needless&lt;br /&gt;
2010-11-24 02:23:05 &amp;lt; Dark_Shikari&amp;gt; other than that lgtm&lt;br /&gt;
2010-11-24 02:23:26 &amp;lt; Jumpyshoes&amp;gt; kk&lt;br /&gt;
2010-11-24 02:25:53 &amp;lt; rfw&amp;gt; actually Dark_Shikari&lt;br /&gt;
2010-11-24 02:25:59 &amp;lt; rfw&amp;gt; can&#039;t i add my repo as a submodule&lt;br /&gt;
2010-11-24 02:26:18 &amp;lt; Dark_Shikari&amp;gt; I would really rather not do that.&lt;br /&gt;
2010-11-24 02:26:23 &amp;lt; rfw&amp;gt; i guess&lt;br /&gt;
2010-11-24 02:26:25 &amp;lt; Dark_Shikari&amp;gt; pengvado has the final word though&lt;br /&gt;
2010-11-24 02:26:32 &amp;lt; Dark_Shikari&amp;gt; actually yeah, pengvado, can you comment on this in general?&lt;br /&gt;
2010-11-24 02:26:37 &amp;lt; Dark_Shikari&amp;gt; python regression test script of magic&lt;br /&gt;
2010-11-24 02:27:23 &amp;lt; pengvado&amp;gt; you mean comment on the magic part, or the python?&lt;br /&gt;
2010-11-24 02:28:17 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 02:28:25 &amp;lt; Dark_Shikari&amp;gt; python isn&#039;t magic?&lt;br /&gt;
2010-11-24 02:28:56 &amp;lt; rfw&amp;gt; now to delete every file recovery tool i installed&lt;br /&gt;
2010-11-24 02:29:13 &amp;lt; Dark_Shikari&amp;gt; lol&lt;br /&gt;
2010-11-24 02:29:19 &amp;lt; pengvado&amp;gt; I don&#039;t see an &amp;quot;import magic&amp;quot;, so no&lt;br /&gt;
2010-11-24 02:29:47 &amp;lt; rfw&amp;gt; i should&#039;ve probably called it magic, then&lt;br /&gt;
2010-11-24 02:30:04 &amp;lt; Dark_Shikari&amp;gt; pengvado: seriously though&lt;br /&gt;
2010-11-24 02:30:20 &amp;lt; Dark_Shikari&amp;gt; topics like &amp;quot;can we just dump this in tools/&amp;quot;&lt;br /&gt;
2010-11-24 02:32:08 &amp;lt; pengvado&amp;gt; I haven&#039;t been following the featurelist, but my general comment on &amp;quot;can we just dump a regression tester in tools/&amp;quot; is &amp;quot;yes&amp;quot;&lt;br /&gt;
2010-11-24 02:32:21 &amp;lt; Dark_Shikari&amp;gt; pengvado: any particular features you want to make sure are in there?&lt;br /&gt;
2010-11-24 02:32:26 &amp;lt; Dark_Shikari&amp;gt; since I imagine you might want to use it too&lt;br /&gt;
2010-11-24 02:33:24 &amp;lt; Jumpyshoes&amp;gt; http://pastebin.com/CEAfyzMd okay, tested w/ 8 and 10 bit&lt;br /&gt;
2010-11-24 02:35:13 &amp;lt; Dark_Shikari&amp;gt; er&lt;br /&gt;
2010-11-24 02:35:15 &amp;lt; Dark_Shikari&amp;gt; you&#039;re pxoring m7&lt;br /&gt;
2010-11-24 02:35:21 &amp;lt; Dark_Shikari&amp;gt; an then using m6?&lt;br /&gt;
2010-11-24 02:36:13 &amp;lt; Jumpyshoes&amp;gt; well, pxor was used in the other function&lt;br /&gt;
2010-11-24 02:36:24 &amp;lt; Dark_Shikari&amp;gt; you&#039;re pxoring m7&lt;br /&gt;
2010-11-24 02:36:25 &amp;lt; Jumpyshoes&amp;gt; oh wait&lt;br /&gt;
2010-11-24 02:36:26 &amp;lt; Dark_Shikari&amp;gt; you never use m7 again&lt;br /&gt;
2010-11-24 02:36:26 &amp;lt; Jumpyshoes&amp;gt; you&#039;re right&lt;br /&gt;
2010-11-24 02:36:27 &amp;lt; Jumpyshoes&amp;gt; i am&lt;br /&gt;
2010-11-24 02:36:49 &amp;lt; Jumpyshoes&amp;gt; yea, i can get rid of that&lt;br /&gt;
2010-11-24 02:36:53 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll fix it locally&lt;br /&gt;
2010-11-24 02:36:54 &amp;lt; Jumpyshoes&amp;gt; the dangers of copoy pasta&lt;br /&gt;
2010-11-24 02:37:44 &amp;lt; Dark_Shikari&amp;gt; aha&lt;br /&gt;
2010-11-24 02:37:46 &amp;lt; Dark_Shikari&amp;gt; your patch fails to apply&lt;br /&gt;
2010-11-24 02:37:48 &amp;lt; Dark_Shikari&amp;gt; trailing whitespace&lt;br /&gt;
2010-11-24 02:37:52 &amp;lt; Dark_Shikari&amp;gt; lines 294, 297, 298, 299&lt;br /&gt;
2010-11-24 02:38:47 &amp;lt; Jumpyshoes&amp;gt; wait, what?&lt;br /&gt;
2010-11-24 02:38:57 &amp;lt; Dark_Shikari&amp;gt; whitespace at the end of lines&lt;br /&gt;
2010-11-24 02:39:04 &amp;lt; Dark_Shikari&amp;gt; git yells about them when I try to apply your patch&lt;br /&gt;
2010-11-24 02:39:11 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-24 02:39:14 &amp;lt; Jumpyshoes&amp;gt; you can&#039;t do that?&lt;br /&gt;
2010-11-24 02:39:23 &amp;lt; Dark_Shikari&amp;gt; I guess I could edit the patch manually ok&lt;br /&gt;
2010-11-24 02:39:29 &amp;lt; Jumpyshoes&amp;gt; sorry, i didn&#039;t know&lt;br /&gt;
2010-11-24 02:40:25 &amp;lt; kemuri-_9&amp;gt; notepad++ &amp;gt; textfx edit &amp;gt; trim trailing whitespace  &amp;lt;--- works wonders&lt;br /&gt;
2010-11-24 02:41:56 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes:&lt;br /&gt;
2010-11-24 02:41:59 &amp;lt; Dark_Shikari&amp;gt; original function: 188 cycles&lt;br /&gt;
2010-11-24 02:42:00 &amp;lt; Dark_Shikari&amp;gt; yours: 30&lt;br /&gt;
2010-11-24 02:42:13 &amp;lt; pengvado&amp;gt; kemuri-_9: does it parse diffs and not strip syntactically significant trailing whitespace?&lt;br /&gt;
2010-11-24 02:42:28 &amp;lt; Jumpyshoes&amp;gt; :O?&lt;br /&gt;
2010-11-24 02:42:29 &amp;lt; Dark_Shikari&amp;gt; pengvado: I think he meant on the code&lt;br /&gt;
2010-11-24 02:42:30 &amp;lt; Dark_Shikari&amp;gt; =p&lt;br /&gt;
2010-11-24 02:42:33 &amp;lt; Dark_Shikari&amp;gt; not the diff&lt;br /&gt;
2010-11-24 02:42:35 &amp;lt; Jumpyshoes&amp;gt; so speedup of about 6x?&lt;br /&gt;
2010-11-24 02:42:38 &amp;lt; Dark_Shikari&amp;gt; yes, for that function&lt;br /&gt;
2010-11-24 02:42:53 &amp;lt; Jumpyshoes&amp;gt; woah, that&#039;s cool&lt;br /&gt;
2010-11-24 02:43:31 &amp;lt; Dark_Shikari&amp;gt; http://pastebin.com/e0aa966g&lt;br /&gt;
2010-11-24 02:43:33 &amp;lt; kemuri-_9&amp;gt; yeah, on the code - should do it before making diffs/commits to catch where you might&#039;ve gotten careless&lt;br /&gt;
2010-11-24 02:43:35 &amp;lt; Dark_Shikari&amp;gt; that&#039;s the final version with commit message&lt;br /&gt;
2010-11-24 02:43:44 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll handle any more changes pengvado wants to make before we push it&lt;br /&gt;
2010-11-24 02:43:49 &amp;lt; astrange&amp;gt; s/^ +$//g&lt;br /&gt;
2010-11-24 02:43:58 &amp;lt; astrange&amp;gt; take out the ^&lt;br /&gt;
2010-11-24 02:44:09 &amp;lt; Jumpyshoes&amp;gt; woah, i&#039;m the first GCI dude?&lt;br /&gt;
2010-11-24 02:44:14 &amp;lt; Dark_Shikari&amp;gt; The first to finish yes&lt;br /&gt;
2010-11-24 02:44:19 &amp;lt; pengvado&amp;gt; Dark_Shikari, rfw: vague wishlist: report whether output did or did not change (distinct from whether it changed enough to visibly affect bitrate/psnr). and the vaguer part: what if it&#039;s supposed to change some configurations and not others?&lt;br /&gt;
2010-11-24 02:44:19 &amp;lt; Jumpyshoes&amp;gt; :O&lt;br /&gt;
2010-11-24 02:44:22 &amp;lt; Jumpyshoes&amp;gt; i should sign up&lt;br /&gt;
2010-11-24 02:45:04 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, so i just take a code an asm func task on the page?&lt;br /&gt;
2010-11-24 02:45:17 &amp;lt; Dark_Shikari&amp;gt; you didn&#039;t take one?  lol&lt;br /&gt;
2010-11-24 02:45:19 &amp;lt; Dark_Shikari&amp;gt; go take one then&lt;br /&gt;
2010-11-24 02:45:20 &amp;lt; Jumpyshoes&amp;gt; nope&lt;br /&gt;
2010-11-24 02:45:42 &amp;lt; Jumpyshoes&amp;gt; what in the world is melange? cause it&#039;s fricking slow&lt;br /&gt;
2010-11-24 02:46:06 &amp;lt; Dark_Shikari&amp;gt; Shit.&lt;br /&gt;
2010-11-24 02:46:07 &amp;lt; Dark_Shikari&amp;gt; That&#039;s what it is.&lt;br /&gt;
2010-11-24 02:46:26 &amp;lt; Jumpyshoes&amp;gt; sigh&lt;br /&gt;
2010-11-24 02:46:34 &amp;lt; pengvado&amp;gt; Jumpyshoes: 319: prototypes of highdepth-aware functions should use dctcoef* and pixel*&lt;br /&gt;
2010-11-24 02:46:34 &amp;lt; Jumpyshoes&amp;gt; using shitty open source to promote open source&lt;br /&gt;
2010-11-24 02:46:37 &amp;lt; Jumpyshoes&amp;gt; good way to go&lt;br /&gt;
2010-11-24 02:46:48 &amp;lt; Dark_Shikari&amp;gt; ah yes&lt;br /&gt;
2010-11-24 02:46:56 &amp;lt; rfw&amp;gt; Dark_Shikari: what do you mean by the second part&lt;br /&gt;
2010-11-24 02:46:58 &amp;lt; Dark_Shikari&amp;gt; pengvado: wait.  what?&lt;br /&gt;
2010-11-24 02:47:01 &amp;lt; Jumpyshoes&amp;gt; ?&lt;br /&gt;
2010-11-24 02:47:05 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t think we&#039;ve done that so far&lt;br /&gt;
2010-11-24 02:47:15 &amp;lt; Dark_Shikari&amp;gt; since the asm functions only support one version at a time&lt;br /&gt;
2010-11-24 02:47:25 &amp;lt; Jumpyshoes&amp;gt; oops, Dark_Shikari, can you add another asm func task?&lt;br /&gt;
2010-11-24 02:47:29 &amp;lt; Jumpyshoes&amp;gt; i think both are taken&lt;br /&gt;
2010-11-24 02:47:50 &amp;lt; Dark_Shikari&amp;gt; I think we&#039;ll have to wait for j-b to show up&lt;br /&gt;
2010-11-24 02:47:53 &amp;lt; Dark_Shikari&amp;gt; yeah they&#039;re getting taken really fast&lt;br /&gt;
2010-11-24 02:47:55 &amp;lt; Dark_Shikari&amp;gt; I&#039;ll have to go spam them&lt;br /&gt;
2010-11-24 02:48:14 &amp;lt; Dark_Shikari&amp;gt; pengvado: it seems this wasn&#039;t done for anything else in dct.h.  what do you want to do?&lt;br /&gt;
2010-11-24 02:48:45 &amp;lt; pengvado&amp;gt; in dct.h I see 3 functions with both versions and a bunch of 8bit-only&lt;br /&gt;
2010-11-24 02:49:17 &amp;lt; Dark_Shikari&amp;gt; ah, I see&lt;br /&gt;
2010-11-24 02:49:17 &amp;lt; Dark_Shikari&amp;gt; ok&lt;br /&gt;
2010-11-24 02:49:31 &amp;lt; Dark_Shikari&amp;gt; but the function only has one version&lt;br /&gt;
2010-11-24 02:49:33 &amp;lt; Dark_Shikari&amp;gt; it doesn&#039;t exist for 8-bit&lt;br /&gt;
2010-11-24 02:49:37 &amp;lt; Dark_Shikari&amp;gt; does it make sense to have it be &amp;quot;templated&amp;quot; then?&lt;br /&gt;
2010-11-24 02:49:50 &amp;lt; pengvado&amp;gt; hmm, do we want to use the prototypes to keep track of which functions have which versions, or change everything once and for all to dctcoef/pixel so that it doesn&#039;t have to change again with each patch to implement a few functions?&lt;br /&gt;
2010-11-24 02:50:04 &amp;lt; Dark_Shikari&amp;gt; I like the first idea&lt;br /&gt;
2010-11-24 02:50:21 &amp;lt; pengvado&amp;gt; ok, then leave it&lt;br /&gt;
2010-11-24 02:51:02 &amp;lt; pengvado&amp;gt; 319: vertical align&lt;br /&gt;
2010-11-24 02:52:07 &amp;lt; Dark_Shikari&amp;gt; how so?  just the [16]?&lt;br /&gt;
2010-11-24 02:52:13 &amp;lt; Dark_Shikari&amp;gt; the rest is impossible to align without shifting all the others&lt;br /&gt;
2010-11-24 02:52:39 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: also, feel free to watch, this is how code reviews work =p&lt;br /&gt;
2010-11-24 02:52:47 &amp;lt; Jumpyshoes&amp;gt; yea, i am&lt;br /&gt;
2010-11-24 02:52:56 &amp;lt; pengvado&amp;gt; shifting the paren would make more match up&lt;br /&gt;
2010-11-24 02:52:57 &amp;lt; Jumpyshoes&amp;gt; i feel sorta bad &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-24 02:53:05 &amp;lt; Jumpyshoes&amp;gt; so many mistakes&lt;br /&gt;
2010-11-24 02:53:13 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: this is how it starts for everyone&lt;br /&gt;
2010-11-24 02:53:21 &amp;lt; Dark_Shikari&amp;gt; even _my_ patches get 250 nitpicks before committing&lt;br /&gt;
2010-11-24 02:53:26 &amp;lt; Dark_Shikari&amp;gt; this is how we make good code&lt;br /&gt;
2010-11-24 02:53:29 &amp;lt; Dark_Shikari&amp;gt; we bitch about each others&#039;&lt;br /&gt;
2010-11-24 02:53:34 &amp;lt; Jumpyshoes&amp;gt; haha&lt;br /&gt;
2010-11-24 02:53:35 &amp;lt; Dark_Shikari&amp;gt; pengvado: you mean shifting all of them?  or what&lt;br /&gt;
2010-11-24 02:53:53 &amp;lt; pengvado&amp;gt; just the new one&lt;br /&gt;
2010-11-24 02:54:12 &amp;lt; Dark_Shikari&amp;gt; so&lt;br /&gt;
2010-11-24 02:54:13 &amp;lt; Dark_Shikari&amp;gt; void x264_add4x4_idct_mmx       ( uint8_t *p_dst, int16_t dct    [16] );&lt;br /&gt;
2010-11-24 02:54:13 &amp;lt; Dark_Shikari&amp;gt; void x264_add4x4_idct_sse2     ( uint16_t *p_dst, int32_t dct    [16] );&lt;br /&gt;
2010-11-24 02:54:14 &amp;lt; Dark_Shikari&amp;gt; ?&lt;br /&gt;
2010-11-24 02:54:16 &amp;lt; pengvado&amp;gt; yes&lt;br /&gt;
2010-11-24 02:54:19 &amp;lt; Dark_Shikari&amp;gt; ok&lt;br /&gt;
2010-11-24 02:54:21 &amp;lt; Dark_Shikari&amp;gt; done&lt;br /&gt;
2010-11-24 02:54:56 &amp;lt; Dark_Shikari&amp;gt; espes: claim accepted&lt;br /&gt;
2010-11-24 02:55:02 &amp;lt; Dark_Shikari&amp;gt; fuck melange&lt;br /&gt;
2010-11-24 02:55:22 &amp;lt; Jumpyshoes&amp;gt; so whenever the claims come out&lt;br /&gt;
2010-11-24 02:55:39 &amp;lt; pengvado&amp;gt; if I&#039;m not holding Jumpyshoes responsible for optimizing arithmetic width since I haven&#039;t written that test yet, then patch ok&lt;br /&gt;
2010-11-24 02:55:51 &amp;lt; Dark_Shikari&amp;gt; pengvado: isn&#039;t that only possible with fdct?&lt;br /&gt;
2010-11-24 02:56:03 &amp;lt; Dark_Shikari&amp;gt; or is there a stage that it&#039;s possible with in idct?&lt;br /&gt;
2010-11-24 02:56:09 &amp;lt; Dark_Shikari&amp;gt; and yeah, I think that&#039;s reasonable&lt;br /&gt;
2010-11-24 02:56:17 &amp;lt; Dark_Shikari&amp;gt; I mean, the fdct is clearly _broken_ now, so...&lt;br /&gt;
2010-11-24 02:56:52 &amp;lt; pengvado&amp;gt; hmm, idct inputs should fit well within 16bit, but they&#039;re a 32bit type since pre-quant coefs need 32bit, so it&#039;s at least inconvenient&lt;br /&gt;
2010-11-24 02:57:07 &amp;lt; Dark_Shikari&amp;gt; why would idct inputs fit within 16-bit if dct outputs won&#039;t?&lt;br /&gt;
2010-11-24 02:58:00 &amp;lt; pengvado&amp;gt; because quant rescales things? at least I think it does.&lt;br /&gt;
2010-11-24 02:58:06 &amp;lt; Dark_Shikari&amp;gt; by that large a margin?  I&#039;m not sure&lt;br /&gt;
2010-11-24 03:00:01 &amp;lt; rfw&amp;gt; x264.c: In function ‘help’: x264.c:351: error: ‘X264_VERSION’ undeclared (first use in this function)&lt;br /&gt;
2010-11-24 03:00:05 &amp;lt; rfw&amp;gt; the hell&lt;br /&gt;
2010-11-24 03:00:18 &amp;lt; Dark_Shikari&amp;gt; configure failed&lt;br /&gt;
2010-11-24 03:00:19 &amp;lt; Dark_Shikari&amp;gt; or something&lt;br /&gt;
2010-11-24 03:00:22 &amp;lt; Dark_Shikari&amp;gt; X264_VERSION gets written by configure&lt;br /&gt;
2010-11-24 03:00:35 &amp;lt; Dark_Shikari&amp;gt; into config.h&lt;br /&gt;
2010-11-24 03:00:40 &amp;lt; Dark_Shikari&amp;gt; pengvado: oh, another thing I wanted to bring up&lt;br /&gt;
2010-11-24 03:00:44 &amp;lt; pengvado&amp;gt; oh, my bad. I was counting bits of expansion, assuming that if iddct expands things by 7 bits and is &amp;gt;&amp;gt;6 then it must have pretty small inputs. but that&#039;s wrong. it just means that it&#039;s syntactically possible to write a bitstream where idct is very very clipped, and even if it isn&#039;t there&#039;s no way to know which of the dct coefs that magnitude is in.&lt;br /&gt;
2010-11-24 03:00:56 &amp;lt; rfw&amp;gt; huh that&#039;s funny&lt;br /&gt;
2010-11-24 03:01:01 &amp;lt; rfw&amp;gt; it didn&#039;t catch the return code&lt;br /&gt;
2010-11-24 03:01:14 &amp;lt; Dark_Shikari&amp;gt; a customer has requested that ffmpeg be able to link to a commercial x264&lt;br /&gt;
2010-11-24 03:01:18 &amp;lt; Dark_Shikari&amp;gt; while ffmpeg remains LGPL&lt;br /&gt;
2010-11-24 03:01:21 &amp;lt; Dark_Shikari&amp;gt; this of course makes sense.&lt;br /&gt;
2010-11-24 03:01:30 &amp;lt; Dark_Shikari&amp;gt; But this requires that ffmpeg configure KNOW that x264 is commercially licensed, and not GPL.&lt;br /&gt;
2010-11-24 03:01:41 &amp;lt; Dark_Shikari&amp;gt; I considered an installed x264_config.h, similar to ffmpeg&#039;s.&lt;br /&gt;
2010-11-24 03:01:45 &amp;lt; Dark_Shikari&amp;gt; What do you think should be done?&lt;br /&gt;
2010-11-24 03:02:35 &amp;lt; rfw&amp;gt; oh lol&lt;br /&gt;
2010-11-24 03:02:36 &amp;lt; rfw&amp;gt; windows encoding&lt;br /&gt;
2010-11-24 03:02:50 &amp;lt; rfw&amp;gt; i swear i turned autocrlf off too&lt;br /&gt;
2010-11-24 03:04:29 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, is my patch okay, or do i need to do what pengvado said?&lt;br /&gt;
2010-11-24 03:04:53 &amp;lt; pengvado&amp;gt; patch ok&lt;br /&gt;
2010-11-24 03:04:58 &amp;lt; Dark_Shikari&amp;gt; you&#039;re good&lt;br /&gt;
2010-11-24 03:05:04 &amp;lt; Jumpyshoes&amp;gt; o&lt;br /&gt;
2010-11-24 03:05:04 &amp;lt; Jumpyshoes&amp;gt; yay&lt;br /&gt;
2010-11-24 03:05:31 &amp;lt; pengvado&amp;gt; I can&#039;t think of any way better than x264_config.h&lt;br /&gt;
2010-11-24 03:05:43 &amp;lt; Dark_Shikari&amp;gt; is there anything else we should move to x264_config.h?&lt;br /&gt;
2010-11-24 03:05:44 &amp;lt; Dark_Shikari&amp;gt; bit depth?&lt;br /&gt;
2010-11-24 03:05:58 &amp;lt; pengvado&amp;gt; of course people will install an x264_config.h of one configuration and a binary of another&lt;br /&gt;
2010-11-24 03:06:19 &amp;lt; pengvado&amp;gt; yes&lt;br /&gt;
2010-11-24 03:06:23 &amp;lt; Dark_Shikari&amp;gt; the problem is that if you rely on an API call to check license&lt;br /&gt;
2010-11-24 03:06:29 &amp;lt; Dark_Shikari&amp;gt; it breaks cross-compiling&lt;br /&gt;
2010-11-24 03:06:31 &amp;lt; Dark_Shikari&amp;gt; so this leaves us two options&lt;br /&gt;
2010-11-24 03:06:33 &amp;lt; Dark_Shikari&amp;gt; x264_config.h&lt;br /&gt;
2010-11-24 03:06:39 &amp;lt; Dark_Shikari&amp;gt; or API call + runtime check in ffmpeg if LGPL is on&lt;br /&gt;
2010-11-24 03:07:08 &amp;lt; pengvado&amp;gt; or x264_config.h + runtime check for consistency&lt;br /&gt;
2010-11-24 03:07:42 &amp;lt; Dark_Shikari&amp;gt; so both bit depth and license will have APIs, *plus* config.h entries?&lt;br /&gt;
2010-11-24 03:08:02 &amp;lt; Dark_Shikari&amp;gt; bit_depth is a variable instead of a function call, should license be a variable too, or should we make both function calls?&lt;br /&gt;
2010-11-24 03:11:48 &amp;lt; pengvado&amp;gt; otoh, mismatched license doesn&#039;t cause segfaults, so maybe that doesn&#039;t need a consistency check&lt;br /&gt;
2010-11-24 03:11:52 &amp;lt; pengvado&amp;gt; bitdepth does though&lt;br /&gt;
2010-11-24 03:13:37 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, if my other patch is good, can i claim dct4x4dc_mmx ?&lt;br /&gt;
2010-11-24 03:13:43 &amp;lt; Dark_Shikari&amp;gt; Jumpyshoes: sure.&lt;br /&gt;
2010-11-24 03:13:46 &amp;lt; Jumpyshoes&amp;gt; cool&lt;br /&gt;
2010-11-24 03:14:18 &amp;lt; Dark_Shikari&amp;gt; important thing to note about that&lt;br /&gt;
2010-11-24 03:14:24 &amp;lt; Dark_Shikari&amp;gt; That function used to only use 16-bit math&lt;br /&gt;
2010-11-24 03:14:29 &amp;lt; Dark_Shikari&amp;gt; and thus looked very similar to all the other nearby functions&lt;br /&gt;
2010-11-24 03:14:40 &amp;lt; Dark_Shikari&amp;gt; however, we found that if the input was all black for one input, and all white for the other&lt;br /&gt;
2010-11-24 03:14:43 &amp;lt; Dark_Shikari&amp;gt; i.e. 00000 vs 255 255 255&lt;br /&gt;
2010-11-24 03:14:47 &amp;lt; Dark_Shikari&amp;gt; it overflowed&lt;br /&gt;
2010-11-24 03:14:54 &amp;lt; Dark_Shikari&amp;gt; so it emulates one extra bit of precision: see SUMSUB_17BIT&lt;br /&gt;
2010-11-24 03:14:59 &amp;lt; Dark_Shikari&amp;gt; However... you&#039;re doing it in 32-bit.&lt;br /&gt;
2010-11-24 03:15:01 &amp;lt; Dark_Shikari&amp;gt; So you don&#039;t need that.&lt;br /&gt;
2010-11-24 03:15:04 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-24 03:15:27 &amp;lt; Jumpyshoes&amp;gt; also, what is     movq   m7, [pw_8000] ; convert to unsigned and back, so that pavgw works          supposed to do, m7 isn&#039; t used in the function&lt;br /&gt;
2010-11-24 03:15:34 &amp;lt; Jumpyshoes&amp;gt; oh yes it is&lt;br /&gt;
2010-11-24 03:15:37 &amp;lt; Jumpyshoes&amp;gt; i&#039;m blind &amp;lt;_&amp;lt;&lt;br /&gt;
2010-11-24 03:15:51 &amp;lt; Dark_Shikari&amp;gt; You should go view the git history for that file&lt;br /&gt;
2010-11-24 03:15:53 &amp;lt; Dark_Shikari&amp;gt; and find were it was changed&lt;br /&gt;
2010-11-24 03:15:56 &amp;lt; Dark_Shikari&amp;gt; and use the old version as you reference.&lt;br /&gt;
2010-11-24 03:16:01 &amp;lt; Dark_Shikari&amp;gt; *your&lt;br /&gt;
2010-11-24 03:16:06 &amp;lt; Dark_Shikari&amp;gt; It will be more applicable.&lt;br /&gt;
2010-11-24 03:16:20 &amp;lt; Jumpyshoes&amp;gt; oh, okay&lt;br /&gt;
2010-11-24 03:16:23 &amp;lt; Dark_Shikari&amp;gt; The 17bit, convert to unsigned, etc are pure hacks to quickly emulate the extra bit.&lt;br /&gt;
2010-11-24 03:17:55  * pengvado sleeps&lt;br /&gt;
2010-11-24 03:20:13 &amp;lt; rfw&amp;gt; Dark_Shikari: so what else am i going to need&lt;br /&gt;
2010-11-24 03:24:07 &amp;lt; Dark_Shikari&amp;gt; rfw: link to the latest patch again?&lt;br /&gt;
2010-11-24 03:24:21 &amp;lt; rfw&amp;gt; um hold on&lt;br /&gt;
2010-11-24 03:24:26 &amp;lt; rfw&amp;gt; i changed a few weird things&lt;br /&gt;
2010-11-24 03:24:29 &amp;lt; Dark_Shikari&amp;gt; I will locally commit it, but it&#039;ll need to go through two tests before it&#039;s done:&lt;br /&gt;
2010-11-24 03:24:46 &amp;lt; Dark_Shikari&amp;gt; 1) I&#039;ll have to use it and be satisfied (along with a few other devs, like bugmaster and pengvado)&lt;br /&gt;
2010-11-24 03:24:51 &amp;lt; Dark_Shikari&amp;gt; 2) pengvado&#039;s code review&lt;br /&gt;
2010-11-24 03:24:55 &amp;lt; Dark_Shikari&amp;gt; of course, if pengvado isn&#039;t interested in python&lt;br /&gt;
2010-11-24 03:24:58 &amp;lt; Dark_Shikari&amp;gt; he might just say &amp;quot;ok&amp;quot;&lt;br /&gt;
2010-11-24 03:25:08 &amp;lt; Dark_Shikari&amp;gt; because it&#039;s not part of the encoder, standards are probably lower.&lt;br /&gt;
2010-11-24 03:25:16 &amp;lt; Dark_Shikari&amp;gt; i.e. functioning is more important than being pretty&lt;br /&gt;
2010-11-24 03:26:00 &amp;lt; Jumpyshoes&amp;gt; Dark_Shikari, do you have an idea when the tasks will come up?&lt;br /&gt;
2010-11-24 03:26:09 &amp;lt; Dark_Shikari&amp;gt; when j-b wakes up&lt;br /&gt;
2010-11-24 03:26:21 &amp;lt; Dark_Shikari&amp;gt; he&#039;s in france, so do the math&lt;br /&gt;
2010-11-24 03:26:33 &amp;lt; JEEBsv&amp;gt; ~3AM in France now I&#039;d guess&lt;br /&gt;
2010-11-24 03:26:48 &amp;lt; Jumpyshoes&amp;gt; ah, okay&lt;br /&gt;
2010-11-24 03:27:02 &amp;lt; rfw&amp;gt; Dark_Shikari: does that mean pengvado is perl supremacist like Kovensky&lt;br /&gt;
2010-11-24 03:27:44 &amp;lt; Dark_Shikari&amp;gt; maybe.&lt;br /&gt;
2010-11-24 03:27:47 &amp;lt; Dark_Shikari&amp;gt; I don&#039;t relaly know&lt;br /&gt;
2010-11-24 03:27:54 &amp;lt; Dark_Shikari&amp;gt; there are many theories.&lt;br /&gt;
2010-11-24 03:28:01 &amp;lt; rfw&amp;gt; http://pastebin.com/nDgwpk6S&lt;br /&gt;
2010-11-24 03:28:02 &amp;lt; Dark_Shikari&amp;gt; some say that he&#039;s an alien&lt;br /&gt;
2010-11-24 03:28:20 &amp;lt; rfw&amp;gt; what exactly is a pengvado&lt;br /&gt;
2010-11-24 03:28:45 &amp;lt; JEEBsv&amp;gt; Nobody knows for sure. Only one thing is sure... they fork()&lt;br /&gt;
2010-11-24 03:28:59 &amp;lt; Dark_Shikari&amp;gt; My guess is a youkai of some sort.&lt;br /&gt;
2010-11-24 03:29:18 &amp;lt; Dark_Shikari&amp;gt; Doesn&#039;t like sunlight, has thought processes alien to a typical human... seems a perfect match.&lt;br /&gt;
2010-11-24 03:29:22 &amp;lt; rfw&amp;gt; does he have a funny hat&lt;br /&gt;
2010-11-24 03:29:59 &amp;lt; Dark_Shikari&amp;gt; well, everyone knows that youkai that hide out in human society don&#039;t wear their funny hats in public.&lt;br /&gt;
2010-11-24 03:30:18 &amp;lt; rfw&amp;gt; :(&lt;br /&gt;
2010-11-24 03:33:58 &amp;lt; Jumpyshoes&amp;gt; was HADAMARD4_1D phased out or something?&lt;br /&gt;
2010-11-24 03:34:20 &amp;lt; Dark_Shikari&amp;gt; No, that change was made because HADAMARD4_1D didn&#039;t keep the necessary precision&lt;br /&gt;
2010-11-24 03:34:34 &amp;lt; Jumpyshoes&amp;gt; i mean, i can&#039;t find it&lt;br /&gt;
2010-11-24 03:34:38 &amp;lt; Dark_Shikari&amp;gt; oh&lt;br /&gt;
2010-11-24 03:34:55 &amp;lt; Dark_Shikari&amp;gt; I think it was, yeah&lt;br /&gt;
2010-11-24 03:35:03 &amp;lt; Jumpyshoes&amp;gt; just cause?&lt;br /&gt;
2010-11-24 03:35:06 &amp;lt; Dark_Shikari&amp;gt; wow, holger has gone missing&lt;br /&gt;
2010-11-24 03:35:13 &amp;lt; Jumpyshoes&amp;gt; or because of precision issues&lt;br /&gt;
2010-11-24 03:35:23 &amp;lt; Jumpyshoes&amp;gt; cause i think i can bring it back for 32-bit... maybe&lt;br /&gt;
2010-11-24 03:35:24 &amp;lt; Dark_Shikari&amp;gt; I&#039;m guessing it relates to holger&#039;s changes&lt;br /&gt;
2010-11-24 03:35:30 &amp;lt; Jumpyshoes&amp;gt; ah, okay&lt;br /&gt;
2010-11-24 03:35:32 &amp;lt; Dark_Shikari&amp;gt; no, you just need WALSH4_1D&lt;br /&gt;
2010-11-24 03:35:35 &amp;lt; Jumpyshoes&amp;gt; i&#039;ll bug him tomorrow or somethin&lt;br /&gt;
2010-11-24 03:35:36 &amp;lt; Jumpyshoes&amp;gt; g&lt;br /&gt;
2010-11-24 03:35:38 &amp;lt; Dark_Shikari&amp;gt;     SUMSUB_BADC w, m1, m0, m3, m2, m4&lt;br /&gt;
2010-11-24 03:35:38 &amp;lt; Dark_Shikari&amp;gt;     SWAP 0, 1&lt;br /&gt;
2010-11-24 03:35:38 &amp;lt; Dark_Shikari&amp;gt;     SWAP 2, 3&lt;br /&gt;
2010-11-24 03:35:38 &amp;lt; Dark_Shikari&amp;gt;     SUMSUB_17BIT 0,2,4,7&lt;br /&gt;
2010-11-24 03:35:38 &amp;lt; Dark_Shikari&amp;gt;     SUMSUB_17BIT 1,3,5,7&lt;br /&gt;
2010-11-24 03:35:41 &amp;lt; Dark_Shikari&amp;gt; these lines replace a&lt;br /&gt;
2010-11-24 03:35:44 &amp;lt; Dark_Shikari&amp;gt;     WALSH4_1D  0,1,2,3,4&lt;br /&gt;
2010-11-24 03:35:48 &amp;lt; Dark_Shikari&amp;gt; You don&#039;t need HADAMARD&lt;br /&gt;
2010-11-24 03:35:57 &amp;lt; Dark_Shikari&amp;gt; we renamed it to WALSH, I think, because it was a more accurate name&lt;br /&gt;
2010-11-24 03:36:07 &amp;lt; Dark_Shikari&amp;gt; as it&#039;s a walsh-ordered transform&lt;br /&gt;
2010-11-24 03:36:10 &amp;lt; Jumpyshoes&amp;gt; oh, so HADAMARD4_1D is WALSH4_1D?&lt;br /&gt;
2010-11-24 03:36:16 &amp;lt; Jumpyshoes&amp;gt; (taking a look at the older revision)&lt;br /&gt;
2010-11-24 03:37:15 &amp;lt; Dark_Shikari&amp;gt; I think so&lt;br /&gt;
2010-11-24 03:37:25 &amp;lt; Dark_Shikari&amp;gt; anyways just look at the current code and mentally replace the thing I said above&lt;br /&gt;
2010-11-24 03:37:28 &amp;lt; Dark_Shikari&amp;gt; with WALSH4_1D&lt;br /&gt;
2010-11-24 03:37:36 &amp;lt; Dark_Shikari&amp;gt; It&#039;s basically that.&lt;br /&gt;
2010-11-24 03:37:42 &amp;lt; Jumpyshoes&amp;gt; ah&lt;br /&gt;
2010-11-24 03:40:36 &amp;lt; darkbringer&amp;gt; rfw, i&#039;m not a developer, but would not it be better not to hardcode akiyo_qcif everywhere? I mean it is quite possible that some people would want to use different clips for testing.&lt;br /&gt;
2010-11-24 03:40:48 &amp;lt; Dark_Shikari&amp;gt; Yeah, that.&lt;br /&gt;
2010-11-24 03:40:52 &amp;lt; rfw&amp;gt; oh&lt;br /&gt;
2010-11-24 03:40:54 &amp;lt; Dark_Shikari&amp;gt; it should be a cli argument&lt;br /&gt;
2010-11-24 03:40:58 &amp;lt; rfw&amp;gt; cirno.tiff&lt;br /&gt;
2010-11-24 03:41:00 &amp;lt; JEEBsv&amp;gt; Yes, indeed&lt;br /&gt;
2010-11-24 03:41:08  * JEEBsv pats (9)-rfw&lt;br /&gt;
2010-11-24 03:41:35 &amp;lt; Dark_Shikari&amp;gt; well next time I make a stupid mistake I can be dar(9)shikari&lt;br /&gt;
2010-11-24 03:43:14 &amp;lt; Jumpyshoes&amp;gt; oh yea, one last question&lt;br /&gt;
2010-11-24 03:43:28 &amp;lt; Jumpyshoes&amp;gt; when do revisions usually go up? i&#039;m too lazy to commit and change everything&lt;br /&gt;
2010-11-24 03:43:32 &amp;lt; Jumpyshoes&amp;gt; so i want to pull the latest one&lt;br /&gt;
2010-11-24 03:43:50 &amp;lt; Dark_Shikari&amp;gt; we make a big push every 1-2 weeks&lt;br /&gt;
2010-11-24 03:43:57 &amp;lt; Dark_Shikari&amp;gt; it depends how many changes there are, and how urgent they are&lt;br /&gt;
2010-11-24 03:44:05 &amp;lt; Dark_Shikari&amp;gt; along with the push comes out a newsletter documenting the changes&lt;br /&gt;
2010-11-24 03:44:12 &amp;lt; Dark_Shikari&amp;gt; pushes usually contain 8-24 commits&lt;br /&gt;
2010-11-24 03:44:18 &amp;lt; Jumpyshoes&amp;gt; ah, okay&lt;br /&gt;
2010-11-24 03:44:21 &amp;lt; Dark_Shikari&amp;gt; there may also be bugfix pushes soon after if bugs come up&lt;br /&gt;
2010-11-24 03:44:24 &amp;lt; Dark_Shikari&amp;gt; these usually contain 1-5 commits&lt;br /&gt;
2010-11-24 03:44:24 &amp;lt; Jumpyshoes&amp;gt; so i guess i&#039;ll work on it now&lt;br /&gt;
2010-11-24 03:44:49 &amp;lt; Dark_Shikari&amp;gt; it&#039;s not really an issue though, asm changes rarely have any conflicts with anything else&lt;br /&gt;
2010-11-24 03:45:22 &amp;lt; reid_&amp;gt; Dark_Shikari: what is the relation between  VLC and x264?&lt;br /&gt;
2010-11-24 03:45:29 &amp;lt; Jumpyshoes&amp;gt; oh, i guess that&#039;s true&lt;br /&gt;
2010-11-24 03:45:30 &amp;lt; JEEBsv&amp;gt; reid_: same host&lt;br /&gt;
2010-11-24 03:45:42 &amp;lt; Dark_Shikari&amp;gt; reid_: Videolan is a big organization that hosts a lot of projects&lt;br /&gt;
2010-11-24 03:45:42 &amp;lt; JEEBsv&amp;gt; and under the same videolan umbrella in GSoC etc.&lt;br /&gt;
2010-11-24 03:45:46 &amp;lt; Dark_Shikari&amp;gt; those projects include VLC and x264&lt;br /&gt;
2010-11-24 03:46:08 &amp;lt; Dark_Shikari&amp;gt; So &amp;quot;Videolan&amp;quot; gets accepted to Google Code-In&lt;br /&gt;
2010-11-24 03:46:13 &amp;lt; Dark_Shikari&amp;gt; which means that any Videolan project can submit tasks&lt;br /&gt;
2010-11-24 03:46:27 &amp;lt; Dark_Shikari&amp;gt; such as VLC, Videolan itself (website, etc), VLMC, x264, etc&lt;br /&gt;
2010-11-24 03:46:45 &amp;lt; reid_&amp;gt; is x264 an application or more like a library?&lt;br /&gt;
2010-11-24 03:46:50 &amp;lt; JEEBsv&amp;gt; both&lt;br /&gt;
2010-11-24 03:46:51 &amp;lt; darkbringer&amp;gt; both&lt;br /&gt;
2010-11-24 03:46:59 &amp;lt; Dark_Shikari&amp;gt; both&lt;br /&gt;
2010-11-24 03:47:04 &amp;lt; JEEBsv&amp;gt; very strong command line app, as well as a highly versatile library&lt;br /&gt;
2010-11-24 03:47:14 &amp;lt; Dark_Shikari&amp;gt; x264cli and libx264 as they&#039;re called&lt;br /&gt;
2010-11-24 03:48:08 &amp;lt; Dark_Shikari&amp;gt; JEEBsv: yes, it&#039;s very strong, it can leap tall buildings in a single bound and make DC 40 fort saves&lt;br /&gt;
2010-11-24 03:48:22 &amp;lt; JEEBsv&amp;gt; haha&lt;br /&gt;
2010-11-24 03:49:37 &amp;lt; reid_&amp;gt; I ask because i&#039;m looking at the filtering system.&lt;br /&gt;
2010-11-24 03:50:42 &amp;lt; Jumpyshoes&amp;gt; i need a better computer&lt;br /&gt;
2010-11-24 03:50:54 &amp;lt; Dark_Shikari&amp;gt; reid_: the filtering task has changed slightly on decree from our BDFL&lt;br /&gt;
2010-11-24 03:50:59 &amp;lt; Jumpyshoes&amp;gt; this laptop is hot and x264 compiles too slowly&lt;br /&gt;
2010-11-24 03:51:00 &amp;lt; Dark_Shikari&amp;gt; it&#039;s now porting new filters into libavfilter ;)&lt;br /&gt;
2010-11-24 03:51:07 &amp;lt; Dark_Shikari&amp;gt; Which we&#039;ll then use from x264&lt;br /&gt;
2010-11-24 03:51:10 &amp;lt; reid_&amp;gt; Jumpyshoes: celeron ftw!&lt;br /&gt;
2010-11-24 03:51:17 &amp;lt; Jumpyshoes&amp;gt; oh&lt;br /&gt;
2010-11-24 03:51:20 &amp;lt; Jumpyshoes&amp;gt; i have an i5&lt;br /&gt;
2010-11-24 03:51:22 &amp;lt; Jumpyshoes&amp;gt; won a laptop&lt;br /&gt;
2010-11-24 03:51:32 &amp;lt; Dark_Shikari&amp;gt; &amp;gt;x264 compiles too slowly&lt;br /&gt;
2010-11-24 03:51:33 &amp;lt; Dark_Shikari&amp;gt; make -j8&lt;br /&gt;
2010-11-24 03:51:35 &amp;lt; Dark_Shikari&amp;gt; problem solved&lt;br /&gt;
2010-11-24 03:51:41 &amp;lt; Jumpyshoes&amp;gt; what?&lt;br /&gt;
2010-11-24 03:51:45 &amp;lt; reid_&amp;gt; you cant get too much better that i5.&lt;br /&gt;
2010-11-24 03:51:52 &amp;lt; Jumpyshoes&amp;gt; oh yes you can&lt;br /&gt;
2010-11-24 03:51:58 &amp;lt; Dark_Shikari&amp;gt; I have a 1.6ghz i7&lt;br /&gt;
2010-11-24 03:51:59 &amp;lt; Dark_Shikari&amp;gt; it&#039;s fast enough&lt;br /&gt;
2010-11-24 03:52:03 &amp;lt; Jumpyshoes&amp;gt; i used a $3000 computer over the summer&lt;br /&gt;
2010-11-24 03:52:04 &amp;lt; Sean_McG&amp;gt; you can get a 16-way Xeon&lt;br /&gt;
2010-11-24 03:52:07  * Sean_McG lollerblades&lt;br /&gt;
2010-11-24 03:52:15 &amp;lt; Jumpyshoes&amp;gt; i miss the days when i could open vs2010 in half a second&lt;br /&gt;
2010-11-24 03:52:18 &amp;lt; Jumpyshoes&amp;gt; instead of two minutes&lt;br /&gt;
2010-11-24 03:52:27 &amp;lt; Dark_Shikari&amp;gt; yes, that&#039;s called &amp;quot;time stop&amp;quot;&lt;br /&gt;
2010-11-24 03:52:37 &amp;lt; Dark_Shikari&amp;gt; And unless you&#039;re a 9th level sorc/wizard, or Sakuya, you can&#039;t do that.&lt;br /&gt;
2010-11-24 03:52:41 &amp;lt; Dark_Shikari&amp;gt; er, 9th spell level&lt;br /&gt;
2010-11-24 03:52:43 &amp;lt; Jumpyshoes&amp;gt; it had an SSD&lt;br /&gt;
2010-11-24 03:52:46 &amp;lt; reid_&amp;gt; Sean_McG: in a laptop?&lt;br /&gt;
2010-11-24 03:52:49 &amp;lt; Dark_Shikari&amp;gt; Oh, that&#039;s the other way to do it.&lt;br /&gt;
2010-11-24 03:52:53 &amp;lt; Sean_McG&amp;gt; reid_: hrm, no.&lt;br /&gt;
2010-11-24 03:52:56 &amp;lt; Jumpyshoes&amp;gt; yea&lt;br /&gt;
2010-11-24 03:52:57 &amp;lt; Jumpyshoes&amp;gt; i love SSDs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18087</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18087"/>
		<updated>2010-12-03T21:53:45Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: /* One */ Add a small statement about the page and a link to the original&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The discussions on this page have been edited for clarity, ease of reading, collation of later questions, and to trim out some noise.  The original transcript can be found here: [[X264asm]]&lt;br /&gt;
&lt;br /&gt;
== One ==&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext, [http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]&amp;lt;br&amp;gt;&lt;br /&gt;
This function does the following:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
cglobal: declares a function accessible from outside of asm&amp;lt;br&amp;gt;&lt;br /&gt;
The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, that argument is uint8_t *src&amp;lt;br&amp;gt;&lt;br /&gt;
If we had a second argument, we&#039;d say &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what tells the function that it&#039;s uint8_t?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up A through D&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up E through H&amp;lt;br&amp;gt;&lt;br /&gt;
# Do the math to get our final value&amp;lt;br&amp;gt;&lt;br /&gt;
# Store it into the 16 output Xs&amp;lt;br&amp;gt;&lt;br /&gt;
So let&#039;s see how this asm implements these.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&amp;lt;br&amp;gt;&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&amp;lt;br&amp;gt;&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit)&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.&amp;lt;br&amp;gt;&lt;br /&gt;
So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&amp;lt;br&amp;gt;&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.&amp;lt;br&amp;gt;&lt;br /&gt;
Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&amp;lt;br&amp;gt;&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&amp;lt;br&amp;gt;&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST]&amp;lt;br&amp;gt;&lt;br /&gt;
A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&amp;lt;br&amp;gt;&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Two ==&lt;br /&gt;
Ok, next.  You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome.  It does like 8 things in one.  Whereas abs() is typically 4 instructions on x86.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up.  That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent).&lt;br /&gt;
:&amp;lt;Q&amp;gt; why is abs() so slow?&lt;br /&gt;
:&amp;lt;A&amp;gt; abs() isn&#039;t slow, there&#039;s just no instructin for it.  The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences.  So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]).  Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]).  This function is pretty simple.  You should be able to see how it works.  Look only at the C for now.&lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro.  So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two paremeters.  They are accessed as %1 and %2.  We call the macro 7 times, one for each size.  The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args)&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is SAD_INC_2x%1P another macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16.  It picks the right one based on the width and it %reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.  Note mm0 is the accumulator which is why it&#039;s zeroed at the start.&lt;br /&gt;
:&amp;lt;Q&amp;gt; The order of args is the same as in the C function?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does punpckldq do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Good question!  punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high.  So punpckl__ ABCD, EFGH will use AB and EF.  And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size.  For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes).  So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL.  So in other words, it stuffs the two sets of 4 bytes we just loaded into one register&lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two.  &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH.  So it effectively concatenates mm1 and mm2 for us.  If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.  We do this because the registers are width 8, but our sad is width 4.  So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re concatenating row 0 and row 1 of each input.&lt;br /&gt;
:&amp;lt;Q&amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step?  Doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why is the lea out of order in SAD_INC_2x8P?  By out of order i mean not next to each other.&lt;br /&gt;
:&amp;lt;A&amp;gt; No particular reason.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are strides not hardcoded btw?&lt;br /&gt;
:&amp;lt;A&amp;gt; SAD can be called on a reference frame thus variable stride&lt;br /&gt;
:&amp;lt;Q&amp;gt; I don&#039;t really get it...&lt;br /&gt;
:A&amp;lt;&amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What?  Why is it so much faster?&lt;br /&gt;
:&amp;lt;A&amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance.  For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units.  The first two are represented with notation like this: &amp;quot;3/1&amp;quot;.  This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle.  Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;.  Between two registers  it is 1/0.33, takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier.  Not all execution units can do all instructions.  Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, what is latency?&lt;br /&gt;
:&amp;lt;A&amp;gt; time from start to finish, in clocks&lt;br /&gt;
:&amp;lt;Q&amp;gt; and inverse throughput and execution units?&lt;br /&gt;
:&amp;lt;A&amp;gt; Inverse throughput is how many you can do per clock.  Execution units are the things in the chip that do stuff.&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three.&lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices.  For example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How about branching?  I heard branching ruins things.&lt;br /&gt;
:&amp;lt;A&amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause.  We can get to a case of that later.&lt;br /&gt;
Now, let&#039;s just analyze SAD.  Suppose we want to analyze the 8x8 SAD.  In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead.  8 SADs: takes 8 cycles (inverse throughput of 1).  8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs.  16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck.  This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.  Loads are a common example.  In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.  The actual runtime of the function is about 22 clocks.  Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you.  How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is there anything that does this automatically for you?&lt;br /&gt;
:&amp;lt;A&amp;gt; Analysis?  not really.  There are intel performance counters and such on the chip  but they&#039;re not magic.  It might be useful to have some kind of tool to analyze asm functions.  In general though, intuition is a powerful tool.&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18086</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18086"/>
		<updated>2010-12-03T21:46:30Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Add second discussion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== One ==&lt;br /&gt;
Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext, [http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]&amp;lt;br&amp;gt;&lt;br /&gt;
This function does the following:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
cglobal: declares a function accessible from outside of asm&amp;lt;br&amp;gt;&lt;br /&gt;
The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, that argument is uint8_t *src&amp;lt;br&amp;gt;&lt;br /&gt;
If we had a second argument, we&#039;d say &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what tells the function that it&#039;s uint8_t?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r4&amp;lt;/tt&amp;gt; and up: can&#039;t use.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up A through D&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up E through H&amp;lt;br&amp;gt;&lt;br /&gt;
# Do the math to get our final value&amp;lt;br&amp;gt;&lt;br /&gt;
# Store it into the 16 output Xs&amp;lt;br&amp;gt;&lt;br /&gt;
So let&#039;s see how this asm implements these.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&amp;lt;br&amp;gt;&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&amp;lt;br&amp;gt;&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit)&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.&amp;lt;br&amp;gt;&lt;br /&gt;
So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&amp;lt;br&amp;gt;&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.&amp;lt;br&amp;gt;&lt;br /&gt;
Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&amp;lt;br&amp;gt;&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&amp;lt;br&amp;gt;&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST]&amp;lt;br&amp;gt;&lt;br /&gt;
A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&amp;lt;br&amp;gt;&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Two ==&lt;br /&gt;
Ok, next.  You may have noticed that &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is awesome.  It does like 8 things in one.  Whereas abs() is typically 4 instructions on x86.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does 8 subtracts, 8 absolute values on those results and then adds them up.  That&#039;s 8 + 32 + 7 = 47 instructions in one (at least, 47 equivalent).&lt;br /&gt;
:&amp;lt;Q&amp;gt; why is abs() so slow?&lt;br /&gt;
:&amp;lt;A&amp;gt; abs() isn&#039;t slow, there&#039;s just no instructin for it.  The typical algorithm is:&lt;br /&gt;
&amp;lt;pre&amp;gt;int sign = x &amp;gt;&amp;gt; 31;&lt;br /&gt;
(x ^ sign) - sign;&amp;lt;/pre&amp;gt;&lt;br /&gt;
:This needs a mov on x86, so that&#039;s 4 instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; is pretty awesome. It&#039;s very awesome for doing what its name implies you should do with it, that is -- SADs -- sum of absolute differences.  So let&#039;s open sad-a.asm and hop down to line 95 ([http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/sad-a.asm;h=0a96837aaa4c54f624b63c020872b74a790f1ffd;hb=HEAD#l95 git link]).  Also open common/pixel.c and look at the first function: SAD ([http://git.videolan.org/?p=x264.git;a=blob;f=common/pixel.c;h=7fa497c7cf151df5795bb105895760fde89facb6;hb=HEAD#l44 git link]).  This function is pretty simple.  You should be able to see how it works.  Look only at the C for now.&lt;br /&gt;
&lt;br /&gt;
So as you&#039;ll notice, the C SAD has 7 different versions for 16x16, 16x8, 8x16, etc and it&#039;s instantiated via a macro.  So, for our asm, we also need 7 versions and we also don&#039;t want to write the function 7 times, just like in the case of C we didn&#039;t.&lt;br /&gt;
&lt;br /&gt;
So in the asm, we define a macro: &amp;lt;tt&amp;gt;%macro SAD 2&amp;lt;/tt&amp;gt; that means this macro has two paremeters.  They are accessed as %1 and %2.  We call the macro 7 times, one for each size.  The function takes 4 args (as you&#039;d expect) and needs 4 regs (just the args)&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is SAD_INC_2x%1P another macro?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, it&#039;s one of three macros, look above, each one does 2 rows worth of SAD for width 4, width 8, and width 16.  It picks the right one based on the width and it %reps it based on the height.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, start analyzing the 3 macros above (the sad macros) and trying to figure out how they work.  Note mm0 is the accumulator which is why it&#039;s zeroed at the start.&lt;br /&gt;
:&amp;lt;Q&amp;gt; The order of args is the same as in the C function?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes&lt;br /&gt;
:&amp;lt;Q&amp;gt; What does punpckldq do?&lt;br /&gt;
:&amp;lt;A&amp;gt; Good question!  punpck is a set of instructions that interleave their arguments in some fashion.&lt;br /&gt;
&lt;br /&gt;
To start with, it can be l or h, low or high.  So punpckl__ ABCD, EFGH will use AB and EF.  And punpbkh__ ABCD, EFGH will use CD and GH.&lt;br /&gt;
&lt;br /&gt;
The next two letters are the source size, and destination size.  For example, &amp;lt;tt&amp;gt;punpcklbw&amp;lt;/tt&amp;gt; interleaves bytes, to create words. So &amp;lt;tt&amp;gt;punpcklbw ABCD, EFGH&amp;lt;/tt&amp;gt; gives you AEBF (if the letters are bytes).  So &amp;lt;tt&amp;gt;punpckldq ABCDEFGH, IJKLMNOP&amp;lt;/tt&amp;gt; gives us ABCDIJKL.  So in other words, it stuffs the two sets of 4 bytes we just loaded into one register&lt;br /&gt;
&lt;br /&gt;
So we can do only one SAD, instead of two.  &amp;lt;tt&amp;gt;punpckldq ABCD0000, EFGH0000&amp;lt;/tt&amp;gt; results in ABCDEFGH.  So it effectively concatenates mm1 and mm2 for us.  If we didn&#039;t do this, we&#039;d have to do twice as many sads and adds.  We do this because the registers are width 8, but our sad is width 4.  So we need to stuff sad information side by side to fill the whole reg.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we punpckldq&#039;ing the [r0+r1] and not [r0]?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re concatenating row 0 and row 1 of each input.&lt;br /&gt;
:&amp;lt;Q&amp;gt;&amp;lt;tt&amp;gt;lea r0, [r0+2*r1]&amp;lt;/tt&amp;gt; Why are we doing this step?  Doesn&#039;t it move r0 over 2*r1?&lt;br /&gt;
:&amp;lt;A&amp;gt; We&#039;re incrementing the pointer by 2*stride&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should understand what SAD_INC_2x4P does, the others work similarly except without the punpck magic because they don&#039;t need it.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why is the lea out of order in SAD_INC_2x8P?  By out of order i mean not next to each other.&lt;br /&gt;
:&amp;lt;A&amp;gt; No particular reason.&lt;br /&gt;
:&amp;lt;Q&amp;gt; So we rep the SAD for however many times so the 2x%1 is completed?&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, so if it&#039;s height 8, we rep it 4 times&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are strides not hardcoded btw?&lt;br /&gt;
:&amp;lt;A&amp;gt; SAD can be called on a reference frame thus variable stride&lt;br /&gt;
:&amp;lt;Q&amp;gt; I don&#039;t really get it...&lt;br /&gt;
:A&amp;lt;&amp;gt; It&#039;s called on frames, as opposed to some temporary block of memory.&lt;br /&gt;
&lt;br /&gt;
Now, for the kicker: the 16x16 SAD function declared here is 15 times faster than C.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What?  Why is it so much faster?&lt;br /&gt;
:&amp;lt;A&amp;gt; psadbw&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s get a bit to how we measure performance.  For any asm instruction, there are three things that matter: latency, inverse throughput, and execution units.  The first two are represented with notation like this: &amp;quot;3/1&amp;quot;.  This means a psadbw takes 3 clocks to finish from when it&#039;s started and you can do one of them per cycle.  Another example is &amp;lt;tt&amp;gt;mov&amp;lt;/tt&amp;gt;.  Between two registers  it is 1/0.33, takes 1 cycle, and you can do 3 per clock.&lt;br /&gt;
&lt;br /&gt;
Execution unit usage is a bit trickier.  Not all execution units can do all instructions.  Intel chips have 6 execution units: p0, p1, p2, p3, p4, p5&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, what is latency?&lt;br /&gt;
:&amp;lt;A&amp;gt; time from start to finish, in clocks&lt;br /&gt;
:&amp;lt;Q&amp;gt; and inverse throughput and execution units?&lt;br /&gt;
:&amp;lt;A&amp;gt; Inverse throughput is how many you can do per clock.  Execution units are the things in the chip that do stuff.&lt;br /&gt;
Of these 6 execution units, three can do math: p0, p1, p5.  &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, for example, can only use one of these (p1), &amp;lt;tt&amp;gt;pxor&amp;lt;/tt&amp;gt; can use all three.&lt;br /&gt;
&lt;br /&gt;
Generally execution units aren&#039;t important until you get into serious optimizing but they can often affect the best instruction choices.  For example, if an execution unit is sitting around doing nothing for a whole function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The instruction tables sheet here http://agner.org/optimize/ has all the information on latency, execution units, and inverse throughput for a wide variety of CPUs.&lt;br /&gt;
:&amp;lt;Q&amp;gt; How about branching?  I heard branching ruins things.&lt;br /&gt;
:&amp;lt;A&amp;gt; Not generally unless it&#039;s unpredictable, branch mispredictions are the cause.  We can get to a case of that later.&lt;br /&gt;
Now, let&#039;s just analyze SAD.  Suppose we want to analyze the 8x8 SAD.  In this function we do: 8 SADs, 8 adds (accumulates), 16 loads, plus the start, end, and calling overhead.  8 SADs: takes 8 cycles (inverse throughput of 1).  8 adds: takes 8 cycles (inverse throughput of 1), and can run at the same time as SADs.  16 loads: takes 16 cycles, and can run at the same time as the above.&lt;br /&gt;
&lt;br /&gt;
So the loads are the bottleneck.  This is an important thing to understand: it&#039;s possible for one type of operation to bottleneck a function.  Loads are a common example.  In this case, SAD is *so fast* that it is effectively free, as we&#039;re sitting around waiting for loads the whole time.  The actual runtime of the function is about 22 clocks.  Which is fitting for 16 + start + end + overhead.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So that&#039;s some basic performance analysis for you.  How long the function should take in theory, how long each instruction takes in theory, and how you can be bottlenecked.&lt;br /&gt;
:&amp;lt;Q&amp;gt; Is there anything that does this automatically for you?&lt;br /&gt;
:&amp;lt;A&amp;gt; Analysis?  not really.  There are intel performance counters and such on the chip  but they&#039;re not magic.  It might be useful to have some kind of tool to analyze asm functions.  In general though, intuition is a powerful tool.&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264&amp;diff=18058</id>
		<title>X264</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264&amp;diff=18058"/>
		<updated>2010-11-30T17:50:13Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: /* Developers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Lowercase}}&lt;br /&gt;
&#039;&#039;&#039;x264&#039;&#039;&#039; is a free software library for encoding [[H.264/MPEG-4 AVC]] video streams.  The code is written by Loren Merritt, Laurent Aimar, Eric Petit, Min Chen, Justin Clay, Måns Rullgård, Radek Czyz, Alex Izvorski, Alex Wright, and Christian Heine from scratch.&lt;br /&gt;
&lt;br /&gt;
x264 has a strong user community based at [http://www.Doom9.org Doom9] where discussions for improved development take place.&lt;br /&gt;
&lt;br /&gt;
== Developers  ==&lt;br /&gt;
&lt;br /&gt;
* [http://developers.videolan.org/x264.html x264 home page]&lt;br /&gt;
* [[Development Notes]]&lt;br /&gt;
* [[X264 TODO]]&lt;br /&gt;
* [[x264 asm intro]]&lt;br /&gt;
&lt;br /&gt;
== Demos ==&lt;br /&gt;
[http://lives.rm.org/demos/flyingskunk.mkv flyingskunk.mkv] demo encoded with x264/vorbis/matroska - (96 MB, 640x480, 25 fps, 6 minutes), created using [http://lives.sourceforge.net LiVES]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{stub}}&lt;br /&gt;
&lt;br /&gt;
[[Category:VideoLAN projects]]&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
	<entry>
		<id>https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18057</id>
		<title>X264 asm intro</title>
		<link rel="alternate" type="text/html" href="https://wiki.videolan.org/index.php?title=X264_asm_intro&amp;diff=18057"/>
		<updated>2010-11-30T17:48:57Z</updated>

		<summary type="html">&lt;p&gt;J Darnley: Created page with &amp;quot;Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext, [http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=H…&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Open common/x86/predict-a.asm, go to predict_4x4_dc_mmxext, [http://git.videolan.org/?p=x264.git;a=blob;f=common/x86/predict-a.asm;h=a05e91beda809b5e113df8ba122496e756442df8;hb=HEAD#l292 git link]&amp;lt;br&amp;gt;&lt;br /&gt;
This function does the following:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;  A B C D&lt;br /&gt;
E X X X X&lt;br /&gt;
F X X X X&lt;br /&gt;
G X X X X&lt;br /&gt;
H X X X X&amp;lt;/pre&amp;gt;&lt;br /&gt;
It calculates (A+B+C+D+E+F+G+H+4)/8, and sets all the Xs equal to that value where those are 8-bit pixels in a 2D array with a stride of FDEC_STRIDE.&lt;br /&gt;
:&amp;lt;Q&amp;gt; What is FDEC_STRIDE?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; x264 does all its pixel operations on the current macroblock in a temporary buffer of constant stride.  It&#039;s faster that way, and better on cache.  So for example, motion compensation will write to this buffer (or intra prediction).&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; What&#039;s a stride?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Stride is the distance between (x,y) and (x,y+1), so to get from one row to the next.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you understand what the function does, let&#039;s look at the asm.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;cglobal predict_4x4_dc_mmxext, 1,4&amp;lt;/pre&amp;gt;&lt;br /&gt;
cglobal: declares a function accessible from outside of asm&amp;lt;br&amp;gt;&lt;br /&gt;
The function&#039;s name is &amp;lt;tt&amp;gt;x264_predict_4x4_dc_mmxext&amp;lt;/tt&amp;gt; (the &amp;lt;tt&amp;gt;x264_&amp;lt;/tt&amp;gt; is auto-added).&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;1&amp;quot; means &amp;quot;we have one argument.  Put it in &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;.&amp;quot;, that argument is uint8_t *src&amp;lt;br&amp;gt;&lt;br /&gt;
If we had a second argument, we&#039;d say &amp;lt;tt&amp;gt;2&amp;lt;/tt&amp;gt; and the second one would go in &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt; and if we had a third, it&#039;d go in &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, etc.  So at the start of the function, &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; contains uint8_t *src.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; &amp;quot;that argument is uint8_t *src&amp;quot;, what does this mean?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; See the comment above: &amp;lt;tt&amp;gt;void predict_4x4_dc( uint8_t *src )&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what tells the function that it&#039;s uint8_t?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Nothing. It doesn&#039;t need to know. Types are a C-ism.&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;quot;4&amp;quot; means we want x264 to give us 4 registers to use. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. This, of course, includes the &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; used for the parameter. So in short, after the first line:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; = src&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; = free&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;r5&amp;lt;/tt&amp;gt; and up: can&#039;t use.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; That&#039;s x86inc.asm&#039;s doing right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, but we aren&#039;t going into that.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I assume it means we can use them, but if you do, it&#039;ll screw around with something you don&#039;t want to?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, which is why you can&#039;t use it.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So now, this function as you can see has 4 real steps:&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up A through D&amp;lt;br&amp;gt;&lt;br /&gt;
# Sum up E through H&amp;lt;br&amp;gt;&lt;br /&gt;
# Do the math to get our final value&amp;lt;br&amp;gt;&lt;br /&gt;
# Store it into the 16 output Xs&amp;lt;br&amp;gt;&lt;br /&gt;
So let&#039;s see how this asm implements these.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we&#039;ll look at step 1&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;pxor mm7, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is a 64-bit register.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;xor&amp;lt;/tt&amp;gt;, as you might know, is a nice way to zero things.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; How do you tell how large a register is?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;mm*&amp;lt;/tt&amp;gt; is 64-bit, &amp;lt;tt&amp;gt;xmm*&amp;lt;/tt&amp;gt; is 128-bit.  The mm registers have a fixed size, only the general purpose registers are wordsize-dependant on x86&amp;lt;br&amp;gt;&lt;br /&gt;
So, now &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd mm0, [r0-FDEC_STRIDE]&amp;lt;/pre&amp;gt;&lt;br /&gt;
This sets &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; equal to {A,B,C,D,0,0,0,0}&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, and how do we know the mm* registers are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; They always are.&amp;lt;br&amp;gt;&lt;br /&gt;
In x86, b = byte, w = word (16-bit), d = doubleword (32-bit), q = quadword (64-bit), dq = double quadword (128-bit)&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; = move doubleword = move 32 bits&amp;lt;br&amp;gt;&lt;br /&gt;
So &amp;lt;tt&amp;gt;movd&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; will load data to the first 4 bytes and zero the rest. Thus &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is now ABCD0000&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;[r0-FDEC_STRIDE]&amp;lt;/tt&amp;gt; is equivalent to &amp;lt;tt&amp;gt;*(src-FDEC_STRIDE)&amp;lt;/tt&amp;gt; in Cstyle.  Hence why it points to ABCD.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Are the &amp;quot;A B C D&amp;quot; on top of the &amp;quot;X X X X&amp;quot; or do they start on top of the &amp;quot;E&amp;quot;?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Former&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;psadbw mm0, mm7&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is what &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt; does:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;uint16_t psadbw( uint8_t in[8], uint8_t out[8] )&lt;br /&gt;
{&lt;br /&gt;
    uint16_t sum = 0;&lt;br /&gt;
    for(int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;
        sum += abs(in[i]-out[i]);&lt;br /&gt;
    return sum;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
Parse that for a moment&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; where is the sum stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;psadbw X, Y&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is where the output is stored.  So &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt; is overwritten. So it&#039;s stored in the low 16 bits of &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, of course, &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is zero!  So we get abs(A-0) + abs(B-0) + abs(C-0) + abs(D-0) + abs(0-0) ...  Or A+B+C+D.&amp;lt;br&amp;gt;&lt;br /&gt;
So after &amp;lt;tt&amp;gt;psadbw&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mm0&amp;lt;/tt&amp;gt; is A+B+C+D and &amp;lt;tt&amp;gt;mm7&amp;lt;/tt&amp;gt; is still zero.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movd r3d, mm0&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now, we move the result to &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt;, a general purpose register&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; is &amp;lt;tt&amp;gt;r3d&amp;lt;/tt&amp;gt; one of the things that come with the 4 registers that are free?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; This is an optimization: on 64-bit, using 32-bit versions of registers results in smaller instruction opcode sizes. So it&#039;s really just &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r1&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r2&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; are the 4 that are free. So we&#039;re using &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;. Note: the suffix &#039;d&#039; means the 32-bit version, as opposed to the native-size version.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Get moving with part 2 of the algorithm.&amp;lt;br&amp;gt;&lt;br /&gt;
Now &amp;lt;tt&amp;gt;r0&amp;lt;/tt&amp;gt; has our source pointer, and &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt; has A+B+C+D. While the CPU is busy doing that, we&#039;ll go and do part 2, the E+F+G+H.&amp;lt;br&amp;gt;&lt;br /&gt;
Unfortunately, these bytes aren&#039;t in a straight line (&amp;quot;straight line&amp;quot; meaning &amp;quot;adjacent in memory&amp;quot;). So we can&#039;t just load EFGH and sad them. We&#039;ll have to do it the naive/slow way.  So, now we&#039;re going to load E, F, G, H.  Now you might notice some preprocessor commands here. &amp;lt;tt&amp;gt;%assign&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;%rep&amp;lt;/tt&amp;gt;, etc are preprocessor commands.&amp;lt;br&amp;gt;&lt;br /&gt;
So, first step: load E into &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx r1d, byte [r0-1]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;movzx&amp;lt;/tt&amp;gt; means &amp;quot;move, with zero extend&amp;quot;.  In C this would be: int r1d = r0[-1];&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; My C is a bit rusty, what does that do? does it just take the location in memory before r0[0]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, [] is just a dereference of a pointer.  *(r0-1) = r0[-1] = (r0-1)[0]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; what is r0-1 in that ascii matrix?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; E.&amp;lt;br&amp;gt;&lt;br /&gt;
So, here&#039;s what these 7 lines look like after the macro runs&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;movzx  r1d, byte [r0-1]&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*1-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*2-1]&lt;br /&gt;
add    r1d, r2d&lt;br /&gt;
movzx  r2d, byte [r0+FDEC_STRIDE*3-1]&lt;br /&gt;
add    r1d, r2d&amp;lt;/pre&amp;gt;&lt;br /&gt;
in order: load E, load F, add F to E, load G, add G to E, load H, add H to E&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Where is n stored?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It isn&#039;t. It&#039;s a preprocessor variable.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Oh, so it&#039;s like a macro?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It is a macro.  Note the pre-processed code above. Everything starting with % in yasm syntax is a macro&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ok, now we have to do step 3: calculating A+B+C+D+E+F+G+H+4 / 8&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;lea r1d, [r1+r3+4]&amp;lt;/pre&amp;gt;&lt;br /&gt;
First, let&#039;s go over x86 addressing.  What you can put inside the brackets is not infinite. Here&#039;s the capabilities, specifically: [REG1 + REG2 * {1,2,4,8} + CONST]&amp;lt;br&amp;gt;&lt;br /&gt;
A register, plus another register * 1/2/4/8, plus a constant (positive or negative). As you might note, this is pretty useful for accessing things like arrays.  E.g. array[n+5], where array is an int array, would be: [array + n*4 + 20]&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; I suppose the [r0+FDEC_STRIDE*n-1] bit gets simplified on assembly to [register + const]?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; Yes, yasm sums up constants for you.&amp;lt;br&amp;gt;&lt;br /&gt;
So, as you might note, that&#039;s a pretty powerful addressing system. That&#039;s more powerful than, say... &amp;quot;add&amp;quot;. So why not expose it in an instruction to let us use it for math? So Intel did.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;lea X, [expr]&amp;lt;/tt&amp;gt; sets X equal to the value of expr just as fast as add.  So that &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; does r1d = r1 + r3 + 4&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Wait, how does that work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; runs the [REG1 + REG2 * {1,2,4,8} + CONST] math on its second argument and adds to the first.  &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt; doesn&#039;t actually address it.  It just calculates the result and stores it instead of going to memory.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; And it&#039;s faster than add?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; It&#039;s just as fast except that you can do more with it.&amp;lt;br&amp;gt;&lt;br /&gt;
Now, technically, you can do more adds per cycle than &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;, so you shouldn&#039;t go replacing all your adds with &amp;lt;tt&amp;gt;lea&amp;lt;/tt&amp;gt;.  But if you can use it to do more than one thing at a time, it&#039;s a big win. So this lets us add &amp;lt;tt&amp;gt;r3&amp;lt;/tt&amp;gt;, and add 4, in one op.&lt;br /&gt;
&amp;lt;pre&amp;gt;shr r1d, 3&amp;lt;/pre&amp;gt;&lt;br /&gt;
There&#039;s one that you can probably figure out yourself - shift right.&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; Why are we shifting right?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; +4 for correct rounding, &amp;gt;&amp;gt; 3 to divide (&amp;gt;&amp;gt;3 = /(2^3) = /8).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now for the final part: storing the results.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;imul r1d, 0x01010101&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is called a &amp;quot;splat&amp;quot; and you may have seen it in C as well.  We&#039;re turning an 8-bit value into 4x that value, e.g. A -&amp;gt; AAAA&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;Q&amp;gt; how does this work?&amp;lt;br&amp;gt;&lt;br /&gt;
:&amp;lt;A&amp;gt; A * 0x01010101 = A A A A&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So now we have a 32-bit register, &amp;lt;tt&amp;gt;r1d&amp;lt;/tt&amp;gt; with one copy of A in each 8-bit nibble of that register. Now we go ahead and store this 4 times and we&#039;re done.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we RET: x264 will automatically clean up after us.&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>J Darnley</name></author>
	</entry>
</feed>