diff --git a/api/frame_transformer_interface.h b/api/frame_transformer_interface.h index 40d2f3655e..9024988db6 100644 --- a/api/frame_transformer_interface.h +++ b/api/frame_transformer_interface.h @@ -12,6 +12,7 @@ #define API_FRAME_TRANSFORMER_INTERFACE_H_ #include +#include #include #include "api/scoped_refptr.h" @@ -53,6 +54,11 @@ class TransformableFrameInterface { // sender frames to allow received frames to be directly re-transmitted on // other PeerConnectionss. virtual Direction GetDirection() const { return Direction::kUnknown; } + virtual std::string GetMimeType() const { + // TODO(bugs.webrtc.org/15579): Change this to pure virtual after it + // is implemented everywhere. + return "unknown/unknown"; + } }; class TransformableVideoFrameInterface : public TransformableFrameInterface { diff --git a/api/test/mock_transformable_video_frame.h b/api/test/mock_transformable_video_frame.h index 21c4dc2b69..b3825ddf48 100644 --- a/api/test/mock_transformable_video_frame.h +++ b/api/test/mock_transformable_video_frame.h @@ -11,6 +11,7 @@ #ifndef API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_ #define API_TEST_MOCK_TRANSFORMABLE_VIDEO_FRAME_H_ +#include #include #include "api/frame_transformer_interface.h" @@ -36,6 +37,7 @@ class MockTransformableVideoFrame GetDirection, (), (const, override)); + MOCK_METHOD(std::string, GetMimeType, (), (const, override)); MOCK_METHOD(VideoFrameMetadata, Metadata, (), (const, override)); MOCK_METHOD(absl::optional, GetCaptureTimeIdentifier, diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc index 2281a2ae27..d255ef4aa9 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc @@ -10,6 +10,7 @@ #include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h" +#include #include #include @@ -97,6 +98,13 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { } Direction GetDirection() const override { return Direction::kSender; } + std::string GetMimeType() const override { + if (!codec_type_.has_value()) { + return "video/x-unknown"; + } + std::string mime_type = "video/"; + return mime_type + CodecTypeToPayloadString(*codec_type_); + } private: rtc::scoped_refptr encoded_data_; diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc index 54cfdbadd7..a376be77b4 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc @@ -74,9 +74,15 @@ class RtpSenderVideoFrameTransformerDelegateTest : public ::testing::Test { frame_to_transform) { frame = std::move(frame_to_transform); }); + RTPVideoHeader rtp_header; + + VideoFrameMetadata metadata; + metadata.SetCodec(VideoCodecType::kVideoCodecVP8); + metadata.SetRTPVideoHeaderCodecSpecifics(RTPVideoHeaderVP8()); + delegate->TransformFrame( /*payload_type=*/1, VideoCodecType::kVideoCodecVP8, /*rtp_timestamp=*/2, - encoded_image, RTPVideoHeader(), + encoded_image, RTPVideoHeader::FromMetadata(metadata), /*expected_retransmission_time=*/TimeDelta::PlusInfinity()); return frame; } @@ -135,6 +141,7 @@ TEST_F(RtpSenderVideoFrameTransformerDelegateTest, std::unique_ptr frame = GetTransformableFrame(delegate); ASSERT_TRUE(frame); + EXPECT_STRCASEEQ("video/VP8", frame->GetMimeType().c_str()); rtc::Event event; EXPECT_CALL(test_sender_, SendVideo).WillOnce(WithoutArgs([&] { @@ -162,6 +169,7 @@ TEST_F(RtpSenderVideoFrameTransformerDelegateTest, CloneSenderVideoFrame) { EXPECT_EQ(clone->IsKeyFrame(), video_frame.IsKeyFrame()); EXPECT_EQ(clone->GetPayloadType(), video_frame.GetPayloadType()); + EXPECT_EQ(clone->GetMimeType(), video_frame.GetMimeType()); EXPECT_EQ(clone->GetSsrc(), video_frame.GetSsrc()); EXPECT_EQ(clone->GetTimestamp(), video_frame.GetTimestamp()); EXPECT_EQ(clone->Metadata(), video_frame.Metadata()); @@ -182,6 +190,7 @@ TEST_F(RtpSenderVideoFrameTransformerDelegateTest, CloneKeyFrame) { EXPECT_EQ(clone->IsKeyFrame(), video_frame.IsKeyFrame()); EXPECT_EQ(clone->GetPayloadType(), video_frame.GetPayloadType()); + EXPECT_EQ(clone->GetMimeType(), video_frame.GetMimeType()); EXPECT_EQ(clone->GetSsrc(), video_frame.GetSsrc()); EXPECT_EQ(clone->GetTimestamp(), video_frame.GetTimestamp()); EXPECT_EQ(clone->Metadata(), video_frame.Metadata()); diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc index 1b3cb7d9ab..ddbd22e34a 100644 --- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc @@ -10,6 +10,7 @@ #include "modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.h" +#include #include #include @@ -75,6 +76,10 @@ class TransformableVideoReceiverFrame } Direction GetDirection() const override { return Direction::kReceiver; } + std::string GetMimeType() const override { + std::string mime_type = "video/"; + return mime_type + CodecTypeToPayloadString(frame_->codec_type()); + } const RtpVideoFrameReceiver* Receiver() { return receiver_; } diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc index bbc1b62b5e..f403c91a74 100644 --- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc @@ -138,6 +138,7 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, ON_CALL(*mock_frame_transformer, Transform) .WillByDefault( [&callback](std::unique_ptr frame) { + EXPECT_STRCASEEQ("video/Generic", frame->GetMimeType().c_str()); callback->OnTransformedFrame(std::move(frame)); }); delegate->TransformFrame(CreateRtpFrameObject(RTPVideoHeader(), csrcs)); diff --git a/test/mock_transformable_frame.h b/test/mock_transformable_frame.h index 17d7e834f9..26eb6b7030 100644 --- a/test/mock_transformable_frame.h +++ b/test/mock_transformable_frame.h @@ -33,6 +33,7 @@ class MockTransformableAudioFrame : public TransformableAudioFrameInterface { MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override)); MOCK_METHOD(void, SetRTPTimestamp, (uint32_t), (override)); MOCK_METHOD(Direction, GetDirection, (), (const, override)); + MOCK_METHOD(std::string, GetMimeType, (), (const, override)); }; } // namespace webrtc