diff options
Diffstat (limited to 'vp8')
31 files changed, 2119 insertions, 121 deletions
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c index edef36094..2dee21191 100644 --- a/vp8/common/alloccommon.c +++ b/vp8/common/alloccommon.c @@ -125,7 +125,16 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height) } void vp8_setup_version(VP8_COMMON *cm) { - switch (cm->version) + if (cm->version & 0x4) + { + if (!CONFIG_EXPERIMENTAL) + vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, + "Bitstream was created by an experimental " + "encoder"); + cm->experimental = 1; + } + + switch (cm->version & 0x3) { case 0: cm->no_lpf = 0; @@ -151,13 +160,6 @@ void vp8_setup_version(VP8_COMMON *cm) cm->use_bilinear_mc_filter = 1; cm->full_pixel = 1; break; - default: - /*4,5,6,7 are reserved for future use*/ - cm->no_lpf = 0; - cm->simpler_lpf = 0; - cm->use_bilinear_mc_filter = 0; - cm->full_pixel = 0; - break; } } void vp8_create_common(VP8_COMMON *oci) diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index fc8e0722c..906e05520 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -29,6 +29,7 @@ void vpx_log(const char *format, ...); #define DCPREDCNTTHRESH 3 #define MB_FEATURE_TREE_PROBS 3 + #define MAX_MB_SEGMENTS 4 #define MAX_REF_LF_DELTAS 4 @@ -166,6 +167,7 @@ typedef struct int as_int; MV as_mv; } mv; + unsigned char segment_flag; unsigned char partitioning; unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ @@ -249,11 +251,15 @@ typedef struct /* 0 (do not update) 1 (update) the macroblock segmentation feature data. */ unsigned char mb_segement_abs_delta; + unsigned char temporal_update; /* Per frame flags that define which MB level features (such as quantizer or loop filter level) */ /* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */ - vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; /* Probability Tree used to code Segment number */ - - signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; /* Segment parameters */ +#if CONFIG_SEGMENTATION + vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS + 3]; // Probability Tree used to code Segment number +#else + vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; +#endif + signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; // Segment parameters /* mode_based Loop filter adjustment */ unsigned char mode_ref_lf_delta_enabled; diff --git a/vp8/common/entropy.c b/vp8/common/entropy.c index a1fe4f4ab..219483289 100644 --- a/vp8/common/entropy.c +++ b/vp8/common/entropy.c @@ -76,7 +76,7 @@ static const Prob Pcat3[] = { 173, 148, 140}; static const Prob Pcat4[] = { 176, 155, 140, 135}; static const Prob Pcat5[] = { 180, 157, 141, 134, 130}; static const Prob Pcat6[] = -{ 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129}; +{ 254, 254, 252, 249, 243, 230, 196, 177, 153, 140, 133, 130, 129}; static vp8_tree_index cat1[2], cat2[4], cat3[6], cat4[8], cat5[10], cat6[22]; @@ -111,7 +111,7 @@ static void init_bit_trees() init_bit_tree(cat3, 3); init_bit_tree(cat4, 4); init_bit_tree(cat5, 5); - init_bit_tree(cat6, 11); + init_bit_tree(cat6, 13); } vp8_extra_bit_struct vp8_extra_bits[12] = @@ -126,7 +126,7 @@ vp8_extra_bit_struct vp8_extra_bits[12] = { cat3, Pcat3, 3, 11}, { cat4, Pcat4, 4, 19}, { cat5, Pcat5, 5, 35}, - { cat6, Pcat6, 11, 67}, + { cat6, Pcat6, 13, 67}, { 0, 0, 0, 0} }; #include "defaultcoefcounts.h" diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h index d174e45b9..77f2673aa 100644 --- a/vp8/common/entropy.h +++ b/vp8/common/entropy.h @@ -27,7 +27,7 @@ #define DCT_VAL_CATEGORY3 7 /* 11-18 Extra Bits 3+1 */ #define DCT_VAL_CATEGORY4 8 /* 19-34 Extra Bits 4+1 */ #define DCT_VAL_CATEGORY5 9 /* 35-66 Extra Bits 5+1 */ -#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 11+1 */ +#define DCT_VAL_CATEGORY6 10 /* 67+ Extra Bits 13+1 */ #define DCT_EOB_TOKEN 11 /* EOB Extra Bits 0+0 */ #define vp8_coef_tokens 12 @@ -51,7 +51,7 @@ extern vp8_extra_bit_struct vp8_extra_bits[12]; /* indexed by token value */ #define PROB_UPDATE_BASELINE_COST 7 #define MAX_PROB 255 -#define DCT_MAX_VALUE 2048 +#define DCT_MAX_VALUE 8192 /* Coefficients are predicted via a 3-dimensional probability table. */ diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c index 5c6464772..2f8997953 100644 --- a/vp8/common/generic/systemdependent.c +++ b/vp8/common/generic/systemdependent.c @@ -78,8 +78,18 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) vp8_arch_x86_common_init(ctx); #endif + #if ARCH_ARM vp8_arch_arm_common_init(ctx); #endif +#if CONFIG_EXTEND_QRANGE + rtcd->idct.idct1 = vp8_short_idct4x4llm_1_c; + rtcd->idct.idct16 = vp8_short_idct4x4llm_c; + rtcd->idct.idct1_scalar_add = vp8_dc_only_idct_add_c; + rtcd->idct.iwalsh1 = vp8_short_inv_walsh4x4_1_c; + rtcd->idct.iwalsh16 = vp8_short_inv_walsh4x4_c; + +#endif + } diff --git a/vp8/common/idctllm.c b/vp8/common/idctllm.c index 196062df6..c65d35adc 100644 --- a/vp8/common/idctllm.c +++ b/vp8/common/idctllm.c @@ -22,6 +22,8 @@ * so * x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) *cos(pi/8)-1). **************************************************************************/ +#include "vpx_ports/config.h" + static const int cospi8sqrt2minus1 = 20091; static const int sinpi8sqrt2 = 35468; static const int rounding = 0; @@ -75,11 +77,19 @@ void vp8_short_idct4x4llm_c(short *input, short *output, int pitch) d1 = temp1 + temp2; +#if !CONFIG_EXTEND_QRANGE op[0] = (a1 + d1 + 4) >> 3; op[3] = (a1 - d1 + 4) >> 3; op[1] = (b1 + c1 + 4) >> 3; op[2] = (b1 - c1 + 4) >> 3; +#else + op[0] = (a1 + d1 + 16) >> 5; + op[3] = (a1 - d1 + 16) >> 5; + + op[1] = (b1 + c1 + 16) >> 5; + op[2] = (b1 - c1 + 16) >> 5; +#endif ip += shortpitch; op += shortpitch; @@ -92,8 +102,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch) int a1; short *op = output; int shortpitch = pitch >> 1; +#if !CONFIG_EXTEND_QRANGE a1 = ((input[0] + 4) >> 3); - +#else + a1 = ((input[0] + 16) >> 5); +#endif for (i = 0; i < 4; i++) { op[0] = a1; @@ -106,7 +119,11 @@ void vp8_short_idct4x4llm_1_c(short *input, short *output, int pitch) void vp8_dc_only_idct_add_c(short input_dc, unsigned char *pred_ptr, unsigned char *dst_ptr, int pitch, int stride) { +#if !CONFIG_EXTEND_QRANGE int a1 = ((input_dc + 4) >> 3); +#else + int a1 = ((input_dc + 16) >> 5); +#endif int r, c; for (r = 0; r < 4; r++) @@ -168,11 +185,17 @@ void vp8_short_inv_walsh4x4_c(short *input, short *output) c2 = a1 - b1; d2 = d1 - c1; +#if !CONFIG_EXTEND_QRANGE op[0] = (a2 + 3) >> 3; op[1] = (b2 + 3) >> 3; op[2] = (c2 + 3) >> 3; op[3] = (d2 + 3) >> 3; - +#else + op[0] = (a2 + 1) >> 2; + op[1] = (b2 + 1) >> 2; + op[2] = (c2 + 1) >> 2; + op[3] = (d2 + 1) >> 2; +#endif ip += 4; op += 4; } @@ -184,7 +207,11 @@ void vp8_short_inv_walsh4x4_1_c(short *input, short *output) int a1; short *op = output; - a1 = ((input[0] + 3) >> 3); +#if !CONFIG_EXTEND_QRANGE + a1 = (input[0] + 3 )>> 3; +#else + a1 = (input[0] + 1 )>> 2; +#endif for (i = 0; i < 4; i++) { diff --git a/vp8/common/maskingmv.c b/vp8/common/maskingmv.c new file mode 100644 index 000000000..d01a18fc8 --- /dev/null +++ b/vp8/common/maskingmv.c @@ -0,0 +1,855 @@ +/* + ============================================================================ + Name : maskingmv.c + Author : jimbankoski + Version : + Copyright : Your copyright notice + Description : Hello World in C, Ansi-style + ============================================================================ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +extern unsigned int vp8_sad16x16_sse3( + unsigned char *src_ptr, + int src_stride, + unsigned char *ref_ptr, + int ref_stride, + int max_err); + +extern void vp8_sad16x16x3_sse3( + unsigned char *src_ptr, + int src_stride, + unsigned char *ref_ptr, + int ref_stride, + int *results); + +extern int vp8_growmaskmb_sse3( + unsigned char *om, + unsigned char *nm); + +extern void vp8_makemask_sse3( + unsigned char *y, + unsigned char *u, + unsigned char *v, + unsigned char *ym, + int yp, + int uvp, + int ys, + int us, + int vs, + int yt, + int ut, + int vt); + +unsigned int vp8_sad16x16_unmasked_wmt( + unsigned char *src_ptr, + int src_stride, + unsigned char *ref_ptr, + int ref_stride, + unsigned char *mask); + +unsigned int vp8_sad16x16_masked_wmt( + unsigned char *src_ptr, + int src_stride, + unsigned char *ref_ptr, + int ref_stride, + unsigned char *mask); + +unsigned int vp8_masked_predictor_wmt( + unsigned char *masked, + unsigned char *unmasked, + int src_stride, + unsigned char *dst_ptr, + int dst_stride, + unsigned char *mask); +unsigned int vp8_masked_predictor_uv_wmt( + unsigned char *masked, + unsigned char *unmasked, + int src_stride, + unsigned char *dst_ptr, + int dst_stride, + unsigned char *mask); +unsigned int vp8_uv_from_y_mask( + unsigned char *ymask, + unsigned char *uvmask); +int yp=16; +unsigned char sxy[]= +{ +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90 +}; + +unsigned char sts[]= +{ +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +}; +unsigned char str[]= +{ +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +unsigned char y[]= +{ +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40, +60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40, +40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40, +40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40, +40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40 +}; +int uvp=8; +unsigned char u[]= +{ +90,80,70,70,90,90,90,17, +90,80,70,70,90,90,90,17, +84,70,70,90,90,90,17,17, +84,70,70,90,90,90,17,17, +80,70,70,90,90,90,17,17, +90,80,70,70,90,90,90,17, +90,80,70,70,90,90,90,17, +90,80,70,70,90,90,90,17 +}; + +unsigned char v[]= +{ +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80 +}; + +unsigned char ym[256]; +unsigned char uvm[64]; +typedef struct +{ + unsigned char y; + unsigned char yt; + unsigned char u; + unsigned char ut; + unsigned char v; + unsigned char vt; + unsigned char use; +} COLOR_SEG_ELEMENT; + +/* +COLOR_SEG_ELEMENT segmentation[]= +{ + { 60,4,80,17,80,10, 1}, + { 40,4,15,10,80,10, 1}, +}; +*/ + +COLOR_SEG_ELEMENT segmentation[]= +{ + { 79,44,92,44, 237,60, 1}, +}; + +unsigned char pixel_mask(unsigned char y,unsigned char u,unsigned char v, + COLOR_SEG_ELEMENT sgm[], + int c) +{ + COLOR_SEG_ELEMENT *s=sgm; + unsigned char m =0; + int i; + for(i=0;i<c;i++,s++) + m |= ( abs(y-s->y)< s->yt && + abs(u-s->u)< s->ut && + abs(v-s->v)< s->vt ? 255 : 0 ); + + return m; +} +int neighbors[256][8]; +int makeneighbors(void) +{ + int i,j; + for(i=0;i<256;i++) + { + int r=(i>>4),c=(i&15); + int ni=0; + for(j=0;j<8;j++) + neighbors[i][j]=i; + for(j=0;j<256;j++) + { + int nr=(j>>4),nc=(j&15); + if(abs(nr-r)<2&&abs(nc-c)<2) + neighbors[i][ni++]=j; + } + } + return 0; +} +void grow_ymask(unsigned char *ym) +{ + unsigned char nym[256]; + int i,j; + + for(i=0;i<256;i++) + { + nym[i]=ym[i]; + for(j=0;j<8;j++) + { + nym[i]|=ym[neighbors[i][j]]; + } + } + for(i=0;i<256;i++) + ym[i]=nym[i]; +} +void make_mb_mask(unsigned char *y, unsigned char *u, unsigned char *v, + unsigned char *ym, unsigned char *uvm, + int yp, int uvp, + COLOR_SEG_ELEMENT sgm[], + int count) +{ + int r,c; + unsigned char *oym = ym; + + memset(ym,20,256); + for(r=0;r<8;r++,uvm+=8,u+=uvp,v+=uvp,y+=(yp+yp),ym+=32) + for(c=0;c<8;c++) + { + int y1=y[c<<1]; + int u1=u[c]; + int v1=v[c]; + int m = pixel_mask(y1,u1,v1,sgm,count); + uvm[c] = m; + ym[c<<1] = uvm[c];// = pixel_mask(y[c<<1],u[c],v[c],sgm,count); + ym[(c<<1)+1] = pixel_mask(y[1+(c<<1)],u[c],v[c],sgm,count); + ym[(c<<1)+16] = pixel_mask(y[yp+(c<<1)],u[c],v[c],sgm,count); + ym[(c<<1)+17] = pixel_mask(y[1+yp+(c<<1)],u[c],v[c],sgm,count); + } + grow_ymask(oym); +} + +int masked_sad(unsigned char *src, int p, unsigned char *dst, int dp, + unsigned char *ym ) +{ + int i,j; + unsigned sad = 0; + for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16) + for(j=0;j<16;j++) + if(ym[j]) + sad+= abs(src[j]-dst[j]); + + return sad; +} + +int compare_masks(unsigned char *sym, unsigned char *ym) +{ + int i,j; + unsigned sad = 0; + for(i=0;i<16;i++,sym += 16,ym+=16) + for(j=0;j<16;j++) + sad+= (sym[j]!=ym[j]?1:0); + + return sad; +} +int unmasked_sad(unsigned char *src, int p, unsigned char *dst, int dp, + unsigned char *ym) +{ + int i,j; + unsigned sad = 0; + for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16) + for(j=0;j<16;j++) + if(!ym[j]) + sad+= abs(src[j]-dst[j]); + + return sad; +} +int masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v, + int yp, int uvp, + unsigned char *dy, unsigned char *du, unsigned char *dv, + int dyp, int duvp, + COLOR_SEG_ELEMENT sgm[], + int count, + int *mi, + int *mj, + int *ui, + int *uj, + int *wm) +{ + int i,j; + + unsigned char ym[256]; + unsigned char uvm[64]; + unsigned char dym[256]; + unsigned char duvm[64]; + unsigned int e = 0 ; + int beste=256; + int bmi=-32,bmj=-32; + int bui=-32,buj=-32; + int beste1=256; + int bmi1=-32,bmj1=-32; + int bui1=-32,buj1=-32; + int obeste; + + // first try finding best mask and then unmasked + beste = 0xffffffff; + + // find best unmasked mv + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + unsigned char *duz = i/2*duvp + du; + unsigned char *dvz = i/2*duvp + dv; + for(j=-32;j<32;j++) + { + // 0,0 masked destination + make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count); + + e = unmasked_sad(y, yp, dyz+j, dyp, dym ); + + if(e<beste) + { + bui=i; + buj=j; + beste=e; + } + } + } + //bui=0;buj=0; + // best mv masked destination + make_mb_mask(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2, + dym, duvm, dyp, duvp,sgm,count); + + obeste = beste; + beste = 0xffffffff; + + // find best masked + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + for(j=-32;j<32;j++) + { + e = masked_sad(y, yp, dyz+j, dyp, dym ); + + if(e<beste) + { + bmi=i; + bmj=j; + beste=e; + } + } + } + beste1=beste+obeste; + bmi1=bmi;bmj1=bmj; + bui1=bui;buj1=buj; + + beste = 0xffffffff; + // source mask + make_mb_mask(y,u, v, ym, uvm, yp, uvp,sgm,count); + + // find best mask + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + unsigned char *duz = i/2*duvp + du; + unsigned char *dvz = i/2*duvp + dv; + for(j=-32;j<32;j++) + { + // 0,0 masked destination + make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count); + + e = compare_masks(ym, dym); + + if(e<beste) + { + bmi=i; + bmj=j; + beste=e; + } + } + } + + + // best mv masked destination + make_mb_mask(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2, + dym, duvm, dyp, duvp,sgm,count); + + obeste = masked_sad(y, yp, dy+bmi*dyp+bmj, dyp, dym ); + + beste = 0xffffffff; + + // find best unmasked mv + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + for(j=-32;j<32;j++) + { + e = unmasked_sad(y, yp, dyz+j, dyp, dym ); + + if(e<beste) + { + bui=i; + buj=j; + beste=e; + } + } + } + beste += obeste; + + + if(beste<beste1) + { + *mi = bmi; + *mj = bmj; + *ui = bui; + *uj = buj; + *wm = 1; + } + else + { + *mi = bmi1; + *mj = bmj1; + *ui = bui1; + *uj = buj1; + *wm = 0; + + } + return 0; +} + +int predict(unsigned char *src, int p, unsigned char *dst, int dp, + unsigned char *ym, unsigned char *prd ) +{ + int i,j; + for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16, prd+=16) + for(j=0;j<16;j++) + prd[j]=(ym[j] ? src[j]:dst[j]); + return 0; +} + +int fast_masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v, + int yp, int uvp, + unsigned char *dy, unsigned char *du, unsigned char *dv, + int dyp, int duvp, + COLOR_SEG_ELEMENT sgm[], + int count, + int *mi, + int *mj, + int *ui, + int *uj, + int *wm) +{ + int i,j; + + unsigned char ym[256]; + unsigned char ym2[256]; + unsigned char uvm[64]; + unsigned char dym2[256]; + unsigned char dym[256]; + unsigned char duvm[64]; + unsigned int e = 0 ; + int beste=256; + int bmi=-32,bmj=-32; + int bui=-32,buj=-32; + int beste1=256; + int bmi1=-32,bmj1=-32; + int bui1=-32,buj1=-32; + int obeste; + + // first try finding best mask and then unmasked + beste = 0xffffffff; + +#if 0 + for(i=0;i<16;i++) + { + unsigned char *dy = i*yp + y; + for(j=0;j<16;j++) + printf("%2x",dy[j]); + printf("\n"); + } + printf("\n"); + + for(i=-32;i<48;i++) + { + unsigned char *dyz = i*dyp + dy; + for(j=-32;j<48;j++) + printf("%2x",dyz[j]); + printf("\n"); + } +#endif + + // find best unmasked mv + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + unsigned char *duz = i/2*duvp + du; + unsigned char *dvz = i/2*duvp + dv; + for(j=-32;j<32;j++) + { + // 0,0 masked destination + vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(dym,dym2); + + e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 ); + + if(e<beste) + { + bui=i; + buj=j; + beste=e; + } + } + } + //bui=0;buj=0; + // best mv masked destination + + vp8_makemask_sse3(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2, + dym, dyp, duvp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(dym,dym2); + + obeste = beste; + beste = 0xffffffff; + + // find best masked + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + for(j=-32;j<32;j++) + { + e = vp8_sad16x16_masked_wmt(y, yp, dyz+j, dyp, dym2 ); + if(e<beste) + { + bmi=i; + bmj=j; + beste=e; + } + } + } + beste1=beste+obeste; + bmi1=bmi;bmj1=bmj; + bui1=bui;buj1=buj; + + // source mask + vp8_makemask_sse3(y,u, v, + ym, yp, uvp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(ym,ym2); + + // find best mask + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + unsigned char *duz = i/2*duvp + du; + unsigned char *dvz = i/2*duvp + dv; + for(j=-32;j<32;j++) + { + // 0,0 masked destination + vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(dym,dym2); + + e = compare_masks(ym2, dym2); + + if(e<beste) + { + bmi=i; + bmj=j; + beste=e; + } + } + } + + vp8_makemask_sse3(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2, + dym, dyp, duvp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(dym,dym2); + + obeste = vp8_sad16x16_masked_wmt(y, yp, dy+bmi*dyp+bmj, dyp, dym2 ); + + beste = 0xffffffff; + + // find best unmasked mv + for(i=-32;i<32;i++) + { + unsigned char *dyz = i*dyp + dy; + for(j=-32;j<32;j++) + { + e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 ); + + if(e<beste) + { + bui=i; + buj=j; + beste=e; + } + } + } + beste += obeste; + + if(beste<beste1) + { + *mi = bmi; + *mj = bmj; + *ui = bui; + *uj = buj; + *wm = 1; + } + else + { + *mi = bmi1; + *mj = bmj1; + *ui = bui1; + *uj = buj1; + *wm = 0; + beste=beste1; + + } + return beste; +} + +int predict_all(unsigned char *ym, unsigned char *um, unsigned char *vm, + int ymp, int uvmp, + unsigned char *yp, unsigned char *up, unsigned char *vp, + int ypp, int uvpp, + COLOR_SEG_ELEMENT sgm[], + int count, + int mi, + int mj, + int ui, + int uj, + int wm) +{ + int i,j; + unsigned char dym[256]; + unsigned char dym2[256]; + unsigned char duvm[64]; + unsigned char *yu=ym,*uu=um, *vu=vm; + + unsigned char *dym3=dym2; + + ym+=mi*ymp+mj; + um+=mi/2*uvmp+mj/2; + vm+=mi/2*uvmp+mj/2; + + yu+=ui*ymp+uj; + uu+=ui/2*uvmp+uj/2; + vu+=ui/2*uvmp+uj/2; + + // best mv masked destination + if(wm) + vp8_makemask_sse3(ym,um, vm, dym, ymp, uvmp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + else + vp8_makemask_sse3(yu,uu, vu, dym, ymp, uvmp, + sgm[0].y,sgm[0].u,sgm[0].v, + sgm[0].yt,sgm[0].ut,sgm[0].vt); + + vp8_growmaskmb_sse3(dym,dym2); + vp8_masked_predictor_wmt(ym,yu,ymp,yp,ypp,dym3); + vp8_uv_from_y_mask(dym3,duvm); + vp8_masked_predictor_uv_wmt(um,uu,uvmp,up,uvpp,duvm); + vp8_masked_predictor_uv_wmt(vm,vu,uvmp,vp,uvpp,duvm); + + return 0; +} + +unsigned char f0p[1280*720*3/2]; +unsigned char f1p[1280*720*3/2]; +unsigned char prd[1280*720*3/2]; +unsigned char msk[1280*720*3/2]; + + +int mainz(int argc, char *argv[]) { + + FILE *f=fopen(argv[1],"rb"); + FILE *g=fopen(argv[2],"wb"); + int w=atoi(argv[3]),h=atoi(argv[4]); + int y_stride=w,uv_stride=w/2; + int r,c; + unsigned char *f0=f0p,*f1=f1p,*t; + unsigned char ym[256],uvm[64]; + unsigned char ym2[256],uvm2[64]; + unsigned char ym3[256],uvm3[64]; + int a,b; + + COLOR_SEG_ELEMENT last={ 20,20,20,20, 230,20, 1},best; +#if 0 + makeneighbors(); + COLOR_SEG_ELEMENT segmentation[]= + { + { 60,4,80,17,80,10, 1}, + { 40,4,15,10,80,10, 1}, + }; + make_mb_mask(y, u, v,ym2,uvm2,16,8,segmentation,1); + + vp8_makemask_sse3(y,u,v,ym, (int) 16,(int) 8, + (int) segmentation[0].y,(int) segmentation[0].u,(int) segmentation[0].v, + segmentation[0].yt,segmentation[0].ut,segmentation[0].vt); + + vp8_growmaskmb_sse3(ym,ym3); + + a = vp8_sad16x16_masked_wmt(str,16,sts,16,ym3); + b = vp8_sad16x16_unmasked_wmt(str,16,sts,16,ym3); + + vp8_masked_predictor_wmt(str,sts,16,ym,16,ym3); + + vp8_uv_from_y_mask(ym3,uvm3); + + return 4; +#endif + makeneighbors(); + + + memset(prd,128,w*h*3/2); + + fread(f0,w*h*3/2,1,f); + + while(!feof(f)) + { + unsigned char *ys=f1,*yd=f0,*yp=prd; + unsigned char *us=f1+w*h,*ud=f0+w*h,*up=prd+w*h; + unsigned char *vs=f1+w*h*5/4,*vd=f0+w*h*5/4,*vp=prd+w*h*5/4; + fread(f1,w*h*3/2,1,f); + + ys+=32*y_stride;yd+=32*y_stride;yp+=32*y_stride; + us+=16*uv_stride;ud+=16*uv_stride;up+=16*uv_stride; + vs+=16*uv_stride;vd+=16*uv_stride;vp+=16*uv_stride; + for(r=32;r<h-32;r+=16, + ys+=16*w,yd+=16*w,yp+=16*w, + us+=8*uv_stride,ud+=8*uv_stride,up+=8*uv_stride, + vs+=8*uv_stride,vd+=8*uv_stride,vp+=8*uv_stride) + { + for(c=32;c<w-32;c+=16) + { + int mi,mj,ui,uj,wm; + int bmi,bmj,bui,buj,bwm; + unsigned char ym[256]; + + if(vp8_sad16x16_sse3( ys+c,y_stride, yd+c,y_stride,0xffff) == 0) + bmi=bmj=bui=buj=bwm=0; + else + { + COLOR_SEG_ELEMENT cs[5]; + int j; + unsigned int beste=0xfffffff; + unsigned int bestj=0; + + // try color from last mb segmentation + cs[0] = last; + + // try color segs from 4 pixels in mb recon as segmentation + cs[1].y = yd[c + y_stride + 1];cs[1].u = ud[c/2 + uv_stride]; + cs[1].v = vd[c/2 + uv_stride]; + cs[1].yt = cs[1].ut = cs[1].vt = 20; + cs[2].y = yd[c + w + 14]; + cs[2].u = ud[c/2 + uv_stride+7]; + cs[2].v = vd[c/2 + uv_stride+7]; + cs[2].yt = cs[2].ut = cs[2].vt = 20; + cs[3].y = yd[c + w*14 + 1]; + cs[3].u = ud[c/2 + uv_stride*7]; + cs[3].v = vd[c/2 + uv_stride*7]; + cs[3].yt = cs[3].ut = cs[3].vt = 20; + cs[4].y = yd[c + w*14 + 14]; + cs[4].u = ud[c/2 + uv_stride*7+7]; + cs[4].v = vd[c/2 + uv_stride*7+7]; + cs[4].yt = cs[4].ut = cs[4].vt = 20; + + for(j=0;j<5;j++) + { + int e; + + e = fast_masked_motion_search( + ys+c, us+c/2, vs+c/2, y_stride, uv_stride, + yd+c, ud+c/2, vd+c/2, y_stride, uv_stride, + &cs[j], 1, &mi,&mj,&ui,&uj,&wm); + + if(e<beste) + { + bmi=mi;bmj=mj;bui=ui;buj=uj,bwm=wm; + bestj=j; + beste=e; + } + } + best = cs[bestj]; + //best = segmentation[0]; + last = best; + } + predict_all(yd+c, ud+c/2, vd+c/2, w, uv_stride, + yp+c, up+c/2, vp+c/2, w, uv_stride, + &best, 1, bmi,bmj,bui,buj,bwm); + + } + } + fwrite(prd,w*h*3/2,1,g); + t=f0; + f0=f1; + f1=t; + + } + fclose(f); + fclose(g); + return; +} diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index c8c227787..a91cb337b 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -117,6 +117,7 @@ typedef struct VP8Common int mode_info_stride; /* profile settings */ + int experimental; int mb_no_coeff_skip; int no_lpf; int simpler_lpf; diff --git a/vp8/common/quant_common.c b/vp8/common/quant_common.c index e9833fe33..b8e6e2972 100644 --- a/vp8/common/quant_common.c +++ b/vp8/common/quant_common.c @@ -11,6 +11,8 @@ #include "quant_common.h" + +#if !CONFIG_EXTEND_QRANGE static const int dc_qlookup[QINDEX_RANGE] = { 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, @@ -34,7 +36,32 @@ static const int ac_qlookup[QINDEX_RANGE] = 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284, }; +#else + +static const int dc_qlookup[QINDEX_RANGE] = +{ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, 40, 42, + 44, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88, + 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, + 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 205, 210, 215, 220, + 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300, + 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, + 472, 484, 496, 508, 520, 532, 544, 556, 572, 588, 608, 628, 648, 668, 692, 720, +}; +static const int ac_qlookup[QINDEX_RANGE] = +{ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51, + 54, 57, 60, 63, 66, 69, 72, 76, 80, 84, 88, 92, 96, 100, 105, 110, + 115, 120, 125, 130, 135, 140, 146, 152, 158, 164, 170, 176, 182, 188, 194, 200, + 206, 212, 218, 224, 232, 240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320, + 330, 340, 350, 360, 370, 380, 392, 404, 416, 428, 440, 454, 468, 482, 496, 510, + 524, 540, 556, 572, 588, 604, 622, 640, 658, 676, 696, 716, 736, 756, 776, 796, + 820, 844, 868, 892, 916, 944, 972, 1000, 1032, 1064, 1096, 1128, 1168, 1208, 1252, 1300 +}; +#endif int vp8_dc_quant(int QIndex, int Delta) { @@ -62,7 +89,11 @@ int vp8_dc2quant(int QIndex, int Delta) else if (QIndex < 0) QIndex = 0; +#if !CONFIG_EXTEND_QRANGE retval = dc_qlookup[ QIndex ] * 2; +#else + retval = dc_qlookup[ QIndex ]; +#endif return retval; } @@ -72,16 +103,13 @@ int vp8_dc_uv_quant(int QIndex, int Delta) QIndex = QIndex + Delta; - if (QIndex > 127) - QIndex = 127; + if (QIndex > 117) + QIndex = 117; else if (QIndex < 0) QIndex = 0; retval = dc_qlookup[ QIndex ]; - if (retval > 132) - retval = 132; - return retval; } @@ -108,12 +136,13 @@ int vp8_ac2quant(int QIndex, int Delta) QIndex = 127; else if (QIndex < 0) QIndex = 0; - +#if !CONFIG_EXTEND_QRANGE retval = (ac_qlookup[ QIndex ] * 155) / 100; - if (retval < 8) retval = 8; - +#else + retval = ac_qlookup[ QIndex ]; +#endif return retval; } int vp8_ac_uv_quant(int QIndex, int Delta) diff --git a/vp8/common/reconintra4x4.c b/vp8/common/reconintra4x4.c index cd70dca73..8ddae0059 100644 --- a/vp8/common/reconintra4x4.c +++ b/vp8/common/reconintra4x4.c @@ -81,10 +81,10 @@ void vp8_predict_intra4x4(BLOCKD *x, { unsigned int ap[4]; - ap[0] = (top_left + 2 * Above[0] + Above[1] + 2) >> 2; - ap[1] = (Above[0] + 2 * Above[1] + Above[2] + 2) >> 2; - ap[2] = (Above[1] + 2 * Above[2] + Above[3] + 2) >> 2; - ap[3] = (Above[2] + 2 * Above[3] + Above[4] + 2) >> 2; + ap[0] = Above[0]; + ap[1] = Above[1]; + ap[2] = Above[2]; + ap[3] = Above[3]; for (r = 0; r < 4; r++) { @@ -105,10 +105,10 @@ void vp8_predict_intra4x4(BLOCKD *x, { unsigned int lp[4]; - lp[0] = (top_left + 2 * Left[0] + Left[1] + 2) >> 2; - lp[1] = (Left[0] + 2 * Left[1] + Left[2] + 2) >> 2; - lp[2] = (Left[1] + 2 * Left[2] + Left[3] + 2) >> 2; - lp[3] = (Left[2] + 2 * Left[3] + Left[3] + 2) >> 2; + lp[0] = Left[0]; + lp[1] = Left[1]; + lp[2] = Left[2]; + lp[3] = Left[3]; for (r = 0; r < 4; r++) { diff --git a/vp8/common/x86/mask_sse3.asm b/vp8/common/x86/mask_sse3.asm new file mode 100644 index 000000000..0d90cfa86 --- /dev/null +++ b/vp8/common/x86/mask_sse3.asm @@ -0,0 +1,484 @@ +; +; 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 "vpx_ports/x86_abi_support.asm" + +;void int vp8_makemask_sse3( +; unsigned char *y, +; unsigned char *u, +; unsigned char *v, +; unsigned char *ym, +; unsigned char *uvm, +; int yp, +; int uvp, +; int ys, +; int us, +; int vs, +; int yt, +; int ut, +; int vt) +global sym(vp8_makemask_sse3) +sym(vp8_makemask_sse3): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 14 + push rsi + push rdi + ; end prolog + + mov rsi, arg(0) ;y + mov rdi, arg(1) ;u + mov rcx, arg(2) ;v + mov rax, arg(3) ;ym + movsxd rbx, dword arg(4) ;yp + movsxd rdx, dword arg(5) ;uvp + + pxor xmm0,xmm0 + + ;make 16 copies of the center y value + movd xmm1, arg(6) + pshufb xmm1, xmm0 + + ; make 16 copies of the center u value + movd xmm2, arg(7) + pshufb xmm2, xmm0 + + ; make 16 copies of the center v value + movd xmm3, arg(8) + pshufb xmm3, xmm0 + unpcklpd xmm2, xmm3 + + ;make 16 copies of the y tolerance + movd xmm3, arg(9) + pshufb xmm3, xmm0 + + ;make 16 copies of the u tolerance + movd xmm4, arg(10) + pshufb xmm4, xmm0 + + ;make 16 copies of the v tolerance + movd xmm5, arg(11) + pshufb xmm5, xmm0 + unpckhpd xmm4, xmm5 + + mov r8,8 + +NextPairOfRows: + + ;grab the y source values + movdqu xmm0, [rsi] + + ;compute abs difference between source and y target + movdqa xmm6, xmm1 + movdqa xmm7, xmm0 + psubusb xmm0, xmm1 + psubusb xmm6, xmm7 + por xmm0, xmm6 + + ;compute abs difference between + movdqa xmm6, xmm3 + pcmpgtb xmm6, xmm0 + + ;grab the y source values + add rsi, rbx + movdqu xmm0, [rsi] + + ;compute abs difference between source and y target + movdqa xmm11, xmm1 + movdqa xmm7, xmm0 + psubusb xmm0, xmm1 + psubusb xmm11, xmm7 + por xmm0, xmm11 + + ;compute abs difference between + movdqa xmm11, xmm3 + pcmpgtb xmm11, xmm0 + + + ;grab the u and v source values + movdqu xmm7, [rdi] + movdqu xmm8, [rcx] + unpcklpd xmm7, xmm8 + + ;compute abs difference between source and uv targets + movdqa xmm9, xmm2 + movdqa xmm10, xmm7 + psubusb xmm7, xmm2 + psubusb xmm9, xmm10 + por xmm7, xmm9 + + ;check whether the number is < tolerance + movdqa xmm0, xmm4 + pcmpgtb xmm0, xmm7 + + ;double u and v masks + movdqa xmm8, xmm0 + punpckhbw xmm0, xmm0 + punpcklbw xmm8, xmm8 + + ;mask row 0 and output + pand xmm6, xmm8 + pand xmm6, xmm0 + movdqa [rax],xmm6 + + ;mask row 1 and output + pand xmm11, xmm8 + pand xmm11, xmm0 + movdqa [rax+16],xmm11 + + + ; to the next row or set of rows + add rsi, rbx + add rdi, rdx + add rcx, rdx + add rax,32 + dec r8 + jnz NextPairOfRows + + + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + +;GROW_HORIZ (register for result, source register or mem local) +; takes source and shifts left and ors with source +; then shifts right and ors with source +%macro GROW_HORIZ 2 + movdqa %1, %2 + movdqa xmm14, %1 + movdqa xmm15, %1 + pslldq xmm14, 1 + psrldq xmm15, 1 + por %1,xmm14 + por %1,xmm15 +%endmacro +;GROW_VERT (result, center row, above row, below row) +%macro GROW_VERT 4 + movdqa %1,%2 + por %1,%3 + por %1,%4 +%endmacro + +;GROW_NEXTLINE (new line to grow, new source, line to write) +%macro GROW_NEXTLINE 3 + GROW_HORIZ %1, %2 + GROW_VERT xmm3, xmm0, xmm1, xmm2 + movdqa %3,xmm3 +%endmacro + + +;void int vp8_growmaskmb_sse3( +; unsigned char *om, +; unsigned char *nm, +global sym(vp8_growmaskmb_sse3) +sym(vp8_growmaskmb_sse3): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 2 + push rsi + push rdi + ; end prolog + + mov rsi, arg(0) ;src + mov rdi, arg(1) ;rst + + GROW_HORIZ xmm0, [rsi] + GROW_HORIZ xmm1, [rsi+16] + GROW_HORIZ xmm2, [rsi+32] + + GROW_VERT xmm3, xmm0, xmm1, xmm2 + por xmm0,xmm1 + movdqa [rdi], xmm0 + movdqa [rdi+16],xmm3 + + GROW_NEXTLINE xmm0,[rsi+48],[rdi+32] + GROW_NEXTLINE xmm1,[rsi+64],[rdi+48] + GROW_NEXTLINE xmm2,[rsi+80],[rdi+64] + GROW_NEXTLINE xmm0,[rsi+96],[rdi+80] + GROW_NEXTLINE xmm1,[rsi+112],[rdi+96] + GROW_NEXTLINE xmm2,[rsi+128],[rdi+112] + GROW_NEXTLINE xmm0,[rsi+144],[rdi+128] + GROW_NEXTLINE xmm1,[rsi+160],[rdi+144] + GROW_NEXTLINE xmm2,[rsi+176],[rdi+160] + GROW_NEXTLINE xmm0,[rsi+192],[rdi+176] + GROW_NEXTLINE xmm1,[rsi+208],[rdi+192] + GROW_NEXTLINE xmm2,[rsi+224],[rdi+208] + GROW_NEXTLINE xmm0,[rsi+240],[rdi+224] + + por xmm0,xmm2 + movdqa [rdi+240], xmm0 + + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + + + +;unsigned int vp8_sad16x16_masked_wmt( +; unsigned char *src_ptr, +; int src_stride, +; unsigned char *ref_ptr, +; int ref_stride, +; unsigned char *mask) +global sym(vp8_sad16x16_masked_wmt) +sym(vp8_sad16x16_masked_wmt): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 5 + push rsi + push rdi + ; end prolog + mov rsi, arg(0) ;src_ptr + mov rdi, arg(2) ;ref_ptr + + mov rbx, arg(4) ;mask + movsxd rax, dword ptr arg(1) ;src_stride + movsxd rdx, dword ptr arg(3) ;ref_stride + + mov rcx, 16 + + pxor xmm3, xmm3 + +NextSadRow: + movdqu xmm0, [rsi] + movdqu xmm1, [rdi] + movdqu xmm2, [rbx] + pand xmm0, xmm2 + pand xmm1, xmm2 + + psadbw xmm0, xmm1 + paddw xmm3, xmm0 + + add rsi, rax + add rdi, rdx + add rbx, 16 + + dec rcx + jnz NextSadRow + + movdqa xmm4 , xmm3 + psrldq xmm4, 8 + paddw xmm3, xmm4 + movq rax, xmm3 + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + + +;unsigned int vp8_sad16x16_unmasked_wmt( +; unsigned char *src_ptr, +; int src_stride, +; unsigned char *ref_ptr, +; int ref_stride, +; unsigned char *mask) +global sym(vp8_sad16x16_unmasked_wmt) +sym(vp8_sad16x16_unmasked_wmt): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 5 + push rsi + push rdi + ; end prolog + mov rsi, arg(0) ;src_ptr + mov rdi, arg(2) ;ref_ptr + + mov rbx, arg(4) ;mask + movsxd rax, dword ptr arg(1) ;src_stride + movsxd rdx, dword ptr arg(3) ;ref_stride + + mov rcx, 16 + + pxor xmm3, xmm3 + +next_vp8_sad16x16_unmasked_wmt: + movdqu xmm0, [rsi] + movdqu xmm1, [rdi] + movdqu xmm2, [rbx] + por xmm0, xmm2 + por xmm1, xmm2 + + psadbw xmm0, xmm1 + paddw xmm3, xmm0 + + add rsi, rax + add rdi, rdx + add rbx, 16 + + dec rcx + jnz next_vp8_sad16x16_unmasked_wmt + + movdqa xmm4 , xmm3 + psrldq xmm4, 8 + paddw xmm3, xmm4 + movq rax, xmm3 + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + + +;unsigned int vp8_masked_predictor_wmt( +; unsigned char *masked, +; unsigned char *unmasked, +; int src_stride, +; unsigned char *dst_ptr, +; int dst_stride, +; unsigned char *mask) +global sym(vp8_masked_predictor_wmt) +sym(vp8_masked_predictor_wmt): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 6 + push rsi + push rdi + ; end prolog + mov rsi, arg(0) ;src_ptr + mov rdi, arg(1) ;ref_ptr + + mov rbx, arg(5) ;mask + movsxd rax, dword ptr arg(2) ;src_stride + mov r11, arg(3) ; destination + movsxd rdx, dword ptr arg(4) ;dst_stride + + mov rcx, 16 + + pxor xmm3, xmm3 + +next_vp8_masked_predictor_wmt: + movdqu xmm0, [rsi] + movdqu xmm1, [rdi] + movdqu xmm2, [rbx] + + pand xmm0, xmm2 + pandn xmm2, xmm1 + por xmm0, xmm2 + movdqu [r11], xmm0 + + add r11, rdx + add rsi, rax + add rdi, rdx + add rbx, 16 + + dec rcx + jnz next_vp8_masked_predictor_wmt + + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + +;unsigned int vp8_masked_predictor_uv_wmt( +; unsigned char *masked, +; unsigned char *unmasked, +; int src_stride, +; unsigned char *dst_ptr, +; int dst_stride, +; unsigned char *mask) +global sym(vp8_masked_predictor_uv_wmt) +sym(vp8_masked_predictor_uv_wmt): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 6 + push rsi + push rdi + ; end prolog + mov rsi, arg(0) ;src_ptr + mov rdi, arg(1) ;ref_ptr + + mov rbx, arg(5) ;mask + movsxd rax, dword ptr arg(2) ;src_stride + mov r11, arg(3) ; destination + movsxd rdx, dword ptr arg(4) ;dst_stride + + mov rcx, 8 + + pxor xmm3, xmm3 + +next_vp8_masked_predictor_uv_wmt: + movq xmm0, [rsi] + movq xmm1, [rdi] + movq xmm2, [rbx] + + pand xmm0, xmm2 + pandn xmm2, xmm1 + por xmm0, xmm2 + movq [r11], xmm0 + + add r11, rdx + add rsi, rax + add rdi, rax + add rbx, 8 + + dec rcx + jnz next_vp8_masked_predictor_uv_wmt + + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + + +;unsigned int vp8_uv_from_y_mask( +; unsigned char *ymask, +; unsigned char *uvmask) +global sym(vp8_uv_from_y_mask) +sym(vp8_uv_from_y_mask): + push rbp + mov rbp, rsp + SHADOW_ARGS_TO_STACK 6 + push rsi + push rdi + ; end prolog + mov rsi, arg(0) ;src_ptr + mov rdi, arg(1) ;dst_ptr + + + mov rcx, 8 + + pxor xmm3, xmm3 + +next_p8_uv_from_y_mask: + movdqu xmm0, [rsi] + pshufb xmm0, [shuf1b] ;[GLOBAL(shuf1b)] + movq [rdi],xmm0 + add rdi, 8 + add rsi,32 + + dec rcx + jnz next_p8_uv_from_y_mask + + ; begin epilog + pop rdi + pop rsi + UNSHADOW_ARGS + pop rbp + ret + +SECTION_RODATA +align 16 +shuf1b: + db 0, 2, 4, 6, 8, 10, 12, 14, 0, 0, 0, 0, 0, 0, 0, 0 + diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index e5830e88b..286659536 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -238,11 +238,13 @@ static const unsigned char mbsplit_fill_offset[4][16] = { - static void mb_mode_mv_init(VP8D_COMP *pbi) { vp8_reader *const bc = & pbi->bc; MV_CONTEXT *const mvc = pbi->common.fc.mvc; +#if CONFIG_SEGMENTATION + MACROBLOCKD *const xd = & pbi->mb; +#endif pbi->prob_skip_false = 0; if (pbi->common.mb_no_coeff_skip) @@ -277,6 +279,9 @@ static void mb_mode_mv_init(VP8D_COMP *pbi) } read_mvcontexts(bc, mvc); +#if CONFIG_SEGMENTATION + xd->temporal_update = vp8_read_bit(bc); +#endif } } @@ -287,7 +292,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, vp8_reader *const bc = & pbi->bc; MV_CONTEXT *const mvc = pbi->common.fc.mvc; const int mis = pbi->common.mode_info_stride; - +#if CONFIG_SEGMENTATION + MACROBLOCKD *const xd = & pbi->mb; + int sum; + int index = mb_row * pbi->common.mb_cols + mb_col; +#endif MV *const mv = & mbmi->mv.as_mv; int mb_to_left_edge; int mb_to_right_edge; @@ -298,7 +307,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mb_to_bottom_edge = pbi->mb.mb_to_bottom_edge; mb_to_top_edge -= LEFT_TOP_MARGIN; mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN; - mbmi->need_to_clamp_mvs = 0; /* Distance of Mb to the various image edges. * These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units @@ -313,7 +321,41 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, /* If required read in new segmentation data for this MB */ if (pbi->mb.update_mb_segmentation_map) - vp8_read_mb_features(bc, mbmi, &pbi->mb); + { +#if CONFIG_SEGMENTATION + if (xd->temporal_update) + { + sum = 0; + + if (mb_col != 0) + sum += (mi-1)->mbmi.segment_flag; + if (mb_row != 0) + sum += (mi-pbi->common.mb_cols)->mbmi.segment_flag; + + if (vp8_read(bc, xd->mb_segment_tree_probs[3+sum]) == 0) + { + mbmi->segment_id = pbi->segmentation_map[index]; + mbmi->segment_flag = 0; + } + else + { + vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb); + mbmi->segment_flag = 1; + pbi->segmentation_map[index] = mbmi->segment_id; + } + + } + else + { + vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb); + pbi->segmentation_map[index] = mbmi->segment_id; + } + index++; +#else + vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb); +#endif + } + /* Read the macroblock coeff skip flag if this feature is in use, else default to 0 */ if (pbi->common.mb_no_coeff_skip) diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 82841e8b8..20de9101a 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -573,7 +573,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) const unsigned char *data = (const unsigned char *)pbi->Source; const unsigned char *const 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; @@ -660,7 +659,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) /* Is segmentation enabled */ xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc); - if (xd->segmentation_enabled) { /* Signal whether or not the segmentation map is being explicitly updated this frame. */ @@ -696,9 +694,12 @@ int vp8_decode_frame(VP8D_COMP *pbi) { /* Which macro block level features are enabled */ vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - +#if CONFIG_SEGMENTATION /* Read the probs used to decode the segment id for each macro block. */ + for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++) +#else for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) +#endif { /* If not explicitly set value is defaulted to 255 by memset above */ if (vp8_read_bit(bc)) @@ -820,7 +821,6 @@ int vp8_decode_frame(VP8D_COMP *pbi) fclose(z); } - { /* read coef probability tree */ @@ -843,6 +843,11 @@ int vp8_decode_frame(VP8D_COMP *pbi) vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG)); vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG)); +#if CONFIG_SEGMENTATION + // Create the encoder segmentation map and set all entries to 0 + CHECK_MEM_ERROR(pbi->segmentation_map, vpx_calloc((pc->mb_rows * pc->mb_cols), 1)); +#endif + /* set up frame new frame for intra coded blocks */ #if CONFIG_MULTITHREAD if (!(pbi->b_multithreaded_rd) || pc->multi_token_partition == ONE_PARTITION || !(pc->filter_level)) diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index c22e0f28c..2d050512a 100755 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -44,23 +44,23 @@ typedef struct { INT16 min_val; INT16 Length; - UINT8 Probs[12]; + UINT8 Probs[14]; } TOKENEXTRABITS; */ DECLARE_ALIGNED(16, static const TOKENEXTRABITS, vp8d_token_extra_bits2[MAX_ENTROPY_TOKENS]) = { - { 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ZERO_TOKEN */ - { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ONE_TOKEN */ - { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* TWO_TOKEN */ - { 3, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* THREE_TOKEN */ - { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* FOUR_TOKEN */ - { 5, 0, { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY1 */ - { 7, 1, { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY2 */ - { 11, 2, { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY3 */ - { 19, 3, { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY4 */ - { 35, 4, { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY5 */ - { 67, 10, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254, 0 } }, /* DCT_VAL_CATEGORY6 */ + { 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ZERO_TOKEN */ + { 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* ONE_TOKEN */ + { 2, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* TWO_TOKEN */ + { 3, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* THREE_TOKEN */ + { 4, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* FOUR_TOKEN */ + { 5, 0, { 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY1 */ + { 7, 1, { 145, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY2 */ + { 11, 2, { 140, 148, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY3 */ + { 19, 3, { 135, 140, 155, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY4 */ + { 35, 4, { 130, 134, 141, 157, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* DCT_VAL_CATEGORY5 */ + { 67, 12, { 129, 130, 133, 140, 153, 177, 196, 230, 243, 249, 252, 254, 254, 0 } }, /* DCT_VAL_CATEGORY6 */ { 0, -1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* EOB TOKEN */ }; diff --git a/vp8/decoder/generic/dsystemdependent.c b/vp8/decoder/generic/dsystemdependent.c index 2406deaaf..f76653231 100644 --- a/vp8/decoder/generic/dsystemdependent.c +++ b/vp8/decoder/generic/dsystemdependent.c @@ -33,7 +33,16 @@ void vp8_dmachine_specific_config(VP8D_COMP *pbi) vp8_arch_x86_decode_init(pbi); #endif + #if ARCH_ARM vp8_arch_arm_decode_init(pbi); #endif + +#if CONFIG_EXTEND_QRANGE + pbi->dequant.idct_add = vp8_dequant_idct_add_c; + pbi->dequant.dc_idct_add = vp8_dequant_dc_idct_add_c; + pbi->dequant.dc_idct_add_y_block = vp8_dequant_dc_idct_add_y_block_c; + pbi->dequant.idct_add_y_block = vp8_dequant_idct_add_y_block_c; + pbi->dequant.idct_add_uv_block = vp8_dequant_idct_add_uv_block_c; +#endif } diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index ef2e00d61..4225798f4 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -50,7 +50,6 @@ void vp8dx_initialize() } } - VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) { VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP)); @@ -100,13 +99,17 @@ VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) return (VP8D_PTR) pbi; } - void vp8dx_remove_decompressor(VP8D_PTR ptr) { VP8D_COMP *pbi = (VP8D_COMP *) ptr; if (!pbi) return; +#if CONFIG_SEGMENTATION + // Delete sementation map + if (pbi->segmentation_map != 0) + vpx_free(pbi->segmentation_map); +#endif #if CONFIG_MULTITHREAD if (pbi->b_multithreaded_rd) @@ -395,6 +398,8 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show); } + vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show); + vp8_clear_system_state(); diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index ac1e332e8..70cb0fe3c 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -41,9 +41,9 @@ typedef struct typedef struct { - INT16 min_val; - INT16 Length; - UINT8 Probs[12]; + INT16 min_val; + INT16 Length; + UINT8 Probs[14]; } TOKENEXTRABITS; typedef struct @@ -81,7 +81,7 @@ typedef struct VP8Decompressor const unsigned char *Source; unsigned int source_sz; - + unsigned char *segmentation_map; unsigned int CPUFreq; unsigned int decode_microseconds; unsigned int time_decoding; @@ -95,7 +95,6 @@ typedef struct VP8Decompressor int current_mb_col_main; int decoding_thread_count; int allocated_decoding_thread_count; - int mt_baseline_filter_level[MAX_MB_SEGMENTS]; int sync_range; int *mt_current_mb_col; /* Each row remembers its already decoded column. */ diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index adbd10698..db883c7d6 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -20,7 +20,9 @@ #include "vp8/common/pragmas.h" #include "vpx_mem/vpx_mem.h" #include "bitstream.h" - +#if CONFIG_SEGMENTATION +static int segment_cost = 0; +#endif const int vp8cx_base_skip_false_prob[128] = { 255, 255, 255, 255, 255, 255, 255, 255, @@ -819,24 +821,39 @@ static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACRO case 0: vp8_write(w, 0, x->mb_segment_tree_probs[0]); vp8_write(w, 0, x->mb_segment_tree_probs[1]); +#if CONFIG_SEGMENTATION + segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]); +#endif break; case 1: vp8_write(w, 0, x->mb_segment_tree_probs[0]); vp8_write(w, 1, x->mb_segment_tree_probs[1]); +#if CONFIG_SEGMENTATION + segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[1]); +#endif break; case 2: vp8_write(w, 1, x->mb_segment_tree_probs[0]); vp8_write(w, 0, x->mb_segment_tree_probs[2]); +#if CONFIG_SEGMENTATION + segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[2]); +#endif break; case 3: vp8_write(w, 1, x->mb_segment_tree_probs[0]); vp8_write(w, 1, x->mb_segment_tree_probs[2]); +#if CONFIG_SEGMENTATION + segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[2]); +#endif break; // TRAP.. This should not happen default: vp8_write(w, 0, x->mb_segment_tree_probs[0]); vp8_write(w, 0, x->mb_segment_tree_probs[1]); +#if CONFIG_SEGMENTATION + segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]); +#endif break; } } @@ -848,7 +865,13 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) VP8_COMMON *const pc = & cpi->common; vp8_writer *const w = & cpi->bc; const MV_CONTEXT *mvc = pc->fc.mvc; - + MACROBLOCKD *xd = &cpi->mb.e_mbd; +#if CONFIG_SEGMENTATION + int left_id, above_id; + int i; + int sum; + int index = 0; +#endif const int *const rfct = cpi->count_mb_ref_frame_usage; const int rf_intra = rfct[INTRA_FRAME]; const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; @@ -905,7 +928,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) update_mbintra_mode_probs(cpi); vp8_write_mvprobs(cpi); - +#if CONFIG_SEGMENTATION + vp8_write_bit(w, (xd->temporal_update) ? 1:0); +#endif while (++mb_row < pc->mb_rows) { int mb_col = -1; @@ -916,7 +941,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) const MV_REFERENCE_FRAME rf = mi->ref_frame; const MB_PREDICTION_MODE mode = mi->mode; - MACROBLOCKD *xd = &cpi->mb.e_mbd; + //MACROBLOCKD *xd = &cpi->mb.e_mbd; // Distance of Mb to the various image edges. // These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units @@ -924,13 +949,46 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3; xd->mb_to_top_edge = -((mb_row * 16)) << 3; xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3; - + xd->up_available = (mb_row != 0); + xd->left_available = (mb_col != 0); #ifdef ENTROPY_STATS active_section = 9; #endif if (cpi->mb.e_mbd.update_mb_segmentation_map) + { +#if CONFIG_SEGMENTATION + if (xd->temporal_update) + { + sum = 0; + if (mb_col != 0) + sum += (m-1)->mbmi.segment_flag; + if (mb_row != 0) + sum += (m-pc->mb_cols)->mbmi.segment_flag; + + if (m->mbmi.segment_flag == 0) + { + vp8_write(w,0,xd->mb_segment_tree_probs[3+sum]); + segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[3+sum]); + } + else + { + vp8_write(w,1,xd->mb_segment_tree_probs[3+sum]); + segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[3+sum]); + write_mb_features(w, mi, &cpi->mb.e_mbd); + cpi->segmentation_map[index] = mi->segment_id; + } + } + else + { + write_mb_features(w, mi, &cpi->mb.e_mbd); + cpi->segmentation_map[index] = mi->segment_id; + } + index++; +#else write_mb_features(w, mi, &cpi->mb.e_mbd); +#endif + } if (pc->mb_no_coeff_skip) vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false); @@ -1058,7 +1116,11 @@ static void write_kfmodes(VP8_COMP *cpi) const VP8_COMMON *const c = & cpi->common; /* const */ MODE_INFO *m = c->mi; - +#if CONFIG_SEGMENTATION + int left_id, above_id; + int i; + int index = 0; +#endif int mb_row = -1; int prob_skip_false = 0; @@ -1083,9 +1145,22 @@ static void write_kfmodes(VP8_COMP *cpi) while (++mb_col < c->mb_cols) { const int ym = m->mbmi.mode; - +#if CONFIG_SEGMENTATION + MACROBLOCKD *xd = &cpi->mb.e_mbd; + xd->up_available = (mb_row != 0); + xd->left_available = (mb_col != 0); +#endif if (cpi->mb.e_mbd.update_mb_segmentation_map) + { +#if CONFIG_SEGMENTATION + + write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd); + cpi->segmentation_map[index] = m->mbmi.segment_id; + index++; +#else write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd); +#endif + } if (c->mb_no_coeff_skip) vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false); @@ -1411,6 +1486,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) else vp8_start_encode(bc, cx_data); + xd->update_mb_segmentation_map = 1; // Signal whether or not Segmentation is enabled vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0); @@ -1461,8 +1537,12 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) if (xd->update_mb_segmentation_map) { + #if CONFIG_SEGMENTATION // Write the probs used to decode the segment id for each macro block. + for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++) +#else for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) +#endif { int Data = xd->mb_segment_tree_probs[i]; @@ -1632,7 +1712,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) active_section = 1; #endif } - +#if CONFIG_SEGMENTATION + //printf("%d\n",segment_cost); +#endif vp8_stop_encode(bc); oh.first_partition_length_in_bytes = cpi->bc.pos; diff --git a/vp8/encoder/dct.c b/vp8/encoder/dct.c index b5a11ae34..69a882c89 100644 --- a/vp8/encoder/dct.c +++ b/vp8/encoder/dct.c @@ -10,7 +10,7 @@ #include <math.h> - +#include "vpx_ports/config.h" void vp8_short_fdct4x4_c(short *input, short *output, int pitch) { int i; @@ -20,11 +20,17 @@ void vp8_short_fdct4x4_c(short *input, short *output, int pitch) for (i = 0; i < 4; i++) { +#if CONFIG_EXTEND_QRANGE + a1 = ((ip[0] + ip[3])<<5); + b1 = ((ip[1] + ip[2])<<5); + c1 = ((ip[1] - ip[2])<<5); + d1 = ((ip[0] - ip[3])<<5); +#else a1 = ((ip[0] + ip[3])<<3); b1 = ((ip[1] + ip[2])<<3); c1 = ((ip[1] - ip[2])<<3); d1 = ((ip[0] - ip[3])<<3); - +#endif op[0] = a1 + b1; op[2] = a1 - b1; @@ -72,12 +78,22 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch) for (i = 0; i < 4; i++) { +#if !CONFIG_EXTEND_QRANGE a1 = ((ip[0] + ip[2])<<2); d1 = ((ip[1] + ip[3])<<2); c1 = ((ip[1] - ip[3])<<2); b1 = ((ip[0] - ip[2])<<2); op[0] = a1 + d1 + (a1!=0); +#else + a1 = ((ip[0] + ip[2])); + d1 = ((ip[1] + ip[3])); + c1 = ((ip[1] - ip[3])); + b1 = ((ip[0] - ip[2])); + + + op[0] = a1 + d1; +#endif op[1] = b1 + c1; op[2] = b1 - c1; op[3] = a1 - d1; @@ -105,11 +121,17 @@ void vp8_short_walsh4x4_c(short *input, short *output, int pitch) c2 += c2<0; d2 += d2<0; +#if !CONFIG_EXTEND_QRANGE op[0] = (a2+3) >> 3; op[4] = (b2+3) >> 3; op[8] = (c2+3) >> 3; op[12]= (d2+3) >> 3; - +#else + op[0] = (a2+1) >> 2; + op[4] = (b2+1) >> 2; + op[8] = (c2+1) >> 2; + op[12]= (d2+1) >> 2; +#endif ip++; op++; } diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index ab4071d35..61c273c7a 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -30,6 +30,7 @@ #include "vp8/common/subpixel.h" #include "vpx_ports/vpx_timer.h" + #if CONFIG_RUNTIME_CPU_DETECT #define RTCD(x) &cpi->common.rtcd.x #define IF_RTCD(x) (x) @@ -37,6 +38,13 @@ #define RTCD(x) NULL #define IF_RTCD(x) NULL #endif + +#if CONFIG_SEGMENTATION +#define SEEK_SEGID 12 +#define SEEK_SAMEID 4 +#define SEEK_DIFFID 7 +#endif + extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ; extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex); @@ -479,7 +487,10 @@ void encode_mb_row(VP8_COMP *cpi, int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride; int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride; int seg_map_index = (mb_row * cpi->common.mb_cols); - +#if CONFIG_SEGMENTATION + int left_id, above_id; + int sum; +#endif #if CONFIG_MULTITHREAD const int nsync = cpi->mt_sync_range; const int rightmost_col = cm->mb_cols - 1; @@ -490,7 +501,6 @@ void encode_mb_row(VP8_COMP *cpi, else last_row_current_mb_col = &rightmost_col; #endif - // reset above block coeffs xd->above_context = cm->above_context; @@ -564,6 +574,7 @@ void encode_mb_row(VP8_COMP *cpi, xd->mode_info_context->mbmi.segment_id = 0; vp8cx_mb_init_quantizer(cpi, x); + } else xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default @@ -627,6 +638,11 @@ void encode_mb_row(VP8_COMP *cpi, x->gf_active_ptr++; // Increment pointer into gf useage flags structure for next mb + if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) + xd->mode_info_context->mbmi.segment_id = 0; + else + xd->mode_info_context->mbmi.segment_id = 1; + for (i = 0; i < 16; i++) vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi)); @@ -638,9 +654,42 @@ void encode_mb_row(VP8_COMP *cpi, recon_yoffset += 16; recon_uvoffset += 8; - // Keep track of segment useage - segment_counts[xd->mode_info_context->mbmi.segment_id] ++; +#if CONFIG_SEGMENTATION + //cpi->segmentation_map[mb_row * cm->mb_cols + mb_col] = xd->mbmi.segment_id; + if (cm->frame_type == KEY_FRAME) + { + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; + } + else + { + sum = 0; + if (mb_col != 0) + sum += (xd->mode_info_context-1)->mbmi.segment_flag; + if (mb_row != 0) + sum += (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag; + + if (xd->mode_info_context->mbmi.segment_id == cpi->segmentation_map[(mb_row*cm->mb_cols) + mb_col]) + xd->mode_info_context->mbmi.segment_flag = 0; + else + xd->mode_info_context->mbmi.segment_flag = 1; + if (xd->mode_info_context->mbmi.segment_flag == 0) + { + segment_counts[SEEK_SAMEID + sum]++; + segment_counts[10]++; + } + else + { + segment_counts[SEEK_DIFFID + sum]++; + segment_counts[11]++; + //calculate individual segment ids + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; + } + } + segment_counts[SEEK_SEGID + xd->mode_info_context->mbmi.segment_id] ++; +#else + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; +#endif // skip to next mb xd->mode_info_context++; x->partition_info++; @@ -665,7 +714,6 @@ void encode_mb_row(VP8_COMP *cpi, xd->mode_info_context++; x->partition_info++; x->activity_sum += activity_sum; - #if CONFIG_MULTITHREAD if ((cpi->b_multi_threaded != 0) && (mb_row == cm->mb_rows - 1)) { @@ -673,7 +721,6 @@ void encode_mb_row(VP8_COMP *cpi, } #endif } - void vp8_encode_frame(VP8_COMP *cpi) { int mb_row; @@ -682,7 +729,13 @@ void vp8_encode_frame(VP8_COMP *cpi) MACROBLOCKD *const xd = & x->e_mbd; TOKENEXTRA *tp = cpi->tok; +#if CONFIG_SEGMENTATION + int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID]; + int prob[3]; + int new_cost, original_cost; +#else int segment_counts[MAX_MB_SEGMENTS]; +#endif int totalrate; // Functions setup for all frame types so we can use MC in AltRef @@ -762,7 +815,7 @@ void vp8_encode_frame(VP8_COMP *cpi) vp8_auto_select_speed(cpi); } - vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q)); + vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q); vp8cx_initialize_me_consts(cpi, cm->base_qindex); // Copy data over into macro block data sturctures. @@ -894,41 +947,126 @@ void vp8_encode_frame(VP8_COMP *cpi) } - // Work out the segment probabilites if segmentation is enabled if (xd->segmentation_enabled) { int tot_count; - int i; + int i,j; + int count1,count2,count3,count4; // Set to defaults vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs)); +#if CONFIG_SEGMENTATION + + tot_count = segment_counts[12] + segment_counts[13] + segment_counts[14] + segment_counts[15]; + count1 = segment_counts[12] + segment_counts[13]; + count2 = segment_counts[14] + segment_counts[15]; + + if (tot_count) + prob[0] = (count1 * 255) / tot_count; + + if (count1 > 0) + prob[1] = (segment_counts[12] * 255) /count1; + + if (count2 > 0) + prob[2] = (segment_counts[14] * 255) /count2; + + if (cm->frame_type != KEY_FRAME) + { + tot_count = segment_counts[4] + segment_counts[7]; + if (tot_count) + xd->mb_segment_tree_probs[3] = (segment_counts[4] * 255)/tot_count; + + tot_count = segment_counts[5] + segment_counts[8]; + if (tot_count) + xd->mb_segment_tree_probs[4] = (segment_counts[5] * 255)/tot_count; + + tot_count = segment_counts[6] + segment_counts[9]; + if (tot_count) + xd->mb_segment_tree_probs[5] = (segment_counts[6] * 255)/tot_count; + } tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3]; + count3 = segment_counts[0] + segment_counts[1]; + count4 = segment_counts[2] + segment_counts[3]; if (tot_count) + xd->mb_segment_tree_probs[0] = (count3 * 255) / tot_count; + + if (count3 > 0) + xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count3; + + if (count4 > 0) + xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count4; + + for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++) { - xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count; + if (xd->mb_segment_tree_probs[i] == 0) + xd->mb_segment_tree_probs[i] = 1; + } - tot_count = segment_counts[0] + segment_counts[1]; + original_cost = count1 * vp8_cost_zero(prob[0]) + count2 * vp8_cost_one(prob[0]); - if (tot_count > 0) - { - xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count; - } + if (count1 > 0) + original_cost += segment_counts[12] * vp8_cost_zero(prob[1]) + segment_counts[13] * vp8_cost_one(prob[1]); + + if (count2 > 0) + original_cost += segment_counts[14] * vp8_cost_zero(prob[2]) + segment_counts[15] * vp8_cost_one(prob[2]) ; - tot_count = segment_counts[2] + segment_counts[3]; + new_cost = 0; - if (tot_count > 0) - xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count; + if (cm->frame_type != KEY_FRAME) + { + new_cost = segment_counts[4] * vp8_cost_zero(xd->mb_segment_tree_probs[3]) + segment_counts[7] * vp8_cost_one(xd->mb_segment_tree_probs[3]); + + new_cost += segment_counts[5] * vp8_cost_zero(xd->mb_segment_tree_probs[4]) + segment_counts[8] * vp8_cost_one(xd->mb_segment_tree_probs[4]); + + new_cost += segment_counts[6] * vp8_cost_zero(xd->mb_segment_tree_probs[5]) + segment_counts[9] * vp8_cost_one (xd->mb_segment_tree_probs[5]); + } - // Zero probabilities not allowed - for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++) + if (tot_count > 0) + new_cost += count3 * vp8_cost_zero(xd->mb_segment_tree_probs[0]) + count4 * vp8_cost_one(xd->mb_segment_tree_probs[0]); + + if (count3 > 0) + new_cost += segment_counts[0] * vp8_cost_zero(xd->mb_segment_tree_probs[1]) + segment_counts[1] * vp8_cost_one(xd->mb_segment_tree_probs[1]); + + if (count4 > 0) + new_cost += segment_counts[2] * vp8_cost_zero(xd->mb_segment_tree_probs[2]) + segment_counts[3] * vp8_cost_one(xd->mb_segment_tree_probs[2]) ; + + if (new_cost < original_cost) + xd->temporal_update = 1; + else + { + xd->temporal_update = 0; + xd->mb_segment_tree_probs[0] = prob[0]; + xd->mb_segment_tree_probs[1] = prob[1]; + xd->mb_segment_tree_probs[2] = prob[2]; + } +#else + tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3]; + count1 = segment_counts[0] + segment_counts[1]; + count2 = segment_counts[2] + segment_counts[3]; + + if (tot_count) + xd->mb_segment_tree_probs[0] = (count1 * 255) / tot_count; + + if (count1 > 0) + xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count1; + + if (count2 > 0) + xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2; + +#endif + // Zero probabilities not allowed +#if CONFIG_SEGMENTATION + for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++) +#else + for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) +#endif { if (xd->mb_segment_tree_probs[i] == 0) xd->mb_segment_tree_probs[i] = 1; } - } } // 256 rate units to the bit diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c index 463dbcaa9..e18b85e43 100644 --- a/vp8/encoder/encodemb.c +++ b/vp8/encoder/encodemb.c @@ -246,7 +246,11 @@ struct vp8_token_state{ // TODO: experiments to find optimal multiple numbers #define Y1_RD_MULT 4 #define UV_RD_MULT 2 +#if !CONFIG_EXTEND_QRANGE #define Y2_RD_MULT 16 +#else +#define Y2_RD_MULT 4 +#endif static const int plane_rd_mult[4]= { diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c index f5006ddab..8aef915b8 100644 --- a/vp8/encoder/ethreading.c +++ b/vp8/encoder/ethreading.c @@ -116,7 +116,7 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data) for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { int seg_map_index = (mb_row * cm->mb_cols); - + if ((mb_col & (nsync - 1)) == 0) { while (mb_col > (*last_row_current_mb_col - nsync) && *last_row_current_mb_col != cm->mb_cols - 1) diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c index 8f24a11a0..cbe50058f 100644 --- a/vp8/encoder/firstpass.c +++ b/vp8/encoder/firstpass.c @@ -537,7 +537,7 @@ void vp8_first_pass(VP8_COMP *cpi) //if ( 0 ) { int flag[2] = {1, 1}; - vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q)); + vp8_initialize_rd_consts(cpi, cm->base_qindex+cm->y1dc_delta_q); vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context)); vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag); } diff --git a/vp8/encoder/generic/csystemdependent.c b/vp8/encoder/generic/csystemdependent.c index 1d672bef9..2f597619f 100644 --- a/vp8/encoder/generic/csystemdependent.c +++ b/vp8/encoder/generic/csystemdependent.c @@ -114,4 +114,12 @@ void vp8_cmachine_specific_config(VP8_COMP *cpi) vp8_arch_arm_encoder_init(cpi); #endif +#if CONFIG_EXTEND_QRANGE + cpi->rtcd.fdct.short4x4 = vp8_short_fdct4x4_c; + cpi->rtcd.fdct.short8x4 = vp8_short_fdct8x4_c; + cpi->rtcd.fdct.fast4x4 = vp8_short_fdct4x4_c; + cpi->rtcd.fdct.fast8x4 = vp8_short_fdct8x4_c; + cpi->rtcd.fdct.walsh_short4x4 = vp8_short_walsh4x4_c; +#endif + } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index a18447d51..87f0f1853 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -151,7 +151,7 @@ extern const int qrounding_factors[129]; extern const int qzbin_factors[129]; extern void vp8cx_init_quantizer(VP8_COMP *cpi); extern const int vp8cx_base_skip_false_prob[128]; - +#if !CONFIG_EXTEND_QRANGE // Tables relating active max Q to active min Q static const int kf_low_motion_minq[QINDEX_RANGE] = { @@ -219,7 +219,76 @@ static const int inter_minq[QINDEX_RANGE] = 71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85, 86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 }; +#else +static const int kf_low_motion_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, + 9, 9, 9, 10,10,11,11,12,12,13,13,14,14,15,15,16, + 16,17,17,18,18,19,19,20,20,21,21,22,23,23,24,24, + 25,25,26,27,28,29,30,30,31,32,33,34,35,35,36,36, + 38,38,39,40,40,41,42,42,43,44,44,45,46,46,47,48, + 49,49,50,50,51,52,52,53,54,55,56,57,58,59,60,61, +}; +static const int kf_high_motion_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,10,10, + 11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,24, + 25,26,27,28,28,29,29,30,30,31,31,32,33,33,34,34, + 35,36,37,38,39,39,40,41,41,42,43,44,45,45,46,46, + 47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54, + 55,55,56,56,57,58,59,60,61,62,63,64,65,67,69,70, +}; + +static const int gf_low_motion_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, + 10,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17, + 17,18,18,19,19,20,21,22,23,24,25,26,27,29,29,30, + 31,32,33,34,35,36,37,38,39,40,41,41,42,42,43,43, + 44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51, + 52,52,53,53,54,54,55,55,56,56,57,57,58,59,60,61, + 62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, +}; +static const int gf_mid_motion_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, + 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,10, + 10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18, + 18,19,19,20,20,21,22,23,24,25,26,27,28,29,30,31, + 32,33,34,35,35,36,36,37,37,38,38,39,39,40,40,41, + 41,42,42,43,43,44,44,45,45,46,46,47,48,49,50,51, + 52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67, + 68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83, +}; +static const int gf_high_motion_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, + 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, 9,10,10, + 11,11,12,12,13,14,15,16,17,18,18,19,19,20,20,21, + 22,23,24,25,26,26,27,28,29,30,31,32,33,34,35,36, + 37,38,39,39,40,40,40,41,41,41,42,42,43,43,44,44, + 44,45,45,45,46,46,47,47,47,48,48,48,49,49,49,50, + 50,50,51,51,52,53,54,54,55,56,57,57,58,59,60,61, + 62,63,64,66,68,69,72,74,77,80,82,85,87,89,91,93, +}; +static const int inter_minq[QINDEX_RANGE] = +{ + 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 8, 9,10,11,12,13,14,15,16,17,18,18,19,19,20,21, + 21,22,23,23,24,25,26,26,27,28,29,30,31,32,32,33, + 34,35,36,36,37,38,39,40,40,41,41,42,43,44,44,45, + 46,46,47,47,48,49,49,50,50,51,52,52,53,54,54,55, + 55,56,57,57,58,59,60,60,61,62,63,63,64,65,66,67, + 68,68,69,70,71,72,72,73,74,75,76,77,78,79,80,81, + 81,82,83,84,85,86,87,88,89,90,90,91,92,93,94,95, +}; +#endif void vp8_initialize() { static int init_done = 0; @@ -342,7 +411,6 @@ static void set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_map) // Copy in the new segmentation map vpx_memcpy(cpi->segmentation_map, segmentation_map, (cpi->common.mb_rows * cpi->common.mb_cols)); - // Signal that the map should be updated. cpi->mb.e_mbd.update_mb_segmentation_map = 1; cpi->mb.e_mbd.update_mb_segmentation_data = 1; @@ -368,12 +436,10 @@ static void set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned ch static void segmentation_test_function(VP8_PTR ptr) { VP8_COMP *cpi = (VP8_COMP *)(ptr); - unsigned char *seg_map; signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS]; - + CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); // Create a temporary map for segmentation data. - CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); // MB loop to set local segmentation map /*for ( i = 0; i < cpi->common.mb_rows; i++ ) @@ -433,7 +499,7 @@ static void cyclic_background_refresh(VP8_COMP *cpi, int Q, int lf_adjustment) int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols; // Create a temporary map for segmentation data. - CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); + CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); cpi->cyclic_refresh_q = Q; @@ -1879,7 +1945,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) CHECK_MEM_ERROR(cpi->lf_ref_frame, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int))); // Create the encoder segmentation map and set all entries to 0 - CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); + CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols)); cpi->active_map_enabled = 0; @@ -1915,13 +1981,12 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) cpi->cyclic_refresh_q = 32; if (cpi->cyclic_refresh_mode_enabled) - { CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); - } else cpi->cyclic_refresh_map = (signed char *) NULL; // Test function for segmentation + //segmentation_test_function((VP8_PTR) cpi); #ifdef ENTROPY_STATS @@ -3138,6 +3203,12 @@ static int decide_key_frame(VP8_COMP *cpi) return code_key_frame; } +#if !CONFIG_EXTEND_QRANGE +#define FIRSTPASS_QINDEX 26 +#else +#define FIRSTPASS_QINDEX 49 +#endif + #if !(CONFIG_REALTIME_ONLY) static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) @@ -3357,6 +3428,10 @@ static void encode_frame_to_data_rate // Test code for segmentation of gf/arf (0,0) //segmentation_test_function((VP8_PTR) cpi); +#if CONFIG_SEGMENTATION + cpi->mb.e_mbd.segmentation_enabled = 1; + cpi->mb.e_mbd.update_mb_segmentation_map = 1; +#endif #if CONFIG_REALTIME_ONLY if(cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME) @@ -3890,6 +3965,17 @@ static void encode_frame_to_data_rate vp8_clear_system_state(); //__asm emms; +#if 0 + if (cpi->pass != 1) + { + FILE *f = fopen("q_used.stt", "a"); + fprintf(f, "%4d, %4d, %8d\n", cpi->common.current_video_frame, + cpi->common.base_qindex, cpi->projected_frame_size); + fclose(f); + } +#endif + + // Test to see if the stats generated for this frame indicate that we should have coded a key frame // (assuming that we didn't)! if (cpi->pass != 2 && cpi->oxcf.auto_key && cm->frame_type != KEY_FRAME) @@ -4586,10 +4672,15 @@ static void encode_frame_to_data_rate fclose(recon_file); } #endif - +#if 0 // DEBUG - //vp8_write_yuv_frame("encoder_recon.yuv", cm->frame_to_show); - + if(cm->current_video_frame>173 && cm->current_video_frame<178) + { + char filename[512]; + sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame); + vp8_write_yuv_frame(filename, cm->frame_to_show); + } +#endif } @@ -5178,7 +5269,15 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon cpi->summed_quality += frame_ssim2 * weight; cpi->summed_weights += weight; - +#if 0 + { + FILE *f = fopen("q_used.stt", "a"); + fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n", + cpi->common.current_video_frame,y2, u2, v2, + frame_psnr2, frame_ssim2); + fclose(f); + } +#endif } } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 0e53f6803..9c363598a 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -195,7 +195,11 @@ typedef struct typedef struct { MACROBLOCK mb; +#if CONFIG_SEGMENTATION + int segment_counts[MAX_MB_SEGMENTS + 8]; +#else int segment_counts[MAX_MB_SEGMENTS]; +#endif int totalrate; } MB_ROW_COMP; diff --git a/vp8/encoder/psnr.c b/vp8/encoder/psnr.c index 5119bb8aa..7ecf6d7cd 100644 --- a/vp8/encoder/psnr.c +++ b/vp8/encoder/psnr.c @@ -13,7 +13,7 @@ #include "math.h" #include "vp8/common/systemdependent.h" /* for vp8_clear_system_state() */ -#define MAX_PSNR 60 +#define MAX_PSNR 100 double vp8_mse2psnr(double Samples, double Peak, double Mse) { diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 9821d2990..f3bcf9921 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -48,6 +48,7 @@ extern int inter_b_modes[10]; // Work in progress recalibration of baseline rate tables based on // the assumption that bits per mb is inversely proportional to the // quantizer value. +#if !CONFIG_EXTEND_QRANGE const int vp8_bits_per_mb[2][QINDEX_RANGE] = { // Intra case 450000/Qintra @@ -89,10 +90,54 @@ const int vp8_bits_per_mb[2][QINDEX_RANGE] = 11445, 11220, 11003, 10795, 10594, 10401, 10215, 10035, } }; +#else +const int vp8_bits_per_mb[2][QINDEX_RANGE] = +{ + // (Updated DEC 2010) Baseline estimate of Bits Per MB at each Q: + // 4500000/Qintra + { + 4500000,3600000,3000000,2571428,2250000,2000000,1800000,1636363, + 1500000,1384615,1285714,1200000,1125000,1058823,1000000, 947368, + 900000, 818181, 750000, 692307, 642857, 600000, 562500, 529411, + 500000, 473684, 450000, 428571, 409090, 391304, 375000, 352941, + 333333, 315789, 300000, 285714, 272727, 260869, 250000, 236842, + 225000, 214285, 204545, 195652, 187500, 180000, 171428, 163636, + 156521, 150000, 144000, 138461, 133333, 128571, 123287, 118421, + 113924, 109756, 105882, 102272, 98901, 95744, 92783, 90000, + 87378, 84905, 82568, 80357, 77586, 75000, 72580, 70312, + 68181, 66176, 64285, 62500, 60810, 59210, 57692, 56250, + 54545, 52941, 51428, 50000, 48648, 47368, 45918, 44554, + 43269, 42056, 40909, 39647, 38461, 37344, 36290, 35294, + 34351, 33333, 32374, 31468, 30612, 29801, 28938, 28125, + 27355, 26627, 25862, 25139, 24456, 23809, 23195, 22613, + 21951, 21327, 20737, 20179, 19650, 19067, 18518, 18000, + 17441, 16917, 16423, 15957, 15410, 14900, 14376, 13846, + }, + //2850000/Qinter + { + 2850000,2280000,1900000,1628571,1425000,1266666,1140000,1036363, + 950000, 876923, 814285, 760000, 712500, 670588, 633333, 600000, + 570000, 518181, 475000, 438461, 407142, 380000, 356250, 335294, + 316666, 300000, 285000, 271428, 259090, 247826, 237500, 223529, + 211111, 200000, 190000, 180952, 172727, 165217, 158333, 150000, + 142500, 135714, 129545, 123913, 118750, 114000, 108571, 103636, + 99130, 95000, 91200, 87692, 84444, 81428, 78082, 75000, + 72151, 69512, 67058, 64772, 62637, 60638, 58762, 57000, + 55339, 53773, 52293, 50892, 49137, 47500, 45967, 44531, + 43181, 41911, 40714, 39583, 38513, 37500, 36538, 35625, + 34545, 33529, 32571, 31666, 30810, 30000, 29081, 28217, + 27403, 26635, 25909, 25110, 24358, 23651, 22983, 22352, + 21755, 21111, 20503, 19930, 19387, 18874, 18327, 17812, + 17325, 16863, 16379, 15921, 15489, 15079, 14690, 14321, + 13902, 13507, 13133, 12780, 12445, 12076, 11728, 11400, + 11046, 10714, 10401, 10106, 9760, 9437, 9105, 8769, + } + }; + #endif static const int kf_boost_qadjustment[QINDEX_RANGE] = -{ - 128, 129, 130, 131, 132, 133, 134, 135, + { + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 863b6d419..078837595 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -160,6 +160,48 @@ static int rd_iifactor [ 32 ] = { 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; +// 3* dc_qlookup[Q]*dc_qlookup[Q]; +#if !CONFIG_EXTEND_QRANGE +static int rdmult_lut[QINDEX_RANGE]= +{ + 48,75,108,147,192,243,300,300, + 363,432,507,588,675,768,867,867, + 972,1083,1200,1200,1323,1323,1452,1452, + 1587,1587,1728,1875,1875,2028,2187,2352, + 2523,2700,2883,3072,3267,3468,3675,3888, + 4107,4107,4332,4563,4800,5043,5292,5547, + 5808,6075,6348,6348,6627,6912,7203,7500, + 7803,8112,8427,8748,9075,9408,9747,10092, + 10443,10800,11163,11532,11907,12288,12675,13068, + 13467,13872,14283,14700,15123,15552,15987,16428, + 16875,17328,17328,17787,18252,18723,19200,19683, + 20172,20667,21168,21675,22188,22707,23232,23763, + 24843,25947,27075,27648,28812,30000,30603,31212, + 32448,33708,34992,36300,37632,38988,40368,41772, + 44652,46128,47628,49152,50700,52272,53868,55488, + 57132,58800,61347,63075,65712,68403,71148,73947, +}; +#else +static int rdmult_lut[QINDEX_RANGE]= +{ + 3,5,7,9,12,15,19,23, + 27,32,37,42,48,54,61,68, + 75,83,91,99,108,117,127,137, + 147,169,192,217,243,271,300,331, + 363,397,450,507,567,631,698,768, + 842,919,999,1083,1170,1261,1355,1452, + 1587,1728,1875,2028,2187,2352,2523,2700, + 2883,3072,3267,3468,3675,3888,4107,4332, + 4563,4800,5043,5292,5547,5808,6075,6348, + 6627,6912,7203,7500,7880,8269,8667,9075, + 9492,9919,10355,10800,11255,11719,12192,12675, + 13167,13669,14180,14700,15230,15769,16317,16875, + 18019,19200,20419,21675,22969,24300,25669,27075, + 28519,30000,31519,33075,34669,36300,37969,39675, + 41772,43923,46128,48387,50700,53067,55488,57963, + 61347,64827,69312,73947,78732,83667,89787,97200, +}; +#endif /* values are now correlated to quantizer */ static int sad_per_bit16lut[QINDEX_RANGE] = @@ -207,12 +249,16 @@ void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex) cpi->mb.sadperbit4 = sad_per_bit4lut[QIndex]; } -void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue) + + + + +void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex) { int q; int i; - double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0; - double rdconst = 3.00; + int *thresh; + int threshmult; vp8_clear_system_state(); //__asm emms; @@ -220,7 +266,8 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue) // for key frames, golden frames and arf frames. // if (cpi->common.refresh_golden_frame || // cpi->common.refresh_alt_ref_frame) - cpi->RDMULT = (int)(rdconst * (capped_q * capped_q)); + QIndex=(QIndex<0)? 0 : ((QIndex>127)?127 : QIndex); + cpi->RDMULT = rdmult_lut[QIndex]; // Extend rate multiplier along side quantizer zbin increases if (cpi->zbin_over_quant > 0) @@ -231,8 +278,7 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue) // Experimental code using the same basic equation as used for Q above // The units of cpi->zbin_over_quant are 1/128 of Q bin size oq_factor = 1.0 + ((double)0.0015625 * cpi->zbin_over_quant); - modq = (int)((double)capped_q * oq_factor); - cpi->RDMULT = (int)(rdconst * (modq * modq)); + cpi->RDMULT = (int)((double)cpi->RDMULT * oq_factor * oq_factor); } if (cpi->pass == 2 && (cpi->common.frame_type != KEY_FRAME)) @@ -243,19 +289,34 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue) cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->next_iiratio]) >> 4; } +#if !CONFIG_EXTEND_QRANGE +#else + if (cpi->RDMULT < 7) + cpi->RDMULT = 7; +#endif cpi->mb.errorperbit = (cpi->RDMULT / 100); cpi->mb.errorperbit += (cpi->mb.errorperbit==0); +#if CONFIG_EXTEND_QRANGE + if(cpi->mb.errorperbit<1) + cpi->mb.errorperbit=1; +#endif vp8_set_speed_features(cpi); if (cpi->common.simpler_lpf) cpi->common.filter_type = SIMPLE_LOOPFILTER; - q = (int)pow(Qvalue, 1.25); + q = (int)pow(vp8_dc_quant(QIndex,0), 1.25); if (q < 8) q = 8; + + +#if CONFIG_EXTEND_QRANGE + cpi->RDMULT *= 16; +#endif + if (cpi->RDMULT > 1000) { cpi->RDDIV = 1; @@ -999,6 +1060,10 @@ static unsigned int vp8_encode_inter_mb_segment(MACROBLOCK *x, int const *labels return distortion; } +#if CONFIG_EXTEND_QRANGE + d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff)<<2; +#else +#endif static const unsigned int segmentation_to_sseshift[4] = {3, 3, 2, 0}; diff --git a/vp8/vp8_common.mk b/vp8/vp8_common.mk index 2a2f0cfad..54a7eacab 100644 --- a/vp8/vp8_common.mk +++ b/vp8/vp8_common.mk @@ -99,6 +99,11 @@ VP8_COMMON_SRCS-$(HAVE_SSE2) += common/x86/postproc_sse2.asm endif VP8_COMMON_SRCS-$(ARCH_ARM) += common/asm_com_offsets.c +ifeq ($(CONFIG_CSM),yes) +VP8_COMMON_SRCS-yes += common/maskingmv.c +VP8_COMMON_SRCS-$(HAVE_SSE3) += common/x86/mask_sse3.asm +endif + VP8_COMMON_SRCS-$(ARCH_ARM) += common/arm/arm_systemdependent.c # common (c) diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 2622738ec..1399f1b8c 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -37,6 +37,7 @@ struct vp8_extracfg unsigned int arnr_max_frames; /* alt_ref Noise Reduction Max Frame Count */ unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */ unsigned int arnr_type; /* alt_ref filter type */ + unsigned int experimental; vp8e_tuning tuning; unsigned int cq_level; /* constrained quality level */ @@ -69,6 +70,7 @@ static const struct extraconfig_map extracfg_map[] = 0, /* arnr_max_frames */ 3, /* arnr_strength */ 3, /* arnr_type*/ + 0, /* experimental mode */ 0, /* tuning*/ 10, /* cq_level */ } @@ -250,7 +252,8 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, struct vp8_extracfg vp8_cfg) { oxcf->multi_threaded = cfg.g_threads; - oxcf->Version = cfg.g_profile; + oxcf->Version = cfg.g_profile; + oxcf->Version |= vp8_cfg.experimental? 0x4 : 0; oxcf->Width = cfg.g_w; oxcf->Height = cfg.g_h; @@ -479,7 +482,10 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, return res; #undef MAP } -static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) + + +static vpx_codec_err_t vp8e_common_init(vpx_codec_ctx_t *ctx, + int experimental) { vpx_codec_err_t res = VPX_DEC_OK; struct vpx_codec_alg_priv *priv; @@ -524,6 +530,7 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) priv->vp8_cfg = extracfg_map[i].cfg; priv->vp8_cfg.pkt_list = &priv->pkt_list.head; + priv->vp8_cfg.experimental = experimental; priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 2; @@ -559,6 +566,21 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) return res; } + +static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx) +{ + return vp8e_common_init(ctx, 0); +} + + +#if CONFIG_EXPERIMENTAL +static vpx_codec_err_t vp8e_exp_init(vpx_codec_ctx_t *ctx) +{ + return vp8e_common_init(ctx, 1); +} +#endif + + static vpx_codec_err_t vp8e_destroy(vpx_codec_alg_priv_t *ctx) { @@ -1147,6 +1169,36 @@ CODEC_INTERFACE(vpx_codec_vp8_cx) = }; +#if CONFIG_EXPERIMENTAL +vpx_codec_iface_t vpx_codec_vp8x_cx_algo = +{ + "VP8 Experimental Encoder" VERSION_STRING, + VPX_CODEC_INTERNAL_ABI_VERSION, + VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, + /* vpx_codec_caps_t caps; */ + vp8e_exp_init, /* vpx_codec_init_fn_t init; */ + vp8e_destroy, /* vpx_codec_destroy_fn_t destroy; */ + vp8e_ctf_maps, /* vpx_codec_ctrl_fn_map_t *ctrl_maps; */ + NOT_IMPLEMENTED, /* vpx_codec_get_mmap_fn_t get_mmap; */ + NOT_IMPLEMENTED, /* vpx_codec_set_mmap_fn_t set_mmap; */ + { + NOT_IMPLEMENTED, /* vpx_codec_peek_si_fn_t peek_si; */ + NOT_IMPLEMENTED, /* vpx_codec_get_si_fn_t get_si; */ + NOT_IMPLEMENTED, /* vpx_codec_decode_fn_t decode; */ + NOT_IMPLEMENTED, /* vpx_codec_frame_get_fn_t frame_get; */ + }, + { + vp8e_usage_cfg_map, /* vpx_codec_enc_cfg_map_t peek_si; */ + vp8e_encode, /* vpx_codec_encode_fn_t encode; */ + vp8e_get_cxdata, /* vpx_codec_get_cx_data_fn_t frame_get; */ + vp8e_set_config, + NOT_IMPLEMENTED, + vp8e_get_preview, + } /* encoder functions */ +}; +#endif + + /* * BEGIN BACKWARDS COMPATIBILITY SHIM. */ |