OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/cast/video_receiver/video_receiver.h" | 5 #include "media/cast/video_receiver/video_receiver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 GetEncodedVideoFrame(base::Bind( | 87 GetEncodedVideoFrame(base::Bind( |
88 &VideoReceiver::DecodeEncodedVideoFrame, | 88 &VideoReceiver::DecodeEncodedVideoFrame, |
89 // Note: Use of Unretained is safe since this Closure is guaranteed to be | 89 // Note: Use of Unretained is safe since this Closure is guaranteed to be |
90 // invoked before destruction of |this|. | 90 // invoked before destruction of |this|. |
91 base::Unretained(this), | 91 base::Unretained(this), |
92 callback)); | 92 callback)); |
93 } | 93 } |
94 | 94 |
95 void VideoReceiver::DecodeEncodedVideoFrame( | 95 void VideoReceiver::DecodeEncodedVideoFrame( |
96 const VideoFrameDecodedCallback& callback, | 96 const VideoFrameDecodedCallback& callback, |
97 scoped_ptr<transport::EncodedVideoFrame> encoded_frame, | 97 scoped_ptr<transport::EncodedFrame> encoded_frame) { |
98 const base::TimeTicks& playout_time) { | |
99 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 98 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
100 if (!encoded_frame) { | 99 if (!encoded_frame) { |
101 callback.Run(make_scoped_refptr<VideoFrame>(NULL), playout_time, false); | 100 callback.Run( |
| 101 make_scoped_refptr<VideoFrame>(NULL), base::TimeTicks(), false); |
102 return; | 102 return; |
103 } | 103 } |
104 const uint32 frame_id = encoded_frame->frame_id; | 104 const uint32 frame_id = encoded_frame->frame_id; |
105 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp; | 105 const uint32 rtp_timestamp = encoded_frame->rtp_timestamp; |
| 106 const base::TimeTicks playout_time = encoded_frame->reference_time; |
106 video_decoder_->DecodeFrame(encoded_frame.Pass(), | 107 video_decoder_->DecodeFrame(encoded_frame.Pass(), |
107 base::Bind(&VideoReceiver::EmitRawVideoFrame, | 108 base::Bind(&VideoReceiver::EmitRawVideoFrame, |
108 cast_environment_, | 109 cast_environment_, |
109 callback, | 110 callback, |
110 frame_id, | 111 frame_id, |
111 rtp_timestamp, | 112 rtp_timestamp, |
112 playout_time)); | 113 playout_time)); |
113 } | 114 } |
114 | 115 |
115 // static | 116 // static |
(...skipping 15 matching lines...) Expand all Loading... |
131 playout_time - now); | 132 playout_time - now); |
132 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 133 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
133 TRACE_EVENT_INSTANT1( | 134 TRACE_EVENT_INSTANT1( |
134 "cast_perf_test", "FrameDecoded", | 135 "cast_perf_test", "FrameDecoded", |
135 TRACE_EVENT_SCOPE_THREAD, | 136 TRACE_EVENT_SCOPE_THREAD, |
136 "rtp_timestamp", rtp_timestamp); | 137 "rtp_timestamp", rtp_timestamp); |
137 } | 138 } |
138 callback.Run(video_frame, playout_time, is_continuous); | 139 callback.Run(video_frame, playout_time, is_continuous); |
139 } | 140 } |
140 | 141 |
141 void VideoReceiver::GetEncodedVideoFrame( | 142 void VideoReceiver::GetEncodedVideoFrame(const FrameEncodedCallback& callback) { |
142 const VideoFrameEncodedCallback& callback) { | |
143 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 143 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
144 frame_request_queue_.push_back(callback); | 144 frame_request_queue_.push_back(callback); |
145 EmitAvailableEncodedFrames(); | 145 EmitAvailableEncodedFrames(); |
146 } | 146 } |
147 | 147 |
148 void VideoReceiver::EmitAvailableEncodedFrames() { | 148 void VideoReceiver::EmitAvailableEncodedFrames() { |
149 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 149 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
150 | 150 |
151 while (!frame_request_queue_.empty()) { | 151 while (!frame_request_queue_.empty()) { |
152 // Attempt to peek at the next completed frame from the |framer_|. | 152 // Attempt to peek at the next completed frame from the |framer_|. |
153 // TODO(miu): We should only be peeking at the metadata, and not copying the | 153 // TODO(miu): We should only be peeking at the metadata, and not copying the |
154 // payload yet! Or, at least, peek using a StringPiece instead of a copy. | 154 // payload yet! Or, at least, peek using a StringPiece instead of a copy. |
155 scoped_ptr<transport::EncodedVideoFrame> encoded_frame( | 155 scoped_ptr<transport::EncodedFrame> encoded_frame( |
156 new transport::EncodedVideoFrame()); | 156 new transport::EncodedFrame()); |
157 bool is_consecutively_next_frame = false; | 157 bool is_consecutively_next_frame = false; |
158 if (!framer_.GetEncodedVideoFrame(encoded_frame.get(), | 158 if (!framer_.GetEncodedVideoFrame(encoded_frame.get(), |
159 &is_consecutively_next_frame)) { | 159 &is_consecutively_next_frame)) { |
160 VLOG(1) << "Wait for more video packets to produce a completed frame."; | 160 VLOG(1) << "Wait for more video packets to produce a completed frame."; |
161 return; // OnReceivedPayloadData() will invoke this method in the future. | 161 return; // OnReceivedPayloadData() will invoke this method in the future. |
162 } | 162 } |
163 | 163 |
164 // If |framer_| has a frame ready that is out of sequence, examine the | 164 // If |framer_| has a frame ready that is out of sequence, examine the |
165 // playout time to determine whether it's acceptable to continue, thereby | 165 // playout time to determine whether it's acceptable to continue, thereby |
166 // skipping one or more frames. Skip if the missing frame wouldn't complete | 166 // skipping one or more frames. Skip if the missing frame wouldn't complete |
(...skipping 27 matching lines...) Expand all Loading... |
194 encoded_frame->data, | 194 encoded_frame->data, |
195 &decrypted_video_data)) { | 195 &decrypted_video_data)) { |
196 // Decryption failed. Give up on this frame, releasing it from the | 196 // Decryption failed. Give up on this frame, releasing it from the |
197 // jitter buffer. | 197 // jitter buffer. |
198 framer_.ReleaseFrame(encoded_frame->frame_id); | 198 framer_.ReleaseFrame(encoded_frame->frame_id); |
199 continue; | 199 continue; |
200 } | 200 } |
201 encoded_frame->data.swap(decrypted_video_data); | 201 encoded_frame->data.swap(decrypted_video_data); |
202 } | 202 } |
203 | 203 |
204 // At this point, we have a decrypted EncodedVideoFrame ready to be emitted. | 204 // At this point, we have a decrypted EncodedFrame ready to be emitted. |
205 encoded_frame->codec = codec_; | 205 encoded_frame->reference_time = playout_time; |
206 framer_.ReleaseFrame(encoded_frame->frame_id); | 206 framer_.ReleaseFrame(encoded_frame->frame_id); |
207 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc | 207 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc |
208 TRACE_EVENT_INSTANT2( | 208 TRACE_EVENT_INSTANT2( |
209 "cast_perf_test", "PullEncodedVideoFrame", | 209 "cast_perf_test", "PullEncodedVideoFrame", |
210 TRACE_EVENT_SCOPE_THREAD, | 210 TRACE_EVENT_SCOPE_THREAD, |
211 "rtp_timestamp", encoded_frame->rtp_timestamp, | 211 "rtp_timestamp", encoded_frame->rtp_timestamp, |
212 // TODO(miu): Need to find an alternative to using ToInternalValue(): | 212 // TODO(miu): Need to find an alternative to using ToInternalValue(): |
213 "render_time", playout_time.ToInternalValue()); | 213 "render_time", playout_time.ToInternalValue()); |
214 cast_environment_->PostTask(CastEnvironment::MAIN, | 214 cast_environment_->PostTask(CastEnvironment::MAIN, |
215 FROM_HERE, | 215 FROM_HERE, |
216 base::Bind(frame_request_queue_.front(), | 216 base::Bind(frame_request_queue_.front(), |
217 base::Passed(&encoded_frame), | 217 base::Passed(&encoded_frame))); |
218 playout_time)); | |
219 frame_request_queue_.pop_front(); | 218 frame_request_queue_.pop_front(); |
220 } | 219 } |
221 } | 220 } |
222 | 221 |
223 void VideoReceiver::EmitAvailableEncodedFramesAfterWaiting() { | 222 void VideoReceiver::EmitAvailableEncodedFramesAfterWaiting() { |
224 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 223 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
225 DCHECK(is_waiting_for_consecutive_frame_); | 224 DCHECK(is_waiting_for_consecutive_frame_); |
226 is_waiting_for_consecutive_frame_ = false; | 225 is_waiting_for_consecutive_frame_ = false; |
227 EmitAvailableEncodedFrames(); | 226 EmitAvailableEncodedFrames(); |
228 } | 227 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 } | 409 } |
411 | 410 |
412 void VideoReceiver::SendNextRtcpReport() { | 411 void VideoReceiver::SendNextRtcpReport() { |
413 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 412 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
414 rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); | 413 rtcp_.SendRtcpFromRtpReceiver(NULL, NULL); |
415 ScheduleNextRtcpReport(); | 414 ScheduleNextRtcpReport(); |
416 } | 415 } |
417 | 416 |
418 } // namespace cast | 417 } // namespace cast |
419 } // namespace media | 418 } // namespace media |
OLD | NEW |