xref: /aosp_15_r20/external/libavc/encoder/ih264e_intra_modes_eval.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /**
22*495ae853SAndroid Build Coastguard Worker *******************************************************************************
23*495ae853SAndroid Build Coastguard Worker * @file
24*495ae853SAndroid Build Coastguard Worker *  ih264e_intra_modes_eval.c
25*495ae853SAndroid Build Coastguard Worker *
26*495ae853SAndroid Build Coastguard Worker * @brief
27*495ae853SAndroid Build Coastguard Worker *  This file contains definitions of routines that perform rate distortion
28*495ae853SAndroid Build Coastguard Worker *  analysis on a macroblock if they are to be coded as intra.
29*495ae853SAndroid Build Coastguard Worker *
30*495ae853SAndroid Build Coastguard Worker * @author
31*495ae853SAndroid Build Coastguard Worker *  ittiam
32*495ae853SAndroid Build Coastguard Worker *
33*495ae853SAndroid Build Coastguard Worker * @par List of Functions:
34*495ae853SAndroid Build Coastguard Worker *  - ih264e_derive_neighbor_availability_of_mbs
35*495ae853SAndroid Build Coastguard Worker *  - ih264e_derive_ngbr_avbl_of_mb_partitions
36*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff
37*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff
38*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff
39*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton
40*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff
41*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra16x16_modes
42*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra4x4_modes
43*495ae853SAndroid Build Coastguard Worker *  - ih264e_evaluate_intra_chroma_modes
44*495ae853SAndroid Build Coastguard Worker *
45*495ae853SAndroid Build Coastguard Worker * @remarks
46*495ae853SAndroid Build Coastguard Worker *  none
47*495ae853SAndroid Build Coastguard Worker *
48*495ae853SAndroid Build Coastguard Worker *******************************************************************************
49*495ae853SAndroid Build Coastguard Worker */
50*495ae853SAndroid Build Coastguard Worker 
51*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
52*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
53*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
54*495ae853SAndroid Build Coastguard Worker 
55*495ae853SAndroid Build Coastguard Worker /* System Include Files */
56*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
57*495ae853SAndroid Build Coastguard Worker #include <string.h>
58*495ae853SAndroid Build Coastguard Worker #include <limits.h>
59*495ae853SAndroid Build Coastguard Worker #include <assert.h>
60*495ae853SAndroid Build Coastguard Worker 
61*495ae853SAndroid Build Coastguard Worker /* User Include Files */
62*495ae853SAndroid Build Coastguard Worker #include "ih264e_config.h"
63*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
64*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
65*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
66*495ae853SAndroid Build Coastguard Worker 
67*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
68*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
69*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_mem_fns.h"
71*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
72*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
73*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_quant_itrans_iquant.h"
74*495ae853SAndroid Build Coastguard Worker #include "ih264_inter_pred_filters.h"
75*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
76*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
77*495ae853SAndroid Build Coastguard Worker #include "ih264_common_tables.h"
78*495ae853SAndroid Build Coastguard Worker #include "ih264_cabac_tables.h"
79*495ae853SAndroid Build Coastguard Worker 
80*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
81*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
82*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
83*495ae853SAndroid Build Coastguard Worker #include "ime_platform_macros.h"
84*495ae853SAndroid Build Coastguard Worker 
85*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
86*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
87*495ae853SAndroid Build Coastguard Worker 
88*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
89*495ae853SAndroid Build Coastguard Worker #include "ih264e_defs.h"
90*495ae853SAndroid Build Coastguard Worker #include "ih264e_globals.h"
91*495ae853SAndroid Build Coastguard Worker #include "ih264e_rate_control.h"
92*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
93*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac_structs.h"
94*495ae853SAndroid Build Coastguard Worker #include "ih264e_structs.h"
95*495ae853SAndroid Build Coastguard Worker #include "ih264e_intra_modes_eval.h"
96*495ae853SAndroid Build Coastguard Worker 
97*495ae853SAndroid Build Coastguard Worker 
98*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
99*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
100*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
101*495ae853SAndroid Build Coastguard Worker 
102*495ae853SAndroid Build Coastguard Worker /**
103*495ae853SAndroid Build Coastguard Worker ******************************************************************************
104*495ae853SAndroid Build Coastguard Worker *
105*495ae853SAndroid Build Coastguard Worker * @brief
106*495ae853SAndroid Build Coastguard Worker *  derivation process for macroblock availability
107*495ae853SAndroid Build Coastguard Worker *
108*495ae853SAndroid Build Coastguard Worker * @par   Description
109*495ae853SAndroid Build Coastguard Worker *  Calculates the availability of the left, top, topright and topleft macroblocks.
110*495ae853SAndroid Build Coastguard Worker *
111*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc_ctxt
112*495ae853SAndroid Build Coastguard Worker *  pointer to proc context (handle)
113*495ae853SAndroid Build Coastguard Worker *
114*495ae853SAndroid Build Coastguard Worker * @remarks Based on section 6.4.5 in H264 spec
115*495ae853SAndroid Build Coastguard Worker *
116*495ae853SAndroid Build Coastguard Worker * @return  none
117*495ae853SAndroid Build Coastguard Worker *
118*495ae853SAndroid Build Coastguard Worker ******************************************************************************
119*495ae853SAndroid Build Coastguard Worker */
ih264e_derive_nghbr_avbl_of_mbs(process_ctxt_t * ps_proc)120*495ae853SAndroid Build Coastguard Worker void ih264e_derive_nghbr_avbl_of_mbs(process_ctxt_t *ps_proc)
121*495ae853SAndroid Build Coastguard Worker {
122*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx_curr = ps_proc->pu1_slice_idx;
123*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx_b;
124*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx_a;
125*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx_c;
126*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx_d;
127*495ae853SAndroid Build Coastguard Worker     block_neighbors_t *ps_ngbr_avbl;
128*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_x, i4_mb_y;
129*495ae853SAndroid Build Coastguard Worker     WORD32 i4_wd_mbs;
130*495ae853SAndroid Build Coastguard Worker 
131*495ae853SAndroid Build Coastguard Worker     i4_mb_x = ps_proc->i4_mb_x;
132*495ae853SAndroid Build Coastguard Worker     i4_mb_y = ps_proc->i4_mb_y;
133*495ae853SAndroid Build Coastguard Worker 
134*495ae853SAndroid Build Coastguard Worker     i4_wd_mbs = ps_proc->i4_wd_mbs;
135*495ae853SAndroid Build Coastguard Worker 
136*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx_curr += (i4_mb_y * i4_wd_mbs) + i4_mb_x;
137*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx_a = pu1_slice_idx_curr - 1;
138*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx_b = pu1_slice_idx_curr - i4_wd_mbs;
139*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx_c = pu1_slice_idx_b + 1;
140*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx_d = pu1_slice_idx_b - 1;
141*495ae853SAndroid Build Coastguard Worker     ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
142*495ae853SAndroid Build Coastguard Worker 
143*495ae853SAndroid Build Coastguard Worker     /**********************************************************************/
144*495ae853SAndroid Build Coastguard Worker     /* The macroblock is marked as available, unless one of the following */
145*495ae853SAndroid Build Coastguard Worker     /* conditions is true in which case the macroblock shall be marked as */
146*495ae853SAndroid Build Coastguard Worker     /* not available.                                                     */
147*495ae853SAndroid Build Coastguard Worker     /* 1. mbAddr < 0                                                      */
148*495ae853SAndroid Build Coastguard Worker     /* 2  mbAddr > CurrMbAddr                                             */
149*495ae853SAndroid Build Coastguard Worker     /* 3. the macroblock with address mbAddr belongs to a different slice */
150*495ae853SAndroid Build Coastguard Worker     /* than the macroblock with address CurrMbAddr                        */
151*495ae853SAndroid Build Coastguard Worker     /**********************************************************************/
152*495ae853SAndroid Build Coastguard Worker 
153*495ae853SAndroid Build Coastguard Worker     /* left macroblock availability */
154*495ae853SAndroid Build Coastguard Worker     if (i4_mb_x == 0)
155*495ae853SAndroid Build Coastguard Worker     { /* macroblocks along first column */
156*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_a = 0;
157*495ae853SAndroid Build Coastguard Worker     }
158*495ae853SAndroid Build Coastguard Worker     else
159*495ae853SAndroid Build Coastguard Worker     { /* macroblocks belong to same slice? */
160*495ae853SAndroid Build Coastguard Worker         if (*pu1_slice_idx_a != *pu1_slice_idx_curr)
161*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_a = 0;
162*495ae853SAndroid Build Coastguard Worker         else
163*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_a = 1;
164*495ae853SAndroid Build Coastguard Worker     }
165*495ae853SAndroid Build Coastguard Worker 
166*495ae853SAndroid Build Coastguard Worker     /* top macroblock availability */
167*495ae853SAndroid Build Coastguard Worker     if (i4_mb_y == 0)
168*495ae853SAndroid Build Coastguard Worker     { /* macroblocks along first row */
169*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_b = 0;
170*495ae853SAndroid Build Coastguard Worker     }
171*495ae853SAndroid Build Coastguard Worker     else
172*495ae853SAndroid Build Coastguard Worker     { /* macroblocks belong to same slice? */
173*495ae853SAndroid Build Coastguard Worker         if (*pu1_slice_idx_b != *pu1_slice_idx_curr)
174*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_b = 0;
175*495ae853SAndroid Build Coastguard Worker         else
176*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_b = 1;
177*495ae853SAndroid Build Coastguard Worker     }
178*495ae853SAndroid Build Coastguard Worker 
179*495ae853SAndroid Build Coastguard Worker     /* top right macroblock availability */
180*495ae853SAndroid Build Coastguard Worker     if (i4_mb_x == i4_wd_mbs-1 || i4_mb_y == 0)
181*495ae853SAndroid Build Coastguard Worker     { /* macroblocks along last column */
182*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_c = 0;
183*495ae853SAndroid Build Coastguard Worker     }
184*495ae853SAndroid Build Coastguard Worker     else
185*495ae853SAndroid Build Coastguard Worker     { /* macroblocks belong to same slice? */
186*495ae853SAndroid Build Coastguard Worker         if (*pu1_slice_idx_c != *pu1_slice_idx_curr)
187*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_c = 0;
188*495ae853SAndroid Build Coastguard Worker         else
189*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_c = 1;
190*495ae853SAndroid Build Coastguard Worker     }
191*495ae853SAndroid Build Coastguard Worker 
192*495ae853SAndroid Build Coastguard Worker     /* top left macroblock availability */
193*495ae853SAndroid Build Coastguard Worker     if (i4_mb_x == 0 || i4_mb_y == 0)
194*495ae853SAndroid Build Coastguard Worker     { /* macroblocks along first column */
195*495ae853SAndroid Build Coastguard Worker         ps_ngbr_avbl->u1_mb_d = 0;
196*495ae853SAndroid Build Coastguard Worker     }
197*495ae853SAndroid Build Coastguard Worker     else
198*495ae853SAndroid Build Coastguard Worker     { /* macroblocks belong to same slice? */
199*495ae853SAndroid Build Coastguard Worker         if (*pu1_slice_idx_d != *pu1_slice_idx_curr)
200*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_d = 0;
201*495ae853SAndroid Build Coastguard Worker         else
202*495ae853SAndroid Build Coastguard Worker             ps_ngbr_avbl->u1_mb_d = 1;
203*495ae853SAndroid Build Coastguard Worker     }
204*495ae853SAndroid Build Coastguard Worker }
205*495ae853SAndroid Build Coastguard Worker 
206*495ae853SAndroid Build Coastguard Worker /**
207*495ae853SAndroid Build Coastguard Worker ******************************************************************************
208*495ae853SAndroid Build Coastguard Worker *
209*495ae853SAndroid Build Coastguard Worker * @brief
210*495ae853SAndroid Build Coastguard Worker *  derivation process for subblock/partition availability
211*495ae853SAndroid Build Coastguard Worker *
212*495ae853SAndroid Build Coastguard Worker * @par   Description
213*495ae853SAndroid Build Coastguard Worker *  Calculates the availability of the left, top, topright and topleft subblock
214*495ae853SAndroid Build Coastguard Worker *  or partitions.
215*495ae853SAndroid Build Coastguard Worker *
216*495ae853SAndroid Build Coastguard Worker * @param[in]    ps_proc_ctxt
217*495ae853SAndroid Build Coastguard Worker *  pointer to macroblock context (handle)
218*495ae853SAndroid Build Coastguard Worker *
219*495ae853SAndroid Build Coastguard Worker * @param[in]    i1_pel_pos_x
220*495ae853SAndroid Build Coastguard Worker *  column position of the pel wrt the current block
221*495ae853SAndroid Build Coastguard Worker *
222*495ae853SAndroid Build Coastguard Worker * @param[in]    i1_pel_pos_y
223*495ae853SAndroid Build Coastguard Worker *  row position of the pel in wrt current block
224*495ae853SAndroid Build Coastguard Worker *
225*495ae853SAndroid Build Coastguard Worker * @remarks     Assumptions: before calling this function it is assumed that
226*495ae853SAndroid Build Coastguard Worker *   the neighbor availability of the current macroblock is already derived.
227*495ae853SAndroid Build Coastguard Worker *   Based on table 6-3 of H264 specification
228*495ae853SAndroid Build Coastguard Worker *
229*495ae853SAndroid Build Coastguard Worker * @return      availability status (yes or no)
230*495ae853SAndroid Build Coastguard Worker *
231*495ae853SAndroid Build Coastguard Worker ******************************************************************************
232*495ae853SAndroid Build Coastguard Worker */
ih264e_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t * ps_ngbr_avbl,WORD8 i1_pel_pos_x,WORD8 i1_pel_pos_y)233*495ae853SAndroid Build Coastguard Worker UWORD8 ih264e_derive_ngbr_avbl_of_mb_partitions(block_neighbors_t *ps_ngbr_avbl,
234*495ae853SAndroid Build Coastguard Worker                                                 WORD8 i1_pel_pos_x,
235*495ae853SAndroid Build Coastguard Worker                                                 WORD8 i1_pel_pos_y)
236*495ae853SAndroid Build Coastguard Worker {
237*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_neighbor_avail=0;
238*495ae853SAndroid Build Coastguard Worker 
239*495ae853SAndroid Build Coastguard Worker     /**********************************************************************/
240*495ae853SAndroid Build Coastguard Worker     /* values of i1_pel_pos_x in the range 0-15 inclusive correspond to   */
241*495ae853SAndroid Build Coastguard Worker     /* various columns of a macroblock                                    */
242*495ae853SAndroid Build Coastguard Worker     /*                                                                    */
243*495ae853SAndroid Build Coastguard Worker     /* values of i1_pel_pos_y in the range 0-15 inclusive correspond to   */
244*495ae853SAndroid Build Coastguard Worker     /* various rows of a macroblock                                       */
245*495ae853SAndroid Build Coastguard Worker     /*                                                                    */
246*495ae853SAndroid Build Coastguard Worker     /* other values of i1_pel_pos_x & i1_pel_pos_y represents elements    */
247*495ae853SAndroid Build Coastguard Worker     /* outside the bound of an mb ie., represents its neighbors.          */
248*495ae853SAndroid Build Coastguard Worker     /**********************************************************************/
249*495ae853SAndroid Build Coastguard Worker     if (i1_pel_pos_x < 0)
250*495ae853SAndroid Build Coastguard Worker     { /* column(-1) */
251*495ae853SAndroid Build Coastguard Worker         if (i1_pel_pos_y < 0)
252*495ae853SAndroid Build Coastguard Worker         { /* row(-1) */
253*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = ps_ngbr_avbl->u1_mb_d; /* current mb topleft availability */
254*495ae853SAndroid Build Coastguard Worker         }
255*495ae853SAndroid Build Coastguard Worker         else if (i1_pel_pos_y >= 0 && i1_pel_pos_y < 16)
256*495ae853SAndroid Build Coastguard Worker         { /* all rows of a macroblock */
257*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = ps_ngbr_avbl->u1_mb_a; /* current mb left availability */
258*495ae853SAndroid Build Coastguard Worker         }
259*495ae853SAndroid Build Coastguard Worker         else /* if (i1_pel_pos_y >= 16) */
260*495ae853SAndroid Build Coastguard Worker         { /* rows(+16) */
261*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = 0;  /* current mb bottom left availability */
262*495ae853SAndroid Build Coastguard Worker         }
263*495ae853SAndroid Build Coastguard Worker     }
264*495ae853SAndroid Build Coastguard Worker     else if (i1_pel_pos_x >= 0 && i1_pel_pos_x < 16)
265*495ae853SAndroid Build Coastguard Worker     { /* all columns of a macroblock */
266*495ae853SAndroid Build Coastguard Worker         if (i1_pel_pos_y < 0)
267*495ae853SAndroid Build Coastguard Worker         { /* row(-1) */
268*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = ps_ngbr_avbl->u1_mb_b; /* current mb top availability */
269*495ae853SAndroid Build Coastguard Worker         }
270*495ae853SAndroid Build Coastguard Worker         else if (i1_pel_pos_y >= 0 && i1_pel_pos_y < 16)
271*495ae853SAndroid Build Coastguard Worker         { /* all rows of a macroblock */
272*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = 1; /* current mb availability */
273*495ae853SAndroid Build Coastguard Worker             /* availability of the partition is dependent on the position of the partition inside the mb */
274*495ae853SAndroid Build Coastguard Worker             /* although the availability is declared as 1 in all cases these needs to be corrected somewhere else and this is not done in here */
275*495ae853SAndroid Build Coastguard Worker         }
276*495ae853SAndroid Build Coastguard Worker         else /* if (i1_pel_pos_y >= 16) */
277*495ae853SAndroid Build Coastguard Worker         { /* rows(+16) */
278*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = 0;  /* current mb bottom availability */
279*495ae853SAndroid Build Coastguard Worker         }
280*495ae853SAndroid Build Coastguard Worker     }
281*495ae853SAndroid Build Coastguard Worker     else if (i1_pel_pos_x >= 16)
282*495ae853SAndroid Build Coastguard Worker     { /* column(+16) */
283*495ae853SAndroid Build Coastguard Worker         if (i1_pel_pos_y < 0)
284*495ae853SAndroid Build Coastguard Worker         { /* row(-1) */
285*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = ps_ngbr_avbl->u1_mb_c; /* current mb top right availability */
286*495ae853SAndroid Build Coastguard Worker         }
287*495ae853SAndroid Build Coastguard Worker         else /* if (i1_pel_pos_y >= 0) */
288*495ae853SAndroid Build Coastguard Worker         { /* all other rows */
289*495ae853SAndroid Build Coastguard Worker             u1_neighbor_avail = 0;  /* current mb right & bottom right availability */
290*495ae853SAndroid Build Coastguard Worker         }
291*495ae853SAndroid Build Coastguard Worker     }
292*495ae853SAndroid Build Coastguard Worker 
293*495ae853SAndroid Build Coastguard Worker     return u1_neighbor_avail;
294*495ae853SAndroid Build Coastguard Worker }
295*495ae853SAndroid Build Coastguard Worker 
296*495ae853SAndroid Build Coastguard Worker /**
297*495ae853SAndroid Build Coastguard Worker ******************************************************************************
298*495ae853SAndroid Build Coastguard Worker *
299*495ae853SAndroid Build Coastguard Worker * @brief
300*495ae853SAndroid Build Coastguard Worker *  evaluate best intra 16x16 mode (rate distortion opt off)
301*495ae853SAndroid Build Coastguard Worker *
302*495ae853SAndroid Build Coastguard Worker * @par Description
303*495ae853SAndroid Build Coastguard Worker *  This function evaluates all the possible intra 16x16 modes and finds the mode
304*495ae853SAndroid Build Coastguard Worker *  that best represents the macro-block (least distortion) and occupies fewer
305*495ae853SAndroid Build Coastguard Worker *  bits in the bit-stream.
306*495ae853SAndroid Build Coastguard Worker *
307*495ae853SAndroid Build Coastguard Worker * @param[in]   ps_proc_ctxt
308*495ae853SAndroid Build Coastguard Worker *  pointer to process context (handle)
309*495ae853SAndroid Build Coastguard Worker *
310*495ae853SAndroid Build Coastguard Worker * @remarks
311*495ae853SAndroid Build Coastguard Worker *  Ideally the cost of encoding a macroblock is calculated as
312*495ae853SAndroid Build Coastguard Worker *  (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
313*495ae853SAndroid Build Coastguard Worker *  input block and the reconstructed block and rate is the number of bits taken
314*495ae853SAndroid Build Coastguard Worker *  to place the macroblock in the bit-stream. In this routine the rate does not
315*495ae853SAndroid Build Coastguard Worker *  exactly point to the total number of bits it takes, rather it points to header
316*495ae853SAndroid Build Coastguard Worker *  bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
317*495ae853SAndroid Build Coastguard Worker *  and residual bits fall in to texture bits the number of bits taken to encoding
318*495ae853SAndroid Build Coastguard Worker *  mbtype is considered as rate, we compute cost. Further we will approximate
319*495ae853SAndroid Build Coastguard Worker *  the distortion as the deviation b/w input and the predicted block as opposed
320*495ae853SAndroid Build Coastguard Worker *  to input and reconstructed block.
321*495ae853SAndroid Build Coastguard Worker *
322*495ae853SAndroid Build Coastguard Worker *  NOTE: As per the Document JVT-O079, for intra 16x16 macroblock,
323*495ae853SAndroid Build Coastguard Worker *  the SAD and cost are one and the same.
324*495ae853SAndroid Build Coastguard Worker *
325*495ae853SAndroid Build Coastguard Worker * @return     none
326*495ae853SAndroid Build Coastguard Worker *
327*495ae853SAndroid Build Coastguard Worker ******************************************************************************
328*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t * ps_proc)329*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc)
330*495ae853SAndroid Build Coastguard Worker {
331*495ae853SAndroid Build Coastguard Worker     /* Codec Context */
332*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
333*495ae853SAndroid Build Coastguard Worker 
334*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 8x8 block */
335*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion = INT_MAX, i4_mb_distortion_least = INT_MAX;
336*495ae853SAndroid Build Coastguard Worker 
337*495ae853SAndroid Build Coastguard Worker     /* lambda */
338*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda = ps_proc->u4_lambda;
339*495ae853SAndroid Build Coastguard Worker 
340*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
341*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_cost= INT_MAX, i4_mb_cost_least = INT_MAX;
342*495ae853SAndroid Build Coastguard Worker 
343*495ae853SAndroid Build Coastguard Worker     /* intra mode */
344*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_intra_mode, u4_best_intra_16x16_mode = DC_I16x16;
345*495ae853SAndroid Build Coastguard Worker 
346*495ae853SAndroid Build Coastguard Worker     /* neighbor pels for intra prediction */
347*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ngbr_pels_i16 = ps_proc->au1_ngbr_pels;
348*495ae853SAndroid Build Coastguard Worker 
349*495ae853SAndroid Build Coastguard Worker     /* neighbor availability */
350*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ngbr_avbl;
351*495ae853SAndroid Build Coastguard Worker 
352*495ae853SAndroid Build Coastguard Worker     /* pointer to src macro block */
353*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_curr_mb = ps_proc->pu1_src_buf_luma;
354*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb = ps_proc->pu1_rec_buf_luma;
355*495ae853SAndroid Build Coastguard Worker 
356*495ae853SAndroid Build Coastguard Worker     /* pointer to prediction macro block */
357*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb_intra_16x16 = ps_proc->pu1_pred_mb_intra_16x16;
358*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb_intra_16x16_plane = ps_proc->pu1_pred_mb_intra_16x16_plane;
359*495ae853SAndroid Build Coastguard Worker 
360*495ae853SAndroid Build Coastguard Worker     /* strides */
361*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_proc->i4_src_strd;
362*495ae853SAndroid Build Coastguard Worker     WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
363*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
364*495ae853SAndroid Build Coastguard Worker 
365*495ae853SAndroid Build Coastguard Worker     /* pointer to neighbors left, top, topleft */
366*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_a = pu1_ref_mb - 1;
367*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd;
368*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_d = pu1_mb_b - 1;
369*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
370*495ae853SAndroid Build Coastguard Worker 
371*495ae853SAndroid Build Coastguard Worker     /* valid intra modes map */
372*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_valid_intra_modes;
373*495ae853SAndroid Build Coastguard Worker 
374*495ae853SAndroid Build Coastguard Worker     /* lut for valid intra modes */
375*495ae853SAndroid Build Coastguard Worker     const UWORD8 u1_valid_intra_modes[8] = {4, 6, 4, 6, 5, 7, 5, 15};
376*495ae853SAndroid Build Coastguard Worker 
377*495ae853SAndroid Build Coastguard Worker     /* temp var */
378*495ae853SAndroid Build Coastguard Worker     UWORD32 i, u4_enable_fast_sad = 0, offset = 0;
379*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
380*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
381*495ae853SAndroid Build Coastguard Worker 
382*495ae853SAndroid Build Coastguard Worker     /* init temp var */
383*495ae853SAndroid Build Coastguard Worker     if (ps_proc->i4_slice_type != ISLICE)
384*495ae853SAndroid Build Coastguard Worker     {
385*495ae853SAndroid Build Coastguard Worker         /* Offset for MBtype */
386*495ae853SAndroid Build Coastguard Worker         offset = (ps_proc->i4_slice_type == PSLICE) ? 5 : 23;
387*495ae853SAndroid Build Coastguard Worker         u4_enable_fast_sad = ps_proc->s_me_ctxt.u4_enable_fast_sad;
388*495ae853SAndroid Build Coastguard Worker     }
389*495ae853SAndroid Build Coastguard Worker 
390*495ae853SAndroid Build Coastguard Worker     /* locating neighbors that are available for prediction */
391*495ae853SAndroid Build Coastguard Worker 
392*495ae853SAndroid Build Coastguard Worker     /* gather prediction pels from the neighbors, if particular set is not available
393*495ae853SAndroid Build Coastguard Worker      * it is set to zero*/
394*495ae853SAndroid Build Coastguard Worker     /* left pels */
395*495ae853SAndroid Build Coastguard Worker     u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
396*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
397*495ae853SAndroid Build Coastguard Worker     if (u1_mb_a)
398*495ae853SAndroid Build Coastguard Worker     {
399*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < 16; i++)
400*495ae853SAndroid Build Coastguard Worker             pu1_ngbr_pels_i16[16-1-i] = pu1_mb_a[i * i4_rec_strd];
401*495ae853SAndroid Build Coastguard Worker     }
402*495ae853SAndroid Build Coastguard Worker     else
403*495ae853SAndroid Build Coastguard Worker     {
404*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_set_mul8(pu1_ngbr_pels_i16,0,MB_SIZE);
405*495ae853SAndroid Build Coastguard Worker     }
406*495ae853SAndroid Build Coastguard Worker     /* top pels */
407*495ae853SAndroid Build Coastguard Worker     u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
408*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
409*495ae853SAndroid Build Coastguard Worker     if (u1_mb_b)
410*495ae853SAndroid Build Coastguard Worker     {
411*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_cpy_mul8(pu1_ngbr_pels_i16+16+1,pu1_mb_b,16);
412*495ae853SAndroid Build Coastguard Worker     }
413*495ae853SAndroid Build Coastguard Worker     else
414*495ae853SAndroid Build Coastguard Worker     {
415*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_set_mul8(pu1_ngbr_pels_i16+16+1,0,MB_SIZE);
416*495ae853SAndroid Build Coastguard Worker     }
417*495ae853SAndroid Build Coastguard Worker     /* topleft pels */
418*495ae853SAndroid Build Coastguard Worker     u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
419*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
420*495ae853SAndroid Build Coastguard Worker     if (u1_mb_d)
421*495ae853SAndroid Build Coastguard Worker     {
422*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_pels_i16[16] = *pu1_mb_d;
423*495ae853SAndroid Build Coastguard Worker     }
424*495ae853SAndroid Build Coastguard Worker     else
425*495ae853SAndroid Build Coastguard Worker     {
426*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_pels_i16[16] = 0;
427*495ae853SAndroid Build Coastguard Worker     }
428*495ae853SAndroid Build Coastguard Worker 
429*495ae853SAndroid Build Coastguard Worker     i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
430*495ae853SAndroid Build Coastguard Worker     ps_proc->i4_ngbr_avbl_16x16_mb = i4_ngbr_avbl;
431*495ae853SAndroid Build Coastguard Worker 
432*495ae853SAndroid Build Coastguard Worker     /* set valid intra modes for evaluation */
433*495ae853SAndroid Build Coastguard Worker     u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
434*495ae853SAndroid Build Coastguard Worker 
435*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST ||
436*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
437*495ae853SAndroid Build Coastguard Worker         u4_valid_intra_modes &= ~(1 << PLANE_I16x16);
438*495ae853SAndroid Build Coastguard Worker 
439*495ae853SAndroid Build Coastguard Worker     /* evaluate b/w HORZ_I16x16, VERT_I16x16 & DC_I16x16 */
440*495ae853SAndroid Build Coastguard Worker     ps_codec->pf_ih264e_evaluate_intra16x16_modes(pu1_curr_mb, pu1_ngbr_pels_i16, pu1_pred_mb_intra_16x16,
441*495ae853SAndroid Build Coastguard Worker                                                   i4_src_strd, i4_pred_strd,
442*495ae853SAndroid Build Coastguard Worker                                                   i4_ngbr_avbl, &u4_intra_mode, &i4_mb_distortion_least,
443*495ae853SAndroid Build Coastguard Worker                                                   u4_valid_intra_modes);
444*495ae853SAndroid Build Coastguard Worker 
445*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
446*495ae853SAndroid Build Coastguard Worker     i4_mb_cost_least = i4_mb_distortion_least;
447*495ae853SAndroid Build Coastguard Worker 
448*495ae853SAndroid Build Coastguard Worker     if (((u4_valid_intra_modes >> 3) & 1) != 0)
449*495ae853SAndroid Build Coastguard Worker     {
450*495ae853SAndroid Build Coastguard Worker         /* intra prediction for PLANE mode*/
451*495ae853SAndroid Build Coastguard Worker         (ps_codec->apf_intra_pred_16_l)[PLANE_I16x16](pu1_ngbr_pels_i16, pu1_pred_mb_intra_16x16_plane, 0, i4_pred_strd, i4_ngbr_avbl);
452*495ae853SAndroid Build Coastguard Worker 
453*495ae853SAndroid Build Coastguard Worker         /* evaluate distortion between the actual blk and the estimated blk for the given mode */
454*495ae853SAndroid Build Coastguard Worker         ps_codec->apf_compute_sad_16x16[u4_enable_fast_sad](pu1_curr_mb, pu1_pred_mb_intra_16x16_plane, i4_src_strd, i4_pred_strd, i4_mb_cost_least, &i4_mb_distortion);
455*495ae853SAndroid Build Coastguard Worker 
456*495ae853SAndroid Build Coastguard Worker         /* cost = distortion + lambda*rate */
457*495ae853SAndroid Build Coastguard Worker         i4_mb_cost = i4_mb_distortion;
458*495ae853SAndroid Build Coastguard Worker 
459*495ae853SAndroid Build Coastguard Worker         /* update the least cost information if necessary */
460*495ae853SAndroid Build Coastguard Worker         if(i4_mb_cost < i4_mb_distortion_least)
461*495ae853SAndroid Build Coastguard Worker         {
462*495ae853SAndroid Build Coastguard Worker             u4_intra_mode = PLANE_I16x16;
463*495ae853SAndroid Build Coastguard Worker 
464*495ae853SAndroid Build Coastguard Worker             i4_mb_cost_least = i4_mb_cost;
465*495ae853SAndroid Build Coastguard Worker             i4_mb_distortion_least = i4_mb_distortion;
466*495ae853SAndroid Build Coastguard Worker         }
467*495ae853SAndroid Build Coastguard Worker     }
468*495ae853SAndroid Build Coastguard Worker 
469*495ae853SAndroid Build Coastguard Worker     u4_best_intra_16x16_mode = u4_intra_mode;
470*495ae853SAndroid Build Coastguard Worker 
471*495ae853SAndroid Build Coastguard Worker     DEBUG("%d partition cost, %d intra mode\n", i4_mb_cost_least * 32, u4_best_intra_16x16_mode);
472*495ae853SAndroid Build Coastguard Worker 
473*495ae853SAndroid Build Coastguard Worker     ps_proc->u1_l_i16_mode = u4_best_intra_16x16_mode;
474*495ae853SAndroid Build Coastguard Worker 
475*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
476*495ae853SAndroid Build Coastguard Worker     i4_mb_cost_least    = i4_mb_distortion_least + u4_lambda*u1_uev_codelength[offset + u4_best_intra_16x16_mode];
477*495ae853SAndroid Build Coastguard Worker 
478*495ae853SAndroid Build Coastguard Worker 
479*495ae853SAndroid Build Coastguard Worker     /* update the type of the mb if necessary */
480*495ae853SAndroid Build Coastguard Worker     if (i4_mb_cost_least < ps_proc->i4_mb_cost)
481*495ae853SAndroid Build Coastguard Worker     {
482*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_cost = i4_mb_cost_least;
483*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_distortion = i4_mb_distortion_least;
484*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_mb_type = I16x16;
485*495ae853SAndroid Build Coastguard Worker     }
486*495ae853SAndroid Build Coastguard Worker     if (i4_mb_cost_least < ps_proc->i4_mb_intra_cost)
487*495ae853SAndroid Build Coastguard Worker     {
488*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_intra_cost = i4_mb_cost_least;
489*495ae853SAndroid Build Coastguard Worker     }
490*495ae853SAndroid Build Coastguard Worker 
491*495ae853SAndroid Build Coastguard Worker     return ;
492*495ae853SAndroid Build Coastguard Worker }
493*495ae853SAndroid Build Coastguard Worker 
494*495ae853SAndroid Build Coastguard Worker 
495*495ae853SAndroid Build Coastguard Worker /**
496*495ae853SAndroid Build Coastguard Worker ******************************************************************************
497*495ae853SAndroid Build Coastguard Worker *
498*495ae853SAndroid Build Coastguard Worker * @brief
499*495ae853SAndroid Build Coastguard Worker *  evaluate best intra 8x8 mode (rate distortion opt on)
500*495ae853SAndroid Build Coastguard Worker *
501*495ae853SAndroid Build Coastguard Worker * @par Description
502*495ae853SAndroid Build Coastguard Worker *  This function evaluates all the possible intra 8x8 modes and finds the mode
503*495ae853SAndroid Build Coastguard Worker *  that best represents the macro-block (least distortion) and occupies fewer
504*495ae853SAndroid Build Coastguard Worker *  bits in the bit-stream.
505*495ae853SAndroid Build Coastguard Worker *
506*495ae853SAndroid Build Coastguard Worker * @param[in]    ps_proc_ctxt
507*495ae853SAndroid Build Coastguard Worker *  pointer to proc ctxt
508*495ae853SAndroid Build Coastguard Worker *
509*495ae853SAndroid Build Coastguard Worker * @remarks Ideally the cost of encoding a macroblock is calculated as
510*495ae853SAndroid Build Coastguard Worker *  (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
511*495ae853SAndroid Build Coastguard Worker *  input block and the reconstructed block and rate is the number of bits taken
512*495ae853SAndroid Build Coastguard Worker *  to place the macroblock in the bit-stream. In this routine the rate does not
513*495ae853SAndroid Build Coastguard Worker *  exactly point to the total number of bits it takes, rather it points to header
514*495ae853SAndroid Build Coastguard Worker *  bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
515*495ae853SAndroid Build Coastguard Worker *  and residual bits fall in to texture bits the number of bits taken to encoding
516*495ae853SAndroid Build Coastguard Worker *  mbtype is considered as rate, we compute cost. Further we will approximate
517*495ae853SAndroid Build Coastguard Worker *  the distortion as the deviation b/w input and the predicted block as opposed
518*495ae853SAndroid Build Coastguard Worker *  to input and reconstructed block.
519*495ae853SAndroid Build Coastguard Worker *
520*495ae853SAndroid Build Coastguard Worker *  NOTE: TODO: This function needs to be tested
521*495ae853SAndroid Build Coastguard Worker *
522*495ae853SAndroid Build Coastguard Worker *  @return      none
523*495ae853SAndroid Build Coastguard Worker *
524*495ae853SAndroid Build Coastguard Worker ******************************************************************************
525*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t * ps_proc)526*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc)
527*495ae853SAndroid Build Coastguard Worker {
528*495ae853SAndroid Build Coastguard Worker     /* Codec Context */
529*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
530*495ae853SAndroid Build Coastguard Worker 
531*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 4x4 block */
532*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_distortion, i4_partition_distortion_least = INT_MAX, i4_total_distortion = 0;
533*495ae853SAndroid Build Coastguard Worker 
534*495ae853SAndroid Build Coastguard Worker     /* lambda */
535*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda = ps_proc->u4_lambda;
536*495ae853SAndroid Build Coastguard Worker 
537*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
538*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_cost, i4_partition_cost_least, i4_total_cost = u4_lambda;
539*495ae853SAndroid Build Coastguard Worker 
540*495ae853SAndroid Build Coastguard Worker     /* cost due to mbtype */
541*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
542*495ae853SAndroid Build Coastguard Worker 
543*495ae853SAndroid Build Coastguard Worker     /* intra mode */
544*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_intra_mode, u4_best_intra_8x8_mode = DC_I8x8, u4_estimated_intra_8x8_mode;
545*495ae853SAndroid Build Coastguard Worker 
546*495ae853SAndroid Build Coastguard Worker     /* neighbor pels for intra prediction */
547*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ngbr_pels_i8 = ps_proc->au1_ngbr_pels;
548*495ae853SAndroid Build Coastguard Worker 
549*495ae853SAndroid Build Coastguard Worker     /* pointer to curr partition */
550*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_curr;
551*495ae853SAndroid Build Coastguard Worker 
552*495ae853SAndroid Build Coastguard Worker     /* pointer to prediction macro block */
553*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
554*495ae853SAndroid Build Coastguard Worker 
555*495ae853SAndroid Build Coastguard Worker     /* strides */
556*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_proc->i4_src_strd;
557*495ae853SAndroid Build Coastguard Worker     WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
558*495ae853SAndroid Build Coastguard Worker 
559*495ae853SAndroid Build Coastguard Worker     /* neighbors left, top, top right, top left */
560*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_a;
561*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_b;
562*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_d;
563*495ae853SAndroid Build Coastguard Worker 
564*495ae853SAndroid Build Coastguard Worker     /* neighbor availability */
565*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ngbr_avbl;
566*495ae853SAndroid Build Coastguard Worker     block_neighbors_t s_ngbr_avbl;
567*495ae853SAndroid Build Coastguard Worker 
568*495ae853SAndroid Build Coastguard Worker     /* temp vars */
569*495ae853SAndroid Build Coastguard Worker     UWORD32  b8, u4_pix_x, u4_pix_y;
570*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
571*495ae853SAndroid Build Coastguard Worker     block_neighbors_t s_ngbr_avbl_MB;
572*495ae853SAndroid Build Coastguard Worker 
573*495ae853SAndroid Build Coastguard Worker     /* ngbr mb syntax information */
574*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
575*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
576*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
577*495ae853SAndroid Build Coastguard Worker 
578*495ae853SAndroid Build Coastguard Worker     /* valid intra modes map */
579*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_valid_intra_modes;
580*495ae853SAndroid Build Coastguard Worker 
581*495ae853SAndroid Build Coastguard Worker     if (ps_proc->ps_ngbr_avbl->u1_mb_c)
582*495ae853SAndroid Build Coastguard Worker     {
583*495ae853SAndroid Build Coastguard Worker         ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + (ps_proc->i4_mb_x + 1);
584*495ae853SAndroid Build Coastguard Worker     }
585*495ae853SAndroid Build Coastguard Worker     /* left pels */
586*495ae853SAndroid Build Coastguard Worker     s_ngbr_avbl_MB.u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
587*495ae853SAndroid Build Coastguard Worker                                   && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
588*495ae853SAndroid Build Coastguard Worker 
589*495ae853SAndroid Build Coastguard Worker     /* top pels */
590*495ae853SAndroid Build Coastguard Worker     s_ngbr_avbl_MB.u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
591*495ae853SAndroid Build Coastguard Worker                                   && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
592*495ae853SAndroid Build Coastguard Worker 
593*495ae853SAndroid Build Coastguard Worker     /* topleft pels */
594*495ae853SAndroid Build Coastguard Worker     s_ngbr_avbl_MB.u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
595*495ae853SAndroid Build Coastguard Worker                                   && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
596*495ae853SAndroid Build Coastguard Worker 
597*495ae853SAndroid Build Coastguard Worker     /* top right */
598*495ae853SAndroid Build Coastguard Worker     s_ngbr_avbl_MB.u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
599*495ae853SAndroid Build Coastguard Worker                                   && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
600*495ae853SAndroid Build Coastguard Worker 
601*495ae853SAndroid Build Coastguard Worker 
602*495ae853SAndroid Build Coastguard Worker     for (b8 = 0; b8 < 4; b8++)
603*495ae853SAndroid Build Coastguard Worker     {
604*495ae853SAndroid Build Coastguard Worker         u4_pix_x = (b8 & 0x01) << 3;
605*495ae853SAndroid Build Coastguard Worker         u4_pix_y = (b8 >> 1) << 3;
606*495ae853SAndroid Build Coastguard Worker 
607*495ae853SAndroid Build Coastguard Worker         pu1_mb_curr = ps_proc->pu1_src_buf_luma + u4_pix_x + (u4_pix_y * i4_src_strd);
608*495ae853SAndroid Build Coastguard Worker         /* when rdopt is off, we use the input as reference for constructing prediction buffer */
609*495ae853SAndroid Build Coastguard Worker         /* as opposed to using the recon pels. (open loop intra prediction) */
610*495ae853SAndroid Build Coastguard Worker         pu1_mb_a = pu1_mb_curr - 1; /* pointer to left macro block */
611*495ae853SAndroid Build Coastguard Worker         pu1_mb_b = pu1_mb_curr - i4_src_strd; /* pointer to top macro block */
612*495ae853SAndroid Build Coastguard Worker         pu1_mb_d = pu1_mb_b - 1; /* pointer to top left macro block */
613*495ae853SAndroid Build Coastguard Worker 
614*495ae853SAndroid Build Coastguard Worker         /* locating neighbors that are available for prediction */
615*495ae853SAndroid Build Coastguard Worker         /* TODO : update the neighbor availability information basing on constrained intra pred information */
616*495ae853SAndroid Build Coastguard Worker         /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines */
617*495ae853SAndroid Build Coastguard Worker         /* basing on neighbors available and hence evade the computation of neighbor availability totally. */
618*495ae853SAndroid Build Coastguard Worker         s_ngbr_avbl.u1_mb_a = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y); /* xD = -1, yD = 0 */
619*495ae853SAndroid Build Coastguard Worker         s_ngbr_avbl.u1_mb_b = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x, u4_pix_y - 1); /* xD = 0, yD = -1 */
620*495ae853SAndroid Build Coastguard Worker         s_ngbr_avbl.u1_mb_c = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x + 8, u4_pix_y - 1); /* xD = BLK_8x8_SIZE, yD = -1 */
621*495ae853SAndroid Build Coastguard Worker         s_ngbr_avbl.u1_mb_d = ih264e_derive_ngbr_avbl_of_mb_partitions(&s_ngbr_avbl_MB, u4_pix_x - 1, u4_pix_y - 1); /* xD = -1, yD = -1 */
622*495ae853SAndroid Build Coastguard Worker 
623*495ae853SAndroid Build Coastguard Worker         /* i4_ngbr_avbl = blk_a * LEFT_MB_AVAILABLE_MASK + blk_b * TOP_MB_AVAILABLE_MASK + blk_c * TOP_RIGHT_MB_AVAILABLE_MASK + blk_d * TOP_LEFT_MB_AVAILABLE_MASK */
624*495ae853SAndroid Build Coastguard Worker         i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) + (s_ngbr_avbl.u1_mb_b << 2) +  (s_ngbr_avbl.u1_mb_c << 3) +
625*495ae853SAndroid Build Coastguard Worker                         (s_ngbr_avbl.u1_mb_a << 4);
626*495ae853SAndroid Build Coastguard Worker         /* if top partition is available and top right is not available for intra prediction, then */
627*495ae853SAndroid Build Coastguard Worker         /* padd top right samples using top sample and make top right also available */
628*495ae853SAndroid Build Coastguard Worker         /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) + (s_ngbr_avbl.u1_mb_b << 2) +  ((s_ngbr_avbl.u1_mb_b | s_ngbr_avbl.u1_mb_c) << 3); */
629*495ae853SAndroid Build Coastguard Worker         ps_proc->ai4_neighbor_avail_8x8_subblks[b8] = i4_ngbr_avbl;
630*495ae853SAndroid Build Coastguard Worker 
631*495ae853SAndroid Build Coastguard Worker 
632*495ae853SAndroid Build Coastguard Worker         ih264_intra_pred_luma_8x8_mode_ref_filtering(pu1_mb_a, pu1_mb_b, pu1_mb_d, pu1_ngbr_pels_i8,
633*495ae853SAndroid Build Coastguard Worker                                                      i4_src_strd, i4_ngbr_avbl);
634*495ae853SAndroid Build Coastguard Worker 
635*495ae853SAndroid Build Coastguard Worker         i4_partition_cost_least = INT_MAX;
636*495ae853SAndroid Build Coastguard Worker         /* set valid intra modes for evaluation */
637*495ae853SAndroid Build Coastguard Worker         u4_valid_intra_modes = 0x1ff;
638*495ae853SAndroid Build Coastguard Worker 
639*495ae853SAndroid Build Coastguard Worker         if (!s_ngbr_avbl.u1_mb_b)
640*495ae853SAndroid Build Coastguard Worker         {
641*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << VERT_I4x4);
642*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << DIAG_DL_I4x4);
643*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << VERT_L_I4x4);
644*495ae853SAndroid Build Coastguard Worker         }
645*495ae853SAndroid Build Coastguard Worker         if (!s_ngbr_avbl.u1_mb_a)
646*495ae853SAndroid Build Coastguard Worker         {
647*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << HORZ_I4x4);
648*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << HORZ_U_I4x4);
649*495ae853SAndroid Build Coastguard Worker         }
650*495ae853SAndroid Build Coastguard Worker         if (!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b || !s_ngbr_avbl.u1_mb_d)
651*495ae853SAndroid Build Coastguard Worker         {
652*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << DIAG_DR_I4x4);
653*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << VERT_R_I4x4);
654*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes &= ~(1 << HORZ_D_I4x4);
655*495ae853SAndroid Build Coastguard Worker         }
656*495ae853SAndroid Build Coastguard Worker 
657*495ae853SAndroid Build Coastguard Worker         /* estimate the intra 8x8 mode for the current partition (for evaluating cost) */
658*495ae853SAndroid Build Coastguard Worker         if (!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
659*495ae853SAndroid Build Coastguard Worker         {
660*495ae853SAndroid Build Coastguard Worker             u4_estimated_intra_8x8_mode = DC_I8x8;
661*495ae853SAndroid Build Coastguard Worker         }
662*495ae853SAndroid Build Coastguard Worker         else
663*495ae853SAndroid Build Coastguard Worker         {
664*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_left_intra_8x8_mode = DC_I8x8;
665*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_top_intra_8x8_mode = DC_I8x8;
666*495ae853SAndroid Build Coastguard Worker 
667*495ae853SAndroid Build Coastguard Worker             if (u4_pix_x == 0)
668*495ae853SAndroid Build Coastguard Worker             {
669*495ae853SAndroid Build Coastguard Worker                 if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I8x8)
670*495ae853SAndroid Build Coastguard Worker                 {
671*495ae853SAndroid Build Coastguard Worker                     u4_left_intra_8x8_mode = ps_proc->au1_left_mb_intra_modes[b8+1];
672*495ae853SAndroid Build Coastguard Worker                 }
673*495ae853SAndroid Build Coastguard Worker                 else if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I4x4)
674*495ae853SAndroid Build Coastguard Worker                 {
675*495ae853SAndroid Build Coastguard Worker                     u4_left_intra_8x8_mode = ps_proc->au1_left_mb_intra_modes[(b8+1)*4+2];
676*495ae853SAndroid Build Coastguard Worker                 }
677*495ae853SAndroid Build Coastguard Worker             }
678*495ae853SAndroid Build Coastguard Worker             else
679*495ae853SAndroid Build Coastguard Worker             {
680*495ae853SAndroid Build Coastguard Worker                 u4_left_intra_8x8_mode = ps_proc->au1_intra_luma_mb_8x8_modes[b8-1];
681*495ae853SAndroid Build Coastguard Worker             }
682*495ae853SAndroid Build Coastguard Worker 
683*495ae853SAndroid Build Coastguard Worker             if (u4_pix_y == 0)
684*495ae853SAndroid Build Coastguard Worker             {
685*495ae853SAndroid Build Coastguard Worker                 if (ps_top_mb_syn_ele->u2_mb_type == I8x8)
686*495ae853SAndroid Build Coastguard Worker                 {
687*495ae853SAndroid Build Coastguard Worker                     u4_top_intra_8x8_mode = pu1_top_mb_intra_modes[b8+2];
688*495ae853SAndroid Build Coastguard Worker                 }
689*495ae853SAndroid Build Coastguard Worker                 else if (ps_top_mb_syn_ele->u2_mb_type == I4x4)
690*495ae853SAndroid Build Coastguard Worker                 {
691*495ae853SAndroid Build Coastguard Worker                     u4_top_intra_8x8_mode = pu1_top_mb_intra_modes[(b8+2)*4+2];
692*495ae853SAndroid Build Coastguard Worker                 }
693*495ae853SAndroid Build Coastguard Worker             }
694*495ae853SAndroid Build Coastguard Worker             else
695*495ae853SAndroid Build Coastguard Worker             {
696*495ae853SAndroid Build Coastguard Worker                 u4_top_intra_8x8_mode = ps_proc->au1_intra_luma_mb_8x8_modes[b8-2];
697*495ae853SAndroid Build Coastguard Worker             }
698*495ae853SAndroid Build Coastguard Worker 
699*495ae853SAndroid Build Coastguard Worker             u4_estimated_intra_8x8_mode = MIN(u4_left_intra_8x8_mode, u4_top_intra_8x8_mode);
700*495ae853SAndroid Build Coastguard Worker         }
701*495ae853SAndroid Build Coastguard Worker 
702*495ae853SAndroid Build Coastguard Worker         /* perform intra mode 8x8 evaluation */
703*495ae853SAndroid Build Coastguard Worker         for (u4_intra_mode = VERT_I8x8; u4_valid_intra_modes != 0; u4_intra_mode++, u4_valid_intra_modes >>= 1)
704*495ae853SAndroid Build Coastguard Worker         {
705*495ae853SAndroid Build Coastguard Worker             if ( (u4_valid_intra_modes & 1) == 0)
706*495ae853SAndroid Build Coastguard Worker                 continue;
707*495ae853SAndroid Build Coastguard Worker 
708*495ae853SAndroid Build Coastguard Worker             /* intra prediction */
709*495ae853SAndroid Build Coastguard Worker             (ps_codec->apf_intra_pred_8_l)[u4_intra_mode](pu1_ngbr_pels_i8, pu1_pred_mb, 0, i4_pred_strd, i4_ngbr_avbl);
710*495ae853SAndroid Build Coastguard Worker 
711*495ae853SAndroid Build Coastguard Worker             /* evaluate distortion between the actual blk and the estimated blk for the given mode */
712*495ae853SAndroid Build Coastguard Worker             ime_compute_sad_8x8(pu1_mb_curr, pu1_pred_mb, i4_src_strd, i4_pred_strd, i4_partition_cost_least, &i4_partition_distortion);
713*495ae853SAndroid Build Coastguard Worker 
714*495ae853SAndroid Build Coastguard Worker             i4_partition_cost = i4_partition_distortion + ((u4_estimated_intra_8x8_mode == u4_intra_mode)?u4_cost_one_bit:u4_cost_four_bits);
715*495ae853SAndroid Build Coastguard Worker 
716*495ae853SAndroid Build Coastguard Worker             /* update the least cost information if necessary */
717*495ae853SAndroid Build Coastguard Worker             if (i4_partition_cost < i4_partition_cost_least)
718*495ae853SAndroid Build Coastguard Worker             {
719*495ae853SAndroid Build Coastguard Worker                 i4_partition_cost_least = i4_partition_cost;
720*495ae853SAndroid Build Coastguard Worker                 i4_partition_distortion_least = i4_partition_distortion;
721*495ae853SAndroid Build Coastguard Worker                 u4_best_intra_8x8_mode = u4_intra_mode;
722*495ae853SAndroid Build Coastguard Worker             }
723*495ae853SAndroid Build Coastguard Worker         }
724*495ae853SAndroid Build Coastguard Worker         /* macroblock distortion */
725*495ae853SAndroid Build Coastguard Worker         i4_total_cost += i4_partition_cost_least;
726*495ae853SAndroid Build Coastguard Worker         i4_total_distortion += i4_partition_distortion_least;
727*495ae853SAndroid Build Coastguard Worker         /* mb partition mode */
728*495ae853SAndroid Build Coastguard Worker         ps_proc->au1_intra_luma_mb_8x8_modes[b8] = u4_best_intra_8x8_mode;
729*495ae853SAndroid Build Coastguard Worker 
730*495ae853SAndroid Build Coastguard Worker     }
731*495ae853SAndroid Build Coastguard Worker 
732*495ae853SAndroid Build Coastguard Worker     /* update the type of the mb if necessary */
733*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_cost)
734*495ae853SAndroid Build Coastguard Worker     {
735*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_cost = i4_total_cost;
736*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_distortion = i4_total_distortion;
737*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_mb_type = I8x8;
738*495ae853SAndroid Build Coastguard Worker     }
739*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_intra_cost)
740*495ae853SAndroid Build Coastguard Worker     {
741*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_intra_cost = i4_total_cost;
742*495ae853SAndroid Build Coastguard Worker     }
743*495ae853SAndroid Build Coastguard Worker 
744*495ae853SAndroid Build Coastguard Worker     return ;
745*495ae853SAndroid Build Coastguard Worker }
746*495ae853SAndroid Build Coastguard Worker 
747*495ae853SAndroid Build Coastguard Worker 
748*495ae853SAndroid Build Coastguard Worker /**
749*495ae853SAndroid Build Coastguard Worker ******************************************************************************
750*495ae853SAndroid Build Coastguard Worker *
751*495ae853SAndroid Build Coastguard Worker * @brief
752*495ae853SAndroid Build Coastguard Worker *  evaluate best intra 4x4 mode (rate distortion opt off)
753*495ae853SAndroid Build Coastguard Worker *
754*495ae853SAndroid Build Coastguard Worker * @par Description
755*495ae853SAndroid Build Coastguard Worker *  This function evaluates all the possible intra 4x4 modes and finds the mode
756*495ae853SAndroid Build Coastguard Worker *  that best represents the macro-block (least distortion) and occupies fewer
757*495ae853SAndroid Build Coastguard Worker *  bits in the bit-stream.
758*495ae853SAndroid Build Coastguard Worker *
759*495ae853SAndroid Build Coastguard Worker * @param[in]    ps_proc_ctxt
760*495ae853SAndroid Build Coastguard Worker *  pointer to proc ctxt
761*495ae853SAndroid Build Coastguard Worker *
762*495ae853SAndroid Build Coastguard Worker * @remarks
763*495ae853SAndroid Build Coastguard Worker *  Ideally the cost of encoding a macroblock is calculated as
764*495ae853SAndroid Build Coastguard Worker *  (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
765*495ae853SAndroid Build Coastguard Worker *  input block and the reconstructed block and rate is the number of bits taken
766*495ae853SAndroid Build Coastguard Worker *  to place the macroblock in the bit-stream. In this routine the rate does not
767*495ae853SAndroid Build Coastguard Worker *  exactly point to the total number of bits it takes, rather it points to header
768*495ae853SAndroid Build Coastguard Worker *  bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
769*495ae853SAndroid Build Coastguard Worker *  and residual bits fall in to texture bits the number of bits taken to encoding
770*495ae853SAndroid Build Coastguard Worker *  mbtype is considered as rate, we compute cost. Further we will approximate
771*495ae853SAndroid Build Coastguard Worker *  the distortion as the deviation b/w input and the predicted block as opposed
772*495ae853SAndroid Build Coastguard Worker *  to input and reconstructed block.
773*495ae853SAndroid Build Coastguard Worker *
774*495ae853SAndroid Build Coastguard Worker *  NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
775*495ae853SAndroid Build Coastguard Worker *  24*lambda is added to the SAD before comparison with the best SAD for
776*495ae853SAndroid Build Coastguard Worker *  inter prediction. This is an empirical value to prevent using too many intra
777*495ae853SAndroid Build Coastguard Worker *  blocks.
778*495ae853SAndroid Build Coastguard Worker *
779*495ae853SAndroid Build Coastguard Worker * @return      none
780*495ae853SAndroid Build Coastguard Worker *
781*495ae853SAndroid Build Coastguard Worker ******************************************************************************
782*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t * ps_proc)783*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc)
784*495ae853SAndroid Build Coastguard Worker {
785*495ae853SAndroid Build Coastguard Worker     /* Codec Context */
786*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
787*495ae853SAndroid Build Coastguard Worker 
788*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 4x4 block */
789*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_distortion_least = INT_MAX, i4_total_distortion = 0;
790*495ae853SAndroid Build Coastguard Worker 
791*495ae853SAndroid Build Coastguard Worker     /* lambda */
792*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda = ps_proc->u4_lambda;
793*495ae853SAndroid Build Coastguard Worker 
794*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
795*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_cost_least, i4_total_cost = (24 + 1) * u4_lambda;
796*495ae853SAndroid Build Coastguard Worker 
797*495ae853SAndroid Build Coastguard Worker     /* cost due to mbtype */
798*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
799*495ae853SAndroid Build Coastguard Worker 
800*495ae853SAndroid Build Coastguard Worker     /* intra mode */
801*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_best_intra_4x4_mode = DC_I4x4, u4_estimated_intra_4x4_mode;
802*495ae853SAndroid Build Coastguard Worker 
803*495ae853SAndroid Build Coastguard Worker     /* neighbor pels for intra prediction */
804*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ngbr_pels_i4 = ps_proc->au1_ngbr_pels;
805*495ae853SAndroid Build Coastguard Worker 
806*495ae853SAndroid Build Coastguard Worker     /* pointer to curr partition */
807*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_curr;
808*495ae853SAndroid Build Coastguard Worker 
809*495ae853SAndroid Build Coastguard Worker     /* pointer to prediction macro block */
810*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
811*495ae853SAndroid Build Coastguard Worker 
812*495ae853SAndroid Build Coastguard Worker     /* strides */
813*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_proc->i4_src_strd;
814*495ae853SAndroid Build Coastguard Worker     WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
815*495ae853SAndroid Build Coastguard Worker 
816*495ae853SAndroid Build Coastguard Worker     /* neighbors left, top, top right, top left */
817*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_a;
818*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_b;
819*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_c;
820*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_d;
821*495ae853SAndroid Build Coastguard Worker 
822*495ae853SAndroid Build Coastguard Worker     /* neighbor availability */
823*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ngbr_avbl;
824*495ae853SAndroid Build Coastguard Worker     block_neighbors_t s_ngbr_avbl;
825*495ae853SAndroid Build Coastguard Worker 
826*495ae853SAndroid Build Coastguard Worker     /* temp vars */
827*495ae853SAndroid Build Coastguard Worker     UWORD32 i, b8, b4, u4_blk_x, u4_blk_y, u4_pix_x, u4_pix_y;
828*495ae853SAndroid Build Coastguard Worker 
829*495ae853SAndroid Build Coastguard Worker     /* scan order inside 4x4 block */
830*495ae853SAndroid Build Coastguard Worker     const UWORD8 u1_scan_order[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
831*495ae853SAndroid Build Coastguard Worker 
832*495ae853SAndroid Build Coastguard Worker     /* ngbr sub mb modes */
833*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
834*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
835*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
836*495ae853SAndroid Build Coastguard Worker 
837*495ae853SAndroid Build Coastguard Worker     /* valid intra modes map */
838*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_valid_intra_modes;
839*495ae853SAndroid Build Coastguard Worker     UWORD16 u2_valid_modes[8] = {4, 262, 4, 262, 141, 399, 141, 511};
840*495ae853SAndroid Build Coastguard Worker 
841*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
842*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
843*495ae853SAndroid Build Coastguard Worker 
844*495ae853SAndroid Build Coastguard Worker     if (ps_proc->ps_ngbr_avbl->u1_mb_c)
845*495ae853SAndroid Build Coastguard Worker     {
846*495ae853SAndroid Build Coastguard Worker         ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x + 1;
847*495ae853SAndroid Build Coastguard Worker     }
848*495ae853SAndroid Build Coastguard Worker     /* left pels */
849*495ae853SAndroid Build Coastguard Worker     u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
850*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
851*495ae853SAndroid Build Coastguard Worker 
852*495ae853SAndroid Build Coastguard Worker     /* top pels */
853*495ae853SAndroid Build Coastguard Worker     u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
854*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
855*495ae853SAndroid Build Coastguard Worker 
856*495ae853SAndroid Build Coastguard Worker     /* topleft pels */
857*495ae853SAndroid Build Coastguard Worker     u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
858*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
859*495ae853SAndroid Build Coastguard Worker 
860*495ae853SAndroid Build Coastguard Worker     /* top right */
861*495ae853SAndroid Build Coastguard Worker     u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
862*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
863*495ae853SAndroid Build Coastguard Worker 
864*495ae853SAndroid Build Coastguard Worker     i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
865*495ae853SAndroid Build Coastguard Worker     memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
866*495ae853SAndroid Build Coastguard Worker 
867*495ae853SAndroid Build Coastguard Worker     for (b8 = 0; b8 < 4; b8++)
868*495ae853SAndroid Build Coastguard Worker     {
869*495ae853SAndroid Build Coastguard Worker         u4_blk_x = (b8 & 0x01) << 3;
870*495ae853SAndroid Build Coastguard Worker         u4_blk_y = (b8 >> 1) << 3;
871*495ae853SAndroid Build Coastguard Worker         for (b4 = 0; b4 < 4; b4++)
872*495ae853SAndroid Build Coastguard Worker         {
873*495ae853SAndroid Build Coastguard Worker             u4_pix_x = u4_blk_x + ((b4 & 0x01) << 2);
874*495ae853SAndroid Build Coastguard Worker             u4_pix_y = u4_blk_y + ((b4 >> 1) << 2);
875*495ae853SAndroid Build Coastguard Worker 
876*495ae853SAndroid Build Coastguard Worker             pu1_mb_curr = ps_proc->pu1_src_buf_luma + u4_pix_x + (u4_pix_y * i4_src_strd);
877*495ae853SAndroid Build Coastguard Worker             /* when rdopt is off, we use the input as reference for constructing prediction buffer */
878*495ae853SAndroid Build Coastguard Worker             /* as opposed to using the recon pels. (open loop intra prediction) */
879*495ae853SAndroid Build Coastguard Worker             pu1_mb_a = pu1_mb_curr - 1; /* pointer to left macro block */
880*495ae853SAndroid Build Coastguard Worker             pu1_mb_b = pu1_mb_curr - i4_src_strd; /* pointer to top macro block */
881*495ae853SAndroid Build Coastguard Worker             pu1_mb_c = pu1_mb_b + 4; /* pointer to top macro block */
882*495ae853SAndroid Build Coastguard Worker             pu1_mb_d = pu1_mb_b - 1; /* pointer to top left macro block */
883*495ae853SAndroid Build Coastguard Worker 
884*495ae853SAndroid Build Coastguard Worker             /* locating neighbors that are available for prediction */
885*495ae853SAndroid Build Coastguard Worker             /* TODO : update the neighbor availability information basing on constrained intra pred information */
886*495ae853SAndroid Build Coastguard Worker             /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines */
887*495ae853SAndroid Build Coastguard Worker             /* basing on neighbors available and hence evade the computation of neighbor availability totally. */
888*495ae853SAndroid Build Coastguard Worker 
889*495ae853SAndroid Build Coastguard Worker             i4_ngbr_avbl = ps_proc->au1_ngbr_avbl_4x4_subblks[(b8 << 2) + b4];
890*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_a = (i4_ngbr_avbl & 0x1);
891*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_d = (i4_ngbr_avbl & 0x2) >> 1;
892*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_b = (i4_ngbr_avbl & 0x4) >> 2;
893*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_c = (i4_ngbr_avbl & 0x8) >> 3;
894*495ae853SAndroid Build Coastguard Worker             /* set valid intra modes for evaluation */
895*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes = u2_valid_modes[i4_ngbr_avbl & 0x7];
896*495ae853SAndroid Build Coastguard Worker 
897*495ae853SAndroid Build Coastguard Worker             /* if top partition is available and top right is not available for intra prediction, then */
898*495ae853SAndroid Build Coastguard Worker             /* padd top right samples using top sample and make top right also available */
899*495ae853SAndroid Build Coastguard Worker             /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) + (s_ngbr_avbl.u1_mb_b << 2) + ((s_ngbr_avbl.u1_mb_b | s_ngbr_avbl.u1_mb_c) << 3); */
900*495ae853SAndroid Build Coastguard Worker 
901*495ae853SAndroid Build Coastguard Worker             /* gather prediction pels from the neighbors */
902*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_a)
903*495ae853SAndroid Build Coastguard Worker             {
904*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < 4; i++)
905*495ae853SAndroid Build Coastguard Worker                     pu1_ngbr_pels_i4[4 - 1 -i] = pu1_mb_a[i * i4_src_strd];
906*495ae853SAndroid Build Coastguard Worker             }
907*495ae853SAndroid Build Coastguard Worker             else
908*495ae853SAndroid Build Coastguard Worker             {
909*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4, 0, 4);
910*495ae853SAndroid Build Coastguard Worker             }
911*495ae853SAndroid Build Coastguard Worker 
912*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_b)
913*495ae853SAndroid Build Coastguard Worker             {
914*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_ngbr_pels_i4 + 4 + 1, pu1_mb_b, 4);
915*495ae853SAndroid Build Coastguard Worker             }
916*495ae853SAndroid Build Coastguard Worker             else
917*495ae853SAndroid Build Coastguard Worker             {
918*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4 + 5, 0, 4);
919*495ae853SAndroid Build Coastguard Worker             }
920*495ae853SAndroid Build Coastguard Worker 
921*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_d)
922*495ae853SAndroid Build Coastguard Worker                 pu1_ngbr_pels_i4[4] = *pu1_mb_d;
923*495ae853SAndroid Build Coastguard Worker             else
924*495ae853SAndroid Build Coastguard Worker                 pu1_ngbr_pels_i4[4] = 0;
925*495ae853SAndroid Build Coastguard Worker 
926*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_c)
927*495ae853SAndroid Build Coastguard Worker             {
928*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_ngbr_pels_i4 + 8 + 1, pu1_mb_c, 4);
929*495ae853SAndroid Build Coastguard Worker             }
930*495ae853SAndroid Build Coastguard Worker             else if (s_ngbr_avbl.u1_mb_b)
931*495ae853SAndroid Build Coastguard Worker             {
932*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4 + 8 + 1, pu1_ngbr_pels_i4[8], 4);
933*495ae853SAndroid Build Coastguard Worker                 s_ngbr_avbl.u1_mb_c = s_ngbr_avbl.u1_mb_b;
934*495ae853SAndroid Build Coastguard Worker             }
935*495ae853SAndroid Build Coastguard Worker 
936*495ae853SAndroid Build Coastguard Worker             i4_partition_cost_least = INT_MAX;
937*495ae853SAndroid Build Coastguard Worker 
938*495ae853SAndroid Build Coastguard Worker             /* predict the intra 4x4 mode for the current partition (for evaluating cost) */
939*495ae853SAndroid Build Coastguard Worker             if (!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
940*495ae853SAndroid Build Coastguard Worker             {
941*495ae853SAndroid Build Coastguard Worker                 u4_estimated_intra_4x4_mode = DC_I4x4;
942*495ae853SAndroid Build Coastguard Worker             }
943*495ae853SAndroid Build Coastguard Worker             else
944*495ae853SAndroid Build Coastguard Worker             {
945*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_left_intra_4x4_mode = DC_I4x4;
946*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_top_intra_4x4_mode = DC_I4x4;
947*495ae853SAndroid Build Coastguard Worker 
948*495ae853SAndroid Build Coastguard Worker                 if (u4_pix_x == 0)
949*495ae853SAndroid Build Coastguard Worker                 {
950*495ae853SAndroid Build Coastguard Worker                     if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I4x4)
951*495ae853SAndroid Build Coastguard Worker                     {
952*495ae853SAndroid Build Coastguard Worker                         u4_left_intra_4x4_mode = ps_proc->au1_left_mb_intra_modes[u1_scan_order[3 + u4_pix_y]];
953*495ae853SAndroid Build Coastguard Worker                     }
954*495ae853SAndroid Build Coastguard Worker                     else if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I8x8)
955*495ae853SAndroid Build Coastguard Worker                     {
956*495ae853SAndroid Build Coastguard Worker                         u4_left_intra_4x4_mode = ps_proc->au1_left_mb_intra_modes[b8 + 1];
957*495ae853SAndroid Build Coastguard Worker                     }
958*495ae853SAndroid Build Coastguard Worker                 }
959*495ae853SAndroid Build Coastguard Worker                 else
960*495ae853SAndroid Build Coastguard Worker                 {
961*495ae853SAndroid Build Coastguard Worker                     u4_left_intra_4x4_mode = ps_proc->au1_intra_luma_mb_4x4_modes[u1_scan_order[(u4_pix_x >> 2) + u4_pix_y - 1]];
962*495ae853SAndroid Build Coastguard Worker                 }
963*495ae853SAndroid Build Coastguard Worker 
964*495ae853SAndroid Build Coastguard Worker                 if (u4_pix_y == 0)
965*495ae853SAndroid Build Coastguard Worker                 {
966*495ae853SAndroid Build Coastguard Worker                     if (ps_top_mb_syn_ele->u2_mb_type == I4x4)
967*495ae853SAndroid Build Coastguard Worker                     {
968*495ae853SAndroid Build Coastguard Worker                         u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[u1_scan_order[12 + (u4_pix_x >> 2)]];
969*495ae853SAndroid Build Coastguard Worker                     }
970*495ae853SAndroid Build Coastguard Worker                     else if (ps_top_mb_syn_ele->u2_mb_type == I8x8)
971*495ae853SAndroid Build Coastguard Worker                     {
972*495ae853SAndroid Build Coastguard Worker                         u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[b8 + 2];
973*495ae853SAndroid Build Coastguard Worker                     }
974*495ae853SAndroid Build Coastguard Worker                 }
975*495ae853SAndroid Build Coastguard Worker                 else
976*495ae853SAndroid Build Coastguard Worker                 {
977*495ae853SAndroid Build Coastguard Worker                     u4_top_intra_4x4_mode = ps_proc->au1_intra_luma_mb_4x4_modes[u1_scan_order[(u4_pix_x >> 2) + u4_pix_y - 4]];
978*495ae853SAndroid Build Coastguard Worker                 }
979*495ae853SAndroid Build Coastguard Worker 
980*495ae853SAndroid Build Coastguard Worker                 u4_estimated_intra_4x4_mode = MIN(u4_left_intra_4x4_mode, u4_top_intra_4x4_mode);
981*495ae853SAndroid Build Coastguard Worker             }
982*495ae853SAndroid Build Coastguard Worker 
983*495ae853SAndroid Build Coastguard Worker             ps_proc->au1_predicted_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_estimated_intra_4x4_mode;
984*495ae853SAndroid Build Coastguard Worker 
985*495ae853SAndroid Build Coastguard Worker             /* mode evaluation and prediction */
986*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_evaluate_intra_4x4_modes(pu1_mb_curr,
987*495ae853SAndroid Build Coastguard Worker                                                          pu1_ngbr_pels_i4,
988*495ae853SAndroid Build Coastguard Worker                                                          pu1_pred_mb, i4_src_strd,
989*495ae853SAndroid Build Coastguard Worker                                                          i4_pred_strd, i4_ngbr_avbl,
990*495ae853SAndroid Build Coastguard Worker                                                          &u4_best_intra_4x4_mode,
991*495ae853SAndroid Build Coastguard Worker                                                          &i4_partition_cost_least,
992*495ae853SAndroid Build Coastguard Worker                                                          u4_valid_intra_modes,
993*495ae853SAndroid Build Coastguard Worker                                                          u4_lambda,
994*495ae853SAndroid Build Coastguard Worker                                                          u4_estimated_intra_4x4_mode);
995*495ae853SAndroid Build Coastguard Worker 
996*495ae853SAndroid Build Coastguard Worker 
997*495ae853SAndroid Build Coastguard Worker             i4_partition_distortion_least = i4_partition_cost_least - ((u4_estimated_intra_4x4_mode == u4_best_intra_4x4_mode) ? u4_cost_one_bit : u4_cost_four_bits);
998*495ae853SAndroid Build Coastguard Worker 
999*495ae853SAndroid Build Coastguard Worker             DEBUG("%d partition cost, %d intra mode\n", i4_partition_cost_least, u4_best_intra_4x4_mode);
1000*495ae853SAndroid Build Coastguard Worker             /* macroblock distortion */
1001*495ae853SAndroid Build Coastguard Worker             i4_total_distortion += i4_partition_distortion_least;
1002*495ae853SAndroid Build Coastguard Worker             i4_total_cost += i4_partition_cost_least;
1003*495ae853SAndroid Build Coastguard Worker             /* mb partition mode */
1004*495ae853SAndroid Build Coastguard Worker             ps_proc->au1_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_best_intra_4x4_mode;
1005*495ae853SAndroid Build Coastguard Worker         }
1006*495ae853SAndroid Build Coastguard Worker     }
1007*495ae853SAndroid Build Coastguard Worker 
1008*495ae853SAndroid Build Coastguard Worker     /* update the type of the mb if necessary */
1009*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_cost)
1010*495ae853SAndroid Build Coastguard Worker     {
1011*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_cost = i4_total_cost;
1012*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_distortion = i4_total_distortion;
1013*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_mb_type = I4x4;
1014*495ae853SAndroid Build Coastguard Worker     }
1015*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_intra_cost)
1016*495ae853SAndroid Build Coastguard Worker     {
1017*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_intra_cost = i4_total_cost;
1018*495ae853SAndroid Build Coastguard Worker     }
1019*495ae853SAndroid Build Coastguard Worker 
1020*495ae853SAndroid Build Coastguard Worker     return ;
1021*495ae853SAndroid Build Coastguard Worker }
1022*495ae853SAndroid Build Coastguard Worker 
1023*495ae853SAndroid Build Coastguard Worker /**
1024*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1025*495ae853SAndroid Build Coastguard Worker *
1026*495ae853SAndroid Build Coastguard Worker * @brief evaluate best intra 4x4 mode (rate distortion opt on)
1027*495ae853SAndroid Build Coastguard Worker *
1028*495ae853SAndroid Build Coastguard Worker * @par Description
1029*495ae853SAndroid Build Coastguard Worker *  This function evaluates all the possible intra 4x4 modes and finds the mode
1030*495ae853SAndroid Build Coastguard Worker *  that best represents the macro-block (least distortion) and occupies fewer
1031*495ae853SAndroid Build Coastguard Worker *  bits in the bit-stream.
1032*495ae853SAndroid Build Coastguard Worker *
1033*495ae853SAndroid Build Coastguard Worker * @param[in]    ps_proc_ctxt
1034*495ae853SAndroid Build Coastguard Worker *  pointer to proc ctxt
1035*495ae853SAndroid Build Coastguard Worker *
1036*495ae853SAndroid Build Coastguard Worker * @remarks
1037*495ae853SAndroid Build Coastguard Worker *  Ideally the cost of encoding a macroblock is calculated as
1038*495ae853SAndroid Build Coastguard Worker *  (distortion + lambda*rate). Where distortion is SAD/SATD,... between the
1039*495ae853SAndroid Build Coastguard Worker *  input block and the reconstructed block and rate is the number of bits taken
1040*495ae853SAndroid Build Coastguard Worker *  to place the macroblock in the bit-stream. In this routine the rate does not
1041*495ae853SAndroid Build Coastguard Worker *  exactly point to the total number of bits it takes, rather it points to header
1042*495ae853SAndroid Build Coastguard Worker *  bits necessary for encoding the macroblock. Assuming the deltaQP, cbp bits
1043*495ae853SAndroid Build Coastguard Worker *  and residual bits fall in to texture bits the number of bits taken to encoding
1044*495ae853SAndroid Build Coastguard Worker *  mbtype is considered as rate, we compute cost. Further we will approximate
1045*495ae853SAndroid Build Coastguard Worker *  the distortion as the deviation b/w input and the predicted block as opposed
1046*495ae853SAndroid Build Coastguard Worker *  to input and reconstructed block.
1047*495ae853SAndroid Build Coastguard Worker *
1048*495ae853SAndroid Build Coastguard Worker *  NOTE: As per the Document JVT-O079, for the whole intra 4x4 macroblock,
1049*495ae853SAndroid Build Coastguard Worker *  24*lambda is added to the SAD before comparison with the best SAD for
1050*495ae853SAndroid Build Coastguard Worker *  inter prediction. This is an empirical value to prevent using too many intra
1051*495ae853SAndroid Build Coastguard Worker *  blocks.
1052*495ae853SAndroid Build Coastguard Worker *
1053*495ae853SAndroid Build Coastguard Worker * @return      none
1054*495ae853SAndroid Build Coastguard Worker *
1055*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1056*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t * ps_proc)1057*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(process_ctxt_t *ps_proc)
1058*495ae853SAndroid Build Coastguard Worker {
1059*495ae853SAndroid Build Coastguard Worker     /* Codec Context */
1060*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
1061*495ae853SAndroid Build Coastguard Worker 
1062*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 4x4 block */
1063*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_distortion_least = INT_MAX, i4_total_distortion = 0;
1064*495ae853SAndroid Build Coastguard Worker 
1065*495ae853SAndroid Build Coastguard Worker     /* lambda */
1066*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_lambda = ps_proc->u4_lambda;
1067*495ae853SAndroid Build Coastguard Worker 
1068*495ae853SAndroid Build Coastguard Worker     /* cost = distortion + lambda*rate */
1069*495ae853SAndroid Build Coastguard Worker     WORD32 i4_partition_cost_least, i4_total_cost = (24 + 1) * u4_lambda;
1070*495ae853SAndroid Build Coastguard Worker 
1071*495ae853SAndroid Build Coastguard Worker     /* cost due to mbtype */
1072*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_cost_one_bit = u4_lambda, u4_cost_four_bits = 4 * u4_lambda;
1073*495ae853SAndroid Build Coastguard Worker 
1074*495ae853SAndroid Build Coastguard Worker     /* intra mode */
1075*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_best_intra_4x4_mode = DC_I4x4, u4_estimated_intra_4x4_mode;
1076*495ae853SAndroid Build Coastguard Worker 
1077*495ae853SAndroid Build Coastguard Worker     /* neighbor pels for intra prediction */
1078*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ngbr_pels_i4 = ps_proc->au1_ngbr_pels;
1079*495ae853SAndroid Build Coastguard Worker 
1080*495ae853SAndroid Build Coastguard Worker     /* pointer to curr partition */
1081*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_curr;
1082*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_ref_left, *pu1_mb_ref_top;
1083*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb_intra_4x4;
1084*495ae853SAndroid Build Coastguard Worker 
1085*495ae853SAndroid Build Coastguard Worker     /* pointer to residual macro block */
1086*495ae853SAndroid Build Coastguard Worker     WORD16 *pi2_res_mb = ps_proc->pi2_res_buf_intra_4x4;
1087*495ae853SAndroid Build Coastguard Worker 
1088*495ae853SAndroid Build Coastguard Worker     /* pointer to prediction macro block */
1089*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb;
1090*495ae853SAndroid Build Coastguard Worker 
1091*495ae853SAndroid Build Coastguard Worker     /* strides */
1092*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd = ps_proc->i4_src_strd;
1093*495ae853SAndroid Build Coastguard Worker     WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
1094*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ref_strd_left, i4_ref_strd_top;
1095*495ae853SAndroid Build Coastguard Worker 
1096*495ae853SAndroid Build Coastguard Worker     /* neighbors left, top, top right, top left */
1097*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_a;
1098*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_b;
1099*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_c;
1100*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_d;
1101*495ae853SAndroid Build Coastguard Worker 
1102*495ae853SAndroid Build Coastguard Worker     /* number of non zero coeffs*/
1103*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_nnz = (UWORD8 *)ps_proc->au4_nnz_intra_4x4;
1104*495ae853SAndroid Build Coastguard Worker 
1105*495ae853SAndroid Build Coastguard Worker     /* quantization parameters */
1106*495ae853SAndroid Build Coastguard Worker     quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
1107*495ae853SAndroid Build Coastguard Worker 
1108*495ae853SAndroid Build Coastguard Worker     /* neighbor availability */
1109*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ngbr_avbl;
1110*495ae853SAndroid Build Coastguard Worker     block_neighbors_t s_ngbr_avbl;
1111*495ae853SAndroid Build Coastguard Worker 
1112*495ae853SAndroid Build Coastguard Worker     /* temp vars */
1113*495ae853SAndroid Build Coastguard Worker     UWORD32 i, b8, b4, u4_blk_x, u4_blk_y, u4_pix_x, u4_pix_y;
1114*495ae853SAndroid Build Coastguard Worker 
1115*495ae853SAndroid Build Coastguard Worker     /* scan order inside 4x4 block */
1116*495ae853SAndroid Build Coastguard Worker     const UWORD8 u1_scan_order[16] = {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
1117*495ae853SAndroid Build Coastguard Worker 
1118*495ae853SAndroid Build Coastguard Worker     /* ngbr sub mb modes */
1119*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (ps_proc->i4_mb_x << 4);
1120*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
1121*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
1122*495ae853SAndroid Build Coastguard Worker 
1123*495ae853SAndroid Build Coastguard Worker     /* valid intra modes map */
1124*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_valid_intra_modes;
1125*495ae853SAndroid Build Coastguard Worker     UWORD16 u2_valid_modes[8] = {4, 262, 4, 262, 141, 399, 141, 511};
1126*495ae853SAndroid Build Coastguard Worker 
1127*495ae853SAndroid Build Coastguard Worker     /* Dummy variable for 4x4 trans function */
1128*495ae853SAndroid Build Coastguard Worker     WORD16 i2_dc_dummy;
1129*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b, u1_mb_c, u1_mb_d;
1130*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
1131*495ae853SAndroid Build Coastguard Worker 
1132*495ae853SAndroid Build Coastguard Worker     /* compute ngbr availability for sub blks */
1133*495ae853SAndroid Build Coastguard Worker     if (ps_proc->ps_ngbr_avbl->u1_mb_c)
1134*495ae853SAndroid Build Coastguard Worker     {
1135*495ae853SAndroid Build Coastguard Worker         ps_top_right_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + (ps_proc->i4_mb_x + 1);
1136*495ae853SAndroid Build Coastguard Worker     }
1137*495ae853SAndroid Build Coastguard Worker 
1138*495ae853SAndroid Build Coastguard Worker     /* left pels */
1139*495ae853SAndroid Build Coastguard Worker     u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
1140*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
1141*495ae853SAndroid Build Coastguard Worker 
1142*495ae853SAndroid Build Coastguard Worker        /* top pels */
1143*495ae853SAndroid Build Coastguard Worker     u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
1144*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
1145*495ae853SAndroid Build Coastguard Worker 
1146*495ae853SAndroid Build Coastguard Worker        /* topleft pels */
1147*495ae853SAndroid Build Coastguard Worker     u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
1148*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
1149*495ae853SAndroid Build Coastguard Worker 
1150*495ae853SAndroid Build Coastguard Worker        /* top right pels */
1151*495ae853SAndroid Build Coastguard Worker     u1_mb_c = ((ps_proc->ps_ngbr_avbl->u1_mb_c)
1152*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_right_mb_syn_ele->u2_is_intra : 1));
1153*495ae853SAndroid Build Coastguard Worker 
1154*495ae853SAndroid Build Coastguard Worker     i4_ngbr_avbl = (u1_mb_a) + (u1_mb_d << 1) + (u1_mb_b << 2) + (u1_mb_c << 3);
1155*495ae853SAndroid Build Coastguard Worker     memcpy(ps_proc->au1_ngbr_avbl_4x4_subblks, gau1_ih264_4x4_ngbr_avbl[i4_ngbr_avbl], 16);
1156*495ae853SAndroid Build Coastguard Worker 
1157*495ae853SAndroid Build Coastguard Worker     for (b8 = 0; b8 < 4; b8++)
1158*495ae853SAndroid Build Coastguard Worker     {
1159*495ae853SAndroid Build Coastguard Worker         u4_blk_x = (b8 & 0x01) << 3;
1160*495ae853SAndroid Build Coastguard Worker         u4_blk_y = (b8 >> 1) << 3;
1161*495ae853SAndroid Build Coastguard Worker         for (b4 = 0; b4 < 4; b4++, pu1_nnz++, pi2_res_mb += MB_SIZE)
1162*495ae853SAndroid Build Coastguard Worker         {
1163*495ae853SAndroid Build Coastguard Worker             u4_pix_x = u4_blk_x + ((b4 & 0x01) << 2);
1164*495ae853SAndroid Build Coastguard Worker             u4_pix_y = u4_blk_y + ((b4 >> 1) << 2);
1165*495ae853SAndroid Build Coastguard Worker 
1166*495ae853SAndroid Build Coastguard Worker             pu1_ref_mb_intra_4x4 = ps_proc->pu1_ref_mb_intra_4x4 + u4_pix_x + (u4_pix_y * i4_pred_strd);
1167*495ae853SAndroid Build Coastguard Worker             pu1_mb_curr = ps_proc->pu1_src_buf_luma + u4_pix_x + (u4_pix_y * i4_src_strd);
1168*495ae853SAndroid Build Coastguard Worker             if (u4_pix_x == 0)
1169*495ae853SAndroid Build Coastguard Worker             {
1170*495ae853SAndroid Build Coastguard Worker                 i4_ref_strd_left = ps_proc->i4_rec_strd;
1171*495ae853SAndroid Build Coastguard Worker                 pu1_mb_ref_left = ps_proc->pu1_rec_buf_luma + u4_pix_x + (u4_pix_y * i4_ref_strd_left);
1172*495ae853SAndroid Build Coastguard Worker             }
1173*495ae853SAndroid Build Coastguard Worker             else
1174*495ae853SAndroid Build Coastguard Worker             {
1175*495ae853SAndroid Build Coastguard Worker                 i4_ref_strd_left = i4_pred_strd;
1176*495ae853SAndroid Build Coastguard Worker                 pu1_mb_ref_left = pu1_ref_mb_intra_4x4;
1177*495ae853SAndroid Build Coastguard Worker             }
1178*495ae853SAndroid Build Coastguard Worker             if (u4_pix_y == 0)
1179*495ae853SAndroid Build Coastguard Worker             {
1180*495ae853SAndroid Build Coastguard Worker                 i4_ref_strd_top = ps_proc->i4_rec_strd;
1181*495ae853SAndroid Build Coastguard Worker                 pu1_mb_ref_top = ps_proc->pu1_rec_buf_luma + u4_pix_x + (u4_pix_y * i4_ref_strd_top);
1182*495ae853SAndroid Build Coastguard Worker             }
1183*495ae853SAndroid Build Coastguard Worker             else
1184*495ae853SAndroid Build Coastguard Worker             {
1185*495ae853SAndroid Build Coastguard Worker                 i4_ref_strd_top = i4_pred_strd;
1186*495ae853SAndroid Build Coastguard Worker                 pu1_mb_ref_top = pu1_ref_mb_intra_4x4;
1187*495ae853SAndroid Build Coastguard Worker             }
1188*495ae853SAndroid Build Coastguard Worker 
1189*495ae853SAndroid Build Coastguard Worker             pu1_mb_a = pu1_mb_ref_left - 1; /* pointer to left macro block */
1190*495ae853SAndroid Build Coastguard Worker             pu1_mb_b = pu1_mb_ref_top - i4_ref_strd_top; /* pointer to top macro block */
1191*495ae853SAndroid Build Coastguard Worker             pu1_mb_c = pu1_mb_b + 4; /* pointer to top right macro block */
1192*495ae853SAndroid Build Coastguard Worker             if (u4_pix_y == 0)
1193*495ae853SAndroid Build Coastguard Worker                 pu1_mb_d = pu1_mb_b - 1;
1194*495ae853SAndroid Build Coastguard Worker             else
1195*495ae853SAndroid Build Coastguard Worker                 pu1_mb_d = pu1_mb_a - i4_ref_strd_left; /* pointer to top left macro block */
1196*495ae853SAndroid Build Coastguard Worker 
1197*495ae853SAndroid Build Coastguard Worker             /* locating neighbors that are available for prediction */
1198*495ae853SAndroid Build Coastguard Worker             /* TODO : update the neighbor availability information basing on constrained intra pred information */
1199*495ae853SAndroid Build Coastguard Worker             /* TODO : i4_ngbr_avbl is only being used in DC mode. Can the DC mode be split in to distinct routines */
1200*495ae853SAndroid Build Coastguard Worker             /* basing on neighbors available and hence evade the computation of neighbor availability totally. */
1201*495ae853SAndroid Build Coastguard Worker 
1202*495ae853SAndroid Build Coastguard Worker             i4_ngbr_avbl = ps_proc->au1_ngbr_avbl_4x4_subblks[(b8 << 2) + b4];
1203*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_a = (i4_ngbr_avbl & 0x1);
1204*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_d = (i4_ngbr_avbl & 0x2) >> 1;
1205*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_b = (i4_ngbr_avbl & 0x4) >> 2;
1206*495ae853SAndroid Build Coastguard Worker             s_ngbr_avbl.u1_mb_c = (i4_ngbr_avbl & 0x8) >> 3;
1207*495ae853SAndroid Build Coastguard Worker             /* set valid intra modes for evaluation */
1208*495ae853SAndroid Build Coastguard Worker             u4_valid_intra_modes = u2_valid_modes[i4_ngbr_avbl & 0x7];
1209*495ae853SAndroid Build Coastguard Worker 
1210*495ae853SAndroid Build Coastguard Worker             /* if top partition is available and top right is not available for intra prediction, then */
1211*495ae853SAndroid Build Coastguard Worker             /* padd top right samples using top sample and make top right also available */
1212*495ae853SAndroid Build Coastguard Worker             /* i4_ngbr_avbl = (s_ngbr_avbl.u1_mb_a) + (s_ngbr_avbl.u1_mb_d << 1) + (s_ngbr_avbl.u1_mb_b << 2) + ((s_ngbr_avbl.u1_mb_b | s_ngbr_avbl.u1_mb_c) << 3); */
1213*495ae853SAndroid Build Coastguard Worker 
1214*495ae853SAndroid Build Coastguard Worker             /* gather prediction pels from the neighbors */
1215*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_a)
1216*495ae853SAndroid Build Coastguard Worker             {
1217*495ae853SAndroid Build Coastguard Worker                 for(i = 0; i < 4; i++)
1218*495ae853SAndroid Build Coastguard Worker                     pu1_ngbr_pels_i4[4 - 1 -i] = pu1_mb_a[i * i4_ref_strd_left];
1219*495ae853SAndroid Build Coastguard Worker             }
1220*495ae853SAndroid Build Coastguard Worker             else
1221*495ae853SAndroid Build Coastguard Worker             {
1222*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4,0,4);
1223*495ae853SAndroid Build Coastguard Worker             }
1224*495ae853SAndroid Build Coastguard Worker             if(s_ngbr_avbl.u1_mb_b)
1225*495ae853SAndroid Build Coastguard Worker             {
1226*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_ngbr_pels_i4 + 4 + 1, pu1_mb_b, 4);
1227*495ae853SAndroid Build Coastguard Worker             }
1228*495ae853SAndroid Build Coastguard Worker             else
1229*495ae853SAndroid Build Coastguard Worker             {
1230*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4 + 4 + 1, 0, 4);
1231*495ae853SAndroid Build Coastguard Worker             }
1232*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_d)
1233*495ae853SAndroid Build Coastguard Worker                 pu1_ngbr_pels_i4[4] = *pu1_mb_d;
1234*495ae853SAndroid Build Coastguard Worker             else
1235*495ae853SAndroid Build Coastguard Worker                 pu1_ngbr_pels_i4[4] = 0;
1236*495ae853SAndroid Build Coastguard Worker             if (s_ngbr_avbl.u1_mb_c)
1237*495ae853SAndroid Build Coastguard Worker             {
1238*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_ngbr_pels_i4 + 8 + 1, pu1_mb_c, 4);
1239*495ae853SAndroid Build Coastguard Worker             }
1240*495ae853SAndroid Build Coastguard Worker             else if (s_ngbr_avbl.u1_mb_b)
1241*495ae853SAndroid Build Coastguard Worker             {
1242*495ae853SAndroid Build Coastguard Worker                 memset(pu1_ngbr_pels_i4 + 8 + 1, pu1_ngbr_pels_i4[8], 4);
1243*495ae853SAndroid Build Coastguard Worker                 s_ngbr_avbl.u1_mb_c = s_ngbr_avbl.u1_mb_b;
1244*495ae853SAndroid Build Coastguard Worker             }
1245*495ae853SAndroid Build Coastguard Worker 
1246*495ae853SAndroid Build Coastguard Worker             i4_partition_cost_least = INT_MAX;
1247*495ae853SAndroid Build Coastguard Worker 
1248*495ae853SAndroid Build Coastguard Worker             /* predict the intra 4x4 mode for the current partition (for evaluating cost) */
1249*495ae853SAndroid Build Coastguard Worker             if (!s_ngbr_avbl.u1_mb_a || !s_ngbr_avbl.u1_mb_b)
1250*495ae853SAndroid Build Coastguard Worker             {
1251*495ae853SAndroid Build Coastguard Worker                 u4_estimated_intra_4x4_mode = DC_I4x4;
1252*495ae853SAndroid Build Coastguard Worker             }
1253*495ae853SAndroid Build Coastguard Worker             else
1254*495ae853SAndroid Build Coastguard Worker             {
1255*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_left_intra_4x4_mode = DC_I4x4;
1256*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_top_intra_4x4_mode = DC_I4x4;
1257*495ae853SAndroid Build Coastguard Worker 
1258*495ae853SAndroid Build Coastguard Worker                 if (u4_pix_x == 0)
1259*495ae853SAndroid Build Coastguard Worker                 {
1260*495ae853SAndroid Build Coastguard Worker                     if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I4x4)
1261*495ae853SAndroid Build Coastguard Worker                     {
1262*495ae853SAndroid Build Coastguard Worker                         u4_left_intra_4x4_mode = ps_proc->au1_left_mb_intra_modes[u1_scan_order[3 + u4_pix_y]];
1263*495ae853SAndroid Build Coastguard Worker                     }
1264*495ae853SAndroid Build Coastguard Worker                     else if (ps_proc->s_left_mb_syntax_ele.u2_mb_type == I8x8)
1265*495ae853SAndroid Build Coastguard Worker                     {
1266*495ae853SAndroid Build Coastguard Worker                         u4_left_intra_4x4_mode = ps_proc->au1_left_mb_intra_modes[b8 + 1];
1267*495ae853SAndroid Build Coastguard Worker                     }
1268*495ae853SAndroid Build Coastguard Worker                 }
1269*495ae853SAndroid Build Coastguard Worker                 else
1270*495ae853SAndroid Build Coastguard Worker                 {
1271*495ae853SAndroid Build Coastguard Worker                     u4_left_intra_4x4_mode = ps_proc->au1_intra_luma_mb_4x4_modes[u1_scan_order[(u4_pix_x >> 2) + u4_pix_y - 1]];
1272*495ae853SAndroid Build Coastguard Worker                 }
1273*495ae853SAndroid Build Coastguard Worker 
1274*495ae853SAndroid Build Coastguard Worker                 if (u4_pix_y == 0)
1275*495ae853SAndroid Build Coastguard Worker                 {
1276*495ae853SAndroid Build Coastguard Worker                     if (ps_top_mb_syn_ele->u2_mb_type == I4x4)
1277*495ae853SAndroid Build Coastguard Worker                     {
1278*495ae853SAndroid Build Coastguard Worker                         u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[u1_scan_order[12 + (u4_pix_x >> 2)]];
1279*495ae853SAndroid Build Coastguard Worker                     }
1280*495ae853SAndroid Build Coastguard Worker                     else if (ps_top_mb_syn_ele->u2_mb_type == I8x8)
1281*495ae853SAndroid Build Coastguard Worker                     {
1282*495ae853SAndroid Build Coastguard Worker                         u4_top_intra_4x4_mode = pu1_top_mb_intra_modes[b8 + 2];
1283*495ae853SAndroid Build Coastguard Worker                     }
1284*495ae853SAndroid Build Coastguard Worker                 }
1285*495ae853SAndroid Build Coastguard Worker                 else
1286*495ae853SAndroid Build Coastguard Worker                 {
1287*495ae853SAndroid Build Coastguard Worker                     u4_top_intra_4x4_mode = ps_proc->au1_intra_luma_mb_4x4_modes[u1_scan_order[(u4_pix_x >> 2) + u4_pix_y - 4]];
1288*495ae853SAndroid Build Coastguard Worker                 }
1289*495ae853SAndroid Build Coastguard Worker 
1290*495ae853SAndroid Build Coastguard Worker                 u4_estimated_intra_4x4_mode = MIN(u4_left_intra_4x4_mode, u4_top_intra_4x4_mode);
1291*495ae853SAndroid Build Coastguard Worker             }
1292*495ae853SAndroid Build Coastguard Worker 
1293*495ae853SAndroid Build Coastguard Worker             ps_proc->au1_predicted_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_estimated_intra_4x4_mode;
1294*495ae853SAndroid Build Coastguard Worker 
1295*495ae853SAndroid Build Coastguard Worker             /*mode evaluation and prediction*/
1296*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_ih264e_evaluate_intra_4x4_modes(pu1_mb_curr,
1297*495ae853SAndroid Build Coastguard Worker                                                          pu1_ngbr_pels_i4,
1298*495ae853SAndroid Build Coastguard Worker                                                          pu1_pred_mb, i4_src_strd,
1299*495ae853SAndroid Build Coastguard Worker                                                          i4_pred_strd, i4_ngbr_avbl,
1300*495ae853SAndroid Build Coastguard Worker                                                          &u4_best_intra_4x4_mode,
1301*495ae853SAndroid Build Coastguard Worker                                                          &i4_partition_cost_least,
1302*495ae853SAndroid Build Coastguard Worker                                                          u4_valid_intra_modes,
1303*495ae853SAndroid Build Coastguard Worker                                                          u4_lambda,
1304*495ae853SAndroid Build Coastguard Worker                                                          u4_estimated_intra_4x4_mode);
1305*495ae853SAndroid Build Coastguard Worker 
1306*495ae853SAndroid Build Coastguard Worker 
1307*495ae853SAndroid Build Coastguard Worker             i4_partition_distortion_least = i4_partition_cost_least - ((u4_estimated_intra_4x4_mode == u4_best_intra_4x4_mode)?u4_cost_one_bit:u4_cost_four_bits);
1308*495ae853SAndroid Build Coastguard Worker 
1309*495ae853SAndroid Build Coastguard Worker             DEBUG("%d partition cost, %d intra mode\n", i4_partition_cost_least, u4_best_intra_4x4_mode);
1310*495ae853SAndroid Build Coastguard Worker 
1311*495ae853SAndroid Build Coastguard Worker             /* macroblock distortion */
1312*495ae853SAndroid Build Coastguard Worker             i4_total_distortion += i4_partition_distortion_least;
1313*495ae853SAndroid Build Coastguard Worker             i4_total_cost += i4_partition_cost_least;
1314*495ae853SAndroid Build Coastguard Worker 
1315*495ae853SAndroid Build Coastguard Worker             /* mb partition mode */
1316*495ae853SAndroid Build Coastguard Worker             ps_proc->au1_intra_luma_mb_4x4_modes[(b8 << 2) + b4] = u4_best_intra_4x4_mode;
1317*495ae853SAndroid Build Coastguard Worker 
1318*495ae853SAndroid Build Coastguard Worker 
1319*495ae853SAndroid Build Coastguard Worker             /********************************************************/
1320*495ae853SAndroid Build Coastguard Worker             /*  error estimation,                                   */
1321*495ae853SAndroid Build Coastguard Worker             /*  transform                                           */
1322*495ae853SAndroid Build Coastguard Worker             /*  quantization                                        */
1323*495ae853SAndroid Build Coastguard Worker             /********************************************************/
1324*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_resi_trans_quant_4x4(pu1_mb_curr, pu1_pred_mb,
1325*495ae853SAndroid Build Coastguard Worker                                               pi2_res_mb, i4_src_strd,
1326*495ae853SAndroid Build Coastguard Worker                                               i4_pred_strd,
1327*495ae853SAndroid Build Coastguard Worker                                               /* No op stride, this implies a buff of lenght 1x16 */
1328*495ae853SAndroid Build Coastguard Worker                                               ps_qp_params->pu2_scale_mat,
1329*495ae853SAndroid Build Coastguard Worker                                               ps_qp_params->pu2_thres_mat,
1330*495ae853SAndroid Build Coastguard Worker                                               ps_qp_params->u1_qbits,
1331*495ae853SAndroid Build Coastguard Worker                                               ps_qp_params->u4_dead_zone,
1332*495ae853SAndroid Build Coastguard Worker                                               pu1_nnz, &i2_dc_dummy);
1333*495ae853SAndroid Build Coastguard Worker 
1334*495ae853SAndroid Build Coastguard Worker             /********************************************************/
1335*495ae853SAndroid Build Coastguard Worker             /*  ierror estimation,                                  */
1336*495ae853SAndroid Build Coastguard Worker             /*  itransform                                          */
1337*495ae853SAndroid Build Coastguard Worker             /*  iquantization                                       */
1338*495ae853SAndroid Build Coastguard Worker             /********************************************************/
1339*495ae853SAndroid Build Coastguard Worker             ps_codec->pf_iquant_itrans_recon_4x4(pi2_res_mb, pu1_pred_mb,
1340*495ae853SAndroid Build Coastguard Worker                                                  pu1_ref_mb_intra_4x4,
1341*495ae853SAndroid Build Coastguard Worker                                                  i4_pred_strd, i4_pred_strd,
1342*495ae853SAndroid Build Coastguard Worker                                                  ps_qp_params->pu2_iscale_mat,
1343*495ae853SAndroid Build Coastguard Worker                                                  ps_qp_params->pu2_weigh_mat,
1344*495ae853SAndroid Build Coastguard Worker                                                  ps_qp_params->u1_qp_div,
1345*495ae853SAndroid Build Coastguard Worker                                                  ps_proc->pv_scratch_buff, 0,
1346*495ae853SAndroid Build Coastguard Worker                                                  NULL);
1347*495ae853SAndroid Build Coastguard Worker         }
1348*495ae853SAndroid Build Coastguard Worker     }
1349*495ae853SAndroid Build Coastguard Worker 
1350*495ae853SAndroid Build Coastguard Worker     /* update the type of the mb if necessary */
1351*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_cost)
1352*495ae853SAndroid Build Coastguard Worker     {
1353*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_cost = i4_total_cost;
1354*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_distortion = i4_total_distortion;
1355*495ae853SAndroid Build Coastguard Worker         ps_proc->u4_mb_type = I4x4;
1356*495ae853SAndroid Build Coastguard Worker     }
1357*495ae853SAndroid Build Coastguard Worker     if (i4_total_cost < ps_proc->i4_mb_intra_cost)
1358*495ae853SAndroid Build Coastguard Worker     {
1359*495ae853SAndroid Build Coastguard Worker         ps_proc->i4_mb_intra_cost = i4_total_cost;
1360*495ae853SAndroid Build Coastguard Worker     }
1361*495ae853SAndroid Build Coastguard Worker 
1362*495ae853SAndroid Build Coastguard Worker     return ;
1363*495ae853SAndroid Build Coastguard Worker }
1364*495ae853SAndroid Build Coastguard Worker 
1365*495ae853SAndroid Build Coastguard Worker /**
1366*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1367*495ae853SAndroid Build Coastguard Worker *
1368*495ae853SAndroid Build Coastguard Worker * @brief
1369*495ae853SAndroid Build Coastguard Worker *  evaluate best chroma intra 8x8 mode (rate distortion opt off)
1370*495ae853SAndroid Build Coastguard Worker *
1371*495ae853SAndroid Build Coastguard Worker * @par Description
1372*495ae853SAndroid Build Coastguard Worker *  This function evaluates all the possible chroma intra 8x8 modes and finds
1373*495ae853SAndroid Build Coastguard Worker *  the mode that best represents the macroblock (least distortion) and occupies
1374*495ae853SAndroid Build Coastguard Worker *  fewer bits in the bitstream.
1375*495ae853SAndroid Build Coastguard Worker *
1376*495ae853SAndroid Build Coastguard Worker * @param[in] ps_proc_ctxt
1377*495ae853SAndroid Build Coastguard Worker *  pointer to macroblock context (handle)
1378*495ae853SAndroid Build Coastguard Worker *
1379*495ae853SAndroid Build Coastguard Worker * @remarks
1380*495ae853SAndroid Build Coastguard Worker *  For chroma best intra pred mode is calculated based only on SAD
1381*495ae853SAndroid Build Coastguard Worker *
1382*495ae853SAndroid Build Coastguard Worker * @returns none
1383*495ae853SAndroid Build Coastguard Worker *
1384*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1385*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t * ps_proc)1386*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(process_ctxt_t *ps_proc)
1387*495ae853SAndroid Build Coastguard Worker {
1388*495ae853SAndroid Build Coastguard Worker     /* Codec Context */
1389*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = ps_proc->ps_codec;
1390*495ae853SAndroid Build Coastguard Worker 
1391*495ae853SAndroid Build Coastguard Worker     /* SAD(distortion metric) of an 8x8 block */
1392*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_distortion, i4_chroma_mb_distortion;
1393*495ae853SAndroid Build Coastguard Worker 
1394*495ae853SAndroid Build Coastguard Worker     /* intra mode */
1395*495ae853SAndroid Build Coastguard Worker     UWORD32  u4_best_chroma_intra_8x8_mode = DC_CH_I8x8;
1396*495ae853SAndroid Build Coastguard Worker 
1397*495ae853SAndroid Build Coastguard Worker     /* neighbor pels for intra prediction */
1398*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ngbr_pels_c_i8x8 = ps_proc->au1_ngbr_pels;
1399*495ae853SAndroid Build Coastguard Worker 
1400*495ae853SAndroid Build Coastguard Worker     /* pointer to curr macro block */
1401*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_curr_mb = ps_proc->pu1_src_buf_chroma;
1402*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_ref_mb = ps_proc->pu1_rec_buf_chroma;
1403*495ae853SAndroid Build Coastguard Worker 
1404*495ae853SAndroid Build Coastguard Worker     /* pointer to prediction macro block */
1405*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb = ps_proc->pu1_pred_mb_intra_chroma;
1406*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_mb_plane = ps_proc->pu1_pred_mb_intra_chroma_plane;
1407*495ae853SAndroid Build Coastguard Worker 
1408*495ae853SAndroid Build Coastguard Worker     /* strides */
1409*495ae853SAndroid Build Coastguard Worker     WORD32 i4_src_strd_c = ps_proc->i4_src_chroma_strd;
1410*495ae853SAndroid Build Coastguard Worker     WORD32 i4_pred_strd = ps_proc->i4_pred_strd;
1411*495ae853SAndroid Build Coastguard Worker     WORD32 i4_rec_strd_c = ps_proc->i4_rec_strd;
1412*495ae853SAndroid Build Coastguard Worker 
1413*495ae853SAndroid Build Coastguard Worker     /* neighbors left, top, top left */
1414*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_a = pu1_ref_mb - 2;
1415*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_b = pu1_ref_mb - i4_rec_strd_c;
1416*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_mb_d = pu1_mb_b - 2;
1417*495ae853SAndroid Build Coastguard Worker 
1418*495ae853SAndroid Build Coastguard Worker     /* neighbor availability */
1419*495ae853SAndroid Build Coastguard Worker     const UWORD8  u1_valid_intra_modes[8] = {1, 3, 1, 3, 5, 7, 5, 15};
1420*495ae853SAndroid Build Coastguard Worker     WORD32 i4_ngbr_avbl;
1421*495ae853SAndroid Build Coastguard Worker 
1422*495ae853SAndroid Build Coastguard Worker     /* valid intra modes map */
1423*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_valid_intra_modes;
1424*495ae853SAndroid Build Coastguard Worker     mb_info_t *ps_top_mb_syn_ele = ps_proc->ps_top_row_mb_syntax_ele + ps_proc->i4_mb_x;
1425*495ae853SAndroid Build Coastguard Worker 
1426*495ae853SAndroid Build Coastguard Worker     /* temp var */
1427*495ae853SAndroid Build Coastguard Worker     UWORD8 i;
1428*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_constrained_intra_pred = ps_proc->ps_codec->s_cfg.u4_constrained_intra_pred;
1429*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b, u1_mb_d;
1430*495ae853SAndroid Build Coastguard Worker 
1431*495ae853SAndroid Build Coastguard Worker     /* locating neighbors that are available for prediction */
1432*495ae853SAndroid Build Coastguard Worker     /* gather prediction pels from the neighbors */
1433*495ae853SAndroid Build Coastguard Worker     /* left pels */
1434*495ae853SAndroid Build Coastguard Worker     u1_mb_a = ((ps_proc->ps_ngbr_avbl->u1_mb_a)
1435*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ?  ps_proc->s_left_mb_syntax_ele.u2_is_intra : 1));
1436*495ae853SAndroid Build Coastguard Worker     if (u1_mb_a)
1437*495ae853SAndroid Build Coastguard Worker     {
1438*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 16; i += 2)
1439*495ae853SAndroid Build Coastguard Worker         {
1440*495ae853SAndroid Build Coastguard Worker             pu1_ngbr_pels_c_i8x8[16 - 2 - i] = pu1_mb_a[(i / 2) * i4_rec_strd_c];
1441*495ae853SAndroid Build Coastguard Worker             pu1_ngbr_pels_c_i8x8[16 - 1 - i] = pu1_mb_a[(i / 2) * i4_rec_strd_c + 1];
1442*495ae853SAndroid Build Coastguard Worker         }
1443*495ae853SAndroid Build Coastguard Worker     }
1444*495ae853SAndroid Build Coastguard Worker     else
1445*495ae853SAndroid Build Coastguard Worker     {
1446*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_set_mul8(pu1_ngbr_pels_c_i8x8, 0, MB_SIZE);
1447*495ae853SAndroid Build Coastguard Worker     }
1448*495ae853SAndroid Build Coastguard Worker 
1449*495ae853SAndroid Build Coastguard Worker     /* top pels */
1450*495ae853SAndroid Build Coastguard Worker     u1_mb_b = ((ps_proc->ps_ngbr_avbl->u1_mb_b)
1451*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_top_mb_syn_ele->u2_is_intra : 1));
1452*495ae853SAndroid Build Coastguard Worker     if (u1_mb_b)
1453*495ae853SAndroid Build Coastguard Worker     {
1454*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_cpy_mul8(&pu1_ngbr_pels_c_i8x8[18], pu1_mb_b, 16);
1455*495ae853SAndroid Build Coastguard Worker     }
1456*495ae853SAndroid Build Coastguard Worker     else
1457*495ae853SAndroid Build Coastguard Worker     {
1458*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_mem_set_mul8((pu1_ngbr_pels_c_i8x8 + 18), 0, MB_SIZE);
1459*495ae853SAndroid Build Coastguard Worker     }
1460*495ae853SAndroid Build Coastguard Worker 
1461*495ae853SAndroid Build Coastguard Worker     /* top left pels */
1462*495ae853SAndroid Build Coastguard Worker     u1_mb_d = ((ps_proc->ps_ngbr_avbl->u1_mb_d)
1463*495ae853SAndroid Build Coastguard Worker                     && (u4_constrained_intra_pred ? ps_proc->s_top_left_mb_syntax_ele.u2_is_intra : 1));
1464*495ae853SAndroid Build Coastguard Worker     if (u1_mb_d)
1465*495ae853SAndroid Build Coastguard Worker     {
1466*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_pels_c_i8x8[16] = *pu1_mb_d;
1467*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_pels_c_i8x8[17] = *(pu1_mb_d + 1);
1468*495ae853SAndroid Build Coastguard Worker     }
1469*495ae853SAndroid Build Coastguard Worker     i4_ngbr_avbl = (u1_mb_a) + (u1_mb_b << 2) + (u1_mb_d << 1);
1470*495ae853SAndroid Build Coastguard Worker     ps_proc->i4_chroma_neighbor_avail_8x8_mb = i4_ngbr_avbl;
1471*495ae853SAndroid Build Coastguard Worker 
1472*495ae853SAndroid Build Coastguard Worker     u4_valid_intra_modes = u1_valid_intra_modes[i4_ngbr_avbl];
1473*495ae853SAndroid Build Coastguard Worker 
1474*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST ||
1475*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
1476*495ae853SAndroid Build Coastguard Worker         u4_valid_intra_modes &= ~(1 << PLANE_CH_I8x8);
1477*495ae853SAndroid Build Coastguard Worker 
1478*495ae853SAndroid Build Coastguard Worker     i4_chroma_mb_distortion = INT_MAX;
1479*495ae853SAndroid Build Coastguard Worker 
1480*495ae853SAndroid Build Coastguard Worker     /* perform intra mode chroma  8x8 evaluation */
1481*495ae853SAndroid Build Coastguard Worker     /* intra prediction */
1482*495ae853SAndroid Build Coastguard Worker     ps_codec->pf_ih264e_evaluate_intra_chroma_modes(pu1_curr_mb,
1483*495ae853SAndroid Build Coastguard Worker                                                     pu1_ngbr_pels_c_i8x8,
1484*495ae853SAndroid Build Coastguard Worker                                                     pu1_pred_mb,
1485*495ae853SAndroid Build Coastguard Worker                                                     i4_src_strd_c,
1486*495ae853SAndroid Build Coastguard Worker                                                     i4_pred_strd,
1487*495ae853SAndroid Build Coastguard Worker                                                     i4_ngbr_avbl,
1488*495ae853SAndroid Build Coastguard Worker                                                     &u4_best_chroma_intra_8x8_mode,
1489*495ae853SAndroid Build Coastguard Worker                                                     &i4_chroma_mb_distortion,
1490*495ae853SAndroid Build Coastguard Worker                                                     u4_valid_intra_modes);
1491*495ae853SAndroid Build Coastguard Worker 
1492*495ae853SAndroid Build Coastguard Worker     if (u4_valid_intra_modes & 8)/* if Chroma PLANE is valid*/
1493*495ae853SAndroid Build Coastguard Worker     {
1494*495ae853SAndroid Build Coastguard Worker         (ps_codec->apf_intra_pred_c)[PLANE_CH_I8x8](pu1_ngbr_pels_c_i8x8, pu1_pred_mb_plane, 0, i4_pred_strd, i4_ngbr_avbl);
1495*495ae853SAndroid Build Coastguard Worker 
1496*495ae853SAndroid Build Coastguard Worker         /* evaluate distortion(sad) */
1497*495ae853SAndroid Build Coastguard Worker         ps_codec->pf_compute_sad_16x8(pu1_curr_mb, pu1_pred_mb_plane, i4_src_strd_c, i4_pred_strd, i4_chroma_mb_distortion, &i4_mb_distortion);
1498*495ae853SAndroid Build Coastguard Worker 
1499*495ae853SAndroid Build Coastguard Worker         /* update the least distortion information if necessary */
1500*495ae853SAndroid Build Coastguard Worker         if(i4_mb_distortion < i4_chroma_mb_distortion)
1501*495ae853SAndroid Build Coastguard Worker         {
1502*495ae853SAndroid Build Coastguard Worker             i4_chroma_mb_distortion = i4_mb_distortion;
1503*495ae853SAndroid Build Coastguard Worker             u4_best_chroma_intra_8x8_mode = PLANE_CH_I8x8;
1504*495ae853SAndroid Build Coastguard Worker         }
1505*495ae853SAndroid Build Coastguard Worker     }
1506*495ae853SAndroid Build Coastguard Worker 
1507*495ae853SAndroid Build Coastguard Worker     DEBUG("%d partition cost, %d intra mode\n", i4_chroma_mb_distortion, u4_best_chroma_intra_8x8_mode);
1508*495ae853SAndroid Build Coastguard Worker 
1509*495ae853SAndroid Build Coastguard Worker     ps_proc->u1_c_i8_mode = u4_best_chroma_intra_8x8_mode;
1510*495ae853SAndroid Build Coastguard Worker 
1511*495ae853SAndroid Build Coastguard Worker     return ;
1512*495ae853SAndroid Build Coastguard Worker }
1513*495ae853SAndroid Build Coastguard Worker 
1514*495ae853SAndroid Build Coastguard Worker 
1515*495ae853SAndroid Build Coastguard Worker /**
1516*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1517*495ae853SAndroid Build Coastguard Worker *
1518*495ae853SAndroid Build Coastguard Worker * @brief
1519*495ae853SAndroid Build Coastguard Worker *  Evaluate best intra 16x16 mode (among VERT, HORZ and DC) and do the
1520*495ae853SAndroid Build Coastguard Worker *  prediction.
1521*495ae853SAndroid Build Coastguard Worker *
1522*495ae853SAndroid Build Coastguard Worker * @par Description
1523*495ae853SAndroid Build Coastguard Worker *  This function evaluates first three 16x16 modes and compute corresponding sad
1524*495ae853SAndroid Build Coastguard Worker *  and return the buffer predicted with best mode.
1525*495ae853SAndroid Build Coastguard Worker *
1526*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_src
1527*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the source
1528*495ae853SAndroid Build Coastguard Worker *
1529*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_ngbr_pels_i16
1530*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to neighbouring pels
1531*495ae853SAndroid Build Coastguard Worker *
1532*495ae853SAndroid Build Coastguard Worker * @param[out] pu1_dst
1533*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the destination
1534*495ae853SAndroid Build Coastguard Worker *
1535*495ae853SAndroid Build Coastguard Worker * @param[in] src_strd
1536*495ae853SAndroid Build Coastguard Worker *  integer source stride
1537*495ae853SAndroid Build Coastguard Worker *
1538*495ae853SAndroid Build Coastguard Worker * @param[in] dst_strd
1539*495ae853SAndroid Build Coastguard Worker *  integer destination stride
1540*495ae853SAndroid Build Coastguard Worker *
1541*495ae853SAndroid Build Coastguard Worker * @param[in] u4_n_avblty
1542*495ae853SAndroid Build Coastguard Worker *  availability of neighbouring pixels
1543*495ae853SAndroid Build Coastguard Worker *
1544*495ae853SAndroid Build Coastguard Worker * @param[in] u4_intra_mode
1545*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which best mode is returned
1546*495ae853SAndroid Build Coastguard Worker *
1547*495ae853SAndroid Build Coastguard Worker * @param[in] pu4_sadmin
1548*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which minimum sad is returned
1549*495ae853SAndroid Build Coastguard Worker *
1550*495ae853SAndroid Build Coastguard Worker * @param[in] u4_valid_intra_modes
1551*495ae853SAndroid Build Coastguard Worker *  Says what all modes are valid
1552*495ae853SAndroid Build Coastguard Worker *
1553*495ae853SAndroid Build Coastguard Worker * @returns      none
1554*495ae853SAndroid Build Coastguard Worker *
1555*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1556*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra16x16_modes(UWORD8 * pu1_src,UWORD8 * pu1_ngbr_pels_i16,UWORD8 * pu1_dst,UWORD32 src_strd,UWORD32 dst_strd,WORD32 u4_n_avblty,UWORD32 * u4_intra_mode,WORD32 * pu4_sadmin,UWORD32 u4_valid_intra_modes)1557*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra16x16_modes(UWORD8 *pu1_src,
1558*495ae853SAndroid Build Coastguard Worker                                       UWORD8 *pu1_ngbr_pels_i16,
1559*495ae853SAndroid Build Coastguard Worker                                       UWORD8 *pu1_dst,
1560*495ae853SAndroid Build Coastguard Worker                                       UWORD32 src_strd,
1561*495ae853SAndroid Build Coastguard Worker                                       UWORD32 dst_strd,
1562*495ae853SAndroid Build Coastguard Worker                                       WORD32 u4_n_avblty,
1563*495ae853SAndroid Build Coastguard Worker                                       UWORD32 *u4_intra_mode,
1564*495ae853SAndroid Build Coastguard Worker                                       WORD32 *pu4_sadmin,
1565*495ae853SAndroid Build Coastguard Worker                                       UWORD32 u4_valid_intra_modes)
1566*495ae853SAndroid Build Coastguard Worker {
1567*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_neighbour;
1568*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_src_temp = pu1_src;
1569*495ae853SAndroid Build Coastguard Worker     UWORD8 left = 0, top = 0;
1570*495ae853SAndroid Build Coastguard Worker     WORD32 u4_dcval = 0;
1571*495ae853SAndroid Build Coastguard Worker     WORD32 i, j;
1572*495ae853SAndroid Build Coastguard Worker     WORD32 i4_sad_vert = INT_MAX, i4_sad_horz = INT_MAX, i4_sad_dc = INT_MAX,
1573*495ae853SAndroid Build Coastguard Worker                     i4_min_sad = INT_MAX;
1574*495ae853SAndroid Build Coastguard Worker     UWORD8 val;
1575*495ae853SAndroid Build Coastguard Worker 
1576*495ae853SAndroid Build Coastguard Worker     left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
1577*495ae853SAndroid Build Coastguard Worker     top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
1578*495ae853SAndroid Build Coastguard Worker 
1579*495ae853SAndroid Build Coastguard Worker     /* left available */
1580*495ae853SAndroid Build Coastguard Worker     if (left)
1581*495ae853SAndroid Build Coastguard Worker     {
1582*495ae853SAndroid Build Coastguard Worker         i4_sad_horz = 0;
1583*495ae853SAndroid Build Coastguard Worker 
1584*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 16; i++)
1585*495ae853SAndroid Build Coastguard Worker         {
1586*495ae853SAndroid Build Coastguard Worker             val = pu1_ngbr_pels_i16[15 - i];
1587*495ae853SAndroid Build Coastguard Worker 
1588*495ae853SAndroid Build Coastguard Worker             u4_dcval += val;
1589*495ae853SAndroid Build Coastguard Worker 
1590*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
1591*495ae853SAndroid Build Coastguard Worker             {
1592*495ae853SAndroid Build Coastguard Worker                 i4_sad_horz += ABS(val - pu1_src_temp[j]);
1593*495ae853SAndroid Build Coastguard Worker             }
1594*495ae853SAndroid Build Coastguard Worker 
1595*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1596*495ae853SAndroid Build Coastguard Worker         }
1597*495ae853SAndroid Build Coastguard Worker         u4_dcval += 8;
1598*495ae853SAndroid Build Coastguard Worker     }
1599*495ae853SAndroid Build Coastguard Worker 
1600*495ae853SAndroid Build Coastguard Worker     pu1_src_temp = pu1_src;
1601*495ae853SAndroid Build Coastguard Worker     /* top available */
1602*495ae853SAndroid Build Coastguard Worker     if (top)
1603*495ae853SAndroid Build Coastguard Worker     {
1604*495ae853SAndroid Build Coastguard Worker         i4_sad_vert = 0;
1605*495ae853SAndroid Build Coastguard Worker 
1606*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 16; i++)
1607*495ae853SAndroid Build Coastguard Worker         {
1608*495ae853SAndroid Build Coastguard Worker             u4_dcval += pu1_ngbr_pels_i16[17 + i];
1609*495ae853SAndroid Build Coastguard Worker 
1610*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
1611*495ae853SAndroid Build Coastguard Worker             {
1612*495ae853SAndroid Build Coastguard Worker                 i4_sad_vert += ABS(pu1_ngbr_pels_i16[17 + j] - pu1_src_temp[j]);
1613*495ae853SAndroid Build Coastguard Worker             }
1614*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1615*495ae853SAndroid Build Coastguard Worker 
1616*495ae853SAndroid Build Coastguard Worker         }
1617*495ae853SAndroid Build Coastguard Worker         u4_dcval += 8;
1618*495ae853SAndroid Build Coastguard Worker     }
1619*495ae853SAndroid Build Coastguard Worker 
1620*495ae853SAndroid Build Coastguard Worker     u4_dcval = (u4_dcval) >> (3 + left + top);
1621*495ae853SAndroid Build Coastguard Worker 
1622*495ae853SAndroid Build Coastguard Worker     pu1_src_temp = pu1_src;
1623*495ae853SAndroid Build Coastguard Worker 
1624*495ae853SAndroid Build Coastguard Worker     /* none available */
1625*495ae853SAndroid Build Coastguard Worker     u4_dcval += (left == 0) * (top == 0) * 128;
1626*495ae853SAndroid Build Coastguard Worker 
1627*495ae853SAndroid Build Coastguard Worker     i4_sad_dc = 0;
1628*495ae853SAndroid Build Coastguard Worker 
1629*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 16; i++)
1630*495ae853SAndroid Build Coastguard Worker     {
1631*495ae853SAndroid Build Coastguard Worker         for (j = 0; j < 16; j++)
1632*495ae853SAndroid Build Coastguard Worker         {
1633*495ae853SAndroid Build Coastguard Worker             i4_sad_dc += ABS(u4_dcval - pu1_src_temp[j]);
1634*495ae853SAndroid Build Coastguard Worker         }
1635*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1636*495ae853SAndroid Build Coastguard Worker     }
1637*495ae853SAndroid Build Coastguard Worker 
1638*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 04) == 0)/* If DC is disabled */
1639*495ae853SAndroid Build Coastguard Worker         i4_sad_dc = INT_MAX;
1640*495ae853SAndroid Build Coastguard Worker 
1641*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 01) == 0)/* If VERT is disabled */
1642*495ae853SAndroid Build Coastguard Worker         i4_sad_vert = INT_MAX;
1643*495ae853SAndroid Build Coastguard Worker 
1644*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 02) == 0)/* If HORZ is disabled */
1645*495ae853SAndroid Build Coastguard Worker         i4_sad_horz = INT_MAX;
1646*495ae853SAndroid Build Coastguard Worker 
1647*495ae853SAndroid Build Coastguard Worker     i4_min_sad = MIN3(i4_sad_horz, i4_sad_dc, i4_sad_vert);
1648*495ae853SAndroid Build Coastguard Worker 
1649*495ae853SAndroid Build Coastguard Worker     /* Finding Minimum sad and doing corresponding prediction */
1650*495ae853SAndroid Build Coastguard Worker     if (i4_min_sad < *pu4_sadmin)
1651*495ae853SAndroid Build Coastguard Worker     {
1652*495ae853SAndroid Build Coastguard Worker         *pu4_sadmin = i4_min_sad;
1653*495ae853SAndroid Build Coastguard Worker         if (i4_min_sad == i4_sad_vert)
1654*495ae853SAndroid Build Coastguard Worker         {
1655*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = VERT_I16x16;
1656*495ae853SAndroid Build Coastguard Worker             pu1_neighbour = pu1_ngbr_pels_i16 + 17;
1657*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
1658*495ae853SAndroid Build Coastguard Worker             {
1659*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_dst, pu1_neighbour, MB_SIZE);
1660*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
1661*495ae853SAndroid Build Coastguard Worker             }
1662*495ae853SAndroid Build Coastguard Worker         }
1663*495ae853SAndroid Build Coastguard Worker         else if (i4_min_sad == i4_sad_horz)
1664*495ae853SAndroid Build Coastguard Worker         {
1665*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = HORZ_I16x16;
1666*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
1667*495ae853SAndroid Build Coastguard Worker             {
1668*495ae853SAndroid Build Coastguard Worker                 val = pu1_ngbr_pels_i16[15 - j];
1669*495ae853SAndroid Build Coastguard Worker                 memset(pu1_dst, val, MB_SIZE);
1670*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
1671*495ae853SAndroid Build Coastguard Worker             }
1672*495ae853SAndroid Build Coastguard Worker         }
1673*495ae853SAndroid Build Coastguard Worker         else
1674*495ae853SAndroid Build Coastguard Worker         {
1675*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = DC_I16x16;
1676*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
1677*495ae853SAndroid Build Coastguard Worker             {
1678*495ae853SAndroid Build Coastguard Worker                 memset(pu1_dst, u4_dcval, MB_SIZE);
1679*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
1680*495ae853SAndroid Build Coastguard Worker             }
1681*495ae853SAndroid Build Coastguard Worker         }
1682*495ae853SAndroid Build Coastguard Worker     }
1683*495ae853SAndroid Build Coastguard Worker     return;
1684*495ae853SAndroid Build Coastguard Worker }
1685*495ae853SAndroid Build Coastguard Worker 
1686*495ae853SAndroid Build Coastguard Worker /**
1687*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1688*495ae853SAndroid Build Coastguard Worker *
1689*495ae853SAndroid Build Coastguard Worker * @brief
1690*495ae853SAndroid Build Coastguard Worker *  Evaluate best intra 4x4 mode and perform prediction.
1691*495ae853SAndroid Build Coastguard Worker *
1692*495ae853SAndroid Build Coastguard Worker * @par Description
1693*495ae853SAndroid Build Coastguard Worker *  This function evaluates  4x4 modes and compute corresponding sad
1694*495ae853SAndroid Build Coastguard Worker *  and return the buffer predicted with best mode.
1695*495ae853SAndroid Build Coastguard Worker *
1696*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_src
1697*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the source
1698*495ae853SAndroid Build Coastguard Worker *
1699*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_ngbr_pels
1700*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to neighbouring pels
1701*495ae853SAndroid Build Coastguard Worker *
1702*495ae853SAndroid Build Coastguard Worker * @param[out] pu1_dst
1703*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the destination
1704*495ae853SAndroid Build Coastguard Worker *
1705*495ae853SAndroid Build Coastguard Worker * @param[in] src_strd
1706*495ae853SAndroid Build Coastguard Worker *  integer source stride
1707*495ae853SAndroid Build Coastguard Worker *
1708*495ae853SAndroid Build Coastguard Worker * @param[in] dst_strd
1709*495ae853SAndroid Build Coastguard Worker *  integer destination stride
1710*495ae853SAndroid Build Coastguard Worker *
1711*495ae853SAndroid Build Coastguard Worker * @param[in] u4_n_avblty
1712*495ae853SAndroid Build Coastguard Worker *  availability of neighbouring pixels
1713*495ae853SAndroid Build Coastguard Worker *
1714*495ae853SAndroid Build Coastguard Worker * @param[in] u4_intra_mode
1715*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which best mode is returned
1716*495ae853SAndroid Build Coastguard Worker *
1717*495ae853SAndroid Build Coastguard Worker * @param[in] pu4_sadmin
1718*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which minimum cost is returned
1719*495ae853SAndroid Build Coastguard Worker *
1720*495ae853SAndroid Build Coastguard Worker * @param[in] u4_valid_intra_modes
1721*495ae853SAndroid Build Coastguard Worker *  Says what all modes are valid
1722*495ae853SAndroid Build Coastguard Worker *
1723*495ae853SAndroid Build Coastguard Worker * @param[in] u4_lambda
1724*495ae853SAndroid Build Coastguard Worker *  Lamda value for computing cost from SAD
1725*495ae853SAndroid Build Coastguard Worker *
1726*495ae853SAndroid Build Coastguard Worker * @param[in] u4_predictd_mode
1727*495ae853SAndroid Build Coastguard Worker *  Predicted mode for cost computation
1728*495ae853SAndroid Build Coastguard Worker *
1729*495ae853SAndroid Build Coastguard Worker * @returns      none
1730*495ae853SAndroid Build Coastguard Worker *
1731*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1732*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra_4x4_modes(UWORD8 * pu1_src,UWORD8 * pu1_ngbr_pels,UWORD8 * pu1_dst,UWORD32 src_strd,UWORD32 dst_strd,WORD32 u4_n_avblty,UWORD32 * u4_intra_mode,WORD32 * pu4_sadmin,UWORD32 u4_valid_intra_modes,UWORD32 u4_lambda,UWORD32 u4_predictd_mode)1733*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra_4x4_modes(UWORD8 *pu1_src,
1734*495ae853SAndroid Build Coastguard Worker                                      UWORD8 *pu1_ngbr_pels,
1735*495ae853SAndroid Build Coastguard Worker                                      UWORD8 *pu1_dst,
1736*495ae853SAndroid Build Coastguard Worker                                      UWORD32 src_strd,
1737*495ae853SAndroid Build Coastguard Worker                                      UWORD32 dst_strd,
1738*495ae853SAndroid Build Coastguard Worker                                      WORD32 u4_n_avblty,
1739*495ae853SAndroid Build Coastguard Worker                                      UWORD32 *u4_intra_mode,
1740*495ae853SAndroid Build Coastguard Worker                                      WORD32 *pu4_sadmin,
1741*495ae853SAndroid Build Coastguard Worker                                      UWORD32 u4_valid_intra_modes,
1742*495ae853SAndroid Build Coastguard Worker                                      UWORD32  u4_lambda,
1743*495ae853SAndroid Build Coastguard Worker                                      UWORD32 u4_predictd_mode)
1744*495ae853SAndroid Build Coastguard Worker {
1745*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_src_temp = pu1_src;
1746*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred = pu1_ngbr_pels;
1747*495ae853SAndroid Build Coastguard Worker     UWORD8 left = 0, top = 0;
1748*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_val = 0;
1749*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals[4] = {0};
1750*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_pred_val = NULL;
1751*495ae853SAndroid Build Coastguard Worker     /* To store FILT121 operated values*/
1752*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals_diag_121[15] = {0};
1753*495ae853SAndroid Build Coastguard Worker     /* To store FILT11 operated values*/
1754*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals_diag_11[15] = {0};
1755*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals_vert_r[8] = {0};
1756*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals_horz_d[10] = {0};
1757*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_pred_vals_horz_u[10] = {0};
1758*495ae853SAndroid Build Coastguard Worker     WORD32 u4_dcval = 0;
1759*495ae853SAndroid Build Coastguard Worker     WORD32 i4_sad[MAX_I4x4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX,
1760*495ae853SAndroid Build Coastguard Worker                                INT_MAX, INT_MAX, INT_MAX, INT_MAX};
1761*495ae853SAndroid Build Coastguard Worker 
1762*495ae853SAndroid Build Coastguard Worker     WORD32 i4_cost[MAX_I4x4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX, INT_MAX,
1763*495ae853SAndroid Build Coastguard Worker                                 INT_MAX, INT_MAX, INT_MAX, INT_MAX};
1764*495ae853SAndroid Build Coastguard Worker     WORD32 i, i4_min_cost = INT_MAX;
1765*495ae853SAndroid Build Coastguard Worker 
1766*495ae853SAndroid Build Coastguard Worker     left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
1767*495ae853SAndroid Build Coastguard Worker     top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
1768*495ae853SAndroid Build Coastguard Worker 
1769*495ae853SAndroid Build Coastguard Worker     /* Computing SAD */
1770*495ae853SAndroid Build Coastguard Worker 
1771*495ae853SAndroid Build Coastguard Worker     /* VERT mode valid */
1772*495ae853SAndroid Build Coastguard Worker     if (u4_valid_intra_modes & 1)
1773*495ae853SAndroid Build Coastguard Worker     {
1774*495ae853SAndroid Build Coastguard Worker         pu1_pred = pu1_ngbr_pels + 5;
1775*495ae853SAndroid Build Coastguard Worker         i4_sad[VERT_I4x4] = 0;
1776*495ae853SAndroid Build Coastguard Worker         i4_cost[VERT_I4x4] = 0;
1777*495ae853SAndroid Build Coastguard Worker 
1778*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
1779*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1780*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
1781*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1782*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
1783*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1784*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, pu1_pred, i4_sad[VERT_I4x4]);
1785*495ae853SAndroid Build Coastguard Worker 
1786*495ae853SAndroid Build Coastguard Worker         i4_cost[VERT_I4x4] = i4_sad[VERT_I4x4] + ((u4_predictd_mode == VERT_I4x4) ?
1787*495ae853SAndroid Build Coastguard Worker                                         u4_lambda : 4 * u4_lambda);
1788*495ae853SAndroid Build Coastguard Worker     }
1789*495ae853SAndroid Build Coastguard Worker 
1790*495ae853SAndroid Build Coastguard Worker     /* HORZ mode valid */
1791*495ae853SAndroid Build Coastguard Worker     if (u4_valid_intra_modes & 2)
1792*495ae853SAndroid Build Coastguard Worker     {
1793*495ae853SAndroid Build Coastguard Worker         i4_sad[HORZ_I4x4] = 0;
1794*495ae853SAndroid Build Coastguard Worker         i4_cost[HORZ_I4x4] =0;
1795*495ae853SAndroid Build Coastguard Worker         pu1_src_temp = pu1_src;
1796*495ae853SAndroid Build Coastguard Worker 
1797*495ae853SAndroid Build Coastguard Worker         u1_pred_val = pu1_ngbr_pels[3];
1798*495ae853SAndroid Build Coastguard Worker 
1799*495ae853SAndroid Build Coastguard Worker         i4_sad[HORZ_I4x4] += ABS(pu1_src_temp[0] - u1_pred_val)
1800*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[1] - u1_pred_val)
1801*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[2] - u1_pred_val)
1802*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[3] - u1_pred_val);
1803*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1804*495ae853SAndroid Build Coastguard Worker 
1805*495ae853SAndroid Build Coastguard Worker         u1_pred_val = pu1_ngbr_pels[2];
1806*495ae853SAndroid Build Coastguard Worker 
1807*495ae853SAndroid Build Coastguard Worker         i4_sad[HORZ_I4x4] += ABS(pu1_src_temp[0] - u1_pred_val)
1808*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[1] - u1_pred_val)
1809*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[2] - u1_pred_val)
1810*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[3] - u1_pred_val);
1811*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1812*495ae853SAndroid Build Coastguard Worker 
1813*495ae853SAndroid Build Coastguard Worker         u1_pred_val = pu1_ngbr_pels[1];
1814*495ae853SAndroid Build Coastguard Worker 
1815*495ae853SAndroid Build Coastguard Worker         i4_sad[HORZ_I4x4] += ABS(pu1_src_temp[0] - u1_pred_val)
1816*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[1] - u1_pred_val)
1817*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[2] - u1_pred_val)
1818*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[3] - u1_pred_val);
1819*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1820*495ae853SAndroid Build Coastguard Worker 
1821*495ae853SAndroid Build Coastguard Worker         u1_pred_val = pu1_ngbr_pels[0];
1822*495ae853SAndroid Build Coastguard Worker 
1823*495ae853SAndroid Build Coastguard Worker         i4_sad[HORZ_I4x4] += ABS(pu1_src_temp[0] - u1_pred_val)
1824*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[1] - u1_pred_val)
1825*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[2] - u1_pred_val)
1826*495ae853SAndroid Build Coastguard Worker                         + ABS(pu1_src_temp[3] - u1_pred_val);
1827*495ae853SAndroid Build Coastguard Worker 
1828*495ae853SAndroid Build Coastguard Worker         i4_cost[HORZ_I4x4] = i4_sad[HORZ_I4x4] + ((u4_predictd_mode == HORZ_I4x4) ?
1829*495ae853SAndroid Build Coastguard Worker                                         u4_lambda : 4 * u4_lambda);
1830*495ae853SAndroid Build Coastguard Worker     }
1831*495ae853SAndroid Build Coastguard Worker 
1832*495ae853SAndroid Build Coastguard Worker     /* DC mode valid */
1833*495ae853SAndroid Build Coastguard Worker     if (u4_valid_intra_modes & 4)
1834*495ae853SAndroid Build Coastguard Worker     {
1835*495ae853SAndroid Build Coastguard Worker         i4_sad[DC_I4x4] = 0;
1836*495ae853SAndroid Build Coastguard Worker         i4_cost[DC_I4x4] = 0;
1837*495ae853SAndroid Build Coastguard Worker         pu1_src_temp = pu1_src;
1838*495ae853SAndroid Build Coastguard Worker 
1839*495ae853SAndroid Build Coastguard Worker         if (left)
1840*495ae853SAndroid Build Coastguard Worker             u4_dcval = pu1_ngbr_pels[0] + pu1_ngbr_pels[1] + pu1_ngbr_pels[2]
1841*495ae853SAndroid Build Coastguard Worker                             + pu1_ngbr_pels[3] + 2;
1842*495ae853SAndroid Build Coastguard Worker         if (top)
1843*495ae853SAndroid Build Coastguard Worker             u4_dcval += pu1_ngbr_pels[5] + pu1_ngbr_pels[6] + pu1_ngbr_pels[7]
1844*495ae853SAndroid Build Coastguard Worker                             + pu1_ngbr_pels[8] + 2;
1845*495ae853SAndroid Build Coastguard Worker 
1846*495ae853SAndroid Build Coastguard Worker         u4_dcval = (u4_dcval) ? (u4_dcval >> (1 + left + top)) : 128;
1847*495ae853SAndroid Build Coastguard Worker 
1848*495ae853SAndroid Build Coastguard Worker         /* none available */
1849*495ae853SAndroid Build Coastguard Worker         memset(u1_pred_vals, u4_dcval, 4);
1850*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
1851*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1852*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
1853*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1854*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
1855*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1856*495ae853SAndroid Build Coastguard Worker         USADA8(pu1_src_temp, u1_pred_vals, i4_sad[DC_I4x4]);
1857*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
1858*495ae853SAndroid Build Coastguard Worker 
1859*495ae853SAndroid Build Coastguard Worker         i4_cost[DC_I4x4] = i4_sad[DC_I4x4] + ((u4_predictd_mode == DC_I4x4) ?
1860*495ae853SAndroid Build Coastguard Worker                                         u4_lambda : 4 * u4_lambda);
1861*495ae853SAndroid Build Coastguard Worker     }
1862*495ae853SAndroid Build Coastguard Worker 
1863*495ae853SAndroid Build Coastguard Worker     /* if modes other than VERT, HORZ and DC are  valid */
1864*495ae853SAndroid Build Coastguard Worker     if (u4_valid_intra_modes > 7)
1865*495ae853SAndroid Build Coastguard Worker     {
1866*495ae853SAndroid Build Coastguard Worker         pu1_pred = pu1_ngbr_pels;
1867*495ae853SAndroid Build Coastguard Worker         pu1_pred[13] = pu1_pred[14] = pu1_pred[12];
1868*495ae853SAndroid Build Coastguard Worker 
1869*495ae853SAndroid Build Coastguard Worker         /* Performing FILT121 and FILT11 operation for all neighbour values*/
1870*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 13; i++)
1871*495ae853SAndroid Build Coastguard Worker         {
1872*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_diag_121[i] = FILT121(pu1_pred[0], pu1_pred[1], pu1_pred[2]);
1873*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_diag_11[i] = FILT11(pu1_pred[0], pu1_pred[1]);
1874*495ae853SAndroid Build Coastguard Worker 
1875*495ae853SAndroid Build Coastguard Worker             pu1_pred++;
1876*495ae853SAndroid Build Coastguard Worker         }
1877*495ae853SAndroid Build Coastguard Worker 
1878*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 8)/* DIAG_DL */
1879*495ae853SAndroid Build Coastguard Worker         {
1880*495ae853SAndroid Build Coastguard Worker             i4_sad[DIAG_DL_I4x4] = 0;
1881*495ae853SAndroid Build Coastguard Worker             i4_cost[DIAG_DL_I4x4] = 0;
1882*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1883*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_121 + 5;
1884*495ae853SAndroid Build Coastguard Worker 
1885*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, pu1_pred_val, i4_sad[DIAG_DL_I4x4]);
1886*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1887*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 1), i4_sad[DIAG_DL_I4x4]);
1888*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1889*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[DIAG_DL_I4x4]);
1890*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1891*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 3), i4_sad[DIAG_DL_I4x4]);
1892*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1893*495ae853SAndroid Build Coastguard Worker             i4_cost[DIAG_DL_I4x4] = i4_sad[DIAG_DL_I4x4] + ((u4_predictd_mode == DIAG_DL_I4x4) ?
1894*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
1895*495ae853SAndroid Build Coastguard Worker         }
1896*495ae853SAndroid Build Coastguard Worker 
1897*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 16)/* DIAG_DR */
1898*495ae853SAndroid Build Coastguard Worker         {
1899*495ae853SAndroid Build Coastguard Worker             i4_sad[DIAG_DR_I4x4] = 0;
1900*495ae853SAndroid Build Coastguard Worker             i4_cost[DIAG_DR_I4x4] = 0;
1901*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1902*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_121 + 3;
1903*495ae853SAndroid Build Coastguard Worker 
1904*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, pu1_pred_val, i4_sad[DIAG_DR_I4x4]);
1905*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1906*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val - 1), i4_sad[DIAG_DR_I4x4]);
1907*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1908*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val - 2), i4_sad[DIAG_DR_I4x4]);
1909*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1910*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val - 3), i4_sad[DIAG_DR_I4x4]);
1911*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1912*495ae853SAndroid Build Coastguard Worker             i4_cost[DIAG_DR_I4x4] = i4_sad[DIAG_DR_I4x4] + ((u4_predictd_mode == DIAG_DR_I4x4) ?
1913*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
1914*495ae853SAndroid Build Coastguard Worker 
1915*495ae853SAndroid Build Coastguard Worker         }
1916*495ae853SAndroid Build Coastguard Worker 
1917*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 32)/* VERT_R mode valid ????*/
1918*495ae853SAndroid Build Coastguard Worker         {
1919*495ae853SAndroid Build Coastguard Worker             i4_sad[VERT_R_I4x4] = 0;
1920*495ae853SAndroid Build Coastguard Worker 
1921*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1922*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_vert_r[0] = u1_pred_vals_diag_121[2];
1923*495ae853SAndroid Build Coastguard Worker             memcpy((u1_pred_vals_vert_r + 1), (u1_pred_vals_diag_11 + 4), 3);
1924*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_vert_r[4] = u1_pred_vals_diag_121[1];
1925*495ae853SAndroid Build Coastguard Worker             memcpy((u1_pred_vals_vert_r + 5), (u1_pred_vals_diag_121 + 3), 3);
1926*495ae853SAndroid Build Coastguard Worker 
1927*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_11 + 4;
1928*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, pu1_pred_val, i4_sad[VERT_R_I4x4]);
1929*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_121 + 3;
1930*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1931*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, pu1_pred_val, i4_sad[VERT_R_I4x4]);
1932*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1933*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (u1_pred_vals_vert_r), i4_sad[VERT_R_I4x4]);
1934*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1935*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (u1_pred_vals_vert_r + 4),
1936*495ae853SAndroid Build Coastguard Worker                    i4_sad[VERT_R_I4x4]);
1937*495ae853SAndroid Build Coastguard Worker 
1938*495ae853SAndroid Build Coastguard Worker             i4_cost[VERT_R_I4x4] = i4_sad[VERT_R_I4x4] + ((u4_predictd_mode == VERT_R_I4x4) ?
1939*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
1940*495ae853SAndroid Build Coastguard Worker         }
1941*495ae853SAndroid Build Coastguard Worker 
1942*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 64)/* HORZ_D mode valid ????*/
1943*495ae853SAndroid Build Coastguard Worker         {
1944*495ae853SAndroid Build Coastguard Worker             i4_sad[HORZ_D_I4x4] = 0;
1945*495ae853SAndroid Build Coastguard Worker 
1946*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1947*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[6] = u1_pred_vals_diag_11[3];
1948*495ae853SAndroid Build Coastguard Worker             memcpy((u1_pred_vals_horz_d + 7), (u1_pred_vals_diag_121 + 3), 3);
1949*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[0] = u1_pred_vals_diag_11[0];
1950*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[1] = u1_pred_vals_diag_121[0];
1951*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[2] = u1_pred_vals_diag_11[1];
1952*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[3] = u1_pred_vals_diag_121[1];
1953*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[4] = u1_pred_vals_diag_11[2];
1954*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_d[5] = u1_pred_vals_diag_121[2];
1955*495ae853SAndroid Build Coastguard Worker 
1956*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_horz_d;
1957*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 6), i4_sad[HORZ_D_I4x4]);
1958*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1959*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 4), i4_sad[HORZ_D_I4x4]);
1960*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1961*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[HORZ_D_I4x4]);
1962*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1963*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[HORZ_D_I4x4]);
1964*495ae853SAndroid Build Coastguard Worker 
1965*495ae853SAndroid Build Coastguard Worker             i4_cost[HORZ_D_I4x4] = i4_sad[HORZ_D_I4x4] + ((u4_predictd_mode == HORZ_D_I4x4) ?
1966*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
1967*495ae853SAndroid Build Coastguard Worker         }
1968*495ae853SAndroid Build Coastguard Worker 
1969*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 128)/* VERT_L mode valid ????*/
1970*495ae853SAndroid Build Coastguard Worker         {
1971*495ae853SAndroid Build Coastguard Worker             i4_sad[VERT_L_I4x4] = 0;
1972*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1973*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_11 + 5;
1974*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
1975*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1976*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_121 + 5;
1977*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
1978*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1979*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_11 + 6;
1980*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
1981*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
1982*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_diag_121 + 6;
1983*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[VERT_L_I4x4]);
1984*495ae853SAndroid Build Coastguard Worker 
1985*495ae853SAndroid Build Coastguard Worker             i4_cost[VERT_L_I4x4] = i4_sad[VERT_L_I4x4] + ((u4_predictd_mode == VERT_L_I4x4) ?
1986*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
1987*495ae853SAndroid Build Coastguard Worker         }
1988*495ae853SAndroid Build Coastguard Worker 
1989*495ae853SAndroid Build Coastguard Worker         if (u4_valid_intra_modes & 256)/* HORZ_U mode valid ????*/
1990*495ae853SAndroid Build Coastguard Worker         {
1991*495ae853SAndroid Build Coastguard Worker             i4_sad[HORZ_U_I4x4] = 0;
1992*495ae853SAndroid Build Coastguard Worker             pu1_src_temp = pu1_src;
1993*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[0] = u1_pred_vals_diag_11[2];
1994*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[1] = u1_pred_vals_diag_121[1];
1995*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[2] = u1_pred_vals_diag_11[1];
1996*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[3] = u1_pred_vals_diag_121[0];
1997*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[4] = u1_pred_vals_diag_11[0];
1998*495ae853SAndroid Build Coastguard Worker             u1_pred_vals_horz_u[5] = FILT121(pu1_ngbr_pels[0], pu1_ngbr_pels[0], pu1_ngbr_pels[1]);
1999*495ae853SAndroid Build Coastguard Worker 
2000*495ae853SAndroid Build Coastguard Worker             memset((u1_pred_vals_horz_u + 6), pu1_ngbr_pels[0], 4);
2001*495ae853SAndroid Build Coastguard Worker 
2002*495ae853SAndroid Build Coastguard Worker             pu1_pred_val = u1_pred_vals_horz_u;
2003*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val), i4_sad[HORZ_U_I4x4]);
2004*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
2005*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 2), i4_sad[HORZ_U_I4x4]);
2006*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
2007*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 4), i4_sad[HORZ_U_I4x4]);
2008*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
2009*495ae853SAndroid Build Coastguard Worker             USADA8(pu1_src_temp, (pu1_pred_val + 6), i4_sad[HORZ_U_I4x4]);
2010*495ae853SAndroid Build Coastguard Worker 
2011*495ae853SAndroid Build Coastguard Worker             i4_cost[HORZ_U_I4x4] = i4_sad[HORZ_U_I4x4] + ((u4_predictd_mode == HORZ_U_I4x4) ?
2012*495ae853SAndroid Build Coastguard Worker                                             u4_lambda : 4 * u4_lambda);
2013*495ae853SAndroid Build Coastguard Worker         }
2014*495ae853SAndroid Build Coastguard Worker 
2015*495ae853SAndroid Build Coastguard Worker         i4_min_cost = MIN3(MIN3(i4_cost[0], i4_cost[1], i4_cost[2]),
2016*495ae853SAndroid Build Coastguard Worker                         MIN3(i4_cost[3], i4_cost[4], i4_cost[5]),
2017*495ae853SAndroid Build Coastguard Worker                         MIN3(i4_cost[6], i4_cost[7], i4_cost[8]));
2018*495ae853SAndroid Build Coastguard Worker 
2019*495ae853SAndroid Build Coastguard Worker     }
2020*495ae853SAndroid Build Coastguard Worker     else
2021*495ae853SAndroid Build Coastguard Worker     {
2022*495ae853SAndroid Build Coastguard Worker         /* Only first three modes valid */
2023*495ae853SAndroid Build Coastguard Worker         i4_min_cost = MIN3(i4_cost[0], i4_cost[1], i4_cost[2]);
2024*495ae853SAndroid Build Coastguard Worker     }
2025*495ae853SAndroid Build Coastguard Worker 
2026*495ae853SAndroid Build Coastguard Worker     *pu4_sadmin = i4_min_cost;
2027*495ae853SAndroid Build Coastguard Worker 
2028*495ae853SAndroid Build Coastguard Worker     if (i4_min_cost == i4_cost[0])
2029*495ae853SAndroid Build Coastguard Worker     {
2030*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = VERT_I4x4;
2031*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = pu1_ngbr_pels + 5;
2032*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2033*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2034*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2035*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2036*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2037*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2038*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2039*495ae853SAndroid Build Coastguard Worker     }
2040*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[1])
2041*495ae853SAndroid Build Coastguard Worker     {
2042*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = HORZ_I4x4;
2043*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, pu1_ngbr_pels[3], 4);
2044*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2045*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, pu1_ngbr_pels[2], 4);
2046*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2047*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, pu1_ngbr_pels[1], 4);
2048*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2049*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, pu1_ngbr_pels[0], 4);
2050*495ae853SAndroid Build Coastguard Worker     }
2051*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[2])
2052*495ae853SAndroid Build Coastguard Worker     {
2053*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = DC_I4x4;
2054*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, u4_dcval, 4);
2055*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2056*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, u4_dcval, 4);
2057*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2058*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, u4_dcval, 4);
2059*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2060*495ae853SAndroid Build Coastguard Worker         memset(pu1_dst, u4_dcval, 4);
2061*495ae853SAndroid Build Coastguard Worker     }
2062*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[3])
2063*495ae853SAndroid Build Coastguard Worker     {
2064*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = DIAG_DL_I4x4;
2065*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_121 + 5;
2066*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2067*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2068*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 1), 4);
2069*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2070*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 2), 4);
2071*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2072*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 3), 4);
2073*495ae853SAndroid Build Coastguard Worker     }
2074*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[4])
2075*495ae853SAndroid Build Coastguard Worker     {
2076*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = DIAG_DR_I4x4;
2077*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_121 + 3;
2078*495ae853SAndroid Build Coastguard Worker 
2079*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2080*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2081*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val - 1), 4);
2082*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2083*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val - 2), 4);
2084*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2085*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val - 3), 4);
2086*495ae853SAndroid Build Coastguard Worker     }
2087*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[5])
2088*495ae853SAndroid Build Coastguard Worker     {
2089*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = VERT_R_I4x4;
2090*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_11 + 4;
2091*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2092*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2093*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_121 + 3;
2094*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2095*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2096*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (u1_pred_vals_vert_r), 4);
2097*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2098*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (u1_pred_vals_vert_r + 4), 4);
2099*495ae853SAndroid Build Coastguard Worker     }
2100*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[6])
2101*495ae853SAndroid Build Coastguard Worker     {
2102*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = HORZ_D_I4x4;
2103*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_horz_d;
2104*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 6), 4);
2105*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2106*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 4), 4);
2107*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2108*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 2), 4);
2109*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2110*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2111*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2112*495ae853SAndroid Build Coastguard Worker     }
2113*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[7])
2114*495ae853SAndroid Build Coastguard Worker     {
2115*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = VERT_L_I4x4;
2116*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_11 + 5;
2117*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2118*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2119*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_121 + 5;
2120*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2121*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2122*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_11 + 6;
2123*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2124*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2125*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_diag_121 + 6;
2126*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2127*495ae853SAndroid Build Coastguard Worker     }
2128*495ae853SAndroid Build Coastguard Worker     else if (i4_min_cost == i4_cost[8])
2129*495ae853SAndroid Build Coastguard Worker     {
2130*495ae853SAndroid Build Coastguard Worker         *u4_intra_mode = HORZ_U_I4x4;
2131*495ae853SAndroid Build Coastguard Worker         pu1_pred_val = u1_pred_vals_horz_u;
2132*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val), 4);
2133*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2134*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 2), 4);
2135*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2136*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 4), 4);
2137*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2138*495ae853SAndroid Build Coastguard Worker         memcpy(pu1_dst, (pu1_pred_val + 6), 4);
2139*495ae853SAndroid Build Coastguard Worker         pu1_dst += dst_strd;
2140*495ae853SAndroid Build Coastguard Worker     }
2141*495ae853SAndroid Build Coastguard Worker 
2142*495ae853SAndroid Build Coastguard Worker     return;
2143*495ae853SAndroid Build Coastguard Worker }
2144*495ae853SAndroid Build Coastguard Worker 
2145*495ae853SAndroid Build Coastguard Worker /**
2146*495ae853SAndroid Build Coastguard Worker ******************************************************************************
2147*495ae853SAndroid Build Coastguard Worker *
2148*495ae853SAndroid Build Coastguard Worker * @brief:
2149*495ae853SAndroid Build Coastguard Worker *  Evaluate best intr chroma mode (among VERT, HORZ and DC ) and do the prediction.
2150*495ae853SAndroid Build Coastguard Worker *
2151*495ae853SAndroid Build Coastguard Worker * @par Description
2152*495ae853SAndroid Build Coastguard Worker *  This function evaluates  first three intra chroma modes and compute corresponding sad
2153*495ae853SAndroid Build Coastguard Worker *  and return the buffer predicted with best mode.
2154*495ae853SAndroid Build Coastguard Worker *
2155*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_src
2156*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the source
2157*495ae853SAndroid Build Coastguard Worker *
2158*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_ngbr_pels
2159*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to neighbouring pels
2160*495ae853SAndroid Build Coastguard Worker *
2161*495ae853SAndroid Build Coastguard Worker * @param[out] pu1_dst
2162*495ae853SAndroid Build Coastguard Worker *  UWORD8 pointer to the destination
2163*495ae853SAndroid Build Coastguard Worker *
2164*495ae853SAndroid Build Coastguard Worker * @param[in] src_strd
2165*495ae853SAndroid Build Coastguard Worker *  integer source stride
2166*495ae853SAndroid Build Coastguard Worker *
2167*495ae853SAndroid Build Coastguard Worker * @param[in] dst_strd
2168*495ae853SAndroid Build Coastguard Worker *  integer destination stride
2169*495ae853SAndroid Build Coastguard Worker *
2170*495ae853SAndroid Build Coastguard Worker * @param[in] u4_n_avblty
2171*495ae853SAndroid Build Coastguard Worker *  availability of neighbouring pixels
2172*495ae853SAndroid Build Coastguard Worker *
2173*495ae853SAndroid Build Coastguard Worker * @param[in] u4_intra_mode
2174*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which best mode is returned
2175*495ae853SAndroid Build Coastguard Worker *
2176*495ae853SAndroid Build Coastguard Worker * @param[in] pu4_sadmin
2177*495ae853SAndroid Build Coastguard Worker *  Pointer to the variable in which minimum sad is returned
2178*495ae853SAndroid Build Coastguard Worker *
2179*495ae853SAndroid Build Coastguard Worker * @param[in] u4_valid_intra_modes
2180*495ae853SAndroid Build Coastguard Worker *  Says what all modes are valid
2181*495ae853SAndroid Build Coastguard Worker *
2182*495ae853SAndroid Build Coastguard Worker * @return      none
2183*495ae853SAndroid Build Coastguard Worker *
2184*495ae853SAndroid Build Coastguard Worker ******************************************************************************
2185*495ae853SAndroid Build Coastguard Worker */
ih264e_evaluate_intra_chroma_modes(UWORD8 * pu1_src,UWORD8 * pu1_ngbr_pels,UWORD8 * pu1_dst,UWORD32 src_strd,UWORD32 dst_strd,WORD32 u4_n_avblty,UWORD32 * u4_intra_mode,WORD32 * pu4_sadmin,UWORD32 u4_valid_intra_modes)2186*495ae853SAndroid Build Coastguard Worker void ih264e_evaluate_intra_chroma_modes(UWORD8 *pu1_src,
2187*495ae853SAndroid Build Coastguard Worker                                         UWORD8 *pu1_ngbr_pels,
2188*495ae853SAndroid Build Coastguard Worker                                         UWORD8 *pu1_dst,
2189*495ae853SAndroid Build Coastguard Worker                                         UWORD32 src_strd,
2190*495ae853SAndroid Build Coastguard Worker                                         UWORD32 dst_strd,
2191*495ae853SAndroid Build Coastguard Worker                                         WORD32 u4_n_avblty,
2192*495ae853SAndroid Build Coastguard Worker                                         UWORD32 *u4_intra_mode,
2193*495ae853SAndroid Build Coastguard Worker                                         WORD32 *pu4_sadmin,
2194*495ae853SAndroid Build Coastguard Worker                                         UWORD32 u4_valid_intra_modes)
2195*495ae853SAndroid Build Coastguard Worker {
2196*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_neighbour;
2197*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_src_temp = pu1_src;
2198*495ae853SAndroid Build Coastguard Worker     UWORD8 left = 0, top = 0;
2199*495ae853SAndroid Build Coastguard Worker     WORD32 u4_dcval_u_l[2] = { 0, 0 }, /*sum left neighbours for 'U' ,two separate sets - sum of first four from top,and sum of four values from bottom */
2200*495ae853SAndroid Build Coastguard Worker            u4_dcval_u_t[2] = { 0, 0 };  /*sum top neighbours for 'U'*/
2201*495ae853SAndroid Build Coastguard Worker 
2202*495ae853SAndroid Build Coastguard Worker     WORD32 u4_dcval_v_l[2] = { 0, 0 }, /*sum left neighbours for 'V'*/
2203*495ae853SAndroid Build Coastguard Worker            u4_dcval_v_t[2] = { 0, 0 }; /*sum top neighbours for 'V'*/
2204*495ae853SAndroid Build Coastguard Worker 
2205*495ae853SAndroid Build Coastguard Worker     WORD32 i, j, row, col, i4_sad_vert = INT_MAX, i4_sad_horz = INT_MAX,
2206*495ae853SAndroid Build Coastguard Worker                     i4_sad_dc = INT_MAX, i4_min_sad = INT_MAX;
2207*495ae853SAndroid Build Coastguard Worker     UWORD8 val_u, val_v;
2208*495ae853SAndroid Build Coastguard Worker 
2209*495ae853SAndroid Build Coastguard Worker     WORD32 u4_dc_val[2][2][2];/*  -----------
2210*495ae853SAndroid Build Coastguard Worker                                   |    |    |  Chroma can have four
2211*495ae853SAndroid Build Coastguard Worker                                   | 00 | 01 |  separate dc value...
2212*495ae853SAndroid Build Coastguard Worker                                   -----------  u4_dc_val corresponds to this dc values
2213*495ae853SAndroid Build Coastguard Worker                                   |    |    |  with u4_dc_val[2][2][U] and u4_dc_val[2][2][V]
2214*495ae853SAndroid Build Coastguard Worker                                   | 10 | 11 |
2215*495ae853SAndroid Build Coastguard Worker                                   -----------                */
2216*495ae853SAndroid Build Coastguard Worker     left = (u4_n_avblty & LEFT_MB_AVAILABLE_MASK);
2217*495ae853SAndroid Build Coastguard Worker     top = (u4_n_avblty & TOP_MB_AVAILABLE_MASK) >> 2;
2218*495ae853SAndroid Build Coastguard Worker 
2219*495ae853SAndroid Build Coastguard Worker     /*Evaluating HORZ*/
2220*495ae853SAndroid Build Coastguard Worker     if (left)/* Ifleft available*/
2221*495ae853SAndroid Build Coastguard Worker     {
2222*495ae853SAndroid Build Coastguard Worker         i4_sad_horz = 0;
2223*495ae853SAndroid Build Coastguard Worker 
2224*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 8; i++)
2225*495ae853SAndroid Build Coastguard Worker         {
2226*495ae853SAndroid Build Coastguard Worker             val_v = pu1_ngbr_pels[15 - 2 * i];
2227*495ae853SAndroid Build Coastguard Worker             val_u = pu1_ngbr_pels[15 - 2 * i - 1];
2228*495ae853SAndroid Build Coastguard Worker             row = i / 4;
2229*495ae853SAndroid Build Coastguard Worker             u4_dcval_u_l[row] += val_u;
2230*495ae853SAndroid Build Coastguard Worker             u4_dcval_v_l[row] += val_v;
2231*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 8; j++)
2232*495ae853SAndroid Build Coastguard Worker             {
2233*495ae853SAndroid Build Coastguard Worker                 i4_sad_horz += ABS(val_u - pu1_src_temp[2 * j]);/* Finding SAD for HORZ mode*/
2234*495ae853SAndroid Build Coastguard Worker                 i4_sad_horz += ABS(val_v - pu1_src_temp[2 * j + 1]);
2235*495ae853SAndroid Build Coastguard Worker             }
2236*495ae853SAndroid Build Coastguard Worker 
2237*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
2238*495ae853SAndroid Build Coastguard Worker         }
2239*495ae853SAndroid Build Coastguard Worker         u4_dcval_u_l[0] += 2;
2240*495ae853SAndroid Build Coastguard Worker         u4_dcval_u_l[1] += 2;
2241*495ae853SAndroid Build Coastguard Worker         u4_dcval_v_l[0] += 2;
2242*495ae853SAndroid Build Coastguard Worker         u4_dcval_v_l[1] += 2;
2243*495ae853SAndroid Build Coastguard Worker     }
2244*495ae853SAndroid Build Coastguard Worker 
2245*495ae853SAndroid Build Coastguard Worker     /*Evaluating VERT**/
2246*495ae853SAndroid Build Coastguard Worker     pu1_src_temp = pu1_src;
2247*495ae853SAndroid Build Coastguard Worker     if (top) /* top available*/
2248*495ae853SAndroid Build Coastguard Worker     {
2249*495ae853SAndroid Build Coastguard Worker         i4_sad_vert = 0;
2250*495ae853SAndroid Build Coastguard Worker 
2251*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < 8; i++)
2252*495ae853SAndroid Build Coastguard Worker         {
2253*495ae853SAndroid Build Coastguard Worker             col = i / 4;
2254*495ae853SAndroid Build Coastguard Worker 
2255*495ae853SAndroid Build Coastguard Worker             val_u = pu1_ngbr_pels[18 + i * 2];
2256*495ae853SAndroid Build Coastguard Worker             val_v = pu1_ngbr_pels[18 + i * 2 + 1];
2257*495ae853SAndroid Build Coastguard Worker             u4_dcval_u_t[col] += val_u;
2258*495ae853SAndroid Build Coastguard Worker             u4_dcval_v_t[col] += val_v;
2259*495ae853SAndroid Build Coastguard Worker 
2260*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 16; j++)
2261*495ae853SAndroid Build Coastguard Worker             {
2262*495ae853SAndroid Build Coastguard Worker                 i4_sad_vert += ABS(pu1_ngbr_pels[18 + j] - pu1_src_temp[j]);/* Finding SAD for VERT mode*/
2263*495ae853SAndroid Build Coastguard Worker             }
2264*495ae853SAndroid Build Coastguard Worker             pu1_src_temp += src_strd;
2265*495ae853SAndroid Build Coastguard Worker 
2266*495ae853SAndroid Build Coastguard Worker         }
2267*495ae853SAndroid Build Coastguard Worker         u4_dcval_u_t[0] += 2;
2268*495ae853SAndroid Build Coastguard Worker         u4_dcval_u_t[1] += 2;
2269*495ae853SAndroid Build Coastguard Worker         u4_dcval_v_t[0] += 2;
2270*495ae853SAndroid Build Coastguard Worker         u4_dcval_v_t[1] += 2;
2271*495ae853SAndroid Build Coastguard Worker     }
2272*495ae853SAndroid Build Coastguard Worker 
2273*495ae853SAndroid Build Coastguard Worker     /* computing DC value*/
2274*495ae853SAndroid Build Coastguard Worker     /* Equation  8-128 in spec*/
2275*495ae853SAndroid Build Coastguard Worker     u4_dc_val[0][0][0] = (u4_dcval_u_l[0] + u4_dcval_u_t[0]) >> (1 + left + top);
2276*495ae853SAndroid Build Coastguard Worker     u4_dc_val[0][0][1] = (u4_dcval_v_l[0] + u4_dcval_v_t[0]) >> (1 + left + top);
2277*495ae853SAndroid Build Coastguard Worker     u4_dc_val[1][1][0] = (u4_dcval_u_l[1] + u4_dcval_u_t[1]) >> (1 + left + top);
2278*495ae853SAndroid Build Coastguard Worker     u4_dc_val[1][1][1] = (u4_dcval_v_l[1] + u4_dcval_v_t[1]) >> (1 + left + top);
2279*495ae853SAndroid Build Coastguard Worker 
2280*495ae853SAndroid Build Coastguard Worker     if (top)
2281*495ae853SAndroid Build Coastguard Worker     {
2282*495ae853SAndroid Build Coastguard Worker         /* Equation  8-132 in spec*/
2283*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][1][0] = (u4_dcval_u_t[1]) >> (1 + top);
2284*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][1][1] = (u4_dcval_v_t[1]) >> (1 + top);
2285*495ae853SAndroid Build Coastguard Worker     }
2286*495ae853SAndroid Build Coastguard Worker     else
2287*495ae853SAndroid Build Coastguard Worker     {
2288*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][1][0] = (u4_dcval_u_l[0]) >> (1 + left);
2289*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][1][1] = (u4_dcval_v_l[0]) >> (1 + left);
2290*495ae853SAndroid Build Coastguard Worker     }
2291*495ae853SAndroid Build Coastguard Worker 
2292*495ae853SAndroid Build Coastguard Worker     if (left)
2293*495ae853SAndroid Build Coastguard Worker     {
2294*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][0][0] = (u4_dcval_u_l[1]) >> (1 + left);
2295*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][0][1] = (u4_dcval_v_l[1]) >> (1 + left);
2296*495ae853SAndroid Build Coastguard Worker     }
2297*495ae853SAndroid Build Coastguard Worker     else
2298*495ae853SAndroid Build Coastguard Worker     {
2299*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][0][0] = (u4_dcval_u_t[0]) >> (1 + top);
2300*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][0][1] = (u4_dcval_v_t[0]) >> (1 + top);
2301*495ae853SAndroid Build Coastguard Worker     }
2302*495ae853SAndroid Build Coastguard Worker 
2303*495ae853SAndroid Build Coastguard Worker     if (!(left || top))
2304*495ae853SAndroid Build Coastguard Worker     {
2305*495ae853SAndroid Build Coastguard Worker         /*none available*/
2306*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][0][0] = u4_dc_val[0][0][1] =
2307*495ae853SAndroid Build Coastguard Worker         u4_dc_val[0][1][0] = u4_dc_val[0][1][1] =
2308*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][0][0] = u4_dc_val[1][0][1] =
2309*495ae853SAndroid Build Coastguard Worker         u4_dc_val[1][1][0] = u4_dc_val[1][1][1] = 128;
2310*495ae853SAndroid Build Coastguard Worker     }
2311*495ae853SAndroid Build Coastguard Worker 
2312*495ae853SAndroid Build Coastguard Worker     /* Evaluating DC */
2313*495ae853SAndroid Build Coastguard Worker     pu1_src_temp = pu1_src;
2314*495ae853SAndroid Build Coastguard Worker     i4_sad_dc = 0;
2315*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < 8; i++)
2316*495ae853SAndroid Build Coastguard Worker     {
2317*495ae853SAndroid Build Coastguard Worker         for (j = 0; j < 8; j++)
2318*495ae853SAndroid Build Coastguard Worker         {
2319*495ae853SAndroid Build Coastguard Worker             col = j / 4;
2320*495ae853SAndroid Build Coastguard Worker             row = i / 4;
2321*495ae853SAndroid Build Coastguard Worker             val_u = u4_dc_val[row][col][0];
2322*495ae853SAndroid Build Coastguard Worker             val_v = u4_dc_val[row][col][1];
2323*495ae853SAndroid Build Coastguard Worker 
2324*495ae853SAndroid Build Coastguard Worker             i4_sad_dc += ABS(val_u - pu1_src_temp[2 * j]);/* Finding SAD for DC mode*/
2325*495ae853SAndroid Build Coastguard Worker             i4_sad_dc += ABS(val_v - pu1_src_temp[2 * j + 1]);
2326*495ae853SAndroid Build Coastguard Worker         }
2327*495ae853SAndroid Build Coastguard Worker         pu1_src_temp += src_strd;
2328*495ae853SAndroid Build Coastguard Worker     }
2329*495ae853SAndroid Build Coastguard Worker 
2330*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 01) == 0)/* If DC is disabled*/
2331*495ae853SAndroid Build Coastguard Worker         i4_sad_dc = INT_MAX;
2332*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 02) == 0)/* If HORZ is disabled*/
2333*495ae853SAndroid Build Coastguard Worker         i4_sad_horz = INT_MAX;
2334*495ae853SAndroid Build Coastguard Worker     if ((u4_valid_intra_modes & 04) == 0)/* If VERT is disabled*/
2335*495ae853SAndroid Build Coastguard Worker         i4_sad_vert = INT_MAX;
2336*495ae853SAndroid Build Coastguard Worker 
2337*495ae853SAndroid Build Coastguard Worker     i4_min_sad = MIN3(i4_sad_horz, i4_sad_dc, i4_sad_vert);
2338*495ae853SAndroid Build Coastguard Worker 
2339*495ae853SAndroid Build Coastguard Worker     /* Finding Minimum sad and doing corresponding prediction*/
2340*495ae853SAndroid Build Coastguard Worker     if (i4_min_sad < *pu4_sadmin)
2341*495ae853SAndroid Build Coastguard Worker     {
2342*495ae853SAndroid Build Coastguard Worker         *pu4_sadmin = i4_min_sad;
2343*495ae853SAndroid Build Coastguard Worker 
2344*495ae853SAndroid Build Coastguard Worker         if (i4_min_sad == i4_sad_dc)
2345*495ae853SAndroid Build Coastguard Worker         {
2346*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = DC_CH_I8x8;
2347*495ae853SAndroid Build Coastguard Worker             for (i = 0; i < 8; i++)
2348*495ae853SAndroid Build Coastguard Worker             {
2349*495ae853SAndroid Build Coastguard Worker                 for (j = 0; j < 8; j++)
2350*495ae853SAndroid Build Coastguard Worker                 {
2351*495ae853SAndroid Build Coastguard Worker                     col = j / 4;
2352*495ae853SAndroid Build Coastguard Worker                     row = i / 4;
2353*495ae853SAndroid Build Coastguard Worker 
2354*495ae853SAndroid Build Coastguard Worker                     pu1_dst[2 * j] = u4_dc_val[row][col][0];
2355*495ae853SAndroid Build Coastguard Worker                     pu1_dst[2 * j + 1] = u4_dc_val[row][col][1];
2356*495ae853SAndroid Build Coastguard Worker                 }
2357*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
2358*495ae853SAndroid Build Coastguard Worker             }
2359*495ae853SAndroid Build Coastguard Worker         }
2360*495ae853SAndroid Build Coastguard Worker         else if (i4_min_sad == i4_sad_horz)
2361*495ae853SAndroid Build Coastguard Worker         {
2362*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = HORZ_CH_I8x8;
2363*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 8; j++)
2364*495ae853SAndroid Build Coastguard Worker             {
2365*495ae853SAndroid Build Coastguard Worker                 val_v = pu1_ngbr_pels[15 - 2 * j];
2366*495ae853SAndroid Build Coastguard Worker                 val_u = pu1_ngbr_pels[15 - 2 * j - 1];
2367*495ae853SAndroid Build Coastguard Worker 
2368*495ae853SAndroid Build Coastguard Worker                 for (i = 0; i < 8; i++)
2369*495ae853SAndroid Build Coastguard Worker                 {
2370*495ae853SAndroid Build Coastguard Worker                     pu1_dst[2 * i] = val_u;
2371*495ae853SAndroid Build Coastguard Worker                     pu1_dst[2 * i + 1] = val_v;
2372*495ae853SAndroid Build Coastguard Worker 
2373*495ae853SAndroid Build Coastguard Worker                 }
2374*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
2375*495ae853SAndroid Build Coastguard Worker             }
2376*495ae853SAndroid Build Coastguard Worker         }
2377*495ae853SAndroid Build Coastguard Worker         else
2378*495ae853SAndroid Build Coastguard Worker         {
2379*495ae853SAndroid Build Coastguard Worker             *u4_intra_mode = VERT_CH_I8x8;
2380*495ae853SAndroid Build Coastguard Worker             pu1_neighbour = pu1_ngbr_pels + 18;
2381*495ae853SAndroid Build Coastguard Worker             for (j = 0; j < 8; j++)
2382*495ae853SAndroid Build Coastguard Worker             {
2383*495ae853SAndroid Build Coastguard Worker                 memcpy(pu1_dst, pu1_neighbour, MB_SIZE);
2384*495ae853SAndroid Build Coastguard Worker                 pu1_dst += dst_strd;
2385*495ae853SAndroid Build Coastguard Worker             }
2386*495ae853SAndroid Build Coastguard Worker         }
2387*495ae853SAndroid Build Coastguard Worker     }
2388*495ae853SAndroid Build Coastguard Worker 
2389*495ae853SAndroid Build Coastguard Worker     return;
2390*495ae853SAndroid Build Coastguard Worker }
2391