video_source_handler.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/media/video_source_handler.h" 6 7#include <string> 8 9#include "base/logging.h" 10#include "content/renderer/media/media_stream.h" 11#include "content/renderer/media/media_stream_dependency_factory.h" 12#include "content/renderer/media/media_stream_registry_interface.h" 13#include "content/renderer/render_thread_impl.h" 14#include "third_party/WebKit/public/platform/WebMediaStream.h" 15#include "third_party/WebKit/public/platform/WebURL.h" 16#include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" 17#include "third_party/libjingle/source/talk/media/base/videoframe.h" 18#include "third_party/libjingle/source/talk/media/base/videorenderer.h" 19#include "url/gurl.h" 20 21using cricket::VideoFrame; 22using cricket::VideoRenderer; 23using webrtc::VideoSourceInterface; 24 25namespace content { 26 27// PpFrameReceiver implements cricket::VideoRenderer so that it can be attached 28// to native video track's video source to receive the captured frame. 29// It can be attached to a FrameReaderInterface to output the received frame. 30class PpFrameReceiver : public cricket::VideoRenderer { 31 public: 32 PpFrameReceiver() : reader_(NULL) {} 33 virtual ~PpFrameReceiver() {} 34 35 // Implements VideoRenderer. 36 virtual bool SetSize(int width, int height, int reserved) OVERRIDE { 37 return true; 38 } 39 virtual bool RenderFrame(const cricket::VideoFrame* frame) OVERRIDE { 40 base::AutoLock auto_lock(lock_); 41 if (reader_) { 42 // |frame| will be invalid after this function is returned. So keep a copy 43 // before return. 44 cricket::VideoFrame* copied_frame = frame->Copy(); 45 copied_frame->MakeExclusive(); 46 reader_->GotFrame(copied_frame); 47 } 48 return true; 49 } 50 51 void SetReader(FrameReaderInterface* reader) { 52 base::AutoLock auto_lock(lock_); 53 reader_ = reader; 54 } 55 56 private: 57 FrameReaderInterface* reader_; 58 base::Lock lock_; 59 60 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver); 61}; 62 63VideoSourceHandler::VideoSourceHandler( 64 MediaStreamRegistryInterface* registry) 65 : registry_(registry) { 66} 67 68VideoSourceHandler::~VideoSourceHandler() { 69 for (SourceInfoMap::iterator it = reader_to_receiver_.begin(); 70 it != reader_to_receiver_.end(); 71 ++it) { 72 delete it->second; 73 } 74} 75 76bool VideoSourceHandler::Open(const std::string& url, 77 FrameReaderInterface* reader) { 78 scoped_refptr<webrtc::VideoSourceInterface> source = GetFirstVideoSource(url); 79 if (!source.get()) { 80 return false; 81 } 82 reader_to_receiver_[reader] = new SourceInfo(source, reader); 83 return true; 84} 85 86bool VideoSourceHandler::Close(FrameReaderInterface* reader) { 87 SourceInfoMap::iterator it = reader_to_receiver_.find(reader); 88 if (it == reader_to_receiver_.end()) { 89 return false; 90 } 91 delete it->second; 92 reader_to_receiver_.erase(it); 93 return true; 94} 95 96scoped_refptr<VideoSourceInterface> VideoSourceHandler::GetFirstVideoSource( 97 const std::string& url) { 98 scoped_refptr<webrtc::VideoSourceInterface> source; 99 blink::WebMediaStream stream; 100 if (registry_) { 101 stream = registry_->GetMediaStream(url); 102 } else { 103 stream = 104 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url)); 105 } 106 if (stream.isNull() || !stream.extraData()) { 107 LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url; 108 return source; 109 } 110 111 // Get the first video track from the stream. 112 webrtc::MediaStreamInterface* native_stream = MediaStream::GetAdapter(stream); 113 webrtc::VideoTrackVector native_video_tracks = 114 native_stream->GetVideoTracks(); 115 if (native_video_tracks.empty()) { 116 LOG(ERROR) << "GetFirstVideoSource - stream has no video track."; 117 return source; 118 } 119 source = native_video_tracks[0]->GetSource(); 120 return source; 121} 122 123VideoRenderer* VideoSourceHandler::GetReceiver( 124 FrameReaderInterface* reader) { 125 SourceInfoMap::iterator it = reader_to_receiver_.find(reader); 126 if (it == reader_to_receiver_.end()) { 127 return NULL; 128 } 129 return it->second->receiver_.get(); 130} 131 132VideoSourceHandler::SourceInfo::SourceInfo( 133 scoped_refptr<webrtc::VideoSourceInterface> source, 134 FrameReaderInterface* reader) 135 : receiver_(new PpFrameReceiver()), 136 source_(source) { 137 source_->AddSink(receiver_.get()); 138 receiver_->SetReader(reader); 139} 140 141VideoSourceHandler::SourceInfo::~SourceInfo() { 142 source_->RemoveSink(receiver_.get()); 143 receiver_->SetReader(NULL); 144} 145 146} // namespace content 147 148