Reland "h264: fix first_packet_in_frame logic for multislice in a single rtp packet"
This reverts commit bdc669347c70160cd648f5cab7a417227d41d82a. Reason for revert: AUDs will be taken into account now. video_replay with the provided out.pcap and these options: --codec H264 --input_file out.pcap --media_payload_type 102 --ssrc 40000 plays smoothly. Original change's description: > Revert "h264: fix first_packet_in_frame logic for multislice in a single rtp packet" > > This reverts commit 3753c8190e3f0aca6758a5521e33f8b5d4f09ab4. > > Reason for revert: Break assembling of hardware encoded h264 P frame on > weak network condition. > > Original change's description: > > h264: fix first_packet_in_frame logic for multislice in a single rtp packet > > > > a frame must be (or should be) first when it contains either SPS (but not just PPS), > > is an IDR or is a slice with first_mb_in_slice == 0. > > > > Fixes an edge case where a STAP-A with SPS, PPS and multiple slices of an IDR fit > > into a single RTP packet which can happen with small 320x196 frames > > > > BUG=webrtc:352379280,webrtc:346608838 > > > > Change-Id: Ic6dea6c81db759d0d7ddd4054407103fd791f6c5 > > No-Try: true > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/357121 > > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> > > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > > Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> > > Cr-Commit-Position: refs/heads/main@{#42652} > > Bug: webrtc:368335257 > Change-Id: I07725c78be628bff71b79b8b9369677e39f5f5ac > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/363080 > Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> > Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> > Reviewed-by: Philipp Hancke <phancke@meta.com> > Cr-Commit-Position: refs/heads/main@{#43062} Bug: webrtc:368335257 Change-Id: Idfae2efc1ebd7b97a2f7ebbd9d1e8c7bf6fcc348 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/363842 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Philipp Hancke <phancke@meta.com> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43113}
This commit is contained in:
parent
4773539f90
commit
949d3c9acf
@ -70,7 +70,7 @@ std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
|
||||
parsed_payload->video_header.height = 0;
|
||||
parsed_payload->video_header.codec = kVideoCodecH264;
|
||||
parsed_payload->video_header.simulcastIdx = 0;
|
||||
parsed_payload->video_header.is_first_packet_in_frame = true;
|
||||
parsed_payload->video_header.is_first_packet_in_frame = false;
|
||||
auto& h264_header = parsed_payload->video_header.video_type_header
|
||||
.emplace<RTPVideoHeaderH264>();
|
||||
|
||||
@ -121,8 +121,7 @@ std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
|
||||
switch (nalu.type) {
|
||||
case H264::NaluType::kSps: {
|
||||
// Check if VUI is present in SPS and if it needs to be modified to
|
||||
// avoid
|
||||
// excessive decoder latency.
|
||||
// avoid excessive decoder latency.
|
||||
|
||||
// Copy any previous data first (likely just the first header).
|
||||
rtc::Buffer output_buffer;
|
||||
@ -175,6 +174,7 @@ std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
|
||||
VideoFrameType::kVideoFrameKey;
|
||||
break;
|
||||
}
|
||||
parsed_payload->video_header.is_first_packet_in_frame = true;
|
||||
break;
|
||||
}
|
||||
case H264::NaluType::kPps: {
|
||||
@ -199,8 +199,9 @@ std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
|
||||
PpsParser::ParseSliceHeader(nalu_data);
|
||||
if (slice_header) {
|
||||
nalu.pps_id = slice_header->pic_parameter_set_id;
|
||||
parsed_payload->video_header.is_first_packet_in_frame &=
|
||||
slice_header->first_mb_in_slice == 0;
|
||||
if (slice_header->first_mb_in_slice == 0) {
|
||||
parsed_payload->video_header.is_first_packet_in_frame = true;
|
||||
}
|
||||
} else {
|
||||
RTC_LOG(LS_WARNING) << "Failed to parse PPS id from slice of type: "
|
||||
<< static_cast<int>(nalu.type);
|
||||
@ -208,8 +209,10 @@ std::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Slices below don't contain SPS or PPS ids.
|
||||
case H264::NaluType::kAud:
|
||||
parsed_payload->video_header.is_first_packet_in_frame = true;
|
||||
break;
|
||||
// Slices below don't contain SPS or PPS ids.
|
||||
case H264::NaluType::kEndOfSequence:
|
||||
case H264::NaluType::kEndOfStream:
|
||||
case H264::NaluType::kFiller:
|
||||
|
||||
@ -439,5 +439,83 @@ TEST(VideoRtpDepacketizerH264Test, BadSlice) {
|
||||
EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
|
||||
}
|
||||
|
||||
TEST(VideoRtpDepacketizerH264Test, StapASpsPpsMultiSlice) {
|
||||
// A STAP-A containing a black 320x192 key frame with multiple slices.
|
||||
const uint8_t kPayload[] = {
|
||||
// clang-format off
|
||||
0x67, 0x42, 0xc0, 0x15, 0x8c, 0x68, 0x14, 0x19, // STAP-A, SPS.
|
||||
0x79, 0xe0, 0x1e, 0x11, 0x08, 0xd4, 0x00, 0x04, 0x68, 0xce, 0x3c, 0x80,
|
||||
0x00, 0x2e, // PPS.
|
||||
// Slices.
|
||||
0x65, 0xb8, 0x00, 0x04, 0x08, 0x79, 0x31, 0x40, 0x00, 0x42, 0xae, 0x4d,
|
||||
0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9,
|
||||
0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xd6, 0xeb, 0xae, 0xba, 0xeb, 0xae,
|
||||
0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xbc, 0x00, 0x2f,
|
||||
0x65, 0x05, 0x2e, 0x00, 0x01, 0x02, 0x1e, 0x4c, 0x50, 0x00, 0x10, 0xab,
|
||||
0x93, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x75, 0xba, 0xeb, 0xae, 0xba,
|
||||
0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xaf, 0x00,
|
||||
0x30, 0x65, 0x02, 0x8b, 0x80, 0x00, 0x40, 0x87, 0x93, 0x14, 0x00, 0x04,
|
||||
0x2a, 0xe4, 0xdc, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
|
||||
0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x6e, 0xba, 0xeb,
|
||||
0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb,
|
||||
0xc0, 0x00, 0x30, 0x65, 0x03, 0xcb, 0x80, 0x00, 0x40, 0x87, 0x93, 0x14,
|
||||
0x00, 0x04, 0x2a, 0xe4, 0xdc, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
|
||||
0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x6e,
|
||||
0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae,
|
||||
0xba, 0xeb, 0xc0, 0x00, 0x30, 0x65, 0x01, 0x42, 0xe0, 0x00, 0x10, 0x21,
|
||||
0xe4, 0xc5, 0x00, 0x01, 0x0a, 0xb9, 0x37, 0x27, 0x27, 0x27, 0x27, 0x27,
|
||||
0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
|
||||
0x27, 0x5b, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae,
|
||||
0xba, 0xeb, 0xae, 0xba, 0xf0, 0x00, 0x30, 0x65, 0x01, 0x92, 0xe0, 0x00,
|
||||
0x10, 0x21, 0xe4, 0xc5, 0x00, 0x01, 0x0a, 0xb9, 0x37, 0x27, 0x27, 0x27,
|
||||
0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
|
||||
0x27, 0x27, 0x27, 0x5b, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba,
|
||||
0xeb, 0xae, 0xba, 0xeb, 0xae, 0xba, 0xf0
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
VideoRtpDepacketizerH264 depacketizer;
|
||||
std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
|
||||
ASSERT_TRUE(parsed);
|
||||
EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
|
||||
}
|
||||
|
||||
TEST(VideoRtpDepacketizerH264Test, SecondSliceIdrNalu) {
|
||||
// First few bytes of a second slice of an IDR nalu with
|
||||
// first_mb_in_slice = 480.
|
||||
const uint8_t kPayload[] = {
|
||||
// clang-format off
|
||||
0x65, 0x00, 0xf0, 0x88, 0x82, 0x01, 0x3b, 0xff, 0xdf, 0xfe, 0x0b, 0xbb,
|
||||
0xfc, 0xb4, 0x30, 0xd1, 0x00, 0xef, 0xfd, 0xef, 0x0e, 0x79, 0x8b, 0x74,
|
||||
0x9b, 0x44, 0xf3, 0xb8, 0x65, 0x8f, 0xa1, 0x92, 0x30, 0xf9, 0x40, 0x06,
|
||||
0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x03, 0x00, 0x18, 0x87, 0x4f, 0x6a, 0xfe, 0x60, 0x03, 0x9f, 0xfe, 0xd8,
|
||||
0x8b, 0xa6, 0x67, 0x31
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
VideoRtpDepacketizerH264 depacketizer;
|
||||
std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
|
||||
ASSERT_TRUE(parsed);
|
||||
EXPECT_FALSE(parsed->video_header.is_first_packet_in_frame);
|
||||
}
|
||||
|
||||
TEST(VideoRtpDepacketizerH264Test, AudSetsFirstPacketInFrame) {
|
||||
const uint8_t kPayload[] = {
|
||||
// clang-format off
|
||||
0x09, 0x10 // AUD.
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
VideoRtpDepacketizerH264 depacketizer;
|
||||
std::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
|
||||
ASSERT_TRUE(parsed);
|
||||
EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user