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