shithub: libvpx

Download patch

ref: 9dfd0060176ad0d6f5beb465ae75a67584169acd
parent: f86e14d8dc0e063ba2623d2b9a71ec5dac1ba839
parent: 6251e9e5cee546c3b20cdc3498d43e0204db97b9
author: John Koleszar <jkoleszar@google.com>
date: Thu Jun 30 04:46:49 EDT 2011

Merge remote branch 'internal/upstream-experimental' into HEAD

Conflicts:
	vp8/encoder/bitstream.c

Change-Id: I44c00f98dcb99eb728ce4f5256aefb135a711a74

--- a/build/make/ads2gas.pl
+++ b/build/make/ads2gas.pl
@@ -82,7 +82,10 @@
     s/CODE([0-9][0-9])/.code $1/;
 
     # No AREA required
-    s/^\s*AREA.*$/.text/;
+    # But ALIGNs in AREA must be obeyed
+    s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
+    # If no ALIGN, strip the AREA and align to 4 bytes
+    s/^\s*AREA.*$/.text\n.p2align 2/;
 
     # DCD to .word
     # This one is for incoming symbols
--- a/build/make/ads2gas_apple.pl
+++ b/build/make/ads2gas_apple.pl
@@ -100,7 +100,10 @@
     s/CODE([0-9][0-9])/.code $1/;
 
     # No AREA required
-    s/^\s*AREA.*$/.text/;
+    # But ALIGNs in AREA must be obeyed
+    s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
+    # If no ALIGN, strip the AREA and align to 4 bytes
+    s/^\s*AREA.*$/.text\n.p2align 2/;
 
     # DCD to .word
     # This one is for incoming symbols
--- a/vp8/common/arm/armv6/bilinearfilter_v6.asm
+++ b/vp8/common/arm/armv6/bilinearfilter_v6.asm
@@ -30,12 +30,12 @@
     ldr     r4, [sp, #36]                   ; width
 
     mov     r12, r3                         ; outer-loop counter
-    sub     r2, r2, r4                      ; src increment for height loop
 
-    ;;IF ARCHITECTURE=6
-    pld     [r0]
-    ;;ENDIF
+    add     r7, r2, r4                      ; preload next row
+    pld     [r0, r7]
 
+    sub     r2, r2, r4                      ; src increment for height loop
+
     ldr     r5, [r11]                       ; load up filter coefficients
 
     mov     r3, r3, lsl #1                  ; height*2
@@ -96,9 +96,8 @@
     add     r0, r0, r2                      ; move to next input row
     subs    r12, r12, #1
 
-    ;;IF ARCHITECTURE=6
-    pld     [r0]
-    ;;ENDIF
+    add     r9, r2, r4, lsl #1              ; adding back block width
+    pld     [r0, r9]                        ; preload next row
 
     add     r11, r11, #2                    ; move over to next column
     mov     r1, r11
--- a/vp8/common/arm/armv6/copymem16x16_v6.asm
+++ b/vp8/common/arm/armv6/copymem16x16_v6.asm
@@ -22,9 +22,7 @@
     ;push   {r4-r7}
 
     ;preload
-    pld     [r0]
-    pld     [r0, r1]
-    pld     [r0, r1, lsl #1]
+    pld     [r0, #31]                ; preload for next 16x16 block
 
     ands    r4, r0, #15
     beq     copy_mem16x16_fast
@@ -90,6 +88,8 @@
     ldrneb  r6, [r0, #2]
     ldrneb  r7, [r0, #3]
 
+    pld     [r0, #31]               ; preload for next 16x16 block
+
     bne     copy_mem16x16_1_loop
 
     ldmia       sp!, {r4 - r7}
@@ -121,6 +121,8 @@
     ldrne   r6, [r0, #8]
     ldrne   r7, [r0, #12]
 
+    pld     [r0, #31]               ; preload for next 16x16 block
+
     bne     copy_mem16x16_4_loop
 
     ldmia       sp!, {r4 - r7}
@@ -148,6 +150,7 @@
 
     add     r2, r2, r3
 
+    pld     [r0, #31]               ; preload for next 16x16 block
     bne     copy_mem16x16_8_loop
 
     ldmia       sp!, {r4 - r7}
@@ -171,6 +174,7 @@
     ;stm        r2, {r4-r7}
     add     r2, r2, r3
 
+    pld     [r0, #31]               ; preload for next 16x16 block
     bne     copy_mem16x16_fast_loop
 
     ldmia       sp!, {r4 - r7}
--- a/vp8/common/arm/armv6/filter_v6.asm
+++ b/vp8/common/arm/armv6/filter_v6.asm
@@ -10,6 +10,8 @@
 
 
     EXPORT  |vp8_filter_block2d_first_pass_armv6|
+    EXPORT  |vp8_filter_block2d_first_pass_16x16_armv6|
+    EXPORT  |vp8_filter_block2d_first_pass_8x8_armv6|
     EXPORT  |vp8_filter_block2d_second_pass_armv6|
     EXPORT  |vp8_filter4_block2d_second_pass_armv6|
     EXPORT  |vp8_filter_block2d_first_pass_only_armv6|
@@ -40,11 +42,6 @@
     add     r12, r3, #16                    ; square off the output
     sub     sp, sp, #4
 
-    ;;IF ARCHITECTURE=6
-    ;pld        [r0, #-2]
-    ;;pld       [r0, #30]
-    ;;ENDIF
-
     ldr     r4, [r11]                       ; load up packed filter coefficients
     ldr     r5, [r11, #4]
     ldr     r6, [r11, #8]
@@ -101,15 +98,10 @@
 
     bne     width_loop_1st_6
 
-    ;;add       r9, r2, #30                 ; attempt to load 2 adjacent cache lines
-    ;;IF ARCHITECTURE=6
-    ;pld        [r0, r2]
-    ;;pld       [r0, r9]
-    ;;ENDIF
-
     ldr     r1, [sp]                        ; load and update dst address
     subs    r7, r7, #0x10000
     add     r0, r0, r2                      ; move to next input line
+
     add     r1, r1, #2                      ; move over to next column
     str     r1, [sp]
 
@@ -120,6 +112,192 @@
 
     ENDP
 
+; --------------------------
+; 16x16 version
+; -----------------------------
+|vp8_filter_block2d_first_pass_16x16_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; vp8_filter address
+    ldr     r7, [sp, #36]                   ; output height
+
+    add     r4, r2, #18                     ; preload next low
+    pld     [r0, r4]
+
+    sub     r2, r2, r3                      ; inside loop increments input array,
+                                            ; so the height loop only needs to add
+                                            ; r2 - width to the input pointer
+
+    mov     r3, r3, lsl #1                  ; multiply width by 2 because using shorts
+    add     r12, r3, #16                    ; square off the output
+    sub     sp, sp, #4
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+    str     r1, [sp]                        ; push destination to stack
+    mov     r7, r7, lsl #16                 ; height is top part of counter
+
+; six tap filter
+|height_loop_1st_16_6|
+    ldrb    r8, [r0, #-2]                   ; load source data
+    ldrb    r9, [r0, #-1]
+    ldrb    r10, [r0], #2
+    orr     r7, r7, r3, lsr #2              ; construct loop counter
+
+|width_loop_1st_16_6|
+    ldrb    r11, [r0, #-1]
+
+    pkhbt   lr, r8, r9, lsl #16             ; r9 | r8
+    pkhbt   r8, r9, r10, lsl #16            ; r10 | r9
+
+    ldrb    r9, [r0]
+
+    smuad   lr, lr, r4                      ; apply the filter
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+    smuad   r8, r8, r4
+    pkhbt   r11, r11, r9, lsl #16           ; r9 | r11
+
+    smlad   lr, r10, r5, lr
+    ldrb    r10, [r0, #1]
+    smlad   r8, r11, r5, r8
+    ldrb    r11, [r0, #2]
+
+    sub     r7, r7, #1
+
+    pkhbt   r9, r9, r10, lsl #16            ; r10 | r9
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+
+    smlad   lr, r9, r6, lr
+    smlad   r11, r10, r6, r8
+
+    ands    r10, r7, #0xff                  ; test loop counter
+
+    add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ldrneb  r8, [r0, #-2]                   ; load data for next loop
+    usat    lr, #8, lr, asr #7
+    add     r11, r11, #0x40
+    ldrneb  r9, [r0, #-1]
+    usat    r11, #8, r11, asr #7
+
+    strh    lr, [r1], r12                   ; result is transposed and stored, which
+                                            ; will make second pass filtering easier.
+    ldrneb  r10, [r0], #2
+    strh    r11, [r1], r12
+
+    bne     width_loop_1st_16_6
+
+    ldr     r1, [sp]                        ; load and update dst address
+    subs    r7, r7, #0x10000
+    add     r0, r0, r2                      ; move to next input line
+
+    add     r11, r2, #34                    ; adding back block width(=16)
+    pld     [r0, r11]                       ; preload next low
+
+    add     r1, r1, #2                      ; move over to next column
+    str     r1, [sp]
+
+    bne     height_loop_1st_16_6
+
+    add     sp, sp, #4
+    ldmia   sp!, {r4 - r11, pc}
+
+    ENDP
+
+; --------------------------
+; 8x8 version
+; -----------------------------
+|vp8_filter_block2d_first_pass_8x8_armv6| PROC
+    stmdb   sp!, {r4 - r11, lr}
+
+    ldr     r11, [sp, #40]                  ; vp8_filter address
+    ldr     r7, [sp, #36]                   ; output height
+
+    add     r4, r2, #10                     ; preload next low
+    pld     [r0, r4]
+
+    sub     r2, r2, r3                      ; inside loop increments input array,
+                                            ; so the height loop only needs to add
+                                            ; r2 - width to the input pointer
+
+    mov     r3, r3, lsl #1                  ; multiply width by 2 because using shorts
+    add     r12, r3, #16                    ; square off the output
+    sub     sp, sp, #4
+
+    ldr     r4, [r11]                       ; load up packed filter coefficients
+    ldr     r5, [r11, #4]
+    ldr     r6, [r11, #8]
+
+    str     r1, [sp]                        ; push destination to stack
+    mov     r7, r7, lsl #16                 ; height is top part of counter
+
+; six tap filter
+|height_loop_1st_8_6|
+    ldrb    r8, [r0, #-2]                   ; load source data
+    ldrb    r9, [r0, #-1]
+    ldrb    r10, [r0], #2
+    orr     r7, r7, r3, lsr #2              ; construct loop counter
+
+|width_loop_1st_8_6|
+    ldrb    r11, [r0, #-1]
+
+    pkhbt   lr, r8, r9, lsl #16             ; r9 | r8
+    pkhbt   r8, r9, r10, lsl #16            ; r10 | r9
+
+    ldrb    r9, [r0]
+
+    smuad   lr, lr, r4                      ; apply the filter
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+    smuad   r8, r8, r4
+    pkhbt   r11, r11, r9, lsl #16           ; r9 | r11
+
+    smlad   lr, r10, r5, lr
+    ldrb    r10, [r0, #1]
+    smlad   r8, r11, r5, r8
+    ldrb    r11, [r0, #2]
+
+    sub     r7, r7, #1
+
+    pkhbt   r9, r9, r10, lsl #16            ; r10 | r9
+    pkhbt   r10, r10, r11, lsl #16          ; r11 | r10
+
+    smlad   lr, r9, r6, lr
+    smlad   r11, r10, r6, r8
+
+    ands    r10, r7, #0xff                  ; test loop counter
+
+    add     lr, lr, #0x40                   ; round_shift_and_clamp
+    ldrneb  r8, [r0, #-2]                   ; load data for next loop
+    usat    lr, #8, lr, asr #7
+    add     r11, r11, #0x40
+    ldrneb  r9, [r0, #-1]
+    usat    r11, #8, r11, asr #7
+
+    strh    lr, [r1], r12                   ; result is transposed and stored, which
+                                            ; will make second pass filtering easier.
+    ldrneb  r10, [r0], #2
+    strh    r11, [r1], r12
+
+    bne     width_loop_1st_8_6
+
+    ldr     r1, [sp]                        ; load and update dst address
+    subs    r7, r7, #0x10000
+    add     r0, r0, r2                      ; move to next input line
+
+    add     r11, r2, #18                    ; adding back block width(=8)
+    pld     [r0, r11]                       ; preload next low
+
+    add     r1, r1, #2                      ; move over to next column
+    str     r1, [sp]
+
+    bne     height_loop_1st_8_6
+
+    add     sp, sp, #4
+    ldmia   sp!, {r4 - r11, pc}
+
+    ENDP
+
 ;---------------------------------
 ; r0    short         *src_ptr,
 ; r1    unsigned char *output_ptr,
@@ -262,6 +440,10 @@
 |vp8_filter_block2d_first_pass_only_armv6| PROC
     stmdb   sp!, {r4 - r11, lr}
 
+    add     r7, r2, r3                      ; preload next low
+    add     r7, r7, #2
+    pld     [r0, r7]
+
     ldr     r4, [sp, #36]                   ; output pitch
     ldr     r11, [sp, #40]                  ; HFilter address
     sub     sp, sp, #8
@@ -330,16 +512,15 @@
 
     bne     width_loop_1st_only_6
 
-    ;;add       r9, r2, #30                 ; attempt to load 2 adjacent cache lines
-    ;;IF ARCHITECTURE=6
-    ;pld        [r0, r2]
-    ;;pld       [r0, r9]
-    ;;ENDIF
-
     ldr     lr, [sp]                        ; load back output pitch
     ldr     r12, [sp, #4]                   ; load back output pitch
     subs    r7, r7, #1
     add     r0, r0, r12                     ; updata src for next loop
+
+    add     r11, r12, r3                    ; preload next low
+    add     r11, r11, #2
+    pld     [r0, r11]
+
     add     r1, r1, lr                      ; update dst for next loop
 
     bne     height_loop_1st_only_6
--- a/vp8/common/arm/armv6/loopfilter_v6.asm
+++ b/vp8/common/arm/armv6/loopfilter_v6.asm
@@ -253,12 +253,6 @@
 
     subs        count, count, #1
 
-    ;pld            [src]
-    ;pld            [src, pstep]
-    ;pld            [src, pstep, lsl #1]
-    ;pld            [src, pstep, lsl #2]
-    ;pld            [src, pstep, lsl #3]
-
     ldrne       r9, [src], pstep            ; p3
     ldrne       r10, [src], pstep           ; p2
     ldrne       r11, [src], pstep           ; p1
@@ -857,15 +851,19 @@
     sub         src, src, #4                ; move src pointer down by 4
     ldr         count, [sp, #40]            ; count for 8-in-parallel
     ldr         r12, [sp, #36]              ; load thresh address
+    pld         [src, #23]                  ; preload for next block
     sub         sp, sp, #16                 ; create temp buffer
 
     ldr         r6, [src], pstep            ; load source data
     ldr         r4, [r2], #4                ; flimit
+    pld         [src, #23]
     ldr         r7, [src], pstep
     ldr         r2, [r3], #4                ; limit
+    pld         [src, #23]
     ldr         r8, [src], pstep
     uadd8       r4, r4, r4                  ; flimit * 2
     ldr         r3, [r12], #4               ; thresh
+    pld         [src, #23]
     ldr         lr, [src], pstep
     mov         count, count, lsl #1        ; 4-in-parallel
     uadd8       r4, r4, r2                  ; flimit * 2 + limit
@@ -1242,9 +1240,13 @@
     sub         src, src, #4
     subs        count, count, #1
 
+    pld         [src, #23]                  ; preload for next block
     ldrne       r6, [src], pstep            ; load source data
+    pld         [src, #23]
     ldrne       r7, [src], pstep
+    pld         [src, #23]
     ldrne       r8, [src], pstep
+    pld         [src, #23]
     ldrne       lr, [src], pstep
 
     bne         MBVnext8
--- a/vp8/common/arm/armv6/simpleloopfilter_v6.asm
+++ b/vp8/common/arm/armv6/simpleloopfilter_v6.asm
@@ -154,10 +154,12 @@
 
     ; load soure data to r7, r8, r9, r10
     ldrh        r3, [src, #-2]
+    pld         [src, #23]                  ; preload for next block
     ldrh        r4, [src], pstep
     uadd8       r12, r12, r12               ; flimit * 2
 
     ldrh        r5, [src, #-2]
+    pld         [src, #23]
     ldrh        r6, [src], pstep
     uadd8       r12, r12, r7                ; flimit * 2 + limit
 
@@ -164,6 +166,7 @@
     pkhbt       r7, r3, r4, lsl #16
 
     ldrh        r3, [src, #-2]
+    pld         [src, #23]
     ldrh        r4, [src], pstep
     ldr         r11, [sp, #40]              ; count (r11) for 8-in-parallel
 
@@ -170,6 +173,7 @@
     pkhbt       r8, r5, r6, lsl #16
 
     ldrh        r5, [src, #-2]
+    pld         [src, #23]
     ldrh        r6, [src], pstep
     mov         r11, r11, lsl #1            ; 4-in-parallel
 
@@ -259,19 +263,23 @@
 
     ; load soure data to r7, r8, r9, r10
     ldrneh      r3, [src, #-2]
+    pld         [src, #23]                  ; preload for next block
     ldrneh      r4, [src], pstep
 
     ldrneh      r5, [src, #-2]
+    pld         [src, #23]
     ldrneh      r6, [src], pstep
 
     pkhbt       r7, r3, r4, lsl #16
 
     ldrneh      r3, [src, #-2]
+    pld         [src, #23]
     ldrneh      r4, [src], pstep
 
     pkhbt       r8, r5, r6, lsl #16
 
     ldrneh      r5, [src, #-2]
+    pld         [src, #23]
     ldrneh      r6, [src], pstep
 
     bne         simple_vnext8
--- a/vp8/common/arm/armv6/sixtappredict8x4_v6.asm
+++ b/vp8/common/arm/armv6/sixtappredict8x4_v6.asm
@@ -32,9 +32,12 @@
     beq         skip_firstpass_filter
 
 ;first-pass filter
-    ldr         r12, _filter8_coeff_
+    adr         r12, filter8_coeff
     sub         r0, r0, r1, lsl #1
 
+    add         r3, r1, #10                 ; preload next low
+    pld         [r0, r3]
+
     add         r2, r12, r2, lsl #4         ;calculate filter location
     add         r0, r0, #3                  ;adjust src only for loading convinience
 
@@ -110,6 +113,9 @@
 
     add         r0, r0, r1                  ; move to next input line
 
+    add         r11, r1, #18                ; preload next low. adding back block width(=8), which is subtracted earlier
+    pld         [r0, r11]
+
     bne         first_pass_hloop_v6
 
 ;second pass filter
@@ -121,7 +127,7 @@
     cmp         r3, #0
     beq         skip_secondpass_filter
 
-    ldr         r12, _filter8_coeff_
+    adr         r12, filter8_coeff
     add         lr, r12, r3, lsl #4         ;calculate filter location
 
     mov         r2, #0x00080000
@@ -245,8 +251,6 @@
 ;-----------------
 ;One word each is reserved. Label filter_coeff can be used to access the data.
 ;Data address: filter_coeff, filter_coeff+4, filter_coeff+8 ...
-_filter8_coeff_
-    DCD     filter8_coeff
 filter8_coeff
     DCD     0x00000000,     0x00000080,     0x00000000,     0x00000000
     DCD     0xfffa0000,     0x000c007b,     0x0000ffff,     0x00000000
--- a/vp8/common/arm/filter_arm.c
+++ b/vp8/common/arm/filter_arm.c
@@ -25,6 +25,28 @@
     const short *vp8_filter
 );
 
+// 8x8
+extern void vp8_filter_block2d_first_pass_8x8_armv6
+(
+    unsigned char *src_ptr,
+    short         *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int output_width,
+    unsigned int output_height,
+    const short *vp8_filter
+);
+
+// 16x16
+extern void vp8_filter_block2d_first_pass_16x16_armv6
+(
+    unsigned char *src_ptr,
+    short         *output_ptr,
+    unsigned int src_pixels_per_line,
+    unsigned int output_width,
+    unsigned int output_height,
+    const short *vp8_filter
+);
+
 extern void vp8_filter_block2d_second_pass_armv6
 (
     short         *src_ptr,
@@ -143,12 +165,12 @@
     {
         if (yoffset & 0x1)
         {
-            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 8, 11, HFilter);
+            vp8_filter_block2d_first_pass_8x8_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 8, 11, HFilter);
             vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
         }
         else
         {
-            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 8, 13, HFilter);
+            vp8_filter_block2d_first_pass_8x8_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 8, 13, HFilter);
             vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
         }
     }
@@ -185,12 +207,12 @@
     {
         if (yoffset & 0x1)
         {
-            vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 16, 19, HFilter);
+            vp8_filter_block2d_first_pass_16x16_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 16, 19, HFilter);
             vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
         }
         else
         {
-            vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 16, 21, HFilter);
+            vp8_filter_block2d_first_pass_16x16_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 16, 21, HFilter);
             vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
         }
     }
--- a/vp8/common/arm/neon/bilinearpredict16x16_neon.asm
+++ b/vp8/common/arm/neon/bilinearpredict16x16_neon.asm
@@ -25,7 +25,7 @@
 |vp8_bilinear_predict16x16_neon| PROC
     push            {r4-r5, lr}
 
-    ldr             r12, _bifilter16_coeff_
+    adr             r12, bifilter16_coeff
     ldr             r4, [sp, #12]           ;load parameters from stack
     ldr             r5, [sp, #16]           ;load parameters from stack
 
@@ -351,8 +351,6 @@
 
 ;-----------------
 
-_bifilter16_coeff_
-    DCD     bifilter16_coeff
 bifilter16_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
--- a/vp8/common/arm/neon/bilinearpredict4x4_neon.asm
+++ b/vp8/common/arm/neon/bilinearpredict4x4_neon.asm
@@ -25,7 +25,7 @@
 |vp8_bilinear_predict4x4_neon| PROC
     push            {r4, lr}
 
-    ldr             r12, _bifilter4_coeff_
+    adr             r12, bifilter4_coeff
     ldr             r4, [sp, #8]            ;load parameters from stack
     ldr             lr, [sp, #12]           ;load parameters from stack
 
@@ -124,8 +124,6 @@
 
 ;-----------------
 
-_bifilter4_coeff_
-    DCD     bifilter4_coeff
 bifilter4_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
--- a/vp8/common/arm/neon/bilinearpredict8x4_neon.asm
+++ b/vp8/common/arm/neon/bilinearpredict8x4_neon.asm
@@ -25,7 +25,7 @@
 |vp8_bilinear_predict8x4_neon| PROC
     push            {r4, lr}
 
-    ldr             r12, _bifilter8x4_coeff_
+    adr             r12, bifilter8x4_coeff
     ldr             r4, [sp, #8]            ;load parameters from stack
     ldr             lr, [sp, #12]           ;load parameters from stack
 
@@ -129,8 +129,6 @@
 
 ;-----------------
 
-_bifilter8x4_coeff_
-    DCD     bifilter8x4_coeff
 bifilter8x4_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
--- a/vp8/common/arm/neon/bilinearpredict8x8_neon.asm
+++ b/vp8/common/arm/neon/bilinearpredict8x8_neon.asm
@@ -25,7 +25,7 @@
 |vp8_bilinear_predict8x8_neon| PROC
     push            {r4, lr}
 
-    ldr             r12, _bifilter8_coeff_
+    adr             r12, bifilter8_coeff
     ldr             r4, [sp, #8]            ;load parameters from stack
     ldr             lr, [sp, #12]           ;load parameters from stack
 
@@ -177,8 +177,6 @@
 
 ;-----------------
 
-_bifilter8_coeff_
-    DCD     bifilter8_coeff
 bifilter8_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
--- a/vp8/common/arm/neon/shortidct4x4llm_neon.asm
+++ b/vp8/common/arm/neon/shortidct4x4llm_neon.asm
@@ -31,7 +31,7 @@
 ;result of the multiplication that is needed in IDCT.
 
 |vp8_short_idct4x4llm_neon| PROC
-    ldr             r12, _idct_coeff_
+    adr             r12, idct_coeff
     vld1.16         {q1, q2}, [r0]
     vld1.16         {d0}, [r12]
 
@@ -114,8 +114,6 @@
 
 ;-----------------
 
-_idct_coeff_
-    DCD     idct_coeff
 idct_coeff
     DCD     0x4e7b4e7b, 0x8a8c8a8c
 
--- a/vp8/common/arm/neon/sixtappredict16x16_neon.asm
+++ b/vp8/common/arm/neon/sixtappredict16x16_neon.asm
@@ -15,6 +15,17 @@
     PRESERVE8
 
     AREA ||.text||, CODE, READONLY, ALIGN=2
+
+filter16_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
 ; r0    unsigned char  *src_ptr,
 ; r1    int  src_pixels_per_line,
 ; r2    int  xoffset,
@@ -33,7 +44,7 @@
 |vp8_sixtap_predict16x16_neon| PROC
     push            {r4-r5, lr}
 
-    ldr             r12, _filter16_coeff_
+    adr             r12, filter16_coeff
     ldr             r4, [sp, #12]           ;load parameters from stack
     ldr             r5, [sp, #16]           ;load parameters from stack
 
@@ -476,17 +487,4 @@
     ENDP
 
 ;-----------------
-
-_filter16_coeff_
-    DCD     filter16_coeff
-filter16_coeff
-    DCD     0,  0,  128,    0,   0,  0,   0,  0
-    DCD     0, -6,  123,   12,  -1,  0,   0,  0
-    DCD     2, -11, 108,   36,  -8,  1,   0,  0
-    DCD     0, -9,   93,   50,  -6,  0,   0,  0
-    DCD     3, -16,  77,   77, -16,  3,   0,  0
-    DCD     0, -6,   50,   93,  -9,  0,   0,  0
-    DCD     1, -8,   36,  108, -11,  2,   0,  0
-    DCD     0, -1,   12,  123,  -6,   0,  0,  0
-
     END
--- a/vp8/common/arm/neon/sixtappredict4x4_neon.asm
+++ b/vp8/common/arm/neon/sixtappredict4x4_neon.asm
@@ -15,6 +15,17 @@
     PRESERVE8
 
     AREA ||.text||, CODE, READONLY, ALIGN=2
+
+filter4_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
 ; r0    unsigned char  *src_ptr,
 ; r1    int  src_pixels_per_line,
 ; r2    int  xoffset,
@@ -25,7 +36,7 @@
 |vp8_sixtap_predict_neon| PROC
     push            {r4, lr}
 
-    ldr             r12, _filter4_coeff_
+    adr             r12, filter4_coeff
     ldr             r4, [sp, #8]            ;load parameters from stack
     ldr             lr, [sp, #12]           ;load parameters from stack
 
@@ -407,17 +418,5 @@
     ENDP
 
 ;-----------------
-
-_filter4_coeff_
-    DCD     filter4_coeff
-filter4_coeff
-    DCD     0,  0,  128,    0,   0,  0,   0,  0
-    DCD     0, -6,  123,   12,  -1,  0,   0,  0
-    DCD     2, -11, 108,   36,  -8,  1,   0,  0
-    DCD     0, -9,   93,   50,  -6,  0,   0,  0
-    DCD     3, -16,  77,   77, -16,  3,   0,  0
-    DCD     0, -6,   50,   93,  -9,  0,   0,  0
-    DCD     1, -8,   36,  108, -11,  2,   0,  0
-    DCD     0, -1,   12,  123,  -6,   0,  0,  0
 
     END
--- a/vp8/common/arm/neon/sixtappredict8x4_neon.asm
+++ b/vp8/common/arm/neon/sixtappredict8x4_neon.asm
@@ -15,6 +15,17 @@
     PRESERVE8
 
     AREA ||.text||, CODE, READONLY, ALIGN=2
+
+filter8_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
 ; r0    unsigned char  *src_ptr,
 ; r1    int  src_pixels_per_line,
 ; r2    int  xoffset,
@@ -25,7 +36,7 @@
 |vp8_sixtap_predict8x4_neon| PROC
     push            {r4-r5, lr}
 
-    ldr             r12, _filter8_coeff_
+    adr             r12, filter8_coeff
     ldr             r4, [sp, #12]           ;load parameters from stack
     ldr             r5, [sp, #16]           ;load parameters from stack
 
@@ -458,17 +469,5 @@
     ENDP
 
 ;-----------------
-
-_filter8_coeff_
-    DCD     filter8_coeff
-filter8_coeff
-    DCD     0,  0,  128,    0,   0,  0,   0,  0
-    DCD     0, -6,  123,   12,  -1,  0,   0,  0
-    DCD     2, -11, 108,   36,  -8,  1,   0,  0
-    DCD     0, -9,   93,   50,  -6,  0,   0,  0
-    DCD     3, -16,  77,   77, -16,  3,   0,  0
-    DCD     0, -6,   50,   93,  -9,  0,   0,  0
-    DCD     1, -8,   36,  108, -11,  2,   0,  0
-    DCD     0, -1,   12,  123,  -6,   0,  0,  0
 
     END
--- a/vp8/common/arm/neon/sixtappredict8x8_neon.asm
+++ b/vp8/common/arm/neon/sixtappredict8x8_neon.asm
@@ -15,6 +15,17 @@
     PRESERVE8
 
     AREA ||.text||, CODE, READONLY, ALIGN=2
+
+filter8_coeff
+    DCD     0,  0,  128,    0,   0,  0,   0,  0
+    DCD     0, -6,  123,   12,  -1,  0,   0,  0
+    DCD     2, -11, 108,   36,  -8,  1,   0,  0
+    DCD     0, -9,   93,   50,  -6,  0,   0,  0
+    DCD     3, -16,  77,   77, -16,  3,   0,  0
+    DCD     0, -6,   50,   93,  -9,  0,   0,  0
+    DCD     1, -8,   36,  108, -11,  2,   0,  0
+    DCD     0, -1,   12,  123,  -6,   0,  0,  0
+
 ; r0    unsigned char  *src_ptr,
 ; r1    int  src_pixels_per_line,
 ; r2    int  xoffset,
@@ -25,7 +36,7 @@
 |vp8_sixtap_predict8x8_neon| PROC
     push            {r4-r5, lr}
 
-    ldr             r12, _filter8_coeff_
+    adr             r12, filter8_coeff
 
     ldr             r4, [sp, #12]           ;load parameters from stack
     ldr             r5, [sp, #16]           ;load parameters from stack
@@ -509,17 +520,5 @@
     ENDP
 
 ;-----------------
-
-_filter8_coeff_
-    DCD     filter8_coeff
-filter8_coeff
-    DCD     0,  0,  128,    0,   0,  0,   0,  0
-    DCD     0, -6,  123,   12,  -1,  0,   0,  0
-    DCD     2, -11, 108,   36,  -8,  1,   0,  0
-    DCD     0, -9,   93,   50,  -6,  0,   0,  0
-    DCD     3, -16,  77,   77, -16,  3,   0,  0
-    DCD     0, -6,   50,   93,  -9,  0,   0,  0
-    DCD     1, -8,   36,  108, -11,  2,   0,  0
-    DCD     0, -1,   12,  123,  -6,   0,  0,  0
 
     END
--- a/vp8/common/coefupdateprobs.h
+++ b/vp8/common/coefupdateprobs.h
@@ -12,7 +12,7 @@
 /* Update probabilities for the nodes in the token entropy tree.
    Generated file included by entropy.c */
 
-const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] =
+const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] =
 {
     {
         {
--- /dev/null
+++ b/vp8/common/defaultcoefcounts.c
@@ -1,0 +1,225 @@
+/*
+ *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "defaultcoefcounts.h"
+
+/* Generated file, included by entropy.c */
+
+const unsigned int vp8_default_coef_counts[BLOCK_TYPES]
+                                          [COEF_BANDS]
+                                          [PREV_COEF_CONTEXTS]
+                                          [MAX_ENTROPY_TOKENS] =
+{
+
+    {
+        /* Block Type ( 0 ) */
+        {
+            /* Coeff Band ( 0 ) */
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+        {
+            /* Coeff Band ( 1 ) */
+            {30190, 26544, 225,  24,   4,   0,   0,   0,   0,   0,   0, 4171593,},
+            {26846, 25157, 1241, 130,  26,   6,   1,   0,   0,   0,   0, 149987,},
+            {10484, 9538, 1006, 160,  36,  18,   0,   0,   0,   0,   0, 15104,},
+        },
+        {
+            /* Coeff Band ( 2 ) */
+            {25842, 40456, 1126,  83,  11,   2,   0,   0,   0,   0,   0,   0,},
+            {9338, 8010, 512,  73,   7,   3,   2,   0,   0,   0,   0, 43294,},
+            {1047, 751, 149,  31,  13,   6,   1,   0,   0,   0,   0, 879,},
+        },
+        {
+            /* Coeff Band ( 3 ) */
+            {26136, 9826, 252,  13,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {8134, 5574, 191,  14,   2,   0,   0,   0,   0,   0,   0, 35302,},
+            { 605, 677, 116,   9,   1,   0,   0,   0,   0,   0,   0, 611,},
+        },
+        {
+            /* Coeff Band ( 4 ) */
+            {10263, 15463, 283,  17,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2773, 2191, 128,   9,   2,   2,   0,   0,   0,   0,   0, 10073,},
+            { 134, 125,  32,   4,   0,   2,   0,   0,   0,   0,   0,  50,},
+        },
+        {
+            /* Coeff Band ( 5 ) */
+            {10483, 2663,  23,   1,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {2137, 1251,  27,   1,   1,   0,   0,   0,   0,   0,   0, 14362,},
+            { 116, 156,  14,   2,   1,   0,   0,   0,   0,   0,   0, 190,},
+        },
+        {
+            /* Coeff Band ( 6 ) */
+            {40977, 27614, 412,  28,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {6113, 5213, 261,  22,   3,   0,   0,   0,   0,   0,   0, 26164,},
+            { 382, 312,  50,  14,   2,   0,   0,   0,   0,   0,   0, 345,},
+        },
+        {
+            /* Coeff Band ( 7 ) */
+            {   0,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  13,   0,   0,   0,   0,   0,   0,   0,   0,   0, 319,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,},
+        },
+    },
+    {
+        /* Block Type ( 1 ) */
+        {
+            /* Coeff Band ( 0 ) */
+            {3268, 19382, 1043, 250,  93,  82,  49,  26,  17,   8,  25, 82289,},
+            {8758, 32110, 5436, 1832, 827, 668, 420, 153,  24,   0,   3, 52914,},
+            {9337, 23725, 8487, 3954, 2107, 1836, 1069, 399,  59,   0,   0, 18620,},
+        },
+        {
+            /* Coeff Band ( 1 ) */
+            {12419, 8420, 452,  62,   9,   1,   0,   0,   0,   0,   0,   0,},
+            {11715, 8705, 693,  92,  15,   7,   2,   0,   0,   0,   0, 53988,},
+            {7603, 8585, 2306, 778, 270, 145,  39,   5,   0,   0,   0, 9136,},
+        },
+        {
+            /* Coeff Band ( 2 ) */
+            {15938, 14335, 1207, 184,  55,  13,   4,   1,   0,   0,   0,   0,},
+            {7415, 6829, 1138, 244,  71,  26,   7,   0,   0,   0,   0, 9980,},
+            {1580, 1824, 655, 241,  89,  46,  10,   2,   0,   0,   0, 429,},
+        },
+        {
+            /* Coeff Band ( 3 ) */
+            {19453, 5260, 201,  19,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {9173, 3758, 213,  22,   1,   1,   0,   0,   0,   0,   0, 9820,},
+            {1689, 1277, 276,  51,  17,   4,   0,   0,   0,   0,   0, 679,},
+        },
+        {
+            /* Coeff Band ( 4 ) */
+            {12076, 10667, 620,  85,  19,   9,   5,   0,   0,   0,   0,   0,},
+            {4665, 3625, 423,  55,  19,   9,   0,   0,   0,   0,   0, 5127,},
+            { 415, 440, 143,  34,  20,   7,   2,   0,   0,   0,   0, 101,},
+        },
+        {
+            /* Coeff Band ( 5 ) */
+            {12183, 4846, 115,  11,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {4226, 3149, 177,  21,   2,   0,   0,   0,   0,   0,   0, 7157,},
+            { 375, 621, 189,  51,  11,   4,   1,   0,   0,   0,   0, 198,},
+        },
+        {
+            /* Coeff Band ( 6 ) */
+            {61658, 37743, 1203,  94,  10,   3,   0,   0,   0,   0,   0,   0,},
+            {15514, 11563, 903, 111,  14,   5,   0,   0,   0,   0,   0, 25195,},
+            { 929, 1077, 291,  78,  14,   7,   1,   0,   0,   0,   0, 507,},
+        },
+        {
+            /* Coeff Band ( 7 ) */
+            {   0, 990,  15,   3,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0, 412,  13,   0,   0,   0,   0,   0,   0,   0,   0, 1641,},
+            {   0,  18,   7,   1,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+    },
+    {
+        /* Block Type ( 2 ) */
+        {
+            /* Coeff Band ( 0 ) */
+            { 953, 24519, 628, 120,  28,  12,   4,   0,   0,   0,   0, 2248798,},
+            {1525, 25654, 2647, 617, 239, 143,  42,   5,   0,   0,   0, 66837,},
+            {1180, 11011, 3001, 1237, 532, 448, 239,  54,   5,   0,   0, 7122,},
+        },
+        {
+            /* Coeff Band ( 1 ) */
+            {1356, 2220,  67,  10,   4,   1,   0,   0,   0,   0,   0,   0,},
+            {1450, 2544, 102,  18,   4,   3,   0,   0,   0,   0,   0, 57063,},
+            {1182, 2110, 470, 130,  41,  21,   0,   0,   0,   0,   0, 6047,},
+        },
+        {
+            /* Coeff Band ( 2 ) */
+            { 370, 3378, 200,  30,   5,   4,   1,   0,   0,   0,   0,   0,},
+            { 293, 1006, 131,  29,  11,   0,   0,   0,   0,   0,   0, 5404,},
+            { 114, 387,  98,  23,   4,   8,   1,   0,   0,   0,   0, 236,},
+        },
+        {
+            /* Coeff Band ( 3 ) */
+            { 579, 194,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            { 395, 213,   5,   1,   0,   0,   0,   0,   0,   0,   0, 4157,},
+            { 119, 122,   4,   0,   0,   0,   0,   0,   0,   0,   0, 300,},
+        },
+        {
+            /* Coeff Band ( 4 ) */
+            {  38, 557,  19,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  21, 114,  12,   1,   0,   0,   0,   0,   0,   0,   0, 427,},
+            {   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,},
+        },
+        {
+            /* Coeff Band ( 5 ) */
+            {  52,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  18,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0, 652,},
+            {   1,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  30,},
+        },
+        {
+            /* Coeff Band ( 6 ) */
+            { 640, 569,  10,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {  25,  77,   2,   0,   0,   0,   0,   0,   0,   0,   0, 517,},
+            {   4,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,},
+        },
+        {
+            /* Coeff Band ( 7 ) */
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+        },
+    },
+    {
+        /* Block Type ( 3 ) */
+        {
+            /* Coeff Band ( 0 ) */
+            {2506, 20161, 2707, 767, 261, 178, 107,  30,  14,   3,   0, 100694,},
+            {8806, 36478, 8817, 3268, 1280, 850, 401, 114,  42,   0,   0, 58572,},
+            {11003, 27214, 11798, 5716, 2482, 2072, 1048, 175,  32,   0,   0, 19284,},
+        },
+        {
+            /* Coeff Band ( 1 ) */
+            {9738, 11313, 959, 205,  70,  18,  11,   1,   0,   0,   0,   0,},
+            {12628, 15085, 1507, 273,  52,  19,   9,   0,   0,   0,   0, 54280,},
+            {10701, 15846, 5561, 1926, 813, 570, 249,  36,   0,   0,   0, 6460,},
+        },
+        {
+            /* Coeff Band ( 2 ) */
+            {6781, 22539, 2784, 634, 182, 123,  20,   4,   0,   0,   0,   0,},
+            {6263, 11544, 2649, 790, 259, 168,  27,   5,   0,   0,   0, 20539,},
+            {3109, 4075, 2031, 896, 457, 386, 158,  29,   0,   0,   0, 1138,},
+        },
+        {
+            /* Coeff Band ( 3 ) */
+            {11515, 4079, 465,  73,   5,  14,   2,   0,   0,   0,   0,   0,},
+            {9361, 5834, 650,  96,  24,   8,   4,   0,   0,   0,   0, 22181,},
+            {4343, 3974, 1360, 415, 132,  96,  14,   1,   0,   0,   0, 1267,},
+        },
+        {
+            /* Coeff Band ( 4 ) */
+            {4787, 9297, 823, 168,  44,  12,   4,   0,   0,   0,   0,   0,},
+            {3619, 4472, 719, 198,  60,  31,   3,   0,   0,   0,   0, 8401,},
+            {1157, 1175, 483, 182,  88,  31,   8,   0,   0,   0,   0, 268,},
+        },
+        {
+            /* Coeff Band ( 5 ) */
+            {8299, 1226,  32,   5,   1,   0,   0,   0,   0,   0,   0,   0,},
+            {3502, 1568,  57,   4,   1,   1,   0,   0,   0,   0,   0, 9811,},
+            {1055, 1070, 166,  29,   6,   1,   0,   0,   0,   0,   0, 527,},
+        },
+        {
+            /* Coeff Band ( 6 ) */
+            {27414, 27927, 1989, 347,  69,  26,   0,   0,   0,   0,   0,   0,},
+            {5876, 10074, 1574, 341,  91,  24,   4,   0,   0,   0,   0, 21954,},
+            {1571, 2171, 778, 324, 124,  65,  16,   0,   0,   0,   0, 979,},
+        },
+        {
+            /* Coeff Band ( 7 ) */
+            {   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
+            {   0,  23,   0,   0,   0,   0,   0,   0,   0,   0,   0, 459,},
+            {   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  13,},
+        },
+    },
+};
--- a/vp8/common/defaultcoefcounts.h
+++ b/vp8/common/defaultcoefcounts.h
@@ -8,214 +8,14 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#ifndef __DEFAULTCOEFCOUNTS_H
+#define __DEFAULTCOEFCOUNTS_H
 
-/* Generated file, included by entropy.c */
+#include "entropy.h"
 
-static const unsigned int default_coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] =
-{
+extern const unsigned int vp8_default_coef_counts[BLOCK_TYPES]
+                                                 [COEF_BANDS]
+                                                 [PREV_COEF_CONTEXTS]
+                                                 [MAX_ENTROPY_TOKENS];
 
-    {
-        /* Block Type ( 0 ) */
-        {
-            /* Coeff Band ( 0 ) */
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-        },
-        {
-            /* Coeff Band ( 1 ) */
-            {30190, 26544, 225,  24,   4,   0,   0,   0,   0,   0,   0, 4171593,},
-            {26846, 25157, 1241, 130,  26,   6,   1,   0,   0,   0,   0, 149987,},
-            {10484, 9538, 1006, 160,  36,  18,   0,   0,   0,   0,   0, 15104,},
-        },
-        {
-            /* Coeff Band ( 2 ) */
-            {25842, 40456, 1126,  83,  11,   2,   0,   0,   0,   0,   0,   0,},
-            {9338, 8010, 512,  73,   7,   3,   2,   0,   0,   0,   0, 43294,},
-            {1047, 751, 149,  31,  13,   6,   1,   0,   0,   0,   0, 879,},
-        },
-        {
-            /* Coeff Band ( 3 ) */
-            {26136, 9826, 252,  13,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {8134, 5574, 191,  14,   2,   0,   0,   0,   0,   0,   0, 35302,},
-            { 605, 677, 116,   9,   1,   0,   0,   0,   0,   0,   0, 611,},
-        },
-        {
-            /* Coeff Band ( 4 ) */
-            {10263, 15463, 283,  17,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {2773, 2191, 128,   9,   2,   2,   0,   0,   0,   0,   0, 10073,},
-            { 134, 125,  32,   4,   0,   2,   0,   0,   0,   0,   0,  50,},
-        },
-        {
-            /* Coeff Band ( 5 ) */
-            {10483, 2663,  23,   1,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {2137, 1251,  27,   1,   1,   0,   0,   0,   0,   0,   0, 14362,},
-            { 116, 156,  14,   2,   1,   0,   0,   0,   0,   0,   0, 190,},
-        },
-        {
-            /* Coeff Band ( 6 ) */
-            {40977, 27614, 412,  28,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {6113, 5213, 261,  22,   3,   0,   0,   0,   0,   0,   0, 26164,},
-            { 382, 312,  50,  14,   2,   0,   0,   0,   0,   0,   0, 345,},
-        },
-        {
-            /* Coeff Band ( 7 ) */
-            {   0,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,  13,   0,   0,   0,   0,   0,   0,   0,   0,   0, 319,},
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,},
-        },
-    },
-    {
-        /* Block Type ( 1 ) */
-        {
-            /* Coeff Band ( 0 ) */
-            {3268, 19382, 1043, 250,  93,  82,  49,  26,  17,   8,  25, 82289,},
-            {8758, 32110, 5436, 1832, 827, 668, 420, 153,  24,   0,   3, 52914,},
-            {9337, 23725, 8487, 3954, 2107, 1836, 1069, 399,  59,   0,   0, 18620,},
-        },
-        {
-            /* Coeff Band ( 1 ) */
-            {12419, 8420, 452,  62,   9,   1,   0,   0,   0,   0,   0,   0,},
-            {11715, 8705, 693,  92,  15,   7,   2,   0,   0,   0,   0, 53988,},
-            {7603, 8585, 2306, 778, 270, 145,  39,   5,   0,   0,   0, 9136,},
-        },
-        {
-            /* Coeff Band ( 2 ) */
-            {15938, 14335, 1207, 184,  55,  13,   4,   1,   0,   0,   0,   0,},
-            {7415, 6829, 1138, 244,  71,  26,   7,   0,   0,   0,   0, 9980,},
-            {1580, 1824, 655, 241,  89,  46,  10,   2,   0,   0,   0, 429,},
-        },
-        {
-            /* Coeff Band ( 3 ) */
-            {19453, 5260, 201,  19,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {9173, 3758, 213,  22,   1,   1,   0,   0,   0,   0,   0, 9820,},
-            {1689, 1277, 276,  51,  17,   4,   0,   0,   0,   0,   0, 679,},
-        },
-        {
-            /* Coeff Band ( 4 ) */
-            {12076, 10667, 620,  85,  19,   9,   5,   0,   0,   0,   0,   0,},
-            {4665, 3625, 423,  55,  19,   9,   0,   0,   0,   0,   0, 5127,},
-            { 415, 440, 143,  34,  20,   7,   2,   0,   0,   0,   0, 101,},
-        },
-        {
-            /* Coeff Band ( 5 ) */
-            {12183, 4846, 115,  11,   1,   0,   0,   0,   0,   0,   0,   0,},
-            {4226, 3149, 177,  21,   2,   0,   0,   0,   0,   0,   0, 7157,},
-            { 375, 621, 189,  51,  11,   4,   1,   0,   0,   0,   0, 198,},
-        },
-        {
-            /* Coeff Band ( 6 ) */
-            {61658, 37743, 1203,  94,  10,   3,   0,   0,   0,   0,   0,   0,},
-            {15514, 11563, 903, 111,  14,   5,   0,   0,   0,   0,   0, 25195,},
-            { 929, 1077, 291,  78,  14,   7,   1,   0,   0,   0,   0, 507,},
-        },
-        {
-            /* Coeff Band ( 7 ) */
-            {   0, 990,  15,   3,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0, 412,  13,   0,   0,   0,   0,   0,   0,   0,   0, 1641,},
-            {   0,  18,   7,   1,   0,   0,   0,   0,   0,   0,   0,  30,},
-        },
-    },
-    {
-        /* Block Type ( 2 ) */
-        {
-            /* Coeff Band ( 0 ) */
-            { 953, 24519, 628, 120,  28,  12,   4,   0,   0,   0,   0, 2248798,},
-            {1525, 25654, 2647, 617, 239, 143,  42,   5,   0,   0,   0, 66837,},
-            {1180, 11011, 3001, 1237, 532, 448, 239,  54,   5,   0,   0, 7122,},
-        },
-        {
-            /* Coeff Band ( 1 ) */
-            {1356, 2220,  67,  10,   4,   1,   0,   0,   0,   0,   0,   0,},
-            {1450, 2544, 102,  18,   4,   3,   0,   0,   0,   0,   0, 57063,},
-            {1182, 2110, 470, 130,  41,  21,   0,   0,   0,   0,   0, 6047,},
-        },
-        {
-            /* Coeff Band ( 2 ) */
-            { 370, 3378, 200,  30,   5,   4,   1,   0,   0,   0,   0,   0,},
-            { 293, 1006, 131,  29,  11,   0,   0,   0,   0,   0,   0, 5404,},
-            { 114, 387,  98,  23,   4,   8,   1,   0,   0,   0,   0, 236,},
-        },
-        {
-            /* Coeff Band ( 3 ) */
-            { 579, 194,   4,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            { 395, 213,   5,   1,   0,   0,   0,   0,   0,   0,   0, 4157,},
-            { 119, 122,   4,   0,   0,   0,   0,   0,   0,   0,   0, 300,},
-        },
-        {
-            /* Coeff Band ( 4 ) */
-            {  38, 557,  19,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {  21, 114,  12,   1,   0,   0,   0,   0,   0,   0,   0, 427,},
-            {   0,   5,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,},
-        },
-        {
-            /* Coeff Band ( 5 ) */
-            {  52,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {  18,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0, 652,},
-            {   1,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  30,},
-        },
-        {
-            /* Coeff Band ( 6 ) */
-            { 640, 569,  10,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {  25,  77,   2,   0,   0,   0,   0,   0,   0,   0,   0, 517,},
-            {   4,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   3,},
-        },
-        {
-            /* Coeff Band ( 7 ) */
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-        },
-    },
-    {
-        /* Block Type ( 3 ) */
-        {
-            /* Coeff Band ( 0 ) */
-            {2506, 20161, 2707, 767, 261, 178, 107,  30,  14,   3,   0, 100694,},
-            {8806, 36478, 8817, 3268, 1280, 850, 401, 114,  42,   0,   0, 58572,},
-            {11003, 27214, 11798, 5716, 2482, 2072, 1048, 175,  32,   0,   0, 19284,},
-        },
-        {
-            /* Coeff Band ( 1 ) */
-            {9738, 11313, 959, 205,  70,  18,  11,   1,   0,   0,   0,   0,},
-            {12628, 15085, 1507, 273,  52,  19,   9,   0,   0,   0,   0, 54280,},
-            {10701, 15846, 5561, 1926, 813, 570, 249,  36,   0,   0,   0, 6460,},
-        },
-        {
-            /* Coeff Band ( 2 ) */
-            {6781, 22539, 2784, 634, 182, 123,  20,   4,   0,   0,   0,   0,},
-            {6263, 11544, 2649, 790, 259, 168,  27,   5,   0,   0,   0, 20539,},
-            {3109, 4075, 2031, 896, 457, 386, 158,  29,   0,   0,   0, 1138,},
-        },
-        {
-            /* Coeff Band ( 3 ) */
-            {11515, 4079, 465,  73,   5,  14,   2,   0,   0,   0,   0,   0,},
-            {9361, 5834, 650,  96,  24,   8,   4,   0,   0,   0,   0, 22181,},
-            {4343, 3974, 1360, 415, 132,  96,  14,   1,   0,   0,   0, 1267,},
-        },
-        {
-            /* Coeff Band ( 4 ) */
-            {4787, 9297, 823, 168,  44,  12,   4,   0,   0,   0,   0,   0,},
-            {3619, 4472, 719, 198,  60,  31,   3,   0,   0,   0,   0, 8401,},
-            {1157, 1175, 483, 182,  88,  31,   8,   0,   0,   0,   0, 268,},
-        },
-        {
-            /* Coeff Band ( 5 ) */
-            {8299, 1226,  32,   5,   1,   0,   0,   0,   0,   0,   0,   0,},
-            {3502, 1568,  57,   4,   1,   1,   0,   0,   0,   0,   0, 9811,},
-            {1055, 1070, 166,  29,   6,   1,   0,   0,   0,   0,   0, 527,},
-        },
-        {
-            /* Coeff Band ( 6 ) */
-            {27414, 27927, 1989, 347,  69,  26,   0,   0,   0,   0,   0,   0,},
-            {5876, 10074, 1574, 341,  91,  24,   4,   0,   0,   0,   0, 21954,},
-            {1571, 2171, 778, 324, 124,  65,  16,   0,   0,   0,   0, 979,},
-        },
-        {
-            /* Coeff Band ( 7 ) */
-            {   0,  29,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,},
-            {   0,  23,   0,   0,   0,   0,   0,   0,   0,   0,   0, 459,},
-            {   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,  13,},
-        },
-    },
-};
+#endif //__DEFAULTCOEFCOUNTS_H
--- a/vp8/common/entropy.c
+++ b/vp8/common/entropy.c
@@ -65,7 +65,7 @@
     -DCT_VAL_CATEGORY5, -DCT_VAL_CATEGORY6   /* 10 = CAT_FIVE */
 };
 
-struct vp8_token_struct vp8_coef_encodings[vp8_coef_tokens];
+struct vp8_token_struct vp8_coef_encodings[MAX_ENTROPY_TOKENS];
 
 /* Trees for extra bits.  Probabilities are constant and
    do not depend on previously encoded bits */
@@ -145,10 +145,12 @@
 
             do
             {
-                unsigned int branch_ct [vp8_coef_tokens-1] [2];
+                unsigned int branch_ct [ENTROPY_NODES] [2];
                 vp8_tree_probs_from_distribution(
-                    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
-                    pc->fc.coef_probs [h][i][k], branch_ct, default_coef_counts [h][i][k],
+                    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+                    pc->fc.coef_probs[h][i][k],
+                    branch_ct,
+                    vp8_default_coef_counts[h][i][k],
                     256, 1);
 
             }
--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -30,13 +30,12 @@
 #define DCT_VAL_CATEGORY6       10      /* 67+       Extra Bits 13+1 */
 #define DCT_EOB_TOKEN           11      /* EOB       Extra Bits 0+0 */
 
-#define vp8_coef_tokens 12
-#define MAX_ENTROPY_TOKENS vp8_coef_tokens
+#define MAX_ENTROPY_TOKENS 12
 #define ENTROPY_NODES 11
 
 extern const vp8_tree_index vp8_coef_tree[];
 
-extern struct vp8_token_struct vp8_coef_encodings[vp8_coef_tokens];
+extern struct vp8_token_struct vp8_coef_encodings[MAX_ENTROPY_TOKENS];
 
 typedef struct
 {
@@ -85,9 +84,9 @@
 /*# define DC_TOKEN_CONTEXTS        3*/ /* 00, 0!0, !0!0 */
 #   define PREV_COEF_CONTEXTS       3
 
-extern DECLARE_ALIGNED(16, const unsigned char, vp8_prev_token_class[vp8_coef_tokens]);
+extern DECLARE_ALIGNED(16, const unsigned char, vp8_prev_token_class[MAX_ENTROPY_TOKENS]);
 
-extern const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
+extern const vp8_prob vp8_coef_update_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
 
 
 struct VP8Common;
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -184,8 +184,11 @@
         int token_partitions; // how many token partitions to create for multi core decoding
         int encode_breakout;  // early breakout encode threshold : for video conf recommend 800
 
-        int error_resilient_mode;  // if running over udp networks provides decodable frames after a
-        // dropped packet
+        unsigned int error_resilient_mode; // Bitfield defining the error
+                                   // resiliency features to enable. Can provide
+                                   // decodable frames after losses in previous
+                                   // frames and decodable partitions after
+                                   // losses in the same frame.
 
         int arnr_max_frames;
         int arnr_strength ;
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -35,6 +35,8 @@
 
 #define NUM_YV12_BUFFERS 4
 
+#define MAX_PARTITIONS 9
+
 typedef struct frame_contexts
 {
     vp8_prob bmode_prob [VP8_BINTRAMODES-1];
@@ -41,7 +43,7 @@
     vp8_prob ymode_prob [VP8_YMODES-1];   /* interframe intra mode probs */
     vp8_prob uv_mode_prob [VP8_UV_MODES-1];
     vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1];
-    vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
+    vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
     MV_CONTEXT mvc[2];
     MV_CONTEXT pre_mvc[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
 } FRAME_CONTEXT;
--- a/vp8/common/onyxd.h
+++ b/vp8/common/onyxd.h
@@ -33,6 +33,7 @@
         int     postprocess;
         int     max_threads;
         int     error_concealment;
+        int     input_partition;
     } VP8D_CONFIG;
     typedef enum
     {
--- a/vp8/decoder/arm/neon/dequant_idct_neon.asm
+++ b/vp8/decoder/arm/neon/dequant_idct_neon.asm
@@ -35,7 +35,7 @@
 
     ldr             r1, [sp, #4]            ; stride
 
-    ldr             r12, _CONSTANTS_
+    adr             r12, cospi8sqrt2minus1  ; pointer to the first constant
 
     vmul.i16        q1, q3, q5              ;input for short_idct4x4llm_neon
     vmul.i16        q2, q4, q6
@@ -123,7 +123,6 @@
     ENDP           ; |vp8_dequant_idct_add_neon|
 
 ; Constant Pool
-_CONSTANTS_       DCD cospi8sqrt2minus1
 cospi8sqrt2minus1 DCD 0x4e7b4e7b
 sinpi8sqrt2       DCD 0x8a8c8a8c
 
--- a/vp8/decoder/arm/neon/idct_dequant_dc_full_2x_neon.asm
+++ b/vp8/decoder/arm/neon/idct_dequant_dc_full_2x_neon.asm
@@ -41,7 +41,7 @@
     ldr             r1, [sp, #4]
     vld1.32         {d31[1]}, [r12]
 
-    ldr             r2, _CONSTANTS_
+    adr             r2, cospi8sqrt2minus1   ; pointer to the first constant
 
     ldrh            r12, [r1], #2           ; lo *dc
     ldrh            r1, [r1]                ; hi *dc
@@ -198,7 +198,6 @@
     ENDP           ; |idct_dequant_dc_full_2x_neon|
 
 ; Constant Pool
-_CONSTANTS_       DCD cospi8sqrt2minus1
 cospi8sqrt2minus1 DCD 0x4e7b
 ; because the lowest bit in 0x8a8c is 0, we can pre-shift this
 sinpi8sqrt2       DCD 0x4546
--- a/vp8/decoder/arm/neon/idct_dequant_full_2x_neon.asm
+++ b/vp8/decoder/arm/neon/idct_dequant_full_2x_neon.asm
@@ -40,7 +40,7 @@
     vld1.32         {d31[0]}, [r2]
     vld1.32         {d31[1]}, [r12]
 
-    ldr             r2, _CONSTANTS_
+    adr             r2, cospi8sqrt2minus1   ; pointer to the first constant
 
     ; dequant: q[i] = q[i] * dq[i]
     vmul.i16        q2, q2, q0
@@ -190,7 +190,6 @@
     ENDP           ; |idct_dequant_full_2x_neon|
 
 ; Constant Pool
-_CONSTANTS_       DCD cospi8sqrt2minus1
 cospi8sqrt2minus1 DCD 0x4e7b
 ; because the lowest bit in 0x8a8c is 0, we can pre-shift this
 sinpi8sqrt2       DCD 0x4546
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -183,7 +183,8 @@
                               unsigned int mb_idx)
 {
     int eobtotal = 0;
-    int i, do_clamp = xd->mode_info_context->mbmi.need_to_clamp_mvs;
+    MB_PREDICTION_MODE mode;
+    int i;
 
     if (xd->mode_info_context->mbmi.mb_skip_coeff)
     {
@@ -195,14 +196,14 @@
     }
 
     /* Perform temporary clamping of the MV to be used for prediction */
-    if (do_clamp)
+    if (xd->mode_info_context->mbmi.need_to_clamp_mvs)
     {
         clamp_mvs(xd);
     }
 
-    eobtotal |= (xd->mode_info_context->mbmi.mode == B_PRED ||
-                  xd->mode_info_context->mbmi.mode == SPLITMV);
-    if (!eobtotal)
+    mode = xd->mode_info_context->mbmi.mode;
+
+    if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV)
     {
         /* Special case:  Force the loopfilter to skip when eobtotal and
          * mb_skip_coeff are zero.
@@ -221,15 +222,12 @@
     {
         RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mbuv)(xd);
 
-        if (xd->mode_info_context->mbmi.mode != B_PRED)
+        if (mode != B_PRED)
         {
             RECON_INVOKE(&pbi->common.rtcd.recon,
                          build_intra_predictors_mby)(xd);
         } else {
             vp8_intra_prediction_down_copy(xd);
-
-
-
         }
     }
     else
@@ -252,41 +250,10 @@
 #endif
 
     /* dequantization and idct */
-    if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
+    if (mode == B_PRED)
     {
-        BLOCKD *b = &xd->block[24];
-
-        DEQUANT_INVOKE(&pbi->dequant, block)(b);
-
-        /* do 2nd order transform on the dc block */
-        if (xd->eobs[24] > 1)
-        {
-            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
-            ((int *)b->qcoeff)[0] = 0;
-            ((int *)b->qcoeff)[1] = 0;
-            ((int *)b->qcoeff)[2] = 0;
-            ((int *)b->qcoeff)[3] = 0;
-            ((int *)b->qcoeff)[4] = 0;
-            ((int *)b->qcoeff)[5] = 0;
-            ((int *)b->qcoeff)[6] = 0;
-            ((int *)b->qcoeff)[7] = 0;
-        }
-        else
-        {
-            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
-            ((int *)b->qcoeff)[0] = 0;
-        }
-
-        DEQUANT_INVOKE (&pbi->dequant, dc_idct_add_y_block)
-                        (xd->qcoeff, xd->block[0].dequant,
-                         xd->predictor, xd->dst.y_buffer,
-                         xd->dst.y_stride, xd->eobs, xd->block[24].diff);
-    }
-    else if (xd->mode_info_context->mbmi.mode == B_PRED)
-    {
         for (i = 0; i < 16; i++)
         {
-
             BLOCKD *b = &xd->block[i];
             RECON_INVOKE(RTCD_VTABLE(recon), intra4x4_predict)
                           (b, b->bmi.as_mode, b->predictor);
@@ -307,7 +274,7 @@
         }
 
     }
-    else
+    else if (mode == SPLITMV)
     {
         DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block)
                         (xd->qcoeff, xd->block[0].dequant,
@@ -314,7 +281,37 @@
                          xd->predictor, xd->dst.y_buffer,
                          xd->dst.y_stride, xd->eobs);
     }
+    else
+    {
+        BLOCKD *b = &xd->block[24];
 
+        DEQUANT_INVOKE(&pbi->dequant, block)(b);
+
+        /* do 2nd order transform on the dc block */
+        if (xd->eobs[24] > 1)
+        {
+            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
+            ((int *)b->qcoeff)[0] = 0;
+            ((int *)b->qcoeff)[1] = 0;
+            ((int *)b->qcoeff)[2] = 0;
+            ((int *)b->qcoeff)[3] = 0;
+            ((int *)b->qcoeff)[4] = 0;
+            ((int *)b->qcoeff)[5] = 0;
+            ((int *)b->qcoeff)[6] = 0;
+            ((int *)b->qcoeff)[7] = 0;
+        }
+        else
+        {
+            IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
+            ((int *)b->qcoeff)[0] = 0;
+        }
+
+        DEQUANT_INVOKE (&pbi->dequant, dc_idct_add_y_block)
+                        (xd->qcoeff, xd->block[0].dequant,
+                         xd->predictor, xd->dst.y_buffer,
+                         xd->dst.y_stride, xd->eobs, xd->block[24].diff);
+    }
+
     DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block)
                     (xd->qcoeff+16*16, xd->block[16].dequant,
                      xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
@@ -463,7 +460,41 @@
     return size;
 }
 
+static void setup_token_decoder_partition_input(VP8D_COMP *pbi)
+{
+    vp8_reader *bool_decoder = &pbi->bc2;
+    int part_idx = 1;
 
+    TOKEN_PARTITION multi_token_partition =
+            (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
+    assert(vp8dx_bool_error(&pbi->bc) ||
+           multi_token_partition == pbi->common.multi_token_partition);
+    if (pbi->num_partitions > 2)
+    {
+        CHECK_MEM_ERROR(pbi->mbc, vpx_malloc((pbi->num_partitions - 1) *
+                                             sizeof(vp8_reader)));
+        bool_decoder = pbi->mbc;
+    }
+
+    for (; part_idx < pbi->num_partitions; ++part_idx)
+    {
+        if (vp8dx_start_decode(bool_decoder,
+                               pbi->partitions[part_idx],
+                               pbi->partition_sizes[part_idx]))
+            vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
+                               "Failed to allocate bool decoder %d",
+                               part_idx);
+
+        bool_decoder++;
+    }
+
+#if CONFIG_MULTITHREAD
+    /* Clamp number of decoder threads */
+    if (pbi->decoding_thread_count > pbi->num_partitions - 1)
+        pbi->decoding_thread_count = pbi->num_partitions - 1;
+#endif
+}
+
 static void setup_token_decoder(VP8D_COMP *pbi,
                                 const unsigned char *cx_data)
 {
@@ -619,12 +650,18 @@
     VP8_COMMON *const pc = & pbi->common;
     MACROBLOCKD *const xd  = & pbi->mb;
     const unsigned char *data = (const unsigned char *)pbi->Source;
-    const unsigned char *const data_end = data + pbi->source_sz;
+    const unsigned char *data_end = data + pbi->source_sz;
     ptrdiff_t first_partition_length_in_bytes;
     int mb_row;
     int i, j, k, l;
     const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
 
+    if (pbi->input_partition)
+    {
+        data = pbi->partitions[0];
+        data_end =  data + pbi->partition_sizes[0];
+    }
+
     /* start with no corruption of current frame */
     xd->corrupted = 0;
     pc->yv12_fb[pc->new_fb_idx].corrupted = 0;
@@ -842,7 +879,14 @@
         }
     }
 
-    setup_token_decoder(pbi, data + first_partition_length_in_bytes);
+    if (pbi->input_partition)
+    {
+        setup_token_decoder_partition_input(pbi);
+    }
+    else
+    {
+        setup_token_decoder(pbi, data + first_partition_length_in_bytes);
+    }
     xd->current_bc = &pbi->bc2;
 
     /* Read the default quantizers. */
@@ -933,11 +977,10 @@
 
     {
         /* read coef probability tree */
-
         for (i = 0; i < BLOCK_TYPES; i++)
             for (j = 0; j < COEF_BANDS; j++)
                 for (k = 0; k < PREV_COEF_CONTEXTS; k++)
-                    for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
+                    for (l = 0; l < ENTROPY_NODES; l++)
                     {
 
                         vp8_prob *const p = pc->fc.coef_probs [i][j][k] + l;
@@ -1025,7 +1068,6 @@
             decode_mb_row(pbi, pc, mb_row, xd);
         }
     }
-
 
     stop_token_decoder(pbi);
 
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -108,6 +108,8 @@
     pbi->ec_enabled = 0;
 #endif
 
+    pbi->input_partition = oxcf->input_partition;
+
     return (VP8D_PTR) pbi;
 }
 
@@ -315,69 +317,92 @@
 
     pbi->common.error.error_code = VPX_CODEC_OK;
 
-    if (size == 0)
+    if (pbi->input_partition && !(source == NULL && size == 0))
     {
-       /* This is used to signal that we are missing frames.
-        * We do not know if the missing frame(s) was supposed to update
-        * any of the reference buffers, but we act conservative and
-        * mark only the last buffer as corrupted.
-        */
-        cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
-
-        /* If error concealment is disabled we won't signal missing frames to
-         * the decoder.
+        /* Store a pointer to this partition and return. We haven't
+         * received the complete frame yet, so we will wait with decoding.
          */
-        if (!pbi->ec_enabled)
+        pbi->partitions[pbi->num_partitions] = source;
+        pbi->partition_sizes[pbi->num_partitions] = size;
+        pbi->source_sz += size;
+        pbi->num_partitions++;
+        if (pbi->num_partitions > (1<<pbi->common.multi_token_partition) + 1)
+            pbi->common.multi_token_partition++;
+        if (pbi->common.multi_token_partition > EIGHT_PARTITION)
         {
-            /* Signal that we have no frame to show. */
-            cm->show_frame = 0;
-
-            /* Nothing more to do. */
-            return 0;
+            pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM;
+            pbi->common.error.setjmp = 0;
+            return -1;
         }
+        return 0;
     }
+    else
+    {
+        if (!pbi->input_partition)
+        {
+            pbi->Source = source;
+            pbi->source_sz = size;
+        }
 
+        if (pbi->source_sz == 0)
+        {
+           /* This is used to signal that we are missing frames.
+            * We do not know if the missing frame(s) was supposed to update
+            * any of the reference buffers, but we act conservative and
+            * mark only the last buffer as corrupted.
+            */
+            cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
 
-#if HAVE_ARMV7
-#if CONFIG_RUNTIME_CPU_DETECT
-    if (cm->rtcd.flags & HAS_NEON)
-#endif
-    {
-        vp8_push_neon(dx_store_reg);
-    }
-#endif
+            /* If error concealment is disabled we won't signal missing frames to
+             * the decoder.
+             */
+            if (!pbi->ec_enabled)
+            {
+                /* Signal that we have no frame to show. */
+                cm->show_frame = 0;
 
-    cm->new_fb_idx = get_free_fb (cm);
+                /* Nothing more to do. */
+                return 0;
+            }
+        }
 
-    if (setjmp(pbi->common.error.jmp))
-    {
 #if HAVE_ARMV7
 #if CONFIG_RUNTIME_CPU_DETECT
         if (cm->rtcd.flags & HAS_NEON)
 #endif
         {
-            vp8_pop_neon(dx_store_reg);
+            vp8_push_neon(dx_store_reg);
         }
 #endif
-        pbi->common.error.setjmp = 0;
 
-       /* We do not know if the missing frame(s) was supposed to update
-        * any of the reference buffers, but we act conservative and
-        * mark only the last buffer as corrupted.
-        */
-        cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
+        cm->new_fb_idx = get_free_fb (cm);
 
-        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
-          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
-        return -1;
-    }
+        if (setjmp(pbi->common.error.jmp))
+        {
+#if HAVE_ARMV7
+#if CONFIG_RUNTIME_CPU_DETECT
+            if (cm->rtcd.flags & HAS_NEON)
+#endif
+            {
+                vp8_pop_neon(dx_store_reg);
+            }
+#endif
+            pbi->common.error.setjmp = 0;
 
-    pbi->common.error.setjmp = 1;
+           /* We do not know if the missing frame(s) was supposed to update
+            * any of the reference buffers, but we act conservative and
+            * mark only the last buffer as corrupted.
+            */
+            cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
 
-    /*cm->current_video_frame++;*/
-    pbi->Source = source;
-    pbi->source_sz = size;
+            if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+              cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
+            return -1;
+        }
 
+        pbi->common.error.setjmp = 1;
+    }
+
     retcode = vp8_decode_frame(pbi);
 
     if (retcode < 0)
@@ -478,6 +503,10 @@
 
     pbi->ready_for_new_data = 0;
     pbi->last_time_stamp = time_stamp;
+    pbi->num_partitions = 0;
+    if (pbi->input_partition)
+        pbi->common.multi_token_partition = 0;
+    pbi->source_sz = 0;
 
 #if 0
     {
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -83,6 +83,9 @@
 
     const unsigned char *Source;
     unsigned int   source_sz;
+    const unsigned char *partitions[MAX_PARTITIONS];
+    unsigned int   partition_sizes[MAX_PARTITIONS];
+    unsigned int   num_partitions;
 
     unsigned char *segmentation_map;
 #if CONFIG_MULTITHREAD
@@ -137,6 +140,7 @@
     unsigned int mvs_corrupt_from_mb;
 #endif
     int ec_enabled;
+    int input_partition;
 
 } VP8D_COMP;
 
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -17,9 +17,12 @@
 #include "vp8/common/systemdependent.h"
 #include <assert.h>
 #include <stdio.h>
+#include <limits.h>
 #include "vp8/common/pragmas.h"
+#include "vpx/vpx_encoder.h"
 #include "vpx_mem/vpx_mem.h"
 #include "bitstream.h"
+#include "vp8/common/defaultcoefcounts.h"
 #if CONFIG_SEGMENTATION
 static int segment_cost = 0;
 #endif
@@ -49,7 +52,7 @@
 
 #ifdef ENTROPY_STATS
 int intra_mode_stats[10][10][10];
-static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] [2];
+static unsigned int tree_update_hist [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] [2];
 extern unsigned int active_section;
 #endif
 
@@ -376,6 +379,7 @@
     unsigned int shift;
     vp8_writer *w = &cpi->bc2;
     *size = 3 * (num_part - 1);
+    cpi->partition_sz[0] += *size;
     ptr = cx_data + (*size);
 
     for (i = 0; i < num_part; i++)
@@ -572,6 +576,9 @@
         vp8_stop_encode(w);
         *size +=   w->pos;
 
+        /* The first partition size is set earlier */
+        cpi->partition_sz[i + 1] = w->pos;
+
         if (i < (num_part - 1))
         {
             write_partition_size(cx_data, w->pos);
@@ -1198,11 +1205,203 @@
         m++;    // skip L prediction border
     }
 }
-int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+
+/* This function is used for debugging probability trees. */
+static void print_prob_tree(vp8_prob
+     coef_probs[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES])
 {
+    /* print coef probability tree */
+    int i,j,k,l;
+    FILE* f = fopen("enc_tree_probs.txt", "a");
+    fprintf(f, "{\n");
+    for (i = 0; i < BLOCK_TYPES; i++)
+    {
+        fprintf(f, "  {\n");
+        for (j = 0; j < COEF_BANDS; j++)
+        {
+            fprintf(f, "    {\n");
+            for (k = 0; k < PREV_COEF_CONTEXTS; k++)
+            {
+                fprintf(f, "      {");
+                for (l = 0; l < ENTROPY_NODES; l++)
+                {
+                    fprintf(f, "%3u, ",
+                            (unsigned int)(coef_probs [i][j][k][l]));
+                }
+                fprintf(f, " }\n");
+            }
+            fprintf(f, "    }\n");
+        }
+        fprintf(f, "  }\n");
+    }
+    fprintf(f, "}\n");
+    fclose(f);
+}
+
+static void sum_probs_over_prev_coef_context(
+        const unsigned int probs[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS],
+        unsigned int* out)
+{
+    int i, j;
+    for (i=0; i < MAX_ENTROPY_TOKENS; ++i)
+    {
+        for (j=0; j < PREV_COEF_CONTEXTS; ++j)
+        {
+            const int tmp = out[i];
+            out[i] += probs[j][i];
+            /* check for wrap */
+            if (out[i] < tmp)
+                out[i] = UINT_MAX;
+        }
+    }
+}
+
+static int prob_update_savings(const unsigned int *ct,
+                                   const vp8_prob oldp, const vp8_prob newp,
+                                   const vp8_prob upd)
+{
+    const int old_b = vp8_cost_branch(ct, oldp);
+    const int new_b = vp8_cost_branch(ct, newp);
+    const int update_b = 8 +
+                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+
+    return old_b - new_b - update_b;
+}
+
+static int independent_coef_context_savings(VP8_COMP *cpi)
+{
+    int savings = 0;
     int i = 0;
+    do
+    {
+        int j = 0;
+        do
+        {
+            int k = 0;
+            unsigned int prev_coef_count_sum[MAX_ENTROPY_TOKENS] = {0};
+            int prev_coef_savings[MAX_ENTROPY_TOKENS] = {0};
+            /* Calculate new probabilities given the constraint that
+             * they must be equal over the prev coef contexts
+             */
+            if (cpi->common.frame_type == KEY_FRAME)
+            {
+                /* Reset to default probabilities at key frames */
+                sum_probs_over_prev_coef_context(vp8_default_coef_counts[i][j],
+                                                 prev_coef_count_sum);
+            }
+            else
+            {
+                sum_probs_over_prev_coef_context(cpi->coef_counts[i][j],
+                                                 prev_coef_count_sum);
+            }
+            do
+            {
+                /* at every context */
+
+                /* calc probs and branch cts for this frame only */
+                //vp8_prob new_p           [ENTROPY_NODES];
+                //unsigned int branch_ct   [ENTROPY_NODES] [2];
+
+                int t = 0;      /* token/prob index */
+
+                vp8_tree_probs_from_distribution(
+                    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+                    cpi->frame_coef_probs[i][j][k],
+                    cpi->frame_branch_ct [i][j][k],
+                    prev_coef_count_sum,
+                    256, 1);
+
+                do
+                {
+                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
+                    const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+                    const vp8_prob oldp = cpi->common.fc.coef_probs [i][j][k][t];
+                    const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+                    const int s = prob_update_savings(ct, oldp, newp, upd);
+
+                    if (cpi->common.frame_type != KEY_FRAME ||
+                        (cpi->common.frame_type == KEY_FRAME && newp != oldp))
+                        prev_coef_savings[t] += s;
+                }
+                while (++t < ENTROPY_NODES);
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+            k = 0;
+            do
+            {
+                /* We only update probabilities if we can save bits, except
+                 * for key frames where we have to update all probabilities
+                 * to get the equal probabilities across the prev coef
+                 * contexts.
+                 */
+                if (prev_coef_savings[k] > 0 ||
+                    cpi->common.frame_type == KEY_FRAME)
+                    savings += prev_coef_savings[k];
+            }
+            while (++k < ENTROPY_NODES);
+        }
+        while (++j < COEF_BANDS);
+    }
+    while (++i < BLOCK_TYPES);
+    return savings;
+}
+
+static int default_coef_context_savings(VP8_COMP *cpi)
+{
     int savings = 0;
+    int i = 0;
+    do
+    {
+        int j = 0;
+        do
+        {
+            int k = 0;
+            do
+            {
+                /* at every context */
 
+                /* calc probs and branch cts for this frame only */
+                //vp8_prob new_p           [ENTROPY_NODES];
+                //unsigned int branch_ct   [ENTROPY_NODES] [2];
+
+                int t = 0;      /* token/prob index */
+
+
+                vp8_tree_probs_from_distribution(
+                    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+                    cpi->frame_coef_probs [i][j][k],
+                    cpi->frame_branch_ct [i][j][k],
+                    cpi->coef_counts [i][j][k],
+                    256, 1
+                );
+
+                do
+                {
+                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
+                    const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
+                    const vp8_prob oldp = cpi->common.fc.coef_probs [i][j][k][t];
+                    const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
+                    const int s = prob_update_savings(ct, oldp, newp, upd);
+
+                    if (s > 0)
+                    {
+                        savings += s;
+                    }
+                }
+                while (++t < ENTROPY_NODES);
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++j < COEF_BANDS);
+    }
+    while (++i < BLOCK_TYPES);
+    return savings;
+}
+
+int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+{
+    int savings = 0;
+
     const int *const rfct = cpi->count_mb_ref_frame_usage;
     const int rf_intra = rfct[INTRA_FRAME];
     const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
@@ -1260,61 +1459,12 @@
     }
 
 
-    do
-    {
-        int j = 0;
+    if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
+        savings += independent_coef_context_savings(cpi);
+    else
+        savings += default_coef_context_savings(cpi);
 
-        do
-        {
-            int k = 0;
 
-            do
-            {
-                /* at every context */
-
-                /* calc probs and branch cts for this frame only */
-                //vp8_prob new_p           [vp8_coef_tokens-1];
-                //unsigned int branch_ct   [vp8_coef_tokens-1] [2];
-
-                int t = 0;      /* token/prob index */
-
-                vp8_tree_probs_from_distribution(
-                    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
-                    cpi->frame_coef_probs [i][j][k], cpi->frame_branch_ct [i][j][k], cpi->coef_counts [i][j][k],
-                    256, 1
-                );
-
-                do
-                {
-                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
-                    const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
-
-                    const vp8_prob old = cpi->common.fc.coef_probs [i][j][k][t];
-                    const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
-
-                    const int old_b = vp8_cost_branch(ct, old);
-                    const int new_b = vp8_cost_branch(ct, newp);
-
-                    const int update_b = 8 +
-                                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
-
-                    const int s = old_b - new_b - update_b;
-
-                    if (s > 0)
-                        savings += s;
-
-
-                }
-                while (++t < vp8_coef_tokens - 1);
-
-
-            }
-            while (++k < PREV_COEF_CONTEXTS);
-        }
-        while (++j < COEF_BANDS);
-    }
-    while (++i < BLOCK_TYPES);
-
     return savings;
 }
 
@@ -1326,7 +1476,6 @@
 
     vp8_clear_system_state(); //__asm emms;
 
-
     do
     {
         int j = 0;
@@ -1334,7 +1483,27 @@
         do
         {
             int k = 0;
+            int prev_coef_savings[ENTROPY_NODES] = {0};
+            if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
+            {
+                for (k = 0; k < PREV_COEF_CONTEXTS; ++k)
+                {
+                    int t;      /* token/prob index */
+                    for (t = 0; t < ENTROPY_NODES; ++t)
+                    {
+                        const unsigned int *ct = cpi->frame_branch_ct [i][j]
+                                                                      [k][t];
+                        const vp8_prob newp = cpi->frame_coef_probs[i][j][k][t];
+                        const vp8_prob oldp = cpi->common.fc.coef_probs[i][j]
+                                                                       [k][t];
+                        const vp8_prob upd = vp8_coef_update_probs[i][j][k][t];
 
+                        prev_coef_savings[t] +=
+                                prob_update_savings(ct, oldp, newp, upd);
+                    }
+                }
+                k = 0;
+            }
             do
             {
                 //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
@@ -1341,13 +1510,13 @@
                 /* at every context */
 
                 /* calc probs and branch cts for this frame only */
-                //vp8_prob new_p           [vp8_coef_tokens-1];
-                //unsigned int branch_ct   [vp8_coef_tokens-1] [2];
+                //vp8_prob new_p           [ENTROPY_NODES];
+                //unsigned int branch_ct   [ENTROPY_NODES] [2];
 
                 int t = 0;      /* token/prob index */
 
                 //vp8_tree_probs_from_distribution(
-                //    vp8_coef_tokens, vp8_coef_encodings, vp8_coef_tree,
+                //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
                 //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
                 //    256, 1
                 //    );
@@ -1354,22 +1523,34 @@
 
                 do
                 {
-                    const unsigned int *ct  = cpi->frame_branch_ct [i][j][k][t];
                     const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
 
                     vp8_prob *Pold = cpi->common.fc.coef_probs [i][j][k] + t;
-                    const vp8_prob old = *Pold;
                     const vp8_prob upd = vp8_coef_update_probs [i][j][k][t];
 
-                    const int old_b = vp8_cost_branch(ct, old);
-                    const int new_b = vp8_cost_branch(ct, newp);
+                    int s = prev_coef_savings[t];
+                    int u = 0;
 
-                    const int update_b = 8 +
-                                         ((vp8_cost_one(upd) - vp8_cost_zero(upd)) >> 8);
+                    if (!(cpi->oxcf.error_resilient_mode &
+                            VPX_ERROR_RESILIENT_PARTITIONS))
+                    {
+                        s = prob_update_savings(
+                                cpi->frame_branch_ct [i][j][k][t],
+                                *Pold, newp, upd);
+                    }
 
-                    const int s = old_b - new_b - update_b;
-                    const int u = s > 0 ? 1 : 0;
+                    if (s > 0)
+                        u = 1;
 
+                    /* Force updates on key frames if the new is different,
+                     * so that we can be sure we end up with equal probabilities
+                     * over the prev coef contexts.
+                     */
+                    if ((cpi->oxcf.error_resilient_mode &
+                            VPX_ERROR_RESILIENT_PARTITIONS) &&
+                        cpi->common.frame_type == KEY_FRAME && newp != *Pold)
+                        u = 1;
+
                     vp8_write(w, u, upd);
 
 
@@ -1389,7 +1570,7 @@
                     }
 
                 }
-                while (++t < vp8_coef_tokens - 1);
+                while (++t < ENTROPY_NODES);
 
                 /* Accum token counts for generation of default statistics */
 #ifdef ENTROPY_STATS
@@ -1399,7 +1580,7 @@
                 {
                     context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t];
                 }
-                while (++t < vp8_coef_tokens);
+                while (++t < MAX_ENTROPY_TOKENS);
 
 #endif
 
@@ -1670,6 +1851,14 @@
         vp8_write_bit(bc, pc->ref_frame_sign_bias[ALTREF_FRAME]);
     }
 
+    if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
+    {
+        if (pc->frame_type == KEY_FRAME)
+            pc->refresh_entropy_probs = 1;
+        else
+            pc->refresh_entropy_probs = 0;
+    }
+
     vp8_write_bit(bc, pc->refresh_entropy_probs);
 
     if (pc->frame_type != KEY_FRAME)
@@ -1737,6 +1926,7 @@
     }
 
     *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc.pos;
+    cpi->partition_sz[0] = *size;
 
     if (pc->multi_token_partition != ONE_PARTITION)
     {
@@ -1762,6 +1952,7 @@
         vp8_stop_encode(&cpi->bc2);
 
         *size += cpi->bc2.pos;
+        cpi->partition_sz[1] = cpi->bc2.pos;
     }
 }
 
@@ -1772,7 +1963,7 @@
     FILE *f = fopen("context.c", "a");
     int Sum;
     fprintf(f, "\n/* Update probabilities for token entropy tree. */\n\n");
-    fprintf(f, "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1] = {\n");
+    fprintf(f, "const vp8_prob tree_update_probs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES] = {\n");
 
     for (i = 0; i < BLOCK_TYPES; i++)
     {
@@ -1786,7 +1977,7 @@
             {
                 fprintf(f, "      {");
 
-                for (l = 0; l < MAX_ENTROPY_TOKENS - 1; l++)
+                for (l = 0; l < ENTROPY_NODES; l++)
                 {
                     Sum = tree_update_hist[i][j][k][l][0] + tree_update_hist[i][j][k][l][1];
 
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -115,7 +115,7 @@
     unsigned char *active_ptr;
     MV_CONTEXT *mvc;
 
-    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
     int optimize;
     int q_index;
 
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -16,6 +16,7 @@
 #include "encodeintra.h"
 #include "vp8/common/setupintrarecon.h"
 #include "mcomp.h"
+#include "firstpass.h"
 #include "vpx_scale/vpxscale.h"
 #include "encodemb.h"
 #include "vp8/common/extend.h"
@@ -49,7 +50,7 @@
 
 extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
 
-#define IIFACTOR   1.4
+#define IIFACTOR   1.5
 #define IIKFACTOR1 1.40
 #define IIKFACTOR2 1.5
 #define RMAX       14.0
@@ -63,6 +64,8 @@
 #define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
 #define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0
 
+#define NEW_BOOST 1
+
 static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
 static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};
 
@@ -96,6 +99,146 @@
     return 1;
 }
 
+// Read frame stats at an offset from the current position
+static int read_frame_stats( VP8_COMP *cpi,
+                             FIRSTPASS_STATS *frame_stats,
+                             int offset )
+{
+    FIRSTPASS_STATS * fps_ptr = cpi->twopass.stats_in;
+
+    // Check legality of offset
+    if ( offset >= 0 )
+    {
+        if ( &fps_ptr[offset] >= cpi->twopass.stats_in_end )
+             return EOF;
+    }
+    else if ( offset < 0 )
+    {
+        if ( &fps_ptr[offset] < cpi->twopass.stats_in_start )
+             return EOF;
+    }
+
+    *frame_stats = fps_ptr[offset];
+    return 1;
+}
+
+static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
+{
+    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
+        return EOF;
+
+    *fps = *cpi->twopass.stats_in;
+    cpi->twopass.stats_in =
+         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
+    return 1;
+}
+
+static void output_stats(const VP8_COMP            *cpi,
+                         struct vpx_codec_pkt_list *pktlist,
+                         FIRSTPASS_STATS            *stats)
+{
+    struct vpx_codec_cx_pkt pkt;
+    pkt.kind = VPX_CODEC_STATS_PKT;
+    pkt.data.twopass_stats.buf = stats;
+    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
+    vpx_codec_pkt_list_add(pktlist, &pkt);
+
+// TEMP debug code
+#if OUTPUT_FPF
+
+    {
+        FILE *fpfile;
+        fpfile = fopen("firstpass.stt", "a");
+
+        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
+                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
+                " %12.0f %12.4f\n",
+                stats->frame,
+                stats->intra_error,
+                stats->coded_error,
+                stats->ssim_weighted_pred_err,
+                stats->pcnt_inter,
+                stats->pcnt_motion,
+                stats->pcnt_second_ref,
+                stats->pcnt_neutral,
+                stats->MVr,
+                stats->mvr_abs,
+                stats->MVc,
+                stats->mvc_abs,
+                stats->MVrv,
+                stats->MVcv,
+                stats->mv_in_out_count,
+                stats->count,
+                stats->duration);
+        fclose(fpfile);
+    }
+#endif
+}
+
+static void zero_stats(FIRSTPASS_STATS *section)
+{
+    section->frame      = 0.0;
+    section->intra_error = 0.0;
+    section->coded_error = 0.0;
+    section->ssim_weighted_pred_err = 0.0;
+    section->pcnt_inter  = 0.0;
+    section->pcnt_motion  = 0.0;
+    section->pcnt_second_ref = 0.0;
+    section->pcnt_neutral = 0.0;
+    section->MVr        = 0.0;
+    section->mvr_abs     = 0.0;
+    section->MVc        = 0.0;
+    section->mvc_abs     = 0.0;
+    section->MVrv       = 0.0;
+    section->MVcv       = 0.0;
+    section->mv_in_out_count  = 0.0;
+    section->count      = 0.0;
+    section->duration   = 1.0;
+}
+
+static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
+{
+    section->frame += frame->frame;
+    section->intra_error += frame->intra_error;
+    section->coded_error += frame->coded_error;
+    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
+    section->pcnt_inter  += frame->pcnt_inter;
+    section->pcnt_motion += frame->pcnt_motion;
+    section->pcnt_second_ref += frame->pcnt_second_ref;
+    section->pcnt_neutral += frame->pcnt_neutral;
+    section->MVr        += frame->MVr;
+    section->mvr_abs     += frame->mvr_abs;
+    section->MVc        += frame->MVc;
+    section->mvc_abs     += frame->mvc_abs;
+    section->MVrv       += frame->MVrv;
+    section->MVcv       += frame->MVcv;
+    section->mv_in_out_count  += frame->mv_in_out_count;
+    section->count      += frame->count;
+    section->duration   += frame->duration;
+}
+
+static void avg_stats(FIRSTPASS_STATS *section)
+{
+    if (section->count < 1.0)
+        return;
+
+    section->intra_error /= section->count;
+    section->coded_error /= section->count;
+    section->ssim_weighted_pred_err /= section->count;
+    section->pcnt_inter  /= section->count;
+    section->pcnt_second_ref /= section->count;
+    section->pcnt_neutral /= section->count;
+    section->pcnt_motion /= section->count;
+    section->MVr        /= section->count;
+    section->mvr_abs     /= section->count;
+    section->MVc        /= section->count;
+    section->mvc_abs     /= section->count;
+    section->MVrv       /= section->count;
+    section->MVcv       /= section->count;
+    section->mv_in_out_count   /= section->count;
+    section->duration   /= section->count;
+}
+
 // Calculate a modified Error used in distributing bits between easier and harder frames
 static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 {
@@ -248,122 +391,6 @@
     return max_bits;
 }
 
-
-static void output_stats(const VP8_COMP            *cpi,
-                         struct vpx_codec_pkt_list *pktlist,
-                         FIRSTPASS_STATS            *stats)
-{
-    struct vpx_codec_cx_pkt pkt;
-    pkt.kind = VPX_CODEC_STATS_PKT;
-    pkt.data.twopass_stats.buf = stats;
-    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
-    vpx_codec_pkt_list_add(pktlist, &pkt);
-
-// TEMP debug code
-#if OUTPUT_FPF
-
-    {
-        FILE *fpfile;
-        fpfile = fopen("firstpass.stt", "a");
-
-        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
-                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
-                " %12.0f %12.4f\n",
-                stats->frame,
-                stats->intra_error,
-                stats->coded_error,
-                stats->ssim_weighted_pred_err,
-                stats->pcnt_inter,
-                stats->pcnt_motion,
-                stats->pcnt_second_ref,
-                stats->pcnt_neutral,
-                stats->MVr,
-                stats->mvr_abs,
-                stats->MVc,
-                stats->mvc_abs,
-                stats->MVrv,
-                stats->MVcv,
-                stats->mv_in_out_count,
-                stats->count,
-                stats->duration);
-        fclose(fpfile);
-    }
-#endif
-}
-
-static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
-{
-    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
-        return EOF;
-
-    *fps = *cpi->twopass.stats_in;
-    cpi->twopass.stats_in =
-         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
-    return 1;
-}
-
-static void zero_stats(FIRSTPASS_STATS *section)
-{
-    section->frame      = 0.0;
-    section->intra_error = 0.0;
-    section->coded_error = 0.0;
-    section->ssim_weighted_pred_err = 0.0;
-    section->pcnt_inter  = 0.0;
-    section->pcnt_motion  = 0.0;
-    section->pcnt_second_ref = 0.0;
-    section->pcnt_neutral = 0.0;
-    section->MVr        = 0.0;
-    section->mvr_abs     = 0.0;
-    section->MVc        = 0.0;
-    section->mvc_abs     = 0.0;
-    section->MVrv       = 0.0;
-    section->MVcv       = 0.0;
-    section->mv_in_out_count  = 0.0;
-    section->count      = 0.0;
-    section->duration   = 1.0;
-}
-static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
-{
-    section->frame += frame->frame;
-    section->intra_error += frame->intra_error;
-    section->coded_error += frame->coded_error;
-    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
-    section->pcnt_inter  += frame->pcnt_inter;
-    section->pcnt_motion += frame->pcnt_motion;
-    section->pcnt_second_ref += frame->pcnt_second_ref;
-    section->pcnt_neutral += frame->pcnt_neutral;
-    section->MVr        += frame->MVr;
-    section->mvr_abs     += frame->mvr_abs;
-    section->MVc        += frame->MVc;
-    section->mvc_abs     += frame->mvc_abs;
-    section->MVrv       += frame->MVrv;
-    section->MVcv       += frame->MVcv;
-    section->mv_in_out_count  += frame->mv_in_out_count;
-    section->count      += frame->count;
-    section->duration   += frame->duration;
-}
-static void avg_stats(FIRSTPASS_STATS *section)
-{
-    if (section->count < 1.0)
-        return;
-
-    section->intra_error /= section->count;
-    section->coded_error /= section->count;
-    section->ssim_weighted_pred_err /= section->count;
-    section->pcnt_inter  /= section->count;
-    section->pcnt_second_ref /= section->count;
-    section->pcnt_neutral /= section->count;
-    section->pcnt_motion /= section->count;
-    section->MVr        /= section->count;
-    section->mvr_abs     /= section->count;
-    section->MVc        /= section->count;
-    section->mvc_abs     /= section->count;
-    section->MVrv       /= section->count;
-    section->MVcv       /= section->count;
-    section->mv_in_out_count   /= section->count;
-    section->duration   /= section->count;
-}
-
 void vp8_init_first_pass(VP8_COMP *cpi)
 {
     zero_stats(cpi->twopass.total_stats);
@@ -854,7 +881,11 @@
 
         //cpi->twopass.est_max_qcorrection_factor /= adjustment_rate;
 
-        cpi->twopass.est_max_qcorrection_factor = (cpi->twopass.est_max_qcorrection_factor < 0.1) ? 0.1 : (cpi->twopass.est_max_qcorrection_factor > 10.0) ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
+        cpi->twopass.est_max_qcorrection_factor =
+            (cpi->twopass.est_max_qcorrection_factor < 0.1)
+                ? 0.1
+                : (cpi->twopass.est_max_qcorrection_factor > 10.0)
+                    ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
     }
 
     // Corrections for higher compression speed settings (reduced compression expected)
@@ -889,7 +920,6 @@
             * speed_correction * cpi->twopass.est_max_qcorrection_factor
             * cpi->twopass.section_max_qfactor
             * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
-        //bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->twopass.est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
 
         if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
             break;
@@ -1233,7 +1263,6 @@
     double motion_decay;
     double motion_pct = next_frame->pcnt_motion;
 
-
     // Initial basis is the % mbs inter coded
     prediction_decay_rate = next_frame->pcnt_inter;
 
@@ -1308,6 +1337,241 @@
     return trans_to_still;
 }
 
+// This function detects a flash through the high relative pcnt_second_ref
+// score in the frame following a flash frame. The offset passed in should
+// reflect this
+static BOOL detect_flash( VP8_COMP *cpi, int offset )
+{
+    FIRSTPASS_STATS next_frame;
+
+    BOOL flash_detected = FALSE;
+
+    // Read the frame data.
+    // The return is FALSE (no flash detected) if not a valid frame
+    if ( read_frame_stats(cpi, &next_frame, offset) != EOF )
+    {
+        // What we are looking for here is a situation where there is a
+        // brief break in prediction (such as a flash) but subsequent frames
+        // are reasonably well predicted by an earlier (pre flash) frame.
+        // The recovery after a flash is indicated by a high pcnt_second_ref
+        // comapred to pcnt_inter.
+        if ( (next_frame.pcnt_second_ref > next_frame.pcnt_inter) &&
+             (next_frame.pcnt_second_ref >= 0.5 ) )
+        {
+            flash_detected = TRUE;
+
+            /*if (1)
+            {
+                FILE *f = fopen("flash.stt", "a");
+                fprintf(f, "%8.0f %6.2f %6.2f\n",
+                    next_frame.frame,
+                    next_frame.pcnt_inter,
+                    next_frame.pcnt_second_ref);
+                fclose(f);
+            }*/
+        }
+    }
+
+    return flash_detected;
+}
+
+// Update the motion related elements to the GF arf boost calculation
+static void accumulate_frame_motion_stats(
+    VP8_COMP *cpi,
+    FIRSTPASS_STATS * this_frame,
+    double * this_frame_mv_in_out,
+    double * mv_in_out_accumulator,
+    double * abs_mv_in_out_accumulator,
+    double * mv_ratio_accumulator )
+{
+    //double this_frame_mv_in_out;
+    double this_frame_mvr_ratio;
+    double this_frame_mvc_ratio;
+    double motion_pct;
+
+    // Accumulate motion stats.
+    motion_pct = this_frame->pcnt_motion;
+
+    // Accumulate Motion In/Out of frame stats
+    *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct;
+    *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct;
+    *abs_mv_in_out_accumulator +=
+        fabs(this_frame->mv_in_out_count * motion_pct);
+
+    // Accumulate a measure of how uniform (or conversely how random)
+    // the motion field is. (A ratio of absmv / mv)
+    if (motion_pct > 0.05)
+    {
+        this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
+                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));
+
+        this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
+                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));
+
+         *mv_ratio_accumulator +=
+            (this_frame_mvr_ratio < this_frame->mvr_abs)
+                ? (this_frame_mvr_ratio * motion_pct)
+                : this_frame->mvr_abs * motion_pct;
+
+        *mv_ratio_accumulator +=
+            (this_frame_mvc_ratio < this_frame->mvc_abs)
+                ? (this_frame_mvc_ratio * motion_pct)
+                : this_frame->mvc_abs * motion_pct;
+
+    }
+}
+
+// Calculate a baseline boost number for the current frame.
+static double calc_frame_boost(
+    VP8_COMP *cpi,
+    FIRSTPASS_STATS * this_frame,
+    double this_frame_mv_in_out )
+{
+    double frame_boost;
+
+    // Underlying boost factor is based on inter intra error ratio
+    if (this_frame->intra_error > cpi->twopass.gf_intra_err_min)
+        frame_boost = (IIFACTOR * this_frame->intra_error /
+                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
+    else
+        frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min /
+                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
+
+    // Increase boost for frames where new data coming into frame
+    // (eg zoom out). Slightly reduce boost if there is a net balance
+    // of motion out of the frame (zoom in).
+    // The range for this_frame_mv_in_out is -1.0 to +1.0
+    if (this_frame_mv_in_out > 0.0)
+        frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
+    // In extreme case boost is halved
+    else
+        frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
+
+    // Clip to maximum
+    if (frame_boost > GF_RMAX)
+        frame_boost = GF_RMAX;
+
+    return frame_boost;
+}
+
+#if NEW_BOOST
+static int calc_arf_boost(
+    VP8_COMP *cpi,
+    int offset,
+    int f_frames,
+    int b_frames,
+    int *f_boost,
+    int *b_boost )
+{
+    FIRSTPASS_STATS this_frame;
+
+    int i;
+    double boost_score = 0.0;
+    double fwd_boost_score = 0.0;
+    double mv_ratio_accumulator = 0.0;
+    double decay_accumulator = 1.0;
+    double this_frame_mv_in_out = 0.0;
+    double mv_in_out_accumulator = 0.0;
+    double abs_mv_in_out_accumulator = 0.0;
+    double r;
+    BOOL flash_detected = FALSE;
+
+    // Search forward from the proposed arf/next gf position
+    for ( i = 0; i < f_frames; i++ )
+    {
+        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
+            break;
+
+        // Update the motion related elements to the boost calculation
+        accumulate_frame_motion_stats( cpi, &this_frame,
+            &this_frame_mv_in_out, &mv_in_out_accumulator,
+            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
+
+        // Calculate the baseline boost number for this frame
+        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
+
+        // We want to discount the the flash frame itself and the recovery
+        // frame that follows as both will have poor scores.
+        flash_detected = detect_flash(cpi, (i+offset)) ||
+                         detect_flash(cpi, (i+offset+1));
+
+        // Cumulative effect of prediction quality decay
+        if ( !flash_detected )
+        {
+            decay_accumulator =
+                decay_accumulator *
+                get_prediction_decay_rate(cpi, &this_frame);
+            decay_accumulator =
+                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
+        }
+        boost_score += (decay_accumulator * r);
+
+        // Break out conditions.
+        if  ( (!flash_detected) &&
+              ((mv_ratio_accumulator > 100.0) ||
+               (abs_mv_in_out_accumulator > 3.0) ||
+               (mv_in_out_accumulator < -2.0) ) )
+        {
+            break;
+        }
+    }
+
+    *f_boost = (int)(boost_score * 100.0) >> 4;
+
+    // Reset for backward looking loop
+    boost_score = 0.0;
+    mv_ratio_accumulator = 0.0;
+    decay_accumulator = 1.0;
+    this_frame_mv_in_out = 0.0;
+    mv_in_out_accumulator = 0.0;
+    abs_mv_in_out_accumulator = 0.0;
+
+    // Search forward from the proposed arf/next gf position
+    for ( i = -1; i >= -b_frames; i-- )
+    {
+        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
+            break;
+
+        // Update the motion related elements to the boost calculation
+        accumulate_frame_motion_stats( cpi, &this_frame,
+            &this_frame_mv_in_out, &mv_in_out_accumulator,
+            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
+
+        // Calculate the baseline boost number for this frame
+        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
+
+        // We want to discount the the flash frame itself and the recovery
+        // frame that follows as both will have poor scores.
+        flash_detected = detect_flash(cpi, (i+offset)) ||
+                         detect_flash(cpi, (i+offset+1));
+
+        // Cumulative effect of prediction quality decay
+        if ( !flash_detected )
+        {
+            decay_accumulator =
+                decay_accumulator *
+                get_prediction_decay_rate(cpi, &this_frame);
+            decay_accumulator =
+                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
+        }
+
+        boost_score += (decay_accumulator * r);
+
+        // Break out conditions.
+        if  ( (!flash_detected) &&
+              ((mv_ratio_accumulator > 100.0) ||
+               (abs_mv_in_out_accumulator > 3.0) ||
+               (mv_in_out_accumulator < -2.0) ) )
+        {
+            break;
+        }
+    }
+    *b_boost = (int)(boost_score * 100.0) >> 4;
+
+    return (*f_boost + *b_boost);
+}
+#endif
+
 // Analyse and define a gf/arf group .
 static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 {
@@ -1314,6 +1578,7 @@
     FIRSTPASS_STATS next_frame;
     FIRSTPASS_STATS *start_pos;
     int i;
+    double r;
     double boost_score = 0.0;
     double old_boost_score = 0.0;
     double gf_group_err = 0.0;
@@ -1320,12 +1585,9 @@
     double gf_first_frame_err = 0.0;
     double mod_frame_err = 0.0;
 
-    double mv_accumulator_rabs  = 0.0;
-    double mv_accumulator_cabs  = 0.0;
     double mv_ratio_accumulator = 0.0;
     double decay_accumulator = 1.0;
 
-    double boost_factor = IIFACTOR;
     double loop_decay_rate = 1.00;          // Starting decay rate
 
     double this_frame_mv_in_out = 0.0;
@@ -1338,6 +1600,11 @@
     unsigned int allow_alt_ref =
                     cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
 
+    int alt_boost = 0;
+    int f_boost = 0;
+    int b_boost = 0;
+    BOOL flash_detected;
+
     cpi->twopass.gf_group_bits = 0;
     cpi->twopass.gf_decay_rate = 0;
 
@@ -1347,7 +1614,7 @@
 
     vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean
 
-    // Preload the stats for the next frame.
+    // Load stats for the current frame.
     mod_frame_err = calculate_modified_err(cpi, this_frame);
 
     // Note the error of the frame at the start of the group (this will be
@@ -1369,12 +1636,6 @@
             ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) &&
            (i < cpi->twopass.frames_to_key))
     {
-        double r;
-        double this_frame_mvr_ratio;
-        double this_frame_mvc_ratio;
-        //double motion_pct = next_frame.pcnt_motion;
-        double motion_pct;
-
         i++;    // Increment the loop counter
 
         // Accumulate error score of frames in this gf group
@@ -1388,82 +1649,33 @@
         if (EOF == input_stats(cpi, &next_frame))
             break;
 
-        // Accumulate motion stats.
-        motion_pct = next_frame.pcnt_motion;
-        mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_pct);
-        mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_pct);
+        // Test for the case where there is a brief flash but the prediction
+        // quality back to an earlier frame is then restored.
+        flash_detected = detect_flash(cpi, 0);
 
-        //Accumulate Motion In/Out of frame stats
-        this_frame_mv_in_out =
-            next_frame.mv_in_out_count * motion_pct;
-        mv_in_out_accumulator +=
-            next_frame.mv_in_out_count * motion_pct;
-        abs_mv_in_out_accumulator +=
-            fabs(next_frame.mv_in_out_count * motion_pct);
+        // Update the motion related elements to the boost calculation
+        accumulate_frame_motion_stats( cpi, &next_frame,
+            &this_frame_mv_in_out, &mv_in_out_accumulator,
+            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
 
-        // If there is a significant amount of motion
-        if (motion_pct > 0.05)
-        {
-            this_frame_mvr_ratio = fabs(next_frame.mvr_abs) /
-                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));
+        // Calculate a baseline boost number for this frame
+        r = calc_frame_boost( cpi, &next_frame, this_frame_mv_in_out );
 
-            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) /
-                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
-
-            mv_ratio_accumulator +=
-                (this_frame_mvr_ratio < next_frame.mvr_abs)
-                    ? (this_frame_mvr_ratio * motion_pct)
-                    : next_frame.mvr_abs * motion_pct;
-
-            mv_ratio_accumulator +=
-                (this_frame_mvc_ratio < next_frame.mvc_abs)
-                    ? (this_frame_mvc_ratio * motion_pct)
-                    : next_frame.mvc_abs * motion_pct;
-        }
-        else
+        // Cumulative effect of prediction quality decay
+        if ( !flash_detected )
         {
-            mv_ratio_accumulator += 0.0;
-            this_frame_mvr_ratio = 1.0;
-            this_frame_mvc_ratio = 1.0;
+            loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
+            decay_accumulator = decay_accumulator * loop_decay_rate;
+            decay_accumulator =
+                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
         }
-
-        // Underlying boost factor is based on inter intra error ratio
-        r = ( boost_factor *
-              ( next_frame.intra_error /
-                DOUBLE_DIVIDE_CHECK(next_frame.coded_error)));
-
-        if (next_frame.intra_error > cpi->twopass.gf_intra_err_min)
-            r = (IIKFACTOR2 * next_frame.intra_error /
-                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
-        else
-            r = (IIKFACTOR2 * cpi->twopass.gf_intra_err_min /
-                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
-
-        // Increase boost for frames where new data coming into frame
-        // (eg zoom out). Slightly reduce boost if there is a net balance
-        // of motion out of the frame (zoom in).
-        // The range for this_frame_mv_in_out is -1.0 to +1.0
-        if (this_frame_mv_in_out > 0.0)
-            r += r * (this_frame_mv_in_out * 2.0);
-        // In extreme case boost is halved
-        else
-            r += r * (this_frame_mv_in_out / 2.0);
-
-        if (r > GF_RMAX)
-            r = GF_RMAX;
-
-        loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
-
-        // Cumulative effect of decay
-        decay_accumulator = decay_accumulator * loop_decay_rate;
-        decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
-
         boost_score += (decay_accumulator * r);
 
         // Break clause to detect very still sections after motion
         // For example a staic image after a fade or other transition.
         if ( detect_transition_to_still( cpi, i, 5,
-                                         loop_decay_rate, decay_accumulator ) )
+                                         loop_decay_rate,
+                                         decay_accumulator ) )
         {
             allow_alt_ref = FALSE;
             boost_score = old_boost_score;
@@ -1471,7 +1683,7 @@
         }
 
         // Break out conditions.
-        if  (   /* i>4 || */
+        if  (
             // Break at cpi->max_gf_interval unless almost totally static
             (i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) ||
             (
@@ -1480,6 +1692,7 @@
                 // Dont break out very close to a key frame
                 ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) &&
                 ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
+                (!flash_detected) &&
                 ((mv_ratio_accumulator > 100.0) ||
                  (abs_mv_in_out_accumulator > 3.0) ||
                  (mv_in_out_accumulator < -2.0) ||
@@ -1527,8 +1740,6 @@
             boost_score = max_boost;
     }
 
-    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
-
     // Dont allow conventional gf too near the next kf
     if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)
     {
@@ -1547,39 +1758,70 @@
         }
     }
 
+    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
+
+#if NEW_BOOST
+    // Alterrnative boost calculation for alt ref
+    alt_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost );
+#endif
+
     // Should we use the alternate refernce frame
     if (allow_alt_ref &&
         (i >= MIN_GF_INTERVAL) &&
         // dont use ARF very near next kf
         (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
-        (((next_frame.pcnt_inter > 0.75) &&
-          ((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) &&
-          //(cpi->gfu_boost>150) &&
-          (cpi->gfu_boost > 100) &&
-          //(cpi->gfu_boost>AF_THRESH2) &&
-          //((cpi->gfu_boost/i)>AF_THRESH) &&
-          //(decay_accumulator > 0.5) &&
-          (cpi->twopass.gf_decay_rate <= (ARF_DECAY_THRESH + (cpi->gfu_boost / 200)))
-         )
-        )
-       )
+#if NEW_BOOST
+        ((next_frame.pcnt_inter > 0.75) ||
+         (next_frame.pcnt_second_ref > 0.5)) &&
+        ((mv_in_out_accumulator / (double)i > -0.2) ||
+         (mv_in_out_accumulator > -2.0)) &&
+        (b_boost > 100) &&
+        (f_boost > 100) )
+#else
+        (next_frame.pcnt_inter > 0.75) &&
+        ((mv_in_out_accumulator / (double)i > -0.2) ||
+         (mv_in_out_accumulator > -2.0)) &&
+        (cpi->gfu_boost > 100) &&
+        (cpi->twopass.gf_decay_rate <=
+            (ARF_DECAY_THRESH + (cpi->gfu_boost / 200))) )
+#endif
     {
         int Boost;
         int allocation_chunks;
-        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
+        int Q = (cpi->oxcf.fixed_q < 0)
+                ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
         int tmp_q;
         int arf_frame_bits = 0;
         int group_bits;
 
+#if NEW_BOOST
+        cpi->gfu_boost = alt_boost;
+#endif
+
         // Estimate the bits to be allocated to the group as a whole
-        if ((cpi->twopass.kf_group_bits > 0) && (cpi->twopass.kf_group_error_left > 0))
-            group_bits = (int)((double)cpi->twopass.kf_group_bits * (gf_group_err / (double)cpi->twopass.kf_group_error_left));
+        if ((cpi->twopass.kf_group_bits > 0) &&
+            (cpi->twopass.kf_group_error_left > 0))
+        {
+            group_bits = (int)((double)cpi->twopass.kf_group_bits *
+                (gf_group_err / (double)cpi->twopass.kf_group_error_left));
+        }
         else
             group_bits = 0;
 
         // Boost for arf frame
+#if NEW_BOOST
+        Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
+#else
         Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
+#endif
         Boost += (i * 50);
+
+        // Set max and minimum boost and hence minimum allocation
+        if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
+            Boost = ((cpi->baseline_gf_interval + 1) * 200);
+        else if (Boost < 125)
+            Boost = 125;
+
         allocation_chunks = (i * 100) + Boost;
 
         // Normalize Altboost and allocations chunck down to prevent overflow
@@ -1589,13 +1831,17 @@
             allocation_chunks /= 2;
         }
 
-        // Calculate the number of bits to be spent on the arf based on the boost number
-        arf_frame_bits = (int)((double)Boost * (group_bits / (double)allocation_chunks));
+        // Calculate the number of bits to be spent on the arf based on the
+        // boost number
+        arf_frame_bits = (int)((double)Boost * (group_bits /
+                               (double)allocation_chunks));
 
-        // Estimate if there are enough bits available to make worthwhile use of an arf.
+        // Estimate if there are enough bits available to make worthwhile use
+        // of an arf.
         tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits);
 
-        // Only use an arf if it is likely we will be able to code it at a lower Q than the surrounding frames.
+        // Only use an arf if it is likely we will be able to code
+        // it at a lower Q than the surrounding frames.
         if (tmp_q < cpi->worst_quality)
         {
             int half_gf_int;
@@ -1605,13 +1851,22 @@
 
             cpi->source_alt_ref_pending = TRUE;
 
-            // For alt ref frames the error score for the end frame of the group (the alt ref frame) should not contribute to the group total and hence
-            // the number of bit allocated to the group. Rather it forms part of the next group (it is the GF at the start of the next group)
-            gf_group_err -= mod_frame_err;
+            // For alt ref frames the error score for the end frame of the
+            // group (the alt ref frame) should not contribute to the group
+            // total and hence the number of bit allocated to the group.
+            // Rather it forms part of the next group (it is the GF at the
+            // start of the next group)
+            // gf_group_err -= mod_frame_err;
 
-            // Set the interval till the next gf or arf. For ARFs this is the number of frames to be coded before the future frame that is coded as an ARF.
+            // For alt ref frames alt ref frame is technically part of the
+            // GF frame for the next group but we always base the error
+            // calculation and bit allocation on the current group of frames.
+
+            // Set the interval till the next gf or arf.
+            // For ARFs this is the number of frames to be coded before the
+            // future frame that is coded as an ARF.
             // The future frame itself is part of the next group
-            cpi->baseline_gf_interval = i - 1;
+            cpi->baseline_gf_interval = i;
 
             // Define the arnr filter width for this group of frames:
             // We only filter frames that lie within a distance of half
@@ -1620,7 +1875,8 @@
             // Note: this_frame->frame has been updated in the loop
             // so it now points at the ARF frame.
             half_gf_int = cpi->baseline_gf_interval >> 1;
-            frames_after_arf = cpi->twopass.total_stats->count - this_frame->frame - 1;
+            frames_after_arf = cpi->twopass.total_stats->count -
+                               this_frame->frame - 1;
 
             switch (cpi->oxcf.arnr_type)
             {
@@ -1669,23 +1925,38 @@
         cpi->baseline_gf_interval = i;
     }
 
-    // Now decide how many bits should be allocated to the GF group as  a proportion of those remaining in the kf group.
-    // The final key frame group in the clip is treated as a special case where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
-    // This is also important for short clips where there may only be one key frame.
-    if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats->count - cpi->common.current_video_frame))
+    // Now decide how many bits should be allocated to the GF group as  a
+    // proportion of those remaining in the kf group.
+    // The final key frame group in the clip is treated as a special case
+    // where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
+    // This is also important for short clips where there may only be one
+    // key frame.
+    if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats->count -
+                                            cpi->common.current_video_frame))
     {
-        cpi->twopass.kf_group_bits = (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
+        cpi->twopass.kf_group_bits =
+            (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
     }
 
     // Calculate the bits to be allocated to the group as a whole
-    if ((cpi->twopass.kf_group_bits > 0) && (cpi->twopass.kf_group_error_left > 0))
-        cpi->twopass.gf_group_bits = (int)((double)cpi->twopass.kf_group_bits * (gf_group_err / (double)cpi->twopass.kf_group_error_left));
+    if ((cpi->twopass.kf_group_bits > 0) &&
+        (cpi->twopass.kf_group_error_left > 0))
+    {
+        cpi->twopass.gf_group_bits =
+            (int)((double)cpi->twopass.kf_group_bits *
+                  (gf_group_err / (double)cpi->twopass.kf_group_error_left));
+    }
     else
         cpi->twopass.gf_group_bits = 0;
 
-    cpi->twopass.gf_group_bits = (cpi->twopass.gf_group_bits < 0) ? 0 : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
+    cpi->twopass.gf_group_bits =
+        (cpi->twopass.gf_group_bits < 0)
+            ? 0
+            : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits)
+                ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
 
-    // Clip cpi->twopass.gf_group_bits based on user supplied data rate variability limit (cpi->oxcf.two_pass_vbrmax_section)
+    // Clip cpi->twopass.gf_group_bits based on user supplied data rate
+    // variability limit (cpi->oxcf.two_pass_vbrmax_section)
     if (cpi->twopass.gf_group_bits > max_bits * cpi->baseline_gf_interval)
         cpi->twopass.gf_group_bits = max_bits * cpi->baseline_gf_interval;
 
@@ -1698,7 +1969,6 @@
     // Assign  bits to the arf or gf.
     for (i = 0; i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); i++) {
         int Boost;
-        int frames_in_section;
         int allocation_chunks;
         int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
         int gf_bits;
@@ -1706,8 +1976,11 @@
         // For ARF frames
         if (cpi->source_alt_ref_pending && i == 0)
         {
+#if NEW_BOOST
+            Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
+#else
             Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
-            //Boost += (cpi->baseline_gf_interval * 25);
+#endif
             Boost += (cpi->baseline_gf_interval * 50);
 
             // Set max and minimum boost and hence minimum allocation
@@ -1716,8 +1989,8 @@
             else if (Boost < 125)
                 Boost = 125;
 
-            frames_in_section = cpi->baseline_gf_interval + 1;
-            allocation_chunks = (frames_in_section * 100) + Boost;
+            allocation_chunks =
+                ((cpi->baseline_gf_interval + 1) * 100) + Boost;
         }
         // Else for standard golden frames
         else
@@ -1731,8 +2004,8 @@
             else if (Boost < 125)
                 Boost = 125;
 
-            frames_in_section = cpi->baseline_gf_interval;
-            allocation_chunks = (frames_in_section * 100) + (Boost - 100);
+            allocation_chunks =
+                (cpi->baseline_gf_interval * 100) + (Boost - 100);
         }
 
         // Normalize Altboost and allocations chunck down to prevent overflow
@@ -1742,8 +2015,11 @@
             allocation_chunks /= 2;
         }
 
-        // Calculate the number of bits to be spent on the gf or arf based on the boost number
-        gf_bits = (int)((double)Boost * (cpi->twopass.gf_group_bits / (double)allocation_chunks));
+        // Calculate the number of bits to be spent on the gf or arf based on
+        // the boost number
+        gf_bits = (int)((double)Boost *
+                        (cpi->twopass.gf_group_bits /
+                         (double)allocation_chunks));
 
         // If the frame that is to be boosted is simpler than the average for
         // the gf/arf group then use an alternative calculation
@@ -1825,17 +2101,26 @@
         if (cpi->twopass.gf_group_bits < 0)
             cpi->twopass.gf_group_bits = 0;
 
-        // Set aside some bits for a mid gf sequence boost
-        if ((cpi->gfu_boost > 150) && (cpi->baseline_gf_interval > 5))
         {
-            int pct_extra = (cpi->gfu_boost - 100) / 50;
-            pct_extra = (pct_extra > 10) ? 10 : pct_extra;
+#if NEW_BOOST
+            int boost = (cpi->source_alt_ref_pending)
+                        ? b_boost : cpi->gfu_boost;
+#else
+            int boost = cpi->gfu_boost;
+#endif
+            // Set aside some bits for a mid gf sequence boost
+            if ((boost > 150) && (cpi->baseline_gf_interval > 5))
+            {
+                int pct_extra = (boost - 100) / 50;
+                pct_extra = (pct_extra > 10) ? 10 : pct_extra;
 
-            cpi->twopass.mid_gf_extra_bits = (cpi->twopass.gf_group_bits * pct_extra) / 100;
-            cpi->twopass.gf_group_bits -= cpi->twopass.mid_gf_extra_bits;
+                cpi->twopass.mid_gf_extra_bits =
+                    (cpi->twopass.gf_group_bits * pct_extra) / 100;
+                cpi->twopass.gf_group_bits -= cpi->twopass.mid_gf_extra_bits;
+            }
+            else
+                cpi->twopass.mid_gf_extra_bits = 0;
         }
-        else
-            cpi->twopass.mid_gf_extra_bits = 0;
     }
 
     // Adjustment to estimate_max_q based on a measure of complexity of the section
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2077,7 +2077,8 @@
         size_t packet_sz = sizeof(FIRSTPASS_STATS);
         int packets = oxcf->two_pass_stats_in.sz / packet_sz;
 
-        cpi->twopass.stats_in = oxcf->two_pass_stats_in.buf;
+        cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
+        cpi->twopass.stats_in = cpi->twopass.stats_in_start;
         cpi->twopass.stats_in_end = (void*)((char *)cpi->twopass.stats_in
                             + (packets - 1) * packet_sz);
         vp8_init_second_pass(cpi);
@@ -4218,7 +4219,7 @@
 
     update_reference_frames(cm);
 
-    if (cpi->oxcf.error_resilient_mode == 1)
+    if (cpi->oxcf.error_resilient_mode)
     {
         cm->refresh_entropy_probs = 0;
     }
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -405,11 +405,11 @@
 
     unsigned int MVcount [2] [MVvals];  /* (row,col) MV cts this frame */
 
-    unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];  /* for this frame */
-    //DECLARE_ALIGNED(16, int, coef_counts_backup [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens]);   //not used any more
+    unsigned int coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];  /* for this frame */
+    //DECLARE_ALIGNED(16, int, coef_counts_backup [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS]);   //not used any more
     //save vp8_tree_probs_from_distribution result for each frame to avoid repeat calculation
-    vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1];
-    unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1][2];
+    vp8_prob frame_coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
+    unsigned int frame_branch_ct [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES][2];
 
     int gfu_boost;
     int kf_boost;
@@ -505,6 +505,7 @@
 #endif
 
     TOKENLIST *tplist;
+    unsigned int partition_sz[MAX_PARTITIONS];
     // end of multithread data
 
 
@@ -528,7 +529,7 @@
         unsigned int this_iiratio;
         FIRSTPASS_STATS *total_stats;
         FIRSTPASS_STATS *this_frame_stats;
-        FIRSTPASS_STATS *stats_in, *stats_in_end;
+        FIRSTPASS_STATS *stats_in, *stats_in_end, *stats_in_start;
         int first_pass_done;
         long long bits_left;
         long long clip_bits_total;
@@ -607,6 +608,8 @@
     // directly or through 0,0
     unsigned char *gf_active_flags;
     int gf_active_count;
+
+    int output_partition;
 
     //Store last frame's MV info for next frame MV prediction
     int_mv *lfmv;
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -134,8 +134,8 @@
 };
 
 static void fill_token_costs(
-    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens],
-    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1]
+    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS],
+    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]
 )
 {
     int i, j, k;
--- a/vp8/encoder/tokenize.c
+++ b/vp8/encoder/tokenize.c
@@ -21,7 +21,7 @@
    compressions, then generating context.c = initial stats. */
 
 #ifdef ENTROPY_STATS
-_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
 #endif
 void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
 void vp8_fix_contexts(MACROBLOCKD *x);
@@ -282,9 +282,9 @@
 
     fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");
 
-    fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];\n\n");
+    fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];\n\n");
 
-    fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] = {");
+    fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS] = {");
 
 # define Comma( X) (X? ",":"")
 
@@ -317,7 +317,7 @@
                     fprintf(f, "%s %d", Comma(t), y);
 
                 }
-                while (++t < vp8_coef_tokens);
+                while (++t < MAX_ENTROPY_TOKENS);
 
                 fprintf(f, "}");
             }
--- a/vp8/encoder/tokenize.h
+++ b/vp8/encoder/tokenize.h
@@ -37,7 +37,7 @@
 void init_context_counters();
 void print_context_counters();
 
-extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
+extern _int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
 #endif
 
 extern const int *vp8_dct_value_cost_ptr;
--- a/vp8/vp8_common.mk
+++ b/vp8/vp8_common.mk
@@ -19,6 +19,7 @@
 VP8_COMMON_SRCS-yes += common/coefupdateprobs.h
 VP8_COMMON_SRCS-yes += common/debugmodes.c
 VP8_COMMON_SRCS-yes += common/defaultcoefcounts.h
+VP8_COMMON_SRCS-yes += common/defaultcoefcounts.c
 VP8_COMMON_SRCS-yes += common/entropy.c
 VP8_COMMON_SRCS-yes += common/entropymode.c
 VP8_COMMON_SRCS-yes += common/entropymv.c
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -753,6 +753,9 @@
         if (ctx->base.init_flags & VPX_CODEC_USE_PSNR)
             ((VP8_COMP *)ctx->cpi)->b_calculate_psnr = 1;
 
+        if (ctx->base.init_flags & VPX_CODEC_USE_OUTPUT_PARTITION)
+            ((VP8_COMP *)ctx->cpi)->output_partition = 1;
+
         /* Convert API flags to internal codec lib flags */
         lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
 
@@ -792,8 +795,6 @@
                 round = 1000000 * ctx->cfg.g_timebase.num / 2 - 1;
                 delta = (dst_end_time_stamp - dst_time_stamp);
                 pkt.kind = VPX_CODEC_CX_FRAME_PKT;
-                pkt.data.frame.buf = cx_data;
-                pkt.data.frame.sz  = size;
                 pkt.data.frame.pts =
                     (dst_time_stamp * ctx->cfg.g_timebase.den + round)
                     / ctx->cfg.g_timebase.num / 10000000;
@@ -819,11 +820,35 @@
                     pkt.data.frame.duration = 0;
                 }
 
-                vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
+                if (cpi->output_partition)
+                {
+                    int i;
+                    const int num_partitions =
+                            (1 << cpi->common.multi_token_partition) + 1;
+                    for (i = 0; i < num_partitions; ++i)
+                    {
+                        pkt.data.frame.buf = cx_data;
+                        pkt.data.frame.sz = cpi->partition_sz[i];
+                        pkt.data.frame.partition_id = i;
+                        /* don't set the fragment bit for the last partition */
+                        if (i < num_partitions - 1)
+                            pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT;
+                        vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
+                        cx_data += cpi->partition_sz[i];
+                        cx_data_sz -= cpi->partition_sz[i];
+                    }
+                }
+                else
+                {
+                    pkt.data.frame.buf = cx_data;
+                    pkt.data.frame.sz  = size;
+                    pkt.data.frame.partition_id = -1;
+                    vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
+                    cx_data += size;
+                    cx_data_sz -= size;
+                }
 
                 //printf("timestamp: %lld, duration: %d\n", pkt->data.frame.pts, pkt->data.frame.duration);
-                cx_data += size;
-                cx_data_sz -= size;
             }
         }
     }
@@ -1143,7 +1168,8 @@
 {
     "WebM Project VP8 Encoder" VERSION_STRING,
     VPX_CODEC_INTERNAL_ABI_VERSION,
-    VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR,
+    VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR |
+    VPX_CODEC_CAP_OUTPUT_PARTITION,
     /* vpx_codec_caps_t          caps; */
     vp8e_init,          /* vpx_codec_init_fn_t       init; */
     vp8e_destroy,       /* vpx_codec_destroy_fn_t    destroy; */
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -368,6 +368,8 @@
             oxcf.max_threads = ctx->cfg.threads;
             oxcf.error_concealment =
                     (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT);
+            oxcf.input_partition =
+                    (ctx->base.init_flags & VPX_CODEC_USE_INPUT_PARTITION);
 
             optr = vp8dx_create_decompressor(&oxcf);
 
@@ -721,7 +723,8 @@
 {
     "WebM Project VP8 Decoder" VERSION_STRING,
     VPX_CODEC_INTERNAL_ABI_VERSION,
-    VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT,
+    VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT |
+    VPX_CODEC_CAP_INPUT_PARTITION,
     /* vpx_codec_caps_t          caps; */
     vp8_init,         /* vpx_codec_init_fn_t       init; */
     vp8_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
--- a/vpx/src/vpx_decoder.c
+++ b/vpx/src/vpx_decoder.c
@@ -39,6 +39,9 @@
     else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
             !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
         res = VPX_CODEC_INCAPABLE;
+    else if ((flags & VPX_CODEC_USE_INPUT_PARTITION) &&
+            !(iface->caps & VPX_CODEC_CAP_INPUT_PARTITION))
+        res = VPX_CODEC_INCAPABLE;
     else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
         res = VPX_CODEC_INCAPABLE;
     else
--- a/vpx/src/vpx_encoder.c
+++ b/vpx/src/vpx_encoder.c
@@ -41,6 +41,9 @@
     else if ((flags & VPX_CODEC_USE_PSNR)
              && !(iface->caps & VPX_CODEC_CAP_PSNR))
         res = VPX_CODEC_INCAPABLE;
+    else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION)
+             && !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION))
+        res = VPX_CODEC_INCAPABLE;
     else
     {
         ctx->iface = iface;
--- a/vpx/vp8.h
+++ b/vpx/vp8.h
@@ -30,7 +30,7 @@
  */
 #ifndef VP8_H
 #define VP8_H
-#include "vpx/vpx_codec_impl_top.h"
+#include "vpx_codec_impl_top.h"
 
 /*!\brief Control functions
  *
@@ -126,5 +126,5 @@
 DECLSPEC_DEPRECATED extern vpx_codec_iface_t vpx_codec_vp8_algo DEPRECATED;
 #endif
 
-#include "vpx/vpx_codec_impl_bottom.h"
+#include "vpx_codec_impl_bottom.h"
 #endif
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -22,7 +22,7 @@
  */
 #ifndef VP8CX_H
 #define VP8CX_H
-#include "vpx/vpx_codec_impl_top.h"
+#include "vpx_codec_impl_top.h"
 
 /*!\name Algorithm interface for VP8
  *
@@ -306,5 +306,5 @@
 VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64,  int *)
 
 /*! @} - end defgroup vp8_encoder */
-#include "vpx/vpx_codec_impl_bottom.h"
+#include "vpx_codec_impl_bottom.h"
 #endif
--- a/vpx/vp8dx.h
+++ b/vpx/vp8dx.h
@@ -22,7 +22,7 @@
  */
 #ifndef VP8DX_H
 #define VP8DX_H
-#include "vpx/vpx_codec_impl_top.h"
+#include "vpx_codec_impl_top.h"
 
 /*!\name Algorithm interface for VP8
  *
@@ -74,5 +74,5 @@
 /*! @} - end defgroup vp8_decoder */
 
 
-#include "vpx/vpx_codec_impl_bottom.h"
+#include "vpx_codec_impl_bottom.h"
 #endif
--- a/vpx/vp8e.h
+++ b/vpx/vp8e.h
@@ -14,7 +14,7 @@
  */
 #ifndef VP8E_H
 #define VP8E_H
-#include "vpx/vpx_codec_impl_top.h"
+#include "vpx_codec_impl_top.h"
 
 #if defined(VPX_CODEC_DISABLE_COMPAT) && VPX_CODEC_DISABLE_COMPAT
 #error "Backwards compatibility disabled: don't include vp8e.h"
@@ -59,5 +59,5 @@
  * #VPX_DL_BEST_QUALITY constants to that parameter instead.
  */
 VPX_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_ENCODING_MODE, vp8e_encoding_mode)
-#include "vpx/vpx_codec_impl_bottom.h"
+#include "vpx_codec_impl_bottom.h"
 #endif
--- a/vpx/vpx_decoder.h
+++ b/vpx/vpx_decoder.h
@@ -55,6 +55,8 @@
 #define VPX_CODEC_CAP_POSTPROC   0x40000 /**< Can postprocess decoded frame */
 #define VPX_CODEC_CAP_ERROR_CONCEALMENT   0x80000 /**< Can conceal errors due to
                                                        packet loss */
+#define VPX_CODEC_CAP_INPUT_PARTITION   0x100000 /**< Can receive encoded frames
+                                                    one partition at a time */
 
     /*! \brief Initialization-time Feature Enabling
      *
@@ -66,6 +68,9 @@
 #define VPX_CODEC_USE_POSTPROC   0x10000 /**< Postprocess decoded frame */
 #define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded
                                                      frames */
+#define VPX_CODEC_USE_INPUT_PARTITION   0x40000 /**< The input frame should be
+                                                    passed to the decoder one
+                                                    partition at a time */
 
     /*!\brief Stream properties
      *
@@ -184,6 +189,11 @@
      * generated, as appropriate. Encoded data \ref MUST be passed in DTS (decode
      * time stamp) order. Frames produced will always be in PTS (presentation
      * time stamp) order.
+     * If the decoder is configured with VPX_CODEC_USE_INPUT_PARTITION enabled,
+     * data and data_sz must contain at most one encoded partition. When no more
+     * data is available, this function should be called with NULL as data and 0
+     * as data_sz. The memory passed to this function must be available until
+     * the frame has been decoded.
      *
      * \param[in] ctx          Pointer to this instance's context
      * \param[in] data         Pointer to this block of new coded data. If
--- a/vpx/vpx_encoder.h
+++ b/vpx/vpx_encoder.h
@@ -55,7 +55,14 @@
      */
 #define VPX_CODEC_CAP_PSNR  0x10000 /**< Can issue PSNR packets */
 
+    /*! Can output one partition at a time. Each partition is returned in its
+     *  own VPX_CODEC_CX_FRAME_PKT, with the FRAME_IS_FRAGMENT flag set for
+     *  every partition but the last. In this mode all frames are always
+     *  returned partition by partition.
+     */
+#define VPX_CODEC_CAP_OUTPUT_PARTITION  0x20000
 
+
     /*! \brief Initialization-time Feature Enabling
      *
      *  Certain codec features must be known at initialization time, to allow
@@ -64,6 +71,8 @@
      *  The available flags are specified by VPX_CODEC_USE_* defines.
      */
 #define VPX_CODEC_USE_PSNR  0x10000 /**< Calculate PSNR on each frame */
+#define VPX_CODEC_USE_OUTPUT_PARTITION  0x20000 /**< Make the encoder output one
+                                                     partition at a time. */
 
 
     /*!\brief Generic fixed size buffer structure
@@ -99,7 +108,26 @@
                 this one) */
 #define VPX_FRAME_IS_INVISIBLE 0x4 /**< frame should be decoded but will not
     be shown */
+#define VPX_FRAME_IS_FRAGMENT  0x8 /**< this is a fragment of the encoded
+    frame */
 
+    /*!\brief Error Resilient flags
+     *
+     * These flags define which error resilient features to enable in the
+     * encoder. The flags are specified through the
+     * vpx_codec_enc_cfg::g_error_resilient variable.
+     */
+    typedef uint32_t vpx_codec_er_flags_t;
+#define VPX_ERROR_RESILIENT_DEFAULT     0x1 /**< Improve resiliency against
+                                                 losses of whole frames */
+#define VPX_ERROR_RESILIENT_PARTITIONS  0x2 /**< The frame partitions are
+                                                 independently decodable by the
+                                                 bool decoder, meaning that
+                                                 partitions can be decoded even
+                                                 though earlier partitions have
+                                                 been lost. Note that intra
+                                                 predicition is still done over
+                                                 the partition boundary. */
 
     /*!\brief Encoder output packet variants
      *
@@ -135,6 +163,13 @@
                 unsigned long            duration; /**< duration to show frame
                                                     (in timebase units) */
                 vpx_codec_frame_flags_t  flags;    /**< flags for this frame */
+                int                      partition_id; /**< the partition id
+                                              defines the decoding order
+                                              of the partitions. Only
+                                              applicable when "output partition"
+                                              mode is enabled. First partition
+                                              has id 0.*/
+
             } frame;  /**< data for compressed frame packet */
             struct vpx_fixed_buf twopass_stats;  /**< data for two-pass packet */
             struct vpx_psnr_pkt
@@ -289,13 +324,13 @@
         struct vpx_rational    g_timebase;
 
 
-        /*!\brief Enable error resilient mode.
+        /*!\brief Enable error resilient modes.
          *
-         * Error resilient mode indicates to the encoder that it should take
-         * measures appropriate for streaming over lossy or noisy links, if
-         * possible. Set to 1 to enable this feature, 0 to disable it.
+         * The error resilient bitfield indicates to the encoder which features
+         * it should enable to take measures for streaming over lossy or noisy
+         * links.
          */
-        unsigned int           g_error_resilient;
+        vpx_codec_er_flags_t   g_error_resilient;
 
 
         /*!\brief Multi-pass Encoding Mode
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -1306,11 +1306,16 @@
 
 
 static void init_rate_histogram(struct rate_hist          *hist,
-                                const vpx_codec_enc_cfg_t *cfg)
+                                const vpx_codec_enc_cfg_t *cfg,
+                                const vpx_rational_t      *fps)
 {
     int i;
 
-    hist->samples = cfg->rc_buf_sz * 60 / 1000; // max 60 fps
+    /* Determine the number of samples in the buffer. Use the file's framerate
+     * to determine the number of frames in rc_buf_sz milliseconds, with an
+     * adjustment (5/4) to account for alt-refs
+     */
+    hist->samples = cfg->rc_buf_sz * 5 / 4 * fps->num / fps->den / 1000;
     hist->pts = calloc(hist->samples, sizeof(*hist->pts));
     hist->sz = calloc(hist->samples, sizeof(*hist->sz));
     for(i=0; i<RATE_BINS; i++)
@@ -1346,8 +1351,10 @@
     if(now < cfg->rc_buf_initial_sz)
         return;
 
+    then = now;
+
     /* Sum the size over the past rc_buf_sz ms */
-    for(i = hist->frames; i > 0; i--)
+    for(i = hist->frames; i > 0 && hist->frames - i < hist->samples; i--)
     {
         int i_idx = (i-1) % hist->samples;
 
@@ -1357,6 +1364,9 @@
         sum_sz += hist->sz[i_idx];
     }
 
+    if (now == then)
+        return;
+
     avg_bitrate = sum_sz * 8 * 1000 / (now - then);
     idx = avg_bitrate * (RATE_BINS/2) / (cfg->rc_target_bitrate * 1000);
     if(idx < 0)
@@ -1707,8 +1717,6 @@
 
     memset(&stats, 0, sizeof(stats));
 
-    init_rate_histogram(&rate_hist, &cfg);
-
     for (pass = one_pass_only ? one_pass_only - 1 : 0; pass < arg_passes; pass++)
     {
         int frames_in = 0, frames_out = 0;
@@ -1835,6 +1843,8 @@
             else
                 vpx_img_alloc(&raw, arg_use_i420 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_YV12,
                               cfg.g_w, cfg.g_h, 1);
+
+            init_rate_histogram(&rate_hist, &cfg, &arg_framerate);
         }
 
         outfile = strcmp(out_fn, "-") ? fopen(out_fn, "wb")
@@ -2048,10 +2058,14 @@
         vpx_codec_destroy(&encoder);
 
         fclose(infile);
+        if (file_type == FILE_TYPE_Y4M)
+            y4m_input_close(&y4m);
 
         if(write_webm)
         {
             write_webm_file_footer(&ebml, hash);
+            free(ebml.cue_list);
+            ebml.cue_list = NULL;
         }
         else
         {