OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 <stdint.h> | 10 #include <stdint.h> |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 | 12 |
13 #include "webrtc/modules/video_coding/utility/include/vp8_header_parser.h" | 13 #include "webrtc/modules/video_coding/utility/include/vp8_header_parser.h" |
14 | 14 |
| 15 #include "webrtc/system_wrappers/interface/logging.h" |
| 16 |
15 namespace webrtc { | 17 namespace webrtc { |
16 | 18 |
17 namespace vp8 { | 19 namespace vp8 { |
| 20 namespace { |
| 21 const size_t kCommonPayloadHeaderLength = 3; |
| 22 const size_t kKeyPayloadHeaderLength = 10; |
| 23 } // namespace |
18 | 24 |
19 static uint32_t BSwap32(uint32_t x) { | 25 static uint32_t BSwap32(uint32_t x) { |
20 return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); | 26 return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); |
21 } | 27 } |
22 | 28 |
23 static void VP8LoadFinalBytes(VP8BitReader* const br) { | 29 static void VP8LoadFinalBytes(VP8BitReader* const br) { |
24 // Only read 8bits at a time. | 30 // Only read 8bits at a time. |
25 if (br->buf_ < br->buf_end_) { | 31 if (br->buf_ < br->buf_end_) { |
26 br->bits_ += 8; | 32 br->bits_ += 8; |
27 br->value_ = static_cast<uint32_t>(*br->buf_++) | (br->value_ << 8); | 33 br->value_ = static_cast<uint32_t>(*br->buf_++) | (br->value_ << 8); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 155 } |
150 for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { | 156 for (i = 0; i < NUM_MODE_LF_DELTAS; ++i) { |
151 if (VP8Get(br)) { | 157 if (VP8Get(br)) { |
152 VP8GetSignedValue(br, 6); | 158 VP8GetSignedValue(br, 6); |
153 } | 159 } |
154 } | 160 } |
155 } | 161 } |
156 } | 162 } |
157 } | 163 } |
158 | 164 |
159 int GetQP(uint8_t* buf) { | 165 bool GetQp(const uint8_t* buf, size_t length, int* qp) { |
| 166 if (length < kCommonPayloadHeaderLength) { |
| 167 LOG(LS_WARNING) << "Failed to get QP, invalid length."; |
| 168 return false; |
| 169 } |
160 VP8BitReader br; | 170 VP8BitReader br; |
161 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); | 171 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); |
162 int key_frame = !(bits & 1); | 172 int key_frame = !(bits & 1); |
163 // Size of first partition in bytes. | 173 // Size of first partition in bytes. |
164 int partition_length = (bits >> 5); | 174 uint32_t partition_length = (bits >> 5); |
165 // Skip past uncompressed header: 10bytes for key, 3bytes for delta frames. | 175 size_t header_length = kCommonPayloadHeaderLength; |
166 if (key_frame) { | 176 if (key_frame) { |
167 buf += 10; | 177 header_length = kKeyPayloadHeaderLength; |
168 } else { | |
169 buf += 3; | |
170 } | 178 } |
| 179 if (header_length + partition_length > length) { |
| 180 LOG(LS_WARNING) << "Failed to get QP, invalid length: " << length; |
| 181 return false; |
| 182 } |
| 183 buf += header_length; |
| 184 |
171 VP8InitBitReader(&br, buf, buf + partition_length); | 185 VP8InitBitReader(&br, buf, buf + partition_length); |
172 if (key_frame) { | 186 if (key_frame) { |
173 // Color space and pixel type. | 187 // Color space and pixel type. |
174 VP8Get(&br); | 188 VP8Get(&br); |
175 VP8Get(&br); | 189 VP8Get(&br); |
176 } | 190 } |
177 ParseSegmentHeader(&br); | 191 ParseSegmentHeader(&br); |
178 ParseFilterHeader(&br); | 192 ParseFilterHeader(&br); |
179 // Number of coefficient data partitions. | 193 // Number of coefficient data partitions. |
180 VP8GetValue(&br, 2); | 194 VP8GetValue(&br, 2); |
181 // Base QP. | 195 // Base QP. |
182 const int base_q0 = VP8GetValue(&br, 7); | 196 const int base_q0 = VP8GetValue(&br, 7); |
183 return base_q0; | 197 if (br.eof_ == 1) { |
| 198 LOG(LS_WARNING) << "Failed to get QP, end of file reached."; |
| 199 return false; |
| 200 } |
| 201 *qp = base_q0; |
| 202 return true; |
184 } | 203 } |
185 | 204 |
186 } // namespace vp8 | 205 } // namespace vp8 |
187 | 206 |
188 } // namespace webrtc | 207 } // namespace webrtc |
OLD | NEW |