diff --git a/examples/test_ref.ppm b/examples/test_ref.ppm index 29bf07ff..97719f01 100644 Binary files a/examples/test_ref.ppm and b/examples/test_ref.ppm differ diff --git a/src/bits.c b/src/bits.c index bdc89e04..1d369389 100644 --- a/src/bits.c +++ b/src/bits.c @@ -67,7 +67,7 @@ uint32_t VP8GetValue(VP8BitReader* const br, int bits) { } int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { - const int value = (bits > 0) ? VP8GetValue(br, bits) : 0; + const int value = VP8GetValue(br, bits); return VP8Get(br) ? -value : value; } diff --git a/src/dsp.c b/src/dsp.c index 420b3b01..229d921f 100644 --- a/src/dsp.c +++ b/src/dsp.c @@ -170,32 +170,32 @@ void (*VP8TransformWHT)(const int16_t* in, int16_t* out) = TransformWHT; static inline void TrueMotion(uint8_t *dst, int size) { const uint8_t* top = dst - BPS; - const int tl = top[-1]; - int x, y; - + const uint8_t* const clip0 = clip1 + 255 - top[-1]; + int y; for (y = 0; y < size; ++y) { - const uint8_t* const clip = clip1 + 255 + dst[-1] - tl; + const uint8_t* const clip = clip0 + dst[-1]; + int x; for (x = 0; x < size; ++x) { dst[x] = clip[top[x]]; } dst += BPS; } } -static void TM4(uint8_t *dst) { TrueMotion(dst, 4); } +static void TM4(uint8_t *dst) { TrueMotion(dst, 4); } static void TM8uv(uint8_t *dst) { TrueMotion(dst, 8); } -static void TM16(uint8_t *dst) { TrueMotion(dst, 16); } +static void TM16(uint8_t *dst) { TrueMotion(dst, 16); } //----------------------------------------------------------------------------- // 16x16 -static void V16(uint8_t *dst) { // vertical +static void VE16(uint8_t *dst) { // vertical int j; for (j = 0; j < 16; ++j) { memcpy(dst + j * BPS, dst - BPS, 16); } } -static void H16(uint8_t *dst) { // horizontal +static void HE16(uint8_t *dst) { // horizontal int j; for (j = 16; j > 0; --j) { memset(dst, dst[-1], 16); @@ -244,30 +244,24 @@ static void DC16NoTopLeft(uint8_t *dst) { // DC with no top and left samples //----------------------------------------------------------------------------- // 4x4 -static inline void Put4(uint32_t v, uint8_t* dst) { - int i; - for (i = 4; i > 0; --i) { - *(uint32_t*)dst = v; - dst += BPS; - } -} - #define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2) #define AVG2(a, b) (((a) + (b) + 1) >> 1) -static void V4(uint8_t *dst) { // vertical +static void VE4(uint8_t *dst) { // vertical const uint8_t* top = dst - BPS; const uint8_t vals[4] = { AVG3(top[-1], top[0], top[1]), - AVG3(top[0], top[1], top[2]), - AVG3(top[1], top[2], top[3]), - AVG3(top[2], top[3], top[4]) + AVG3(top[ 0], top[1], top[2]), + AVG3(top[ 1], top[2], top[3]), + AVG3(top[ 2], top[3], top[4]) }; - const uint32_t v = *(uint32_t*)vals; - Put4(v, dst); + int i; + for (i = 0; i < 4; ++i) { + memcpy(dst + i * BPS, vals, sizeof(vals)); + } } -static void H4(uint8_t *dst) { // horizontal +static void HE4(uint8_t *dst) { // horizontal const int A = dst[-1 - BPS]; const int B = dst[-1]; const int C = dst[-1 + BPS]; @@ -282,10 +276,9 @@ static void H4(uint8_t *dst) { // horizontal static void DC4(uint8_t *dst) { // DC uint32_t dc = 4; int i; - for (i = 0; i < 4; ++i) { - dc += dst[i - BPS] + dst[-1 + i * BPS]; - } - Put4((dc >> 3) * 0x01010101U, dst); + for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS]; + dc >>= 3; + for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4); } static void RD4(uint8_t *dst) { // Down-right @@ -413,14 +406,14 @@ static void HD4(uint8_t *dst) { // Horizontal-Down //----------------------------------------------------------------------------- // Chroma -static void V8uv(uint8_t *dst) { // vertical +static void VE8uv(uint8_t *dst) { // vertical int j; for (j = 0; j < 8; ++j) { memcpy(dst + j * BPS, dst - BPS, 8); } } -static void H8uv(uint8_t *dst) { // horizontal +static void HE8uv(uint8_t *dst) { // horizontal int j; for (j = 0; j < 8; ++j) { memset(dst, dst[-1], 8); @@ -471,16 +464,16 @@ static void DC8uvNoTopLeft(uint8_t *dst) { // DC with nothing // default C implementations VP8PredFunc VP8PredLuma4[11] = { - DC4, TM4, V4, H4, LD4, RD4, VR4, VL4, HD4, HU4 + DC4, TM4, VE4, HE4, RD4, VR4, LD4, VL4, HD4, HU4 }; VP8PredFunc VP8PredLuma16[7] = { - DC16, TM16, V16, H16, + DC16, TM16, VE16, HE16, DC16NoTop, DC16NoLeft, DC16NoTopLeft }; VP8PredFunc VP8PredChroma8[7] = { - DC8uv, TM8uv, V8uv, H8uv, + DC8uv, TM8uv, VE8uv, HE8uv, DC8uvNoTop, DC8uvNoLeft, DC8uvNoTopLeft }; diff --git a/src/tree.c b/src/tree.c index 1d5c422e..03cb745c 100644 --- a/src/tree.c +++ b/src/tree.c @@ -11,6 +11,7 @@ #include #include "vp8i.h" + #define USE_GENERIC_TREE #if defined(__cplusplus) || defined(c_plusplus) @@ -32,6 +33,12 @@ static const int8_t kYModesIntra4[18] = { #endif #ifndef ONLY_KEYFRAME_CODE + +// inter prediction modes +enum { + LEFT4 = 0, ABOVE4 = 1, ZERO4 = 2, NEW4 = 3, + NEARESTMV, NEARMV, ZEROMV, NEWMV, SPLITMV }; + static const int8_t kYModesInter[8] = { -DC_PRED, 1, 2, 3, @@ -216,14 +223,13 @@ static const uint8_t // Paragraph 11.5 static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { - // genereated using vp8_kf_default_bmode_probs() { { 231, 120, 48, 89, 115, 113, 120, 152, 112 }, { 152, 179, 64, 126, 170, 118, 46, 70, 95 }, { 175, 69, 143, 80, 85, 82, 72, 155, 103 }, { 56, 58, 10, 171, 218, 189, 17, 13, 152 }, - { 144, 71, 10, 38, 171, 213, 144, 34, 26 }, { 114, 26, 17, 163, 44, 195, 21, 10, 173 }, { 121, 24, 80, 195, 26, 62, 44, 64, 85 }, + { 144, 71, 10, 38, 171, 213, 144, 34, 26 }, { 170, 46, 55, 19, 136, 160, 33, 206, 71 }, { 63, 20, 8, 114, 114, 208, 12, 9, 226 }, { 81, 40, 11, 96, 182, 84, 29, 16, 36 } }, @@ -231,9 +237,9 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 72, 187, 100, 130, 157, 111, 32, 75, 80 }, { 66, 102, 167, 99, 74, 62, 40, 234, 128 }, { 41, 53, 9, 178, 241, 141, 26, 8, 107 }, - { 104, 79, 12, 27, 217, 255, 87, 17, 7 }, { 74, 43, 26, 146, 73, 166, 49, 23, 157 }, { 65, 38, 105, 160, 51, 52, 31, 115, 128 }, + { 104, 79, 12, 27, 217, 255, 87, 17, 7 }, { 87, 68, 71, 44, 114, 51, 15, 186, 23 }, { 47, 41, 14, 110, 182, 183, 21, 17, 194 }, { 66, 45, 25, 102, 197, 189, 23, 18, 22 } }, @@ -241,9 +247,9 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 43, 97, 183, 117, 85, 38, 35, 179, 61 }, { 39, 53, 200, 87, 26, 21, 43, 232, 171 }, { 56, 34, 51, 104, 114, 102, 29, 93, 77 }, - { 107, 54, 32, 26, 51, 1, 81, 43, 31 }, { 39, 28, 85, 171, 58, 165, 90, 98, 64 }, { 34, 22, 116, 206, 23, 34, 43, 166, 73 }, + { 107, 54, 32, 26, 51, 1, 81, 43, 31 }, { 68, 25, 106, 22, 64, 171, 36, 225, 114 }, { 34, 19, 21, 102, 132, 188, 16, 76, 124 }, { 62, 18, 78, 95, 85, 57, 50, 48, 51 } }, @@ -251,29 +257,19 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 60, 148, 31, 172, 219, 228, 21, 18, 111 }, { 112, 113, 77, 85, 179, 255, 38, 120, 114 }, { 40, 42, 1, 196, 245, 209, 10, 25, 109 }, - { 100, 80, 8, 43, 154, 1, 51, 26, 71 }, { 88, 43, 29, 140, 166, 213, 37, 43, 154 }, { 61, 63, 30, 155, 67, 45, 68, 1, 209 }, + { 100, 80, 8, 43, 154, 1, 51, 26, 71 }, { 142, 78, 78, 16, 255, 128, 34, 197, 171 }, { 41, 40, 5, 102, 211, 183, 4, 1, 221 }, { 51, 50, 17, 168, 209, 192, 23, 25, 82 } }, - { { 125, 98, 42, 88, 104, 85, 117, 175, 82 }, - { 95, 84, 53, 89, 128, 100, 113, 101, 45 }, - { 75, 79, 123, 47, 51, 128, 81, 171, 1 }, - { 57, 17, 5, 71, 102, 57, 53, 41, 49 }, - { 115, 21, 2, 10, 102, 255, 166, 23, 6 }, - { 38, 33, 13, 121, 57, 73, 26, 1, 85 }, - { 41, 10, 67, 138, 77, 110, 90, 47, 114 }, - { 101, 29, 16, 10, 85, 128, 101, 196, 26 }, - { 57, 18, 10, 102, 102, 213, 34, 20, 43 }, - { 117, 20, 15, 36, 163, 128, 68, 1, 26 } }, { { 138, 31, 36, 171, 27, 166, 38, 44, 229 }, { 67, 87, 58, 169, 82, 115, 26, 59, 179 }, { 63, 59, 90, 180, 59, 166, 93, 73, 154 }, { 40, 40, 21, 116, 143, 209, 34, 39, 175 }, - { 57, 46, 22, 24, 128, 1, 54, 17, 37 }, { 47, 15, 16, 183, 34, 223, 49, 45, 183 }, { 46, 17, 33, 183, 6, 98, 15, 32, 183 }, + { 57, 46, 22, 24, 128, 1, 54, 17, 37 }, { 65, 32, 73, 115, 28, 128, 23, 128, 205 }, { 40, 3, 9, 115, 51, 192, 18, 6, 223 }, { 87, 37, 9, 115, 59, 77, 64, 21, 47 } }, @@ -281,19 +277,29 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 64, 90, 70, 205, 40, 41, 23, 26, 57 }, { 54, 57, 112, 184, 5, 41, 38, 166, 213 }, { 30, 34, 26, 133, 152, 116, 10, 32, 134 }, - { 75, 32, 12, 51, 192, 255, 160, 43, 51 }, { 39, 19, 53, 221, 26, 114, 32, 73, 255 }, { 31, 9, 65, 234, 2, 15, 1, 118, 73 }, + { 75, 32, 12, 51, 192, 255, 160, 43, 51 }, { 88, 31, 35, 67, 102, 85, 55, 186, 85 }, { 56, 21, 23, 111, 59, 205, 45, 37, 192 }, { 55, 38, 70, 124, 73, 102, 1, 34, 98 } }, + { { 125, 98, 42, 88, 104, 85, 117, 175, 82 }, + { 95, 84, 53, 89, 128, 100, 113, 101, 45 }, + { 75, 79, 123, 47, 51, 128, 81, 171, 1 }, + { 57, 17, 5, 71, 102, 57, 53, 41, 49 }, + { 38, 33, 13, 121, 57, 73, 26, 1, 85 }, + { 41, 10, 67, 138, 77, 110, 90, 47, 114 }, + { 115, 21, 2, 10, 102, 255, 166, 23, 6 }, + { 101, 29, 16, 10, 85, 128, 101, 196, 26 }, + { 57, 18, 10, 102, 102, 213, 34, 20, 43 }, + { 117, 20, 15, 36, 163, 128, 68, 1, 26 } }, { { 102, 61, 71, 37, 34, 53, 31, 243, 192 }, { 69, 60, 71, 38, 73, 119, 28, 222, 37 }, { 68, 45, 128, 34, 1, 47, 11, 245, 171 }, { 62, 17, 19, 70, 146, 85, 55, 62, 70 }, - { 75, 15, 9, 9, 64, 255, 184, 119, 16 }, { 37, 43, 37, 154, 100, 163, 85, 160, 1 }, { 63, 9, 92, 136, 28, 64, 32, 201, 85 }, + { 75, 15, 9, 9, 64, 255, 184, 119, 16 }, { 86, 6, 28, 5, 64, 255, 25, 248, 1 }, { 56, 8, 17, 132, 137, 255, 55, 116, 128 }, { 58, 15, 20, 82, 135, 57, 26, 121, 40 } }, @@ -301,9 +307,9 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 51, 103, 44, 131, 131, 123, 31, 6, 158 }, { 86, 40, 64, 135, 148, 224, 45, 183, 128 }, { 22, 26, 17, 131, 240, 154, 14, 1, 209 }, - { 83, 12, 13, 54, 192, 255, 68, 47, 28 }, { 45, 16, 21, 91, 64, 222, 7, 1, 197 }, { 56, 21, 39, 155, 60, 138, 23, 102, 213 }, + { 83, 12, 13, 54, 192, 255, 68, 47, 28 }, { 85, 26, 85, 85, 128, 128, 32, 146, 171 }, { 18, 11, 7, 63, 144, 171, 4, 4, 246 }, { 35, 27, 10, 146, 174, 171, 12, 26, 128 } }, @@ -311,9 +317,9 @@ static const uint8_t kBModesProba[NUM_BMODES][NUM_BMODES][NUM_BMODES - 1] = { { 85, 126, 47, 87, 176, 51, 41, 20, 32 }, { 101, 75, 128, 139, 118, 146, 116, 128, 85 }, { 56, 41, 15, 176, 236, 85, 37, 9, 62 }, - { 146, 36, 19, 30, 171, 255, 97, 27, 20 }, { 71, 30, 17, 119, 118, 255, 17, 18, 138 }, { 101, 38, 60, 138, 55, 70, 43, 26, 142 }, + { 146, 36, 19, 30, 171, 255, 97, 27, 20 }, { 138, 45, 61, 62, 219, 1, 81, 188, 64 }, { 32, 41, 20, 117, 151, 142, 20, 21, 163 }, { 112, 19, 12, 61, 195, 128, 48, 4, 24 } } @@ -551,25 +557,27 @@ void VP8ParseProba(VP8BitReader* const br, VP8Decoder* const dec) { } #ifndef ONLY_KEYFRAME_CODE if (!dec->frm_hdr_.key_frame_) { + int i; dec->intra_p_ = VP8GetValue(br, 8); dec->last_p_ = VP8GetValue(br, 8); dec->golden_p_ = VP8GetValue(br, 8); if (VP8Get(br)) { // update y-mode - for (int i = 0; i < 4; ++i) { + for (i = 0; i < 4; ++i) { proba->ymode_[i] = VP8GetValue(br, 8); } } if (VP8Get(br)) { // update uv-mode - for (int i = 0; i < 3; ++i) { + for (i = 0; i < 3; ++i) { proba->uvmode_[i] = VP8GetValue(br, 8); } } // update MV - for (int d = 0; d < 2; ++d) { - for (int k = 0; k < NUM_MV_PROBAS; ++k) { - if (VP8GetBit(br, MVUpdateProba[d][k])) { + for (i = 0; i < 2; ++i) { + int k; + for (k = 0; k < NUM_MV_PROBAS; ++k) { + if (VP8GetBit(br, MVUpdateProba[i][k])) { const int v = VP8GetValue(br, 7); - proba->mv_[d][k] = v ? v << 1 : 1; + proba->mv_[i][k] = v ? v << 1 : 1; } } } diff --git a/src/vp8.c b/src/vp8.c index 58241925..f1455399 100644 --- a/src/vp8.c +++ b/src/vp8.c @@ -302,15 +302,16 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { } // Paragraph 9.8 +#ifndef ONLY_KEYFRAME_CODE dec->update_proba_ = VP8Get(br); if (!dec->update_proba_) { // save for later restore dec->proba_saved_ = dec->proba_; } - -#ifndef ONLY_KEYFRAME_CODE dec->buffer_flags_ &= 1 << 8; dec->buffer_flags_ |= (frm_hdr->key_frame_ || VP8Get(br)) << 8; // refresh last frame +#else + VP8Get(br); // just ignore the value of update_proba_ #endif VP8ParseProba(br, dec); @@ -555,9 +556,12 @@ static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { } // Finish +#ifndef ONLY_KEYFRAME_CODE if (!dec->update_proba_) { dec->proba_ = dec->proba_saved_; } +#endif + return ok; } diff --git a/src/vp8i.h b/src/vp8i.h index 15a21ee8..76985b8a 100644 --- a/src/vp8i.h +++ b/src/vp8i.h @@ -29,9 +29,9 @@ enum { B_DC_PRED = 0, // 4x4 modes B_TM_PRED, B_VE_PRED, B_HE_PRED, - B_LD_PRED, B_RD_PRED, B_VR_PRED, + B_LD_PRED, B_VL_PRED, B_HD_PRED, B_HU_PRED, @@ -47,13 +47,6 @@ enum { B_DC_PRED = 0, // 4x4 modes B_DC_PRED_NOLEFT = 5, B_DC_PRED_NOTOPLEFT = 6 }; -#ifndef ONLY_KEYFRAME_CODE -// inter prediction modes -enum { - LEFT4 = 0, ABOVE4 = 1, ZERO4 = 2, NEW4 = 3, - NEARESTMV, NEARMV, ZEROMV, NEWMV, SPLITMV }; -#endif - enum { MB_FEATURE_TREE_PROBS = 3, NUM_MB_SEGMENTS = 4, NUM_REF_LF_DELTAS = 4, @@ -177,10 +170,10 @@ struct VP8Decoder { VP8BitReader br_; // headers - VP8FrameHeader frm_hdr_; - VP8PictureHeader pic_hdr_; - VP8FilterHeader filter_hdr_; - VP8SegmentHeader segment_hdr_; + VP8FrameHeader frm_hdr_; + VP8PictureHeader pic_hdr_; + VP8FilterHeader filter_hdr_; + VP8SegmentHeader segment_hdr_; // dimension, in macroblock units. int mb_w_, mb_h_; @@ -201,10 +194,14 @@ struct VP8Decoder { VP8QuantMatrix dqm_[NUM_MB_SEGMENTS]; // probabilities - VP8Proba proba_, proba_saved_; - int update_proba_; + VP8Proba proba_; int use_skip_proba_; - uint8_t skip_p_, intra_p_, last_p_, golden_p_; + uint8_t skip_p_; +#ifndef ONLY_KEYFRAME_CODE + uint8_t intra_p_, last_p_, golden_p_; + VP8Proba proba_saved_; + int update_proba_; +#endif // Boundary data cache and persistent buffers. uint8_t* intra_t_; // top intra modes values: 4 * mb_w_