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 ¶ms)
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