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