FreeRDP
Loading...
Searching...
No Matches
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
27WINPR_ATTR_FORMAT_ARG(2, 3)
28static void write_log(unsigned log_level, WINPR_FORMAT_ARG const char* fmt, ...)
29{
30 wLog* log = WLog_Get(TAG);
31
32 if (WLog_IsLevelActive(log, log_level))
33 {
34 char buffer[1024] = WINPR_C_ARRAY_INIT;
35
36 va_list ap = WINPR_C_ARRAY_INIT;
37 va_start(ap, fmt);
38 (void)vsnprintf(buffer, sizeof(buffer), fmt, ap);
39 va_end(ap);
40
41 WLog_PrintTextMessage(log, log_level, __LINE__, __FILE__, __func__, "%s", buffer);
42 }
43}
44
45BOOL 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 size_t offset = 0;
75 while (offset < length)
76 {
77 size_t consumed = 0;
78 const ssize_t encoded = fdk_aac_dsp_impl_encode(
79 context->fdkAacInstance, &data[offset], length - offset, Stream_Pointer(out),
80 Stream_GetRemainingCapacity(out), &consumed, write_log);
81 if ((encoded < 0) || (consumed == 0))
82 return FALSE;
83 Stream_Seek(out, (size_t)encoded);
84 offset += consumed;
85 }
86 return TRUE;
87}
88
89BOOL fdk_aac_dsp_decode(FREERDP_DSP_COMMON_CONTEXT* context, const AUDIO_FORMAT* srcFormat,
90 const BYTE* data, size_t length, wStream* out)
91{
92 WINPR_ASSERT(context);
93 WINPR_ASSERT(srcFormat);
94
95 if (srcFormat->wFormatTag != WAVE_FORMAT_AAC_MS)
96 {
97 WLog_WARN(TAG, "Feeding %s format data to encoder function, but require %s",
98 audio_format_get_tag_string(srcFormat->wFormatTag),
99 audio_format_get_tag_string(WAVE_FORMAT_AAC_MS));
100 return FALSE;
101 }
102
103 if (!context->fdkSetup)
104 {
105 ssize_t rc = fdk_aac_dsp_impl_config(
106 context->fdkAacInstance, &context->buffersize, context->encoder,
107 context->format.nSamplesPerSec, context->format.nChannels,
108 context->format.nAvgBytesPerSec, context->frames_per_packet, write_log);
109 if (rc < 0)
110 return FALSE;
111
112 context->fdkSetup = TRUE;
113 }
114
115 ssize_t rest = 0;
116 do
117 {
118 rest = fdk_aac_dsp_impl_decode_fill(context->fdkAacInstance, data, length, write_log);
119 if (rest < 0)
120 {
121 WLog_WARN(TAG, "DecodeFill() failed");
122 return FALSE;
123 }
124
125 ssize_t ret = -1;
126 do
127 {
128 const size_t expect = context->buffersize;
129 if (!Stream_EnsureRemainingCapacity(out, expect))
130 return FALSE;
131
132 ret = fdk_aac_dsp_impl_decode_read(context->fdkAacInstance, Stream_Pointer(out), expect,
133 write_log);
134 if (ret < 0)
135 return FALSE;
136
137 Stream_Seek(out, (size_t)ret);
138 } while (ret > 0);
139 } while (rest > 0);
140
141 return TRUE;
142}
143
144void fdk_aac_dsp_uninit(FREERDP_DSP_COMMON_CONTEXT* context)
145{
146 WINPR_ASSERT(context);
147
148 fdk_aac_dsp_impl_uninit(&context->fdkAacInstance, context->encoder, write_log);
149}
150
151BOOL fdk_aac_dsp_init(FREERDP_DSP_COMMON_CONTEXT* context, size_t frames_per_packet)
152{
153 WINPR_ASSERT(context);
154 context->fdkSetup = FALSE;
155 WINPR_ASSERT(frames_per_packet <= UINT_MAX);
156 context->frames_per_packet = (unsigned)frames_per_packet;
157 return fdk_aac_dsp_impl_init(&context->fdkAacInstance, context->encoder, write_log);
158}