summaryrefslogtreecommitdiffstats
path: root/Src/aacdec-mft/MKVAACDecoder.cpp
blob: 49de01d72cf8efb2ddca498ffc4e814a82dab169 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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