mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-19 00:27:51 +01:00
Adding a LayerSync bit to VP8 RTP header
Updated RtpFormatVp8, ModuleRTPUtility, VP8Encoder and VP8Decoder to support a new LayerSync ("Y") bit. Note, in VP8Encoder the bit must be used together with a non-negative value for temporalIdx. Fixing the plumbing between RTP module and and from VP8 wrapper. Updating unit tests; all pass. The new bit is yet to be used by the VP8 wrapper. Review URL: http://webrtc-codereview.appspot.com/323008 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1169 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
4aae0e489f
commit
eda86dc76b
16 changed files with 72 additions and 28 deletions
|
@ -57,6 +57,7 @@ struct RTPVideoHeaderVP8
|
||||||
pictureId = kNoPictureId;
|
pictureId = kNoPictureId;
|
||||||
tl0PicIdx = kNoTl0PicIdx;
|
tl0PicIdx = kNoTl0PicIdx;
|
||||||
temporalIdx = kNoTemporalIdx;
|
temporalIdx = kNoTemporalIdx;
|
||||||
|
layerSync = false;
|
||||||
keyIdx = kNoKeyIdx;
|
keyIdx = kNoKeyIdx;
|
||||||
partitionId = 0;
|
partitionId = 0;
|
||||||
beginningOfPartition = false;
|
beginningOfPartition = false;
|
||||||
|
@ -70,6 +71,8 @@ struct RTPVideoHeaderVP8
|
||||||
WebRtc_Word16 tl0PicIdx; // TL0PIC_IDX, 8 bits;
|
WebRtc_Word16 tl0PicIdx; // TL0PIC_IDX, 8 bits;
|
||||||
// kNoTl0PicIdx means no value provided.
|
// kNoTl0PicIdx means no value provided.
|
||||||
WebRtc_Word8 temporalIdx; // Temporal layer index, or kNoTemporalIdx.
|
WebRtc_Word8 temporalIdx; // Temporal layer index, or kNoTemporalIdx.
|
||||||
|
bool layerSync; // This frame is a layer sync frame.
|
||||||
|
// Disabled if temporalIdx == kNoTemporalIdx.
|
||||||
int keyIdx; // 5 bits; kNoKeyIdx means not used.
|
int keyIdx; // 5 bits; kNoKeyIdx means not used.
|
||||||
int partitionId; // VP8 partition ID
|
int partitionId; // VP8 partition ID
|
||||||
bool beginningOfPartition; // True if this packet is the first
|
bool beginningOfPartition; // True if this packet is the first
|
||||||
|
|
|
@ -167,7 +167,7 @@ int RtpFormatVp8::WriteHeaderAndPayload(int payload_bytes,
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PIC_IDX | (optional)
|
// L: | TL0PIC_IDX | (optional)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// T/K: | TID | KEYIDX | (optional)
|
// T/K: |TID:Y| KEYIDX | (optional)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
assert(payload_bytes > 0);
|
assert(payload_bytes > 0);
|
||||||
|
@ -280,7 +280,9 @@ int RtpFormatVp8::WriteTIDAndKeyIdxFields(WebRtc_UWord8* x_field,
|
||||||
*data_field = 0;
|
*data_field = 0;
|
||||||
if (TIDFieldPresent()) {
|
if (TIDFieldPresent()) {
|
||||||
*x_field |= kTBit;
|
*x_field |= kTBit;
|
||||||
*data_field |= hdr_info_.temporalIdx << 5;
|
assert(hdr_info_.temporalIdx >= 0 && hdr_info_.temporalIdx <= 3);
|
||||||
|
*data_field |= hdr_info_.temporalIdx << 6;
|
||||||
|
*data_field |= hdr_info_.layerSync ? kYBit : 0;
|
||||||
}
|
}
|
||||||
if (KeyIdxFieldPresent()) {
|
if (KeyIdxFieldPresent()) {
|
||||||
*x_field |= kKBit;
|
*x_field |= kKBit;
|
||||||
|
@ -314,6 +316,8 @@ bool RtpFormatVp8::XFieldPresent() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpFormatVp8::TIDFieldPresent() const {
|
bool RtpFormatVp8::TIDFieldPresent() const {
|
||||||
|
assert((hdr_info_.layerSync == false) ||
|
||||||
|
(hdr_info_.temporalIdx != kNoTemporalIdx));
|
||||||
return (hdr_info_.temporalIdx != kNoTemporalIdx);
|
return (hdr_info_.temporalIdx != kNoTemporalIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ class RtpFormatVp8 {
|
||||||
static const int kLBit = 0x40;
|
static const int kLBit = 0x40;
|
||||||
static const int kTBit = 0x20;
|
static const int kTBit = 0x20;
|
||||||
static const int kKBit = 0x10;
|
static const int kKBit = 0x10;
|
||||||
|
static const int kYBit = 0x20;
|
||||||
|
|
||||||
// Calculate size of next chunk to send. Returns 0 if none can be sent.
|
// Calculate size of next chunk to send. Returns 0 if none can be sent.
|
||||||
int CalcNextSize(int max_payload_len, int remaining_bytes,
|
int CalcNextSize(int max_payload_len, int remaining_bytes,
|
||||||
|
@ -114,7 +115,7 @@ class RtpFormatVp8 {
|
||||||
int WriteTl0PicIdxFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
int WriteTl0PicIdxFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
||||||
int buffer_length, int* extension_length) const;
|
int buffer_length, int* extension_length) const;
|
||||||
|
|
||||||
// Set the T and K bits in the x_field, and write TID and KeyIdx to the
|
// Set the T and K bits in the x_field, and write TID, Y and KeyIdx to the
|
||||||
// appropriate position in buffer. The function returns 0 on success,
|
// appropriate position in buffer. The function returns 0 on success,
|
||||||
// -1 otherwise.
|
// -1 otherwise.
|
||||||
int WriteTIDAndKeyIdxFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
int WriteTIDAndKeyIdxFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
||||||
|
|
|
@ -94,7 +94,9 @@ void RtpFormatVp8Test::TearDown() {
|
||||||
|
|
||||||
#define EXPECT_BIT_K_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
|
#define EXPECT_BIT_K_EQ(x, a) EXPECT_BIT_EQ(x, 4, a)
|
||||||
|
|
||||||
#define EXPECT_TID_EQ(x, a) EXPECT_EQ((((x) & 0xE0) >> 5), a)
|
#define EXPECT_TID_EQ(x, a) EXPECT_EQ((((x) & 0xC0) >> 6), a)
|
||||||
|
|
||||||
|
#define EXPECT_BIT_Y_EQ(x, a) EXPECT_BIT_EQ(x, 5, a)
|
||||||
|
|
||||||
#define EXPECT_KEYIDX_EQ(x, a) EXPECT_EQ(((x) & 0x1F), a)
|
#define EXPECT_KEYIDX_EQ(x, a) EXPECT_EQ(((x) & 0x1F), a)
|
||||||
|
|
||||||
|
@ -170,9 +172,11 @@ void RtpFormatVp8Test::CheckTIDAndKeyIdx() {
|
||||||
if (hdr_info_.temporalIdx != kNoTemporalIdx) {
|
if (hdr_info_.temporalIdx != kNoTemporalIdx) {
|
||||||
EXPECT_BIT_T_EQ(buffer_[1], 1);
|
EXPECT_BIT_T_EQ(buffer_[1], 1);
|
||||||
EXPECT_TID_EQ(buffer_[payload_start_], hdr_info_.temporalIdx);
|
EXPECT_TID_EQ(buffer_[payload_start_], hdr_info_.temporalIdx);
|
||||||
|
EXPECT_BIT_Y_EQ(buffer_[payload_start_], hdr_info_.layerSync);
|
||||||
} else {
|
} else {
|
||||||
EXPECT_BIT_T_EQ(buffer_[1], 0);
|
EXPECT_BIT_T_EQ(buffer_[1], 0);
|
||||||
EXPECT_TID_EQ(buffer_[payload_start_], 0);
|
EXPECT_TID_EQ(buffer_[payload_start_], 0);
|
||||||
|
EXPECT_BIT_Y_EQ(buffer_[payload_start_], false);
|
||||||
}
|
}
|
||||||
if (hdr_info_.keyIdx != kNoKeyIdx) {
|
if (hdr_info_.keyIdx != kNoKeyIdx) {
|
||||||
EXPECT_BIT_K_EQ(buffer_[1], 1);
|
EXPECT_BIT_K_EQ(buffer_[1], 1);
|
||||||
|
@ -404,13 +408,14 @@ TEST_F(RtpFormatVp8Test, TestNonReferenceBit) {
|
||||||
EXPECT_BIT_N_EQ(buffer_[0], 1);
|
EXPECT_BIT_N_EQ(buffer_[0], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Tl0PicIdx and TID fields
|
// Verify Tl0PicIdx and TID fields, and layerSync bit.
|
||||||
TEST_F(RtpFormatVp8Test, TestTl0PicIdxAndTID) {
|
TEST_F(RtpFormatVp8Test, TestTl0PicIdxAndTID) {
|
||||||
int send_bytes = 0;
|
int send_bytes = 0;
|
||||||
bool last;
|
bool last;
|
||||||
|
|
||||||
hdr_info_.tl0PicIdx = 117;
|
hdr_info_.tl0PicIdx = 117;
|
||||||
hdr_info_.temporalIdx = 2;
|
hdr_info_.temporalIdx = 2;
|
||||||
|
hdr_info_.layerSync = true;
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
hdr_info_, *fragmentation_,
|
hdr_info_, *fragmentation_,
|
||||||
kAggregate);
|
kAggregate);
|
||||||
|
|
|
@ -644,8 +644,13 @@ RTPReceiverVideo::ReceiveVp8Codec(WebRtcRTPHeader* rtpHeader,
|
||||||
kNoPictureId;
|
kNoPictureId;
|
||||||
toHeader->tl0PicIdx = fromHeader->hasTl0PicIdx ? fromHeader->tl0PicIdx :
|
toHeader->tl0PicIdx = fromHeader->hasTl0PicIdx ? fromHeader->tl0PicIdx :
|
||||||
kNoTl0PicIdx;
|
kNoTl0PicIdx;
|
||||||
toHeader->temporalIdx = fromHeader->hasTID ? fromHeader->tID :
|
if (fromHeader->hasTID) {
|
||||||
kNoTemporalIdx;
|
toHeader->temporalIdx = fromHeader->tID;
|
||||||
|
toHeader->layerSync = fromHeader->layerSync;
|
||||||
|
} else {
|
||||||
|
toHeader->temporalIdx = kNoTemporalIdx;
|
||||||
|
toHeader->layerSync = false;
|
||||||
|
}
|
||||||
toHeader->keyIdx = fromHeader->hasKeyIdx ? fromHeader->keyIdx : kNoKeyIdx;
|
toHeader->keyIdx = fromHeader->hasKeyIdx ? fromHeader->keyIdx : kNoKeyIdx;
|
||||||
|
|
||||||
toHeader->frameWidth = fromHeader->frameWidth;
|
toHeader->frameWidth = fromHeader->frameWidth;
|
||||||
|
|
|
@ -434,6 +434,7 @@ ModuleRTPUtility::RTPPayload::SetType(RtpVideoCodecTypes videoType)
|
||||||
info.VP8.pictureID = -1;
|
info.VP8.pictureID = -1;
|
||||||
info.VP8.tl0PicIdx = -1;
|
info.VP8.tl0PicIdx = -1;
|
||||||
info.VP8.tID = -1;
|
info.VP8.tID = -1;
|
||||||
|
info.VP8.layerSync = false;
|
||||||
info.VP8.frameWidth = 0;
|
info.VP8.frameWidth = 0;
|
||||||
info.VP8.frameHeight = 0;
|
info.VP8.frameHeight = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -867,7 +868,7 @@ ModuleRTPUtility::RTPPayloadParser::ParseMPEG4(
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PICIDX | (OPTIONAL)
|
// L: | TL0PICIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// T/K: | TID | KEYIDX | (OPTIONAL)
|
// T/K: |TID:Y| KEYIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
//
|
//
|
||||||
// Payload header (considered part of the actual payload, sent to decoder)
|
// Payload header (considered part of the actual payload, sent to decoder)
|
||||||
|
@ -1041,7 +1042,8 @@ int ModuleRTPUtility::RTPPayloadParser::ParseVP8TIDAndKeyIdx(
|
||||||
if (*dataLength <= 0) return -1;
|
if (*dataLength <= 0) return -1;
|
||||||
if (vp8->hasTID)
|
if (vp8->hasTID)
|
||||||
{
|
{
|
||||||
vp8->tID = ((**dataPtr >> 5) & 0x07);
|
vp8->tID = ((**dataPtr >> 6) & 0x03);
|
||||||
|
vp8->layerSync = (**dataPtr & 0x20) ? true : false; // Y bit
|
||||||
}
|
}
|
||||||
if (vp8->hasKeyIdx)
|
if (vp8->hasKeyIdx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,6 +167,7 @@ namespace ModuleRTPUtility
|
||||||
int pictureID;
|
int pictureID;
|
||||||
int tl0PicIdx;
|
int tl0PicIdx;
|
||||||
int tID;
|
int tID;
|
||||||
|
bool layerSync;
|
||||||
int keyIdx;
|
int keyIdx;
|
||||||
int frameWidth;
|
int frameWidth;
|
||||||
int frameHeight;
|
int frameHeight;
|
||||||
|
|
|
@ -35,7 +35,7 @@ using ModuleRTPUtility::RTPPayloadVP8;
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PICIDX | (OPTIONAL)
|
// L: | TL0PICIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// T/K: | TID | KEYIDX | (OPTIONAL)
|
// T/K: |TID:Y| KEYIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
//
|
//
|
||||||
// Payload header
|
// Payload header
|
||||||
|
@ -153,11 +153,11 @@ TEST(ParseVP8Test, Tl0PicIdx) {
|
||||||
EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(13 - 3, parsedPacket.info.VP8.dataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseVP8Test, TID) {
|
TEST(ParseVP8Test, TIDAndLayerSync) {
|
||||||
WebRtc_UWord8 payload[10] = {0};
|
WebRtc_UWord8 payload[10] = {0};
|
||||||
payload[0] = 0x88;
|
payload[0] = 0x88;
|
||||||
payload[1] = 0x20;
|
payload[1] = 0x20;
|
||||||
payload[2] = 0x40;
|
payload[2] = 0x80; // TID(2) + LayerSync(false)
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@ TEST(ParseVP8Test, TID) {
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
|
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
|
||||||
|
|
||||||
EXPECT_EQ(2, parsedPacket.info.VP8.tID);
|
EXPECT_EQ(2, parsedPacket.info.VP8.tID);
|
||||||
|
EXPECT_FALSE(parsedPacket.info.VP8.layerSync);
|
||||||
|
|
||||||
EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
|
EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
|
||||||
EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
|
||||||
|
@ -206,7 +207,7 @@ TEST(ParseVP8Test, MultipleExtensions) {
|
||||||
payload[2] = 0x80 | 17; // PictureID, high 7 bits.
|
payload[2] = 0x80 | 17; // PictureID, high 7 bits.
|
||||||
payload[3] = 17; // PictureID, low 8 bits.
|
payload[3] = 17; // PictureID, low 8 bits.
|
||||||
payload[4] = 42; // Tl0PicIdx.
|
payload[4] = 42; // Tl0PicIdx.
|
||||||
payload[5] = 0x40 | 0x11; // TID + KEYIDX.
|
payload[5] = 0x40 | 0x20 | 0x11; // TID(1) + LayerSync(true) + KEYIDX(17).
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
|
@ -221,7 +222,7 @@ TEST(ParseVP8Test, MultipleExtensions) {
|
||||||
|
|
||||||
EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
|
EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
|
||||||
EXPECT_EQ(42, parsedPacket.info.VP8.tl0PicIdx);
|
EXPECT_EQ(42, parsedPacket.info.VP8.tl0PicIdx);
|
||||||
EXPECT_EQ(2, parsedPacket.info.VP8.tID);
|
EXPECT_EQ(1, parsedPacket.info.VP8.tID);
|
||||||
EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
|
EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
|
||||||
|
|
||||||
EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
|
EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
|
||||||
|
@ -248,6 +249,7 @@ TEST(ParseVP8Test, TestWithPacketizer) {
|
||||||
inputHeader.nonReference = true;
|
inputHeader.nonReference = true;
|
||||||
inputHeader.pictureId = 300;
|
inputHeader.pictureId = 300;
|
||||||
inputHeader.temporalIdx = 1;
|
inputHeader.temporalIdx = 1;
|
||||||
|
inputHeader.layerSync = false;
|
||||||
inputHeader.tl0PicIdx = kNoTl0PicIdx; // Disable.
|
inputHeader.tl0PicIdx = kNoTl0PicIdx; // Disable.
|
||||||
inputHeader.keyIdx = 31;
|
inputHeader.keyIdx = 31;
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload, 10, inputHeader);
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload, 10, inputHeader);
|
||||||
|
@ -276,6 +278,7 @@ TEST(ParseVP8Test, TestWithPacketizer) {
|
||||||
|
|
||||||
EXPECT_EQ(inputHeader.pictureId, parsedPacket.info.VP8.pictureID);
|
EXPECT_EQ(inputHeader.pictureId, parsedPacket.info.VP8.pictureID);
|
||||||
EXPECT_EQ(inputHeader.temporalIdx, parsedPacket.info.VP8.tID);
|
EXPECT_EQ(inputHeader.temporalIdx, parsedPacket.info.VP8.tID);
|
||||||
|
EXPECT_EQ(inputHeader.layerSync, parsedPacket.info.VP8.layerSync);
|
||||||
EXPECT_EQ(inputHeader.keyIdx, parsedPacket.info.VP8.keyIdx);
|
EXPECT_EQ(inputHeader.keyIdx, parsedPacket.info.VP8.keyIdx);
|
||||||
|
|
||||||
EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
|
EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct CodecSpecificInfoVP8
|
||||||
bool nonReference;
|
bool nonReference;
|
||||||
WebRtc_UWord8 simulcastIdx;
|
WebRtc_UWord8 simulcastIdx;
|
||||||
WebRtc_UWord8 temporalIdx;
|
WebRtc_UWord8 temporalIdx;
|
||||||
|
bool layerSync;
|
||||||
int tl0PicIdx; // Negative value to skip tl0PicIdx
|
int tl0PicIdx; // Negative value to skip tl0PicIdx
|
||||||
WebRtc_Word8 keyIdx; // negative value to skip keyIdx
|
WebRtc_Word8 keyIdx; // negative value to skip keyIdx
|
||||||
};
|
};
|
||||||
|
|
|
@ -509,6 +509,7 @@ void VP8Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
vp8Info->temporalIdx = kNoTemporalIdx;
|
vp8Info->temporalIdx = kNoTemporalIdx;
|
||||||
|
vp8Info->layerSync = false;
|
||||||
vp8Info->tl0PicIdx = kNoTl0PicIdx;
|
vp8Info->tl0PicIdx = kNoTl0PicIdx;
|
||||||
#if WEBRTC_LIBVPX_VERSION >= 971
|
#if WEBRTC_LIBVPX_VERSION >= 971
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header)
|
||||||
// This is the first packet for this frame.
|
// This is the first packet for this frame.
|
||||||
_codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
|
_codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
|
||||||
_codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
|
_codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
|
||||||
|
_codecSpecificInfo.codecSpecific.VP8.layerSync = false;
|
||||||
_codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
|
_codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
|
||||||
_codecSpecificInfo.codecType = kVideoCodecVP8;
|
_codecSpecificInfo.codecType = kVideoCodecVP8;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +127,8 @@ void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header)
|
||||||
{
|
{
|
||||||
_codecSpecificInfo.codecSpecific.VP8.temporalIdx =
|
_codecSpecificInfo.codecSpecific.VP8.temporalIdx =
|
||||||
header->codecHeader.VP8.temporalIdx;
|
header->codecHeader.VP8.temporalIdx;
|
||||||
|
_codecSpecificInfo.codecSpecific.VP8.layerSync =
|
||||||
|
header->codecHeader.VP8.layerSync;
|
||||||
}
|
}
|
||||||
if (header->codecHeader.VP8.keyIdx != kNoKeyIdx)
|
if (header->codecHeader.VP8.keyIdx != kNoKeyIdx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,6 +76,10 @@ int VCMFrameBuffer::TemporalId() const {
|
||||||
return _sessionInfo.TemporalId();
|
return _sessionInfo.TemporalId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VCMFrameBuffer::LayerSync() const {
|
||||||
|
return _sessionInfo.LayerSync();
|
||||||
|
}
|
||||||
|
|
||||||
int VCMFrameBuffer::Tl0PicId() const {
|
int VCMFrameBuffer::Tl0PicId() const {
|
||||||
return _sessionInfo.Tl0PicId();
|
return _sessionInfo.Tl0PicId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
|
|
||||||
int PictureId() const;
|
int PictureId() const;
|
||||||
int TemporalId() const;
|
int TemporalId() const;
|
||||||
|
bool LayerSync() const;
|
||||||
int Tl0PicId() const;
|
int Tl0PicId() const;
|
||||||
bool NonReference() const;
|
bool NonReference() const;
|
||||||
|
|
||||||
|
|
|
@ -267,6 +267,8 @@ void VCMEncodedFrameCallback::CopyCodecSpecific(const CodecSpecificInfo& info,
|
||||||
info.codecSpecific.VP8.nonReference;
|
info.codecSpecific.VP8.nonReference;
|
||||||
(*rtp)->codecHeader.VP8.temporalIdx =
|
(*rtp)->codecHeader.VP8.temporalIdx =
|
||||||
info.codecSpecific.VP8.temporalIdx;
|
info.codecSpecific.VP8.temporalIdx;
|
||||||
|
(*rtp)->codecHeader.VP8.layerSync =
|
||||||
|
info.codecSpecific.VP8.layerSync;
|
||||||
(*rtp)->codecHeader.VP8.tl0PicIdx =
|
(*rtp)->codecHeader.VP8.tl0PicIdx =
|
||||||
info.codecSpecific.VP8.tl0PicIdx;
|
info.codecSpecific.VP8.tl0PicIdx;
|
||||||
(*rtp)->codecHeader.VP8.keyIdx =
|
(*rtp)->codecHeader.VP8.keyIdx =
|
||||||
|
|
|
@ -59,6 +59,13 @@ int VCMSessionInfo::TemporalId() const {
|
||||||
return packets_.front().codecSpecificHeader.codecHeader.VP8.temporalIdx;
|
return packets_.front().codecSpecificHeader.codecHeader.VP8.temporalIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VCMSessionInfo::LayerSync() const {
|
||||||
|
if (packets_.empty() ||
|
||||||
|
packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
|
||||||
|
return false;
|
||||||
|
return packets_.front().codecSpecificHeader.codecHeader.VP8.layerSync;
|
||||||
|
}
|
||||||
|
|
||||||
int VCMSessionInfo::Tl0PicId() const {
|
int VCMSessionInfo::Tl0PicId() const {
|
||||||
if (packets_.empty() ||
|
if (packets_.empty() ||
|
||||||
packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
|
packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
|
||||||
|
|
|
@ -63,6 +63,7 @@ class VCMSessionInfo {
|
||||||
int HighSequenceNumber() const;
|
int HighSequenceNumber() const;
|
||||||
int PictureId() const;
|
int PictureId() const;
|
||||||
int TemporalId() const;
|
int TemporalId() const;
|
||||||
|
bool LayerSync() const;
|
||||||
int Tl0PicId() const;
|
int Tl0PicId() const;
|
||||||
bool NonReference() const;
|
bool NonReference() const;
|
||||||
int PrepareForDecode(uint8_t* frame_buffer);
|
int PrepareForDecode(uint8_t* frame_buffer);
|
||||||
|
|
Loading…
Reference in a new issue