mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Added support for PCM u/a-law audio in FLV containers
This commit is contained in:
parent
d79f8f64de
commit
4f2cced4da
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.extractor.flv;
|
package com.google.android.exoplayer2.extractor.flv;
|
||||||
|
|
||||||
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioTrack;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
@ -30,6 +32,8 @@ import java.util.Collections;
|
|||||||
/* package */ final class AudioTagPayloadReader extends TagPayloadReader {
|
/* package */ final class AudioTagPayloadReader extends TagPayloadReader {
|
||||||
|
|
||||||
// Audio format
|
// Audio format
|
||||||
|
private static final int AUDIO_FORMAT_ALAW = 7;
|
||||||
|
private static final int AUDIO_FORMAT_ULAW = 8;
|
||||||
private static final int AUDIO_FORMAT_AAC = 10;
|
private static final int AUDIO_FORMAT_AAC = 10;
|
||||||
|
|
||||||
// AAC PACKET TYPE
|
// AAC PACKET TYPE
|
||||||
@ -44,6 +48,7 @@ import java.util.Collections;
|
|||||||
// State variables
|
// State variables
|
||||||
private boolean hasParsedAudioDataHeader;
|
private boolean hasParsedAudioDataHeader;
|
||||||
private boolean hasOutputFormat;
|
private boolean hasOutputFormat;
|
||||||
|
private int audioFormat;
|
||||||
|
|
||||||
public AudioTagPayloadReader(TrackOutput output) {
|
public AudioTagPayloadReader(TrackOutput output) {
|
||||||
super(output);
|
super(output);
|
||||||
@ -58,15 +63,26 @@ import java.util.Collections;
|
|||||||
protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException {
|
protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException {
|
||||||
if (!hasParsedAudioDataHeader) {
|
if (!hasParsedAudioDataHeader) {
|
||||||
int header = data.readUnsignedByte();
|
int header = data.readUnsignedByte();
|
||||||
int audioFormat = (header >> 4) & 0x0F;
|
audioFormat = (header >> 4) & 0x0F;
|
||||||
int sampleRateIndex = (header >> 2) & 0x03;
|
int sampleRateIndex = (header >> 2) & 0x03;
|
||||||
|
int encodingSize = header & 0x01;
|
||||||
if (sampleRateIndex < 0 || sampleRateIndex >= AUDIO_SAMPLING_RATE_TABLE.length) {
|
if (sampleRateIndex < 0 || sampleRateIndex >= AUDIO_SAMPLING_RATE_TABLE.length) {
|
||||||
throw new UnsupportedFormatException("Invalid sample rate index: " + sampleRateIndex);
|
throw new UnsupportedFormatException("Invalid sample rate index: " + sampleRateIndex);
|
||||||
}
|
}
|
||||||
// TODO: Add support for MP3 and PCM.
|
// TODO: Add support for MP3.
|
||||||
if (audioFormat != AUDIO_FORMAT_AAC) {
|
if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) {
|
||||||
throw new UnsupportedFormatException("Audio format not supported: " + audioFormat);
|
|
||||||
|
String type = (audioFormat == AUDIO_FORMAT_ALAW) ? MimeTypes.AUDIO_ALAW : MimeTypes.AUDIO_ULAW;
|
||||||
|
int encoding = (encodingSize == 1) ? C.ENCODING_PCM_16BIT : C.ENCODING_PCM_8BIT;
|
||||||
|
Format format = Format.createAudioSampleFormat(null, type, null, Format.NO_VALUE, Format.NO_VALUE,
|
||||||
|
1, 8000, encoding, null, null, 0, null);
|
||||||
|
output.format(format);
|
||||||
|
|
||||||
|
hasOutputFormat = true;
|
||||||
|
} else if (audioFormat != AUDIO_FORMAT_AAC ) {
|
||||||
|
throw new UnsupportedFormatException("Audio format not supported: " + audioFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasParsedAudioDataHeader = true;
|
hasParsedAudioDataHeader = true;
|
||||||
} else {
|
} else {
|
||||||
// Skip header if it was parsed previously.
|
// Skip header if it was parsed previously.
|
||||||
@ -78,8 +94,9 @@ import java.util.Collections;
|
|||||||
@Override
|
@Override
|
||||||
protected void parsePayload(ParsableByteArray data, long timeUs) {
|
protected void parsePayload(ParsableByteArray data, long timeUs) {
|
||||||
int packetType = data.readUnsignedByte();
|
int packetType = data.readUnsignedByte();
|
||||||
// Parse sequence header just in case it was not done before.
|
|
||||||
if (packetType == AAC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
|
if (packetType == AAC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
|
||||||
|
// Parse sequence header just in case it was not done before.
|
||||||
byte[] audioSpecifiConfig = new byte[data.bytesLeft()];
|
byte[] audioSpecifiConfig = new byte[data.bytesLeft()];
|
||||||
data.readBytes(audioSpecifiConfig, 0, audioSpecifiConfig.length);
|
data.readBytes(audioSpecifiConfig, 0, audioSpecifiConfig.length);
|
||||||
Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
|
Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
|
||||||
@ -89,12 +106,10 @@ import java.util.Collections;
|
|||||||
Collections.singletonList(audioSpecifiConfig), null, 0, null);
|
Collections.singletonList(audioSpecifiConfig), null, 0, null);
|
||||||
output.format(format);
|
output.format(format);
|
||||||
hasOutputFormat = true;
|
hasOutputFormat = true;
|
||||||
} else if (packetType == AAC_PACKET_TYPE_AAC_RAW) {
|
} else if (audioFormat != AUDIO_FORMAT_AAC || packetType == AAC_PACKET_TYPE_AAC_RAW) {
|
||||||
// Sample audio AAC frames
|
int bytes = data.bytesLeft();
|
||||||
int bytesToWrite = data.bytesLeft();
|
output.sampleData(data, bytes);
|
||||||
output.sampleData(data, bytesToWrite);
|
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, bytes, 0, null);
|
||||||
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, bytesToWrite, 0, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,8 @@ public final class MimeTypes {
|
|||||||
public static final String AUDIO_MPEG_L1 = BASE_TYPE_AUDIO + "/mpeg-L1";
|
public static final String AUDIO_MPEG_L1 = BASE_TYPE_AUDIO + "/mpeg-L1";
|
||||||
public static final String AUDIO_MPEG_L2 = BASE_TYPE_AUDIO + "/mpeg-L2";
|
public static final String AUDIO_MPEG_L2 = BASE_TYPE_AUDIO + "/mpeg-L2";
|
||||||
public static final String AUDIO_RAW = BASE_TYPE_AUDIO + "/raw";
|
public static final String AUDIO_RAW = BASE_TYPE_AUDIO + "/raw";
|
||||||
|
public static final String AUDIO_ALAW = BASE_TYPE_AUDIO + "/g711-alaw";
|
||||||
|
public static final String AUDIO_ULAW = BASE_TYPE_AUDIO + "/g711-mlaw";
|
||||||
public static final String AUDIO_AC3 = BASE_TYPE_AUDIO + "/ac3";
|
public static final String AUDIO_AC3 = BASE_TYPE_AUDIO + "/ac3";
|
||||||
public static final String AUDIO_E_AC3 = BASE_TYPE_AUDIO + "/eac3";
|
public static final String AUDIO_E_AC3 = BASE_TYPE_AUDIO + "/eac3";
|
||||||
public static final String AUDIO_TRUEHD = BASE_TYPE_AUDIO + "/true-hd";
|
public static final String AUDIO_TRUEHD = BASE_TYPE_AUDIO + "/true-hd";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user