1 /*
2 * Copyright © 2014 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Zhao Yakui <yakui.zhao@intel.com>
26 *
27 */
28
29 /*
30 * Copyright (c) 2010, The WebM Project authors. All rights reserved.
31 *
32 * An additional intellectual property rights grant can be found
33 * in the file LIBVPX_PATENTS. All contributing project authors may
34 * be found in the LIBVPX_AUTHORS file.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions are met:
38
39 * Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 *
42 * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the distribution.
45
46 * Neither the name of Google, nor the WebM Project, nor the names
47 * of its contributors may be used to endorse or promote products
48 * derived from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 */
63
64 #include "intel_hybrid_hostvld_vp9_parser.h"
65 #include "intel_hybrid_hostvld_vp9_loopfilter.h"
66 #include "intel_hybrid_hostvld_vp9_context.h"
67 #include "intel_hybrid_hostvld_vp9_engine.h"
68
69
70 #define VP9_SafeFreeMemory(ptr) \
71 if (ptr) free(ptr); \
72
73 #define INTEL_HOSTVLD_VP9_THREAD_NUM 1
74 #define INTEL_HOSTVLD_VP9_HOSTBUF_NUM 2
75 #define INTEL_HOSTVLD_VP9_DDIBUF_NUM INTEL_MT_DXVA_BUF_NUM
76 #define INTEL_HOSTVLD_VP9_SEM_QUEUE_SIZE 128
77 #define INTEL_HOSTVLD_VP9_PAGE_SIZE 0x1000
78 #define INTEL_HOSTVLD_VP9_EARLY_DECODE_BUFFER_NUM 3
79
80 #define VP9_ALIGNED_FREE_MEMORY(pAlignedBuffer) \
81 do { \
82 if (pAlignedBuffer) \
83 { \
84 free(pAlignedBuffer); \
85 } \
86 } while(0)
87
88 #define VP9_REALLOCATE_ABOVE_CTX_BUFFER(pAboveCtxBuffer, size) \
89 do { \
90 VP9_ALIGNED_FREE_MEMORY(pAboveCtxBuffer); \
91 pAboveCtxBuffer = (PUINT8)aligned_alloc(INTEL_HOSTVLD_VP9_PAGE_SIZE, size); \
92 } while(0)
93
94 #define VP9_REALLOCATE_HOSTVLD_1D_BUFFER_UINT8(pHostvldBuffer, dwBufferSize) \
95 do \
96 { \
97 VP9_ALIGNED_FREE_MEMORY((pHostvldBuffer)->pu8Buffer); \
98 (pHostvldBuffer)->dwSize = dwBufferSize; \
99 (pHostvldBuffer)->pu8Buffer = (PUINT8)aligned_alloc(INTEL_HOSTVLD_VP9_PAGE_SIZE, dwBufferSize); \
100 } while (0)
101
102 VAStatus Intel_HostvldVp9_Execute_MT (
103 INTEL_HOSTVLD_VP9_HANDLE hHostVld);
104
105 VAStatus Intel_HostvldVp9_PostLoopFilter (
106 PVOID pVp9FrameState);
107
Intel_HostvldVp9_GetPartitions(PINTEL_HOSTVLD_VP9_FRAME_INFO pFrameInfo,PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVideoBuffer,PINTEL_VP9_PIC_PARAMS pPicParams)108 static VAStatus Intel_HostvldVp9_GetPartitions(
109 PINTEL_HOSTVLD_VP9_FRAME_INFO pFrameInfo,
110 PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVideoBuffer,
111 PINTEL_VP9_PIC_PARAMS pPicParams)
112 {
113 VAStatus eStatus = VA_STATUS_SUCCESS;
114
115
116 if (pPicParams->UncompressedHeaderLengthInBytes >= 2)
117 pFrameInfo->FirstPartition.pu8Buffer =
118 pVideoBuffer->pbBitsData + pPicParams->UncompressedHeaderLengthInBytes;
119 pFrameInfo->FirstPartition.dwSize = pPicParams->FirstPartitionSize;
120
121 pFrameInfo->SecondPartition.pu8Buffer =
122 pFrameInfo->FirstPartition.pu8Buffer + pFrameInfo->FirstPartition.dwSize;
123 pFrameInfo->SecondPartition.dwSize =
124 pVideoBuffer->dwBitsSize - pPicParams->UncompressedHeaderLengthInBytes - pFrameInfo->FirstPartition.dwSize;
125
126 return eStatus;
127 }
128
Intel_HostvldVp9_FillIntraFrameRefFrame(PINTEL_HOSTVLD_VP9_1D_BUFFER pBufferRefFrame)129 static VAStatus Intel_HostvldVp9_FillIntraFrameRefFrame(
130 PINTEL_HOSTVLD_VP9_1D_BUFFER pBufferRefFrame)
131 {
132 PINT8 pi8Buffer;
133 UINT i;
134 VAStatus eStatus = VA_STATUS_SUCCESS;
135
136
137 pi8Buffer = (PINT8)pBufferRefFrame->pu8Buffer;
138
139 for(i = 0; i < pBufferRefFrame->dwSize; i++)
140 {
141 *(pi8Buffer++) = VP9_REF_FRAME_INTRA;
142 *(pi8Buffer++) = VP9_REF_FRAME_INTRA;
143 }
144
145 return eStatus;
146 }
147
Intel_HostvldVp9_Create(PINTEL_HOSTVLD_VP9_HANDLE phHostVld,PINTEL_HOSTVLD_VP9_CALLBACKS pCallbacks)148 VAStatus Intel_HostvldVp9_Create (
149 PINTEL_HOSTVLD_VP9_HANDLE phHostVld,
150 PINTEL_HOSTVLD_VP9_CALLBACKS pCallbacks)
151 {
152 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
153 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState;
154 PINTEL_HOSTVLD_VP9_TILE_STATE pTileState;
155 PINTEL_HOSTVLD_VP9_FRAME_CONTEXT pContext;
156 uint32_t dwThreadNumber;
157 uint32_t i = 0;
158 uint32_t uiTileIndex = 0;
159 VAStatus eStatus = VA_STATUS_SUCCESS;
160
161
162 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)calloc(1, sizeof(*pVp9HostVld));
163 *phHostVld = (INTEL_HOSTVLD_VP9_HANDLE)pVp9HostVld;
164
165
166 dwThreadNumber = INTEL_HOSTVLD_VP9_THREAD_NUM;
167
168 pVp9HostVld->pfnRenderCb = pCallbacks->pfnHostVldRenderCb;
169 pVp9HostVld->pfnSyncCb = pCallbacks->pfnHostVldSyncCb;
170 pVp9HostVld->pvStandardState = pCallbacks->pvStandardState;
171 pVp9HostVld->dwThreadNumber = dwThreadNumber;
172 pVp9HostVld->dwBufferNumber = INTEL_HOSTVLD_VP9_HOSTBUF_NUM;
173 pVp9HostVld->dwDDIBufNumber = dwThreadNumber;
174 pVp9HostVld->ui8BufNumEarlyDec = 1; //not early decode for Sinlge thread case
175 pVp9HostVld->PrevParserID = -1;
176
177 pthread_mutex_init(&pVp9HostVld->MutexSync, NULL);
178 // Create Frame State
179 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)calloc(pVp9HostVld->dwBufferNumber, sizeof(*pFrameState));
180 pVp9HostVld->pFrameStateBase = pFrameState;
181
182 for (i = 0; i < pVp9HostVld->dwBufferNumber; i++)
183 {
184
185 // Create Tile State
186 pTileState = (PINTEL_HOSTVLD_VP9_TILE_STATE)calloc(dwThreadNumber, sizeof(*pTileState));
187 pFrameState->pTileStateBase = pTileState;
188
189 // Initialize Tile States
190 for (uiTileIndex = 0; uiTileIndex < dwThreadNumber; uiTileIndex++)
191 {
192 pTileState->pFrameState = pFrameState;
193 pTileState->dwCurrColIndex = uiTileIndex;
194 pTileState++;
195 }
196
197 // Create Context Model
198 pFrameState->pVp9HostVld = pVp9HostVld;
199 pFrameState->dwLastTaskID = -1; // Invalid ID
200 pFrameState++;
201 }
202
203 pVp9HostVld->pEarlyDecBufferBase = (PINTEL_HOSTVLD_VP9_EARLY_DEC_BUFFER)calloc(
204 pVp9HostVld->ui8BufNumEarlyDec, sizeof(*(pVp9HostVld->pEarlyDecBufferBase)));
205
206 pVp9HostVld->pLastParserTaskID = (PUINT)malloc(pVp9HostVld->ui8BufNumEarlyDec * sizeof(UINT));
207 memset(pVp9HostVld->pLastParserTaskID, -1, pVp9HostVld->ui8BufNumEarlyDec * sizeof(UINT));
208
209 for (i = 0; i < pVp9HostVld->ui8BufNumEarlyDec; i++)
210 {
211 pContext = &pVp9HostVld->pEarlyDecBufferBase[i].CurrContext;
212 pContext->TxProbTables[TX_8X8].pui8ProbTable = &pContext->TxProbTableSet.Tx_8X8[0][0];
213 pContext->TxProbTables[TX_8X8].uiStride = TX_8X8;
214 pContext->TxProbTables[TX_16X16].pui8ProbTable = &pContext->TxProbTableSet.Tx_16X16[0][0];
215 pContext->TxProbTables[TX_16X16].uiStride = TX_16X16;
216 pContext->TxProbTables[TX_32X32].pui8ProbTable = &pContext->TxProbTableSet.Tx_32X32[0][0];
217 pContext->TxProbTables[TX_32X32].uiStride = TX_32X32;
218 }
219
220 return eStatus;
221 }
222
Intel_HostvldVp9_QueryBufferSize(INTEL_HOSTVLD_VP9_HANDLE hHostVld,uint32_t * pdwBufferSize)223 VAStatus Intel_HostvldVp9_QueryBufferSize (
224 INTEL_HOSTVLD_VP9_HANDLE hHostVld,
225 uint32_t *pdwBufferSize)
226 {
227 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
228 VAStatus eStatus = VA_STATUS_SUCCESS;
229
230 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)hHostVld;
231
232 if (pdwBufferSize)
233 {
234 *pdwBufferSize = pVp9HostVld->dwBufferNumber;
235 }
236
237 return eStatus;
238 }
239
Intel_HostvldVp9_SetOutputBuffer(INTEL_HOSTVLD_VP9_HANDLE hHostVld,PINTEL_HOSTVLD_VP9_OUTPUT_BUFFER pOutputBuffer)240 VAStatus Intel_HostvldVp9_SetOutputBuffer (
241 INTEL_HOSTVLD_VP9_HANDLE hHostVld,
242 PINTEL_HOSTVLD_VP9_OUTPUT_BUFFER pOutputBuffer)
243 {
244 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
245 VAStatus eStatus = VA_STATUS_SUCCESS;
246
247
248
249 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)hHostVld;
250
251 pVp9HostVld->pOutputBufferBase = pOutputBuffer;
252
253 return eStatus;
254 }
255
Intel_HostvldVp9_Initialize(INTEL_HOSTVLD_VP9_HANDLE hHostVld,PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVideoBuffer)256 VAStatus Intel_HostvldVp9_Initialize (
257 INTEL_HOSTVLD_VP9_HANDLE hHostVld,
258 PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVideoBuffer)
259 {
260 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
261 VAStatus eStatus = VA_STATUS_SUCCESS;
262
263
264 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)hHostVld;
265
266 {
267 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
268 DWORD dwCurrIndex;
269
270 dwCurrIndex = (pVp9HostVld->dwCurrIndex + 1) % pVp9HostVld->dwBufferNumber;
271 pFrameState = pVp9HostVld->pFrameStateBase + dwCurrIndex;
272
273 pFrameState->dwPrevIndex = pVp9HostVld->dwCurrIndex;
274 pFrameState->dwCurrIndex = dwCurrIndex;
275 pFrameState->pOutputBuffer = pVp9HostVld->pOutputBufferBase + dwCurrIndex;
276 pFrameState->pVideoBuffer = pVideoBuffer;
277 pFrameState->LastFrameType = pVp9HostVld->LastFrameType;
278 pFrameState->FrameInfo.pContext = &pVp9HostVld->pEarlyDecBufferBase[0].CurrContext; //for ST, there is only 1 early dec buffer
279 pFrameState->pLastSegIdBuf = &pVp9HostVld->pEarlyDecBufferBase[0].LastSegId;
280
281 pVp9HostVld->dwCurrIndex = dwCurrIndex;
282 }
283
284 return eStatus;
285 }
286
Intel_HostvldVp9_PreParser(PVOID pVp9FrameState)287 VAStatus Intel_HostvldVp9_PreParser (PVOID pVp9FrameState)
288 {
289 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
290 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
291 PINTEL_HOSTVLD_VP9_FRAME_STATE pPrevFrameState = NULL;
292 PINTEL_HOSTVLD_VP9_TILE_STATE pTileState = NULL;
293 PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVideoBuffer;
294 PINTEL_HOSTVLD_VP9_OUTPUT_BUFFER pOutputBuffer;
295 PINTEL_HOSTVLD_VP9_FRAME_INFO pFrameInfo;
296 PINTEL_VP9_PIC_PARAMS pPicParams;
297 PINTEL_VP9_SEGMENT_PARAMS pSegmentData;
298 INT iMarkerBit;
299 DWORD dwNumAboveCtx, dwSize, i;
300 DWORD dwPrevPicWidth, dwPrevPicHeight;
301 BOOL bPrevShowFrame;
302 BOOL bResetLastSegId = FALSE;
303 VAStatus eStatus = VA_STATUS_SUCCESS;
304
305
306
307 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState;
308 pVp9HostVld = pFrameState->pVp9HostVld;
309 pVideoBuffer = pFrameState->pVideoBuffer;
310 pOutputBuffer = pFrameState->pOutputBuffer;
311 pFrameInfo = &pFrameState->FrameInfo;
312
313 pPrevFrameState = pFrameState->pVp9HostVld->pFrameStateBase + pFrameState->dwPrevIndex;
314 dwPrevPicWidth = pPrevFrameState->FrameInfo.dwPicWidthCropped;
315 dwPrevPicHeight = pPrevFrameState->FrameInfo.dwPicHeightCropped;
316 bPrevShowFrame = pPrevFrameState->FrameInfo.bShowFrame;
317
318 pPicParams = pVideoBuffer->pVp9PicParams;
319 pSegmentData = pVideoBuffer->pVp9SegmentData;
320 pFrameInfo->pPicParams = pPicParams;
321 pFrameInfo->pSegmentData = pVideoBuffer->pVp9SegmentData;
322
323 pFrameInfo->ui8SegEnabled = pPicParams->PicFlags.fields.segmentation_enabled;
324 pFrameInfo->ui8SegUpdMap = pPicParams->PicFlags.fields.segmentation_update_map;
325 pFrameInfo->ui8TemporalUpd = pPicParams->PicFlags.fields.segmentation_temporal_update;
326
327 pFrameInfo->LastFrameType = pFrameState->LastFrameType;
328 pFrameInfo->dwPicWidthCropped = pPicParams->FrameWidthMinus1 + 1;
329 pFrameInfo->dwPicHeightCropped = pPicParams->FrameHeightMinus1 + 1;
330 pFrameInfo->dwPicWidth = ALIGN(pPicParams->FrameWidthMinus1 + 1, 8);
331 pFrameInfo->dwPicHeight = ALIGN(pPicParams->FrameHeightMinus1 + 1, 8);
332 pFrameInfo->dwB8Columns = pFrameInfo->dwPicWidth >> VP9_LOG2_B8_SIZE;
333 pFrameInfo->dwB8Rows = pFrameInfo->dwPicHeight >> VP9_LOG2_B8_SIZE;
334 pFrameInfo->dwB8ColumnsAligned = ALIGN(pFrameInfo->dwB8Columns, VP9_B64_SIZE_IN_B8);
335 pFrameInfo->dwB8RowsAligned = ALIGN(pFrameInfo->dwB8Rows, VP9_B64_SIZE_IN_B8);
336 pFrameInfo->dwPicWidthAligned = pFrameInfo->dwB8ColumnsAligned << VP9_LOG2_B8_SIZE;
337 pFrameInfo->dwLog2TileRows = pPicParams->log2_tile_rows;
338 pFrameInfo->dwLog2TileColumns = pPicParams->log2_tile_columns;
339 pFrameInfo->dwTileRows = 1 << pPicParams->log2_tile_rows;
340 pFrameInfo->dwTileColumns = 1 << pPicParams->log2_tile_columns;
341 pFrameInfo->dwMbStride = pFrameInfo->dwB8ColumnsAligned;
342 pFrameInfo->bLossLess = pPicParams->PicFlags.fields.LosslessFlag;
343 pFrameInfo->bShowFrame = pPicParams->PicFlags.fields.show_frame;
344 pFrameInfo->bIsIntraOnly =
345 (pPicParams->PicFlags.fields.frame_type == KEY_FRAME) ||
346 (pPicParams->PicFlags.fields.intra_only);
347 pFrameInfo->bFrameParallelDisabled =
348 !pPicParams->PicFlags.fields.frame_parallel_decoding_mode;
349 pFrameInfo->bErrorResilientMode =
350 pPicParams->PicFlags.fields.error_resilient_mode;
351 pFrameInfo->uiFrameContextIndex =
352 pPicParams->PicFlags.fields.frame_context_idx;
353 pFrameInfo->uiResetFrameContext =
354 pPicParams->PicFlags.fields.reset_frame_context;
355 pFrameInfo->bIsKeyFrame = pPicParams->PicFlags.fields.frame_type == KEY_FRAME;
356 pFrameInfo->eInterpolationType =
357 (INTEL_HOSTVLD_VP9_INTERPOLATION_TYPE)pPicParams->PicFlags.fields.mcomp_filter_type;
358
359 //Inter
360 pFrameInfo->bIsSwitchableInterpolation =
361 pPicParams->PicFlags.fields.mcomp_filter_type == VP9_INTERP_SWITCHABLE;
362 pFrameInfo->bAllowHighPrecisionMv = pPicParams->PicFlags.fields.allow_high_precision_mv;
363 pFrameInfo->RefFrameSignBias[VP9_REF_FRAME_LAST] = pPicParams->PicFlags.fields.LastRefSignBias;
364 pFrameInfo->RefFrameSignBias[VP9_REF_FRAME_GOLDEN] = pPicParams->PicFlags.fields.GoldenRefSignBias;
365 pFrameInfo->RefFrameSignBias[VP9_REF_FRAME_ALTREF] = pPicParams->PicFlags.fields.AltRefSignBias;
366
367 for (i = 0; i < VP9_MAX_SEGMENTS; i++)
368 {
369 // pack segment QP
370 pFrameInfo->SegQP[INTEL_HOSTVLD_VP9_YUV_PLANE_Y][i] =
371 (((UINT32)pSegmentData->SegData[i].LumaACQuantScale) << 16) | pSegmentData->SegData[i].LumaDCQuantScale;
372 pFrameInfo->SegQP[INTEL_HOSTVLD_VP9_YUV_PLANE_UV][i] =
373 (((UINT32)pSegmentData->SegData[i].ChromaACQuantScale) << 16) | pSegmentData->SegData[i].ChromaDCQuantScale;
374 }
375
376 Intel_HostvldVp9_GetPartitions(pFrameInfo, pVideoBuffer, pPicParams);
377
378 // Initialize BAC engine
379 iMarkerBit = Intel_HostvldVp9_BacEngineInit(
380 &pFrameState->BacEngine,
381 pFrameInfo->FirstPartition.pu8Buffer,
382 pFrameInfo->FirstPartition.dwSize);
383
384 if (0 != iMarkerBit)
385 {
386 eStatus = VA_STATUS_ERROR_OPERATION_FAILED;
387 goto finish;
388 }
389
390 pFrameInfo->bResetContext = FALSE;
391 if (pFrameInfo->bIsIntraOnly || pFrameInfo->bErrorResilientMode)
392 {
393 // reset context
394 Intel_HostvldVp9_ResetContext(pVp9HostVld->ContextTable, pFrameInfo);
395 }
396
397 if (!pFrameInfo->bResetContext)
398 {
399 // If we didn't reset the context, initialize current frame context by copying from context table
400 Intel_HostvldVp9_GetCurrFrameContext(
401 pVp9HostVld->ContextTable,
402 pFrameInfo);
403 }
404
405 Intel_HostvldVp9_SetupSegmentationProbs(
406 pFrameInfo->pContext,
407 pPicParams->SegTreeProbs,
408 pPicParams->SegPredProbs);
409
410 pFrameState->dwTileStatesInUse = MIN(pFrameInfo->dwTileColumns, pVp9HostVld->dwThreadNumber);
411 pTileState = pFrameState->pTileStateBase;
412 for (i = 0; i < pFrameState->dwTileStatesInUse; i++)
413 {
414 memset(&(pTileState->Count), 0, sizeof(pTileState->Count));
415 pTileState++;
416 }
417
418 // Only reallocate above context buffers when picture width becomes bigger //Need To Check
419 dwNumAboveCtx = pFrameInfo->dwPicWidthAligned >> VP9_LOG2_B8_SIZE;
420 if (dwNumAboveCtx > pFrameInfo->dwNumAboveCtx)
421 {
422 pFrameInfo->dwNumAboveCtx = dwNumAboveCtx;
423
424 // allocate above context
425 dwSize = dwNumAboveCtx * sizeof(*pFrameInfo->pContextAbove);
426 VP9_ALIGNED_FREE_MEMORY(pFrameInfo->pContextAbove);
427 pFrameInfo->pContextAbove =
428 (PINTEL_HOSTVLD_VP9_NEIGHBOR)aligned_alloc(INTEL_HOSTVLD_VP9_PAGE_SIZE, dwSize);
429
430 dwNumAboveCtx <<= 1;
431 // Entropy context, per 4x4 block. Allocate once for all the planes
432 dwSize = dwNumAboveCtx * sizeof(*pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_Y]) * 2;
433 VP9_REALLOCATE_ABOVE_CTX_BUFFER(pFrameInfo->EntropyContextAbove.pu8Buffer, dwSize);
434 pFrameInfo->EntropyContextAbove.dwSize = dwSize;
435 pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_Y] =
436 pFrameInfo->EntropyContextAbove.pu8Buffer;
437 pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_U] =
438 pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_Y] + (dwSize >> 1);
439 pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_V] =
440 pFrameInfo->pEntropyContextAbove[VP9_CODED_YUV_PLANE_U] + (dwSize >> 2); // we only support 4:2:0 so far.
441 }
442
443 // Reallocate mode info buffer if changed to bigger resolution
444 dwSize = pFrameInfo->dwB8ColumnsAligned * pFrameInfo->dwB8RowsAligned;
445 if (dwSize > pFrameInfo->ModeInfo.dwSize)
446 {
447 VP9_ALIGNED_FREE_MEMORY(pFrameInfo->ModeInfo.pBuffer);
448 pFrameInfo->ModeInfo.pBuffer = aligned_alloc(INTEL_HOSTVLD_VP9_PAGE_SIZE,
449 dwSize * sizeof(INTEL_HOSTVLD_VP9_MODE_INFO));
450 pFrameInfo->ModeInfo.dwSize = dwSize;
451 }
452
453 // Zero last segment id buffer if resolution changed
454 if (dwSize > pFrameState->pLastSegIdBuf->dwSize)
455 {
456 // Per 8x8 block, UINT8
457 VP9_REALLOCATE_HOSTVLD_1D_BUFFER_UINT8(pFrameState->pLastSegIdBuf, dwSize);
458 bResetLastSegId |= TRUE;
459 }
460 if ((pFrameInfo->dwPicWidthCropped != dwPrevPicWidth) ||
461 (pFrameInfo->dwPicHeightCropped != dwPrevPicHeight) ||
462 pFrameInfo->bIsIntraOnly ||
463 pFrameInfo->bErrorResilientMode)
464 {
465 bResetLastSegId |= TRUE;
466 }
467
468 if (bResetLastSegId)
469 {
470 memset(pFrameState->pLastSegIdBuf->pu8Buffer, 0, pFrameState->pLastSegIdBuf->dwSize);
471 }
472
473 if (pVp9HostVld->pfnSyncCb)
474 {
475 pVp9HostVld->pfnSyncCb(
476 pVp9HostVld->pvStandardState,
477 pVideoBuffer,
478 pFrameState->dwCurrIndex,
479 pFrameState->dwPrevIndex);
480 }
481
482 pFrameInfo->bHasPrevFrame =
483 (pFrameInfo->dwPicWidthCropped == dwPrevPicWidth) &&
484 (pFrameInfo->dwPicHeightCropped == dwPrevPicHeight) &&
485 !pFrameInfo->bErrorResilientMode &&
486 !pFrameInfo->bIsIntraOnly &&
487 bPrevShowFrame;
488
489 if (pFrameInfo->bIsIntraOnly)
490 {
491 Intel_HostvldVp9_FillIntraFrameRefFrame(&pOutputBuffer->ReferenceFrame);
492 }
493
494 Intel_HostvldVp9_ParseCompressedHeader(pFrameState);
495
496 Intel_HostvldVp9_PreParseTiles(pFrameState);
497
498 finish:
499 return eStatus;
500 }
501
502
Intel_HostvldVp9_PostParser(PVOID pVp9FrameState)503 VAStatus Intel_HostvldVp9_PostParser (PVOID pVp9FrameState)
504 {
505 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
506 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
507 PINTEL_HOSTVLD_VP9_FRAME_INFO pFrameInfo = NULL;
508 VAStatus eStatus = VA_STATUS_SUCCESS;
509
510
511 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState;
512 pVp9HostVld = pFrameState->pVp9HostVld;
513 pFrameInfo = &pFrameState->FrameInfo;
514
515 Intel_HostvldVp9_PostParseTiles(pFrameState);
516
517 if (pFrameInfo->bIsIntraOnly || pFrameInfo->bErrorResilientMode)
518 {
519 Intel_HostvldVp9_UpdateContextTables(pVp9HostVld->ContextTable, pFrameInfo);
520 }
521
522 Intel_HostvldVp9_AdaptProbabilities(pFrameState);
523
524 Intel_HostvldVp9_RefreshFrameContext(pVp9HostVld->ContextTable, pFrameInfo);
525
526 pFrameState->ReferenceFrame.pu16Buffer = pFrameState->pOutputBuffer->ReferenceFrame.pu16Buffer;
527 pFrameState->ReferenceFrame.dwSize = pFrameState->pOutputBuffer->ReferenceFrame.dwSize;
528
529 if(pFrameState->FrameInfo.dwTileColumns > 1)
530 {
531 Intel_HostvldVp9_PostLoopFilter(pVp9FrameState);
532 }
533
534 return eStatus;
535 }
536
Intel_HostvldVp9_TileColumnParser(PVOID pVp9TileState)537 VAStatus Intel_HostvldVp9_TileColumnParser (PVOID pVp9TileState)
538 {
539 PINTEL_HOSTVLD_VP9_TILE_STATE pTileState = NULL;
540 DWORD dwTileColumns, dwCurrColIndex, dwTileStateNumber;
541 VAStatus eStatus = VA_STATUS_SUCCESS;
542
543
544 pTileState = (PINTEL_HOSTVLD_VP9_TILE_STATE)pVp9TileState;
545 dwTileColumns = pTileState->pFrameState->FrameInfo.dwTileColumns;
546 dwCurrColIndex = pTileState->dwCurrColIndex;
547 dwTileStateNumber = pTileState->pFrameState->pVp9HostVld->dwThreadNumber;
548
549 while(dwCurrColIndex < dwTileColumns)
550 {
551 Intel_HostvldVp9_ParseTileColumn(pTileState, dwCurrColIndex);
552 dwCurrColIndex += dwTileStateNumber;
553 }
554
555 return eStatus;
556 }
557
Intel_HostvldVp9_Parser(PVOID pVp9FrameState)558 VAStatus Intel_HostvldVp9_Parser (PVOID pVp9FrameState)
559 {
560 VAStatus eStatus = VA_STATUS_SUCCESS;
561
562
563 eStatus = Intel_HostvldVp9_PreParser(pVp9FrameState);
564
565 eStatus = Intel_HostvldVp9_ParseTiles((PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState);
566
567 if (((PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState)->pVp9HostVld->dwThreadNumber == 1)
568 {
569 eStatus = Intel_HostvldVp9_PostParser(pVp9FrameState);
570 }
571
572 return eStatus;
573 }
574
Intel_HostvldVp9_LoopFilterTiles(PVOID pVp9TileState)575 VAStatus Intel_HostvldVp9_LoopFilterTiles (PVOID pVp9TileState)
576 {
577 PINTEL_HOSTVLD_VP9_TILE_STATE pTileState = NULL;
578 DWORD dwTileColumns, dwCurrColIndex, dwTileStateNumber;
579 VAStatus eStatus = VA_STATUS_SUCCESS;
580
581 pTileState = (PINTEL_HOSTVLD_VP9_TILE_STATE)pVp9TileState;
582 dwTileColumns = pTileState->pFrameState->FrameInfo.dwTileColumns;
583 dwCurrColIndex = pTileState->dwCurrColIndex;
584 dwTileStateNumber = pTileState->pFrameState->pVp9HostVld->dwThreadNumber;
585
586 while(dwCurrColIndex < dwTileColumns)
587 {
588 Intel_HostvldVp9_LoopfilterTileColumn(pTileState, dwCurrColIndex);
589 dwCurrColIndex += dwTileStateNumber;
590 }
591
592 return eStatus;
593 }
594
Intel_HostvldVp9_PostLoopFilter(PVOID pVp9FrameState)595 VAStatus Intel_HostvldVp9_PostLoopFilter (PVOID pVp9FrameState)
596 {
597 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
598 VAStatus eStatus = VA_STATUS_SUCCESS;
599
600 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState;
601
602 // Calc Loop filter threshold
603 Intel_HostvldVp9_LoopfilterCalcThreshold(pFrameState);
604
605 Intel_HostvldVp9_SetOutOfBoundValues(pFrameState);
606
607 return eStatus;
608 }
609
Intel_HostvldVp9_LoopfilterFrame(PVOID pVp9FrameState)610 VAStatus Intel_HostvldVp9_LoopfilterFrame(PVOID pVp9FrameState)
611 {
612 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
613 PINTEL_HOSTVLD_VP9_FRAME_INFO pFrameInfo = NULL;
614 PINTEL_HOSTVLD_VP9_TILE_STATE pTileState = NULL;
615 DWORD dwTileX;
616 VAStatus eStatus = VA_STATUS_SUCCESS;
617
618 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState;
619
620 pFrameInfo = &pFrameState->FrameInfo;
621 pTileState = pFrameState->pTileStateBase;
622 pTileState->pFrameState = pFrameState;
623
624 // decode tiles
625 for (dwTileX = 0; dwTileX < pFrameInfo->dwTileColumns; dwTileX++)
626 {
627 Intel_HostvldVp9_LoopfilterTileColumn(pTileState,dwTileX);
628 }
629
630 Intel_HostvldVp9_PostLoopFilter(pFrameState);
631
632 return eStatus;
633 }
634
Intel_HostvldVp9_Render(PVOID pVp9FrameState)635 VAStatus Intel_HostvldVp9_Render (PVOID pVp9FrameState)
636 {
637 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
638 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
639 VAStatus eStatus = VA_STATUS_SUCCESS;
640
641 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pVp9FrameState;
642 pVp9HostVld = pFrameState->pVp9HostVld;
643
644 if (pVp9HostVld->pfnRenderCb)
645 {
646 pVp9HostVld->pfnRenderCb(
647 pVp9HostVld->pvStandardState,
648 pFrameState->dwCurrIndex,
649 pFrameState->dwPrevIndex);
650 }
651
652 return eStatus;
653 }
654
Intel_HostvldVp9_Execute(INTEL_HOSTVLD_VP9_HANDLE hHostVld)655 VAStatus Intel_HostvldVp9_Execute (
656 INTEL_HOSTVLD_VP9_HANDLE hHostVld)
657 {
658 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
659 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState = NULL;
660 VAStatus eStatus = VA_STATUS_SUCCESS;
661 PINTEL_HOSTVLD_VP9_VIDEO_BUFFER pVp9VideoBuffer = NULL;
662
663
664 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)hHostVld;
665
666 pFrameState = pVp9HostVld->pFrameStateBase + pVp9HostVld->dwCurrIndex;
667
668 eStatus = Intel_HostvldVp9_Parser(pFrameState);
669 if (eStatus != VA_STATUS_SUCCESS)
670 goto finish;
671
672 eStatus = Intel_HostvldVp9_LoopfilterFrame(pFrameState);
673 if (eStatus != VA_STATUS_SUCCESS)
674 goto finish;
675
676 pVp9VideoBuffer = pFrameState->pVideoBuffer;
677
678 if (pVp9VideoBuffer->slice_data_bo) {
679 dri_bo_unmap(pVp9VideoBuffer->slice_data_bo);
680 pVp9VideoBuffer->slice_data_bo = NULL;
681 }
682
683 eStatus = Intel_HostvldVp9_Render(pFrameState);
684 if (eStatus != VA_STATUS_SUCCESS)
685 goto finish;
686
687 pVp9HostVld->LastFrameType = (INTEL_HOSTVLD_VP9_FRAME_TYPE)(pFrameState->pVideoBuffer->pVp9PicParams->PicFlags.fields.frame_type);
688
689 finish:
690 return eStatus;
691 }
692
693
Intel_HostvldVp9_InitFrameState(PVOID pInitData,PVOID pData)694 VAStatus Intel_HostvldVp9_InitFrameState (
695 PVOID pInitData,
696 PVOID pData)
697 {
698 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState;
699 PINTEL_HOSTVLD_VP9_TASK_USERDATA pTaskUserData;
700 VAStatus eStatus = VA_STATUS_SUCCESS;
701
702
703 pFrameState = (PINTEL_HOSTVLD_VP9_FRAME_STATE)pData;
704 pTaskUserData = (PINTEL_HOSTVLD_VP9_TASK_USERDATA)pInitData;
705
706 pFrameState->pVideoBuffer = pTaskUserData->pVideoBuffer;
707 pFrameState->pOutputBuffer = pTaskUserData->pOutputBuffer;
708 pFrameState->pRenderTarget = pTaskUserData->pVideoBuffer->pRenderTarget;
709 pFrameState->dwCurrIndex = pTaskUserData->dwCurrIndex;
710 pFrameState->dwPrevIndex = pTaskUserData->dwPrevIndex;
711 pFrameState->LastFrameType = pTaskUserData->LastFrameType;
712 pFrameState->FrameInfo.pContext = pTaskUserData->pCurrContext;
713 pFrameState->pLastSegIdBuf = pTaskUserData->pLastSegIdBuf;
714
715 return eStatus;
716 }
717
718
Intel_HostvldVp9_Destroy(INTEL_HOSTVLD_VP9_HANDLE hHostVld)719 VAStatus Intel_HostvldVp9_Destroy (
720 INTEL_HOSTVLD_VP9_HANDLE hHostVld)
721 {
722 PINTEL_HOSTVLD_VP9_STATE pVp9HostVld = NULL;
723 VAStatus eStatus = VA_STATUS_SUCCESS;
724 unsigned int i = 0;
725
726
727
728 pVp9HostVld = (PINTEL_HOSTVLD_VP9_STATE)hHostVld;
729
730 if (pVp9HostVld)
731 {
732 PINTEL_HOSTVLD_VP9_FRAME_STATE pFrameState;
733 PINTEL_HOSTVLD_VP9_EARLY_DEC_BUFFER pEarlyDecBufferBase;
734
735 pFrameState = pVp9HostVld->pFrameStateBase;
736 if (pFrameState)
737 {
738 for(i = 0; i < pVp9HostVld->dwBufferNumber; i++)
739 {
740 if (pFrameState)
741 {
742 VP9_ALIGNED_FREE_MEMORY(pFrameState->FrameInfo.pContextAbove);
743 VP9_ALIGNED_FREE_MEMORY(pFrameState->FrameInfo.EntropyContextAbove.pu8Buffer);
744 VP9_ALIGNED_FREE_MEMORY(pFrameState->FrameInfo.ModeInfo.pBuffer);
745 VP9_SafeFreeMemory(pFrameState->pTileStateBase);
746 }
747 pFrameState++;
748 }
749
750 VP9_SafeFreeMemory(pVp9HostVld->pFrameStateBase);
751 }
752 pEarlyDecBufferBase = pVp9HostVld->pEarlyDecBufferBase;
753 for (i = 0; i< pVp9HostVld->ui8BufNumEarlyDec; i++)
754 {
755 VP9_ALIGNED_FREE_MEMORY(pEarlyDecBufferBase->LastSegId.pu8Buffer);
756
757 pEarlyDecBufferBase++;
758 }
759 VP9_SafeFreeMemory(pVp9HostVld->pEarlyDecBufferBase);
760 VP9_SafeFreeMemory(pVp9HostVld->pLastParserTaskID);
761
762 pthread_mutex_destroy(&pVp9HostVld->MutexSync);
763
764 free(pVp9HostVld);
765 }
766
767 return eStatus;
768 }
769