Move H.264 SPS VUI rewriting to FrameEncodeMetadataWriter.

Bug: webrtc:10559
Change-Id: I956287e71a47856cfb6dd807d9715d6ee2572f55
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138263
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28100}
This commit is contained in:
Mirta Dvornicic
2019-05-28 16:30:16 +02:00
committed by Commit Bot
parent a1d1a1e976
commit 28f0eb2dde
12 changed files with 248 additions and 104 deletions

View File

@ -76,26 +76,15 @@ RtpPacketizerH264::RtpPacketizerH264(
H264PacketizationMode packetization_mode,
const RTPFragmentationHeader& fragmentation)
: limits_(limits),
modified_buffer_(new rtc::Buffer()),
num_packets_left_(0) {
// Guard against uninitialized memory in packetization_mode.
RTC_CHECK(packetization_mode == H264PacketizationMode::NonInterleaved ||
packetization_mode == H264PacketizationMode::SingleNalUnit);
RTPFragmentationHeader modified_fragmentation;
modified_fragmentation.CopyFrom(fragmentation);
SpsVuiRewriter::ParseOutgoingBitstreamAndRewriteSps(
payload, fragmentation.fragmentationVectorSize,
fragmentation.fragmentationOffset, fragmentation.fragmentationLength,
modified_buffer_.get(), modified_fragmentation.fragmentationOffset,
modified_fragmentation.fragmentationLength);
for (size_t i = 0; i < modified_fragmentation.fragmentationVectorSize; ++i) {
const uint8_t* fragment = modified_buffer_->data() +
modified_fragmentation.fragmentationOffset[i];
const size_t fragment_length =
modified_fragmentation.fragmentationLength[i];
for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) {
const uint8_t* fragment =
payload.data() + fragmentation.fragmentationOffset[i];
const size_t fragment_length = fragmentation.fragmentationLength[i];
input_fragments_.push_back(Fragment(fragment, fragment_length));
}

View File

@ -90,7 +90,6 @@ class RtpPacketizerH264 : public RtpPacketizer {
void NextFragmentPacket(RtpPacketToSend* rtp_packet);
const PayloadSizeLimits limits_;
std::unique_ptr<rtc::Buffer> modified_buffer_;
size_t num_packets_left_;
std::deque<Fragment> input_fragments_;
std::queue<PacketUnit> packets_;

View File

@ -497,7 +497,6 @@ TEST(RtpPacketizerH264Test, RejectsOverlongDataInPacketizationMode0) {
EXPECT_THAT(packets, IsEmpty());
}
const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01};
const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
0xF4, 0x05, 0x03, 0xC7, 0xC0};
const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03,
@ -505,79 +504,6 @@ const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03,
const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04};
const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11};
class RtpPacketizerH264TestSpsRewriting : public ::testing::Test {
public:
void SetUp() override {
fragmentation_header_.VerifyAndAllocateFragmentationHeader(3);
fragmentation_header_.fragmentationVectorSize = 3;
in_buffer_.AppendData(kStartSequence);
fragmentation_header_.fragmentationOffset[0] = in_buffer_.size();
fragmentation_header_.fragmentationLength[0] = sizeof(kOriginalSps);
in_buffer_.AppendData(kOriginalSps);
fragmentation_header_.fragmentationOffset[1] = in_buffer_.size();
fragmentation_header_.fragmentationLength[1] = sizeof(kIdrOne);
in_buffer_.AppendData(kIdrOne);
fragmentation_header_.fragmentationOffset[2] = in_buffer_.size();
fragmentation_header_.fragmentationLength[2] = sizeof(kIdrTwo);
in_buffer_.AppendData(kIdrTwo);
}
protected:
rtc::Buffer in_buffer_;
RTPFragmentationHeader fragmentation_header_;
};
TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
const size_t kHeaderOverhead = kFuAHeaderSize + 1;
// Set size to fragment SPS into two FU-A packets.
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = sizeof(kOriginalSps) - 2 + kHeaderOverhead;
RtpPacketizerH264 packetizer(in_buffer_, limits,
H264PacketizationMode::NonInterleaved,
fragmentation_header_);
std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
size_t offset = H264::kNaluTypeSize;
size_t length = packets[0].payload_size() - kFuAHeaderSize;
EXPECT_THAT(packets[0].payload().subview(kFuAHeaderSize),
ElementsAreArray(&kRewrittenSps[offset], length));
offset += length;
length = packets[1].payload_size() - kFuAHeaderSize;
EXPECT_THAT(packets[1].payload().subview(kFuAHeaderSize),
ElementsAreArray(&kRewrittenSps[offset], length));
offset += length;
EXPECT_EQ(offset, sizeof(kRewrittenSps));
}
TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) {
const size_t kHeaderOverhead = kFuAHeaderSize + 1;
const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type.
sizeof(kRewrittenSps) + sizeof(kIdrOne) +
sizeof(kIdrTwo) + (kLengthFieldLength * 3);
// Set size to include SPS and the rest of the packets in a Stap-A package.
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kExpectedTotalSize + kHeaderOverhead;
RtpPacketizerH264 packetizer(in_buffer_, limits,
H264PacketizationMode::NonInterleaved,
fragmentation_header_);
std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
ASSERT_THAT(packets, SizeIs(1));
EXPECT_EQ(packets[0].payload_size(), kExpectedTotalSize);
EXPECT_THAT(
packets[0].payload().subview(H264::kNaluTypeSize + kLengthFieldLength,
sizeof(kRewrittenSps)),
ElementsAreArray(kRewrittenSps));
}
struct H264ParsedPayload : public RtpDepacketizer::ParsedPayload {
RTPVideoHeaderH264& h264() {
return absl::get<RTPVideoHeaderH264>(video.video_type_header);