Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,266 @@
#include "ADTSAACDecoder.h"
#include <nsaac/ADTSHeader.h>
#include "../nsutil/pcm.h"
#include <bfc/error.h>
#include <Mferror.h>
ADTSAACDecoder::ADTSAACDecoder()
{
predelay = 0;
useFloat = false; /* we'll fix during Initialize */
gain=1.0f; /* we'll fix during Initialize */
// get bps
bitsPerSample = 16; /* we'll fix during Initialize */
allowRG = false; /* we'll fix during Initialize */
}
int ADTSAACDecoder::Initialize(bool forceMono, bool reverse_stereo, bool allowSurround, int maxBits, bool _allowRG, bool _useFloat, bool _useCRC)
{
allowRG = _allowRG;
useFloat = _useFloat;
if (_useFloat) {
bitsPerSample = 32;
} else if (maxBits >= 24) {
bitsPerSample = 24;
} else {
bitsPerSample = 16;
}
decoder.Open();
return adts::SUCCESS;
}
bool ADTSAACDecoder::Open(ifc_mpeg_stream_reader *file)
{
if (allowRG)
gain = file->MPEGStream_Gain();
return true;
}
void ADTSAACDecoder::Close()
{
}
void ADTSAACDecoder::GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate)
{
uint32_t local_sample_rate, local_channels;
decoder.GetOutputProperties(&local_sample_rate, &local_channels);
*sampleRate = local_sample_rate;
*numChannels = local_channels;
*numBits = bitsPerSample;
}
void ADTSAACDecoder::CalculateFrameSize(int *frameSize)
{
size_t local_frame_size;
if (SUCCEEDED(decoder.OutputBlockSizeSamples(&local_frame_size))) {
*frameSize = (int)local_frame_size;
} else {
*frameSize = 0;
}
}
void ADTSAACDecoder::Flush(ifc_mpeg_stream_reader *file)
{
decoder.Flush();
}
size_t ADTSAACDecoder::GetCurrentBitrate()
{
return 0; // TODO?
}
size_t ADTSAACDecoder::GetDecoderDelay()
{
return predelay;
}
static int ADTSSync(const uint8_t *buffer, size_t bytes_in_buffer, size_t *header_position)
{
for (size_t position=0;position<bytes_in_buffer;position++)
{
// find POTENTIAL sync
if (buffer[position] == 0xFF && bytes_in_buffer - position >= 7)
{
ADTSHeader header;
if (nsaac_adts_parse(&header, &buffer[position]) == NErr_Success)
{
int frame_length = (int)header.frame_length;
if (frame_length && bytes_in_buffer - position - frame_length >= 7)
{
ADTSHeader header2;
if (nsaac_adts_parse(&header2, &buffer[position+frame_length]) == NErr_Success)
{
// verify that parameters match
if (nsaac_adts_match(&header, &header2) != NErr_True)
return NErr_Changed;
// do a dummy read to advance the stream
*header_position = position;
return NErr_Success;
}
}
else
{
/* not enough in the buffer to verify the next header */
*header_position = position;
return NErr_NeedMoreData;
}
}
}
}
return NErr_False;
}
static int ReturnIsEOF(ifc_mpeg_stream_reader *file)
{
if (file->MPEGStream_EOF())
return adts::ENDOFFILE;
else
return adts::NEEDMOREDATA;
}
int ADTSAACDecoder::Internal_Decode(ifc_mpeg_stream_reader *file,
const void *input, size_t input_length,
unsigned __int8 *output, size_t outputSize, size_t *outputWritten)
{
*outputWritten = outputSize;
if (SUCCEEDED(decoder.Feed(input, input_length))) {
HRESULT hr = decoder.Decode(output, outputWritten, bitsPerSample, useFloat, gain);
if (SUCCEEDED(hr)) {
if (*outputWritten == 0) {
return adts::NEEDMOREDATA;
}
return adts::SUCCESS;
} else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
*outputWritten = 0;
return adts::SUCCESS;
}
}
return adts::FAILURE;
}
int ADTSAACDecoder::Sync(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate)
{
/* ok this will be interesting. we'll peek from the input buffer and try to synchronize on an ADTS header */
uint8_t peek_buffer[16384];
size_t bytes_read = 0;
if (file->MPEGStream_Peek(peek_buffer, sizeof(peek_buffer), &bytes_read) != 0)
{
return adts::FAILURE;
}
size_t header_position=0;
int ret = ADTSSync(peek_buffer, bytes_read, &header_position);
if (ret == NErr_NeedMoreData)
{
// this one means we found one sync but not enough to verify the next frame
// if the header was at the start of the block, then unfortunately this might be the LAST adts frame in the file, so let's just pass it the decoder and hope for the best
if (header_position != 0)
{
if (file->MPEGStream_EOF())
return adts::ENDOFFILE;
/* dummy read to advance the stream */
file->MPEGStream_Read(peek_buffer, header_position, &header_position);
return adts::NEEDMOREDATA;
}
}
else if (ret == NErr_False)
{
if (file->MPEGStream_EOF())
return adts::ENDOFFILE;
// not even a potential sync found
/* dummy read to advance the stream */
file->MPEGStream_Read(peek_buffer, bytes_read, &bytes_read);
return adts::NEEDMOREDATA;
}
else if (ret != NErr_Success)
{
if (file->MPEGStream_EOF())
return adts::ENDOFFILE;
return adts::FAILURE;
}
ADTSHeader header;
if (nsaac_adts_parse(&header, &peek_buffer[header_position]) == NErr_Success)
{
/* all this error checking might be uncessary, since in theory we did a successful peek above. but you never know ... */
if (file->MPEGStream_Read(peek_buffer, header_position, &bytes_read)) /* dummy read to advance the stream */
return adts::FAILURE;
if (bytes_read != header_position)
return ReturnIsEOF(file);
if (file->MPEGStream_Read(peek_buffer, header.frame_length, &bytes_read)) /* read ADTS frame */
return adts::FAILURE;
if (bytes_read != header.frame_length)
return ReturnIsEOF(file);
if (bytes_read < 7) /* bad header data? */
return adts::FAILURE;
/* ok, we've created the decoder, but we should really decode the frame to see if there's VBR, PS or MPEGS in it */
size_t header_size = nsaac_adts_get_header_size(&header);
int ret = Internal_Decode(file, peek_buffer, bytes_read, output, outputSize, outputWritten);
if (ret == adts::SUCCESS && *outputWritten == 0) {
return adts::NEEDMOREDATA;
}
return ret;
}
return adts::FAILURE;
}
int ADTSAACDecoder::Decode(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut)
{
HRESULT hr = decoder.Decode(output, outputWritten, bitsPerSample, useFloat, gain);
if (SUCCEEDED(hr) && *outputWritten) {
return adts::SUCCESS;
}
uint8_t peek_buffer[8192];
size_t bytes_read = 0;
file->MPEGStream_Peek(peek_buffer, 7, &bytes_read);
if (bytes_read != 7)
return ReturnIsEOF(file);
ADTSHeader header;
if (nsaac_adts_parse(&header, peek_buffer) == NErr_Success)
{
if (header.frame_length < 7)
return adts::FAILURE;
file->MPEGStream_Peek(peek_buffer, header.frame_length, &bytes_read);
if (bytes_read != header.frame_length)
return ReturnIsEOF(file);
file->MPEGStream_Read(peek_buffer, header.frame_length, &bytes_read);
size_t header_size = nsaac_adts_get_header_size(&header);
*bitrate = nsaac_adts_get_frame_bitrate(&header)/1000;
return Internal_Decode(file, peek_buffer, bytes_read, output, outputSize, outputWritten);
}
else
{
/* Resynchronize */
return Sync(file, output, outputSize, outputWritten, bitrate);
}
}
int ADTSAACDecoder::GetLayer()
{
return 4;
}
void ADTSAACDecoder::Release()
{
delete this;
}

View file

@ -0,0 +1,39 @@
#pragma once
#include "../Plugins/Input/in_mp3/adts.h"
#include "MFTDecoder.h"
// {19450308-90D7-4E45-8A9D-DC71E67123E2}
static const GUID adts_aac_guid =
{ 0x19450308, 0x90d7, 0x4e45, { 0x8a, 0x9d, 0xdc, 0x71, 0xe6, 0x71, 0x23, 0xe2 } };
class ADTSAACDecoder : public adts
{
public:
static const char *getServiceName() { return "MFT AAC ADTS Decoder"; }
static GUID getServiceGuid() { return adts_aac_guid; }
ADTSAACDecoder();
int Initialize(bool forceMono, bool reverse_stereo, bool allowSurround, int maxBits, bool allowRG, bool _useFloat, bool _useCRC);
bool Open(ifc_mpeg_stream_reader *file);
void Close();
void GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate);
void CalculateFrameSize(int *frameSize);
void Flush(ifc_mpeg_stream_reader *file);
size_t GetCurrentBitrate();
size_t GetDecoderDelay();
int Sync(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate);
int Decode(ifc_mpeg_stream_reader *file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut);
int GetLayer();
void Release();
private:
int Internal_Decode(ifc_mpeg_stream_reader *file, const void *input, size_t input_length, unsigned __int8 *output, size_t outputSize, size_t *outputWritten);
MFTDecoder decoder;
int bitsPerSample;
float gain;
bool allowRG;
bool useFloat;
size_t predelay;
};

View file

@ -0,0 +1,116 @@
#include "AVIAACDecoder.h"
#include <math.h>
#include "../nsutil/pcm.h"
int AVIDecoder::CreateAudioDecoder(const nsavi::AVIH *avi_header,
const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data,
unsigned int preferred_bits, unsigned int max_channels, bool floating_point,
ifc_aviaudiodecoder **decoder)
{
nsavi::audio_format *waveformat = (nsavi::audio_format *)stream_format;
if (waveformat->format == nsavi::audio_format_aac)
{
AVIAACDecoder *aac_decoder = AVIAACDecoder::Create(waveformat, preferred_bits, max_channels, floating_point);
if (aac_decoder)
{
*decoder = aac_decoder;
return CREATEDECODER_SUCCESS;
}
return CREATEDECODER_SUCCESS;
}
return CREATEDECODER_NOT_MINE;
}
#define CBCLASS AVIDecoder
START_DISPATCH;
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
END_DISPATCH;
#undef CBCLASS
AVIAACDecoder *AVIAACDecoder::Create(const nsavi::audio_format *waveformat, unsigned int preferred_bits, unsigned int max_channels, bool floating_point)
{
if (!floating_point)
{
if (preferred_bits >= 24)
preferred_bits=24;
else
preferred_bits=16;
}
/*if (!max_channels)
max_channels = 8;*/
if (waveformat->extra_size_bytes)
{
AVIAACDecoder * decoder = new AVIAACDecoder(preferred_bits, floating_point);
if (decoder && SUCCEEDED(decoder->decoder.Open((const unsigned char *)(waveformat + 1), waveformat->extra_size_bytes))) {
return decoder;
}
delete decoder;
}
return 0;
}
AVIAACDecoder::AVIAACDecoder(unsigned int bps, bool floating_point)
: bps(bps), floating_point(floating_point)
{
}
int AVIAACDecoder::OutputFrameSize(size_t *frame_size)
{
size_t local_frame_size;
if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) {
return AVI_FAILURE;
}
*frame_size = local_frame_size;
return AVI_SUCCESS;
}
int AVIAACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
{
uint32_t local_sample_rate, local_channels;
HRESULT hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
if (FAILED(hr)) {
return AVI_FAILURE;
}
*sampleRate = local_sample_rate;
*channels = local_channels;
*bitsPerSample = bps;
*isFloat = floating_point;
return AVI_SUCCESS;
}
int AVIAACDecoder::DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
{
if (SUCCEEDED(decoder.Feed(*inputBuffer, *inputBufferBytes))
&& SUCCEEDED(decoder.Decode(outputBuffer, outputBufferBytes, bps, false, 1.0))) {
*inputBufferBytes = 0;
return AVI_SUCCESS;
}
return AVI_FAILURE;
}
void AVIAACDecoder::Flush()
{
decoder.Flush();
}
void AVIAACDecoder::Close()
{
delete this;
}
#define CBCLASS AVIAACDecoder
START_DISPATCH;
CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
CB(DECODE_CHUNK, DecodeChunk)
VCB(FLUSH, Flush)
VCB(CLOSE, Close)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,40 @@
#pragma once
#include "../Plugins/Input/in_avi/svc_avidecoder.h"
#include "../Plugins/Input/in_avi/ifc_aviaudiodecoder.h"
#include "MFTDecoder.h"
// {D6DB50A7-5E2F-4374-97B0-67CA707EB3CD}
static const GUID avi_aac_guid =
{ 0xd6db50a7, 0x5e2f, 0x4374, { 0x97, 0xb0, 0x67, 0xca, 0x70, 0x7e, 0xb3, 0xcd } };
class AVIDecoder : public svc_avidecoder
{
public:
static const char *getServiceName() { return "MFT AAC AVI Decoder"; }
static GUID getServiceGuid() { return avi_aac_guid; }
int CreateAudioDecoder(const nsavi::AVIH *avi_header, const nsavi::STRH *stream_header, const nsavi::STRF *stream_format, const nsavi::STRD *stream_data, unsigned int preferred_bits, unsigned int max_channels, bool floating_point, ifc_aviaudiodecoder **decoder);
protected:
RECVS_DISPATCH;
};
class AVIAACDecoder : public ifc_aviaudiodecoder
{
public:
AVIAACDecoder(unsigned int bps, bool floating_point);
static AVIAACDecoder *Create(const nsavi::audio_format *stream_format, unsigned int preferred_bits, unsigned int max_channels, bool floating_point);
protected:
RECVS_DISPATCH;
private:
/* ifc_aviaudiodecoder implementation */
int OutputFrameSize(size_t *frame_size);
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
int DecodeChunk(uint16_t type, void **inputBuffer, size_t *inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
void Flush();
void Close();
/* data */
MFTDecoder decoder;
unsigned int bps;
bool floating_point;
};

View file

@ -0,0 +1,115 @@
#include "FLVAACDecoder.h"
#include <math.h>
#include "../nsutil/pcm.h"
int FLVDecoder::CreateAudioDecoder(int stereo, int bits, int sample_rate, int format_type, ifc_flvaudiodecoder **decoder)
{
if (format_type == FLV::AUDIO_FORMAT_AAC)
{
FLVAAC *aac = new FLVAAC();
if (!aac)
{
return CREATEDECODER_FAILURE;
}
*decoder = aac;
return CREATEDECODER_SUCCESS;
}
return CREATEDECODER_NOT_MINE;
}
int FLVDecoder::HandlesAudio(int format_type)
{
if (format_type == FLV::AUDIO_FORMAT_AAC)
{
return CREATEDECODER_SUCCESS;
}
return CREATEDECODER_NOT_MINE;
}
#define CBCLASS FLVDecoder
START_DISPATCH;
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
CB(HANDLES_AUDIO, HandlesAudio)
END_DISPATCH;
#undef CBCLASS
/* --- */
FLVAAC::FLVAAC()
{
bps = 16;
preDelay=0;
got_decoder_config = false;
}
int FLVAAC::GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *_bits)
{
uint32_t local_sample_rate, local_channels;
HRESULT hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
if (FAILED(hr)) {
return FLV_AUDIO_FAILURE;
}
*sample_rate = local_sample_rate;
*channels = local_channels;
*_bits = bps;
return FLV_AUDIO_SUCCESS;
}
int FLVAAC::DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate)
{
const uint8_t *type = (const uint8_t *)input_buffer;
if (type[0] == 0)
{
decoder.Open(type+1, input_buffer_bytes-1);
got_decoder_config=true;
*samples_size_bytes=0;
return FLV_AUDIO_SUCCESS;
return FLV_AUDIO_FAILURE;
}
else if (type[0] == 1)
{
decoder.Feed(input_buffer, input_buffer_bytes);
decoder.Decode(samples, samples_size_bytes, bps, false, 1.0);
*bitrate = 0;
return FLV_AUDIO_SUCCESS;
}
else
return FLV_AUDIO_FAILURE;
}
void FLVAAC::Flush()
{
decoder.Flush();
}
void FLVAAC::Close()
{
delete this;
}
int FLVAAC::Ready()
{
return !!got_decoder_config;
}
void FLVAAC::SetPreferences(unsigned int _max_channels, unsigned int preferred_bits)
{
if (preferred_bits)
bps = preferred_bits;
// TODO: max channels
}
#define CBCLASS FLVAAC
START_DISPATCH;
CB(FLV_AUDIO_GETOUTPUTFORMAT, GetOutputFormat)
CB(FLV_AUDIO_DECODE, DecodeSample)
VCB(FLV_AUDIO_FLUSH, Flush)
VCB(FLV_AUDIO_CLOSE, Close)
CB(FLV_AUDIO_READY, Ready)
VCB(FLV_AUDIO_SETPREFERENCES, SetPreferences)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,43 @@
#pragma once
#include "../Plugins/Input/in_flv/svc_flvdecoder.h"
#include "../Plugins/Input/in_flv/FLVAudioHeader.h"
#include "../Plugins/Input/in_flv/ifc_flvaudiodecoder.h"
#include "MFTDecoder.h"
// {B670EC35-1313-460a-A2EA-C7120AD18BAD}
static const GUID flv_aac_guid =
{ 0xb670ec35, 0x1313, 0x460a, { 0xa2, 0xea, 0xc7, 0x12, 0xa, 0xd1, 0x8b, 0xad } };
class FLVDecoder : public svc_flvdecoder
{
public:
static const char *getServiceName() { return "MFT AAC FLV Decoder"; }
static GUID getServiceGuid() { return flv_aac_guid; }
int CreateAudioDecoder(int stereo, int bits, int sample_rate, int format, ifc_flvaudiodecoder **decoder);
int HandlesAudio(int format_type);
protected:
RECVS_DISPATCH;
};
class FLVAAC : public ifc_flvaudiodecoder
{
public:
FLVAAC();
int GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *bits);
int DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate);
void Flush();
void Close();
int Ready();
void SetPreferences(unsigned int max_channels, unsigned int preferred_bits);
private:
/* data */
MFTDecoder decoder;
unsigned int bps;
size_t preDelay;
bool got_decoder_config;
protected:
RECVS_DISPATCH;
};

View file

@ -0,0 +1,209 @@
#include "MFTDecoder.h"
#include "util.h"
#include "../nsutil/pcm.h"
#include <Mfapi.h>
#include <Mferror.h>
static // Release the events that an MFT might allocate in IMFTransform::ProcessOutput().
void ReleaseEventCollection(MFT_OUTPUT_DATA_BUFFER* pBuffers)
{
if (pBuffers->pEvents)
{
pBuffers->pEvents->Release();
pBuffers->pEvents = NULL;
}
}
MFTDecoder::MFTDecoder()
{
decoder=0;
output_buffer=0;
output_sample=0;
}
MFTDecoder::~MFTDecoder()
{
if (decoder) {
decoder->Release();
}
decoder = 0;
if (output_buffer) {
output_buffer->Release();
}
output_buffer = 0;
if (output_sample) {
output_sample->Release();
}
output_sample = 0;
}
HRESULT MFTDecoder::Open(const void *asc, size_t asc_bytes)
{
HRESULT hr = CreateAACDecoder(&decoder, asc, asc_bytes);
if (SUCCEEDED(hr)) {
decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
}
return hr;
}
HRESULT MFTDecoder::Open()
{
HRESULT hr = CreateADTSDecoder(&decoder);
if (SUCCEEDED(hr)) {
decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
}
return hr;
}
void MFTDecoder::Flush()
{
if (decoder) {
decoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
}
}
HRESULT MFTDecoder::GetOutputProperties(uint32_t *sampleRate, uint32_t *channels)
{
HRESULT hr;
IMFMediaType *media_type;
UINT32 local_sample_rate, local_channels;
if (!decoder) {
return E_FAIL;
}
hr = decoder->GetOutputCurrentType(0, &media_type);
if (FAILED(hr)) {
return hr;
}
if (FAILED(hr=media_type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &local_sample_rate))
|| FAILED(hr=media_type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &local_channels))) {
media_type->Release();
return hr;
}
*sampleRate = local_sample_rate;
*channels = local_channels;
return hr;
}
HRESULT MFTDecoder::Feed(const void *inputBuffer, size_t inputBufferBytes)
{
HRESULT hr;
if (inputBuffer && inputBufferBytes) {
IMFMediaBuffer *media_buffer=0;
IMFSample *media_sample=0;
MFCreateMemoryBuffer((DWORD)inputBufferBytes, &media_buffer);
MFCreateSample(&media_sample);
media_sample->AddBuffer(media_buffer);
BYTE *buffer;
DWORD max_length, current_length;
media_buffer->Lock(&buffer, &max_length, &current_length);
memcpy(buffer, inputBuffer, inputBufferBytes);
media_buffer->Unlock();
media_buffer->SetCurrentLength((DWORD)inputBufferBytes);
hr = decoder->ProcessInput(0, media_sample, 0);
media_sample->Release();
media_buffer->Release();
media_sample=0;
media_buffer=0;
} else {
decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
decoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
}
return S_OK;
}
HRESULT MFTDecoder::Decode(void *outputBuffer, size_t *outputBufferBytes, unsigned int bitsPerSample, bool isFloat, double gain)
{
HRESULT hr;
if (!output_sample) {
MFT_OUTPUT_STREAM_INFO output_stream_info;
hr = decoder->GetOutputStreamInfo(0, &output_stream_info);
if (FAILED(hr)) {
return hr;
}
MFCreateMemoryBuffer(output_stream_info.cbSize, &output_buffer);
MFCreateSample(&output_sample);
output_sample->AddBuffer(output_buffer);
}
output_buffer->SetCurrentLength(0);
MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0, output_sample, 0, 0};
DWORD status=0;
hr = decoder->ProcessOutput(0, 1, &output_data_buffer, &status);
if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
*outputBufferBytes = 0;
return S_OK;
} else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
AssociateFloat(decoder);
*outputBufferBytes = 0;
return hr;
}
IMFMediaBuffer *decimation_buffer;
hr = output_data_buffer.pSample->ConvertToContiguousBuffer(&decimation_buffer);
float *pcm;
DWORD max_length, current_length;
decimation_buffer->Lock((BYTE **)&pcm, &max_length, &current_length);
size_t num_samples = current_length / 4;
*outputBufferBytes = num_samples*bitsPerSample/8;
if (!isFloat)
{
nsutil_pcm_FloatToInt_Interleaved_Gain(outputBuffer, pcm, bitsPerSample, num_samples, (float)gain);
}
else
{
for (size_t i = 0;i != num_samples;i++)
((float *)outputBuffer)[i] = pcm[i] * (float)gain;
}
decimation_buffer->Unlock();
decimation_buffer->Release();
ReleaseEventCollection(&output_data_buffer);
return S_OK;
}
HRESULT MFTDecoder::OutputBlockSizeSamples(size_t *frameSize)
{
HRESULT hr;
MFT_OUTPUT_STREAM_INFO output_stream_info;
if (!decoder) {
return E_FAIL;
}
hr = decoder->GetOutputStreamInfo(0, &output_stream_info);
if (FAILED(hr)) {
return hr;
}
*frameSize = output_stream_info.cbSize;
return hr;
}
bool MFTDecoder::AcceptingInput()
{
DWORD flags;
if (decoder && SUCCEEDED(decoder->GetInputStatus(0, &flags))) {
if (flags & MFT_INPUT_STATUS_ACCEPT_DATA) {
return true;
}
}
return false;
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <mftransform.h>
#include <bfc/platform/types.h>
// generic API for use by all decoder flavors (MP4, MKV, etc)
class MFTDecoder
{
public:
MFTDecoder();
~MFTDecoder();
HRESULT Open(const void *asc, size_t asc_bytes);
HRESULT Open();
void Flush();
HRESULT GetOutputProperties(uint32_t *sampleRate, uint32_t *channels);
HRESULT Feed(const void *buffer, size_t bufferBytes);
HRESULT Decode(void *outputBuffer, size_t *outputBufferBytes, unsigned int bitsPerSample, bool useFloat, double gain);
HRESULT OutputBlockSizeSamples(size_t *frameSize);
bool AcceptingInput();
private:
IMFTransform *decoder;
IMFMediaBuffer *output_buffer;
IMFSample *output_sample;
};

View file

@ -0,0 +1,116 @@
#include "MKVAACDecoder.h"
#include <math.h>
#include "../nsutil/pcm.h"
MKVAACDecoder::MKVAACDecoder(unsigned int bps, bool floating_point)
: bps(bps), floating_point(floating_point)
{
}
MKVAACDecoder *MKVAACDecoder::Create(const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels, bool floating_point)
{
if (!floating_point)
{
if (preferred_bits >= 24)
preferred_bits=24;
else
preferred_bits=16;
}
/*if (!max_channels)
max_channels = 8;*/
if (track_entry_data->codec_private && track_entry_data->codec_private_len)
{
MKVAACDecoder *decoder = new MKVAACDecoder(preferred_bits, floating_point);
if (decoder && SUCCEEDED(decoder->decoder.Open(track_entry_data->codec_private, track_entry_data->codec_private_len))) {
return decoder;
}
delete decoder;
}
return 0;
}
int MKVAACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
{
uint32_t local_sample_rate, local_channels;
HRESULT hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
if (FAILED(hr)) {
return MKV_FAILURE;
}
*sampleRate = local_sample_rate;
*channels = local_channels;
*bitsPerSample = bps;
*isFloat = floating_point;
return MKV_SUCCESS;
}
void MKVAACDecoder::Flush()
{
decoder.Flush();
}
int MKVAACDecoder::OutputFrameSize(size_t *frame_size)
{
size_t local_frame_size;
if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) {
return MKV_FAILURE;
}
*frame_size = local_frame_size;
return MKV_SUCCESS;
}
void MKVAACDecoder::Close()
{
delete this;
}
int MKVAACDecoder::DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
{
decoder.Feed(inputBuffer, inputBufferBytes);
decoder.Decode(outputBuffer, outputBufferBytes, bps, false, 1.0);
return MKV_SUCCESS;
}
void MKVAACDecoder::EndOfStream()
{
decoder.Feed(0, 0);
}
#define CBCLASS MKVAACDecoder
START_DISPATCH;
CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
CB(DECODE_BLOCK, DecodeBlock)
VCB(FLUSH, Flush)
VCB(CLOSE, Close)
VCB(END_OF_STREAM, EndOfStream)
END_DISPATCH;
#undef CBCLASS
int MKVDecoder::CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels,bool floating_point, ifc_mkvaudiodecoder **decoder)
{
if (!strcmp(codec_id, "A_AAC"))
{
MKVAACDecoder *aac_decoder = MKVAACDecoder::Create(track_entry_data, audio_data, preferred_bits, max_channels, floating_point);
if (aac_decoder)
{
*decoder = aac_decoder;
return CREATEDECODER_SUCCESS;
}
return CREATEDECODER_FAILURE;
}
return CREATEDECODER_NOT_MINE;
}
#define CBCLASS MKVDecoder
START_DISPATCH;
CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,46 @@
#pragma once
#include "../Plugins/Input/in_mkv/ifc_mkvaudiodecoder.h"
#include "MFTDecoder.h"
#include "../nsmkv/Tracks.h"
#include "../Plugins/Input/in_mkv/svc_mkvdecoder.h"
// {437C68FA-2972-4ede-A157-CBD371E5E263}
static const GUID AACMKVGUID =
{ 0x437c68fa, 0x2972, 0x4ede, { 0xa1, 0x57, 0xcb, 0xd3, 0x71, 0xe5, 0xe2, 0x63 } };
class MKVDecoder : public svc_mkvdecoder
{
public:
static const char *getServiceName() { return "MFT AAC MKV Decoder"; }
static GUID getServiceGuid() { return AACMKVGUID; }
int CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int preferred_channels, bool floating_point, ifc_mkvaudiodecoder **decoder);
protected:
RECVS_DISPATCH;
};
class MKVAACDecoder : public ifc_mkvaudiodecoder
{
public:
static MKVAACDecoder *Create(const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels, bool floating_point);
protected:
RECVS_DISPATCH;
private:
/* ifc_mkvaudiodecoder implementation */
int OutputFrameSize(size_t *frame_size);
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat);
int DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
void Flush();
void Close();
void EndOfStream(); // no more input, output anything you have buffered
private:
MKVAACDecoder(unsigned int bps, bool floating_point);
/* internal implementation */
/* data */
MFTDecoder decoder;
unsigned int bps;
bool floating_point;
};

View file

@ -0,0 +1,171 @@
#include "MP4AACDecoder.h"
#include <Mferror.h>
#include <Mfapi.h>
#include "../external_dependencies/libmp4v2/mp4.h"
#include "util.h"
#include "../nsutil/pcm.h"
MP4AACDecoder::MP4AACDecoder()
{
isFloat = false;
gain=1.0f;
channels = 0;
}
MP4AACDecoder::~MP4AACDecoder()
{
}
int MP4AACDecoder::OpenMP4(MP4FileHandle mp4_file, MP4TrackId mp4_track, size_t output_bits, size_t maxChannels, bool useFloat)
{
HRESULT hr;
unsigned char *buffer;
uint32_t buffer_size;
if (useFloat) {
this->bitsPerSample = 32;
} else if (output_bits) {
this->bitsPerSample = (unsigned int)output_bits;
} else {
this->bitsPerSample = 16;
}
this->isFloat = useFloat;
if (MP4GetTrackESConfiguration(mp4_file, mp4_track, (uint8_t **)&buffer, &buffer_size) && buffer) {
hr = decoder.Open(buffer, buffer_size);
if (SUCCEEDED(hr)) {
uint32_t local_sample_rate, local_channels;
hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
if (SUCCEEDED(hr)) {
this->channels = local_channels;
return MP4_SUCCESS;
}
}
}
return MP4_FAILURE;
}
void MP4AACDecoder::Close()
{
}
void MP4AACDecoder::Flush()
{
decoder.Flush();
}
int MP4AACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *_bitsPerSample)
{
bool dummy;
return GetOutputPropertiesEx(sampleRate, channels, _bitsPerSample, &dummy);
}
int MP4AACDecoder::GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *useFloat)
{
HRESULT hr;
UINT32 local_sample_rate, local_channels;
hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
if (FAILED(hr)) {
return MP4_FAILURE;
}
*sampleRate = local_sample_rate;
*channels = local_channels;
*bitsPerSample = this->bitsPerSample;
*useFloat = this->isFloat;
return MP4_SUCCESS;
}
int MP4AACDecoder::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
{
HRESULT hr;
hr = decoder.Feed(inputBuffer, inputBufferBytes);
if (FAILED(hr)) {
return MP4_FAILURE;
}
hr = decoder.Decode(outputBuffer, outputBufferBytes, this->bitsPerSample, this->isFloat, this->gain);
if (FAILED(hr)) {
return MP4_FAILURE;
}
return MP4_SUCCESS;
}
int MP4AACDecoder::OutputFrameSize(size_t *frameSize)
{
if (channels == 0) {
return MP4_FAILURE;
}
size_t local_frame_size;
if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) {
return MP4_FAILURE;
}
*frameSize = local_frame_size / channels;
return MP4_SUCCESS;
}
int MP4AACDecoder::CanHandleCodec(const char *codecName)
{
return !strcmp(codecName, "mp4a");
}
int MP4AACDecoder::CanHandleType(uint8_t type)
{
switch (type)
{
case MP4_TYPE_MPEG4_AUDIO:
return 1;
case MP4_TYPE_MPEG2_AAC_LC_AUDIO:
return 1;
default:
return 0;
}
}
int MP4AACDecoder::CanHandleMPEG4Type(uint8_t type)
{
switch (type)
{
case MP4_MPEG4_TYPE_AAC_LC_AUDIO:
case MP4_MPEG4_TYPE_AAC_HE_AUDIO:
case MP4_MPEG4_TYPE_PARAMETRIC_STEREO:
return 1;
default:
return 0;
}
}
void MP4AACDecoder::EndOfStream()
{
decoder.Feed(0, 0);
}
#ifdef CBCLASS
#undef CBCLASS
#endif
#define CBCLASS MP4AACDecoder
START_DISPATCH;
CB(MPEG4_AUDIO_OPENMP4, OpenMP4)
#if 0
CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate)
#endif
CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize)
CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties)
CB(MPEG4_AUDIO_OUTPUTINFO_EX, GetOutputPropertiesEx)
CB(MPEG4_AUDIO_DECODE, DecodeSample)
VCB(MPEG4_AUDIO_FLUSH, Flush)
VCB(MPEG4_AUDIO_CLOSE, Close)
CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec)
CB(MPEG4_AUDIO_HANDLES_TYPE, CanHandleType)
CB(MPEG4_AUDIO_HANDLES_MPEG4_TYPE, CanHandleMPEG4Type)
CB(MPEG4_AUDIO_SET_GAIN, SetGain)
END_DISPATCH;

View file

@ -0,0 +1,40 @@
#pragma once
#include "../Plugins/Input/in_mp4/mpeg4audio.h"
#include "MFTDecoder.h"
// {3C0B6E1B-0C21-4716-B8D6-C7665CBC90E9}
static const GUID mp4_aac_guid =
{ 0x3c0b6e1b, 0xc21, 0x4716, { 0xb8, 0xd6, 0xc7, 0x66, 0x5c, 0xbc, 0x90, 0xe9 } };
class MP4AACDecoder : public MP4AudioDecoder
{
public:
static const char *getServiceName() { return "MFT AAC MP4 Decoder"; }
static GUID getServiceGuid() { return mp4_aac_guid; }
MP4AACDecoder();
~MP4AACDecoder();
int OpenMP4(MP4FileHandle mp4_file, MP4TrackId mp4_track, size_t output_bits, size_t maxChannels, bool useFloat);
void Close();
int GetCurrentBitrate(unsigned int *bitrate);
int AudioSpecificConfiguration(void *buffer, size_t buffer_size); // reads ASC block from mp4 file
void Flush();
int GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *_bitsPerSample);
int GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *useFloat);
int DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes);
int OutputFrameSize(size_t *frameSize);
int CanHandleCodec(const char *codecName);
int CanHandleType(uint8_t type);
int CanHandleMPEG4Type(uint8_t type);
int SetGain(float _gain) { gain=_gain; return MP4_SUCCESS; }
void EndOfStream();
private:
MFTDecoder decoder;
unsigned int bitsPerSample;
bool isFloat;
float gain;
unsigned int channels;
protected:
RECVS_DISPATCH;
};

View file

@ -0,0 +1,121 @@
#include "NSVAACDecoder.h"
#include <assert.h>
#include "api.h"
#include "../nsv/nsvlib.h"
#include "api.h"
#include "../nsv/nsvlib.h"
#include "../nsv/dec_if.h"
#include <string.h>
#include <bfc/platform/export.h>
#include "NSVAACDecoder.h"
#include <bfc/error.h>
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
NSVAACDecoder *NSVAACDecoder::CreateDecoder()
{
NSVAACDecoder *decoder=0;
WASABI_API_MEMMGR->New(&decoder);
if (!decoder)
{
return 0;
}
decoder->Initialize();
return decoder;
}
NSVAACDecoder::NSVAACDecoder()
{
source_position=0;
out_left=0;
in_position=0;
}
NSVAACDecoder::~NSVAACDecoder()
{
}
void NSVAACDecoder::Initialize()
{
decoder.Open();
}
void NSVAACDecoder::flush()
{
decoder.Flush();
}
// returns -1 on error, 0 on success (done with data in 'in'), 1 on success
// but to pass 'in' again next time around.
int NSVAACDecoder::decode(void *in, int in_len, void *out, int *out_len, unsigned int out_fmt[8])
{
HRESULT hr;
size_t local_out_len = *out_len;
if (SUCCEEDED(decoder.Decode(out, &local_out_len, 16, false, 1.0))) {
*out_len = (int)local_out_len;
if (local_out_len) {
uint32_t local_sample_rate, local_channels;
if (SUCCEEDED(decoder.GetOutputProperties(&local_sample_rate, &local_channels))) {
out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
out_fmt[1] = local_sample_rate;
out_fmt[2] = local_channels;
out_fmt[3] = 16;
}
return 1;
}
}
hr = decoder.Feed(in, in_len);
if (FAILED(hr)) {
hr=hr;
}
local_out_len = *out_len;
if (SUCCEEDED(decoder.Decode(out, &local_out_len, 16, false, 1.0))) {
*out_len = (int)local_out_len;
if (local_out_len) {
uint32_t local_sample_rate, local_channels;
if (SUCCEEDED(decoder.GetOutputProperties(&local_sample_rate, &local_channels))) {
out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
out_fmt[1] = local_sample_rate;
out_fmt[2] = local_channels;
out_fmt[3] = 16;
}
}
} else {
*out_len = 0;
}
return 0;
}
IAudioDecoder *NSVDecoder::CreateAudioDecoder(FOURCC format, IAudioOutput **output)
{
switch (format)
{
case NSV_MAKETYPE('A', 'A', 'C', ' ') :
case NSV_MAKETYPE('A', 'A', 'C', 'P'):
case NSV_MAKETYPE('A', 'P', 'L', ' '):
{
NSVAACDecoder *dec = NSVAACDecoder::CreateDecoder();
return dec;
}
default:
return 0;
}
}
#define CBCLASS NSVDecoder
START_DISPATCH;
CB(SVC_NSVFACTORY_CREATEAUDIODECODER, CreateAudioDecoder)
END_DISPATCH;
#undef CBCLASS

View file

@ -0,0 +1,45 @@
#pragma once
#include "../nsv/dec_if.h"
#include "MFTDecoder.h"
#include <bfc/platform/types.h>
//#include "ADTSHeader.h"
#include "../nsv/svc_nsvFactory.h"
// {E890E15C-A6D8-4ed9-9204-85C77AB80C53}
static const GUID NSV_AAC_GUID =
{ 0xe890e15c, 0xa6d8, 0x4ed9, { 0x92, 0x4, 0x85, 0xc7, 0x7a, 0xb8, 0xc, 0x53 } };
class NSVDecoder : public svc_nsvFactory
{
public:
static const char *getServiceName() { return "MFT AAC NSV Decoder"; }
static GUID getServiceGuid() { return NSV_AAC_GUID; }
IAudioDecoder *CreateAudioDecoder(FOURCC format, IAudioOutput **output) override;
protected:
RECVS_DISPATCH;
};
class NSVAACDecoder : public IAudioDecoder
{
public:
static NSVAACDecoder *CreateDecoder();
NSVAACDecoder();
~NSVAACDecoder();
void Initialize();
int decode(void *in, int in_len, void *out, int *out_len, unsigned int out_fmt[8]);
void flush();
bool OK();
private:
void FillOutputFormat(unsigned int out_fmt[8]);
void CopyToOutput(void *out, int *out_len);
private:
/* data */
MFTDecoder decoder;
int in_position;
int out_left;
size_t source_position;
};

View file

@ -0,0 +1,76 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,53 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29424.173
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aacdec-mft", "aacdec-mft.vcxproj", "{F6962367-6A6C-4E7D-B661-B767E904F451}"
ProjectSection(ProjectDependencies) = postProject
{DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmp4v2", "..\libmp4v2\libmp4v2.vcxproj", "{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F6962367-6A6C-4E7D-B661-B767E904F451}.Debug|Win32.ActiveCfg = Debug|Win32
{F6962367-6A6C-4E7D-B661-B767E904F451}.Debug|Win32.Build.0 = Debug|Win32
{F6962367-6A6C-4E7D-B661-B767E904F451}.Debug|x64.ActiveCfg = Debug|x64
{F6962367-6A6C-4E7D-B661-B767E904F451}.Debug|x64.Build.0 = Debug|x64
{F6962367-6A6C-4E7D-B661-B767E904F451}.Release|Win32.ActiveCfg = Release|Win32
{F6962367-6A6C-4E7D-B661-B767E904F451}.Release|x64.ActiveCfg = Release|x64
{F6962367-6A6C-4E7D-B661-B767E904F451}.Release|x64.Build.0 = Release|x64
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.Build.0 = Release|x64
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Debug|Win32.ActiveCfg = Debug|Win32
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Debug|Win32.Build.0 = Debug|Win32
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Debug|x64.ActiveCfg = Debug|x64
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Debug|x64.Build.0 = Debug|x64
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Release|Win32.ActiveCfg = Release|Win32
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Release|Win32.Build.0 = Release|Win32
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Release|x64.ActiveCfg = Release|x64
{EFB9B882-6A8B-463D-A8E3-A2807AFC5D9F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FC646532-2050-40A5-A2AB-F699F1C071C4}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F6962367-6A6C-4E7D-B661-B767E904F451}</ProjectGuid>
<RootNamespace>aacdec</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetName>aacdec</TargetName>
<TargetExt>.w5s</TargetExt>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetName>aacdec</TargetName>
<TargetExt>.w5s</TargetExt>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetName>aacdec</TargetName>
<TargetExt>.w5s</TargetExt>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<TargetName>aacdec</TargetName>
<TargetExt>.w5s</TargetExt>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../Wasabi;../replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;AACDECMFT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfuuid.lib;mfplat.lib;wmcodecdspuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../Wasabi;../replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;AACDECMFT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfuuid.lib;mfplat.lib;wmcodecdspuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../Wasabi;../replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;AACDECMFT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfuuid.lib;mfplat.lib;wmcodecdspuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(ProjectDir)x86_Release\$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>../Wasabi;../replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;AACDECMFT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfuuid.lib;mfplat.lib;wmcodecdspuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(ProjectDir)x64_Release\$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\external_dependencies\libmp4v2\libmp4v2.vcxproj">
<Project>{efb9b882-6a8b-463d-a8e3-a2807afc5d9f}</Project>
</ProjectReference>
<ProjectReference Include="..\nsutil\nsutil.vcxproj">
<Project>{dabe6307-f8dd-416d-9dac-673e2decb73f}</Project>
</ProjectReference>
<ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\replicant\nsaac\ADTSHeader.c" />
<ClCompile Include="ADTSAACDecoder.cpp" />
<ClCompile Include="api.cpp" />
<ClCompile Include="AVIAACDecoder.cpp" />
<ClCompile Include="FLVAACDecoder.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="mft-util.cpp" />
<ClCompile Include="MFTDecoder.cpp" />
<ClCompile Include="MKVAACDecoder.cpp" />
<ClCompile Include="MP4AACDecoder.cpp" />
<ClCompile Include="NSVAACDecoder.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\replicant\nsaac\ADTSHeader.h" />
<ClInclude Include="ADTSAACDecoder.h" />
<ClInclude Include="api.h" />
<ClInclude Include="AVIAACDecoder.h" />
<ClInclude Include="FLVAACDecoder.h" />
<ClInclude Include="MFTDecoder.h" />
<ClInclude Include="MKVAACDecoder.h" />
<ClInclude Include="MP4AACDecoder.h" />
<ClInclude Include="NSVAACDecoder.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="util.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="aacdec-mft.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="ADTSAACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\replicant\nsaac\ADTSHeader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="api.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AVIAACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FLVAACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MFTDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mft-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MKVAACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MP4AACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NSVAACDecoder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ADTSAACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\replicant\nsaac\ADTSHeader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="api.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AVIAACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FLVAACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MFTDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MKVAACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MP4AACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NSVAACDecoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{fba2fb29-46f5-449a-a2d4-f599c329c299}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{f5dc361a-609c-422d-a515-244e8f22edf1}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{6fca69fe-c362-4e6d-a1d2-307925c9cbbe}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="aacdec-mft.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

5
Src/aacdec-mft/api.cpp Normal file
View file

@ -0,0 +1,5 @@
#include "api.h"
api_service *WASABI_API_SVC=0;
api_config *AGAVE_API_CONFIG=0;
api_memmgr *WASABI_API_MEMMGR=0;

12
Src/aacdec-mft/api.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include <api/service/api_service.h>
extern api_service *serviceManager;
#define WASABI_API_SVC serviceManager
#include "../Agave/Config/api_config.h"
#include <api/memmgr/api_memmgr.h>
extern api_memmgr *memmgrApi;
#define WASABI_API_MEMMGR memmgrApi

79
Src/aacdec-mft/main.cpp Normal file
View file

@ -0,0 +1,79 @@
#include "api.h"
#include "../nu/Singleton.h"
#include "../nu/factoryt.h"
#include "AVIAACDecoder.h"
#include "FLVAACDecoder.h"
#include "MKVAACDecoder.h"
#include "MP4AACDecoder.h"
#include "ADTSAACDecoder.h"
#include "NSVAACDecoder.h"
#include <bfc/platform/export.h>
#include "../Agave/Component/ifc_wa5component.h"
#include "../nu/ServiceBuilder.h"
class AACDecoderComponent : public ifc_wa5component
{
public:
void RegisterServices(api_service *service);
int RegisterServicesSafeModeOk();
void DeregisterServices(api_service *service);
protected:
RECVS_DISPATCH;
};
static SingletonServiceFactory<svc_avidecoder, AVIDecoder> avi_factory;
static AVIDecoder avi_decoder;
static SingletonServiceFactory<svc_mkvdecoder, MKVDecoder> mkv_factory;
static MKVDecoder mkv_decoder;
static SingletonServiceFactory<svc_flvdecoder, FLVDecoder> flv_factory;
static FLVDecoder flv_decoder;
static ServiceFactoryT<MP4AudioDecoder, MP4AACDecoder> mp4_factory;
static ServiceFactoryT<adts, ADTSAACDecoder> adts_factory;
static NSVDecoder nsv_decoder;
static SingletonServiceFactory<svc_nsvFactory, NSVDecoder> nsv_factory;
void AACDecoderComponent::RegisterServices(api_service *service)
{
WASABI_API_SVC = service;
avi_factory.Register(WASABI_API_SVC, &avi_decoder);
mkv_factory.Register(WASABI_API_SVC, &mkv_decoder);
flv_factory.Register(WASABI_API_SVC, &flv_decoder);
nsv_factory.Register(WASABI_API_SVC, &nsv_decoder);
mp4_factory.Register(WASABI_API_SVC);
adts_factory.Register(WASABI_API_SVC);
ServiceBuild(WASABI_API_SVC, AGAVE_API_CONFIG, AgaveConfigGUID);
ServiceBuild(WASABI_API_SVC, WASABI_API_MEMMGR, memMgrApiServiceGuid);
}
void AACDecoderComponent::DeregisterServices(api_service *service)
{
avi_factory.Deregister(WASABI_API_SVC);
mkv_factory.Deregister(WASABI_API_SVC);
mp4_factory.Deregister(WASABI_API_SVC);
flv_factory.Deregister(WASABI_API_SVC);
nsv_factory.Deregister(WASABI_API_SVC);
adts_factory.Deregister(WASABI_API_SVC);
ServiceRelease(WASABI_API_SVC, AGAVE_API_CONFIG, AgaveConfigGUID);
ServiceRelease(WASABI_API_SVC, WASABI_API_MEMMGR, memMgrApiServiceGuid);
}
int AACDecoderComponent::RegisterServicesSafeModeOk()
{
return 1;
}
AACDecoderComponent aac_decoder_component;
extern "C" DLLEXPORT ifc_wa5component *GetWinamp5SystemComponent()
{
return &aac_decoder_component;
}
#define CBCLASS AACDecoderComponent
START_DISPATCH;
VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
CB(15, RegisterServicesSafeModeOk)
VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
END_DISPATCH;
#undef CBCLASS

191
Src/aacdec-mft/mft-util.cpp Normal file
View file

@ -0,0 +1,191 @@
#include "util.h"
#include <bfc/platform/types.h>
#include <mferror.h>
#include <mftransform.h>
#include <wmcodecdsp.h>
#include <Mfidl.h>
#include <Mfapi.h>
struct AACUserData {
WORD wPayloadType;
WORD wAudioProfileLevelIndication;
WORD wStructType;
WORD wReserved1;
DWORD dwReserved2;
uint8_t buffer[16];
};
HRESULT GetAACCodec(IMFTransform **pDecoder)
{
HRESULT hr = S_OK;
UINT32 count = 0;
IMFActivate **ppActivate = NULL; // Array of activation objects.
MFT_REGISTER_TYPE_INFO info = { MFMediaType_Audio, MFAudioFormat_AAC };
UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT |
MFT_ENUM_FLAG_LOCALMFT |
MFT_ENUM_FLAG_SORTANDFILTER;
hr = MFTEnumEx(
MFT_CATEGORY_AUDIO_DECODER,
unFlags,
&info, // Input type
NULL, // Output type
&ppActivate,
&count
);
if (SUCCEEDED(hr) && count == 0)
{
hr = MF_E_TOPO_CODEC_NOT_FOUND;
}
// Create the first decoder in the list.
if (SUCCEEDED(hr))
{
hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(pDecoder));
}
for (UINT32 i = 0; i < count; i++)
{
ppActivate[i]->Release();
}
CoTaskMemFree(ppActivate);
return hr;
}
bool AssociateFloat(IMFTransform *decoder)
{
IMFMediaType *media_type;
DWORD index=0;
for (;;)
{
GUID subtype;
UINT32 bps;
HRESULT hr = decoder->GetOutputAvailableType(0, index++, &media_type);
if (hr != S_OK)
return false;
if (media_type->GetGUID(MF_MT_SUBTYPE, &subtype) != S_OK
|| media_type->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bps) != S_OK)
{
media_type->Release();
return false;
}
if (subtype == MFAudioFormat_Float && bps == 32)
{
hr = decoder->SetOutputType(0, media_type, 0);
media_type->Release();
return true;
}
media_type->Release();
}
}
static uint32_t SampleRateForASC(const void *asc, size_t aacConfigLength)
{
const uint8_t *pAacConfig = (const uint8_t *)asc;
const uint32_t samplingRates[]={96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};
int index;
if (aacConfigLength >= 5 && (pAacConfig[4] >> 7) == 1)
{
index = (pAacConfig[4] >> 3) & 0x7;
} else if (aacConfigLength >= 2) {
index = ((pAacConfig[0] & 0x7) << 1) | (pAacConfig[1] >> 7); // bits 5-8
} else {
index = 12;
}
return samplingRates[index];
}
HRESULT CreateAACDecoder(IMFTransform **pDecoder, const void *asc, size_t asc_bytes)
{
HRESULT hr;
IMFMediaType *media_type;
hr = GetAACCodec(pDecoder);
if (FAILED(hr)) {
return hr;
}
hr = MFCreateMediaType(&media_type);
if (FAILED(hr)) {
return hr;
}
hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
//
hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0); // The stream contains raw_data_block elements only.
uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
media_type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, SampleRateForASC(asc, asc_bytes));
// this is such a pain in the ass, it's part of an HEAACWAVEINFO struct packed together with the ASC data
AACUserData aacinfo;
aacinfo.wPayloadType = 0;
aacinfo.wAudioProfileLevelIndication = profile_level;
aacinfo.wStructType = 0;
if (asc && asc_bytes) {
if (asc_bytes > 16) { // don't overrun the buffer
return E_FAIL;
}
memcpy(aacinfo.buffer, asc, asc_bytes);
hr = media_type->SetBlob(MF_MT_USER_DATA, (const UINT8 *)&aacinfo, 12+(UINT)asc_bytes);
}
hr = (*pDecoder)->SetInputType(0, media_type, 0);
if (FAILED(hr)) {
return hr;
}
media_type->Release();
media_type=0;
AssociateFloat(*pDecoder);
return S_OK;
}
HRESULT CreateADTSDecoder(IMFTransform **pDecoder)
{
HRESULT hr;
IMFMediaType *media_type;
hr = GetAACCodec(pDecoder);
if (FAILED(hr)) {
return hr;
}
hr = MFCreateMediaType(&media_type);
if (FAILED(hr)) {
return hr;
}
hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1); // ADTS
//hr = media_type->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16); // 16 bits per sample
uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
const BYTE user_data[] = {0x01, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
hr = media_type->SetBlob(MF_MT_USER_DATA, user_data, sizeof(user_data));
hr = (*pDecoder)->SetInputType(0, media_type, 0);
if (FAILED(hr)) {
return hr;
}
media_type->Release();
media_type=0;
AssociateFloat(*pDecoder);
return S_OK;
}

14
Src/aacdec-mft/resource.h Normal file
View file

@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by aacdec-mft.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

8
Src/aacdec-mft/util.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include <mftransform.h>
#include <bfc/platform/types.h>
HRESULT GetAACCodec(IMFTransform **pDecoder);
HRESULT CreateAACDecoder(IMFTransform **pDecoder, const void *asc, size_t asc_bytes);
HRESULT CreateADTSDecoder(IMFTransform **pDecoder);
bool AssociateFloat(IMFTransform *decoder);

View file

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION WINAMP_PRODUCTVER
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp 5.x System Component"
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
VALUE "InternalName", "aacdec-mft.w5s"
VALUE "LegalCopyright", "Copyright © 2015-2019 Ben Allison"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "aacdec.w5s"
VALUE "ProductName", "Winamp AAC Decoder Service"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END