1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 /**
19 *******************************************************************************
20 * @file
21 *  ihevc_weighted_pred.c
22 *
23 * @brief
24 *  Contains function definitions for weighted prediction used in inter
25 * prediction
26 *
27 * @author
28 *  Srinivas T
29 *
30 * @par List of Functions:
31 *   - ihevc_weighted_pred_uni()
32 *   - ihevc_weighted_pred_bi()
33 *   - ihevc_weighted_pred_bi_default()
34 *   - ihevc_weighted_pred_chroma_uni()
35 *   - ihevc_weighted_pred_chroma_bi()
36 *   - ihevc_weighted_pred_chroma_bi_default()
37 *
38 * @remarks
39 *  None
40 *
41 *******************************************************************************
42 */
43 /*****************************************************************************/
44 /* File Includes                                                             */
45 /*****************************************************************************/
46 #include "ihevc_typedefs.h"
47 #include "ihevc_defs.h"
48 #include "ihevc_macros.h"
49 #include "ihevc_platform_macros.h"
50 #include "ihevc_func_selector.h"
51 
52 #include "ihevc_inter_pred.h"
53 
54 /**
55 *******************************************************************************
56 *
57 * @brief
58 *  Does uni-weighted prediction on the array pointed by  pi2_src and stores
59 * it at the location pointed by pi2_dst
60 *
61 * @par Description:
62 *  dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) )  >> shift +
63 * offset
64 *
65 * @param[in] pi2_src
66 *  Pointer to the source
67 *
68 * @param[out] pu1_dst
69 *  Pointer to the destination
70 *
71 * @param[in] src_strd
72 *  Source stride
73 *
74 * @param[in] dst_strd
75 *  Destination stride
76 *
77 * @param[in] wgt0
78 *  weight to be multiplied to the source
79 *
80 * @param[in] off0
81 *  offset to be added after rounding and
82 *
83 * @param[in] shifting
84 *
85 *
86 * @param[in] shift
87 *  (14 Bit depth) + log2_weight_denominator
88 *
89 * @param[in] lvl_shift
90 *  added before shift and offset
91 *
92 * @param[in] ht
93 *  height of the source
94 *
95 * @param[in] wd
96 *  width of the source
97 *
98 * @returns
99 *
100 * @remarks
101 *  None
102 *
103 *******************************************************************************
104 */
105 
ihevc_weighted_pred_uni(WORD16 * pi2_src,UWORD8 * pu1_dst,WORD32 src_strd,WORD32 dst_strd,WORD32 wgt0,WORD32 off0,WORD32 shift,WORD32 lvl_shift,WORD32 ht,WORD32 wd)106 void ihevc_weighted_pred_uni(WORD16 *pi2_src,
107                              UWORD8 *pu1_dst,
108                              WORD32 src_strd,
109                              WORD32 dst_strd,
110                              WORD32 wgt0,
111                              WORD32 off0,
112                              WORD32 shift,
113                              WORD32 lvl_shift,
114                              WORD32 ht,
115                              WORD32 wd)
116 {
117     WORD32 row, col;
118     WORD32 i4_tmp;
119 
120     for(row = 0; row < ht; row++)
121     {
122         for(col = 0; col < wd; col++)
123         {
124             i4_tmp = (pi2_src[col] + lvl_shift) * wgt0;
125             i4_tmp += 1 << (shift - 1);
126             i4_tmp = (i4_tmp >> shift) + off0;
127 
128             pu1_dst[col] = CLIP_U8(i4_tmp);
129         }
130 
131         pi2_src += src_strd;
132         pu1_dst += dst_strd;
133     }
134 }
135 //WEIGHTED_PRED_UNI
136 
137 /**
138 *******************************************************************************
139 *
140 * @brief
141 * Does chroma uni-weighted prediction on array pointed by pi2_src and stores
142 * it at the location pointed by pi2_dst
143 *
144 * @par Description:
145 *  dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) )  >> shift +
146 * offset
147 *
148 * @param[in] pi2_src
149 *  Pointer to the source
150 *
151 * @param[out] pu1_dst
152 *  Pointer to the destination
153 *
154 * @param[in] src_strd
155 *  Source stride
156 *
157 * @param[in] dst_strd
158 *  Destination stride
159 *
160 * @param[in] wgt0
161 *  weight to be multiplied to the source
162 *
163 * @param[in] off0
164 *  offset to be added after rounding and
165 *
166 * @param[in] shifting
167 *
168 *
169 * @param[in] shift
170 *  (14 Bit depth) + log2_weight_denominator
171 *
172 * @param[in] lvl_shift
173 *  added before shift and offset
174 *
175 * @param[in] ht
176 *  height of the source
177 *
178 * @param[in] wd
179 *  width of the source (each colour component)
180 *
181 * @returns
182 *
183 * @remarks
184 *  None
185 *
186 *******************************************************************************
187 */
188 
ihevc_weighted_pred_chroma_uni(WORD16 * pi2_src,UWORD8 * pu1_dst,WORD32 src_strd,WORD32 dst_strd,WORD32 wgt0_cb,WORD32 wgt0_cr,WORD32 off0_cb,WORD32 off0_cr,WORD32 shift,WORD32 lvl_shift,WORD32 ht,WORD32 wd)189 void ihevc_weighted_pred_chroma_uni(WORD16 *pi2_src,
190                                     UWORD8 *pu1_dst,
191                                     WORD32 src_strd,
192                                     WORD32 dst_strd,
193                                     WORD32 wgt0_cb,
194                                     WORD32 wgt0_cr,
195                                     WORD32 off0_cb,
196                                     WORD32 off0_cr,
197                                     WORD32 shift,
198                                     WORD32 lvl_shift,
199                                     WORD32 ht,
200                                     WORD32 wd)
201 {
202     WORD32 row, col;
203     WORD32 i4_tmp;
204 
205     for(row = 0; row < ht; row++)
206     {
207         for(col = 0; col < 2 * wd; col += 2)
208         {
209             i4_tmp = (pi2_src[col] + lvl_shift) * wgt0_cb;
210             i4_tmp += 1 << (shift - 1);
211             i4_tmp = (i4_tmp >> shift) + off0_cb;
212 
213             pu1_dst[col] = CLIP_U8(i4_tmp);
214 
215             i4_tmp = (pi2_src[col + 1] + lvl_shift) * wgt0_cr;
216             i4_tmp += 1 << (shift - 1);
217             i4_tmp = (i4_tmp >> shift) + off0_cr;
218 
219             pu1_dst[col + 1] = CLIP_U8(i4_tmp);
220         }
221 
222         pi2_src += src_strd;
223         pu1_dst += dst_strd;
224     }
225 }
226 //WEIGHTED_PRED_CHROMA_UNI
227 
228 /**
229 *******************************************************************************
230 *
231 * @brief
232 *  Does bi-weighted prediction on the arrays pointed by  pi2_src1 and
233 * pi2_src2 and stores it at location pointed  by pi2_dst
234 *
235 * @par Description:
236 *  dst = ( (src1 + lvl_shift1)*wgt0 +  (src2 + lvl_shift2)*wgt1 +  (off0 +
237 * off1 + 1) << (shift - 1) ) >> shift
238 *
239 * @param[in] pi2_src1
240 *  Pointer to source 1
241 *
242 * @param[in] pi2_src2
243 *  Pointer to source 2
244 *
245 * @param[out] pu1_dst
246 *  Pointer to destination
247 *
248 * @param[in] src_strd1
249 *  Source stride 1
250 *
251 * @param[in] src_strd2
252 *  Source stride 2
253 *
254 * @param[in] dst_strd
255 *  Destination stride
256 *
257 * @param[in] wgt0
258 *  weight to be multiplied to source 1
259 *
260 * @param[in] off0
261 *  offset 0
262 *
263 * @param[in] wgt1
264 *  weight to be multiplied to source 2
265 *
266 * @param[in] off1
267 *  offset 1
268 *
269 * @param[in] shift
270 *  (14 Bit depth) + log2_weight_denominator
271 *
272 * @param[in] lvl_shift1
273 *  added before shift and offset
274 *
275 * @param[in] lvl_shift2
276 *  added before shift and offset
277 *
278 * @param[in] ht
279 *  height of the source
280 *
281 * @param[in] wd
282 *  width of the source
283 *
284 * @returns
285 *
286 * @remarks
287 *  None
288 *
289 *******************************************************************************
290 */
291 
ihevc_weighted_pred_bi(WORD16 * pi2_src1,WORD16 * pi2_src2,UWORD8 * pu1_dst,WORD32 src_strd1,WORD32 src_strd2,WORD32 dst_strd,WORD32 wgt0,WORD32 off0,WORD32 wgt1,WORD32 off1,WORD32 shift,WORD32 lvl_shift1,WORD32 lvl_shift2,WORD32 ht,WORD32 wd)292 void ihevc_weighted_pred_bi(WORD16 *pi2_src1,
293                             WORD16 *pi2_src2,
294                             UWORD8 *pu1_dst,
295                             WORD32 src_strd1,
296                             WORD32 src_strd2,
297                             WORD32 dst_strd,
298                             WORD32 wgt0,
299                             WORD32 off0,
300                             WORD32 wgt1,
301                             WORD32 off1,
302                             WORD32 shift,
303                             WORD32 lvl_shift1,
304                             WORD32 lvl_shift2,
305                             WORD32 ht,
306                             WORD32 wd)
307 {
308     WORD32 row, col;
309     WORD32 i4_tmp;
310 
311     for(row = 0; row < ht; row++)
312     {
313         for(col = 0; col < wd; col++)
314         {
315             i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0;
316             i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1;
317             i4_tmp += (off0 + off1 + 1) << (shift - 1);
318 
319             pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
320         }
321 
322         pi2_src1 += src_strd1;
323         pi2_src2 += src_strd2;
324         pu1_dst += dst_strd;
325     }
326 }
327 //WEIGHTED_PRED_BI
328 
329 /**
330 *******************************************************************************
331 *
332 * @brief
333 * Does chroma bi-weighted prediction on the arrays pointed by  pi2_src1 and
334 * pi2_src2 and stores it at location pointed  by pi2_dst
335 *
336 * @par Description:
337 *  dst = ( (src1 + lvl_shift1)*wgt0 +  (src2 + lvl_shift2)*wgt1 +  (off0 +
338 * off1 + 1) << (shift - 1) ) >> shift
339 *
340 * @param[in] pi2_src1
341 *  Pointer to source 1
342 *
343 * @param[in] pi2_src2
344 *  Pointer to source 2
345 *
346 * @param[out] pu1_dst
347 *  Pointer to destination
348 *
349 * @param[in] src_strd1
350 *  Source stride 1
351 *
352 * @param[in] src_strd2
353 *  Source stride 2
354 *
355 * @param[in] dst_strd
356 *  Destination stride
357 *
358 * @param[in] wgt0
359 *  weight to be multiplied to source 1
360 *
361 * @param[in] off0
362 *  offset 0
363 *
364 * @param[in] wgt1
365 *  weight to be multiplied to source 2
366 *
367 * @param[in] off1
368 *  offset 1
369 *
370 * @param[in] shift
371 *  (14 Bit depth) + log2_weight_denominator
372 *
373 * @param[in] lvl_shift1
374 *  added before shift and offset
375 *
376 * @param[in] lvl_shift2
377 *  added before shift and offset
378 *
379 * @param[in] ht
380 *  height of the source
381 *
382 * @param[in] wd
383 *  width of the source (each colour component)
384 *
385 * @returns
386 *
387 * @remarks
388 *  None
389 *
390 *******************************************************************************
391 */
392 
ihevc_weighted_pred_chroma_bi(WORD16 * pi2_src1,WORD16 * pi2_src2,UWORD8 * pu1_dst,WORD32 src_strd1,WORD32 src_strd2,WORD32 dst_strd,WORD32 wgt0_cb,WORD32 wgt0_cr,WORD32 off0_cb,WORD32 off0_cr,WORD32 wgt1_cb,WORD32 wgt1_cr,WORD32 off1_cb,WORD32 off1_cr,WORD32 shift,WORD32 lvl_shift1,WORD32 lvl_shift2,WORD32 ht,WORD32 wd)393 void ihevc_weighted_pred_chroma_bi(WORD16 *pi2_src1,
394                                    WORD16 *pi2_src2,
395                                    UWORD8 *pu1_dst,
396                                    WORD32 src_strd1,
397                                    WORD32 src_strd2,
398                                    WORD32 dst_strd,
399                                    WORD32 wgt0_cb,
400                                    WORD32 wgt0_cr,
401                                    WORD32 off0_cb,
402                                    WORD32 off0_cr,
403                                    WORD32 wgt1_cb,
404                                    WORD32 wgt1_cr,
405                                    WORD32 off1_cb,
406                                    WORD32 off1_cr,
407                                    WORD32 shift,
408                                    WORD32 lvl_shift1,
409                                    WORD32 lvl_shift2,
410                                    WORD32 ht,
411                                    WORD32 wd)
412 {
413     WORD32 row, col;
414     WORD32 i4_tmp;
415 
416     for(row = 0; row < ht; row++)
417     {
418         for(col = 0; col < 2 * wd; col += 2)
419         {
420             i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0_cb;
421             i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1_cb;
422             i4_tmp += (off0_cb + off1_cb + 1) << (shift - 1);
423 
424             pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
425 
426             i4_tmp = (pi2_src1[col + 1] + lvl_shift1) * wgt0_cr;
427             i4_tmp += (pi2_src2[col + 1] + lvl_shift2) * wgt1_cr;
428             i4_tmp += (off0_cr + off1_cr + 1) << (shift - 1);
429 
430             pu1_dst[col + 1] = CLIP_U8(i4_tmp >> shift);
431         }
432 
433         pi2_src1 += src_strd1;
434         pi2_src2 += src_strd2;
435         pu1_dst += dst_strd;
436     }
437 }
438 //WEIGHTED_PRED_CHROMA_BI
439 
440 /**
441 *******************************************************************************
442 *
443 * @brief
444 *  Does default bi-weighted prediction on the arrays pointed by pi2_src1 and
445 * pi2_src2 and stores it at location  pointed by pi2_dst
446 *
447 * @par Description:
448 *  dst = ( (src1 + lvl_shift1) +  (src2 + lvl_shift2) +  1 << (shift - 1) )
449 * >> shift  where shift = 15 - BitDepth
450 *
451 * @param[in] pi2_src1
452 *  Pointer to source 1
453 *
454 * @param[in] pi2_src2
455 *  Pointer to source 2
456 *
457 * @param[out] pu1_dst
458 *  Pointer to destination
459 *
460 * @param[in] src_strd1
461 *  Source stride 1
462 *
463 * @param[in] src_strd2
464 *  Source stride 2
465 *
466 * @param[in] dst_strd
467 *  Destination stride
468 *
469 * @param[in] lvl_shift1
470 *  added before shift and offset
471 *
472 * @param[in] lvl_shift2
473 *  added before shift and offset
474 *
475 * @param[in] ht
476 *  height of the source
477 *
478 * @param[in] wd
479 *  width of the source
480 *
481 * @returns
482 *
483 * @remarks
484 *  None
485 *
486 *******************************************************************************
487 */
488 
ihevc_weighted_pred_bi_default(WORD16 * pi2_src1,WORD16 * pi2_src2,UWORD8 * pu1_dst,WORD32 src_strd1,WORD32 src_strd2,WORD32 dst_strd,WORD32 lvl_shift1,WORD32 lvl_shift2,WORD32 ht,WORD32 wd)489 void ihevc_weighted_pred_bi_default(WORD16 *pi2_src1,
490                                     WORD16 *pi2_src2,
491                                     UWORD8 *pu1_dst,
492                                     WORD32 src_strd1,
493                                     WORD32 src_strd2,
494                                     WORD32 dst_strd,
495                                     WORD32 lvl_shift1,
496                                     WORD32 lvl_shift2,
497                                     WORD32 ht,
498                                     WORD32 wd)
499 {
500     WORD32 row, col;
501     WORD32 i4_tmp;
502     WORD32 shift;
503 
504     shift = SHIFT_14_MINUS_BIT_DEPTH + 1;
505     for(row = 0; row < ht; row++)
506     {
507         for(col = 0; col < wd; col++)
508         {
509             i4_tmp = pi2_src1[col] + lvl_shift1;
510             i4_tmp += pi2_src2[col] + lvl_shift2;
511             i4_tmp += 1 << (shift - 1);
512 
513             pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
514         }
515 
516         pi2_src1 += src_strd1;
517         pi2_src2 += src_strd2;
518         pu1_dst += dst_strd;
519     }
520 }
521 //WEIGHTED_PRED_BI_DEFAULT
522 
523 /**
524 *******************************************************************************
525 *
526 * @brief
527 *  Does chroma default bi-weighted prediction on arrays pointed by pi2_src1 and
528 * pi2_src2 and stores it at location  pointed by pi2_dst
529 *
530 * @par Description:
531 *  dst = ( (src1 + lvl_shift1) +  (src2 + lvl_shift2) +  1 << (shift - 1) )
532 * >> shift  where shift = 15 - BitDepth
533 *
534 * @param[in] pi2_src1
535 *  Pointer to source 1
536 *
537 * @param[in] pi2_src2
538 *  Pointer to source 2
539 *
540 * @param[out] pu1_dst
541 *  Pointer to destination
542 *
543 * @param[in] src_strd1
544 *  Source stride 1
545 *
546 * @param[in] src_strd2
547 *  Source stride 2
548 *
549 * @param[in] dst_strd
550 *  Destination stride
551 *
552 * @param[in] lvl_shift1
553 *  added before shift and offset
554 *
555 * @param[in] lvl_shift2
556 *  added before shift and offset
557 *
558 * @param[in] ht
559 *  height of the source
560 *
561 * @param[in] wd
562 *  width of the source (each colour component)
563 *
564 * @returns
565 *
566 * @remarks
567 *  None
568 *
569 *******************************************************************************
570 */
571 
ihevc_weighted_pred_chroma_bi_default(WORD16 * pi2_src1,WORD16 * pi2_src2,UWORD8 * pu1_dst,WORD32 src_strd1,WORD32 src_strd2,WORD32 dst_strd,WORD32 lvl_shift1,WORD32 lvl_shift2,WORD32 ht,WORD32 wd)572 void ihevc_weighted_pred_chroma_bi_default(WORD16 *pi2_src1,
573                                            WORD16 *pi2_src2,
574                                            UWORD8 *pu1_dst,
575                                            WORD32 src_strd1,
576                                            WORD32 src_strd2,
577                                            WORD32 dst_strd,
578                                            WORD32 lvl_shift1,
579                                            WORD32 lvl_shift2,
580                                            WORD32 ht,
581                                            WORD32 wd)
582 {
583     WORD32 row, col;
584     WORD32 i4_tmp;
585     WORD32 shift;
586 
587     shift = SHIFT_14_MINUS_BIT_DEPTH + 1;
588     for(row = 0; row < ht; row++)
589     {
590         for(col = 0; col < 2 * wd; col++)
591         {
592             i4_tmp = pi2_src1[col] + lvl_shift1;
593             i4_tmp += pi2_src2[col] + lvl_shift2;
594             i4_tmp += 1 << (shift - 1);
595 
596             pu1_dst[col] = CLIP_U8(i4_tmp >> shift);
597         }
598 
599         pi2_src1 += src_strd1;
600         pi2_src2 += src_strd2;
601         pu1_dst += dst_strd;
602     }
603 }
604 //WEIGHTED_PRED_CHROMA_BI_DEFAULT
605