FreeRDP
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 
39 static 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 
76 static 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 
165 static 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 
206 static 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 
253 static 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 
304 int 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 
334 void 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 
356 ssize_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 
377 static 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 
405 int 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 
502 ssize_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 
531 ssize_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 
562 ssize_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 }