1 /***************************************************************************** 2 * Copyright (C) 2013 x265 project 3 * 4 * Authors: Gopu Govindaswamy <gopu@multicorewareinc.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. 19 * 20 * This program is also available under a commercial proprietary license. 21 * For more information, contact us at license @ x265.com. 22 *****************************************************************************/ 23 24 #ifndef X265_LOWRES_H 25 #define X265_LOWRES_H 26 27 #include "primitives.h" 28 #include "common.h" 29 #include "picyuv.h" 30 #include "mv.h" 31 32 namespace X265_NS { 33 // private namespace 34 35 struct ReferencePlanes 36 { ReferencePlanesReferencePlanes37 ReferencePlanes() { memset(this, 0, sizeof(ReferencePlanes)); } 38 39 pixel* fpelPlane[3]; 40 pixel* lowresPlane[4]; 41 PicYuv* reconPic; 42 43 bool isWeighted; 44 bool isLowres; 45 46 intptr_t lumaStride; 47 intptr_t chromaStride; 48 49 struct { 50 int weight; 51 int offset; 52 int shift; 53 int round; 54 } w[3]; 55 getLumaAddrReferencePlanes56 pixel* getLumaAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[0] + reconPic->m_cuOffsetY[ctuAddr] + reconPic->m_buOffsetY[absPartIdx]; } getCbAddrReferencePlanes57 pixel* getCbAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[1] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; } getCrAddrReferencePlanes58 pixel* getCrAddr(uint32_t ctuAddr, uint32_t absPartIdx) { return fpelPlane[2] + reconPic->m_cuOffsetC[ctuAddr] + reconPic->m_buOffsetC[absPartIdx]; } 59 60 /* lowres motion compensation, you must provide a buffer and stride for QPEL averaged pixels 61 * in case QPEL is required. Else it returns a pointer to the HPEL pixels */ lowresMCReferencePlanes62 inline pixel *lowresMC(intptr_t blockOffset, const MV& qmv, pixel *buf, intptr_t& outstride) 63 { 64 if ((qmv.x | qmv.y) & 1) 65 { 66 int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1); 67 pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; 68 int qmvx = qmv.x + (qmv.x & 1); 69 int qmvy = qmv.y + (qmv.y & 1); 70 int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1); 71 pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride; 72 primitives.pu[LUMA_8x8].pixelavg_pp(buf, outstride, frefA, lumaStride, frefB, lumaStride, 32); 73 return buf; 74 } 75 else 76 { 77 outstride = lumaStride; 78 int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1); 79 return lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; 80 } 81 } 82 lowresQPelCostReferencePlanes83 inline int lowresQPelCost(pixel *fenc, intptr_t blockOffset, const MV& qmv, pixelcmp_t comp) 84 { 85 if ((qmv.x | qmv.y) & 1) 86 { 87 ALIGN_VAR_16(pixel, subpelbuf[8 * 8]); 88 int hpelA = (qmv.y & 2) | ((qmv.x & 2) >> 1); 89 pixel *frefA = lowresPlane[hpelA] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; 90 int qmvx = qmv.x + (qmv.x & 1); 91 int qmvy = qmv.y + (qmv.y & 1); 92 int hpelB = (qmvy & 2) | ((qmvx & 2) >> 1); 93 pixel *frefB = lowresPlane[hpelB] + blockOffset + (qmvx >> 2) + (qmvy >> 2) * lumaStride; 94 primitives.pu[LUMA_8x8].pixelavg_pp(subpelbuf, 8, frefA, lumaStride, frefB, lumaStride, 32); 95 return comp(fenc, FENC_STRIDE, subpelbuf, 8); 96 } 97 else 98 { 99 int hpel = (qmv.y & 2) | ((qmv.x & 2) >> 1); 100 pixel *fref = lowresPlane[hpel] + blockOffset + (qmv.x >> 2) + (qmv.y >> 2) * lumaStride; 101 return comp(fenc, FENC_STRIDE, fref, lumaStride); 102 } 103 } 104 }; 105 106 /* lowres buffers, sizes and strides */ 107 struct Lowres : public ReferencePlanes 108 { 109 pixel *buffer[4]; 110 111 int frameNum; // Presentation frame number 112 int sliceType; // Slice type decided by lookahead 113 int width; // width of lowres frame in pixels 114 int lines; // height of lowres frame in pixel lines 115 int leadingBframes; // number of leading B frames for P or I 116 117 bool bScenecut; // Set to false if the frame cannot possibly be part of a real scenecut. 118 bool bKeyframe; 119 bool bLastMiniGopBFrame; 120 121 /* lookahead output data */ 122 int64_t costEst[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; 123 int64_t costEstAq[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; 124 int32_t* rowSatds[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]; 125 int intraMbs[X265_BFRAME_MAX + 2]; 126 int32_t* intraCost; 127 uint8_t* intraMode; 128 int64_t satdCost; 129 uint16_t* lowresCostForRc; 130 uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]); 131 int32_t* lowresMvCosts[2][X265_BFRAME_MAX + 1]; 132 MV* lowresMvs[2][X265_BFRAME_MAX + 1]; 133 uint32_t maxBlocksInRow; 134 uint32_t maxBlocksInCol; 135 136 /* used for vbvLookahead */ 137 int plannedType[X265_LOOKAHEAD_MAX + 1]; 138 int64_t plannedSatd[X265_LOOKAHEAD_MAX + 1]; 139 int indB; 140 int bframes; 141 142 /* rate control / adaptive quant data */ 143 double* qpAqOffset; // AQ QP offset values for each 16x16 CU 144 double* qpCuTreeOffset; // cuTree QP offset values for each 16x16 CU 145 int* invQscaleFactor; // qScale values for qp Aq Offsets 146 uint64_t wp_ssd[3]; // This is different than SSDY, this is sum(pixel^2) - sum(pixel)^2 for entire frame 147 uint64_t wp_sum[3]; 148 149 /* cutree intermediate data */ 150 uint16_t* propagateCost; 151 double weightedCostDelta[X265_BFRAME_MAX + 2]; 152 153 bool create(PicYuv *origPic, int _bframes, bool bAqEnabled); 154 void destroy(); 155 void init(PicYuv *origPic, int poc); 156 }; 157 } 158 159 #endif // ifndef X265_LOWRES_H 160