Merge "Copy macroblock data to a buffer before encoding it"
authorYunqing Wang <yunqingwang@google.com>
Thu, 30 Jun 2011 18:14:24 +0000 (11:14 -0700)
committerCode Review <code-review@webmproject.org>
Thu, 30 Jun 2011 18:14:24 +0000 (11:14 -0700)
68 files changed:
build/make/ads2gas.pl
build/make/ads2gas_apple.pl
build/make/configure.sh
examples/decode_with_partial_drops.txt
libs.mk
vp8/common/alloccommon.c
vp8/common/arm/armv6/bilinearfilter_v6.asm
vp8/common/arm/armv6/copymem16x16_v6.asm
vp8/common/arm/armv6/filter_v6.asm
vp8/common/arm/armv6/loopfilter_v6.asm
vp8/common/arm/armv6/simpleloopfilter_v6.asm
vp8/common/arm/armv6/sixtappredict8x4_v6.asm
vp8/common/arm/filter_arm.c
vp8/common/arm/neon/bilinearpredict16x16_neon.asm
vp8/common/arm/neon/bilinearpredict4x4_neon.asm
vp8/common/arm/neon/bilinearpredict8x4_neon.asm
vp8/common/arm/neon/bilinearpredict8x8_neon.asm
vp8/common/arm/neon/shortidct4x4llm_neon.asm
vp8/common/arm/neon/sixtappredict16x16_neon.asm
vp8/common/arm/neon/sixtappredict4x4_neon.asm
vp8/common/arm/neon/sixtappredict8x4_neon.asm
vp8/common/arm/neon/sixtappredict8x8_neon.asm
vp8/common/coefupdateprobs.h
vp8/common/defaultcoefcounts.c [new file with mode: 0644]
vp8/common/defaultcoefcounts.h
vp8/common/entropy.c
vp8/common/entropy.h
vp8/common/onyx.h
vp8/common/onyxc_int.h
vp8/common/onyxd.h
vp8/common/postproc.c
vp8/decoder/arm/neon/dequant_idct_neon.asm
vp8/decoder/arm/neon/idct_dequant_dc_full_2x_neon.asm
vp8/decoder/arm/neon/idct_dequant_full_2x_neon.asm
vp8/decoder/dboolhuff.h
vp8/decoder/decodframe.c
vp8/decoder/error_concealment.c
vp8/decoder/onyxd_if.c
vp8/decoder/onyxd_int.h
vp8/decoder/threading.c
vp8/encoder/bitstream.c
vp8/encoder/block.h
vp8/encoder/encodeframe.c
vp8/encoder/firstpass.c
vp8/encoder/mcomp.c
vp8/encoder/mcomp.h
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/pickinter.c
vp8/encoder/picklpf.c
vp8/encoder/ratectrl.c
vp8/encoder/rdopt.c
vp8/encoder/tokenize.c
vp8/encoder/tokenize.h
vp8/vp8_common.mk
vp8/vp8_cx_iface.c
vp8/vp8_dx_iface.c
vp8/vp8cx_arm.mk
vp8/vp8dx_arm.mk
vpx/src/vpx_decoder.c
vpx/src/vpx_encoder.c
vpx/vp8.h
vpx/vp8cx.h
vpx/vp8dx.h
vpx/vp8e.h
vpx/vpx_decoder.h
vpx/vpx_encoder.h
vpxenc.c

index efdfce7..be46582 100755 (executable)
@@ -82,7 +82,10 @@ while (<STDIN>)
     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
index 1b30393..78f4a97 100755 (executable)
@@ -100,7 +100,10 @@ while (<STDIN>)
     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
index 66e0dbf..23cf443 100755 (executable)
@@ -642,8 +642,8 @@ process_common_toolchain() {
     # on arm, isa versions are supersets
     enabled armv7a && soft_enable armv7 ### DEBUG
     enabled armv7 && soft_enable armv6
-    enabled armv6 && soft_enable armv5te
-    enabled armv6 && soft_enable fast_unaligned
+    enabled armv7 || enabled armv6 && soft_enable armv5te
+    enabled armv7 || enabled armv6 && soft_enable fast_unaligned
     enabled iwmmxt2 && soft_enable iwmmxt
     enabled iwmmxt && soft_enable armv5te
 
index 30854d6..7b0d3d2 100644 (file)
@@ -110,7 +110,7 @@ void throw_packets(unsigned char* frame, int* size, int loss_rate,
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DEC_INIT
 /* Initialize codec */
 flags = VPX_CODEC_USE_ERROR_CONCEALMENT;
-res = vpx_codec_dec_init(&codec, interface, NULL, flags);
+res = vpx_codec_dec_init(&codec, interface, &dec_cfg, flags);
 if(res)
     die_codec(&codec, "Failed to initialize decoder");
 
@@ -123,11 +123,15 @@ which specifies the range or pattern of frames to drop. The parameter is
 parsed as follows:
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
-if(argc!=4 && argc != 5)
-    die("Usage: %s <infile> <outfile> <N-M|N/M|L,S>\n", argv[0]);
+if(argc < 4 || argc > 6)
+    die("Usage: %s <infile> <outfile> [-t <num threads>] <N-M|N/M|L,S>\n",
+        argv[0]);
 {
     char *nptr;
-    n = strtol(argv[3], &nptr, 0);
+    int arg_num = 3;
+    if (argc == 6 && strncmp(argv[arg_num++], "-t", 2) == 0)
+        dec_cfg.threads = strtol(argv[arg_num++], NULL, 0);
+    n = strtol(argv[arg_num], &nptr, 0);
     mode = (*nptr == '\0' || *nptr == ',') ? 2 : (*nptr == '-') ? 1 : 0;
 
     m = strtol(nptr+1, NULL, 0);
@@ -138,6 +142,7 @@ if(argc!=4 && argc != 5)
 seed = (m > 0) ? m : (unsigned int)time(NULL);
 srand(seed);thrown_frame = 0;
 printf("Seed: %u\n", seed);
+printf("Threads: %d\n", dec_cfg.threads);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ USAGE
 
 
@@ -181,6 +186,7 @@ int              n, m, mode;
 unsigned int     seed;
 int              thrown=0, kept=0;
 int              thrown_frame=0, kept_frame=0;
+vpx_codec_dec_cfg_t  dec_cfg = {0};
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EXTRA_VARS
 
 
diff --git a/libs.mk b/libs.mk
index c09581c..ae86fbd 100644 (file)
--- a/libs.mk
+++ b/libs.mk
@@ -198,7 +198,7 @@ libvpx.ver: $(call enabled,CODEC_EXPORTS)
        $(qexec)echo "local: *; };" >> $@
 CLEAN-OBJS += libvpx.ver
 
-$(addprefix $(DIST_DIR)/,$(LIBVPX_SO_SYMLINKS)):
+$(addprefix $(DIST_DIR)/,$(LIBVPX_SO_SYMLINKS)): $(DIST_DIR)/$(LIBSUBDIR)/$(LIBVPX_SO)
        @echo "    [LN]      $@"
        $(qexec)ln -sf $(LIBVPX_SO) $@
 
index 216590c..376707e 100644 (file)
@@ -70,7 +70,7 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
 
     for (i = 0; i < NUM_YV12_BUFFERS; i++)
     {
-        oci->fb_idx_ref_cnt[0] = 0;
+        oci->fb_idx_ref_cnt[i] = 0;
         oci->yv12_fb[i].flags = 0;
         if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, VP8BORDERINPIXELS) < 0)
         {
index a86ed5d..9704b42 100644 (file)
     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
 
@@ -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
index fca91a0..abf048c 100644 (file)
@@ -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 @@ copy_mem16x16_1_loop
     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 @@ copy_mem16x16_4_loop
     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 @@ copy_mem16x16_8_loop
 
     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 @@ copy_mem16x16_fast_loop
     ;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}
index 03b5bcc..1ba91dd 100644 (file)
@@ -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|
     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]
 
     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]
 
 
     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,
 |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
 
     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
index b6417de..c7441b0 100644 (file)
@@ -253,12 +253,6 @@ count       RN  r5
 
     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 @@ count       RN  r5
     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 @@ count       RN  r5
     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
index 0137120..40a71f4 100644 (file)
@@ -154,22 +154,26 @@ pstep       RN  r1
 
     ; 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
 
     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
 
     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 @@ pstep       RN  r1
 
     ; 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
index 029e02a..e81aef5 100644 (file)
     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
 
 
     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 @@ secondpass_filter
     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 @@ skip_secondpass_hloop
 ;-----------------
 ;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
index fe3c5a5..6582fb2 100644 (file)
@@ -25,6 +25,28 @@ extern void vp8_filter_block2d_first_pass_armv6
     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 @@ void vp8_sixtap_predict8x8_armv6
     {
         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 @@ void vp8_sixtap_predict16x16_armv6
     {
         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);
         }
     }
index 79e1a69..e392786 100644 (file)
@@ -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 @@ filt_blk2d_spo16x16_loop_neon
 
 ;-----------------
 
-_bifilter16_coeff_
-    DCD     bifilter16_coeff
 bifilter16_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
index 10cd1b8..0ac6243 100644 (file)
@@ -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 @@ skip_secondpass_filter
 
 ;-----------------
 
-_bifilter4_coeff_
-    DCD     bifilter4_coeff
 bifilter4_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
index bf37bb0..41f5c45 100644 (file)
@@ -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 @@ skip_secondpass_filter
 
 ;-----------------
 
-_bifilter8x4_coeff_
-    DCD     bifilter8x4_coeff
 bifilter8x4_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
index 9b29df6..c4711bc 100644 (file)
@@ -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 @@ skip_secondpass_filter
 
 ;-----------------
 
-_bifilter8_coeff_
-    DCD     bifilter8_coeff
 bifilter8_coeff
     DCD     128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
 
index 16c4d2d..b74c315 100644 (file)
@@ -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]
 
 
 ;-----------------
 
-_idct_coeff_
-    DCD     idct_coeff
 idct_coeff
     DCD     0x4e7b4e7b, 0x8a8c8a8c
 
index 3c22fa1..9fdafd3 100644 (file)
     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 @@ secondpass_only_inner_loop_neon
     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
index 2dc3f59..41510e8 100644 (file)
     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
 
@@ -408,16 +419,4 @@ secondpass_filter4x4_only
 
 ;-----------------
 
-_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
index 0904f52..a57ec01 100644 (file)
     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
 
@@ -459,16 +470,4 @@ secondpass_filter8x4_only
 
 ;-----------------
 
-_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
index 33af86f..00ed5ae 100644 (file)
     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
@@ -510,16 +521,4 @@ filt_blk2d_spo8x8_loop_neon
 
 ;-----------------
 
-_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
index 785e3ff..9e194dc 100644 (file)
@@ -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] =
 {
     {
         {
diff --git a/vp8/common/defaultcoefcounts.c b/vp8/common/defaultcoefcounts.c
new file mode 100644 (file)
index 0000000..b0e2e70
--- /dev/null
@@ -0,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,},
+        },
+    },
+};
index ca58d56..7a1e28b 100644 (file)
  *  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
index a1fe4f4..fba7a07 100644 (file)
@@ -65,7 +65,7 @@ const vp8_tree_index vp8_coef_tree[ 22] =     /* corresponding _CONTEXT_NODEs */
     -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 @@ void vp8_default_coef_probs(VP8_COMMON *pc)
 
             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);
 
             }
index d174e45..66d282b 100644 (file)
 #define DCT_VAL_CATEGORY6       10      /* 67+       Extra Bits 11+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 @@ extern DECLARE_ALIGNED(16, const unsigned char, vp8_coef_bands[16]);
 /*# 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;
index a059519..545798a 100644 (file)
@@ -184,8 +184,11 @@ extern "C"
         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 ;
index 862307e..a381dfe 100644 (file)
@@ -35,13 +35,15 @@ void vp8_initialize_common(void);
 
 #define NUM_YV12_BUFFERS 4
 
+#define MAX_PARTITIONS 9
+
 typedef struct frame_contexts
 {
     vp8_prob bmode_prob [VP8_BINTRAMODES-1];
     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;
index 140dc57..8a4703a 100644 (file)
@@ -22,6 +22,7 @@ extern "C"
 #include "vpx_scale/yv12config.h"
 #include "ppflags.h"
 #include "vpx_ports/mem.h"
+#include "vpx/vpx_codec.h"
 
     typedef void   *VP8D_PTR;
     typedef struct
@@ -32,6 +33,7 @@ extern "C"
         int     postprocess;
         int     max_threads;
         int     error_concealment;
+        int     input_partition;
     } VP8D_CONFIG;
     typedef enum
     {
@@ -54,8 +56,8 @@ extern "C"
     int vp8dx_receive_compressed_data(VP8D_PTR comp, unsigned long size, const unsigned char *dest, INT64 time_stamp);
     int vp8dx_get_raw_frame(VP8D_PTR comp, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags);
 
-    int vp8dx_get_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
-    int vp8dx_set_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    vpx_codec_err_t vp8dx_get_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
+    vpx_codec_err_t vp8dx_set_reference(VP8D_PTR comp, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd);
 
     VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf);
 
index 7dbe966..14c3b7b 100644 (file)
@@ -837,7 +837,6 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
         YV12_BUFFER_CONFIG *post = &oci->post_proc_buffer;
         int width  = post->y_width;
         int height = post->y_height;
-        int mb_cols = width  >> 4;
         unsigned char *y_buffer = oci->post_proc_buffer.y_buffer;
         int y_stride = oci->post_proc_buffer.y_stride;
         MODE_INFO *mi = oci->mi;
@@ -861,7 +860,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                     {
                         case 0 :    /* mv_top_bottom */
                         {
-                            B_MODE_INFO *bmi = &mi->bmi[0];
+                            union b_mode_info *bmi = &mi->bmi[0];
                             MV *mv = &bmi->mv.as_mv;
 
                             x1 = x0 + 8 + (mv->col >> 3);
@@ -882,7 +881,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                         }
                         case 1 :    /* mv_left_right */
                         {
-                            B_MODE_INFO *bmi = &mi->bmi[0];
+                            union b_mode_info *bmi = &mi->bmi[0];
                             MV *mv = &bmi->mv.as_mv;
 
                             x1 = x0 + 4 + (mv->col >> 3);
@@ -903,7 +902,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                         }
                         case 2 :    /* mv_quarters   */
                         {
-                            B_MODE_INFO *bmi = &mi->bmi[0];
+                            union b_mode_info *bmi = &mi->bmi[0];
                             MV *mv = &bmi->mv.as_mv;
 
                             x1 = x0 + 4 + (mv->col >> 3);
@@ -939,7 +938,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                         }
                         default :
                         {
-                            B_MODE_INFO *bmi = mi->bmi;
+                            union b_mode_info *bmi = mi->bmi;
                             int bx0, by0;
 
                             for (by0 = y0; by0 < (y0+16); by0 += 4)
@@ -1012,7 +1011,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                 {
                     int by, bx;
                     unsigned char *yl, *ul, *vl;
-                    B_MODE_INFO *bmi = mi->bmi;
+                    union b_mode_info *bmi = mi->bmi;
 
                     yl = y_ptr + x;
                     ul = u_ptr + (x>>1);
@@ -1025,9 +1024,9 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t
                             if ((ppflags->display_b_modes_flag & (1<<mi->mbmi.mode))
                                 || (ppflags->display_mb_modes_flag & B_PRED))
                             {
-                                Y = B_PREDICTION_MODE_colors[bmi->mode][0];
-                                U = B_PREDICTION_MODE_colors[bmi->mode][1];
-                                V = B_PREDICTION_MODE_colors[bmi->mode][2];
+                                Y = B_PREDICTION_MODE_colors[bmi->as_mode][0];
+                                U = B_PREDICTION_MODE_colors[bmi->as_mode][1];
+                                V = B_PREDICTION_MODE_colors[bmi->as_mode][2];
 
                                 POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_b)
                                     (yl+bx, ul+(bx>>1), vl+(bx>>1), Y, U, V, 0xc000, y_stride);
index 1923be4..4bf6618 100644 (file)
@@ -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
     ENDP           ; |vp8_dequant_idct_add_neon|
 
 ; Constant Pool
-_CONSTANTS_       DCD cospi8sqrt2minus1
 cospi8sqrt2minus1 DCD 0x4e7b4e7b
 sinpi8sqrt2       DCD 0x8a8c8a8c
 
index ad4364a..61fa660 100644 (file)
@@ -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
     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
index 85fff11..772ec46 100644 (file)
@@ -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
     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
index 5f6b211..f729837 100644 (file)
@@ -81,11 +81,14 @@ static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
     int count;
     unsigned int range;
 
+    split = 1 + (((br->range - 1) * probability) >> 8);
+
+    if(br->count < 0)
+        vp8dx_bool_decoder_fill(br);
+
     value = br->value;
     count = br->count;
-    range = br->range;
 
-    split = 1 + (((range - 1) * probability) >> 8);
     bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
 
     range = split;
@@ -106,8 +109,7 @@ static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
     br->value = value;
     br->count = count;
     br->range = range;
-    if(count < 0)
-        vp8dx_bool_decoder_fill(br);
+
     return bit;
 }
 
index 734ab36..a300bb5 100644 (file)
@@ -183,7 +183,8 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
                               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 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
     }
 
     /* 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 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
     {
         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
@@ -239,53 +237,23 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
 
 #if CONFIG_ERROR_CONCEALMENT
     if (pbi->ec_enabled &&
-        (mb_idx > pbi->mvs_corrupt_from_mb ||
+        (mb_idx >= pbi->mvs_corrupt_from_mb ||
         vp8dx_bool_error(xd->current_bc)))
     {
         /* MB with corrupt residuals or corrupt mode/motion vectors.
          * Better to use the predictor as reconstruction.
          */
+        vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
         vp8_conceal_corrupt_mb(xd);
         return;
     }
 #endif
 
     /* dequantization and idct */
-    if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
-    {
-        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)
+    if (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);
@@ -306,13 +274,43 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
         }
 
     }
-    else
+    else if (mode == SPLITMV)
     {
         DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block)
                         (xd->qcoeff, xd->block[0].dequant,
                          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,
@@ -462,6 +460,40 @@ static unsigned int read_partition_size(const unsigned char *cx_size)
     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)
@@ -474,7 +506,13 @@ static void setup_token_decoder(VP8D_COMP *pbi,
     const unsigned char *partition;
 
     /* Parse number of token partitions to use */
-    pc->multi_token_partition = (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
+    const TOKEN_PARTITION multi_token_partition =
+            (TOKEN_PARTITION)vp8_read_literal(&pbi->bc, 2);
+    /* Only update the multi_token_partition field if we are sure the value
+     * is correct. */
+    if (!pbi->ec_enabled || !vp8dx_bool_error(&pbi->bc))
+        pc->multi_token_partition = multi_token_partition;
+
     num_part = 1 << pc->multi_token_partition;
 
     /* Set up pointers to the first partition */
@@ -612,13 +650,19 @@ int vp8_decode_frame(VP8D_COMP *pbi)
     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;
@@ -834,7 +878,14 @@ int vp8_decode_frame(VP8D_COMP *pbi)
         }
     }
 
-    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. */
@@ -923,14 +974,12 @@ int vp8_decode_frame(VP8D_COMP *pbi)
         fclose(z);
     }
 
-
     {
         /* 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;
@@ -1014,7 +1063,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
         }
     }
 
-
     stop_token_decoder(pbi);
 
     /* Collect information about decoder corruption. */
index c06bdcf..4f8f1a6 100644 (file)
@@ -382,6 +382,7 @@ static void estimate_missing_mvs(MB_OVERLAP *overlaps,
             mi->mbmi.mode = SPLITMV;
             mi->mbmi.uv_mode = DC_PRED;
             mi->mbmi.partitioning = 3;
+            mi->mbmi.segment_id = 0;
             estimate_mb_mvs(block_overlaps,
                                 mi,
                                 mb_to_left_edge,
@@ -563,6 +564,12 @@ static void interpolate_mvs(MACROBLOCKD *mb,
                                                        mb->mb_to_top_edge,
                                                        mb->mb_to_bottom_edge);
             }
+            else
+            {
+                mv->as_int = 0;
+                mi->bmi[row*4 + col].as_mode = NEW4X4;
+                mi->mbmi.need_to_clamp_mvs = 0;
+            }
         }
     }
 }
@@ -597,6 +604,7 @@ void vp8_interpolate_motion(MACROBLOCKD *mb,
     mb->mode_info_context->mbmi.mode = SPLITMV;
     mb->mode_info_context->mbmi.uv_mode = DC_PRED;
     mb->mode_info_context->mbmi.partitioning = 3;
+    mb->mode_info_context->mbmi.segment_id = 0;
 }
 
 void vp8_conceal_corrupt_mb(MACROBLOCKD *xd)
index 4845cd0..5f81ee6 100644 (file)
@@ -109,6 +109,8 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
     pbi->ec_enabled = 0;
 #endif
 
+    pbi->input_partition = oxcf->input_partition;
+
     return (VP8D_PTR) pbi;
 }
 
@@ -134,7 +136,7 @@ void vp8dx_remove_decompressor(VP8D_PTR ptr)
 }
 
 
-int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+vpx_codec_err_t vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
     VP8_COMMON *cm = &pbi->common;
@@ -146,16 +148,27 @@ int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_C
         ref_fb_idx = cm->gld_fb_idx;
     else if (ref_frame_flag == VP8_ALT_FLAG)
         ref_fb_idx = cm->alt_fb_idx;
-    else
-        return -1;
+    else{
+        vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+            "Invalid reference frame");
+        return pbi->common.error.error_code;
+    }
 
-    vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
+    if(cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
+        cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
+        cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
+        cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){
+        vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+            "Incorrect buffer dimensions");
+    }
+    else
+        vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
 
-    return 0;
+    return pbi->common.error.error_code;
 }
 
 
-int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
+vpx_codec_err_t vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
 {
     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
     VP8_COMMON *cm = &pbi->common;
@@ -168,20 +181,32 @@ int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_C
         ref_fb_ptr = &cm->gld_fb_idx;
     else if (ref_frame_flag == VP8_ALT_FLAG)
         ref_fb_ptr = &cm->alt_fb_idx;
-    else
-        return -1;
-
-    /* Find an empty frame buffer. */
-    free_fb = get_free_fb(cm);
-    /* Decrease fb_idx_ref_cnt since it will be increased again in
-     * ref_cnt_fb() below. */
-    cm->fb_idx_ref_cnt[free_fb]--;
+    else{
+        vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+            "Invalid reference frame");
+        return pbi->common.error.error_code;
+    }
 
-    /* Manage the reference counters and copy image. */
-    ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
-    vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
+    if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
+        cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
+        cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
+        cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){
+        vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
+            "Incorrect buffer dimensions");
+    }
+    else{
+        /* Find an empty frame buffer. */
+        free_fb = get_free_fb(cm);
+        /* Decrease fb_idx_ref_cnt since it will be increased again in
+         * ref_cnt_fb() below. */
+        cm->fb_idx_ref_cnt[free_fb]--;
+
+        /* Manage the reference counters and copy image. */
+        ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
+        vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
+    }
 
-    return 0;
+   return pbi->common.error.error_code;
 }
 
 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
@@ -289,68 +314,91 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
 
     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 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;
+
+                /* Nothing more to do. */
+                return 0;
+            }
+        }
 
 #if HAVE_ARMV7
 #if CONFIG_RUNTIME_CPU_DETECT
-    if (cm->rtcd.flags & HAS_NEON)
+        if (cm->rtcd.flags & HAS_NEON)
 #endif
-    {
-        vp8_push_neon(dx_store_reg);
-    }
+        {
+            vp8_push_neon(dx_store_reg);
+        }
 #endif
 
-    cm->new_fb_idx = get_free_fb (cm);
+        cm->new_fb_idx = get_free_fb (cm);
 
-    if (setjmp(pbi->common.error.jmp))
-    {
+        if (setjmp(pbi->common.error.jmp))
+        {
 #if HAVE_ARMV7
 #if CONFIG_RUNTIME_CPU_DETECT
-        if (cm->rtcd.flags & HAS_NEON)
+            if (cm->rtcd.flags & HAS_NEON)
 #endif
-        {
-            vp8_pop_neon(dx_store_reg);
-        }
+            {
+                vp8_pop_neon(dx_store_reg);
+            }
 #endif
-        pbi->common.error.setjmp = 0;
+            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;
+           /* 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 (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;
+            if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+              cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
+            return -1;
+        }
 
-    /*cm->current_video_frame++;*/
-    pbi->Source = source;
-    pbi->source_sz = size;
+        pbi->common.error.setjmp = 1;
+    }
 
     retcode = vp8_decode_frame(pbi);
 
@@ -450,6 +498,10 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
 
     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
     {
index ea6de3d..be6ffe6 100644 (file)
@@ -83,6 +83,9 @@ typedef struct VP8Decompressor
 
     const unsigned char *Source;
     unsigned int   source_sz;
+    const unsigned char *partitions[MAX_PARTITIONS];
+    unsigned int   partition_sizes[MAX_PARTITIONS];
+    unsigned int   num_partitions;
 
 #if CONFIG_MULTITHREAD
     /* variable for threading */
@@ -137,6 +140,7 @@ typedef struct VP8Decompressor
     unsigned int mvs_corrupt_from_mb;
 #endif
     int ec_enabled;
+    int input_partition;
 
 } VP8D_COMP;
 
index c1df823..a7af9ac 100644 (file)
@@ -22,6 +22,9 @@
 #include "detokenize.h"
 #include "vp8/common/reconinter.h"
 #include "reconintra_mt.h"
+#if CONFIG_ERROR_CONCEALMENT
+#include "error_concealment.h"
+#endif
 
 extern void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd);
 extern void clamp_mvs(MACROBLOCKD *xd);
@@ -151,6 +154,20 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, int mb_row, int m
         vp8_build_inter_predictors_mb(xd);
     }
 
+#if CONFIG_ERROR_CONCEALMENT
+    if (pbi->ec_enabled &&
+        (mb_row * pbi->common.mb_cols + mb_col >= pbi->mvs_corrupt_from_mb ||
+        vp8dx_bool_error(xd->current_bc)))
+    {
+        /* MB with corrupt residuals or corrupt mode/motion vectors.
+         * Better to use the predictor as reconstruction.
+         */
+        vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff));
+        vp8_conceal_corrupt_mb(xd);
+        return;
+    }
+#endif
+
     /* dequantization and idct */
     if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV)
     {
@@ -291,12 +308,37 @@ static THREAD_FUNCTION thread_decoding_proc(void *p_data)
 
                         update_blockd_bmi(xd);
 
-                        /* Distance of Mb to the various image edges.
-                         * These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
+                        /* Distance of MB to the various image edges.
+                         * These are specified to 8th pel as they are always
+                         * compared to values that are in 1/8th pel units.
                          */
                         xd->mb_to_left_edge = -((mb_col * 16) << 3);
                         xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
 
+#if CONFIG_ERROR_CONCEALMENT
+                        if (pbi->ec_enabled &&
+                            (xd->mode_info_context->mbmi.ref_frame ==
+                                                                 INTRA_FRAME) &&
+                            vp8dx_bool_error(xd->current_bc))
+                        {
+                            /* We have an intra block with corrupt coefficients,
+                             * better to conceal with an inter block.
+                             * Interpolate MVs from neighboring MBs
+                             *
+                             * Note that for the first mb with corrupt residual
+                             * in a frame, we might not discover that before
+                             * decoding the residual. That happens after this
+                             * check, and therefore no inter concealment will be
+                             * done.
+                             */
+                            vp8_interpolate_motion(xd,
+                                                   mb_row, mb_col,
+                                                   pc->mb_rows, pc->mb_cols,
+                                                   pc->mode_info_stride);
+                        }
+#endif
+
+
                         xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                         xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                         xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
@@ -772,12 +814,35 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd)
 
                 update_blockd_bmi(xd);
 
-                /* Distance of Mb to the various image edges.
-                 * These are specified to 8th pel as they are always compared to values that are in 1/8th pel units
+                /* Distance of MB to the various image edges.
+                 * These are specified to 8th pel as they are always compared to
+                 * values that are in 1/8th pel units.
                  */
                 xd->mb_to_left_edge = -((mb_col * 16) << 3);
                 xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
 
+#if CONFIG_ERROR_CONCEALMENT
+                if (pbi->ec_enabled &&
+                    (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
+                    vp8dx_bool_error(xd->current_bc))
+                {
+                    /* We have an intra block with corrupt coefficients, better
+                     * to conceal with an inter block. Interpolate MVs from
+                     * neighboring MBs
+                     *
+                     * Note that for the first mb with corrupt residual in a
+                     * frame, we might not discover that before decoding the
+                     * residual. That happens after this check, and therefore no
+                     * inter concealment will be done.
+                     */
+                    vp8_interpolate_motion(xd,
+                                           mb_row, mb_col,
+                                           pc->mb_rows, pc->mb_cols,
+                                           pc->mode_info_stride);
+                }
+#endif
+
+
                 xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                 xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                 xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
index e93d30d..134e848 100644 (file)
 #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"
 
 const int vp8cx_base_skip_false_prob[128] =
 {
@@ -47,7 +50,7 @@ unsigned __int64 Sectionbits[500];
 
 #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
 
@@ -374,6 +377,7 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
     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++)
@@ -570,6 +574,9 @@ static void pack_tokens_into_partitions_c(VP8_COMP *cpi, unsigned char *cx_data,
         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);
@@ -1123,9 +1130,201 @@ static void write_kfmodes(VP8_COMP *cpi)
         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;
@@ -1185,60 +1384,11 @@ int vp8_estimate_entropy_savings(VP8_COMP *cpi)
     }
 
 
-    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           [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);
-
+    if (cpi->oxcf.error_resilient_mode & VPX_ERROR_RESILIENT_PARTITIONS)
+        savings += independent_coef_context_savings(cpi);
+    else
+        savings += default_coef_context_savings(cpi);
 
-            }
-            while (++k < PREV_COEF_CONTEXTS);
-        }
-        while (++j < COEF_BANDS);
-    }
-    while (++i < BLOCK_TYPES);
 
     return savings;
 }
@@ -1251,7 +1401,6 @@ static void update_coef_probs(VP8_COMP *cpi)
 
     vp8_clear_system_state(); //__asm emms;
 
-
     do
     {
         int j = 0;
@@ -1259,41 +1408,73 @@ static void update_coef_probs(VP8_COMP *cpi)
         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.
                 /* 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
                 //    );
 
                 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);
 
@@ -1314,7 +1495,7 @@ static void update_coef_probs(VP8_COMP *cpi)
                     }
 
                 }
-                while (++t < vp8_coef_tokens - 1);
+                while (++t < ENTROPY_NODES);
 
                 /* Accum token counts for generation of default statistics */
 #ifdef ENTROPY_STATS
@@ -1324,7 +1505,7 @@ static void update_coef_probs(VP8_COMP *cpi)
                 {
                     context_counters [i][j][k][t] += cpi->coef_counts [i][j][k][t];
                 }
-                while (++t < vp8_coef_tokens);
+                while (++t < MAX_ENTROPY_TOKENS);
 
 #endif
 
@@ -1590,6 +1771,14 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
         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)
@@ -1655,6 +1844,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
     }
 
     *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc.pos;
+    cpi->partition_sz[0] = *size;
 
     if (pc->multi_token_partition != ONE_PARTITION)
     {
@@ -1680,6 +1870,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
         vp8_stop_encode(&cpi->bc2);
 
         *size += cpi->bc2.pos;
+        cpi->partition_sz[1] = cpi->bc2.pos;
     }
 }
 
@@ -1690,7 +1881,7 @@ void print_tree_update_probs()
     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++)
     {
@@ -1704,7 +1895,7 @@ void print_tree_update_probs()
             {
                 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];
 
index 7d44493..0d14b54 100644 (file)
@@ -117,7 +117,7 @@ typedef struct
     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;
 
index 7343dcc..0efb9f6 100644 (file)
@@ -338,7 +338,8 @@ void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x)
 {
 #if USE_ACT_INDEX
     x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
-    x->errorperbit = x->rdmult/x->rddiv;
+    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
+    x->errorperbit += (x->errorperbit==0);
 #else
     INT64 a;
     INT64 b;
@@ -349,8 +350,8 @@ void vp8_activity_masking(VP8_COMP *cpi, MACROBLOCK *x)
     b = (2*act) + cpi->activity_avg;
 
     x->rdmult = (unsigned int)(((INT64)x->rdmult*b + (a>>1))/a);
-    x->errorperbit = x->rdmult/x->rddiv;
-
+    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
+    x->errorperbit += (x->errorperbit==0);
 #endif
 
     // Activity based Zbin adjustment
index 2188f25..4fc6a8a 100644 (file)
@@ -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 int vp8_kf_boost_qadjustment[QINDEX_RANGE];
 
 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 @@ extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
 #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 @@ static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
     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)
 {
@@ -214,58 +357,33 @@ static int frame_max_bits(VP8_COMP *cpi)
     int max_bits;
 
     // For CBR we need to also consider buffer fullness.
+    // If we are running below the optimal level then we need to gradually tighten up on max_bits.
     if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
     {
-        max_bits = 2 * cpi->av_per_frame_bandwidth;
-        max_bits -= cpi->buffered_av_per_frame_bandwidth;
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
-    }
-    // VBR
-    else
-    {
-        // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
-        max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
-    }
+        double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
 
-    // Trap case where we are out of bits
-    if (max_bits < 0)
-        max_bits = 0;
-
-    return max_bits;
-}
+        // For CBR base this on the target average bits per frame plus the maximum sedction rate passed in by the user
+        max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
 
+        // If our buffer is below the optimum level
+        if (buffer_fullness_ratio < 1.0)
+        {
+            // The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4.
+            int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
 
-static int gf_group_max_bits(VP8_COMP *cpi)
-{
-    // Max allocation for a golden frame group
-    int max_bits;
+            max_bits = (int)(max_bits * buffer_fullness_ratio);
 
-    // For CBR we need to also consider buffer fullness.
-    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
-    {
-        max_bits = cpi->av_per_frame_bandwidth * cpi->baseline_gf_interval;
-        if (max_bits > cpi->oxcf.optimal_buffer_level)
-        {
-            max_bits -= cpi->oxcf.optimal_buffer_level;
-            max_bits += cpi->buffer_level;
+            if (max_bits < min_max_bits)
+                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
         }
-        else
-        {
-            max_bits -= (cpi->buffered_av_per_frame_bandwidth
-                         - cpi->av_per_frame_bandwidth)
-                        * cpi->baseline_gf_interval;
-        }
-
-        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
     }
+    // VBR
     else
     {
         // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
         max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
-        max_bits *=  cpi->baseline_gf_interval;
     }
 
-
     // Trap case where we are out of bits
     if (max_bits < 0)
         max_bits = 0;
@@ -273,122 +391,6 @@ static int gf_group_max_bits(VP8_COMP *cpi)
     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);
@@ -882,7 +884,11 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
 
         //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)
@@ -917,7 +923,6 @@ static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_
             * 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;
@@ -1261,7 +1266,6 @@ static double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_fra
     double motion_decay;
     double motion_pct = next_frame->pcnt_motion;
 
-
     // Initial basis is the % mbs inter coded
     prediction_decay_rate = next_frame->pcnt_inter;
 
@@ -1336,24 +1340,257 @@ static int detect_transition_to_still(
     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)
 {
     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;
     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;
@@ -1361,11 +1598,16 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
     double abs_mv_in_out_accumulator = 0.0;
     double mod_err_per_mb_accumulator = 0.0;
 
-    int max_group_bits;
+    int max_bits = frame_max_bits(cpi);     // Max for a single frame
 
     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;
 
@@ -1375,7 +1617,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 
     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
@@ -1397,12 +1639,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             ((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
@@ -1416,82 +1652,33 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         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));
-
-            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;
+        // Calculate a baseline boost number for this frame
+        r = calc_frame_boost( cpi, &next_frame, this_frame_mv_in_out );
 
-            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;
@@ -1499,7 +1686,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         }
 
         // 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)) ||
             (
@@ -1508,6 +1695,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
                 // 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) ||
@@ -1555,8 +1743,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             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)
     {
@@ -1575,39 +1761,70 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         }
     }
 
+    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
@@ -1617,13 +1834,17 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             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;
@@ -1633,13 +1854,22 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
 
             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;
+
+            // 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.
+            // 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
@@ -1648,7 +1878,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             // 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)
             {
@@ -1697,26 +1928,40 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         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)
-    max_group_bits = gf_group_max_bits(cpi);
-    if (cpi->twopass.gf_group_bits > max_group_bits)
-        cpi->twopass.gf_group_bits = max_group_bits;
+    // 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;
 
     // Reset the file position
     reset_fpf_position(cpi, start_pos);
@@ -1727,7 +1972,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
     // 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;
@@ -1735,8 +1979,11 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         // 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
@@ -1745,8 +1992,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             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
@@ -1760,8 +2007,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             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
@@ -1771,8 +2018,11 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             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
@@ -1811,6 +2061,13 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
             }
         }
 
+        // Apply an additional limit for CBR
+        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
+        {
+            if (cpi->twopass.gf_bits > (cpi->buffer_level >> 1))
+                cpi->twopass.gf_bits = cpi->buffer_level >> 1;
+        }
+
         // Dont allow a negative value for gf_bits
         if (gf_bits < 0)
             gf_bits = 0;
@@ -1847,17 +2104,26 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
         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
index 4169488..6f314a3 100644 (file)
@@ -286,8 +286,8 @@ int vp8_find_best_sub_pixel_step_iteratively(MACROBLOCK *x, BLOCK *b, BLOCKD *d,
     bestmv->as_mv.row = br << 1;
     bestmv->as_mv.col = bc << 1;
 
-    if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > MAX_FULL_PEL_VAL) ||
-        (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > MAX_FULL_PEL_VAL))
+    if ((abs(bestmv->as_mv.col - ref_mv->as_mv.col) > (MAX_FULL_PEL_VAL<<3)) ||
+        (abs(bestmv->as_mv.row - ref_mv->as_mv.row) > (MAX_FULL_PEL_VAL<<3)))
         return INT_MAX;
 
     return besterr;
index 44ed055..416c4d5 100644 (file)
@@ -22,7 +22,7 @@ extern void accum_mv_refs(MB_PREDICTION_MODE, const int near_mv_ref_cts[4]);
 
 
 #define MAX_MVSEARCH_STEPS 8                                    // The maximum number of steps in a step search given the largest allowed initial step
-#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS+3)) - 8)    // Max full pel mv specified in 1/8 pel units
+#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1)      // Max full pel mv specified in 1 pel units
 #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1))            // Maximum size of the first step in full pel units
 
 extern void print_mode_context(void);
index bebc941..80f7ae6 100644 (file)
@@ -1477,7 +1477,6 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
     cpi->rolling_actual_bits          = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_target_bits     = cpi->av_per_frame_bandwidth;
     cpi->long_rolling_actual_bits     = cpi->av_per_frame_bandwidth;
-    cpi->buffered_av_per_frame_bandwidth = cpi->av_per_frame_bandwidth;
 
     cpi->total_actual_bits            = 0;
     cpi->total_target_vs_actual       = 0;
@@ -1573,7 +1572,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
         break;
     }
 
-    if (cpi->pass == 0 && cpi->oxcf.end_usage != USAGE_STREAM_FROM_SERVER)
+    if (cpi->pass == 0)
         cpi->auto_worst_q = 1;
 
     cpi->oxcf.worst_allowed_q = q_trans[oxcf->worst_allowed_q];
@@ -2013,7 +2012,8 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
         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);
@@ -3454,8 +3454,7 @@ static void encode_frame_to_data_rate
     // For CBR if the buffer reaches its maximum level then we can no longer
     // save up bits for later frames so we might as well use them up
     // on the current frame.
-    if (cpi->pass == 2
-        && (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
+    if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) &&
         (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level) && cpi->buffered_mode)
     {
         int Adjustment = cpi->active_worst_quality / 4;       // Max adjustment is 1/4
@@ -3546,9 +3545,6 @@ static void encode_frame_to_data_rate
         }
         else
         {
-            if(cpi->pass != 2)
-                Q = cpi->avg_frame_qindex;
-
             cpi->active_best_quality = inter_minq[Q];
 
             // For the constant/constrained quality mode we dont want
@@ -3850,16 +3846,15 @@ static void encode_frame_to_data_rate
             (cpi->active_worst_quality < cpi->worst_quality)      &&
             (cpi->projected_frame_size > frame_over_shoot_limit))
         {
-            /* step down active_worst_quality such that the corresponding
-             * active_best_quality will be equal to the current
-             * active_worst_quality + 1
-             */
-            int i;
+            int over_size_percent = ((cpi->projected_frame_size - frame_over_shoot_limit) * 100) / frame_over_shoot_limit;
 
-            for(i=cpi->active_worst_quality; i<cpi->worst_quality; i++)
-                if(inter_minq[i] >= cpi->active_worst_quality + 1)
-                    break;
-            cpi->active_worst_quality = i;
+            // If so is there any scope for relaxing it
+            while ((cpi->active_worst_quality < cpi->worst_quality) && (over_size_percent > 0))
+            {
+                cpi->active_worst_quality++;
+                top_index = cpi->active_worst_quality;
+                over_size_percent = (int)(over_size_percent * 0.96);        // Assume 1 qstep = about 4% on frame size.
+            }
 
             // If we have updated the active max Q do not call vp8_update_rate_correction_factors() this loop.
             active_worst_qchanged = TRUE;
@@ -4138,7 +4133,7 @@ static void encode_frame_to_data_rate
 
     update_reference_frames(cm);
 
-    if (cpi->oxcf.error_resilient_mode == 1)
+    if (cpi->oxcf.error_resilient_mode)
     {
         cm->refresh_entropy_probs = 0;
     }
@@ -4247,9 +4242,10 @@ static void encode_frame_to_data_rate
 
     // Update the buffer level variable.
     // Non-viewable frames are a special case and are treated as pure overhead.
-    if ( cm->show_frame )
-        cpi->bits_off_target += cpi->av_per_frame_bandwidth;
-    cpi->bits_off_target -= cpi->projected_frame_size;
+    if ( !cm->show_frame )
+        cpi->bits_off_target -= cpi->projected_frame_size;
+    else
+        cpi->bits_off_target += cpi->av_per_frame_bandwidth - cpi->projected_frame_size;
 
     // Rolling monitors of whether we are over or underspending used to help regulate min and Max Q in two pass.
     cpi->rolling_target_bits = ((cpi->rolling_target_bits * 3) + cpi->this_frame_target + 2) / 4;
@@ -4263,33 +4259,7 @@ static void encode_frame_to_data_rate
     // Debug stats
     cpi->total_target_vs_actual += (cpi->this_frame_target - cpi->projected_frame_size);
 
-    // Update the buffered average bitrate
-    {
-        long long numerator;
-
-        numerator = cpi->oxcf.maximum_buffer_size
-                    - cpi->buffered_av_per_frame_bandwidth
-                    + cpi->projected_frame_size;
-        numerator *= cpi->buffered_av_per_frame_bandwidth;
-        cpi->buffered_av_per_frame_bandwidth = numerator
-                                               / cpi->oxcf.maximum_buffer_size;
-    }
-
-    {
-        long long tmp = (long long)cpi->buffered_av_per_frame_bandwidth
-                        * cpi->oxcf.maximum_buffer_size
-                        / cpi->av_per_frame_bandwidth;
-        cpi->buffer_level = cpi->oxcf.maximum_buffer_size
-                            - tmp
-                            + cpi->oxcf.optimal_buffer_level;
-    }
-
-    // Accumulate overshoot error.
-    cpi->accumulated_overshoot +=
-        (cpi->projected_frame_size > cpi->av_per_frame_bandwidth)
-        ? cpi->projected_frame_size - cpi->av_per_frame_bandwidth
-        : 0;
-
+    cpi->buffer_level = cpi->bits_off_target;
 
     // Update bits left to the kf and gf groups to account for overshoot or undershoot on these frames
     if (cm->frame_type == KEY_FRAME)
index c460b9d..ce401fd 100644 (file)
@@ -351,10 +351,6 @@ typedef struct VP8_COMP
     int per_frame_bandwidth;          // Current section per frame bandwidth target
     int av_per_frame_bandwidth;        // Average frame size target for clip
     int min_frame_bandwidth;          // Minimum allocation that should be used for any frame
-    int buffered_av_per_frame_bandwidth; // Average bitrate over the last buffer
-    int buffered_av_per_frame_bandwidth_rem; // Average bitrate remainder
-    int accumulated_overshoot;           // Accumulated # of bits spent > target
-
     int inter_frame_target;
     double output_frame_rate;
     long long last_time_stamp_seen;
@@ -405,11 +401,11 @@ typedef struct VP8_COMP
 
     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 +501,7 @@ typedef struct VP8_COMP
 #endif
 
     TOKENLIST *tplist;
+    unsigned int partition_sz[MAX_PARTITIONS];
     // end of multithread data
 
 
@@ -528,7 +525,7 @@ typedef struct VP8_COMP
         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;
@@ -608,6 +605,8 @@ typedef struct VP8_COMP
     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;
     int *lf_ref_frame_sign_bias;
index 99d69f6..fac068f 100644 (file)
@@ -588,10 +588,10 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
 
             /* adjust mvp to make sure it is within MV range */
             vp8_clamp_mv(&mvp,
-                         best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL);
+                         best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
         }
 
         switch (this_mode)
@@ -681,10 +681,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
                 mvp.as_int = best_ref_mv.as_int;
             }
 
-            col_min = (best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL) >>3;
-            col_max = (best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL) >>3;
-            row_min = (best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL) >>3;
-            row_max = (best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL) >>3;
+            col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL)
+                                                 :((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL);
+            col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL)
+                                                 :((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL);
+            row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
+                                                 :((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
+            row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
+                                                 :((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
 
             // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
             if (x->mv_col_min < col_min )
index 4f9d412..3d47412 100644 (file)
@@ -141,13 +141,11 @@ static int get_max_filter_level(VP8_COMP *cpi, int base_qindex)
     // jbb chg: 20100118 - not so any more with this overquant stuff allow high values
     // with lots of intra coming in.
     int max_filter_level = MAX_LOOP_FILTER ;//* 3 / 4;
+    (void)base_qindex;
 
     if (cpi->twopass.section_intra_rating > 8)
         max_filter_level = MAX_LOOP_FILTER * 3 / 4;
 
-    (void) cpi;
-    (void) base_qindex;
-
     return max_filter_level;
 }
 
@@ -157,8 +155,8 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
 
     int best_err = 0;
     int filt_err = 0;
-    int min_filter_level = 0;
-    int max_filter_level = MAX_LOOP_FILTER * 3 / 4;   // PGW August 2006: Highest filter values almost always a bad idea
+    int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
+    int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
     int filt_val;
     int best_filt_val = cm->filter_level;
 
@@ -171,10 +169,6 @@ void vp8cx_pick_filter_level_fast(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
     else
         cm->sharpness_level = cpi->oxcf.Sharpness;
 
-    // Enforce a minimum filter level based upon Q
-    min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
-    max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
-
     // Start the search at the previous frame filter level unless it is now out of range.
     if (cm->filter_level < min_filter_level)
         cm->filter_level = min_filter_level;
@@ -294,8 +288,8 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
 
     int best_err = 0;
     int filt_err = 0;
-    int min_filter_level;
-    int max_filter_level;
+    int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
+    int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
 
     int filter_step;
     int filt_high = 0;
@@ -329,10 +323,6 @@ void vp8cx_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP8_COMP *cpi)
     else
         cm->sharpness_level = cpi->oxcf.Sharpness;
 
-    // Enforce a minimum filter level based upon Q
-    min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
-    max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
-
     // Start the search at the previous frame filter level unless it is now out of range.
     filt_mid = cm->filter_level;
 
index 73e1437..54c394d 100644 (file)
@@ -605,10 +605,10 @@ static void calc_gf_params(VP8_COMP *cpi)
 
 static void calc_pframe_target_size(VP8_COMP *cpi)
 {
-    int min_frame_target, max_frame_target;
+    int min_frame_target;
     int Adjustment;
 
-    min_frame_target = 1;
+    min_frame_target = 0;
 
     if (cpi->pass == 2)
     {
@@ -616,19 +616,10 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
 
         if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
             min_frame_target = cpi->av_per_frame_bandwidth >> 5;
-
-        max_frame_target = INT_MAX;
     }
-    else
-    {
-        if (min_frame_target < cpi->per_frame_bandwidth / 4)
-            min_frame_target = cpi->per_frame_bandwidth / 4;
+    else if (min_frame_target < cpi->per_frame_bandwidth / 4)
+        min_frame_target = cpi->per_frame_bandwidth / 4;
 
-        /* Don't allow the target to completely deplete the buffer. */
-        max_frame_target = cpi->buffer_level + cpi->av_per_frame_bandwidth;
-        if(max_frame_target < min_frame_target)
-            max_frame_target = min_frame_target;
-    }
 
     // Special alt reference frame case
     if (cpi->common.refresh_alt_ref_frame)
@@ -1121,32 +1112,6 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
 
         }
     }
-
-    if (cpi->pass==0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER){
-        /* determine the accumulated error to apply to this frame. Apply
-         * more of the error when we've been undershooting, less when
-         * we've been overshooting
-         */
-        long long adjust;
-        int bitrate_error;
-
-        bitrate_error = cpi->av_per_frame_bandwidth
-                        - cpi->buffered_av_per_frame_bandwidth;
-
-        adjust = cpi->accumulated_overshoot;
-        adjust *= cpi->av_per_frame_bandwidth + bitrate_error;
-        adjust /= cpi->oxcf.maximum_buffer_size;
-        if (adjust > (cpi->this_frame_target - min_frame_target))
-            adjust = (cpi->this_frame_target - min_frame_target);
-        else if (adjust < 0)
-            adjust = 0;
-
-        cpi->this_frame_target -= adjust;
-        cpi->accumulated_overshoot -= adjust;
-    }
-
-    if(cpi->this_frame_target > max_frame_target)
-        cpi->this_frame_target = max_frame_target;
 }
 
 
index c6e3461..355542e 100644 (file)
@@ -134,8 +134,8 @@ const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] =
 };
 
 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;
@@ -238,7 +238,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
                 (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
     }
 
-    cpi->mb.errorperbit = (cpi->RDMULT / 100);
+    cpi->mb.errorperbit = (cpi->RDMULT / 110);
     cpi->mb.errorperbit += (cpi->mb.errorperbit==0);
 
     vp8_set_speed_features(cpi);
@@ -1330,10 +1330,14 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
 
         if (bsi.segment_rd < best_rd)
         {
-            int col_min = (best_ref_mv->as_mv.col - MAX_FULL_PEL_VAL) >>3;
-            int col_max = (best_ref_mv->as_mv.col + MAX_FULL_PEL_VAL) >>3;
-            int row_min = (best_ref_mv->as_mv.row - MAX_FULL_PEL_VAL) >>3;
-            int row_max = (best_ref_mv->as_mv.row + MAX_FULL_PEL_VAL) >>3;
+            int col_min = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) - MAX_FULL_PEL_VAL)
+                                                      :((best_ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL);
+            int col_max = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) + MAX_FULL_PEL_VAL)
+                                                      :((best_ref_mv->as_mv.col>>3) + MAX_FULL_PEL_VAL);
+            int row_min = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) - MAX_FULL_PEL_VAL)
+                                                      :((best_ref_mv->as_mv.row>>3) - MAX_FULL_PEL_VAL);
+            int row_max = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) + MAX_FULL_PEL_VAL)
+                                                      :((best_ref_mv->as_mv.row>>3) + MAX_FULL_PEL_VAL);
 
             int tmp_col_min = x->mv_col_min;
             int tmp_col_max = x->mv_col_max;
@@ -1878,10 +1882,10 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
 
             /* adjust mvp to make sure it is within MV range */
             vp8_clamp_mv(&mvp,
-                         best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL,
-                         best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL);
+                         best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
+                         best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
         }
 
         // Check to see if the testing frequency for this mode is at its max
@@ -2013,10 +2017,14 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
 
             int sadpb = x->sadperbit16;
 
-            int col_min = (best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL) >>3;
-            int col_max = (best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL) >>3;
-            int row_min = (best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL) >>3;
-            int row_max = (best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL) >>3;
+            int col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL)
+                                                     :((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL);
+            int col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL)
+                                                     :((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL);
+            int row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
+                                                     :((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
+            int row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
+                                                     :((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
 
             int tmp_col_min = x->mv_col_min;
             int tmp_col_max = x->mv_col_max;
index 329abac..e14e6fc 100644 (file)
@@ -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 @@ void print_context_counters()
 
     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 @@ void print_context_counters()
                     fprintf(f, "%s %d", Comma(t), y);
 
                 }
-                while (++t < vp8_coef_tokens);
+                while (++t < MAX_ENTROPY_TOKENS);
 
                 fprintf(f, "}");
             }
index d87c1a3..04a8879 100644 (file)
@@ -37,7 +37,7 @@ int rd_cost_mby(MACROBLOCKD *);
 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;
index 5f5ba3a..f55c899 100644 (file)
@@ -19,6 +19,7 @@ VP8_COMMON_SRCS-yes += common/blockd.c
 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
@@ -99,15 +100,15 @@ VP8_COMMON_SRCS-$(HAVE_MMX) += common/x86/postproc_mmx.asm
 VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/postproc_sse2.asm
 endif
 
+# common (c)
 VP8_COMMON_SRCS-$(ARCH_ARM)  += common/asm_com_offsets.c
 VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/arm_systemdependent.c
 
-# common (c)
-VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/bilinearfilter_arm.c
-VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/bilinearfilter_arm.h
-VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/filter_arm.c
-VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/loopfilter_arm.c
-VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/reconintra_arm.c
+VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/bilinearfilter_arm.c
+VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/bilinearfilter_arm.h
+VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/filter_arm.c
+VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/loopfilter_arm.c
+VP8_COMMON_SRCS-$(ARCH_ARM)  += common/arm/reconintra_arm.c
 
 # common (armv6)
 VP8_COMMON_SRCS-$(HAVE_ARMV6)  += common/arm/armv6/bilinearfilter_v6$(ASM)
index db60bfe..5e1278a 100644 (file)
@@ -731,6 +731,9 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
         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;
 
@@ -770,8 +773,6 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
                 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;
@@ -797,11 +798,35 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
                     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;
             }
         }
     }
@@ -1121,7 +1146,8 @@ CODEC_INTERFACE(vpx_codec_vp8_cx) =
 {
     "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; */
index e0f4c0a..58dc486 100644 (file)
@@ -368,6 +368,8 @@ static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t  *ctx,
             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);
 
@@ -588,8 +590,7 @@ static vpx_codec_err_t vp8_set_reference(vpx_codec_alg_priv_t *ctx,
 
         image2yuvconfig(&frame->img, &sd);
 
-        vp8dx_set_reference(ctx->pbi, frame->frame_type, &sd);
-        return VPX_CODEC_OK;
+        return vp8dx_set_reference(ctx->pbi, frame->frame_type, &sd);
     }
     else
         return VPX_CODEC_INVALID_PARAM;
@@ -610,8 +611,7 @@ static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx,
 
         image2yuvconfig(&frame->img, &sd);
 
-        vp8dx_get_reference(ctx->pbi, frame->frame_type, &sd);
-        return VPX_CODEC_OK;
+        return vp8dx_get_reference(ctx->pbi, frame->frame_type, &sd);
     }
     else
         return VPX_CODEC_INVALID_PARAM;
@@ -723,7 +723,8 @@ CODEC_INTERFACE(vpx_codec_vp8_dx) =
 {
     "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; */
index 165dada..599bf47 100644 (file)
 # encoder
 VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/arm_csystemdependent.c
 
-VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/quantize_arm.c
-VP8_CX_SRCS-$(HAVE_ARMV7)  += encoder/arm/picklpf_arm.c
-VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/dct_arm.c
-VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/variance_arm.c
-VP8_CX_SRCS-$(HAVE_ARMV6)  += encoder/arm/variance_arm.h
-VP8_CX_SRCS-$(HAVE_ARMV5TE) += encoder/arm/boolhuff_arm.c
-
-VP8_CX_SRCS_REMOVE-$(HAVE_ARMV5TE)  += encoder/boolhuff.c
+VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/quantize_arm.c
+VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/picklpf_arm.c
+VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/dct_arm.c
+VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/variance_arm.c
+VP8_CX_SRCS-$(ARCH_ARM)  += encoder/arm/variance_arm.h
 
 #File list for armv5te
 # encoder
+VP8_CX_SRCS-$(HAVE_ARMV5TE) += encoder/arm/boolhuff_arm.c
+VP8_CX_SRCS_REMOVE-$(HAVE_ARMV5TE)  += encoder/boolhuff.c
 VP8_CX_SRCS-$(HAVE_ARMV5TE)  += encoder/arm/armv5te/boolhuff_armv5te$(ASM)
 VP8_CX_SRCS-$(HAVE_ARMV5TE)  += encoder/arm/armv5te/vp8_packtokens_armv5$(ASM)
 VP8_CX_SRCS-$(HAVE_ARMV5TE)  += encoder/arm/armv5te/vp8_packtokens_mbrow_armv5$(ASM)
index 03084c5..583562b 100644 (file)
@@ -14,7 +14,7 @@
 VP8_DX_SRCS-$(ARCH_ARM)  += decoder/arm/arm_dsystemdependent.c
 VP8_CX_SRCS-$(ARCH_ARM)  += decoder/asm_dec_offsets.c
 
-VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/dequantize_arm.c
+VP8_DX_SRCS-$(ARCH_ARM)  += decoder/arm/dequantize_arm.c
 
 #File list for armv6
 VP8_DX_SRCS-$(HAVE_ARMV6)  += decoder/arm/armv6/dequant_dc_idct_v6$(ASM)
index 42aedee..6e877b0 100644 (file)
@@ -39,6 +39,9 @@ vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
     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
index dab7554..5e86835 100644 (file)
@@ -41,6 +41,9 @@ vpx_codec_err_t vpx_codec_enc_init_ver(vpx_codec_ctx_t      *ctx,
     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;
index 7ca5c6e..983cc4a 100644 (file)
--- 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 @@ VPX_CTRL_USE_TYPE(VP8_SET_DBG_DISPLAY_MV,      int)
 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
index 6fd161b..b6bd7fc 100644 (file)
@@ -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
  *
@@ -296,5 +296,5 @@ VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER,     int *)
 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
index 4a3aef7..1d9d531 100644 (file)
@@ -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 @@ VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED,    int *)
 /*! @} - end defgroup vp8_decoder */
 
 
-#include "vpx/vpx_codec_impl_bottom.h"
+#include "vpx_codec_impl_bottom.h"
 #endif
index abfce33..ca907c9 100644 (file)
@@ -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_CTRL_USE_TYPE_DEPRECATED(VP8E_SET_FRAMETYPE,          int)
  * #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
index e50fd76..0fc38c6 100644 (file)
@@ -55,6 +55,8 @@ extern "C" {
 #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 @@ extern "C" {
 #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 @@ extern "C" {
      * 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
index 6dbce0d..71153d5 100644 (file)
@@ -55,6 +55,13 @@ extern "C" {
      */
 #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
      *
@@ -64,6 +71,8 @@ extern "C" {
      *  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 @@ extern "C" {
                 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 @@ extern "C" {
                 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 @@ extern "C" {
         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
index 89cdef0..042f07b 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -23,6 +23,7 @@
 #include <stdarg.h>
 #include <string.h>
 #include <limits.h>
+#include <assert.h>
 #include "vpx/vpx_encoder.h"
 #if USE_POSIX_MMAP
 #include <sys/types.h>
@@ -909,12 +910,16 @@ static const arg_def_t framerate        = ARG_DEF(NULL, "fps", 1,
         "Stream frame rate (rate/scale)");
 static const arg_def_t use_ivf          = ARG_DEF(NULL, "ivf", 0,
         "Output IVF (default is WebM)");
+static const arg_def_t q_hist_n         = ARG_DEF(NULL, "q-hist", 1,
+        "Show quantizer histogram (n-buckets)");
+static const arg_def_t rate_hist_n         = ARG_DEF(NULL, "rate-hist", 1,
+        "Show rate histogram (n-buckets)");
 static const arg_def_t *main_args[] =
 {
     &debugmode,
     &outputfile, &codecarg, &passes, &pass_arg, &fpf_name, &limit, &deadline,
     &best_dl, &good_dl, &rt_dl,
-    &verbosearg, &psnrarg, &use_ivf,
+    &verbosearg, &psnrarg, &use_ivf, &q_hist_n, &rate_hist_n,
     NULL
 };
 
@@ -1107,6 +1112,291 @@ static void usage_exit()
     exit(EXIT_FAILURE);
 }
 
+
+#define HIST_BAR_MAX 40
+struct hist_bucket
+{
+    int low, high, count;
+};
+
+
+static int merge_hist_buckets(struct hist_bucket *bucket,
+                              int *buckets_,
+                              int max_buckets)
+{
+    int small_bucket = 0, merge_bucket = INT_MAX, big_bucket=0;
+    int buckets = *buckets_;
+    int i;
+
+    /* Find the extrema for this list of buckets */
+    big_bucket = small_bucket = 0;
+    for(i=0; i < buckets; i++)
+    {
+        if(bucket[i].count < bucket[small_bucket].count)
+            small_bucket = i;
+        if(bucket[i].count > bucket[big_bucket].count)
+            big_bucket = i;
+    }
+
+    /* If we have too many buckets, merge the smallest with an ajacent
+     * bucket.
+     */
+    while(buckets > max_buckets)
+    {
+        int last_bucket = buckets - 1;
+
+        // merge the small bucket with an adjacent one.
+        if(small_bucket == 0)
+            merge_bucket = 1;
+        else if(small_bucket == last_bucket)
+            merge_bucket = last_bucket - 1;
+        else if(bucket[small_bucket - 1].count < bucket[small_bucket + 1].count)
+            merge_bucket = small_bucket - 1;
+        else
+            merge_bucket = small_bucket + 1;
+
+        assert(abs(merge_bucket - small_bucket) <= 1);
+        assert(small_bucket < buckets);
+        assert(big_bucket < buckets);
+        assert(merge_bucket < buckets);
+
+        if(merge_bucket < small_bucket)
+        {
+            bucket[merge_bucket].high = bucket[small_bucket].high;
+            bucket[merge_bucket].count += bucket[small_bucket].count;
+        }
+        else
+        {
+            bucket[small_bucket].high = bucket[merge_bucket].high;
+            bucket[small_bucket].count += bucket[merge_bucket].count;
+            merge_bucket = small_bucket;
+        }
+
+        assert(bucket[merge_bucket].low != bucket[merge_bucket].high);
+
+        buckets--;
+
+        /* Remove the merge_bucket from the list, and find the new small
+         * and big buckets while we're at it
+         */
+        big_bucket = small_bucket = 0;
+        for(i=0; i < buckets; i++)
+        {
+            if(i > merge_bucket)
+                bucket[i] = bucket[i+1];
+
+            if(bucket[i].count < bucket[small_bucket].count)
+                small_bucket = i;
+            if(bucket[i].count > bucket[big_bucket].count)
+                big_bucket = i;
+        }
+
+    }
+
+    *buckets_ = buckets;
+    return bucket[big_bucket].count;
+}
+
+
+static void show_histogram(const struct hist_bucket *bucket,
+                           int                       buckets,
+                           int                       total,
+                           int                       scale)
+{
+    const char *pat1, *pat2;
+    int i;
+
+    switch((int)(log(bucket[buckets-1].high)/log(10))+1)
+    {
+        case 1:
+        case 2:
+            pat1 = "%4d %2s: ";
+            pat2 = "%4d-%2d: ";
+            break;
+        case 3:
+            pat1 = "%5d %3s: ";
+            pat2 = "%5d-%3d: ";
+            break;
+        case 4:
+            pat1 = "%6d %4s: ";
+            pat2 = "%6d-%4d: ";
+            break;
+        case 5:
+            pat1 = "%7d %5s: ";
+            pat2 = "%7d-%5d: ";
+            break;
+        case 6:
+            pat1 = "%8d %6s: ";
+            pat2 = "%8d-%6d: ";
+            break;
+        case 7:
+            pat1 = "%9d %7s: ";
+            pat2 = "%9d-%7d: ";
+            break;
+        default:
+            pat1 = "%12d %10s: ";
+            pat2 = "%12d-%10d: ";
+            break;
+    }
+
+    for(i=0; i<buckets; i++)
+    {
+        int len;
+        int j;
+        float pct;
+
+        pct = 100.0 * (float)bucket[i].count / (float)total;
+        len = HIST_BAR_MAX * bucket[i].count / scale;
+        if(len < 1)
+            len = 1;
+        assert(len <= HIST_BAR_MAX);
+
+        if(bucket[i].low == bucket[i].high)
+            fprintf(stderr, pat1, bucket[i].low, "");
+        else
+            fprintf(stderr, pat2, bucket[i].low, bucket[i].high);
+
+        for(j=0; j<HIST_BAR_MAX; j++)
+            fprintf(stderr, j<len?"=":" ");
+        fprintf(stderr, "\t%5d (%6.2f%%)\n",bucket[i].count,pct);
+    }
+}
+
+
+static void show_q_histogram(const int counts[64], int max_buckets)
+{
+    struct hist_bucket bucket[64];
+    int buckets = 0;
+    int total = 0;
+    int scale;
+    int i;
+
+
+    for(i=0; i<64; i++)
+    {
+        if(counts[i])
+        {
+            bucket[buckets].low = bucket[buckets].high = i;
+            bucket[buckets].count = counts[i];
+            buckets++;
+            total += counts[i];
+        }
+    }
+
+    fprintf(stderr, "\nQuantizer Selection:\n");
+    scale = merge_hist_buckets(bucket, &buckets, max_buckets);
+    show_histogram(bucket, buckets, total, scale);
+}
+
+
+#define RATE_BINS (100)
+struct rate_hist
+{
+    int64_t            *pts;
+    int                *sz;
+    int                 samples;
+    int                 frames;
+    struct hist_bucket  bucket[RATE_BINS];
+    int                 total;
+};
+
+
+static void init_rate_histogram(struct rate_hist          *hist,
+                                const vpx_codec_enc_cfg_t *cfg,
+                                const vpx_rational_t      *fps)
+{
+    int i;
+
+    /* 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++)
+    {
+        hist->bucket[i].low = INT_MAX;
+        hist->bucket[i].high = 0;
+        hist->bucket[i].count = 0;
+    }
+}
+
+
+static void destroy_rate_histogram(struct rate_hist *hist)
+{
+    free(hist->pts);
+    free(hist->sz);
+}
+
+
+static void update_rate_histogram(struct rate_hist          *hist,
+                                  const vpx_codec_enc_cfg_t *cfg,
+                                  const vpx_codec_cx_pkt_t  *pkt)
+{
+    int i, idx;
+    int64_t now, then, sum_sz = 0, avg_bitrate;
+
+    now = pkt->data.frame.pts * 1000
+          * (uint64_t)cfg->g_timebase.num / (uint64_t)cfg->g_timebase.den;
+
+    idx = hist->frames++ % hist->samples;
+    hist->pts[idx] = now;
+    hist->sz[idx] = pkt->data.frame.sz;
+
+    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 && hist->frames - i < hist->samples; i--)
+    {
+        int i_idx = (i-1) % hist->samples;
+
+        then = hist->pts[i_idx];
+        if(now - then > cfg->rc_buf_sz)
+            break;
+        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)
+        idx = 0;
+    if(idx > RATE_BINS-1)
+        idx = RATE_BINS-1;
+    if(hist->bucket[idx].low > avg_bitrate)
+        hist->bucket[idx].low = avg_bitrate;
+    if(hist->bucket[idx].high < avg_bitrate)
+        hist->bucket[idx].high = avg_bitrate;
+    hist->bucket[idx].count++;
+    hist->total++;
+}
+
+
+static void show_rate_histogram(struct rate_hist          *hist,
+                                const vpx_codec_enc_cfg_t *cfg,
+                                int                        max_buckets)
+{
+    int i, scale;
+    int buckets = 0;
+
+    for(i = 0; i < RATE_BINS; i++)
+    {
+        if(hist->bucket[i].low == INT_MAX)
+            continue;
+        hist->bucket[buckets++] = hist->bucket[i];
+    }
+
+    fprintf(stderr, "\nRate (over %dms window):\n", cfg->rc_buf_sz);
+    scale = merge_hist_buckets(hist->bucket, &buckets, max_buckets);
+    show_histogram(hist->bucket, buckets, hist->total, scale);
+}
+
 #define ARG_CTRL_CNT_MAX 10
 
 int main(int argc, const char **argv_)
@@ -1145,6 +1435,10 @@ int main(int argc, const char **argv_)
     double                   psnr_totals[4] = {0, 0, 0, 0};
     int                      psnr_count = 0;
     stereo_format_t          stereo_fmt = STEREO_FORMAT_MONO;
+    int                      counts[64]={0};
+    int                      show_q_hist_buckets=0;
+    int                      show_rate_hist_buckets=0;
+    struct rate_hist         rate_hist={0};
 
     exec_name = argv_[0];
     ebml.last_pts_ms = -1;
@@ -1228,6 +1522,10 @@ int main(int argc, const char **argv_)
             out_fn = arg.val;
         else if (arg_match(&arg, &debugmode, argi))
             ebml.debug = 1;
+        else if (arg_match(&arg, &q_hist_n, argi))
+            show_q_hist_buckets = arg_parse_uint(&arg);
+        else if (arg_match(&arg, &rate_hist_n, argi))
+            show_rate_hist_buckets = arg_parse_uint(&arg);
         else
             argj++;
     }
@@ -1537,6 +1835,8 @@ int main(int argc, const char **argv_)
             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")
@@ -1648,6 +1948,16 @@ int main(int argc, const char **argv_)
             vpx_usec_timer_mark(&timer);
             cx_time += vpx_usec_timer_elapsed(&timer);
             ctx_exit_on_error(&encoder, "Failed to encode frame");
+
+            if(cfg.g_pass != VPX_RC_FIRST_PASS)
+            {
+                int q;
+
+                vpx_codec_control(&encoder, VP8E_GET_LAST_QUANTIZER_64, &q);
+                ctx_exit_on_error(&encoder, "Failed to read quantizer");
+                counts[q]++;
+            }
+
             got_data = 0;
 
             while ((pkt = vpx_codec_get_cx_data(&encoder, &iter)))
@@ -1661,6 +1971,7 @@ int main(int argc, const char **argv_)
                     fprintf(stderr, " %6luF",
                             (unsigned long)pkt->data.frame.sz);
 
+                    update_rate_histogram(&rate_hist, &cfg, pkt);
                     if(write_webm)
                     {
                         /* Update the hash */
@@ -1739,10 +2050,14 @@ int main(int argc, const char **argv_)
         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
         {
@@ -1758,6 +2073,13 @@ int main(int argc, const char **argv_)
             break;
     }
 
+    if (show_q_hist_buckets)
+        show_q_histogram(counts, show_q_hist_buckets);
+
+    if (show_rate_hist_buckets)
+        show_rate_histogram(&rate_hist, &cfg, show_rate_hist_buckets);
+    destroy_rate_histogram(&rate_hist);
+
     vpx_img_free(&raw);
     free(argv);
     return EXIT_SUCCESS;