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 | 10 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 hdr.spatial_idx == kNoSpatialIdx) ? 0 : 2; | 88 hdr.spatial_idx == kNoSpatialIdx) ? 0 : 2; |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 bool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) { | 92 bool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) { |
93 return LayerInfoLength(hdr) > 0; | 93 return LayerInfoLength(hdr) > 0; |
94 } | 94 } |
95 | 95 |
96 // Reference indices: | 96 // Reference indices: |
97 // | 97 // |
98 // +-+-+-+-+-+-+-+-+ -| P=1,F=1: At least one reference index | 98 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
99 // P,F: | P_DIFF |X|N| . has to be specified. | 99 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
100 // +-+-+-+-+-+-+-+-+ . up to 3 times | 100 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows |
101 // X: |EXTENDED P_DIFF| . X=1: Extended P_DIFF is used (14 | 101 // current P_DIFF. |
102 // +-+-+-+-+-+-+-+-+ -| bits). Else 6 bits are used. | 102 // |
103 // N=1: An additional P_DIFF follows | |
104 // current P_DIFF. | |
105 size_t RefIndicesLength(const RTPVideoHeaderVP9& hdr) { | 103 size_t RefIndicesLength(const RTPVideoHeaderVP9& hdr) { |
106 if (!hdr.inter_pic_predicted || !hdr.flexible_mode) | 104 if (!hdr.inter_pic_predicted || !hdr.flexible_mode) |
107 return 0; | 105 return 0; |
108 | 106 |
109 RTC_DCHECK_GT(hdr.num_ref_pics, 0U); | 107 RTC_DCHECK_GT(hdr.num_ref_pics, 0U); |
110 RTC_DCHECK_LE(hdr.num_ref_pics, kMaxVp9RefPics); | 108 RTC_DCHECK_LE(hdr.num_ref_pics, kMaxVp9RefPics); |
111 size_t length = 0; | 109 return hdr.num_ref_pics; |
112 for (size_t i = 0; i < hdr.num_ref_pics; ++i) { | |
113 length += hdr.pid_diff[i] > 0x3F ? 2 : 1; // P_DIFF > 6 bits => extended | |
114 } | |
115 return length; | |
116 } | 110 } |
117 | 111 |
118 // Scalability structure (SS). | 112 // Scalability structure (SS). |
119 // | 113 // |
120 // +-+-+-+-+-+-+-+-+ | 114 // +-+-+-+-+-+-+-+-+ |
121 // V: | N_S |Y| N_G | | 115 // V: | N_S |Y| N_G | |
122 // +-+-+-+-+-+-+-+-+ -| | 116 // +-+-+-+-+-+-+-+-+ -| |
123 // Y: | WIDTH | (OPTIONAL) . | 117 // Y: | WIDTH | (OPTIONAL) . |
124 // + + . | 118 // + + . |
125 // | | (OPTIONAL) . | 119 // | | (OPTIONAL) . |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 rtc::BitBufferWriter* writer) { | 224 rtc::BitBufferWriter* writer) { |
231 if (vp9.flexible_mode) { | 225 if (vp9.flexible_mode) { |
232 return WriteLayerInfoFlexibleMode(vp9, writer); | 226 return WriteLayerInfoFlexibleMode(vp9, writer); |
233 } else { | 227 } else { |
234 return WriteLayerInfoNonFlexibleMode(vp9, writer); | 228 return WriteLayerInfoNonFlexibleMode(vp9, writer); |
235 } | 229 } |
236 } | 230 } |
237 | 231 |
238 // Reference indices: | 232 // Reference indices: |
239 // | 233 // |
240 // +-+-+-+-+-+-+-+-+ -| P=1,F=1: At least one reference index | 234 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
241 // P,F: | P_DIFF |X|N| . has to be specified. | 235 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
242 // +-+-+-+-+-+-+-+-+ . up to 3 times | 236 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows |
243 // X: |EXTENDED P_DIFF| . X=1: Extended P_DIFF is used (14 | 237 // current P_DIFF. |
244 // +-+-+-+-+-+-+-+-+ -| bits). Else 6 bits are used. | 238 // |
245 // N=1: An additional P_DIFF follows | |
246 // current P_DIFF. | |
247 bool WriteRefIndices(const RTPVideoHeaderVP9& vp9, | 239 bool WriteRefIndices(const RTPVideoHeaderVP9& vp9, |
248 rtc::BitBufferWriter* writer) { | 240 rtc::BitBufferWriter* writer) { |
249 if (!PictureIdPresent(vp9) || | 241 if (!PictureIdPresent(vp9) || |
250 vp9.num_ref_pics == 0 || vp9.num_ref_pics > kMaxVp9RefPics) { | 242 vp9.num_ref_pics == 0 || vp9.num_ref_pics > kMaxVp9RefPics) { |
251 return false; | 243 return false; |
252 } | 244 } |
253 for (size_t i = 0; i < vp9.num_ref_pics; ++i) { | 245 for (size_t i = 0; i < vp9.num_ref_pics; ++i) { |
254 bool x_bit = (vp9.pid_diff[i] > 0x3F); | |
255 bool n_bit = !(i == vp9.num_ref_pics - 1); | 246 bool n_bit = !(i == vp9.num_ref_pics - 1); |
256 if (x_bit) { | 247 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.pid_diff[i], 7)); |
257 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.pid_diff[i] >> 8, 6)); | 248 RETURN_FALSE_ON_ERROR(writer->WriteBits(n_bit ? 1 : 0, 1)); |
258 RETURN_FALSE_ON_ERROR(writer->WriteBits(x_bit ? 1 : 0, 1)); | |
259 RETURN_FALSE_ON_ERROR(writer->WriteBits(n_bit ? 1 : 0, 1)); | |
260 RETURN_FALSE_ON_ERROR(writer->WriteUInt8(vp9.pid_diff[i])); | |
261 } else { | |
262 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.pid_diff[i], 6)); | |
263 RETURN_FALSE_ON_ERROR(writer->WriteBits(x_bit ? 1 : 0, 1)); | |
264 RETURN_FALSE_ON_ERROR(writer->WriteBits(n_bit ? 1 : 0, 1)); | |
265 } | |
266 } | 249 } |
267 return true; | 250 return true; |
268 } | 251 } |
269 | 252 |
270 // Scalability structure (SS). | 253 // Scalability structure (SS). |
271 // | 254 // |
272 // +-+-+-+-+-+-+-+-+ | 255 // +-+-+-+-+-+-+-+-+ |
273 // V: | N_S |Y| N_G | | 256 // V: | N_S |Y| N_G | |
274 // +-+-+-+-+-+-+-+-+ -| | 257 // +-+-+-+-+-+-+-+-+ -| |
275 // Y: | WIDTH | (OPTIONAL) . | 258 // Y: | WIDTH | (OPTIONAL) . |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 bool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { | 367 bool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { |
385 if (vp9->flexible_mode) { | 368 if (vp9->flexible_mode) { |
386 return ParseLayerInfoFlexibleMode(parser, vp9); | 369 return ParseLayerInfoFlexibleMode(parser, vp9); |
387 } else { | 370 } else { |
388 return ParseLayerInfoNonFlexibleMode(parser, vp9); | 371 return ParseLayerInfoNonFlexibleMode(parser, vp9); |
389 } | 372 } |
390 } | 373 } |
391 | 374 |
392 // Reference indices: | 375 // Reference indices: |
393 // | 376 // |
394 // +-+-+-+-+-+-+-+-+ -| P=1,F=1: At least one reference index | 377 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
395 // P,F: | P_DIFF |X|N| . has to be specified. | 378 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
396 // +-+-+-+-+-+-+-+-+ . up to 3 times | 379 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows |
397 // X: |EXTENDED P_DIFF| . X=1: Extended P_DIFF is used (14 | 380 // current P_DIFF. |
398 // +-+-+-+-+-+-+-+-+ -| bits). Else 6 bits are used. | 381 // |
399 // N=1: An additional P_DIFF follows | |
400 // current P_DIFF. | |
401 bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { | 382 bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { |
402 if (vp9->picture_id == kNoPictureId) | 383 if (vp9->picture_id == kNoPictureId) |
403 return false; | 384 return false; |
404 | 385 |
405 vp9->num_ref_pics = 0; | 386 vp9->num_ref_pics = 0; |
406 uint32_t n_bit; | 387 uint32_t n_bit; |
407 do { | 388 do { |
408 if (vp9->num_ref_pics == kMaxVp9RefPics) | 389 if (vp9->num_ref_pics == kMaxVp9RefPics) |
409 return false; | 390 return false; |
410 | 391 |
411 uint32_t p_diff, x_bit; | 392 uint32_t p_diff; |
412 RETURN_FALSE_ON_ERROR(parser->ReadBits(&p_diff, 6)); | 393 RETURN_FALSE_ON_ERROR(parser->ReadBits(&p_diff, 7)); |
413 RETURN_FALSE_ON_ERROR(parser->ReadBits(&x_bit, 1)); | |
414 RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_bit, 1)); | 394 RETURN_FALSE_ON_ERROR(parser->ReadBits(&n_bit, 1)); |
415 | 395 |
416 if (x_bit) { | |
417 // P_DIFF is 14 bits. | |
418 uint8_t ext_p_diff; | |
419 RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&ext_p_diff)); | |
420 p_diff = (p_diff << 8) + ext_p_diff; | |
421 } | |
422 | |
423 vp9->pid_diff[vp9->num_ref_pics] = p_diff; | 396 vp9->pid_diff[vp9->num_ref_pics] = p_diff; |
424 uint32_t scaled_pid = vp9->picture_id; | 397 uint32_t scaled_pid = vp9->picture_id; |
425 while (p_diff > scaled_pid) { | 398 if (p_diff > scaled_pid) { |
| 399 // TODO(asapersson): Max should correspond to the picture id of last wrap. |
426 scaled_pid += vp9->max_picture_id + 1; | 400 scaled_pid += vp9->max_picture_id + 1; |
427 } | 401 } |
428 vp9->ref_picture_id[vp9->num_ref_pics++] = scaled_pid - p_diff; | 402 vp9->ref_picture_id[vp9->num_ref_pics++] = scaled_pid - p_diff; |
429 } while (n_bit); | 403 } while (n_bit); |
430 | 404 |
431 return true; | 405 return true; |
432 } | 406 } |
433 | 407 |
434 // Scalability structure (SS). | 408 // Scalability structure (SS). |
435 // | 409 // |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 // 0 1 2 3 4 5 6 7 | 564 // 0 1 2 3 4 5 6 7 |
591 // +-+-+-+-+-+-+-+-+ | 565 // +-+-+-+-+-+-+-+-+ |
592 // |I|P|L|F|B|E|V|-| (REQUIRED) | 566 // |I|P|L|F|B|E|V|-| (REQUIRED) |
593 // +-+-+-+-+-+-+-+-+ | 567 // +-+-+-+-+-+-+-+-+ |
594 // I: |M| PICTURE ID | (RECOMMENDED) | 568 // I: |M| PICTURE ID | (RECOMMENDED) |
595 // +-+-+-+-+-+-+-+-+ | 569 // +-+-+-+-+-+-+-+-+ |
596 // M: | EXTENDED PID | (RECOMMENDED) | 570 // M: | EXTENDED PID | (RECOMMENDED) |
597 // +-+-+-+-+-+-+-+-+ | 571 // +-+-+-+-+-+-+-+-+ |
598 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) | 572 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) |
599 // +-+-+-+-+-+-+-+-+ -| | 573 // +-+-+-+-+-+-+-+-+ -| |
600 // P,F: | P_DIFF |X|N| (CONDITIONALLY RECOMMENDED) . | 574 // P,F: | P_DIFF |N| (CONDITIONALLY RECOMMENDED) . up to 3 times |
601 // +-+-+-+-+-+-+-+-+ . up to 3 times | |
602 // X: |EXTENDED P_DIFF| . | |
603 // +-+-+-+-+-+-+-+-+ -| | 575 // +-+-+-+-+-+-+-+-+ -| |
604 // V: | SS | | 576 // V: | SS | |
605 // | .. | | 577 // | .. | |
606 // +-+-+-+-+-+-+-+-+ | 578 // +-+-+-+-+-+-+-+-+ |
607 // | 579 // |
608 // Payload descriptor for F = 0 (non-flexible mode) | 580 // Payload descriptor for F = 0 (non-flexible mode) |
609 // 0 1 2 3 4 5 6 7 | 581 // 0 1 2 3 4 5 6 7 |
610 // +-+-+-+-+-+-+-+-+ | 582 // +-+-+-+-+-+-+-+-+ |
611 // |I|P|L|F|B|E|V|-| (REQUIRED) | 583 // |I|P|L|F|B|E|V|-| (REQUIRED) |
612 // +-+-+-+-+-+-+-+-+ | 584 // +-+-+-+-+-+-+-+-+ |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 if (parsed_payload->payload_length == 0) { | 728 if (parsed_payload->payload_length == 0) { |
757 LOG(LS_ERROR) << "Failed parsing VP9 payload data."; | 729 LOG(LS_ERROR) << "Failed parsing VP9 payload data."; |
758 return false; | 730 return false; |
759 } | 731 } |
760 parsed_payload->payload = | 732 parsed_payload->payload = |
761 payload + payload_length - parsed_payload->payload_length; | 733 payload + payload_length - parsed_payload->payload_length; |
762 | 734 |
763 return true; | 735 return true; |
764 } | 736 } |
765 } // namespace webrtc | 737 } // namespace webrtc |
OLD | NEW |