xref: /aosp_15_r20/external/intel-media-driver/media_driver/linux/common/codec/ddi/media_ddi_encode_vp8.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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