OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "media/muxers/webm_muxer.h" | 5 #include "media/muxers/webm_muxer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" |
8 #include "media/base/audio_parameters.h" | 9 #include "media/base/audio_parameters.h" |
9 #include "media/base/limits.h" | 10 #include "media/base/limits.h" |
10 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
11 #include "media/filters/opus_constants.h" | 12 #include "media/filters/opus_constants.h" |
12 #include "ui/gfx/geometry/size.h" | 13 #include "ui/gfx/geometry/size.h" |
13 | 14 |
14 namespace media { | 15 namespace media { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 } | 100 } |
100 | 101 |
101 WebmMuxer::~WebmMuxer() { | 102 WebmMuxer::~WebmMuxer() { |
102 // No need to segment_.Finalize() since is not Seekable(), i.e. a live | 103 // No need to segment_.Finalize() since is not Seekable(), i.e. a live |
103 // stream, but is a good practice. | 104 // stream, but is a good practice. |
104 DCHECK(thread_checker_.CalledOnValidThread()); | 105 DCHECK(thread_checker_.CalledOnValidThread()); |
105 segment_.Finalize(); | 106 segment_.Finalize(); |
106 } | 107 } |
107 | 108 |
108 void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame, | 109 void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame, |
109 scoped_ptr<std::string> encoded_data, | 110 std::unique_ptr<std::string> encoded_data, |
110 base::TimeTicks timestamp, | 111 base::TimeTicks timestamp, |
111 bool is_key_frame) { | 112 bool is_key_frame) { |
112 DVLOG(1) << __FUNCTION__ << " - " << encoded_data->size() << "B"; | 113 DVLOG(1) << __FUNCTION__ << " - " << encoded_data->size() << "B"; |
113 DCHECK(thread_checker_.CalledOnValidThread()); | 114 DCHECK(thread_checker_.CalledOnValidThread()); |
114 | 115 |
115 if (!video_track_index_) { | 116 if (!video_track_index_) { |
116 // |track_index_|, cannot be zero (!), initialize WebmMuxer in that case. | 117 // |track_index_|, cannot be zero (!), initialize WebmMuxer in that case. |
117 // http://www.matroska.org/technical/specs/index.html#Tracks | 118 // http://www.matroska.org/technical/specs/index.html#Tracks |
118 AddVideoTrack(video_frame->visible_rect().size(), | 119 AddVideoTrack(video_frame->visible_rect().size(), |
119 GetFrameRate(video_frame)); | 120 GetFrameRate(video_frame)); |
120 if (first_frame_timestamp_video_.is_null()) | 121 if (first_frame_timestamp_video_.is_null()) |
121 first_frame_timestamp_video_ = timestamp; | 122 first_frame_timestamp_video_ = timestamp; |
122 } | 123 } |
123 | 124 |
124 // TODO(ajose): Support multiple tracks: http://crbug.com/528523 | 125 // TODO(ajose): Support multiple tracks: http://crbug.com/528523 |
125 if (has_audio_ && !audio_track_index_) { | 126 if (has_audio_ && !audio_track_index_) { |
126 DVLOG(1) << __FUNCTION__ << ": delaying until audio track ready."; | 127 DVLOG(1) << __FUNCTION__ << ": delaying until audio track ready."; |
127 if (is_key_frame) // Upon Key frame reception, empty the encoded queue. | 128 if (is_key_frame) // Upon Key frame reception, empty the encoded queue. |
128 encoded_frames_queue_.clear(); | 129 encoded_frames_queue_.clear(); |
129 | 130 |
130 encoded_frames_queue_.push_back(make_scoped_ptr(new EncodedVideoFrame( | 131 encoded_frames_queue_.push_back(base::WrapUnique(new EncodedVideoFrame( |
131 std::move(encoded_data), timestamp, is_key_frame))); | 132 std::move(encoded_data), timestamp, is_key_frame))); |
132 return; | 133 return; |
133 } | 134 } |
134 | 135 |
135 // Dump all saved encoded video frames if any. | 136 // Dump all saved encoded video frames if any. |
136 while (!encoded_frames_queue_.empty()) { | 137 while (!encoded_frames_queue_.empty()) { |
137 AddFrame( | 138 AddFrame( |
138 std::move(encoded_frames_queue_.front()->data), video_track_index_, | 139 std::move(encoded_frames_queue_.front()->data), video_track_index_, |
139 encoded_frames_queue_.front()->timestamp - first_frame_timestamp_video_, | 140 encoded_frames_queue_.front()->timestamp - first_frame_timestamp_video_, |
140 encoded_frames_queue_.front()->is_keyframe); | 141 encoded_frames_queue_.front()->is_keyframe); |
141 encoded_frames_queue_.pop_front(); | 142 encoded_frames_queue_.pop_front(); |
142 } | 143 } |
143 | 144 |
144 AddFrame(std::move(encoded_data), video_track_index_, | 145 AddFrame(std::move(encoded_data), video_track_index_, |
145 timestamp - first_frame_timestamp_video_, is_key_frame); | 146 timestamp - first_frame_timestamp_video_, is_key_frame); |
146 } | 147 } |
147 | 148 |
148 void WebmMuxer::OnEncodedAudio(const media::AudioParameters& params, | 149 void WebmMuxer::OnEncodedAudio(const media::AudioParameters& params, |
149 scoped_ptr<std::string> encoded_data, | 150 std::unique_ptr<std::string> encoded_data, |
150 base::TimeTicks timestamp) { | 151 base::TimeTicks timestamp) { |
151 DVLOG(2) << __FUNCTION__ << " - " << encoded_data->size() << "B"; | 152 DVLOG(2) << __FUNCTION__ << " - " << encoded_data->size() << "B"; |
152 DCHECK(thread_checker_.CalledOnValidThread()); | 153 DCHECK(thread_checker_.CalledOnValidThread()); |
153 | 154 |
154 if (!audio_track_index_) { | 155 if (!audio_track_index_) { |
155 AddAudioTrack(params); | 156 AddAudioTrack(params); |
156 if (first_frame_timestamp_audio_.is_null()) | 157 if (first_frame_timestamp_audio_.is_null()) |
157 first_frame_timestamp_audio_ = timestamp; | 158 first_frame_timestamp_audio_ = timestamp; |
158 } | 159 } |
159 | 160 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 return false; | 275 return false; |
275 } | 276 } |
276 | 277 |
277 void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id, | 278 void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id, |
278 mkvmuxer::int64 position) { | 279 mkvmuxer::int64 position) { |
279 // This method gets pinged before items are sent to |write_data_callback_|. | 280 // This method gets pinged before items are sent to |write_data_callback_|. |
280 DCHECK_GE(position, position_.ValueOrDefault(0)) | 281 DCHECK_GE(position, position_.ValueOrDefault(0)) |
281 << "Can't go back in a live WebM stream."; | 282 << "Can't go back in a live WebM stream."; |
282 } | 283 } |
283 | 284 |
284 void WebmMuxer::AddFrame(scoped_ptr<std::string> encoded_data, | 285 void WebmMuxer::AddFrame(std::unique_ptr<std::string> encoded_data, |
285 uint8_t track_index, | 286 uint8_t track_index, |
286 base::TimeDelta timestamp, | 287 base::TimeDelta timestamp, |
287 bool is_key_frame) { | 288 bool is_key_frame) { |
288 DCHECK(thread_checker_.CalledOnValidThread()); | 289 DCHECK(thread_checker_.CalledOnValidThread()); |
289 DCHECK(!has_video_ || video_track_index_); | 290 DCHECK(!has_video_ || video_track_index_); |
290 DCHECK(!has_audio_ || audio_track_index_); | 291 DCHECK(!has_audio_ || audio_track_index_); |
291 | 292 |
292 most_recent_timestamp_ = | 293 most_recent_timestamp_ = |
293 std::max(most_recent_timestamp_, timestamp - total_time_in_pause_); | 294 std::max(most_recent_timestamp_, timestamp - total_time_in_pause_); |
294 | 295 |
295 segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data->data()), | 296 segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data->data()), |
296 encoded_data->size(), track_index, | 297 encoded_data->size(), track_index, |
297 most_recent_timestamp_.InMicroseconds() * | 298 most_recent_timestamp_.InMicroseconds() * |
298 base::Time::kNanosecondsPerMicrosecond, | 299 base::Time::kNanosecondsPerMicrosecond, |
299 is_key_frame); | 300 is_key_frame); |
300 } | 301 } |
301 | 302 |
302 WebmMuxer::EncodedVideoFrame::EncodedVideoFrame(scoped_ptr<std::string> data, | 303 WebmMuxer::EncodedVideoFrame::EncodedVideoFrame( |
303 base::TimeTicks timestamp, | 304 std::unique_ptr<std::string> data, |
304 bool is_keyframe) | 305 base::TimeTicks timestamp, |
| 306 bool is_keyframe) |
305 : data(std::move(data)), timestamp(timestamp), is_keyframe(is_keyframe) {} | 307 : data(std::move(data)), timestamp(timestamp), is_keyframe(is_keyframe) {} |
306 | 308 |
307 WebmMuxer::EncodedVideoFrame::~EncodedVideoFrame() {} | 309 WebmMuxer::EncodedVideoFrame::~EncodedVideoFrame() {} |
308 | 310 |
309 } // namespace media | 311 } // namespace media |
OLD | NEW |