1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/zsl588-OpenCorePkg

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
OcMp3Lib.c 5.1 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
vit9696 Отправлено 4 лет назад f9abab4
/** @file
Copyright (C) 2021, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcMp3Lib.h>
#include "helix/mp3dec.h"
/**
Ensure that buffer always has enough memory to hold one frame.
@param[in,out] Buffer Pointer to buffer memory.
@param[in,out] BufferCurr Pointer to buffer current position.
@param[in,out] BufferSize Pointer to buffer size.
@retval TRUE on success.
@retval FALSE on allocation falure.
**/
STATIC
BOOLEAN
BufferResize (
IN OUT VOID **Buffer,
IN OUT VOID **BufferCurr,
IN OUT UINT32 *BufferSize
)
{
UINT32 OrgSize;
UINT32 OrgOffset;
UINT32 RemainingSize;
VOID *NewBuffer;
if (*BufferSize == 0) {
OrgOffset = 0;
RemainingSize = 0;
} else {
OrgOffset = (UINT32) ((UINTN) *BufferCurr - (UINTN) *Buffer);
RemainingSize = *BufferSize - OrgOffset;
}
if (RemainingSize >= MAX_NCHAN * MAX_NGRAN * MAX_NSAMP) {
return TRUE;
}
if (*BufferSize == 0) {
*BufferSize = MAX_NCHAN * MAX_NGRAN * MAX_NSAMP * 10;
*BufferCurr = *Buffer = AllocatePool (*BufferSize);
return *Buffer != NULL;
}
OrgSize = *BufferSize;
if (OcOverflowMulU32 (OrgSize, 2, BufferSize)) {
FreePool (*Buffer);
return FALSE;
}
ASSERT (OrgSize + MAX_NCHAN * MAX_NGRAN * MAX_NSAMP <= *BufferSize);
NewBuffer = ReallocatePool (
OrgSize,
*BufferSize,
*Buffer
);
if (NewBuffer == NULL) {
FreePool (*Buffer);
return FALSE;
}
*Buffer = NewBuffer;
*BufferCurr = (UINT8 *) NewBuffer + OrgOffset;
return TRUE;
}
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
)
{
HMP3Decoder Decoder;
MP3FrameInfo FrameInfo;
unsigned char *Walker;
VOID *OutBufferCurr;
int ErrorCode;
int BytesLeft;
int SyncOffset;
Decoder = MP3InitDecoder ();
if (Decoder == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ZeroMem (&FrameInfo, sizeof (FrameInfo));
Walker = (VOID *) InBuffer;
BytesLeft = (int) InBufferSize;
*OutBuffer = NULL;
OutBufferCurr = NULL;
*OutBufferSize = 0;
while (BytesLeft > 0) {
//
// Find next frame.
//
SyncOffset = MP3FindSyncWord (
Walker,
BytesLeft
);
if (SyncOffset < 0) {
//
// Not a valid file.
//
if (OutBufferCurr == NULL) {
MP3FreeDecoder (Decoder);
return EFI_OUT_OF_RESOURCES;
}
break;
}
Walker += SyncOffset;
BytesLeft -= SyncOffset;
if (!BufferResize (OutBuffer, &OutBufferCurr, OutBufferSize)) {
MP3FreeDecoder (Decoder);
return EFI_OUT_OF_RESOURCES;
}
ErrorCode = MP3Decode (
Decoder,
&Walker,
&BytesLeft,
OutBufferCurr,
0
);
//
// Do nothing, we will get enough data on the next frame.
//
if (ErrorCode == ERR_MP3_MAINDATA_UNDERFLOW) {
continue;
}
if (ErrorCode < 0) {
MP3FreeDecoder (Decoder);
FreePool (*OutBuffer);
return EFI_UNSUPPORTED;
}
MP3GetLastFrameInfo (Decoder, &FrameInfo);
OutBufferCurr = (UINT8 *) OutBufferCurr + FrameInfo.bitsPerSample / 8 * FrameInfo.outputSamps;
}
MP3FreeDecoder (Decoder);
switch (FrameInfo.bitsPerSample) {
case 8:
*Bits = EfiAudioIoBits8;
break;
case 16:
*Bits = EfiAudioIoBits16;
break;
case 20:
*Bits = EfiAudioIoBits16;
break;
case 24:
*Bits = EfiAudioIoBits24;
break;
case 32:
*Bits = EfiAudioIoBits32;
break;
default:
FreePool (*OutBuffer);
return EFI_UNSUPPORTED;
}
switch (FrameInfo.samprate) {
case 8000:
*Frequency = EfiAudioIoFreq8kHz;
break;
case 11025:
*Frequency = EfiAudioIoFreq11kHz;
break;
case 22050:
*Frequency = EfiAudioIoFreq22kHz;
break;
case 32000:
*Frequency = EfiAudioIoFreq32kHz;
break;
case 44100:
*Frequency = EfiAudioIoFreq44kHz;
break;
case 48000:
*Frequency = EfiAudioIoFreq48kHz;
break;
default:
FreePool (*OutBuffer);
return EFI_UNSUPPORTED;
}
*Channels = (UINT8) FrameInfo.nChans;
*OutBufferSize = (UINT32) ((UINT8 *) OutBufferCurr - (UINT8 *) *OutBuffer);
return EFI_SUCCESS;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/zsl588-OpenCorePkg.git
git@gitlife.ru:oschina-mirror/zsl588-OpenCorePkg.git
oschina-mirror
zsl588-OpenCorePkg
zsl588-OpenCorePkg
0.7.7