mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Added MPEG audio support to TsExtractor v.2
This commit is contained in:
parent
1545a052f0
commit
2ce938d650
2 changed files with 28 additions and 17 deletions
|
|
@ -38,7 +38,6 @@ import java.util.Collections;
|
||||||
private static final int STATE_READING_SAMPLE = 2;
|
private static final int STATE_READING_SAMPLE = 2;
|
||||||
|
|
||||||
private static final int HEADER_SIZE = 4;
|
private static final int HEADER_SIZE = 4;
|
||||||
private static final int SYNCWORD_SIZE = 2;
|
|
||||||
private static final int CRC_SIZE = 2;
|
private static final int CRC_SIZE = 2;
|
||||||
|
|
||||||
private final ParsableBitArray mpaScratch;
|
private final ParsableBitArray mpaScratch;
|
||||||
|
|
@ -172,13 +171,8 @@ import java.util.Collections;
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_HEADER:
|
||||||
int targetLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE;
|
int targetLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE;
|
||||||
if (continueRead(data, mpaScratch.getData(), targetLength)) {
|
if (continueRead(data, mpaScratch.getData(), targetLength)) {
|
||||||
parseHeader();
|
|
||||||
startSample(timeUs);
|
startSample(timeUs);
|
||||||
/**
|
parseHeader();
|
||||||
* Reset buffer after Header data extraction in order to pass full
|
|
||||||
* mpeg audio frame to the mpeg decoder
|
|
||||||
*/
|
|
||||||
data.setPosition(data.getPosition() - targetLength);
|
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
state = STATE_READING_SAMPLE;
|
state = STATE_READING_SAMPLE;
|
||||||
}
|
}
|
||||||
|
|
@ -260,6 +254,7 @@ import java.util.Collections;
|
||||||
* Parses the sample header.
|
* Parses the sample header.
|
||||||
*/
|
*/
|
||||||
private void parseHeader() {
|
private void parseHeader() {
|
||||||
|
int headerLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE;
|
||||||
mpaScratch.setPosition(0);
|
mpaScratch.setPosition(0);
|
||||||
|
|
||||||
if (!hasMediaFormat()) {
|
if (!hasMediaFormat()) {
|
||||||
|
|
@ -270,12 +265,7 @@ import java.util.Collections;
|
||||||
int audioObjectType = 32 + layer;
|
int audioObjectType = 32 + layer;
|
||||||
int bitRate = MPA_BITRATES[isLSF][layer][mpaScratch.readBits(4)];
|
int bitRate = MPA_BITRATES[isLSF][layer][mpaScratch.readBits(4)];
|
||||||
int sampleRate = MPA_SAMPLING_RATES[3 - isLSF][mpaScratch.readBits(2)];
|
int sampleRate = MPA_SAMPLING_RATES[3 - isLSF][mpaScratch.readBits(2)];
|
||||||
int sampleRateIndex = 0;
|
int sampleRateIndex = CodecSpecificDataUtil.getSampleRateIndex(sampleRate);
|
||||||
for (; sampleRateIndex < (CodecSpecificDataUtil.AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE).length; sampleRateIndex++) {
|
|
||||||
if ((CodecSpecificDataUtil.AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE)[sampleRateIndex] == sampleRate) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int paddingBit = (mpaScratch.readBit()) ? 1 : 0;
|
int paddingBit = (mpaScratch.readBit()) ? 1 : 0;
|
||||||
mpaScratch.skipBits(1);
|
mpaScratch.skipBits(1);
|
||||||
int channelConfig = mpaScratch.readBits(2) == 3 ? 1 : 2;
|
int channelConfig = mpaScratch.readBits(2) == 3 ? 1 : 2;
|
||||||
|
|
@ -291,7 +281,12 @@ import java.util.Collections;
|
||||||
Collections.singletonList(audioSpecificConfig));
|
Collections.singletonList(audioSpecificConfig));
|
||||||
frameDurationUs = (C.MICROS_PER_SECOND * MPA_SAMPLES_PER_FRAME[isLSF][layer]) / mediaFormat.sampleRate;
|
frameDurationUs = (C.MICROS_PER_SECOND * MPA_SAMPLES_PER_FRAME[isLSF][layer]) / mediaFormat.sampleRate;
|
||||||
setMediaFormat(mediaFormat);
|
setMediaFormat(mediaFormat);
|
||||||
sampleSize = CalcMpaFrameSize(layer, isLSF, bitRate * 1000, sampleRate, paddingBit);
|
sampleSize = CalcMpaFrameSize(layer, isLSF, bitRate * 1000, sampleRate, paddingBit) - headerLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mpaScratch.setPosition(0);
|
||||||
|
|
||||||
|
ParsableByteArray header = new ParsableByteArray(mpaScratch.getData(),headerLength);
|
||||||
|
appendData(header, headerLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,11 @@ public final class CodecSpecificDataUtil {
|
||||||
|
|
||||||
private static final byte[] NAL_START_CODE = new byte[] {0, 0, 0, 1};
|
private static final byte[] NAL_START_CODE = new byte[] {0, 0, 0, 1};
|
||||||
|
|
||||||
public static final int[] AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE = new int[] {
|
private static final int[] AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE = new int[] {
|
||||||
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
|
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final int[] AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE = new int[] {
|
private static final int[] AUDIO_SPECIFIC_CONFIG_CHANNEL_COUNT_TABLE = new int[] {
|
||||||
0, 1, 2, 3, 4, 5, 6, 8
|
0, 1, 2, 3, 4, 5, 6, 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,6 +41,22 @@ public final class CodecSpecificDataUtil {
|
||||||
|
|
||||||
private CodecSpecificDataUtil() {}
|
private CodecSpecificDataUtil() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sample rate index.
|
||||||
|
*
|
||||||
|
* @param sampleRate The sample rate in Hz.
|
||||||
|
* @return The sample rate index.
|
||||||
|
*/
|
||||||
|
public static int getSampleRateIndex(int sampleRate) {
|
||||||
|
int sampleRateIndex = 0;
|
||||||
|
for (; sampleRateIndex < AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE.length; sampleRateIndex++) {
|
||||||
|
if (AUDIO_SPECIFIC_CONFIG_SAMPLING_RATE_TABLE[sampleRateIndex] == sampleRate) {
|
||||||
|
return sampleRateIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
|
* Parses an AudioSpecificConfig, as defined in ISO 14496-3 1.6.2.1
|
||||||
*
|
*
|
||||||
|
|
@ -49,7 +65,7 @@ public final class CodecSpecificDataUtil {
|
||||||
*/
|
*/
|
||||||
public static Pair<Integer, Integer> parseAudioSpecificConfig(byte[] audioSpecificConfig) {
|
public static Pair<Integer, Integer> parseAudioSpecificConfig(byte[] audioSpecificConfig) {
|
||||||
int audioObjectType = (audioSpecificConfig[0] >> 3) & 0x1F;
|
int audioObjectType = (audioSpecificConfig[0] >> 3) & 0x1F;
|
||||||
if (audioObjectType != 31) {
|
if (audioObjectType < 31) {
|
||||||
int byteOffset = audioObjectType == 5 || audioObjectType == 29 ? 1 : 0;
|
int byteOffset = audioObjectType == 5 || audioObjectType == 29 ? 1 : 0;
|
||||||
int frequencyIndex = (audioSpecificConfig[byteOffset] & 0x7) << 1 |
|
int frequencyIndex = (audioSpecificConfig[byteOffset] & 0x7) << 1 |
|
||||||
((audioSpecificConfig[byteOffset + 1] >> 7) & 0x1);
|
((audioSpecificConfig[byteOffset + 1] >> 7) & 0x1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue