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 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 1530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { | 1541 splice_dts, max_splice_end_dts, &pre_splice_buffers)) { |
1542 return; | 1542 return; |
1543 } | 1543 } |
1544 | 1544 |
1545 // If there are gaps in the timeline, it's possible that we only find buffers | 1545 // If there are gaps in the timeline, it's possible that we only find buffers |
1546 // after the splice point but within the splice range. For simplicity, we do | 1546 // after the splice point but within the splice range. For simplicity, we do |
1547 // not generate splice frames in this case. | 1547 // not generate splice frames in this case. |
1548 // | 1548 // |
1549 // We also do not want to generate splices if the first new buffer replaces an | 1549 // We also do not want to generate splices if the first new buffer replaces an |
1550 // existing buffer exactly. | 1550 // existing buffer exactly. |
1551 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) | 1551 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) { |
| 1552 LogDegenerateSplice(); |
1552 return; | 1553 return; |
| 1554 } |
1553 | 1555 |
1554 // If any |pre_splice_buffers| are already splices or preroll, do not generate | 1556 // If any |pre_splice_buffers| are already splices or preroll, do not generate |
1555 // a splice. | 1557 // a splice. |
1556 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { | 1558 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) { |
1557 const BufferQueue& original_splice_buffers = | 1559 const BufferQueue& original_splice_buffers = |
1558 pre_splice_buffers[i]->splice_buffers(); | 1560 pre_splice_buffers[i]->splice_buffers(); |
1559 if (!original_splice_buffers.empty()) { | 1561 if (!original_splice_buffers.empty()) { |
1560 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " | 1562 DVLOG(1) << "Can't generate splice: overlapped buffers contain a " |
1561 "pre-existing splice."; | 1563 "pre-existing splice."; |
| 1564 LogDegenerateSplice(); |
1562 return; | 1565 return; |
1563 } | 1566 } |
1564 | 1567 |
1565 if (pre_splice_buffers[i]->preroll_buffer().get()) { | 1568 if (pre_splice_buffers[i]->preroll_buffer().get()) { |
1566 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; | 1569 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll."; |
| 1570 LogDegenerateSplice(); |
1567 return; | 1571 return; |
1568 } | 1572 } |
1569 } | 1573 } |
1570 | 1574 |
1571 // Don't generate splice frames which represent less than a millisecond (which | 1575 // Don't generate splice frames which represent less than a millisecond (which |
1572 // is frequently the extent of timestamp resolution for poorly encoded media) | 1576 // is frequently the extent of timestamp resolution for poorly encoded media) |
1573 // or less than two frames (need at least two to crossfade). | 1577 // or less than two frames (need at least two to crossfade). |
1574 const base::TimeDelta splice_duration = | 1578 const base::TimeDelta splice_duration = |
1575 pre_splice_buffers.back()->timestamp() + | 1579 pre_splice_buffers.back()->timestamp() + |
1576 pre_splice_buffers.back()->duration() - splice_timestamp; | 1580 pre_splice_buffers.back()->duration() - splice_timestamp; |
1577 const base::TimeDelta minimum_splice_duration = std::max( | 1581 const base::TimeDelta minimum_splice_duration = std::max( |
1578 base::TimeDelta::FromMilliseconds(1), | 1582 base::TimeDelta::FromMilliseconds(1), |
1579 base::TimeDelta::FromSecondsD( | 1583 base::TimeDelta::FromSecondsD( |
1580 2.0 / audio_configs_[append_config_index_].samples_per_second())); | 1584 2.0 / audio_configs_[append_config_index_].samples_per_second())); |
1581 if (splice_duration < minimum_splice_duration) { | 1585 if (splice_duration < minimum_splice_duration) { |
1582 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " | 1586 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have " |
1583 << splice_duration.InMicroseconds() << " us, but need " | 1587 << splice_duration.InMicroseconds() << " us, but need " |
1584 << minimum_splice_duration.InMicroseconds() << " us."; | 1588 << minimum_splice_duration.InMicroseconds() << " us."; |
| 1589 LogDegenerateSplice(); |
1585 return; | 1590 return; |
1586 } | 1591 } |
1587 | 1592 |
1588 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() | 1593 DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp() |
1589 << ", splice duration: " << splice_duration.InMicroseconds() | 1594 << ", splice duration: " << splice_duration.InMicroseconds() |
1590 << " us"; | 1595 << " us"; |
| 1596 LogSplice(splice_duration.InSecondsF()); |
1591 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); | 1597 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers); |
1592 } | 1598 } |
1593 | 1599 |
1594 bool SourceBufferStream::SetPendingBuffer( | 1600 bool SourceBufferStream::SetPendingBuffer( |
1595 scoped_refptr<StreamParserBuffer>* out_buffer) { | 1601 scoped_refptr<StreamParserBuffer>* out_buffer) { |
1596 DCHECK(out_buffer->get()); | 1602 DCHECK(out_buffer->get()); |
1597 DCHECK(!pending_buffer_.get()); | 1603 DCHECK(!pending_buffer_.get()); |
1598 | 1604 |
1599 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); | 1605 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty(); |
1600 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); | 1606 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get(); |
1601 | 1607 |
1602 if (!have_splice_buffers && !have_preroll_buffer) | 1608 if (!have_splice_buffers && !have_preroll_buffer) |
1603 return false; | 1609 return false; |
1604 | 1610 |
1605 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1611 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
1606 splice_buffers_index_ = 0; | 1612 splice_buffers_index_ = 0; |
1607 pending_buffer_.swap(*out_buffer); | 1613 pending_buffer_.swap(*out_buffer); |
1608 pending_buffers_complete_ = false; | 1614 pending_buffers_complete_ = false; |
1609 return true; | 1615 return true; |
1610 } | 1616 } |
1611 | 1617 |
| 1618 void SourceBufferStream::LogSplice(double splice_duration) { |
| 1619 splice_stats_.OnSplice(splice_duration); |
| 1620 media_log_->AddEvent( |
| 1621 media_log_->CreateBufferedSpliceStatisticsChangedEvent(splice_stats_)); |
| 1622 } |
| 1623 |
| 1624 void SourceBufferStream::LogDegenerateSplice() { |
| 1625 splice_stats_.OnDegenerateSplice(); |
| 1626 media_log_->AddEvent( |
| 1627 media_log_->CreateBufferedSpliceStatisticsChangedEvent(splice_stats_)); |
| 1628 } |
| 1629 |
1612 } // namespace media | 1630 } // namespace media |
OLD | NEW |