blob: 5c8e65675b0380034ed70ad88d6d465010681856 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/media_stream_center.h"
#include <string>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/renderer/media/media_stream_impl.h"
#include "content/renderer/media/media_stream_extra_data.h"
#include "content/renderer/render_view_impl.h"
#include "third_party/libjingle/source/talk/app/webrtc/jsep.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebICECandidateDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamCenterClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamComponent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSource.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSourcesRequest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSessionDescriptionDescriptor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
namespace content {
static MediaStreamImpl* GetMediaStreamImpl(WebKit::WebFrame* web_frame) {
RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
if (!render_view)
return NULL;
// TODO(perkj): Avoid this cast?
return static_cast<MediaStreamImpl*>(render_view->userMediaClient());
}
static webrtc::MediaStreamInterface* GetNativeMediaStream(
const WebKit::WebMediaStreamDescriptor& stream) {
MediaStreamExtraData* extra_data =
static_cast<MediaStreamExtraData*>(stream.extraData());
if (extra_data && extra_data->remote_stream())
return extra_data->remote_stream();
if (extra_data && extra_data->local_stream())
return extra_data->local_stream();
// TODO(perkj): This can occur if a JS create a new MediaStream based on an
// existing MediaStream.
NOTIMPLEMENTED();
return NULL;
}
template <class TrackList>
static webrtc::MediaStreamTrackInterface* GetTrack(
const std::string& source_id,
TrackList* tracks) {
for (size_t i = 0; i < tracks->count(); ++i) {
if (tracks->at(i)->label() == source_id)
return tracks->at(i);
}
return NULL;
}
static webrtc::MediaStreamTrackInterface* GetNativeMediaStreamTrack(
const WebKit::WebMediaStreamDescriptor& stream,
const WebKit::WebMediaStreamComponent& component) {
std::string source_id = UTF16ToUTF8(component.source().id());
webrtc::MediaStreamInterface* native_stream = GetNativeMediaStream(stream);
if (native_stream) {
if (component.source().type() == WebKit::WebMediaStreamSource::TypeAudio) {
return GetTrack<webrtc::AudioTracks>(
source_id, native_stream->audio_tracks());
}
if (component.source().type() == WebKit::WebMediaStreamSource::TypeVideo) {
return GetTrack<webrtc::VideoTracks>(
source_id, native_stream->video_tracks());
}
}
// TODO(perkj): This can occur if a JS create a new MediaStream based on an
// existing MediaStream.
NOTIMPLEMENTED();
return NULL;
}
MediaStreamCenter::MediaStreamCenter(
WebKit::WebMediaStreamCenterClient* client)
: client_(client) {
}
void MediaStreamCenter::queryMediaStreamSources(
const WebKit::WebMediaStreamSourcesRequest& request) {
WebKit::WebVector<WebKit::WebMediaStreamSource> audioSources, videoSources;
request.didCompleteQuery(audioSources, videoSources);
}
void MediaStreamCenter::didEnableMediaStreamTrack(
const WebKit::WebMediaStreamDescriptor& stream,
const WebKit::WebMediaStreamComponent& component) {
webrtc::MediaStreamTrackInterface* track =
GetNativeMediaStreamTrack(stream, component);
if (track)
track->set_enabled(true);
}
void MediaStreamCenter::didDisableMediaStreamTrack(
const WebKit::WebMediaStreamDescriptor& stream,
const WebKit::WebMediaStreamComponent& component) {
webrtc::MediaStreamTrackInterface* track =
GetNativeMediaStreamTrack(stream, component);
if (track)
track->set_enabled(false);
}
void MediaStreamCenter::didStopLocalMediaStream(
const WebKit::WebMediaStreamDescriptor& stream) {
DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext();
if (!web_frame)
return;
MediaStreamImpl* ms_impl = GetMediaStreamImpl(web_frame);
if (ms_impl) {
ms_impl->StopLocalMediaStream(stream);
return;
}
NOTREACHED();
}
void MediaStreamCenter::didCreateMediaStream(
WebKit::WebMediaStreamDescriptor& stream) {
WebKit::WebFrame* web_frame = WebKit::WebFrame::frameForCurrentContext();
if (!web_frame)
return;
MediaStreamImpl* ms_impl = GetMediaStreamImpl(web_frame);
if (ms_impl) {
ms_impl->CreateMediaStream(web_frame, &stream);
return;
}
NOTREACHED();
}
WebKit::WebString MediaStreamCenter::constructSDP(
const WebKit::WebICECandidateDescriptor& candidate) {
int m_line_index = -1;
if (!base::StringToInt(UTF16ToUTF8(candidate.label()), &m_line_index)) {
LOG(ERROR) << "Invalid candidate label: " << UTF16ToUTF8(candidate.label());
return WebKit::WebString();
}
scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
m_line_index,
UTF16ToUTF8(candidate.candidateLine())));
std::string sdp;
if (!native_candidate->ToString(&sdp))
LOG(ERROR) << "Could not create SDP string";
return UTF8ToUTF16(sdp);
}
WebKit::WebString MediaStreamCenter::constructSDP(
const WebKit::WebSessionDescriptionDescriptor& description) {
scoped_ptr<webrtc::SessionDescriptionInterface> native_desc(
webrtc::CreateSessionDescription(UTF16ToUTF8(description.initialSDP())));
if (!native_desc.get())
return WebKit::WebString();
for (size_t i = 0; i < description.numberOfAddedCandidates(); ++i) {
WebKit::WebICECandidateDescriptor candidate = description.candidate(i);
int m_line_index = -1;
if (!base::StringToInt(UTF16ToUTF8(candidate.label()), &m_line_index)) {
LOG(ERROR) << "Invalid candidate label: "
<< UTF16ToUTF8(candidate.label());
continue;
}
scoped_ptr<webrtc::IceCandidateInterface> native_candidate(
webrtc::CreateIceCandidate(UTF16ToUTF8(candidate.label()),
m_line_index,
UTF16ToUTF8(candidate.candidateLine())));
native_desc->AddCandidate(native_candidate.get());
}
std::string sdp;
if (!native_desc->ToString(&sdp))
LOG(ERROR) << "Could not create SDP string";
return UTF8ToUTF16(sdp);
}
} // namespace content