Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ed88f4f1
authored
Feb 03, 2020
by
kimvde
Committed by
kim-vde
Feb 11, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add possibility to update ExtractorOutput duration
PiperOrigin-RevId: 292912511
parent
de387723
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
50 additions
and
22 deletions
library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp3/IndexSeeker.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.0.dump
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.1.dump
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.2.dump
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.3.dump
library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java
View file @
ed88f4f1
...
...
@@ -653,8 +653,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override
public
void
seekMap
(
SeekMap
seekMap
)
{
this
.
seekMap
=
icyHeaders
==
null
?
seekMap
:
new
Unseekable
(
/* durationUs */
C
.
TIME_UNSET
);
handler
.
post
(
maybeFinishPrepareRunnable
);
handler
.
post
(()
->
setSeekMap
(
seekMap
));
}
// Icy metadata. Called by the loading thread.
...
...
@@ -691,6 +690,20 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return
trackOutput
;
}
private
void
setSeekMap
(
SeekMap
seekMap
)
{
this
.
seekMap
=
icyHeaders
==
null
?
seekMap
:
new
Unseekable
(
/* durationUs */
C
.
TIME_UNSET
);
if
(
preparedState
==
null
)
{
maybeFinishPrepare
();
}
else
{
preparedState
=
new
PreparedState
(
seekMap
,
preparedState
.
tracks
,
preparedState
.
trackIsAudioVideoFlags
);
}
durationUs
=
seekMap
.
getDurationUs
();
isLive
=
length
==
C
.
LENGTH_UNSET
&&
seekMap
.
getDurationUs
()
==
C
.
TIME_UNSET
;
dataType
=
isLive
?
C
.
DATA_TYPE_MEDIA_PROGRESSIVE_LIVE
:
C
.
DATA_TYPE_MEDIA
;
listener
.
onSourceInfoRefreshed
(
durationUs
,
seekMap
.
isSeekable
(),
isLive
);
}
private
void
maybeFinishPrepare
()
{
SeekMap
seekMap
=
this
.
seekMap
;
if
(
released
||
preparedState
!=
null
||
!
sampleQueuesBuilt
||
seekMap
==
null
)
{
...
...
@@ -705,7 +718,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int
trackCount
=
sampleQueues
.
length
;
TrackGroup
[]
trackArray
=
new
TrackGroup
[
trackCount
];
boolean
[]
trackIsAudioVideoFlags
=
new
boolean
[
trackCount
];
durationUs
=
seekMap
.
getDurationUs
();
for
(
int
i
=
0
;
i
<
trackCount
;
i
++)
{
Format
trackFormat
=
sampleQueues
[
i
].
getUpstreamFormat
();
String
mimeType
=
trackFormat
.
sampleMimeType
;
...
...
@@ -731,11 +743,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
trackArray
[
i
]
=
new
TrackGroup
(
trackFormat
);
}
isLive
=
length
==
C
.
LENGTH_UNSET
&&
seekMap
.
getDurationUs
()
==
C
.
TIME_UNSET
;
dataType
=
isLive
?
C
.
DATA_TYPE_MEDIA_PROGRESSIVE_LIVE
:
C
.
DATA_TYPE_MEDIA
;
preparedState
=
new
PreparedState
(
seekMap
,
new
TrackGroupArray
(
trackArray
),
trackIsAudioVideoFlags
);
listener
.
onSourceInfoRefreshed
(
durationUs
,
seekMap
.
isSeekable
(),
isLive
);
Assertions
.
checkNotNull
(
callback
).
onPrepared
(
this
);
}
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp3/IndexSeeker.java
View file @
ed88f4f1
...
...
@@ -27,11 +27,12 @@ import com.google.android.exoplayer2.util.Util;
@VisibleForTesting
/* package */
static
final
long
MIN_TIME_BETWEEN_POINTS_US
=
C
.
MICROS_PER_SECOND
/
10
;
private
final
long
durationUs
;
private
final
long
dataEndPosition
;
private
final
LongArray
timesUs
;
private
final
LongArray
positions
;
private
long
durationUs
;
public
IndexSeeker
(
long
durationUs
,
long
dataStartPosition
,
long
dataEndPosition
)
{
this
.
durationUs
=
durationUs
;
this
.
dataEndPosition
=
dataEndPosition
;
...
...
@@ -104,4 +105,8 @@ import com.google.android.exoplayer2.util.Util;
long
lastIndexedTimeUs
=
timesUs
.
get
(
timesUs
.
size
()
-
1
);
return
timeUs
-
lastIndexedTimeUs
<
MIN_TIME_BETWEEN_POINTS_US
;
}
/* package */
void
setDurationUs
(
long
durationUs
)
{
this
.
durationUs
=
durationUs
;
}
}
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp3/Mp3Extractor.java
View file @
ed88f4f1
...
...
@@ -216,6 +216,31 @@ public final class Mp3Extractor implements Extractor {
public
int
read
(
ExtractorInput
input
,
PositionHolder
seekPosition
)
throws
IOException
,
InterruptedException
{
assertInitialized
();
int
readResult
=
readInternal
(
input
);
if
(
readResult
==
RESULT_END_OF_INPUT
&&
seeker
instanceof
IndexSeeker
)
{
// Duration is exact when index seeker is used.
long
durationUs
=
computeTimeUs
(
samplesRead
);
if
(
seeker
.
getDurationUs
()
!=
durationUs
)
{
((
IndexSeeker
)
seeker
).
setDurationUs
(
durationUs
);
extractorOutput
.
seekMap
(
seeker
);
}
}
return
readResult
;
}
/**
* Disables the extractor from being able to seek through the media.
*
* <p>Please note that this needs to be called before {@link #read}.
*/
public
void
disableSeeking
()
{
disableSeeking
=
true
;
}
// Internal methods.
@RequiresNonNull
({
"extractorOutput"
,
"currentTrackOutput"
,
"realTrackOutput"
})
private
int
readInternal
(
ExtractorInput
input
)
throws
IOException
,
InterruptedException
{
if
(
synchronizedHeaderData
==
0
)
{
try
{
synchronize
(
input
,
false
);
...
...
@@ -254,17 +279,6 @@ public final class Mp3Extractor implements Extractor {
return
readSample
(
input
);
}
/**
* Disables the extractor from being able to seek through the media.
*
* <p>Please note that this needs to be called before {@link #read}.
*/
public
void
disableSeeking
()
{
disableSeeking
=
true
;
}
// Internal methods.
@RequiresNonNull
({
"currentTrackOutput"
,
"realTrackOutput"
,
"seeker"
})
private
int
readSample
(
ExtractorInput
extractorInput
)
throws
IOException
,
InterruptedException
{
if
(
sampleBytesRemaining
==
0
)
{
...
...
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.0.dump
View file @
ed88f4f1
seekMap:
isSeekable = true
duration =
UNSET TIME
duration =
2808000
getPosition(0) = [[timeUs=0, position=224]]
numberOfTracks = 1
track 0:
...
...
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.1.dump
View file @
ed88f4f1
seekMap:
isSeekable = true
duration =
UNSET TIME
duration =
2808000
getPosition(0) = [[timeUs=0, position=224]]
numberOfTracks = 1
track 0:
...
...
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.2.dump
View file @
ed88f4f1
seekMap:
isSeekable = true
duration =
UNSET TIME
duration =
2808000
getPosition(0) = [[timeUs=0, position=224]]
numberOfTracks = 1
track 0:
...
...
library/extractor/src/test/assets/mp3/bear-vbr-no-seek-table.mp3.3.dump
View file @
ed88f4f1
seekMap:
isSeekable = true
duration =
UNSET TIME
duration =
2808000
getPosition(0) = [[timeUs=0, position=224]]
numberOfTracks = 1
track 0:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment