OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 const RTPFragmentationHeader* fragmentation, | 293 const RTPFragmentationHeader* fragmentation, |
294 const RTPVideoHeader* video_header) { | 294 const RTPVideoHeader* video_header) { |
295 if (payload_size == 0) | 295 if (payload_size == 0) |
296 return false; | 296 return false; |
297 | 297 |
298 // Create header that will be reused in all packets. | 298 // Create header that will be reused in all packets. |
299 std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket(); | 299 std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket(); |
300 rtp_header->SetPayloadType(payload_type); | 300 rtp_header->SetPayloadType(payload_type); |
301 rtp_header->SetTimestamp(rtp_timestamp); | 301 rtp_header->SetTimestamp(rtp_timestamp); |
302 rtp_header->set_capture_time_ms(capture_time_ms); | 302 rtp_header->set_capture_time_ms(capture_time_ms); |
303 std::unique_ptr<RtpPacketToSend> rtp_header_with_extensions( | |
danilchap
2017/05/12 08:34:40
this name makes false impression rtp_header doesn'
ilnik
2017/05/12 09:17:57
Done.
| |
304 new RtpPacketToSend(*rtp_header)); | |
danilchap
2017/05/12 08:34:40
in base/ptr_util.h there is helper for this scenar
ilnik
2017/05/12 09:17:58
Done.
| |
303 | 305 |
304 size_t fec_packet_overhead; | 306 size_t fec_packet_overhead; |
305 bool red_enabled; | 307 bool red_enabled; |
306 int32_t retransmission_settings; | 308 int32_t retransmission_settings; |
307 { | 309 { |
308 rtc::CritScope cs(&crit_); | 310 rtc::CritScope cs(&crit_); |
309 // According to | 311 // According to |
310 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ | 312 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ |
311 // ts_126114v120700p.pdf Section 7.4.5: | 313 // ts_126114v120700p.pdf Section 7.4.5: |
312 // The MTSI client shall add the payload bytes as defined in this clause | 314 // The MTSI client shall add the payload bytes as defined in this clause |
313 // onto the last RTP packet in each group of packets which make up a key | 315 // onto the last RTP packet in each group of packets which make up a key |
314 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 | 316 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 |
315 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP | 317 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP |
316 // packet in each group of packets which make up another type of frame | 318 // packet in each group of packets which make up another type of frame |
317 // (e.g. a P-Frame) only if the current value is different from the previous | 319 // (e.g. a P-Frame) only if the current value is different from the previous |
318 // value sent. | 320 // value sent. |
319 if (video_header) { | 321 if (video_header) { |
320 // Set rotation when key frame or when changed (to follow standard). | 322 // Set rotation when key frame or when changed (to follow standard). |
321 // Or when different from 0 (to follow current receiver implementation). | 323 // Or when different from 0 (to follow current receiver implementation). |
322 VideoRotation current_rotation = video_header->rotation; | 324 VideoRotation current_rotation = video_header->rotation; |
323 if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ || | 325 if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ || |
324 current_rotation != kVideoRotation_0) | 326 current_rotation != kVideoRotation_0) |
325 rtp_header->SetExtension<VideoOrientation>(current_rotation); | 327 rtp_header_with_extensions->SetExtension<VideoOrientation>( |
328 current_rotation); | |
326 last_rotation_ = current_rotation; | 329 last_rotation_ = current_rotation; |
327 // Report content type only for key frames. | 330 // Report content type only for key frames. |
328 if (frame_type == kVideoFrameKey && | 331 if (frame_type == kVideoFrameKey && |
329 video_header->content_type != VideoContentType::UNSPECIFIED) { | 332 video_header->content_type != VideoContentType::UNSPECIFIED) { |
330 rtp_header->SetExtension<VideoContentTypeExtension>( | 333 rtp_header_with_extensions->SetExtension<VideoContentTypeExtension>( |
331 video_header->content_type); | 334 video_header->content_type); |
332 } | 335 } |
333 } | 336 } |
334 | 337 |
335 // FEC settings. | 338 // FEC settings. |
336 const FecProtectionParams& fec_params = | 339 const FecProtectionParams& fec_params = |
337 frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_; | 340 frame_type == kVideoFrameKey ? key_fec_params_ : delta_fec_params_; |
338 if (flexfec_enabled()) | 341 if (flexfec_enabled()) |
339 flexfec_sender_->SetFecParameters(fec_params); | 342 flexfec_sender_->SetFecParameters(fec_params); |
340 if (ulpfec_enabled()) | 343 if (ulpfec_enabled()) |
341 ulpfec_generator_.SetFecParameters(fec_params); | 344 ulpfec_generator_.SetFecParameters(fec_params); |
342 | 345 |
343 fec_packet_overhead = CalculateFecPacketOverhead(); | 346 fec_packet_overhead = CalculateFecPacketOverhead(); |
344 red_enabled = this->red_enabled(); | 347 red_enabled = this->red_enabled(); |
345 retransmission_settings = retransmission_settings_; | 348 retransmission_settings = retransmission_settings_; |
346 } | 349 } |
347 | 350 |
348 size_t packet_capacity = rtp_sender_->MaxRtpPacketSize() - | 351 size_t packet_capacity = rtp_sender_->MaxRtpPacketSize() - |
349 fec_packet_overhead - | 352 fec_packet_overhead - |
350 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); | 353 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); |
351 RTC_DCHECK_LE(packet_capacity, rtp_header->capacity()); | 354 RTC_DCHECK_LE(packet_capacity, rtp_header->capacity()); |
352 RTC_DCHECK_GT(packet_capacity, rtp_header->headers_size()); | 355 RTC_DCHECK_GT(packet_capacity, rtp_header->headers_size()); |
356 RTC_DCHECK_GT(packet_capacity, rtp_header_with_extensions->headers_size()); | |
353 size_t max_data_payload_length = packet_capacity - rtp_header->headers_size(); | 357 size_t max_data_payload_length = packet_capacity - rtp_header->headers_size(); |
358 size_t last_packet_extensions_len = | |
359 rtp_header_with_extensions->headers_size() - rtp_header->headers_size(); | |
354 | 360 |
355 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 361 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
356 video_type, max_data_payload_length, | 362 video_type, max_data_payload_length, last_packet_extensions_len, |
357 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 363 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); |
358 // Media packet storage. | 364 // Media packet storage. |
359 StorageType storage = packetizer->GetStorageType(retransmission_settings); | 365 StorageType storage = packetizer->GetStorageType(retransmission_settings); |
360 | 366 |
361 // TODO(changbin): we currently don't support to configure the codec to | 367 // TODO(changbin): we currently don't support to configure the codec to |
362 // output multiple partitions for VP8. Should remove below check after the | 368 // output multiple partitions for VP8. Should remove below check after the |
363 // issue is fixed. | 369 // issue is fixed. |
364 const RTPFragmentationHeader* frag = | 370 const RTPFragmentationHeader* frag = |
365 (video_type == kRtpVideoVp8) ? nullptr : fragmentation; | 371 (video_type == kRtpVideoVp8) ? nullptr : fragmentation; |
366 packetizer->SetPayloadData(payload_data, payload_size, frag); | 372 packetizer->SetPayloadData(payload_data, payload_size, frag); |
367 | 373 |
368 bool first_frame = first_frame_sent_(); | 374 bool first_frame = first_frame_sent_(); |
369 bool first = true; | |
370 bool last = false; | 375 bool last = false; |
danilchap
2017/05/12 08:34:40
is it used outside for loop?
ilnik
2017/05/12 09:17:57
No. Moved inside.
| |
371 while (!last) { | 376 size_t total_packets = packetizer->TotalPackets(); |
danilchap
2017/05/12 08:34:40
may be num_packets
ilnik
2017/05/12 09:17:57
Done.
| |
372 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); | 377 for (size_t current_packet = 0; current_packet < total_packets; |
danilchap
2017/05/12 08:34:40
may be name iterator to show it is not a packet (s
ilnik
2017/05/12 09:17:57
Done.
| |
373 | 378 ++current_packet) { |
374 if (!packetizer->NextPacket(packet.get(), &last)) | 379 RtpPacketToSend* rtp_header_to_use = rtp_header.get(); |
380 last = (current_packet + 1) == total_packets; | |
381 if (last) | |
382 rtp_header_to_use = rtp_header_with_extensions.get(); | |
383 std::unique_ptr<RtpPacketToSend> packet( | |
384 new RtpPacketToSend(*rtp_header_to_use)); | |
385 if (!packetizer->NextPacket(packet.get())) | |
375 return false; | 386 return false; |
376 RTC_DCHECK_LE(packet->payload_size(), max_data_payload_length); | 387 if (last) { |
danilchap
2017/05/12 08:34:40
may be instead of branch
RTC_DCHECK_LE(packet->siz
ilnik
2017/05/12 09:17:57
Great idea. Done.
| |
388 RTC_DCHECK_LE(packet->payload_size(), | |
389 max_data_payload_length - last_packet_extensions_len); | |
390 } else { | |
391 RTC_DCHECK_LE(packet->payload_size(), max_data_payload_length); | |
392 } | |
377 | 393 |
378 if (!rtp_sender_->AssignSequenceNumber(packet.get())) | 394 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
379 return false; | 395 return false; |
380 | 396 |
381 const bool protect_packet = | 397 const bool protect_packet = |
382 (packetizer->GetProtectionType() == kProtectedPacket); | 398 (packetizer->GetProtectionType() == kProtectedPacket); |
383 if (flexfec_enabled()) { | 399 if (flexfec_enabled()) { |
384 // TODO(brandtr): Remove the FlexFEC code path when FlexfecSender | 400 // TODO(brandtr): Remove the FlexFEC code path when FlexfecSender |
385 // is wired up to PacedSender instead. | 401 // is wired up to PacedSender instead. |
386 SendVideoPacketWithFlexfec(std::move(packet), storage, protect_packet); | 402 SendVideoPacketWithFlexfec(std::move(packet), storage, protect_packet); |
387 } else if (red_enabled) { | 403 } else if (red_enabled) { |
388 SendVideoPacketAsRedMaybeWithUlpfec(std::move(packet), storage, | 404 SendVideoPacketAsRedMaybeWithUlpfec(std::move(packet), storage, |
389 protect_packet); | 405 protect_packet); |
390 } else { | 406 } else { |
391 SendVideoPacket(std::move(packet), storage); | 407 SendVideoPacket(std::move(packet), storage); |
392 } | 408 } |
393 | 409 |
394 if (first_frame) { | 410 if (first_frame) { |
395 if (first) { | 411 if (current_packet == 0) { |
396 LOG(LS_INFO) | 412 LOG(LS_INFO) |
397 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 413 << "Sent first RTP packet of the first video frame (pre-pacer)"; |
398 } | 414 } |
399 if (last) { | 415 if (last) { |
400 LOG(LS_INFO) | 416 LOG(LS_INFO) |
401 << "Sent last RTP packet of the first video frame (pre-pacer)"; | 417 << "Sent last RTP packet of the first video frame (pre-pacer)"; |
402 } | 418 } |
403 } | 419 } |
404 first = false; | |
405 } | 420 } |
406 | 421 |
407 TRACE_EVENT_ASYNC_END1("webrtc", "Video", capture_time_ms, "timestamp", | 422 TRACE_EVENT_ASYNC_END1("webrtc", "Video", capture_time_ms, "timestamp", |
408 rtp_timestamp); | 423 rtp_timestamp); |
409 return true; | 424 return true; |
410 } | 425 } |
411 | 426 |
412 uint32_t RTPSenderVideo::VideoBitrateSent() const { | 427 uint32_t RTPSenderVideo::VideoBitrateSent() const { |
413 rtc::CritScope cs(&stats_crit_); | 428 rtc::CritScope cs(&stats_crit_); |
414 return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); | 429 return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); |
415 } | 430 } |
416 | 431 |
417 uint32_t RTPSenderVideo::FecOverheadRate() const { | 432 uint32_t RTPSenderVideo::FecOverheadRate() const { |
418 rtc::CritScope cs(&stats_crit_); | 433 rtc::CritScope cs(&stats_crit_); |
419 return fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); | 434 return fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); |
420 } | 435 } |
421 | 436 |
422 int RTPSenderVideo::SelectiveRetransmissions() const { | 437 int RTPSenderVideo::SelectiveRetransmissions() const { |
423 rtc::CritScope cs(&crit_); | 438 rtc::CritScope cs(&crit_); |
424 return retransmission_settings_; | 439 return retransmission_settings_; |
425 } | 440 } |
426 | 441 |
427 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 442 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
428 rtc::CritScope cs(&crit_); | 443 rtc::CritScope cs(&crit_); |
429 retransmission_settings_ = settings; | 444 retransmission_settings_ = settings; |
430 } | 445 } |
431 | 446 |
432 } // namespace webrtc | 447 } // namespace webrtc |
OLD | NEW |