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
106void 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
189void 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
292void 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
393void 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
489void 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
572void 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