OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/source_buffer_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 TRACE_EVENT2("media", "SourceBufferStream::Append", | 182 TRACE_EVENT2("media", "SourceBufferStream::Append", |
183 "stream type", GetStreamTypeName(), | 183 "stream type", GetStreamTypeName(), |
184 "buffers to append", buffers.size()); | 184 "buffers to append", buffers.size()); |
185 | 185 |
186 DCHECK(!buffers.empty()); | 186 DCHECK(!buffers.empty()); |
187 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); | 187 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp()); |
188 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); | 188 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp()); |
189 DCHECK(!end_of_stream_); | 189 DCHECK(!end_of_stream_); |
190 | 190 |
191 // New media segments must begin with a keyframe. | 191 // New media segments must begin with a keyframe. |
192 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { | 192 if (new_media_segment_ && !buffers.front()->is_key_frame()) { |
193 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe."; | 193 MEDIA_LOG(log_cb_) << "Media segment did not begin with key frame."; |
194 return false; | 194 return false; |
195 } | 195 } |
196 | 196 |
197 // Buffers within a media segment should be monotonically increasing. | 197 // Buffers within a media segment should be monotonically increasing. |
198 if (!IsMonotonicallyIncreasing(buffers)) | 198 if (!IsMonotonicallyIncreasing(buffers)) |
199 return false; | 199 return false; |
200 | 200 |
201 if (media_segment_start_time_ < DecodeTimestamp() || | 201 if (media_segment_start_time_ < DecodeTimestamp() || |
202 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { | 202 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) { |
203 MEDIA_LOG(log_cb_) | 203 MEDIA_LOG(log_cb_) |
204 << "Cannot append a media segment with negative timestamps."; | 204 << "Cannot append a media segment with negative timestamps."; |
205 return false; | 205 return false; |
206 } | 206 } |
207 | 207 |
208 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), | 208 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(), |
209 buffers.front()->IsKeyframe())) { | 209 buffers.front()->is_key_frame())) { |
210 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time " | 210 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time " |
211 << buffers.front()->GetDecodeTimestamp().InSecondsF(); | 211 << buffers.front()->GetDecodeTimestamp().InSecondsF(); |
212 | 212 |
213 return false; | 213 return false; |
214 } | 214 } |
215 | 215 |
216 UpdateMaxInterbufferDistance(buffers); | 216 UpdateMaxInterbufferDistance(buffers); |
217 SetConfigIds(buffers); | 217 SetConfigIds(buffers); |
218 | 218 |
219 // Save a snapshot of stream state before range modifications are made. | 219 // Save a snapshot of stream state before range modifications are made. |
220 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 220 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); |
221 BufferQueue deleted_buffers; | 221 BufferQueue deleted_buffers; |
222 | 222 |
223 PrepareRangesForNextAppend(buffers, &deleted_buffers); | 223 PrepareRangesForNextAppend(buffers, &deleted_buffers); |
224 | 224 |
225 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, | 225 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise, |
226 // create a new range with |buffers|. | 226 // create a new range with |buffers|. |
227 if (range_for_next_append_ != ranges_.end()) { | 227 if (range_for_next_append_ != ranges_.end()) { |
228 (*range_for_next_append_)->AppendBuffersToEnd(buffers); | 228 (*range_for_next_append_)->AppendBuffersToEnd(buffers); |
229 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 229 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
230 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); | 230 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); |
231 } else { | 231 } else { |
232 DecodeTimestamp new_range_start_time = std::min( | 232 DecodeTimestamp new_range_start_time = std::min( |
233 media_segment_start_time_, buffers.front()->GetDecodeTimestamp()); | 233 media_segment_start_time_, buffers.front()->GetDecodeTimestamp()); |
234 const BufferQueue* buffers_for_new_range = &buffers; | 234 const BufferQueue* buffers_for_new_range = &buffers; |
235 BufferQueue trimmed_buffers; | 235 BufferQueue trimmed_buffers; |
236 | 236 |
237 // If the new range is not being created because of a new media | 237 // If the new range is not being created because of a new media |
238 // segment, then we must make sure that we start with a keyframe. | 238 // segment, then we must make sure that we start with a key frame. |
239 // This can happen if the GOP in the previous append gets destroyed | 239 // This can happen if the GOP in the previous append gets destroyed |
240 // by a Remove() call. | 240 // by a Remove() call. |
241 if (!new_media_segment_) { | 241 if (!new_media_segment_) { |
242 BufferQueue::const_iterator itr = buffers.begin(); | 242 BufferQueue::const_iterator itr = buffers.begin(); |
243 | 243 |
244 // Scan past all the non-keyframes. | 244 // Scan past all the non-key-frames. |
245 while (itr != buffers.end() && !(*itr)->IsKeyframe()) { | 245 while (itr != buffers.end() && !(*itr)->is_key_frame()) { |
246 ++itr; | 246 ++itr; |
247 } | 247 } |
248 | 248 |
249 // If we didn't find a keyframe, then update the last appended | 249 // If we didn't find a key frame, then update the last appended |
250 // buffer state and return. | 250 // buffer state and return. |
251 if (itr == buffers.end()) { | 251 if (itr == buffers.end()) { |
252 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); | 252 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp(); |
253 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe(); | 253 last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame(); |
254 return true; | 254 return true; |
255 } else if (itr != buffers.begin()) { | 255 } else if (itr != buffers.begin()) { |
256 // Copy the first keyframe and everything after it into | 256 // Copy the first key frame and everything after it into |
257 // |trimmed_buffers|. | 257 // |trimmed_buffers|. |
258 trimmed_buffers.assign(itr, buffers.end()); | 258 trimmed_buffers.assign(itr, buffers.end()); |
259 buffers_for_new_range = &trimmed_buffers; | 259 buffers_for_new_range = &trimmed_buffers; |
260 } | 260 } |
261 | 261 |
262 new_range_start_time = | 262 new_range_start_time = |
263 buffers_for_new_range->front()->GetDecodeTimestamp(); | 263 buffers_for_new_range->front()->GetDecodeTimestamp(); |
264 } | 264 } |
265 | 265 |
266 range_for_next_append_ = | 266 range_for_next_append_ = |
267 AddToRanges(new SourceBufferRange( | 267 AddToRanges(new SourceBufferRange( |
268 TypeToGapPolicy(GetType()), | 268 TypeToGapPolicy(GetType()), |
269 *buffers_for_new_range, new_range_start_time, | 269 *buffers_for_new_range, new_range_start_time, |
270 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, | 270 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
271 base::Unretained(this)))); | 271 base::Unretained(this)))); |
272 last_appended_buffer_timestamp_ = | 272 last_appended_buffer_timestamp_ = |
273 buffers_for_new_range->back()->GetDecodeTimestamp(); | 273 buffers_for_new_range->back()->GetDecodeTimestamp(); |
274 last_appended_buffer_is_keyframe_ = | 274 last_appended_buffer_is_keyframe_ = |
275 buffers_for_new_range->back()->IsKeyframe(); | 275 buffers_for_new_range->back()->is_key_frame(); |
276 } | 276 } |
277 | 277 |
278 new_media_segment_ = false; | 278 new_media_segment_ = false; |
279 | 279 |
280 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); | 280 MergeWithAdjacentRangeIfNecessary(range_for_next_append_); |
281 | 281 |
282 // Seek to try to fulfill a previous call to Seek(). | 282 // Seek to try to fulfill a previous call to Seek(). |
283 if (seek_pending_) { | 283 if (seek_pending_) { |
284 DCHECK(!selected_range_); | 284 DCHECK(!selected_range_); |
285 DCHECK(deleted_buffers.empty()); | 285 DCHECK(deleted_buffers.empty()); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 } | 449 } |
450 | 450 |
451 bool SourceBufferStream::IsMonotonicallyIncreasing( | 451 bool SourceBufferStream::IsMonotonicallyIncreasing( |
452 const BufferQueue& buffers) const { | 452 const BufferQueue& buffers) const { |
453 DCHECK(!buffers.empty()); | 453 DCHECK(!buffers.empty()); |
454 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 454 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
455 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | 455 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; |
456 for (BufferQueue::const_iterator itr = buffers.begin(); | 456 for (BufferQueue::const_iterator itr = buffers.begin(); |
457 itr != buffers.end(); ++itr) { | 457 itr != buffers.end(); ++itr) { |
458 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); | 458 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp(); |
459 bool current_is_keyframe = (*itr)->IsKeyframe(); | 459 bool current_is_keyframe = (*itr)->is_key_frame(); |
460 DCHECK(current_timestamp != kNoDecodeTimestamp()); | 460 DCHECK(current_timestamp != kNoDecodeTimestamp()); |
461 DCHECK((*itr)->duration() >= base::TimeDelta()) | 461 DCHECK((*itr)->duration() >= base::TimeDelta()) |
462 << "Packet with invalid duration." | 462 << "Packet with invalid duration." |
463 << " pts " << (*itr)->timestamp().InSecondsF() | 463 << " pts " << (*itr)->timestamp().InSecondsF() |
464 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() | 464 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF() |
465 << " dur " << (*itr)->duration().InSecondsF(); | 465 << " dur " << (*itr)->duration().InSecondsF(); |
466 | 466 |
467 if (prev_timestamp != kNoDecodeTimestamp()) { | 467 if (prev_timestamp != kNoDecodeTimestamp()) { |
468 if (current_timestamp < prev_timestamp) { | 468 if (current_timestamp < prev_timestamp) { |
469 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; | 469 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing."; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 | 733 |
734 // Handle splices between the existing buffers and the new buffers. If a | 734 // Handle splices between the existing buffers and the new buffers. If a |
735 // splice is generated the timestamp and duration of the first buffer in | 735 // splice is generated the timestamp and duration of the first buffer in |
736 // |new_buffers| will be modified. | 736 // |new_buffers| will be modified. |
737 if (splice_frames_enabled_) | 737 if (splice_frames_enabled_) |
738 GenerateSpliceFrame(new_buffers); | 738 GenerateSpliceFrame(new_buffers); |
739 | 739 |
740 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; | 740 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_; |
741 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; | 741 bool prev_is_keyframe = last_appended_buffer_is_keyframe_; |
742 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); | 742 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp(); |
743 bool next_is_keyframe = new_buffers.front()->IsKeyframe(); | 743 bool next_is_keyframe = new_buffers.front()->is_key_frame(); |
744 | 744 |
745 if (prev_timestamp != kNoDecodeTimestamp() && | 745 if (prev_timestamp != kNoDecodeTimestamp() && |
746 prev_timestamp != next_timestamp) { | 746 prev_timestamp != next_timestamp) { |
747 // Clean up the old buffers between the last appended buffer and the | 747 // Clean up the old buffers between the last appended buffer and the |
748 // beginning of |new_buffers|. | 748 // beginning of |new_buffers|. |
749 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); | 749 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers); |
750 } | 750 } |
751 | 751 |
752 // Make the delete range exclusive if we are dealing with an allowed same | 752 // Make the delete range exclusive if we are dealing with an allowed same |
753 // timestamp situation. This prevents the first buffer in the current append | 753 // timestamp situation. This prevents the first buffer in the current append |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 return false; | 1471 return false; |
1472 | 1472 |
1473 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1473 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1474 splice_buffers_index_ = 0; | 1474 splice_buffers_index_ = 0; |
1475 pending_buffer_.swap(*out_buffer); | 1475 pending_buffer_.swap(*out_buffer); |
1476 pending_buffers_complete_ = false; | 1476 pending_buffers_complete_ = false; |
1477 return true; | 1477 return true; |
1478 } | 1478 } |
1479 | 1479 |
1480 } // namespace media | 1480 } // namespace media |
OLD | NEW |