1 /*
2 * Copyright (c) 2009-2017, 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 "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file media_ddi_encode_vp8.cpp
24 //! \brief Defines class for DDI media vp8 encode.
25 //!
26
27 #include "media_libva.h"
28 #include "media_libva_encoder.h"
29 #include "media_libva_util.h"
30 #include "media_ddi_encode_vp8.h"
31 #include "media_ddi_encode_const.h"
32 #include "media_ddi_factory.h"
33
34 extern template class MediaDdiFactoryNoArg<DdiEncodeBase>;
35 static bool isEncodeVp8Registered =
36 MediaDdiFactoryNoArg<DdiEncodeBase>::RegisterCodec<DdiEncodeVp8>(ENCODE_ID_VP8);
37
~DdiEncodeVp8()38 DdiEncodeVp8::~DdiEncodeVp8()
39 {
40 if (m_encodeCtx == nullptr)
41 {
42 return;
43 }
44
45 MOS_FreeMemory(m_encodeCtx->pSeqParams);
46 m_encodeCtx->pSeqParams = nullptr;
47
48 MOS_FreeMemory(m_encodeCtx->pPicParams);
49 m_encodeCtx->pPicParams = nullptr;
50
51 MOS_FreeMemory(m_encodeCtx->pQmatrixParams);
52 m_encodeCtx->pQmatrixParams = nullptr;
53
54 MOS_FreeMemory(m_encodeCtx->pEncodeStatusReport);
55 m_encodeCtx->pEncodeStatusReport = nullptr;
56
57 if (m_encodeCtx->pbsBuffer)
58 {
59 MOS_FreeMemory(m_encodeCtx->pbsBuffer->pBase);
60 m_encodeCtx->pbsBuffer->pBase = nullptr;
61
62 MOS_FreeMemory(m_encodeCtx->pbsBuffer);
63 m_encodeCtx->pbsBuffer = nullptr;
64 }
65 }
66
ContextInitialize(CodechalSetting * codecHalSettings)67 VAStatus DdiEncodeVp8::ContextInitialize(CodechalSetting *codecHalSettings)
68 {
69 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
70 DDI_CHK_NULL(m_encodeCtx->pCpDdiInterface, "nullptr m_encodeCtx->pCpDdiInterface.", VA_STATUS_ERROR_INVALID_CONTEXT);
71 DDI_CHK_NULL(codecHalSettings, "nullptr codecHalSettings.", VA_STATUS_ERROR_INVALID_CONTEXT);
72
73 codecHalSettings->codecFunction = m_encodeCtx->codecFunction;
74 codecHalSettings->width = m_encodeCtx->dwFrameWidth;
75 codecHalSettings->height = m_encodeCtx->dwFrameHeight;
76 codecHalSettings->mode = m_encodeCtx->wModeType;
77 codecHalSettings->standard = CODECHAL_VP8;
78 VAStatus vaStatus = VA_STATUS_SUCCESS;
79
80 m_encodeCtx->pSeqParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODEC_VP8_ENCODE_SEQUENCE_PARAMS));
81 DDI_CHK_NULL(m_encodeCtx->pSeqParams, "nullptr m_encodeCtx->pSeqParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
82
83 m_encodeCtx->pPicParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODEC_VP8_ENCODE_PIC_PARAMS));
84 DDI_CHK_NULL(m_encodeCtx->pPicParams, "nullptr m_encodeCtx->pPicParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
85
86 m_encodeCtx->pQmatrixParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODEC_VP8_ENCODE_QUANT_DATA));
87 DDI_CHK_NULL(m_encodeCtx->pQmatrixParams, "nullptr m_encodeCtx->pQmatrixParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
88
89 if (m_encodeCtx->codecFunction == CODECHAL_FUNCTION_HYBRIDPAK)
90 {
91 m_encodeCtx->pSliceParams = (void *)MOS_AllocAndZeroMemory(sizeof(CODECHAL_VP8_HYBRIDPAK_FRAMEUPDATE));
92 DDI_CHK_NULL(m_encodeCtx->pSliceParams, "nullptr m_encodeCtx->pSliceParams.", VA_STATUS_ERROR_ALLOCATION_FAILED);
93 }
94
95 // Allocate Encode Status Report
96 m_encodeCtx->pEncodeStatusReport = (void *)MOS_AllocAndZeroMemory(CODECHAL_ENCODE_STATUS_NUM * sizeof(EncodeStatusReport));
97 DDI_CHK_NULL(m_encodeCtx->pEncodeStatusReport, "nullptr m_encodeCtx->pEncodeStatusReport.", VA_STATUS_ERROR_ALLOCATION_FAILED);
98
99 // Create the bit stream buffer to hold the packed headers from application
100 m_encodeCtx->pbsBuffer = (PBSBuffer)MOS_AllocAndZeroMemory(sizeof(BSBuffer));
101 DDI_CHK_NULL(m_encodeCtx->pbsBuffer, "nullptr m_encodeCtx->pbsBuffer.", VA_STATUS_ERROR_ALLOCATION_FAILED);
102
103 uint32_t bufferSize = CODECHAL_VP8_FRAME_HEADER_SIZE;
104 m_encodeCtx->pbsBuffer->pBase = (uint8_t *)MOS_AllocAndZeroMemory(bufferSize);
105 DDI_CHK_NULL(m_encodeCtx->pbsBuffer->pBase, "nullptr m_encodeCtx->pbsBuffer->pBase.", VA_STATUS_ERROR_ALLOCATION_FAILED);
106
107 m_encodeCtx->pbsBuffer->BufferSize = bufferSize;
108
109 // calculate mv offset
110 uint32_t numMBs = DDI_CODEC_NUM_MACROBLOCKS_WIDTH(m_encodeCtx->dwFrameWidth) * DDI_CODEC_NUM_MACROBLOCKS_HEIGHT(m_encodeCtx->dwFrameHeight);
111
112 if (VA_RC_CQP == m_encodeCtx->uiRCMethod)
113 {
114 m_mvOffset = MOS_ALIGN_CEIL(CODECHAL_VP8_MB_CODE_SIZE * sizeof(uint32_t),
115 CODECHAL_VP8_MB_CODE_ALIGNMENT) *
116 numMBs;
117 }
118 else
119 {
120 m_mvOffset = MOS_ALIGN_CEIL(CODECHAL_VP8_MB_CODE_SIZE * sizeof(uint32_t) + CODECHAL_VP8_MB_MV_CODE_SIZE, CODECHAL_VP8_MB_CODE_ALIGNMENT) + MOS_ALIGN_CEIL(CODECHAL_VP8_MB_CODE_SIZE * sizeof(uint32_t), CODECHAL_VP8_MB_CODE_ALIGNMENT) * numMBs;
121 }
122
123 return vaStatus;
124 }
125
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)126 VAStatus DdiEncodeVp8::RenderPicture(VADriverContextP ctx, VAContextID context, VABufferID *buffers, int32_t numBuffers)
127 {
128 VAStatus vaStatus = VA_STATUS_SUCCESS;
129
130 DDI_FUNCTION_ENTER();
131
132 DDI_CHK_NULL(ctx, "nullptr context", VA_STATUS_ERROR_INVALID_CONTEXT);
133
134 DDI_MEDIA_CONTEXT *mediaCtx = DdiMedia_GetMediaContext(ctx);
135 DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
136
137 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_CONTEXT);
138 DDI_CHK_NULL(m_encodeCtx->pCodecHal, "nullptr m_encodeCtx->pCodecHal", VA_STATUS_ERROR_INVALID_CONTEXT);
139
140 for (int32_t i = 0; i < numBuffers; i++)
141 {
142 DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
143 DDI_CHK_NULL(buf, "Invalid buffer.", VA_STATUS_ERROR_INVALID_BUFFER);
144 if (buf->uiType == VAEncMacroblockDisableSkipMapBufferType)
145 {
146 DdiMedia_MediaBufferToMosResource(buf, &(m_encodeCtx->resPerMBSkipMapBuffer));
147 m_encodeCtx->bMbDisableSkipMapEnabled = true;
148 continue;
149 }
150 uint32_t dataSize = buf->iSize;
151 // can use internal function instead of DdiMedia_MapBuffer here?
152 void *data = nullptr;
153 DdiMedia_MapBuffer(ctx, buffers[i], &data);
154 DDI_CHK_NULL(data, "nullptr data.", VA_STATUS_ERROR_INVALID_BUFFER);
155
156 switch (buf->uiType)
157 {
158 case VAIQMatrixBufferType:
159 case VAQMatrixBufferType:
160 DDI_CHK_STATUS(Qmatrix(data), VA_STATUS_ERROR_INVALID_BUFFER);
161 break;
162
163 case VAEncSequenceParameterBufferType:
164 DDI_CHK_STATUS(ParseSeqParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
165 m_encodeCtx->bNewSeq = true;
166 break;
167
168 case VAEncPictureParameterBufferType:
169 DDI_CHK_STATUS(ParsePicParams(mediaCtx, data), VA_STATUS_ERROR_INVALID_BUFFER);
170
171 DDI_CHK_STATUS(
172 AddToStatusReportQueue((void *)m_encodeCtx->resBitstreamBuffer.bo),
173 VA_STATUS_ERROR_INVALID_BUFFER);
174 break;
175
176 case VAEncMiscParameterBufferType:
177 DDI_CHK_STATUS(ParseMiscParams(data), VA_STATUS_ERROR_INVALID_BUFFER);
178 break;
179
180 case VAEncMacroblockMapBufferType:
181 DDI_CHK_STATUS(ParseSegMapParams(buf), VA_STATUS_ERROR_INVALID_BUFFER);
182 break;
183
184 case VAEncQPBufferType:
185 DdiMedia_MediaBufferToMosResource(buf, &m_encodeCtx->resMBQpBuffer);
186 m_encodeCtx->bMBQpEnable = true;
187 break;
188
189 default:
190 DDI_ASSERTMESSAGE("not supported buffer type.");
191 break;
192 }
193 DdiMedia_UnmapBuffer(ctx, buffers[i]);
194 }
195
196 DDI_FUNCTION_EXIT(vaStatus);
197 return vaStatus;
198 }
199
StatusReport(DDI_MEDIA_BUFFER * mediaBuf,void ** buf)200 VAStatus DdiEncodeVp8::StatusReport(
201 DDI_MEDIA_BUFFER *mediaBuf,
202 void **buf)
203 {
204 DDI_CHK_NULL(m_encodeCtx->pCpDdiInterface, "nullptr m_encodeCtx->pCpDdiInterface", VA_STATUS_ERROR_INVALID_CONTEXT);
205 DDI_CHK_NULL(mediaBuf, "nullptr mediaBuf", VA_STATUS_ERROR_INVALID_PARAMETER);
206 DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_PARAMETER);
207
208 m_encodeCtx->BufMgr.pCodedBufferSegment->status = 0;
209
210 //when this function is called, there must be a frame is ready, will wait until get the right information.
211 uint32_t size = 0;
212 int32_t index = 0;
213 uint32_t status = 0;
214 uint32_t timeOutCount = 0;
215 VAStatus vaStatus = VA_STATUS_SUCCESS;
216
217 // Get encoded frame information from status buffer queue.
218 while (VA_STATUS_SUCCESS == (vaStatus = GetSizeFromStatusReportBuffer(mediaBuf, &size, &status, &index)))
219 {
220 if ((index >= 0) && (size != 0)) //Get the matched encoded buffer information
221 {
222 uint32_t sizeOfExtStatusReportBuf = 0; //reset or not used
223
224 // the first segment in the single-link list: pointer for the coded bitstream and the size
225 m_encodeCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(mediaBuf, MOS_LOCKFLAG_READONLY);
226 m_encodeCtx->BufMgr.pCodedBufferSegment->size = size;
227 m_encodeCtx->BufMgr.pCodedBufferSegment->status = status;
228
229 //making a segment for the StatusReport: pointer for the StatusReport and the size of it
230 VACodedBufferSegment *pVACodedBufferSegmentForStatusReport;
231 pVACodedBufferSegmentForStatusReport = m_encodeCtx->BufMgr.pCodedBufferSegmentForStatusReport;
232 DDI_CHK_NULL(pVACodedBufferSegmentForStatusReport, "nullptr check in pVACodedBufferSegmentForStatusReport", VA_STATUS_ERROR_INVALID_CONTEXT);
233
234 pVACodedBufferSegmentForStatusReport->size = sizeOfExtStatusReportBuf;
235 pVACodedBufferSegmentForStatusReport->buf = (void *)((char *)(m_encodeCtx->BufMgr.pCodedBufferSegment->buf) + size);
236 pVACodedBufferSegmentForStatusReport->next = nullptr;
237
238 VACodedBufferSegment *pFindTheLastEntry;
239 pFindTheLastEntry = m_encodeCtx->BufMgr.pCodedBufferSegment;
240 // if HDCP2 is enabled, the second segment for counter values is already there So, move the connection as the third one
241 if (m_encodeCtx->pCpDdiInterface->IsHdcp2Enabled())
242 pFindTheLastEntry = (VACodedBufferSegment *)pFindTheLastEntry->next;
243 // connect Status report here
244 pFindTheLastEntry->next = pVACodedBufferSegmentForStatusReport;
245
246 break;
247 }
248
249 mos_bo_wait_rendering(mediaBuf->bo);
250
251 EncodeStatusReport* encodeStatusReport = (EncodeStatusReport*)m_encodeCtx->pEncodeStatusReport;
252 encodeStatusReport->bSequential = true; //Query the encoded frame status in sequential.
253
254 uint16_t numStatus = 1;
255 m_encodeCtx->pCodecHal->GetStatusReport(encodeStatusReport, numStatus);
256
257 if (CODECHAL_STATUS_SUCCESSFUL == encodeStatusReport[0].CodecStatus)
258 {
259 // Only AverageQP is reported at this time. Populate other bits with relevant informaiton later;
260 status = (encodeStatusReport[0].AverageQp & VA_CODED_BUF_STATUS_PICTURE_AVE_QP_MASK);
261 // fill hdcp related buffer
262 DDI_CHK_RET(m_encodeCtx->pCpDdiInterface->StatusReportForHdcp2Buffer(&m_encodeCtx->BufMgr, encodeStatusReport), "fail to get hdcp2 status report!");
263 if (UpdateStatusReportBuffer(encodeStatusReport[0].bitstreamSize, status) != VA_STATUS_SUCCESS)
264 {
265 m_encodeCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(mediaBuf, MOS_LOCKFLAG_READONLY);
266 m_encodeCtx->BufMgr.pCodedBufferSegment->size = 0;
267 m_encodeCtx->BufMgr.pCodedBufferSegment->status |= VA_CODED_BUF_STATUS_BAD_BITSTREAM;
268 m_encodeCtx->statusReportBuf.ulUpdatePosition = (m_encodeCtx->statusReportBuf.ulUpdatePosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
269 break;
270 }
271 //Add encoded frame information into status buffer queue.
272 continue;
273 }
274 else if (CODECHAL_STATUS_INCOMPLETE == encodeStatusReport[0].CodecStatus)
275 {
276 CodechalEncoderState *encoder = dynamic_cast<CodechalEncoderState *>(m_encodeCtx->pCodecHal);
277 if (encoder != nullptr && encoder->m_inlineEncodeStatusUpdate)
278 {
279 m_encodeCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(mediaBuf, MOS_LOCKFLAG_READONLY);
280 m_encodeCtx->BufMgr.pCodedBufferSegment->size = 0;
281 m_encodeCtx->BufMgr.pCodedBufferSegment->status |= VA_CODED_BUF_STATUS_BAD_BITSTREAM;
282 m_encodeCtx->statusReportBuf.ulUpdatePosition = (m_encodeCtx->statusReportBuf.ulUpdatePosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
283 DDI_ASSERTMESSAGE("Something unexpected happened in HW, return error to application");
284 break;
285 }
286 // Wait until encode PAK complete, sometimes we application detect encoded buffer object is Idle, may Enc done, but Pak not.
287 uint32_t maxTimeOut = 100000; //set max sleep times to 100000 = 1s, other wise return error.
288 if (timeOutCount < maxTimeOut)
289 {
290 //sleep 10 us to wait encode complete, it won't impact the performance.
291 uint32_t sleepTime = 10; //sleep 10 us when encode is not complete.
292 usleep(sleepTime);
293 timeOutCount++;
294 continue;
295 }
296 else
297 {
298 //if HW didn't response in 1s, assume there is an error in encoding process, return error to App.
299 m_encodeCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(mediaBuf, MOS_LOCKFLAG_READONLY);
300 m_encodeCtx->BufMgr.pCodedBufferSegment->size = 0;
301 m_encodeCtx->BufMgr.pCodedBufferSegment->status |= VA_CODED_BUF_STATUS_BAD_BITSTREAM;
302 m_encodeCtx->statusReportBuf.ulUpdatePosition = (m_encodeCtx->statusReportBuf.ulUpdatePosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
303 DDI_ASSERTMESSAGE("Something unexpected happened in HW, return error to application");
304 break;
305 }
306 }
307 else if (CODECHAL_STATUS_ERROR == encodeStatusReport[0].CodecStatus)
308 {
309 DDI_NORMALMESSAGE("Encoding failure due to HW issue");
310 m_encodeCtx->BufMgr.pCodedBufferSegment->buf = DdiMediaUtil_LockBuffer(mediaBuf, MOS_LOCKFLAG_READONLY);
311 m_encodeCtx->BufMgr.pCodedBufferSegment->size = 0;
312 m_encodeCtx->BufMgr.pCodedBufferSegment->status |= VA_CODED_BUF_STATUS_BAD_BITSTREAM;
313 m_encodeCtx->statusReportBuf.ulUpdatePosition = (m_encodeCtx->statusReportBuf.ulUpdatePosition + 1) % DDI_ENCODE_MAX_STATUS_REPORT_BUFFER;
314 break;
315 }
316 else
317 {
318 break;
319 }
320 }
321
322 if (vaStatus != VA_STATUS_SUCCESS)
323 {
324 return vaStatus;
325 }
326
327 *buf = m_encodeCtx->BufMgr.pCodedBufferSegment;
328 return vaStatus;
329 }
330
InitCompBuffer()331 VAStatus DdiEncodeVp8::InitCompBuffer()
332 {
333 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx.", VA_STATUS_ERROR_INVALID_CONTEXT);
334 DDI_CHK_NULL(m_encodeCtx->pCpDdiInterface, "nullptr m_encodeCtx->pCpDdiInterface.", VA_STATUS_ERROR_INVALID_CONTEXT);
335
336 DDI_CODEC_COM_BUFFER_MGR *pBufMgr = &(m_encodeCtx->BufMgr);
337
338 // memory allocation in the beging of the sequence for extended StatusReport and then save it from DDI_CODEC_COM_BUFFER_MGR, for example, VP8
339 VACodedBufferSegment *pVACodedBufferSegmentForStatusReport = (VACodedBufferSegment *)MOS_AllocAndZeroMemory(sizeof(VACodedBufferSegment));
340 if (pVACodedBufferSegmentForStatusReport == nullptr)
341 {
342 return VA_STATUS_ERROR_ALLOCATION_FAILED;
343 }
344 pBufMgr->pCodedBufferSegmentForStatusReport = pVACodedBufferSegmentForStatusReport;
345
346 DDI_CHK_RET(DdiEncodeBase::InitCompBuffer(), "InitCompBuffer failed!");
347
348 return VA_STATUS_SUCCESS;
349 }
350
FreeCompBuffer()351 void DdiEncodeVp8::FreeCompBuffer()
352 {
353 DdiEncodeBase::FreeCompBuffer();
354
355 DDI_CODEC_COM_BUFFER_MGR *pBufMgr = &(m_encodeCtx->BufMgr);
356 if (pBufMgr->pCodedBufferSegmentForStatusReport != nullptr)
357 {
358 MOS_FreeMemory(pBufMgr->pCodedBufferSegmentForStatusReport);
359 pBufMgr->pCodedBufferSegmentForStatusReport = nullptr;
360 }
361 }
362
ResetAtFrameLevel()363 VAStatus DdiEncodeVp8::ResetAtFrameLevel()
364 {
365 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
366
367 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)(m_encodeCtx->pSeqParams);
368 DDI_CHK_NULL(seqParams, "nullptr seqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
369 seqParams->ResetBRC = 0x0;
370
371 // reset bsbuffer every frame
372 m_encodeCtx->pbsBuffer->pCurrent = m_encodeCtx->pbsBuffer->pBase;
373 m_encodeCtx->pbsBuffer->SliceOffset = 0x0;
374 m_encodeCtx->pbsBuffer->BitOffset = 0x0;
375 m_encodeCtx->pbsBuffer->BitSize = 0x0;
376
377 return VA_STATUS_SUCCESS;
378 }
379
Qmatrix(void * ptr)380 VAStatus DdiEncodeVp8::Qmatrix(void *ptr)
381 {
382 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
383 DDI_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
384
385 VAQMatrixBufferVP8 *quantParams = (VAQMatrixBufferVP8 *)ptr;
386
387 CODEC_VP8_ENCODE_QUANT_DATA *vp8QuantParams = (CODEC_VP8_ENCODE_QUANT_DATA *)(m_encodeCtx->pQmatrixParams);
388 DDI_CHK_NULL(vp8QuantParams, "nullptr vp8QuantParams", VA_STATUS_ERROR_INVALID_PARAMETER);
389
390 MOS_ZeroMemory(vp8QuantParams, sizeof(CODEC_VP8_ENCODE_QUANT_DATA));
391
392 for (int32_t i = 0; i < 4; i++)
393 {
394 vp8QuantParams->QIndex[i] = quantParams->quantization_index[i];
395 }
396
397 for (int32_t i = 0; i < 5; i++)
398 {
399 vp8QuantParams->QIndexDelta[i] = quantParams->quantization_index_delta[i];
400 }
401
402 return VA_STATUS_SUCCESS;
403 }
404
ParseSeqParams(void * ptr)405 VAStatus DdiEncodeVp8::ParseSeqParams(void *ptr)
406 {
407 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
408 DDI_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
409
410 VAEncSequenceParameterBufferVP8 *seqParams = (VAEncSequenceParameterBufferVP8 *)ptr;
411
412 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *vp8SeqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)(m_encodeCtx->pSeqParams);
413 DDI_CHK_NULL(vp8SeqParams, "nullptr vp8SeqParams", VA_STATUS_ERROR_INVALID_PARAMETER);
414
415 MOS_ZeroMemory(vp8SeqParams, sizeof(CODEC_VP8_ENCODE_SEQUENCE_PARAMS));
416
417 vp8SeqParams->FrameWidth = seqParams->frame_width;
418 vp8SeqParams->FrameWidthScale = seqParams->frame_width_scale;
419 vp8SeqParams->FrameHeight = seqParams->frame_height;
420 vp8SeqParams->FrameHeightScale = seqParams->frame_height_scale;
421
422 vp8SeqParams->GopPicSize = seqParams->intra_period;
423
424 vp8SeqParams->TargetBitRate[0] = MOS_ROUNDUP_DIVIDE(seqParams->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
425
426 return VA_STATUS_SUCCESS;
427 }
428
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)429 VAStatus DdiEncodeVp8::ParsePicParams(DDI_MEDIA_CONTEXT *mediaCtx, void *ptr)
430 {
431 DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
432 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
433 DDI_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
434
435 VAEncPictureParameterBufferVP8 *picParams = (VAEncPictureParameterBufferVP8 *)ptr;
436
437 CODEC_VP8_ENCODE_PIC_PARAMS *vp8PicParams = (CODEC_VP8_ENCODE_PIC_PARAMS *)(m_encodeCtx->pPicParams);
438 DDI_CHK_NULL(vp8PicParams, "nullptr vp8PicParams", VA_STATUS_ERROR_INVALID_PARAMETER);
439
440 MOS_ZeroMemory(vp8PicParams, sizeof(CODEC_VP8_ENCODE_PIC_PARAMS));
441
442 vp8PicParams->frame_type = picParams->pic_flags.bits.frame_type;
443 vp8PicParams->version = picParams->pic_flags.bits.version;
444 vp8PicParams->show_frame = picParams->pic_flags.bits.show_frame;
445 vp8PicParams->color_space = picParams->pic_flags.bits.color_space;
446 vp8PicParams->clamping_type = picParams->pic_flags.bits.clamping_type;
447 vp8PicParams->segmentation_enabled = picParams->pic_flags.bits.segmentation_enabled;
448 vp8PicParams->update_mb_segmentation_map = picParams->pic_flags.bits.update_mb_segmentation_map;
449 vp8PicParams->update_segment_feature_data = picParams->pic_flags.bits.update_segment_feature_data;
450 vp8PicParams->filter_type = picParams->pic_flags.bits.loop_filter_type;
451 vp8PicParams->loop_filter_adj_enable = picParams->pic_flags.bits.loop_filter_adj_enable;
452 vp8PicParams->CodedCoeffTokenPartition = picParams->pic_flags.bits.num_token_partitions;
453 vp8PicParams->refresh_golden_frame = picParams->pic_flags.bits.refresh_golden_frame;
454 vp8PicParams->refresh_alternate_frame = picParams->pic_flags.bits.refresh_alternate_frame;
455 vp8PicParams->copy_buffer_to_golden = picParams->pic_flags.bits.copy_buffer_to_golden;
456 vp8PicParams->copy_buffer_to_alternate = picParams->pic_flags.bits.copy_buffer_to_alternate;
457 vp8PicParams->sign_bias_golden = picParams->pic_flags.bits.sign_bias_golden;
458 vp8PicParams->sign_bias_alternate = picParams->pic_flags.bits.sign_bias_alternate;
459 vp8PicParams->refresh_entropy_probs = picParams->pic_flags.bits.refresh_entropy_probs;
460 vp8PicParams->refresh_last = picParams->pic_flags.bits.refresh_last;
461 vp8PicParams->mb_no_coeff_skip = picParams->pic_flags.bits.mb_no_coeff_skip;
462 vp8PicParams->forced_lf_adjustment = picParams->pic_flags.bits.forced_lf_adjustment;
463
464 if (vp8PicParams->frame_type == 0)
465 {
466 vp8PicParams->ref_frame_ctrl = 0;
467 }
468 else
469 {
470 vp8PicParams->ref_frame_ctrl = (!picParams->ref_flags.bits.no_ref_last) | ((!picParams->ref_flags.bits.no_ref_gf) << 1) | ((!picParams->ref_flags.bits.no_ref_arf) << 2);
471 }
472
473 // first_ref and second_ref parameters are currently passed through the reserved parameter by the application
474 vp8PicParams->first_ref = picParams->ref_flags.bits.first_ref;
475 vp8PicParams->second_ref = picParams->ref_flags.bits.second_ref;
476 #ifdef ANDROID
477 vp8PicParams->temporal_id = picParams->ref_flags.bits.temporal_id;
478 #endif
479 // Copy list of 4 loop filter level values, delta values for ref frame and coding mode based MB-level
480 for (int32_t i = 0; i < 4; i++)
481 {
482 vp8PicParams->loop_filter_level[i] = picParams->loop_filter_level[i];
483 vp8PicParams->ref_lf_delta[i] = picParams->ref_lf_delta[i];
484 vp8PicParams->mode_lf_delta[i] = picParams->mode_lf_delta[i];
485 }
486
487 vp8PicParams->sharpness_level = picParams->sharpness_level;
488 vp8PicParams->ClampQindexHigh = picParams->clamp_qindex_high;
489 vp8PicParams->ClampQindexLow = picParams->clamp_qindex_low;
490
491 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
492
493 rtTbl->pCurrentReconTarget = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParams->reconstructed_frame);
494 DDI_CHK_NULL(rtTbl->pCurrentReconTarget, "nullptr rtTbl->pCurrentReconTarget", VA_STATUS_ERROR_INVALID_PARAMETER);
495 DDI_CHK_RET(RegisterRTSurfaces(rtTbl,rtTbl->pCurrentReconTarget), "register RT surfaces error");
496
497 SetupCodecPicture(mediaCtx, rtTbl, &vp8PicParams->CurrReconstructedPic, picParams->reconstructed_frame, false);
498 // curr orig pic
499 vp8PicParams->CurrOriginalPic.FrameIdx = GetRenderTargetID(rtTbl, rtTbl->pCurrentReconTarget);
500 vp8PicParams->CurrOriginalPic.PicFlags = vp8PicParams->CurrReconstructedPic.PicFlags;
501
502 SetupCodecPicture(mediaCtx, rtTbl, &vp8PicParams->LastRefPic, picParams->ref_last_frame, true);
503
504 SetupCodecPicture(mediaCtx, rtTbl, &vp8PicParams->GoldenRefPic, picParams->ref_gf_frame, true);
505
506 SetupCodecPicture(mediaCtx, rtTbl, &vp8PicParams->AltRefPic, picParams->ref_arf_frame, true);
507
508 DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, picParams->coded_buf);
509 DDI_CHK_NULL(buf, "nullptr buf", VA_STATUS_ERROR_INVALID_PARAMETER);
510 RemoveFromStatusReportQueue(buf);
511 DdiMedia_MediaBufferToMosResource(buf, &(m_encodeCtx->resBitstreamBuffer));
512
513 return VA_STATUS_SUCCESS;
514 }
515
516 // Parse Misc Params
ParseMiscParams(void * ptr)517 VAStatus DdiEncodeVp8::ParseMiscParams(void *ptr)
518 {
519 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
520 DDI_CHK_NULL(ptr, "nullptr ptr", VA_STATUS_ERROR_INVALID_PARAMETER);
521
522 VAEncMiscParameterBuffer *miscParamBuf = (VAEncMiscParameterBuffer *)ptr;
523 DDI_CHK_NULL(miscParamBuf->data, "nullptr miscParamBuf->data", VA_STATUS_ERROR_INVALID_PARAMETER);
524
525 switch ((int32_t)(miscParamBuf->type))
526 {
527 case VAEncMiscParameterTypeHRD:
528 {
529 ParseMiscParamVBV((void *)miscParamBuf->data);
530 break;
531 }
532 case VAEncMiscParameterTypeFrameRate:
533 {
534 ParseMiscParamFR((void *)miscParamBuf->data);
535 break;
536 }
537 case VAEncMiscParameterTypeQualityLevel: // for target usage
538 {
539 ParseBufferQualityLevel((void *)miscParamBuf->data);
540 break;
541 }
542 case VAEncMiscParameterTypeRateControl:
543 {
544 ParseMiscParamRC((void *)miscParamBuf->data);
545 break;
546 }
547 case VAEncMiscParameterTypeTemporalLayerStructure:
548 {
549 ParseMiscParameterTemporalLayerParams((void *)miscParamBuf->data);
550 break;
551 }
552 default:
553 {
554 DDI_ASSERTMESSAGE("DDI: unsupported misc parameter type.");
555 return VA_STATUS_ERROR_INVALID_PARAMETER;
556 }
557 }
558
559 return VA_STATUS_SUCCESS;
560 }
561
EncodeInCodecHal(uint32_t numSlices)562 VAStatus DdiEncodeVp8::EncodeInCodecHal(uint32_t numSlices)
563 {
564 DDI_UNUSED(numSlices);
565
566 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_encodeCtx->RTtbl);
567
568 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (PCODEC_VP8_ENCODE_SEQUENCE_PARAMS)(m_encodeCtx->pSeqParams);
569
570 EncoderParams encodeParams;
571 MOS_ZeroMemory(&encodeParams, sizeof(EncoderParams));
572 encodeParams.ExecCodecFunction = m_encodeCtx->codecFunction;
573
574 // Raw Surface
575 MOS_SURFACE rawSurface;
576 MOS_ZeroMemory(&rawSurface, sizeof(MOS_SURFACE));
577 rawSurface.Format = Format_NV12;
578 rawSurface.dwOffset = 0;
579
580 DdiMedia_MediaSurfaceToMosResource(rtTbl->pCurrentRT, &(rawSurface.OsResource));
581 // Recon Surface
582 MOS_SURFACE reconSurface;
583 MOS_ZeroMemory(&reconSurface, sizeof(MOS_SURFACE));
584 reconSurface.Format = Format_NV12;
585 reconSurface.dwOffset = 0;
586
587 DdiMedia_MediaSurfaceToMosResource(rtTbl->pCurrentReconTarget, &(reconSurface.OsResource));
588 // Bitstream surface
589 MOS_RESOURCE bitstreamSurface;
590 MOS_ZeroMemory(&bitstreamSurface, sizeof(MOS_RESOURCE));
591 bitstreamSurface = m_encodeCtx->resBitstreamBuffer; // in render picture
592 bitstreamSurface.Format = Format_Buffer;
593
594 MOS_RESOURCE mbCodeSurface;
595 MOS_ZeroMemory(&mbCodeSurface, sizeof(MOS_RESOURCE));
596 mbCodeSurface = m_encodeCtx->resMbCodeBuffer;
597 encodeParams.psRawSurface = &rawSurface;
598 encodeParams.psReconSurface = &reconSurface;
599 encodeParams.presBitstreamBuffer = &bitstreamSurface;
600 encodeParams.presMbCodeSurface = &mbCodeSurface;
601
602 // Segmentation map buffer
603 encodeParams.psMbSegmentMapSurface = &m_encodeCtx->segMapBuffer;
604
605 if (VA_RC_CQP == m_encodeCtx->uiRCMethod)
606 {
607 seqParams->RateControlMethod = RATECONTROL_CQP;
608 seqParams->TargetBitRate[0] = 0;
609 seqParams->MaxBitRate = 0;
610 seqParams->MinBitRate = 0;
611 seqParams->InitVBVBufferFullnessInBit = 0;
612 seqParams->VBVBufferSizeInBit = 0;
613 }
614 else if (VA_RC_CBR == m_encodeCtx->uiRCMethod)
615 {
616 seqParams->RateControlMethod = RATECONTROL_CBR;
617 seqParams->MaxBitRate = seqParams->TargetBitRate[0];
618 seqParams->MinBitRate = seqParams->TargetBitRate[0];
619 }
620 else if (VA_RC_VBR == m_encodeCtx->uiRCMethod)
621 {
622 seqParams->RateControlMethod = RATECONTROL_VBR;
623 }
624 if((m_encodeCtx->uiTargetBitRate != seqParams->TargetBitRate[0]) || (m_encodeCtx->uiMaxBitRate != seqParams-> MaxBitRate))
625 {
626 if(m_encodeCtx->uiTargetBitRate )
627 {
628 seqParams->ResetBRC = 0x1;
629 }
630 m_encodeCtx->uiTargetBitRate = seqParams->TargetBitRate[0];
631 m_encodeCtx->uiMaxBitRate = seqParams->MaxBitRate;
632 }
633
634 encodeParams.pSeqParams = m_encodeCtx->pSeqParams;
635 encodeParams.pPicParams = m_encodeCtx->pPicParams;
636 encodeParams.pSliceParams = m_encodeCtx->pSliceParams;
637
638 encodeParams.uiFrameRate = m_encodeCtx->uFrameRate;
639
640 // Sequence data
641 encodeParams.bNewSeq = m_encodeCtx->bNewSeq;
642
643 // IQmatrix params
644 encodeParams.bNewQmatrixData = m_encodeCtx->bNewQmatrixData;
645 encodeParams.bPicQuant = m_encodeCtx->bPicQuant;
646
647 encodeParams.pQuantData = m_encodeCtx->pQmatrixParams;
648
649 encodeParams.pBSBuffer = m_encodeCtx->pbsBuffer;
650
651 MOS_STATUS status = m_encodeCtx->pCodecHal->Execute(&encodeParams);
652 if (MOS_STATUS_SUCCESS != status)
653 {
654 DDI_ASSERTMESSAGE("DDI:Failed in Codechal!");
655 return VA_STATUS_ERROR_ENCODING_ERROR;
656 }
657
658 return VA_STATUS_SUCCESS;
659 }
660
ParseSegMapParams(DDI_MEDIA_BUFFER * buf)661 VAStatus DdiEncodeVp8::ParseSegMapParams(DDI_MEDIA_BUFFER *buf)
662 {
663 DDI_CHK_NULL(m_encodeCtx, "nullptr m_encodeCtx", VA_STATUS_ERROR_INVALID_PARAMETER);
664
665 MOS_ZeroMemory(&(m_encodeCtx->segMapBuffer), sizeof(MOS_SURFACE));
666 m_encodeCtx->segMapBuffer.Format = Format_Buffer_2D;
667 m_encodeCtx->segMapBuffer.dwOffset = 0;
668 DdiMedia_MediaBufferToMosResource(buf, &((m_encodeCtx->segMapBuffer).OsResource));
669 return VA_STATUS_SUCCESS;
670 }
671
AddExtStatusReportParam(DDI_MEDIA_BUFFER * buf,uint32_t size)672 uint32_t DdiEncodeVp8::AddExtStatusReportParam(DDI_MEDIA_BUFFER *buf, uint32_t size)
673 {
674 return 0;
675 }
676
ParseBufferQualityLevel(void * data)677 void DdiEncodeVp8::ParseBufferQualityLevel(void *data)
678 {
679 VAEncMiscParameterBufferQualityLevel *vaEncMiscParamQualityLevel = (VAEncMiscParameterBufferQualityLevel *)data;
680
681 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)m_encodeCtx->pSeqParams;
682 seqParams->TargetUsage = vaEncMiscParamQualityLevel->quality_level;
683 }
684
ParseMiscParamVBV(void * data)685 void DdiEncodeVp8::ParseMiscParamVBV(void *data)
686 {
687 VAEncMiscParameterHRD *vaEncMiscParamHRD = (VAEncMiscParameterHRD *)data;
688
689 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)m_encodeCtx->pSeqParams;
690
691 seqParams->VBVBufferSizeInBit = vaEncMiscParamHRD->buffer_size;
692 seqParams->InitVBVBufferFullnessInBit = vaEncMiscParamHRD->initial_buffer_fullness;
693 seqParams->RateControlMethod = RATECONTROL_CBR;
694 }
695
ParseMiscParamFR(void * data)696 void DdiEncodeVp8::ParseMiscParamFR(void *data)
697 {
698 VAEncMiscParameterFrameRate *vaFrameRate = (VAEncMiscParameterFrameRate *)data;
699 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (PCODEC_VP8_ENCODE_SEQUENCE_PARAMS)m_encodeCtx->pSeqParams;
700
701 uint32_t numerator = (vaFrameRate->framerate & 0xffff) * 100;
702 auto denominator = (vaFrameRate->framerate >> 16)&0xfff;
703 if(denominator == 0)
704 {
705 denominator = 1;
706 }
707
708 uint32_t tmpId = 0;
709 #ifdef ANDROID
710 tmpId = vaFrameRate->framerate_flags.bits.temporal_id;
711 #endif
712 seqParams->FramesPer100Sec[tmpId] = numerator/denominator;
713 if(m_framesPer100Sec && m_framesPer100Sec != seqParams->FramesPer100Sec[tmpId])
714 {
715 seqParams->ResetBRC = 0x1;
716 }
717 m_framesPer100Sec = seqParams->FramesPer100Sec[tmpId];
718 }
719
ParseMiscParamRC(void * data)720 void DdiEncodeVp8::ParseMiscParamRC(void *data)
721 {
722 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)(m_encodeCtx->pSeqParams);
723
724 VAEncMiscParameterRateControl *vaEncMiscParamRC = (VAEncMiscParameterRateControl *)data;
725
726 uint32_t tmpId = 0;
727 #ifdef ANDROID
728 tmpId = vaEncMiscParamRC->rc_flags.bits.temporal_id;
729 #endif
730 seqParams->MaxBitRate = MOS_ROUNDUP_DIVIDE(vaEncMiscParamRC->bits_per_second, CODECHAL_ENCODE_BRC_KBPS);
731 seqParams->TargetBitRate[tmpId] = seqParams->MaxBitRate;
732 seqParams->ResetBRC = vaEncMiscParamRC->rc_flags.bits.reset; // adding reset here. will apply both CBR and VBR
733 seqParams->MBBRC = vaEncMiscParamRC->rc_flags.bits.mb_rate_control;
734
735 if (VA_RC_CBR == m_encodeCtx->uiRCMethod)
736 {
737 seqParams->MinBitRate = seqParams->MaxBitRate;
738 seqParams->RateControlMethod = RATECONTROL_CBR;
739 }
740 else if (VA_RC_VBR == m_encodeCtx->uiRCMethod)
741 {
742 seqParams->MinBitRate = seqParams->MaxBitRate * (2 * vaEncMiscParamRC->target_percentage - 100) / 100;
743 seqParams->TargetBitRate[tmpId] = seqParams->MaxBitRate * vaEncMiscParamRC->target_percentage / 100; // VBR target bits
744 seqParams->RateControlMethod = RATECONTROL_VBR;
745 }
746 }
747
ParseMiscParamPrivate(void * data)748 void DdiEncodeVp8::ParseMiscParamPrivate(void *data)
749 {
750 DDI_UNUSED(data);
751 // Nothing to do here
752 return;
753 }
754
ParseMiscParameterTemporalLayerParams(void * data)755 void DdiEncodeVp8::ParseMiscParameterTemporalLayerParams(void *data)
756 {
757 CODEC_VP8_ENCODE_SEQUENCE_PARAMS *seqParams = (CODEC_VP8_ENCODE_SEQUENCE_PARAMS *)(m_encodeCtx->pSeqParams);
758
759 VAEncMiscParameterTemporalLayerStructure *vaEncTempLayerStruct = (VAEncMiscParameterTemporalLayerStructure *)data;
760
761 if (vaEncTempLayerStruct->number_of_layers > 0)
762 {
763 seqParams->NumTemporalLayersMinus1 = vaEncTempLayerStruct->number_of_layers - 1;
764 }
765 else
766 {
767 seqParams->NumTemporalLayersMinus1 = 0;
768 }
769 }
770
SetupCodecPicture(DDI_MEDIA_CONTEXT * mediaCtx,DDI_CODEC_RENDER_TARGET_TABLE * rtTbl,CODEC_PICTURE * codecHalPic,VASurfaceID surfaceID,bool picReference)771 void DdiEncodeVp8::SetupCodecPicture(
772 DDI_MEDIA_CONTEXT *mediaCtx,
773 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl,
774 CODEC_PICTURE *codecHalPic,
775 VASurfaceID surfaceID,
776 bool picReference)
777 {
778 if(DDI_CODEC_INVALID_FRAME_INDEX != surfaceID)
779 {
780 DDI_MEDIA_SURFACE *surface = DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, surfaceID);
781 codecHalPic->FrameIdx = GetRenderTargetID(rtTbl, surface);
782 }
783 else
784 {
785 codecHalPic->FrameIdx = (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX;
786 }
787
788 if (picReference)
789 {
790 if (codecHalPic->FrameIdx == (uint8_t)DDI_CODEC_INVALID_FRAME_INDEX)
791 {
792 codecHalPic->PicFlags = PICTURE_INVALID;
793 }
794 else
795 {
796 codecHalPic->PicFlags = PICTURE_SHORT_TERM_REFERENCE; // No long term references in VP8
797 }
798 }
799 else
800 {
801 codecHalPic->PicFlags = PICTURE_FRAME;
802 }
803 }
804
getSequenceParameterBufferSize()805 uint32_t DdiEncodeVp8::getSequenceParameterBufferSize()
806 {
807 return sizeof(VAEncSequenceParameterBufferVP8);
808 }
809
getPictureParameterBufferSize()810 uint32_t DdiEncodeVp8::getPictureParameterBufferSize()
811 {
812 return sizeof(VAEncPictureParameterBufferVP8);
813 }
814
getQMatrixBufferSize()815 uint32_t DdiEncodeVp8::getQMatrixBufferSize()
816 {
817 return sizeof(VAQMatrixBufferVP8);
818 }
819