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 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 | 41 |
42 uint8_t SpatialIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { | 42 uint8_t SpatialIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { |
43 return (hdr.spatial_idx == kNoSpatialIdx) ? def : hdr.spatial_idx; | 43 return (hdr.spatial_idx == kNoSpatialIdx) ? def : hdr.spatial_idx; |
44 } | 44 } |
45 | 45 |
46 int16_t Tl0PicIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { | 46 int16_t Tl0PicIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { |
47 return (hdr.tl0_pic_idx == kNoTl0PicIdx) ? def : hdr.tl0_pic_idx; | 47 return (hdr.tl0_pic_idx == kNoTl0PicIdx) ? def : hdr.tl0_pic_idx; |
48 } | 48 } |
49 | 49 |
50 uint8_t GofIdxField(const RTPVideoHeaderVP9& hdr, uint8_t def) { | |
51 return (hdr.gof_idx == kNoGofIdx) ? def : hdr.gof_idx; | |
52 } | |
53 | |
54 // Picture ID: | 50 // Picture ID: |
55 // | 51 // |
56 // +-+-+-+-+-+-+-+-+ | 52 // +-+-+-+-+-+-+-+-+ |
57 // I: |M| PICTURE ID | M:0 => picture id is 7 bits. | 53 // I: |M| PICTURE ID | M:0 => picture id is 7 bits. |
58 // +-+-+-+-+-+-+-+-+ M:1 => picture id is 15 bits. | 54 // +-+-+-+-+-+-+-+-+ M:1 => picture id is 15 bits. |
59 // M: | EXTENDED PID | | 55 // M: | EXTENDED PID | |
60 // +-+-+-+-+-+-+-+-+ | 56 // +-+-+-+-+-+-+-+-+ |
61 // | 57 // |
62 size_t PictureIdLength(const RTPVideoHeaderVP9& hdr) { | 58 size_t PictureIdLength(const RTPVideoHeaderVP9& hdr) { |
63 if (hdr.picture_id == kNoPictureId) | 59 if (hdr.picture_id == kNoPictureId) |
64 return 0; | 60 return 0; |
65 return (hdr.max_picture_id == kMaxOneBytePictureId) ? 1 : 2; | 61 return (hdr.max_picture_id == kMaxOneBytePictureId) ? 1 : 2; |
66 } | 62 } |
67 | 63 |
68 bool PictureIdPresent(const RTPVideoHeaderVP9& hdr) { | 64 bool PictureIdPresent(const RTPVideoHeaderVP9& hdr) { |
69 return PictureIdLength(hdr) > 0; | 65 return PictureIdLength(hdr) > 0; |
70 } | 66 } |
71 | 67 |
72 // Layer indices: | 68 // Layer indices: |
73 // | 69 // |
74 // Flexible mode (F=1): Non-flexible mode (F=0): | 70 // Flexible mode (F=1): Non-flexible mode (F=0): |
75 // | 71 // |
76 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | 72 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |
77 // L: | T |U| S |D| |GOF_IDX| S |D| | 73 // L: | T |U| S |D| | T |U| S |D| |
78 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ | 74 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |
79 // | TL0PICIDX | | 75 // | TL0PICIDX | |
80 // +-+-+-+-+-+-+-+-+ | 76 // +-+-+-+-+-+-+-+-+ |
81 // | 77 // |
82 size_t LayerInfoLength(const RTPVideoHeaderVP9& hdr) { | 78 size_t LayerInfoLength(const RTPVideoHeaderVP9& hdr) { |
83 if (hdr.flexible_mode) { | 79 if (hdr.temporal_idx == kNoTemporalIdx && |
84 return (hdr.temporal_idx == kNoTemporalIdx && | 80 hdr.spatial_idx == kNoSpatialIdx) { |
85 hdr.spatial_idx == kNoSpatialIdx) ? 0 : 1; | 81 return 0; |
86 } else { | |
87 return (hdr.gof_idx == kNoGofIdx && | |
88 hdr.spatial_idx == kNoSpatialIdx) ? 0 : 2; | |
89 } | 82 } |
| 83 return hdr.flexible_mode ? 1 : 2; |
90 } | 84 } |
91 | 85 |
92 bool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) { | 86 bool LayerInfoPresent(const RTPVideoHeaderVP9& hdr) { |
93 return LayerInfoLength(hdr) > 0; | 87 return LayerInfoLength(hdr) > 0; |
94 } | 88 } |
95 | 89 |
96 // Reference indices: | 90 // Reference indices: |
97 // | 91 // |
98 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index | 92 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
99 // P,F: | P_DIFF |N| up to 3 times has to be specified. | 93 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 } | 185 } |
192 | 186 |
193 // Layer indices: | 187 // Layer indices: |
194 // | 188 // |
195 // Flexible mode (F=1): | 189 // Flexible mode (F=1): |
196 // | 190 // |
197 // +-+-+-+-+-+-+-+-+ | 191 // +-+-+-+-+-+-+-+-+ |
198 // L: | T |U| S |D| | 192 // L: | T |U| S |D| |
199 // +-+-+-+-+-+-+-+-+ | 193 // +-+-+-+-+-+-+-+-+ |
200 // | 194 // |
201 bool WriteLayerInfoFlexibleMode(const RTPVideoHeaderVP9& vp9, | 195 bool WriteLayerInfoCommon(const RTPVideoHeaderVP9& vp9, |
202 rtc::BitBufferWriter* writer) { | 196 rtc::BitBufferWriter* writer) { |
203 RETURN_FALSE_ON_ERROR(writer->WriteBits(TemporalIdxField(vp9, 0), 3)); | 197 RETURN_FALSE_ON_ERROR(writer->WriteBits(TemporalIdxField(vp9, 0), 3)); |
204 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.temporal_up_switch ? 1 : 0, 1)); | 198 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.temporal_up_switch ? 1 : 0, 1)); |
205 RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3)); | 199 RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3)); |
206 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.inter_layer_predicted ? 1: 0, 1)); | 200 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.inter_layer_predicted ? 1: 0, 1)); |
207 return true; | 201 return true; |
208 } | 202 } |
209 | 203 |
210 // Non-flexible mode (F=0): | 204 // Non-flexible mode (F=0): |
211 // | 205 // |
212 // +-+-+-+-+-+-+-+-+ | 206 // +-+-+-+-+-+-+-+-+ |
213 // L: |GOF_IDX| S |D| | 207 // L: | T |U| S |D| |
214 // +-+-+-+-+-+-+-+-+ | 208 // +-+-+-+-+-+-+-+-+ |
215 // | TL0PICIDX | | 209 // | TL0PICIDX | |
216 // +-+-+-+-+-+-+-+-+ | 210 // +-+-+-+-+-+-+-+-+ |
217 // | 211 // |
218 bool WriteLayerInfoNonFlexibleMode(const RTPVideoHeaderVP9& vp9, | 212 bool WriteLayerInfoNonFlexibleMode(const RTPVideoHeaderVP9& vp9, |
219 rtc::BitBufferWriter* writer) { | 213 rtc::BitBufferWriter* writer) { |
220 RETURN_FALSE_ON_ERROR(writer->WriteBits(GofIdxField(vp9, 0), 4)); | |
221 RETURN_FALSE_ON_ERROR(writer->WriteBits(SpatialIdxField(vp9, 0), 3)); | |
222 RETURN_FALSE_ON_ERROR(writer->WriteBits(vp9.inter_layer_predicted ? 1: 0, 1)); | |
223 RETURN_FALSE_ON_ERROR(writer->WriteUInt8(Tl0PicIdxField(vp9, 0))); | 214 RETURN_FALSE_ON_ERROR(writer->WriteUInt8(Tl0PicIdxField(vp9, 0))); |
224 return true; | 215 return true; |
225 } | 216 } |
226 | 217 |
227 bool WriteLayerInfo(const RTPVideoHeaderVP9& vp9, | 218 bool WriteLayerInfo(const RTPVideoHeaderVP9& vp9, |
228 rtc::BitBufferWriter* writer) { | 219 rtc::BitBufferWriter* writer) { |
229 if (vp9.flexible_mode) { | 220 if (!WriteLayerInfoCommon(vp9, writer)) |
230 return WriteLayerInfoFlexibleMode(vp9, writer); | 221 return false; |
231 } else { | 222 |
232 return WriteLayerInfoNonFlexibleMode(vp9, writer); | 223 if (vp9.flexible_mode) |
233 } | 224 return true; |
| 225 |
| 226 return WriteLayerInfoNonFlexibleMode(vp9, writer); |
234 } | 227 } |
235 | 228 |
236 // Reference indices: | 229 // Reference indices: |
237 // | 230 // |
238 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index | 231 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
239 // P,F: | P_DIFF |N| up to 3 times has to be specified. | 232 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
240 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows | 233 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows |
241 // current P_DIFF. | 234 // current P_DIFF. |
242 // | 235 // |
243 bool WriteRefIndices(const RTPVideoHeaderVP9& vp9, | 236 bool WriteRefIndices(const RTPVideoHeaderVP9& vp9, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 vp9->picture_id = picture_id; | 323 vp9->picture_id = picture_id; |
331 return true; | 324 return true; |
332 } | 325 } |
333 | 326 |
334 // Layer indices (flexible mode): | 327 // Layer indices (flexible mode): |
335 // | 328 // |
336 // +-+-+-+-+-+-+-+-+ | 329 // +-+-+-+-+-+-+-+-+ |
337 // L: | T |U| S |D| | 330 // L: | T |U| S |D| |
338 // +-+-+-+-+-+-+-+-+ | 331 // +-+-+-+-+-+-+-+-+ |
339 // | 332 // |
340 bool ParseLayerInfoFlexibleMode(rtc::BitBuffer* parser, | 333 bool ParseLayerInfoCommon(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { |
341 RTPVideoHeaderVP9* vp9) { | |
342 uint32_t t, u_bit, s, d_bit; | 334 uint32_t t, u_bit, s, d_bit; |
343 RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3)); | 335 RETURN_FALSE_ON_ERROR(parser->ReadBits(&t, 3)); |
344 RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1)); | 336 RETURN_FALSE_ON_ERROR(parser->ReadBits(&u_bit, 1)); |
345 RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3)); | 337 RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3)); |
346 RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1)); | 338 RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1)); |
347 vp9->temporal_idx = t; | 339 vp9->temporal_idx = t; |
348 vp9->temporal_up_switch = u_bit ? true : false; | 340 vp9->temporal_up_switch = u_bit ? true : false; |
349 vp9->spatial_idx = s; | 341 vp9->spatial_idx = s; |
350 vp9->inter_layer_predicted = d_bit ? true : false; | 342 vp9->inter_layer_predicted = d_bit ? true : false; |
351 return true; | 343 return true; |
352 } | 344 } |
353 | 345 |
354 // Layer indices (non-flexible mode): | 346 // Layer indices (non-flexible mode): |
355 // | 347 // |
356 // +-+-+-+-+-+-+-+-+ | 348 // +-+-+-+-+-+-+-+-+ |
357 // L: |GOF_IDX| S |D| | 349 // L: | T |U| S |D| |
358 // +-+-+-+-+-+-+-+-+ | 350 // +-+-+-+-+-+-+-+-+ |
359 // | TL0PICIDX | | 351 // | TL0PICIDX | |
360 // +-+-+-+-+-+-+-+-+ | 352 // +-+-+-+-+-+-+-+-+ |
361 // | 353 // |
362 bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser, | 354 bool ParseLayerInfoNonFlexibleMode(rtc::BitBuffer* parser, |
363 RTPVideoHeaderVP9* vp9) { | 355 RTPVideoHeaderVP9* vp9) { |
364 uint32_t gof_idx, s, d_bit; | |
365 uint8_t tl0picidx; | 356 uint8_t tl0picidx; |
366 RETURN_FALSE_ON_ERROR(parser->ReadBits(&gof_idx, 4)); | |
367 RETURN_FALSE_ON_ERROR(parser->ReadBits(&s, 3)); | |
368 RETURN_FALSE_ON_ERROR(parser->ReadBits(&d_bit, 1)); | |
369 RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx)); | 357 RETURN_FALSE_ON_ERROR(parser->ReadUInt8(&tl0picidx)); |
370 vp9->gof_idx = gof_idx; | |
371 vp9->spatial_idx = s; | |
372 vp9->inter_layer_predicted = d_bit ? true : false; | |
373 vp9->tl0_pic_idx = tl0picidx; | 358 vp9->tl0_pic_idx = tl0picidx; |
374 return true; | 359 return true; |
375 } | 360 } |
376 | 361 |
377 bool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { | 362 bool ParseLayerInfo(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { |
378 if (vp9->flexible_mode) { | 363 if (!ParseLayerInfoCommon(parser, vp9)) |
379 return ParseLayerInfoFlexibleMode(parser, vp9); | 364 return false; |
380 } else { | 365 |
381 return ParseLayerInfoNonFlexibleMode(parser, vp9); | 366 if (vp9->flexible_mode) |
382 } | 367 return true; |
| 368 |
| 369 return ParseLayerInfoNonFlexibleMode(parser, vp9); |
383 } | 370 } |
384 | 371 |
385 // Reference indices: | 372 // Reference indices: |
386 // | 373 // |
387 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index | 374 // +-+-+-+-+-+-+-+-+ P=1,F=1: At least one reference index |
388 // P,F: | P_DIFF |N| up to 3 times has to be specified. | 375 // P,F: | P_DIFF |N| up to 3 times has to be specified. |
389 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows | 376 // +-+-+-+-+-+-+-+-+ N=1: An additional P_DIFF follows |
390 // current P_DIFF. | 377 // current P_DIFF. |
391 // | 378 // |
392 bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { | 379 bool ParseRefIndices(rtc::BitBuffer* parser, RTPVideoHeaderVP9* vp9) { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // | 584 // |
598 // Payload descriptor for F = 0 (non-flexible mode) | 585 // Payload descriptor for F = 0 (non-flexible mode) |
599 // 0 1 2 3 4 5 6 7 | 586 // 0 1 2 3 4 5 6 7 |
600 // +-+-+-+-+-+-+-+-+ | 587 // +-+-+-+-+-+-+-+-+ |
601 // |I|P|L|F|B|E|V|-| (REQUIRED) | 588 // |I|P|L|F|B|E|V|-| (REQUIRED) |
602 // +-+-+-+-+-+-+-+-+ | 589 // +-+-+-+-+-+-+-+-+ |
603 // I: |M| PICTURE ID | (RECOMMENDED) | 590 // I: |M| PICTURE ID | (RECOMMENDED) |
604 // +-+-+-+-+-+-+-+-+ | 591 // +-+-+-+-+-+-+-+-+ |
605 // M: | EXTENDED PID | (RECOMMENDED) | 592 // M: | EXTENDED PID | (RECOMMENDED) |
606 // +-+-+-+-+-+-+-+-+ | 593 // +-+-+-+-+-+-+-+-+ |
607 // L: |GOF_IDX| S |D| (CONDITIONALLY RECOMMENDED) | 594 // L: | T |U| S |D| (CONDITIONALLY RECOMMENDED) |
608 // +-+-+-+-+-+-+-+-+ | 595 // +-+-+-+-+-+-+-+-+ |
609 // | TL0PICIDX | (CONDITIONALLY REQUIRED) | 596 // | TL0PICIDX | (CONDITIONALLY REQUIRED) |
610 // +-+-+-+-+-+-+-+-+ | 597 // +-+-+-+-+-+-+-+-+ |
611 // V: | SS | | 598 // V: | SS | |
612 // | .. | | 599 // | .. | |
613 // +-+-+-+-+-+-+-+-+ | 600 // +-+-+-+-+-+-+-+-+ |
614 | 601 |
615 bool RtpPacketizerVp9::WriteHeaderAndPayload(const PacketInfo& packet_info, | 602 bool RtpPacketizerVp9::WriteHeaderAndPayload(const PacketInfo& packet_info, |
616 uint8_t* buffer, | 603 uint8_t* buffer, |
617 size_t* bytes_to_send) const { | 604 size_t* bytes_to_send) const { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 if (parsed_payload->payload_length == 0) { | 733 if (parsed_payload->payload_length == 0) { |
747 LOG(LS_ERROR) << "Failed parsing VP9 payload data."; | 734 LOG(LS_ERROR) << "Failed parsing VP9 payload data."; |
748 return false; | 735 return false; |
749 } | 736 } |
750 parsed_payload->payload = | 737 parsed_payload->payload = |
751 payload + payload_length - parsed_payload->payload_length; | 738 payload + payload_length - parsed_payload->payload_length; |
752 | 739 |
753 return true; | 740 return true; |
754 } | 741 } |
755 } // namespace webrtc | 742 } // namespace webrtc |
OLD | NEW |