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
4c8f9a8c
authored
Apr 11, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Remove source package, and restore original FrameworkSampleSource.
parent
587edf8e
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
140 additions
and
340 deletions
demo/src/main/java/com/google/android/exoplayer/demo/player/DefaultRendererBuilder.java
library/src/main/java/com/google/android/exoplayer/source/FrameworkSampleExtractor.java → library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java
library/src/main/java/com/google/android/exoplayer/source/DefaultSampleSource.java
library/src/main/java/com/google/android/exoplayer/source/SampleExtractor.java
demo/src/main/java/com/google/android/exoplayer/demo/player/DefaultRendererBuilder.java
View file @
4c8f9a8c
...
...
@@ -15,13 +15,12 @@
*/
package
com
.
google
.
android
.
exoplayer
.
demo
.
player
;
import
com.google.android.exoplayer.FrameworkSampleSource
;
import
com.google.android.exoplayer.MediaCodecAudioTrackRenderer
;
import
com.google.android.exoplayer.MediaCodecVideoTrackRenderer
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilder
;
import
com.google.android.exoplayer.demo.player.DemoPlayer.RendererBuilderCallback
;
import
com.google.android.exoplayer.source.DefaultSampleSource
;
import
com.google.android.exoplayer.source.FrameworkSampleExtractor
;
import
android.content.Context
;
import
android.media.MediaCodec
;
...
...
@@ -47,8 +46,7 @@ public class DefaultRendererBuilder implements RendererBuilder {
@Override
public
void
buildRenderers
(
DemoPlayer
player
,
RendererBuilderCallback
callback
)
{
// Build the video and audio renderers.
DefaultSampleSource
sampleSource
=
new
DefaultSampleSource
(
new
FrameworkSampleExtractor
(
context
,
uri
,
null
),
2
);
FrameworkSampleSource
sampleSource
=
new
FrameworkSampleSource
(
context
,
uri
,
null
,
2
);
MediaCodecVideoTrackRenderer
videoRenderer
=
new
MediaCodecVideoTrackRenderer
(
sampleSource
,
null
,
true
,
MediaCodec
.
VIDEO_SCALING_MODE_SCALE_TO_FIT
,
5000
,
null
,
player
.
getMainHandler
(),
player
,
50
);
...
...
library/src/main/java/com/google/android/exoplayer/
source/FrameworkSampleExtractor
.java
→
library/src/main/java/com/google/android/exoplayer/
FrameworkSampleSource
.java
View file @
4c8f9a8c
...
...
@@ -13,12 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
source
;
package
com
.
google
.
android
.
exoplayer
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.SampleHolder
;
import
com.google.android.exoplayer.SampleSource
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.drm.DrmInitData
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
...
...
@@ -34,11 +30,19 @@ import java.io.IOException;
import
java.util.Map
;
import
java.util.UUID
;
/** {@link SampleExtractor} that extracts samples from a stream using {@link MediaExtractor}. */
/**
* Extracts samples from a stream using Android's {@link MediaExtractor}.
*/
// TODO: This implementation needs to be fixed so that its methods are non-blocking (either
// through use of a background thread, or through changes to the framework's MediaExtractor API).
@TargetApi
(
16
)
public
final
class
FrameworkSampleExtractor
implements
SampleExtractor
{
public
final
class
FrameworkSampleSource
implements
SampleSource
{
private
static
final
int
ALLOWED_FLAGS_MASK
=
C
.
SAMPLE_FLAG_SYNC
|
C
.
SAMPLE_FLAG_ENCRYPTED
;
private
static
final
int
TRACK_STATE_DISABLED
=
0
;
private
static
final
int
TRACK_STATE_ENABLED
=
1
;
private
static
final
int
TRACK_STATE_FORMAT_SENT
=
2
;
// Parameters for a Uri data source.
private
final
Context
context
;
...
...
@@ -50,7 +54,14 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
private
final
long
fileDescriptorOffset
;
private
final
long
fileDescriptorLength
;
private
final
MediaExtractor
mediaExtractor
;
private
MediaExtractor
extractor
;
private
TrackInfo
[]
trackInfos
;
private
boolean
prepared
;
private
int
remainingReleaseCount
;
private
int
[]
trackStates
;
private
boolean
[]
pendingDiscontinuities
;
private
long
seekPositionUs
;
/**
* Instantiates a new sample extractor reading from the specified {@code uri}.
...
...
@@ -58,9 +69,12 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
* @param context Context for resolving {@code uri}.
* @param uri The content URI from which to extract data.
* @param headers Headers to send with requests for data.
* @param downstreamRendererCount Number of track renderers dependent on this sample source.
*/
public
FrameworkSampleExtractor
(
Context
context
,
Uri
uri
,
Map
<
String
,
String
>
headers
)
{
public
FrameworkSampleSource
(
Context
context
,
Uri
uri
,
Map
<
String
,
String
>
headers
,
int
downstreamRendererCount
)
{
Assertions
.
checkState
(
Util
.
SDK_INT
>=
16
);
this
.
remainingReleaseCount
=
downstreamRendererCount
;
this
.
context
=
Assertions
.
checkNotNull
(
context
);
this
.
uri
=
Assertions
.
checkNotNull
(
uri
);
...
...
@@ -69,8 +83,6 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
fileDescriptor
=
null
;
fileDescriptorOffset
=
0
;
fileDescriptorLength
=
0
;
mediaExtractor
=
new
MediaExtractor
();
}
/**
...
...
@@ -80,9 +92,12 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
* @param fileDescriptor File descriptor from which to read.
* @param offset The offset in bytes into the file where the data to be extracted starts.
* @param length The length in bytes of the data to be extracted.
* @param downstreamRendererCount Number of track renderers dependent on this sample source.
*/
public
FrameworkSampleExtractor
(
FileDescriptor
fileDescriptor
,
long
offset
,
long
length
)
{
public
FrameworkSampleSource
(
FileDescriptor
fileDescriptor
,
long
offset
,
long
length
,
int
downstreamRendererCount
)
{
Assertions
.
checkState
(
Util
.
SDK_INT
>=
16
);
this
.
remainingReleaseCount
=
downstreamRendererCount
;
context
=
null
;
uri
=
null
;
...
...
@@ -91,96 +106,144 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
this
.
fileDescriptor
=
Assertions
.
checkNotNull
(
fileDescriptor
);
fileDescriptorOffset
=
offset
;
fileDescriptorLength
=
length
;
mediaExtractor
=
new
MediaExtractor
();
}
@Override
public
boolean
prepare
()
throws
IOException
{
if
(
context
!=
null
)
{
mediaExtractor
.
setDataSource
(
context
,
uri
,
headers
);
}
else
{
mediaExtractor
.
setDataSource
(
fileDescriptor
,
fileDescriptorOffset
,
fileDescriptorLength
);
}
if
(!
prepared
)
{
extractor
=
new
MediaExtractor
();
if
(
context
!=
null
)
{
extractor
.
setDataSource
(
context
,
uri
,
headers
);
}
else
{
extractor
.
setDataSource
(
fileDescriptor
,
fileDescriptorOffset
,
fileDescriptorLength
);
}
trackStates
=
new
int
[
extractor
.
getTrackCount
()];
pendingDiscontinuities
=
new
boolean
[
trackStates
.
length
];
trackInfos
=
new
TrackInfo
[
trackStates
.
length
];
for
(
int
i
=
0
;
i
<
trackStates
.
length
;
i
++)
{
android
.
media
.
MediaFormat
format
=
extractor
.
getTrackFormat
(
i
);
long
durationUs
=
format
.
containsKey
(
android
.
media
.
MediaFormat
.
KEY_DURATION
)
?
format
.
getLong
(
android
.
media
.
MediaFormat
.
KEY_DURATION
)
:
C
.
UNKNOWN_TIME_US
;
String
mime
=
format
.
getString
(
android
.
media
.
MediaFormat
.
KEY_MIME
);
trackInfos
[
i
]
=
new
TrackInfo
(
mime
,
durationUs
);
}
prepared
=
true
;
}
return
true
;
}
@Override
public
void
selectTrack
(
int
index
)
{
mediaExtractor
.
selectTrack
(
index
);
public
int
getTrackCount
()
{
Assertions
.
checkState
(
prepared
);
return
trackStates
.
length
;
}
@Override
public
void
deselectTrack
(
int
index
)
{
mediaExtractor
.
unselectTrack
(
index
);
public
TrackInfo
getTrackInfo
(
int
track
)
{
Assertions
.
checkState
(
prepared
);
return
trackInfos
[
track
];
}
@Override
public
long
getBufferedPositionUs
()
{
long
bufferedDurationUs
=
mediaExtractor
.
getCachedDuration
();
if
(
bufferedDurationUs
==
-
1
)
{
return
TrackRenderer
.
UNKNOWN_TIME_US
;
}
else
{
long
sampleTime
=
mediaExtractor
.
getSampleTime
();
return
sampleTime
==
-
1
?
TrackRenderer
.
END_OF_TRACK_US
:
sampleTime
+
bufferedDurationUs
;
}
public
void
enable
(
int
track
,
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
==
TRACK_STATE_DISABLED
);
trackStates
[
track
]
=
TRACK_STATE_ENABLED
;
extractor
.
selectTrack
(
track
);
seekToUsInternal
(
positionUs
,
positionUs
!=
0
);
}
@Override
public
void
seekTo
(
long
positionUs
)
{
mediaExtractor
.
seekTo
(
positionUs
,
MediaExtractor
.
SEEK_TO_PREVIOUS_SYNC
);
public
boolean
continueBuffering
(
long
positionUs
)
{
// MediaExtractor takes care of buffering and blocks until it has samples, so we can always
// return true here. Although note that the blocking behavior is itself as bug, as per the
// TODO further up this file. This method will need to return something else as part of fixing
// the TODO.
return
true
;
}
@Override
public
int
getTrackCount
()
{
return
mediaExtractor
.
getTrackCount
();
public
int
readData
(
int
track
,
long
positionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
!=
TRACK_STATE_DISABLED
);
if
(
pendingDiscontinuities
[
track
])
{
pendingDiscontinuities
[
track
]
=
false
;
return
DISCONTINUITY_READ
;
}
if
(
onlyReadDiscontinuity
)
{
return
NOTHING_READ
;
}
if
(
trackStates
[
track
]
!=
TRACK_STATE_FORMAT_SENT
)
{
formatHolder
.
format
=
MediaFormat
.
createFromFrameworkMediaFormatV16
(
extractor
.
getTrackFormat
(
track
));
formatHolder
.
drmInitData
=
Util
.
SDK_INT
>=
18
?
getDrmInitDataV18
()
:
null
;
trackStates
[
track
]
=
TRACK_STATE_FORMAT_SENT
;
return
FORMAT_READ
;
}
int
extractorTrackIndex
=
extractor
.
getSampleTrackIndex
();
if
(
extractorTrackIndex
==
track
)
{
if
(
sampleHolder
.
data
!=
null
)
{
int
offset
=
sampleHolder
.
data
.
position
();
sampleHolder
.
size
=
extractor
.
readSampleData
(
sampleHolder
.
data
,
offset
);
sampleHolder
.
data
.
position
(
offset
+
sampleHolder
.
size
);
}
else
{
sampleHolder
.
size
=
0
;
}
sampleHolder
.
timeUs
=
extractor
.
getSampleTime
();
sampleHolder
.
flags
=
extractor
.
getSampleFlags
()
&
ALLOWED_FLAGS_MASK
;
if
(
sampleHolder
.
isEncrypted
())
{
sampleHolder
.
cryptoInfo
.
setFromExtractorV16
(
extractor
);
}
seekPositionUs
=
C
.
UNKNOWN_TIME_US
;
extractor
.
advance
();
return
SAMPLE_READ
;
}
else
{
return
extractorTrackIndex
<
0
?
END_OF_STREAM
:
NOTHING_READ
;
}
}
@Override
public
MediaFormat
getMediaFormat
(
int
track
)
{
return
MediaFormat
.
createFromFrameworkMediaFormatV16
(
mediaExtractor
.
getTrackFormat
(
track
));
public
void
disable
(
int
track
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
!=
TRACK_STATE_DISABLED
);
extractor
.
unselectTrack
(
track
);
pendingDiscontinuities
[
track
]
=
false
;
trackStates
[
track
]
=
TRACK_STATE_DISABLED
;
}
@Override
public
DrmInitData
getDrmInitData
(
int
track
)
{
return
Util
.
SDK_INT
>=
18
?
getDrmInitDataV18
()
:
null
;
public
void
seekToUs
(
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
seekToUsInternal
(
positionUs
,
false
);
}
@Override
public
int
readSample
(
int
track
,
SampleHolder
sampleHolder
)
{
int
sampleTrack
=
mediaExtractor
.
getSampleTrackIndex
();
if
(
sampleTrack
!=
track
)
{
return
sampleTrack
<
0
?
SampleSource
.
END_OF_STREAM
:
SampleSource
.
NOTHING_READ
;
}
if
(
sampleHolder
.
data
!=
null
)
{
int
offset
=
sampleHolder
.
data
.
position
();
sampleHolder
.
size
=
mediaExtractor
.
readSampleData
(
sampleHolder
.
data
,
offset
);
sampleHolder
.
data
.
position
(
offset
+
sampleHolder
.
size
);
public
long
getBufferedPositionUs
()
{
Assertions
.
checkState
(
prepared
);
long
bufferedDurationUs
=
extractor
.
getCachedDuration
();
if
(
bufferedDurationUs
==
-
1
)
{
return
TrackRenderer
.
UNKNOWN_TIME_US
;
}
else
{
sampleHolder
.
size
=
0
;
}
sampleHolder
.
timeUs
=
mediaExtractor
.
getSampleTime
();
sampleHolder
.
flags
=
mediaExtractor
.
getSampleFlags
();
if
(
sampleHolder
.
isEncrypted
())
{
sampleHolder
.
cryptoInfo
.
setFromExtractorV16
(
mediaExtractor
);
long
sampleTime
=
extractor
.
getSampleTime
();
return
sampleTime
==
-
1
?
TrackRenderer
.
END_OF_TRACK_US
:
sampleTime
+
bufferedDurationUs
;
}
mediaExtractor
.
advance
();
return
SampleSource
.
SAMPLE_READ
;
}
@Override
public
void
release
()
{
mediaExtractor
.
release
();
Assertions
.
checkState
(
remainingReleaseCount
>
0
);
if
(--
remainingReleaseCount
==
0
)
{
extractor
.
release
();
extractor
=
null
;
}
}
@TargetApi
(
18
)
private
DrmInitData
getDrmInitDataV18
()
{
// MediaExtractor only supports psshInfo for MP4, so it's ok to hard code the mimeType here.
Map
<
UUID
,
byte
[]>
psshInfo
=
mediaE
xtractor
.
getPsshInfo
();
Map
<
UUID
,
byte
[]>
psshInfo
=
e
xtractor
.
getPsshInfo
();
if
(
psshInfo
==
null
||
psshInfo
.
isEmpty
())
{
return
null
;
}
...
...
@@ -189,4 +252,18 @@ public final class FrameworkSampleExtractor implements SampleExtractor {
return
drmInitData
;
}
private
void
seekToUsInternal
(
long
positionUs
,
boolean
force
)
{
// Unless forced, avoid duplicate calls to the underlying extractor's seek method in the case
// that there have been no interleaving calls to readSample.
if
(
force
||
seekPositionUs
!=
positionUs
)
{
seekPositionUs
=
positionUs
;
extractor
.
seekTo
(
positionUs
,
MediaExtractor
.
SEEK_TO_PREVIOUS_SYNC
);
for
(
int
i
=
0
;
i
<
trackStates
.
length
;
++
i
)
{
if
(
trackStates
[
i
]
!=
TRACK_STATE_DISABLED
)
{
pendingDiscontinuities
[
i
]
=
true
;
}
}
}
}
}
library/src/main/java/com/google/android/exoplayer/source/DefaultSampleSource.java
deleted
100644 → 0
View file @
587edf8e
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
source
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.MediaFormatHolder
;
import
com.google.android.exoplayer.SampleHolder
;
import
com.google.android.exoplayer.SampleSource
;
import
com.google.android.exoplayer.TrackInfo
;
import
com.google.android.exoplayer.util.Assertions
;
import
java.io.IOException
;
/** {@link SampleSource} that extracts sample data using a {@link SampleExtractor} */
public
final
class
DefaultSampleSource
implements
SampleSource
{
private
static
final
int
TRACK_STATE_DISABLED
=
0
;
private
static
final
int
TRACK_STATE_ENABLED
=
1
;
private
static
final
int
TRACK_STATE_FORMAT_SENT
=
2
;
private
final
SampleExtractor
sampleExtractor
;
private
TrackInfo
[]
trackInfos
;
private
boolean
prepared
;
private
int
remainingReleaseCount
;
private
int
[]
trackStates
;
private
boolean
[]
pendingDiscontinuities
;
private
long
seekPositionUs
;
/**
* Creates a new sample source that extracts samples using {@code sampleExtractor}. Specify the
* {@code downstreamRendererCount} to ensure that the sample source is released only when all
* downstream renderers have been released.
*
* @param sampleExtractor Sample extractor for accessing media samples.
* @param downstreamRendererCount Number of track renderers dependent on this sample source.
*/
public
DefaultSampleSource
(
SampleExtractor
sampleExtractor
,
int
downstreamRendererCount
)
{
this
.
sampleExtractor
=
Assertions
.
checkNotNull
(
sampleExtractor
);
this
.
remainingReleaseCount
=
downstreamRendererCount
;
}
@Override
public
boolean
prepare
()
throws
IOException
{
if
(
prepared
)
{
return
true
;
}
if
(
sampleExtractor
.
prepare
())
{
prepared
=
true
;
int
trackCount
=
sampleExtractor
.
getTrackCount
();
trackStates
=
new
int
[
trackCount
];
pendingDiscontinuities
=
new
boolean
[
trackCount
];
trackInfos
=
new
TrackInfo
[
trackCount
];
for
(
int
track
=
0
;
track
<
trackCount
;
track
++)
{
MediaFormat
mediaFormat
=
sampleExtractor
.
getMediaFormat
(
track
);
trackInfos
[
track
]
=
new
TrackInfo
(
mediaFormat
.
mimeType
,
mediaFormat
.
durationUs
);
}
}
return
prepared
;
}
@Override
public
int
getTrackCount
()
{
Assertions
.
checkState
(
prepared
);
return
trackInfos
.
length
;
}
@Override
public
TrackInfo
getTrackInfo
(
int
track
)
{
Assertions
.
checkState
(
prepared
);
return
trackInfos
[
track
];
}
@Override
public
void
enable
(
int
track
,
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
==
TRACK_STATE_DISABLED
);
trackStates
[
track
]
=
TRACK_STATE_ENABLED
;
sampleExtractor
.
selectTrack
(
track
);
seekToUsInternal
(
positionUs
,
positionUs
!=
0
);
}
@Override
public
void
disable
(
int
track
)
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
!=
TRACK_STATE_DISABLED
);
sampleExtractor
.
deselectTrack
(
track
);
pendingDiscontinuities
[
track
]
=
false
;
trackStates
[
track
]
=
TRACK_STATE_DISABLED
;
}
@Override
public
boolean
continueBuffering
(
long
positionUs
)
throws
IOException
{
// Do nothing.
return
true
;
}
@Override
public
int
readData
(
int
track
,
long
positionUs
,
MediaFormatHolder
formatHolder
,
SampleHolder
sampleHolder
,
boolean
onlyReadDiscontinuity
)
throws
IOException
{
Assertions
.
checkState
(
prepared
);
Assertions
.
checkState
(
trackStates
[
track
]
!=
TRACK_STATE_DISABLED
);
if
(
pendingDiscontinuities
[
track
])
{
pendingDiscontinuities
[
track
]
=
false
;
return
DISCONTINUITY_READ
;
}
if
(
onlyReadDiscontinuity
)
{
return
NOTHING_READ
;
}
if
(
trackStates
[
track
]
!=
TRACK_STATE_FORMAT_SENT
)
{
formatHolder
.
format
=
sampleExtractor
.
getMediaFormat
(
track
);
formatHolder
.
drmInitData
=
sampleExtractor
.
getDrmInitData
(
track
);
trackStates
[
track
]
=
TRACK_STATE_FORMAT_SENT
;
return
FORMAT_READ
;
}
seekPositionUs
=
C
.
UNKNOWN_TIME_US
;
return
sampleExtractor
.
readSample
(
track
,
sampleHolder
);
}
@Override
public
void
seekToUs
(
long
positionUs
)
{
Assertions
.
checkState
(
prepared
);
seekToUsInternal
(
positionUs
,
false
);
}
@Override
public
long
getBufferedPositionUs
()
{
Assertions
.
checkState
(
prepared
);
return
sampleExtractor
.
getBufferedPositionUs
();
}
@Override
public
void
release
()
{
Assertions
.
checkState
(
remainingReleaseCount
>
0
);
if
(--
remainingReleaseCount
==
0
)
{
sampleExtractor
.
release
();
}
}
private
void
seekToUsInternal
(
long
positionUs
,
boolean
force
)
{
// Unless forced, avoid duplicate calls to the underlying extractor's seek method in the case
// that there have been no interleaving calls to readSample.
if
(
force
||
seekPositionUs
!=
positionUs
)
{
seekPositionUs
=
positionUs
;
sampleExtractor
.
seekTo
(
positionUs
);
for
(
int
i
=
0
;
i
<
trackStates
.
length
;
++
i
)
{
if
(
trackStates
[
i
]
!=
TRACK_STATE_DISABLED
)
{
pendingDiscontinuities
[
i
]
=
true
;
}
}
}
}
}
library/src/main/java/com/google/android/exoplayer/source/SampleExtractor.java
deleted
100644 → 0
View file @
587edf8e
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
google
.
android
.
exoplayer
.
source
;
import
com.google.android.exoplayer.MediaFormat
;
import
com.google.android.exoplayer.SampleHolder
;
import
com.google.android.exoplayer.SampleSource
;
import
com.google.android.exoplayer.TrackRenderer
;
import
com.google.android.exoplayer.drm.DrmInitData
;
import
java.io.IOException
;
/**
* Extractor for reading track metadata and samples stored in tracks.
*
* <p>Call {@link #prepare} until it returns {@code true}, then access track metadata via
* {@link #getMediaFormat}.
*
* <p>Pass indices of tracks to read from to {@link #selectTrack}. A track can later be deselected
* by calling {@link #deselectTrack}. It is safe to select/deselect tracks after reading sample
* data or seeking. Initially, all tracks are deselected.
*
* <p>Call {@link #release()} when the extractor is no longer needed to free resources.
*/
public
interface
SampleExtractor
{
/**
* Prepares the extractor for reading track metadata and samples.
*
* @return Whether the source is ready; if {@code false}, {@link #prepare()} must be called again.
* @throws IOException Thrown if the source can't be read.
*/
boolean
prepare
()
throws
IOException
;
/** Selects the track at {@code index} for reading sample data. */
void
selectTrack
(
int
index
);
/** Deselects the track at {@code index}, so no more samples will be read from that track. */
void
deselectTrack
(
int
index
);
/**
* Returns an estimate of the position up to which data is buffered.
*
* <p>This method should not be called until after the extractor has been successfully prepared.
*
* @return An estimate of the absolute position in microseconds up to which data is buffered,
* or {@link TrackRenderer#END_OF_TRACK_US} if data is buffered to the end of the stream, or
* {@link TrackRenderer#UNKNOWN_TIME_US} if no estimate is available.
*/
long
getBufferedPositionUs
();
/**
* Seeks to the specified time in microseconds.
*
* <p>This method should not be called until after the extractor has been successfully prepared.
*
* @param positionUs The seek position in microseconds.
*/
void
seekTo
(
long
positionUs
);
/** Returns the number of tracks, if {@link #prepare} has returned {@code true}. */
int
getTrackCount
();
/** Returns the {@link MediaFormat} of {@code track}. */
MediaFormat
getMediaFormat
(
int
track
);
/** Returns the DRM initialization data for {@code track}. */
DrmInitData
getDrmInitData
(
int
track
);
/**
* Reads the next sample in the track at index {@code track} into {@code sampleHolder}, returning
* {@link SampleSource#SAMPLE_READ} if it is available.
*
* <p>Advances to the next sample if a sample was read.
*
* @param track The index of the track from which to read a sample.
* @param sampleHolder The holder for read sample data, if {@link SampleSource#SAMPLE_READ} is
* returned.
* @return {@link SampleSource#SAMPLE_READ} if a sample was read into {@code sampleHolder}, or
* {@link SampleSource#END_OF_STREAM} if the last samples in all tracks have been read, or
* {@link SampleSource#NOTHING_READ} if the sample cannot be read immediately as it is not
* loaded.
* @throws IOException Thrown if the source can't be read.
*/
int
readSample
(
int
track
,
SampleHolder
sampleHolder
)
throws
IOException
;
/** Releases resources associated with this extractor. */
void
release
();
}
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