Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: webrtc/modules/video_coding/utility/vp9_uncomp_header_parser.cc

Issue 2891803003: Add vp9 QP parser. (Closed)
Patch Set: Fix compile warnings. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_uncomp_header_parser.h"
11
brandtr 2017/05/19 14:10:27 General comment: have you looked into using the rt
jianj1 2017/05/19 21:20:56 Done.
12 #include "webrtc/base/logging.h"
13
14 namespace webrtc {
15
16 namespace vp9 {
17 namespace {
18 const size_t kVp9MaxProfile = 4;
19 const size_t kVp9NumRefsPerFrame = 3;
20 const size_t kVp9MaxRefLFDeltas = 4;
21 const size_t kVp9MaxModeLFDeltas = 2;
22 } // namespace
23
24 static void VP9InitBitReader(VP9BitReader *const br, const uint8_t *const start,
brandtr 2017/05/19 14:10:27 To me, it seems that VP9BitReader could be a full-
jianj1 2017/05/19 21:20:56 Done. BTW, the same thing could be done to vp8_he
25 const uint8_t *const end) {
brandtr 2017/05/19 14:10:27 const uint8_t*, here and in other signatures.
jianj1 2017/05/19 21:20:56 Done.
26 br->offset_ = 0;
27 br->buf_ = start;
28 br->buf_end_ = end;
29 }
30
31 static int32_t VP9GetBit(VP9BitReader *const br) {
32 const size_t off = br->offset_;
33 const size_t p = off >> 3;
34 const int q = 7 - static_cast<int>(off & 0x7);
35 if (br->buf_ + p < br->buf_end_) {
36 const int bit = (br->buf_[p] >> q) & 1;
37 br->offset_ = off + 1;
38 return bit;
39 } else {
40 LOG(LS_WARNING) << "Failed to get QP. Reached EOF.";
41 return 0;
42 }
43 }
44
45 static int32_t VP9GetValue(VP9BitReader *const br, int bits) {
46 int value = 0, bit;
47 for (bit = bits - 1; bit >= 0; bit--)
48 value |= VP9GetBit(br) << bit;
49 return value;
50 }
51
52 static int32_t VP9GetSignedValue(VP9BitReader *const br, int bits) {
53 const int value = VP9GetValue(br, bits);
54 return VP9GetBit(br) ? -value : value;
55 }
56
57 static uint8_t VP9ReadProfile(VP9BitReader *const br) {
58 uint8_t profile = 0;
59 if (VP9GetBit(br))
60 profile |= 1;
61 if (VP9GetBit(br))
62 profile |= 2;
63 if (profile > 2 && VP9GetBit(br))
64 profile += 1;
65 return profile;
66 }
67
68 static bool VP9ReadColorConfig(VP9BitReader *const br, const uint8_t profile) {
69 if (profile == 2 || profile == 3) {
70 // bitdepth
71 VP9GetBit(br);
72 }
73
74 uint8_t color_space = VP9GetValue(br, 3);
75 // SRGB is 7
76 if (color_space != 7) {
77 // yuv range flag
78 VP9GetBit(br);
79 if (profile == 1 || profile == 3) {
80 // subsampling x
brandtr 2017/05/19 14:10:27 Comments: start with capital letter and end with p
jianj1 2017/05/19 21:20:56 Done.
81 VP9GetBit(br);
82 // subsampling y
83 VP9GetBit(br);
84 // reserved
85 if (VP9GetBit(br)) {
86 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set.";
87 return false;
88 }
89 }
90 } else {
91 if (profile == 1 || profile == 3) {
92 // reserved
93 if (VP9GetBit(br)) {
94 LOG(LS_WARNING) << "Failed to get QP. Reserved bit set.";
95 return false;
96 }
97 } else {
98 LOG(LS_WARNING) << "Failed to get QP. 4:4:4 color not supported in "
99 "profile 0 or 2.";
100 return false;
101 }
102 }
103
104 return true;
105 }
106
107 static void VP9ReadFrameSize(VP9BitReader *const br) {
108 // frame width
109 uint32_t width = VP9GetValue(br, 16);
110 (void)width;
111 // frame height
112 uint32_t height = VP9GetValue(br, 16);
113 (void)height;
114 }
115
116 static void VP9ReadRenderSize(VP9BitReader *const br) {
117 // scaling
118 if (VP9GetBit(br)) {
119 // render width
120 uint32_t width = VP9GetValue(br, 16);
121 // render height
122 uint32_t height = VP9GetValue(br, 16);
123 (void)width;
124 (void)height;
125 }
126 }
127
128 static void VP9ReadFrameSizeFromRefs(VP9BitReader *const br) {
129 int found_ref = 0;
130 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
131 // size in refs
132 found_ref = VP9GetBit(br);
133 if (found_ref)
134 break;
135 }
136
137 if (!found_ref)
138 VP9ReadFrameSize(br);
139
140 VP9ReadRenderSize(br);
141 }
142
143 static void VP9ReadInterpolationFilter(VP9BitReader *const br) {
144 if (VP9GetBit(br))
145 return;
146
147 VP9GetValue(br, 2);
148 }
149
150 static void VP9ReadLoopfilter(VP9BitReader *const br) {
151 // filter level
152 VP9GetValue(br, 6);
153 // sharpness level
154 VP9GetValue(br, 3);
155 uint32_t mode_ref_delta_enabled = VP9GetBit(br);
156 if (mode_ref_delta_enabled) {
157 uint32_t mode_ref_delta_update = VP9GetBit(br);
158 if (mode_ref_delta_update) {
159 for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) {
160 if (VP9GetBit(br))
161 VP9GetSignedValue(br, 6);
162 }
163 for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) {
164 if (VP9GetBit(br))
165 VP9GetSignedValue(br, 6);
166 }
167 }
168 }
169 }
170
171 bool GetQp(const uint8_t *buf, size_t length, int *qp) {
172 VP9BitReader br;
173 VP9InitBitReader(&br, buf, buf + length);
174
175 // frame marker
176 if (VP9GetValue(&br, 2) != 0x2) {
177 LOG(LS_WARNING) << "Failed to get QP. Frame marker should be 2.";
178 return false;
179 }
180
181 // profile
182 uint8_t profile = VP9ReadProfile(&br);
183 if (profile > kVp9MaxProfile) {
184 LOG(LS_WARNING) << "Failed to get QP. Unsupported bitstream profile: "
185 << profile;
186 return false;
187 }
188
189 // show existing frame
190 if (VP9GetBit(&br)) {
191 VP9GetValue(&br, 3);
192 return false;
193 }
194
195 // frame type: KEY_FRAME(0), INTER_FRAME(1)
196 uint8_t frame_type = VP9GetBit(&br);
197 // show frame
198 uint8_t show_frame = VP9GetBit(&br);
199 // error resilient
200 uint8_t error_resilient = VP9GetBit(&br);
201
202 if (!frame_type) {
203 // sync code
204 uint32_t sync_code = VP9GetValue(&br, 24);
205 if (sync_code != 0x498342) {
206 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code.";
207 return false;
208 }
209
210 if (!VP9ReadColorConfig(&br, profile))
211 return false;
212
213 VP9ReadFrameSize(&br);
214 VP9ReadRenderSize(&br);
215 } else {
216 uint8_t intra_only = 0;
217 if (!show_frame)
218 intra_only = VP9GetBit(&br);
219
220 if (!error_resilient)
221 // reset frame context
222 VP9GetValue(&br, 2);
223
224 if (intra_only) {
225 // sync code
226 if (VP9GetValue(&br, 24) != 0x498342) {
227 LOG(LS_WARNING) << "Failed to get QP. Invalid sync code.";
228 return false;
229 }
230 if (profile > 0) {
231 if (!VP9ReadColorConfig(&br, profile))
232 return false;
233 }
234 // refresh frame flags
235 VP9GetValue(&br, 8);
236
237 VP9ReadFrameSize(&br);
238 VP9ReadRenderSize(&br);
239 } else {
240 // refresh frame flags
241 int32_t test = VP9GetValue(&br, 8);
242 (void)test;
243
244 for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
245 // ref frame index
246 int32_t idx = VP9GetValue(&br, 3);
247 // ref frame sign biases
248 int32_t bias = VP9GetBit(&br);
249 (void)idx;
250 (void)bias;
251 }
252
253 VP9ReadFrameSizeFromRefs(&br);
254
255 // allow high precision mv
256 VP9GetBit(&br);
257
258 // interpolation filter
259 VP9ReadInterpolationFilter(&br);
260 }
261 }
262
263 if (!error_resilient) {
264 // refresh frame context
265 VP9GetBit(&br);
266 // frame parallel decoding mode
267 VP9GetBit(&br);
268 }
269
270 // frame context index
271 VP9GetValue(&br, 2);
272
273 VP9ReadLoopfilter(&br);
274
275 // Base QP.
276 const int base_q0 = VP9GetValue(&br, 8);
277 *qp = base_q0;
278 return true;
279 }
280
281 } // namespace vp9
282
283 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698