avoid memory leak at sound play

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-04-15 12:13:51 +03:00
parent 1f85d633c4
commit 0733b704ff
6 changed files with 64 additions and 42 deletions

View File

@ -3739,8 +3739,8 @@ XTheme::GetThemeTagSettings (void* DictP)
#if XCINEMA
Dict = GetProperty (DictPointer, "Anime");
if (Dict != NULL) {
INTN i, Count = GetTagCount (Dict);
for (i = 0; i < Count; i++) {
INTN Count = GetTagCount (Dict);
for (INTN i = 0; i < Count; i++) {
FILM *NewFilm = new FILM();
if (EFI_ERROR (GetElement (Dict, i, &Dict3))) {
continue;
@ -3797,10 +3797,13 @@ XTheme::GetThemeTagSettings (void* DictP)
Dict2 = GetProperty (Dict3, "Once");
NewFilm->RunOnce = IsPropertyTrue (Dict2);
NewFilm->GetFrames(ThemeX); //used properties: ID, Path, NumFrames
ThemeX.Cinema.AddFilm(NewFilm);
// delete NewFilm; //looks like already deleted
}
}
#else
Dict = GetProperty (DictPointer, "Anime");
@ -4165,7 +4168,7 @@ finish:
Status = StartupSoundPlay(ThemeX.ThemeDir, NULL);
} else { // theme loaded successfully
ThemeX.embedded = false;
ThemeX.Theme.takeValueFrom(GlobalConfig.Theme);
ThemeX.Theme.takeValueFrom(GlobalConfig.Theme); //XStringW from CHAR16*)
// read theme settings
if (!ThemeX.TypeSVG) {
TagPtr DictPointer = GetProperty(ThemeDict, "Theme");

View File

@ -69,25 +69,34 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
UINT8 OutputIndex = (OldChosenAudio & 0xFF);
UINT8 OutputVolume = DefaultAudioVolume;
UINT16 *TempData = NULL;
BOOLEAN AllocAsPage = FALSE;
if (!AudioIo) {
Status = EFI_DEVICE_ERROR;
// DBG("not found AudioIo to play\n");
goto DONE_ERROR;
}
if (SoundFile) {
Status = egLoadFile(Dir, SoundFile, &FileData, &FileDataLength);
if (EFI_ERROR(Status)) {
DBG("file sound read: %ls %s\n", SoundFile, strerror(Status));
// DBG("file sound read: %ls %s\n", SoundFile, strerror(Status));
return Status;
}
} else {
FileData = EmbeddedSound;
FileDataLength = EmbeddedSoundLength;
DBG("got embedded sound\n");
// DBG("got embedded sound\n");
}
WaveData.Samples = NULL;
Status = WaveGetFileData(FileData, (UINT32)FileDataLength, &WaveData);
Status = WaveGetFileData(FileData, (UINT32)FileDataLength, &WaveData); //
if (EFI_ERROR(Status)) {
MsgLog(" wrong sound file, wave status=%s\n", strerror(Status));
//if error then data not allocated
return Status;
}
AllocAsPage = TRUE;
MsgLog(" Channels: %u Sample rate: %u Hz Bits: %u\n", WaveData.Format->Channels, WaveData.Format->SamplesPerSec, WaveData.Format->BitsPerSample);
EFI_AUDIO_IO_PROTOCOL_BITS bits;
@ -108,7 +117,7 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
bits = EfiAudioIoBits32;
break;
default:
return EFI_UNSUPPORTED;
goto DONE_ERROR;
}
EFI_AUDIO_IO_PROTOCOL_FREQ freq;
@ -144,14 +153,14 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
freq = EfiAudioIoFreq192kHz;
break;
default:
return EFI_UNSUPPORTED;
goto DONE_ERROR;
}
DBG("output to channel %d with volume %d, len=%d\n", OutputIndex, OutputVolume, WaveData.SamplesLength);
DBG(" sound channels=%d bits=%d freq=%d\n", WaveData.Format->Channels, WaveData.Format->BitsPerSample, WaveData.Format->SamplesPerSec);
if (!WaveData.SamplesLength || !OutputVolume) {
// DBG("nothing to play\n");
// DBG("nothing to play\n"); //but data allocated
Status = EFI_NOT_FOUND;
goto DONE_ERROR;
}
@ -185,16 +194,11 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
WaveData.SamplesLength *= 6;
DBG("sound converted to 48kHz\n");
WaveData.Samples = (UINT8*)TempData;
AllocAsPage = FALSE;
} else {
TempData = (UINT16*)WaveData.Samples;
}
if (!AudioIo) {
Status = EFI_DEVICE_ERROR;
// DBG("not found AudioIo to play\n");
goto DONE_ERROR;
}
// Setup playback.
if (OutputIndex > AudioNum) {
OutputIndex = 0;
@ -210,13 +214,13 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
// Start playback.
if (gSettings.PlayAsync) {
Status = AudioIo->StartPlaybackAsync(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0, NULL, NULL);
DBG("async started, status=%s\n", strerror(Status));
// DBG("async started, status=%s\n", strerror(Status));
} else {
Status = AudioIo->StartPlayback(AudioIo, (UINT8*)TempData, WaveData.SamplesLength, 0);
// DBG("sync started, status=%s\n", strerror(Status));
if (!EFI_ERROR(Status)) {
FreePool(TempData);
}
// if (!EFI_ERROR(Status)) {
// FreePool(TempData);
// }
}
if (EFI_ERROR(Status)) {
@ -224,10 +228,20 @@ StartupSoundPlay(EFI_FILE *Dir, CONST CHAR16* SoundFile)
}
DONE_ERROR:
// here we have memory leak with TempData == WaveData.Samples
// TempData allocated as AllocatePool while Samples allocated as AllocatePages
// and we can't keep the info up to stop AsyncPlay
if (FileData && SoundFile) { //dont free embedded sound
// DBG("free sound\n");
FreePool(FileData);
}
if (!gSettings.PlayAsync) { //dont free sound when async play
if (AllocAsPage) {
FreePages(WaveData.Samples,EFI_SIZE_TO_PAGES(WaveData.SamplesLength+4095));
} else {
FreePool(TempData);
}
}
DBG("sound play end with status=%s\n", strerror(Status));
return Status;
}

View File

@ -11,17 +11,20 @@
#include "XCinema.h"
#include "../gui/REFIT_MENU_SCREEN.h"
#ifndef DEBUG_ALL
#define DEBUG_CINEMA 1
#else
#define DEBUG_CINEMA DEBUG_ALL
#endif
#if DEBUG_CINEMA == 0
#define DBG(...)
#else
#define DBG(...) DebugLog(DEBUG_CINEMA, __VA_ARGS__)
#endif
//Screen.UpdateAnime(); called from Menu cycle wait for event
//Now = AsmReadTsc();
//if (TimeDiff(LastDraw, Now) < FrameTime) return;
//if (Film[CurrentFrame]) { Draw }
// else skip draw
// CurrentFrame++;
//if (CurrentFrame >= Frames) {
// AnimeRun = !Once;
// CurrentFrame = 0;
//}
//LastDraw = Now;
// object XCinema::Cinema is a part of Theme
// object FILM::FilmX is a part or current Screen. Must be initialized from Cinema somewhere on Screen init
@ -51,7 +54,9 @@ VOID REFIT_MENU_SCREEN::UpdateFilm()
#endif
FILM* XCinema::GetFilm(INTN Id)
{
DBG("ask film %lld\n", Id);
for (size_t i = 0; i < Cinema.size(); ++i) {
DBG("check film %lld\n", Cinema[i].GetIndex());
if (Cinema[i].GetIndex() == Id) {
return &Cinema[i];
}
@ -67,8 +72,10 @@ void XCinema::AddFilm(FILM* NewFilm)
static XImage NullImage;
const XImage& FILM::GetImage(INTN Index) const
{
DBG("ask for frame #%lld\n", Index);
for (size_t i = 0; i < Frames.size(); ++i) {
if (Frames[i].getIndex() == Index) {
DBG("...found\n");
return Frames[i].getImage();
}
}
@ -85,7 +92,6 @@ const XImage& FILM::GetImage() const
return NullImage;
}
void FILM::AddFrame(XImage* Frame, INTN Index)
{
IndexedImage* NewFrame = new IndexedImage(Index);
@ -107,9 +113,11 @@ void FILM::GetFrames(XTheme& TheTheme /*, const XStringW& Path*/) // Path alread
Status = TheTheme.LoadSvgFrame(Index, &NewImage);
} else {
XStringW Name = SWPrintf("%ls\\%ls_%03lld.png", Path.wc_str(), Path.wc_str(), Index);
// DBG("try to load %ls\n", Name.wc_str()); //fine
if (FileExists(ThemeDir, Name.wc_str())) {
Status = NewImage.LoadXImage(ThemeDir, Name);
}
// DBG(" read status=%s\n", strerror(Status));
}
if (!EFI_ERROR(Status)) {
AddFrame(&NewImage, Index);

View File

@ -10,7 +10,7 @@
#include "../refit/menu.h"
#ifndef DEBUG_ALL
#define DEBUG_MOUSE 1
#define DEBUG_MOUSE 0
#else
#define DEBUG_MOUSE DEBUG_ALL
#endif

View File

@ -2861,7 +2861,7 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
fontChain = fontChain->next;
}
if (!fontChain && fontChainSimilar) { //font with this style is not found but we have same font with other style
DBG("found similar font with style=%c\n", fontChainSimilar->font->fontStyle);
// DBG("found similar font with style=%c\n", fontChainSimilar->font->fontStyle);
fontChain = fontChainSimilar;
fontSVG = fontChain->font;
}
@ -2871,13 +2871,11 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
UINTN FileDataLength = 0;
NSVGparser *p1 = NULL;
EFI_STATUS Status;
DBG("required font %s not found, try to load external\n", text->fontFace->fontFamily);
// CONST CHAR16 *FontFileName = PoolPrint(L"%a.svg", text->fontFace->fontFamily);
// DBG("required font %s not found, try to load external\n", text->fontFace->fontFamily);
XStringW FontFileName = XStringW().takeValueFrom(text->fontFace->fontFamily) + L".svg"_XSW;
DBG(" file name =%ls\n", FontFileName.wc_str());
// DBG(" file name =%ls\n", FontFileName.wc_str());
Status = egLoadFile(ThemeX.ThemeDir, FontFileName.wc_str(), &FileData, &FileDataLength);
// FreePool(FontFileName);
DBG(" font %s loaded status=%lld, %s\n", text->fontFace->fontFamily, Status, strerror(Status));
// DBG(" font %s loaded status=%lld, %s\n", text->fontFace->fontFamily, Status, strerror(Status));
if (!EFI_ERROR(Status)) {
p1 = nsvgParse((CHAR8*)FileData, 72, 1.0f); //later we will free parser p1
if (!p1) {
@ -2923,7 +2921,7 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
textFace[1].size = (INTN)text->fontSize;
textFace[1].color = text->fontColor;
textFace[1].valid = TRUE;
DBG("set message->font=%s color=%X size=%f as in MessageRow\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
DBG("set message_night->font=%s color=%X size=%f as in MessageRow\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
break;
} else if (strcmp(group->id, "MenuRows") == 0) {
if (!textFace[2].valid) {
@ -2954,15 +2952,12 @@ static void nsvg__parseText(NSVGparser* p, const char** dict)
textFace[0].size = (INTN)text->fontSize;
textFace[0].color = text->fontColor;
textFace[0].valid = TRUE;
DBG("set help->font=%s color=%X size=%f as in HelpRows\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
DBG("set help_night->font=%s color=%X size=%f as in HelpRows\n", fontSVG->fontFamily, text->fontColor, text->fontSize);
break;
}
group = group->next;
}
}
// if ((!text->font || !text->font->glyphs) && fontsDB) {
// text->font = fontsDB->font; //first found
// }
//add to head
text->next = p->text;

View File

@ -482,11 +482,13 @@ INTN HybridRepositioning(INTN Edge, INTN Value, INTN ImageDimension, INTN Screen
BOOLEAN REFIT_MENU_SCREEN::GetAnime()
{
FilmC = ThemeX.Cinema.GetFilm(ID);
DBG("ScreenID=%lld Film found=%d\n", ID, (FilmC != nullptr)?1:0);
return FilmC != nullptr;
}
VOID REFIT_MENU_SCREEN::InitAnime()
{
if (FilmC && (FilmC->FilmX >=0) && (FilmC->FilmX <=100) &&
(FilmC->FilmY >=0) && (FilmC->FilmY <=100)) {
// Check if screen size being used is different from theme origination size.