diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.cc b/modules/rtp_rtcp/source/rtp_format_vp9.cc index ad0a7cf52d..28f84355be 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp9.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp9.cc @@ -591,7 +591,7 @@ bool RtpPacketizerVp9::NextPacket(RtpPacketToSend* packet) { // Payload descriptor for F = 1 (flexible mode) // 0 1 2 3 4 5 6 7 // +-+-+-+-+-+-+-+-+ -// |I|P|L|F|B|E|V|-| (REQUIRED) +// |I|P|L|F|B|E|V|Z| (REQUIRED) // +-+-+-+-+-+-+-+-+ // I: |M| PICTURE ID | (RECOMMENDED) // +-+-+-+-+-+-+-+-+ @@ -608,7 +608,7 @@ bool RtpPacketizerVp9::NextPacket(RtpPacketToSend* packet) { // Payload descriptor for F = 0 (non-flexible mode) // 0 1 2 3 4 5 6 7 // +-+-+-+-+-+-+-+-+ -// |I|P|L|F|B|E|V|-| (REQUIRED) +// |I|P|L|F|B|E|V|Z| (REQUIRED) // +-+-+-+-+-+-+-+-+ // I: |M| PICTURE ID | (RECOMMENDED) // +-+-+-+-+-+-+-+-+ @@ -652,6 +652,7 @@ bool RtpPacketizerVp9::WriteHeader(const PacketInfo& packet_info, bool b_bit = packet_info.layer_begin; bool e_bit = packet_info.layer_end; bool v_bit = hdr_.ss_data_available && b_bit; + bool z_bit = hdr_.non_ref_for_inter_layer_pred; rtc::BitBufferWriter writer(buffer, max_payload_length_); RETURN_FALSE_ON_ERROR(writer.WriteBits(i_bit ? 1 : 0, 1)); @@ -661,7 +662,7 @@ bool RtpPacketizerVp9::WriteHeader(const PacketInfo& packet_info, RETURN_FALSE_ON_ERROR(writer.WriteBits(b_bit ? 1 : 0, 1)); RETURN_FALSE_ON_ERROR(writer.WriteBits(e_bit ? 1 : 0, 1)); RETURN_FALSE_ON_ERROR(writer.WriteBits(v_bit ? 1 : 0, 1)); - RETURN_FALSE_ON_ERROR(writer.WriteBits(kReservedBitValue0, 1)); + RETURN_FALSE_ON_ERROR(writer.WriteBits(z_bit ? 1 : 0, 1)); // Add fields that are present. if (i_bit && !WritePictureId(hdr_, &writer)) { @@ -701,7 +702,7 @@ bool RtpDepacketizerVp9::Parse(ParsedPayload* parsed_payload, // Parse mandatory first byte of payload descriptor. rtc::BitBuffer parser(payload, payload_length); - uint32_t i_bit, p_bit, l_bit, f_bit, b_bit, e_bit, v_bit; + uint32_t i_bit, p_bit, l_bit, f_bit, b_bit, e_bit, v_bit, z_bit; RETURN_FALSE_ON_ERROR(parser.ReadBits(&i_bit, 1)); RETURN_FALSE_ON_ERROR(parser.ReadBits(&p_bit, 1)); RETURN_FALSE_ON_ERROR(parser.ReadBits(&l_bit, 1)); @@ -709,7 +710,7 @@ bool RtpDepacketizerVp9::Parse(ParsedPayload* parsed_payload, RETURN_FALSE_ON_ERROR(parser.ReadBits(&b_bit, 1)); RETURN_FALSE_ON_ERROR(parser.ReadBits(&e_bit, 1)); RETURN_FALSE_ON_ERROR(parser.ReadBits(&v_bit, 1)); - RETURN_FALSE_ON_ERROR(parser.ConsumeBits(1)); + RETURN_FALSE_ON_ERROR(parser.ReadBits(&z_bit, 1)); // Parsed payload. parsed_payload->type.Video.width = 0; @@ -726,6 +727,7 @@ bool RtpDepacketizerVp9::Parse(ParsedPayload* parsed_payload, vp9->beginning_of_frame = b_bit ? true : false; vp9->end_of_frame = e_bit ? true : false; vp9->ss_data_available = v_bit ? true : false; + vp9->non_ref_for_inter_layer_pred = z_bit ? true : false; // Parse fields that are present. if (i_bit && !ParsePictureId(&parser, vp9)) { diff --git a/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc b/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc index d9083fb4c6..1360ecc6fe 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc @@ -27,6 +27,8 @@ void VerifyHeader(const RTPVideoHeaderVP9& expected, EXPECT_EQ(expected.beginning_of_frame, actual.beginning_of_frame); EXPECT_EQ(expected.end_of_frame, actual.end_of_frame); EXPECT_EQ(expected.ss_data_available, actual.ss_data_available); + EXPECT_EQ(expected.non_ref_for_inter_layer_pred, + actual.non_ref_for_inter_layer_pred); EXPECT_EQ(expected.picture_id, actual.picture_id); EXPECT_EQ(expected.max_picture_id, actual.max_picture_id); EXPECT_EQ(expected.temporal_idx, actual.temporal_idx); @@ -90,7 +92,7 @@ void ParseAndCheckPacket(const uint8_t* packet, // Payload descriptor for flexible mode // 0 1 2 3 4 5 6 7 // +-+-+-+-+-+-+-+-+ -// |I|P|L|F|B|E|V|-| (REQUIRED) +// |I|P|L|F|B|E|V|Z| (REQUIRED) // +-+-+-+-+-+-+-+-+ // I: |M| PICTURE ID | (RECOMMENDED) // +-+-+-+-+-+-+-+-+ @@ -107,7 +109,7 @@ void ParseAndCheckPacket(const uint8_t* packet, // Payload descriptor for non-flexible mode // 0 1 2 3 4 5 6 7 // +-+-+-+-+-+-+-+-+ -// |I|P|L|F|B|E|V|-| (REQUIRED) +// |I|P|L|F|B|E|V|Z| (REQUIRED) // +-+-+-+-+-+-+-+-+ // I: |M| PICTURE ID | (RECOMMENDED) // +-+-+-+-+-+-+-+-+ @@ -189,7 +191,7 @@ TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_OnePacket) { Init(kFrameSize, kPacketSize); // One packet: - // I:0, P:0, L:0, F:0, B:1, E:1, V:0 (1hdr + 25 payload) + // I:0, P:0, L:0, F:0, B:1, E:1, V:0, Z:0 (1hdr + 25 payload) const size_t kExpectedHdrSizes[] = {1}; const size_t kExpectedSizes[] = {26}; const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); @@ -202,8 +204,8 @@ TEST_F(RtpPacketizerVp9Test, TestEqualSizedMode_TwoPackets) { Init(kFrameSize, kPacketSize); // Two packets: - // I:0, P:0, L:0, F:0, B:1, E:0, V:0 (1hdr + 14 payload) - // I:0, P:0, L:0, F:0, B:0, E:1, V:0 (1hdr + 13 payload) + // I:0, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (1hdr + 14 payload) + // I:0, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (1hdr + 13 payload) const size_t kExpectedHdrSizes[] = {1, 1}; const size_t kExpectedSizes[] = {14, 15}; const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); @@ -228,9 +230,9 @@ TEST_F(RtpPacketizerVp9Test, TestOneBytePictureId) { Init(kFrameSize, kPacketSize); // Three packets: - // I:1, P:0, L:0, F:0, B:1, E:0, V:0 (2hdr + 10 payload) - // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (2hdr + 10 payload) - // I:1, P:0, L:0, F:0, B:0, E:1, V:0 (2hdr + 10 payload) + // I:1, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (2hdr + 10 payload) + // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (2hdr + 10 payload) + // I:1, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (2hdr + 10 payload) const size_t kExpectedHdrSizes[] = {2, 2, 2}; const size_t kExpectedSizes[] = {12, 12, 12}; const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); @@ -245,10 +247,10 @@ TEST_F(RtpPacketizerVp9Test, TestTwoBytePictureId) { Init(kFrameSize, kPacketSize); // Four packets: - // I:1, P:0, L:0, F:0, B:1, E:0, V:0 (3hdr + 8 payload) - // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (3hdr + 8 payload) - // I:1, P:0, L:0, F:0, B:0, E:0, V:0 (3hdr + 8 payload) - // I:1, P:0, L:0, F:0, B:0, E:1, V:0 (3hdr + 7 payload) + // I:1, P:0, L:0, F:0, B:1, E:0, V:0, Z:0 (3hdr + 8 payload) + // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (3hdr + 8 payload) + // I:1, P:0, L:0, F:0, B:0, E:0, V:0, Z:0 (3hdr + 8 payload) + // I:1, P:0, L:0, F:0, B:0, E:1, V:0, Z:0 (3hdr + 7 payload) const size_t kExpectedHdrSizes[] = {3, 3, 3, 3}; const size_t kExpectedSizes[] = {10, 11, 11, 11}; const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); @@ -268,9 +270,9 @@ TEST_F(RtpPacketizerVp9Test, TestLayerInfoWithNonFlexibleMode) { Init(kFrameSize, kPacketSize); // Two packets: - // | I:0, P:0, L:1, F:0, B:1, E:0, V:0 | (3hdr + 15 payload) + // | I:0, P:0, L:1, F:0, B:1, E:0, V:0 Z:0 | (3hdr + 15 payload) // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 | - // | I:0, P:0, L:1, F:0, B:0, E:1, V:0 | (3hdr + 15 payload) + // | I:0, P:0, L:1, F:0, B:0, E:1, V:0 Z:0 | (3hdr + 15 payload) // L: | T:3, U:1, S:2, D:1 | TL0PICIDX:117 | const size_t kExpectedHdrSizes[] = {3, 3}; const size_t kExpectedSizes[] = {18, 18}; @@ -318,7 +320,7 @@ TEST_F(RtpPacketizerVp9Test, TestRefIdx) { Init(kFrameSize, kPacketSize); // Two packets: - // I:1, P:1, L:0, F:1, B:1, E:1, V:0 (5hdr + 16 payload) + // I:1, P:1, L:0, F:1, B:1, E:1, V:0, Z:0 (5hdr + 16 payload) // I: 2 // P,F: P_DIFF:1, N:1 // P_DIFF:3, N:1 @@ -358,7 +360,7 @@ TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutSpatialResolutionPresent) { Init(kFrameSize, kPacketSize); // One packet: - // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (5hdr + 21 payload) + // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (5hdr + 21 payload) // N_S:0, Y:0, G:1 // N_G:1 // T:0, U:1, R:1 | P_DIFF[0][0]:4 @@ -379,7 +381,7 @@ TEST_F(RtpPacketizerVp9Test, TestSsDataWithoutGbitPresent) { Init(kFrameSize, kPacketSize); // One packet: - // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (2hdr + 21 payload) + // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (2hdr + 21 payload) // N_S:0, Y:0, G:0 const size_t kExpectedHdrSizes[] = {2}; const size_t kExpectedSizes[] = {23}; @@ -416,7 +418,7 @@ TEST_F(RtpPacketizerVp9Test, TestSsData) { Init(kFrameSize, kPacketSize); // One packet: - // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (19hdr + 21 payload) + // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (19hdr + 21 payload) // N_S:1, Y:1, G:1 // WIDTH:640 // 2 bytes // HEIGHT:360 // 2 bytes @@ -461,7 +463,7 @@ TEST_F(RtpPacketizerVp9Test, TestSsDataDoesNotFitInAveragePacket) { Init(kFrameSize, kPacketSize); // Three packets: - // I:0, P:0, L:0, F:0, B:1, E:1, V:1 (19hdr + 1 payload) + // I:0, P:0, L:0, F:0, B:1, E:1, V:1, Z:0 (19hdr + 1 payload) // N_S:1, Y:1, G:1 // WIDTH:640 // 2 bytes // HEIGHT:360 // 2 bytes @@ -566,6 +568,20 @@ TEST_F(RtpPacketizerVp9Test, TestRespectsLastPacketReductionLen) { EXPECT_TRUE(packet.Marker()); } +TEST_F(RtpPacketizerVp9Test, TestNonRefForInterLayerPred) { + const size_t kFrameSize = 25; + const size_t kPacketSize = 26; + + expected_.non_ref_for_inter_layer_pred = true; + Init(kFrameSize, kPacketSize); + + // I:0, P:0, L:0, F:0, B:1, E:1, V:0, Z:1 (1hdr + 25 payload) + const size_t kExpectedHdrSizes[] = {1}; + const size_t kExpectedSizes[] = {26}; + const size_t kExpectedNum = GTEST_ARRAY_SIZE_(kExpectedSizes); + CreateParseAndCheckPackets(kExpectedHdrSizes, kExpectedSizes, kExpectedNum); +} + class RtpDepacketizerVp9Test : public ::testing::Test { protected: RtpDepacketizerVp9Test() @@ -580,7 +596,7 @@ class RtpDepacketizerVp9Test : public ::testing::Test { TEST_F(RtpDepacketizerVp9Test, ParseBasicHeader) { const uint8_t kHeaderLength = 1; uint8_t packet[4] = {0}; - packet[0] = 0x0C; // I:0 P:0 L:0 F:0 B:1 E:1 V:0 R:0 + packet[0] = 0x0C; // I:0 P:0 L:0 F:0 B:1 E:1 V:0 Z:0 expected_.beginning_of_frame = true; expected_.end_of_frame = true; ParseAndCheckPacket(packet, expected_, kHeaderLength, sizeof(packet)); @@ -589,7 +605,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseBasicHeader) { TEST_F(RtpDepacketizerVp9Test, ParseOneBytePictureId) { const uint8_t kHeaderLength = 2; uint8_t packet[10] = {0}; - packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 R:0 + packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 Z:0 packet[1] = kMaxOneBytePictureId; expected_.picture_id = kMaxOneBytePictureId; @@ -600,7 +616,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseOneBytePictureId) { TEST_F(RtpDepacketizerVp9Test, ParseTwoBytePictureId) { const uint8_t kHeaderLength = 3; uint8_t packet[10] = {0}; - packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 R:0 + packet[0] = 0x80; // I:1 P:0 L:0 F:0 B:0 E:0 V:0 Z:0 packet[1] = 0x80 | ((kMaxTwoBytePictureId >> 8) & 0x7F); packet[2] = kMaxTwoBytePictureId & 0xFF; @@ -617,7 +633,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithNonFlexibleMode) { const uint8_t kDbit = 1; const uint8_t kTl0PicIdx = 17; uint8_t packet[13] = {0}; - packet[0] = 0x20; // I:0 P:0 L:1 F:0 B:0 E:0 V:0 R:0 + packet[0] = 0x20; // I:0 P:0 L:1 F:0 B:0 E:0 V:0 Z:0 packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit; packet[2] = kTl0PicIdx; @@ -638,10 +654,10 @@ TEST_F(RtpDepacketizerVp9Test, ParseLayerInfoWithFlexibleMode) { const uint8_t kSpatialIdx = 0; const uint8_t kDbit = 0; uint8_t packet[13] = {0}; - packet[0] = 0x38; // I:0 P:0 L:1 F:1 B:1 E:0 V:0 R:0 + packet[0] = 0x38; // I:0 P:0 L:1 F:1 B:1 E:0 V:0 Z:0 packet[1] = (kTemporalIdx << 5) | (kUbit << 4) | (kSpatialIdx << 1) | kDbit; - // I:0 P:0 L:1 F:1 B:1 E:0 V:0 + // I:0 P:0 L:1 F:1 B:1 E:0 V:0 Z:0 // L: T:2 U:1 S:0 D:0 expected_.beginning_of_frame = true; expected_.flexible_mode = true; @@ -659,14 +675,14 @@ TEST_F(RtpDepacketizerVp9Test, ParseRefIdx) { const uint8_t kPdiff2 = 18; const uint8_t kPdiff3 = 127; uint8_t packet[13] = {0}; - packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0 + packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0 packet[1] = 0x80 | ((kPictureId >> 8) & 0x7F); // Two byte pictureID. packet[2] = kPictureId; packet[3] = (kPdiff1 << 1) | 1; // P_DIFF N:1 packet[4] = (kPdiff2 << 1) | 1; // P_DIFF N:1 packet[5] = (kPdiff3 << 1) | 0; // P_DIFF N:0 - // I:1 P:1 L:0 F:1 B:1 E:0 V:0 + // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0 // I: PICTURE ID:17 // I: // P,F: P_DIFF:17 N:1 => refPicId = 17 - 17 = 0 @@ -689,7 +705,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseRefIdx) { TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) { const uint8_t kPdiff = 3; uint8_t packet[13] = {0}; - packet[0] = 0x58; // I:0 P:1 L:0 F:1 B:1 E:0 V:0 R:0 + packet[0] = 0x58; // I:0 P:1 L:0 F:1 B:1 E:0 V:0 Z:0 packet[1] = (kPdiff << 1); // P,F: P_DIFF:3 N:0 RtpDepacketizer::ParsedPayload parsed; @@ -699,7 +715,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithNoPictureId) { TEST_F(RtpDepacketizerVp9Test, ParseRefIdxFailsWithTooManyRefPics) { const uint8_t kPdiff = 3; uint8_t packet[13] = {0}; - packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 R:0 + packet[0] = 0xD8; // I:1 P:1 L:0 F:1 B:1 E:0 V:0 Z:0 packet[1] = kMaxOneBytePictureId; // I: PICTURE ID:127 packet[2] = (kPdiff << 1) | 1; // P,F: P_DIFF:3 N:1 packet[3] = (kPdiff << 1) | 1; // P,F: P_DIFF:3 N:1 @@ -716,7 +732,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseSsData) { const size_t kNs = 2; const size_t kNg = 2; uint8_t packet[23] = {0}; - packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 R:0 + packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 Z:0 packet[1] = ((kNs - 1) << 5) | (kYbit << 4) | (1 << 3); // N_S Y G:1 - packet[2] = kNg; // N_G packet[3] = (0 << 5) | (1 << 4) | (0 << 2) | 0; // T:0 U:1 R:0 - @@ -740,7 +756,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseSsData) { TEST_F(RtpDepacketizerVp9Test, ParseFirstPacketInKeyFrame) { uint8_t packet[2] = {0}; - packet[0] = 0x08; // I:0 P:0 L:0 F:0 B:1 E:0 V:0 R:0 + packet[0] = 0x08; // I:0 P:0 L:0 F:0 B:1 E:0 V:0 Z:0 RtpDepacketizer::ParsedPayload parsed; ASSERT_TRUE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); @@ -750,7 +766,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseFirstPacketInKeyFrame) { TEST_F(RtpDepacketizerVp9Test, ParseLastPacketInDeltaFrame) { uint8_t packet[2] = {0}; - packet[0] = 0x44; // I:0 P:1 L:0 F:0 B:0 E:1 V:0 R:0 + packet[0] = 0x44; // I:0 P:1 L:0 F:0 B:0 E:1 V:0 Z:0 RtpDepacketizer::ParsedPayload parsed; ASSERT_TRUE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); @@ -762,7 +778,7 @@ TEST_F(RtpDepacketizerVp9Test, ParseResolution) { const uint16_t kWidth[2] = {640, 1280}; const uint16_t kHeight[2] = {360, 720}; uint8_t packet[20] = {0}; - packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 R:0 + packet[0] = 0x0A; // I:0 P:0 L:0 F:0 B:1 E:0 V:1 Z:0 packet[1] = (1 << 5) | (1 << 4) | 0; // N_S:1 Y:1 G:0 packet[2] = kWidth[0] >> 8; packet[3] = kWidth[0] & 0xFF; @@ -792,4 +808,19 @@ TEST_F(RtpDepacketizerVp9Test, ParseFailsForTooShortBufferToFitPayload) { EXPECT_FALSE(depacketizer_->Parse(&parsed, packet, sizeof(packet))); } +TEST_F(RtpDepacketizerVp9Test, ParseNonRefForInterLayerPred) { + uint8_t packet[2] = {0}; + + packet[0] = 0x08; // I:0 P:0 L:0 F:0 B:1 E:0 V:0 Z:0 + expected_.beginning_of_frame = true; + expected_.non_ref_for_inter_layer_pred = false; + ParseAndCheckPacket(packet, expected_, 1, sizeof(packet)); + + packet[0] = 0x05; // I:0 P:0 L:0 F:0 B:0 E:1 V:0 Z:1 + expected_.beginning_of_frame = false; + expected_.end_of_frame = true; + expected_.non_ref_for_inter_layer_pred = true; + ParseAndCheckPacket(packet, expected_, 1, sizeof(packet)); +} + } // namespace webrtc diff --git a/modules/video_coding/codecs/vp9/include/vp9_globals.h b/modules/video_coding/codecs/vp9/include/vp9_globals.h index f24ab3e1b5..4d8ff3ccd2 100644 --- a/modules/video_coding/codecs/vp9/include/vp9_globals.h +++ b/modules/video_coding/codecs/vp9/include/vp9_globals.h @@ -162,6 +162,7 @@ struct RTPVideoHeaderVP9 { beginning_of_frame = false; end_of_frame = false; ss_data_available = false; + non_ref_for_inter_layer_pred = false; picture_id = kNoPictureId; max_picture_id = kMaxTwoBytePictureId; tl0_pic_idx = kNoTl0PicIdx; @@ -183,6 +184,8 @@ struct RTPVideoHeaderVP9 { bool end_of_frame; // True if this packet is the last in a VP9 layer frame. bool ss_data_available; // True if SS data is available in this payload // descriptor. + bool non_ref_for_inter_layer_pred; // True for frame which is not used as + // reference for inter-layer prediction. int16_t picture_id; // PictureID index, 15 bits; // kNoPictureId if PictureID does not exist. int16_t max_picture_id; // Maximum picture ID index; either 0x7F or 0x7FFF; diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index 5076af2e9d..d133e66962 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -602,6 +602,7 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, ((pkt.data.frame.flags & VPX_FRAME_IS_KEY) && !codec_.VP9()->flexibleMode) ? true : false; + vp9_info->non_ref_for_inter_layer_pred = false; vpx_svc_layer_id_t layer_id = {0}; vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id); diff --git a/modules/video_coding/include/video_codec_interface.h b/modules/video_coding/include/video_codec_interface.h index 204098c6c6..aad3759281 100644 --- a/modules/video_coding/include/video_codec_interface.h +++ b/modules/video_coding/include/video_codec_interface.h @@ -48,6 +48,7 @@ struct CodecSpecificInfoVP9 { // coded frame(s). bool flexible_mode; bool ss_data_available; + bool non_ref_for_inter_layer_pred; // TODO(nisse): Used on receive side only. Move elsewhere? int tl0_pic_idx; // Negative value to skip tl0PicIdx. diff --git a/video/payload_router.cc b/video/payload_router.cc index b76257794b..4eef06877d 100644 --- a/video/payload_router.cc +++ b/video/payload_router.cc @@ -43,6 +43,8 @@ void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) { info->codecSpecific.VP9.flexible_mode; rtp->codecHeader.VP9.ss_data_available = info->codecSpecific.VP9.ss_data_available; + rtp->codecHeader.VP9.non_ref_for_inter_layer_pred = + info->codecSpecific.VP9.non_ref_for_inter_layer_pred; rtp->codecHeader.VP9.temporal_idx = info->codecSpecific.VP9.temporal_idx; rtp->codecHeader.VP9.spatial_idx = info->codecSpecific.VP9.spatial_idx; rtp->codecHeader.VP9.temporal_up_switch =