Coverage Report

Created: 2026-03-08 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/x265/source/common/picyuv.cpp
Line
Count
Source
1
/*****************************************************************************
2
 * Copyright (C) 2013-2020 MulticoreWare, Inc
3
 *
4
 * Authors: Steve Borho <steve@borho.org>
5
 *          Min Chen <chenm003@163.com>
6
 *
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.
11
 *
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.
16
 *
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.
20
 *
21
 * This program is also available under a commercial proprietary license.
22
 * For more information, contact us at license @ x265.com.
23
 *****************************************************************************/
24
25
#include "common.h"
26
#include "picyuv.h"
27
#include "slice.h"
28
#include "primitives.h"
29
30
using namespace X265_NS;
31
32
PicYuv::PicYuv()
33
1.30k
{
34
1.30k
    m_picBuf[0] = NULL;
35
1.30k
    m_picBuf[1] = NULL;
36
1.30k
    m_picBuf[2] = NULL;
37
38
1.30k
    m_picOrg[0] = NULL;
39
1.30k
    m_picOrg[1] = NULL;
40
1.30k
    m_picOrg[2] = NULL;
41
42
1.30k
    m_cuOffsetY = NULL;
43
1.30k
    m_cuOffsetC = NULL;
44
1.30k
    m_buOffsetY = NULL;
45
1.30k
    m_buOffsetC = NULL;
46
47
1.30k
    m_maxLumaLevel = 0;
48
1.30k
    m_avgLumaLevel = 0;
49
50
1.30k
    m_maxChromaULevel = 0;
51
1.30k
    m_avgChromaULevel = 0;
52
53
1.30k
    m_maxChromaVLevel = 0;
54
1.30k
    m_avgChromaVLevel = 0;
55
56
#if (X265_DEPTH > 8)
57
    m_minLumaLevel = 0xFFFF;
58
    m_minChromaULevel = 0xFFFF;
59
    m_minChromaVLevel = 0xFFFF;
60
#else
61
1.30k
    m_minLumaLevel = 0xFF;
62
1.30k
    m_minChromaULevel = 0xFF;
63
1.30k
    m_minChromaVLevel = 0xFF;
64
1.30k
#endif
65
66
1.30k
    m_stride = 0;
67
1.30k
    m_strideC = 0;
68
1.30k
    m_hChromaShift = 0;
69
1.30k
    m_vChromaShift = 0;
70
1.30k
}
71
72
bool PicYuv::create(x265_param* param, bool picAlloc, pixel *pixelbuf)
73
1.30k
{
74
1.30k
    m_param = param;
75
1.30k
    uint32_t picWidth = m_param->sourceWidth;
76
1.30k
    uint32_t picHeight = m_param->sourceHeight;
77
1.30k
    uint32_t picCsp = m_param->internalCsp;
78
1.30k
    m_picWidth  = picWidth;
79
1.30k
    m_picHeight = picHeight;
80
1.30k
    m_hChromaShift = CHROMA_H_SHIFT(picCsp);
81
1.30k
    m_vChromaShift = CHROMA_V_SHIFT(picCsp);
82
1.30k
    m_picCsp = picCsp;
83
84
1.30k
    uint32_t numCuInWidth = (m_picWidth + param->maxCUSize - 1)  / param->maxCUSize;
85
1.30k
    uint32_t numCuInHeight = (m_picHeight + param->maxCUSize - 1) / param->maxCUSize;
86
87
1.30k
    m_lumaMarginX = param->maxCUSize + 32; // search margin and 8-tap filter half-length, padded for 32-byte alignment
88
1.30k
    m_lumaMarginY = param->maxCUSize + 16; // margin for 8-tap filter and infinite padding
89
1.30k
    m_stride = (numCuInWidth * param->maxCUSize) + (m_lumaMarginX << 1);
90
91
1.30k
    int maxHeight = numCuInHeight * param->maxCUSize;
92
1.30k
    if (pixelbuf)
93
0
        m_picOrg[0] = pixelbuf;
94
1.30k
    else
95
1.30k
    {
96
1.30k
        if (picAlloc)
97
1.30k
        {
98
1.30k
            CHECKED_MALLOC(m_picBuf[0], pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
99
1.30k
            m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
100
1.30k
        }
101
1.30k
    }
102
103
1.30k
    if (picCsp != X265_CSP_I400)
104
1.30k
    {
105
1.30k
        m_chromaMarginX = m_lumaMarginX;  // keep 16-byte alignment for chroma CTUs
106
1.30k
        m_chromaMarginY = m_lumaMarginY >> m_vChromaShift;
107
1.30k
        m_strideC = ((numCuInWidth * m_param->maxCUSize) >> m_hChromaShift) + (m_chromaMarginX * 2);
108
1.30k
        if (picAlloc)
109
1.30k
        {
110
1.30k
            CHECKED_MALLOC(m_picBuf[1], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
111
1.30k
            CHECKED_MALLOC(m_picBuf[2], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
112
113
1.30k
            m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC + m_chromaMarginX;
114
1.30k
            m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC + m_chromaMarginX;
115
1.30k
        }
116
1.30k
    }
117
0
    else
118
0
    {
119
0
        m_picBuf[1] = m_picBuf[2] = NULL;
120
0
        m_picOrg[1] = m_picOrg[2] = NULL;
121
0
    }
122
1.30k
    return true;
123
124
0
fail:
125
0
    this->destroy();
126
0
    return false;
127
1.30k
}
128
129
/*Copy pixels from the picture buffer of a frame to picture buffer of another frame*/
130
void PicYuv::copyFromFrame(PicYuv* source)
131
0
{
132
0
    uint32_t numCuInHeight = (m_picHeight + m_param->maxCUSize - 1) / m_param->maxCUSize;
133
134
0
    int maxHeight = numCuInHeight * m_param->maxCUSize;
135
0
    memcpy(m_picBuf[0], source->m_picBuf[0], sizeof(pixel)* m_stride * (maxHeight + (m_lumaMarginY * 2)));
136
0
    m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
137
138
0
    if (m_picCsp != X265_CSP_I400)
139
0
    {
140
0
        memcpy(m_picBuf[1], source->m_picBuf[1], sizeof(pixel)* m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
141
0
        memcpy(m_picBuf[2], source->m_picBuf[2], sizeof(pixel)* m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
142
143
0
        m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC + m_chromaMarginX;
144
0
        m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC + m_chromaMarginX;
145
0
    }
146
0
    else
147
0
    {
148
0
        m_picBuf[1] = m_picBuf[2] = NULL;
149
0
        m_picOrg[1] = m_picOrg[2] = NULL;
150
0
    }
151
0
}
152
153
bool PicYuv::createScaledPicYUV(x265_param* param, uint8_t scaleFactor)
154
0
{
155
0
    m_param = param;
156
0
    m_picWidth = m_param->sourceWidth / scaleFactor;
157
0
    m_picHeight = m_param->sourceHeight / scaleFactor;
158
0
    int maxBlocksInRow = (m_picWidth + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
159
0
    int maxBlocksInCol = (m_picHeight + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
160
0
    m_picWidth = maxBlocksInRow * X265_LOWRES_CU_SIZE;
161
0
    m_picHeight = maxBlocksInCol * X265_LOWRES_CU_SIZE;
162
163
0
    m_picCsp = m_param->internalCsp;
164
0
    m_hChromaShift = CHROMA_H_SHIFT(m_picCsp);
165
0
    m_vChromaShift = CHROMA_V_SHIFT(m_picCsp);
166
167
0
    uint32_t numCuInWidth = (m_picWidth + param->maxCUSize - 1) / param->maxCUSize;
168
0
    uint32_t numCuInHeight = (m_picHeight + param->maxCUSize - 1) / param->maxCUSize;
169
170
0
    m_lumaMarginX = 128; // search margin for L0 and L1 ME in horizontal direction
171
0
    m_lumaMarginY = 128; // search margin for L0 and L1 ME in vertical direction
172
0
    m_stride = (numCuInWidth * param->maxCUSize) + (m_lumaMarginX << 1);
173
174
0
    int maxHeight = numCuInHeight * param->maxCUSize;
175
0
    CHECKED_MALLOC_ZERO(m_picBuf[0], pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
176
0
    m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
177
0
    m_picBuf[1] = m_picBuf[2] = NULL;
178
0
    m_picOrg[1] = m_picOrg[2] = NULL;
179
0
    return true;
180
181
0
fail:
182
0
    return false;
183
0
}
184
185
int PicYuv::getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t picCsp)
186
0
{
187
0
    m_picWidth = picWidth;
188
0
    m_picHeight = picHeight;
189
0
    m_hChromaShift = CHROMA_H_SHIFT(picCsp);
190
0
    m_vChromaShift = CHROMA_V_SHIFT(picCsp);
191
0
    m_picCsp = picCsp;
192
193
0
    uint32_t numCuInWidth = (m_picWidth + m_param->maxCUSize - 1) / m_param->maxCUSize;
194
0
    uint32_t numCuInHeight = (m_picHeight + m_param->maxCUSize - 1) / m_param->maxCUSize;
195
196
0
    m_lumaMarginX = m_param->maxCUSize + 32; // search margin and 8-tap filter half-length, padded for 32-byte alignment
197
0
    m_lumaMarginY = m_param->maxCUSize + 16; // margin for 8-tap filter and infinite padding
198
0
    m_stride = (numCuInWidth * m_param->maxCUSize) + (m_lumaMarginX << 1);
199
200
0
    int maxHeight = numCuInHeight * m_param->maxCUSize;
201
0
    int bufLen = (int)(m_stride * (maxHeight + (m_lumaMarginY * 2)));
202
203
0
    return bufLen;
204
0
}
205
206
/* the first picture allocated by the encoder will be asked to generate these
207
 * offset arrays. Once generated, they will be provided to all future PicYuv
208
 * allocated by the same encoder. */
209
bool PicYuv::createOffsets(const SPS& sps)
210
654
{
211
654
    uint32_t numPartitions = 1 << (m_param->unitSizeDepth * 2);
212
213
654
    if (m_picCsp != X265_CSP_I400)
214
654
    {
215
654
        CHECKED_MALLOC(m_cuOffsetY, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
216
654
        CHECKED_MALLOC(m_cuOffsetC, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
217
3.93k
        for (uint32_t cuRow = 0; cuRow < sps.numCuInHeight; cuRow++)
218
3.27k
        {
219
16.9k
            for (uint32_t cuCol = 0; cuCol < sps.numCuInWidth; cuCol++)
220
13.7k
            {
221
13.7k
                m_cuOffsetY[cuRow * sps.numCuInWidth + cuCol] = m_stride * cuRow * m_param->maxCUSize + cuCol * m_param->maxCUSize;
222
13.7k
                m_cuOffsetC[cuRow * sps.numCuInWidth + cuCol] = m_strideC * cuRow * (m_param->maxCUSize >> m_vChromaShift) + cuCol * (m_param->maxCUSize >> m_hChromaShift);
223
13.7k
            }
224
3.27k
        }
225
226
654
        CHECKED_MALLOC(m_buOffsetY, intptr_t, (size_t)numPartitions);
227
654
        CHECKED_MALLOC(m_buOffsetC, intptr_t, (size_t)numPartitions);
228
117k
        for (uint32_t idx = 0; idx < numPartitions; ++idx)
229
116k
        {
230
116k
            intptr_t x = g_zscanToPelX[idx];
231
116k
            intptr_t y = g_zscanToPelY[idx];
232
116k
            m_buOffsetY[idx] = m_stride * y + x;
233
116k
            m_buOffsetC[idx] = m_strideC * (y >> m_vChromaShift) + (x >> m_hChromaShift);
234
116k
        }
235
654
    }
236
0
    else
237
0
    {
238
0
        CHECKED_MALLOC(m_cuOffsetY, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
239
0
        for (uint32_t cuRow = 0; cuRow < sps.numCuInHeight; cuRow++)
240
0
        for (uint32_t cuCol = 0; cuCol < sps.numCuInWidth; cuCol++)
241
0
            m_cuOffsetY[cuRow * sps.numCuInWidth + cuCol] = m_stride * cuRow * m_param->maxCUSize + cuCol * m_param->maxCUSize;
242
243
0
        CHECKED_MALLOC(m_buOffsetY, intptr_t, (size_t)numPartitions);
244
0
        for (uint32_t idx = 0; idx < numPartitions; ++idx)
245
0
        {
246
0
            intptr_t x = g_zscanToPelX[idx];
247
0
            intptr_t y = g_zscanToPelY[idx];
248
0
            m_buOffsetY[idx] = m_stride * y + x;
249
0
        }
250
0
    }
251
654
    return true;
252
253
0
fail:
254
0
    return false;
255
654
}
256
257
void PicYuv::destroy()
258
1.30k
{
259
5.23k
    for (int i = 0; i < MAX_NUM_COMPONENT; i++)
260
3.92k
    {
261
3.92k
        if (m_picBuf[i])
262
3.92k
        {
263
3.92k
            x265_free(m_picBuf[i]);
264
3.92k
            m_picBuf[i] = NULL;
265
3.92k
        }
266
3.92k
    }
267
1.30k
}
268
269
/* Copy pixels from an x265_picture into internal PicYuv instance.
270
 * Shift pixels as necessary, mask off bits above X265_DEPTH for safety. */
271
void PicYuv::copyFromPicture(const x265_picture& pic, const x265_param& param, int padx, int pady, bool isBase)
272
654
{
273
    /* m_picWidth is the width that is being encoded, padx indicates how many
274
     * of those pixels are padding to reach multiple of MinCU(4) size.
275
     *
276
     * Internally, we need to extend rows out to a multiple of 16 for lowres
277
     * downscale and other operations. But those padding pixels are never
278
     * encoded.
279
     *
280
     * The same applies to m_picHeight and pady */
281
282
    /* width and height - without padsize (input picture raw width and height) */
283
654
    int width = m_picWidth - padx;
284
654
    int height = m_picHeight - pady;
285
286
    /* internal pad to multiple of 16x16 blocks */
287
654
    uint8_t rem = width & 15;
288
289
654
    padx = rem ? 16 - rem : padx;
290
654
    rem = height & 15;
291
654
    pady = rem ? 16 - rem : pady;
292
293
    /* add one more row and col of pad for downscale interpolation, fixes
294
     * warnings from valgrind about using uninitialized pixels */
295
654
    padx++;
296
654
    pady++;
297
654
    m_picCsp = pic.colorSpace;
298
299
654
    X265_CHECK(pic.bitDepth >= 8, "pic.bitDepth check failure");
300
301
654
    uint64_t lumaSum;
302
654
    uint64_t cbSum;
303
654
    uint64_t crSum;
304
654
    lumaSum = cbSum = crSum = 0;
305
306
654
    if (m_param->bCopyPicToFrame)
307
654
    {
308
654
        if (pic.bitDepth == 8)
309
654
        {
310
#if (X265_DEPTH > 8)
311
        {
312
            pixel *yPixel = m_picOrg[0];
313
314
            uint8_t *yChar = (uint8_t*)pic.planes[0];
315
            int shift = (X265_DEPTH - 8);
316
317
            primitives.planecopy_cp(yChar, pic.stride[0] / sizeof(*yChar), yPixel, m_stride, width, height, shift);
318
319
            if (param.internalCsp != X265_CSP_I400)
320
            {
321
                pixel *uPixel = m_picOrg[1];
322
                pixel *vPixel = m_picOrg[2];
323
324
                uint8_t *uChar = (uint8_t*)pic.planes[1];
325
                uint8_t *vChar = (uint8_t*)pic.planes[2];
326
327
                primitives.planecopy_cp(uChar, pic.stride[1] / sizeof(*uChar), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift);
328
                primitives.planecopy_cp(vChar, pic.stride[2] / sizeof(*vChar), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift);
329
            }
330
        }
331
#else /* Case for (X265_DEPTH == 8) */
332
            // TODO: Does we need this path? may merge into above in future
333
654
        {
334
654
            if (isBase || param.numViews > 1)
335
654
            {
336
654
                int offsetX, offsetY;
337
654
                offsetX = (!isBase && pic.format == 1 ? width : 0);
338
654
                offsetY = (!isBase && pic.format == 2 ? pic.stride[0] * height : 0);
339
654
                pixel *yPixel = m_picOrg[0];
340
654
                uint8_t* yChar = (uint8_t*)pic.planes[0] + offsetX + offsetY;
341
342
112k
                for (int r = 0; r < height; r++)
343
112k
                {
344
112k
                    memcpy(yPixel, yChar, width * sizeof(pixel));
345
346
112k
                    yPixel += m_stride;
347
112k
                    yChar += pic.stride[0] / sizeof(*yChar);
348
112k
                }
349
350
654
                if (param.internalCsp != X265_CSP_I400)
351
654
                {
352
654
                    offsetX = offsetX >> m_hChromaShift;
353
654
                    int offsetYU = (!isBase && pic.format == 2 ? pic.stride[1] * (height >> m_vChromaShift) : 0);
354
654
                    int offsetYV = (!isBase && pic.format == 2 ? pic.stride[2] * (height >> m_vChromaShift) : 0);
355
356
654
                    pixel *uPixel = m_picOrg[1];
357
654
                    pixel *vPixel = m_picOrg[2];
358
359
654
                    uint8_t* uChar = (uint8_t*)pic.planes[1] + offsetX + offsetYU;
360
654
                    uint8_t* vChar = (uint8_t*)pic.planes[2] + offsetX + offsetYV;
361
362
56.7k
                    for (int r = 0; r < height >> m_vChromaShift; r++)
363
56.1k
                    {
364
56.1k
                        memcpy(uPixel, uChar, (width >> m_hChromaShift) * sizeof(pixel));
365
56.1k
                        memcpy(vPixel, vChar, (width >> m_hChromaShift) * sizeof(pixel));
366
367
56.1k
                        uPixel += m_strideC;
368
56.1k
                        vPixel += m_strideC;
369
56.1k
                        uChar += pic.stride[1] / sizeof(*uChar);
370
56.1k
                        vChar += pic.stride[2] / sizeof(*vChar);
371
56.1k
                    }
372
654
                }
373
654
            }
374
#if ENABLE_ALPHA
375
            if (!isBase && param.bEnableAlpha)
376
            {
377
                pixel* aPixel = m_picOrg[0];
378
                uint8_t* aChar = (uint8_t*)pic.planes[3];
379
380
                for (int r = 0; r < height; r++)
381
                {
382
                    memcpy(aPixel, aChar, width * sizeof(pixel));
383
384
                    aPixel += m_stride;
385
                    aChar += pic.stride[0] / sizeof(*aChar);
386
                }
387
388
                pixel* uPixel = m_picOrg[1];
389
                pixel* vPixel = m_picOrg[2];
390
391
                for (int r = 0; r < height >> m_vChromaShift; r++)
392
                {
393
                    memset(uPixel, 128, (width >> m_hChromaShift) * sizeof(pixel));
394
                    memset(vPixel, 128, (width >> m_hChromaShift) * sizeof(pixel));
395
396
                    uPixel += m_strideC;
397
                    vPixel += m_strideC;
398
                }
399
            }
400
#endif
401
654
        }
402
654
#endif /* (X265_DEPTH > 8) */
403
654
        }
404
0
        else /* pic.bitDepth > 8 */
405
0
        {
406
            /* defensive programming, mask off bits that are supposed to be zero */
407
0
            if (isBase)
408
0
            {
409
0
                uint16_t mask = (1 << X265_DEPTH) - 1;
410
0
                int shift = abs(pic.bitDepth - X265_DEPTH);
411
0
                pixel* yPixel = m_picOrg[0];
412
413
0
                uint16_t* yShort = (uint16_t*)pic.planes[0];
414
415
0
                if (pic.bitDepth > X265_DEPTH)
416
0
                {
417
                    /* shift right and mask pixels to final size */
418
0
                    primitives.planecopy_sp(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
419
0
                }
420
0
                else /* Case for (pic.bitDepth <= X265_DEPTH) */
421
0
                {
422
                    /* shift left and mask pixels to final size */
423
0
                    primitives.planecopy_sp_shl(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
424
0
                }
425
426
0
                if (param.internalCsp != X265_CSP_I400)
427
0
                {
428
0
                    pixel* uPixel = m_picOrg[1];
429
0
                    pixel* vPixel = m_picOrg[2];
430
431
0
                    uint16_t* uShort = (uint16_t*)pic.planes[1];
432
0
                    uint16_t* vShort = (uint16_t*)pic.planes[2];
433
434
0
                    if (pic.bitDepth > X265_DEPTH)
435
0
                    {
436
0
                        primitives.planecopy_sp(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
437
0
                        primitives.planecopy_sp(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
438
0
                    }
439
0
                    else /* Case for (pic.bitDepth <= X265_DEPTH) */
440
0
                    {
441
0
                        primitives.planecopy_sp_shl(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
442
0
                        primitives.planecopy_sp_shl(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
443
0
                    }
444
0
                }
445
0
            }
446
#if ENABLE_ALPHA
447
            if (!isBase && param.bEnableAlpha)
448
            {
449
                /* defensive programming, mask off bits that are supposed to be zero */
450
                uint16_t mask = (1 << X265_DEPTH) - 1;
451
                int shift = abs(pic.bitDepth - X265_DEPTH);
452
                pixel* yPixel = m_picOrg[0];
453
454
                uint16_t* yShort = (uint16_t*)pic.planes[3];
455
456
                if (pic.bitDepth > X265_DEPTH)
457
                {
458
                    /* shift right and mask pixels to final size */
459
                    primitives.planecopy_sp(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
460
                }
461
                else /* Case for (pic.bitDepth <= X265_DEPTH) */
462
                {
463
                    /* shift left and mask pixels to final size */
464
                    primitives.planecopy_sp_shl(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
465
                }
466
467
                if (param.internalCsp != X265_CSP_I400)
468
                {
469
                    pixel* uPixel = m_picOrg[1];
470
                    pixel* vPixel = m_picOrg[2];
471
472
                    for (int r = 0; r < height >> m_vChromaShift; r++)
473
                    {
474
                        for (int c = 0; c < (width >> m_hChromaShift); c++)
475
                        {
476
                            uPixel[c] = ((1 << X265_DEPTH) >> 1);
477
                            vPixel[c] = ((1 << X265_DEPTH) >> 1);
478
                        }
479
                        uPixel += m_strideC;
480
                        vPixel += m_strideC;
481
                    }
482
                }
483
            }
484
#endif
485
0
        }
486
654
    }
487
0
    else
488
0
    {
489
0
        m_picOrg[0] = (pixel*)pic.planes[0];
490
0
        m_picOrg[1] = (pixel*)pic.planes[1];
491
0
        m_picOrg[2] = (pixel*)pic.planes[2];
492
0
    }
493
494
654
    pixel *Y = m_picOrg[0];
495
654
    pixel *U = m_picOrg[1];
496
654
    pixel *V = m_picOrg[2];
497
498
654
    pixel *yPic = m_picOrg[0];
499
654
    pixel *uPic = m_picOrg[1];
500
654
    pixel *vPic = m_picOrg[2];
501
502
654
    if(param.minLuma != 0 || param.maxLuma != PIXEL_MAX)
503
0
    {
504
0
        for (int r = 0; r < height; r++)
505
0
        {
506
0
            for (int c = 0; c < width; c++)
507
0
            {
508
0
                yPic[c] = X265_MIN(yPic[c], (pixel)param.maxLuma);
509
0
                yPic[c] = X265_MAX(yPic[c], (pixel)param.minLuma);
510
0
            }
511
0
            yPic += m_stride;
512
0
        }
513
0
    }
514
654
    yPic = m_picOrg[0];
515
654
    if (param.csvLogLevel >= 2 || param.maxCLL || param.maxFALL)
516
0
    {
517
0
        for (int r = 0; r < height; r++)
518
0
        {
519
0
            for (int c = 0; c < width; c++)
520
0
            {
521
0
                m_maxLumaLevel = X265_MAX(yPic[c], m_maxLumaLevel);
522
0
                m_minLumaLevel = X265_MIN(yPic[c], m_minLumaLevel);
523
0
                lumaSum += yPic[c];
524
0
            }
525
0
            yPic += m_stride;
526
0
        }
527
0
        m_avgLumaLevel = (double)lumaSum / (m_picHeight * m_picWidth);
528
0
    }
529
654
    if (param.csvLogLevel >= 2)
530
0
    {
531
0
        if (param.internalCsp != X265_CSP_I400)
532
0
        {
533
0
            for (int r = 0; r < height >> m_vChromaShift; r++)
534
0
            {
535
0
                for (int c = 0; c < width >> m_hChromaShift; c++)
536
0
                {
537
0
                    m_maxChromaULevel = X265_MAX(uPic[c], m_maxChromaULevel);
538
0
                    m_minChromaULevel = X265_MIN(uPic[c], m_minChromaULevel);
539
0
                    cbSum += uPic[c];
540
541
0
                    m_maxChromaVLevel = X265_MAX(vPic[c], m_maxChromaVLevel);
542
0
                    m_minChromaVLevel = X265_MIN(vPic[c], m_minChromaVLevel);
543
0
                    crSum += vPic[c];
544
0
                }
545
546
0
                uPic += m_strideC;
547
0
                vPic += m_strideC;
548
0
            }
549
0
            m_avgChromaULevel = (double)cbSum / ((height >> m_vChromaShift) * (width >> m_hChromaShift));
550
0
            m_avgChromaVLevel = (double)crSum / ((height >> m_vChromaShift) * (width >> m_hChromaShift));
551
0
        }
552
0
    }
553
554
#if HIGH_BIT_DEPTH
555
    bool calcHDRParams = !!param.minLuma || (param.maxLuma != PIXEL_MAX);
556
    /* Apply min/max luma bounds for HDR pixel manipulations */
557
    if (calcHDRParams)
558
    {
559
        X265_CHECK(pic.bitDepth == 10, "HDR stats can be applied/calculated only for 10bpp content");
560
        uint64_t sumLuma;
561
        m_maxLumaLevel = primitives.planeClipAndMax(Y, m_stride, width, height, &sumLuma, (pixel)param.minLuma, (pixel)param.maxLuma);
562
        m_avgLumaLevel = (double) sumLuma / (m_picHeight * m_picWidth);
563
    }
564
#else
565
654
    (void) param;
566
654
#endif
567
568
    /* extend the right edge if width was not multiple of the minimum CU size */
569
112k
    for (int r = 0; r < height; r++)
570
112k
    {
571
811k
        for (int x = 0; x < padx; x++)
572
698k
            Y[width + x] = Y[width - 1];
573
112k
        Y += m_stride;
574
112k
    }
575
576
    /* extend the bottom if height was not multiple of the minimum CU size */
577
654
    Y = m_picOrg[0] + (height - 1) * m_stride;
578
4.97k
    for (int i = 1; i <= pady; i++)
579
4.32k
        memcpy(Y + i * m_stride, Y, (width + padx) * sizeof(pixel));
580
581
654
    if (param.internalCsp != X265_CSP_I400)
582
654
    {
583
56.7k
        for (int r = 0; r < height >> m_vChromaShift; r++)
584
56.1k
        {
585
202k
            for (int x = 0; x < padx >> m_hChromaShift; x++)
586
146k
            {
587
146k
                U[(width >> m_hChromaShift) + x] = U[(width >> m_hChromaShift) - 1];
588
146k
                V[(width >> m_hChromaShift) + x] = V[(width >> m_hChromaShift) - 1];
589
146k
            }
590
591
56.1k
            U += m_strideC;
592
56.1k
            V += m_strideC;
593
56.1k
        }
594
595
654
        U = m_picOrg[1] + ((height >> m_vChromaShift) - 1) * m_strideC;
596
654
        V = m_picOrg[2] + ((height >> m_vChromaShift) - 1) * m_strideC;
597
598
2.48k
        for (int j = 1; j <= pady >> m_vChromaShift; j++)
599
1.83k
        {
600
1.83k
            memcpy(U + j * m_strideC, U, ((width + padx) >> m_hChromaShift) * sizeof(pixel));
601
1.83k
            memcpy(V + j * m_strideC, V, ((width + padx) >> m_hChromaShift) * sizeof(pixel));
602
1.83k
        }
603
654
    }
604
654
}
605
606
namespace X265_NS {
607
608
template<uint32_t OUTPUT_BITDEPTH_DIV8>
609
static void md5_block(MD5Context& md5, const pixel* plane, uint32_t n)
610
0
{
611
    /* create a 64 byte buffer for packing pixel's into */
612
0
    uint8_t buf[64 / OUTPUT_BITDEPTH_DIV8][OUTPUT_BITDEPTH_DIV8];
613
614
0
    for (uint32_t i = 0; i < n; i++)
615
0
    {
616
0
        pixel pel = plane[i];
617
        /* perform bitdepth and endian conversion */
618
0
        for (uint32_t d = 0; d < OUTPUT_BITDEPTH_DIV8; d++)
619
0
            buf[i][d] = (uint8_t)(pel >> (d * 8));
620
0
    }
621
622
0
    MD5Update(&md5, (uint8_t*)buf, n * OUTPUT_BITDEPTH_DIV8);
623
0
}
Unexecuted instantiation: picyuv.cpp:void x265::md5_block<1u>(x265::MD5Context&, unsigned char const*, unsigned int)
Unexecuted instantiation: picyuv.cpp:void x265::md5_block<2u>(x265::MD5Context&, unsigned char const*, unsigned int)
624
625
/* Update md5 with all samples in plane in raster order, each sample
626
 * is adjusted to OUTBIT_BITDEPTH_DIV8 */
627
template<uint32_t OUTPUT_BITDEPTH_DIV8>
628
static void md5_plane(MD5Context& md5, const pixel* plane, uint32_t width, uint32_t height, intptr_t stride)
629
0
{
630
    /* N is the number of samples to process per md5 update.
631
     * All N samples must fit in buf */
632
0
    uint32_t N = 32;
633
0
    uint32_t width_modN = width % N;
634
0
    uint32_t width_less_modN = width - width_modN;
635
636
0
    for (uint32_t y = 0; y < height; y++)
637
0
    {
638
        /* convert pel's into uint32_t chars in little endian byte order.
639
         * NB, for 8bit data, data is truncated to 8bits. */
640
0
        for (uint32_t x = 0; x < width_less_modN; x += N)
641
0
            md5_block<OUTPUT_BITDEPTH_DIV8>(md5, &plane[y * stride + x], N);
642
643
        /* mop up any of the remaining line */
644
0
        md5_block<OUTPUT_BITDEPTH_DIV8>(md5, &plane[y * stride + width_less_modN], width_modN);
645
0
    }
646
0
}
Unexecuted instantiation: picyuv.cpp:void x265::md5_plane<1u>(x265::MD5Context&, unsigned char const*, unsigned int, unsigned int, long)
Unexecuted instantiation: picyuv.cpp:void x265::md5_plane<2u>(x265::MD5Context&, unsigned char const*, unsigned int, unsigned int, long)
647
648
void updateCRC(const pixel* plane, uint32_t& crcVal, uint32_t height, uint32_t width, intptr_t stride)
649
0
{
650
0
    uint32_t crcMsb;
651
0
    uint32_t bitVal;
652
0
    uint32_t bitIdx;
653
654
0
    for (uint32_t y = 0; y < height; y++)
655
0
    {
656
0
        for (uint32_t x = 0; x < width; x++)
657
0
        {
658
            // take CRC of first pictureData byte
659
0
            for (bitIdx = 0; bitIdx < 8; bitIdx++)
660
0
            {
661
0
                crcMsb = (crcVal >> 15) & 1;
662
0
                bitVal = (plane[y * stride + x] >> (7 - bitIdx)) & 1;
663
0
                crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021);
664
0
            }
665
666
#if _MSC_VER
667
#pragma warning(disable: 4127) // conditional expression is constant
668
#endif
669
            // take CRC of second pictureData byte if bit depth is greater than 8-bits
670
0
            if (X265_DEPTH > 8)
671
0
            {
672
0
                for (bitIdx = 0; bitIdx < 8; bitIdx++)
673
0
                {
674
0
                    crcMsb = (crcVal >> 15) & 1;
675
0
                    bitVal = (plane[y * stride + x] >> (15 - bitIdx)) & 1;
676
0
                    crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021);
677
0
                }
678
0
            }
679
0
        }
680
0
    }
681
0
}
682
683
void crcFinish(uint32_t& crcVal, uint8_t digest[16])
684
0
{
685
0
    uint32_t crcMsb;
686
687
0
    for (int bitIdx = 0; bitIdx < 16; bitIdx++)
688
0
    {
689
0
        crcMsb = (crcVal >> 15) & 1;
690
0
        crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021);
691
0
    }
692
693
0
    digest[0] = (crcVal >> 8)  & 0xff;
694
0
    digest[1] =  crcVal        & 0xff;
695
0
}
696
697
void updateChecksum(const pixel* plane, uint32_t& checksumVal, uint32_t height, uint32_t width, intptr_t stride, int row, uint32_t cuHeight)
698
0
{
699
0
    uint8_t xor_mask;
700
701
0
    for (uint32_t y = row * cuHeight; y < ((row * cuHeight) + height); y++)
702
0
    {
703
0
        for (uint32_t x = 0; x < width; x++)
704
0
        {
705
0
            xor_mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
706
0
            checksumVal = (checksumVal + ((plane[y * stride + x] & 0xff) ^ xor_mask)) & 0xffffffff;
707
708
0
            if (X265_DEPTH > 8)
709
0
                checksumVal = (checksumVal + ((plane[y * stride + x] >> 7 >> 1) ^ xor_mask)) & 0xffffffff;
710
0
        }
711
0
    }
712
0
}
713
714
void checksumFinish(uint32_t checksum, uint8_t digest[16])
715
0
{
716
0
    digest[0] = (checksum >> 24) & 0xff;
717
0
    digest[1] = (checksum >> 16) & 0xff;
718
0
    digest[2] = (checksum >> 8)  & 0xff;
719
0
    digest[3] =  checksum        & 0xff;
720
0
}
721
722
void updateMD5Plane(MD5Context& md5, const pixel* plane, uint32_t width, uint32_t height, intptr_t stride)
723
0
{
724
    /* choose an md5_plane packing function based on the system bitdepth */
725
0
    typedef void(*MD5PlaneFunc)(MD5Context&, const pixel*, uint32_t, uint32_t, intptr_t);
726
0
    MD5PlaneFunc md5_plane_func;
727
0
    md5_plane_func = X265_DEPTH <= 8 ? (MD5PlaneFunc)md5_plane<1> : (MD5PlaneFunc)md5_plane<2>;
728
729
0
    md5_plane_func(md5, plane, width, height, stride);
730
0
}
731
}