Chromium Code Reviews| 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 |