OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 #include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h" | |
11 | |
12 namespace webrtc { | |
13 | |
14 namespace vp9 { | |
15 namespace { | |
16 const size_t kVp9MaxProfile = 4; | |
17 const size_t kVp9NumRefsPerFrame = 3; | |
18 const size_t kVp9MaxRefLFDeltas = 4; | |
19 const size_t kVp9MaxModeLFDeltas = 2; | |
20 } // namespace | |
21 | |
22 static uint8_t VP9ReadProfile(VP9BitReader* const br) { | |
brandtr
2017/05/22 18:34:56
I think you can drop the const here, and in the si
jianj1
2017/05/22 21:18:57
Done.
| |
23 uint8_t profile = 0; | |
24 if (br->GetBit()) | |
25 profile |= 1; | |
26 if (br->GetBit()) | |
27 profile |= 2; | |
28 if (profile > 2 && br->GetBit()) | |
29 profile += 1; | |
30 return profile; | |
31 } | |
32 | |
33 static bool VP9ReadColorConfig(VP9BitReader* const br, const uint8_t profile) { | |
34 if (profile == 2 || profile == 3) { | |
35 // bitdepth | |
brandtr
2017/05/22 18:34:56
Nit: start comments with capital and end with peri
jianj1
2017/05/22 21:18:57
Done.
| |
36 br->GetBit(); | |
37 } | |
38 | |
39 uint8_t color_space = br->GetValue(3); | |
40 // SRGB is 7 | |
41 if (color_space != 7) { | |
42 // yuv range flag | |
43 br->GetBit(); | |
44 if (profile == 1 || profile == 3) { | |
45 // Subsampling x. | |
46 br->GetBit(); | |
47 // Subsampling y. | |
48 br->GetBit(); | |
49 // Reserved. | |
50 if (br->GetBit()) { | |
51 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; | |
52 return false; | |
53 } | |
54 } | |
55 } else { | |
56 if (profile == 1 || profile == 3) { | |
57 // Reserved. | |
58 if (br->GetBit()) { | |
59 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; | |
60 return false; | |
61 } | |
62 } else { | |
63 LOG(LS_WARNING) << "Failed to get QP. 4:4:4 color not supported in " | |
64 "profile 0 or 2."; | |
65 return false; | |
66 } | |
67 } | |
68 | |
69 return true; | |
70 } | |
71 | |
72 static void VP9ReadFrameSize(VP9BitReader* const br) { | |
73 // Frame width. | |
74 uint32_t width = br->GetValue(16); | |
brandtr
2017/05/22 18:34:56
I think you could drop the comments, or drop the v
jianj1
2017/05/22 21:18:57
Done.
| |
75 (void)width; | |
76 // Frame height. | |
77 uint32_t height = br->GetValue(16); | |
78 (void)height; | |
79 } | |
80 | |
81 static void VP9ReadRenderSize(VP9BitReader* const br) { | |
82 // Scaling. | |
83 if (br->GetBit()) { | |
84 // Render width. | |
85 uint32_t width = br->GetValue(16); | |
86 // Render height. | |
87 uint32_t height = br->GetValue(16); | |
88 (void)width; | |
89 (void)height; | |
90 } | |
91 } | |
92 | |
93 static void VP9ReadFrameSizeFromRefs(VP9BitReader* const br) { | |
94 int found_ref = 0; | |
95 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { | |
96 // Size in refs. | |
97 found_ref = br->GetBit(); | |
98 if (found_ref) | |
99 break; | |
100 } | |
101 | |
102 if (!found_ref) | |
103 VP9ReadFrameSize(br); | |
104 | |
105 VP9ReadRenderSize(br); | |
106 } | |
107 | |
108 static void VP9ReadInterpolationFilter(VP9BitReader* const br) { | |
109 if (br->GetBit()) | |
110 return; | |
111 | |
112 br->GetValue(2); | |
113 } | |
114 | |
115 static void VP9ReadLoopfilter(VP9BitReader* const br) { | |
116 // Filter level. | |
117 br->GetValue(6); | |
118 // Sharpness level. | |
119 br->GetValue(3); | |
120 uint32_t mode_ref_delta_enabled = br->GetBit(); | |
121 if (mode_ref_delta_enabled) { | |
122 uint32_t mode_ref_delta_update = br->GetBit(); | |
123 if (mode_ref_delta_update) { | |
124 for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) { | |
125 if (br->GetBit()) | |
126 br->GetSignedValue(6); | |
127 } | |
128 for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) { | |
129 if (br->GetBit()) | |
130 br->GetSignedValue(6); | |
131 } | |
132 } | |
133 } | |
134 } | |
135 | |
136 bool GetQp(const uint8_t* buf, size_t length, int* qp) { | |
137 VP9BitReader br(buf, length); | |
138 // VP9InitBitReader(&br, buf, buf + length); | |
brandtr
2017/05/22 18:34:56
Remove?
jianj1
2017/05/22 21:18:57
Done.
| |
139 | |
140 // Frame marker. | |
141 if (br.GetValue(2) != 0x2) { | |
142 LOG(LS_WARNING) << "Failed to get QP. Frame marker should be 2."; | |
143 return false; | |
144 } | |
145 | |
146 // Profile. | |
147 uint8_t profile = VP9ReadProfile(&br); | |
148 if (profile > kVp9MaxProfile) { | |
149 LOG(LS_WARNING) << "Failed to get QP. Unsupported bitstream profile: " | |
150 << profile; | |
151 return false; | |
152 } | |
153 | |
154 // Show existing frame. | |
155 if (br.GetBit()) { | |
156 br.GetValue(3); | |
brandtr
2017/05/22 18:34:56
Is this row needed when you return below?
jianj1
2017/05/22 21:18:57
Done.
| |
157 return false; | |
158 } | |
159 | |
160 // Frame type: KEY_FRAME(0), INTER_FRAME(1). | |
161 uint8_t frame_type = br.GetBit(); | |
162 // Show frame. | |
163 uint8_t show_frame = br.GetBit(); | |
164 // Error resilient. | |
165 uint8_t error_resilient = br.GetBit(); | |
166 | |
167 if (!frame_type) { | |
168 // Sync code. | |
169 uint32_t sync_code = br.GetValue(24); | |
170 if (sync_code != 0x498342) { | |
171 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code."; | |
172 return false; | |
173 } | |
174 | |
175 if (!VP9ReadColorConfig(&br, profile)) | |
176 return false; | |
177 | |
178 VP9ReadFrameSize(&br); | |
179 VP9ReadRenderSize(&br); | |
180 } else { | |
181 uint8_t intra_only = 0; | |
182 if (!show_frame) | |
183 intra_only = br.GetBit(); | |
184 | |
185 if (!error_resilient) | |
186 // Reset frame context. | |
187 br.GetValue(2); | |
188 | |
189 if (intra_only) { | |
190 // Sync code. | |
191 if (br.GetValue(24) != 0x498342) { | |
192 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code."; | |
193 return false; | |
194 } | |
195 if (profile > 0) { | |
196 if (!VP9ReadColorConfig(&br, profile)) | |
197 return false; | |
198 } | |
199 // Refresh frame flags. | |
200 br.GetValue(8); | |
201 | |
202 VP9ReadFrameSize(&br); | |
203 VP9ReadRenderSize(&br); | |
204 } else { | |
205 // Refresh frame flags. | |
206 int32_t test = br.GetValue(8); | |
207 (void)test; | |
208 | |
209 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { | |
brandtr
2017/05/22 18:34:56
Maybe move this to its own function too?
jianj1
2017/05/22 21:18:57
Done.
It's probably better to keep it here since
brandtr
2017/05/23 08:59:02
Makes sense. Thanks.
| |
210 // Ref frame index. | |
211 int32_t idx = br.GetValue(3); | |
212 // Ref frame sign biases. | |
213 int32_t bias = br.GetBit(); | |
214 (void)idx; | |
215 (void)bias; | |
216 } | |
217 | |
218 VP9ReadFrameSizeFromRefs(&br); | |
219 // Allow high precision mv. | |
220 br.GetBit(); | |
221 // Interpolation filter. | |
222 VP9ReadInterpolationFilter(&br); | |
223 } | |
224 } | |
225 | |
226 if (!error_resilient) { | |
227 // Refresh frame context. | |
228 br.GetBit(); | |
229 // Frame parallel decoding mode. | |
230 br.GetBit(); | |
231 } | |
232 | |
233 // Frame context index. | |
234 br.GetValue(2); | |
235 | |
236 VP9ReadLoopfilter(&br); | |
237 | |
238 // Base QP. | |
239 const int base_q0 = br.GetValue(8); | |
240 *qp = base_q0; | |
241 return true; | |
242 } | |
243 | |
244 } // namespace vp9 | |
245 | |
246 } // namespace webrtc | |
OLD | NEW |