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
ec90eac3
authored
Sep 11, 2014
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Support anamorphic video content.
parent
6c3ae7f1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
95 additions
and
32 deletions
demo/src/main/java/com/google/android/exoplayer/demo/full/EventLogger.java
demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java
demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java
demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/MediaFormat.java
library/src/main/java/com/google/android/exoplayer/parser/mp4/Atom.java
library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java
demo/src/main/java/com/google/android/exoplayer/demo/full/EventLogger.java
View file @
ec90eac3
...
...
@@ -73,8 +73,8 @@ public class EventLogger implements DemoPlayer.Listener, DemoPlayer.InfoListener
}
@Override
public
void
onVideoSizeChanged
(
int
width
,
int
height
)
{
Log
.
d
(
TAG
,
"videoSizeChanged ["
+
width
+
", "
+
height
+
"]"
);
public
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthHeightRatio
)
{
Log
.
d
(
TAG
,
"videoSizeChanged ["
+
width
+
", "
+
height
+
"
, "
+
pixelWidthHeightRatio
+
"
]"
);
}
// DemoPlayer.InfoListener
...
...
demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java
View file @
ec90eac3
...
...
@@ -260,9 +260,10 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba
}
@Override
public
void
onVideoSizeChanged
(
int
width
,
int
height
)
{
public
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthAspectRatio
)
{
shutterView
.
setVisibility
(
View
.
GONE
);
surfaceView
.
setVideoWidthHeightRatio
(
height
==
0
?
1
:
(
float
)
width
/
height
);
surfaceView
.
setVideoWidthHeightRatio
(
height
==
0
?
1
:
(
width
*
pixelWidthAspectRatio
)
/
height
);
}
// User controls
...
...
demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java
View file @
ec90eac3
...
...
@@ -93,7 +93,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
public
interface
Listener
{
void
onStateChanged
(
boolean
playWhenReady
,
int
playbackState
);
void
onError
(
Exception
e
);
void
onVideoSizeChanged
(
int
width
,
int
height
);
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthHeightRatio
);
}
/**
...
...
@@ -377,9 +377,9 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
}
@Override
public
void
onVideoSizeChanged
(
int
width
,
int
height
)
{
public
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthHeightRatio
)
{
for
(
Listener
listener
:
listeners
)
{
listener
.
onVideoSizeChanged
(
width
,
height
);
listener
.
onVideoSizeChanged
(
width
,
height
,
pixelWidthHeightRatio
);
}
}
...
...
demo/src/main/java/com/google/android/exoplayer/demo/simple/SimplePlayerActivity.java
View file @
ec90eac3
...
...
@@ -231,8 +231,9 @@ public class SimplePlayerActivity extends Activity implements SurfaceHolder.Call
// MediaCodecVideoTrackRenderer.Listener
@Override
public
void
onVideoSizeChanged
(
int
width
,
int
height
)
{
surfaceView
.
setVideoWidthHeightRatio
(
height
==
0
?
1
:
(
float
)
width
/
height
);
public
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthHeightRatio
)
{
surfaceView
.
setVideoWidthHeightRatio
(
height
==
0
?
1
:
(
pixelWidthHeightRatio
*
width
)
/
height
);
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
View file @
ec90eac3
...
...
@@ -79,18 +79,19 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
/**
* Value
of {@link #sourceState
} when the source is not ready.
* Value
returned by {@link #getSourceState()
} when the source is not ready.
*/
protected
static
final
int
SOURCE_STATE_NOT_READY
=
0
;
/**
* Value of {@link #sourceState} when the source is ready and we're able to read from it.
* Value returned by {@link #getSourceState()} when the source is ready and we're able to read
* from it.
*/
protected
static
final
int
SOURCE_STATE_READY
=
1
;
/**
* Value
of {@link #sourceState} when the source is ready but we might not be able to read from
*
it. We transition to this state when an attempt to read a sample fails despite the sourc
e
*
reporting that samples are available. This can occur when the next sample to be provided by
* the source is for another renderer.
* Value
returned by {@link #getSourceState()} when the source is ready but we might not be able
*
to read from it. We transition to this state when an attempt to read a sample fails despite th
e
*
source reporting that samples are available. This can occur when the next sample to be provided
*
by
the source is for another renderer.
*/
protected
static
final
int
SOURCE_STATE_READY_READ_MAY_FAIL
=
2
;
...
...
@@ -620,7 +621,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
* @param formatHolder Holds the new format.
* @throws ExoPlaybackException If an error occurs reinitializing the {@link MediaCodec}.
*/
pr
ivate
void
onInputFormatChanged
(
MediaFormatHolder
formatHolder
)
throws
ExoPlaybackException
{
pr
otected
void
onInputFormatChanged
(
MediaFormatHolder
formatHolder
)
throws
ExoPlaybackException
{
MediaFormat
oldFormat
=
format
;
format
=
formatHolder
.
format
;
drmInitData
=
formatHolder
.
drmInitData
;
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
View file @
ec90eac3
...
...
@@ -58,8 +58,11 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
*
* @param width The video width in pixels.
* @param height The video height in pixels.
* @param pixelWidthHeightRatio The width to height ratio of each pixel. For the normal case
* of square pixels this will be equal to 1.0. Different values are indicative of anamorphic
* content.
*/
void
onVideoSizeChanged
(
int
width
,
int
height
);
void
onVideoSizeChanged
(
int
width
,
int
height
,
float
pixelWidthHeightRatio
);
/**
* Invoked when a frame is rendered to a surface for the first time following that surface
...
...
@@ -98,8 +101,10 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
private
int
currentWidth
;
private
int
currentHeight
;
private
float
currentPixelWidthHeightRatio
;
private
int
lastReportedWidth
;
private
int
lastReportedHeight
;
private
float
lastReportedPixelWidthHeightRatio
;
/**
* @param source The upstream source from which the renderer obtains samples.
...
...
@@ -208,8 +213,10 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
joiningDeadlineUs
=
-
1
;
currentWidth
=
-
1
;
currentHeight
=
-
1
;
currentPixelWidthHeightRatio
=
-
1
;
lastReportedWidth
=
-
1
;
lastReportedHeight
=
-
1
;
lastReportedPixelWidthHeightRatio
=
-
1
;
}
@Override
...
...
@@ -272,8 +279,10 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
super
.
onDisabled
();
currentWidth
=
-
1
;
currentHeight
=
-
1
;
currentPixelWidthHeightRatio
=
-
1
;
lastReportedWidth
=
-
1
;
lastReportedHeight
=
-
1
;
lastReportedPixelWidthHeightRatio
=
-
1
;
}
@Override
...
...
@@ -316,6 +325,14 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
@Override
protected
void
onInputFormatChanged
(
MediaFormatHolder
holder
)
throws
ExoPlaybackException
{
super
.
onInputFormatChanged
(
holder
);
// TODO: Ideally this would be read in onOutputFormatChanged, but there doesn't seem
// to be a way to pass a custom key/value pair value through to the output format.
currentPixelWidthHeightRatio
=
holder
.
format
.
pixelWidthHeightRatio
;
}
@Override
protected
void
onOutputFormatChanged
(
android
.
media
.
MediaFormat
format
)
{
boolean
hasCrop
=
format
.
containsKey
(
KEY_CROP_RIGHT
)
&&
format
.
containsKey
(
KEY_CROP_LEFT
)
&&
format
.
containsKey
(
KEY_CROP_BOTTOM
)
&&
format
.
containsKey
(
KEY_CROP_TOP
);
...
...
@@ -394,10 +411,12 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
private
void
renderOutputBuffer
(
MediaCodec
codec
,
int
bufferIndex
)
{
if
(
lastReportedWidth
!=
currentWidth
||
lastReportedHeight
!=
currentHeight
)
{
if
(
lastReportedWidth
!=
currentWidth
||
lastReportedHeight
!=
currentHeight
||
lastReportedPixelWidthHeightRatio
!=
currentPixelWidthHeightRatio
)
{
lastReportedWidth
=
currentWidth
;
lastReportedHeight
=
currentHeight
;
notifyVideoSizeChanged
(
currentWidth
,
currentHeight
);
lastReportedPixelWidthHeightRatio
=
currentPixelWidthHeightRatio
;
notifyVideoSizeChanged
(
currentWidth
,
currentHeight
,
currentPixelWidthHeightRatio
);
}
TraceUtil
.
beginSection
(
"renderVideoBuffer"
);
codec
.
releaseOutputBuffer
(
bufferIndex
,
true
);
...
...
@@ -409,12 +428,13 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
}
private
void
notifyVideoSizeChanged
(
final
int
width
,
final
int
height
)
{
private
void
notifyVideoSizeChanged
(
final
int
width
,
final
int
height
,
final
float
pixelWidthHeightRatio
)
{
if
(
eventHandler
!=
null
&&
eventListener
!=
null
)
{
eventHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
eventListener
.
onVideoSizeChanged
(
width
,
height
);
eventListener
.
onVideoSizeChanged
(
width
,
height
,
pixelWidthHeightRatio
);
}
});
}
...
...
library/src/main/java/com/google/android/exoplayer/MediaFormat.java
View file @
ec90eac3
...
...
@@ -31,6 +31,9 @@ import java.util.List;
*/
public
class
MediaFormat
{
private
static
final
String
KEY_PIXEL_WIDTH_HEIGHT_RATIO
=
"com.google.android.videos.pixelWidthHeightRatio"
;
public
static
final
int
NO_VALUE
=
-
1
;
public
final
String
mimeType
;
...
...
@@ -38,6 +41,7 @@ public class MediaFormat {
public
final
int
width
;
public
final
int
height
;
public
final
float
pixelWidthHeightRatio
;
public
final
int
channelCount
;
public
final
int
sampleRate
;
...
...
@@ -59,14 +63,19 @@ public class MediaFormat {
public
static
MediaFormat
createVideoFormat
(
String
mimeType
,
int
maxInputSize
,
int
width
,
int
height
,
List
<
byte
[]>
initializationData
)
{
return
new
MediaFormat
(
mimeType
,
maxInputSize
,
width
,
height
,
NO_VALUE
,
NO_VALUE
,
initializationData
);
return
createVideoFormat
(
mimeType
,
maxInputSize
,
width
,
height
,
1
,
initializationData
);
}
public
static
MediaFormat
createVideoFormat
(
String
mimeType
,
int
maxInputSize
,
int
width
,
int
height
,
float
pixelWidthHeightRatio
,
List
<
byte
[]>
initializationData
)
{
return
new
MediaFormat
(
mimeType
,
maxInputSize
,
width
,
height
,
pixelWidthHeightRatio
,
NO_VALUE
,
NO_VALUE
,
initializationData
);
}
public
static
MediaFormat
createAudioFormat
(
String
mimeType
,
int
maxInputSize
,
int
channelCount
,
int
sampleRate
,
List
<
byte
[]>
initializationData
)
{
return
new
MediaFormat
(
mimeType
,
maxInputSize
,
NO_VALUE
,
NO_VALUE
,
channelCount
,
sampleRate
,
initializationData
);
return
new
MediaFormat
(
mimeType
,
maxInputSize
,
NO_VALUE
,
NO_VALUE
,
NO_VALUE
,
channelCount
,
sampleRate
,
initializationData
);
}
@TargetApi
(
16
)
...
...
@@ -78,6 +87,7 @@ public class MediaFormat {
height
=
getOptionalIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_HEIGHT
);
channelCount
=
getOptionalIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_CHANNEL_COUNT
);
sampleRate
=
getOptionalIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_SAMPLE_RATE
);
pixelWidthHeightRatio
=
getOptionalFloatV16
(
format
,
KEY_PIXEL_WIDTH_HEIGHT_RATIO
);
initializationData
=
new
ArrayList
<
byte
[]>();
for
(
int
i
=
0
;
format
.
containsKey
(
"csd-"
+
i
);
i
++)
{
ByteBuffer
buffer
=
format
.
getByteBuffer
(
"csd-"
+
i
);
...
...
@@ -90,12 +100,14 @@ public class MediaFormat {
maxHeight
=
NO_VALUE
;
}
private
MediaFormat
(
String
mimeType
,
int
maxInputSize
,
int
width
,
int
height
,
int
channelCount
,
int
sampleRate
,
List
<
byte
[]>
initializationData
)
{
private
MediaFormat
(
String
mimeType
,
int
maxInputSize
,
int
width
,
int
height
,
float
pixelWidthHeightRatio
,
int
channelCount
,
int
sampleRate
,
List
<
byte
[]>
initializationData
)
{
this
.
mimeType
=
mimeType
;
this
.
maxInputSize
=
maxInputSize
;
this
.
width
=
width
;
this
.
height
=
height
;
this
.
pixelWidthHeightRatio
=
pixelWidthHeightRatio
;
this
.
channelCount
=
channelCount
;
this
.
sampleRate
=
sampleRate
;
this
.
initializationData
=
initializationData
==
null
?
Collections
.<
byte
[]>
emptyList
()
...
...
@@ -128,6 +140,7 @@ public class MediaFormat {
result
=
31
*
result
+
maxInputSize
;
result
=
31
*
result
+
width
;
result
=
31
*
result
+
height
;
result
=
31
*
result
+
Float
.
floatToRawIntBits
(
pixelWidthHeightRatio
);
result
=
31
*
result
+
maxWidth
;
result
=
31
*
result
+
maxHeight
;
result
=
31
*
result
+
channelCount
;
...
...
@@ -163,6 +176,7 @@ public class MediaFormat {
private
boolean
equalsInternal
(
MediaFormat
other
,
boolean
ignoreMaxDimensions
)
{
if
(
maxInputSize
!=
other
.
maxInputSize
||
width
!=
other
.
width
||
height
!=
other
.
height
||
pixelWidthHeightRatio
!=
other
.
pixelWidthHeightRatio
||
(!
ignoreMaxDimensions
&&
(
maxWidth
!=
other
.
maxWidth
||
maxHeight
!=
other
.
maxHeight
))
||
channelCount
!=
other
.
channelCount
||
sampleRate
!=
other
.
sampleRate
||
!
Util
.
areEqual
(
mimeType
,
other
.
mimeType
)
...
...
@@ -179,8 +193,9 @@ public class MediaFormat {
@Override
public
String
toString
()
{
return
"MediaFormat("
+
mimeType
+
", "
+
maxInputSize
+
", "
+
width
+
", "
+
height
+
", "
+
channelCount
+
", "
+
sampleRate
+
", "
+
maxWidth
+
", "
+
maxHeight
+
")"
;
return
"MediaFormat("
+
mimeType
+
", "
+
maxInputSize
+
", "
+
width
+
", "
+
height
+
", "
+
pixelWidthHeightRatio
+
", "
+
channelCount
+
", "
+
sampleRate
+
", "
+
maxWidth
+
", "
+
maxHeight
+
")"
;
}
/**
...
...
@@ -196,6 +211,7 @@ public class MediaFormat {
maybeSetIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_HEIGHT
,
height
);
maybeSetIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_CHANNEL_COUNT
,
channelCount
);
maybeSetIntegerV16
(
format
,
android
.
media
.
MediaFormat
.
KEY_SAMPLE_RATE
,
sampleRate
);
maybeSetFloatV16
(
format
,
KEY_PIXEL_WIDTH_HEIGHT_RATIO
,
pixelWidthHeightRatio
);
for
(
int
i
=
0
;
i
<
initializationData
.
size
();
i
++)
{
format
.
setByteBuffer
(
"csd-"
+
i
,
ByteBuffer
.
wrap
(
initializationData
.
get
(
i
)));
}
...
...
@@ -221,9 +237,21 @@ public class MediaFormat {
}
@TargetApi
(
16
)
private
static
final
int
getOptionalIntegerV16
(
android
.
media
.
MediaFormat
format
,
String
key
)
{
private
static
final
void
maybeSetFloatV16
(
android
.
media
.
MediaFormat
format
,
String
key
,
float
value
)
{
if
(
value
!=
NO_VALUE
)
{
format
.
setFloat
(
key
,
value
);
}
}
@TargetApi
(
16
)
private
static
final
int
getOptionalIntegerV16
(
android
.
media
.
MediaFormat
format
,
String
key
)
{
return
format
.
containsKey
(
key
)
?
format
.
getInteger
(
key
)
:
NO_VALUE
;
}
@TargetApi
(
16
)
private
static
final
float
getOptionalFloatV16
(
android
.
media
.
MediaFormat
format
,
String
key
)
{
return
format
.
containsKey
(
key
)
?
format
.
getFloat
(
key
)
:
NO_VALUE
;
}
}
library/src/main/java/com/google/android/exoplayer/parser/mp4/Atom.java
View file @
ec90eac3
...
...
@@ -53,6 +53,7 @@ import java.util.ArrayList;
public
static
final
int
TYPE_saiz
=
0x7361697A
;
public
static
final
int
TYPE_uuid
=
0x75756964
;
public
static
final
int
TYPE_senc
=
0x73656E63
;
public
static
final
int
TYPE_pasp
=
0x70617370
;
public
final
int
type
;
...
...
library/src/main/java/com/google/android/exoplayer/parser/mp4/FragmentedMp4Extractor.java
View file @
ec90eac3
...
...
@@ -106,6 +106,7 @@ public final class FragmentedMp4Extractor implements Extractor {
parsedAtoms
.
add
(
Atom
.
TYPE_saiz
);
parsedAtoms
.
add
(
Atom
.
TYPE_uuid
);
parsedAtoms
.
add
(
Atom
.
TYPE_senc
);
parsedAtoms
.
add
(
Atom
.
TYPE_pasp
);
PARSED_ATOMS
=
Collections
.
unmodifiableSet
(
parsedAtoms
);
}
...
...
@@ -529,6 +530,7 @@ public final class FragmentedMp4Extractor implements Extractor {
parent
.
skip
(
24
);
int
width
=
parent
.
readUnsignedShort
();
int
height
=
parent
.
readUnsignedShort
();
float
pixelWidthHeightRatio
=
1
;
parent
.
skip
(
50
);
List
<
byte
[]>
initializationData
=
null
;
...
...
@@ -543,12 +545,14 @@ public final class FragmentedMp4Extractor implements Extractor {
initializationData
=
parseAvcCFromParent
(
parent
,
childStartPosition
);
}
else
if
(
childAtomType
==
Atom
.
TYPE_sinf
)
{
trackEncryptionBox
=
parseSinfFromParent
(
parent
,
childStartPosition
,
childAtomSize
);
}
else
if
(
childAtomType
==
Atom
.
TYPE_pasp
)
{
pixelWidthHeightRatio
=
parsePaspFromParent
(
parent
,
childStartPosition
);
}
childPosition
+=
childAtomSize
;
}
MediaFormat
format
=
MediaFormat
.
createVideoFormat
(
MimeTypes
.
VIDEO_H264
,
MediaFormat
.
NO_VALUE
,
width
,
height
,
initializationData
);
width
,
height
,
pixelWidthHeightRatio
,
initializationData
);
return
Pair
.
create
(
format
,
trackEncryptionBox
);
}
...
...
@@ -643,6 +647,13 @@ public final class FragmentedMp4Extractor implements Extractor {
return
trackEncryptionBox
;
}
private
static
float
parsePaspFromParent
(
ParsableByteArray
parent
,
int
position
)
{
parent
.
setPosition
(
position
+
ATOM_HEADER_SIZE
);
int
hSpacing
=
parent
.
readUnsignedIntToInt
();
int
vSpacing
=
parent
.
readUnsignedIntToInt
();
return
(
float
)
hSpacing
/
vSpacing
;
}
private
static
TrackEncryptionBox
parseSchiFromParent
(
ParsableByteArray
parent
,
int
position
,
int
size
)
{
int
childPosition
=
position
+
ATOM_HEADER_SIZE
;
...
...
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