1 // Copyright (c) 2017-2019 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #include <limits>
22 #include "mfx_vp9_dec_decode.h"
23 
24 #include "mfx_common.h"
25 #include "mfx_common_decode_int.h"
26 #include "mfx_vpx_dec_common.h"
27 #include "mfx_enc_common.h"
28 
29 #if defined(MFX_ENABLE_VP9_VIDEO_DECODE_HW)
30 
31 #include "umc_vp9_utils.h"
32 #include "umc_vp9_bitstream.h"
33 #include "umc_vp9_frame.h"
34 
35 using namespace UMC_VP9_DECODER;
36 
37 
38 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
39 // MFX_VP9_Utility implementation
40 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 
42 namespace MFX_VP9_Utility {
43 
DecodeHeader(VideoCORE * core,mfxBitstream * bs,mfxVideoParam * params)44 mfxStatus DecodeHeader(VideoCORE* core, mfxBitstream* bs, mfxVideoParam* params)
45 {
46     mfxStatus sts = MFX_ERR_NONE;
47 
48     MFX_CHECK_NULL_PTR3(core, bs, params);
49 
50     sts = CheckBitstream(bs);
51     MFX_CHECK_STS(sts);
52 
53     if (bs->DataLength < 3)
54     {
55         MoveBitstreamData(*bs, bs->DataLength);
56         return MFX_ERR_MORE_DATA;
57     }
58 
59     bool bHeaderRead = false;
60 
61     VP9DecoderFrame frame{};
62     frame.bit_depth = 8;
63 
64     for (;;)
65     {
66         VP9Bitstream bsReader(bs->Data + bs->DataOffset,  bs->DataLength - bs->DataOffset);
67 
68         if (VP9_FRAME_MARKER != bsReader.GetBits(2))
69             break; // invalid
70 
71         frame.profile = bsReader.GetBit();
72         frame.profile |= bsReader.GetBit() << 1;
73         if (frame.profile > 2)
74             frame.profile += bsReader.GetBit();
75 
76         if (frame.profile >= 4)
77             return MFX_ERR_UNDEFINED_BEHAVIOR;
78 
79         if (bsReader.GetBit()) // show_existing_frame
80             break;
81 
82         VP9_FRAME_TYPE frameType = (VP9_FRAME_TYPE) bsReader.GetBit();
83         mfxU32 showFrame = bsReader.GetBit();
84         mfxU32 errorResilientMode = bsReader.GetBit();
85 
86         if (KEY_FRAME == frameType)
87         {
88             if (!CheckSyncCode(&bsReader))
89                 return MFX_ERR_UNDEFINED_BEHAVIOR;
90 
91             if (frame.profile >= 2)
92             {
93                 frame.bit_depth = bsReader.GetBit() ? 12 : 10;
94             }
95 
96             if (SRGB != (COLOR_SPACE)bsReader.GetBits(3)) // color_space
97             {
98                 bsReader.GetBit(); // color_range
99                 if (1 == frame.profile || 3 == frame.profile)
100                 {
101                     frame.subsamplingX = bsReader.GetBit();
102                     frame.subsamplingY = bsReader.GetBit();
103                     bsReader.GetBit(); // reserved_zero
104                 }
105                 else
106                 {
107                     frame.subsamplingX = 1;
108                     frame.subsamplingY = 1;
109                 }
110             }
111             else
112             {
113                 if (1 == frame.profile || 3 == frame.profile)
114                     bsReader.GetBit();
115                 else
116                     break; // invalid
117             }
118 
119             frame.width = (mfxU16)bsReader.GetBits(16) + 1;
120             frame.height = (mfxU16)bsReader.GetBits(16) + 1;
121 
122             bHeaderRead = true;
123         }
124         else
125         {
126             mfxU32 intraOnly = showFrame ? 0 : bsReader.GetBit();
127             if (!intraOnly)
128                 break;
129 
130             if (!errorResilientMode)
131                 bsReader.GetBits(2);
132 
133             if (!CheckSyncCode(&bsReader))
134                 return MFX_ERR_UNDEFINED_BEHAVIOR;
135 
136             if (frame.profile >= 2)
137                 frame.bit_depth = bsReader.GetBit() ? 12 : 10;
138 
139             if (frame.profile == 0)
140             {
141                 // There is no color format info in intra-only frame for frame.profile 0
142                 frame.subsamplingX = 1;
143                 frame.subsamplingY = 1;
144             }
145             else // frame.profile > 0
146             {
147                 if (SRGB != (COLOR_SPACE)bsReader.GetBits(3)) // color_space
148                 {
149                     bsReader.GetBit(); // color_range
150                     if (1 == frame.profile || 3 == frame.profile)
151                     {
152                         frame.subsamplingX = bsReader.GetBit();
153                         frame.subsamplingY = bsReader.GetBit();
154                         bsReader.GetBit(); // reserved_zero
155                     }
156                     else
157                     {
158                         frame.subsamplingX = 1;
159                         frame.subsamplingY = 1;
160                     }
161                 }
162                 else
163                 {
164                     if (1 == frame.profile || 3 == frame.profile)
165                         bsReader.GetBit();
166                     else
167                         break; // invalid
168                 }
169             }
170 
171             bsReader.GetBits(NUM_REF_FRAMES);
172 
173             frame.width = (mfxU16)bsReader.GetBits(16) + 1;
174             frame.height = (mfxU16)bsReader.GetBits(16) + 1;
175 
176             bHeaderRead = true;
177         }
178 
179         break;
180     }
181 
182     if (!bHeaderRead)
183     {
184         MoveBitstreamData(*bs, bs->DataLength);
185         return MFX_ERR_MORE_DATA;
186     }
187 
188     FillVideoParam(core->GetPlatformType(), frame, *params);
189 
190     return MFX_ERR_NONE;
191 }
192 
FillVideoParam(eMFXPlatform platform,UMC_VP9_DECODER::VP9DecoderFrame const & frame,mfxVideoParam & params)193 void FillVideoParam(eMFXPlatform platform, UMC_VP9_DECODER::VP9DecoderFrame const& frame, mfxVideoParam &params)
194 {
195     params.mfx.CodecProfile = mfxU16(frame.profile + 1);
196 
197     params.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
198     params.mfx.FrameInfo.AspectRatioW = 1;
199     params.mfx.FrameInfo.AspectRatioH = 1;
200 
201     params.mfx.FrameInfo.CropX = 0;
202     params.mfx.FrameInfo.CropY = 0;
203     params.mfx.FrameInfo.CropW = static_cast<mfxU16>(frame.width);
204     params.mfx.FrameInfo.CropH = static_cast<mfxU16>(frame.height);
205 
206     params.mfx.FrameInfo.Width  = mfx::align2_value(params.mfx.FrameInfo.CropW, 16);
207     params.mfx.FrameInfo.Height = mfx::align2_value(params.mfx.FrameInfo.CropH, 16);
208 
209     if (!frame.subsamplingX && !frame.subsamplingY)
210         params.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV444;
211     //else if (!subsampling_x && subsampling_y)
212     //    params.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV440;
213     else if (frame.subsamplingX && !frame.subsamplingY)
214         params.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV422;
215     else if (frame.subsamplingX && frame.subsamplingY)
216         params.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
217 
218     switch (frame.bit_depth)
219     {
220         case  8:
221             params.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
222             if (MFX_CHROMAFORMAT_YUV444 == params.mfx.FrameInfo.ChromaFormat)
223                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_AYUV;
224             else if (MFX_CHROMAFORMAT_YUV422 == params.mfx.FrameInfo.ChromaFormat)
225                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_YUY2;
226             params.mfx.FrameInfo.BitDepthLuma   = 8;
227             params.mfx.FrameInfo.BitDepthChroma = 8;
228             params.mfx.FrameInfo.Shift = 0;
229             break;
230 
231         case 10:
232             params.mfx.FrameInfo.FourCC = MFX_FOURCC_P010;
233 #if (MFX_VERSION >= 1027)
234             if (MFX_CHROMAFORMAT_YUV444 == params.mfx.FrameInfo.ChromaFormat)
235                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_Y410;
236             else if (MFX_CHROMAFORMAT_YUV422 == params.mfx.FrameInfo.ChromaFormat)
237                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_Y210;
238 #endif
239             params.mfx.FrameInfo.BitDepthLuma   = 10;
240             params.mfx.FrameInfo.BitDepthChroma = 10;
241             break;
242 
243         case 12:
244             params.mfx.FrameInfo.FourCC = 0;
245 #if (MFX_VERSION >= 1031)
246             if (MFX_CHROMAFORMAT_YUV420 == params.mfx.FrameInfo.ChromaFormat)
247                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_P016;
248             else if(MFX_CHROMAFORMAT_YUV444 == params.mfx.FrameInfo.ChromaFormat)
249                 params.mfx.FrameInfo.FourCC = MFX_FOURCC_Y416;
250 #endif
251             params.mfx.FrameInfo.BitDepthLuma   = 12;
252             params.mfx.FrameInfo.BitDepthChroma = 12;
253             break;
254     }
255 
256     if (platform == MFX_PLATFORM_HARDWARE)
257     {
258         params.mfx.FrameInfo.Shift = 0;
259 
260         if (params.mfx.FrameInfo.FourCC == MFX_FOURCC_P010
261 #if (MFX_VERSION >= 1031)
262             || params.mfx.FrameInfo.FourCC == MFX_FOURCC_P016
263             || params.mfx.FrameInfo.FourCC == MFX_FOURCC_Y416
264 #endif
265         )
266         {
267             params.mfx.FrameInfo.Shift = 1;
268         }
269     }
270 }
271 
272 } //MFX_VP9_Utility
273 
274 #endif // #if defined(MFX_ENABLE_VP9_VIDEO_DECODE) || defined(MFX_ENABLE_VP9_VIDEO_DECODE_HW)
275