Lines 57-62
Link Here
|
57 |
|
57 |
|
58 |
namespace { |
58 |
namespace { |
59 |
|
59 |
|
|
|
60 |
constexpr int64_t kRelativeTsBase = static_cast<int64_t>(0x7ffeffffffffffff); |
61 |
|
60 |
void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) { |
62 |
void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) { |
61 |
DCHECK(stream); |
63 |
DCHECK(stream); |
62 |
stream->discard = discard; |
64 |
stream->discard = discard; |
Lines 88-94
Link Here
|
88 |
frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
90 |
frames * base::Time::kMicrosecondsPerSecond / sample_rate); |
89 |
} |
91 |
} |
90 |
|
92 |
|
91 |
static base::TimeDelta ExtractStartTime(AVStream* stream) { |
93 |
static base::TimeDelta ExtractStartTime(AVStream* stream, int64_t first_dts) { |
92 |
// The default start time is zero. |
94 |
// The default start time is zero. |
93 |
base::TimeDelta start_time; |
95 |
base::TimeDelta start_time; |
94 |
|
96 |
|
Lines 98-109
Link Here
|
98 |
|
100 |
|
99 |
// Next try to use the first DTS value, for codecs where we know PTS == DTS |
101 |
// Next try to use the first DTS value, for codecs where we know PTS == DTS |
100 |
// (excludes all H26x codecs). The start time must be returned in PTS. |
102 |
// (excludes all H26x codecs). The start time must be returned in PTS. |
101 |
if (av_stream_get_first_dts(stream) != kNoFFmpegTimestamp && |
103 |
if (first_dts != AV_NOPTS_VALUE && |
102 |
stream->codecpar->codec_id != AV_CODEC_ID_HEVC && |
104 |
stream->codecpar->codec_id != AV_CODEC_ID_HEVC && |
103 |
stream->codecpar->codec_id != AV_CODEC_ID_H264 && |
105 |
stream->codecpar->codec_id != AV_CODEC_ID_H264 && |
104 |
stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) { |
106 |
stream->codecpar->codec_id != AV_CODEC_ID_MPEG4) { |
105 |
const base::TimeDelta first_pts = |
107 |
const base::TimeDelta first_pts = |
106 |
ConvertFromTimeBase(stream->time_base, av_stream_get_first_dts(stream)); |
108 |
ConvertFromTimeBase(stream->time_base, first_dts); |
107 |
if (first_pts < start_time) |
109 |
if (first_pts < start_time) |
108 |
start_time = first_pts; |
110 |
start_time = first_pts; |
109 |
} |
111 |
} |
Lines 287-292
Link Here
|
287 |
fixup_negative_timestamps_(false), |
289 |
fixup_negative_timestamps_(false), |
288 |
fixup_chained_ogg_(false), |
290 |
fixup_chained_ogg_(false), |
289 |
num_discarded_packet_warnings_(0), |
291 |
num_discarded_packet_warnings_(0), |
|
|
292 |
first_dts_(AV_NOPTS_VALUE), |
290 |
last_packet_pos_(AV_NOPTS_VALUE), |
293 |
last_packet_pos_(AV_NOPTS_VALUE), |
291 |
last_packet_dts_(AV_NOPTS_VALUE) { |
294 |
last_packet_dts_(AV_NOPTS_VALUE) { |
292 |
DCHECK(demuxer_); |
295 |
DCHECK(demuxer_); |
Lines 353-358
Link Here
|
353 |
int64_t packet_dts = |
356 |
int64_t packet_dts = |
354 |
packet->dts == AV_NOPTS_VALUE ? packet->pts : packet->dts; |
357 |
packet->dts == AV_NOPTS_VALUE ? packet->pts : packet->dts; |
355 |
|
358 |
|
|
|
359 |
if (first_dts_ == AV_NOPTS_VALUE && packet->dts != AV_NOPTS_VALUE && |
360 |
last_packet_dts_ != AV_NOPTS_VALUE) { |
361 |
first_dts_ = packet->dts - (last_packet_dts_ + kRelativeTsBase); |
362 |
} |
363 |
|
356 |
// Chained ogg files have non-monotonically increasing position and time stamp |
364 |
// Chained ogg files have non-monotonically increasing position and time stamp |
357 |
// values, which prevents us from using them to determine if a packet should |
365 |
// values, which prevents us from using them to determine if a packet should |
358 |
// be dropped. Since chained ogg is only allowed on single track audio only |
366 |
// be dropped. Since chained ogg is only allowed on single track audio only |
Lines 1430-1436
Link Here
|
1430 |
|
1438 |
|
1431 |
max_duration = std::max(max_duration, streams_[i]->duration()); |
1439 |
max_duration = std::max(max_duration, streams_[i]->duration()); |
1432 |
|
1440 |
|
1433 |
base::TimeDelta start_time = ExtractStartTime(stream); |
1441 |
base::TimeDelta start_time = ExtractStartTime(stream, streams_[i]->first_dts()); |
1434 |
|
1442 |
|
1435 |
// Note: This value is used for seeking, so we must take the true value and |
1443 |
// Note: This value is used for seeking, so we must take the true value and |
1436 |
// not the one possibly clamped to zero below. |
1444 |
// not the one possibly clamped to zero below. |
Lines 1587-1592
Link Here
|
1587 |
for (const auto& stream : streams_) { |
1595 |
for (const auto& stream : streams_) { |
1588 |
if (!stream || stream->IsEnabled() != enabled) |
1596 |
if (!stream || stream->IsEnabled() != enabled) |
1589 |
continue; |
1597 |
continue; |
|
|
1598 |
if (stream->first_dts() == AV_NOPTS_VALUE) |
1599 |
continue; |
1590 |
if (!lowest_start_time_stream || |
1600 |
if (!lowest_start_time_stream || |
1591 |
stream->start_time() < lowest_start_time_stream->start_time()) { |
1601 |
stream->start_time() < lowest_start_time_stream->start_time()) { |
1592 |
lowest_start_time_stream = stream.get(); |
1602 |
lowest_start_time_stream = stream.get(); |
Lines 1604-1609
Link Here
|
1604 |
if (stream && stream->type() == DemuxerStream::VIDEO && |
1614 |
if (stream && stream->type() == DemuxerStream::VIDEO && |
1605 |
stream->IsEnabled()) { |
1615 |
stream->IsEnabled()) { |
1606 |
video_stream = stream.get(); |
1616 |
video_stream = stream.get(); |
|
|
1617 |
|
1618 |
if (stream->first_dts() == AV_NOPTS_VALUE) |
1619 |
continue; |
1620 |
|
1607 |
if (video_stream->start_time() <= seek_time) { |
1621 |
if (video_stream->start_time() <= seek_time) { |
1608 |
return video_stream; |
1622 |
return video_stream; |
1609 |
} |
1623 |
} |