| Index: chrome/renderer/extensions/cast_streaming_native_handler.cc
|
| diff --git a/chrome/renderer/extensions/cast_streaming_native_handler.cc b/chrome/renderer/extensions/cast_streaming_native_handler.cc
|
| index 62e00874db792593103b84d7b4ec0fad22054e6a..4fdaf2a2aef307aa8cefdece6af54d001300c549 100644
|
| --- a/chrome/renderer/extensions/cast_streaming_native_handler.cc
|
| +++ b/chrome/renderer/extensions/cast_streaming_native_handler.cc
|
| @@ -32,6 +32,7 @@
|
| #include "chrome/renderer/media/cast_udp_transport.h"
|
| #include "content/public/child/v8_value_converter.h"
|
| #include "content/public/renderer/media_stream_utils.h"
|
| +#include "extensions/common/extension.h"
|
| #include "extensions/renderer/script_context.h"
|
| #include "media/base/audio_parameters.h"
|
| #include "media/base/limits.h"
|
| @@ -74,6 +75,8 @@ constexpr char kUnableToConvertParams[] = "Unable to convert params";
|
| constexpr char kCodecNameOpus[] = "OPUS";
|
| constexpr char kCodecNameVp8[] = "VP8";
|
| constexpr char kCodecNameH264[] = "H264";
|
| +constexpr char kCodecNameRemoteAudio[] = "REMOTE_AUDIO";
|
| +constexpr char kCodecNameRemoteVideo[] = "REMOTE_VIDEO";
|
|
|
| // To convert from kilobits per second to bits per second.
|
| constexpr int kBitsPerKilobit = 1000;
|
| @@ -213,6 +216,12 @@ bool ToFrameSenderConfigOrThrow(v8::Isolate* isolate,
|
| if (!config->use_external_encoder)
|
| config->video_codec_params.number_of_encode_threads =
|
| NumberOfEncodeThreads();
|
| + } else if (ext_params.codec_name == kCodecNameRemoteAudio) {
|
| + config->rtp_payload_type = media::cast::RtpPayloadType::REMOTE_AUDIO;
|
| + config->codec = media::cast::CODEC_AUDIO_REMOTE;
|
| + } else if (ext_params.codec_name == kCodecNameRemoteVideo) {
|
| + config->rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
|
| + config->codec = media::cast::CODEC_VIDEO_REMOTE;
|
| } else {
|
| DVLOG(1) << "codec_name " << ext_params.codec_name << " is invalid";
|
| isolate->ThrowException(v8::Exception::Error(
|
| @@ -251,6 +260,12 @@ void FromFrameSenderConfig(const FrameSenderConfig& config,
|
| case media::cast::CODEC_VIDEO_H264:
|
| ext_params->codec_name = kCodecNameH264;
|
| break;
|
| + case media::cast::CODEC_AUDIO_REMOTE:
|
| + ext_params->codec_name = kCodecNameRemoteAudio;
|
| + break;
|
| + case media::cast::CODEC_VIDEO_REMOTE:
|
| + ext_params->codec_name = kCodecNameRemoteVideo;
|
| + break;
|
| default:
|
| NOTREACHED();
|
| }
|
| @@ -272,9 +287,19 @@ void FromFrameSenderConfig(const FrameSenderConfig& config,
|
|
|
| } // namespace
|
|
|
| +// |last_transport_id_| is the identifier for the next created RTP stream. To
|
| +// create globally unique IDs used for referring to RTP stream objects in
|
| +// browser process, we set its higher 16 bits as HASH(extension_id)&0x7fff, and
|
| +// lower 16 bits as the sequence number of the RTP stream created in the same
|
| +// extension. Collision will happen when the first RTP stream keeps alive after
|
| +// creating another 64k-1 RTP streams in the same extension, which is very
|
| +// unlikely to happen in normal use cases.
|
| CastStreamingNativeHandler::CastStreamingNativeHandler(ScriptContext* context)
|
| : ObjectBackedNativeHandler(context),
|
| - last_transport_id_(1),
|
| + last_transport_id_(
|
| + context->extension()
|
| + ? (((base::Hash(context->extension()->id()) & 0x7fff) << 16) + 1)
|
| + : 1),
|
| weak_factory_(this) {
|
| RouteFunction("CreateSession", "cast.streaming.session",
|
| base::Bind(&CastStreamingNativeHandler::CreateCastSession,
|
| @@ -343,36 +368,40 @@ void CastStreamingNativeHandler::CreateCastSession(
|
| CHECK(args[2]->IsFunction());
|
|
|
| v8::Isolate* isolate = context()->v8_context()->GetIsolate();
|
| - if ((args[0]->IsNull() || args[0]->IsUndefined()) &&
|
| - (args[1]->IsNull() || args[1]->IsUndefined())) {
|
| - isolate->ThrowException(v8::Exception::Error(
|
| - v8::String::NewFromUtf8(isolate, kInvalidStreamArgs)));
|
| - return;
|
| - }
|
|
|
| scoped_refptr<CastSession> session(new CastSession());
|
| std::unique_ptr<CastRtpStream> stream1, stream2;
|
| - if (!args[0]->IsNull() && !args[0]->IsUndefined()) {
|
| - CHECK(args[0]->IsObject());
|
| - blink::WebDOMMediaStreamTrack track =
|
| - blink::WebDOMMediaStreamTrack::fromV8Value(args[0]);
|
| - if (track.isNull()) {
|
| - isolate->ThrowException(v8::Exception::Error(
|
| - v8::String::NewFromUtf8(isolate, kInvalidStreamArgs)));
|
| - return;
|
| + if ((args[0]->IsNull() || args[0]->IsUndefined()) &&
|
| + (args[1]->IsNull() || args[1]->IsUndefined())) {
|
| + DVLOG(3) << "CreateCastSession for remoting.";
|
| + // Creates audio/video RTP streams for media remoting.
|
| + stream1.reset(new CastRtpStream(true, session));
|
| + stream2.reset(new CastRtpStream(false, session));
|
| + } else {
|
| + // Creates RTP streams that consume from an audio and/or a video
|
| + // MediaStreamTrack.
|
| + if (!args[0]->IsNull() && !args[0]->IsUndefined()) {
|
| + CHECK(args[0]->IsObject());
|
| + blink::WebDOMMediaStreamTrack track =
|
| + blink::WebDOMMediaStreamTrack::fromV8Value(args[0]);
|
| + if (track.isNull()) {
|
| + isolate->ThrowException(v8::Exception::Error(
|
| + v8::String::NewFromUtf8(isolate, kInvalidStreamArgs)));
|
| + return;
|
| + }
|
| + stream1.reset(new CastRtpStream(track.component(), session));
|
| }
|
| - stream1.reset(new CastRtpStream(track.component(), session));
|
| - }
|
| - if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
|
| - CHECK(args[1]->IsObject());
|
| - blink::WebDOMMediaStreamTrack track =
|
| - blink::WebDOMMediaStreamTrack::fromV8Value(args[1]);
|
| - if (track.isNull()) {
|
| - isolate->ThrowException(v8::Exception::Error(
|
| - v8::String::NewFromUtf8(isolate, kInvalidStreamArgs)));
|
| - return;
|
| + if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
|
| + CHECK(args[1]->IsObject());
|
| + blink::WebDOMMediaStreamTrack track =
|
| + blink::WebDOMMediaStreamTrack::fromV8Value(args[1]);
|
| + if (track.isNull()) {
|
| + isolate->ThrowException(v8::Exception::Error(
|
| + v8::String::NewFromUtf8(isolate, kInvalidStreamArgs)));
|
| + return;
|
| + }
|
| + stream2.reset(new CastRtpStream(track.component(), session));
|
| }
|
| - stream2.reset(new CastRtpStream(track.component(), session));
|
| }
|
| std::unique_ptr<CastUdpTransport> udp_transport(
|
| new CastUdpTransport(session));
|
| @@ -529,7 +558,10 @@ void CastStreamingNativeHandler::StartCastRtpStream(
|
| base::Bind(&CastStreamingNativeHandler::CallErrorCallback,
|
| weak_factory_.GetWeakPtr(),
|
| transport_id);
|
| - transport->Start(config, start_callback, stop_callback, error_callback);
|
| +
|
| + // |transport_id| is a globally unique identifier for the RTP stream.
|
| + transport->Start(transport_id, config, start_callback, stop_callback,
|
| + error_callback);
|
| }
|
|
|
| void CastStreamingNativeHandler::StopCastRtpStream(
|
|
|