OLD | NEW |
---|---|
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/client/plugin/media_source_video_renderer.h" | 5 #include "remoting/client/plugin/media_source_video_renderer.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 17 matching lines...) Expand all Loading... | |
28 int64_t last_frame_timestamp() { return timecode_ - kFrameIntervalNs; } | 28 int64_t last_frame_timestamp() { return timecode_ - kFrameIntervalNs; } |
29 | 29 |
30 // IMkvWriter interface. | 30 // IMkvWriter interface. |
31 virtual mkvmuxer::int32 Write(const void* buf, mkvmuxer::uint32 len) OVERRIDE; | 31 virtual mkvmuxer::int32 Write(const void* buf, mkvmuxer::uint32 len) OVERRIDE; |
32 virtual mkvmuxer::int64 Position() const OVERRIDE; | 32 virtual mkvmuxer::int64 Position() const OVERRIDE; |
33 virtual mkvmuxer::int32 Position(mkvmuxer::int64 position) OVERRIDE; | 33 virtual mkvmuxer::int32 Position(mkvmuxer::int64 position) OVERRIDE; |
34 virtual bool Seekable() const OVERRIDE; | 34 virtual bool Seekable() const OVERRIDE; |
35 virtual void ElementStartNotify(mkvmuxer::uint64 element_id, | 35 virtual void ElementStartNotify(mkvmuxer::uint64 element_id, |
36 mkvmuxer::int64 position) OVERRIDE; | 36 mkvmuxer::int64 position) OVERRIDE; |
37 | 37 |
38 scoped_ptr<DataBuffer> OnVideoFrame(const std::string& video_data); | 38 scoped_ptr<DataBuffer> OnVideoFrame(const std::string& video_data, |
39 bool keyframe); | |
39 | 40 |
40 private: | 41 private: |
41 webrtc::DesktopSize frame_size_; | 42 webrtc::DesktopSize frame_size_; |
42 scoped_ptr<DataBuffer> output_data_; | 43 scoped_ptr<DataBuffer> output_data_; |
43 int64_t position_; | 44 int64_t position_; |
44 scoped_ptr<mkvmuxer::Segment> segment_; | 45 scoped_ptr<mkvmuxer::Segment> segment_; |
45 int64_t timecode_; | 46 int64_t timecode_; |
46 }; | 47 }; |
47 | 48 |
48 MediaSourceVideoRenderer::VideoWriter::VideoWriter( | 49 MediaSourceVideoRenderer::VideoWriter::VideoWriter( |
49 const webrtc::DesktopSize& frame_size) | 50 const webrtc::DesktopSize& frame_size) |
50 : frame_size_(frame_size), | 51 : frame_size_(frame_size), |
51 position_(0), | 52 position_(0), |
52 timecode_(0) { | 53 timecode_(0) { |
53 segment_.reset(new mkvmuxer::Segment()); | 54 segment_.reset(new mkvmuxer::Segment()); |
54 segment_->Init(this); | 55 segment_->Init(this); |
55 segment_->set_mode(mkvmuxer::Segment::kLive); | 56 segment_->set_mode(mkvmuxer::Segment::kLive); |
57 segment_->set_max_cluster_duration(0); | |
58 segment_->set_max_cluster_size(0); | |
Jamie
2014/06/11 21:41:42
I don't understand what these lines do. Are they c
Sergey Ulanov
2014/06/11 23:41:12
That was my attempt to workaround crbug.com/382807
| |
56 | 59 |
57 // DateUTC is specified in nanoseconds from 0:00 on January 1st, 2001. | 60 // DateUTC is specified in nanoseconds from 0:00 on January 1st, 2001. |
58 base::Time::Exploded millennium_exploded; | 61 base::Time::Exploded millennium_exploded; |
59 memset(&millennium_exploded, 0, sizeof(millennium_exploded)); | 62 memset(&millennium_exploded, 0, sizeof(millennium_exploded)); |
60 millennium_exploded.year = 2001; | 63 millennium_exploded.year = 2001; |
61 millennium_exploded.month = 1; | 64 millennium_exploded.month = 1; |
62 millennium_exploded.day_of_month = 1; | 65 millennium_exploded.day_of_month = 1; |
63 segment_->GetSegmentInfo()->set_date_utc( | 66 segment_->GetSegmentInfo()->set_date_utc( |
64 (base::Time::Now() - base::Time::FromUTCExploded(millennium_exploded)) | 67 (base::Time::Now() - base::Time::FromUTCExploded(millennium_exploded)) |
65 .InMicroseconds() * | 68 .InMicroseconds() * |
(...skipping 13 matching lines...) Expand all Loading... | |
79 crop_bottom = 1; | 82 crop_bottom = 1; |
80 } | 83 } |
81 | 84 |
82 segment_->AddVideoTrack(width, height, 1); | 85 segment_->AddVideoTrack(width, height, 1); |
83 mkvmuxer::VideoTrack* video_track = | 86 mkvmuxer::VideoTrack* video_track = |
84 reinterpret_cast<mkvmuxer::VideoTrack*>(segment_->GetTrackByNumber(1)); | 87 reinterpret_cast<mkvmuxer::VideoTrack*>(segment_->GetTrackByNumber(1)); |
85 video_track->set_crop_right(crop_right); | 88 video_track->set_crop_right(crop_right); |
86 video_track->set_crop_bottom(crop_bottom); | 89 video_track->set_crop_bottom(crop_bottom); |
87 video_track->set_frame_rate(base::Time::kNanosecondsPerSecond / | 90 video_track->set_frame_rate(base::Time::kNanosecondsPerSecond / |
88 kFrameIntervalNs); | 91 kFrameIntervalNs); |
89 video_track->set_default_duration(base::Time::kNanosecondsPerSecond); | 92 video_track->set_default_duration(kFrameIntervalNs); |
90 mkvmuxer::SegmentInfo* const info = segment_->GetSegmentInfo(); | 93 mkvmuxer::SegmentInfo* const info = segment_->GetSegmentInfo(); |
91 info->set_writing_app("ChromotingViewer"); | 94 info->set_writing_app("ChromotingViewer"); |
92 info->set_muxing_app("ChromotingViewer"); | 95 info->set_muxing_app("ChromotingViewer"); |
93 } | 96 } |
94 | 97 |
95 MediaSourceVideoRenderer::VideoWriter::~VideoWriter() {} | 98 MediaSourceVideoRenderer::VideoWriter::~VideoWriter() {} |
96 | 99 |
97 mkvmuxer::int32 MediaSourceVideoRenderer::VideoWriter::Write( | 100 mkvmuxer::int32 MediaSourceVideoRenderer::VideoWriter::Write( |
98 const void* buf, | 101 const void* buf, |
99 mkvmuxer::uint32 len) { | 102 mkvmuxer::uint32 len) { |
(...skipping 17 matching lines...) Expand all Loading... | |
117 return false; | 120 return false; |
118 } | 121 } |
119 | 122 |
120 void MediaSourceVideoRenderer::VideoWriter::ElementStartNotify( | 123 void MediaSourceVideoRenderer::VideoWriter::ElementStartNotify( |
121 mkvmuxer::uint64 element_id, | 124 mkvmuxer::uint64 element_id, |
122 mkvmuxer::int64 position) { | 125 mkvmuxer::int64 position) { |
123 } | 126 } |
124 | 127 |
125 scoped_ptr<MediaSourceVideoRenderer::VideoWriter::DataBuffer> | 128 scoped_ptr<MediaSourceVideoRenderer::VideoWriter::DataBuffer> |
126 MediaSourceVideoRenderer::VideoWriter::OnVideoFrame( | 129 MediaSourceVideoRenderer::VideoWriter::OnVideoFrame( |
127 const std::string& video_data) { | 130 const std::string& video_data, |
131 bool keyframe) { | |
128 DCHECK(!output_data_); | 132 DCHECK(!output_data_); |
129 | 133 |
130 output_data_.reset(new DataBuffer()); | 134 output_data_.reset(new DataBuffer()); |
131 bool first_frame = (timecode_ == 0); | |
132 segment_->AddFrame(reinterpret_cast<const uint8_t*>(video_data.data()), | 135 segment_->AddFrame(reinterpret_cast<const uint8_t*>(video_data.data()), |
133 video_data.size(), 1, timecode_, first_frame); | 136 video_data.size(), 1, timecode_, keyframe); |
134 timecode_ += kFrameIntervalNs; | 137 timecode_ += kFrameIntervalNs; |
135 return output_data_.Pass(); | 138 return output_data_.Pass(); |
136 } | 139 } |
137 | 140 |
138 MediaSourceVideoRenderer::MediaSourceVideoRenderer(Delegate* delegate) | 141 MediaSourceVideoRenderer::MediaSourceVideoRenderer(Delegate* delegate) |
139 : delegate_(delegate), | 142 : delegate_(delegate), |
140 latest_sequence_number_(0) { | 143 latest_sequence_number_(0) { |
141 } | 144 } |
142 | 145 |
143 MediaSourceVideoRenderer::~MediaSourceVideoRenderer() {} | 146 MediaSourceVideoRenderer::~MediaSourceVideoRenderer() {} |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 // Fallback for the case when the host didn't include the desktop shape. | 211 // Fallback for the case when the host didn't include the desktop shape. |
209 desktop_shape = | 212 desktop_shape = |
210 webrtc::DesktopRegion(webrtc::DesktopRect::MakeSize(frame_size)); | 213 webrtc::DesktopRegion(webrtc::DesktopRect::MakeSize(frame_size)); |
211 } | 214 } |
212 | 215 |
213 if (!desktop_shape_.Equals(desktop_shape)) { | 216 if (!desktop_shape_.Equals(desktop_shape)) { |
214 desktop_shape_.Swap(&desktop_shape); | 217 desktop_shape_.Swap(&desktop_shape); |
215 delegate_->OnMediaSourceShape(desktop_shape_); | 218 delegate_->OnMediaSourceShape(desktop_shape_); |
216 } | 219 } |
217 | 220 |
221 // First bit indicates I-frames. | |
Jamie
2014/06/11 21:41:42
s/I/key/?
Sergey Ulanov
2014/06/11 23:41:12
Done.
| |
222 bool keyframe = (packet->data()[0] & 1) == 0; | |
223 | |
218 scoped_ptr<VideoWriter::DataBuffer> buffer = | 224 scoped_ptr<VideoWriter::DataBuffer> buffer = |
219 writer_->OnVideoFrame(packet->data()); | 225 writer_->OnVideoFrame(packet->data(), keyframe); |
220 delegate_->OnMediaSourceData(&(*(buffer->begin())), buffer->size()); | 226 delegate_->OnMediaSourceData(&(*(buffer->begin())), buffer->size(), keyframe); |
221 } | 227 } |
222 | 228 |
223 } // namespace remoting | 229 } // namespace remoting |
OLD | NEW |