OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 #include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h" | 10 #include "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h" |
11 | 11 |
12 #include "webrtc/base/bitbuffer.h" | |
13 #include "webrtc/base/logging.h" | |
14 | |
12 namespace webrtc { | 15 namespace webrtc { |
13 | 16 |
17 #define RETURN_FALSE_IF_ERROR(x) \ | |
18 if (!(x)) { \ | |
19 return false; \ | |
20 } | |
21 | |
14 namespace vp9 { | 22 namespace vp9 { |
15 namespace { | 23 namespace { |
16 const size_t kVp9MaxProfile = 4; | 24 const size_t kVp9MaxProfile = 4; |
17 const size_t kVp9NumRefsPerFrame = 3; | 25 const size_t kVp9NumRefsPerFrame = 3; |
18 const size_t kVp9MaxRefLFDeltas = 4; | 26 const size_t kVp9MaxRefLFDeltas = 4; |
19 const size_t kVp9MaxModeLFDeltas = 2; | 27 const size_t kVp9MaxModeLFDeltas = 2; |
20 } // namespace | |
21 | 28 |
22 static uint8_t VP9ReadProfile(VP9BitReader* br) { | 29 bool Vp9ReadProfile(rtc::BitBuffer* br, uint8_t* profile) { |
23 uint8_t profile = 0; | 30 uint32_t high_bit; |
24 if (br->GetBit()) | 31 uint32_t low_bit; |
25 profile |= 1; | 32 RETURN_FALSE_IF_ERROR(br->ReadBits(&low_bit, 1)); |
26 if (br->GetBit()) | 33 RETURN_FALSE_IF_ERROR(br->ReadBits(&high_bit, 1)); |
27 profile |= 2; | 34 *profile = (high_bit << 1) + low_bit; |
28 if (profile > 2 && br->GetBit()) | 35 if (*profile > 2) { |
29 profile += 1; | 36 RETURN_FALSE_IF_ERROR(br->ConsumeBits(1)); |
30 return profile; | 37 *profile += 1; |
38 } | |
39 if (*profile > kVp9MaxProfile) { | |
åsapersson
2017/05/30 11:45:00
Can this happen? Max profile here 4?
| |
40 LOG(LS_WARNING) << "Failed to get QP. Unsupported bitstream profile: " | |
41 << *profile; | |
42 return false; | |
43 } | |
44 return true; | |
31 } | 45 } |
32 | 46 |
33 static bool VP9ReadColorConfig(VP9BitReader* br, uint8_t profile) { | 47 bool Vp9ReadSyncCode(rtc::BitBuffer* br) { |
48 uint32_t sync_code; | |
49 RETURN_FALSE_IF_ERROR(br->ReadBits(&sync_code, 24)); | |
50 if (sync_code != 0x498342) { | |
51 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code."; | |
52 return false; | |
53 } | |
54 return true; | |
55 } | |
56 | |
57 bool Vp9ReadColorConfig(rtc::BitBuffer* br, uint8_t profile) { | |
34 if (profile == 2 || profile == 3) { | 58 if (profile == 2 || profile == 3) { |
35 // Bitdepth. | 59 // Bitdepth. |
36 br->GetBit(); | 60 RETURN_FALSE_IF_ERROR(br->ConsumeBits(1)); |
37 } | 61 } |
62 uint32_t color_space; | |
63 RETURN_FALSE_IF_ERROR(br->ReadBits(&color_space, 3)); | |
38 | 64 |
39 uint8_t color_space = br->GetValue(3); | |
40 // SRGB is 7. | 65 // SRGB is 7. |
41 if (color_space != 7) { | 66 if (color_space != 7) { |
42 // YUV range flag. | 67 // YUV range flag. |
43 br->GetBit(); | 68 RETURN_FALSE_IF_ERROR(br->ConsumeBits(1)); |
44 if (profile == 1 || profile == 3) { | 69 if (profile == 1 || profile == 3) { |
45 // Subsampling x. | 70 // 1 bit: subsampling x. |
46 br->GetBit(); | 71 // 1 bit: subsampling y. |
47 // Subsampling y. | 72 RETURN_FALSE_IF_ERROR(br->ConsumeBits(2)); |
48 br->GetBit(); | 73 uint32_t reserved_bit; |
49 // Reserved. | 74 RETURN_FALSE_IF_ERROR(br->ReadBits(&reserved_bit, 1)); |
50 if (br->GetBit()) { | 75 if (reserved_bit) { |
51 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; | 76 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; |
52 return false; | 77 return false; |
53 } | 78 } |
54 } | 79 } |
55 } else { | 80 } else { |
56 if (profile == 1 || profile == 3) { | 81 if (profile == 1 || profile == 3) { |
57 // Reserved. | 82 uint32_t reserved_bit; |
58 if (br->GetBit()) { | 83 RETURN_FALSE_IF_ERROR(br->ReadBits(&reserved_bit, 1)); |
84 if (reserved_bit) { | |
59 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; | 85 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set."; |
60 return false; | 86 return false; |
61 } | 87 } |
62 } else { | 88 } else { |
63 LOG(LS_WARNING) << "Failed to get QP. 4:4:4 color not supported in " | 89 LOG(LS_WARNING) << "Failed to get QP. 4:4:4 color not supported in " |
64 "profile 0 or 2."; | 90 "profile 0 or 2."; |
65 return false; | 91 return false; |
66 } | 92 } |
67 } | 93 } |
68 | 94 |
69 return true; | 95 return true; |
70 } | 96 } |
71 | 97 |
72 static void VP9ReadFrameSize(VP9BitReader* br) { | 98 bool Vp9ReadFrameSize(rtc::BitBuffer* br) { |
73 // Frame width. | 99 // 2 bytes: frame width. |
74 br->GetValue(16); | 100 // 2 bytes: frame height. |
75 // Frame height. | 101 RETURN_FALSE_IF_ERROR(br->ConsumeBytes(4)); |
76 br->GetValue(16); | 102 return true; |
77 } | 103 } |
78 | 104 |
79 static void VP9ReadRenderSize(VP9BitReader* br) { | 105 bool Vp9ReadRenderSize(rtc::BitBuffer* br) { |
80 // Scaling. | 106 uint32_t bit; |
81 if (br->GetBit()) { | 107 RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1)); |
82 // Render width. | 108 if (bit) { |
83 br->GetValue(16); | 109 // 2 bytes: render width. |
84 // Render height. | 110 // 2 bytes: render height. |
85 br->GetValue(16); | 111 RETURN_FALSE_IF_ERROR(br->ConsumeBytes(4)); |
86 } | 112 } |
113 return true; | |
87 } | 114 } |
88 | 115 |
89 static void VP9ReadFrameSizeFromRefs(VP9BitReader* br) { | 116 bool Vp9ReadFrameSizeFromRefs(rtc::BitBuffer* br) { |
90 int found_ref = 0; | 117 uint32_t found_ref = 0; |
91 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { | 118 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { |
92 // Size in refs. | 119 // Size in refs. |
93 found_ref = br->GetBit(); | 120 RETURN_FALSE_IF_ERROR(br->ReadBits(&found_ref, 1)); |
94 if (found_ref) | 121 if (found_ref) |
95 break; | 122 break; |
96 } | 123 } |
97 | 124 |
98 if (!found_ref) | 125 if (!found_ref) { |
99 VP9ReadFrameSize(br); | 126 if (!Vp9ReadFrameSize(br)) |
brandtr
2017/05/30 15:13:49
Add {} to make it easier to read.
åsapersson
2017/05/31 11:57:20
Done.
| |
100 | 127 return false; |
101 VP9ReadRenderSize(br); | 128 } |
129 return Vp9ReadRenderSize(br); | |
102 } | 130 } |
103 | 131 |
104 static void VP9ReadInterpolationFilter(VP9BitReader* br) { | 132 bool Vp9ReadInterpolationFilter(rtc::BitBuffer* br) { |
105 if (br->GetBit()) | 133 uint32_t bit; |
106 return; | 134 RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1)); |
135 if (bit) | |
136 return true; | |
107 | 137 |
108 br->GetValue(2); | 138 RETURN_FALSE_IF_ERROR(br->ConsumeBits(2)); |
139 return true; | |
109 } | 140 } |
110 | 141 |
111 static void VP9ReadLoopfilter(VP9BitReader* br) { | 142 bool Vp9ReadLoopfilter(rtc::BitBuffer* br) { |
112 // Filter level. | 143 // 6 bits: filter level. |
113 br->GetValue(6); | 144 // 3 bits: sharpness level. |
114 // Sharpness level. | 145 RETURN_FALSE_IF_ERROR(br->ConsumeBits(9)); |
115 br->GetValue(3); | 146 |
116 uint32_t mode_ref_delta_enabled = br->GetBit(); | 147 uint32_t mode_ref_delta_enabled; |
148 RETURN_FALSE_IF_ERROR(br->ReadBits(&mode_ref_delta_enabled, 1)); | |
117 if (mode_ref_delta_enabled) { | 149 if (mode_ref_delta_enabled) { |
118 uint32_t mode_ref_delta_update = br->GetBit(); | 150 uint32_t mode_ref_delta_update; |
151 RETURN_FALSE_IF_ERROR(br->ReadBits(&mode_ref_delta_update, 1)); | |
119 if (mode_ref_delta_update) { | 152 if (mode_ref_delta_update) { |
153 uint32_t bit; | |
120 for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) { | 154 for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) { |
121 if (br->GetBit()) | 155 RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1)); |
122 br->GetSignedValue(6); | 156 if (bit) { |
157 RETURN_FALSE_IF_ERROR(br->ConsumeBits(7)); | |
158 } | |
123 } | 159 } |
124 for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) { | 160 for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) { |
125 if (br->GetBit()) | 161 RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1)); |
126 br->GetSignedValue(6); | 162 if (bit) { |
163 RETURN_FALSE_IF_ERROR(br->ConsumeBits(7)); | |
164 } | |
127 } | 165 } |
128 } | 166 } |
129 } | 167 } |
168 return true; | |
130 } | 169 } |
170 } // namespace | |
131 | 171 |
132 bool GetQp(const uint8_t* buf, size_t length, int* qp) { | 172 bool GetQp(const uint8_t* buf, size_t length, int* qp) { |
133 VP9BitReader br(buf, length); | 173 rtc::BitBuffer br(buf, length); |
134 | 174 |
135 // Frame marker. | 175 // Frame marker. |
136 if (br.GetValue(2) != 0x2) { | 176 uint32_t frame_marker; |
177 RETURN_FALSE_IF_ERROR(br.ReadBits(&frame_marker, 2)); | |
178 if (frame_marker != 0x2) { | |
137 LOG(LS_WARNING) << "Failed to get QP. Frame marker should be 2."; | 179 LOG(LS_WARNING) << "Failed to get QP. Frame marker should be 2."; |
138 return false; | 180 return false; |
139 } | 181 } |
140 | 182 |
141 // Profile. | 183 // Profile. |
142 uint8_t profile = VP9ReadProfile(&br); | 184 uint8_t profile; |
143 if (profile > kVp9MaxProfile) { | 185 if (!Vp9ReadProfile(&br, &profile)) |
144 LOG(LS_WARNING) << "Failed to get QP. Unsupported bitstream profile: " | |
145 << profile; | |
146 return false; | 186 return false; |
147 } | |
148 | 187 |
149 // Show existing frame. | 188 // Show existing frame. |
150 if (br.GetBit()) | 189 uint32_t show_existing_frame; |
190 RETURN_FALSE_IF_ERROR(br.ReadBits(&show_existing_frame, 1)); | |
191 if (show_existing_frame) | |
151 return false; | 192 return false; |
152 | 193 |
153 // Frame type: KEY_FRAME(0), INTER_FRAME(1). | 194 // Frame type: KEY_FRAME(0), INTER_FRAME(1). |
154 uint8_t frame_type = br.GetBit(); | 195 uint32_t frame_type; |
155 // Show frame. | 196 uint32_t show_frame; |
156 uint8_t show_frame = br.GetBit(); | 197 uint32_t error_resilient; |
157 // Error resilient. | 198 RETURN_FALSE_IF_ERROR(br.ReadBits(&frame_type, 1)); |
158 uint8_t error_resilient = br.GetBit(); | 199 RETURN_FALSE_IF_ERROR(br.ReadBits(&show_frame, 1)); |
200 RETURN_FALSE_IF_ERROR(br.ReadBits(&error_resilient, 1)); | |
159 | 201 |
160 if (!frame_type) { | 202 if (!frame_type) { |
161 // Sync code. | 203 if (!Vp9ReadSyncCode(&br)) |
162 uint32_t sync_code = br.GetValue(24); | |
163 if (sync_code != 0x498342) { | |
164 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code."; | |
165 return false; | 204 return false; |
166 } | 205 if (!Vp9ReadColorConfig(&br, profile)) |
167 | 206 return false; |
168 if (!VP9ReadColorConfig(&br, profile)) | 207 if (!Vp9ReadFrameSize(&br)) |
208 return false; | |
209 if (!Vp9ReadRenderSize(&br)) | |
169 return false; | 210 return false; |
170 | 211 |
171 VP9ReadFrameSize(&br); | |
172 VP9ReadRenderSize(&br); | |
173 } else { | 212 } else { |
174 uint8_t intra_only = 0; | 213 uint32_t intra_only = 0; |
175 if (!show_frame) | 214 if (!show_frame) |
176 intra_only = br.GetBit(); | 215 RETURN_FALSE_IF_ERROR(br.ReadBits(&intra_only, 1)); |
177 | |
178 if (!error_resilient) | 216 if (!error_resilient) |
179 // Reset frame context. | 217 RETURN_FALSE_IF_ERROR(br.ConsumeBits(2)); // Reset frame context. |
180 br.GetValue(2); | |
181 | 218 |
182 if (intra_only) { | 219 if (intra_only) { |
183 // Sync code. | 220 if (!Vp9ReadSyncCode(&br)) |
184 if (br.GetValue(24) != 0x498342) { | |
185 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code."; | |
186 return false; | 221 return false; |
187 } | 222 |
188 if (profile > 0) { | 223 if (profile > 0) { |
189 if (!VP9ReadColorConfig(&br, profile)) | 224 if (!Vp9ReadColorConfig(&br, profile)) |
190 return false; | 225 return false; |
191 } | 226 } |
192 // Refresh frame flags. | 227 // Refresh frame flags. |
193 br.GetValue(8); | 228 RETURN_FALSE_IF_ERROR(br.ConsumeBits(8)); |
194 | 229 if (!Vp9ReadFrameSize(&br)) |
195 VP9ReadFrameSize(&br); | 230 return false; |
196 VP9ReadRenderSize(&br); | 231 if (!Vp9ReadRenderSize(&br)) |
232 return false; | |
197 } else { | 233 } else { |
198 // Refresh frame flags. | 234 // Refresh frame flags. |
199 br.GetValue(8); | 235 RETURN_FALSE_IF_ERROR(br.ConsumeBits(8)); |
200 | 236 |
201 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { | 237 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) { |
202 // Ref frame index. | 238 // 3 bits: Ref frame index. |
203 br.GetValue(3); | 239 // 1 bit: Ref frame sign biases. |
204 // Ref frame sign biases. | 240 RETURN_FALSE_IF_ERROR(br.ConsumeBits(4)); |
205 br.GetBit(); | |
206 } | 241 } |
207 | 242 |
208 VP9ReadFrameSizeFromRefs(&br); | 243 if (!Vp9ReadFrameSizeFromRefs(&br)) |
244 return false; | |
245 | |
209 // Allow high precision mv. | 246 // Allow high precision mv. |
210 br.GetBit(); | 247 RETURN_FALSE_IF_ERROR(br.ConsumeBits(1)); |
211 // Interpolation filter. | 248 // Interpolation filter. |
212 VP9ReadInterpolationFilter(&br); | 249 if (!Vp9ReadInterpolationFilter(&br)) |
250 return false; | |
213 } | 251 } |
214 } | 252 } |
215 | 253 |
216 if (!error_resilient) { | 254 if (!error_resilient) { |
217 // Refresh frame context. | 255 // 1 bit: Refresh frame context. |
218 br.GetBit(); | 256 // 1 bit: Frame parallel decoding mode. |
219 // Frame parallel decoding mode. | 257 RETURN_FALSE_IF_ERROR(br.ConsumeBits(2)); |
220 br.GetBit(); | |
221 } | 258 } |
222 | 259 |
223 // Frame context index. | 260 // Frame context index. |
224 br.GetValue(2); | 261 RETURN_FALSE_IF_ERROR(br.ConsumeBits(2)); |
225 | 262 |
226 VP9ReadLoopfilter(&br); | 263 if (!Vp9ReadLoopfilter(&br)) |
264 return false; | |
227 | 265 |
228 // Base QP. | 266 // Base QP. |
229 const int base_q0 = br.GetValue(8); | 267 uint8_t base_q0; |
268 RETURN_FALSE_IF_ERROR(br.ReadUInt8(&base_q0)); | |
230 *qp = base_q0; | 269 *qp = base_q0; |
231 return true; | 270 return true; |
232 } | 271 } |
233 | 272 |
234 } // namespace vp9 | 273 } // namespace vp9 |
235 | 274 |
236 } // namespace webrtc | 275 } // namespace webrtc |
OLD | NEW |