FreeRDP
Loading...
Searching...
No Matches
dsp_fdk_impl.c
1
21#include <assert.h>
22#include <string.h>
23#include <stdio.h>
24#include <limits.h>
25#include <inttypes.h>
26
27#include <fdk-aac/aacdecoder_lib.h>
28#include <fdk-aac/aacenc_lib.h>
29
30#include "dsp_fdk_impl.h"
31
32#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 202003L))
33#define nullptr NULL
34#endif
35
36// #define WLOG_TRACE 0
37#define WLOG_DEBUG 1
38// #define WLOG_INFO 2
39#define WLOG_WARN 3
40#define WLOG_ERROR 4
41// #define WLOG_FATAL 5
42
43static const char* enc_err_str(AACENC_ERROR err)
44{
45 switch (err)
46 {
47 case AACENC_OK:
48 return "AACENC_OK";
49 case AACENC_INVALID_HANDLE:
50 return "AACENC_INVALID_HANDLE";
51 case AACENC_MEMORY_ERROR:
52 return "AACENC_MEMORY_ERROR";
53 case AACENC_UNSUPPORTED_PARAMETER:
54 return "AACENC_UNSUPPORTED_PARAMETER";
55 case AACENC_INVALID_CONFIG:
56 return "AACENC_INVALID_CONFIG";
57 case AACENC_INIT_ERROR:
58 return "AACENC_INIT_ERROR";
59 case AACENC_INIT_AAC_ERROR:
60 return "AACENC_INIT_AAC_ERROR";
61 case AACENC_INIT_SBR_ERROR:
62 return "AACENC_INIT_SBR_ERROR";
63 case AACENC_INIT_TP_ERROR:
64 return "AACENC_INIT_TP_ERROR";
65 case AACENC_INIT_META_ERROR:
66 return "AACENC_INIT_META_ERROR";
67#ifdef AACENC_INIT_MPS_ERROR
68 case AACENC_INIT_MPS_ERROR:
69 return "AACENC_INIT_MPS_ERROR";
70#endif
71 case AACENC_ENCODE_ERROR:
72 return "AACENC_ENCODE_ERROR";
73 case AACENC_ENCODE_EOF:
74 return "AACENC_ENCODE_EOF";
75 default:
76 return "AACENC_UNKNOWN";
77 }
78}
79
80static const char* dec_err_str(AAC_DECODER_ERROR err)
81{
82 switch (err)
83 {
84 case AAC_DEC_OK:
85 return "AAC_DEC_OK";
86 case AAC_DEC_OUT_OF_MEMORY:
87 return "AAC_DEC_OUT_OF_MEMORY";
88 case AAC_DEC_UNKNOWN:
89 return "AAC_DEC_UNKNOWN";
90 case aac_dec_sync_error_start:
91 return "aac_dec_sync_error_start";
92 case AAC_DEC_TRANSPORT_SYNC_ERROR:
93 return "AAC_DEC_TRANSPORT_SYNC_ERROR";
94 case AAC_DEC_NOT_ENOUGH_BITS:
95 return "AAC_DEC_NOT_ENOUGH_BITS";
96 case aac_dec_sync_error_end:
97 return "aac_dec_sync_error_end";
98 case aac_dec_init_error_start:
99 return "aac_dec_init_error_start";
100 case AAC_DEC_INVALID_HANDLE:
101 return "AAC_DEC_INVALID_HANDLE";
102 case AAC_DEC_UNSUPPORTED_FORMAT:
103 return "AAC_DEC_UNSUPPORTED_FORMAT";
104 case AAC_DEC_UNSUPPORTED_ER_FORMAT:
105 return "AAC_DEC_UNSUPPORTED_ER_FORMAT";
106 case AAC_DEC_UNSUPPORTED_EPCONFIG:
107 return "AAC_DEC_UNSUPPORTED_EPCONFIG";
108 case AAC_DEC_UNSUPPORTED_MULTILAYER:
109 return "AAC_DEC_UNSUPPORTED_MULTILAYER";
110 case AAC_DEC_UNSUPPORTED_CHANNELCONFIG:
111 return "AAC_DEC_UNSUPPORTED_CHANNELCONFIG";
112 case AAC_DEC_UNSUPPORTED_SAMPLINGRATE:
113 return "AAC_DEC_UNSUPPORTED_SAMPLINGRATE";
114 case AAC_DEC_INVALID_SBR_CONFIG:
115 return "AAC_DEC_INVALID_SBR_CONFIG";
116 case AAC_DEC_SET_PARAM_FAIL:
117 return "AAC_DEC_SET_PARAM_FAIL";
118 case AAC_DEC_NEED_TO_RESTART:
119 return "AAC_DEC_NEED_TO_RESTART";
120 case AAC_DEC_OUTPUT_BUFFER_TOO_SMALL:
121 return "AAC_DEC_OUTPUT_BUFFER_TOO_SMALL";
122 case aac_dec_init_error_end:
123 return "aac_dec_init_error_end";
124 case aac_dec_decode_error_start:
125 return "aac_dec_decode_error_start";
126 case AAC_DEC_TRANSPORT_ERROR:
127 return "AAC_DEC_TRANSPORT_ERROR";
128 case AAC_DEC_PARSE_ERROR:
129 return "AAC_DEC_PARSE_ERROR";
130 case AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD:
131 return "AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD";
132 case AAC_DEC_DECODE_FRAME_ERROR:
133 return "AAC_DEC_DECODE_FRAME_ERROR";
134 case AAC_DEC_CRC_ERROR:
135 return "AAC_DEC_CRC_ERROR";
136 case AAC_DEC_INVALID_CODE_BOOK:
137 return "AAC_DEC_INVALID_CODE_BOOK";
138 case AAC_DEC_UNSUPPORTED_PREDICTION:
139 return "AAC_DEC_UNSUPPORTED_PREDICTION";
140 case AAC_DEC_UNSUPPORTED_CCE:
141 return "AAC_DEC_UNSUPPORTED_CCE";
142 case AAC_DEC_UNSUPPORTED_LFE:
143 return "AAC_DEC_UNSUPPORTED_LFE";
144 case AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA:
145 return "AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA";
146 case AAC_DEC_UNSUPPORTED_SBA:
147 return "AAC_DEC_UNSUPPORTED_SBA";
148 case AAC_DEC_TNS_READ_ERROR:
149 return "AAC_DEC_TNS_READ_ERROR";
150 case AAC_DEC_RVLC_ERROR:
151 return "AAC_DEC_RVLC_ERROR";
152 case aac_dec_decode_error_end:
153 return "aac_dec_decode_error_end";
154 case aac_dec_anc_data_error_start:
155 return "aac_dec_anc_data_error_start";
156 case AAC_DEC_ANC_DATA_ERROR:
157 return "AAC_DEC_ANC_DATA_ERROR";
158 case AAC_DEC_TOO_SMALL_ANC_BUFFER:
159 return "AAC_DEC_TOO_SMALL_ANC_BUFFER";
160 case AAC_DEC_TOO_MANY_ANC_ELEMENTS:
161 return "AAC_DEC_TOO_MANY_ANC_ELEMENTS";
162 case aac_dec_anc_data_error_end:
163 return "aac_dec_anc_data_error_end";
164 default:
165 return "AAC_DEC unknown value";
166 }
167}
168
169static void log_dec_info(const CStreamInfo* info, fdk_log_fkt_t log)
170{
171 assert(info);
172 assert(log);
173
174 log(WLOG_DEBUG,
175 "info:"
176 "aacSampleRate: %d, "
177 "frameSize: %d, "
178 "numChannels: %d, "
179 "pChannelType: %p, "
180 "pChannelIndices: %p, "
181 "aacSampleRate: %d, "
182 "profile: %d, "
183 "aot: %d, " /* TODO: Enum 2 string */
184 "channelConfig: %d, "
185 "bitRate: %d, "
186 "aacSamplesPerFrame: %d, "
187 "aacNumChannels: %d, "
188 "extAot: %d" /* TODO: Enum 2 string */
189 "extSamplingRate: %d, "
190 "outputDelay: %u, "
191 "flags: %u, "
192 "epConfig: %d, "
193 "numLostAccessUnits: %d, "
194 "numTotalBytes: %" PRIu64 ", "
195 "numBadBytes: %" PRIu64 ", "
196 "numTotalAccessUnits: %" PRIu64 ", "
197 "numBadAccessUnits: %" PRIu64 ", "
198 "drcProgRefLev: %d, "
199 "drcPresMode: %d, ",
200 info->aacSampleRate, info->frameSize, info->numChannels, info->pChannelType,
201 info->pChannelIndices, info->aacSampleRate, info->profile, info->aot, info->channelConfig,
202 info->bitRate, info->aacSamplesPerFrame, info->aacNumChannels, info->extAot,
203 info->extSamplingRate, info->outputDelay, info->flags, (int)info->epConfig,
204 info->numLostAccessUnits,
205
206 info->numTotalBytes, info->numBadBytes, info->numTotalAccessUnits, info->numBadAccessUnits,
207
208 (int)info->drcProgRefLev, (int)info->drcPresMode);
209}
210
211static void log_enc_info(const AACENC_InfoStruct* info, fdk_log_fkt_t log)
212{
213 char confBuf[1024] = { 0 };
214
215 assert(info);
216 assert(log);
217
218 size_t offset = 0;
219 size_t remain = sizeof(confBuf) - 1;
220 int rc = snprintf(confBuf, remain, "{");
221 if (rc <= 0)
222 return;
223 offset += (size_t)rc;
224
225 for (size_t x = 0; x < 64; x++)
226 {
227 rc = snprintf(&confBuf[offset], remain - offset, "0x%02x%s", (unsigned)info->confBuf[x],
228 (x > 0) ? ", " : "");
229 if (rc <= 0)
230 return;
231 }
232
233 rc = snprintf(confBuf, remain - offset, "}");
234 if (rc <= 0)
235 return;
236
237 log(WLOG_DEBUG,
238 "[encoder info] "
239 "maxOutBufBytes : %u, "
240 "maxAncBytes : %u, "
241 "inBufFillLevel : %u, "
242 "inputChannels : %u, "
243 "frameLength : %u, "
244#ifdef MODE_7_1_BACK
245 "nDelay : %u, "
246 "nDelayCore : %u, "
247#endif
248 "confBuf[64] : %s, "
249 "confSize : %u",
250 info->maxOutBufBytes, info->maxAncBytes, info->inBufFillLevel, info->inputChannels,
251 info->frameLength,
252#ifdef MODE_7_1_BACK
253 info->nDelay, info->nDelayCore,
254#endif
255 confBuf, info->confSize);
256}
257
258static const char* aac_enc_param_str(AACENC_PARAM param)
259{
260 switch (param)
261 {
262 case AACENC_AOT:
263 return "AACENC_AOT";
264 case AACENC_BITRATE:
265 return "AACENC_BITRATE";
266 case AACENC_BITRATEMODE:
267 return "AACENC_BITRATEMODE";
268 case AACENC_SAMPLERATE:
269 return "AACENC_SAMPLERATE";
270 case AACENC_SBR_MODE:
271 return "AACENC_SBR_MODE";
272 case AACENC_GRANULE_LENGTH:
273 return "AACENC_GRANULE_LENGTH";
274 case AACENC_CHANNELMODE:
275 return "AACENC_CHANNELMODE";
276 case AACENC_CHANNELORDER:
277 return "AACENC_CHANNELORDER";
278 case AACENC_SBR_RATIO:
279 return "AACENC_SBR_RATIO";
280 case AACENC_AFTERBURNER:
281 return "AACENC_AFTERBURNER";
282 case AACENC_BANDWIDTH:
283 return "AACENC_BANDWIDTH";
284 case AACENC_PEAK_BITRATE:
285 return "AACENC_PEAK_BITRATE";
286 case AACENC_TRANSMUX:
287 return "AACENC_TRANSMUX";
288 case AACENC_HEADER_PERIOD:
289 return "AACENC_HEADER_PERIOD";
290 case AACENC_SIGNALING_MODE:
291 return "AACENC_SIGNALING_MODE";
292 case AACENC_TPSUBFRAMES:
293 return "AACENC_TPSUBFRAMES";
294 case AACENC_AUDIOMUXVER:
295 return "AACENC_AUDIOMUXVER";
296 case AACENC_PROTECTION:
297 return "AACENC_PROTECTION";
298 case AACENC_ANCILLARY_BITRATE:
299 return "AACENC_ANCILLARY_BITRATE";
300 case AACENC_METADATA_MODE:
301 return "AACENC_METADATA_MODE";
302 case AACENC_CONTROL_STATE:
303 return "AACENC_CONTROL_STATE";
304 default:
305 return "AACENC_UNKNOWN";
306 }
307}
308
309int fdk_aac_dsp_impl_init(void** handle, int encoder, fdk_log_fkt_t log)
310{
311 assert(handle);
312 assert(log);
313
314 if (encoder)
315 {
316 HANDLE_AACENCODER* h = (HANDLE_AACENCODER*)handle;
317 AACENC_ERROR err = aacEncOpen(h, 0, 0);
318 if (err != AACENC_OK)
319 {
320 log(WLOG_ERROR, "aacEncOpen failed with %s", enc_err_str(err));
321 return 0;
322 }
323 }
324 else
325 {
326 HANDLE_AACDECODER* h = (HANDLE_AACDECODER*)handle;
327 assert(nullptr == *h);
328
329 *h = aacDecoder_Open(TT_MP4_RAW, 1);
330 if (!*h)
331 {
332 log(WLOG_ERROR, "aacDecoder_Open failed");
333 return 0;
334 }
335 }
336 return 1;
337}
338
339void fdk_aac_dsp_impl_uninit(void** handle, int encoder, fdk_log_fkt_t log)
340{
341 assert(handle);
342 assert(log);
343
344 if (encoder)
345 {
346 HANDLE_AACENCODER* h = (HANDLE_AACENCODER*)handle;
347 AACENC_ERROR err = aacEncClose(h);
348 if (err != AACENC_OK)
349 log(WLOG_ERROR, "aacEncClose failed with %s", enc_err_str(err));
350 }
351 else
352 {
353 HANDLE_AACDECODER* h = (HANDLE_AACDECODER*)handle;
354 if (h)
355 aacDecoder_Close(*h);
356 }
357
358 *handle = nullptr;
359}
360
361ssize_t fdk_aac_dsp_impl_decode_read(void* handle, void* dst, size_t dstSize, fdk_log_fkt_t log)
362{
363 assert(handle);
364 assert((dstSize / sizeof(INT_PCM)) <= INT_MAX);
365
366 const INT nrsamples = (INT)(dstSize / sizeof(INT_PCM));
367 UINT flags = 0;
368 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
369 AAC_DECODER_ERROR err = aacDecoder_DecodeFrame(self, dst, nrsamples, flags);
370 switch (err)
371 {
372 case AAC_DEC_OK:
373 return fdk_aac_dsp_impl_stream_info(handle, 0, log);
374 case AAC_DEC_NOT_ENOUGH_BITS:
375 return 0;
376 default:
377 log(WLOG_WARN, "aacDecoder_DecodeFrame failed with %s, discarding...",
378 dec_err_str(err));
379 return 0;
380 }
381}
382
383static unsigned get_channelmode(unsigned channels)
384{
385 switch (channels)
386 {
387 case 1:
388 return MODE_1;
389 case 2:
390 return MODE_2;
391 case 3:
392 return MODE_1_2;
393 case 4:
394 return MODE_1_2_1;
395 case 5:
396 return MODE_1_2_2;
397 case 6:
398 return MODE_1_2_2_1;
399 case 7:
400 return MODE_1_2_2_2_1;
401#ifdef MODE_7_1_BACK
402 case 8:
403 return MODE_7_1_BACK;
404#endif
405
406 default:
407 return MODE_2;
408 }
409}
410
411int fdk_aac_dsp_impl_config(void* handle, size_t* pbuffersize, int encoder, unsigned samplerate,
412 unsigned channels, unsigned bytes_per_second,
413 unsigned frames_per_packet, fdk_log_fkt_t log)
414{
415 assert(handle);
416 assert(log);
417 assert(pbuffersize);
418
419 log(WLOG_DEBUG,
420 "fdk_aac_dsp_impl_config: samplerate: %ld, channels: %ld, bytes_pers_second: %ld",
421 samplerate, channels, bytes_per_second);
422
423 struct t_param_pair
424 {
425 AACENC_PARAM param;
426 UINT value;
427 };
428
429 const struct t_param_pair params[] = {
430 { AACENC_AOT, 2 },
431 { AACENC_SAMPLERATE, samplerate },
432 { AACENC_CHANNELMODE, get_channelmode(channels) },
433 { AACENC_CHANNELORDER, 0 },
434 { AACENC_BITRATE, bytes_per_second * 8 },
435 { AACENC_TRANSMUX, 0 },
436 { AACENC_AFTERBURNER, 1 }
437 // The value supplied via RDP of 441 packets is not compatible, so skip this here.
438 //, { AACENC_GRANULE_LENGTH, frames_per_packet }
439 };
440
441 HANDLE_AACENCODER self = nullptr;
442 if (encoder)
443 self = (HANDLE_AACENCODER)handle;
444 else
445 {
446 AACENC_ERROR err = aacEncOpen(&self, 0, channels);
447 if (err != AACENC_OK)
448 {
449 log(WLOG_ERROR, "aacEncOpen failed with %s", enc_err_str(err));
450 return -1;
451 }
452 }
453
454 for (size_t x = 0; x < sizeof(params) / sizeof(params[0]); x++)
455 {
456 const struct t_param_pair* param = &params[x];
457
458 AACENC_ERROR err = aacEncoder_SetParam(self, param->param, param->value);
459 if (err != AACENC_OK)
460 {
461 log(WLOG_ERROR, "aacEncoder_SetParam(%s, %d) failed with %s",
462 aac_enc_param_str(param->param), param->value, enc_err_str(err));
463 return -1;
464 }
465 }
466
467 AACENC_ERROR err = aacEncEncode(self, nullptr, nullptr, nullptr, nullptr);
468 if (err != AACENC_OK)
469 {
470 log(WLOG_ERROR, "aacEncEncode failed with %s", enc_err_str(err));
471 return -1;
472 }
473
474 AACENC_InfoStruct info = { 0 };
475 err = aacEncInfo(self, &info);
476 if (err != AACENC_OK)
477 {
478 log(WLOG_ERROR, "aacEncInfo failed with %s", enc_err_str(err));
479 return -1;
480 }
481
482 if (encoder)
483 {
484 *pbuffersize = info.maxOutBufBytes;
485 log_enc_info(&info, log);
486 return 0;
487 }
488 else
489 {
490 err = aacEncClose(&self);
491 if (err != AACENC_OK)
492 log(WLOG_WARN, "aacEncClose failed with %s", enc_err_str(err));
493
494 *pbuffersize = sizeof(INT_PCM) * info.frameLength * info.inputChannels;
495
496 HANDLE_AACDECODER aacdec = (HANDLE_AACDECODER)handle;
497
498 UCHAR* asc[] = { info.confBuf };
499 UINT ascSize[] = { info.confSize };
500
501 assert(handle);
502
503 AAC_DECODER_ERROR decerr = aacDecoder_ConfigRaw(aacdec, asc, ascSize);
504 if (decerr != AAC_DEC_OK)
505 {
506 log(WLOG_ERROR, "aacDecoder_ConfigRaw failed with %s", dec_err_str(decerr));
507 return -1;
508 }
509 return 0;
510 }
511}
512
513ssize_t fdk_aac_dsp_impl_decode_fill(void* handle, const void* data, size_t size, fdk_log_fkt_t log)
514{
515 assert(handle);
516 assert(log);
517 assert(size <= UINT_MAX);
518 UINT leftBytes = (UINT)size;
519 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
520
521 union
522 {
523 const void* cpv;
524 UCHAR* puc;
525 } cnv;
526 cnv.cpv = data;
527 UCHAR* pBuffer[] = { cnv.puc };
528 const UINT bufferSize[] = { leftBytes };
529
530 assert(handle);
531 assert(data || (size == 0));
532
533 AAC_DECODER_ERROR err = aacDecoder_Fill(self, pBuffer, bufferSize, &leftBytes);
534 if (err != AAC_DEC_OK)
535 {
536 log(WLOG_ERROR, "aacDecoder_Fill failed with %s", dec_err_str(err));
537 return -1;
538 }
539 return leftBytes;
540}
541
542ssize_t fdk_aac_dsp_impl_stream_info(void* handle, int encoder, fdk_log_fkt_t log)
543{
544 assert(handle);
545 assert(log);
546
547 if (encoder)
548 {
549 AACENC_InfoStruct info = { 0 };
550 HANDLE_AACENCODER self = (HANDLE_AACENCODER)handle;
551 AACENC_ERROR err = aacEncInfo(self, &info);
552 if (err != AACENC_OK)
553 {
554 log(WLOG_ERROR, "aacEncInfo failed with %s", enc_err_str(err));
555 return -1;
556 }
557 return info.maxOutBufBytes;
558 }
559 else
560 {
561 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
562 CStreamInfo* info = aacDecoder_GetStreamInfo(self);
563 if (!info)
564 {
565 log(WLOG_ERROR, "aacDecoder_GetStreamInfo failed");
566 return -1;
567 }
568 log_dec_info(info, log);
569 if (info->numChannels <= 0)
570 return -1;
571 if (info->frameSize <= 0)
572 return -1;
573 const size_t rsize = sizeof(INT_PCM) * (size_t)info->numChannels * (size_t)info->frameSize;
574 return (ssize_t)rsize;
575 }
576}
577
578ssize_t fdk_aac_dsp_impl_encode(void* handle, const void* data, size_t size, void* dst,
579 size_t dstSize, fdk_log_fkt_t log)
580{
581 INT inSizes[] = { (INT)size };
582 INT inElSizes[] = { sizeof(INT_PCM) };
583 INT inIdentifiers[] = { IN_AUDIO_DATA };
584 union
585 {
586 const void* cpv;
587 void* pv;
588 } cnv;
589 cnv.cpv = data;
590 void* inBuffers[] = { cnv.pv };
591
592 const AACENC_BufDesc inBufDesc = {
593 .numBufs = 1,
594 .bufs = inBuffers,
595 .bufferIdentifiers = inIdentifiers,
596 .bufSizes = inSizes,
597 .bufElSizes = inElSizes /* TODO: 8/16 bit input? */
598 };
599
600 INT outSizes[] = { (INT)dstSize };
601 INT outElSizes[] = { 1 };
602 INT outIdentifiers[] = { OUT_BITSTREAM_DATA };
603 void* outBuffers[] = { dst };
604 const AACENC_BufDesc outBufDesc = { .numBufs = 1,
605 .bufs = outBuffers,
606 .bufferIdentifiers = outIdentifiers,
607 .bufSizes = outSizes,
608 .bufElSizes = outElSizes };
609
610 const AACENC_InArgs inArgs = { .numInSamples =
611 (INT)(size / sizeof(INT_PCM)), /* TODO: 8/16 bit input? */
612 .numAncBytes = 0 };
613 AACENC_OutArgs outArgs = { 0 };
614
615 HANDLE_AACENCODER self = (HANDLE_AACENCODER)handle;
616
617 assert(handle);
618 assert(log);
619
620 AACENC_ERROR err = aacEncEncode(self, &inBufDesc, &outBufDesc, &inArgs, &outArgs);
621 if (err != AACENC_OK)
622 {
623 log(WLOG_ERROR, "aacEncEncode failed with %s", enc_err_str(err));
624 return -1;
625 }
626 return outArgs.numOutBytes;
627}