1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
5 * Deepthi Devaki <deepthidevaki@multicorewareinc.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
21 * This program is also available under a commercial proprietary license.
22 * For more information, contact us at license @ x265.com.
23 *****************************************************************************/
26 #include "primitives.h"
30 #include "reference.h"
34 MotionReference::MotionReference()
36 weightBuffer
[0] = NULL
;
37 weightBuffer
[1] = NULL
;
38 weightBuffer
[2] = NULL
;
41 MotionReference::~MotionReference()
43 X265_FREE(weightBuffer
[0]);
44 X265_FREE(weightBuffer
[1]);
45 X265_FREE(weightBuffer
[2]);
48 int MotionReference::init(PicYuv
* recPic
, WeightParam
*wp
, const x265_param
& p
)
52 lumaStride
= recPic
->m_stride
;
53 chromaStride
= recPic
->m_strideC
;
54 numInterpPlanes
= p
.subpelRefine
> 2 ? 3 : 1; /* is chroma satd possible? */
56 /* directly reference the extended integer pel planes */
57 fpelPlane
[0] = recPic
->m_picOrg
[0];
58 fpelPlane
[1] = recPic
->m_picOrg
[1];
59 fpelPlane
[2] = recPic
->m_picOrg
[2];
64 uint32_t numCUinHeight
= (reconPic
->m_picHeight
+ g_maxCUSize
- 1) / g_maxCUSize
;
66 int marginX
= reconPic
->m_lumaMarginX
;
67 int marginY
= reconPic
->m_lumaMarginY
;
68 intptr_t stride
= reconPic
->m_stride
;
69 int cuHeight
= g_maxCUSize
;
71 for (int c
= 0; c
< numInterpPlanes
; c
++)
75 marginX
= reconPic
->m_chromaMarginX
;
76 marginY
= reconPic
->m_chromaMarginY
;
77 stride
= reconPic
->m_strideC
;
78 cuHeight
>>= reconPic
->m_vChromaShift
;
81 if (wp
[c
].bPresentFlag
)
85 size_t padheight
= (numCUinHeight
* cuHeight
) + marginY
* 2;
86 weightBuffer
[c
] = X265_MALLOC(pixel
, stride
* padheight
);
91 /* use our buffer which will have weighted pixels written to it */
92 fpelPlane
[c
] = weightBuffer
[c
] + marginY
* stride
+ marginX
;
93 X265_CHECK(recPic
->m_picOrg
[c
] - recPic
->m_picBuf
[c
] == marginY
* stride
+ marginX
, "PicYuv pad calculation mismatch\n");
95 w
[c
].weight
= wp
[c
].inputWeight
;
96 w
[c
].offset
= wp
[c
].inputOffset
* (1 << (X265_DEPTH
- 8));
97 w
[c
].shift
= wp
[c
].log2WeightDenom
;
98 w
[c
].round
= w
[c
].shift
? 1 << (w
[c
].shift
- 1) : 0;
108 void MotionReference::applyWeight(int finishedRows
, int maxNumRows
)
110 finishedRows
= X265_MIN(finishedRows
, maxNumRows
);
111 if (numWeightedRows
>= finishedRows
)
114 int marginX
= reconPic
->m_lumaMarginX
;
115 int marginY
= reconPic
->m_lumaMarginY
;
116 intptr_t stride
= reconPic
->m_stride
;
117 int width
= reconPic
->m_picWidth
;
118 int height
= (finishedRows
- numWeightedRows
) * g_maxCUSize
;
119 if (finishedRows
== maxNumRows
&& (reconPic
->m_picHeight
% g_maxCUSize
))
121 /* the last row may be partial height */
122 height
-= g_maxCUSize
;
123 height
+= reconPic
->m_picHeight
% g_maxCUSize
;
125 int cuHeight
= g_maxCUSize
;
127 for (int c
= 0; c
< numInterpPlanes
; c
++)
131 marginX
= reconPic
->m_chromaMarginX
;
132 marginY
= reconPic
->m_chromaMarginY
;
133 stride
= reconPic
->m_strideC
;
134 width
>>= reconPic
->m_hChromaShift
;
135 height
>>= reconPic
->m_vChromaShift
;
136 cuHeight
>>= reconPic
->m_vChromaShift
;
139 /* Do not generate weighted predictions if using original picture */
140 if (fpelPlane
[c
] == reconPic
->m_picOrg
[c
])
143 const pixel
* src
= reconPic
->m_picOrg
[c
] + numWeightedRows
* cuHeight
* stride
;
144 pixel
* dst
= fpelPlane
[c
] + numWeightedRows
* cuHeight
* stride
;
146 // Computing weighted CU rows
147 int correction
= IF_INTERNAL_PREC
- X265_DEPTH
; // intermediate interpolation depth
148 int padwidth
= (width
+ 15) & ~15; // weightp assembly needs even 16 byte widths
149 primitives
.weight_pp(src
, dst
, stride
, padwidth
, height
, w
[c
].weight
, w
[c
].round
<< correction
, w
[c
].shift
+ correction
, w
[c
].offset
);
151 // Extending Left & Right
152 primitives
.extendRowBorder(dst
, stride
, width
, height
, marginX
);
155 if (numWeightedRows
== 0)
157 pixel
*pixY
= fpelPlane
[c
] - marginX
;
158 for (int y
= 0; y
< marginY
; y
++)
159 memcpy(pixY
- (y
+ 1) * stride
, pixY
, stride
* sizeof(pixel
));
163 if (finishedRows
== maxNumRows
)
165 int picHeight
= reconPic
->m_picHeight
;
166 if (c
) picHeight
>>= reconPic
->m_vChromaShift
;
167 pixel
*pixY
= fpelPlane
[c
] - marginX
+ (picHeight
- 1) * stride
;
168 for (int y
= 0; y
< marginY
; y
++)
169 memcpy(pixY
+ (y
+ 1) * stride
, pixY
, stride
* sizeof(pixel
));
173 numWeightedRows
= finishedRows
;