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