aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/Classes
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Game/Code/Classes/UAudio_FFMpeg.pas2
-rw-r--r--Game/Code/Classes/UAudio_bass.pas27
-rw-r--r--Game/Code/Classes/UMedia_dummy.pas276
-rw-r--r--Game/Code/Classes/UMusic.pas142
-rw-r--r--Game/Code/Classes/UVideo.pas625
5 files changed, 758 insertions, 314 deletions
diff --git a/Game/Code/Classes/UAudio_FFMpeg.pas b/Game/Code/Classes/UAudio_FFMpeg.pas
index 2a3c5cb5..959d904a 100644
--- a/Game/Code/Classes/UAudio_FFMpeg.pas
+++ b/Game/Code/Classes/UAudio_FFMpeg.pas
@@ -16,8 +16,6 @@ uses Classes,
{$IFNDEF FPC}
Forms,
{$ENDIF}
-
- bass,
ULog,
UMusic;
diff --git a/Game/Code/Classes/UAudio_bass.pas b/Game/Code/Classes/UAudio_bass.pas
index cbeadc47..5aecfc89 100644
--- a/Game/Code/Classes/UAudio_bass.pas
+++ b/Game/Code/Classes/UAudio_bass.pas
@@ -79,7 +79,7 @@ type
procedure Close;
function Finished: boolean;
function Length: real;
- function Position: real;
+ function getPosition: real;
procedure PlayStart;
procedure PlayBack;
procedure PlaySwoosh;
@@ -118,17 +118,22 @@ var
Pet: integer;
S: integer;
begin
- Log.BenchmarkStart(4);
- Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
+ writeln( 'TAudio_bass.InitializePlayback' );
+// Log.BenchmarkStart(4);
+// Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
Loaded := false;
Loop := false;
+
+ writeln( 'TAudio_bass AllocateHWND' );
{$ifdef win32}
// TODO : JB_Linux ... is this needed ? :)
fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function
{$ENDIF}
+
+ writeln( 'TAudio_bass BASS_Init' );
// TODO : jb_linux replace with something other than bass
if not BASS_Init(1, 44100, 0, fHWND, nil) then
begin
@@ -139,15 +144,16 @@ begin
Exit;
end;
- Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
+// Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
// config playing buffer
// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
// BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
- Log.LogStatus('Loading Sounds', 'Music Initialize');
+// Log.LogStatus('Loading Sounds', 'Music Initialize');
- Log.BenchmarkStart(4);
+ writeln( 'TAudio_bass LoadSoundFromFile' );
+// Log.BenchmarkStart(4);
LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3');
LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3');
LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3');
@@ -161,8 +167,8 @@ begin
// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3');
- Log.BenchmarkEnd(4);
- Log.LogBenchmark('--> Loading Sounds', 4);
+// Log.BenchmarkEnd(4);
+// Log.LogBenchmark('--> Loading Sounds', 4);
end;
procedure TAudio_bass.InitializeRecord;
@@ -347,7 +353,7 @@ begin
Result := BASS_ChannelBytes2Seconds(Bass, bytes);
end;
-function TAudio_bass.Position: real;
+function TAudio_bass.getPosition: real;
var
bytes: integer;
begin
@@ -631,7 +637,10 @@ initialization
AudioManager.add( IAudioInput( singleton_MusicBass ) );
finalization
+ writeln( 'UAudio_Bass - UnRegister Playback' );
AudioManager.Remove( IAudioPlayback( singleton_MusicBass ) );
+
+ writeln( 'UAudio_Bass - UnRegister Input' );
AudioManager.Remove( IAudioInput( singleton_MusicBass ) );
end.
diff --git a/Game/Code/Classes/UMedia_dummy.pas b/Game/Code/Classes/UMedia_dummy.pas
new file mode 100644
index 00000000..0752ab64
--- /dev/null
+++ b/Game/Code/Classes/UMedia_dummy.pas
@@ -0,0 +1,276 @@
+unit UMedia_dummy;
+{< #############################################################################
+# FFmpeg support for UltraStar deluxe #
+# #
+# Created by b1indy #
+# based on 'An ffmpeg and SDL Tutorial' (http://www.dranger.com/ffmpeg/) #
+# #
+# http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg09949.html #
+# http://www.nabble.com/file/p11795857/mpegpas01.zip #
+# #
+############################################################################## }
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+implementation
+
+uses
+ SysUtils,
+ UMusic;
+
+
+var
+ singleton_dummy : IVideoPlayback;
+
+type
+ Tmedia_dummy = class( TInterfacedObject, IVideoPlayback, IAudioPlayback, IAudioInput )
+ private
+ public
+ constructor create();
+ function GetName: String;
+
+ procedure init();
+
+ function Open( aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure MoveTo(Time: real);
+ function getPosition: real;
+
+ procedure FFmpegGetFrame(Time: Extended);
+ procedure FFmpegDrawGL(Screen: integer);
+
+ // IAudioInput
+ procedure InitializeRecord;
+ procedure CaptureStart;
+ procedure CaptureStop;
+ procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
+ procedure StopCard(Card: byte);
+ function GetFFTData: TFFTData;
+
+ // IAudioPlayback
+ procedure InitializePlayback;
+ procedure SetVolume(Volume: integer);
+ procedure SetMusicVolume(Volume: integer);
+ procedure SetLoop(Enabled: boolean);
+ procedure Rewind;
+
+ function Finished: boolean;
+ function Length: real;
+
+ procedure PlayStart;
+ procedure PlayBack;
+ procedure PlaySwoosh;
+ procedure PlayChange;
+ procedure PlayOption;
+ procedure PlayClick;
+ procedure PlayDrum;
+ procedure PlayHihat;
+ procedure PlayClap;
+ procedure PlayShuffle;
+ procedure StopShuffle;
+
+ function LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+
+ function LoadCustomSound(const Filename: String): Cardinal;
+ procedure PlayCustomSound(const Index: Cardinal );
+
+ end;
+
+
+
+function Tmedia_dummy.GetName: String;
+begin
+ result := 'dummy';
+end;
+
+
+procedure Tmedia_dummy.FFmpegGetFrame(Time: Extended);
+begin
+end;
+
+procedure Tmedia_dummy.FFmpegDrawGL(Screen: integer);
+begin
+end;
+
+constructor Tmedia_dummy.create();
+begin
+end;
+
+procedure Tmedia_dummy.init();
+begin
+end;
+
+
+function Tmedia_dummy.Open( aFileName : string): boolean; // true if succeed
+begin
+ result := false;
+end;
+
+procedure Tmedia_dummy.Close;
+begin
+end;
+
+procedure Tmedia_dummy.Play;
+begin
+end;
+
+procedure Tmedia_dummy.Pause;
+begin
+end;
+
+procedure Tmedia_dummy.Stop;
+begin
+end;
+
+procedure Tmedia_dummy.MoveTo(Time: real);
+begin
+end;
+
+function Tmedia_dummy.getPosition: real;
+begin
+ result := 0;
+end;
+
+// IAudioInput
+procedure Tmedia_dummy.InitializeRecord;
+begin
+end;
+
+procedure Tmedia_dummy.CaptureStart;
+begin
+end;
+
+procedure Tmedia_dummy.CaptureStop;
+begin
+end;
+
+procedure Tmedia_dummy.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
+begin
+end;
+
+procedure Tmedia_dummy.StopCard(Card: byte);
+begin
+end;
+
+function Tmedia_dummy.GetFFTData: TFFTData;
+begin
+end;
+
+// IAudioPlayback
+procedure Tmedia_dummy.InitializePlayback;
+begin
+end;
+
+procedure Tmedia_dummy.SetVolume(Volume: integer);
+begin
+end;
+
+procedure Tmedia_dummy.SetMusicVolume(Volume: integer);
+begin
+end;
+
+procedure Tmedia_dummy.SetLoop(Enabled: boolean);
+begin
+end;
+
+procedure Tmedia_dummy.Rewind;
+begin
+end;
+
+function Tmedia_dummy.Finished: boolean;
+begin
+end;
+
+function Tmedia_dummy.Length: real;
+begin
+end;
+
+procedure Tmedia_dummy.PlayStart;
+begin
+end;
+
+procedure Tmedia_dummy.PlayBack;
+begin
+end;
+
+procedure Tmedia_dummy.PlaySwoosh;
+begin
+end;
+
+procedure Tmedia_dummy.PlayChange;
+begin
+end;
+
+procedure Tmedia_dummy.PlayOption;
+begin
+end;
+
+procedure Tmedia_dummy.PlayClick;
+begin
+end;
+
+procedure Tmedia_dummy.PlayDrum;
+begin
+end;
+
+procedure Tmedia_dummy.PlayHihat;
+begin
+end;
+
+procedure Tmedia_dummy.PlayClap;
+begin
+end;
+
+procedure Tmedia_dummy.PlayShuffle;
+begin
+end;
+
+procedure Tmedia_dummy.StopShuffle;
+begin
+end;
+
+function Tmedia_dummy.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+begin
+ result := false;
+end;
+
+function Tmedia_dummy.LoadCustomSound(const Filename: String): Cardinal;
+begin
+ result := 0;
+end;
+
+procedure Tmedia_dummy.PlayCustomSound(const Index: Cardinal );
+begin
+end;
+
+
+
+initialization
+ singleton_dummy := Tmedia_dummy.create();
+
+ writeln( 'UMedia_dummy - Register dummy Video_Playback' );
+ AudioManager.add( IVideoPlayback( singleton_dummy ) );
+
+ writeln( 'UMedia_dummy - Register dummy Video_Playback' );
+ AudioManager.add( IAudioPlayback( singleton_dummy ) );
+
+ writeln( 'UMedia_dummy - Register dummy Video_Playback' );
+ AudioManager.add( IAudioInput( singleton_dummy ) );
+
+finalization
+ AudioManager.Remove( IVideoPlayback( singleton_dummy ) );
+ AudioManager.Remove( IAudioPlayback( singleton_dummy ) );
+ AudioManager.Remove( IAudioInput( singleton_dummy ) );
+
+
+end.
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas
index 8aa59d41..88d845f7 100644
--- a/Game/Code/Classes/UMusic.pas
+++ b/Game/Code/Classes/UMusic.pas
@@ -8,8 +8,7 @@ interface
{$MODE Delphi}
{$ENDIF}
-uses Classes // UCommon
- ;
+uses Classes ;
type
TMuzyka = record
@@ -94,23 +93,58 @@ type
end;
type
- IAudioPlayback = Interface
+ IGenericPlayback = Interface
+ ['{63A5EBC3-3F4D-4F23-8DFB-B5165FCE33DD}']
+ function GetName: String;
+
+ function Open(Name: string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure MoveTo(Time: real);
+ function getPosition: real;
+
+ property position : real READ getPosition WRITE MoveTo;
+ end;
+
+ IVideoPlayback = Interface( IGenericPlayback )
+ ['{3574C40C-28AE-4201-B3D1-3D1F0759B131}']
+(*
+ procedure FFmpegOpenFile(FileName: pAnsiChar);
+ procedure FFmpegClose;
+
+ procedure FFmpegGetFrame(Time: Extended);
+ procedure FFmpegDrawGL(Screen: integer);
+ procedure FFmpegTogglePause;
+ procedure FFmpegSkip(Time: Single);
+*)
+ procedure init();
+
+ procedure FFmpegGetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC
+ procedure FFmpegDrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC
+
+ end;
+
+ IAudioPlayback = Interface( IGenericPlayback )
['{E4AE0B40-3C21-4DC5-847C-20A87E0DFB96}']
- function GetName: String;
procedure InitializePlayback;
procedure SetVolume(Volume: integer);
procedure SetMusicVolume(Volume: integer);
procedure SetLoop(Enabled: boolean);
- function Open(Name: string): boolean; // true if succeed
+// function Open(Name: string): boolean; // true if succeed
procedure Rewind;
- procedure MoveTo(Time: real);
- procedure Play;
- procedure Pause; //Pause Mod
- procedure Stop;
- procedure Close;
+// procedure MoveTo(Time: real);
+// procedure Play;
+// procedure Pause;
+// procedure Stop;
+// procedure Close;
function Finished: boolean;
function Length: real;
- function Position: real;
+// function getPosition: real;
+
procedure PlayStart;
procedure PlayBack;
procedure PlaySwoosh;
@@ -159,6 +193,7 @@ var // TODO : JB --- THESE SHOULD NOT BE GLOBAL
procedure InitializeSound;
+function VideoPlayback(): IVideoPlayback;
function AudioPlayback(): IAudioPlayback;
function AudioInput(): IAudioInput;
@@ -168,21 +203,30 @@ function AudioManager: TInterfaceList;
implementation
uses
- sysutils,
- uLog;
+ sysutils;
+// uLog;
var
- singleton_AudioPlayback : IAudioPlayback;
- singleton_AudioInput : IAudioInput;
- singleton_AudioManager : TInterfaceList;
+ singleton_VideoPlayback : IVideoPlayback = nil;
+ singleton_AudioPlayback : IAudioPlayback = nil;
+ singleton_AudioInput : IAudioInput = nil;
+ singleton_AudioManager : TInterfaceList = nil;
function AudioManager: TInterfaceList;
begin
+ if singleton_AudioManager = nil then
+ singleton_AudioManager := TInterfaceList.Create();
+
Result := singleton_AudioManager;
end; //CompressionPluginManager
+function VideoPlayback(): IVideoPlayback;
+begin
+ result := singleton_VideoPlayback;
+end;
+
function AudioPlayback(): IAudioPlayback;
begin
result := singleton_AudioPlayback;
@@ -195,45 +239,71 @@ end;
procedure InitializeSound;
var
- lTmpPlayBack : IAudioPlayback;
- lTmpInput : IAudioInput;
- iCount : Integer;
+ lTmpInterface : IInterface;
+ iCount : Integer;
begin
- lTmpPlayBack := nil;
- lTmpInput := nil;
+ lTmpInterface := nil;
+
+ singleton_AudioPlayback := nil;
+ singleton_AudioInput := nil;
+ singleton_VideoPlayback := nil;
writeln( 'InitializeSound , Enumerate Registered Audio Interfaces' );
- for iCount := 0 to singleton_AudioManager.Count - 1 do
+ for iCount := 0 to AudioManager.Count - 1 do
begin
if assigned( AudioManager[iCount] ) then
begin
// if this interface is a Playback, then set it as the default used
- if ( AudioManager[iCount].QueryInterface( IAudioPlayback, lTmpPlayBack ) = 0 ) AND
- ( not assigned( singleton_AudioPlayback ) ) then
+
+ if ( AudioManager[iCount].QueryInterface( IAudioPlayback, lTmpInterface ) = 0 ) AND
+ ( true ) then
+// ( not assigned( singleton_AudioPlayback ) ) then
begin
- singleton_AudioPlayback := lTmpPlayBack;
+ singleton_AudioPlayback := IAudioPlayback( lTmpInterface );
end;
// if this interface is a Input, then set it as the default used
- if ( AudioManager[iCount].QueryInterface( IAudioInput, lTmpInput ) = 0 ) AND
- ( not assigned( singleton_AudioInput ) ) then
+ if ( AudioManager[iCount].QueryInterface( IAudioInput, lTmpInterface ) = 0 ) AND
+ ( true ) then
+// ( not assigned( singleton_AudioInput ) ) then
begin
- singleton_AudioInput := lTmpInput;
+ singleton_AudioInput := IAudioInput( lTmpInterface );
end;
+
+ // if this interface is a Input, then set it as the default used
+ if ( AudioManager[iCount].QueryInterface( IVideoPlayback, lTmpInterface ) = 0 ) AND
+ ( true ) then
+// ( not assigned( singleton_VideoPlayback ) ) then
+ begin
+ singleton_VideoPlayback := IVideoPlayback( lTmpInterface );
+ end;
+
end;
end;
- writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName );
- writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName );
+ if VideoPlayback <> nil then
+ begin
+ writeln( 'Registered Video Playback Interface : ' + VideoPlayback.GetName );
+ end;
+
+ if AudioPlayback <> nil then
+ begin
+ writeln( 'Registered Audio Playback Interface : ' + AudioPlayback.GetName );
+ // Log.LogStatus('Initializing Playback ('+AudioPlayback.GetName+')', 'InitializeSound');
+ AudioPlayback.InitializePlayback;
+ end;
+
+ if AudioInput <> nil then
+ begin
+ writeln( 'Registered Audio Input Interface : ' + AudioInput.GetName );
+
+// Log.LogStatus('Initializing Record ('+AudioPlayback.GetName+')', 'InitializeSound');
+ AudioInput.InitializeRecord;
+ end;
- // Initialize Playback
- Log.LogStatus('Initializing Playback ('+AudioPlayback.GetName+')', 'InitializeSound');
- AudioPlayback.InitializePlayback;
+ writeln( 'InitializeSound DONE' );
- // Initialize Input
- Log.LogStatus('Initializing Record ('+AudioPlayback.GetName+')', 'InitializeSound');
- AudioInput.InitializeRecord;
end;
initialization
diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas
index ed1e5fe3..6e16a7a3 100644
--- a/Game/Code/Classes/UVideo.pas
+++ b/Game/Code/Classes/UVideo.pas
@@ -22,6 +22,14 @@ interface
{$MODE DELPHI}
{$ENDIF}
+(*
+
+ look into
+ av_read_play
+
+*)
+
+implementation
uses SDL,
UGraphicClasses,
@@ -37,56 +45,69 @@ uses SDL,
dialogs,
{$endif}
{$ENDIF}
- UIni;
+ UIni,
+ UMusic;
-procedure Init;
-procedure FFmpegOpenFile(FileName: pAnsiChar);
-procedure FFmpegClose;
-procedure FFmpegGetFrame(Time: Extended);
-procedure FFmpegDrawGL(Screen: integer);
-procedure FFmpegTogglePause;
-procedure FFmpegSkip(Time: Single);
-{
- @author(Jay Binks <jaybinks@gmail.com>)
- @created(2007-10-09)
- @lastmod(2007-10-09)
+var
+ singleton_VideoFFMpeg : IVideoPlayback;
- @param(aFormatCtx is a PAVFormatContext returned from av_open_input_file )
- @param(aFirstVideoStream is an OUT value of type integer, this is the index of the video stream)
- @param(aFirstAudioStream is an OUT value of type integer, this is the index of the audio stream)
- @returns(@true on success, @false otherwise)
+type
+ TVideoPlayback_ffmpeg = class( TInterfacedObject, IVideoPlayback )
+ private
+ fVideoOpened ,
+ fVideoPaused : Boolean;
- translated from "Setting Up the Audio" section at
- http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html
- }
-function find_stream_ids( const aFormatCtx : PAVFormatContext; Out aFirstVideoStream, aFirstAudioStream : integer ): boolean;
+ fVideoTex : glUint;
+ fVideoSkipTime : Single;
+
+ fTexData : array of Byte;
+
+ VideoFormatContext: PAVFormatContext;
+
+ VideoStreamIndex ,
+ AudioStreamIndex : Integer;
+ VideoCodecContext: PAVCodecContext;
+ VideoCodec: PAVCodec;
+ AVFrame: PAVFrame;
+ AVFrameRGB: PAVFrame;
+ myBuffer: pByte;
+
+ TexX, TexY, dataX, dataY: Cardinal;
+
+ ScaledVideoWidth, ScaledVideoHeight: Real;
+ VideoAspect: Real;
+ VideoTextureU, VideoTextureV: Real;
+ VideoTimeBase, VideoTime, LastFrameTime, TimeDifference: Extended;
+
+
+ WantedAudioCodecContext,
+ AudioCodecContext : PSDL_AudioSpec;
+ aCodecCtx : PAVCodecContext;
+
+
+ function find_stream_ids( const aFormatCtx : PAVFormatContext; Out aFirstVideoStream, aFirstAudioStream : integer ): boolean;
+ public
+ constructor create();
+ function GetName: String;
+
+ procedure init();
+
+ function Open( aFileName : string): boolean; // true if succeed
+ procedure Close;
+
+ procedure Play;
+ procedure Pause;
+ procedure Stop;
+
+ procedure MoveTo(Time: real);
+ function getPosition: real;
+
+ procedure FFmpegGetFrame(Time: Extended); // WANT TO RENAME THESE TO BE MORE GENERIC
+ procedure FFmpegDrawGL(Screen: integer); // WANT TO RENAME THESE TO BE MORE GENERIC
+
+ end;
-var
- VideoOpened, VideoPaused: Boolean;
- VideoFormatContext: PAVFormatContext;
- VideoStreamIndex ,
- AudioStreamIndex : Integer;
- VideoCodecContext: PAVCodecContext;
- VideoCodec: PAVCodec;
- AVFrame: PAVFrame;
- AVFrameRGB: PAVFrame;
- myBuffer: pByte;
- VideoTex: glUint;
- TexX, TexY, dataX, dataY: Cardinal;
- TexData: array of Byte;
- ScaledVideoWidth, ScaledVideoHeight: Real;
- VideoAspect: Real;
- VideoTextureU, VideoTextureV: Real;
- VideoTimeBase, VideoTime, LastFrameTime, TimeDifference: Extended;
- VideoSkipTime: Single;
-
-
- WantedAudioCodecContext,
- AudioCodecContext : PSDL_AudioSpec;
- aCodecCtx : PAVCodecContext;
-
-implementation
{$ifdef DebugDisplay}
//{$ifNdef win32}
@@ -102,15 +123,10 @@ end;
{ ------------------------------------------------------------------------------
asdf
------------------------------------------------------------------------------ }
-procedure Init;
-begin
- av_register_all;
- VideoOpened:=False;
- VideoPaused:=False;
-
- glGenTextures(1, PglUint(@VideoTex));
- SetLength(TexData,0);
+function TVideoPlayback_ffmpeg.GetName: String;
+begin
+ result := 'FFMpeg';
end;
{
@@ -126,7 +142,7 @@ end;
translated from "Setting Up the Audio" section at
http://www.dranger.com/ffmpeg/ffmpegtutorial_all.html
}
-function find_stream_ids( const aFormatCtx : PAVFormatContext; Out aFirstVideoStream, aFirstAudioStream : integer ): boolean;
+function TVideoPlayback_ffmpeg.find_stream_ids( const aFormatCtx : PAVFormatContext; Out aFirstVideoStream, aFirstAudioStream : integer ): boolean;
var
i : integer;
st : pAVStream;
@@ -164,202 +180,10 @@ begin
(aFirstVideoStream > -1) ; // Didn't find a video stream
end;
-procedure FFmpegOpenFile(FileName: pAnsiChar);
-var errnum, i, x,y: Integer;
- lStreamsCount : Integer;
-
-begin
- VideoOpened := False;
- VideoPaused := False;
- VideoTimeBase := 0;
- VideoTime := 0;
- LastFrameTime := 0;
- TimeDifference := 0;
- VideoFormatContext := 0;
-
- writeln( Filename );
-
- errnum := av_open_input_file(VideoFormatContext, FileName, Nil, 0, Nil);
- writeln( 'Errnum : ' +inttostr( errnum ));
- if(errnum <> 0) then
- begin
-{$ifdef DebugDisplay}
- case errnum of
- AVERROR_UNKNOWN: showmessage('failed to open file '+Filename+#13#10+'AVERROR_UNKNOWN');
- AVERROR_IO: showmessage('failed to open file '+Filename+#13#10+'AVERROR_IO');
- AVERROR_NUMEXPECTED: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NUMEXPECTED');
- AVERROR_INVALIDDATA: showmessage('failed to open file '+Filename+#13#10+'AVERROR_INVALIDDATA');
- AVERROR_NOMEM: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOMEM');
- AVERROR_NOFMT: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOFMT');
- AVERROR_NOTSUPP: showmessage('failed to open file '+Filename+#13#10+'AVERROR_NOTSUPP');
- else showmessage('failed to open file '+Filename+#13#10+'Error number: '+inttostr(Errnum));
- end;
-{$ENDIF}
- Exit;
- end
- else
- begin
- VideoStreamIndex := -1;
- AudioStreamIndex := -1;
-
- // Find which stream contains the video
- if( av_find_stream_info(VideoFormatContext) >= 0 ) then
- begin
- find_stream_ids( VideoFormatContext, VideoStreamIndex, AudioStreamIndex );
-
- writeln( 'VideoStreamIndex : ' + inttostr(VideoStreamIndex) );
- writeln( 'AudioStreamIndex : ' + inttostr(AudioStreamIndex) );
- end;
- aCodecCtx := VideoFormatContext.streams[ AudioStreamIndex ].codec;
-
- WantedAudioCodecContext.freq := aCodecCtx^.sample_rate;
- WantedAudioCodecContext.format := AUDIO_S16SYS;
- WantedAudioCodecContext.channels := aCodecCtx^.channels;
- WantedAudioCodecContext.silence := 0;
- WantedAudioCodecContext.samples := 1024;//SDL_AUDIO_BUFFER_SIZE;
-// WantedAudioCodecContext.callback := audio_callback;
- WantedAudioCodecContext.userdata := aCodecCtx;
-
-
-(*
- if(SDL_OpenAudio(WantedAudioCodecContext, AudioCodecContext) < 0) then
- begin
- writeln( 'Could not do SDL_OpenAudio' );
- exit;
- end;
-*)
-
- if(VideoStreamIndex >= 0) then
- begin
- VideoCodecContext:=VideoFormatContext^.streams[VideoStreamIndex]^.codec;
- VideoCodec:=avcodec_find_decoder(VideoCodecContext^.codec_id);
- end
- else
- begin
-{$ifdef DebugDisplay}
- showmessage('found no video stream');
-{$ENDIF}
- av_close_input_file(VideoFormatContext);
- Exit;
- end;
-
-
- if(VideoCodec<>Nil) then
- begin
- errnum:=avcodec_open(VideoCodecContext, VideoCodec);
- end else begin
-{$ifdef DebugDisplay}
- showmessage('no matching codec found');
-{$ENDIF}
- avcodec_close(VideoCodecContext);
- av_close_input_file(VideoFormatContext);
- Exit;
- end;
- if(errnum >=0) then
- begin
-{$ifdef DebugDisplay}
- showmessage('Found a matching Codec: '+ VideoCodecContext^.Codec.Name +#13#10#13#10+
- ' Width = '+inttostr(VideoCodecContext^.width)+ ', Height='+inttostr(VideoCodecContext^.height)+#13#10+
- ' Aspect : '+inttostr(VideoCodecContext^.sample_aspect_ratio.num)+'/'+inttostr(VideoCodecContext^.sample_aspect_ratio.den)+#13#10+
- ' Framerate : '+inttostr(VideoCodecContext^.time_base.num)+'/'+inttostr(VideoCodecContext^.time_base.den));
-{$endif}
- // allocate space for decoded frame and rgb frame
- AVFrame:=avcodec_alloc_frame;
- AVFrameRGB:=avcodec_alloc_frame;
- end;
- myBuffer:=Nil;
- if(AVFrame <> Nil) and (AVFrameRGB <> Nil) then
- begin
- myBuffer:=av_malloc(avpicture_get_size(PIX_FMT_RGB24, VideoCodecContext^.width,
- VideoCodecContext^.height));
- end;
- if myBuffer <> Nil then errnum:=avpicture_fill(PAVPicture(AVFrameRGB), myBuffer, PIX_FMT_RGB24,
- VideoCodecContext^.width, VideoCodecContext^.height)
- else begin
-{$ifdef DebugDisplay}
- showmessage('failed to allocate video buffer');
-{$endif}
- av_free(AVFrameRGB);
- av_free(AVFrame);
- avcodec_close(VideoCodecContext);
- av_close_input_file(VideoFormatContext);
- Exit;
- end;
- if errnum >=0 then
- begin
- VideoOpened:=True;
-
- TexX := VideoCodecContext^.width;
- TexY := VideoCodecContext^.height;
- dataX := Round(Power(2, Ceil(Log2(TexX))));
- dataY := Round(Power(2, Ceil(Log2(TexY))));
- SetLength(TexData,dataX*dataY*3);
- // calculate some information for video display
- VideoAspect:=VideoCodecContext^.sample_aspect_ratio.num/VideoCodecContext^.sample_aspect_ratio.den;
- if (VideoAspect = 0) then
- VideoAspect:=VideoCodecContext^.width/VideoCodecContext^.height
- else
- VideoAspect:=VideoAspect*VideoCodecContext^.width/VideoCodecContext^.height;
- if VideoAspect >= 4/3 then
- begin
- ScaledVideoWidth:=800.0;
- ScaledVideoHeight:=800.0/VideoAspect;
- end else
- begin
- ScaledVideoHeight:=600.0;
- ScaledVideoWidth:=600.0*VideoAspect;
- end;
- VideoTimeBase:=VideoCodecContext^.time_base.num/VideoCodecContext^.time_base.den;
- // hack to get reasonable timebase for divx
-{$ifdef DebugDisplay}
- showmessage('framerate: '+inttostr(floor(1/videotimebase))+'fps');
-{$endif}
- if VideoTimeBase < 0.02 then // 0.02 <-> 50 fps
- begin
- VideoTimeBase:=VideoCodecContext^.time_base.den/VideoCodecContext^.time_base.num;
- while VideoTimeBase > 50 do VideoTimeBase:=VideoTimeBase/10;
- VideoTimeBase:=1/VideoTimeBase;
- end;
-{$ifdef DebugDisplay}
- showmessage('corrected framerate: '+inttostr(floor(1/videotimebase))+'fps');
-
- if ((VideoAspect*VideoCodecContext^.width*VideoCodecContext^.height)>200000) then
- showmessage('you are trying to play a rather large video'+#13#10+
- 'be prepared to experience some timing problems');
-{$endif}
- end;
- end;
-end;
-
-procedure FFmpegClose;
-begin
- if VideoOpened then begin
- av_free(myBuffer);
- av_free(AVFrameRGB);
- av_free(AVFrame);
- avcodec_close(VideoCodecContext);
- av_close_input_file(VideoFormatContext);
- SetLength(TexData,0);
- VideoOpened:=False;
- end;
-end;
-procedure FFmpegTogglePause;
-begin
- if VideoPaused then VideoPaused:=False
- else VideoPaused:=True;
-end;
-procedure FFmpegSkip(Time: Single);
-begin
- VideoSkiptime:=Time;
- if VideoSkipTime > 0 then begin
- av_seek_frame(VideoFormatContext,-1,Floor((VideoSkipTime)*1500000),0);
- VideoTime:=VideoSkipTime;
- end;
-end;
-procedure FFmpegGetFrame(Time: Extended);
+procedure TVideoPlayback_ffmpeg.FFmpegGetFrame(Time: Extended);
var
FrameFinished: Integer;
AVPacket: TAVPacket;
@@ -372,13 +196,13 @@ var
const
FRAMEDROPCOUNT=3;
begin
- if not VideoOpened then Exit;
+ if not fVideoOpened then Exit;
- if VideoPaused then Exit;
-
- myTime:=Time+VideoSkipTime;
- TimeDifference:=myTime-VideoTime;
- DropFrame:=False;
+ if fVideoPaused then Exit;
+
+ myTime := Time + fVideoSkipTime;
+ TimeDifference := myTime - VideoTime;
+ DropFrame := False;
{$IFDEF DebugDisplay}
showmessage('Time: '+inttostr(floor(Time*1000))+#13#10+
@@ -404,7 +228,8 @@ begin
Exit;// we don't need a new frame now
end;
-
+
+
VideoTime:=VideoTime+VideoTimeBase;
TimeDifference:=myTime-VideoTime;
if TimeDifference >= (FRAMEDROPCOUNT-1)*VideoTimeBase then // skip frames
@@ -415,37 +240,52 @@ begin
{$endif}
{$IFDEF DebugDisplay}
+
showmessage('skipping frames'+#13#10+
'TimeBase: '+inttostr(floor(VideoTimeBase*1000))+#13#10+
'TimeDiff: '+inttostr(floor(TimeDifference*1000))+#13#10+
'Time2Skip: '+inttostr(floor((Time-LastFrameTime)*1000)));
+
{$endif}
-// av_seek_frame(VideoFormatContext,VideoStreamIndex,Floor(Time*VideoTimeBase),0);
+// av_seek_frame(VideoFormatContext.,VideoStreamIndex,Floor(Time*VideoTimeBase),0);
{ av_seek_frame(VideoFormatContext,-1,Floor((myTime+VideoTimeBase)*1500000),0);
VideoTime:=floor(myTime/VideoTimeBase)*VideoTimeBase;}
VideoTime:=VideoTime+FRAMEDROPCOUNT*VideoTimeBase;
DropFrame:=True;
end;
+
// av_init_packet(@AVPacket);
+ AVPacket.data := nil;
av_init_packet( AVPacket ); // JB-ffmpeg
-
+
+
FrameFinished:=0;
// read packets until we have a finished frame (or there are no more packets)
// while (FrameFinished=0) and (av_read_frame(VideoFormatContext, @AVPacket)>=0) do
while (FrameFinished=0) and (av_read_frame(VideoFormatContext, AVPacket)>=0) do // JB-ffmpeg
begin
+
+
// if we got a packet from the video stream, then decode it
if (AVPacket.stream_index=VideoStreamIndex) then
// errnum:=avcodec_decode_video(VideoCodecContext, AVFrame, @frameFinished , AVPacket.data, AVPacket.size);
errnum := avcodec_decode_video(VideoCodecContext, AVFrame, frameFinished , AVPacket.data, AVPacket.size); // JB-ffmpeg
-
+
// release internal packet structure created by av_read_frame
// av_free_packet(PAVPacket(@AVPacket));
- av_free_packet( AVPacket ); // JB-ffmpeg
+
+ try
+ if AVPacket.data <> nil then
+ av_free_packet( AVPacket ); // JB-ffmpeg
+ except
+ // TODO : JB_FFMpeg ... why does this now AV sometimes ( or always !! )
+ end;
+
end;
-
+
+
if DropFrame then
for droppedFrames:=1 to FRAMEDROPCOUNT do begin
FrameFinished:=0;
@@ -485,12 +325,12 @@ begin
linesize := AVFrameRGB^.linesize[0];
for y:=0 to TexY-1 do
begin
- System.Move(FrameDataPtr[y*linesize],TexData[3*y*dataX],linesize);
+ System.Move(FrameDataPtr[y*linesize],fTexData[3*y*dataX],linesize);
end;
// generate opengl texture out of whatever we got
- glBindTexture(GL_TEXTURE_2D, VideoTex);
- glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0, GL_RGB, GL_UNSIGNED_BYTE, TexData);
+ glBindTexture(GL_TEXTURE_2D, fVideoTex);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, dataX, dataY, 0, GL_RGB, GL_UNSIGNED_BYTE, fTexData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
{$ifdef DebugFrames}
@@ -501,20 +341,21 @@ begin
end;
end;
-procedure FFmpegDrawGL(Screen: integer);
+procedure TVideoPlayback_ffmpeg.FFmpegDrawGL(Screen: integer);
begin
// have a nice black background to draw on (even if there were errors opening the vid)
- if Screen=1 then begin
+ if Screen=1 then
+ begin
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 VideoOpened then Exit;
+ if not fVideoOpened then Exit;
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, VideoTex);
+ glBindTexture(GL_TEXTURE_2D, fVideoTex);
glbegin(gl_quads);
glTexCoord2f( 0, 0); glVertex2f(400-ScaledVideoWidth/2, 300-ScaledVideoHeight/2);
glTexCoord2f( 0, TexY/dataY); glVertex2f(400-ScaledVideoWidth/2, 300+ScaledVideoHeight/2);
@@ -525,7 +366,8 @@ begin
glDisable(GL_BLEND);
{$ifdef Info}
- if VideoSkipTime+VideoTime+VideoTimeBase < 0 then begin
+ if VideoSkipTime+VideoTime+VideoTimeBase < 0 then
+ begin
glColor4f(0.7, 1, 0.3, 1);
SetFontStyle (1);
SetFontItalic(False);
@@ -558,4 +400,253 @@ begin
{$endif}
end;
+constructor TVideoPlayback_ffmpeg.create();
+begin
+ writeln( 'UVideo_FFMpeg - TVideoPlayback_ffmpeg.create()' );
+
+ writeln( 'UVideo_FFMpeg - av_register_all' );
+ av_register_all;
+
+ fVideoOpened := False;
+ fVideoPaused := False;
+
+end;
+
+procedure TVideoPlayback_ffmpeg.init();
+begin
+ writeln( 'UVideo_FFMpeg - glGenTextures(1, PglUint(@fVideoTex))' );
+ glGenTextures(1, PglUint(@fVideoTex));
+
+ writeln( 'UVideo_FFMpeg - SetLength(fTexData,0)' );
+ SetLength(fTexData,0);
+end;
+
+
+function TVideoPlayback_ffmpeg.Open( aFileName : string): boolean; // true if succeed
+var
+ errnum, i, x,y: Integer;
+ lStreamsCount : Integer;
+
+begin
+ fVideoOpened := False;
+ fVideoPaused := False;
+ VideoTimeBase := 0;
+ VideoTime := 0;
+ LastFrameTime := 0;
+ TimeDifference := 0;
+ VideoFormatContext := 0;
+
+ writeln( aFileName );
+
+ errnum := av_open_input_file(VideoFormatContext, pchar( aFileName ), Nil, 0, Nil);
+ writeln( 'Errnum : ' +inttostr( errnum ));
+ if(errnum <> 0) then
+ begin
+{$ifdef DebugDisplay}
+ case errnum of
+ AVERROR_UNKNOWN: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_UNKNOWN');
+ AVERROR_IO: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_IO');
+ AVERROR_NUMEXPECTED: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_NUMEXPECTED');
+ AVERROR_INVALIDDATA: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_INVALIDDATA');
+ AVERROR_NOMEM: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_NOMEM');
+ AVERROR_NOFMT: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_NOFMT');
+ AVERROR_NOTSUPP: showmessage('failed to open file '+aFileName+#13#10+'AVERROR_NOTSUPP');
+ else showmessage('failed to open file '+aFileName+#13#10+'Error number: '+inttostr(Errnum));
+ end;
+{$ENDIF}
+ Exit;
+ end
+ else
+ begin
+ VideoStreamIndex := -1;
+ AudioStreamIndex := -1;
+
+ // Find which stream contains the video
+ if( av_find_stream_info(VideoFormatContext) >= 0 ) then
+ begin
+ find_stream_ids( VideoFormatContext, VideoStreamIndex, AudioStreamIndex );
+
+ writeln( 'VideoStreamIndex : ' + inttostr(VideoStreamIndex) );
+ writeln( 'AudioStreamIndex : ' + inttostr(AudioStreamIndex) );
+ end;
+ aCodecCtx := VideoFormatContext.streams[ AudioStreamIndex ].codec;
+
+(*
+ WantedAudioCodecContext.freq := aCodecCtx^.sample_rate;
+ WantedAudioCodecContext.format := AUDIO_S16SYS;
+ WantedAudioCodecContext.channels := aCodecCtx^.channels;
+ WantedAudioCodecContext.silence := 0;
+ WantedAudioCodecContext.samples := 1024;//SDL_AUDIO_BUFFER_SIZE;
+// WantedAudioCodecContext.callback := audio_callback;
+ WantedAudioCodecContext.userdata := aCodecCtx;
+*)
+
+(*
+ if(SDL_OpenAudio(WantedAudioCodecContext, AudioCodecContext) < 0) then
+ begin
+ writeln( 'Could not do SDL_OpenAudio' );
+ exit;
+ end;
+*)
+
+ if(VideoStreamIndex >= 0) then
+ begin
+ VideoCodecContext:=VideoFormatContext^.streams[VideoStreamIndex]^.codec;
+ VideoCodec:=avcodec_find_decoder(VideoCodecContext^.codec_id);
+ end
+ else
+ begin
+{$ifdef DebugDisplay}
+ showmessage('found no video stream');
+{$ENDIF}
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+
+
+ if(VideoCodec<>Nil) then
+ begin
+ errnum:=avcodec_open(VideoCodecContext, VideoCodec);
+ end else begin
+{$ifdef DebugDisplay}
+ showmessage('no matching codec found');
+{$ENDIF}
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+ if(errnum >=0) then
+ begin
+{$ifdef DebugDisplay}
+ showmessage('Found a matching Codec: '+ VideoCodecContext^.Codec.Name +#13#10#13#10+
+ ' Width = '+inttostr(VideoCodecContext^.width)+ ', Height='+inttostr(VideoCodecContext^.height)+#13#10+
+ ' Aspect : '+inttostr(VideoCodecContext^.sample_aspect_ratio.num)+'/'+inttostr(VideoCodecContext^.sample_aspect_ratio.den)+#13#10+
+ ' Framerate : '+inttostr(VideoCodecContext^.time_base.num)+'/'+inttostr(VideoCodecContext^.time_base.den));
+{$endif}
+ // allocate space for decoded frame and rgb frame
+ AVFrame:=avcodec_alloc_frame;
+ AVFrameRGB:=avcodec_alloc_frame;
+ end;
+ myBuffer:=Nil;
+ if(AVFrame <> Nil) and (AVFrameRGB <> Nil) then
+ begin
+ myBuffer:=av_malloc(avpicture_get_size(PIX_FMT_RGB24, VideoCodecContext^.width,
+ VideoCodecContext^.height));
+ end;
+ if myBuffer <> Nil then errnum:=avpicture_fill(PAVPicture(AVFrameRGB), myBuffer, PIX_FMT_RGB24,
+ VideoCodecContext^.width, VideoCodecContext^.height)
+ else begin
+{$ifdef DebugDisplay}
+ showmessage('failed to allocate video buffer');
+{$endif}
+ av_free(AVFrameRGB);
+ av_free(AVFrame);
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+ Exit;
+ end;
+ if errnum >=0 then
+ begin
+ fVideoOpened:=True;
+
+ TexX := VideoCodecContext^.width;
+ TexY := VideoCodecContext^.height;
+ dataX := Round(Power(2, Ceil(Log2(TexX))));
+ dataY := Round(Power(2, Ceil(Log2(TexY))));
+ SetLength(fTexData,dataX*dataY*3);
+ // calculate some information for video display
+ VideoAspect:=VideoCodecContext^.sample_aspect_ratio.num/VideoCodecContext^.sample_aspect_ratio.den;
+ if (VideoAspect = 0) then
+ VideoAspect:=VideoCodecContext^.width/VideoCodecContext^.height
+ else
+ VideoAspect:=VideoAspect*VideoCodecContext^.width/VideoCodecContext^.height;
+ if VideoAspect >= 4/3 then
+ begin
+ ScaledVideoWidth:=800.0;
+ ScaledVideoHeight:=800.0/VideoAspect;
+ end else
+ begin
+ ScaledVideoHeight:=600.0;
+ ScaledVideoWidth:=600.0*VideoAspect;
+ end;
+ VideoTimeBase:=VideoCodecContext^.time_base.num/VideoCodecContext^.time_base.den;
+ // hack to get reasonable timebase for divx
+{$ifdef DebugDisplay}
+ showmessage('framerate: '+inttostr(floor(1/videotimebase))+'fps');
+{$endif}
+ if VideoTimeBase < 0.02 then // 0.02 <-> 50 fps
+ begin
+ VideoTimeBase:=VideoCodecContext^.time_base.den/VideoCodecContext^.time_base.num;
+ while VideoTimeBase > 50 do VideoTimeBase:=VideoTimeBase/10;
+ VideoTimeBase:=1/VideoTimeBase;
+ end;
+{$ifdef DebugDisplay}
+ showmessage('corrected framerate: '+inttostr(floor(1/videotimebase))+'fps');
+
+ if ((VideoAspect*VideoCodecContext^.width*VideoCodecContext^.height)>200000) then
+ showmessage('you are trying to play a rather large video'+#13#10+
+ 'be prepared to experience some timing problems');
+{$endif}
+ end;
+ end;
+end;
+
+procedure TVideoPlayback_ffmpeg.Close;
+begin
+ if fVideoOpened then
+ begin
+ av_free(myBuffer);
+ av_free(AVFrameRGB);
+ av_free(AVFrame);
+
+ avcodec_close(VideoCodecContext);
+ av_close_input_file(VideoFormatContext);
+
+ SetLength(fTexData,0);
+
+ fVideoOpened:=False;
+ end;
+end;
+
+procedure TVideoPlayback_ffmpeg.Play;
+begin
+end;
+
+procedure TVideoPlayback_ffmpeg.Pause;
+begin
+ fVideoPaused := not fVideoPaused;
+end;
+
+procedure TVideoPlayback_ffmpeg.Stop;
+begin
+end;
+
+procedure TVideoPlayback_ffmpeg.MoveTo(Time: real);
+begin
+ fVideoSkipTime := Time;
+
+ if fVideoSkipTime > 0 then
+ begin
+ av_seek_frame(VideoFormatContext,-1,Floor((fVideoSkipTime)*1500000),0);
+
+ VideoTime := fVideoSkipTime;
+ end;
+end;
+
+function TVideoPlayback_ffmpeg.getPosition: real;
+begin
+ result := 0;
+end;
+
+initialization
+ singleton_VideoFFMpeg := TVideoPlayback_ffmpeg.create();
+
+ writeln( 'UVideo_FFMpeg - Register Playback' );
+ AudioManager.add( IVideoPlayback( singleton_VideoFFMpeg ) );
+
+
+finalization
+ AudioManager.Remove( IVideoPlayback( singleton_VideoFFMpeg ) );
+
+
end.