| 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 ae9d31fa045b6b30e25c570b094fd55b01b98bfb..bf60ddbe22d51ba3e2331235c4cd4d064d4b7f9b 100644
 | 
| --- a/content/renderer/media/media_stream_impl.cc
 | 
| +++ b/content/renderer/media/media_stream_impl.cc
 | 
| @@ -90,7 +90,7 @@ void CreateWebKitSourceVector(
 | 
|            type,
 | 
|            UTF8ToUTF16(devices[i].device.name));
 | 
|      webkit_sources[i].setExtraData(
 | 
| -        new content::MediaStreamSourceExtraData(devices[i]));
 | 
| +        new content::MediaStreamSourceExtraData(devices[i], webkit_sources[i]));
 | 
|      webkit_sources[i].setDeviceId(UTF8ToUTF16(devices[i].device.id.c_str()));
 | 
|    }
 | 
|  }
 | 
| @@ -306,11 +306,13 @@ void MediaStreamImpl::OnStreamGenerated(
 | 
|    CreateWebKitSourceVector(label, audio_array,
 | 
|                             WebKit::WebMediaStreamSource::TypeAudio,
 | 
|                             audio_source_vector);
 | 
| +  request_info->audio_sources.assign(audio_source_vector);
 | 
|    WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector(
 | 
|        video_array.size());
 | 
|    CreateWebKitSourceVector(label, video_array,
 | 
|                             WebKit::WebMediaStreamSource::TypeVideo,
 | 
|                             video_source_vector);
 | 
| +  request_info->video_sources.assign(video_source_vector);
 | 
|  
 | 
|    WebKit::WebUserMediaRequest* request = &(request_info->request);
 | 
|    WebKit::WebString webkit_label = UTF8ToUTF16(label);
 | 
| @@ -560,8 +562,10 @@ MediaStreamImpl::CreateLocalAudioRenderer(
 | 
|  }
 | 
|  
 | 
|  MediaStreamSourceExtraData::MediaStreamSourceExtraData(
 | 
| -    const StreamDeviceInfo& device_info)
 | 
| -    : device_info_(device_info) {
 | 
| +    const StreamDeviceInfo& device_info,
 | 
| +    const WebKit::WebMediaStreamSource& webkit_source)
 | 
| +    : device_info_(device_info),
 | 
| +      webkit_source_(webkit_source) {
 | 
|  }
 | 
|  
 | 
|  MediaStreamSourceExtraData::MediaStreamSourceExtraData(
 | 
| @@ -590,4 +594,35 @@ void MediaStreamExtraData::OnLocalStreamStop() {
 | 
|      stream_stop_callback_.Run(stream_->label());
 | 
|  }
 | 
|  
 | 
| +MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo()
 | 
| +    : request_id(0), generated(false), frame(NULL), request() {
 | 
| +}
 | 
| +
 | 
| +MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo(
 | 
| +    int request_id,
 | 
| +    WebKit::WebFrame* frame,
 | 
| +    const WebKit::WebUserMediaRequest& request)
 | 
| +    : request_id(request_id), generated(false), frame(frame),
 | 
| +      request(request) {
 | 
| +}
 | 
| +
 | 
| +MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() {
 | 
| +  // Release the extra data field of all sources created by
 | 
| +  // MediaStreamImpl for this request. This breaks the circular reference to
 | 
| +  // WebKit::MediaStreamSource.
 | 
| +  // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been
 | 
| +  // implemented to fully avoid a circular dependency.
 | 
| +  for (size_t i = 0; i < audio_sources.size(); ++i) {
 | 
| +    audio_sources[i].setReadyState(
 | 
| +        WebKit::WebMediaStreamSource::ReadyStateEnded);
 | 
| +    audio_sources[i].setExtraData(NULL);
 | 
| +  }
 | 
| +
 | 
| +  for (size_t i = 0; i < video_sources.size(); ++i) {
 | 
| +    video_sources[i].setReadyState(
 | 
| +            WebKit::WebMediaStreamSource::ReadyStateEnded);
 | 
| +    video_sources[i].setExtraData(NULL);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  }  // namespace content
 | 
| 
 |