1 /*
2  * Copyright 2003-2021 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include "FaadDecoderPlugin.hxx"
21 #include "../DecoderAPI.hxx"
22 #include "../DecoderBuffer.hxx"
23 #include "input/InputStream.hxx"
24 #include "pcm/CheckAudioFormat.hxx"
25 #include "tag/Handler.hxx"
26 #include "util/ScopeExit.hxx"
27 #include "util/ConstBuffer.hxx"
28 #include "util/Domain.hxx"
29 #include "util/Math.hxx"
30 #include "Log.hxx"
31 
32 #include <cassert>
33 #include <cstring>
34 
35 #include <neaacdec.h>
36 
37 static const unsigned adts_sample_rates[] =
38     { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
39 	16000, 12000, 11025, 8000, 7350, 0, 0, 0
40 };
41 
42 static constexpr Domain faad_decoder_domain("faad_decoder");
43 
44 /**
45  * Check whether the buffer head is an AAC frame, and return the frame
46  * length.  Returns 0 if it is not a frame.
47  */
48 static size_t
adts_check_frame(const unsigned char * data)49 adts_check_frame(const unsigned char *data)
50 {
51 	/* check syncword */
52 	if (!((data[0] == 0xFF) && ((data[1] & 0xF6) == 0xF0)))
53 		return 0;
54 
55 	return (((unsigned int)data[3] & 0x3) << 11) |
56 		(((unsigned int)data[4]) << 3) |
57 		(data[5] >> 5);
58 }
59 
60 /**
61  * Find the next AAC frame in the buffer.  Returns 0 if no frame is
62  * found or if not enough data is available.
63  */
64 static size_t
adts_find_frame(DecoderBuffer & buffer)65 adts_find_frame(DecoderBuffer &buffer)
66 {
67 	while (true) {
68 		auto data = ConstBuffer<uint8_t>::FromVoid(buffer.Need(8));
69 		if (data.IsNull())
70 			/* failed */
71 			return 0;
72 
73 		/* find the 0xff marker */
74 		auto p = (const uint8_t *)std::memchr(data.data, 0xff, data.size);
75 		if (p == nullptr) {
76 			/* no marker - discard the buffer */
77 			buffer.Clear();
78 			continue;
79 		}
80 
81 		if (p > data.data) {
82 			/* discard data before 0xff */
83 			buffer.Consume(p - data.data);
84 			continue;
85 		}
86 
87 		/* is it a frame? */
88 		const size_t frame_length = adts_check_frame(data.data);
89 		if (frame_length == 0) {
90 			/* it's just some random 0xff byte; discard it
91 			   and continue searching */
92 			buffer.Consume(1);
93 			continue;
94 		}
95 
96 		if (buffer.Need(frame_length).IsNull()) {
97 			/* not enough data; discard this frame to
98 			   prevent a possible buffer overflow */
99 			buffer.Clear();
100 			continue;
101 		}
102 
103 		/* found a full frame! */
104 		return frame_length;
105 	}
106 }
107 
108 static SignedSongTime
adts_song_duration(DecoderBuffer & buffer)109 adts_song_duration(DecoderBuffer &buffer)
110 {
111 	const InputStream &is = buffer.GetStream();
112 	const bool estimate = !is.CheapSeeking();
113 	if (estimate && !is.KnownSize())
114 		return SignedSongTime::Negative();
115 
116 	unsigned sample_rate = 0;
117 
118 	/* Read all frames to ensure correct time and bitrate */
119 	unsigned frames = 0;
120 	for (;; frames++) {
121 		const unsigned frame_length = adts_find_frame(buffer);
122 		if (frame_length == 0)
123 			break;
124 
125 		if (frames == 0) {
126 			auto data = ConstBuffer<uint8_t>::FromVoid(buffer.Read());
127 			assert(!data.empty());
128 			assert(frame_length <= data.size);
129 
130 			sample_rate = adts_sample_rates[(data.data[2] & 0x3c) >> 2];
131 			if (sample_rate == 0)
132 				break;
133 		}
134 
135 		buffer.Consume(frame_length);
136 
137 		if (estimate && frames == 128) {
138 			/* if this is a remote file, don't slurp the
139 			   whole file just for checking the song
140 			   duration; instead, stop after some time and
141 			   extrapolate the song duration from what we
142 			   have until now */
143 
144 			const auto offset = is.GetOffset()
145 				- buffer.GetAvailable();
146 			if (offset <= 0)
147 				return SignedSongTime::Negative();
148 
149 			const auto file_size = is.GetSize();
150 			frames = (frames * file_size) / offset;
151 			break;
152 		}
153 	}
154 
155 	if (sample_rate == 0)
156 		return SignedSongTime::Negative();
157 
158 	return SignedSongTime::FromScale<uint64_t>(frames * uint64_t(1024),
159 						   sample_rate);
160 }
161 
162 static SignedSongTime
faad_song_duration(DecoderBuffer & buffer,InputStream & is)163 faad_song_duration(DecoderBuffer &buffer, InputStream &is)
164 {
165 	auto data = ConstBuffer<uint8_t>::FromVoid(buffer.Need(5));
166 	if (data.IsNull())
167 		return SignedSongTime::Negative();
168 
169 	size_t tagsize = 0;
170 	if (data.size >= 10 && !memcmp(data.data, "ID3", 3)) {
171 		/* skip the ID3 tag */
172 
173 		tagsize = (data.data[6] << 21) | (data.data[7] << 14) |
174 		    (data.data[8] << 7) | (data.data[9] << 0);
175 
176 		tagsize += 10;
177 
178 		if (!buffer.Skip(tagsize))
179 			return SignedSongTime::Negative();
180 
181 		data = ConstBuffer<uint8_t>::FromVoid(buffer.Need(5));
182 		if (data.IsNull())
183 			return SignedSongTime::Negative();
184 	}
185 
186 	if (data.size >= 8 && adts_check_frame(data.data) > 0) {
187 		/* obtain the duration from the ADTS header */
188 
189 		if (!is.IsSeekable())
190 			return SignedSongTime::Negative();
191 
192 		auto song_length = adts_song_duration(buffer);
193 
194 		try {
195 			is.LockSeek(tagsize);
196 		} catch (...) {
197 		}
198 
199 		buffer.Clear();
200 
201 		return song_length;
202 	} else if (data.size >= 5 && memcmp(data.data, "ADIF", 4) == 0) {
203 		/* obtain the duration from the ADIF header */
204 
205 		if (!is.KnownSize())
206 			return SignedSongTime::Negative();
207 
208 		size_t skip_size = (data.data[4] & 0x80) ? 9 : 0;
209 
210 		if (8 + skip_size > data.size)
211 			/* not enough data yet; skip parsing this
212 			   header */
213 			return SignedSongTime::Negative();
214 
215 		unsigned bit_rate = ((data.data[4 + skip_size] & 0x0F) << 19) |
216 			(data.data[5 + skip_size] << 11) |
217 			(data.data[6 + skip_size] << 3) |
218 			(data.data[7 + skip_size] & 0xE0);
219 
220 		const auto size = is.GetSize();
221 		if (bit_rate == 0)
222 			return SignedSongTime::Negative();
223 
224 		return SongTime::FromScale(size, bit_rate / 8);
225 	} else
226 		return SignedSongTime::Negative();
227 }
228 
229 static NeAACDecHandle
faad_decoder_new()230 faad_decoder_new()
231 {
232 	auto decoder = NeAACDecOpen();
233 
234 	NeAACDecConfigurationPtr config =
235 		NeAACDecGetCurrentConfiguration(decoder);
236 	config->outputFormat = FAAD_FMT_16BIT;
237 	config->downMatrix = 1;
238 	config->dontUpSampleImplicitSBR = 0;
239 	NeAACDecSetConfiguration(decoder, config);
240 
241 	return decoder;
242 }
243 
244 /**
245  * Wrapper for NeAACDecInit() which works around some API
246  * inconsistencies in libfaad.
247  *
248  * Throws #std::runtime_error on error.
249  */
250 static void
faad_decoder_init(NeAACDecHandle decoder,DecoderBuffer & buffer,AudioFormat & audio_format)251 faad_decoder_init(NeAACDecHandle decoder, DecoderBuffer &buffer,
252 		  AudioFormat &audio_format)
253 {
254 	auto data = ConstBuffer<uint8_t>::FromVoid(buffer.Read());
255 	if (data.empty())
256 		throw std::runtime_error("Empty file");
257 
258 	uint8_t channels;
259 	unsigned long sample_rate;
260 	long nbytes = NeAACDecInit(decoder,
261 				   /* deconst hack, libfaad requires this */
262 				   const_cast<unsigned char *>(data.data),
263 				   data.size,
264 				   &sample_rate, &channels);
265 	if (nbytes < 0)
266 		throw std::runtime_error("Not an AAC stream");
267 
268 	buffer.Consume(nbytes);
269 
270 	audio_format = CheckAudioFormat(sample_rate, SampleFormat::S16,
271 					channels);
272 }
273 
274 /**
275  * Wrapper for NeAACDecDecode() which works around some API
276  * inconsistencies in libfaad.
277  */
278 static const void *
faad_decoder_decode(NeAACDecHandle decoder,DecoderBuffer & buffer,NeAACDecFrameInfo * frame_info)279 faad_decoder_decode(NeAACDecHandle decoder, DecoderBuffer &buffer,
280 		    NeAACDecFrameInfo *frame_info)
281 {
282 	auto data = ConstBuffer<uint8_t>::FromVoid(buffer.Read());
283 	if (data.empty())
284 		return nullptr;
285 
286 	return NeAACDecDecode(decoder, frame_info,
287 			      /* deconst hack, libfaad requires this */
288 			      const_cast<uint8_t *>(data.data),
289 			      data.size);
290 }
291 
292 /**
293  * Determine a song file's total playing time.
294  *
295  * The first return value specifies whether the file was recognized.
296  * The second return value is the duration.
297  */
298 static std::pair<bool, SignedSongTime>
faad_get_file_time(InputStream & is)299 faad_get_file_time(InputStream &is)
300 {
301 	DecoderBuffer buffer(nullptr, is,
302 			     FAAD_MIN_STREAMSIZE * MAX_CHANNELS);
303 	auto duration = faad_song_duration(buffer, is);
304 	bool recognized = !duration.IsNegative();
305 
306 	if (!recognized) {
307 		NeAACDecHandle decoder = faad_decoder_new();
308 		AtScopeExit(decoder) { NeAACDecClose(decoder); };
309 
310 		buffer.Fill();
311 
312 		AudioFormat audio_format;
313 		try {
314 			faad_decoder_init(decoder, buffer, audio_format);
315 			recognized = true;
316 		} catch (...) {
317 		}
318 	}
319 
320 	return {recognized, duration};
321 }
322 
323 static void
faad_stream_decode(DecoderClient & client,InputStream & is,DecoderBuffer & buffer,NeAACDecHandle decoder)324 faad_stream_decode(DecoderClient &client, InputStream &is,
325 		   DecoderBuffer &buffer, NeAACDecHandle decoder)
326 {
327 	const auto total_time = faad_song_duration(buffer, is);
328 
329 	if (adts_find_frame(buffer) == 0)
330 		return;
331 
332 	/* initialize it */
333 
334 	AudioFormat audio_format;
335 	faad_decoder_init(decoder, buffer, audio_format);
336 
337 	/* initialize the MPD core */
338 
339 	client.Ready(audio_format, false, total_time);
340 
341 	/* the decoder loop */
342 
343 	DecoderCommand cmd;
344 	unsigned bit_rate = 0;
345 	do {
346 		/* find the next frame */
347 
348 		const size_t frame_size = adts_find_frame(buffer);
349 		if (frame_size == 0)
350 			/* end of file */
351 			break;
352 
353 		/* decode it */
354 
355 		NeAACDecFrameInfo frame_info;
356 		const void *const decoded =
357 			faad_decoder_decode(decoder, buffer, &frame_info);
358 
359 		if (frame_info.error > 0) {
360 			FmtWarning(faad_decoder_domain,
361 				   "error decoding AAC stream: {}",
362 				   NeAACDecGetErrorMessage(frame_info.error));
363 			break;
364 		}
365 
366 		if (frame_info.channels != audio_format.channels) {
367 			FmtNotice(faad_decoder_domain,
368 				  "channel count changed from {} to {}",
369 				  audio_format.channels, frame_info.channels);
370 			break;
371 		}
372 
373 		if (frame_info.samplerate != audio_format.sample_rate) {
374 			FmtNotice(faad_decoder_domain,
375 				  "sample rate changed from {} to {}",
376 				  audio_format.sample_rate,
377 				  frame_info.samplerate);
378 			break;
379 		}
380 
381 		buffer.Consume(frame_info.bytesconsumed);
382 
383 		/* update bit rate and position */
384 
385 		if (frame_info.samples > 0) {
386 			bit_rate = lround(frame_info.bytesconsumed * 8.0 *
387 					  frame_info.channels * audio_format.sample_rate /
388 					  frame_info.samples / 1000);
389 		}
390 
391 		/* send PCM samples to MPD */
392 
393 		cmd = client.SubmitData(is, decoded,
394 					(size_t)frame_info.samples * 2,
395 					bit_rate);
396 	} while (cmd != DecoderCommand::STOP);
397 }
398 
399 static void
faad_stream_decode(DecoderClient & client,InputStream & is)400 faad_stream_decode(DecoderClient &client, InputStream &is)
401 {
402 	DecoderBuffer buffer(&client, is,
403 			     FAAD_MIN_STREAMSIZE * MAX_CHANNELS);
404 
405 	/* create the libfaad decoder */
406 
407 	auto decoder = faad_decoder_new();
408 	AtScopeExit(decoder) { NeAACDecClose(decoder); };
409 
410 	faad_stream_decode(client, is, buffer, decoder);
411 }
412 
413 static bool
faad_scan_stream(InputStream & is,TagHandler & handler)414 faad_scan_stream(InputStream &is, TagHandler &handler)
415 {
416 	auto result = faad_get_file_time(is);
417 	if (!result.first)
418 		return false;
419 
420 	if (!result.second.IsNegative())
421 		handler.OnDuration(SongTime(result.second));
422 	return true;
423 }
424 
425 static const char *const faad_suffixes[] = { "aac", nullptr };
426 static const char *const faad_mime_types[] = {
427 	"audio/aac", "audio/aacp", nullptr
428 };
429 
430 constexpr DecoderPlugin faad_decoder_plugin =
431 	DecoderPlugin("faad", faad_stream_decode, faad_scan_stream)
432 	.WithSuffixes(faad_suffixes)
433 	.WithMimeTypes(faad_mime_types);
434