OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcMp3Lib.c
Go to the documentation of this file.
1
15#include <Uefi.h>
16
17#include <Library/BaseMemoryLib.h>
18#include <Library/BaseOverflowLib.h>
19#include <Library/DebugLib.h>
20#include <Library/MemoryAllocationLib.h>
21#include <Library/OcMp3Lib.h>
22#include "helix/mp3dec.h"
23
34STATIC
35BOOLEAN
37 IN OUT VOID **Buffer,
38 IN OUT VOID **BufferCurr,
39 IN OUT UINT32 *BufferSize
40 )
41{
42 UINT32 OrgSize;
43 UINT32 OrgOffset;
44 UINT32 RemainingSize;
45 VOID *NewBuffer;
46
47 if (*BufferSize == 0) {
48 OrgOffset = 0;
49 RemainingSize = 0;
50 } else {
51 OrgOffset = (UINT32)((UINTN)*BufferCurr - (UINTN)*Buffer);
52 RemainingSize = *BufferSize - OrgOffset;
53 }
54
55 if (RemainingSize >= MAX_NCHAN * MAX_NGRAN * MAX_NSAMP) {
56 return TRUE;
57 }
58
59 if (*BufferSize == 0) {
60 *BufferSize = MAX_NCHAN * MAX_NGRAN * MAX_NSAMP * 10;
61 *BufferCurr = *Buffer = AllocatePool (*BufferSize);
62 return *Buffer != NULL;
63 }
64
65 OrgSize = *BufferSize;
66 if (BaseOverflowMulU32 (OrgSize, 2, BufferSize)) {
67 FreePool (*Buffer);
68 return FALSE;
69 }
70
71 ASSERT (OrgSize + MAX_NCHAN * MAX_NGRAN * MAX_NSAMP <= *BufferSize);
72
73 NewBuffer = ReallocatePool (
74 OrgSize,
75 *BufferSize,
76 *Buffer
77 );
78 if (NewBuffer == NULL) {
79 FreePool (*Buffer);
80 return FALSE;
81 }
82
83 *Buffer = NewBuffer;
84 *BufferCurr = (UINT8 *)NewBuffer + OrgOffset;
85 return TRUE;
86}
87
88EFI_STATUS
90 IN CONST VOID *InBuffer,
91 IN UINT32 InBufferSize,
92 OUT VOID **OutBuffer,
93 OUT UINT32 *OutBufferSize,
94 OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
96 OUT UINT8 *Channels
97 )
98{
99 HMP3Decoder Decoder;
100 MP3FrameInfo FrameInfo;
101 unsigned char *Walker;
102 VOID *OutBufferCurr;
103 int ErrorCode;
104 int BytesLeft;
105 int SyncOffset;
106
107 Decoder = MP3InitDecoder ();
108 if (Decoder == NULL) {
109 return EFI_OUT_OF_RESOURCES;
110 }
111
112 ZeroMem (&FrameInfo, sizeof (FrameInfo));
113
114 Walker = (VOID *)InBuffer;
115 BytesLeft = (int)InBufferSize;
116 *OutBuffer = NULL;
117 OutBufferCurr = NULL;
118 *OutBufferSize = 0;
119
120 while (BytesLeft > 0) {
121 //
122 // Find next frame.
123 //
124 SyncOffset = MP3FindSyncWord (
125 Walker,
126 BytesLeft
127 );
128 if (SyncOffset < 0) {
129 //
130 // Not a valid file.
131 //
132 if (OutBufferCurr == NULL) {
133 MP3FreeDecoder (Decoder);
134 return EFI_OUT_OF_RESOURCES;
135 }
136
137 break;
138 }
139
140 Walker += SyncOffset;
141 BytesLeft -= SyncOffset;
142
143 if (!BufferResize (OutBuffer, &OutBufferCurr, OutBufferSize)) {
144 MP3FreeDecoder (Decoder);
145 return EFI_OUT_OF_RESOURCES;
146 }
147
148 ErrorCode = MP3Decode (
149 Decoder,
150 &Walker,
151 &BytesLeft,
152 OutBufferCurr,
153 0
154 );
155
156 //
157 // Do nothing, we will get enough data on the next frame.
158 //
159 if (ErrorCode == ERR_MP3_MAINDATA_UNDERFLOW) {
160 continue;
161 }
162
163 if (ErrorCode < 0) {
164 MP3FreeDecoder (Decoder);
165 FreePool (*OutBuffer);
166 return EFI_UNSUPPORTED;
167 }
168
169 MP3GetLastFrameInfo (Decoder, &FrameInfo);
170 OutBufferCurr = (UINT8 *)OutBufferCurr + FrameInfo.bitsPerSample / 8 * FrameInfo.outputSamps;
171 }
172
173 MP3FreeDecoder (Decoder);
174
175 switch (FrameInfo.bitsPerSample) {
176 case 8:
177 *Bits = EfiAudioIoBits8;
178 break;
179 case 16:
180 *Bits = EfiAudioIoBits16;
181 break;
182 case 20:
183 *Bits = EfiAudioIoBits16;
184 break;
185 case 24:
186 *Bits = EfiAudioIoBits24;
187 break;
188 case 32:
189 *Bits = EfiAudioIoBits32;
190 break;
191 default:
192 FreePool (*OutBuffer);
193 return EFI_UNSUPPORTED;
194 }
195
196 switch (FrameInfo.samprate) {
197 case 8000:
198 *Frequency = EfiAudioIoFreq8kHz;
199 break;
200 case 11025:
201 *Frequency = EfiAudioIoFreq11kHz;
202 break;
203 case 22050:
204 *Frequency = EfiAudioIoFreq22kHz;
205 break;
206 case 32000:
207 *Frequency = EfiAudioIoFreq32kHz;
208 break;
209 case 44100:
210 *Frequency = EfiAudioIoFreq44kHz;
211 break;
212 case 48000:
213 *Frequency = EfiAudioIoFreq48kHz;
214 break;
215 default:
216 FreePool (*OutBuffer);
217 return EFI_UNSUPPORTED;
218 }
219
220 *Channels = (UINT8)FrameInfo.nChans;
221 *OutBufferSize = (UINT32)((UINT8 *)OutBufferCurr - (UINT8 *)*OutBuffer);
222
223 return EFI_SUCCESS;
224}
EFI_AUDIO_IO_PROTOCOL_FREQ
Definition AudioIo.h:104
@ EfiAudioIoFreq11kHz
Definition AudioIo.h:106
@ EfiAudioIoFreq22kHz
Definition AudioIo.h:108
@ EfiAudioIoFreq44kHz
Definition AudioIo.h:110
@ EfiAudioIoFreq48kHz
Definition AudioIo.h:111
@ EfiAudioIoFreq32kHz
Definition AudioIo.h:109
@ EfiAudioIoFreq8kHz
Definition AudioIo.h:105
EFI_AUDIO_IO_PROTOCOL_BITS
Definition AudioIo.h:93
@ EfiAudioIoBits24
Definition AudioIo.h:97
@ EfiAudioIoBits16
Definition AudioIo.h:95
@ EfiAudioIoBits8
Definition AudioIo.h:94
@ EfiAudioIoBits32
Definition AudioIo.h:98
EFI_STATUS OcDecodeMp3(IN CONST VOID *InBuffer, IN UINT32 InBufferSize, OUT VOID **OutBuffer, OUT UINT32 *OutBufferSize, OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency, OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits, OUT UINT8 *Channels)
Definition OcMp3Lib.c:89
STATIC BOOLEAN BufferResize(IN OUT VOID **Buffer, IN OUT VOID **BufferCurr, IN OUT UINT32 *BufferSize)
Definition OcMp3Lib.c:36
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55
void MP3GetLastFrameInfo(HMP3Decoder hMP3Decoder, MP3FrameInfo *mp3FrameInfo)
Definition mp3dec.c:189
int MP3Decode(HMP3Decoder hMP3Decoder, unsigned char **inbuf, int *bytesLeft, short *outbuf, int useSize)
Definition mp3dec.c:285
void MP3FreeDecoder(HMP3Decoder hMP3Decoder)
Definition mp3dec.c:86
HMP3Decoder MP3InitDecoder(void)
Definition mp3dec.c:65
int MP3FindSyncWord(unsigned char *buf, int nBytes)
Definition mp3dec.c:109
#define MAX_NCHAN
Definition mp3dec.h:79
void * HMP3Decoder
Definition mp3dec.h:89
@ ERR_MP3_MAINDATA_UNDERFLOW
Definition mp3dec.h:94
#define MAX_NGRAN
Definition mp3dec.h:78
#define MAX_NSAMP
Definition mp3dec.h:80
int outputSamps
Definition mp3dec.h:114
int bitsPerSample
Definition mp3dec.h:113