Add VideoRtpDepacketizerGeneric
Bug: webrtc:11152 Change-Id: I27d6a62093d36a4e77dd35d4c115af8cdcc0178a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/162202 Reviewed-by: Markus Handell <handellm@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30160}
This commit is contained in:
parent
dc7fe40f49
commit
27f4d325ad
@ -213,6 +213,8 @@ rtc_library("rtp_rtcp") {
|
||||
"source/ulpfec_receiver_impl.cc",
|
||||
"source/ulpfec_receiver_impl.h",
|
||||
"source/video_rtp_depacketizer.h",
|
||||
"source/video_rtp_depacketizer_generic.cc",
|
||||
"source/video_rtp_depacketizer_generic.h",
|
||||
"source/video_rtp_depacketizer_raw.cc",
|
||||
"source/video_rtp_depacketizer_raw.h",
|
||||
"source/video_rtp_depacketizer_vp8.cc",
|
||||
@ -483,6 +485,7 @@ if (rtc_include_tests) {
|
||||
"source/ulpfec_generator_unittest.cc",
|
||||
"source/ulpfec_header_reader_writer_unittest.cc",
|
||||
"source/ulpfec_receiver_unittest.cc",
|
||||
"source/video_rtp_depacketizer_generic_unittest.cc",
|
||||
"source/video_rtp_depacketizer_raw_unittest.cc",
|
||||
"source/video_rtp_depacketizer_vp8_unittest.cc",
|
||||
"source/video_rtp_depacketizer_vp9_unittest.cc",
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "absl/types/optional.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_format.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"
|
||||
#include "rtc_base/checks.h"
|
||||
@ -56,15 +57,18 @@ class LegacyRtpDepacketizer : public VideoRtpDepacketizer {
|
||||
|
||||
std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
|
||||
VideoCodecType codec) {
|
||||
// TODO(bugs.webrtc.org/11152): switch on codec and create specialized
|
||||
// VideoRtpDepacketizers when they are migrated to new interface.
|
||||
switch (codec) {
|
||||
case kVideoCodecH264:
|
||||
return std::make_unique<LegacyRtpDepacketizer>(codec);
|
||||
case kVideoCodecVP8:
|
||||
return std::make_unique<VideoRtpDepacketizerVp8>();
|
||||
case kVideoCodecVP9:
|
||||
return std::make_unique<VideoRtpDepacketizerVp9>();
|
||||
default:
|
||||
case kVideoCodecAV1:
|
||||
return std::make_unique<LegacyRtpDepacketizer>(codec);
|
||||
case kVideoCodecGeneric:
|
||||
case kVideoCodecMultiplex:
|
||||
return std::make_unique<VideoRtpDepacketizerGeneric>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
72
modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc
Normal file
72
modules/rtp_rtcp/source/video_rtp_depacketizer_generic.cc
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_video_header.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
|
||||
#include "rtc_base/copy_on_write_buffer.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
constexpr uint8_t kKeyFrameBit = 0b0000'0001;
|
||||
constexpr uint8_t kFirstPacketBit = 0b0000'0010;
|
||||
// If this bit is set, there will be an extended header contained in this
|
||||
// packet. This was added later so old clients will not send this.
|
||||
constexpr uint8_t kExtendedHeaderBit = 0b0000'0100;
|
||||
|
||||
constexpr size_t kGenericHeaderLength = 1;
|
||||
constexpr size_t kExtendedHeaderLength = 2;
|
||||
} // namespace
|
||||
|
||||
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
|
||||
VideoRtpDepacketizerGeneric::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
|
||||
if (rtp_payload.size() == 0) {
|
||||
RTC_LOG(LS_WARNING) << "Empty payload.";
|
||||
return absl::nullopt;
|
||||
}
|
||||
absl::optional<ParsedRtpPayload> parsed(absl::in_place);
|
||||
const uint8_t* payload_data = rtp_payload.cdata();
|
||||
|
||||
uint8_t generic_header = payload_data[0];
|
||||
size_t offset = kGenericHeaderLength;
|
||||
|
||||
parsed->video_header.frame_type = (generic_header & kKeyFrameBit)
|
||||
? VideoFrameType::kVideoFrameKey
|
||||
: VideoFrameType::kVideoFrameDelta;
|
||||
parsed->video_header.is_first_packet_in_frame =
|
||||
(generic_header & kFirstPacketBit) != 0;
|
||||
parsed->video_header.codec = kVideoCodecGeneric;
|
||||
parsed->video_header.width = 0;
|
||||
parsed->video_header.height = 0;
|
||||
|
||||
if (generic_header & kExtendedHeaderBit) {
|
||||
if (rtp_payload.size() < offset + kExtendedHeaderLength) {
|
||||
RTC_LOG(LS_WARNING) << "Too short payload for generic header.";
|
||||
return absl::nullopt;
|
||||
}
|
||||
parsed->video_header.generic.emplace();
|
||||
parsed->video_header.generic->frame_id =
|
||||
((payload_data[1] & 0x7F) << 8) | payload_data[2];
|
||||
offset += kExtendedHeaderLength;
|
||||
}
|
||||
|
||||
parsed->video_payload =
|
||||
rtp_payload.Slice(offset, rtp_payload.size() - offset);
|
||||
return parsed;
|
||||
}
|
||||
} // namespace webrtc
|
||||
30
modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h
Normal file
30
modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_GENERIC_H_
|
||||
#define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_GENERIC_H_
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
|
||||
#include "rtc_base/copy_on_write_buffer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class VideoRtpDepacketizerGeneric : public VideoRtpDepacketizer {
|
||||
public:
|
||||
~VideoRtpDepacketizerGeneric() override = default;
|
||||
|
||||
absl::optional<ParsedRtpPayload> Parse(
|
||||
rtc::CopyOnWriteBuffer rtp_payload) override;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_GENERIC_H_
|
||||
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "rtc_base/copy_on_write_buffer.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
using ::testing::SizeIs;
|
||||
|
||||
TEST(VideoRtpDepacketizerGeneric, NonExtendedHeaderNoFrameId) {
|
||||
const size_t kRtpPayloadSize = 10;
|
||||
const uint8_t kPayload[kRtpPayloadSize] = {0x01};
|
||||
rtc::CopyOnWriteBuffer rtp_payload(kPayload);
|
||||
|
||||
VideoRtpDepacketizerGeneric depacketizer;
|
||||
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtp_payload);
|
||||
|
||||
ASSERT_TRUE(parsed);
|
||||
EXPECT_EQ(parsed->video_header.generic, absl::nullopt);
|
||||
EXPECT_THAT(parsed->video_payload, SizeIs(kRtpPayloadSize - 1));
|
||||
}
|
||||
|
||||
TEST(VideoRtpDepacketizerGeneric, ExtendedHeaderParsesFrameId) {
|
||||
const size_t kRtpPayloadSize = 10;
|
||||
const uint8_t kPayload[kRtpPayloadSize] = {0x05, 0x13, 0x37};
|
||||
rtc::CopyOnWriteBuffer rtp_payload(kPayload);
|
||||
|
||||
VideoRtpDepacketizerGeneric depacketizer;
|
||||
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtp_payload);
|
||||
|
||||
ASSERT_TRUE(parsed);
|
||||
ASSERT_TRUE(parsed->video_header.generic);
|
||||
EXPECT_EQ(parsed->video_header.generic->frame_id, 0x1337);
|
||||
EXPECT_THAT(parsed->video_payload, SizeIs(kRtpPayloadSize - 3));
|
||||
}
|
||||
|
||||
TEST(VideoRtpDepacketizerGeneric, PassRtpPayloadAsVideoPayload) {
|
||||
const uint8_t kPayload[] = {0x01, 0x25, 0x52};
|
||||
rtc::CopyOnWriteBuffer rtp_payload(kPayload);
|
||||
|
||||
VideoRtpDepacketizerGeneric depacketizer;
|
||||
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
|
||||
depacketizer.Parse(rtp_payload);
|
||||
|
||||
ASSERT_TRUE(parsed);
|
||||
// Check there was no memcpy involved by verifying return and original buffers
|
||||
// point to the same buffer.
|
||||
EXPECT_EQ(parsed->video_payload.cdata(), rtp_payload.cdata() + 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user