Слияние кода завершено, страница обновится автоматически
/** @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 )