| 1 | // Copyright 2014 Google Inc. All Rights Reserved. | 
|---|
| 2 | // | 
|---|
| 3 | // Use of this source code is governed by a BSD-style license | 
|---|
| 4 | // that can be found in the COPYING file in the root of the source | 
|---|
| 5 | // tree. An additional intellectual property rights grant can be found | 
|---|
| 6 | // in the file PATENTS. All contributing project authors may | 
|---|
| 7 | // be found in the AUTHORS file in the root of the source tree. | 
|---|
| 8 | // ----------------------------------------------------------------------------- | 
|---|
| 9 | // | 
|---|
| 10 | // Author: Djordje Pesut (djordje.pesut@imgtec.com) | 
|---|
| 11 |  | 
|---|
| 12 | #include "./dsp.h" | 
|---|
| 13 |  | 
|---|
| 14 | #if defined(WEBP_USE_MIPS_DSP_R2) | 
|---|
| 15 |  | 
|---|
| 16 | #include "../enc/cost_enc.h" | 
|---|
| 17 |  | 
|---|
| 18 | static int GetResidualCost(int ctx0, const VP8Residual* const res) { | 
|---|
| 19 | int temp0, temp1; | 
|---|
| 20 | int v_reg, ctx_reg; | 
|---|
| 21 | int n = res->first; | 
|---|
| 22 | // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1 | 
|---|
| 23 | int p0 = res->prob[n][ctx0][0]; | 
|---|
| 24 | CostArrayPtr const costs = res->costs; | 
|---|
| 25 | const uint16_t* t = costs[n][ctx0]; | 
|---|
| 26 | // bit_cost(1, p0) is already incorporated in t[] tables, but only if ctx != 0 | 
|---|
| 27 | // (as required by the syntax). For ctx0 == 0, we need to add it here or it'll | 
|---|
| 28 | // be missing during the loop. | 
|---|
| 29 | int cost = (ctx0 == 0) ? VP8BitCost(1, p0) : 0; | 
|---|
| 30 | const int16_t* res_coeffs = res->coeffs; | 
|---|
| 31 | const int res_last = res->last; | 
|---|
| 32 | const int const_max_level = MAX_VARIABLE_LEVEL; | 
|---|
| 33 | const int const_2 = 2; | 
|---|
| 34 | const uint16_t** p_costs = &costs[n][0]; | 
|---|
| 35 | const size_t inc_p_costs = NUM_CTX * sizeof(*p_costs); | 
|---|
| 36 |  | 
|---|
| 37 | if (res->last < 0) { | 
|---|
| 38 | return VP8BitCost(0, p0); | 
|---|
| 39 | } | 
|---|
| 40 |  | 
|---|
| 41 | __asm__ volatile ( | 
|---|
| 42 | ".set      push                                                     \n\t" | 
|---|
| 43 | ".set      noreorder                                                \n\t" | 
|---|
| 44 | "subu      %[temp1],        %[res_last],        %[n]                \n\t" | 
|---|
| 45 | "blez      %[temp1],        2f                                      \n\t" | 
|---|
| 46 | " nop                                                               \n\t" | 
|---|
| 47 | "1:                                                                   \n\t" | 
|---|
| 48 | "sll       %[temp0],        %[n],               1                   \n\t" | 
|---|
| 49 | "lhx       %[v_reg],        %[temp0](%[res_coeffs])                 \n\t" | 
|---|
| 50 | "addiu     %[n],            %[n],               1                   \n\t" | 
|---|
| 51 | "absq_s.w  %[v_reg],        %[v_reg]                                \n\t" | 
|---|
| 52 | "sltiu     %[temp0],        %[v_reg],           2                   \n\t" | 
|---|
| 53 | "move      %[ctx_reg],      %[v_reg]                                \n\t" | 
|---|
| 54 | "movz      %[ctx_reg],      %[const_2],         %[temp0]            \n\t" | 
|---|
| 55 | "sll       %[temp1],        %[v_reg],           1                   \n\t" | 
|---|
| 56 | "lhx       %[temp1],        %[temp1](%[VP8LevelFixedCosts])         \n\t" | 
|---|
| 57 | "slt       %[temp0],        %[v_reg],           %[const_max_level]  \n\t" | 
|---|
| 58 | "movz      %[v_reg],        %[const_max_level], %[temp0]            \n\t" | 
|---|
| 59 | "addu      %[cost],         %[cost],            %[temp1]            \n\t" | 
|---|
| 60 | "sll       %[v_reg],        %[v_reg],           1                   \n\t" | 
|---|
| 61 | "sll       %[ctx_reg],      %[ctx_reg],         2                   \n\t" | 
|---|
| 62 | "lhx       %[temp0],        %[v_reg](%[t])                          \n\t" | 
|---|
| 63 | "addu      %[p_costs],      %[p_costs],         %[inc_p_costs]      \n\t" | 
|---|
| 64 | "addu      %[t],            %[p_costs],         %[ctx_reg]          \n\t" | 
|---|
| 65 | "addu      %[cost],         %[cost],            %[temp0]            \n\t" | 
|---|
| 66 | "bne       %[n],            %[res_last],        1b                  \n\t" | 
|---|
| 67 | " lw       %[t],            0(%[t])                                 \n\t" | 
|---|
| 68 | "2:                                                                   \n\t" | 
|---|
| 69 | ".set      pop                                                      \n\t" | 
|---|
| 70 | : [cost] "+&r"(cost), [t] "+&r"(t), [n] "+&r"(n), [v_reg] "=&r"(v_reg), | 
|---|
| 71 | [ctx_reg] "=&r"(ctx_reg), [p_costs] "+&r"(p_costs), [temp0] "=&r"(temp0), | 
|---|
| 72 | [temp1] "=&r"(temp1) | 
|---|
| 73 | : [const_2] "r"(const_2), [const_max_level] "r"(const_max_level), | 
|---|
| 74 | [VP8LevelFixedCosts] "r"(VP8LevelFixedCosts), [res_last] "r"(res_last), | 
|---|
| 75 | [res_coeffs] "r"(res_coeffs), [inc_p_costs] "r"(inc_p_costs) | 
|---|
| 76 | : "memory" | 
|---|
| 77 | ); | 
|---|
| 78 |  | 
|---|
| 79 | // Last coefficient is always non-zero | 
|---|
| 80 | { | 
|---|
| 81 | const int v = abs(res->coeffs[n]); | 
|---|
| 82 | assert(v != 0); | 
|---|
| 83 | cost += VP8LevelCost(t, v); | 
|---|
| 84 | if (n < 15) { | 
|---|
| 85 | const int b = VP8EncBands[n + 1]; | 
|---|
| 86 | const int ctx = (v == 1) ? 1 : 2; | 
|---|
| 87 | const int last_p0 = res->prob[b][ctx][0]; | 
|---|
| 88 | cost += VP8BitCost(0, last_p0); | 
|---|
| 89 | } | 
|---|
| 90 | } | 
|---|
| 91 | return cost; | 
|---|
| 92 | } | 
|---|
| 93 |  | 
|---|
| 94 | //------------------------------------------------------------------------------ | 
|---|
| 95 | // Entry point | 
|---|
| 96 |  | 
|---|
| 97 | extern void VP8EncDspCostInitMIPSdspR2(void); | 
|---|
| 98 |  | 
|---|
| 99 | WEBP_TSAN_IGNORE_FUNCTION void VP8EncDspCostInitMIPSdspR2(void) { | 
|---|
| 100 | VP8GetResidualCost = GetResidualCost; | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 | #else  // !WEBP_USE_MIPS_DSP_R2 | 
|---|
| 104 |  | 
|---|
| 105 | WEBP_DSP_INIT_STUB(VP8EncDspCostInitMIPSdspR2) | 
|---|
| 106 |  | 
|---|
| 107 | #endif  // WEBP_USE_MIPS_DSP_R2 | 
|---|
| 108 |  | 
|---|