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_lpla.cpp
24 //! \brief    Defines the common interface for LowPower Lookahead encode
25 //!
26 
27 #include "encode_lpla.h"
28 
29 namespace encode
30 {
CalculateTargetBufferFullness(uint32_t & targetBufferFulness,uint32_t & prevTargetFrameSize,uint32_t & averageFrameSize)31     MOS_STATUS EncodeLPLA::CalculateTargetBufferFullness(
32         uint32_t &targetBufferFulness,
33         uint32_t &prevTargetFrameSize,
34         uint32_t &averageFrameSize)
35     {
36         ENCODE_FUNC_CALL();
37         if (prevTargetFrameSize > 0)
38         {
39             int64_t bufferFulness = (int64_t)targetBufferFulness;
40             bufferFulness += (int64_t)(prevTargetFrameSize << 3) - (int64_t)averageFrameSize;
41             targetBufferFulness = bufferFulness < 0 ? 0 : (bufferFulness > 0xFFFFFFFF ? 0xFFFFFFFF : (uint32_t)bufferFulness);
42         }
43 
44         return MOS_STATUS_SUCCESS;
45     }
46 
CheckFrameRate(uint32_t & Numerator,uint32_t & Denominator,uint32_t & TargetBitRate,uint32_t & averageFrameSize)47      MOS_STATUS EncodeLPLA::CheckFrameRate(
48         uint32_t &Numerator,
49         uint32_t &Denominator,
50         uint32_t &TargetBitRate,
51         uint32_t &averageFrameSize)
52     {
53         ENCODE_FUNC_CALL();
54         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
55 
56         uint64_t targetBitRate = (uint64_t)TargetBitRate * 1000;
57         double   frameRate     = (Denominator ? (double) Numerator / Denominator : 30);
58         if ((frameRate < 1) || (targetBitRate < frameRate) || (targetBitRate > 0xFFFFFFFF))
59         {
60             eStatus = MOS_STATUS_INVALID_PARAMETER;
61             ENCODE_ASSERTMESSAGE("Invalid FrameRate or TargetBitRate in LPLA!\n");
62         }
63         averageFrameSize = (uint32_t)(targetBitRate / frameRate);
64 
65         return eStatus;
66     }
67 
CheckVBVBuffer(uint32_t & VBVBufferSizeInBit,uint32_t & InitVBVBufferFullnessInBit)68     MOS_STATUS EncodeLPLA::CheckVBVBuffer(
69         uint32_t &VBVBufferSizeInBit,
70         uint32_t &InitVBVBufferFullnessInBit)
71     {
72         ENCODE_FUNC_CALL();
73         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
74 
75         if (VBVBufferSizeInBit < InitVBVBufferFullnessInBit)
76         {
77             eStatus = MOS_STATUS_INVALID_PARAMETER;
78             ENCODE_ASSERTMESSAGE("VBVBufferSizeInBit is less than InitVBVBufferFullnessInBit\n");
79             return eStatus;
80         }
81 
82         return eStatus;
83     }
84 
CalculateDeltaQP(uint8_t & QpModulationStrength,bool & initDeltaQP,bool isLastPass,uint8_t & DeltaQP,uint32_t & prevQpModulationStrength)85     MOS_STATUS EncodeLPLA::CalculateDeltaQP(
86         uint8_t  &QpModulationStrength,
87         bool     &initDeltaQP,
88         bool     isLastPass,
89         uint8_t  &DeltaQP,
90         uint32_t &prevQpModulationStrength)
91     {
92         ENCODE_FUNC_CALL();
93         uint8_t QpStrength = (uint8_t)(QpModulationStrength + (QpModulationStrength >> 1));
94         if (!initDeltaQP)
95         {
96             DeltaQP = QpModulationStrength ? (prevQpModulationStrength + QpStrength + 1) >> 1 : 0;
97         }
98         else
99         {
100             DeltaQP = QpStrength;
101             if (isLastPass)
102             {
103                 initDeltaQP = false;
104             }
105         }
106         prevQpModulationStrength = DeltaQP;
107 
108         return MOS_STATUS_SUCCESS;
109     }
110 
111 } // encode
112