blob: 75ff66c861501d5d1dada3b7144ada0b0370ec9b [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#include "pv_audio_config_parser.h"
#include "oscl_mem.h"
#include "getactualaacconfig.h"
#include "oscl_dll.h"
//Macros for WMA
#define GetUnalignedWord( pb, w ) \
(w) = ((uint16) *(pb + 1) << 8) + *pb;
#define GetUnalignedDword( pb, dw ) \
(dw) = ((uint32) *(pb + 3) << 24) + \
((uint32) *(pb + 2) << 16) + \
((uint16) *(pb + 1) << 8) + *pb;
#define GetUnalignedWordEx( pb, w ) GetUnalignedWord( pb, w ); (pb) += sizeof(uint16);
#define GetUnalignedDwordEx( pb, dw ) GetUnalignedDword( pb, dw ); (pb) += sizeof(uint32);
#define LoadWORD( w, p ) GetUnalignedWordEx( p, w )
#define LoadDWORD( dw, p ) GetUnalignedDwordEx( p, dw )
#define WAVE_FORMAT_MSAUDIO1 0x0160
#define WAVE_FORMAT_WMAUDIO2 0x0161
#define WAVE_FORMAT_WMAUDIO3 0x0162
#define WAVE_FORMAT_WMAUDIO_LOSSLESS 0x0163
#define WAVE_FORMAT_WMAUDIO2_ES 0x0165
#define WAVE_FORMAT_WMASPDIF 0x164
#define WAVE_FORMAT_WMAUDIO3_ES 0x0166
#define WAVE_FORMAT_WMAUDIO_LOSSLESS_ES 0x0167
#define WAVE_FORMAT_MSSPEECH 10
//AdvancedEncodeOpt
#define ENCOPT4_PLUSVER 0xe000
#define ENCOPT4_PLUSV1 0xc000
#define ENCOPT4_PLUSV1ALT 0x8000
#define ENCOPT4_PLUSV2 0x2000
#define ENCOPT4_PLUSV3 0x4000
//The following is from \codecs_v2\wma\dec\src\macros.h
//-------------------------------------------------------------------------------------
//If no build is defined in the pre-processor definitions, then code for all supported wma formats will be included
#if !defined(BUILD_WMASTD) && !defined(BUILD_WMAPRO) && !defined(BUILD_WMALSL) && !defined(BUILD_WMAPROPLUS)
#define BUILD_WMASTD
#define BUILD_WMAPRO
#define BUILD_WMAPROPLUS
//#define BUILD_WMAPRO_PLLM
//#define BUILD_WMALSL
#endif // !BUILD_WMASTD && !BUILD_WMAPRO && !BUILD_WMAPROPLUS && !BUILD_WMALSL
#if defined(BUILD_WMAPROPLUS) && !defined(BUILD_WMAPRO)
#define BUILD_WMAPRO
#endif
#if defined(BUILD_WMAPRO) && !defined(BUILD_WMAPROPLUS)
#define BUILD_WMAPROPLUS
#endif
//-------------------------------------------------------------------------------------
OSCL_DLL_ENTRY_POINT_DEFAULT()
// This routine parses the wma config header and returns Sampling Rate, Number of Channels, and Bits Per Sample
OSCL_EXPORT_REF int32 pv_audio_config_parser(pvAudioConfigParserInputs *aInputs, pvAudioConfigParserOutputs *aOutputs)
{
bool bBitStreamValid = true;
bool bBitStreamSupported = true;
if (aInputs->iMimeType == PVMF_MIME_WMA)
{
uint16 wdata;
uint32 dwdata;
uint32 AvgBytesPerSec;
uint16 AdvancedEncodeOpt;
/**** decoder header *******/
uint8* tp = aInputs->inPtr;
LoadWORD(wdata , tp);
switch (wdata)
{
// WMA Lossless
case WAVE_FORMAT_WMAUDIO_LOSSLESS:
{
if (aInputs->inBytes < 36)
{
bBitStreamValid = false;
break;
}
LoadWORD(wdata, tp);
aOutputs->Channels = wdata;
LoadDWORD(dwdata, tp);
aOutputs->SamplesPerSec = dwdata;
LoadDWORD(dwdata, tp);
AvgBytesPerSec = dwdata;
tp = aInputs->inPtr + 14;
LoadWORD(wdata , tp);
// Round up to the byte to get the container size
aOutputs->BitsPerSample = 8 * ((wdata + 7) / 8);
// Has V3 specific info
tp = aInputs->inPtr + 34;
LoadWORD(wdata , tp);
AdvancedEncodeOpt = wdata;
#if !defined(BUILD_WMALSL)
bBitStreamSupported = false;
#endif // BUILD_WMALSL
// more limits according to the current PV WMA implementation
// do not supoprt multi-channel
if (aOutputs->Channels > 2)
{
bBitStreamSupported = false;
break;
}
// do not support 24-bit
if (aOutputs->BitsPerSample > 16)
{
bBitStreamSupported = false;
break;
}
}
break;
// WMA Pro, Pro+
case WAVE_FORMAT_WMAUDIO3:
{
if (aInputs->inBytes < 36)
{
bBitStreamValid = false;
break;
}
LoadWORD(wdata, tp);
aOutputs->Channels = wdata;
LoadDWORD(dwdata, tp);
aOutputs->SamplesPerSec = dwdata;
LoadDWORD(dwdata, tp);
AvgBytesPerSec = dwdata;
tp = aInputs->inPtr + 14;
LoadWORD(wdata , tp); //iValidBitsPerSample
// Round up to the byte to get the container size
aOutputs->BitsPerSample = 8 * ((wdata + 7) / 8);
// Has V3 specific info
tp = aInputs->inPtr + 34;
LoadWORD(wdata , tp);
AdvancedEncodeOpt = wdata;
#if !defined(BUILD_WMAPRO)
bBitStreamSupported = false;
break;
#endif // BUILD_WMAPRO
#if !defined(BUILD_WMAPROPLUS)
if (0 != (AdvancedEncodeOpt & ENCOPT4_PLUSVER))
{
bBitStreamSupported = false;
break;
}
#endif // BUILD_WMAPROPLUS
// more limits according to the current PV WMA implementation
// do not supoprt multi-channel
if (aOutputs->Channels > 2)
{
bBitStreamSupported = false;
break;
}
// do not support 24-bit
if (aOutputs->BitsPerSample > 16)
{
bBitStreamSupported = false;
break;
}
#if defined(WMAPLUS_64KBPS_PROFILE_ONLY)
// limit to M0-profile bitrate and sampling rate
if (AvgBytesPerSec > 192000 || aOutputs->SamplesPerSec > 48000)
{
bBitStreamSupported = false;
break;
}
// only decode PLUSV1 (not including PLUSV1ALT)
if (ENCOPT4_PLUSV1 != (AdvancedEncodeOpt & ENCOPT4_PLUSVER))
{
bBitStreamSupported = false;
break;
}
#endif // WMAPLUS_64KBPS_PROFILE_ONLY
}
break;
//WMA Standard
case WAVE_FORMAT_WMAUDIO2:
{
if (aInputs->inBytes < 28)
{
bBitStreamValid = false;
break;
}
LoadWORD(wdata, tp);
aOutputs->Channels = wdata;
LoadDWORD(dwdata, tp);
aOutputs->SamplesPerSec = dwdata;
tp = aInputs->inPtr + 14;
LoadWORD(wdata , tp);
aOutputs->BitsPerSample = wdata;
if (aOutputs->SamplesPerSec > 48000)
{
// not a valid sample rate for WMA Std spec
bBitStreamValid = false;
break;
}
if (aOutputs->Channels > 2)
{
// not a valid number of channels for the WMA Std spec
bBitStreamValid = false;
break;
}
if (aOutputs->BitsPerSample != 16)
{
// not a valid number of bits per sample for the WMA Std spec
bBitStreamValid = false;
break;
}
#if !defined(BUILD_WMASTD)
bBitStreamSupported = false;
#endif // BUILD_WMASTD
}
break;
//WMA Standard (bitstream v1)
case WAVE_FORMAT_MSAUDIO1:
{
if (aInputs->inBytes < 22)
{
bBitStreamValid = false;
break;
}
tp = aInputs->inPtr + 4;
LoadDWORD(dwdata, tp);
aOutputs->SamplesPerSec = dwdata;
tp = aInputs->inPtr + 2;
LoadWORD(wdata , tp);
aOutputs->Channels = wdata;
tp = aInputs->inPtr + 14;
LoadWORD(wdata , tp);
aOutputs->BitsPerSample = wdata;
if (aOutputs->SamplesPerSec > 48000)
{
// not a valid sample rate for WMA Std spec
bBitStreamValid = false;
break;
}
if (aOutputs->Channels > 2)
{
// not a valid number of channels for the WMA Std spec
bBitStreamValid = false;
break;
}
if (aOutputs->BitsPerSample != 16)
{
// not a valid number of bits per sample for the WMA Std spec
bBitStreamValid = false;
break;
}
#if !defined(BUILD_WMASTD)
bBitStreamSupported = false;
#endif // BUILD_WMASTD
}
break;
// WMA Voice
case WAVE_FORMAT_MSSPEECH:
{
if (aInputs->inBytes < 18)
{
bBitStreamValid = false;
break;
}
tp = aInputs->inPtr + 4;
LoadDWORD(dwdata, tp);
aOutputs->SamplesPerSec = dwdata;
tp = aInputs->inPtr + 8;
LoadDWORD(dwdata, tp);
//AvgBytesPerSec = dwdata;
tp = aInputs->inPtr + 12;
LoadWORD(wdata , tp);
//BlockAlign = wdata;
tp = aInputs->inPtr + 2;
LoadWORD(wdata , tp);
aOutputs->Channels = wdata;
tp = aInputs->inPtr + 14;
LoadWORD(wdata , tp);
aOutputs->BitsPerSample = wdata;
#if !defined(BUILD_WMAVOICE)
bBitStreamSupported = false;
#endif // BUILD_WMAVOICE
}
break;
case WAVE_FORMAT_WMASPDIF:
case WAVE_FORMAT_WMAUDIO2_ES:
case WAVE_FORMAT_WMAUDIO3_ES:
case WAVE_FORMAT_WMAUDIO_LOSSLESS_ES:
{
// these formats aren't supported
bBitStreamSupported = false;
}
break;
default:
{
// invalid wma format
bBitStreamValid = false;
}
}
}
else if (aInputs->iMimeType == PVMF_MIME_MPEG4_AUDIO || // AAC
aInputs->iMimeType == PVMF_MIME_3640 ||
aInputs->iMimeType == PVMF_MIME_LATM ||
aInputs->iMimeType == PVMF_MIME_ADIF ||
aInputs->iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
aInputs->iMimeType == PVMF_MIME_AAC_SIZEHDR)
{
int32 bytes_consumed, status;
uint8 aAudioObjectType, SamplingRateIndex;
uint32 NumChannels;
bytes_consumed = (int32)aInputs->inBytes;
status = GetActualAacConfig(aInputs->inPtr,
&aAudioObjectType,
&bytes_consumed,
&SamplingRateIndex,
&NumChannels);
aOutputs->Channels = (uint16)NumChannels;
if (aOutputs->Channels > 2)
{
// not a valid number of channels for the AAC
bBitStreamValid = false;
}
}
if (!bBitStreamValid)
{
bBitStreamSupported = false;
}
return (bBitStreamSupported ? 1 : 0);
}