Commit 0a2e8662 authored by hclam@chromium.org's avatar hclam@chromium.org

Data type conversion between extensions API and Cast API

Converts to and from Cast API types. Also fixed a couple issues to
match the API between Cast and Extensions API.

Cast Extensions API is now fully redirected to Cast native APIs. Minus
the conversion of MediaStreamTrack.

BUG=301920

Review URL: https://codereview.chromium.org/47343005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233366 0039d316-1c4b-4281-b951-d872f2087c98
parent 88562b51
...@@ -2,12 +2,20 @@ ...@@ -2,12 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace extensions { namespace extensions {
class WebrtcCastApiTest : public ExtensionApiTest { class WebrtcCastApiTest : public ExtensionApiTest {
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(
switches::kWhitelistedExtensionID,
"ddchlicdkolnonkihahngkmmmjnjlkkf");
}
}; };
// Test running the test extension for Cast Mirroring API. // Test running the test extension for Cast Mirroring API.
......
...@@ -37,7 +37,7 @@ namespace webrtc.castSendTransport { ...@@ -37,7 +37,7 @@ namespace webrtc.castSendTransport {
long? height; long? height;
// A list of codec specific params. // A list of codec specific params.
CodecSpecificParams[] codecSpecficParams; CodecSpecificParams[] codecSpecificParams;
}; };
// Cast transport capabilities // Cast transport capabilities
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "chrome/renderer/extensions/webrtc_native_handler.h" #include "chrome/renderer/extensions/webrtc_native_handler.h"
#include <functional>
#include "base/logging.h" #include "base/logging.h"
#include "chrome/common/extensions/api/webrtc_cast_send_transport.h" #include "chrome/common/extensions/api/webrtc_cast_send_transport.h"
#include "chrome/common/extensions/api/webrtc_cast_udp_transport.h" #include "chrome/common/extensions/api/webrtc_cast_udp_transport.h"
...@@ -17,6 +19,7 @@ ...@@ -17,6 +19,7 @@
using content::V8ValueConverter; using content::V8ValueConverter;
// Extension types. // Extension types.
using extensions::api::webrtc_cast_send_transport::CodecSpecificParams;
using extensions::api::webrtc_cast_send_transport::RtpCaps; using extensions::api::webrtc_cast_send_transport::RtpCaps;
using extensions::api::webrtc_cast_send_transport::RtpParams; using extensions::api::webrtc_cast_send_transport::RtpParams;
using extensions::api::webrtc_cast_send_transport::RtpPayloadParams; using extensions::api::webrtc_cast_send_transport::RtpPayloadParams;
...@@ -32,30 +35,119 @@ const char kInvalidUdpParams[] = "Invalid UDP params"; ...@@ -32,30 +35,119 @@ const char kInvalidUdpParams[] = "Invalid UDP params";
const char kInvalidRtpCaps[] = "Invalid value for RTP caps"; const char kInvalidRtpCaps[] = "Invalid value for RTP caps";
const char kInvalidRtpParams[] = "Invalid value for RTP params"; const char kInvalidRtpParams[] = "Invalid value for RTP params";
const char kUnableToConvertArgs[] = "Unable to convert arguments"; const char kUnableToConvertArgs[] = "Unable to convert arguments";
const char kUnableToConvertCaps[] = "Unable to convert caps";
const char kUnableToConvertParams[] = "Unable to convert params"; const char kUnableToConvertParams[] = "Unable to convert params";
// These helper methods are used to convert between Extension API // These helper methods are used to convert between Extension API
// types and Cast types. // types and Cast types.
bool ToCastRtpCaps(const RtpCaps& ext_caps, CastRtpCaps* cast_caps) { void ToCastCodecSpecificParams(const CodecSpecificParams& ext_params,
NOTIMPLEMENTED(); CastCodecSpecificParams* cast_params) {
return true; cast_params->key = ext_params.key;
cast_params->value = ext_params.value;
}
void FromCastCodecSpecificParams(const CastCodecSpecificParams& cast_params,
CodecSpecificParams* ext_params) {
ext_params->key = cast_params.key;
ext_params->value = cast_params.value;
}
void ToCastRtpPayloadParams(const RtpPayloadParams& ext_params,
CastRtpPayloadParams* cast_params) {
cast_params->payload_type = ext_params.payload_type;
cast_params->codec_name = ext_params.codec_name;
cast_params->ssrc = ext_params.ssrc ? *ext_params.ssrc : 0;
cast_params->clock_rate = ext_params.clock_rate ? *ext_params.clock_rate : 0;
cast_params->min_bitrate =
ext_params.min_bitrate ? *ext_params.min_bitrate : 0;
cast_params->max_bitrate =
ext_params.max_bitrate ? *ext_params.max_bitrate : 0;
cast_params->channels = ext_params.channels ? *ext_params.channels : 0;
cast_params->width = ext_params.width ? *ext_params.width : 0;
cast_params->height = ext_params.height ? *ext_params.height : 0;
for (size_t i = 0; i < ext_params.codec_specific_params.size(); ++i) {
CastCodecSpecificParams cast_codec_params;
ToCastCodecSpecificParams(*ext_params.codec_specific_params[i],
&cast_codec_params);
cast_params->codec_specific_params.push_back(cast_codec_params);
}
} }
bool FromCastRtpCaps(const CastRtpCaps& cast_caps, RtpCaps* ext_caps) { void FromCastRtpPayloadParams(const CastRtpPayloadParams& cast_params,
NOTIMPLEMENTED(); RtpPayloadParams* ext_params) {
return true; ext_params->payload_type = cast_params.payload_type;
ext_params->codec_name = cast_params.codec_name;
if (cast_params.ssrc)
ext_params->ssrc.reset(new int(cast_params.ssrc));
if (cast_params.clock_rate)
ext_params->clock_rate.reset(new int(cast_params.clock_rate));
if (cast_params.min_bitrate)
ext_params->min_bitrate.reset(new int(cast_params.min_bitrate));
if (cast_params.max_bitrate)
ext_params->max_bitrate.reset(new int(cast_params.max_bitrate));
if (cast_params.channels)
ext_params->channels.reset(new int(cast_params.channels));
if (cast_params.width)
ext_params->width.reset(new int(cast_params.width));
if (cast_params.height)
ext_params->height.reset(new int(cast_params.height));
for (size_t i = 0; i < cast_params.codec_specific_params.size(); ++i) {
linked_ptr<CodecSpecificParams> ext_codec_params(
new CodecSpecificParams());
FromCastCodecSpecificParams(cast_params.codec_specific_params[i],
ext_codec_params.get());
ext_params->codec_specific_params.push_back(ext_codec_params);
}
} }
bool ToCastRtpParams(const RtpParams& ext_params, CastRtpParams* cast_params) { void ToCastRtpCaps(const RtpCaps& ext_caps, CastRtpCaps* cast_caps) {
NOTIMPLEMENTED(); std::copy(ext_caps.rtcp_features.begin(), ext_caps.rtcp_features.end(),
return true; cast_caps->rtcp_features.begin());
std::copy(ext_caps.fec_mechanisms.begin(), ext_caps.fec_mechanisms.end(),
cast_caps->fec_mechanisms.begin());
for (size_t i = 0; i < ext_caps.payloads.size(); ++i) {
CastRtpPayloadParams cast_payload_params;
ToCastRtpPayloadParams(*ext_caps.payloads[i], &cast_payload_params);
cast_caps->payloads.push_back(cast_payload_params);
}
} }
bool FromCastRtpParams(const CastRtpParams& cast_params, void FromCastRtpCaps(const CastRtpCaps& cast_caps, RtpCaps* ext_caps) {
std::copy(cast_caps.rtcp_features.begin(), cast_caps.rtcp_features.end(),
ext_caps->rtcp_features.begin());
std::copy(cast_caps.fec_mechanisms.begin(), cast_caps.fec_mechanisms.end(),
ext_caps->fec_mechanisms.begin());
for (size_t i = 0; i < cast_caps.payloads.size(); ++i) {
linked_ptr<RtpPayloadParams> ext_payload_params(new RtpPayloadParams());
FromCastRtpPayloadParams(cast_caps.payloads[i], ext_payload_params.get());
ext_caps->payloads.push_back(ext_payload_params);
}
}
void ToCastRtpParams(const RtpParams& ext_params, CastRtpParams* cast_params) {
std::copy(ext_params.rtcp_features.begin(), ext_params.rtcp_features.end(),
cast_params->rtcp_features.begin());
std::copy(ext_params.fec_mechanisms.begin(), ext_params.fec_mechanisms.end(),
cast_params->fec_mechanisms.begin());
for (size_t i = 0; i < ext_params.payloads.size(); ++i) {
CastRtpPayloadParams cast_payload_params;
ToCastRtpPayloadParams(*ext_params.payloads[i], &cast_payload_params);
cast_params->payloads.push_back(cast_payload_params);
}
}
void FromCastRtpParams(const CastRtpParams& cast_params,
RtpParams* ext_params) { RtpParams* ext_params) {
NOTIMPLEMENTED(); std::copy(cast_params.rtcp_features.begin(), cast_params.rtcp_features.end(),
return true; ext_params->rtcp_features.begin());
std::copy(cast_params.fec_mechanisms.begin(),
cast_params.fec_mechanisms.end(),
ext_params->fec_mechanisms.begin());
for (size_t i = 0; i < cast_params.payloads.size(); ++i) {
linked_ptr<RtpPayloadParams> ext_payload_params(new RtpPayloadParams());
FromCastRtpPayloadParams(cast_params.payloads[i],
ext_payload_params.get());
ext_params->payloads.push_back(ext_payload_params);
}
} }
} // namespace } // namespace
...@@ -162,18 +254,10 @@ void WebRtcNativeHandler::CreateParamsCastSendTransport( ...@@ -162,18 +254,10 @@ void WebRtcNativeHandler::CreateParamsCastSendTransport(
} }
CastRtpCaps cast_remote_caps; CastRtpCaps cast_remote_caps;
if (!ToCastRtpCaps(*remote_caps, &cast_remote_caps)) { ToCastRtpCaps(*remote_caps, &cast_remote_caps);
v8::ThrowException(v8::Exception::TypeError(v8::String::New(
kUnableToConvertCaps)));
return;
}
CastRtpParams cast_params = transport->CreateParams(cast_remote_caps); CastRtpParams cast_params = transport->CreateParams(cast_remote_caps);
RtpParams params; RtpParams params;
if (!FromCastRtpParams(cast_params, &params)) { FromCastRtpParams(cast_params, &params);
v8::ThrowException(v8::Exception::TypeError(v8::String::New(
kUnableToConvertParams)));
return;
}
scoped_ptr<base::DictionaryValue> params_value = params.ToValue(); scoped_ptr<base::DictionaryValue> params_value = params.ToValue();
v8::Handle<v8::Value> params_v8 = converter->ToV8Value( v8::Handle<v8::Value> params_v8 = converter->ToV8Value(
...@@ -195,11 +279,7 @@ void WebRtcNativeHandler::GetCapsCastSendTransport( ...@@ -195,11 +279,7 @@ void WebRtcNativeHandler::GetCapsCastSendTransport(
CastRtpCaps cast_caps = transport->GetCaps(); CastRtpCaps cast_caps = transport->GetCaps();
RtpCaps caps; RtpCaps caps;
if (!FromCastRtpCaps(cast_caps, &caps)) { FromCastRtpCaps(cast_caps, &caps);
v8::ThrowException(v8::Exception::TypeError(v8::String::New(
kUnableToConvertCaps)));
return;
}
scoped_ptr<base::DictionaryValue> caps_value = caps.ToValue(); scoped_ptr<base::DictionaryValue> caps_value = caps.ToValue();
scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
...@@ -236,11 +316,7 @@ void WebRtcNativeHandler::StartCastSendTransport( ...@@ -236,11 +316,7 @@ void WebRtcNativeHandler::StartCastSendTransport(
} }
CastRtpCaps cast_params; CastRtpCaps cast_params;
if (!ToCastRtpParams(*params, &cast_params)) { ToCastRtpParams(*params, &cast_params);
v8::ThrowException(v8::Exception::TypeError(v8::String::New(
kUnableToConvertParams)));
return;
}
transport->Start(cast_params); transport->Start(cast_params);
} }
......
...@@ -18,7 +18,8 @@ CastRtpPayloadParams::CastRtpPayloadParams() ...@@ -18,7 +18,8 @@ CastRtpPayloadParams::CastRtpPayloadParams()
: payload_type(0), : payload_type(0),
ssrc(0), ssrc(0),
clock_rate(0), clock_rate(0),
bitrate(0), max_bitrate(0),
min_bitrate(0),
channels(0), channels(0),
width(0), width(0),
height(0) { height(0) {
......
...@@ -38,8 +38,11 @@ struct CastRtpPayloadParams { ...@@ -38,8 +38,11 @@ struct CastRtpPayloadParams {
// Update frequency of payload sample. // Update frequency of payload sample.
int clock_rate; int clock_rate;
// Uncompressed bitrate. // Maximum bitrate.
int bitrate; int max_bitrate;
// Minimum bitrate.
int min_bitrate;
// Number of audio channels. // Number of audio channels.
int channels; int channels;
...@@ -67,7 +70,7 @@ struct CastRtpCaps { ...@@ -67,7 +70,7 @@ struct CastRtpCaps {
std::vector<std::string> rtcp_features; std::vector<std::string> rtcp_features;
// Names of supported FEC (Forward Error Correction) mechanisms. // Names of supported FEC (Forward Error Correction) mechanisms.
std::vector<std::string> fec_mechanism; std::vector<std::string> fec_mechanisms;
CastRtpCaps(); CastRtpCaps();
~CastRtpCaps(); ~CastRtpCaps();
...@@ -84,7 +87,7 @@ class CastSendTransport { ...@@ -84,7 +87,7 @@ class CastSendTransport {
explicit CastSendTransport(CastUdpTransport* udp_transport); explicit CastSendTransport(CastUdpTransport* udp_transport);
~CastSendTransport(); ~CastSendTransport();
// Return capabilities currently spported by this transport. // Return capabilities currently supported by this transport.
CastRtpCaps GetCaps(); CastRtpCaps GetCaps();
// Return parameters set to this transport. // Return parameters set to this transport.
......
...@@ -2,15 +2,103 @@ ...@@ -2,15 +2,103 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
var sendTransport = chrome.webrtc.castSendTransport;
var tabCapture = chrome.tabCapture;
var udpTransport = chrome.webrtc.castUdpTransport;
chrome.test.runTests([ chrome.test.runTests([
function udpTransport() { function udpTransportCreate() {
chrome.webrtc.castUdpTransport.create(function(info) { udpTransport.create(function(info) {
chrome.webrtc.castUdpTransport.start( udpTransport.start(
info.transportId, info.transportId,
{address: "127.0.0.1", port: 60613}); {address: "127.0.0.1", port: 60613});
chrome.webrtc.castUdpTransport.stop(info.transportId); udpTransport.stop(info.transportId);
chrome.webrtc.castUdpTransport.destroy(info.transportId); udpTransport.destroy(info.transportId);
chrome.test.succeed(); chrome.test.succeed();
}); });
} },
function sendTransportCreate() {
tabCapture.capture({audio: true}, function(stream) {
chrome.test.assertTrue(!!stream);
udpTransport.create(function(stream, udpInfo) {
sendTransport.create(
udpInfo.transportId,
stream.getAudioTracks()[0],
function(stream, udpInfo, sendTransportId) {
sendTransport.destroy(sendTransportId);
udpTransport.destroy(udpInfo.transportId);
stream.stop();
chrome.test.succeed();
}.bind(null, stream, udpInfo));
}.bind(null, stream));
});
},
function sendTransportGetCaps() {
tabCapture.capture({audio: true}, function(stream) {
chrome.test.assertTrue(!!stream);
udpTransport.create(function(stream, udpInfo) {
sendTransport.create(
udpInfo.transportId,
stream.getAudioTracks()[0],
function(stream, udpInfo, sendTransportId) {
sendTransport.getCaps(sendTransportId, function(
stream, udpInfo, sendTransportId, caps) {
sendTransport.destroy(sendTransportId);
udpTransport.destroy(udpInfo.transportId);
stream.stop();
chrome.test.succeed();
}.bind(null, stream, udpInfo, sendTransportId));
}.bind(null, stream, udpInfo));
}.bind(null, stream));
});
},
function sendTransportCreateParams() {
tabCapture.capture({audio: true}, function(stream) {
chrome.test.assertTrue(!!stream);
udpTransport.create(function(stream, udpInfo) {
sendTransport.create(
udpInfo.transportId,
stream.getAudioTracks()[0],
function(stream, udpInfo, sendTransportId) {
// TODO(hclam): Pass a valid value for |remoteCaps|.
var remoteCaps = {
payloads: [],
rtcpFeatures: [],
fecMechanisms: [],
};
sendTransport.createParams(sendTransportId, remoteCaps, function(
stream, udpInfo, sendTransportId, caps) {
sendTransport.destroy(sendTransportId);
udpTransport.destroy(udpInfo.transportId);
stream.stop();
chrome.test.succeed();
}.bind(null, stream, udpInfo, sendTransportId));
}.bind(null, stream, udpInfo));
}.bind(null, stream));
});
},
function sendTransportStart() {
tabCapture.capture({audio: true}, function(stream) {
chrome.test.assertTrue(!!stream);
udpTransport.create(function(stream, udpInfo) {
sendTransport.create(
udpInfo.transportId,
stream.getAudioTracks()[0],
function(stream, udpInfo, sendTransportId) {
// TODO(hclam): Pass a valid value for |params|.
var params = {
payloads: [],
rtcpFeatures: [],
fecMechanisms: [],
};
sendTransport.start(sendTransportId, params);
sendTransport.stop(sendTransportId);
sendTransport.destroy(sendTransportId);
udpTransport.destroy(udpInfo.transportId);
stream.stop();
chrome.test.succeed();
}.bind(null, stream, udpInfo));
}.bind(null, stream));
});
},
]); ]);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment