1 /*
2 * Copyright (c) 2021, 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_av1_vdenc_lpla_enc.cpp
24 //! \brief    Implementation for encode av1 lowpower lookahead(Encode Pass) feature
25 //!
26 
27 #include "encode_av1_vdenc_lpla_enc.h"
28 #include "encode_av1_vdenc_feature_manager.h"
29 
30 namespace encode
31 {
AV1VdencLplaEnc(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)32     AV1VdencLplaEnc::AV1VdencLplaEnc(
33         MediaFeatureManager *featureManager,
34         EncodeAllocator     *allocator,
35         CodechalHwInterfaceNext *hwInterface,
36         void                *constSettings) :
37         MediaFeature(constSettings),
38         m_allocator(allocator)
39     {
40     }
41 
~AV1VdencLplaEnc()42     AV1VdencLplaEnc::~AV1VdencLplaEnc()
43     {
44         if (m_lplaHelper)
45         {
46             MOS_Delete(m_lplaHelper);
47             m_lplaHelper = nullptr;
48         }
49     }
50 
Init(void * setting)51     MOS_STATUS AV1VdencLplaEnc::Init(void *setting)
52     {
53         ENCODE_FUNC_CALL();
54         m_lplaHelper = MOS_New(EncodeLPLA);
55         ENCODE_CHK_NULL_RETURN(m_lplaHelper);
56 
57         return MOS_STATUS_SUCCESS;
58     }
59 
Update(void * params)60     MOS_STATUS AV1VdencLplaEnc::Update(void *params)
61     {
62         ENCODE_FUNC_CALL();
63         ENCODE_CHK_NULL_RETURN(params);
64 
65         EncoderParams *encodeParams = (EncoderParams *)params;
66         m_av1SeqParams = static_cast<PCODEC_AV1_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
67         ENCODE_CHK_NULL_RETURN(m_av1SeqParams);
68         m_enabled = (m_av1SeqParams->LookaheadDepth > 0) && (m_av1SeqParams->RateControlMethod != RATECONTROL_CQP);
69         if (!m_enabled)
70         {
71             return MOS_STATUS_SUCCESS;
72         }
73         m_av1PicParams = static_cast<PCODEC_AV1_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams);
74         ENCODE_CHK_NULL_RETURN(m_av1PicParams);
75         ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
76 
77         return MOS_STATUS_SUCCESS;
78     }
79 
SetSequenceStructs()80     MOS_STATUS AV1VdencLplaEnc::SetSequenceStructs()
81     {
82         ENCODE_FUNC_CALL();
83         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
84 
85         ENCODE_CHK_NULL_RETURN(m_lplaHelper);
86         ENCODE_CHK_STATUS_RETURN(m_lplaHelper->CheckFrameRate(m_av1SeqParams->FrameRate[0].Numerator,
87             m_av1SeqParams->FrameRate[0].Denominator,
88             m_av1SeqParams->TargetBitRate[0], m_averageFrameSize));
89 
90         ENCODE_CHK_STATUS_RETURN(m_lplaHelper->CheckVBVBuffer(m_av1SeqParams->VBVBufferSizeInBit,
91             m_av1SeqParams->InitVBVBufferFullnessInBit));
92         if (m_targetBufferFulness == 0 && m_prevTargetFrameSize == 0)
93         {
94             m_targetBufferFulness = m_av1SeqParams->VBVBufferSizeInBit - m_av1SeqParams->InitVBVBufferFullnessInBit;
95         }
96         ENCODE_CHK_STATUS_RETURN(m_lplaHelper->CalculateTargetBufferFullness(m_targetBufferFulness, m_prevTargetFrameSize, m_averageFrameSize));
97         m_prevTargetFrameSize = m_av1PicParams->TargetFrameSize;
98 
99         return eStatus;
100     }
101 
MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE,AV1VdencLplaEnc)102     MHW_SETPAR_DECL_SRC(HUC_DMEM_STATE, AV1VdencLplaEnc)
103     {
104         ENCODE_FUNC_CALL();
105 
106         if (!m_enabled)
107         {
108             return MOS_STATUS_SUCCESS;
109         }
110 
111         ENCODE_CHK_NULL_RETURN(params.hucDataSource);
112         ENCODE_CHK_NULL_RETURN(m_lplaHelper);
113 
114         if (params.function == BRC_UPDATE)
115         {
116             auto dmem = (VdencAv1HucBrcUpdateDmem*)m_allocator->LockResourceForWrite(params.hucDataSource);
117             ENCODE_CHK_NULL_RETURN(dmem);
118             dmem->UPD_LA_TargetFULNESS = m_targetBufferFulness;
119             dmem->UPD_LALength = m_av1SeqParams->LookaheadDepth;
120             dmem->UPD_TR_TargetSize = m_av1PicParams->TargetFrameSize << 3;  // byte to bit
121             bool isLastPass = (params.currentPass ==  (params.passNum - 1));
122             ENCODE_CHK_STATUS_RETURN(m_lplaHelper->CalculateDeltaQP(m_av1PicParams->QpModulationStrength, m_initDeltaQP, isLastPass,
123                 dmem->UPD_Delta, m_prevQpModulationStrength));
124 
125             ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(params.hucDataSource));
126         }
127 
128         return MOS_STATUS_SUCCESS;
129     }
130 
131 }  // encode
132