| Index: content/renderer/media/media_stream_impl.cc
|
| diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
|
| index f659aaf9c93188385bbe257acea278284f1033cc..d5c299858c31648ccf790f699581a06a20c26782 100644
|
| --- a/content/renderer/media/media_stream_impl.cc
|
| +++ b/content/renderer/media/media_stream_impl.cc
|
| @@ -11,10 +11,11 @@
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "content/renderer/media/media_stream_audio_renderer.h"
|
| +#include "content/renderer/media/media_stream_audio_source.h"
|
| #include "content/renderer/media/media_stream_dependency_factory.h"
|
| #include "content/renderer/media/media_stream_dispatcher.h"
|
| #include "content/renderer/media/media_stream_extra_data.h"
|
| -#include "content/renderer/media/media_stream_source_extra_data.h"
|
| +#include "content/renderer/media/media_stream_video_capturer_source.h"
|
| #include "content/renderer/media/peer_connection_tracker.h"
|
| #include "content/renderer/media/rtc_video_renderer.h"
|
| #include "content/renderer/media/webrtc_audio_capturer.h"
|
| @@ -73,18 +74,6 @@ void GetDefaultOutputDeviceParams(
|
| *output_buffer_size = hardware_config->GetOutputBufferSize();
|
| }
|
|
|
| -void RemoveSource(const blink::WebMediaStreamSource& source,
|
| - std::vector<blink::WebMediaStreamSource>* sources) {
|
| - for (std::vector<blink::WebMediaStreamSource>::iterator it =
|
| - sources->begin();
|
| - it != sources->end(); ++it) {
|
| - if (source.id() == it->id()) {
|
| - sources->erase(it);
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| MediaStreamImpl::MediaStreamImpl(
|
| @@ -321,73 +310,33 @@ void MediaStreamImpl::OnStreamGenerated(
|
| }
|
| request_info->generated = true;
|
|
|
| - blink::WebVector<blink::WebMediaStreamSource> audio_source_vector(
|
| - audio_array.size());
|
| -
|
| - // Log the device names for this request.
|
| - for (StreamDeviceInfoArray::const_iterator it = audio_array.begin();
|
| - it != audio_array.end(); ++it) {
|
| - WebRtcLogMessage(base::StringPrintf(
|
| - "Generated media stream for request id %d contains audio device name"
|
| - " \"%s\"",
|
| - request_id,
|
| - it->device.name.c_str()));
|
| - }
|
| -
|
| - StreamDeviceInfoArray overridden_audio_array = audio_array;
|
| - if (!request_info->enable_automatic_output_device_selection) {
|
| - // If the GetUserMedia request did not explicitly set the constraint
|
| - // kMediaStreamRenderToAssociatedSink, the output device parameters must
|
| - // be removed.
|
| - for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin();
|
| - it != overridden_audio_array.end(); ++it) {
|
| - it->device.matched_output_device_id = "";
|
| - it->device.matched_output = MediaStreamDevice::AudioDeviceParameters();
|
| - }
|
| - }
|
| - CreateWebKitSourceVector(label, overridden_audio_array,
|
| - blink::WebMediaStreamSource::TypeAudio,
|
| - request_info->frame,
|
| - audio_source_vector);
|
| -
|
| - blink::WebVector<blink::WebMediaStreamSource> video_source_vector(
|
| - video_array.size());
|
| - CreateWebKitSourceVector(label, video_array,
|
| - blink::WebMediaStreamSource::TypeVideo,
|
| - request_info->frame,
|
| - video_source_vector);
|
| + // WebUserMediaRequest don't have an implementation in unit tests.
|
| + // Therefore we need to check for isNull here.
|
| blink::WebUserMediaRequest* request = &(request_info->request);
|
| - blink::WebString webkit_id = base::UTF8ToUTF16(label);
|
| - blink::WebMediaStream* web_stream = &(request_info->web_stream);
|
| + blink::WebMediaConstraints audio_constraints = request->isNull() ?
|
| + blink::WebMediaConstraints() : request->audioConstraints();
|
| + blink::WebMediaConstraints video_constraints = request->isNull() ?
|
| + blink::WebMediaConstraints() : request->videoConstraints();
|
|
|
| blink::WebVector<blink::WebMediaStreamTrack> audio_track_vector(
|
| audio_array.size());
|
| - for (size_t i = 0; i < audio_track_vector.size(); ++i) {
|
| - audio_track_vector[i].initialize(audio_source_vector[i]);
|
| - request_info->sources.push_back(audio_source_vector[i]);
|
| - }
|
| + CreateAudioTracks(audio_array, audio_constraints, &audio_track_vector,
|
| + request_info);
|
|
|
| blink::WebVector<blink::WebMediaStreamTrack> video_track_vector(
|
| video_array.size());
|
| - for (size_t i = 0; i < video_track_vector.size(); ++i) {
|
| - video_track_vector[i].initialize(video_source_vector[i]);
|
| - request_info->sources.push_back(video_source_vector[i]);
|
| - }
|
| + CreateVideoTracks(video_array, video_constraints, &video_track_vector,
|
| + request_info);
|
| +
|
| + blink::WebString webkit_id = base::UTF8ToUTF16(label);
|
| + blink::WebMediaStream* web_stream = &(request_info->web_stream);
|
|
|
| web_stream->initialize(webkit_id, audio_track_vector,
|
| video_track_vector);
|
|
|
| - // WebUserMediaRequest don't have an implementation in unit tests.
|
| - // Therefore we need to check for isNull here.
|
| - blink::WebMediaConstraints audio_constraints = request->isNull() ?
|
| - blink::WebMediaConstraints() : request->audioConstraints();
|
| - blink::WebMediaConstraints video_constraints = request->isNull() ?
|
| - blink::WebMediaConstraints() : request->videoConstraints();
|
| -
|
| - dependency_factory_->CreateNativeMediaSources(
|
| - RenderViewObserver::routing_id(),
|
| - audio_constraints, video_constraints, web_stream,
|
| - base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr()));
|
| + // Wait for the tracks to be started successfully or to fail.
|
| + request_info->CallbackOnTracksStarted(
|
| + base::Bind(&MediaStreamImpl::OnCreateNativeTracksComplete, AsWeakPtr()));
|
| }
|
|
|
| // Callback from MediaStreamDispatcher.
|
| @@ -443,8 +392,8 @@ void MediaStreamImpl::OnDeviceStopped(
|
| // MediaStream::Stop().
|
| UserMediaRequests::iterator it = user_media_requests_.begin();
|
| while (it != user_media_requests_.end()) {
|
| - RemoveSource(source, &(*it)->sources);
|
| - if ((*it)->sources.empty()) {
|
| + (*it)->RemoveSource(source);
|
| + if ((*it)->IsAllSourcesRemoved()) {
|
| it = user_media_requests_.erase(it);
|
| } else {
|
| ++it;
|
| @@ -452,64 +401,133 @@ void MediaStreamImpl::OnDeviceStopped(
|
| }
|
| }
|
|
|
| -void MediaStreamImpl::CreateWebKitSourceVector(
|
| - const std::string& label,
|
| - const StreamDeviceInfoArray& devices,
|
| +void MediaStreamImpl::InitializeSourceObject(
|
| + const StreamDeviceInfo& device,
|
| blink::WebMediaStreamSource::Type type,
|
| + const blink::WebMediaConstraints& constraints,
|
| blink::WebFrame* frame,
|
| - blink::WebVector<blink::WebMediaStreamSource>& webkit_sources) {
|
| - CHECK_EQ(devices.size(), webkit_sources.size());
|
| + blink::WebMediaStreamSource* webkit_source) {
|
| + const blink::WebMediaStreamSource* existing_source =
|
| + FindLocalSource(device);
|
| + if (existing_source) {
|
| + *webkit_source = *existing_source;
|
| + DVLOG(1) << "Source already exist. Reusing source with id "
|
| + << webkit_source->id().utf8();
|
| + return;
|
| + }
|
| +
|
| + webkit_source->initialize(
|
| + base::UTF8ToUTF16(device.device.id),
|
| + type,
|
| + base::UTF8ToUTF16(device.device.name));
|
| +
|
| + DVLOG(1) << "Initialize source object :"
|
| + << "id = " << webkit_source->id().utf8()
|
| + << ", name = " << webkit_source->name().utf8();
|
| +
|
| + if (type == blink::WebMediaStreamSource::TypeVideo) {
|
| + MediaStreamVideoCapturerSource* video_source(
|
| + new content::MediaStreamVideoCapturerSource(
|
| + device,
|
| + base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr()),
|
| + dependency_factory_));
|
| + webkit_source->setExtraData(video_source);
|
| + } else {
|
| + DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio, type);
|
| + MediaStreamAudioSource* audio_source(
|
| + new MediaStreamAudioSource(
|
| + device,
|
| + base::Bind(&MediaStreamImpl::OnLocalSourceStopped, AsWeakPtr())));
|
| + webkit_source->setExtraData(audio_source);
|
| + // TODO(xians): Move initialization from MediaStreamDependencyFactory
|
| + // to MediaStreamAudioSource.
|
| + dependency_factory_->InitializeMediaStreamAudioSource(
|
| + RenderViewObserver::routing_id(),
|
| + constraints,
|
| + *webkit_source);
|
| + }
|
| + local_sources_.push_back(LocalStreamSource(frame, *webkit_source));
|
| + return;
|
| +}
|
| +
|
| +void MediaStreamImpl::CreateVideoTracks(
|
| + const StreamDeviceInfoArray& devices,
|
| + const blink::WebMediaConstraints& constraints,
|
| + blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
|
| + UserMediaRequestInfo* request) {
|
| + DCHECK_EQ(devices.size(), webkit_tracks->size());
|
| +
|
| for (size_t i = 0; i < devices.size(); ++i) {
|
| - const blink::WebMediaStreamSource* existing_source =
|
| - FindLocalSource(devices[i]);
|
| - if (existing_source) {
|
| - webkit_sources[i] = *existing_source;
|
| - DVLOG(1) << "Source already exist. Reusing source with id "
|
| - << webkit_sources[i]. id().utf8();
|
| - continue;
|
| + blink::WebMediaStreamSource webkit_source;
|
| + InitializeSourceObject(devices[i],
|
| + blink::WebMediaStreamSource::TypeVideo,
|
| + constraints,
|
| + request->frame,
|
| + &webkit_source);
|
| + (*webkit_tracks)[i].initialize(webkit_source);
|
| + request->StartTrack((*webkit_tracks)[i], constraints);
|
| + }
|
| +}
|
| +
|
| +void MediaStreamImpl::CreateAudioTracks(
|
| + const StreamDeviceInfoArray& devices,
|
| + const blink::WebMediaConstraints& constraints,
|
| + blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
|
| + UserMediaRequestInfo* request) {
|
| + DCHECK_EQ(devices.size(), webkit_tracks->size());
|
| +
|
| + // Log the device names for this request.
|
| + for (StreamDeviceInfoArray::const_iterator it = devices.begin();
|
| + it != devices.end(); ++it) {
|
| + WebRtcLogMessage(base::StringPrintf(
|
| + "Generated media stream for request id %d contains audio device name"
|
| + " \"%s\"",
|
| + request->request_id,
|
| + it->device.name.c_str()));
|
| + }
|
| +
|
| + StreamDeviceInfoArray overridden_audio_array = devices;
|
| + if (!request->enable_automatic_output_device_selection) {
|
| + // If the GetUserMedia request did not explicitly set the constraint
|
| + // kMediaStreamRenderToAssociatedSink, the output device parameters must
|
| + // be removed.
|
| + for (StreamDeviceInfoArray::iterator it = overridden_audio_array.begin();
|
| + it != overridden_audio_array.end(); ++it) {
|
| + it->device.matched_output_device_id = "";
|
| + it->device.matched_output = MediaStreamDevice::AudioDeviceParameters();
|
| }
|
| - webkit_sources[i].initialize(
|
| - base::UTF8ToUTF16(devices[i].device.id),
|
| - type,
|
| - base::UTF8ToUTF16(devices[i].device.name));
|
| - MediaStreamSourceExtraData* source_extra_data(
|
| - new content::MediaStreamSourceExtraData(
|
| - devices[i],
|
| - base::Bind(&MediaStreamImpl::OnLocalSourceStop, AsWeakPtr())));
|
| - // |source_extra_data| is owned by webkit_sources[i].
|
| - webkit_sources[i].setExtraData(source_extra_data);
|
| - local_sources_.push_back(LocalStreamSource(frame, webkit_sources[i]));
|
| - }
|
| -}
|
| -
|
| -// Callback from MediaStreamDependencyFactory when the sources in |web_stream|
|
| -// have been generated.
|
| -void MediaStreamImpl::OnCreateNativeSourcesComplete(
|
| - blink::WebMediaStream* web_stream,
|
| - bool request_succeeded) {
|
| - UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(web_stream);
|
| - if (!request_info) {
|
| - // This can happen if the request is canceled or the frame reloads while
|
| - // MediaStreamDependencyFactory is creating the sources.
|
| - DVLOG(1) << "Request ID not found";
|
| - return;
|
| }
|
|
|
| + for (size_t i = 0; i < overridden_audio_array.size(); ++i) {
|
| + blink::WebMediaStreamSource webkit_source;
|
| + InitializeSourceObject(overridden_audio_array[i],
|
| + blink::WebMediaStreamSource::TypeAudio,
|
| + constraints,
|
| + request->frame,
|
| + &webkit_source);
|
| + (*webkit_tracks)[i].initialize(webkit_source);
|
| + request->StartTrack((*webkit_tracks)[i], constraints);
|
| + }
|
| +}
|
| +
|
| +void MediaStreamImpl::OnCreateNativeTracksComplete(
|
| + UserMediaRequestInfo* request,
|
| + bool request_succeeded) {
|
| // Create a native representation of the stream.
|
| if (request_succeeded) {
|
| dependency_factory_->CreateNativeLocalMediaStream(
|
| - web_stream,
|
| + &request->web_stream,
|
| base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr()));
|
| }
|
| - DVLOG(1) << "MediaStreamImpl::OnCreateNativeSourcesComplete("
|
| - << "{request_id = " << request_info->request_id << "} "
|
| + DVLOG(1) << "MediaStreamImpl::OnCreateNativeTracksComplete("
|
| + << "{request_id = " << request->request_id << "} "
|
| << "{request_succeeded = " << request_succeeded << "})";
|
| - CompleteGetUserMediaRequest(request_info->web_stream, &request_info->request,
|
| + CompleteGetUserMediaRequest(request->web_stream, &request->request,
|
| request_succeeded);
|
| if (!request_succeeded) {
|
| // TODO(perkj): Once we don't support MediaStream::Stop the |request_info|
|
| // can be deleted even if the request succeeds.
|
| - DeleteUserMediaRequestInfo(request_info);
|
| + DeleteUserMediaRequestInfo(request);
|
| StopUnreferencedSources(true);
|
| }
|
| }
|
| @@ -552,10 +570,9 @@ const blink::WebMediaStreamSource* MediaStreamImpl::FindLocalSource(
|
| const StreamDeviceInfo& device) const {
|
| for (LocalStreamSources::const_iterator it = local_sources_.begin();
|
| it != local_sources_.end(); ++it) {
|
| - MediaStreamSourceExtraData* extra_data =
|
| - static_cast<MediaStreamSourceExtraData*>(
|
| - it->source.extraData());
|
| - const StreamDeviceInfo& active_device = extra_data->device_info();
|
| + MediaStreamSource* source =
|
| + static_cast<MediaStreamSource*>(it->source.extraData());
|
| + const StreamDeviceInfo& active_device = source->device_info();
|
| if (active_device.device.id == device.device.id &&
|
| active_device.device.type == device.device.type &&
|
| active_device.session_id == device.session_id) {
|
| @@ -569,15 +586,8 @@ bool MediaStreamImpl::FindSourceInRequests(
|
| const blink::WebMediaStreamSource& source) const {
|
| for (UserMediaRequests::const_iterator req_it = user_media_requests_.begin();
|
| req_it != user_media_requests_.end(); ++req_it) {
|
| - const std::vector<blink::WebMediaStreamSource>& sources =
|
| - (*req_it)->sources;
|
| - for (std::vector<blink::WebMediaStreamSource>::const_iterator source_it =
|
| - sources.begin();
|
| - source_it != sources.end(); ++source_it) {
|
| - if (source_it->id() == source.id()) {
|
| - return true;
|
| - }
|
| - }
|
| + if ((*req_it)->IsSourceUsed(source))
|
| + return true;
|
| }
|
| return false;
|
| }
|
| @@ -613,17 +623,6 @@ MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) {
|
| return NULL;
|
| }
|
|
|
| -MediaStreamImpl::UserMediaRequestInfo*
|
| -MediaStreamImpl::FindUserMediaRequestInfo(
|
| - blink::WebMediaStream* web_stream) {
|
| - UserMediaRequests::iterator it = user_media_requests_.begin();
|
| - for (; it != user_media_requests_.end(); ++it) {
|
| - if (&((*it)->web_stream) == web_stream)
|
| - return (*it);
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| void MediaStreamImpl::DeleteUserMediaRequestInfo(
|
| UserMediaRequestInfo* request) {
|
| UserMediaRequests::iterator it = user_media_requests_.begin();
|
| @@ -687,12 +686,10 @@ void MediaStreamImpl::OnLocalMediaStreamStop(
|
| StopUnreferencedSources(true);
|
| }
|
|
|
| -void MediaStreamImpl::OnLocalSourceStop(
|
| +void MediaStreamImpl::OnLocalSourceStopped(
|
| const blink::WebMediaStreamSource& source) {
|
| DCHECK(CalledOnValidThread());
|
|
|
| - StopLocalSource(source, true);
|
| -
|
| bool device_found = false;
|
| for (LocalStreamSources::iterator device_it = local_sources_.begin();
|
| device_it != local_sources_.end(); ++device_it) {
|
| @@ -709,37 +706,32 @@ void MediaStreamImpl::OnLocalSourceStop(
|
| // MediaStream::Stop().
|
| UserMediaRequests::iterator it = user_media_requests_.begin();
|
| while (it != user_media_requests_.end()) {
|
| - RemoveSource(source, &(*it)->sources);
|
| - if ((*it)->sources.empty()) {
|
| + (*it)->RemoveSource(source);
|
| + if ((*it)->IsAllSourcesRemoved()) {
|
| it = user_media_requests_.erase(it);
|
| } else {
|
| ++it;
|
| }
|
| }
|
| +
|
| + MediaStreamSource* source_impl =
|
| + static_cast<MediaStreamSource*> (source.extraData());
|
| + media_stream_dispatcher_->StopStreamDevice(source_impl->device_info());
|
| }
|
|
|
| void MediaStreamImpl::StopLocalSource(
|
| const blink::WebMediaStreamSource& source,
|
| bool notify_dispatcher) {
|
| - MediaStreamSourceExtraData* extra_data =
|
| - static_cast<MediaStreamSourceExtraData*> (source.extraData());
|
| - CHECK(extra_data);
|
| + MediaStreamSource* source_impl =
|
| + static_cast<MediaStreamSource*> (source.extraData());
|
| DVLOG(1) << "MediaStreamImpl::StopLocalSource("
|
| - << "{device_id = " << extra_data->device_info().device.id << "})";
|
| -
|
| - if (source.type() == blink::WebMediaStreamSource::TypeAudio) {
|
| - if (extra_data->GetAudioCapturer()) {
|
| - extra_data->GetAudioCapturer()->Stop();
|
| - }
|
| - }
|
| + << "{device_id = " << source_impl->device_info().device.id << "})";
|
|
|
| if (notify_dispatcher)
|
| - media_stream_dispatcher_->StopStreamDevice(extra_data->device_info());
|
| + media_stream_dispatcher_->StopStreamDevice(source_impl->device_info());
|
|
|
| - blink::WebMediaStreamSource writable_source(source);
|
| - writable_source.setReadyState(
|
| - blink::WebMediaStreamSource::ReadyStateEnded);
|
| - writable_source.setExtraData(NULL);
|
| + source_impl->ResetSourceStoppedCallback();
|
| + source_impl->StopSource();
|
| }
|
|
|
| void MediaStreamImpl::StopUnreferencedSources(bool notify_dispatcher) {
|
| @@ -816,23 +808,6 @@ bool MediaStreamImpl::GetAuthorizedDeviceInfoForAudioRenderer(
|
| output_frames_per_buffer);
|
| }
|
|
|
| -MediaStreamSourceExtraData::MediaStreamSourceExtraData(
|
| - const StreamDeviceInfo& device_info,
|
| - const SourceStopCallback& stop_callback)
|
| - : device_info_(device_info),
|
| - stop_callback_(stop_callback) {
|
| -}
|
| -
|
| -MediaStreamSourceExtraData::MediaStreamSourceExtraData() {
|
| -}
|
| -
|
| -MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {}
|
| -
|
| -void MediaStreamSourceExtraData::OnLocalSourceStop() {
|
| - if (!stop_callback_.is_null())
|
| - stop_callback_.Run(owner());
|
| -}
|
| -
|
| MediaStreamExtraData::MediaStreamExtraData(
|
| webrtc::MediaStreamInterface* stream, bool is_local)
|
| : stream_(stream),
|
| @@ -862,10 +837,78 @@ MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
|
| enable_automatic_output_device_selection(
|
| enable_automatic_output_device_selection),
|
| frame(frame),
|
| - request(request) {
|
| + request(request),
|
| + request_failed_(false) {
|
| }
|
|
|
| MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() {
|
| + DVLOG(1) << "~UserMediaRequestInfo";
|
| +}
|
| +
|
| +void MediaStreamImpl::UserMediaRequestInfo::StartTrack(
|
| + const blink::WebMediaStreamTrack& track,
|
| + const blink::WebMediaConstraints& constraints) {
|
| + MediaStreamSource* native_source =
|
| + static_cast <MediaStreamSource*>(track.source().extraData());
|
| + DCHECK(native_source);
|
| +
|
| + sources_.push_back(track.source());
|
| + sources_waiting_for_callback_.push_back(native_source);
|
| + native_source->AddTrack(
|
| + track, constraints, base::Bind(
|
| + &MediaStreamImpl::UserMediaRequestInfo::OnTrackStarted,
|
| + AsWeakPtr()));
|
| +}
|
| +
|
| +void MediaStreamImpl::UserMediaRequestInfo::CallbackOnTracksStarted(
|
| + const ResourcesReady& callback) {
|
| + DCHECK(ready_callback_.is_null());
|
| + ready_callback_ = callback;
|
| + CheckAllTracksStarted();
|
| +}
|
| +
|
| +void MediaStreamImpl::UserMediaRequestInfo::OnTrackStarted(
|
| + MediaStreamSource* source, bool success) {
|
| + DVLOG(1) << "OnTrackStarted";
|
| + std::vector<MediaStreamSource*>::iterator it =
|
| + std::find(sources_waiting_for_callback_.begin(),
|
| + sources_waiting_for_callback_.end(),
|
| + source);
|
| + DCHECK(it != sources_waiting_for_callback_.end());
|
| + sources_waiting_for_callback_.erase(it);
|
| + // All tracks must be started successfully. Otherwise the request is a
|
| + // failure.
|
| + if (!success)
|
| + request_failed_ = true;
|
| + CheckAllTracksStarted();
|
| +}
|
| +
|
| +void MediaStreamImpl::UserMediaRequestInfo::CheckAllTracksStarted() {
|
| + if (!ready_callback_.is_null() && sources_waiting_for_callback_.empty())
|
| + ready_callback_.Run(this, !request_failed_);
|
| +}
|
| +
|
| +bool MediaStreamImpl::UserMediaRequestInfo::IsSourceUsed(
|
| + const blink::WebMediaStreamSource& source) const {
|
| + for (std::vector<blink::WebMediaStreamSource>::const_iterator source_it =
|
| + sources_.begin();
|
| + source_it != sources_.end(); ++source_it) {
|
| + if (source_it->id() == source.id())
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void MediaStreamImpl::UserMediaRequestInfo::RemoveSource(
|
| + const blink::WebMediaStreamSource& source) {
|
| + for (std::vector<blink::WebMediaStreamSource>::iterator it =
|
| + sources_.begin();
|
| + it != sources_.end(); ++it) {
|
| + if (source.id() == it->id()) {
|
| + sources_.erase(it);
|
| + return;
|
| + }
|
| + }
|
| }
|
|
|
| } // namespace content
|
|
|