History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

Showing the changes to codec/encoder/core/src/svc_encode_mb.cpp (1 of 308 files). Show all

Unified · Split

codec/encoder/core/src/svc_encode_mb.cpp+413−0
@@ -0,0 +1,413 @@
1/*!
2 * \copy
3 * Copyright (c) 2009-2013, Cisco Systems
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *
32 * \file encode_mb.c
33 *
34 * \brief Implementaion for pCurMb encoding
35 *
36 * \date 05/19/2009 Created
37 *************************************************************************************
38 */
39
40#include <stdio.h> //test use for file operation
41#include <string.h>
42
43#include "svc_encode_mb.h"
44#include "encode_mb_aux.h"
45#include "decode_mb_aux.h"
46#include "ls_defines.h"
47#include "cpu_core.h"
48#include "as264_common.h"
49#include "mb_cache.h"
50#include "array_stack_align.h"
51
52namespace WelsSVCEnc {
53void WelsDctMb(int16_t* pRes, uint8_t* pEncMb, int32_t iEncStride, uint8_t* pBestPred, PDctFunc pfDctFourT4)
54{
55 pfDctFourT4(pRes, pEncMb, iEncStride, pBestPred, 16);
56 pfDctFourT4(pRes + 64, pEncMb + 8, iEncStride, pBestPred + 8, 16);
57 pfDctFourT4(pRes + 128, pEncMb + 8 * iEncStride, iEncStride, pBestPred + 128, 16);
58 pfDctFourT4(pRes + 192, pEncMb + 8 * iEncStride + 8, iEncStride, pBestPred + 136, 16);
59}
60
61void WelsEncRecI16x16Y(sWelsEncCtx *pEncCtx, SMB *pCurMb, SMbCache *pMbCache)
62{
63 ENFORCE_STACK_ALIGN_1D(int16_t, aDctT4Dc, 16, 16)
64 SWelsFuncPtrList *pFuncList = pEncCtx->pFuncList;
65 SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
66 const int32_t kiEncStride = pCurDqLayer->iEncStride[0];
67 int16_t *pRes = pMbCache->pCoeffLevel;
68 uint8_t *pPred = pMbCache->SPicData.pCsMb[0];
69 const int32_t kiRecStride = pCurDqLayer->iCsStride[0];
70 int16_t *pBlock = pMbCache->pDct->iLumaBlock[0];
71 uint8_t *pBestPred = pMbCache->pMemPredLuma;
72 const uint8_t* kpNoneZeroCountIdx = &g_kuiMbCountScan4Idx[0];
73 uint8_t i, uiQp = pCurMb->uiLumaQp;
74 uint32_t uiNoneZeroCount, uiNoneZeroCountMbAc = 0, uiCountI16x16Dc;
75
76 int16_t* pMF = g_kiQuantMF[uiQp], *pFF = g_iQuantIntraFF[uiQp];
77
78 WelsDctMb(pRes, pMbCache->SPicData.pEncMb[0], kiEncStride, pBestPred, pEncCtx->pFuncList->pfDctFourT4);
79
80 pFuncList->pfTransformHadamard4x4Dc(aDctT4Dc, pRes);
81 pFuncList->pfQuantizationDc4x4( aDctT4Dc, pFF[0]<<1, pMF[0]>>1);
82 pFuncList->pfScan4x4( pMbCache->pDct->iLumaI16x16Dc, aDctT4Dc);
83 uiCountI16x16Dc = pFuncList->pfGetNoneZeroCount(pMbCache->pDct->iLumaI16x16Dc);
84
85 for(i = 0; i < 4; i++)
86 {
87 pFuncList->pfQuantizationFour4x4(pRes, pFF, pMF);
88 pFuncList->pfScan4x4Ac(pBlock, pRes );
89 pFuncList->pfScan4x4Ac(pBlock + 16, pRes + 16 );
90 pFuncList->pfScan4x4Ac(pBlock + 32, pRes + 32 );
91 pFuncList->pfScan4x4Ac(pBlock + 48, pRes + 48 );
92 pRes += 64;
93 pBlock += 64;
94 }
95 pRes -= 256;
96 pBlock -= 256;
97
98 for(i=0; i<16; i++) {
99 uiNoneZeroCount = pFuncList->pfGetNoneZeroCount(pBlock);
100 pCurMb->pNonZeroCount[*kpNoneZeroCountIdx++] = uiNoneZeroCount;
101 uiNoneZeroCountMbAc += uiNoneZeroCount;
102 pBlock += 16;
103 }
104
105 if( uiCountI16x16Dc > 0 ){
106 if(uiQp < 12)
107 {
108 WelsIHadamard4x4Dc(aDctT4Dc);
109 WelsDequantLumaDc4x4(aDctT4Dc, uiQp);
110 }
111 else
112 pFuncList->pfDequantizationIHadamard4x4(aDctT4Dc, g_kuiDequantCoeff[uiQp][0]>>2);
113 }
114
115 if( uiNoneZeroCountMbAc > 0 )
116 {
117 pCurMb->uiCbp = 15;
118 pFuncList->pfDequantizationFour4x4(pRes, g_kuiDequantCoeff[uiQp]);
119 pFuncList->pfDequantizationFour4x4(pRes+64, g_kuiDequantCoeff[uiQp]);
120 pFuncList->pfDequantizationFour4x4(pRes+128, g_kuiDequantCoeff[uiQp]);
121 pFuncList->pfDequantizationFour4x4(pRes+192, g_kuiDequantCoeff[uiQp]);
122
123 pRes[0] = aDctT4Dc[0]; pRes[16] = aDctT4Dc[1];
124 pRes[32] = aDctT4Dc[4]; pRes[48] = aDctT4Dc[5];
125 pRes[64] = aDctT4Dc[2]; pRes[80] = aDctT4Dc[3];
126 pRes[96] = aDctT4Dc[6]; pRes[112]= aDctT4Dc[7];
127 pRes[128]= aDctT4Dc[8]; pRes[144]= aDctT4Dc[9];
128 pRes[160]= aDctT4Dc[12]; pRes[176]= aDctT4Dc[13];
129 pRes[192]= aDctT4Dc[10]; pRes[208]= aDctT4Dc[11];
130 pRes[224]= aDctT4Dc[14]; pRes[240]= aDctT4Dc[15];
131
132 pFuncList->pfIDctFourT4(pPred, kiRecStride, pBestPred, 16, pRes );
133 pFuncList->pfIDctFourT4(pPred + 8, kiRecStride, pBestPred + 8, 16, pRes + 64 );
134 pFuncList->pfIDctFourT4(pPred + kiRecStride*8, kiRecStride, pBestPred + 128, 16, pRes + 128);
135 pFuncList->pfIDctFourT4(pPred + kiRecStride*8 + 8, kiRecStride, pBestPred + 136, 16, pRes + 192);
136 }
137 else if( uiCountI16x16Dc > 0 ){
138 pFuncList->pfIDctI16x16Dc(pPred, kiRecStride, pBestPred, 16, aDctT4Dc);
139 }
140 else{
141 pFuncList->pfCopy16x16Aligned(pPred, kiRecStride, pBestPred, 16);
142 }
143}
144void WelsEncRecI4x4Y( sWelsEncCtx *pEncCtx, SMB *pCurMb, SMbCache *pMbCache, uint8_t uiI4x4Idx)
145{
146 SWelsFuncPtrList *pFuncList = pEncCtx->pFuncList;
147 SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
148 int32_t iEncStride = pCurDqLayer->iEncStride[0];
149 uint8_t uiQp = pCurMb->uiLumaQp;
150
151 int16_t *pResI4x4 = pMbCache->pCoeffLevel;
152 uint8_t *pPredI4x4;
153
154 uint8_t *pPred = pMbCache->SPicData.pCsMb[0];
155 int32_t iRecStride = pCurDqLayer->iCsStride[0];
156
157 uint32_t uiOffset = g_kuiMbCountScan4Idx[uiI4x4Idx];
158 uint8_t* pEncMb = pMbCache->SPicData.pEncMb[0];
159 uint8_t *pBestPred = pMbCache->pBestPredI4x4Blk4;
160 int16_t* pBlock = pMbCache->pDct->iLumaBlock[uiI4x4Idx];
161
162 int16_t *pMF = g_kiQuantMF[uiQp], *pFF = g_iQuantIntraFF[uiQp];
163
164 int32_t *pStrideEncBlockOffset = pEncCtx->pStrideTab->pStrideEncBlockOffset[pEncCtx->uiDependencyId];
165 int32_t *pStrideDecBlockOffset = pEncCtx->pStrideTab->pStrideDecBlockOffset[pEncCtx->uiDependencyId][0==pEncCtx->uiTemporalId];
166 int32_t iNoneZeroCount = 0;
167
168 pFuncList->pfDctT4( pResI4x4, &(pEncMb[pStrideEncBlockOffset[uiI4x4Idx]]), iEncStride, pBestPred, 4 );
169 pFuncList->pfQuantization4x4(pResI4x4, pFF, pMF);
170 pFuncList->pfScan4x4(pBlock, pResI4x4);
171
172 iNoneZeroCount = pFuncList->pfGetNoneZeroCount(pBlock);
173 pCurMb->pNonZeroCount[uiOffset] = iNoneZeroCount;
174
175 pPredI4x4 = pPred + pStrideDecBlockOffset[uiI4x4Idx];
176 if ( iNoneZeroCount > 0 )
177 {
178 pCurMb->uiCbp |= 1 << (uiI4x4Idx>>2);
179 pFuncList->pfDequantization4x4( pResI4x4, g_kuiDequantCoeff[uiQp]);
180 pFuncList->pfIDctT4(pPredI4x4, iRecStride, pBestPred, 4, pResI4x4);
181 }
182 else
183 WelsCopy4x4(pPredI4x4, iRecStride, pBestPred, 4);
184}
185
186void WelsEncInterY(SWelsFuncPtrList *pFuncList, SMB * pCurMb, SMbCache *pMbCache)
187{
188 PQuantizationMaxFunc pfQuantizationFour4x4Max = pFuncList->pfQuantizationFour4x4Max;
189 PSetMemoryZero pfSetMemZeroSize8 = pFuncList->pfSetMemZeroSize8;
190 PSetMemoryZero pfSetMemZeroSize64 = pFuncList->pfSetMemZeroSize64;
191 PScanFunc pfScan4x4 = pFuncList->pfScan4x4;
192 PCalculateSingleCtrFunc pfCalculateSingleCtr4x4 = pFuncList->pfCalculateSingleCtr4x4;
193 PGetNoneZeroCountFunc pfGetNoneZeroCount = pFuncList->pfGetNoneZeroCount;
194 PDeQuantizationFunc pfDequantizationFour4x4 = pFuncList->pfDequantizationFour4x4;
195 int16_t *pRes = pMbCache->pCoeffLevel;
196 int32_t iSingleCtrMb = 0, iSingleCtr8x8[4];
197 int16_t* pBlock = pMbCache->pDct->iLumaBlock[0];
198 uint8_t uiQp = pCurMb->uiLumaQp;
199 int16_t *pMF = g_kiQuantMF[uiQp], *pFF = g_kiQuantInterFF[uiQp], aMax[16];
200 int32_t i, j, iNoneZeroCountMbDcAc = 0, iNoneZeroCount=0;
201
202 for(i = 0; i < 4; i++)
203 {
204 pfQuantizationFour4x4Max(pRes, pFF, pMF, aMax+(i<<2));
205 iSingleCtr8x8[i] = 0;
206 for(j = 0; j < 4; j++)
207 {
208 if(aMax[(i<<2)+j] == 0)
209 pfSetMemZeroSize8(pBlock, 32);
210 else
211 {
212 pfScan4x4(pBlock, pRes);
213 if(aMax[(i<<2)+j] > 1)
214 iSingleCtr8x8[i] += 9;
215 else if(iSingleCtr8x8[i] < 6)
216 iSingleCtr8x8[i] += pfCalculateSingleCtr4x4(pBlock);
217 }
218 pRes += 16;
219 pBlock += 16;
220 }
221 iSingleCtrMb += iSingleCtr8x8[i];
222 }
223 pBlock -= 256;
224 pRes -= 256;
225
226 memset(pCurMb->pNonZeroCount, 0, 16);
227
228
229 if( iSingleCtrMb < 6 ) //from JVT-O079
230 {
231 iNoneZeroCountMbDcAc = 0;
232 pfSetMemZeroSize64( pRes, 768 ); // confirmed_safe_unsafe_usage
233 }
234 else
235 {
236 const uint8_t* kpNoneZeroCountIdx = g_kuiMbCountScan4Idx;
237 for(i = 0; i < 4; i++)
238 {
239 if( iSingleCtr8x8[i] >= 4 ){
240 for( j = 0; j < 4; j++ ){
241 iNoneZeroCount = pfGetNoneZeroCount(pBlock);
242 pCurMb->pNonZeroCount[*kpNoneZeroCountIdx++] = iNoneZeroCount;
243 iNoneZeroCountMbDcAc += iNoneZeroCount;
244 pBlock += 16;
245 }
246 pfDequantizationFour4x4(pRes, g_kuiDequantCoeff[uiQp]);
247 pCurMb->uiCbp |= 1 << i;
248 }
249 else { // set zero for an 8x8 pBlock
250 pfSetMemZeroSize64(pRes, 128); // confirmed_safe_unsafe_usage
251 kpNoneZeroCountIdx += 4;
252 pBlock += 64;
253 }
254 pRes += 64;
255 }
256 }
257}
258
259void WelsEncRecUV(SWelsFuncPtrList *pFuncList, SMB * pCurMb, SMbCache *pMbCache, int16_t * pRes, int32_t iUV)
260{
261 PQuantizationHadamardFunc pfQuantizationHadamard2x2 = pFuncList->pfQuantizationHadamard2x2;
262 PQuantizationMaxFunc pfQuantizationFour4x4Max = pFuncList->pfQuantizationFour4x4Max;
263 PSetMemoryZero pfSetMemZeroSize8 = pFuncList->pfSetMemZeroSize8;
264 PSetMemoryZero pfSetMemZeroSize64 = pFuncList->pfSetMemZeroSize64;
265 PScanFunc pfScan4x4Ac = pFuncList->pfScan4x4Ac;
266 PCalculateSingleCtrFunc pfCalculateSingleCtr4x4 = pFuncList->pfCalculateSingleCtr4x4;
267 PGetNoneZeroCountFunc pfGetNoneZeroCount = pFuncList->pfGetNoneZeroCount;
268 PDeQuantizationFunc pfDequantizationFour4x4 = pFuncList->pfDequantizationFour4x4;
269 const int32_t kiInterFlag = !IS_INTRA( pCurMb->uiMbType);
270 const uint8_t kiQp = pCurMb->uiChromaQp;
271 uint8_t i, uiNoneZeroCount, uiNoneZeroCountMbAc = 0, uiNoneZeroCountMbDc = 0;
272 uint8_t uiNoneZeroCountOffset = (iUV - 1)<<1; //UV==1 or 2
273 uint8_t uiSubMbIdx = 16 + ((iUV - 1)<<2); //uiSubMbIdx == 16 or 20
274 int16_t* iChromaDc = pMbCache->pDct->iChromaDc[iUV-1], *pBlock = pMbCache->pDct->iChromaBlock[(iUV - 1)<<2];
275 int16_t aDct2x2[4], j, aMax[4];
276 int32_t iSingleCtr8x8 = 0;
277 int16_t* pMF = g_kiQuantMF[kiQp], *pFF = g_kiQuantInterFF[(!kiInterFlag)*6+kiQp];
278
279 uiNoneZeroCountMbDc = pfQuantizationHadamard2x2(pRes, pFF[0]<<1, pMF[0]>>1, aDct2x2, iChromaDc);
280
281 pfQuantizationFour4x4Max(pRes, pFF, pMF, aMax);
282
283 for(j = 0; j < 4; j++)
284 {
285 if(aMax[j] == 0)
286 pfSetMemZeroSize8(pBlock, 32);
287 else
288 {
289 pfScan4x4Ac(pBlock, pRes);
290 if(kiInterFlag)
291 {
292 if(aMax[j] > 1)
293 iSingleCtr8x8 += 9;
294 else if(iSingleCtr8x8 < 7)
295 iSingleCtr8x8 += pfCalculateSingleCtr4x4(pBlock);
296 }
297 else
298 iSingleCtr8x8 = INT_MAX;
299 }
300 pRes += 16;
301 pBlock += 16;
302 }
303 pRes -= 64;
304
305 if( iSingleCtr8x8 < 7 ) //from JVT-O079
306 {
307 pfSetMemZeroSize64(pRes, 128); // confirmed_safe_unsafe_usage
308 ST16( &pCurMb->pNonZeroCount[16+uiNoneZeroCountOffset], 0 );
309 ST16( &pCurMb->pNonZeroCount[20+uiNoneZeroCountOffset], 0 );
310 }
311 else
312 {
313 const uint8_t* kpNoneZeroCountIdx = &g_kuiMbCountScan4Idx[uiSubMbIdx];
314 pBlock -= 64;
315 for(i=0; i<4; i++){
316 uiNoneZeroCount = pfGetNoneZeroCount(pBlock);
317 pCurMb->pNonZeroCount[*kpNoneZeroCountIdx++] = uiNoneZeroCount;
318 uiNoneZeroCountMbAc += uiNoneZeroCount;
319 pBlock += 16;
320 }
321 pfDequantizationFour4x4(pRes, g_kuiDequantCoeff[pCurMb->uiChromaQp]);
322 pCurMb->uiCbp &= 0x0F;
323 pCurMb->uiCbp |= 0x20;
324 }
325
326 if (uiNoneZeroCountMbDc > 0)
327 {
328 WelsDequantIHadamard2x2Dc(aDct2x2, g_kuiDequantCoeff[kiQp][0] >> 1);
329 if ( 2 != (pCurMb->uiCbp >> 4) )
330 pCurMb->uiCbp |= (0x01 << 4) ;
331 pRes[0] = aDct2x2[0];
332 pRes[16] = aDct2x2[1];
333 pRes[32] = aDct2x2[2];
334 pRes[48] = aDct2x2[3];
335 }
336}
337
338
339void WelsRecPskip(SDqLayer *pCurLayer, SWelsFuncPtrList *pFuncList, SMB * pCurMb, SMbCache *pMbCache)
340{
341 int32_t* iRecStride = pCurLayer->iCsStride;
342 uint8_t** pCsMb = &pMbCache->SPicData.pCsMb[0];
343
344 pFuncList->pfCopy16x16Aligned(pCsMb[0], *iRecStride++, pMbCache->pSkipMb, 16);
345 pFuncList->pfCopy8x8Aligned( pCsMb[1], *iRecStride++, pMbCache->pSkipMb + 256, 8);
346 pFuncList->pfCopy8x8Aligned( pCsMb[2], *iRecStride, pMbCache->pSkipMb + 320, 8);
347 pFuncList->pfSetMemZeroSize8( pCurMb->pNonZeroCount, 24 );
348}
349
350BOOL_T WelsTryPYskip(sWelsEncCtx * pEncCtx, SMB * pCurMb, SMbCache *pMbCache)
351{
352 int32_t iSingleCtrMb = 0;
353 int16_t *pRes = pMbCache->pCoeffLevel;
354 const uint8_t kuiQp = pCurMb->uiLumaQp;
355
356 int16_t* pBlock = pMbCache->pDct->iLumaBlock[0];
357 uint16_t aMax[4], i, j;
358 int16_t* pMF = g_kiQuantMF[kuiQp], *pFF = g_kiQuantInterFF[kuiQp];
359
360 for(i = 0; i < 4; i++)
361 {
362 pEncCtx->pFuncList->pfQuantizationFour4x4Max(pRes, pFF, pMF, (int16_t*)aMax);
363
364 for(j = 0; j < 4; j++)
365 {
366 if(aMax[j] > 1) return FALSE; // iSingleCtrMb += 9, can't be P_SKIP
367 else if( aMax[j] == 1)
368 {
369 pEncCtx->pFuncList->pfScan4x4(pBlock, pRes); //
370 iSingleCtrMb += pEncCtx->pFuncList->pfCalculateSingleCtr4x4(pBlock);
371 }
372 if(iSingleCtrMb >= 6) return FALSE; //from JVT-O079
373 pRes += 16;
374 pBlock += 16;
375 }
376 }
377 return TRUE;
378}
379
380BOOL_T WelsTryPUVskip(sWelsEncCtx * pEncCtx, SMB * pCurMb, SMbCache *pMbCache, int32_t iUV)
381{
382 int16_t* pRes = ((iUV == 1) ? &(pMbCache->pCoeffLevel[256]):&(pMbCache->pCoeffLevel[256+64]));
383
384 const uint8_t kuiQp = g_kuiChromaQpTable[CLIP3_QP_0_51(pCurMb->uiLumaQp + pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset)];
385
386 int16_t* pMF = g_kiQuantMF[kuiQp], *pFF = g_kiQuantInterFF[kuiQp];
387
388 if(pEncCtx->pFuncList->pfQuantizationHadamard2x2Skip(pRes, pFF[0]<<1, pMF[0]>>1))
389 return FALSE;
390 else
391 {
392 uint16_t aMax[4], j;
393 int32_t iSingleCtrMb = 0;
394 int16_t* pBlock = pMbCache->pDct->iChromaBlock[(iUV-1)<<2];
395 pEncCtx->pFuncList->pfQuantizationFour4x4Max(pRes, pFF, pMF, (int16_t*)aMax);
396
397 for(j = 0; j < 4; j++)
398 {
399 if( aMax[j] > 1) return FALSE; // iSingleCtrMb += 9, can't be P_SKIP
400 else if( aMax[j] == 1)
401 {
402 pEncCtx->pFuncList->pfScan4x4Ac(pBlock, pRes);
403 iSingleCtrMb += pEncCtx->pFuncList->pfCalculateSingleCtr4x4(pBlock);
404 }
405 if(iSingleCtrMb >= 7) return FALSE; //from JVT-O079
406 pRes += 16;
407 pBlock += 16;
408 }
409 return TRUE;
410 }
411}
412
413} // namespace WelsSVCEnc

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t