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