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:
Jean-Yves Avenard 2016-04-14 23:32:40 +10:00
Родитель 6c9ed7d3ec
Коммит c2567cb4bd
2 изменённых файлов: 234 добавлений и 39 удалений

Просмотреть файл

@ -137,6 +137,7 @@ enum {
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
kKeyIsADTS = 'adts', // bool (int32_t)
kKeyAACAOT = 'aaot', // int32_t
// If a MediaBuffer's data represents (at least partially) encrypted
// data, the following fields aid in decryption.

Просмотреть файл

@ -2462,6 +2462,58 @@ status_t MPEG4Extractor::verifyTrack(Track *track) {
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(
const void *esds_data, size_t esds_size) {
ESDS esds(esds_data, esds_size);
@ -2473,9 +2525,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
if (objectTypeIndication == 0xe1) {
// This isn't MPEG4 audio at all, it's QCELP 14k...
if (!mLastTrack) {
return ERROR_MALFORMED;
}
if (mLastTrack == NULL)
return ERROR_MALFORMED;
mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
return OK;
}
@ -2496,8 +2548,10 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
}
#if 0
printf("ESD of size %d\n", csd_size);
hexdump(csd, csd_size);
if (kUseHexDump) {
printf("ESD of size %zu\n", csd_size);
hexdump(csd, csd_size);
}
#endif
if (csd_size == 0) {
@ -2512,6 +2566,11 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
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);
if (br.numBitsLeft() < 5) {
return ERROR_MALFORMED;
@ -2525,13 +2584,16 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
objectType = 32 + br.getBits(6);
}
if (mLastTrack == NULL)
return ERROR_MALFORMED;
if (objectType >= 1 && objectType <= 4) {
if (!mLastTrack) {
return ERROR_MALFORMED;
}
mLastTrack->meta->setInt32(kKeyAACProfile, objectType);
}
//keep AOT type
mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
if (br.numBitsLeft() < 4) {
return ERROR_MALFORMED;
}
@ -2540,47 +2602,179 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
int32_t sampleRate = 0;
int32_t numChannels = 0;
if (freqIndex == 15) {
if (csd_size < 5) {
return ERROR_MALFORMED;
}
if (br.numBitsLeft() < 24 + 4) {
return ERROR_MALFORMED;
}
if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
sampleRate = br.getBits(24);
numChannels = br.getBits(4);
} else {
if (br.numBitsLeft() < 4) {
if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
numChannels = br.getBits(4);
if (freqIndex == 13 || freqIndex == 14) {
return ERROR_MALFORMED;
}
numChannels = br.getBits(4);
if (objectType == 5) {
// SBR specific config per 14496-3 table 1.13
if (br.numBitsLeft() < 4) {
sampleRate = kSamplingRate[freqIndex];
}
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;
}
freqIndex = br.getBits(4);
if (freqIndex == 15) {
if (csd_size < 8) {
return ERROR_MALFORMED;
}
if (br.numBitsLeft() < 24) {
return ERROR_MALFORMED;
}
sampleRate = br.getBits(24);
if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
extSampleRate = br.getBits(24);
} else {
if (extFreqIndex == 13 || extFreqIndex == 14) {
return ERROR_MALFORMED;
}
extSampleRate = kSamplingRate[extFreqIndex];
}
//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) {
static uint32_t kSamplingRate[] = {
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000, 7350
};
const int32_t dependsOnCoreCoder = br.getBits(1);
if (freqIndex == 13 || freqIndex == 14) {
return ERROR_MALFORMED;
if (dependsOnCoreCoder ) {
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;
}
if (!mLastTrack) {
return ERROR_MALFORMED;
}
if (mLastTrack == NULL)
return ERROR_MALFORMED;
int32_t prevSampleRate;
CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));