summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild/make/ads2gas.pl5
-rwxr-xr-xbuild/make/ads2gas_apple.pl5
-rw-r--r--vp8/common/arm/armv6/bilinearfilter_v6.asm13
-rw-r--r--vp8/common/arm/armv6/copymem16x16_v6.asm10
-rw-r--r--vp8/common/arm/armv6/filter_v6.asm215
-rw-r--r--vp8/common/arm/armv6/loopfilter_v6.asm14
-rw-r--r--vp8/common/arm/armv6/simpleloopfilter_v6.asm8
-rw-r--r--vp8/common/arm/armv6/sixtappredict8x4_v6.asm6
-rw-r--r--vp8/common/arm/filter_arm.c30
-rw-r--r--vp8/common/defaultcoefcounts.c225
-rw-r--r--vp8/common/defaultcoefcounts.h216
-rw-r--r--vp8/common/entropy.c4
-rw-r--r--vp8/common/onyx.h7
-rw-r--r--vp8/common/onyxc_int.h2
-rw-r--r--vp8/common/onyxd.h1
-rw-r--r--vp8/decoder/decodframe.c135
-rw-r--r--vp8/decoder/onyxd_if.c113
-rw-r--r--vp8/decoder/onyxd_int.h4
-rw-r--r--vp8/encoder/bitstream.c319
-rw-r--r--vp8/encoder/onyx_if.c2
-rw-r--r--vp8/encoder/onyx_int.h3
-rw-r--r--vp8/vp8_common.mk1
-rw-r--r--vp8/vp8_cx_iface.c38
-rw-r--r--vp8/vp8_dx_iface.c5
-rw-r--r--vpx/src/vpx_decoder.c3
-rw-r--r--vpx/src/vpx_encoder.c3
-rw-r--r--vpx/vp8.h4
-rw-r--r--vpx/vp8cx.h4
-rw-r--r--vpx/vp8dx.h4
-rw-r--r--vpx/vp8e.h4
-rw-r--r--vpx/vpx_decoder.h10
-rw-r--r--vpx/vpx_encoder.h45
-rw-r--r--vpxenc.c4
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;
diff --git a/vpx/vp8.h b/vpx/vp8.h
index 7ca5c6e07..983cc4ad4 100644
--- 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
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
diff --git a/vpxenc.c b/vpxenc.c
index d311a14ce..26afcd6f4 100644
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -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
{