Use sps and pps to determine decodability of H.264 frames.

NOPRESUBMIT=true
BUG=webrtc:6208
R=philipel@webrtc.org

Review URL: https://codereview.webrtc.org/2341713002 .

Cr-Commit-Position: refs/heads/master@{#14458}
This commit is contained in:
Stefan Holmer
2016-09-30 15:24:14 +02:00
parent 55d932b331
commit 17b0263366
9 changed files with 213 additions and 17 deletions

View File

@ -12,9 +12,9 @@
#include <list>
#include <memory>
#include <vector>
#include "webrtc/test/gtest.h"
#include "webrtc/test/gmock.h"
#include "webrtc/common_video/h264/h264_common.h"
#include "webrtc/modules/video_coding/frame_buffer.h"
#include "webrtc/modules/video_coding/jitter_buffer.h"
#include "webrtc/modules/video_coding/media_opt_util.h"
@ -26,6 +26,8 @@
#include "webrtc/system_wrappers/include/metrics.h"
#include "webrtc/system_wrappers/include/metrics_default.h"
#include "webrtc/test/field_trial.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
@ -1160,6 +1162,89 @@ TEST_F(TestBasicJitterBuffer, H264InsertStartCode) {
jitter_buffer_->ReleaseFrame(frame_out);
}
TEST_F(TestBasicJitterBuffer, SpsAndPpsHandling) {
jitter_buffer_->SetDecodeErrorMode(kNoErrors);
packet_->timestamp = timestamp_;
packet_->frameType = kVideoFrameKey;
packet_->isFirstPacket = true;
packet_->markerBit = true;
packet_->codec = kVideoCodecH264;
packet_->video_header.codec = kRtpVideoH264;
packet_->video_header.codecHeader.H264.nalu_type = H264::NaluType::kIdr;
packet_->video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kIdr;
packet_->video_header.codecHeader.H264.nalus[0].sps_id = -1;
packet_->video_header.codecHeader.H264.nalus[0].pps_id = 0;
packet_->video_header.codecHeader.H264.nalus_length = 1;
bool retransmitted = false;
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
// Not decodable since sps and pps are missing.
EXPECT_EQ(nullptr, DecodeCompleteFrame());
timestamp_ += 3000;
packet_->timestamp = timestamp_;
++seq_num_;
packet_->seqNum = seq_num_;
packet_->frameType = kVideoFrameKey;
packet_->isFirstPacket = true;
packet_->markerBit = false;
packet_->codec = kVideoCodecH264;
packet_->video_header.codec = kRtpVideoH264;
packet_->video_header.codecHeader.H264.nalu_type = H264::NaluType::kStapA;
packet_->video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kSps;
packet_->video_header.codecHeader.H264.nalus[0].sps_id = 0;
packet_->video_header.codecHeader.H264.nalus[0].pps_id = -1;
packet_->video_header.codecHeader.H264.nalus[1].type = H264::NaluType::kPps;
packet_->video_header.codecHeader.H264.nalus[1].sps_id = 0;
packet_->video_header.codecHeader.H264.nalus[1].pps_id = 0;
packet_->video_header.codecHeader.H264.nalus_length = 2;
// Not complete since the marker bit hasn't been received.
EXPECT_EQ(kIncomplete,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
++seq_num_;
packet_->seqNum = seq_num_;
packet_->frameType = kVideoFrameKey;
packet_->isFirstPacket = false;
packet_->markerBit = true;
packet_->codec = kVideoCodecH264;
packet_->video_header.codec = kRtpVideoH264;
packet_->video_header.codecHeader.H264.nalu_type = H264::NaluType::kIdr;
packet_->video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kIdr;
packet_->video_header.codecHeader.H264.nalus[0].sps_id = -1;
packet_->video_header.codecHeader.H264.nalus[0].pps_id = 0;
packet_->video_header.codecHeader.H264.nalus_length = 1;
// Complete and decodable since the pps and sps are received in the first
// packet of this frame.
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
VCMEncodedFrame* frame_out = DecodeCompleteFrame();
ASSERT_NE(nullptr, frame_out);
jitter_buffer_->ReleaseFrame(frame_out);
timestamp_ += 3000;
packet_->timestamp = timestamp_;
++seq_num_;
packet_->seqNum = seq_num_;
packet_->frameType = kVideoFrameDelta;
packet_->isFirstPacket = true;
packet_->markerBit = true;
packet_->codec = kVideoCodecH264;
packet_->video_header.codec = kRtpVideoH264;
packet_->video_header.codecHeader.H264.nalu_type = H264::NaluType::kSlice;
packet_->video_header.codecHeader.H264.nalus[0].type = H264::NaluType::kSlice;
packet_->video_header.codecHeader.H264.nalus[0].sps_id = -1;
packet_->video_header.codecHeader.H264.nalus[0].pps_id = 0;
packet_->video_header.codecHeader.H264.nalus_length = 1;
// Complete and decodable since sps, pps and key frame has been received.
EXPECT_EQ(kCompleteSession,
jitter_buffer_->InsertPacket(*packet_, &retransmitted));
frame_out = DecodeCompleteFrame();
ASSERT_NE(nullptr, frame_out);
jitter_buffer_->ReleaseFrame(frame_out);
}
// Test threshold conditions of decodable state.
TEST_F(TestBasicJitterBuffer, PacketLossWithSelectiveErrorsThresholdCheck) {
jitter_buffer_->SetDecodeErrorMode(kSelectiveErrors);
@ -2633,5 +2718,4 @@ TEST_F(TestJitterBufferNack, ResetByFutureKeyFrameDoesntError) {
nack_list = jitter_buffer_->GetNackList(&extended);
EXPECT_EQ(0u, nack_list.size());
}
} // namespace webrtc