| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/media/cast_rtp_stream.h" | 5 #include "chrome/renderer/media/cast_rtp_stream.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 // This constant defines the number of sets of audio data to buffer | 44 // This constant defines the number of sets of audio data to buffer |
| 45 // in the FIFO. If input audio and output data have different resampling | 45 // in the FIFO. If input audio and output data have different resampling |
| 46 // rates then buffer is necessary to avoid audio glitches. | 46 // rates then buffer is necessary to avoid audio glitches. |
| 47 // See CastAudioSink::ResampleData() and CastAudioSink::OnSetFormat() | 47 // See CastAudioSink::ResampleData() and CastAudioSink::OnSetFormat() |
| 48 // for more defaults. | 48 // for more defaults. |
| 49 const int kBufferAudioData = 2; | 49 const int kBufferAudioData = 2; |
| 50 | 50 |
| 51 CastRtpPayloadParams DefaultOpusPayload() { | 51 CastRtpPayloadParams DefaultOpusPayload() { |
| 52 CastRtpPayloadParams payload; | 52 CastRtpPayloadParams payload; |
| 53 payload.payload_type = 127; |
| 54 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; |
| 53 payload.ssrc = 1; | 55 payload.ssrc = 1; |
| 54 payload.feedback_ssrc = 2; | 56 payload.feedback_ssrc = 2; |
| 55 payload.payload_type = 127; | 57 payload.clock_rate = media::cast::kDefaultAudioSamplingRate; |
| 56 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; | |
| 57 payload.codec_name = kCodecNameOpus; | |
| 58 payload.clock_rate = 48000; | |
| 59 payload.channels = 2; | |
| 60 // The value is 0 which means VBR. | 58 // The value is 0 which means VBR. |
| 61 payload.min_bitrate = payload.max_bitrate = | 59 payload.min_bitrate = payload.max_bitrate = |
| 62 media::cast::kDefaultAudioEncoderBitrate; | 60 media::cast::kDefaultAudioEncoderBitrate; |
| 61 payload.channels = 2; |
| 62 payload.max_frame_rate = 100; // 10 ms audio frames |
| 63 payload.codec_name = kCodecNameOpus; |
| 63 return payload; | 64 return payload; |
| 64 } | 65 } |
| 65 | 66 |
| 66 CastRtpPayloadParams DefaultVp8Payload() { | 67 CastRtpPayloadParams DefaultVp8Payload() { |
| 67 CastRtpPayloadParams payload; | 68 CastRtpPayloadParams payload; |
| 69 payload.payload_type = 96; |
| 70 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; |
| 68 payload.ssrc = 11; | 71 payload.ssrc = 11; |
| 69 payload.feedback_ssrc = 12; | 72 payload.feedback_ssrc = 12; |
| 70 payload.payload_type = 96; | 73 payload.clock_rate = media::cast::kVideoFrequency; |
| 71 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; | 74 payload.max_bitrate = 2000; |
| 72 payload.codec_name = kCodecNameVp8; | 75 payload.min_bitrate = 50; |
| 73 payload.clock_rate = 90000; | 76 payload.channels = 1; |
| 77 payload.max_frame_rate = media::cast::kDefaultMaxFrameRate; |
| 74 payload.width = 1280; | 78 payload.width = 1280; |
| 75 payload.height = 720; | 79 payload.height = 720; |
| 76 payload.min_bitrate = 50; | 80 payload.codec_name = kCodecNameVp8; |
| 77 payload.max_bitrate = 2000; | |
| 78 return payload; | 81 return payload; |
| 79 } | 82 } |
| 80 | 83 |
| 81 CastRtpPayloadParams DefaultH264Payload() { | 84 CastRtpPayloadParams DefaultH264Payload() { |
| 82 CastRtpPayloadParams payload; | 85 CastRtpPayloadParams payload; |
| 83 // TODO(hshi): set different ssrc/rtpPayloadType values for H264 and VP8 | 86 // TODO(hshi): set different ssrc/rtpPayloadType values for H264 and VP8 |
| 84 // once b/13696137 is fixed. | 87 // once b/13696137 is fixed. |
| 88 payload.payload_type = 96; |
| 89 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; |
| 85 payload.ssrc = 11; | 90 payload.ssrc = 11; |
| 86 payload.feedback_ssrc = 12; | 91 payload.feedback_ssrc = 12; |
| 87 payload.payload_type = 96; | 92 payload.clock_rate = media::cast::kVideoFrequency; |
| 88 payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; | 93 payload.max_bitrate = 2000; |
| 89 payload.codec_name = kCodecNameH264; | 94 payload.min_bitrate = 50; |
| 90 payload.clock_rate = 90000; | 95 payload.channels = 1; |
| 96 payload.max_frame_rate = media::cast::kDefaultMaxFrameRate; |
| 91 payload.width = 1280; | 97 payload.width = 1280; |
| 92 payload.height = 720; | 98 payload.height = 720; |
| 93 payload.min_bitrate = 50; | 99 payload.codec_name = kCodecNameH264; |
| 94 payload.max_bitrate = 2000; | |
| 95 return payload; | 100 return payload; |
| 96 } | 101 } |
| 97 | 102 |
| 98 bool IsHardwareVP8EncodingSupported() { | 103 bool IsHardwareVP8EncodingSupported() { |
| 99 // Query for hardware VP8 encoder support. | 104 // Query for hardware VP8 encoder support. |
| 100 std::vector<media::VideoEncodeAccelerator::SupportedProfile> vea_profiles = | 105 std::vector<media::VideoEncodeAccelerator::SupportedProfile> vea_profiles = |
| 101 content::GetSupportedVideoEncodeAcceleratorProfiles(); | 106 content::GetSupportedVideoEncodeAcceleratorProfiles(); |
| 102 for (size_t i = 0; i < vea_profiles.size(); ++i) { | 107 for (size_t i = 0; i < vea_profiles.size(); ++i) { |
| 103 if (vea_profiles[i].profile >= media::VP8PROFILE_MIN && | 108 if (vea_profiles[i].profile >= media::VP8PROFILE_MIN && |
| 104 vea_profiles[i].profile <= media::VP8PROFILE_MAX) { | 109 vea_profiles[i].profile <= media::VP8PROFILE_MAX) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 return false; | 190 return false; |
| 186 config->target_playout_delay = | 191 config->target_playout_delay = |
| 187 base::TimeDelta::FromMilliseconds(params.payload.max_latency_ms); | 192 base::TimeDelta::FromMilliseconds(params.payload.max_latency_ms); |
| 188 if (config->target_playout_delay <= base::TimeDelta()) | 193 if (config->target_playout_delay <= base::TimeDelta()) |
| 189 return false; | 194 return false; |
| 190 config->rtp_payload_type = params.payload.payload_type; | 195 config->rtp_payload_type = params.payload.payload_type; |
| 191 config->width = params.payload.width; | 196 config->width = params.payload.width; |
| 192 config->height = params.payload.height; | 197 config->height = params.payload.height; |
| 193 if (config->width < 2 || config->height < 2) | 198 if (config->width < 2 || config->height < 2) |
| 194 return false; | 199 return false; |
| 195 // TODO(miu): Should the frame rate be parsed from the |params|? | |
| 196 config->max_frame_rate = 30; | |
| 197 config->min_bitrate = config->start_bitrate = | 200 config->min_bitrate = config->start_bitrate = |
| 198 params.payload.min_bitrate * kBitrateMultiplier; | 201 params.payload.min_bitrate * kBitrateMultiplier; |
| 199 config->max_bitrate = params.payload.max_bitrate * kBitrateMultiplier; | 202 config->max_bitrate = params.payload.max_bitrate * kBitrateMultiplier; |
| 200 if (config->min_bitrate > config->max_bitrate) | 203 if (config->min_bitrate > config->max_bitrate) |
| 201 return false; | 204 return false; |
| 202 config->start_bitrate = config->min_bitrate; | 205 config->start_bitrate = config->min_bitrate; |
| 206 config->max_frame_rate = static_cast<int>( |
| 207 std::max(1.0, params.payload.max_frame_rate) + 0.5); |
| 208 if (config->max_frame_rate > 120) |
| 209 return false; |
| 203 if (params.payload.codec_name == kCodecNameVp8) { | 210 if (params.payload.codec_name == kCodecNameVp8) { |
| 204 config->use_external_encoder = IsHardwareVP8EncodingSupported(); | 211 config->use_external_encoder = IsHardwareVP8EncodingSupported(); |
| 205 config->codec = media::cast::CODEC_VIDEO_VP8; | 212 config->codec = media::cast::CODEC_VIDEO_VP8; |
| 206 } else if (params.payload.codec_name == kCodecNameH264) { | 213 } else if (params.payload.codec_name == kCodecNameH264) { |
| 207 config->use_external_encoder = IsHardwareH264EncodingSupported(); | 214 config->use_external_encoder = IsHardwareH264EncodingSupported(); |
| 208 config->codec = media::cast::CODEC_VIDEO_H264; | 215 config->codec = media::cast::CODEC_VIDEO_H264; |
| 209 } else { | 216 } else { |
| 210 return false; | 217 return false; |
| 211 } | 218 } |
| 212 if (!config->use_external_encoder) { | 219 if (!config->use_external_encoder) { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 | 463 |
| 457 CastRtpPayloadParams::CastRtpPayloadParams() | 464 CastRtpPayloadParams::CastRtpPayloadParams() |
| 458 : payload_type(0), | 465 : payload_type(0), |
| 459 max_latency_ms(0), | 466 max_latency_ms(0), |
| 460 ssrc(0), | 467 ssrc(0), |
| 461 feedback_ssrc(0), | 468 feedback_ssrc(0), |
| 462 clock_rate(0), | 469 clock_rate(0), |
| 463 max_bitrate(0), | 470 max_bitrate(0), |
| 464 min_bitrate(0), | 471 min_bitrate(0), |
| 465 channels(0), | 472 channels(0), |
| 473 max_frame_rate(0.0), |
| 466 width(0), | 474 width(0), |
| 467 height(0) {} | 475 height(0) {} |
| 468 | 476 |
| 469 CastRtpPayloadParams::~CastRtpPayloadParams() {} | 477 CastRtpPayloadParams::~CastRtpPayloadParams() {} |
| 470 | 478 |
| 471 CastRtpParams::CastRtpParams() {} | 479 CastRtpParams::CastRtpParams() {} |
| 472 | 480 |
| 473 CastRtpParams::~CastRtpParams() {} | 481 CastRtpParams::~CastRtpParams() {} |
| 474 | 482 |
| 475 CastRtpStream::CastRtpStream(const blink::WebMediaStreamTrack& track, | 483 CastRtpStream::CastRtpStream(const blink::WebMediaStreamTrack& track, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 void CastRtpStream::DidEncounterError(const std::string& message) { | 581 void CastRtpStream::DidEncounterError(const std::string& message) { |
| 574 VLOG(1) << "CastRtpStream::DidEncounterError(" << message << ") = " | 582 VLOG(1) << "CastRtpStream::DidEncounterError(" << message << ") = " |
| 575 << (IsAudio() ? "audio" : "video"); | 583 << (IsAudio() ? "audio" : "video"); |
| 576 // Save the WeakPtr first because the error callback might delete this object. | 584 // Save the WeakPtr first because the error callback might delete this object. |
| 577 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); | 585 base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr(); |
| 578 error_callback_.Run(message); | 586 error_callback_.Run(message); |
| 579 content::RenderThread::Get()->GetMessageLoop()->PostTask( | 587 content::RenderThread::Get()->GetMessageLoop()->PostTask( |
| 580 FROM_HERE, | 588 FROM_HERE, |
| 581 base::Bind(&CastRtpStream::Stop, ptr)); | 589 base::Bind(&CastRtpStream::Stop, ptr)); |
| 582 } | 590 } |
| OLD | NEW |