]> granicus.if.org Git - libvpx/blob - vp8/encoder/encodeintra.c
safety check to avoid divide by 0s
[libvpx] / vp8 / encoder / encodeintra.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11
12 #include "vpx_ports/config.h"
13 #include "idct.h"
14 #include "quantize.h"
15 #include "reconintra.h"
16 #include "reconintra4x4.h"
17 #include "encodemb.h"
18 #include "invtrans.h"
19 #include "recon.h"
20 #include "dct.h"
21 #include "g_common.h"
22 #include "encodeintra.h"
23
24 #define intra4x4ibias_rate    128
25 #define intra4x4pbias_rate    256
26
27
28 void vp8_update_mode_context(int *abmode, int *lbmode, int i, int best_mode)
29 {
30     if (i < 12)
31     {
32         abmode[i+4] = best_mode;
33     }
34
35     if ((i & 3) != 3)
36     {
37         lbmode[i+1] = best_mode;
38     }
39
40 }
41 #if CONFIG_RUNTIME_CPU_DETECT
42 #define IF_RTCD(x) (x)
43 #else
44 #define IF_RTCD(x) NULL
45 #endif
46 void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
47 {
48     vp8_predict_intra4x4(b, best_mode, b->predictor);
49
50     ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
51
52     x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
53
54     x->quantize_b(be, b);
55
56     vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);
57
58     RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
59 }
60
61 void vp8_encode_intra4x4block_rd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
62 {
63     vp8_predict_intra4x4(b, best_mode, b->predictor);
64
65     ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
66
67     x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
68
69     x->quantize_b(be, b);
70
71     IDCT_INVOKE(&rtcd->common->idct, idct16)(b->dqcoeff, b->diff, 32);
72
73     RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
74 }
75
76 void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb)
77 {
78     int i;
79
80     MACROBLOCKD *x = &mb->e_mbd;
81     vp8_intra_prediction_down_copy(x);
82
83     for (i = 0; i < 16; i++)
84     {
85         BLOCK *be = &mb->block[i];
86         BLOCKD *b = &x->block[i];
87
88         vp8_encode_intra4x4block(rtcd, mb, be, b, b->bmi.mode);
89     }
90
91     return;
92 }
93
94 void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
95 {
96     int b;
97
98     vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
99
100     ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
101
102     vp8_transform_intra_mby(x);
103
104     vp8_quantize_mby(x);
105
106 #if !(CONFIG_REALTIME_ONLY)
107 #if 1
108     if (x->optimize && x->rddiv > 1)
109         vp8_optimize_mby(x, rtcd);
110
111 #endif
112 #endif
113
114     vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
115
116     vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
117
118     // make sure block modes are set the way we want them for context updates
119     for (b = 0; b < 16; b++)
120     {
121         BLOCKD *d = &x->e_mbd.block[b];
122
123         switch (x->e_mbd.mode_info_context->mbmi.mode)
124         {
125
126         case DC_PRED:
127             d->bmi.mode = B_DC_PRED;
128             break;
129         case V_PRED:
130             d->bmi.mode = B_VE_PRED;
131             break;
132         case H_PRED:
133             d->bmi.mode = B_HE_PRED;
134             break;
135         case TM_PRED:
136             d->bmi.mode = B_TM_PRED;
137             break;
138         default:
139             d->bmi.mode = B_DC_PRED;
140             break;
141
142         }
143     }
144 }
145
146 void vp8_encode_intra16x16mbyrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
147 {
148     int b;
149
150     vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
151
152     ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);
153
154     vp8_transform_intra_mby(x);
155
156     vp8_quantize_mby(x);
157
158     vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
159
160     vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
161
162     // make sure block modes are set the way we want them for context updates
163     for (b = 0; b < 16; b++)
164     {
165         BLOCKD *d = &x->e_mbd.block[b];
166
167         switch (x->e_mbd.mode_info_context->mbmi.mode)
168         {
169
170         case DC_PRED:
171             d->bmi.mode = B_DC_PRED;
172             break;
173         case V_PRED:
174             d->bmi.mode = B_VE_PRED;
175             break;
176         case H_PRED:
177             d->bmi.mode = B_HE_PRED;
178             break;
179         case TM_PRED:
180             d->bmi.mode = B_TM_PRED;
181             break;
182         default:
183             d->bmi.mode = B_DC_PRED;
184             break;
185
186         }
187     }
188 }
189
190 void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
191 {
192     vp8_build_intra_predictors_mbuv(&x->e_mbd);
193
194     ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
195
196     vp8_transform_mbuv(x);
197
198     vp8_quantize_mbuv(x);
199
200 #if !(CONFIG_REALTIME_ONLY)
201 #if 1
202
203     if (x->optimize && x->rddiv > 1)
204         vp8_optimize_mbuv(x, rtcd);
205
206 #endif
207 #endif
208
209     vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
210
211     vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
212 }
213
214 void vp8_encode_intra16x16mbuvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
215 {
216     vp8_build_intra_predictors_mbuv(&x->e_mbd);
217
218     ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
219
220     vp8_transform_mbuv(x);
221
222     vp8_quantize_mbuv(x);
223
224     vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
225
226     vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
227 }