diff --git a/api/video/BUILD.gn b/api/video/BUILD.gn index 0424b55805..8df3018f1b 100644 --- a/api/video/BUILD.gn +++ b/api/video/BUILD.gn @@ -337,12 +337,14 @@ rtc_source_set("video_frame_metadata") { ":video_frame_type", ":video_rtp_headers", "..:array_view", + "../../modules/video_coding:codec_globals_headers", "../../rtc_base/system:rtc_export", "../transport/rtp:dependency_descriptor", ] absl_deps = [ "//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/types:optional", + "//third_party/abseil-cpp/absl/types:variant", ] } diff --git a/api/video/DEPS b/api/video/DEPS index deca998c7c..d1d39121b4 100644 --- a/api/video/DEPS +++ b/api/video/DEPS @@ -45,6 +45,12 @@ specific_include_rules = { "+rtc_base/ref_count.h", ], + "video_frame_metadata\.h": [ + "+modules/video_coding/codecs/h264/include/h264_globals.h", + "+modules/video_coding/codecs/vp8/include/vp8_globals.h", + "+modules/video_coding/codecs/vp9/include/vp9_globals.h", + ], + "video_stream_decoder_create.cc": [ "+video/video_stream_decoder_impl.h", ], diff --git a/api/video/video_frame_metadata.cc b/api/video/video_frame_metadata.cc index 842aeb0524..e1863e9c13 100644 --- a/api/video/video_frame_metadata.cc +++ b/api/video/video_frame_metadata.cc @@ -10,6 +10,8 @@ #include "api/video/video_frame_metadata.h" +#include + namespace webrtc { VideoFrameMetadata::VideoFrameMetadata() = default; @@ -124,4 +126,14 @@ void VideoFrameMetadata::SetCodec(VideoCodecType codec) { codec_ = codec; } +const RTPVideoHeaderCodecSpecifics& +VideoFrameMetadata::GetRTPVideoHeaderCodecSpecifics() const { + return codec_specifics_; +} + +void VideoFrameMetadata::SetRTPVideoHeaderCodecSpecifics( + RTPVideoHeaderCodecSpecifics codec_specifics) { + codec_specifics_ = std::move(codec_specifics); +} + } // namespace webrtc diff --git a/api/video/video_frame_metadata.h b/api/video/video_frame_metadata.h index 6e3f32fdbf..2703f11324 100644 --- a/api/video/video_frame_metadata.h +++ b/api/video/video_frame_metadata.h @@ -15,16 +15,25 @@ #include "absl/container/inlined_vector.h" #include "absl/types/optional.h" +#include "absl/types/variant.h" #include "api/array_view.h" #include "api/transport/rtp/dependency_descriptor.h" #include "api/video/video_codec_type.h" #include "api/video/video_content_type.h" #include "api/video/video_frame_type.h" #include "api/video/video_rotation.h" +#include "modules/video_coding/codecs/h264/include/h264_globals.h" +#include "modules/video_coding/codecs/vp8/include/vp8_globals.h" +#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { +using RTPVideoHeaderCodecSpecifics = absl::variant; + // A subset of metadata from the RTP video header, exposed in insertable streams // API. class RTC_EXPORT VideoFrameMetadata { @@ -74,6 +83,11 @@ class RTC_EXPORT VideoFrameMetadata { VideoCodecType GetCodec() const; void SetCodec(VideoCodecType codec); + // Which varient is used depends on the VideoCodecType from GetCodecs(). + const RTPVideoHeaderCodecSpecifics& GetRTPVideoHeaderCodecSpecifics() const; + void SetRTPVideoHeaderCodecSpecifics( + RTPVideoHeaderCodecSpecifics codec_specifics); + private: VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame; int16_t width_ = 0; @@ -91,6 +105,7 @@ class RTC_EXPORT VideoFrameMetadata { bool is_last_frame_in_picture_ = true; uint8_t simulcast_idx_ = 0; VideoCodecType codec_ = VideoCodecType::kVideoCodecGeneric; + RTPVideoHeaderCodecSpecifics codec_specifics_; }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_video_header.cc b/modules/rtp_rtcp/source/rtp_video_header.cc index 1da43eec2d..8351c8c2ab 100644 --- a/modules/rtp_rtcp/source/rtp_video_header.cc +++ b/modules/rtp_rtcp/source/rtp_video_header.cc @@ -38,6 +38,23 @@ VideoFrameMetadata RTPVideoHeader::GetAsMetadata() const { metadata.SetIsLastFrameInPicture(is_last_frame_in_picture); metadata.SetSimulcastIdx(simulcastIdx); metadata.SetCodec(codec); + switch (codec) { + case VideoCodecType::kVideoCodecVP8: + metadata.SetRTPVideoHeaderCodecSpecifics( + absl::get(video_type_header)); + break; + case VideoCodecType::kVideoCodecVP9: + metadata.SetRTPVideoHeaderCodecSpecifics( + absl::get(video_type_header)); + break; + case VideoCodecType::kVideoCodecH264: + metadata.SetRTPVideoHeaderCodecSpecifics( + absl::get(video_type_header)); + break; + default: + // Codec-specifics are not supported for this codec. + break; + } return metadata; } diff --git a/modules/rtp_rtcp/source/rtp_video_header_unittest.cc b/modules/rtp_rtcp/source/rtp_video_header_unittest.cc index c8439e1796..e6e5b48cc5 100644 --- a/modules/rtp_rtcp/source/rtp_video_header_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_video_header_unittest.cc @@ -158,9 +158,49 @@ TEST(RTPVideoHeaderTest, GetAsMetadataGetSimulcastIdx) { TEST(RTPVideoHeaderTest, GetAsMetadataGetCodec) { RTPVideoHeader video_header; video_header.codec = VideoCodecType::kVideoCodecVP9; + video_header.video_type_header = RTPVideoHeaderVP9(); VideoFrameMetadata metadata = video_header.GetAsMetadata(); EXPECT_EQ(metadata.GetCodec(), VideoCodecType::kVideoCodecVP9); } +TEST(RTPVideoHeaderTest, GetAsMetadataGetRTPVideoHeaderCodecSpecifics) { + RTPVideoHeader video_header; + { + video_header.codec = VideoCodecType::kVideoCodecVP8; + RTPVideoHeaderVP8 vp8_specifics; + vp8_specifics.InitRTPVideoHeaderVP8(); + vp8_specifics.pictureId = 42; + video_header.video_type_header = vp8_specifics; + VideoFrameMetadata metadata = video_header.GetAsMetadata(); + EXPECT_EQ( + absl::get(metadata.GetRTPVideoHeaderCodecSpecifics()) + .pictureId, + vp8_specifics.pictureId); + } + { + video_header.codec = VideoCodecType::kVideoCodecVP9; + RTPVideoHeaderVP9 vp9_specifics; + vp9_specifics.InitRTPVideoHeaderVP9(); + vp9_specifics.max_picture_id = 42; + video_header.video_type_header = vp9_specifics; + VideoFrameMetadata metadata = video_header.GetAsMetadata(); + EXPECT_EQ( + absl::get(metadata.GetRTPVideoHeaderCodecSpecifics()) + .max_picture_id, + vp9_specifics.max_picture_id); + } + { + video_header.codec = VideoCodecType::kVideoCodecH264; + RTPVideoHeaderH264 h264_specifics; + h264_specifics.nalu_type = 42; + video_header.video_type_header = h264_specifics; + VideoFrameMetadata metadata = video_header.GetAsMetadata(); + EXPECT_EQ(absl::get( + metadata.GetRTPVideoHeaderCodecSpecifics()) + .nalu_type, + h264_specifics.nalu_type); + } +} + } // namespace } // namespace webrtc