mirror of https://github.com/red-prig/fpPS4.git
Minor avplayer optimization (#101)
* Check for file size instead to determine if we need to update cache or not * Reduce amount of alloc/free/move data around * Embed file size into cache fmv name
This commit is contained in:
parent
af25023e5d
commit
865d4d6c97
|
@ -265,6 +265,8 @@ type
|
|||
lastAudioTimeStamp :QWord;
|
||||
audioBuffer :array[0..BUFFER_COUNT-1] of PSmallInt;
|
||||
videoBuffer :array[0..BUFFER_COUNT-1] of PByte;
|
||||
audioChunk,
|
||||
videoChunk :TMemChunk;
|
||||
durationInMs :QWord;
|
||||
streamCount :DWord;
|
||||
videoStreamId :Integer;
|
||||
|
@ -384,6 +386,28 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure _FreeChunk(var chunk:TMemChunk);
|
||||
begin
|
||||
if chunk.pAddr<>nil then
|
||||
begin
|
||||
FreeMem(chunk.pAddr);
|
||||
chunk.pAddr:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _CompareAndAllocChunk(var chunk:TMemChunk;const nSize:QWord);
|
||||
begin
|
||||
if nSize<>chunk.nSize then
|
||||
begin
|
||||
if chunk.pAddr<>nil then
|
||||
begin
|
||||
FreeMem(chunk.pAddr);
|
||||
end;
|
||||
chunk.pAddr:=AllocMem(nSize);
|
||||
chunk.nSize:=nSize;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure AvHandleClean(data,userdata:Pointer);
|
||||
var
|
||||
handle:SceAvPlayerHandle;
|
||||
|
@ -591,6 +615,8 @@ begin
|
|||
|
||||
audioPackets:=TAVPacketQueue.Create;
|
||||
videoPackets:=TAVPacketQueue.Create;
|
||||
audioChunk:=Default(TMemChunk);
|
||||
videoChunk:=Default(TMemChunk);
|
||||
end;
|
||||
|
||||
procedure TAvPlayerState.FreeMedia;
|
||||
|
@ -615,6 +641,8 @@ begin
|
|||
end;
|
||||
audioPackets.Free;
|
||||
videoPackets.Free;
|
||||
_FreeChunk(audioChunk);
|
||||
_FreeChunk(videoChunk);
|
||||
|
||||
if videoCodecContext<>nil then
|
||||
begin
|
||||
|
@ -688,12 +716,12 @@ var
|
|||
frame :PAVFrame;
|
||||
i, j :Integer;
|
||||
fdata :PSingle;
|
||||
nsize :QWord;
|
||||
pcmSample:SmallInt;
|
||||
begin
|
||||
Result:=Default(TMemChunk);
|
||||
if (audioStreamId<0) or ((not ignoreIsPlaying) and (not IsPlaying)) then Exit;
|
||||
frame:=av_frame_alloc;
|
||||
Result.pAddr:=nil;
|
||||
while True do
|
||||
begin
|
||||
err:=avcodec_receive_frame(audioCodecContext,frame);
|
||||
|
@ -711,18 +739,19 @@ begin
|
|||
channelCount:=frame^.channels;
|
||||
sampleCount:=frame^.nb_samples;
|
||||
sampleRate:=frame^.sample_rate;
|
||||
Result.nSize:=sampleCount*channelCount*SizeOf(SmallInt);
|
||||
GetMem(Result.pAddr,Result.nSize);
|
||||
nsize:=sampleCount*channelCount*SizeOf(SmallInt);
|
||||
_CompareAndAllocChunk(audioChunk,nsize);
|
||||
for i:=0 to sampleCount-1 do
|
||||
for j:=0 to channelCount-1 do
|
||||
begin
|
||||
fdata:=PSingle(frame^.data[j]);
|
||||
pcmSample:=Floor(fdata[i]*High(SmallInt));
|
||||
PSmallInt(Result.pAddr)[i*channelCount+j]:=pcmSample;
|
||||
PSmallInt(audioChunk.pAddr)[i*channelCount+j]:=pcmSample;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
av_frame_free(frame);
|
||||
Result:=audioChunk;
|
||||
end;
|
||||
|
||||
function TAvPlayerState.ReceiveVideo:TMemChunk;
|
||||
|
@ -732,6 +761,7 @@ var
|
|||
j :Integer;
|
||||
i :Integer;
|
||||
fdata :PSingle;
|
||||
nsize :QWord;
|
||||
sample :Single;
|
||||
pcmSamplex:Word;
|
||||
p :PByte;
|
||||
|
@ -739,7 +769,6 @@ begin
|
|||
Result:=Default(TMemChunk);
|
||||
if (videoStreamId<0) or (not IsPlaying) then Exit;
|
||||
frame:=av_frame_alloc;
|
||||
Result.pAddr:=nil;
|
||||
while True do
|
||||
begin
|
||||
err:=avcodec_receive_frame(videoCodecContext,frame);
|
||||
|
@ -754,27 +783,30 @@ begin
|
|||
if frame^.format<>Integer(AV_PIX_FMT_YUV420P) then
|
||||
Writeln(StdErr,'ERROR: Unknown video format: ',frame^.format);
|
||||
lastVideoTimeStamp:=av_rescale_q(frame^.best_effort_timestamp,formatContext^.streams[videoStreamId]^.time_base,AV_TIME_BASE_Q);
|
||||
Result.nSize:=videoCodecContext^.width*videoCodecContext^.height*3 div 2;
|
||||
GetMem(Result.pAddr,Result.nSize);
|
||||
|
||||
p:=Result.pAddr;
|
||||
for i:=0 to frame^.height-1 do
|
||||
nsize:=videoCodecContext^.width*videoCodecContext^.height*3 div 2;
|
||||
_CompareAndAllocChunk(videoChunk,nsize);
|
||||
if lastVideoTimeStamp>=lastAudioTimeStamp then // Only copy frame when video is synced with audio
|
||||
begin
|
||||
Move(frame^.data[0][frame^.linesize[0]*i],p[0],frame^.width);
|
||||
p:=p+frame^.width;
|
||||
end;
|
||||
for i:=0 to frame^.height div 2-1 do
|
||||
begin
|
||||
for j:=0 to frame^.width div 2-1 do
|
||||
p:=videoChunk.pAddr;
|
||||
for i:=0 to frame^.height-1 do
|
||||
begin
|
||||
p[0]:=frame^.data[1][frame^.linesize[1]*i+j];
|
||||
p[1]:=frame^.data[2][frame^.linesize[2]*i+j];
|
||||
p:=p+2;
|
||||
Move(frame^.data[0][frame^.linesize[0]*i],p[0],frame^.width);
|
||||
p:=p+frame^.width;
|
||||
end;
|
||||
for i:=0 to frame^.height div 2-1 do
|
||||
begin
|
||||
for j:=0 to frame^.width div 2-1 do
|
||||
begin
|
||||
p[0]:=frame^.data[1][frame^.linesize[1]*i+j];
|
||||
p[1]:=frame^.data[2][frame^.linesize[2]*i+j];
|
||||
p:=p+2;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
av_frame_free(frame);
|
||||
Result:=videoChunk;
|
||||
end;
|
||||
|
||||
function TAvPlayerState.GetFramerate:QWord;
|
||||
|
@ -809,7 +841,6 @@ begin
|
|||
audioBuffer[0]:=playerInfo.Allocate(32,chunk.nSize);
|
||||
end;
|
||||
Move(chunk.pAddr^,audioBuffer[0]^,chunk.nSize);
|
||||
FreeMem(chunk.pAddr);
|
||||
end;
|
||||
Exit(audioBuffer[0]);
|
||||
end else
|
||||
|
@ -821,7 +852,6 @@ begin
|
|||
videoBuffer[0]:=playerInfo.AllocateTexture(32,chunk.nSize);
|
||||
end;
|
||||
Move(chunk.pAddr^,videoBuffer[0]^,chunk.nSize);
|
||||
FreeMem(chunk.pAddr);
|
||||
end;
|
||||
Exit(videoBuffer[0]);
|
||||
end;
|
||||
|
@ -934,6 +964,18 @@ var
|
|||
f :THandle;
|
||||
path,
|
||||
source :RawByteString;
|
||||
|
||||
function getFileSize(aFileName:RawByteString):Int64;
|
||||
var
|
||||
info:TSearchRec;
|
||||
begin
|
||||
if FindFirst(aFileName,0,info)=0 then
|
||||
Result:=Info.Size
|
||||
else
|
||||
Result:=-1;
|
||||
FindClose(info);
|
||||
end;
|
||||
|
||||
begin
|
||||
if DISABLE_FMV_HACK then
|
||||
Exit(-1);
|
||||
|
@ -962,8 +1004,8 @@ begin
|
|||
path:=DIRECTORY_AVPLAYER_DUMP+'/'+param_sfo.ParamSfoGetString('TITLE_ID');
|
||||
CreateDir(path);
|
||||
//
|
||||
source:=path+'/'+ExtractFileName(argFilename);
|
||||
if not FileExists(source) then
|
||||
source:=path+'/'+IntToStr(fileSize)+'_'+ExtractFileName(argFilename);
|
||||
if fileSize<>getFileSize(source) then
|
||||
begin
|
||||
f:=FileCreate(source,fmOpenWrite);
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue