OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/filters/video_decoder_impl.h" | 5 #include "media/filters/video_decoder_impl.h" |
6 | 6 |
7 #include "base/task.h" | 7 #include "base/task.h" |
8 #include "media/base/filters.h" | 8 #include "media/base/filters.h" |
9 #include "media/base/limits.h" | 9 #include "media/base/limits.h" |
10 #include "media/base/video_frame.h" | 10 #include "media/base/video_frame.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 205 |
206 VideoDecoderImpl::TimeTuple VideoDecoderImpl::FindPtsAndDuration( | 206 VideoDecoderImpl::TimeTuple VideoDecoderImpl::FindPtsAndDuration( |
207 const AVRational& time_base, | 207 const AVRational& time_base, |
208 const PtsHeap& pts_heap, | 208 const PtsHeap& pts_heap, |
209 const TimeTuple& last_pts, | 209 const TimeTuple& last_pts, |
210 const VideoFrame* frame) { | 210 const VideoFrame* frame) { |
211 TimeTuple pts; | 211 TimeTuple pts; |
212 | 212 |
213 // First search the VideoFrame for the pts. This is the most authoritative. | 213 // First search the VideoFrame for the pts. This is the most authoritative. |
214 // Make a special exclusion for the value pts == 0. Though this is | 214 // Make a special exclusion for the value pts == 0. Though this is |
215 // technically a valid value, it seems a number of ffmpeg codecs will | 215 // technically a valid value, it seems a number of FFmpeg codecs will |
216 // mistakenly always set pts to 0. | 216 // mistakenly always set pts to 0. |
| 217 // |
| 218 // TODO(scherkus): FFmpegVideoDecodeEngine should be able to detect this |
| 219 // situation and set the timestamp to kInvalidTimestamp. |
217 DCHECK(frame); | 220 DCHECK(frame); |
218 base::TimeDelta timestamp = frame->GetTimestamp(); | 221 base::TimeDelta timestamp = frame->GetTimestamp(); |
219 if (timestamp != StreamSample::kInvalidTimestamp && | 222 if (timestamp != StreamSample::kInvalidTimestamp && |
220 timestamp.ToInternalValue() != 0) { | 223 timestamp.ToInternalValue() != 0) { |
221 pts.timestamp = ConvertTimestamp(time_base, timestamp.ToInternalValue()); | 224 pts.timestamp = timestamp; |
222 pts.duration = ConvertTimestamp(time_base, 1 + frame->GetRepeatCount()); | 225 } else if (!pts_heap.IsEmpty()) { |
223 return pts; | 226 // If the frame did not have pts, try to get the pts from the |pts_heap|. |
| 227 pts.timestamp = pts_heap.Top(); |
| 228 } else if (last_pts.timestamp != StreamSample::kInvalidTimestamp && |
| 229 last_pts.duration != StreamSample::kInvalidTimestamp) { |
| 230 // Guess assuming this frame was the same as the last frame. |
| 231 pts.timestamp = last_pts.timestamp + last_pts.duration; |
| 232 } else { |
| 233 // Now we really have no clue!!! Mark an invalid timestamp and let the |
| 234 // video renderer handle it (i.e., drop frame). |
| 235 pts.timestamp = StreamSample::kInvalidTimestamp; |
224 } | 236 } |
225 | 237 |
226 if (!pts_heap.IsEmpty()) { | 238 // Fill in the duration, using the frame itself as the authoratative source. |
227 // If the frame did not have pts, try to get the pts from the |pts_heap|. | 239 base::TimeDelta duration = frame->GetDuration(); |
228 pts.timestamp = pts_heap.Top(); | 240 if (duration != StreamSample::kInvalidTimestamp && |
| 241 duration.ToInternalValue() != 0) { |
| 242 pts.duration = duration; |
229 } else { | 243 } else { |
230 DCHECK(last_pts.timestamp != StreamSample::kInvalidTimestamp); | 244 // Otherwise assume a normal frame duration. |
231 DCHECK(last_pts.duration != StreamSample::kInvalidTimestamp); | 245 pts.duration = ConvertTimestamp(time_base, 1); |
232 // Unable to read the pts from anywhere. Time to guess. | |
233 pts.timestamp = last_pts.timestamp + last_pts.duration; | |
234 } | 246 } |
235 | 247 |
236 // Fill in the duration while accounting for repeated frames. | |
237 pts.duration = ConvertTimestamp(time_base, 1); | |
238 | |
239 return pts; | 248 return pts; |
240 } | 249 } |
241 | 250 |
242 void VideoDecoderImpl::SignalPipelineError() { | 251 void VideoDecoderImpl::SignalPipelineError() { |
243 host()->SetError(PIPELINE_ERROR_DECODE); | 252 host()->SetError(PIPELINE_ERROR_DECODE); |
244 state_ = kDecodeFinished; | 253 state_ = kDecodeFinished; |
245 } | 254 } |
246 | 255 |
247 void VideoDecoderImpl::SetVideoDecodeEngineForTest( | 256 void VideoDecoderImpl::SetVideoDecodeEngineForTest( |
248 VideoDecodeEngine* engine) { | 257 VideoDecodeEngine* engine) { |
249 decode_engine_.reset(engine); | 258 decode_engine_.reset(engine); |
250 } | 259 } |
251 | 260 |
252 } // namespace media | 261 } // namespace media |
OLD | NEW |