Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(778)

Side by Side Diff: remoting/host/video_frame_recorder_host_extension.cc

Issue 468613002: Readability review. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/video_frame_recorder_host_extension.h" 5 #include "remoting/host/video_frame_recorder_host_extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "remoting/codec/video_encoder_verbatim.h" 12 #include "remoting/codec/video_encoder_verbatim.h"
13 #include "remoting/host/host_extension_session.h" 13 #include "remoting/host/host_extension_session.h"
14 #include "remoting/host/video_frame_recorder.h" 14 #include "remoting/host/video_frame_recorder.h"
15 #include "remoting/proto/control.pb.h" 15 #include "remoting/proto/control.pb.h"
16 #include "remoting/proto/video.pb.h" 16 #include "remoting/proto/video.pb.h"
17 #include "remoting/protocol/client_stub.h" 17 #include "remoting/protocol/client_stub.h"
18 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 18 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
19 19
20 namespace remoting { 20 namespace remoting {
21 21
22 namespace { 22 namespace {
23 23
24 const char kVideoRecorderCapabilities[] = "videoRecorder";
25
26 const char kVideoRecorderType[] = "video-recorder";
27
28 const char kType[] = "type";
29 const char kData[] = "data";
30
31 const char kStartType[] = "start";
32 const char kStopType[] = "stop";
33 const char kNextFrameType[] = "next-frame";
34 const char kNextFrameReplyType[] = "next-frame-reply";
35
36 class VideoFrameRecorderHostExtensionSession : public HostExtensionSession { 24 class VideoFrameRecorderHostExtensionSession : public HostExtensionSession {
37 public: 25 public:
38 explicit VideoFrameRecorderHostExtensionSession(int64_t max_content_bytes); 26 explicit VideoFrameRecorderHostExtensionSession(int64_t max_content_bytes);
39 virtual ~VideoFrameRecorderHostExtensionSession() {} 27 virtual ~VideoFrameRecorderHostExtensionSession();
40 28
41 // remoting::HostExtensionSession interface. 29 // remoting::HostExtensionSession interface.
42 virtual scoped_ptr<VideoEncoder> OnCreateVideoEncoder( 30 virtual void OnCreateVideoEncoder(scoped_ptr<VideoEncoder>* encoder) OVERRIDE;
43 scoped_ptr<VideoEncoder> encoder) OVERRIDE;
44 virtual bool ModifiesVideoPipeline() const OVERRIDE; 31 virtual bool ModifiesVideoPipeline() const OVERRIDE;
45 virtual bool OnExtensionMessage( 32 virtual bool OnExtensionMessage(
46 ClientSessionControl* client_session_control, 33 ClientSessionControl* client_session_control,
47 protocol::ClientStub* client_stub, 34 protocol::ClientStub* client_stub,
48 const protocol::ExtensionMessage& message) OVERRIDE; 35 const protocol::ExtensionMessage& message) OVERRIDE;
49 36
50 private: 37 private:
51 VideoEncoderVerbatim verbatim_encoder; 38 // Handlers for the different frame recorder extension message types.
52 VideoFrameRecorder video_frame_recorder; 39 void OnStart();
40 void OnStop();
41 void OnNextFrame(protocol::ClientStub* client_stub);
42
43 VideoEncoderVerbatim verbatim_encoder_;
44 VideoFrameRecorder video_frame_recorder_;
53 bool first_frame_; 45 bool first_frame_;
54 46
55 DISALLOW_COPY_AND_ASSIGN(VideoFrameRecorderHostExtensionSession); 47 DISALLOW_COPY_AND_ASSIGN(VideoFrameRecorderHostExtensionSession);
56 }; 48 };
57 49
58 VideoFrameRecorderHostExtensionSession::VideoFrameRecorderHostExtensionSession( 50 VideoFrameRecorderHostExtensionSession::VideoFrameRecorderHostExtensionSession(
59 int64_t max_content_bytes) : first_frame_(false) { 51 int64_t max_content_bytes)
60 video_frame_recorder.SetMaxContentBytes(max_content_bytes); 52 : first_frame_(false) {
53 video_frame_recorder_.SetMaxContentBytes(max_content_bytes);
61 } 54 }
62 55
63 scoped_ptr<VideoEncoder> 56 VideoFrameRecorderHostExtensionSession::~VideoFrameRecorderHostExtensionSession(
64 VideoFrameRecorderHostExtensionSession::OnCreateVideoEncoder( 57 ) {
Peter Kasting 2014/08/26 20:58:15 Nit: I have absolutely no idea how the Google styl
Wez 2014/08/28 00:13:20 Done.
65 scoped_ptr<VideoEncoder> encoder) { 58 }
66 video_frame_recorder.DetachVideoEncoderWrapper(); 59
67 return video_frame_recorder.WrapVideoEncoder(encoder.Pass()); 60 void VideoFrameRecorderHostExtensionSession::OnCreateVideoEncoder(
61 scoped_ptr<VideoEncoder>* encoder) {
62 video_frame_recorder_.DetachVideoEncoderWrapper();
63 *encoder = video_frame_recorder_.WrapVideoEncoder(encoder->Pass());
68 } 64 }
69 65
70 bool VideoFrameRecorderHostExtensionSession::ModifiesVideoPipeline() const { 66 bool VideoFrameRecorderHostExtensionSession::ModifiesVideoPipeline() const {
71 return true; 67 return true;
72 } 68 }
73 69
70 // Name of the extension message type field, and its value for this extension.
71 const char kType[] = "type";
72 const char kVideoRecorderType[] = "video-recorder";
Peter Kasting 2014/08/26 20:58:15 Nit: Since these two are used by multiple function
Wez 2014/08/28 00:13:20 Declaring them in the class complicates things wit
73
74 bool VideoFrameRecorderHostExtensionSession::OnExtensionMessage( 74 bool VideoFrameRecorderHostExtensionSession::OnExtensionMessage(
75 ClientSessionControl* client_session_control, 75 ClientSessionControl* client_session_control,
76 protocol::ClientStub* client_stub, 76 protocol::ClientStub* client_stub,
77 const protocol::ExtensionMessage& message) { 77 const protocol::ExtensionMessage& message) {
78 if (message.type() != kVideoRecorderType) { 78 if (message.type() != kVideoRecorderType) {
79 return false; 79 return false;
80 } 80 }
81 81
82 if (!message.has_data()) { 82 if (!message.has_data()) {
83 return true; 83 return true;
84 } 84 }
85 85
86 scoped_ptr<base::Value> value(base::JSONReader::Read(message.data())); 86 scoped_ptr<base::Value> value(base::JSONReader::Read(message.data()));
87 base::DictionaryValue* client_message; 87 base::DictionaryValue* client_message;
88 if (value && value->GetAsDictionary(&client_message)) { 88 if (!value || !value->GetAsDictionary(&client_message)) {
89 std::string type; 89 return true;
90 if (!client_message->GetString(kType, &type)) { 90 }
91 LOG(ERROR) << "Invalid video-recorder message";
92 return true;
93 }
94 91
95 if (type == kStartType) { 92 std::string type;
96 video_frame_recorder.SetEnableRecording(true); 93 if (!client_message->GetString(kType, &type)) {
97 first_frame_ = true; 94 LOG(ERROR) << "Invalid video-recorder message";
98 } else if (type == kStopType) { 95 return true;
99 video_frame_recorder.SetEnableRecording(false); 96 }
100 } else if (type == kNextFrameType) {
101 scoped_ptr<webrtc::DesktopFrame> frame(video_frame_recorder.NextFrame());
102 97
103 // TODO(wez): This involves six copies of the entire frame. 98 const char kStartType[] = "start";
104 // See if there's some way to optimize at least a few of them out. 99 const char kStopType[] = "stop";
105 base::DictionaryValue reply_message; 100 const char kNextFrameType[] = "next-frame";
106 reply_message.SetString(kType, kNextFrameReplyType);
107 if (frame) {
108 // If this is the first frame then override the updated region so that
109 // the encoder will send the whole frame's contents.
110 if (first_frame_) {
111 first_frame_ = false;
112 101
113 frame->mutable_updated_region()->SetRect( 102 if (type == kStartType) {
114 webrtc::DesktopRect::MakeSize(frame->size())); 103 OnStart();
115 } 104 } else if (type == kStopType) {
116 105 OnStop();
117 // Encode the frame into a raw ARGB VideoPacket. 106 } else if (type == kNextFrameType) {
118 scoped_ptr<VideoPacket> encoded_frame( 107 OnNextFrame(client_stub);
119 verbatim_encoder.Encode(*frame)); 108 } else {
120 109 VLOG(1) << "Unknown video-recorder message";
Peter Kasting 2014/08/26 20:58:15 Nit: As noted before, it's usually better to avoid
Wez 2014/08/28 00:13:20 Removed the logging.
121 // Serialize that packet into a string.
122 std::string data;
123 data.resize(encoded_frame->ByteSize());
124 encoded_frame->SerializeWithCachedSizesToArray(
125 reinterpret_cast<uint8_t*>(&data[0]));
126
127 // Convert that string to Base64, so it's JSON-friendly.
128 std::string base64_data;
129 base::Base64Encode(data, &base64_data);
130
131 // Copy the Base64 data into the message.
132 reply_message.SetString(kData, base64_data);
133 }
134
135 // JSON-encode the reply into a string.
136 std::string reply_json;
137 if (!base::JSONWriter::Write(&reply_message, &reply_json)) {
138 LOG(ERROR) << "Failed to create reply json";
139 return true;
140 }
141
142 // Return the frame (or a 'data'-less reply) to the client.
143 protocol::ExtensionMessage message;
144 message.set_type(kVideoRecorderType);
145 message.set_data(reply_json);
146 client_stub->DeliverHostMessage(message);
147 }
148 } 110 }
149 111
150 return true; 112 return true;
151 } 113 }
152 114
115 void VideoFrameRecorderHostExtensionSession::OnStart() {
116 video_frame_recorder_.SetEnableRecording(true);
117 first_frame_ = true;
118 }
119
120 void VideoFrameRecorderHostExtensionSession::OnStop() {
121 video_frame_recorder_.SetEnableRecording(false);
122 }
123
124 void VideoFrameRecorderHostExtensionSession::OnNextFrame(
125 protocol::ClientStub* client_stub) {
126 scoped_ptr<webrtc::DesktopFrame> frame(video_frame_recorder_.NextFrame());
127
128 // TODO(wez): This involves six copies of the entire frame.
129 // See if there's some way to optimize at least a few of them out.
130 const char kNextFrameReplyType[] = "next-frame-reply";
131 base::DictionaryValue reply_message;
132 reply_message.SetString(kType, kNextFrameReplyType);
133 if (frame) {
134 // If this is the first frame then override the updated region so that
135 // the encoder will send the whole frame's contents.
136 if (first_frame_) {
137 first_frame_ = false;
138
139 frame->mutable_updated_region()->SetRect(
140 webrtc::DesktopRect::MakeSize(frame->size()));
141 }
142
143 // Encode the frame into a raw ARGB VideoPacket.
144 scoped_ptr<VideoPacket> encoded_frame(
145 verbatim_encoder_.Encode(*frame));
146
147 // Serialize that packet into a string.
148 std::string data(encoded_frame->ByteSize(), 0);
149 encoded_frame->SerializeWithCachedSizesToArray(
150 reinterpret_cast<uint8_t*>(&data[0]));
151
152 // Convert that string to Base64, so it's JSON-friendly.
153 std::string base64_data;
154 base::Base64Encode(data, &base64_data);
155
156 // Copy the Base64 data into the message.
157 const char kData[] = "data";
158 reply_message.SetString(kData, base64_data);
159 }
160
161 // JSON-encode the reply into a string.
162 // Note that JSONWriter::Write() can only fail due to invalid inputs, and will
163 // DCHECK in Debug builds in that case.
164 std::string reply_json;
165 if (!base::JSONWriter::Write(&reply_message, &reply_json)) {
166 return;
167 }
168
169 // Return the frame (or a 'data'-less reply) to the client.
170 protocol::ExtensionMessage message;
171 message.set_type(kVideoRecorderType);
172 message.set_data(reply_json);
173 client_stub->DeliverHostMessage(message);
174 }
175
153 } // namespace 176 } // namespace
154 177
178 VideoFrameRecorderHostExtension::VideoFrameRecorderHostExtension() {}
179
180 VideoFrameRecorderHostExtension::~VideoFrameRecorderHostExtension() {}
181
155 void VideoFrameRecorderHostExtension::SetMaxContentBytes( 182 void VideoFrameRecorderHostExtension::SetMaxContentBytes(
156 int64_t max_content_bytes) { 183 int64_t max_content_bytes) {
157 max_content_bytes_ = max_content_bytes; 184 max_content_bytes_ = max_content_bytes;
158 } 185 }
159 186
160 std::string VideoFrameRecorderHostExtension::capability() const { 187 std::string VideoFrameRecorderHostExtension::capability() const {
161 return kVideoRecorderCapabilities; 188 const char kVideoRecorderCapability[] = "videoRecorder";
189 return kVideoRecorderCapability;
162 } 190 }
163 191
164 scoped_ptr<HostExtensionSession> 192 scoped_ptr<HostExtensionSession>
165 VideoFrameRecorderHostExtension::CreateExtensionSession( 193 VideoFrameRecorderHostExtension::CreateExtensionSession(
166 ClientSessionControl* client_session_control, 194 ClientSessionControl* client_session_control,
167 protocol::ClientStub* client_stub) { 195 protocol::ClientStub* client_stub) {
168 return scoped_ptr<HostExtensionSession>( 196 return scoped_ptr<HostExtensionSession>(
169 new VideoFrameRecorderHostExtensionSession(max_content_bytes_)); 197 new VideoFrameRecorderHostExtensionSession(max_content_bytes_));
170 } 198 }
171 199
172 } // namespace remoting 200 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698