mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
parent
2380f937f3
commit
f0e0ee421f
@ -34,6 +34,8 @@
|
|||||||
to proceed.
|
to proceed.
|
||||||
* Fix handling of E-AC-3 streams that contain AC-3 syncframes
|
* Fix handling of E-AC-3 streams that contain AC-3 syncframes
|
||||||
([#6602](https://github.com/google/ExoPlayer/issues/6602)).
|
([#6602](https://github.com/google/ExoPlayer/issues/6602)).
|
||||||
|
* Support "twos" codec (big endian PCM) in MP4
|
||||||
|
([#5789](https://github.com/google/ExoPlayer/issues/5789)).
|
||||||
|
|
||||||
### 2.11.1 (2019-12-20) ###
|
### 2.11.1 (2019-12-20) ###
|
||||||
|
|
||||||
|
@ -150,10 +150,11 @@ public final class C {
|
|||||||
/**
|
/**
|
||||||
* Represents an audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
|
* Represents an audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
|
||||||
* {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
|
* {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
|
||||||
* #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT}, {@link #ENCODING_PCM_FLOAT}, {@link
|
* #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
||||||
* #ENCODING_PCM_MU_LAW}, {@link #ENCODING_PCM_A_LAW}, {@link #ENCODING_MP3}, {@link
|
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_MU_LAW}, {@link #ENCODING_PCM_A_LAW}, {@link
|
||||||
* #ENCODING_AC3}, {@link #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC}, {@link #ENCODING_AC4},
|
* #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC},
|
||||||
* {@link #ENCODING_DTS}, {@link #ENCODING_DTS_HD} or {@link #ENCODING_DOLBY_TRUEHD}.
|
* {@link #ENCODING_AC4}, {@link #ENCODING_DTS}, {@link #ENCODING_DTS_HD} or {@link
|
||||||
|
* #ENCODING_DOLBY_TRUEHD}.
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@ -162,6 +163,7 @@ public final class C {
|
|||||||
ENCODING_INVALID,
|
ENCODING_INVALID,
|
||||||
ENCODING_PCM_8BIT,
|
ENCODING_PCM_8BIT,
|
||||||
ENCODING_PCM_16BIT,
|
ENCODING_PCM_16BIT,
|
||||||
|
ENCODING_PCM_16BIT_BIG_ENDIAN,
|
||||||
ENCODING_PCM_24BIT,
|
ENCODING_PCM_24BIT,
|
||||||
ENCODING_PCM_32BIT,
|
ENCODING_PCM_32BIT,
|
||||||
ENCODING_PCM_FLOAT,
|
ENCODING_PCM_FLOAT,
|
||||||
@ -181,8 +183,8 @@ public final class C {
|
|||||||
/**
|
/**
|
||||||
* Represents a PCM audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
|
* Represents a PCM audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
|
||||||
* {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
|
* {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
|
||||||
* #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT}, {@link #ENCODING_PCM_FLOAT}, {@link
|
* #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
||||||
* #ENCODING_PCM_MU_LAW} or {@link #ENCODING_PCM_A_LAW}.
|
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_MU_LAW} or {@link #ENCODING_PCM_A_LAW}.
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@ -191,6 +193,7 @@ public final class C {
|
|||||||
ENCODING_INVALID,
|
ENCODING_INVALID,
|
||||||
ENCODING_PCM_8BIT,
|
ENCODING_PCM_8BIT,
|
||||||
ENCODING_PCM_16BIT,
|
ENCODING_PCM_16BIT,
|
||||||
|
ENCODING_PCM_16BIT_BIG_ENDIAN,
|
||||||
ENCODING_PCM_24BIT,
|
ENCODING_PCM_24BIT,
|
||||||
ENCODING_PCM_32BIT,
|
ENCODING_PCM_32BIT,
|
||||||
ENCODING_PCM_FLOAT,
|
ENCODING_PCM_FLOAT,
|
||||||
@ -204,6 +207,8 @@ public final class C {
|
|||||||
public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT;
|
public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT;
|
||||||
/** @see AudioFormat#ENCODING_PCM_16BIT */
|
/** @see AudioFormat#ENCODING_PCM_16BIT */
|
||||||
public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT;
|
public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT;
|
||||||
|
/** Like {@link #ENCODING_PCM_16BIT}, but with the bytes in big endian order. */
|
||||||
|
public static final int ENCODING_PCM_16BIT_BIG_ENDIAN = 0x08000000;
|
||||||
/** PCM encoding with 24 bits per sample. */
|
/** PCM encoding with 24 bits per sample. */
|
||||||
public static final int ENCODING_PCM_24BIT = 0x80000000;
|
public static final int ENCODING_PCM_24BIT = 0x80000000;
|
||||||
/** PCM encoding with 32 bits per sample. */
|
/** PCM encoding with 32 bits per sample. */
|
||||||
|
@ -29,8 +29,11 @@ import java.nio.ByteBuffer;
|
|||||||
public AudioFormat onConfigure(AudioFormat inputAudioFormat)
|
public AudioFormat onConfigure(AudioFormat inputAudioFormat)
|
||||||
throws UnhandledAudioFormatException {
|
throws UnhandledAudioFormatException {
|
||||||
@C.PcmEncoding int encoding = inputAudioFormat.encoding;
|
@C.PcmEncoding int encoding = inputAudioFormat.encoding;
|
||||||
if (encoding != C.ENCODING_PCM_8BIT && encoding != C.ENCODING_PCM_16BIT
|
if (encoding != C.ENCODING_PCM_8BIT
|
||||||
&& encoding != C.ENCODING_PCM_24BIT && encoding != C.ENCODING_PCM_32BIT) {
|
&& encoding != C.ENCODING_PCM_16BIT
|
||||||
|
&& encoding != C.ENCODING_PCM_16BIT_BIG_ENDIAN
|
||||||
|
&& encoding != C.ENCODING_PCM_24BIT
|
||||||
|
&& encoding != C.ENCODING_PCM_32BIT) {
|
||||||
throw new UnhandledAudioFormatException(inputAudioFormat);
|
throw new UnhandledAudioFormatException(inputAudioFormat);
|
||||||
}
|
}
|
||||||
return encoding != C.ENCODING_PCM_16BIT
|
return encoding != C.ENCODING_PCM_16BIT
|
||||||
@ -50,6 +53,9 @@ import java.nio.ByteBuffer;
|
|||||||
case C.ENCODING_PCM_8BIT:
|
case C.ENCODING_PCM_8BIT:
|
||||||
resampledSize = size * 2;
|
resampledSize = size * 2;
|
||||||
break;
|
break;
|
||||||
|
case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
|
||||||
|
resampledSize = size;
|
||||||
|
break;
|
||||||
case C.ENCODING_PCM_24BIT:
|
case C.ENCODING_PCM_24BIT:
|
||||||
resampledSize = (size / 3) * 2;
|
resampledSize = (size / 3) * 2;
|
||||||
break;
|
break;
|
||||||
@ -70,21 +76,28 @@ import java.nio.ByteBuffer;
|
|||||||
ByteBuffer buffer = replaceOutputBuffer(resampledSize);
|
ByteBuffer buffer = replaceOutputBuffer(resampledSize);
|
||||||
switch (inputAudioFormat.encoding) {
|
switch (inputAudioFormat.encoding) {
|
||||||
case C.ENCODING_PCM_8BIT:
|
case C.ENCODING_PCM_8BIT:
|
||||||
// 8->16 bit resampling. Shift each byte from [0, 256) to [-128, 128) and scale up.
|
// 8 -> 16 bit resampling. Shift each byte from [0, 256) to [-128, 128) and scale up.
|
||||||
for (int i = position; i < limit; i++) {
|
for (int i = position; i < limit; i++) {
|
||||||
buffer.put((byte) 0);
|
buffer.put((byte) 0);
|
||||||
buffer.put((byte) ((inputBuffer.get(i) & 0xFF) - 128));
|
buffer.put((byte) ((inputBuffer.get(i) & 0xFF) - 128));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
|
||||||
|
// Big endian to little endian resampling. Swap the byte order.
|
||||||
|
for (int i = position; i < limit; i += 2) {
|
||||||
|
buffer.put(inputBuffer.get(i + 1));
|
||||||
|
buffer.put(inputBuffer.get(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case C.ENCODING_PCM_24BIT:
|
case C.ENCODING_PCM_24BIT:
|
||||||
// 24->16 bit resampling. Drop the least significant byte.
|
// 24 -> 16 bit resampling. Drop the least significant byte.
|
||||||
for (int i = position; i < limit; i += 3) {
|
for (int i = position; i < limit; i += 3) {
|
||||||
buffer.put(inputBuffer.get(i + 1));
|
buffer.put(inputBuffer.get(i + 1));
|
||||||
buffer.put(inputBuffer.get(i + 2));
|
buffer.put(inputBuffer.get(i + 2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case C.ENCODING_PCM_32BIT:
|
case C.ENCODING_PCM_32BIT:
|
||||||
// 32->16 bit resampling. Drop the two least significant bytes.
|
// 32 -> 16 bit resampling. Drop the two least significant bytes.
|
||||||
for (int i = position; i < limit; i += 4) {
|
for (int i = position; i < limit; i += 4) {
|
||||||
buffer.put(inputBuffer.get(i + 2));
|
buffer.put(inputBuffer.get(i + 2));
|
||||||
buffer.put(inputBuffer.get(i + 3));
|
buffer.put(inputBuffer.get(i + 3));
|
||||||
|
@ -379,6 +379,9 @@ import java.util.List;
|
|||||||
@SuppressWarnings("ConstantCaseForConstants")
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
public static final int TYPE_dfLa = 0x64664c61;
|
public static final int TYPE_dfLa = 0x64664c61;
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
|
public static final int TYPE_twos = 0x74776f73;
|
||||||
|
|
||||||
public final int type;
|
public final int type;
|
||||||
|
|
||||||
public Atom(int type) {
|
public Atom(int type) {
|
||||||
|
@ -798,6 +798,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
|| childAtomType == Atom.TYPE_sawb
|
|| childAtomType == Atom.TYPE_sawb
|
||||||
|| childAtomType == Atom.TYPE_lpcm
|
|| childAtomType == Atom.TYPE_lpcm
|
||||||
|| childAtomType == Atom.TYPE_sowt
|
|| childAtomType == Atom.TYPE_sowt
|
||||||
|
|| childAtomType == Atom.TYPE_twos
|
||||||
|| childAtomType == Atom.TYPE__mp3
|
|| childAtomType == Atom.TYPE__mp3
|
||||||
|| childAtomType == Atom.TYPE_alac
|
|| childAtomType == Atom.TYPE_alac
|
||||||
|| childAtomType == Atom.TYPE_alaw
|
|| childAtomType == Atom.TYPE_alaw
|
||||||
@ -1086,6 +1087,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
|
|
||||||
int channelCount;
|
int channelCount;
|
||||||
int sampleRate;
|
int sampleRate;
|
||||||
|
@C.PcmEncoding int pcmEncoding = Format.NO_VALUE;
|
||||||
|
|
||||||
if (quickTimeSoundDescriptionVersion == 0 || quickTimeSoundDescriptionVersion == 1) {
|
if (quickTimeSoundDescriptionVersion == 0 || quickTimeSoundDescriptionVersion == 1) {
|
||||||
channelCount = parent.readUnsignedShort();
|
channelCount = parent.readUnsignedShort();
|
||||||
@ -1147,6 +1149,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
mimeType = MimeTypes.AUDIO_AMR_WB;
|
mimeType = MimeTypes.AUDIO_AMR_WB;
|
||||||
} else if (atomType == Atom.TYPE_lpcm || atomType == Atom.TYPE_sowt) {
|
} else if (atomType == Atom.TYPE_lpcm || atomType == Atom.TYPE_sowt) {
|
||||||
mimeType = MimeTypes.AUDIO_RAW;
|
mimeType = MimeTypes.AUDIO_RAW;
|
||||||
|
pcmEncoding = C.ENCODING_PCM_16BIT;
|
||||||
|
} else if (atomType == Atom.TYPE_twos) {
|
||||||
|
mimeType = MimeTypes.AUDIO_RAW;
|
||||||
|
pcmEncoding = C.ENCODING_PCM_16BIT_BIG_ENDIAN;
|
||||||
} else if (atomType == Atom.TYPE__mp3) {
|
} else if (atomType == Atom.TYPE__mp3) {
|
||||||
mimeType = MimeTypes.AUDIO_MPEG;
|
mimeType = MimeTypes.AUDIO_MPEG;
|
||||||
} else if (atomType == Atom.TYPE_alac) {
|
} else if (atomType == Atom.TYPE_alac) {
|
||||||
@ -1233,9 +1239,6 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (out.format == null && mimeType != null) {
|
if (out.format == null && mimeType != null) {
|
||||||
// TODO: Determine the correct PCM encoding.
|
|
||||||
@C.PcmEncoding int pcmEncoding =
|
|
||||||
MimeTypes.AUDIO_RAW.equals(mimeType) ? C.ENCODING_PCM_16BIT : Format.NO_VALUE;
|
|
||||||
out.format = Format.createAudioSampleFormat(Integer.toString(trackId), mimeType, null,
|
out.format = Format.createAudioSampleFormat(Integer.toString(trackId), mimeType, null,
|
||||||
Format.NO_VALUE, Format.NO_VALUE, channelCount, sampleRate, pcmEncoding,
|
Format.NO_VALUE, Format.NO_VALUE, channelCount, sampleRate, pcmEncoding,
|
||||||
initializationData == null ? null : Collections.singletonList(initializationData),
|
initializationData == null ? null : Collections.singletonList(initializationData),
|
||||||
|
@ -1355,6 +1355,7 @@ public final class Util {
|
|||||||
public static boolean isEncodingLinearPcm(@C.Encoding int encoding) {
|
public static boolean isEncodingLinearPcm(@C.Encoding int encoding) {
|
||||||
return encoding == C.ENCODING_PCM_8BIT
|
return encoding == C.ENCODING_PCM_8BIT
|
||||||
|| encoding == C.ENCODING_PCM_16BIT
|
|| encoding == C.ENCODING_PCM_16BIT
|
||||||
|
|| encoding == C.ENCODING_PCM_16BIT_BIG_ENDIAN
|
||||||
|| encoding == C.ENCODING_PCM_24BIT
|
|| encoding == C.ENCODING_PCM_24BIT
|
||||||
|| encoding == C.ENCODING_PCM_32BIT
|
|| encoding == C.ENCODING_PCM_32BIT
|
||||||
|| encoding == C.ENCODING_PCM_FLOAT;
|
|| encoding == C.ENCODING_PCM_FLOAT;
|
||||||
@ -1423,6 +1424,7 @@ public final class Util {
|
|||||||
case C.ENCODING_PCM_8BIT:
|
case C.ENCODING_PCM_8BIT:
|
||||||
return channelCount;
|
return channelCount;
|
||||||
case C.ENCODING_PCM_16BIT:
|
case C.ENCODING_PCM_16BIT:
|
||||||
|
case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
|
||||||
return channelCount * 2;
|
return channelCount * 2;
|
||||||
case C.ENCODING_PCM_24BIT:
|
case C.ENCODING_PCM_24BIT:
|
||||||
return channelCount * 3;
|
return channelCount * 3;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user