const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t maxBitRate,
- ModuleRTPUtility::Payload*& payload) {
+ RtpUtility::Payload*& payload) {
CriticalSectionScoped cs(_sendVideoCritsect);
RtpVideoCodecTypes videoType = kRtpVideoGeneric;
- if (ModuleRTPUtility::StringCompare(payloadName, "VP8",3)) {
+ if (RtpUtility::StringCompare(payloadName, "VP8", 3)) {
videoType = kRtpVideoVp8;
- } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
+ } else if (RtpUtility::StringCompare(payloadName, "H264", 4)) {
+ videoType = kRtpVideoH264;
+ } else if (RtpUtility::StringCompare(payloadName, "I420", 4)) {
videoType = kRtpVideoGeneric;
} else {
videoType = kRtpVideoGeneric;
}
- payload = new ModuleRTPUtility::Payload;
+ payload = new RtpUtility::Payload;
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
payload->typeSpecific.Video.videoCodecType = videoType;
data[2] = 0;
data[3] = 1; // length
- ModuleRTPUtility::AssignUWord32ToBuffer(data+4, _rtpSender.SSRC());
+ RtpUtility::AssignUWord32ToBuffer(data + 4, _rtpSender.SSRC());
TRACE_EVENT_INSTANT1("webrtc_rtp",
"Video::IntraRequest",
return 0;
}
-int32_t
-RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
- const FrameType frameType,
- const int8_t payloadType,
- const uint32_t captureTimeStamp,
- int64_t capture_time_ms,
- const uint8_t* payloadData,
- const uint32_t payloadSize,
- const RTPFragmentationHeader* fragmentation,
- VideoCodecInformation* codecInfo,
- const RTPVideoTypeHeader* rtpTypeHdr)
-{
- if( payloadSize == 0)
- {
- return -1;
- }
+int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
+ const FrameType frameType,
+ const int8_t payloadType,
+ const uint32_t captureTimeStamp,
+ int64_t capture_time_ms,
+ const uint8_t* payloadData,
+ const uint32_t payloadSize,
+ const RTPFragmentationHeader* fragmentation,
+ VideoCodecInformation* codecInfo,
+ const RTPVideoTypeHeader* rtpTypeHdr) {
+ if (payloadSize == 0) {
+ return -1;
+ }
- if (frameType == kVideoFrameKey) {
- producer_fec_.SetFecParameters(&key_fec_params_,
- _numberFirstPartition);
- } else {
- producer_fec_.SetFecParameters(&delta_fec_params_,
- _numberFirstPartition);
- }
+ if (frameType == kVideoFrameKey) {
+ producer_fec_.SetFecParameters(&key_fec_params_, _numberFirstPartition);
+ } else {
+ producer_fec_.SetFecParameters(&delta_fec_params_, _numberFirstPartition);
+ }
- // Default setting for number of first partition packets:
- // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
- _numberFirstPartition = 0;
+ // Default setting for number of first partition packets:
+ // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
+ _numberFirstPartition = 0;
- int32_t retVal = -1;
- switch(videoType)
- {
+ switch (videoType) {
case kRtpVideoGeneric:
- retVal = SendGeneric(frameType, payloadType, captureTimeStamp,
- capture_time_ms, payloadData, payloadSize);
- break;
- case kRtpVideoVp8:
- retVal = SendVP8(frameType,
+ return SendGeneric(frameType,
payloadType,
captureTimeStamp,
capture_time_ms,
payloadData,
- payloadSize,
- fragmentation,
- rtpTypeHdr);
- break;
+ payloadSize);
+ case kRtpVideoVp8:
+ return SendVP8(frameType,
+ payloadType,
+ captureTimeStamp,
+ capture_time_ms,
+ payloadData,
+ payloadSize,
+ fragmentation,
+ rtpTypeHdr);
+ case kRtpVideoH264:
+ return SendH264(frameType,
+ payloadType,
+ captureTimeStamp,
+ capture_time_ms,
+ payloadData,
+ payloadSize,
+ fragmentation,
+ rtpTypeHdr)
+ ? 0
+ : -1;
default:
- assert(false);
- break;
- }
- if(retVal <= 0)
- {
- return retVal;
- }
- return 0;
+ assert(false);
+ break;
+ }
+ return 0;
}
int32_t RTPSenderVideo::SendGeneric(const FrameType frame_type,
assert(rtpTypeHdr);
// Initialize disregarding partition boundaries: this will use kEqualSize
// packetization mode, which produces ~equal size packets for each frame.
- RtpFormatVp8 packetizer(data, payloadBytesToSend, rtpTypeHdr->VP8,
- maxPayloadLengthVP8);
+ RtpPacketizerVp8 packetizer(rtpTypeHdr->VP8, maxPayloadLengthVP8);
+ packetizer.SetPayloadData(data, payloadBytesToSend, NULL);
StorageType storage = kAllowRetransmission;
if (rtpTypeHdr->VP8.temporalIdx == 0 &&
!(_retransmissionSettings & kRetransmitBaseLayer)) {
storage = kDontRetransmit;
- }
- if (rtpTypeHdr->VP8.temporalIdx > 0 &&
+ } else if (rtpTypeHdr->VP8.temporalIdx != kNoTemporalIdx &&
+ rtpTypeHdr->VP8.temporalIdx > 0 &&
!(_retransmissionSettings & kRetransmitHigherLayers)) {
storage = kDontRetransmit;
}
bool last = false;
_numberFirstPartition = 0;
- // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or -1 if the field
- // isn't used. We currently only protect base layers.
- bool protect = (rtpTypeHdr->VP8.temporalIdx < 1);
+ // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or kNoTemporalIdx
+ // if the field isn't used (so all layers are the base layer). We currently
+ // only protect base layers, so look for these two cases.
+ bool protect = rtpTypeHdr->VP8.temporalIdx == 0 ||
+ rtpTypeHdr->VP8.temporalIdx == kNoTemporalIdx;
while (!last)
{
// Write VP8 Payload Descriptor and VP8 payload.
uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
- int payloadBytesInPacket = 0;
- int packetStartPartition =
- packetizer.NextPacket(&dataBuffer[rtpHeaderLength],
- &payloadBytesInPacket, &last);
- // TODO(holmer): Temporarily disable first partition packet counting
- // to avoid a bug in ProducerFec which doesn't properly handle
- // important packets.
- // if (packetStartPartition == 0)
- // {
- // ++_numberFirstPartition;
- // }
- // else
- if (packetStartPartition < 0)
- {
- return -1;
- }
+ size_t payloadBytesInPacket = 0;
+ if (!packetizer.NextPacket(
+ &dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last))
+ return -1;
// Write RTP header.
// Set marker bit true if this is the last packet in frame.
return 0;
}
+bool RTPSenderVideo::SendH264(const FrameType frameType,
+ const int8_t payloadType,
+ const uint32_t captureTimeStamp,
+ int64_t capture_time_ms,
+ const uint8_t* payloadData,
+ const uint32_t payloadSize,
+ const RTPFragmentationHeader* fragmentation,
+ const RTPVideoTypeHeader* rtpTypeHdr) {
+ size_t rtp_header_length = _rtpSender.RTPHeaderLength();
+ int32_t payload_bytes_to_send = payloadSize;
+ const uint8_t* data = payloadData;
+ size_t max_payload_length = _rtpSender.MaxDataPayloadLength();
+
+ scoped_ptr<RtpPacketizer> packetizer(
+ RtpPacketizer::Create(kRtpVideoH264, max_payload_length));
+ packetizer->SetPayloadData(data, payload_bytes_to_send, fragmentation);
+
+ StorageType storage = kAllowRetransmission;
+ bool protect = (frameType == kVideoFrameKey);
+ bool last = false;
+
+ while (!last) {
+ // Write H264 payload.
+ uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
+ size_t payload_bytes_in_packet = 0;
+ if (!packetizer->NextPacket(
+ &dataBuffer[rtp_header_length], &payload_bytes_in_packet, &last)) {
+ return false;
+ }
+
+ // Write RTP header.
+ // Set marker bit true if this is the last packet in frame.
+ _rtpSender.BuildRTPheader(
+ dataBuffer, payloadType, last, captureTimeStamp, capture_time_ms);
+ if (SendVideoPacket(dataBuffer,
+ payload_bytes_in_packet,
+ rtp_header_length,
+ captureTimeStamp,
+ capture_time_ms,
+ storage,
+ protect)) {
+ LOG(LS_WARNING)
+ << "RTPSenderVideo::SendH264 failed to send packet number "
+ << _rtpSender.SequenceNumber();
+ }
+ }
+ return true;
+}
+
void RTPSenderVideo::ProcessBitrate() {
_videoBitrate.Process();
_fecOverheadRate.Process();