aboutsummaryrefslogtreecommitdiffstats
path: root/Lua/src/media
diff options
context:
space:
mode:
authorwhiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-12-11 17:34:54 +0000
committerwhiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>2009-12-11 17:34:54 +0000
commit1ab628e8ad6c85c8f1b562f10480253ee3e622b7 (patch)
treed21621f68850ecd7762137e1c4387fa15731a811 /Lua/src/media
parent6ec275387c320d3d9a8f5b6fe185687643565b8c (diff)
downloadusdx-1ab628e8ad6c85c8f1b562f10480253ee3e622b7.tar.gz
usdx-1ab628e8ad6c85c8f1b562f10480253ee3e622b7.tar.xz
usdx-1ab628e8ad6c85c8f1b562f10480253ee3e622b7.zip
merged trunk into lua branch
plugin loading is disabled atm because of a bug reading the files (lua may be the reason). Reading the files in usdx and passing the contents to lua may solve this git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2019 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Lua/src/media')
-rw-r--r--Lua/src/media/UAudioConverter.pas14
-rw-r--r--Lua/src/media/UAudioCore_Bass.pas12
-rw-r--r--Lua/src/media/UAudioDecoder_Bass.pas25
-rw-r--r--Lua/src/media/UAudioDecoder_FFmpeg.pas68
-rw-r--r--Lua/src/media/UAudioInput_Bass.pas7
-rw-r--r--Lua/src/media/UAudioInput_Portaudio.pas3
-rw-r--r--Lua/src/media/UAudioPlaybackBase.pas23
-rw-r--r--Lua/src/media/UAudioPlayback_Bass.pas24
-rw-r--r--Lua/src/media/UAudioPlayback_SDL.pas14
-rw-r--r--Lua/src/media/UAudioPlayback_SoftMixer.pas44
-rw-r--r--Lua/src/media/UMediaCore_FFmpeg.pas124
-rw-r--r--Lua/src/media/UMedia_dummy.pas15
-rw-r--r--Lua/src/media/UVideo.pas79
-rw-r--r--Lua/src/media/UVisualizer.pas20
14 files changed, 328 insertions, 144 deletions
diff --git a/Lua/src/media/UAudioConverter.pas b/Lua/src/media/UAudioConverter.pas
index 24131b16..657b80dd 100644
--- a/Lua/src/media/UAudioConverter.pas
+++ b/Lua/src/media/UAudioConverter.pas
@@ -70,7 +70,7 @@ type
function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
destructor Destroy(); override;
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer; override;
function GetOutputBufferSize(InputSize: integer): integer; override;
function GetRatio(): double; override;
end;
@@ -87,7 +87,7 @@ type
function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
destructor Destroy(); override;
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer; override;
function GetOutputBufferSize(InputSize: integer): integer; override;
function GetRatio(): double; override;
end;
@@ -103,7 +103,7 @@ type
function Init(SrcFormatInfo: TAudioFormatInfo; DstFormatInfo: TAudioFormatInfo): boolean; override;
destructor Destroy(); override;
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; override;
+ function Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer; override;
function GetOutputBufferSize(InputSize: integer): integer; override;
function GetRatio(): double; override;
end;
@@ -173,7 +173,7 @@ begin
Result := cvt.len_ratio;
end;
-function TAudioConverter_SDL.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+function TAudioConverter_SDL.Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer;
begin
Result := -1;
@@ -242,7 +242,7 @@ begin
inherited;
end;
-function TAudioConverter_FFmpeg.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+function TAudioConverter_FFmpeg.Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer;
var
InputSampleCount: integer;
OutputSampleCount: integer;
@@ -360,11 +360,11 @@ begin
inherited;
end;
-function TAudioConverter_SRC.Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer;
+function TAudioConverter_SRC.Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer;
var
FloatInputBuffer: PSingle;
FloatOutputBuffer: PSingle;
- TempBuffer: PChar;
+ TempBuffer: PByteArray;
TempSize: integer;
NumSamples: integer;
OutputSize: integer;
diff --git a/Lua/src/media/UAudioCore_Bass.pas b/Lua/src/media/UAudioCore_Bass.pas
index 12623dc1..197f9760 100644
--- a/Lua/src/media/UAudioCore_Bass.pas
+++ b/Lua/src/media/UAudioCore_Bass.pas
@@ -44,6 +44,7 @@ type
public
constructor Create();
class function GetInstance(): TAudioCore_Bass;
+ function CheckVersion(): boolean;
function ErrorGetString(): string; overload;
function ErrorGetString(errCode: integer): string; overload;
function ConvertAudioFormatToBASSFlags(Format: TAudioSampleFormat; out Flags: DWORD): boolean;
@@ -56,6 +57,12 @@ uses
UMain,
ULog;
+const
+ // TODO: 2.4.2 is not ABI compatible with older versions
+ // as (BASS_RECORDINFO.driver was removed)
+ //BASS_MIN_REQUIRED_VERSION = $02040201;
+ BASS_MIN_REQUIRED_VERSION = $02000000;
+
var
Instance: TAudioCore_Bass;
@@ -71,6 +78,11 @@ begin
Result := Instance;
end;
+function TAudioCore_Bass.CheckVersion(): boolean;
+begin
+ Result := BASS_GetVersion() >= BASS_MIN_REQUIRED_VERSION;
+end;
+
function TAudioCore_Bass.ErrorGetString(): string;
begin
Result := ErrorGetString(BASS_ErrorGetCode());
diff --git a/Lua/src/media/UAudioDecoder_Bass.pas b/Lua/src/media/UAudioDecoder_Bass.pas
index 3c31175d..d6d2425a 100644
--- a/Lua/src/media/UAudioDecoder_Bass.pas
+++ b/Lua/src/media/UAudioDecoder_Bass.pas
@@ -38,11 +38,12 @@ implementation
uses
Classes,
SysUtils,
+ bass,
UMain,
UMusic,
UAudioCore_Bass,
ULog,
- bass;
+ UPath;
type
TBassDecodeStream = class(TAudioDecodeStream)
@@ -65,7 +66,7 @@ type
function IsEOF(): boolean; override;
function IsError(): boolean; override;
- function ReadData(Buffer: PChar; BufSize: integer): integer; override;
+ function ReadData(Buffer: PByteArray; BufSize: integer): integer; override;
end;
type
@@ -75,7 +76,7 @@ type
function InitializeDecoder(): boolean;
function FinalizeDecoder(): boolean;
- function Open(const Filename: string): TAudioDecodeStream;
+ function Open(const Filename: IPath): TAudioDecodeStream;
end;
var
@@ -193,7 +194,7 @@ begin
Result := Error;
end;
-function TBassDecodeStream.ReadData(Buffer: PChar; BufSize: integer): integer;
+function TBassDecodeStream.ReadData(Buffer: PByteArray; BufSize: integer): integer;
begin
Result := BASS_ChannelGetData(Handle, Buffer, BufSize);
// check error state (do not handle EOF as error)
@@ -213,7 +214,10 @@ end;
function TAudioDecoder_Bass.InitializeDecoder(): boolean;
begin
+ Result := false;
BassCore := TAudioCore_Bass.GetInstance();
+ if not BassCore.CheckVersion then
+ Exit;
Result := true;
end;
@@ -222,7 +226,7 @@ begin
Result := true;
end;
-function TAudioDecoder_Bass.Open(const Filename: string): TAudioDecodeStream;
+function TAudioDecoder_Bass.Open(const Filename: IPath): TAudioDecodeStream;
var
Stream: HSTREAM;
ChannelInfo: BASS_CHANNELINFO;
@@ -237,7 +241,14 @@ begin
// TODO: use BASS_STREAM_PRESCAN for accurate seeking in VBR-files?
// disadvantage: seeking will slow down.
- Stream := BASS_StreamCreateFile(False, PChar(Filename), 0, 0, BASS_STREAM_DECODE);
+
+ {$IFDEF MSWINDOWS}
+ // Windows: Use UTF-16 version
+ Stream := BASS_StreamCreateFile(False, PWideChar(Filename.ToWide), 0, 0, BASS_STREAM_DECODE or BASS_UNICODE);
+ {$ELSE}
+ // Mac OS X: Use UTF8/ANSI version
+ Stream := BASS_StreamCreateFile(False, PAnsiChar(Filename.ToNative), 0, 0, BASS_STREAM_DECODE);
+ {$ENDIF}
if (Stream = 0) then
begin
//Log.LogError(BassCore.ErrorGetString(), 'TAudioDecoder_Bass.Open');
@@ -247,7 +258,7 @@ begin
// check if BASS opened some erroneously recognized file-formats
if BASS_ChannelGetInfo(Stream, channelInfo) then
begin
- fileExt := ExtractFileExt(Filename);
+ fileExt := Filename.GetExtension.ToUTF8;
// BASS opens FLV-files (maybe others too) although it cannot handle them.
// Setting BASS_CONFIG_VERIFY to the max. value (100000) does not help.
if ((fileExt = '.flv') and (channelInfo.ctype = BASS_CTYPE_STREAM_MP1)) then
diff --git a/Lua/src/media/UAudioDecoder_FFmpeg.pas b/Lua/src/media/UAudioDecoder_FFmpeg.pas
index 399c2f52..d079afdc 100644
--- a/Lua/src/media/UAudioDecoder_FFmpeg.pas
+++ b/Lua/src/media/UAudioDecoder_FFmpeg.pas
@@ -56,23 +56,24 @@ interface
implementation
uses
+ SDL, // SDL redefines some base types -> include before SysUtils to ignore them
Classes,
- SysUtils,
Math,
- UMusic,
- UIni,
- UMain,
+ SysUtils,
avcodec,
avformat,
avutil,
avio,
mathematics, // used for av_rescale_q
rational,
+ UMusic,
+ UIni,
+ UMain,
UMediaCore_FFmpeg,
- SDL,
ULog,
UCommon,
- UConfig;
+ UConfig,
+ UPath;
const
MAX_AUDIOQ_SIZE = (5 * 16 * 1024);
@@ -129,16 +130,16 @@ type
// state-vars for DecodeFrame (locked by DecoderLock)
AudioPaket: TAVPacket;
- AudioPaketData: PChar;
+ AudioPaketData: PByteArray;
AudioPaketSize: integer;
AudioPaketSilence: integer; // number of bytes of silence to return
// state-vars for AudioCallback (locked by DecoderLock)
AudioBufferPos: integer;
AudioBufferSize: integer;
- AudioBuffer: PChar;
+ AudioBuffer: PByteArray;
- Filename: string;
+ Filename: IPath;
procedure SetPositionIntern(Time: real; Flush: boolean; Blocking: boolean);
procedure SetEOF(State: boolean); {$IFDEF HasInline}inline;{$ENDIF}
@@ -153,7 +154,7 @@ type
procedure PauseParser();
procedure ResumeParser();
- function DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
+ function DecodeFrame(Buffer: PByteArray; BufferSize: integer): integer;
procedure FlushCodecBuffers();
procedure PauseDecoder();
procedure ResumeDecoder();
@@ -161,7 +162,7 @@ type
constructor Create();
destructor Destroy(); override;
- function Open(const Filename: string): boolean;
+ function Open(const Filename: IPath): boolean;
procedure Close(); override;
function GetLength(): real; override;
@@ -173,17 +174,17 @@ type
function IsEOF(): boolean; override;
function IsError(): boolean; override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer; override;
end;
type
- TAudioDecoder_FFmpeg = class( TInterfacedObject, IAudioDecoder )
+ TAudioDecoder_FFmpeg = class(TInterfacedObject, IAudioDecoder)
public
function GetName: string;
function InitializeDecoder(): boolean;
function FinalizeDecoder(): boolean;
- function Open(const Filename: string): TAudioDecodeStream;
+ function Open(const Filename: IPath): TAudioDecodeStream;
end;
var
@@ -270,7 +271,7 @@ begin
inherited;
end;
-function TFFmpegDecodeStream.Open(const Filename: string): boolean;
+function TFFmpegDecodeStream.Open(const Filename: IPath): boolean;
var
SampleFormat: TAudioSampleFormat;
AVResult: integer;
@@ -280,18 +281,18 @@ begin
Close();
Reset();
- if (not FileExists(Filename)) then
+ if (not Filename.IsFile) then
begin
- Log.LogError('Audio-file does not exist: "' + Filename + '"', 'UAudio_FFmpeg');
+ Log.LogError('Audio-file does not exist: "' + Filename.ToNative + '"', 'UAudio_FFmpeg');
Exit;
end;
Self.Filename := Filename;
- // open audio file
- if (av_open_input_file(FormatCtx, PChar(Filename), nil, 0, nil) <> 0) then
+ // use custom 'ufile' protocol for UTF-8 support
+ if (av_open_input_file(FormatCtx, PAnsiChar('ufile:'+FileName.ToUTF8), nil, 0, nil) <> 0) then
begin
- Log.LogError('av_open_input_file failed: "' + Filename + '"', 'UAudio_FFmpeg');
+ Log.LogError('av_open_input_file failed: "' + Filename.ToNative + '"', 'UAudio_FFmpeg');
Exit;
end;
@@ -301,7 +302,7 @@ begin
// retrieve stream information
if (av_find_stream_info(FormatCtx) < 0) then
begin
- Log.LogError('av_find_stream_info failed: "' + Filename + '"', 'UAudio_FFmpeg');
+ Log.LogError('av_find_stream_info failed: "' + Filename.ToNative + '"', 'UAudio_FFmpeg');
Close();
Exit;
end;
@@ -310,13 +311,13 @@ begin
FormatCtx^.pb.eof_reached := 0;
{$IFDEF DebugFFmpegDecode}
- dump_format(FormatCtx, 0, pchar(Filename), 0);
+ dump_format(FormatCtx, 0, PAnsiChar(Filename.ToNative), 0);
{$ENDIF}
AudioStreamIndex := FFmpegCore.FindAudioStreamIndex(FormatCtx);
if (AudioStreamIndex < 0) then
begin
- Log.LogError('FindAudioStreamIndex: No Audio-stream found "' + Filename + '"', 'UAudio_FFmpeg');
+ Log.LogError('FindAudioStreamIndex: No Audio-stream found "' + Filename.ToNative + '"', 'UAudio_FFmpeg');
Close();
Exit;
end;
@@ -378,14 +379,14 @@ begin
// try standard format
SampleFormat := asfS16;
end;
-
+ if CodecCtx^.channels > 255 then
+ Log.LogStatus('Error: CodecCtx^.channels > 255', 'TFFmpegDecodeStream.Open');
FormatInfo := TAudioFormatInfo.Create(
- CodecCtx^.channels,
+ byte(CodecCtx^.channels),
CodecCtx^.sample_rate,
SampleFormat
);
-
PacketQueue := TPacketQueue.Create();
// finally start the decode thread
@@ -446,7 +447,9 @@ end;
function TFFmpegDecodeStream.GetLength(): real;
begin
- // do not forget to consider the start_time value here
+ // do not forget to consider the start_time value here
+ // there is a type size mismatch warnign because start_time and duration are cint64.
+ // So, in principle there could be an overflow when doing the sum.
Result := (FormatCtx^.start_time + FormatCtx^.duration) / AV_TIME_BASE;
end;
@@ -643,7 +646,6 @@ end;
function TFFmpegDecodeStream.ParseLoop(): boolean;
var
Packet: TAVPacket;
- StatusPacket: PAVPacket;
SeekTarget: int64;
ByteIOCtx: PByteIOContext;
ErrorCode: integer;
@@ -862,7 +864,7 @@ begin
end;
end;
-function TFFmpegDecodeStream.DecodeFrame(Buffer: PChar; BufferSize: integer): integer;
+function TFFmpegDecodeStream.DecodeFrame(Buffer: PByteArray; BufferSize: integer): integer;
var
PaketDecodedSize: integer; // size of packet data used for decoding
DataSize: integer; // size of output data decoded by FFmpeg
@@ -945,7 +947,7 @@ begin
Exit;
// handle Status-packet
- if (PChar(AudioPaket.data) = STATUS_PACKET) then
+ if (PAnsiChar(AudioPaket.data) = STATUS_PACKET) then
begin
AudioPaket.data := nil;
AudioPaketData := nil;
@@ -986,7 +988,7 @@ begin
Continue;
end;
- AudioPaketData := PChar(AudioPaket.data);
+ AudioPaketData := AudioPaket.data;
AudioPaketSize := AudioPaket.size;
// if available, update the stream position to the presentation time of this package
@@ -1005,7 +1007,7 @@ begin
end;
end;
-function TFFmpegDecodeStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TFFmpegDecodeStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
var
CopyByteCount: integer; // number of bytes to copy
RemainByteCount: integer; // number of bytes left (remain) to read
@@ -1116,7 +1118,7 @@ begin
Result := true;
end;
-function TAudioDecoder_FFmpeg.Open(const Filename: string): TAudioDecodeStream;
+function TAudioDecoder_FFmpeg.Open(const Filename: IPath): TAudioDecodeStream;
var
Stream: TFFmpegDecodeStream;
begin
diff --git a/Lua/src/media/UAudioInput_Bass.pas b/Lua/src/media/UAudioInput_Bass.pas
index cf292c45..9d4417f1 100644
--- a/Lua/src/media/UAudioInput_Bass.pas
+++ b/Lua/src/media/UAudioInput_Bass.pas
@@ -95,7 +95,7 @@ var
* user - players associated with left/right channels
*}
function MicrophoneCallback(stream: HSTREAM; buffer: Pointer;
- len: Cardinal; inputDevice: Pointer): boolean; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
+ len: integer; inputDevice: Pointer): boolean; {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
begin
AudioInputProcessor.HandleMicrophoneData(buffer, len, inputDevice);
Result := true;
@@ -489,6 +489,11 @@ end;
function TAudioInput_Bass.InitializeRecord(): boolean;
begin
BassCore := TAudioCore_Bass.GetInstance();
+ if not BassCore.CheckVersion then
+ begin
+ Result := false;
+ Exit;
+ end;
Result := EnumDevices();
end;
diff --git a/Lua/src/media/UAudioInput_Portaudio.pas b/Lua/src/media/UAudioInput_Portaudio.pas
index 53080a03..31d2882b 100644
--- a/Lua/src/media/UAudioInput_Portaudio.pas
+++ b/Lua/src/media/UAudioInput_Portaudio.pas
@@ -95,7 +95,6 @@ var
Error: TPaError;
inputParams: TPaStreamParameters;
deviceInfo: PPaDeviceInfo;
- SourceIndex: integer;
begin
Result := false;
@@ -291,8 +290,6 @@ var
sourceIndex: integer;
sourceName: string;
{$ENDIF}
- cbPolls: integer;
- cbWorks: boolean;
begin
Result := false;
diff --git a/Lua/src/media/UAudioPlaybackBase.pas b/Lua/src/media/UAudioPlaybackBase.pas
index 7d143fdc..de2d5563 100644
--- a/Lua/src/media/UAudioPlaybackBase.pas
+++ b/Lua/src/media/UAudioPlaybackBase.pas
@@ -34,7 +34,8 @@ interface
{$I switches.inc}
uses
- UMusic;
+ UMusic,
+ UPath;
type
TAudioPlaybackBase = class(TInterfacedObject, IAudioPlayback)
@@ -46,12 +47,12 @@ type
function GetLatency(): double; virtual; abstract;
// open sound or music stream (used by Open() and OpenSound())
- function OpenStream(const Filename: string): TAudioPlaybackStream;
- function OpenDecodeStream(const Filename: string): TAudioDecodeStream;
+ function OpenStream(const Filename: IPath): TAudioPlaybackStream;
+ function OpenDecodeStream(const Filename: IPath): TAudioDecodeStream;
public
function GetName: string; virtual; abstract;
- function Open(const Filename: string): boolean; // true if succeed
+ function Open(const Filename: IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -79,7 +80,7 @@ type
function Length: real;
// Sounds
- function OpenSound(const Filename: string): TAudioPlaybackStream;
+ function OpenSound(const Filename: IPath): TAudioPlaybackStream;
procedure PlaySound(Stream: TAudioPlaybackStream);
procedure StopSound(Stream: TAudioPlaybackStream);
@@ -108,7 +109,7 @@ begin
Result := true;
end;
-function TAudioPlaybackBase.Open(const Filename: string): boolean;
+function TAudioPlaybackBase.Open(const Filename: IPath): boolean;
begin
// free old MusicStream
MusicStream.Free;
@@ -130,7 +131,7 @@ begin
FreeAndNil(MusicStream);
end;
-function TAudioPlaybackBase.OpenDecodeStream(const Filename: String): TAudioDecodeStream;
+function TAudioPlaybackBase.OpenDecodeStream(const Filename: IPath): TAudioDecodeStream;
var
i: integer;
begin
@@ -140,7 +141,7 @@ begin
if (assigned(Result)) then
begin
Log.LogInfo('Using decoder ' + IAudioDecoder(AudioDecoders[i]).GetName() +
- ' for "' + Filename + '"', 'TAudioPlaybackBase.OpenDecodeStream');
+ ' for "' + Filename.ToNative + '"', 'TAudioPlaybackBase.OpenDecodeStream');
Exit;
end;
end;
@@ -157,7 +158,7 @@ begin
SourceStream.Free;
end;
-function TAudioPlaybackBase.OpenStream(const Filename: string): TAudioPlaybackStream;
+function TAudioPlaybackBase.OpenStream(const Filename: IPath): TAudioPlaybackStream;
var
PlaybackStream: TAudioPlaybackStream;
DecodeStream: TAudioDecodeStream;
@@ -169,7 +170,7 @@ begin
DecodeStream := OpenDecodeStream(Filename);
if (not assigned(DecodeStream)) then
begin
- Log.LogStatus('Could not open "' + Filename + '"', 'TAudioPlayback_Bass.OpenStream');
+ Log.LogStatus('Could not open "' + Filename.ToNative + '"', 'TAudioPlayback_Bass.OpenStream');
Exit;
end;
@@ -283,7 +284,7 @@ begin
Result := 0;
end;
-function TAudioPlaybackBase.OpenSound(const Filename: string): TAudioPlaybackStream;
+function TAudioPlaybackBase.OpenSound(const Filename: IPath): TAudioPlaybackStream;
begin
Result := OpenStream(Filename);
end;
diff --git a/Lua/src/media/UAudioPlayback_Bass.pas b/Lua/src/media/UAudioPlayback_Bass.pas
index d68ac1d4..1d7a44dc 100644
--- a/Lua/src/media/UAudioPlayback_Bass.pas
+++ b/Lua/src/media/UAudioPlayback_Bass.pas
@@ -37,7 +37,6 @@ implementation
uses
Classes,
- SysUtils,
Math,
UIni,
UMain,
@@ -46,7 +45,8 @@ uses
UAudioCore_Bass,
ULog,
sdl,
- bass;
+ bass,
+ SysUtils;
type
PHDSP = ^HDSP;
@@ -90,7 +90,7 @@ type
function GetAudioFormatInfo(): TAudioFormatInfo; override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer;
property EOF: boolean READ IsEOF;
end;
@@ -106,8 +106,8 @@ type
function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
procedure Close(); override;
- procedure WriteData(Buffer: PChar; BufferSize: integer); override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ procedure WriteData(Buffer: PByteArray; BufferSize: integer); override;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer; override;
function IsEOF(): boolean; override;
function IsError(): boolean; override;
end;
@@ -163,14 +163,14 @@ begin
Result := BytesRead;
end;
-function TBassPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TBassPlaybackStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
var
AdjustedSize: integer;
RequestedSourceSize, SourceSize: integer;
SkipCount: integer;
SourceFormatInfo: TAudioFormatInfo;
FrameSize: integer;
- PadFrame: PChar;
+ PadFrame: PByteArray;
//Info: BASS_INFO;
//Latency: double;
begin
@@ -610,7 +610,7 @@ begin
inherited Close();
end;
-procedure TBassVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
+procedure TBassVoiceStream.WriteData(Buffer: PByteArray; BufferSize: integer);
var QueueSize: DWORD;
begin
if ((Handle <> 0) and (BufferSize > 0)) then
@@ -626,7 +626,7 @@ begin
end;
// Note: we do not need the read-function for the BASS implementation
-function TBassVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TBassVoiceStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
begin
Result := -1;
end;
@@ -684,9 +684,11 @@ end;
function TAudioPlayback_Bass.InitializePlayback(): boolean;
begin
- result := false;
+ Result := false;
BassCore := TAudioCore_Bass.GetInstance();
+ if not BassCore.CheckVersion then
+ Exit;
EnumDevices();
@@ -706,7 +708,7 @@ begin
//BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
//BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
- result := true;
+ Result := true;
end;
function TAudioPlayback_Bass.FinalizePlayback(): boolean;
diff --git a/Lua/src/media/UAudioPlayback_SDL.pas b/Lua/src/media/UAudioPlayback_SDL.pas
index b0887676..8403ef03 100644
--- a/Lua/src/media/UAudioPlayback_SDL.pas
+++ b/Lua/src/media/UAudioPlayback_SDL.pas
@@ -33,16 +33,14 @@ interface
{$I switches.inc}
-uses
- Classes,
- SysUtils,
- UMusic;
-
implementation
uses
+ Classes,
sdl,
+ SysUtils,
UAudioPlayback_SoftMixer,
+ UMusic,
ULog,
UIni,
UMain;
@@ -60,13 +58,13 @@ type
function GetLatency(): double; override;
public
function GetName: String; override;
- procedure MixBuffers(dst, src: PChar; size: Cardinal; volume: Single); override;
+ procedure MixBuffers(dst, src: PByteArray; size: Cardinal; volume: Single); override;
end;
{ TAudioPlayback_SDL }
-procedure SDLAudioCallback(userdata: Pointer; stream: PChar; len: integer); cdecl;
+procedure SDLAudioCallback(userdata: Pointer; stream: PByteArray; len: integer); cdecl;
var
Engine: TAudioPlayback_SDL;
begin
@@ -172,7 +170,7 @@ begin
Result := Latency;
end;
-procedure TAudioPlayback_SDL.MixBuffers(dst, src: PChar; size: Cardinal; volume: Single);
+procedure TAudioPlayback_SDL.MixBuffers(dst, src: PByteArray; size: Cardinal; volume: Single);
begin
SDL_MixAudio(PUInt8(dst), PUInt8(src), size, Round(volume * SDL_MIX_MAXVOLUME));
end;
diff --git a/Lua/src/media/UAudioPlayback_SoftMixer.pas b/Lua/src/media/UAudioPlayback_SoftMixer.pas
index f3797dd6..c87e461d 100644
--- a/Lua/src/media/UAudioPlayback_SoftMixer.pas
+++ b/Lua/src/media/UAudioPlayback_SoftMixer.pas
@@ -35,8 +35,8 @@ interface
uses
Classes,
- SysUtils,
sdl,
+ SysUtils,
URingBuffer,
UMusic,
UAudioPlaybackBase;
@@ -48,12 +48,12 @@ type
private
Engine: TAudioPlayback_SoftMixer;
- SampleBuffer: PChar;
+ SampleBuffer: PByteArray;
SampleBufferSize: integer;
SampleBufferCount: integer; // number of available bytes in SampleBuffer
- SampleBufferPos: cardinal;
+ SampleBufferPos: integer;
- SourceBuffer: PChar;
+ SourceBuffer: PByteArray;
SourceBufferSize: integer;
SourceBufferCount: integer; // number of available bytes in SourceBuffer
@@ -70,7 +70,7 @@ type
procedure Reset();
- procedure ApplySoundEffects(Buffer: PChar; BufferSize: integer);
+ procedure ApplySoundEffects(Buffer: PByteArray; BufferSize: integer);
function InitFormatConversion(): boolean;
procedure FlushBuffers();
@@ -100,7 +100,7 @@ type
function GetAudioFormatInfo(): TAudioFormatInfo; override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer;
function GetPCMData(var Data: TPCMData): Cardinal; override;
procedure GetFFTData(var Data: TFFTData); override;
@@ -114,7 +114,7 @@ type
Engine: TAudioPlayback_SoftMixer;
ActiveStreams: TList;
- MixerBuffer: PChar;
+ MixerBuffer: PByteArray;
InternalLock: PSDL_Mutex;
AppVolume: single;
@@ -129,7 +129,7 @@ type
destructor Destroy(); override;
procedure AddStream(Stream: TAudioPlaybackStream);
procedure RemoveStream(Stream: TAudioPlaybackStream);
- function ReadData(Buffer: PChar; BufferSize: integer): integer;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer;
property Volume: single read GetVolume write SetVolume;
end;
@@ -144,7 +144,7 @@ type
function StartAudioPlaybackEngine(): boolean; virtual; abstract;
procedure StopAudioPlaybackEngine(); virtual; abstract;
function FinalizeAudioPlaybackEngine(): boolean; virtual; abstract;
- procedure AudioCallback(Buffer: PChar; Size: integer); {$IFDEF HasInline}inline;{$ENDIF}
+ procedure AudioCallback(Buffer: PByteArray; Size: integer); {$IFDEF HasInline}inline;{$ENDIF}
function CreatePlaybackStream(): TAudioPlaybackStream; override;
public
@@ -159,7 +159,7 @@ type
function GetMixer(): TAudioMixerStream; {$IFDEF HasInline}inline;{$ENDIF}
function GetAudioFormatInfo(): TAudioFormatInfo;
- procedure MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single); virtual;
+ procedure MixBuffers(DstBuffer, SrcBuffer: PByteArray; Size: Cardinal; Volume: Single); virtual;
end;
type
@@ -174,8 +174,8 @@ type
function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; override;
procedure Close(); override;
- procedure WriteData(Buffer: PChar; BufferSize: integer); override;
- function ReadData(Buffer: PChar; BufferSize: integer): integer; override;
+ procedure WriteData(Buffer: PByteArray; BufferSize: integer); override;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer; override;
function IsEOF(): boolean; override;
function IsError(): boolean; override;
end;
@@ -276,7 +276,7 @@ begin
Unlock();
end;
-function TAudioMixerStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TAudioMixerStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
var
i: integer;
Size: integer;
@@ -545,7 +545,7 @@ begin
SourceBufferCount := 0;
end;
-procedure TGenericPlaybackStream.ApplySoundEffects(Buffer: PChar; BufferSize: integer);
+procedure TGenericPlaybackStream.ApplySoundEffects(Buffer: PByteArray; BufferSize: integer);
var
i: integer;
begin
@@ -558,23 +558,21 @@ begin
end;
end;
-function TGenericPlaybackStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TGenericPlaybackStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
var
ConversionInputCount: integer;
ConversionOutputSize: integer; // max. number of converted data (= buffer size)
ConversionOutputCount: integer; // actual number of converted data
SourceSize: integer;
- RequestedSourceSize: integer;
NeededSampleBufferSize: integer;
- BytesNeeded, BytesAvail: integer;
+ BytesNeeded: integer;
SourceFormatInfo, OutputFormatInfo: TAudioFormatInfo;
SourceFrameSize, OutputFrameSize: integer;
SkipOutputCount: integer; // number of output-data bytes to skip
SkipSourceCount: integer; // number of source-data bytes to skip
FillCount: integer; // number of bytes to fill with padding data
CopyCount: integer;
- PadFrame: PChar;
- i: integer;
+ PadFrame: PByteArray;
begin
Result := -1;
@@ -986,7 +984,7 @@ begin
inherited Close();
end;
-procedure TGenericVoiceStream.WriteData(Buffer: PChar; BufferSize: integer);
+procedure TGenericVoiceStream.WriteData(Buffer: PByteArray; BufferSize: integer);
begin
// lock access to buffer
SDL_mutexP(BufferLock);
@@ -999,7 +997,7 @@ begin
end;
end;
-function TGenericVoiceStream.ReadData(Buffer: PChar; BufferSize: integer): integer;
+function TGenericVoiceStream.ReadData(Buffer: PByteArray; BufferSize: integer): integer;
begin
Result := -1;
@@ -1059,7 +1057,7 @@ begin
Result := true;
end;
-procedure TAudioPlayback_SoftMixer.AudioCallback(Buffer: PChar; Size: integer);
+procedure TAudioPlayback_SoftMixer.AudioCallback(Buffer: PByteArray; Size: integer);
begin
MixerStream.ReadData(Buffer, Size);
end;
@@ -1102,7 +1100,7 @@ begin
MixerStream.Volume := Volume;
end;
-procedure TAudioPlayback_SoftMixer.MixBuffers(DstBuffer, SrcBuffer: PChar; Size: Cardinal; Volume: Single);
+procedure TAudioPlayback_SoftMixer.MixBuffers(DstBuffer, SrcBuffer: PByteArray; Size: Cardinal; Volume: Single);
var
SampleIndex: Cardinal;
SampleInt: Integer;
diff --git a/Lua/src/media/UMediaCore_FFmpeg.pas b/Lua/src/media/UMediaCore_FFmpeg.pas
index 9ad19a5b..b4951fe1 100644
--- a/Lua/src/media/UMediaCore_FFmpeg.pas
+++ b/Lua/src/media/UMediaCore_FFmpeg.pas
@@ -34,12 +34,16 @@ interface
{$I switches.inc}
uses
- UMusic,
+ Classes,
+ ctypes,
+ sdl,
avcodec,
avformat,
avutil,
+ avio,
+ UMusic,
ULog,
- sdl;
+ UPath;
type
PPacketQueue = ^TPacketQueue;
@@ -97,12 +101,29 @@ implementation
uses
SysUtils;
+function FFmpegStreamOpen(h: PURLContext; filename: PChar; flags: cint): cint; cdecl; forward;
+function FFmpegStreamRead(h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; forward;
+function FFmpegStreamWrite(h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; forward;
+function FFmpegStreamSeek(h: PURLContext; pos: int64; whence: cint): int64; cdecl; forward;
+function FFmpegStreamClose(h: PURLContext): cint; cdecl; forward;
+
+const
+ UTF8FileProtocol: TURLProtocol = (
+ name: 'ufile';
+ url_open: FFmpegStreamOpen;
+ url_read: FFmpegStreamRead;
+ url_write: FFmpegStreamWrite;
+ url_seek: FFmpegStreamSeek;
+ url_close: FFmpegStreamClose;
+ );
+
var
Instance: TMediaCore_FFmpeg;
constructor TMediaCore_FFmpeg.Create();
begin
inherited;
+ av_register_protocol(@UTF8FileProtocol);
AVCodecLock := SDL_CreateMutex();
end;
@@ -220,6 +241,105 @@ begin
Result := true;
end;
+
+{**
+ * UTF-8 Filename wrapper based on:
+ * http://www.mail-archive.com/libav-user@mplayerhq.hu/msg02460.html
+ *}
+
+function FFmpegStreamOpen(h: PURLContext; filename: PChar; flags: cint): cint; cdecl;
+var
+ Stream: TStream;
+ Mode: word;
+ ProtPrefix: string;
+ FilePath: IPath;
+begin
+ // check for protocol prefix ('ufile:') and strip it
+ ProtPrefix := Format('%s:', [UTF8FileProtocol.name]);
+ if (StrLComp(filename, PChar(ProtPrefix), Length(ProtPrefix)) = 0) then
+ begin
+ Inc(filename, Length(ProtPrefix));
+ end;
+
+ FilePath := Path(filename);
+
+ if ((flags and URL_RDWR) <> 0) then
+ Mode := fmCreate
+ else if ((flags and URL_WRONLY) <> 0) then
+ Mode := fmCreate // TODO: fmCreate is Read+Write -> reopen with fmOpenWrite
+ else
+ Mode := fmOpenRead;
+
+ Result := 0;
+
+ try
+ Stream := TBinaryFileStream.Create(FilePath, Mode);
+ h.priv_data := Stream;
+ except
+ Result := AVERROR_NOENT;
+ end;
+end;
+
+function FFmpegStreamRead(h: PURLContext; buf: PByteArray; size: cint): cint; cdecl;
+var
+ Stream: TStream;
+begin
+ Stream := TStream(h.priv_data);
+ if (Stream = nil) then
+ raise EInvalidContainer.Create('FFmpegStreamRead on nil');
+ try
+ Result := Stream.Read(buf[0], size);
+ except
+ Result := -1;
+ end;
+end;
+
+function FFmpegStreamWrite(h: PURLContext; buf: PByteArray; size: cint): cint; cdecl;
+var
+ Stream: TStream;
+begin
+ Stream := TStream(h.priv_data);
+ if (Stream = nil) then
+ raise EInvalidContainer.Create('FFmpegStreamWrite on nil');
+ try
+ Result := Stream.Write(buf[0], size);
+ except
+ Result := -1;
+ end;
+end;
+
+function FFmpegStreamSeek(h: PURLContext; pos: int64; whence: cint): int64; cdecl;
+var
+ Stream : TStream;
+ Origin : TSeekOrigin;
+begin
+ Stream := TStream(h.priv_data);
+ if (Stream = nil) then
+ raise EInvalidContainer.Create('FFmpegStreamSeek on nil');
+ case whence of
+ 0 {SEEK_SET}: Origin := soBeginning;
+ 1 {SEEK_CUR}: Origin := soCurrent;
+ 2 {SEEK_END}: Origin := soEnd;
+ AVSEEK_SIZE: begin
+ Result := Stream.Size;
+ Exit;
+ end
+ else
+ Origin := soBeginning;
+ end;
+ Result := Stream.Seek(pos, Origin);
+end;
+
+function FFmpegStreamClose(h: PURLContext): cint; cdecl;
+var
+ Stream : TStream;
+begin
+ Stream := TStream(h.priv_data);
+ Stream.Free;
+ Result := 0;
+end;
+
+
{ TPacketQueue }
constructor TPacketQueue.Create();
diff --git a/Lua/src/media/UMedia_dummy.pas b/Lua/src/media/UMedia_dummy.pas
index 7558dd0b..25e94724 100644
--- a/Lua/src/media/UMedia_dummy.pas
+++ b/Lua/src/media/UMedia_dummy.pas
@@ -36,9 +36,10 @@ interface
implementation
uses
- SysUtils,
- math,
- UMusic;
+ SysUtils,
+ math,
+ UMusic,
+ UPath;
type
TMedia_dummy = class( TInterfacedObject, IVideoPlayback, IVideoVisualization, IAudioPlayback, IAudioInput )
@@ -51,7 +52,7 @@ type
function Init(): boolean;
function Finalize(): boolean;
- function Open(const aFileName : string): boolean; // true if succeed
+ function Open(const aFileName: IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -88,7 +89,7 @@ type
function Finished: boolean;
function Length: real;
- function OpenSound(const Filename: string): TAudioPlaybackStream;
+ function OpenSound(const Filename: IPath): TAudioPlaybackStream;
procedure CloseSound(var PlaybackStream: TAudioPlaybackStream);
procedure PlaySound(stream: TAudioPlaybackStream);
procedure StopSound(stream: TAudioPlaybackStream);
@@ -125,7 +126,7 @@ begin
Result := true;
end;
-function TMedia_dummy.Open(const aFileName : string): boolean; // true if succeed
+function TMedia_dummy.Open(const aFileName : IPath): boolean; // true if succeed
begin
Result := false;
end;
@@ -236,7 +237,7 @@ begin
Result := 60;
end;
-function TMedia_dummy.OpenSound(const Filename: string): TAudioPlaybackStream;
+function TMedia_dummy.OpenSound(const Filename: IPath): TAudioPlaybackStream;
begin
Result := nil;
end;
diff --git a/Lua/src/media/UVideo.pas b/Lua/src/media/UVideo.pas
index 197fc572..6db9cd20 100644
--- a/Lua/src/media/UVideo.pas
+++ b/Lua/src/media/UVideo.pas
@@ -22,7 +22,7 @@
* $URL$
* $Id$
*}
-
+
unit UVideo;
{*
@@ -69,8 +69,9 @@ type
implementation
uses
+ SysUtils,
+ Math,
SDL,
- textgl,
avcodec,
avformat,
avutil,
@@ -79,17 +80,17 @@ uses
{$IFDEF UseSWScale}
swscale,
{$ENDIF}
- UMediaCore_FFmpeg,
- math,
gl,
glext,
- SysUtils,
+ textgl,
+ UMediaCore_FFmpeg,
UCommon,
UConfig,
ULog,
UMusic,
UGraphicClasses,
- UGraphic;
+ UGraphic,
+ UPath;
const
{$IFDEF PIXEL_FMT_BGR}
@@ -135,7 +136,7 @@ type
fAspect: real; //**< width/height ratio
fAspectCorrection: TAspectCorrection;
-
+
fTimeBase: extended; //**< FFmpeg time base per time unit
fTime: extended; //**< video time position (absolute)
fLoopTime: extended; //**< start time of the current loop
@@ -145,7 +146,7 @@ type
procedure SynchronizeTime(Frame: PAVFrame; var pts: double);
procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords);
-
+
procedure ShowDebugInfo();
public
@@ -154,7 +155,7 @@ type
function Init(): boolean;
function Finalize: boolean;
- function Open(const aFileName : string): boolean; // true if succeed
+ function Open(const FileName : IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -171,7 +172,7 @@ type
var
FFmpegCore: TMediaCore_FFmpeg;
-
+
// These are called whenever we allocate a frame buffer.
// We use this to store the global_pts in a frame at the time it is allocated.
function PtsGetBuffer(CodecCtx: PAVCodecContext; Frame: PAVFrame): integer; cdecl;
@@ -248,11 +249,11 @@ begin
// TODO: do we really want this by default?
fLoop := true;
fLoopTime := 0;
-
+
fAspectCorrection := acoCrop;
end;
-function TVideoPlayback_FFmpeg.Open(const aFileName : string): boolean; // true if succeed
+function TVideoPlayback_FFmpeg.Open(const FileName : IPath): boolean; // true if succeed
var
errnum: Integer;
AudioStreamIndex: integer;
@@ -261,10 +262,11 @@ begin
Reset();
- errnum := av_open_input_file(fFormatContext, PChar(aFileName), nil, 0, nil);
+ // use custom 'ufile' protocol for UTF-8 support
+ errnum := av_open_input_file(fFormatContext, PAnsiChar('ufile:'+FileName.ToNative), nil, 0, nil);
if (errnum <> 0) then
begin
- Log.LogError('Failed to open file "'+aFileName+'" ('+FFmpegCore.GetErrorString(errnum)+')');
+ Log.LogError('Failed to open file "'+ FileName.ToNative +'" ('+FFmpegCore.GetErrorString(errnum)+')');
Exit;
end;
@@ -434,7 +436,7 @@ begin
fAVFrame := nil;
fAVFrameRGB := nil;
fFrameBuffer := nil;
-
+
if (fCodecContext <> nil) then
begin
// avcodec_close() is not thread-safe
@@ -479,7 +481,7 @@ end;
* Decode a new frame from the video stream.
* The decoded frame is stored in fAVFrame. fTime is updated to the new frame's
* time.
- * @param pts will be updated to the presentation time of the decoded frame.
+ * @param pts will be updated to the presentation time of the decoded frame.
* returns true if a frame could be decoded. False if an error or EOF occured.
*}
function TVideoPlayback_FFmpeg.DecodeFrame(): boolean;
@@ -532,8 +534,17 @@ begin
end;
// no error -> wait for user input
- SDL_Delay(100);
+{
+ SDL_Delay(100); // initial version, left for documentation
continue;
+}
+
+ // Patch by Hawkear:
+ // Why should this function loop in an endless loop if there is an error?
+ // This runs in the main thread, so it halts the whole program
+ // Therefore, it is better to exit when an error occurs
+ Exit;
+
end;
// if we got a packet from the video stream, then decode it
@@ -564,6 +575,10 @@ begin
begin
pts := 0;
end;
+
+ if fStream^.start_time <> AV_NOPTS_VALUE then
+ pts := pts - fStream^.start_time;
+
pts := pts * av_q2d(fStream^.time_base);
// synchronize time on each complete frame
@@ -611,7 +626,7 @@ begin
'TimeDiff: '+inttostr(floor(TimeDifference*1000)));
{$endif}
- // check if last time is more than one frame in the past
+ // check if last time is more than one frame in the past
if (TimeDifference < fTimeBase) then
begin
{$ifdef DebugFrames}
@@ -635,7 +650,7 @@ begin
{$IFDEF VideoBenchmark}
Log.BenchmarkStart(15);
{$ENDIF}
-
+
// fetch new frame (updates fTime)
Success := DecodeFrame();
TimeDifference := NewTime - fTime;
@@ -662,7 +677,7 @@ begin
Success := DecodeFrame();
end;
- // check if we got an EOF or error
+ // check if we got an EOF or error
if (not Success) then
begin
if fLoop then
@@ -688,11 +703,17 @@ begin
0, fCodecContext^.Height,
@(fAVFrameRGB.data), @(fAVFrameRGB.linesize));
{$ELSE}
+ // img_convert from lib/ffmpeg/avcodec.pas is actually deprecated.
+ // If ./configure does not find SWScale then this gives the error
+ // that the identifier img_convert is not known or similar.
+ // I think this should be removed, but am not sure whether there should
+ // be some other replacement or a warning, Therefore, I leave it for now.
+ // April 2009, mischi
errnum := img_convert(PAVPicture(fAVFrameRGB), PIXEL_FMT_FFMPEG,
PAVPicture(fAVFrame), fCodecContext^.pix_fmt,
fCodecContext^.width, fCodecContext^.height);
{$ENDIF}
-
+
if (errnum < 0) then
begin
Log.LogError('Image conversion failed', 'TVideoPlayback_ffmpeg.GetFrame');
@@ -785,8 +806,18 @@ var
begin
// have a nice black background to draw on
// (even if there were errors opening the vid)
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ // TODO: Philipp: IMO TVideoPlayback should not clear the screen at
+ // all, because clearing is already done by the background class
+ // at this moment.
+ if (Screen = 1) then
+ begin
+ // It is important that we just clear once before we start
+ // drawing the first screen otherwise the first screen
+ // would be cleared by the drawgl called when the second
+ // screen is drawn
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
// exit if there's nothing to draw
if (not fOpened) then
@@ -913,7 +944,7 @@ begin
fTime := Time;
fEOF := false;
- fFrameTexValid := false;
+ fFrameTexValid := false;
if (av_seek_frame(fFormatContext, fStreamIndex, Floor(Time/fTimeBase), SeekFlags) < 0) then
begin
diff --git a/Lua/src/media/UVisualizer.pas b/Lua/src/media/UVisualizer.pas
index 9af6d8c2..b25d68a9 100644
--- a/Lua/src/media/UVisualizer.pas
+++ b/Lua/src/media/UVisualizer.pas
@@ -77,6 +77,7 @@ uses
UGraphic,
UMain,
UConfig,
+ UPath,
ULog;
{$IF PROJECTM_VERSION < 1000000} // < 1.0
@@ -130,7 +131,7 @@ type
function Init(): boolean;
function Finalize(): boolean;
- function Open(const aFileName : string): boolean; // true if succeed
+ function Open(const aFileName: IPath): boolean; // true if succeed
procedure Close;
procedure Play;
@@ -183,7 +184,7 @@ begin
Result := true;
end;
-function TVideoPlayback_ProjectM.Open(const aFileName : string): boolean; // true if succeed
+function TVideoPlayback_ProjectM.Open(const aFileName: IPath): boolean; // true if succeed
begin
Result := false;
end;
@@ -484,7 +485,11 @@ begin
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
- gluOrtho2D(0, 1, 0, 1);
+ // Use count of screens instead of 1 for the right corner
+ // otherwise we would draw the visualization streched over both screens
+ // another point is that we draw over the at this time drawn first
+ // screen, if Screen = 2
+ gluOrtho2D(0, Screens, 0, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
@@ -496,11 +501,12 @@ begin
glColor4f(1, 1, 1, 1);
// draw projectM frame
+ // Screen is 1 to 2. So current screen is from (Screen - 1) to (Screen)
glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(0, 0);
- glTexCoord2f(1, 0); glVertex2f(1, 0);
- glTexCoord2f(1, 1); glVertex2f(1, 1);
- glTexCoord2f(0, 1); glVertex2f(0, 1);
+ glTexCoord2f(0, 0); glVertex2f((Screen - 1), 0);
+ glTexCoord2f(1, 0); glVertex2f(Screen, 0);
+ glTexCoord2f(1, 1); glVertex2f(Screen, 1);
+ glTexCoord2f(0, 1); glVertex2f((Screen - 1), 1);
glEnd();
glDisable(GL_TEXTURE_2D);