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