зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1264622: [MP4] Resync stagefright's updateAudioTrackInfoFromESDS_MPEG4Audio with upstream. r=kentuckyfriedtakahe
This adds support for parsing AOT audio specific config (which contains extended channels layout). MozReview-Commit-ID: 7yNGBEAI7sv --HG-- extra : rebase_source : 6f29c04f1f29785ba097d64df13794f80672fb50
This commit is contained in:
Родитель
6c9ed7d3ec
Коммит
c2567cb4bd
|
@ -137,6 +137,7 @@ enum {
|
||||||
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
|
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
|
||||||
|
|
||||||
kKeyIsADTS = 'adts', // bool (int32_t)
|
kKeyIsADTS = 'adts', // bool (int32_t)
|
||||||
|
kKeyAACAOT = 'aaot', // int32_t
|
||||||
|
|
||||||
// If a MediaBuffer's data represents (at least partially) encrypted
|
// If a MediaBuffer's data represents (at least partially) encrypted
|
||||||
// data, the following fields aid in decryption.
|
// data, the following fields aid in decryption.
|
||||||
|
|
|
@ -2462,6 +2462,58 @@ status_t MPEG4Extractor::verifyTrack(Track *track) {
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
//AOT_NONE = -1,
|
||||||
|
//AOT_NULL_OBJECT = 0,
|
||||||
|
//AOT_AAC_MAIN = 1, /**< Main profile */
|
||||||
|
AOT_AAC_LC = 2, /**< Low Complexity object */
|
||||||
|
//AOT_AAC_SSR = 3,
|
||||||
|
//AOT_AAC_LTP = 4,
|
||||||
|
AOT_SBR = 5,
|
||||||
|
//AOT_AAC_SCAL = 6,
|
||||||
|
//AOT_TWIN_VQ = 7,
|
||||||
|
//AOT_CELP = 8,
|
||||||
|
//AOT_HVXC = 9,
|
||||||
|
//AOT_RSVD_10 = 10, /**< (reserved) */
|
||||||
|
//AOT_RSVD_11 = 11, /**< (reserved) */
|
||||||
|
//AOT_TTSI = 12, /**< TTSI Object */
|
||||||
|
//AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */
|
||||||
|
//AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */
|
||||||
|
//AOT_GEN_MIDI = 15, /**< General MIDI object */
|
||||||
|
//AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
|
||||||
|
AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */
|
||||||
|
//AOT_RSVD_18 = 18, /**< (reserved) */
|
||||||
|
//AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */
|
||||||
|
AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */
|
||||||
|
//AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */
|
||||||
|
AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */
|
||||||
|
AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */
|
||||||
|
//AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */
|
||||||
|
//AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */
|
||||||
|
//AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */
|
||||||
|
//AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */
|
||||||
|
//AOT_RSVD_28 = 28, /**< might become SSC */
|
||||||
|
AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */
|
||||||
|
//AOT_MPEGS = 30, /**< MPEG Surround */
|
||||||
|
|
||||||
|
AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */
|
||||||
|
|
||||||
|
//AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */
|
||||||
|
//AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */
|
||||||
|
//AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */
|
||||||
|
//AOT_RSVD_35 = 35, /**< might become DST */
|
||||||
|
//AOT_RSVD_36 = 36, /**< might become ALS */
|
||||||
|
//AOT_AAC_SLS = 37, /**< AAC + SLS */
|
||||||
|
//AOT_SLS = 38, /**< SLS */
|
||||||
|
//AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */
|
||||||
|
|
||||||
|
//AOT_USAC = 42, /**< USAC */
|
||||||
|
//AOT_SAOC = 43, /**< SAOC */
|
||||||
|
//AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
|
||||||
|
|
||||||
|
//AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
|
||||||
|
} AUDIO_OBJECT_TYPE;
|
||||||
|
|
||||||
status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
const void *esds_data, size_t esds_size) {
|
const void *esds_data, size_t esds_size) {
|
||||||
ESDS esds(esds_data, esds_size);
|
ESDS esds(esds_data, esds_size);
|
||||||
|
@ -2473,9 +2525,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
|
|
||||||
if (objectTypeIndication == 0xe1) {
|
if (objectTypeIndication == 0xe1) {
|
||||||
// This isn't MPEG4 audio at all, it's QCELP 14k...
|
// This isn't MPEG4 audio at all, it's QCELP 14k...
|
||||||
if (!mLastTrack) {
|
if (mLastTrack == NULL)
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
|
||||||
mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
|
mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -2496,8 +2548,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("ESD of size %d\n", csd_size);
|
if (kUseHexDump) {
|
||||||
hexdump(csd, csd_size);
|
printf("ESD of size %zu\n", csd_size);
|
||||||
|
hexdump(csd, csd_size);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (csd_size == 0) {
|
if (csd_size == 0) {
|
||||||
|
@ -2512,6 +2566,11 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t kSamplingRate[] = {
|
||||||
|
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
|
||||||
|
16000, 12000, 11025, 8000, 7350
|
||||||
|
};
|
||||||
|
|
||||||
ABitReader br(csd, csd_size);
|
ABitReader br(csd, csd_size);
|
||||||
if (br.numBitsLeft() < 5) {
|
if (br.numBitsLeft() < 5) {
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
|
@ -2525,13 +2584,16 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
objectType = 32 + br.getBits(6);
|
objectType = 32 + br.getBits(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mLastTrack == NULL)
|
||||||
|
return ERROR_MALFORMED;
|
||||||
|
|
||||||
if (objectType >= 1 && objectType <= 4) {
|
if (objectType >= 1 && objectType <= 4) {
|
||||||
if (!mLastTrack) {
|
|
||||||
return ERROR_MALFORMED;
|
|
||||||
}
|
|
||||||
mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
|
mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//keep AOT type
|
||||||
|
mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
|
||||||
|
|
||||||
if (br.numBitsLeft() < 4) {
|
if (br.numBitsLeft() < 4) {
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
}
|
||||||
|
@ -2540,47 +2602,179 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
int32_t sampleRate = 0;
|
int32_t sampleRate = 0;
|
||||||
int32_t numChannels = 0;
|
int32_t numChannels = 0;
|
||||||
if (freqIndex == 15) {
|
if (freqIndex == 15) {
|
||||||
if (csd_size < 5) {
|
if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
|
||||||
return ERROR_MALFORMED;
|
|
||||||
}
|
|
||||||
if (br.numBitsLeft() < 24 + 4) {
|
|
||||||
return ERROR_MALFORMED;
|
|
||||||
}
|
|
||||||
sampleRate = br.getBits(24);
|
sampleRate = br.getBits(24);
|
||||||
numChannels = br.getBits(4);
|
numChannels = br.getBits(4);
|
||||||
} else {
|
} else {
|
||||||
if (br.numBitsLeft() < 4) {
|
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
|
||||||
|
numChannels = br.getBits(4);
|
||||||
|
|
||||||
|
if (freqIndex == 13 || freqIndex == 14) {
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
}
|
||||||
numChannels = br.getBits(4);
|
|
||||||
if (objectType == 5) {
|
sampleRate = kSamplingRate[freqIndex];
|
||||||
// SBR specific config per 14496-3 table 1.13
|
}
|
||||||
if (br.numBitsLeft() < 4) {
|
|
||||||
|
if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 table 1.13
|
||||||
|
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
|
||||||
|
uint32_t extFreqIndex = br.getBits(4);
|
||||||
|
int32_t extSampleRate;
|
||||||
|
if (extFreqIndex == 15) {
|
||||||
|
if (csd_size < 8) {
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
}
|
||||||
freqIndex = br.getBits(4);
|
if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
|
||||||
if (freqIndex == 15) {
|
extSampleRate = br.getBits(24);
|
||||||
if (csd_size < 8) {
|
} else {
|
||||||
return ERROR_MALFORMED;
|
if (extFreqIndex == 13 || extFreqIndex == 14) {
|
||||||
}
|
return ERROR_MALFORMED;
|
||||||
if (br.numBitsLeft() < 24) {
|
}
|
||||||
return ERROR_MALFORMED;
|
extSampleRate = kSamplingRate[extFreqIndex];
|
||||||
}
|
}
|
||||||
sampleRate = br.getBits(24);
|
//TODO: save the extension sampling rate value in meta data =>
|
||||||
|
// mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (numChannels) {
|
||||||
|
// values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
|
||||||
|
case 0:
|
||||||
|
case 1:// FC
|
||||||
|
case 2:// FL FR
|
||||||
|
case 3:// FC, FL FR
|
||||||
|
case 4:// FC, FL FR, RC
|
||||||
|
case 5:// FC, FL FR, SL SR
|
||||||
|
case 6:// FC, FL FR, SL SR, LFE
|
||||||
|
//numChannels already contains the right value
|
||||||
|
break;
|
||||||
|
case 11:// FC, FL FR, SL SR, RC, LFE
|
||||||
|
numChannels = 7;
|
||||||
|
break;
|
||||||
|
case 7: // FC, FCL FCR, FL FR, SL SR, LFE
|
||||||
|
case 12:// FC, FL FR, SL SR, RL RR, LFE
|
||||||
|
case 14:// FC, FL FR, SL SR, LFE, FHL FHR
|
||||||
|
numChannels = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (objectType == AOT_SBR || objectType == AOT_PS) {
|
||||||
|
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
|
||||||
|
objectType = br.getBits(5);
|
||||||
|
|
||||||
|
if (objectType == AOT_ESCAPE) {
|
||||||
|
if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
|
||||||
|
objectType = 32 + br.getBits(6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
|
||||||
|
objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
|
||||||
|
objectType == AOT_ER_BSAC) {
|
||||||
|
if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
|
||||||
|
const int32_t frameLengthFlag = br.getBits(1);
|
||||||
|
|
||||||
if (sampleRate == 0) {
|
const int32_t dependsOnCoreCoder = br.getBits(1);
|
||||||
static uint32_t kSamplingRate[] = {
|
|
||||||
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
|
|
||||||
16000, 12000, 11025, 8000, 7350
|
|
||||||
};
|
|
||||||
|
|
||||||
if (freqIndex == 13 || freqIndex == 14) {
|
if (dependsOnCoreCoder ) {
|
||||||
return ERROR_MALFORMED;
|
if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
|
||||||
|
const int32_t coreCoderDelay = br.getBits(14);
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleRate = kSamplingRate[freqIndex];
|
int32_t extensionFlag = -1;
|
||||||
|
if (br.numBitsLeft() > 0) {
|
||||||
|
extensionFlag = br.getBits(1);
|
||||||
|
} else {
|
||||||
|
switch (objectType) {
|
||||||
|
// 14496-3 4.5.1.1 extensionFlag
|
||||||
|
case AOT_AAC_LC:
|
||||||
|
extensionFlag = 0;
|
||||||
|
break;
|
||||||
|
case AOT_ER_AAC_LC:
|
||||||
|
case AOT_ER_AAC_SCAL:
|
||||||
|
case AOT_ER_BSAC:
|
||||||
|
case AOT_ER_AAC_LD:
|
||||||
|
extensionFlag = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ERROR_MALFORMED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ALOGW("csd missing extension flag; assuming %d for object type %u.",
|
||||||
|
extensionFlag, objectType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numChannels == 0) {
|
||||||
|
int32_t channelsEffectiveNum = 0;
|
||||||
|
int32_t channelsNum = 0;
|
||||||
|
if (br.numBitsLeft() < 32) {
|
||||||
|
return ERROR_MALFORMED;
|
||||||
|
}
|
||||||
|
const int32_t ElementInstanceTag = br.getBits(4);
|
||||||
|
const int32_t Profile = br.getBits(2);
|
||||||
|
const int32_t SamplingFrequencyIndex = br.getBits(4);
|
||||||
|
const int32_t NumFrontChannelElements = br.getBits(4);
|
||||||
|
const int32_t NumSideChannelElements = br.getBits(4);
|
||||||
|
const int32_t NumBackChannelElements = br.getBits(4);
|
||||||
|
const int32_t NumLfeChannelElements = br.getBits(2);
|
||||||
|
const int32_t NumAssocDataElements = br.getBits(3);
|
||||||
|
const int32_t NumValidCcElements = br.getBits(4);
|
||||||
|
|
||||||
|
const int32_t MonoMixdownPresent = br.getBits(1);
|
||||||
|
|
||||||
|
if (MonoMixdownPresent != 0) {
|
||||||
|
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
|
||||||
|
const int32_t MonoMixdownElementNumber = br.getBits(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
|
||||||
|
const int32_t StereoMixdownPresent = br.getBits(1);
|
||||||
|
if (StereoMixdownPresent != 0) {
|
||||||
|
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
|
||||||
|
const int32_t StereoMixdownElementNumber = br.getBits(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
|
||||||
|
const int32_t MatrixMixdownIndexPresent = br.getBits(1);
|
||||||
|
if (MatrixMixdownIndexPresent != 0) {
|
||||||
|
if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
|
||||||
|
const int32_t MatrixMixdownIndex = br.getBits(2);
|
||||||
|
const int32_t PseudoSurroundEnable = br.getBits(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i=0; i < NumFrontChannelElements; i++) {
|
||||||
|
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
|
||||||
|
const int32_t FrontElementIsCpe = br.getBits(1);
|
||||||
|
const int32_t FrontElementTagSelect = br.getBits(4);
|
||||||
|
channelsNum += FrontElementIsCpe ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < NumSideChannelElements; i++) {
|
||||||
|
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
|
||||||
|
const int32_t SideElementIsCpe = br.getBits(1);
|
||||||
|
const int32_t SideElementTagSelect = br.getBits(4);
|
||||||
|
channelsNum += SideElementIsCpe ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < NumBackChannelElements; i++) {
|
||||||
|
if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
|
||||||
|
const int32_t BackElementIsCpe = br.getBits(1);
|
||||||
|
const int32_t BackElementTagSelect = br.getBits(4);
|
||||||
|
channelsNum += BackElementIsCpe ? 2 : 1;
|
||||||
|
}
|
||||||
|
channelsEffectiveNum = channelsNum;
|
||||||
|
|
||||||
|
for (i=0; i < NumLfeChannelElements; i++) {
|
||||||
|
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
|
||||||
|
const int32_t LfeElementTagSelect = br.getBits(4);
|
||||||
|
channelsNum += 1;
|
||||||
|
}
|
||||||
|
ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
|
||||||
|
ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
|
||||||
|
numChannels = channelsNum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2588,9 +2782,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
|
||||||
return ERROR_UNSUPPORTED;
|
return ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mLastTrack) {
|
if (mLastTrack == NULL)
|
||||||
return ERROR_MALFORMED;
|
return ERROR_MALFORMED;
|
||||||
}
|
|
||||||
int32_t prevSampleRate;
|
int32_t prevSampleRate;
|
||||||
CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
|
CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче