Use MIME types rather than PCM encodings for ALAW and MLAW
PiperOrigin-RevId: 287999703
This commit is contained in:
parent
88e70d7c1b
commit
f1f0ff3a65
@ -40,6 +40,9 @@
|
|||||||
* Show ad group markers in `DefaultTimeBar` even if they are after the end of
|
* Show ad group markers in `DefaultTimeBar` even if they are after the end of
|
||||||
the current window
|
the current window
|
||||||
([#6552](https://github.com/google/ExoPlayer/issues/6552)).
|
([#6552](https://github.com/google/ExoPlayer/issues/6552)).
|
||||||
|
* WAV:
|
||||||
|
* Support IMA ADPCM encoded data.
|
||||||
|
* Improve support for G.711 A-law and mu-law encoded data.
|
||||||
|
|
||||||
### 2.11.1 (2019-12-20) ###
|
### 2.11.1 (2019-12-20) ###
|
||||||
|
|
||||||
|
@ -98,8 +98,7 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
|
|||||||
Assertions.checkNotNull(format.sampleMimeType);
|
Assertions.checkNotNull(format.sampleMimeType);
|
||||||
if (!FfmpegLibrary.isAvailable()) {
|
if (!FfmpegLibrary.isAvailable()) {
|
||||||
return FORMAT_UNSUPPORTED_TYPE;
|
return FORMAT_UNSUPPORTED_TYPE;
|
||||||
} else if (!FfmpegLibrary.supportsFormat(format.sampleMimeType, format.pcmEncoding)
|
} else if (!FfmpegLibrary.supportsFormat(format.sampleMimeType) || !isOutputSupported(format)) {
|
||||||
|| !isOutputSupported(format)) {
|
|
||||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||||
return FORMAT_UNSUPPORTED_DRM;
|
return FORMAT_UNSUPPORTED_DRM;
|
||||||
|
@ -64,9 +64,7 @@ import java.util.List;
|
|||||||
throw new FfmpegDecoderException("Failed to load decoder native libraries.");
|
throw new FfmpegDecoderException("Failed to load decoder native libraries.");
|
||||||
}
|
}
|
||||||
Assertions.checkNotNull(format.sampleMimeType);
|
Assertions.checkNotNull(format.sampleMimeType);
|
||||||
codecName =
|
codecName = Assertions.checkNotNull(FfmpegLibrary.getCodecName(format.sampleMimeType));
|
||||||
Assertions.checkNotNull(
|
|
||||||
FfmpegLibrary.getCodecName(format.sampleMimeType, format.pcmEncoding));
|
|
||||||
extraData = getExtraData(format.sampleMimeType, format.initializationData);
|
extraData = getExtraData(format.sampleMimeType, format.initializationData);
|
||||||
encoding = outputFloat ? C.ENCODING_PCM_FLOAT : C.ENCODING_PCM_16BIT;
|
encoding = outputFloat ? C.ENCODING_PCM_FLOAT : C.ENCODING_PCM_16BIT;
|
||||||
outputBufferSize = outputFloat ? OUTPUT_BUFFER_SIZE_32BIT : OUTPUT_BUFFER_SIZE_16BIT;
|
outputBufferSize = outputFloat ? OUTPUT_BUFFER_SIZE_32BIT : OUTPUT_BUFFER_SIZE_16BIT;
|
||||||
@ -145,16 +143,12 @@ import java.util.List;
|
|||||||
nativeContext = 0;
|
nativeContext = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Returns the channel count of output audio. */
|
||||||
* Returns the channel count of output audio. May only be called after {@link #decode}.
|
|
||||||
*/
|
|
||||||
public int getChannelCount() {
|
public int getChannelCount() {
|
||||||
return channelCount;
|
return channelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Returns the sample rate of output audio. */
|
||||||
* Returns the sample rate of output audio. May only be called after {@link #decode}.
|
|
||||||
*/
|
|
||||||
public int getSampleRate() {
|
public int getSampleRate() {
|
||||||
return sampleRate;
|
return sampleRate;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package com.google.android.exoplayer2.ext.ffmpeg;
|
package com.google.android.exoplayer2.ext.ffmpeg;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||||
import com.google.android.exoplayer2.util.LibraryLoader;
|
import com.google.android.exoplayer2.util.LibraryLoader;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
@ -65,13 +64,12 @@ public final class FfmpegLibrary {
|
|||||||
* Returns whether the underlying library supports the specified MIME type.
|
* Returns whether the underlying library supports the specified MIME type.
|
||||||
*
|
*
|
||||||
* @param mimeType The MIME type to check.
|
* @param mimeType The MIME type to check.
|
||||||
* @param encoding The PCM encoding for raw audio.
|
|
||||||
*/
|
*/
|
||||||
public static boolean supportsFormat(String mimeType, @C.PcmEncoding int encoding) {
|
public static boolean supportsFormat(String mimeType) {
|
||||||
if (!isAvailable()) {
|
if (!isAvailable()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String codecName = getCodecName(mimeType, encoding);
|
String codecName = getCodecName(mimeType);
|
||||||
if (codecName == null) {
|
if (codecName == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -86,7 +84,7 @@ public final class FfmpegLibrary {
|
|||||||
* Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null}
|
* Returns the name of the FFmpeg decoder that could be used to decode the format, or {@code null}
|
||||||
* if it's unsupported.
|
* if it's unsupported.
|
||||||
*/
|
*/
|
||||||
/* package */ static @Nullable String getCodecName(String mimeType, @C.PcmEncoding int encoding) {
|
/* package */ static @Nullable String getCodecName(String mimeType) {
|
||||||
switch (mimeType) {
|
switch (mimeType) {
|
||||||
case MimeTypes.AUDIO_AAC:
|
case MimeTypes.AUDIO_AAC:
|
||||||
return "aac";
|
return "aac";
|
||||||
@ -116,14 +114,10 @@ public final class FfmpegLibrary {
|
|||||||
return "flac";
|
return "flac";
|
||||||
case MimeTypes.AUDIO_ALAC:
|
case MimeTypes.AUDIO_ALAC:
|
||||||
return "alac";
|
return "alac";
|
||||||
case MimeTypes.AUDIO_RAW:
|
case MimeTypes.AUDIO_MLAW:
|
||||||
if (encoding == C.ENCODING_PCM_MU_LAW) {
|
return "pcm_mulaw";
|
||||||
return "pcm_mulaw";
|
case MimeTypes.AUDIO_ALAW:
|
||||||
} else if (encoding == C.ENCODING_PCM_A_LAW) {
|
return "pcm_alaw";
|
||||||
return "pcm_alaw";
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -151,10 +151,9 @@ 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_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
* #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
||||||
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_MU_LAW}, {@link #ENCODING_PCM_A_LAW}, {@link
|
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link
|
||||||
* #ENCODING_MP3}, {@link #ENCODING_AC3}, {@link #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC},
|
* #ENCODING_E_AC3}, {@link #ENCODING_E_AC3_JOC}, {@link #ENCODING_AC4}, {@link #ENCODING_DTS},
|
||||||
* {@link #ENCODING_AC4}, {@link #ENCODING_DTS}, {@link #ENCODING_DTS_HD} or {@link
|
* {@link #ENCODING_DTS_HD} or {@link #ENCODING_DOLBY_TRUEHD}.
|
||||||
* #ENCODING_DOLBY_TRUEHD}.
|
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@ -167,8 +166,6 @@ public final class C {
|
|||||||
ENCODING_PCM_24BIT,
|
ENCODING_PCM_24BIT,
|
||||||
ENCODING_PCM_32BIT,
|
ENCODING_PCM_32BIT,
|
||||||
ENCODING_PCM_FLOAT,
|
ENCODING_PCM_FLOAT,
|
||||||
ENCODING_PCM_MU_LAW,
|
|
||||||
ENCODING_PCM_A_LAW,
|
|
||||||
ENCODING_MP3,
|
ENCODING_MP3,
|
||||||
ENCODING_AC3,
|
ENCODING_AC3,
|
||||||
ENCODING_E_AC3,
|
ENCODING_E_AC3,
|
||||||
@ -176,7 +173,7 @@ public final class C {
|
|||||||
ENCODING_AC4,
|
ENCODING_AC4,
|
||||||
ENCODING_DTS,
|
ENCODING_DTS,
|
||||||
ENCODING_DTS_HD,
|
ENCODING_DTS_HD,
|
||||||
ENCODING_DOLBY_TRUEHD,
|
ENCODING_DOLBY_TRUEHD
|
||||||
})
|
})
|
||||||
public @interface Encoding {}
|
public @interface Encoding {}
|
||||||
|
|
||||||
@ -184,7 +181,7 @@ 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_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
* #ENCODING_PCM_16BIT_BIG_ENDIAN}, {@link #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT},
|
||||||
* {@link #ENCODING_PCM_FLOAT}, {@link #ENCODING_PCM_MU_LAW} or {@link #ENCODING_PCM_A_LAW}.
|
* {@link #ENCODING_PCM_FLOAT}.
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@ -196,9 +193,7 @@ public final class C {
|
|||||||
ENCODING_PCM_16BIT_BIG_ENDIAN,
|
ENCODING_PCM_16BIT_BIG_ENDIAN,
|
||||||
ENCODING_PCM_24BIT,
|
ENCODING_PCM_24BIT,
|
||||||
ENCODING_PCM_32BIT,
|
ENCODING_PCM_32BIT,
|
||||||
ENCODING_PCM_FLOAT,
|
ENCODING_PCM_FLOAT
|
||||||
ENCODING_PCM_MU_LAW,
|
|
||||||
ENCODING_PCM_A_LAW
|
|
||||||
})
|
})
|
||||||
public @interface PcmEncoding {}
|
public @interface PcmEncoding {}
|
||||||
/** @see AudioFormat#ENCODING_INVALID */
|
/** @see AudioFormat#ENCODING_INVALID */
|
||||||
@ -208,17 +203,13 @@ public final class C {
|
|||||||
/** @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. */
|
/** Like {@link #ENCODING_PCM_16BIT}, but with the bytes in big endian order. */
|
||||||
public static final int ENCODING_PCM_16BIT_BIG_ENDIAN = 0x08000000;
|
public static final int ENCODING_PCM_16BIT_BIG_ENDIAN = 0x10000000;
|
||||||
/** 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 = 0x20000000;
|
||||||
/** PCM encoding with 32 bits per sample. */
|
/** PCM encoding with 32 bits per sample. */
|
||||||
public static final int ENCODING_PCM_32BIT = 0x40000000;
|
public static final int ENCODING_PCM_32BIT = 0x30000000;
|
||||||
/** @see AudioFormat#ENCODING_PCM_FLOAT */
|
/** @see AudioFormat#ENCODING_PCM_FLOAT */
|
||||||
public static final int ENCODING_PCM_FLOAT = AudioFormat.ENCODING_PCM_FLOAT;
|
public static final int ENCODING_PCM_FLOAT = AudioFormat.ENCODING_PCM_FLOAT;
|
||||||
/** Audio encoding for mu-law. */
|
|
||||||
public static final int ENCODING_PCM_MU_LAW = 0x10000000;
|
|
||||||
/** Audio encoding for A-law. */
|
|
||||||
public static final int ENCODING_PCM_A_LAW = 0x20000000;
|
|
||||||
/** @see AudioFormat#ENCODING_MP3 */
|
/** @see AudioFormat#ENCODING_MP3 */
|
||||||
public static final int ENCODING_MP3 = AudioFormat.ENCODING_MP3;
|
public static final int ENCODING_MP3 = AudioFormat.ENCODING_MP3;
|
||||||
/** @see AudioFormat#ENCODING_AC3 */
|
/** @see AudioFormat#ENCODING_AC3 */
|
||||||
|
@ -138,13 +138,7 @@ public final class Format implements Parcelable {
|
|||||||
* The audio sampling rate in Hz, or {@link #NO_VALUE} if unknown or not applicable.
|
* The audio sampling rate in Hz, or {@link #NO_VALUE} if unknown or not applicable.
|
||||||
*/
|
*/
|
||||||
public final int sampleRate;
|
public final int sampleRate;
|
||||||
/**
|
/** The {@link C.PcmEncoding} for PCM audio. Set to {@link #NO_VALUE} for other media types. */
|
||||||
* The encoding for PCM audio streams. If {@link #sampleMimeType} is {@link MimeTypes#AUDIO_RAW}
|
|
||||||
* then one of {@link C#ENCODING_PCM_8BIT}, {@link C#ENCODING_PCM_16BIT}, {@link
|
|
||||||
* C#ENCODING_PCM_24BIT}, {@link C#ENCODING_PCM_32BIT}, {@link C#ENCODING_PCM_FLOAT}, {@link
|
|
||||||
* C#ENCODING_PCM_MU_LAW} or {@link C#ENCODING_PCM_A_LAW}. Set to {@link #NO_VALUE} for other
|
|
||||||
* media types.
|
|
||||||
*/
|
|
||||||
public final @C.PcmEncoding int pcmEncoding;
|
public final @C.PcmEncoding int pcmEncoding;
|
||||||
/**
|
/**
|
||||||
* The number of frames to trim from the start of the decoded audio stream, or 0 if not
|
* The number of frames to trim from the start of the decoded audio stream, or 0 if not
|
||||||
|
@ -1149,9 +1149,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
case C.ENCODING_PCM_24BIT:
|
case C.ENCODING_PCM_24BIT:
|
||||||
case C.ENCODING_PCM_32BIT:
|
case C.ENCODING_PCM_32BIT:
|
||||||
case C.ENCODING_PCM_8BIT:
|
case C.ENCODING_PCM_8BIT:
|
||||||
case C.ENCODING_PCM_A_LAW:
|
|
||||||
case C.ENCODING_PCM_FLOAT:
|
case C.ENCODING_PCM_FLOAT:
|
||||||
case C.ENCODING_PCM_MU_LAW:
|
|
||||||
case Format.NO_VALUE:
|
case Format.NO_VALUE:
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
@ -64,8 +64,6 @@ import java.nio.ByteBuffer;
|
|||||||
break;
|
break;
|
||||||
case C.ENCODING_PCM_16BIT:
|
case C.ENCODING_PCM_16BIT:
|
||||||
case C.ENCODING_PCM_FLOAT:
|
case C.ENCODING_PCM_FLOAT:
|
||||||
case C.ENCODING_PCM_A_LAW:
|
|
||||||
case C.ENCODING_PCM_MU_LAW:
|
|
||||||
case C.ENCODING_INVALID:
|
case C.ENCODING_INVALID:
|
||||||
case Format.NO_VALUE:
|
case Format.NO_VALUE:
|
||||||
default:
|
default:
|
||||||
@ -105,8 +103,6 @@ import java.nio.ByteBuffer;
|
|||||||
break;
|
break;
|
||||||
case C.ENCODING_PCM_16BIT:
|
case C.ENCODING_PCM_16BIT:
|
||||||
case C.ENCODING_PCM_FLOAT:
|
case C.ENCODING_PCM_FLOAT:
|
||||||
case C.ENCODING_PCM_A_LAW:
|
|
||||||
case C.ENCODING_PCM_MU_LAW:
|
|
||||||
case C.ENCODING_INVALID:
|
case C.ENCODING_INVALID:
|
||||||
case Format.NO_VALUE:
|
case Format.NO_VALUE:
|
||||||
default:
|
default:
|
||||||
|
@ -36,9 +36,9 @@ public final class WavUtil {
|
|||||||
/** WAVE type value for float PCM audio data. */
|
/** WAVE type value for float PCM audio data. */
|
||||||
public static final int TYPE_FLOAT = 0x0003;
|
public static final int TYPE_FLOAT = 0x0003;
|
||||||
/** WAVE type value for 8-bit ITU-T G.711 A-law audio data. */
|
/** WAVE type value for 8-bit ITU-T G.711 A-law audio data. */
|
||||||
public static final int TYPE_A_LAW = 0x0006;
|
public static final int TYPE_ALAW = 0x0006;
|
||||||
/** WAVE type value for 8-bit ITU-T G.711 mu-law audio data. */
|
/** WAVE type value for 8-bit ITU-T G.711 mu-law audio data. */
|
||||||
public static final int TYPE_MU_LAW = 0x0007;
|
public static final int TYPE_MLAW = 0x0007;
|
||||||
/** WAVE type value for IMA ADPCM audio data. */
|
/** WAVE type value for IMA ADPCM audio data. */
|
||||||
public static final int TYPE_IMA_ADPCM = 0x0011;
|
public static final int TYPE_IMA_ADPCM = 0x0011;
|
||||||
/** WAVE type value for extended WAVE format. */
|
/** WAVE type value for extended WAVE format. */
|
||||||
@ -59,10 +59,6 @@ public final class WavUtil {
|
|||||||
case C.ENCODING_PCM_24BIT:
|
case C.ENCODING_PCM_24BIT:
|
||||||
case C.ENCODING_PCM_32BIT:
|
case C.ENCODING_PCM_32BIT:
|
||||||
return TYPE_PCM;
|
return TYPE_PCM;
|
||||||
case C.ENCODING_PCM_A_LAW:
|
|
||||||
return TYPE_A_LAW;
|
|
||||||
case C.ENCODING_PCM_MU_LAW:
|
|
||||||
return TYPE_MU_LAW;
|
|
||||||
case C.ENCODING_PCM_FLOAT:
|
case C.ENCODING_PCM_FLOAT:
|
||||||
return TYPE_FLOAT;
|
return TYPE_FLOAT;
|
||||||
case C.ENCODING_INVALID:
|
case C.ENCODING_INVALID:
|
||||||
@ -83,10 +79,6 @@ public final class WavUtil {
|
|||||||
return Util.getPcmEncoding(bitsPerSample);
|
return Util.getPcmEncoding(bitsPerSample);
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
return bitsPerSample == 32 ? C.ENCODING_PCM_FLOAT : C.ENCODING_INVALID;
|
return bitsPerSample == 32 ? C.ENCODING_PCM_FLOAT : C.ENCODING_INVALID;
|
||||||
case TYPE_A_LAW:
|
|
||||||
return C.ENCODING_PCM_A_LAW;
|
|
||||||
case TYPE_MU_LAW:
|
|
||||||
return C.ENCODING_PCM_MU_LAW;
|
|
||||||
default:
|
default:
|
||||||
return C.ENCODING_INVALID;
|
return C.ENCODING_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,20 @@ import java.util.Collections;
|
|||||||
} else if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) {
|
} else if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) {
|
||||||
String type = audioFormat == AUDIO_FORMAT_ALAW ? MimeTypes.AUDIO_ALAW
|
String type = audioFormat == AUDIO_FORMAT_ALAW ? MimeTypes.AUDIO_ALAW
|
||||||
: MimeTypes.AUDIO_MLAW;
|
: MimeTypes.AUDIO_MLAW;
|
||||||
int pcmEncoding = (header & 0x01) == 1 ? C.ENCODING_PCM_16BIT : C.ENCODING_PCM_8BIT;
|
Format format =
|
||||||
Format format = Format.createAudioSampleFormat(null, type, null, Format.NO_VALUE,
|
Format.createAudioSampleFormat(
|
||||||
Format.NO_VALUE, 1, 8000, pcmEncoding, null, null, 0, null);
|
/* id= */ null,
|
||||||
|
/* sampleMimeType= */ type,
|
||||||
|
/* codecs= */ null,
|
||||||
|
/* bitrate= */ Format.NO_VALUE,
|
||||||
|
/* maxInputSize= */ Format.NO_VALUE,
|
||||||
|
/* channelCount= */ 1,
|
||||||
|
/* sampleRate= */ 8000,
|
||||||
|
/* pcmEncoding= */ Format.NO_VALUE,
|
||||||
|
/* initializationData= */ null,
|
||||||
|
/* drmInitData= */ null,
|
||||||
|
/* selectionFlags= */ 0,
|
||||||
|
/* language= */ null);
|
||||||
output.format(format);
|
output.format(format);
|
||||||
hasOutputFormat = true;
|
hasOutputFormat = true;
|
||||||
} else if (audioFormat != AUDIO_FORMAT_AAC) {
|
} else if (audioFormat != AUDIO_FORMAT_AAC) {
|
||||||
|
@ -94,13 +94,31 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
||||||
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, header);
|
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, header);
|
||||||
|
} else if (header.formatType == WavUtil.TYPE_ALAW) {
|
||||||
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput,
|
||||||
|
trackOutput,
|
||||||
|
header,
|
||||||
|
MimeTypes.AUDIO_ALAW,
|
||||||
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
|
} else if (header.formatType == WavUtil.TYPE_MLAW) {
|
||||||
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput,
|
||||||
|
trackOutput,
|
||||||
|
header,
|
||||||
|
MimeTypes.AUDIO_MLAW,
|
||||||
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
} else {
|
} else {
|
||||||
@C.PcmEncoding
|
@C.PcmEncoding
|
||||||
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
||||||
if (pcmEncoding == C.ENCODING_INVALID) {
|
if (pcmEncoding == C.ENCODING_INVALID) {
|
||||||
throw new ParserException("Unsupported WAV format type: " + header.formatType);
|
throw new ParserException("Unsupported WAV format type: " + header.formatType);
|
||||||
}
|
}
|
||||||
outputWriter = new PcmOutputWriter(extractorOutput, trackOutput, header, pcmEncoding);
|
outputWriter =
|
||||||
|
new PassthroughOutputWriter(
|
||||||
|
extractorOutput, trackOutput, header, MimeTypes.AUDIO_RAW, pcmEncoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,12 +173,12 @@ public final class WavExtractor implements Extractor {
|
|||||||
throws IOException, InterruptedException;
|
throws IOException, InterruptedException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class PcmOutputWriter implements OutputWriter {
|
private static final class PassthroughOutputWriter implements OutputWriter {
|
||||||
|
|
||||||
private final ExtractorOutput extractorOutput;
|
private final ExtractorOutput extractorOutput;
|
||||||
private final TrackOutput trackOutput;
|
private final TrackOutput trackOutput;
|
||||||
private final WavHeader header;
|
private final WavHeader header;
|
||||||
private final @C.PcmEncoding int pcmEncoding;
|
private final Format format;
|
||||||
/** The target size of each output sample, in bytes. */
|
/** The target size of each output sample, in bytes. */
|
||||||
private final int targetSampleSizeBytes;
|
private final int targetSampleSizeBytes;
|
||||||
|
|
||||||
@ -178,19 +196,33 @@ public final class WavExtractor implements Extractor {
|
|||||||
*/
|
*/
|
||||||
private long outputFrameCount;
|
private long outputFrameCount;
|
||||||
|
|
||||||
public PcmOutputWriter(
|
public PassthroughOutputWriter(
|
||||||
ExtractorOutput extractorOutput,
|
ExtractorOutput extractorOutput,
|
||||||
TrackOutput trackOutput,
|
TrackOutput trackOutput,
|
||||||
WavHeader header,
|
WavHeader header,
|
||||||
|
String mimeType,
|
||||||
@C.PcmEncoding int pcmEncoding) {
|
@C.PcmEncoding int pcmEncoding) {
|
||||||
this.extractorOutput = extractorOutput;
|
this.extractorOutput = extractorOutput;
|
||||||
this.trackOutput = trackOutput;
|
this.trackOutput = trackOutput;
|
||||||
this.header = header;
|
this.header = header;
|
||||||
this.pcmEncoding = pcmEncoding;
|
// Blocks are expected to correspond to single frames. This is validated in init(int, long).
|
||||||
// For PCM blocks correspond to single frames. This is validated in init(int, long).
|
|
||||||
int bytesPerFrame = header.blockSize;
|
int bytesPerFrame = header.blockSize;
|
||||||
targetSampleSizeBytes =
|
targetSampleSizeBytes =
|
||||||
Math.max(bytesPerFrame, header.frameRateHz * bytesPerFrame / TARGET_SAMPLES_PER_SECOND);
|
Math.max(bytesPerFrame, header.frameRateHz * bytesPerFrame / TARGET_SAMPLES_PER_SECOND);
|
||||||
|
format =
|
||||||
|
Format.createAudioSampleFormat(
|
||||||
|
/* id= */ null,
|
||||||
|
mimeType,
|
||||||
|
/* codecs= */ null,
|
||||||
|
/* bitrate= */ header.frameRateHz * bytesPerFrame * 8,
|
||||||
|
/* maxInputSize= */ targetSampleSizeBytes,
|
||||||
|
header.numChannels,
|
||||||
|
header.frameRateHz,
|
||||||
|
pcmEncoding,
|
||||||
|
/* initializationData= */ null,
|
||||||
|
/* drmInitData= */ null,
|
||||||
|
/* selectionFlags= */ 0,
|
||||||
|
/* language= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -209,25 +241,9 @@ public final class WavExtractor implements Extractor {
|
|||||||
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize);
|
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the seek map.
|
// Output the seek map and format.
|
||||||
extractorOutput.seekMap(
|
extractorOutput.seekMap(
|
||||||
new WavSeekMap(header, /* framesPerBlock= */ 1, dataStartPosition, dataEndPosition));
|
new WavSeekMap(header, /* framesPerBlock= */ 1, dataStartPosition, dataEndPosition));
|
||||||
|
|
||||||
// Output the format.
|
|
||||||
Format format =
|
|
||||||
Format.createAudioSampleFormat(
|
|
||||||
/* id= */ null,
|
|
||||||
MimeTypes.AUDIO_RAW,
|
|
||||||
/* codecs= */ null,
|
|
||||||
/* bitrate= */ header.frameRateHz * bytesPerFrame * 8,
|
|
||||||
/* maxInputSize= */ targetSampleSizeBytes,
|
|
||||||
header.numChannels,
|
|
||||||
header.frameRateHz,
|
|
||||||
pcmEncoding,
|
|
||||||
/* initializationData= */ null,
|
|
||||||
/* drmInitData= */ null,
|
|
||||||
/* selectionFlags= */ 0,
|
|
||||||
/* language= */ null);
|
|
||||||
trackOutput.format(format);
|
trackOutput.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1431,8 +1431,6 @@ public final class Util {
|
|||||||
case C.ENCODING_PCM_32BIT:
|
case C.ENCODING_PCM_32BIT:
|
||||||
case C.ENCODING_PCM_FLOAT:
|
case C.ENCODING_PCM_FLOAT:
|
||||||
return channelCount * 4;
|
return channelCount * 4;
|
||||||
case C.ENCODING_PCM_A_LAW:
|
|
||||||
case C.ENCODING_PCM_MU_LAW:
|
|
||||||
case C.ENCODING_INVALID:
|
case C.ENCODING_INVALID:
|
||||||
case Format.NO_VALUE:
|
case Format.NO_VALUE:
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user