Add CVO support to Vie layer.
1. standard plumbing CVO through vie layer. 2. added a rtp_cvo.h which has both conversion functions from rtp header byte to/from VideoRotation. WebRTCVideoEngine will later pass the rotation info in SendFrame() through VieVideoFrameI420. BUG=4145 R=mflodman@webrtc.org, tommi@webrtc.org Review URL: https://webrtc-codereview.appspot.com/46429007 Cr-Commit-Position: refs/heads/master@{#8703} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8703 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
4f85288e71
commit
fdd1057949
@ -109,6 +109,11 @@ const int kRtpAbsoluteSenderTimeHeaderExtensionDefaultId = 3;
|
||||
const char kRtpAbsoluteSenderTimeHeaderExtension[] =
|
||||
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
|
||||
|
||||
const int kRtpVideoRotationHeaderExtensionDefaultId = 4;
|
||||
const char kRtpVideoRotationHeaderExtension[] = "urn:3gpp:video-orientation";
|
||||
const char kRtpVideoRotation6BitsHeaderExtensionForTesting[] =
|
||||
"urn:3gpp:video-orientation:6";
|
||||
|
||||
const int kNumDefaultUnsignalledVideoRecvStreams = 0;
|
||||
|
||||
|
||||
|
||||
@ -121,21 +121,29 @@ extern const char kGoogleSctpDataCodecName[];
|
||||
|
||||
extern const char kComfortNoiseCodecName[];
|
||||
|
||||
// Extension header for audio levels, as defined in
|
||||
// Header extension for audio levels, as defined in
|
||||
// http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
|
||||
extern const int kRtpAudioLevelHeaderExtensionDefaultId;
|
||||
extern const char kRtpAudioLevelHeaderExtension[];
|
||||
|
||||
// Extension header for RTP timestamp offset, see RFC 5450 for details:
|
||||
// Header extension for RTP timestamp offset, see RFC 5450 for details:
|
||||
// http://tools.ietf.org/html/rfc5450
|
||||
extern const int kRtpTimestampOffsetHeaderExtensionDefaultId;
|
||||
extern const char kRtpTimestampOffsetHeaderExtension[];
|
||||
|
||||
// Extension header for absolute send time, see url for details:
|
||||
// Header extension for absolute send time, see url for details:
|
||||
// http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||
extern const int kRtpAbsoluteSenderTimeHeaderExtensionDefaultId;
|
||||
extern const char kRtpAbsoluteSenderTimeHeaderExtension[];
|
||||
|
||||
// Header extension for coordination of video orientation, see url for details:
|
||||
// http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/
|
||||
// ts_126114v120700p.pdf
|
||||
extern const int kRtpVideoRotationHeaderExtensionDefaultId;
|
||||
extern const char kRtpVideoRotationHeaderExtension[];
|
||||
// We don't support 6 bit CVO. Added here for testing purpose.
|
||||
extern const char kRtpVideoRotation6BitsHeaderExtensionForTesting[];
|
||||
|
||||
extern const int kNumDefaultUnsignalledVideoRecvStreams;
|
||||
} // namespace cricket
|
||||
|
||||
|
||||
@ -285,6 +285,8 @@ class FakeWebRtcVideoEngine
|
||||
rtp_offset_receive_id_(-1),
|
||||
rtp_absolute_send_time_send_id_(-1),
|
||||
rtp_absolute_send_time_receive_id_(-1),
|
||||
rtp_video_rotation_send_id_(-1),
|
||||
rtp_video_rotation_receive_id_(-1),
|
||||
sender_target_delay_(0),
|
||||
receiver_target_delay_(0),
|
||||
transmission_smoothing_(false),
|
||||
@ -325,6 +327,8 @@ class FakeWebRtcVideoEngine
|
||||
int rtp_offset_receive_id_;
|
||||
int rtp_absolute_send_time_send_id_;
|
||||
int rtp_absolute_send_time_receive_id_;
|
||||
int rtp_video_rotation_send_id_;
|
||||
int rtp_video_rotation_receive_id_;
|
||||
int sender_target_delay_;
|
||||
int receiver_target_delay_;
|
||||
bool transmission_smoothing_;
|
||||
@ -503,6 +507,8 @@ class FakeWebRtcVideoEngine
|
||||
return channels_.find(channel)->second->rtp_offset_send_id_;
|
||||
} else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
|
||||
return channels_.find(channel)->second->rtp_absolute_send_time_send_id_;
|
||||
} else if (extension == kRtpVideoRotationHeaderExtension) {
|
||||
return channels_.find(channel)->second->rtp_video_rotation_send_id_;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -513,6 +519,8 @@ class FakeWebRtcVideoEngine
|
||||
} else if (extension == kRtpAbsoluteSenderTimeHeaderExtension) {
|
||||
return
|
||||
channels_.find(channel)->second->rtp_absolute_send_time_receive_id_;
|
||||
} else if (extension == kRtpVideoRotationHeaderExtension) {
|
||||
return channels_.find(channel)->second->rtp_video_rotation_receive_id_;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -1107,25 +1115,36 @@ class FakeWebRtcVideoEngine
|
||||
WEBRTC_FUNC(SetSendTimestampOffsetStatus, (int channel, bool enable,
|
||||
int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_offset_send_id_ = (enable) ? id : -1;
|
||||
channels_[channel]->rtp_offset_send_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_FUNC(SetReceiveTimestampOffsetStatus, (int channel, bool enable,
|
||||
int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_offset_receive_id_ = (enable) ? id : -1;
|
||||
channels_[channel]->rtp_offset_receive_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_FUNC(SetSendAbsoluteSendTimeStatus, (int channel, bool enable,
|
||||
int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_absolute_send_time_send_id_ = (enable) ? id : -1;
|
||||
channels_[channel]->rtp_absolute_send_time_send_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_FUNC(SetReceiveAbsoluteSendTimeStatus, (int channel, bool enable,
|
||||
int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_absolute_send_time_receive_id_ = (enable) ? id : -1;
|
||||
channels_[channel]->rtp_absolute_send_time_receive_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_FUNC(SetSendVideoRotationStatus, (int channel, bool enable, int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_video_rotation_send_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_FUNC(SetReceiveVideoRotationStatus,
|
||||
(int channel, bool enable, int id)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtp_video_rotation_receive_id_ = enable? id : -1;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_STUB(SetRtcpXrRrtrStatus, (int, bool));
|
||||
|
||||
@ -51,6 +51,7 @@ struct RtpExtension {
|
||||
|
||||
static const char* kTOffset;
|
||||
static const char* kAbsSendTime;
|
||||
static const char* kVideoRotation;
|
||||
std::string name;
|
||||
int id;
|
||||
};
|
||||
|
||||
54
webrtc/modules/rtp_rtcp/interface/rtp_cvo.h
Normal file
54
webrtc/modules/rtp_rtcp/interface/rtp_cvo.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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 WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_CVO__H_
|
||||
#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_CVO__H_
|
||||
|
||||
#include "webrtc/common_video/rotation.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Please refer to http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/
|
||||
// 12.07.00_60/ts_126114v120700p.pdf Section 7.4.5. The rotation of a frame is
|
||||
// the clockwise angle the frames must be rotated in order to display the frames
|
||||
// correctly if the display is rotated in its natural orientation.
|
||||
inline uint8_t ConvertVideoRotationToCVOByte(VideoRotation rotation) {
|
||||
switch (rotation) {
|
||||
case kVideoRotation_0:
|
||||
return 0;
|
||||
case kVideoRotation_90:
|
||||
return 1;
|
||||
case kVideoRotation_180:
|
||||
return 2;
|
||||
case kVideoRotation_270:
|
||||
return 3;
|
||||
}
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline VideoRotation ConvertCVOByteToVideoRotation(uint8_t rotation) {
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
return kVideoRotation_0;
|
||||
case 1:
|
||||
return kVideoRotation_90;
|
||||
case 2:
|
||||
return kVideoRotation_180;
|
||||
break;
|
||||
case 3:
|
||||
return kVideoRotation_270;
|
||||
default:
|
||||
assert(false);
|
||||
return kVideoRotation_0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_CVO__H_
|
||||
@ -13,6 +13,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
||||
@ -62,6 +63,13 @@ int32_t RTPReceiverVideo::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
|
||||
const size_t payload_data_length =
|
||||
payload_length - rtp_header->header.paddingLength;
|
||||
|
||||
// Retrieve the video rotation information.
|
||||
rtp_header->type.Video.rotation = kVideoRotation_0;
|
||||
if (rtp_header->header.extension.hasVideoRotation) {
|
||||
rtp_header->type.Video.rotation = ConvertCVOByteToVideoRotation(
|
||||
rtp_header->header.extension.videoRotation);
|
||||
}
|
||||
|
||||
if (payload == NULL || payload_data_length == 0) {
|
||||
return data_callback_->OnReceivedPayloadData(NULL, 0, rtp_header) == 0 ? 0
|
||||
: -1;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include <stdlib.h> // srand
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
|
||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||
@ -453,25 +454,6 @@ int32_t RTPSender::CheckPayloadType(int8_t payload_type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Please refer to http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/
|
||||
// 12.07.00_60/ts_126114v120700p.pdf Section 7.4.5. The rotation of a frame is
|
||||
// the clockwise angle the frames must be rotated in order to display the frames
|
||||
// correctly if the display is rotated in its natural orientation.
|
||||
uint8_t RTPSender::ConvertToCVOByte(VideoRotation rotation) {
|
||||
switch (rotation) {
|
||||
case kVideoRotation_0:
|
||||
return 0;
|
||||
case kVideoRotation_90:
|
||||
return 1;
|
||||
case kVideoRotation_180:
|
||||
return 2;
|
||||
case kVideoRotation_270:
|
||||
return 3;
|
||||
}
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t RTPSender::SendOutgoingData(FrameType frame_type,
|
||||
int8_t payload_type,
|
||||
uint32_t capture_timestamp,
|
||||
@ -1367,7 +1349,7 @@ uint8_t RTPSender::BuildVideoRotationExtension(uint8_t* data_buffer) const {
|
||||
size_t pos = 0;
|
||||
const uint8_t len = 0;
|
||||
data_buffer[pos++] = (id << 4) + len;
|
||||
data_buffer[pos++] = ConvertToCVOByte(rotation_);
|
||||
data_buffer[pos++] = ConvertVideoRotationToCVOByte(rotation_);
|
||||
data_buffer[pos++] = 0; // padding
|
||||
data_buffer[pos++] = 0; // padding
|
||||
assert(pos == kVideoRotationLength);
|
||||
@ -1508,7 +1490,7 @@ bool RTPSender::UpdateVideoRotation(uint8_t* rtp_packet,
|
||||
LOG(LS_WARNING) << "Failed to update CVO.";
|
||||
return false;
|
||||
}
|
||||
rtp_packet[block_pos + 1] = ConvertToCVOByte(rotation);
|
||||
rtp_packet[block_pos + 1] = ConvertVideoRotationToCVOByte(rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -284,8 +284,6 @@ class RTPSender : public RTPSenderInterface {
|
||||
void SetRtxRtpState(const RtpState& rtp_state);
|
||||
RtpState GetRtxRtpState() const;
|
||||
|
||||
static uint8_t ConvertToCVOByte(VideoRotation rotation);
|
||||
|
||||
protected:
|
||||
int32_t CheckPayloadType(int8_t payload_type, RtpVideoCodecTypes* video_type);
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "webrtc/base/buffer.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
#include "webrtc/modules/pacing/include/mock/mock_paced_sender.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
||||
@ -189,7 +190,7 @@ class RtpSenderVideoTest : public RtpSenderTest {
|
||||
EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.ssrc);
|
||||
EXPECT_EQ(0, rtp_header.numCSRCs);
|
||||
EXPECT_EQ(0U, rtp_header.paddingLength);
|
||||
EXPECT_EQ(RTPSender::ConvertToCVOByte(rotation),
|
||||
EXPECT_EQ(ConvertVideoRotationToCVOByte(rotation),
|
||||
rtp_header.extension.videoRotation);
|
||||
}
|
||||
};
|
||||
@ -427,7 +428,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithVideoRotation_MarkerBit) {
|
||||
VerifyRTPHeaderCommon(rtp_header);
|
||||
EXPECT_EQ(length, rtp_header.headerLength);
|
||||
EXPECT_TRUE(rtp_header.extension.hasVideoRotation);
|
||||
EXPECT_EQ(RTPSender::ConvertToCVOByte(kRotation),
|
||||
EXPECT_EQ(ConvertVideoRotationToCVOByte(kRotation),
|
||||
rtp_header.extension.videoRotation);
|
||||
}
|
||||
|
||||
|
||||
@ -41,10 +41,12 @@ namespace webrtc {
|
||||
const char* RtpExtension::kTOffset = "urn:ietf:params:rtp-hdrext:toffset";
|
||||
const char* RtpExtension::kAbsSendTime =
|
||||
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
|
||||
const char* RtpExtension::kVideoRotation = "urn:3gpp:video-orientation";
|
||||
|
||||
bool RtpExtension::IsSupported(const std::string& name) {
|
||||
return name == webrtc::RtpExtension::kTOffset ||
|
||||
name == webrtc::RtpExtension::kAbsSendTime;
|
||||
name == webrtc::RtpExtension::kAbsSendTime ||
|
||||
name == webrtc::RtpExtension::kVideoRotation;
|
||||
}
|
||||
|
||||
VideoEncoder* VideoEncoder::Create(VideoEncoder::EncoderType codec_type) {
|
||||
|
||||
@ -181,6 +181,9 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
||||
} else if (extension == RtpExtension::kAbsSendTime) {
|
||||
if (rtp_rtcp_->SetReceiveAbsoluteSendTimeStatus(channel_, true, id) != 0)
|
||||
abort();
|
||||
} else if (extension == RtpExtension::kVideoRotation) {
|
||||
if (rtp_rtcp_->SetReceiveVideoRotationStatus(channel_, true, id) != 0)
|
||||
abort();
|
||||
} else {
|
||||
abort(); // Unsupported extension.
|
||||
}
|
||||
|
||||
@ -144,6 +144,9 @@ VideoSendStream::VideoSendStream(
|
||||
} else if (extension == RtpExtension::kAbsSendTime) {
|
||||
if (rtp_rtcp_->SetSendAbsoluteSendTimeStatus(channel_, true, id) != 0)
|
||||
abort();
|
||||
} else if (extension == RtpExtension::kVideoRotation) {
|
||||
if (rtp_rtcp_->SetSendVideoRotationStatus(channel_, true, id) != 0)
|
||||
abort();
|
||||
} else {
|
||||
abort(); // Unsupported extension.
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ struct ViEVideoFrameI420 {
|
||||
v_pitch = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
rotation = kVideoRotation_0;
|
||||
}
|
||||
|
||||
unsigned char* y_plane;
|
||||
@ -83,6 +84,7 @@ struct ViEVideoFrameI420 {
|
||||
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
VideoRotation rotation;
|
||||
};
|
||||
|
||||
// This class declares an abstract interface to be used when implementing
|
||||
|
||||
@ -245,6 +245,14 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
|
||||
bool enable,
|
||||
int id) = 0;
|
||||
|
||||
virtual int SetSendVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id) = 0;
|
||||
|
||||
virtual int SetReceiveVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id) = 0;
|
||||
|
||||
// Enables/disables RTCP Receiver Reference Time Report Block extension/
|
||||
// DLRR Report Block extension (RFC 3611).
|
||||
virtual int SetRtcpXrRrtrStatus(int video_channel, bool enable) = 0;
|
||||
|
||||
@ -325,7 +325,8 @@ int ViECapturer::IncomingFrameI420(const ViEVideoFrameI420& video_frame,
|
||||
video_frame.height,
|
||||
video_frame.y_pitch,
|
||||
video_frame.u_pitch,
|
||||
video_frame.v_pitch);
|
||||
video_frame.v_pitch,
|
||||
video_frame.rotation);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_F(LS_ERROR) << "Could not create I420Frame.";
|
||||
|
||||
@ -118,6 +118,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
||||
bandwidth_observer_(bandwidth_observer),
|
||||
send_timestamp_extension_id_(kInvalidRtpExtensionId),
|
||||
absolute_send_time_extension_id_(kInvalidRtpExtensionId),
|
||||
video_rotation_extension_id_(kInvalidRtpExtensionId),
|
||||
external_transport_(NULL),
|
||||
decoder_reset_(true),
|
||||
wait_for_key_frame_(false),
|
||||
@ -459,6 +460,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
if (rtp_rtcp->RegisterSendRtpHeaderExtension(
|
||||
kRtpExtensionTransmissionTimeOffset,
|
||||
send_timestamp_extension_id_) != 0) {
|
||||
LOG(LS_WARNING) << "Register Transmission Time Offset failed";
|
||||
}
|
||||
} else {
|
||||
rtp_rtcp->DeregisterSendRtpHeaderExtension(
|
||||
@ -471,11 +473,23 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
if (rtp_rtcp->RegisterSendRtpHeaderExtension(
|
||||
kRtpExtensionAbsoluteSendTime,
|
||||
absolute_send_time_extension_id_) != 0) {
|
||||
LOG(LS_WARNING) << "Register Absolute Send Time failed";
|
||||
}
|
||||
} else {
|
||||
rtp_rtcp->DeregisterSendRtpHeaderExtension(
|
||||
kRtpExtensionAbsoluteSendTime);
|
||||
}
|
||||
if (video_rotation_extension_id_ != kInvalidRtpExtensionId) {
|
||||
// Deregister in case the extension was previously enabled.
|
||||
rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
if (rtp_rtcp->RegisterSendRtpHeaderExtension(
|
||||
kRtpExtensionVideoRotation, video_rotation_extension_id_) !=
|
||||
0) {
|
||||
LOG(LS_WARNING) << "Register VideoRotation extension failed";
|
||||
}
|
||||
} else {
|
||||
rtp_rtcp->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
}
|
||||
rtp_rtcp->RegisterRtcpStatisticsCallback(
|
||||
rtp_rtcp_->GetRtcpStatisticsCallback());
|
||||
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
|
||||
@ -899,6 +913,37 @@ int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
|
||||
return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1;
|
||||
}
|
||||
|
||||
int ViEChannel::SetSendVideoRotationStatus(bool enable, int id) {
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
int error = 0;
|
||||
if (enable) {
|
||||
// Enable the extension, but disable possible old id to avoid errors.
|
||||
video_rotation_extension_id_ = id;
|
||||
rtp_rtcp_->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
|
||||
kRtpExtensionVideoRotation, id);
|
||||
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
|
||||
it != simulcast_rtp_rtcp_.end(); it++) {
|
||||
(*it)->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
error |=
|
||||
(*it)->RegisterSendRtpHeaderExtension(kRtpExtensionVideoRotation, id);
|
||||
}
|
||||
} else {
|
||||
// Disable the extension.
|
||||
video_rotation_extension_id_ = kInvalidRtpExtensionId;
|
||||
rtp_rtcp_->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
|
||||
it != simulcast_rtp_rtcp_.end(); it++) {
|
||||
(*it)->DeregisterSendRtpHeaderExtension(kRtpExtensionVideoRotation);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int ViEChannel::SetReceiveVideoRotationStatus(bool enable, int id) {
|
||||
return vie_receiver_.SetReceiveVideoRotationStatus(enable, id) ? 0 : -1;
|
||||
}
|
||||
|
||||
void ViEChannel::SetRtcpXrRrtrStatus(bool enable) {
|
||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||
rtp_rtcp_->SetRtcpXrRrtrStatus(enable);
|
||||
|
||||
@ -131,6 +131,8 @@ class ViEChannel
|
||||
int SetSendAbsoluteSendTimeStatus(bool enable, int id);
|
||||
int SetReceiveAbsoluteSendTimeStatus(bool enable, int id);
|
||||
bool GetReceiveAbsoluteSendTimeStatus() const;
|
||||
int SetSendVideoRotationStatus(bool enable, int id);
|
||||
int SetReceiveVideoRotationStatus(bool enable, int id);
|
||||
void SetRtcpXrRrtrStatus(bool enable);
|
||||
void SetTransmissionSmoothingStatus(bool enable);
|
||||
void EnableTMMBR(bool enable);
|
||||
@ -526,6 +528,7 @@ class ViEChannel
|
||||
rtc::scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
|
||||
int send_timestamp_extension_id_;
|
||||
int absolute_send_time_extension_id_;
|
||||
int video_rotation_extension_id_;
|
||||
|
||||
Transport* external_transport_;
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/remote_ntp_time_estimator.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_cvo.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||
@ -58,6 +59,7 @@ ViEReceiver::ViEReceiver(const int32_t channel_id,
|
||||
receiving_(false),
|
||||
restored_packet_in_use_(false),
|
||||
receiving_ast_enabled_(false),
|
||||
receiving_cvo_enabled_(false),
|
||||
last_packet_log_ms_(-1) {
|
||||
assert(remote_bitrate_estimator);
|
||||
}
|
||||
@ -187,6 +189,22 @@ bool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ViEReceiver::SetReceiveVideoRotationStatus(bool enable, int id) {
|
||||
if (enable) {
|
||||
if (rtp_header_parser_->RegisterRtpHeaderExtension(
|
||||
kRtpExtensionVideoRotation, id)) {
|
||||
receiving_cvo_enabled_ = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
receiving_cvo_enabled_ = false;
|
||||
return rtp_header_parser_->DeregisterRtpHeaderExtension(
|
||||
kRtpExtensionVideoRotation);
|
||||
}
|
||||
}
|
||||
|
||||
int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
|
||||
size_t rtp_packet_length,
|
||||
const PacketTime& packet_time) {
|
||||
@ -382,6 +400,11 @@ void ViEReceiver::NotifyReceiverOfFecPacket(const RTPHeader& header) {
|
||||
return;
|
||||
}
|
||||
rtp_header.type.Video.codec = payload_specific.Video.videoCodecType;
|
||||
rtp_header.type.Video.rotation = kVideoRotation_0;
|
||||
if (header.extension.hasVideoRotation) {
|
||||
rtp_header.type.Video.rotation =
|
||||
ConvertCVOByteToVideoRotation(header.extension.videoRotation);
|
||||
}
|
||||
OnReceivedPayloadData(NULL, 0, &rtp_header);
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ class ViEReceiver : public RtpData {
|
||||
|
||||
bool SetReceiveTimestampOffsetStatus(bool enable, int id);
|
||||
bool SetReceiveAbsoluteSendTimeStatus(bool enable, int id);
|
||||
bool SetReceiveVideoRotationStatus(bool enable, int id);
|
||||
|
||||
void StartReceive();
|
||||
void StopReceive();
|
||||
@ -123,6 +124,7 @@ class ViEReceiver : public RtpData {
|
||||
uint8_t restored_packet_[kViEMaxMtu];
|
||||
bool restored_packet_in_use_;
|
||||
bool receiving_ast_enabled_;
|
||||
bool receiving_cvo_enabled_;
|
||||
int64_t last_packet_log_ms_;
|
||||
};
|
||||
|
||||
|
||||
@ -615,6 +615,43 @@ int ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(int video_channel,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViERTP_RTCPImpl::SetSendVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id) {
|
||||
LOG_F(LS_INFO) << "channel: " << video_channel
|
||||
<< " enable: " << (enable ? "on" : "off") << " id: " << id;
|
||||
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (vie_channel->SetSendVideoRotationStatus(enable, id) != 0) {
|
||||
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViERTP_RTCPImpl::SetReceiveVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id) {
|
||||
LOG_F(LS_INFO) << "channel: " << video_channel
|
||||
<< " enable: " << (enable ? "on" : "off") << " id: " << id;
|
||||
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
|
||||
ViEChannel* vie_channel = cs.Channel(video_channel);
|
||||
if (!vie_channel) {
|
||||
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
|
||||
return -1;
|
||||
}
|
||||
if (vie_channel->SetReceiveVideoRotationStatus(enable, id) != 0) {
|
||||
shared_data_->SetLastError(kViERtpRtcpUnknownError);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViERTP_RTCPImpl::SetRtcpXrRrtrStatus(int video_channel, bool enable) {
|
||||
LOG_F(LS_INFO) << "channel: " << video_channel
|
||||
<< " enable: " << (enable ? "on" : "off");
|
||||
|
||||
@ -90,6 +90,12 @@ class ViERTP_RTCPImpl
|
||||
virtual int SetReceiveAbsoluteSendTimeStatus(int video_channel,
|
||||
bool enable,
|
||||
int id);
|
||||
virtual int SetSendVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id);
|
||||
virtual int SetReceiveVideoRotationStatus(int video_channel,
|
||||
bool enable,
|
||||
int id);
|
||||
virtual int SetRtcpXrRrtrStatus(int video_channel, bool enable);
|
||||
virtual int SetTransmissionSmoothingStatus(int video_channel, bool enable);
|
||||
virtual int SetMinTransmitBitrate(int video_channel,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user