Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1207)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc

Issue 2871173008: Fix packetization logic to leave space for extensions in the last packet (Closed)
Patch Set: Fix packet buffer allocations bugs and old tests with incorrect assumptions about extensions locati… Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698