1 /*
2 * Copyright (c) 2020-2023, 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     encode_vp9_hpu.h
24 //! \brief    Defines the common interface for vp9 encode hpu (header probabiloity update) features
25 //!
26 #ifndef __ENCODE_VP9_HPU_H__
27 #define __ENCODE_VP9_HPU_H__
28 
29 #include "encode_vp9_basic_feature.h"
30 #include "media_vp9_packet_defs.h"
31 #include "codec_def_vp9_probs.h"
32 
33 namespace encode
34 {
35 
36 class Vp9EncodeHpu : public MediaFeature, public mhw::vdbox::huc::Itf::ParSetting, public mhw::vdbox::hcp::Itf::ParSetting
37 {
38 public:
39     //!
40     //! \brief  Vp9EncodeHpu feature constructor
41     //!
42     //! \param  [in] featureManager
43     //!         Pointer to MediaFeatureManager
44     //! \param  [in] allocator
45     //!         Pointer to EncodeAllocator
46     //! \param  [in] hwInterface
47     //!         Pointer to CodechalHwInterface
48     //! \param  [in] constSettings
49     //!         Pointer to const settings
50     //!
51     Vp9EncodeHpu(
52         MediaFeatureManager *featureManager,
53         EncodeAllocator *    allocator,
54         CodechalHwInterfaceNext *hwInterface,
55         void *               constSettings);
56 
57     //!
58     //! \brief  Vp9EncodeHpu feature destructor
59     //!
~Vp9EncodeHpu()60     virtual ~Vp9EncodeHpu() {}
61 
62     //!
63     //! \brief  Init CQP basic features related parameter
64     //! \param  [in] settings
65     //!         Pointer to settings
66     //! \return MOS_STATUS
67     //!         MOS_STATUS_SUCCESS if success, else fail reason
68     //!
69     MOS_STATUS Init(void *settings) override;
70 
71     //!
72     //! \brief  Update CQP basic features related parameter
73     //! \param  [in] params
74     //!         Pointer to parameters
75     //! \return MOS_STATUS
76     //!         MOS_STATUS_SUCCESS if success, else fail reason
77     //!
78     MOS_STATUS Update(void *params) override;
79 
80     //!
81     //! \brief  Set regions for huc prob
82     //! \param  [in] params
83     //!         Pointer to parameters
84     //! \return MOS_STATUS
85     //!         MOS_STATUS_SUCCESS if success, else fail reason
86     //!
87     MOS_STATUS SetRegions(
88         mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR &params) const;
89 
90     //!
91     //! \brief  Get probability buffer
92     //! \param  [in] idx
93     //!         Index of the probability buffer
94     //! \param  [out] buffer
95     //!         Reference to the buffer get from Brc feature
96     //! \return MOS_STATUS
97     //!         MOS_STATUS_SUCCESS if success, else fail reason
98     //!
99     virtual MOS_STATUS GetProbabilityBuffer(
100         uint32_t       idx,
101         PMOS_RESOURCE &buffer);
102 
103     //!
104     //! \brief  Get huc probability dmem buffer
105     //! \param  [in] idx
106     //!         Index of the huc probability dmem buffer
107     //! \param  [out] buffer
108     //!         Reference to the buffer get from Brc feature
109     //! \return MOS_STATUS
110     //!         MOS_STATUS_SUCCESS if success, else fail reason
111     //!
112     virtual MOS_STATUS GetHucProbDmemBuffer(
113         uint32_t       idx,
114         PMOS_RESOURCE &buffer);
115 
116     //!
117     //! \brief  Set Last Pass flag
118     //! \param  [in] bool
119     //!         Last Pass
120     //! \return MOS_STATUS
121     //!         MOS_STATUS_SUCCESS if success, else fail reason
122     //!
123     MOS_STATUS SetIsLastPass(bool isLastPass);
124 
125     //!
126     //! \brief    Set default tx probs
127     //! \details
128     //! \param    [in,out] ctxBuffer
129     //!           Pointer to context buffer
130     //! \param    [in,out] byteCnt
131     //!           Numbe rof bytes counter
132     //! \return   MOS_STATUS
133     //!           MOS_STATUS_SUCCESS if success, else fail reason
134     //!
135     MOS_STATUS SetDefaultTxProbs(
136         uint8_t  *ctxBuffer,
137         uint32_t &byteCnt) const;
138 
139     //!
140     //! \brief    Set default coeff probs
141     //! \details
142     //! \param    [in,out] ctxBuffer
143     //!           Pointer to context buffer
144     //! \param    [in,out] byteCnt
145     //!           Numbe rof bytes counter
146     //! \return   MOS_STATUS
147     //!           MOS_STATUS_SUCCESS if success, else fail reason
148     //!
149     MOS_STATUS SetDefaultCoeffProbs(
150         uint8_t  *ctxBuffer,
151         uint32_t &byteCnt) const;
152 
153     //!
154     //! \brief    Set default mb skip probs
155     //! \details
156     //! \param    [in,out] ctxBuffer
157     //!           Pointer to context buffer
158     //! \param    [in,out] byteCnt
159     //!           Numbe rof bytes counter
160     //! \return   MOS_STATUS
161     //!           MOS_STATUS_SUCCESS if success, else fail reason
162     //!
163     MOS_STATUS SetDefaultMbskipProbs(
164         uint8_t  *ctxBuffer,
165         uint32_t &byteCnt) const;
166 
167     //!
168     //! \brief    Populate prob values which are different between Key and Non-Key frame
169     //! \details
170     //! \param    [in,out] ctxBuffer
171     //!           Pointer to context buffer
172     //! \param    [in] setToKey
173     //!           Specify if it's key frame
174     //! \return   MOS_STATUS
175     //!           MOS_STATUS_SUCCESS if success, else fail reason
176     //!
177     MOS_STATUS CtxBufDiffInit(
178         uint8_t *ctxBuffer,
179         bool     setToKey) const;
180 
181     //!
182     //! \brief    Set default inter mode probs
183     //! \details
184     //! \param    [in,out] ctxBuffer
185     //!           Pointer to context buffer
186     //! \param    [in,out] byteCnt
187     //!           Numbe rof bytes counter
188     //! \param    [in] setToKey
189     //!           Specify if it's key frame
190     //! \return   MOS_STATUS
191     //!           MOS_STATUS_SUCCESS if success, else fail reason
192     //!
193     MOS_STATUS SetDefaultInterModeProbs(
194         uint8_t  *ctxBuffer,
195         uint32_t &byteCnt,
196         bool      setToKey) const;
197 
198     //!
199     //! \brief    Set default switchable interprediction Prob
200     //! \details
201     //! \param    [in,out] ctxBuffer
202     //!           Pointer to context buffer
203     //! \param    [in,out] byteCnt
204     //!           Numbe rof bytes counter
205     //! \param    [in] setToKey
206     //!           Specify if it's key frame
207     //! \return   MOS_STATUS
208     //!           MOS_STATUS_SUCCESS if success, else fail reason
209     //!
210     MOS_STATUS SetDefaultSwitchableInterpProb(
211         uint8_t  *ctxBuffer,
212         uint32_t &byteCnt,
213         bool      setToKey) const;
214 
215     //!
216     //! \brief    Set default intra-inter prob
217     //! \details
218     //! \param    [in,out] ctxBuffer
219     //!           Pointer to context buffer
220     //! \param    [in,out] byteCnt
221     //!           Numbe rof bytes counter
222     //! \param    [in] setToKey
223     //!           Specify if it's key frame
224     //! \return   MOS_STATUS
225     //!           MOS_STATUS_SUCCESS if success, else fail reason
226     //!
227     MOS_STATUS SetDefaultIntraInterProb(
228         uint8_t  *ctxBuffer,
229         uint32_t &byteCnt,
230         bool      setToKey) const;
231 
232     //!
233     //! \brief    Set default comp inter prob
234     //! \details
235     //! \param    [in,out] ctxBuffer
236     //!           Pointer to context buffer
237     //! \param    [in,out] byteCnt
238     //!           Numbe rof bytes counter
239     //! \param    [in] setToKey
240     //!           Specify if it's key frame
241     //! \return   MOS_STATUS
242     //!           MOS_STATUS_SUCCESS if success, else fail reason
243     //!
244     MOS_STATUS SetDefaultCompInterProb(
245         uint8_t  *ctxBuffer,
246         uint32_t &byteCnt,
247         bool      setToKey) const;
248 
249     //!
250     //! \brief    Set default single reference prob
251     //! \details
252     //! \param    [in,out] ctxBuffer
253     //!           Pointer to context buffer
254     //! \param    [in,out] byteCnt
255     //!           Numbe rof bytes counter
256     //! \param    [in] setToKey
257     //!           Specify if it's key frame
258     //! \return   MOS_STATUS
259     //!           MOS_STATUS_SUCCESS if success, else fail reason
260     //!
261     MOS_STATUS SetDefaultSingleRefProb(
262         uint8_t  *ctxBuffer,
263         uint32_t &byteCnt,
264         bool      setToKey) const;
265 
266     //!
267     //! \brief    Set default comp reference prob
268     //! \details
269     //! \param    [in,out] ctxBuffer
270     //!           Pointer to context buffer
271     //! \param    [in,out] byteCnt
272     //!           Numbe rof bytes counter
273     //! \param    [in] setToKey
274     //!           Specify if it's key frame
275     //! \return   MOS_STATUS
276     //!           MOS_STATUS_SUCCESS if success, else fail reason
277     //!
278     MOS_STATUS SetDefaultCompRefProb(
279         uint8_t  *ctxBuffer,
280         uint32_t &byteCnt,
281         bool      setToKey) const;
282 
283     //!
284     //! \brief    Set default Y mode prob
285     //! \details
286     //! \param    [in,out] ctxBuffer
287     //!           Pointer to context buffer
288     //! \param    [in,out] byteCnt
289     //!           Numbe rof bytes counter
290     //! \param    [in] setToKey
291     //!           Specify if it's key frame
292     //! \return   MOS_STATUS
293     //!           MOS_STATUS_SUCCESS if success, else fail reason
294     //!
295     MOS_STATUS SetDefaultYModeProb(
296         uint8_t  *ctxBuffer,
297         uint32_t &byteCnt,
298         bool      setToKey) const;
299 
300     //!
301     //! \brief    Set default partition prob
302     //! \details
303     //! \param    [in,out] ctxBuffer
304     //!           Pointer to context buffer
305     //! \param    [in,out] byteCnt
306     //!           Numbe rof bytes counter
307     //! \param    [in] setToKey
308     //!           Specify if it's key frame
309     //! \return   MOS_STATUS
310     //!           MOS_STATUS_SUCCESS if success, else fail reason
311     //!
312     MOS_STATUS SetDefaultPartitionProb(
313         uint8_t  *ctxBuffer,
314         uint32_t &byteCnt,
315         bool      setToKey) const;
316 
317     //!
318     //! \brief    Set default NMV prob
319     //! \details
320     //! \param    [in,out] ctxBuffer
321     //!           Pointer to context buffer
322     //! \param    [in,out] byteCnt
323     //!           Numbe rof bytes counter
324     //! \param    [in] setToKey
325     //!           Specify if it's key frame
326     //! \return   MOS_STATUS
327     //!           MOS_STATUS_SUCCESS if success, else fail reason
328     //!
329     MOS_STATUS SetDefaultNmvContext(
330         uint8_t  *ctxBuffer,
331         uint32_t &byteCnt,
332         bool      setToKey) const;
333 
334     //!
335     //! \brief    Set default UV mode prob
336     //! \details
337     //! \param    [in,out] ctxBuffer
338     //!           Pointer to context buffer
339     //! \param    [in,out] byteCnt
340     //!           Numbe rof bytes counter
341     //! \param    [in] setToKey
342     //!           Specify if it's key frame
343     //! \return   MOS_STATUS
344     //!           MOS_STATUS_SUCCESS if success, else fail reason
345     //!
346     MOS_STATUS SetDefaultUVModeProbs(
347         uint8_t  *ctxBuffer,
348         uint32_t &byteCnt,
349         bool      setToKey) const;
350 
351     //!
352     //! \brief    Init context buffer
353     //! \details
354     //! \param    [in,out] ctxBuffer
355     //!           Pointer to context buffer
356     //! \param    [in] setToKey
357     //!           Specify if it's key frame
358     //! \return   MOS_STATUS
359     //!           MOS_STATUS_SUCCESS if success, else fail reason
360     //!
361     MOS_STATUS ContextBufferInit(
362         uint8_t *ctxBuffer,
363         bool     setToKey) const;
364 
365     //!
366     //! \brief  Refresh frame interlnal buffers
367     //! \return MOS_STATUS
368     //!         MOS_STATUS_SUCCESS if success, else fail reason
369     //!
370     MOS_STATUS RefreshFrameInternalBuffers();
371 
372     //!
373     //! \brief MHW parameters declaration
374     //!
375     MHW_SETPAR_DECL_HDR(HCP_IND_OBJ_BASE_ADDR_STATE);
376     MHW_SETPAR_DECL_HDR(HCP_PIPE_BUF_ADDR_STATE);
377 
378 protected:
379 
380     //! \brief  Allocate feature related resources
381     //! \return MOS_STATUS
382     //!         MOS_STATUS_SUCCESS if success, else fail reason
383     //!
384     MOS_STATUS AllocateResources() override;
385 
386     static constexpr uint32_t m_probabilityCounterBufferSize = 193 * CODECHAL_CACHELINE_SIZE;
387     static const uint32_t     m_probDmem[320];
388 
389     EncodeAllocator *     m_allocator    = nullptr;
390     Vp9BasicFeature *     m_basicFeature = nullptr;
391 
392     // HuC Prob resoruces/buffers
393     MOS_RESOURCE m_resProbabilityDeltaBuffer             = {0};                        //!< Probability delta buffer
394     MOS_RESOURCE m_resProbabilityCounterBuffer           = {0};                        //!< Probability counter buffer
395     MOS_RESOURCE m_resHucProbDmemBuffer[CODECHAL_ENCODE_RECYCLED_BUFFER_NUM][3] = {0}; //!< VDENC HuC Prob DMEM buffer
396     MOS_RESOURCE m_resHucProbOutputBuffer                = {0};                        //!< HuC Prob output buffer
397     MOS_RESOURCE m_resProbBuffer[CODEC_VP9_NUM_CONTEXTS] = {0};                        //!< Probability buffer
398 
399     mutable bool m_isLastPass = false;
400 
401     //!
402     //! \struct    CompressedHeader
403     //! \brief     Compressed header
404     //!
405     struct CompressedHeader
406     {
407         union
408         {
409             struct
410             {
411                 uint8_t valid : 1;         // valid =1, invalid = 0
412                 uint8_t bin_probdiff : 1;  // 1= bin, 0 = prob diff
413                 uint8_t prob : 1;          // 0 = 128, 1 = 252
414                 uint8_t bin : 1;
415                 uint8_t reserved : 4;
416             } fields;
417             uint8_t value;
418         };
419     };
420 
421     /* BinIdx for compressed header generation for PAK */
422     /* The first value indicates previous SE index and second value indicates the size of the previous SE*/
423     static constexpr uint32_t PAK_TX_MODE_IDX                 = 0;                                     //idx=0
424     static constexpr uint32_t PAK_TX_MODE_SELECT_IDX          = (PAK_TX_MODE_IDX + 2);                 //idx=2
425     static constexpr uint32_t PAK_TX_8x8_PROB_IDX             = (PAK_TX_MODE_SELECT_IDX + 1);          //idx=3
426     static constexpr uint32_t PAK_TX_16x16_PROB_IDX           = (PAK_TX_8x8_PROB_IDX + 4);             //idx=7
427     static constexpr uint32_t PAK_TX_32x32_PROB_IDX           = (PAK_TX_16x16_PROB_IDX + 8);           //idx=15
428     static constexpr uint32_t PAK_TX_4x4_COEFF_PROB_IDX       = (PAK_TX_32x32_PROB_IDX + 12);          //idx=27
429     static constexpr uint32_t PAK_TX_8x8_COEFF_PROB_IDX       = (PAK_TX_4x4_COEFF_PROB_IDX + 793);     //idx=820
430     static constexpr uint32_t PAK_TX_16x16_COEFF_PROB_IDX     = (PAK_TX_8x8_COEFF_PROB_IDX + 793);     //idx=1613
431     static constexpr uint32_t PAK_TX_32x32_COEFF_PROB_IDX     = (PAK_TX_16x16_COEFF_PROB_IDX + 793);   //idx=2406
432     static constexpr uint32_t PAK_SKIP_CONTEXT_IDX            = (PAK_TX_32x32_COEFF_PROB_IDX + 793);   //idx=3199
433     static constexpr uint32_t PAK_INTER_MODE_CTX_IDX          = (PAK_SKIP_CONTEXT_IDX + 6);            //idx=3205
434     static constexpr uint32_t PAK_SWITCHABLE_FILTER_CTX_IDX   = (PAK_INTER_MODE_CTX_IDX + 42);         //idx=3247
435     static constexpr uint32_t PAK_INTRA_INTER_CTX_IDX         = (PAK_SWITCHABLE_FILTER_CTX_IDX + 16);  //idx=3263
436     static constexpr uint32_t PAK_COMPOUND_PRED_MODE_IDX      = (PAK_INTRA_INTER_CTX_IDX + 8);         //idx=3271
437     static constexpr uint32_t PAK_HYBRID_PRED_CTX_IDX         = (PAK_COMPOUND_PRED_MODE_IDX + 2);      //idx=3273
438     static constexpr uint32_t PAK_SINGLE_REF_PRED_CTX_IDX     = (PAK_HYBRID_PRED_CTX_IDX + 10);        //idx=3283
439     static constexpr uint32_t PAK_CMPUND_PRED_CTX_IDX         = (PAK_SINGLE_REF_PRED_CTX_IDX + 20);    //idx=3303
440     static constexpr uint32_t PAK_INTRA_MODE_PROB_CTX_IDX     = (PAK_CMPUND_PRED_CTX_IDX + 10);        //idx=3313
441     static constexpr uint32_t PAK_PARTITION_PROB_IDX          = (PAK_INTRA_MODE_PROB_CTX_IDX + 72);    //idx=3385
442     static constexpr uint32_t PAK_MVJOINTS_PROB_IDX           = (PAK_PARTITION_PROB_IDX + 96);         //idx=3481
443     static constexpr uint32_t PAK_MVCOMP0_IDX                 = (PAK_MVJOINTS_PROB_IDX + 24);          //idx=3505
444     static constexpr uint32_t PAK_MVCOMP1_IDX                 = (PAK_MVCOMP0_IDX + 176);               //idx=3681
445     static constexpr uint32_t PAK_MVFRAC_COMP0_IDX            = (PAK_MVCOMP1_IDX + 176);               //idx=3857
446     static constexpr uint32_t PAK_MVFRAC_COMP1_IDX            = (PAK_MVFRAC_COMP0_IDX + 72);           //idx=3929
447     static constexpr uint32_t PAK_MVHP_COMP0_IDX              = (PAK_MVFRAC_COMP1_IDX + 72);           //idx=4001
448     static constexpr uint32_t PAK_MVHP_COMP1_IDX              = (PAK_MVHP_COMP0_IDX + 16);             //idx=4017
449     static constexpr uint32_t PAK_COMPRESSED_HDR_SYNTAX_ELEMS = (PAK_MVHP_COMP1_IDX + 16);             //=4033
450 
451     bool    m_clearAllToKey[CODEC_VP9_NUM_CONTEXTS]               = {false};
452     bool    m_isPreCtx0InterProbSaved                             = false;
453     uint8_t m_preCtx0InterProbSaved[CODECHAL_VP9_INTER_PROB_SIZE] = {0};
454 
455     //!
456     //! \enum     PRED_MODE
457     //! \brief    Pred mode
458     //!
459     enum PRED_MODE
460     {
461         PRED_MODE_SINGLE   = 0,
462         PRED_MODE_COMPOUND = 1,
463         PRED_MODE_HYBRID   = 2
464     };
465 
466     //!
467     //! \brief      Put data for compressed header
468     //!
469     //! \param      [in] compressedHdr
470     //!             Compressed header
471     //! \param      [in] bit
472     //!             Bit
473     //! \param      [in] prob
474     //!             Prob
475     //! \param      [in] binIdx
476     //!             Bin index
477     //!
478     void PutDataForCompressedHdr(
479         CompressedHeader *compressedHdr,
480         uint32_t          bit,
481         uint32_t          prob,
482         uint32_t          binIdx);
483 
484 MEDIA_CLASS_DEFINE_END(encode__Vp9EncodeHpu)
485 };
486 
487 }  // namespace encode
488 
489 #endif  // __ENCODE_VP9_CQP_H__
490