Index: content/renderer/media/media_stream_impl.cc |
=================================================================== |
--- content/renderer/media/media_stream_impl.cc (revision 117190) |
+++ content/renderer/media/media_stream_impl.cc (working copy) |
@@ -1,35 +1,15 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2011 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_impl.h" |
-#include <utility> |
- |
-#include "base/bind.h" |
-#include "base/logging.h" |
-#include "base/synchronization/waitable_event.h" |
-#include "base/utf_string_conversions.h" |
+#include "base/string_util.h" |
#include "content/renderer/media/capture_video_decoder.h" |
-#include "content/renderer/media/media_stream_dependency_factory.h" |
-#include "content/renderer/media/media_stream_dispatcher.h" |
-#include "content/renderer/media/peer_connection_handler.h" |
-#include "content/renderer/media/rtc_video_decoder.h" |
#include "content/renderer/media/video_capture_impl_manager.h" |
-#include "content/renderer/media/video_capture_module_impl.h" |
-#include "content/renderer/media/webrtc_audio_device_impl.h" |
-#include "content/renderer/p2p/ipc_network_manager.h" |
-#include "content/renderer/p2p/ipc_socket_factory.h" |
-#include "content/renderer/p2p/socket_dispatcher.h" |
-#include "jingle/glue/thread_wrapper.h" |
+#include "googleurl/src/gurl.h" |
#include "media/base/message_loop_factory.h" |
-#include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h" |
-#include "third_party/libjingle/source/talk/session/phone/dummydevicemanager.h" |
-#include "third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamDescriptor.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistry.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStreamSource.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
+#include "media/base/pipeline.h" |
namespace { |
@@ -37,211 +17,24 @@ |
static const int kVideoCaptureHeight = 288; |
static const int kVideoCaptureFramePerSecond = 30; |
-} // namespace |
+static const int kStartOpenSessionId = 1; |
-int MediaStreamImpl::next_request_id_ = 0; |
+// TODO(wjia): remove this string when full media stream code is checked in. |
+static const char kRawMediaScheme[] = "mediastream"; |
-MediaStreamImpl::MediaStreamImpl( |
- MediaStreamDispatcher* media_stream_dispatcher, |
- content::P2PSocketDispatcher* p2p_socket_dispatcher, |
- VideoCaptureImplManager* vc_manager, |
- MediaStreamDependencyFactory* dependency_factory) |
- : dependency_factory_(dependency_factory), |
- media_stream_dispatcher_(media_stream_dispatcher), |
- media_engine_(NULL), |
- p2p_socket_dispatcher_(p2p_socket_dispatcher), |
- network_manager_(NULL), |
- vc_manager_(vc_manager), |
- peer_connection_handler_(NULL), |
- message_loop_proxy_(base::MessageLoopProxy::current()), |
- signaling_thread_(NULL), |
- worker_thread_(NULL), |
- chrome_worker_thread_("Chrome_libJingle_WorkerThread"), |
- vcm_created_(false) { |
-} |
+} // namespace |
-MediaStreamImpl::~MediaStreamImpl() { |
- DCHECK(!peer_connection_handler_); |
- if (dependency_factory_.get()) |
- dependency_factory_->DeletePeerConnectionFactory(); |
- if (network_manager_) { |
- // The network manager needs to free its resources on the thread they were |
- // created, which is the worked thread. |
- if (chrome_worker_thread_.IsRunning()) { |
- chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
- &MediaStreamImpl::DeleteIpcNetworkManager, |
- base::Unretained(this))); |
- } else { |
- NOTREACHED() << "Worker thread not running."; |
- } |
- } |
+MediaStreamImpl::MediaStreamImpl(VideoCaptureImplManager* vc_manager) |
+ : vc_manager_(vc_manager) { |
} |
-WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( |
- WebKit::WebPeerConnectionHandlerClient* client) { |
- DCHECK(CalledOnValidThread()); |
- if (peer_connection_handler_) { |
- DVLOG(1) << "A PeerConnection already exists"; |
- return NULL; |
- } |
+MediaStreamImpl::~MediaStreamImpl() {} |
- if (!media_engine_) { |
- media_engine_ = dependency_factory_->CreateWebRtcMediaEngine(); |
- } |
- |
- if (!signaling_thread_) { |
- jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); |
- jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
- signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); |
- } |
- |
- if (!worker_thread_) { |
- if (!chrome_worker_thread_.IsRunning()) { |
- if (!chrome_worker_thread_.Start()) { |
- LOG(ERROR) << "Could not start worker thread"; |
- delete media_engine_; |
- media_engine_ = NULL; |
- signaling_thread_ = NULL; |
- return NULL; |
- } |
- } |
- base::WaitableEvent event(true, false); |
- chrome_worker_thread_.message_loop()->PostTask( |
- FROM_HERE, |
- base::Bind(&MediaStreamImpl::InitializeWorkerThread, this, |
- &worker_thread_, &event)); |
- event.Wait(); |
- DCHECK(worker_thread_); |
- } |
- |
- if (!network_manager_) |
- network_manager_ = new content::IpcNetworkManager(p2p_socket_dispatcher_); |
- |
- if (!socket_factory_.get()) { |
- socket_factory_.reset( |
- new content::IpcPacketSocketFactory(p2p_socket_dispatcher_)); |
- } |
- |
- if (!dependency_factory_->PeerConnectionFactoryCreated()) { |
- if (!dependency_factory_->CreatePeerConnectionFactory(media_engine_, |
- worker_thread_)) { |
- LOG(ERROR) << "Could not initialize PeerConnection factory"; |
- return NULL; |
- } |
- } |
- |
- peer_connection_handler_ = new PeerConnectionHandler( |
- client, |
- this, |
- dependency_factory_.get(), |
- signaling_thread_, |
- p2p_socket_dispatcher_, |
- network_manager_, |
- socket_factory_.get()); |
- |
- return peer_connection_handler_; |
-} |
- |
-void MediaStreamImpl::ClosePeerConnection() { |
- DCHECK(CalledOnValidThread()); |
- rtc_video_decoder_ = NULL; |
- media_engine_->SetVideoCaptureModule(NULL); |
- vcm_created_ = false; |
- peer_connection_handler_ = NULL; |
-} |
- |
-bool MediaStreamImpl::SetVideoCaptureModule(const std::string& label) { |
- DCHECK(CalledOnValidThread()); |
- if (vcm_created_) |
- return true; |
- // Set the capture device. |
- // TODO(grunell): Instead of using the first track, the selected track |
- // should be used. |
- int id = media_stream_dispatcher_->video_session_id(label, 0); |
- if (id == media_stream::StreamDeviceInfo::kNoId) |
- return false; |
- webrtc::VideoCaptureModule* vcm = |
- new VideoCaptureModuleImpl(id, vc_manager_.get()); |
- vcm_created_ = true; |
- media_engine_->SetVideoCaptureModule(vcm); |
- return true; |
-} |
- |
-void MediaStreamImpl::requestUserMedia( |
- const WebKit::WebUserMediaRequest& user_media_request, |
- const WebKit::WebVector<WebKit::WebMediaStreamSource>& |
- media_stream_source_vector) { |
- DCHECK(CalledOnValidThread()); |
- DCHECK(!user_media_request.isNull()); |
- |
- int request_id = next_request_id_++; |
- |
- bool audio = user_media_request.audio(); |
- media_stream::StreamOptions::VideoOption video_option = |
- media_stream::StreamOptions::kNoCamera; |
- if (user_media_request.video()) { |
- // If no preference is set, use user facing camera. |
- video_option = media_stream::StreamOptions::kFacingUser; |
- if (user_media_request.cameraPreferenceUser() && |
- user_media_request.cameraPreferenceEnvironment()) { |
- video_option = media_stream::StreamOptions::kFacingBoth; |
- } else if (user_media_request.cameraPreferenceEnvironment()) { |
- video_option = media_stream::StreamOptions::kFacingEnvironment; |
- } |
- } |
- |
- std::string security_origin = UTF16ToUTF8( |
- user_media_request.securityOrigin().toString()); |
- |
- DVLOG(1) << "MediaStreamImpl::generateStream(" << request_id << ", [ " |
- << (audio ? "audio " : "") |
- << ((user_media_request.cameraPreferenceUser()) ? |
- "video_facing_user " : "") |
- << ((user_media_request.cameraPreferenceEnvironment()) ? |
- "video_facing_environment " : "") << "], " |
- << security_origin << ")"; |
- |
- user_media_requests_.insert( |
- std::pair<int, WebKit::WebUserMediaRequest>( |
- request_id, user_media_request)); |
- |
- media_stream_dispatcher_->GenerateStream( |
- request_id, |
- this, |
- media_stream::StreamOptions(audio, video_option), |
- security_origin); |
-} |
- |
-void MediaStreamImpl::cancelUserMediaRequest( |
- const WebKit::WebUserMediaRequest& user_media_request) { |
- // TODO(grunell): Implement. |
- NOTIMPLEMENTED(); |
-} |
- |
scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( |
- const GURL& url, |
- media::MessageLoopFactory* message_loop_factory) { |
- DCHECK(CalledOnValidThread()); |
- WebKit::WebMediaStreamDescriptor descriptor( |
- WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); |
- if (descriptor.isNull()) |
- return NULL; // This is not a valid stream. |
- WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector; |
- descriptor.sources(source_vector); |
- std::string label; |
- for (size_t i = 0; i < source_vector.size(); ++i) { |
- if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) { |
- label = UTF16ToUTF8(source_vector[i].id()); |
- break; |
- } |
- } |
- if (label.empty()) |
- return NULL; |
- |
- scoped_refptr<media::VideoDecoder> decoder; |
- if (media_stream_dispatcher_->IsStream(label)) { |
- // It's a local stream. |
- int video_session_id = media_stream_dispatcher_->video_session_id(label, 0); |
+ const GURL& url, media::MessageLoopFactory* message_loop_factory) { |
+ bool raw_media = (url.spec().find(kRawMediaScheme) == 0); |
+ media::VideoDecoder* decoder = NULL; |
+ if (raw_media) { |
media::VideoCapture::VideoCaptureCapability capability; |
capability.width = kVideoCaptureWidth; |
capability.height = kVideoCaptureHeight; |
@@ -249,118 +42,10 @@ |
capability.expected_capture_delay = 0; |
capability.raw_type = media::VideoFrame::I420; |
capability.interlaced = false; |
+ |
decoder = new CaptureVideoDecoder( |
- message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), |
- video_session_id, |
- vc_manager_.get(), |
- capability); |
- } else { |
- // It's a remote stream. |
- size_t found = label.rfind("-remote"); |
- if (found != std::string::npos) |
- label = label.substr(0, found); |
- if (rtc_video_decoder_.get()) { |
- // The renderer is used by PeerConnection, release it first. |
- if (peer_connection_handler_) |
- peer_connection_handler_->SetVideoRenderer(label, NULL); |
- } |
- rtc_video_decoder_ = new RTCVideoDecoder( |
- message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), |
- url.spec()); |
- decoder = rtc_video_decoder_; |
- if (peer_connection_handler_) |
- peer_connection_handler_->SetVideoRenderer(label, rtc_video_decoder_); |
+ message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoder").get(), |
+ kStartOpenSessionId, vc_manager_.get(), capability); |
} |
return decoder; |
} |
- |
-void MediaStreamImpl::OnStreamGenerated( |
- int request_id, |
- const std::string& label, |
- const media_stream::StreamDeviceInfoArray& audio_array, |
- const media_stream::StreamDeviceInfoArray& video_array) { |
- DCHECK(CalledOnValidThread()); |
- |
- // We only support max one audio track and one video track. If the UI |
- // for selecting device starts to allow several devices, we must implement |
- // handling for this. |
- DCHECK_LE(audio_array.size(), 1u); |
- DCHECK_LE(video_array.size(), 1u); |
- WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector( |
- audio_array.size() + video_array.size()); |
- |
- WebKit::WebString track_label_audio(UTF8ToUTF16("AudioDevice")); |
- WebKit::WebString track_label_video(UTF8ToUTF16("VideoCapture")); |
- size_t track_num = source_vector.size(); |
- while (track_num--) { |
- if (track_num < audio_array.size()) { |
- source_vector[track_num].initialize( |
- UTF8ToUTF16(label), |
- WebKit::WebMediaStreamSource::TypeAudio, |
- track_label_audio); |
- } else { |
- source_vector[track_num].initialize( |
- UTF8ToUTF16(label), |
- WebKit::WebMediaStreamSource::TypeVideo, |
- track_label_video); |
- } |
- } |
- |
- MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
- if (it == user_media_requests_.end()) { |
- DVLOG(1) << "Request ID not found"; |
- return; |
- } |
- WebKit::WebUserMediaRequest user_media_request = it->second; |
- user_media_requests_.erase(it); |
- stream_labels_.push_back(label); |
- |
- user_media_request.requestSucceeded(source_vector); |
-} |
- |
-void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { |
- DCHECK(CalledOnValidThread()); |
- DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" |
- << request_id << ")"; |
- MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
- if (it == user_media_requests_.end()) { |
- DVLOG(1) << "Request ID not found"; |
- return; |
- } |
- WebKit::WebUserMediaRequest user_media_request = it->second; |
- user_media_requests_.erase(it); |
- |
- user_media_request.requestFailed(); |
-} |
- |
-void MediaStreamImpl::OnVideoDeviceFailed(const std::string& label, |
- int index) { |
- DCHECK(CalledOnValidThread()); |
- DVLOG(1) << "MediaStreamImpl::OnVideoDeviceFailed(" |
- << label << ", " << index << ")"; |
- // TODO(grunell): Implement. Currently not supported in WebKit. |
- NOTIMPLEMENTED(); |
-} |
- |
-void MediaStreamImpl::OnAudioDeviceFailed(const std::string& label, |
- int index) { |
- DCHECK(CalledOnValidThread()); |
- DVLOG(1) << "MediaStreamImpl::OnAudioDeviceFailed(" |
- << label << ", " << index << ")"; |
- // TODO(grunell): Implement. Currently not supported in WebKit. |
- NOTIMPLEMENTED(); |
-} |
- |
-void MediaStreamImpl::InitializeWorkerThread(talk_base::Thread** thread, |
- base::WaitableEvent* event) { |
- jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); |
- jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
- *thread = jingle_glue::JingleThreadWrapper::current(); |
- event->Signal(); |
-} |
- |
-void MediaStreamImpl::DeleteIpcNetworkManager() { |
- DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); |
- delete network_manager_; |
- network_manager_ = NULL; |
-} |