Updating to VP8 RTP spec rev -02
Updating the VP8 packetizer class (RtpFormatVp8) and VP8 parser (in class RTPPayloadParser) to follow the -02 revision of the spec. See http://tools.ietf.org/html/draft-ietf-payload-vp8-02. Updating the unit tests, too. Finally, updating the tests to follow the recommendations from the test team; specifically including the test code in the webrtc namespace, and omitting the main function at the end of each test file. Review URL: http://webrtc-codereview.appspot.com/296003 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1013 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
517dcb71f2
commit
6f2c0168f0
@ -46,6 +46,7 @@ struct RTPVideoHeaderH263
|
|||||||
enum {kNoPictureId = -1};
|
enum {kNoPictureId = -1};
|
||||||
enum {kNoTl0PicIdx = -1};
|
enum {kNoTl0PicIdx = -1};
|
||||||
enum {kNoTemporalIdx = -1};
|
enum {kNoTemporalIdx = -1};
|
||||||
|
enum {kNoKeyIdx = -1};
|
||||||
enum {kNoSimulcastIdx = 0};
|
enum {kNoSimulcastIdx = 0};
|
||||||
|
|
||||||
struct RTPVideoHeaderVP8
|
struct RTPVideoHeaderVP8
|
||||||
@ -56,6 +57,7 @@ struct RTPVideoHeaderVP8
|
|||||||
pictureId = kNoPictureId;
|
pictureId = kNoPictureId;
|
||||||
tl0PicIdx = kNoTl0PicIdx;
|
tl0PicIdx = kNoTl0PicIdx;
|
||||||
temporalIdx = kNoTemporalIdx;
|
temporalIdx = kNoTemporalIdx;
|
||||||
|
keyIdx = kNoKeyIdx;
|
||||||
partitionId = 0;
|
partitionId = 0;
|
||||||
beginningOfPartition = false;
|
beginningOfPartition = false;
|
||||||
frameWidth = 0;
|
frameWidth = 0;
|
||||||
@ -68,6 +70,7 @@ 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.
|
||||||
|
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
|
||||||
// in a VP8 partition. Otherwise false
|
// in a VP8 partition. Otherwise false
|
||||||
|
@ -173,19 +173,19 @@ int RtpFormatVp8::WriteHeaderAndPayload(int payload_bytes,
|
|||||||
int buffer_length)
|
int buffer_length)
|
||||||
{
|
{
|
||||||
// Write the VP8 payload descriptor.
|
// Write the VP8 payload descriptor.
|
||||||
// 0
|
// 0
|
||||||
// 0 1 2 3 4 5 6 7 8
|
// 0 1 2 3 4 5 6 7 8
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// |X| |N|S| PART_ID |
|
// |X| |N|S| PART_ID |
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// X: |I|L|T| | (mandatory if any of the below are used)
|
// X: |I|L|T|K| | (mandatory if any of the below are used)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// I: |PictureID (8/16b)| (optional)
|
// I: |PictureID (8/16b)| (optional)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PIC_IDX | (optional)
|
// L: | TL0PIC_IDX | (optional)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
// T: | TID | | (optional)
|
// T/K: | TID | KEYIDX | (optional)
|
||||||
// +-+-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
assert(payload_bytes > 0);
|
assert(payload_bytes > 0);
|
||||||
assert(payload_bytes_sent_ + payload_bytes <= payload_size_);
|
assert(payload_bytes_sent_ + payload_bytes <= payload_size_);
|
||||||
@ -235,9 +235,9 @@ const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TIDFieldPresent())
|
if (TIDFieldPresent() || KeyIdxFieldPresent())
|
||||||
{
|
{
|
||||||
if (WriteTIDFields(x_field, buffer, buffer_length,
|
if (WriteTIDAndKeyIdxFields(x_field, buffer, buffer_length,
|
||||||
&extension_length) < 0)
|
&extension_length) < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@ -299,19 +299,29 @@ int RtpFormatVp8::WriteTl0PicIdxFields(WebRtc_UWord8* x_field,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RtpFormatVp8::WriteTIDFields(WebRtc_UWord8* x_field,
|
int RtpFormatVp8::WriteTIDAndKeyIdxFields(WebRtc_UWord8* x_field,
|
||||||
WebRtc_UWord8* buffer,
|
WebRtc_UWord8* buffer,
|
||||||
int buffer_length,
|
int buffer_length,
|
||||||
int* extension_length) const
|
int* extension_length) const
|
||||||
{
|
{
|
||||||
if (buffer_length < vp8_fixed_payload_descriptor_bytes_ + *extension_length
|
if (buffer_length < vp8_fixed_payload_descriptor_bytes_ + *extension_length
|
||||||
+ 1)
|
+ 1)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*x_field |= kTBit;
|
WebRtc_UWord8* data_field =
|
||||||
buffer[vp8_fixed_payload_descriptor_bytes_ + *extension_length]
|
&buffer[vp8_fixed_payload_descriptor_bytes_ + *extension_length];
|
||||||
= hdr_info_.temporalIdx << 5;
|
*data_field = 0;
|
||||||
|
if (TIDFieldPresent())
|
||||||
|
{
|
||||||
|
*x_field |= kTBit;
|
||||||
|
*data_field |= hdr_info_.temporalIdx << 5;
|
||||||
|
}
|
||||||
|
if (KeyIdxFieldPresent())
|
||||||
|
{
|
||||||
|
*x_field |= kKBit;
|
||||||
|
*data_field |= (hdr_info_.keyIdx & kKeyIdxField);
|
||||||
|
}
|
||||||
++*extension_length;
|
++*extension_length;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -320,8 +330,8 @@ int RtpFormatVp8::PayloadDescriptorExtraLength() const
|
|||||||
{
|
{
|
||||||
int length_bytes = PictureIdLength();
|
int length_bytes = PictureIdLength();
|
||||||
if (TL0PicIdxFieldPresent()) ++length_bytes;
|
if (TL0PicIdxFieldPresent()) ++length_bytes;
|
||||||
if (TIDFieldPresent()) ++length_bytes;
|
if (TIDFieldPresent() || KeyIdxFieldPresent()) ++length_bytes;
|
||||||
if (length_bytes > 0) ++length_bytes; // Include the extension field.
|
if (length_bytes > 0) ++length_bytes; // Include the extension field.
|
||||||
return length_bytes;
|
return length_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,7 +350,8 @@ int RtpFormatVp8::PictureIdLength() const
|
|||||||
|
|
||||||
bool RtpFormatVp8::XFieldPresent() const
|
bool RtpFormatVp8::XFieldPresent() const
|
||||||
{
|
{
|
||||||
return (TIDFieldPresent() || TL0PicIdxFieldPresent() || PictureIdPresent());
|
return (TIDFieldPresent() || TL0PicIdxFieldPresent() || PictureIdPresent()
|
||||||
|
|| KeyIdxFieldPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RtpFormatVp8::TIDFieldPresent() const
|
bool RtpFormatVp8::TIDFieldPresent() const
|
||||||
@ -348,6 +359,11 @@ bool RtpFormatVp8::TIDFieldPresent() const
|
|||||||
return (hdr_info_.temporalIdx != kNoTemporalIdx);
|
return (hdr_info_.temporalIdx != kNoTemporalIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RtpFormatVp8::KeyIdxFieldPresent() const
|
||||||
|
{
|
||||||
|
return (hdr_info_.keyIdx != kNoKeyIdx);
|
||||||
|
}
|
||||||
|
|
||||||
bool RtpFormatVp8::TL0PicIdxFieldPresent() const
|
bool RtpFormatVp8::TL0PicIdxFieldPresent() const
|
||||||
{
|
{
|
||||||
return (hdr_info_.tl0PicIdx != kNoTl0PicIdx);
|
return (hdr_info_.tl0PicIdx != kNoTl0PicIdx);
|
||||||
|
@ -84,9 +84,11 @@ private:
|
|||||||
static const int kNBit = 0x20;
|
static const int kNBit = 0x20;
|
||||||
static const int kSBit = 0x10;
|
static const int kSBit = 0x10;
|
||||||
static const int kPartIdField = 0x0F;
|
static const int kPartIdField = 0x0F;
|
||||||
|
static const int kKeyIdxField = 0x1F;
|
||||||
static const int kIBit = 0x80;
|
static const int kIBit = 0x80;
|
||||||
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;
|
||||||
|
|
||||||
// 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,
|
||||||
@ -115,10 +117,11 @@ private:
|
|||||||
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 bit in the x_field, and write TID to the appropriate
|
// Set the T and K bits in the x_field, and write TID and KeyIdx to the
|
||||||
// position in buffer. The function returns 0 on success, -1 otherwise.
|
// appropriate position in buffer. The function returns 0 on success,
|
||||||
int WriteTIDFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
// -1 otherwise.
|
||||||
int buffer_length, int* extension_length) const;
|
int WriteTIDAndKeyIdxFields(WebRtc_UWord8* x_field, WebRtc_UWord8* buffer,
|
||||||
|
int buffer_length, int* extension_length) const;
|
||||||
|
|
||||||
// Write the PictureID from codec_specific_info_ to buffer. One or two
|
// Write the PictureID from codec_specific_info_ to buffer. One or two
|
||||||
// bytes are written, depending on magnitude of PictureID. The function
|
// bytes are written, depending on magnitude of PictureID. The function
|
||||||
@ -136,6 +139,7 @@ private:
|
|||||||
// Check whether each of the optional fields will be included in the header.
|
// Check whether each of the optional fields will be included in the header.
|
||||||
bool XFieldPresent() const;
|
bool XFieldPresent() const;
|
||||||
bool TIDFieldPresent() const;
|
bool TIDFieldPresent() const;
|
||||||
|
bool KeyIdxFieldPresent() const;
|
||||||
bool TL0PicIdxFieldPresent() const;
|
bool TL0PicIdxFieldPresent() const;
|
||||||
bool PictureIdPresent() const { return (PictureIdLength() > 0); }
|
bool PictureIdPresent() const { return (PictureIdLength() > 0); }
|
||||||
|
|
||||||
|
@ -18,11 +18,7 @@
|
|||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include "rtp_format_vp8.h"
|
#include "rtp_format_vp8.h"
|
||||||
|
|
||||||
namespace {
|
namespace webrtc {
|
||||||
|
|
||||||
using webrtc::RTPFragmentationHeader;
|
|
||||||
using webrtc::RtpFormatVp8;
|
|
||||||
using webrtc::RTPVideoHeaderVP8;
|
|
||||||
|
|
||||||
const int kPayloadSize = 30;
|
const int kPayloadSize = 30;
|
||||||
const int kBufferSize = kPayloadSize + 6; // Add space for payload descriptor.
|
const int kBufferSize = kPayloadSize + 6; // Add space for payload descriptor.
|
||||||
@ -35,7 +31,7 @@ class RtpFormatVp8Test : public ::testing::Test {
|
|||||||
void CheckHeader(bool first_in_frame, bool frag_start, int part_id);
|
void CheckHeader(bool first_in_frame, bool frag_start, int part_id);
|
||||||
void CheckPictureID();
|
void CheckPictureID();
|
||||||
void CheckTl0PicIdx();
|
void CheckTl0PicIdx();
|
||||||
void CheckTID();
|
void CheckTIDAndKeyIdx();
|
||||||
void CheckPayload(int payload_end);
|
void CheckPayload(int payload_end);
|
||||||
void CheckLast(bool last) const;
|
void CheckLast(bool last) const;
|
||||||
void CheckPacket(int send_bytes, int expect_bytes, bool last,
|
void CheckPacket(int send_bytes, int expect_bytes, bool last,
|
||||||
@ -66,10 +62,11 @@ void RtpFormatVp8Test::SetUp() {
|
|||||||
fragmentation_->fragmentationOffset[1] = 10;
|
fragmentation_->fragmentationOffset[1] = 10;
|
||||||
fragmentation_->fragmentationOffset[2] = 20;
|
fragmentation_->fragmentationOffset[2] = 20;
|
||||||
|
|
||||||
hdr_info_.pictureId = webrtc::kNoPictureId;
|
hdr_info_.pictureId = kNoPictureId;
|
||||||
hdr_info_.nonReference = false;
|
hdr_info_.nonReference = false;
|
||||||
hdr_info_.temporalIdx = webrtc::kNoTemporalIdx;
|
hdr_info_.temporalIdx = kNoTemporalIdx;
|
||||||
hdr_info_.tl0PicIdx = webrtc::kNoTl0PicIdx;
|
hdr_info_.tl0PicIdx = kNoTl0PicIdx;
|
||||||
|
hdr_info_.keyIdx = kNoKeyIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpFormatVp8Test::TearDown() {
|
void RtpFormatVp8Test::TearDown() {
|
||||||
@ -96,7 +93,11 @@ void RtpFormatVp8Test::TearDown() {
|
|||||||
|
|
||||||
#define EXPECT_BIT_T_EQ(x,a) EXPECT_BIT_EQ(x, 5, a)
|
#define EXPECT_BIT_T_EQ(x,a) EXPECT_BIT_EQ(x, 5, a)
|
||||||
|
|
||||||
#define EXPECT_TID_EQ(x,a) EXPECT_EQ((((x)&0xE0) >> 5), 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_KEYIDX_EQ(x,a) EXPECT_EQ(((x) & 0x1F), a)
|
||||||
|
|
||||||
void RtpFormatVp8Test::CheckHeader(bool first_in_frame, bool frag_start,
|
void RtpFormatVp8Test::CheckHeader(bool first_in_frame, bool frag_start,
|
||||||
int part_id)
|
int part_id)
|
||||||
@ -105,15 +106,16 @@ void RtpFormatVp8Test::CheckHeader(bool first_in_frame, bool frag_start,
|
|||||||
EXPECT_BIT_EQ(buffer_[0], 6, 0); // check reserved bit
|
EXPECT_BIT_EQ(buffer_[0], 6, 0); // check reserved bit
|
||||||
|
|
||||||
|
|
||||||
if (hdr_info_.pictureId != webrtc::kNoPictureId ||
|
if (hdr_info_.pictureId != kNoPictureId ||
|
||||||
hdr_info_.temporalIdx != webrtc::kNoTemporalIdx ||
|
hdr_info_.temporalIdx != kNoTemporalIdx ||
|
||||||
hdr_info_.tl0PicIdx != webrtc::kNoTl0PicIdx)
|
hdr_info_.tl0PicIdx != kNoTl0PicIdx ||
|
||||||
|
hdr_info_.keyIdx != kNoKeyIdx)
|
||||||
{
|
{
|
||||||
EXPECT_BIT_X_EQ(buffer_[0], 1);
|
EXPECT_BIT_X_EQ(buffer_[0], 1);
|
||||||
++payload_start_;
|
++payload_start_;
|
||||||
CheckPictureID();
|
CheckPictureID();
|
||||||
CheckTl0PicIdx();
|
CheckTl0PicIdx();
|
||||||
CheckTID();
|
CheckTIDAndKeyIdx();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -137,7 +139,7 @@ void RtpFormatVp8Test::CheckHeader(bool first_in_frame, bool frag_start,
|
|||||||
|
|
||||||
void RtpFormatVp8Test::CheckPictureID()
|
void RtpFormatVp8Test::CheckPictureID()
|
||||||
{
|
{
|
||||||
if (hdr_info_.pictureId != webrtc::kNoPictureId)
|
if (hdr_info_.pictureId != kNoPictureId)
|
||||||
{
|
{
|
||||||
EXPECT_BIT_I_EQ(buffer_[1], 1);
|
EXPECT_BIT_I_EQ(buffer_[1], 1);
|
||||||
if (hdr_info_.pictureId > 0x7F)
|
if (hdr_info_.pictureId > 0x7F)
|
||||||
@ -165,7 +167,7 @@ void RtpFormatVp8Test::CheckPictureID()
|
|||||||
|
|
||||||
void RtpFormatVp8Test::CheckTl0PicIdx()
|
void RtpFormatVp8Test::CheckTl0PicIdx()
|
||||||
{
|
{
|
||||||
if (hdr_info_.tl0PicIdx != webrtc::kNoTl0PicIdx)
|
if (hdr_info_.tl0PicIdx != kNoTl0PicIdx)
|
||||||
{
|
{
|
||||||
EXPECT_BIT_L_EQ(buffer_[1], 1);
|
EXPECT_BIT_L_EQ(buffer_[1], 1);
|
||||||
EXPECT_EQ(buffer_[payload_start_], hdr_info_.tl0PicIdx);
|
EXPECT_EQ(buffer_[payload_start_], hdr_info_.tl0PicIdx);
|
||||||
@ -177,19 +179,36 @@ void RtpFormatVp8Test::CheckTl0PicIdx()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpFormatVp8Test::CheckTID()
|
void RtpFormatVp8Test::CheckTIDAndKeyIdx()
|
||||||
{
|
{
|
||||||
if (hdr_info_.temporalIdx != webrtc::kNoTemporalIdx)
|
if (hdr_info_.temporalIdx == kNoTemporalIdx &&
|
||||||
|
hdr_info_.keyIdx == kNoKeyIdx)
|
||||||
|
{
|
||||||
|
EXPECT_BIT_T_EQ(buffer_[1], 0);
|
||||||
|
EXPECT_BIT_K_EQ(buffer_[1], 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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_EQ(buffer_[payload_start_] & 0x1F, 0);
|
|
||||||
++payload_start_;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EXPECT_BIT_T_EQ(buffer_[1], 0);
|
EXPECT_BIT_T_EQ(buffer_[1], 0);
|
||||||
|
EXPECT_TID_EQ(buffer_[payload_start_], 0);
|
||||||
}
|
}
|
||||||
|
if (hdr_info_.keyIdx != kNoKeyIdx)
|
||||||
|
{
|
||||||
|
EXPECT_BIT_K_EQ(buffer_[1], 1);
|
||||||
|
EXPECT_KEYIDX_EQ(buffer_[payload_start_], hdr_info_.keyIdx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EXPECT_BIT_K_EQ(buffer_[1], 0);
|
||||||
|
EXPECT_KEYIDX_EQ(buffer_[payload_start_], 0);
|
||||||
|
}
|
||||||
|
++payload_start_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpFormatVp8Test::CheckPayload(int payload_end)
|
void RtpFormatVp8Test::CheckPayload(int payload_end)
|
||||||
@ -232,7 +251,7 @@ TEST_F(RtpFormatVp8Test, TestStrictMode)
|
|||||||
|
|
||||||
hdr_info_.pictureId = 200; // > 0x7F should produce 2-byte PictureID
|
hdr_info_.pictureId = 200; // > 0x7F should produce 2-byte PictureID
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
hdr_info_, *fragmentation_, webrtc::kStrict);
|
hdr_info_, *fragmentation_, kStrict);
|
||||||
|
|
||||||
// get first packet, expect balanced size ~= same as second packet
|
// get first packet, expect balanced size ~= same as second packet
|
||||||
EXPECT_EQ(0, packetizer.NextPacket(13, buffer_, &send_bytes, &last));
|
EXPECT_EQ(0, packetizer.NextPacket(13, buffer_, &send_bytes, &last));
|
||||||
@ -289,7 +308,7 @@ TEST_F(RtpFormatVp8Test, TestAggregateMode)
|
|||||||
|
|
||||||
hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID
|
hdr_info_.pictureId = 20; // <= 0x7F should produce 1-byte PictureID
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
hdr_info_, *fragmentation_, webrtc::kAggregate);
|
hdr_info_, *fragmentation_, kAggregate);
|
||||||
|
|
||||||
// get first packet
|
// get first packet
|
||||||
// first part of first partition (balanced fragments are expected)
|
// first part of first partition (balanced fragments are expected)
|
||||||
@ -328,9 +347,9 @@ TEST_F(RtpFormatVp8Test, TestSloppyMode)
|
|||||||
bool last;
|
bool last;
|
||||||
bool first_in_frame = true;
|
bool first_in_frame = true;
|
||||||
|
|
||||||
hdr_info_.pictureId = webrtc::kNoPictureId; // no PictureID
|
hdr_info_.pictureId = kNoPictureId; // no PictureID
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
hdr_info_, *fragmentation_, webrtc::kSloppy);
|
hdr_info_, *fragmentation_, kSloppy);
|
||||||
|
|
||||||
// get first packet
|
// get first packet
|
||||||
EXPECT_EQ(0, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
|
EXPECT_EQ(0, packetizer.NextPacket(9, buffer_, &send_bytes, &last));
|
||||||
@ -431,7 +450,7 @@ TEST_F(RtpFormatVp8Test, TestTl0PicIdxAndTID) {
|
|||||||
hdr_info_.tl0PicIdx = 117;
|
hdr_info_.tl0PicIdx = 117;
|
||||||
hdr_info_.temporalIdx = 2;
|
hdr_info_.temporalIdx = 2;
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
hdr_info_, *fragmentation_, webrtc::kAggregate);
|
hdr_info_, *fragmentation_, kAggregate);
|
||||||
|
|
||||||
// get first and only packet
|
// get first and only packet
|
||||||
EXPECT_EQ(0, packetizer.NextPacket(kBufferSize, buffer_, &send_bytes,
|
EXPECT_EQ(0, packetizer.NextPacket(kBufferSize, buffer_, &send_bytes,
|
||||||
@ -442,10 +461,41 @@ TEST_F(RtpFormatVp8Test, TestTl0PicIdxAndTID) {
|
|||||||
/* frag_start */ true);
|
/* frag_start */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
// Verify KeyIdx field
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
TEST_F(RtpFormatVp8Test, TestKeyIdx) {
|
||||||
|
int send_bytes = 0;
|
||||||
|
bool last;
|
||||||
|
|
||||||
return RUN_ALL_TESTS();
|
hdr_info_.keyIdx = 17;
|
||||||
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
|
hdr_info_, *fragmentation_, kAggregate);
|
||||||
|
|
||||||
|
// get first and only packet
|
||||||
|
EXPECT_EQ(0, packetizer.NextPacket(kBufferSize, buffer_, &send_bytes,
|
||||||
|
&last));
|
||||||
|
bool first_in_frame = true;
|
||||||
|
CheckPacket(send_bytes, kPayloadSize + 3, last,
|
||||||
|
first_in_frame,
|
||||||
|
/* frag_start */ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify TID field and KeyIdx field in combination
|
||||||
|
TEST_F(RtpFormatVp8Test, TestTIDAndKeyIdx) {
|
||||||
|
int send_bytes = 0;
|
||||||
|
bool last;
|
||||||
|
|
||||||
|
hdr_info_.temporalIdx = 1;
|
||||||
|
hdr_info_.keyIdx = 5;
|
||||||
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload_data_, kPayloadSize,
|
||||||
|
hdr_info_, *fragmentation_, kAggregate);
|
||||||
|
|
||||||
|
// get first and only packet
|
||||||
|
EXPECT_EQ(0, packetizer.NextPacket(kBufferSize, buffer_, &send_bytes,
|
||||||
|
&last));
|
||||||
|
bool first_in_frame = true;
|
||||||
|
CheckPacket(send_bytes, kPayloadSize + 3, last,
|
||||||
|
first_in_frame,
|
||||||
|
/* frag_start */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -808,26 +808,26 @@ ModuleRTPUtility::RTPPayloadParser::ParseMPEG4(
|
|||||||
// VP8 format:
|
// VP8 format:
|
||||||
//
|
//
|
||||||
// Payload descriptor
|
// Payload descriptor
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// |X|R|N|S|PartID | (REQUIRED)
|
// |X|R|N|S|PartID | (REQUIRED)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// X: |I|L|T| RSV-A | (OPTIONAL)
|
// X: |I|L|T|K| RSV | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// I: | PictureID | (OPTIONAL)
|
// I: | PictureID | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PICIDX | (OPTIONAL)
|
// L: | TL0PICIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// T: | TID | RSV-B | (OPTIONAL)
|
// T/K: | TID | KEYIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
//
|
//
|
||||||
// Payload header (considered part of the actual payload, sent to decoder)
|
// Payload header (considered part of the actual payload, sent to decoder)
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// |Size0|H| VER |P|
|
// |Size0|H| VER |P|
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// | ... |
|
// | ... |
|
||||||
// + +
|
// + +
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ModuleRTPUtility::RTPPayloadParser::ParseVP8(RTPPayload& parsedPacket) const
|
ModuleRTPUtility::RTPPayloadParser::ParseVP8(RTPPayload& parsedPacket) const
|
||||||
@ -912,6 +912,7 @@ int ModuleRTPUtility::RTPPayloadParser::ParseVP8Extension(
|
|||||||
vp8->hasPictureID = (*dataPtr & 0x80) ? true : false; // I bit
|
vp8->hasPictureID = (*dataPtr & 0x80) ? true : false; // I bit
|
||||||
vp8->hasTl0PicIdx = (*dataPtr & 0x40) ? true : false; // L bit
|
vp8->hasTl0PicIdx = (*dataPtr & 0x40) ? true : false; // L bit
|
||||||
vp8->hasTID = (*dataPtr & 0x20) ? true : false; // T bit
|
vp8->hasTID = (*dataPtr & 0x20) ? true : false; // T bit
|
||||||
|
vp8->hasKeyIdx = (*dataPtr & 0x10) ? true : false; // K bit
|
||||||
|
|
||||||
// Advance dataPtr and decrease remaining payload size
|
// Advance dataPtr and decrease remaining payload size
|
||||||
dataPtr++;
|
dataPtr++;
|
||||||
@ -934,9 +935,9 @@ int ModuleRTPUtility::RTPPayloadParser::ParseVP8Extension(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vp8->hasTID)
|
if (vp8->hasTID || vp8->hasKeyIdx)
|
||||||
{
|
{
|
||||||
if (ParseVP8TID(vp8, &dataPtr, &dataLength, &parsedBytes) != 0)
|
if (ParseVP8TIDAndKeyIdx(vp8, &dataPtr, &dataLength, &parsedBytes) != 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -982,14 +983,21 @@ ModuleRTPUtility::RTPPayloadParser::ParseVP8Tl0PicIdx(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModuleRTPUtility::RTPPayloadParser::ParseVP8TID(
|
int ModuleRTPUtility::RTPPayloadParser::ParseVP8TIDAndKeyIdx(
|
||||||
RTPPayloadVP8 *vp8,
|
RTPPayloadVP8 *vp8,
|
||||||
const WebRtc_UWord8 **dataPtr,
|
const WebRtc_UWord8 **dataPtr,
|
||||||
int *dataLength,
|
int *dataLength,
|
||||||
int *parsedBytes) const
|
int *parsedBytes) const
|
||||||
{
|
{
|
||||||
if (*dataLength <= 0) return -1;
|
if (*dataLength <= 0) return -1;
|
||||||
vp8->tID = ((**dataPtr >> 5) & 0x07);
|
if (vp8->hasTID)
|
||||||
|
{
|
||||||
|
vp8->tID = ((**dataPtr >> 5) & 0x07);
|
||||||
|
}
|
||||||
|
if (vp8->hasKeyIdx)
|
||||||
|
{
|
||||||
|
vp8->keyIdx = (**dataPtr & 0x1F);
|
||||||
|
}
|
||||||
(*dataPtr)++;
|
(*dataPtr)++;
|
||||||
(*parsedBytes)++;
|
(*parsedBytes)++;
|
||||||
(*dataLength)--;
|
(*dataLength)--;
|
||||||
|
@ -145,9 +145,11 @@ namespace ModuleRTPUtility
|
|||||||
bool hasPictureID;
|
bool hasPictureID;
|
||||||
bool hasTl0PicIdx;
|
bool hasTl0PicIdx;
|
||||||
bool hasTID;
|
bool hasTID;
|
||||||
|
bool hasKeyIdx;
|
||||||
int pictureID;
|
int pictureID;
|
||||||
int tl0PicIdx;
|
int tl0PicIdx;
|
||||||
int tID;
|
int tID;
|
||||||
|
int keyIdx;
|
||||||
int frameWidth;
|
int frameWidth;
|
||||||
int frameHeight;
|
int frameHeight;
|
||||||
|
|
||||||
@ -208,10 +210,10 @@ namespace ModuleRTPUtility
|
|||||||
int *dataLength,
|
int *dataLength,
|
||||||
int *parsedBytes) const;
|
int *parsedBytes) const;
|
||||||
|
|
||||||
int ParseVP8TID(RTPPayloadVP8 *vp8,
|
int ParseVP8TIDAndKeyIdx(RTPPayloadVP8 *vp8,
|
||||||
const WebRtc_UWord8 **dataPtr,
|
const WebRtc_UWord8 **dataPtr,
|
||||||
int *dataLength,
|
int *dataLength,
|
||||||
int *parsedBytes) const;
|
int *parsedBytes) const;
|
||||||
|
|
||||||
int ParseVP8FrameSize(RTPPayload& parsedPacket,
|
int ParseVP8FrameSize(RTPPayload& parsedPacket,
|
||||||
const WebRtc_UWord8 *dataPtr,
|
const WebRtc_UWord8 *dataPtr,
|
||||||
|
@ -19,44 +19,43 @@
|
|||||||
#include "rtp_utility.h"
|
#include "rtp_utility.h"
|
||||||
#include "rtp_format_vp8.h"
|
#include "rtp_format_vp8.h"
|
||||||
|
|
||||||
namespace {
|
namespace webrtc {
|
||||||
|
|
||||||
using webrtc::ModuleRTPUtility::RTPPayloadParser;
|
using ModuleRTPUtility::RTPPayloadParser;
|
||||||
using webrtc::ModuleRTPUtility::RTPPayload;
|
using ModuleRTPUtility::RTPPayload;
|
||||||
using webrtc::ModuleRTPUtility::RTPPayloadVP8;
|
using ModuleRTPUtility::RTPPayloadVP8;
|
||||||
using webrtc::RtpVideoCodecTypes;
|
|
||||||
|
|
||||||
// Payload descriptor
|
// Payload descriptor
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// |X|R|N|S|PartID | (REQUIRED)
|
// |X|R|N|S|PartID | (REQUIRED)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// X: |I|L|T| RSV-A | (OPTIONAL)
|
// X: |I|L|T|K| RSV | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// I: | PictureID | (OPTIONAL)
|
// I: | PictureID | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// L: | TL0PICIDX | (OPTIONAL)
|
// L: | TL0PICIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// T: | TID | RSV-B | (OPTIONAL)
|
// T/K: | TID | KEYIDX | (OPTIONAL)
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
//
|
//
|
||||||
// Payload header
|
// Payload header
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// |Size0|H| VER |P|
|
// |Size0|H| VER |P|
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// | Size1 |
|
// | Size1 |
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// | Size2 |
|
// | Size2 |
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// | Bytes 4..N of |
|
// | Bytes 4..N of |
|
||||||
// | VP8 payload |
|
// | VP8 payload |
|
||||||
// : :
|
// : :
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
// | OPTIONAL RTP |
|
// | OPTIONAL RTP |
|
||||||
// | padding |
|
// | padding |
|
||||||
// : :
|
// : :
|
||||||
// +-+-+-+-+-+-+-+-+
|
// +-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
void VerifyBasicHeader(const RTPPayloadVP8 &header, bool N, bool S, int PartID)
|
void VerifyBasicHeader(const RTPPayloadVP8 &header, bool N, bool S, int PartID)
|
||||||
{
|
{
|
||||||
@ -65,11 +64,13 @@ void VerifyBasicHeader(const RTPPayloadVP8 &header, bool N, bool S, int PartID)
|
|||||||
EXPECT_EQ(PartID, header.partitionID);
|
EXPECT_EQ(PartID, header.partitionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerifyExtensions(const RTPPayloadVP8 &header, bool I, bool L, bool T)
|
void VerifyExtensions(const RTPPayloadVP8 &header,
|
||||||
|
bool I, bool L, bool T, bool K)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(I, header.hasPictureID);
|
EXPECT_EQ(I, header.hasPictureID);
|
||||||
EXPECT_EQ(L, header.hasTl0PicIdx);
|
EXPECT_EQ(L, header.hasTl0PicIdx);
|
||||||
EXPECT_EQ(T, header.hasTID);
|
EXPECT_EQ(T, header.hasTID);
|
||||||
|
EXPECT_EQ(K, header.hasKeyIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseVP8Test, BasicHeader) {
|
TEST(ParseVP8Test, BasicHeader) {
|
||||||
@ -77,16 +78,16 @@ TEST(ParseVP8Test, BasicHeader) {
|
|||||||
payload[0] = 0x14; // binary 0001 0100; S = 1, PartID = 4
|
payload[0] = 0x14; // binary 0001 0100; S = 1, PartID = 4
|
||||||
payload[1] = 0x01; // P frame
|
payload[1] = 0x01; // P frame
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 4, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 4, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/);
|
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
|
||||||
|
|
||||||
EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data);
|
EXPECT_EQ(payload + 1, parsedPacket.info.VP8.data);
|
||||||
EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(4 - 1, parsedPacket.info.VP8.dataLength);
|
||||||
@ -98,16 +99,16 @@ TEST(ParseVP8Test, PictureID) {
|
|||||||
payload[1] = 0x80;
|
payload[1] = 0x80;
|
||||||
payload[2] = 17;
|
payload[2] = 17;
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/);
|
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
|
||||||
|
|
||||||
EXPECT_EQ(17, parsedPacket.info.VP8.pictureID);
|
EXPECT_EQ(17, parsedPacket.info.VP8.pictureID);
|
||||||
|
|
||||||
@ -118,12 +119,12 @@ TEST(ParseVP8Test, PictureID) {
|
|||||||
// Re-use payload, but change to long PictureID
|
// Re-use payload, but change to long PictureID
|
||||||
payload[2] = 0x80 | 17;
|
payload[2] = 0x80 | 17;
|
||||||
payload[3] = 17;
|
payload[3] = 17;
|
||||||
RTPPayloadParser rtpPayloadParser2(webrtc::kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser2(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/);
|
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
|
||||||
|
|
||||||
EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
|
EXPECT_EQ((17<<8) + 17, parsedPacket.info.VP8.pictureID);
|
||||||
|
|
||||||
@ -137,16 +138,16 @@ TEST(ParseVP8Test, Tl0PicIdx) {
|
|||||||
payload[1] = 0x40;
|
payload[1] = 0x40;
|
||||||
payload[2] = 17;
|
payload[2] = 17;
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 13, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 13, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kIFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/);
|
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/);
|
||||||
|
|
||||||
EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx);
|
EXPECT_EQ(17, parsedPacket.info.VP8.tl0PicIdx);
|
||||||
|
|
||||||
@ -160,16 +161,16 @@ TEST(ParseVP8Test, TID) {
|
|||||||
payload[1] = 0x20;
|
payload[1] = 0x20;
|
||||||
payload[2] = 0x40;
|
payload[2] = 0x40;
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/);
|
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);
|
||||||
|
|
||||||
@ -177,29 +178,53 @@ TEST(ParseVP8Test, TID) {
|
|||||||
EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ParseVP8Test, KeyIdx) {
|
||||||
|
WebRtc_UWord8 payload[10] = {0};
|
||||||
|
payload[0] = 0x88;
|
||||||
|
payload[1] = 0x10; // K = 1
|
||||||
|
payload[2] = 0x11; // KEYIDX = 17 decimal
|
||||||
|
|
||||||
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
|
RTPPayload parsedPacket;
|
||||||
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
|
EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
||||||
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
|
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
|
||||||
|
VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/);
|
||||||
|
|
||||||
|
EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
|
||||||
|
|
||||||
|
EXPECT_EQ(payload + 3, parsedPacket.info.VP8.data);
|
||||||
|
EXPECT_EQ(10 - 3, parsedPacket.info.VP8.dataLength);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ParseVP8Test, MultipleExtensions) {
|
TEST(ParseVP8Test, MultipleExtensions) {
|
||||||
WebRtc_UWord8 payload[10] = {0};
|
WebRtc_UWord8 payload[10] = {0};
|
||||||
payload[0] = 0x88;
|
payload[0] = 0x88;
|
||||||
payload[1] = 0x80 | 0x40 | 0x20;
|
payload[1] = 0x80 | 0x40 | 0x20 | 0x10;
|
||||||
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; // TID
|
payload[5] = 0x40 | 0x11; // TID + KEYIDX
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 10, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
|
VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
|
||||||
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/);
|
VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/);
|
||||||
|
|
||||||
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(2, parsedPacket.info.VP8.tID);
|
||||||
|
EXPECT_EQ(17, parsedPacket.info.VP8.keyIdx);
|
||||||
|
|
||||||
EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
|
EXPECT_EQ(payload + 6, parsedPacket.info.VP8.data);
|
||||||
EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(10 - 6, parsedPacket.info.VP8.dataLength);
|
||||||
@ -208,19 +233,16 @@ TEST(ParseVP8Test, MultipleExtensions) {
|
|||||||
TEST(ParseVP8Test, TooShortHeader) {
|
TEST(ParseVP8Test, TooShortHeader) {
|
||||||
WebRtc_UWord8 payload[4] = {0};
|
WebRtc_UWord8 payload[4] = {0};
|
||||||
payload[0] = 0x88;
|
payload[0] = 0x88;
|
||||||
payload[1] = 0x80 | 0x40 | 0x20; // All extensions are enabled
|
payload[1] = 0x80 | 0x40 | 0x20 | 0x10; // All extensions are enabled
|
||||||
payload[2] = 0x80 | 17; //... but only 2 bytes PictureID is provided
|
payload[2] = 0x80 | 17; //... but only 2 bytes PictureID is provided
|
||||||
payload[3] = 17; // PictureID, low 8 bits
|
payload[3] = 17; // PictureID, low 8 bits
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, payload, 4, 0);
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 4, 0);
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
|
EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
using webrtc::RtpFormatVp8;
|
|
||||||
using webrtc::RTPVideoHeaderVP8;
|
|
||||||
|
|
||||||
TEST(ParseVP8Test, TestWithPacketizer) {
|
TEST(ParseVP8Test, TestWithPacketizer) {
|
||||||
WebRtc_UWord8 payload[10] = {0};
|
WebRtc_UWord8 payload[10] = {0};
|
||||||
WebRtc_UWord8 packet[20] = {0};
|
WebRtc_UWord8 packet[20] = {0};
|
||||||
@ -228,21 +250,21 @@ TEST(ParseVP8Test, TestWithPacketizer) {
|
|||||||
inputHeader.nonReference = true;
|
inputHeader.nonReference = true;
|
||||||
inputHeader.pictureId = 300;
|
inputHeader.pictureId = 300;
|
||||||
inputHeader.temporalIdx = 1;
|
inputHeader.temporalIdx = 1;
|
||||||
inputHeader.tl0PicIdx = -1; // disable
|
inputHeader.tl0PicIdx = kNoTl0PicIdx; // disable
|
||||||
|
inputHeader.keyIdx = 31;
|
||||||
RtpFormatVp8 packetizer = RtpFormatVp8(payload, 10, inputHeader);
|
RtpFormatVp8 packetizer = RtpFormatVp8(payload, 10, inputHeader);
|
||||||
bool last;
|
bool last;
|
||||||
int send_bytes;
|
int send_bytes;
|
||||||
ASSERT_EQ(0, packetizer.NextPacket(20, packet, &send_bytes, &last));
|
ASSERT_EQ(0, packetizer.NextPacket(20, packet, &send_bytes, &last));
|
||||||
ASSERT_TRUE(last);
|
ASSERT_TRUE(last);
|
||||||
|
|
||||||
RTPPayloadParser rtpPayloadParser(webrtc::kRtpVp8Video, packet, send_bytes,
|
RTPPayloadParser rtpPayloadParser(kRtpVp8Video, packet, send_bytes, 0);
|
||||||
0);
|
|
||||||
|
|
||||||
RTPPayload parsedPacket;
|
RTPPayload parsedPacket;
|
||||||
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
|
||||||
|
|
||||||
EXPECT_EQ(webrtc::ModuleRTPUtility::kIFrame, parsedPacket.frameType);
|
EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
|
||||||
EXPECT_EQ(webrtc::kRtpVp8Video, parsedPacket.type);
|
EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
|
||||||
|
|
||||||
VerifyBasicHeader(parsedPacket.info.VP8,
|
VerifyBasicHeader(parsedPacket.info.VP8,
|
||||||
inputHeader.nonReference /*N*/,
|
inputHeader.nonReference /*N*/,
|
||||||
@ -251,19 +273,15 @@ TEST(ParseVP8Test, TestWithPacketizer) {
|
|||||||
VerifyExtensions(parsedPacket.info.VP8,
|
VerifyExtensions(parsedPacket.info.VP8,
|
||||||
1 /*I*/,
|
1 /*I*/,
|
||||||
0 /*L*/,
|
0 /*L*/,
|
||||||
1 /*T*/);
|
1 /*T*/,
|
||||||
|
1 /*K*/);
|
||||||
|
|
||||||
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.keyIdx, parsedPacket.info.VP8.keyIdx);
|
||||||
|
|
||||||
EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
|
EXPECT_EQ(packet + 5, parsedPacket.info.VP8.data);
|
||||||
EXPECT_EQ(send_bytes - 5, parsedPacket.info.VP8.dataLength);
|
EXPECT_EQ(send_bytes - 5, parsedPacket.info.VP8.dataLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user