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.
5 #include "content/renderer/media/video_source_handler.h"
9 #include "base/logging.h"
10 #include "content/renderer/media/media_stream_dependency_factory.h"
11 #include "content/renderer/media/media_stream_registry_interface.h"
12 #include "content/renderer/render_thread_impl.h"
13 #include "third_party/WebKit/public/platform/WebMediaStream.h"
14 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
15 #include "third_party/libjingle/source/talk/media/base/videoframe.h"
16 #include "third_party/libjingle/source/talk/media/base/videorenderer.h"
18 using cricket::VideoFrame
;
19 using cricket::VideoRenderer
;
20 using webrtc::VideoSourceInterface
;
24 // PpFrameReceiver implements cricket::VideoRenderer so that it can be attached
25 // to native video track's video source to receive the captured frame.
26 // It can be attached to a FrameReaderInterface to output the received frame.
27 class PpFrameReceiver
: public cricket::VideoRenderer
{
29 PpFrameReceiver() : reader_(NULL
) {}
30 virtual ~PpFrameReceiver() {}
32 // Implements VideoRenderer.
33 virtual bool SetSize(int width
, int height
, int reserved
) OVERRIDE
{
36 virtual bool RenderFrame(const cricket::VideoFrame
* frame
) OVERRIDE
{
37 base::AutoLock
auto_lock(lock_
);
39 // Make a shallow copy of the frame as the |reader_| may need to queue it.
40 // Both frames will share a single reference-counted frame buffer.
41 reader_
->GotFrame(frame
->Copy());
46 void SetReader(FrameReaderInterface
* reader
) {
47 base::AutoLock
auto_lock(lock_
);
52 FrameReaderInterface
* reader_
;
55 DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver
);
58 VideoSourceHandler::VideoSourceHandler(
59 MediaStreamRegistryInterface
* registry
)
60 : registry_(registry
) {
63 VideoSourceHandler::~VideoSourceHandler() {
64 // All the opened readers should have been closed by now.
65 DCHECK(reader_to_receiver_
.empty());
68 bool VideoSourceHandler::Open(const std::string
& url
,
69 FrameReaderInterface
* reader
) {
70 scoped_refptr
<webrtc::VideoSourceInterface
> source
= GetFirstVideoSource(url
);
74 PpFrameReceiver
* receiver
= new PpFrameReceiver();
75 receiver
->SetReader(reader
);
76 source
->AddSink(receiver
);
77 reader_to_receiver_
[reader
] = receiver
;
81 bool VideoSourceHandler::Close(const std::string
& url
,
82 FrameReaderInterface
* reader
) {
83 scoped_refptr
<webrtc::VideoSourceInterface
> source
= GetFirstVideoSource(url
);
85 LOG(ERROR
) << "VideoSourceHandler::Close - Failed to get the video source "
86 << "from MediaStream with url: " << url
;
89 PpFrameReceiver
* receiver
=
90 static_cast<PpFrameReceiver
*>(GetReceiver(reader
));
92 LOG(ERROR
) << "VideoSourceHandler::Close - Failed to find receiver that "
93 << "is associated with the given reader.";
96 receiver
->SetReader(NULL
);
97 source
->RemoveSink(receiver
);
98 reader_to_receiver_
.erase(reader
);
103 scoped_refptr
<VideoSourceInterface
> VideoSourceHandler::GetFirstVideoSource(
104 const std::string
& url
) {
105 scoped_refptr
<webrtc::VideoSourceInterface
> source
;
106 blink::WebMediaStream stream
;
108 stream
= registry_
->GetMediaStream(url
);
111 blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url
));
113 if (stream
.isNull() || !stream
.extraData()) {
114 LOG(ERROR
) << "GetFirstVideoSource - invalid url: " << url
;
118 // Get the first video track from the stream.
119 MediaStreamExtraData
* extra_data
=
120 static_cast<MediaStreamExtraData
*>(stream
.extraData());
122 LOG(ERROR
) << "GetFirstVideoSource - MediaStreamExtraData is NULL.";
125 webrtc::MediaStreamInterface
* native_stream
= extra_data
->stream().get();
126 if (!native_stream
) {
127 LOG(ERROR
) << "GetFirstVideoSource - native stream is NULL.";
130 webrtc::VideoTrackVector native_video_tracks
=
131 native_stream
->GetVideoTracks();
132 if (native_video_tracks
.empty()) {
133 LOG(ERROR
) << "GetFirstVideoSource - stream has no video track.";
136 source
= native_video_tracks
[0]->GetSource();
140 VideoRenderer
* VideoSourceHandler::GetReceiver(
141 FrameReaderInterface
* reader
) {
142 std::map
<FrameReaderInterface
*, VideoRenderer
*>::iterator it
;
143 it
= reader_to_receiver_
.find(reader
);
144 if (it
== reader_to_receiver_
.end()) {
150 } // namespace content