FreeRDP
dsp_fdk_aac.c
1 
21 #include "dsp_fdk_aac.h"
22 #include "dsp_fdk_impl.h"
23 
24 #include <freerdp/log.h>
25 #define TAG FREERDP_TAG("dsp.fdk")
26 
27 static void write_log(unsigned log_level, const char* fmt, ...)
28 {
29  wLog* log = WLog_Get(TAG);
30 
31  if (WLog_IsLevelActive(log, log_level))
32  {
33  char buffer[1024] = { 0 };
34 
35  va_list ap = { 0 };
36  va_start(ap, fmt);
37  vsnprintf(buffer, sizeof(buffer), fmt, ap);
38  va_end(ap);
39 
40  WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, log_level, __LINE__, __FILE__, __func__, "%s",
41  buffer);
42  }
43 }
44 
45 BOOL fdk_aac_dsp_encode(FREERDP_DSP_COMMON_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
46  const BYTE* data, size_t length, wStream* out)
47 {
48  WINPR_ASSERT(context);
49  WINPR_ASSERT(srcFormat);
50 
51  if (srcFormat->wFormatTag != WAVE_FORMAT_PCM)
52  {
53  WLog_WARN(TAG, "Feeding %s format data to encoder function, but require %s",
54  audio_format_get_tag_string(srcFormat->wFormatTag),
55  audio_format_get_tag_string(WAVE_FORMAT_PCM));
56  return FALSE;
57  }
58 
59  if (!context->fdkSetup)
60  {
61  ssize_t rc = fdk_aac_dsp_impl_config(
62  context->fdkAacInstance, &context->buffersize, context->encoder,
63  context->format.nSamplesPerSec, context->format.nChannels,
64  context->format.nAvgBytesPerSec, context->frames_per_packet, write_log);
65  if (rc < 0)
66  return FALSE;
67 
68  context->fdkSetup = TRUE;
69  }
70 
71  if (!Stream_EnsureRemainingCapacity(out, context->buffersize))
72  return FALSE;
73 
74  {
75  const ssize_t encoded =
76  fdk_aac_dsp_impl_encode(context->fdkAacInstance, data, length, Stream_Pointer(out),
77  Stream_GetRemainingCapacity(out), write_log);
78  if (encoded < 0)
79  return FALSE;
80  Stream_Seek(out, (size_t)encoded);
81  return TRUE;
82  }
83 }
84 
85 BOOL fdk_aac_dsp_decode(FREERDP_DSP_COMMON_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
86  const BYTE* data, size_t length, wStream* out)
87 {
88  WINPR_ASSERT(context);
89  WINPR_ASSERT(srcFormat);
90 
91  if (srcFormat->wFormatTag != WAVE_FORMAT_AAC_MS)
92  {
93  WLog_WARN(TAG, "Feeding %s format data to encoder function, but require %s",
94  audio_format_get_tag_string(srcFormat->wFormatTag),
95  audio_format_get_tag_string(WAVE_FORMAT_AAC_MS));
96  return FALSE;
97  }
98 
99  if (!context->fdkSetup)
100  {
101  ssize_t rc = fdk_aac_dsp_impl_config(
102  context->fdkAacInstance, &context->buffersize, context->encoder,
103  context->format.nSamplesPerSec, context->format.nChannels,
104  context->format.nAvgBytesPerSec, context->frames_per_packet, write_log);
105  if (rc < 0)
106  return FALSE;
107 
108  context->fdkSetup = TRUE;
109  }
110 
111  ssize_t rest = 0;
112  do
113  {
114  rest = fdk_aac_dsp_impl_decode_fill(context->fdkAacInstance, data, length, write_log);
115  if (rest < 0)
116  {
117  WLog_WARN(TAG, "DecodeFill() failed");
118  return FALSE;
119  }
120 
121  ssize_t ret = -1;
122  do
123  {
124  const size_t expect = context->buffersize;
125  if (!Stream_EnsureRemainingCapacity(out, expect))
126  return FALSE;
127 
128  ret = fdk_aac_dsp_impl_decode_read(context->fdkAacInstance, Stream_Pointer(out), expect,
129  write_log);
130  if (ret < 0)
131  return FALSE;
132 
133  Stream_Seek(out, (size_t)ret);
134  } while (ret > 0);
135  } while (rest > 0);
136 
137  return TRUE;
138 }
139 
140 void fdk_aac_dsp_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
141 {
142  WINPR_ASSERT(context);
143 
144  fdk_aac_dsp_impl_uninit(&context->fdkAacInstance, context->encoder, write_log);
145 }
146 
147 BOOL fdk_aac_dsp_init(FREERDP_DSP_COMMON_CONTEXT* context, size_t frames_per_packet)
148 {
149  WINPR_ASSERT(context);
150  context->fdkSetup = FALSE;
151  WINPR_ASSERT(frames_per_packet <= UINT_MAX);
152  context->frames_per_packet = (unsigned)frames_per_packet;
153  return fdk_aac_dsp_impl_init(&context->fdkAacInstance, context->encoder, write_log);
154 }