diff options
33 files changed, 1038 insertions, 424 deletions
diff --git a/build/make/ads2gas.pl b/build/make/ads2gas.pl index efdfce7a1..be4658253 100755 --- a/build/make/ads2gas.pl +++ b/build/make/ads2gas.pl @@ -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 diff --git a/build/make/ads2gas_apple.pl b/build/make/ads2gas_apple.pl index 1b3039374..78f4a97f5 100755 --- a/build/make/ads2gas_apple.pl +++ b/build/make/ads2gas_apple.pl @@ -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 diff --git a/vp8/common/arm/armv6/bilinearfilter_v6.asm b/vp8/common/arm/armv6/bilinearfilter_v6.asm index a86ed5d0a..9704b4210 100644 --- a/vp8/common/arm/armv6/bilinearfilter_v6.asm +++ b/vp8/common/arm/armv6/bilinearfilter_v6.asm @@ -30,11 +30,11 @@ 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 diff --git a/vp8/common/arm/armv6/copymem16x16_v6.asm b/vp8/common/arm/armv6/copymem16x16_v6.asm index fca91a0db..abf048c2f 100644 --- a/vp8/common/arm/armv6/copymem16x16_v6.asm +++ b/vp8/common/arm/armv6/copymem16x16_v6.asm @@ -22,9 +22,7 @@ ;push {r4-r7} ;preload - pld [r0] - pld [r0, r1] - pld [r0, r1, lsl #1] + pld [r0, #31] ; preload for next 16x16 block ands r4, r0, #15 beq copy_mem16x16_fast @@ -90,6 +88,8 @@ 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} diff --git a/vp8/common/arm/armv6/filter_v6.asm b/vp8/common/arm/armv6/filter_v6.asm index 03b5bccd7..1ba91ddd6 100644 --- a/vp8/common/arm/armv6/filter_v6.asm +++ b/vp8/common/arm/armv6/filter_v6.asm @@ -10,6 +10,8 @@ EXPORT |vp8_filter_block2d_first_pass_armv6| + EXPORT |vp8_filter_block2d_first_pass_16x16_armv6| + EXPORT |vp8_filter_block2d_first_pass_8x8_armv6| EXPORT |vp8_filter_block2d_second_pass_armv6| EXPORT |vp8_filter4_block2d_second_pass_armv6| EXPORT |vp8_filter_block2d_first_pass_only_armv6| @@ -40,11 +42,6 @@ add r12, r3, #16 ; square off the output sub sp, sp, #4 - ;;IF ARCHITECTURE=6 - ;pld [r0, #-2] - ;;pld [r0, #30] - ;;ENDIF - ldr r4, [r11] ; load up packed filter coefficients ldr r5, [r11, #4] ldr r6, [r11, #8] @@ -101,15 +98,10 @@ bne width_loop_1st_6 - ;;add r9, r2, #30 ; attempt to load 2 adjacent cache lines - ;;IF ARCHITECTURE=6 - ;pld [r0, r2] - ;;pld [r0, r9] - ;;ENDIF - ldr r1, [sp] ; load and update dst address subs r7, r7, #0x10000 add r0, r0, r2 ; move to next input line + add r1, r1, #2 ; move over to next column str r1, [sp] @@ -120,6 +112,192 @@ ENDP +; -------------------------- +; 16x16 version +; ----------------------------- +|vp8_filter_block2d_first_pass_16x16_armv6| PROC + stmdb sp!, {r4 - r11, lr} + + ldr r11, [sp, #40] ; vp8_filter address + ldr r7, [sp, #36] ; output height + + add r4, r2, #18 ; preload next low + pld [r0, r4] + + sub r2, r2, r3 ; inside loop increments input array, + ; so the height loop only needs to add + ; r2 - width to the input pointer + + mov r3, r3, lsl #1 ; multiply width by 2 because using shorts + add r12, r3, #16 ; square off the output + sub sp, sp, #4 + + ldr r4, [r11] ; load up packed filter coefficients + ldr r5, [r11, #4] + ldr r6, [r11, #8] + + str r1, [sp] ; push destination to stack + mov r7, r7, lsl #16 ; height is top part of counter + +; six tap filter +|height_loop_1st_16_6| + ldrb r8, [r0, #-2] ; load source data + ldrb r9, [r0, #-1] + ldrb r10, [r0], #2 + orr r7, r7, r3, lsr #2 ; construct loop counter + +|width_loop_1st_16_6| + ldrb r11, [r0, #-1] + + pkhbt lr, r8, r9, lsl #16 ; r9 | r8 + pkhbt r8, r9, r10, lsl #16 ; r10 | r9 + + ldrb r9, [r0] + + smuad lr, lr, r4 ; apply the filter + pkhbt r10, r10, r11, lsl #16 ; r11 | r10 + smuad r8, r8, r4 + pkhbt r11, r11, r9, lsl #16 ; r9 | r11 + + smlad lr, r10, r5, lr + ldrb r10, [r0, #1] + smlad r8, r11, r5, r8 + ldrb r11, [r0, #2] + + sub r7, r7, #1 + + pkhbt r9, r9, r10, lsl #16 ; r10 | r9 + pkhbt r10, r10, r11, lsl #16 ; r11 | r10 + + smlad lr, r9, r6, lr + smlad r11, r10, r6, r8 + + ands r10, r7, #0xff ; test loop counter + + add lr, lr, #0x40 ; round_shift_and_clamp + ldrneb r8, [r0, #-2] ; load data for next loop + usat lr, #8, lr, asr #7 + add r11, r11, #0x40 + ldrneb r9, [r0, #-1] + usat r11, #8, r11, asr #7 + + strh lr, [r1], r12 ; result is transposed and stored, which + ; will make second pass filtering easier. + ldrneb r10, [r0], #2 + strh r11, [r1], r12 + + bne width_loop_1st_16_6 + + ldr r1, [sp] ; load and update dst address + subs r7, r7, #0x10000 + add r0, r0, r2 ; move to next input line + + add r11, r2, #34 ; adding back block width(=16) + pld [r0, r11] ; preload next low + + add r1, r1, #2 ; move over to next column + str r1, [sp] + + bne height_loop_1st_16_6 + + add sp, sp, #4 + ldmia sp!, {r4 - r11, pc} + + ENDP + +; -------------------------- +; 8x8 version +; ----------------------------- +|vp8_filter_block2d_first_pass_8x8_armv6| PROC + stmdb sp!, {r4 - r11, lr} + + ldr r11, [sp, #40] ; vp8_filter address + ldr r7, [sp, #36] ; output height + + add r4, r2, #10 ; preload next low + pld [r0, r4] + + sub r2, r2, r3 ; inside loop increments input array, + ; so the height loop only needs to add + ; r2 - width to the input pointer + + mov r3, r3, lsl #1 ; multiply width by 2 because using shorts + add r12, r3, #16 ; square off the output + sub sp, sp, #4 + + ldr r4, [r11] ; load up packed filter coefficients + ldr r5, [r11, #4] + ldr r6, [r11, #8] + + str r1, [sp] ; push destination to stack + mov r7, r7, lsl #16 ; height is top part of counter + +; six tap filter +|height_loop_1st_8_6| + ldrb r8, [r0, #-2] ; load source data + ldrb r9, [r0, #-1] + ldrb r10, [r0], #2 + orr r7, r7, r3, lsr #2 ; construct loop counter + +|width_loop_1st_8_6| + ldrb r11, [r0, #-1] + + pkhbt lr, r8, r9, lsl #16 ; r9 | r8 + pkhbt r8, r9, r10, lsl #16 ; r10 | r9 + + ldrb r9, [r0] + + smuad lr, lr, r4 ; apply the filter + pkhbt r10, r10, r11, lsl #16 ; r11 | r10 + smuad r8, r8, r4 + pkhbt r11, r11, r9, lsl #16 ; r9 | r11 + + smlad lr, r10, r5, lr + ldrb r10, [r0, #1] + smlad r8, r11, r5, r8 + ldrb r11, [r0, #2] + + sub r7, r7, #1 + + pkhbt r9, r9, r10, lsl #16 ; r10 | r9 + pkhbt r10, r10, r11, lsl #16 ; r11 | r10 + + smlad lr, r9, r6, lr + smlad r11, r10, r6, r8 + + ands r10, r7, #0xff ; test loop counter + + add lr, lr, #0x40 ; round_shift_and_clamp + ldrneb r8, [r0, #-2] ; load data for next loop + usat lr, #8, lr, asr #7 + add r11, r11, #0x40 + ldrneb r9, [r0, #-1] + usat r11, #8, r11, asr #7 + + strh lr, [r1], r12 ; result is transposed and stored, which + ; will make second pass filtering easier. + ldrneb r10, [r0], #2 + strh r11, [r1], r12 + + bne width_loop_1st_8_6 + + ldr r1, [sp] ; load and update dst address + subs r7, r7, #0x10000 + add r0, r0, r2 ; move to next input line + + add r11, r2, #18 ; adding back block width(=8) + pld [r0, r11] ; preload next low + + add r1, r1, #2 ; move over to next column + str r1, [sp] + + bne height_loop_1st_8_6 + + add sp, sp, #4 + ldmia sp!, {r4 - r11, pc} + + ENDP + ;--------------------------------- ; r0 short *src_ptr, ; r1 unsigned char *output_ptr, @@ -262,6 +440,10 @@ |vp8_filter_block2d_first_pass_only_armv6| PROC stmdb sp!, {r4 - r11, lr} + add r7, r2, r3 ; preload next low + add r7, r7, #2 + pld [r0, r7] + ldr r4, [sp, #36] ; output pitch ldr r11, [sp, #40] ; HFilter address sub sp, sp, #8 @@ -330,16 +512,15 @@ bne width_loop_1st_only_6 - ;;add r9, r2, #30 ; attempt to load 2 adjacent cache lines - ;;IF ARCHITECTURE=6 - ;pld [r0, r2] - ;;pld [r0, r9] - ;;ENDIF - ldr lr, [sp] ; load back output pitch ldr r12, [sp, #4] ; load back output pitch subs r7, r7, #1 add r0, r0, r12 ; updata src for next loop + + add r11, r12, r3 ; preload next low + add r11, r11, #2 + pld [r0, r11] + add r1, r1, lr ; update dst for next loop bne height_loop_1st_only_6 diff --git a/vp8/common/arm/armv6/loopfilter_v6.asm b/vp8/common/arm/armv6/loopfilter_v6.asm index b6417dee6..c7441b055 100644 --- a/vp8/common/arm/armv6/loopfilter_v6.asm +++ b/vp8/common/arm/armv6/loopfilter_v6.asm @@ -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 diff --git a/vp8/common/arm/armv6/simpleloopfilter_v6.asm b/vp8/common/arm/armv6/simpleloopfilter_v6.asm index 013712036..40a71f49d 100644 --- a/vp8/common/arm/armv6/simpleloopfilter_v6.asm +++ b/vp8/common/arm/armv6/simpleloopfilter_v6.asm @@ -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 diff --git a/vp8/common/arm/armv6/sixtappredict8x4_v6.asm b/vp8/common/arm/armv6/sixtappredict8x4_v6.asm index c8399d2c2..e81aef53d 100644 --- a/vp8/common/arm/armv6/sixtappredict8x4_v6.asm +++ b/vp8/common/arm/armv6/sixtappredict8x4_v6.asm @@ -35,6 +35,9 @@ adr r12, filter8_coeff sub r0, r0, r1, lsl #1 + add r3, r1, #10 ; preload next low + pld [r0, r3] + add r2, r12, r2, lsl #4 ;calculate filter location add r0, r0, #3 ;adjust src only for loading convinience @@ -110,6 +113,9 @@ add r0, r0, r1 ; move to next input line + add r11, r1, #18 ; preload next low. adding back block width(=8), which is subtracted earlier + pld [r0, r11] + bne first_pass_hloop_v6 ;second pass filter diff --git a/vp8/common/arm/filter_arm.c b/vp8/common/arm/filter_arm.c index fe3c5a52e..6582fb29a 100644 --- a/vp8/common/arm/filter_arm.c +++ b/vp8/common/arm/filter_arm.c @@ -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); } } diff --git a/vp8/common/defaultcoefcounts.c b/vp8/common/defaultcoefcounts.c new file mode 100644 index 000000000..ebb78164c --- /dev/null +++ b/vp8/common/defaultcoefcounts.c @@ -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] + [vp8_coef_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,}, + }, + }, +}; diff --git a/vp8/common/defaultcoefcounts.h b/vp8/common/defaultcoefcounts.h index ca58d565a..ebe8d7a2a 100644 --- a/vp8/common/defaultcoefcounts.h +++ b/vp8/common/defaultcoefcounts.h @@ -8,214 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ +#ifndef __DEFAULTCOEFCOUNTS_H +#define __DEFAULTCOEFCOUNTS_H -/* Generated file, included by entropy.c */ +#include "entropy.h" -static const unsigned int default_coef_counts [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] = -{ +extern const unsigned int vp8_default_coef_counts[BLOCK_TYPES] + [COEF_BANDS] + [PREV_COEF_CONTEXTS] + [vp8_coef_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 diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c index a1fe4f4ab..b89ca92eb 100644 --- a/vp8/common/entropy.c +++ b/vp8/common/entropy.c @@ -148,7 +148,9 @@ void vp8_default_coef_probs(VP8_COMMON *pc) unsigned int branch_ct [vp8_coef_tokens-1] [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], + pc->fc.coef_probs[h][i][k], + branch_ct, + vp8_default_coef_counts[h][i][k], 256, 1); } diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index a05951933..545798ac7 100644 --- a/vp8/common/onyx.h +++ b/vp8/common/onyx.h @@ -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 ; diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 862307ebb..d366b9b1b 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -35,6 +35,8 @@ 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]; diff --git a/vp8/common/onyxd.h b/vp8/common/onyxd.h index cf16a26da..8a4703a8b 100644 --- a/vp8/common/onyxd.h +++ b/vp8/common/onyxd.h @@ -33,6 +33,7 @@ extern "C" int postprocess; int max_threads; int error_concealment; + int input_partition; } VP8D_CONFIG; typedef enum { diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 00e001733..648fdb288 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -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 @@ -252,41 +250,10 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, #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); @@ -307,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, @@ -463,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) @@ -619,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; @@ -841,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. */ @@ -930,10 +974,8 @@ 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++) @@ -1021,7 +1063,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) } } - stop_token_decoder(pbi); /* Collect information about decoder corruption. */ diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index 9de5ce2c4..5f81ee638 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -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; } @@ -312,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; - - /* 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; + pbi->common.error.setjmp = 0; - if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) - cm->fb_idx_ref_cnt[cm->new_fb_idx]--; - return -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; - 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); @@ -473,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 { diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index ea6de3dda..be6ffe6be 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -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; diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index e93d30d1a..ac2981263 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -17,9 +17,12 @@ #include "vp8/common/systemdependent.h" #include <assert.h> #include <stdio.h> +#include <limits.h> #include "vp8/common/pragmas.h" +#include "vpx/vpx_encoder.h" #include "vpx_mem/vpx_mem.h" #include "bitstream.h" +#include "vp8/common/defaultcoefcounts.h" const int vp8cx_base_skip_false_prob[128] = { @@ -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][vp8_coef_tokens-1]) +{ + /* 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 < MAX_ENTROPY_TOKENS - 1; 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][vp8_coef_tokens], + unsigned int* out) +{ + int i, j; + for (i=0; i < vp8_coef_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[vp8_coef_tokens] = {0}; + int prev_coef_savings[vp8_coef_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 [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], + 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 < vp8_coef_tokens - 1); + } + 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 < vp8_coef_tokens - 1); + } + 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 [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 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 < vp8_coef_tokens - 1); + } + 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,61 +1384,12 @@ 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,7 +1408,27 @@ static void update_coef_probs(VP8_COMP *cpi) do { int k = 0; - + int prev_coef_savings[vp8_coef_tokens - 1] = {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 < vp8_coef_tokens - 1; ++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. @@ -1279,21 +1448,33 @@ static void update_coef_probs(VP8_COMP *cpi) 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); @@ -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; } } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 0296d9290..a6d7a4304 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -4132,7 +4132,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; } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 3ca61a7cd..d94436bd8 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -501,6 +501,7 @@ typedef struct VP8_COMP #endif TOKENLIST *tplist; + unsigned int partition_sz[MAX_PARTITIONS]; // end of multithread data @@ -604,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; diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk index acc9334f4..f55c899db 100644 --- a/vp8/vp8_common.mk +++ b/vp8/vp8_common.mk @@ -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 diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index db60bfe4f..5e1278a4c 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -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; */ diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index d74dc87bc..58dc486de 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -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); @@ -721,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; */ diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c index 42aedee7e..6e877b067 100644 --- a/vpx/src/vpx_decoder.c +++ b/vpx/src/vpx_decoder.c @@ -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 diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c index dab755430..5e86835ea 100644 --- a/vpx/src/vpx_encoder.c +++ b/vpx/src/vpx_encoder.c @@ -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; @@ -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 diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 6fd161ba2..b6bd7fc5f 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -22,7 +22,7 @@ */ #ifndef VP8CX_H #define VP8CX_H -#include "vpx/vpx_codec_impl_top.h" +#include "vpx_codec_impl_top.h" /*!\name Algorithm interface for VP8 * @@ -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 diff --git a/vpx/vp8dx.h b/vpx/vp8dx.h index 4a3aef760..1d9d53165 100644 --- a/vpx/vp8dx.h +++ b/vpx/vp8dx.h @@ -22,7 +22,7 @@ */ #ifndef VP8DX_H #define VP8DX_H -#include "vpx/vpx_codec_impl_top.h" +#include "vpx_codec_impl_top.h" /*!\name Algorithm interface for VP8 * @@ -74,5 +74,5 @@ 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 diff --git a/vpx/vp8e.h b/vpx/vp8e.h index abfce333a..ca907c96f 100644 --- a/vpx/vp8e.h +++ b/vpx/vp8e.h @@ -14,7 +14,7 @@ */ #ifndef VP8E_H #define VP8E_H -#include "vpx/vpx_codec_impl_top.h" +#include "vpx_codec_impl_top.h" #if defined(VPX_CODEC_DISABLE_COMPAT) && VPX_CODEC_DISABLE_COMPAT #error "Backwards compatibility disabled: don't include vp8e.h" @@ -59,5 +59,5 @@ VPX_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 diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h index e50fd765f..0fc38c69f 100644 --- a/vpx/vpx_decoder.h +++ b/vpx/vpx_decoder.h @@ -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 diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index 6dbce0d56..71153d55f 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -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 @@ -2040,10 +2040,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 { |