diff options
Diffstat (limited to '')
-rw-r--r-- | Game/Code/Classes/UAudio_FFMpeg.pas | 153 | ||||
-rw-r--r-- | Game/Code/Classes/UCommon.pas | 88 | ||||
-rw-r--r-- | Game/Code/Classes/UFiles.pas | 20 | ||||
-rw-r--r-- | Game/Code/Classes/USongs.pas | 65 | ||||
-rw-r--r-- | Game/Code/Classes/UVideo.pas | 85 |
5 files changed, 297 insertions, 114 deletions
diff --git a/Game/Code/Classes/UAudio_FFMpeg.pas b/Game/Code/Classes/UAudio_FFMpeg.pas index 548fb343..35822a3b 100644 --- a/Game/Code/Classes/UAudio_FFMpeg.pas +++ b/Game/Code/Classes/UAudio_FFMpeg.pas @@ -7,6 +7,8 @@ This unit is primarily based upon - and tutorial03.c + http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html + *******************************************************************************) interface @@ -25,10 +27,10 @@ uses Classes, {$IFNDEF FPC} Forms, {$ENDIF} + SDL, // Used for Audio output Interface avcodec, // FFMpeg Audio file decoding avformat, avutil, - SDL, // Used for Audio output Interface ULog, UMusic; @@ -47,19 +49,28 @@ type function packet_queue_get(var aPacketQueue : TPacketQueue; var AVPacket : TAVPacket; block : integer ): integer; procedure packet_queue_init( var aPacketQueue : TPacketQueue ); procedure audio_callback( userdata: Pointer; stream: PUInt8; len: Integer ); cdecl; - function audio_decode_frame(aCodecCtx : TAVCodecContext; audio_buf : PUInt8; buf_size: integer): integer; + function audio_decode_frame(aCodecCtx : TAVCodecContext; aAudio_buf : PUInt8; buf_size: integer): integer; var singleton_MusicFFMpeg : IAudioPlayback = nil; +var + audioq : TPacketQueue; + quit : integer = 0; +// faudio_buf : array[ 0 .. 0 ] of byte; //pUInt8{$ifndef fpc};{$else} = nil;{$endif} +// audio_buf : array[ 0 .. AVCODEC_MAX_AUDIO_FRAME_SIZE ] of byte; //pUInt8{$ifndef fpc};{$else} = nil;{$endif} + +type + Taudiobuff = array[ 0 .. AVCODEC_MAX_AUDIO_FRAME_SIZE ] of byte; + PAudioBuff = ^Taudiobuff; implementation uses {$IFDEF FPC} lclintf, - {$ENDIF} libc, + {$ENDIF} // URecord, UIni, UMain, @@ -82,9 +93,6 @@ type const ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); -var - audioq : TPacketQueue; - quit : integer = 0; type @@ -154,7 +162,7 @@ end; constructor TAudio_ffMpeg.create(); begin - writeln( 'UVideo_FFMpeg - av_register_all' ); +// writeln( 'UVideo_FFMpeg - av_register_all' ); av_register_all; end; @@ -170,20 +178,20 @@ begin i := 0; while ( i < aFormatCtx.nb_streams ) do begin - writeln( ' aFormatCtx.streams[i] : ' + inttostr( i ) ); +// writeln( ' aFormatCtx.streams[i] : ' + inttostr( i ) ); st := aFormatCtx.streams[i]; if(st.codec.codec_type = CODEC_TYPE_VIDEO ) AND (aFirstVideoStream < 0) THEN begin - writeln( 'Found Video Stream' ); +// writeln( 'Found Video Stream' ); aFirstVideoStream := i; end; if ( st.codec.codec_type = CODEC_TYPE_AUDIO ) AND ( aFirstAudioStream < 0) THEN begin - writeln( 'Found Audio Stream' ); +// writeln( 'Found Audio Stream' ); aFirstAudioStream := i; end; @@ -206,8 +214,8 @@ var S: integer; begin - LoadSoundFromFile(BassStart, SoundPath + 'foo fighters - best of you.mp3'); - +// LoadSoundFromFile(BassStart, SoundPath + 'Green Day - American Idiot.mp3'); + (* LoadSoundFromFile(BassStart, SoundPath + 'Common start.mp3'); LoadSoundFromFile(BassBack, SoundPath + 'Common back.mp3'); @@ -438,12 +446,13 @@ end; procedure TAudio_ffMpeg.StopCard(Card: byte); begin + // TODO : jb_linux replace with something other than bass // BASS_RecordSetDevice(Card); // BASS_RecordFree; end; -function audio_decode_frame(aCodecCtx : TAVCodecContext; audio_buf : PUInt8; buf_size: integer): integer; +function audio_decode_frame(aCodecCtx : TAVCodecContext; aAudio_buf : PUInt8; buf_size: integer): integer; var pkt : TAVPacket; audio_pkt_data : pchar;//PUInt8 = nil; @@ -451,26 +460,44 @@ var len1 , data_size : integer; begin -// result := 1; -// exit; + {$ifdef win32} + FillChar(pkt, sizeof(pkt), #0); + {$else} + memset(@pkt, 0, sizeof(pkt)); // todo : jb memset + {$endif} + + audio_pkt_data := nil; + audio_pkt_size := 0; while true do begin while ( audio_pkt_size > 0 ) do begin - writeln( 'got audio packet' ); +// writeln( 'got audio packet' ); data_size := buf_size; - -// len1 := avcodec_decode_audio2(aCodecCtx, (int16_t )audio_buf, &data_size, audio_pkt_data, audio_pkt_size); - len1 := avcodec_decode_audio(@aCodecCtx, PWord( audio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box. + + len1 := -1; + + if aAudio_buf <> nil then + begin +// writeln( 'pre avcodec_decode_audio' ); + {$ifdef fpc} + len1 := avcodec_decode_audio(@aCodecCtx, PWord( aAudio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box. + {$else} + len1 := avcodec_decode_audio(@aCodecCtx, Pointer( aAudio_buf ), data_size, audio_pkt_data, audio_pkt_size); // Todo.. should be avcodec_decode_audio2 but this wont link on my ubuntu box. + {$endif} +// writeln( 'post avcodec_decode_audio' ); + + end; // writeln('avcodec_decode_audio'); if(len1 < 0) then begin //* if error, skip frame */ - audio_pkt_size := 0; +// writeln( 'Skip audio frame' ); + audio_pkt_size := 0; break; end; @@ -506,7 +533,7 @@ begin audio_pkt_data := pchar( pkt.data ); audio_pkt_size := pkt.size; - writeln( 'Audio Packet Size - ' + inttostr(audio_pkt_size) ); +// writeln( 'Audio Packet Size - ' + inttostr(audio_pkt_size) ); end; end; @@ -517,52 +544,69 @@ var audio_size , len1 : integer; aCodecCtx : TAVCodecContext; - audio_buf : pUInt8 = nil; + + lSrc : pointer; + + // this is used to emulate ...... static uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; + lAudio_buf_data : Taudiobuff; // This created the memory we need + laudio_buf : PAudioBuff; // this makes it easy to work with.. since its the pointer to that memeory everywhere begin - aCodecCtx := pAVCodecContext(userdata)^; - audio_buf := UInt8( (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) div 2); // todo : JB - audio_size := -1; + laudio_buf := @lAudio_buf_data ; -// writeln('----------- audio callback' ); + aCodecCtx := pAVCodecContext(userdata)^; + audio_size := -1; + audio_buf_index := 0; + audio_buf_size := 0; while (len > 0) do begin if(audio_buf_index >= audio_buf_size) then begin // We have already sent all our data; get more */ - audio_size := audio_decode_frame(aCodecCtx, audio_buf, sizeof(audio_buf)); + audio_size := audio_decode_frame(aCodecCtx, pUInt8( laudio_buf ), sizeof(laudio_buf)); if(audio_size < 0) then begin // If error, output silence */ audio_buf_size := 1024; // arbitrary? - memset(audio_buf, 0, audio_buf_size); // todo : jb memset + + {$ifdef win32} + FillChar(laudio_buf, audio_buf_size, #0); + {$else} + memset(laudio_buf, 0, audio_buf_size); // todo : jb memset + {$endif} end else begin audio_buf_size := audio_size; end; -// audio_buf_index := 0; // Todo : jb - SegFault ? + audio_buf_index := 0; // Todo : jb - SegFault ? end; len1 := audio_buf_size - audio_buf_index; if (len1 > len) then len1 := len; - - memcpy(stream, PUInt8( audio_buf ) + audio_buf_index , len1); - len := len - len1; - stream := stream + len1; + + {$ifdef win32} + lSrc := PUInt8( integer( laudio_buf ) + audio_buf_index ); + CopyMemory(stream, lSrc , len1); + {$else} + memcpy(stream, PUInt8( laudio_buf ) + audio_buf_index , len1); + {$endif} + + len := len - len1; + stream^ := stream^ + len1; audio_buf_index := audio_buf_index + len1; end; end; function TAudio_ffMpeg.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; var - L: Integer; - pFormatCtx: PAVFormatContext; + L : Integer; + pFormatCtx : PAVFormatContext; lVidStreamID , lAudStreamID : Integer; aCodecCtx : pAVCodecContext; @@ -578,7 +622,7 @@ begin if FileExists(Name) then begin - writeln('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); +// writeln('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); // Open video file if (av_open_input_file(pFormatCtx, pchar(Name), nil, 0, nil) > 0) then @@ -593,11 +637,11 @@ begin if not find_stream_ids( pFormatCtx, lVidStreamID, lAudStreamID ) then exit; - writeln( 'done searching for stream ids' ); +// writeln( 'done searching for stream ids' ); if lAudStreamID > -1 then begin - writeln( 'Audio Stream ID is : '+ inttostr( lAudStreamID ) ); +// writeln( 'Audio Stream ID is : '+ inttostr( lAudStreamID ) ); lAudioStream := pFormatCtx.streams[lAudStreamID]; aCodecCtx := lAudioStream.codec; @@ -617,9 +661,9 @@ begin writeln('SDL_OpenAudio: '+SDL_GetError()); exit end; - - writeln( 'SDL opened audio device' ); - + +// writeln( 'SDL opened audio device' ); + aCodec := avcodec_find_decoder(aCodecCtx.codec_id); if (aCodec = nil) then begin @@ -629,27 +673,28 @@ begin avcodec_open(aCodecCtx, aCodec); - writeln( 'Opened the codec' ); +// writeln( 'Opened the codec' ); packet_queue_init( audioq ); SDL_PauseAudio(0); - writeln( 'SDL_PauseAudio' ); +// writeln( 'SDL_PauseAudio' ); i := 0; - while (av_read_frame(pFormatCtx, packet)>=0) do + while (av_read_frame(pFormatCtx, packet) >= 0) do begin - writeln( 'ffmpeg - av_read_frame' ); +// writeln( 'ffmpeg - av_read_frame' ); if (packet.stream_index = lAudStreamID ) then begin +// writeln( 'packet_queue_put' ); packet_queue_put(audioq, packet); end else begin av_free_packet(packet); end; - + // Free the packet that was allocated by av_read_frame SDL_PollEvent(@event); @@ -665,12 +710,14 @@ begin *) end; - + +// halt(0); + // Close the codec - avcodec_close(aCodecCtx); +// avcodec_close(aCodecCtx); // Close the video file - av_close_input_file(pFormatCtx); +// av_close_input_file(pFormatCtx); (* try @@ -698,7 +745,11 @@ end; procedure packet_queue_init(var aPacketQueue : TPacketQueue ); begin - memset(@aPacketQueue, 0, sizeof(TPacketQueue)); + {$ifdef win32} + FillChar(aPacketQueue, sizeof(TPacketQueue), #0); + {$else} + memset(@aPacketQueue, 0, sizeof(TPacketQueue)); + {$endif} aPacketQueue.mutex := SDL_CreateMutex(); aPacketQueue.cond := SDL_CreateCond(); @@ -710,7 +761,7 @@ var begin result := -1; - writeln( 'TAudio_ffMpeg.packet_queue_put' ); +// writeln( 'TAudio_ffMpeg.packet_queue_put' ); if av_dup_packet(@AVPacket) < 0 then exit; diff --git a/Game/Code/Classes/UCommon.pas b/Game/Code/Classes/UCommon.pas index af9ae82d..44ec6bb3 100644 --- a/Game/Code/Classes/UCommon.pas +++ b/Game/Code/Classes/UCommon.pas @@ -58,6 +58,26 @@ function AdaptFilePaths( const aPath : widestring ): widestring; procedure ZeroMemory( Destination: Pointer; Length: DWORD ); {$ENDIF} +{$IFDEF Win32} + +type + TSearchRecW = record + Time: Integer;
+ Size: Integer;
+ Attr: Integer;
+ Name: WideString;
+ ExcludeAttr: Integer;
+ FindHandle: THandle;
+ FindData: TWin32FindDataW;
+ end;
+
+ function FindFirstW(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer;
+ function FindNextW(var F: TSearchRecW): Integer;
+ procedure FindCloseW(var F: TSearchRecW);
+ function FindMatchingFileW(var F: TSearchRecW): Integer;
+ function DirectoryExistsW(const Directory: widestring): Boolean;
+{$endif} + implementation function StringReplaceW(text : WideString; search, rep: WideChar):WideString; @@ -190,7 +210,75 @@ begin end; {$ENDIF} + + +
{$ENDIF} +{$ifdef win32} +function FindFirstW(const Path: widestring; Attr: Integer; var F: TSearchRecW): Integer;
+const
+ faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
+begin
+ F.ExcludeAttr := not Attr and faSpecial;
+ F.FindHandle := FindFirstFileW(PWideChar(Path), F.FindData);
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Result := FindMatchingFileW(F);
+ if Result <> 0 then FindCloseW(F);
+ end else
+ Result := GetLastError;
+end;
+
+function FindNextW(var F: TSearchRecW): Integer;
+begin
+ if FindNextFileW(F.FindHandle, F.FindData) then
+ Result := FindMatchingFileW(F)
+ else
+ Result := GetLastError;
+end;
+
+procedure FindCloseW(var F: TSearchRecW);
+begin
+ if F.FindHandle <> INVALID_HANDLE_VALUE then
+ begin
+ Windows.FindClose(F.FindHandle);
+ F.FindHandle := INVALID_HANDLE_VALUE;
+ end;
+end;
+
+function FindMatchingFileW(var F: TSearchRecW): Integer;
+var
+ LocalFileTime: TFileTime;
+begin
+ with F do
+ begin
+ while FindData.dwFileAttributes and ExcludeAttr <> 0 do
+ if not FindNextFileW(FindHandle, FindData) then
+ begin
+ Result := GetLastError;
+ Exit;
+ end;
+ FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
+ FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo);
+ Size := FindData.nFileSizeLow;
+ Attr := FindData.dwFileAttributes;
+ Name := FindData.cFileName;
+ end;
+ Result := 0;
+end;
+
+function DirectoryExistsW(const Directory: widestring): Boolean;
+var
+ Code: Integer;
+begin
+ Code := GetFileAttributesW(PWideChar(Directory));
+ Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
+end;
+{$endif} + + + + end. diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 7e23b42f..717d20e2 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -333,16 +333,22 @@ Result := False; //Open File and set File Pointer to the beginning AssignFile(SongFile, Song.Path + Song.FileName); - Reset(SongFile); +// if assinged( SongFile ) then + begin + try + Reset(SongFile); - //Clear old Song Header - ClearSong(Song); + //Clear old Song Header + ClearSong(Song); - //Read Header - Result := ReadTxTHeader(Song); + //Read Header + Result := ReadTxTHeader(Song); - //And Close File - CloseFile(SongFile); + //And Close File + finally + CloseFile(SongFile); + end; + end; {except CloseFile(SongFile); diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas index 99474961..e3c54ac4 100644 --- a/Game/Code/Classes/USongs.pas +++ b/Game/Code/Classes/USongs.pas @@ -13,6 +13,7 @@ uses SysUtils, {$endif} ULog, UTexture, + UCommon, UCatCovers; type @@ -23,33 +24,33 @@ type end; TScore = record - Name: string; + Name: widestring; Score: integer; Length: string; end; TSong = record - Path: string; - Folder: string; // for sorting by folder - FileName: string; + Path: widestring; + Folder: widestring; // for sorting by folder + FileName: widestring; // sorting methods - Category: array of string; // I think I won't need this - Genre: string; - Edition: string; - Language: string; // 0.5.0: new + Category: array of widestring; // I think I won't need this + Genre: widestring; + Edition: widestring; + Language: widestring; // 0.5.0: new - Title: string; - Artist: string; + Title: widestring; + Artist: widestring; - Text: string; - Creator: string; + Text: widestring; + Creator: widestring; - Cover: string; + Cover: widestring; CoverTex: TTexture; - Mp3: string; - Background: string; - Video: string; + Mp3: widestring; + Background: widestring; + Video: widestring; VideoGAP: real; VideoLoaded: boolean; // 0.5.0: true if the video has been loaded NotesGAP: integer; @@ -79,7 +80,7 @@ type procedure LoadSongList; // load all songs procedure BrowseDir(Dir: widestring); // should return number of songs in the future procedure Sort(Order: integer); - function FindSongFile(Dir, Mask: string): string; + function FindSongFile(Dir, Mask: widestring): widestring; end; TCatSongs = class @@ -133,7 +134,7 @@ end; procedure TSongs.BrowseDir(Dir: widestring); var - SR: TSearchRec; // for parsing Songs Directory + SR: TSearchRecW; // for parsing Songs Directory SLen: integer; {$ifndef win32} @@ -144,16 +145,16 @@ var {$endif} begin {$ifdef win32} - if FindFirst(Dir + '*', faDirectory, SR) = 0 then // JB_Unicode - windows + if FindFirstW(Dir + '*', faDirectory, SR) = 0 then // JB_Unicode - windows begin repeat if (SR.Name <> '.') and (SR.Name <> '..') then begin BrowseDir(Dir + Sr.Name + PathDelim); end - until FindNext(SR) <> 0; + until FindNextw(SR) <> 0; end; // if - FindClose(SR); + FindClosew(SR); {$else} // Itterate the Songs Directory... ( With unicode capable functions for linux ) TheDir := opendir( Dir ); // JB_Unicode - linux @@ -178,7 +179,7 @@ begin // Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList'); - if FindFirst(Dir + '*.txt', 0, SR) = 0 then + if FindFirstW(Dir + '*.txt', 0, SR) = 0 then begin repeat SLen := BrowsePos; @@ -204,9 +205,9 @@ begin SetLength(Song, Length(Song) + 50); end; - until FindNext(SR) <> 0; + until FindNextW(SR) <> 0; end; // if FindFirst - FindClose(SR); + FindCloseW(SR); end; procedure TSongs.Sort(Order: integer); @@ -309,7 +310,7 @@ begin end; // case end; -function TSongs.FindSongFile(Dir, Mask: string): string; +function TSongs.FindSongFile(Dir, Mask: widestring): widestring; var SR: TSearchRec; // for parsing song directory begin @@ -463,10 +464,12 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sTitle) and (Length(Songs.Song[S].Title)>=1) and (Letter <> UpCase(Songs.Song[S].Title[1])) then begin + else if (Ini.Sorting = sTitle) and + (Length(Songs.Song[S].Title)>=1) and + (Letter <> UpperCase(Songs.Song[S].Title)[1]) then begin // add a letter Category Button Inc(Order); - Letter := UpCase(Songs.Song[S].Title[1]); + Letter := Uppercase(Songs.Song[S].Title)[1]; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := '[' + Letter + ']'; @@ -491,10 +494,10 @@ case Ini.Sorting of CatSongs.Song[CatLen].Visible := true; end - else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpCase(Songs.Song[S].Artist[1])) then begin + else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> UpperCase(Songs.Song[S].Artist)[1]) then begin // add a letter Category Button Inc(Order); - Letter := UpCase(Songs.Song[S].Artist[1]); + Letter := UpperCase(Songs.Song[S].Artist)[1]; CatLen := Length(CatSongs.Song); SetLength(CatSongs.Song, CatLen+1); CatSongs.Song[CatLen].Artist := '[' + Letter + ']'; @@ -545,7 +548,7 @@ case Ini.Sorting of end else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin - if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpCase(Songs.Song[S].Title[1]); + if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Title)[1]; if (Letter <> Letter2) then begin // add a letter Category Button Inc(Order); @@ -575,7 +578,7 @@ case Ini.Sorting of end else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin - if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpCase(Songs.Song[S].Artist[1]); + if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := UpperCase(Songs.Song[S].Artist)[1]; if (Letter <> Letter2) then begin // add a letter Category Button Inc(Order); diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas index 4c27867d..154cd04c 100644 --- a/Game/Code/Classes/UVideo.pas +++ b/Game/Code/Classes/UVideo.pas @@ -10,9 +10,11 @@ unit UVideo; # # ############################################################################## } -{$define DebugDisplay} // uncomment if u want to see the debug stuff +//{$define DebugDisplay} // uncomment if u want to see the debug stuff //{$define DebugFrames} //{$define Info} + +//{$define FFMpegAudio} {} @@ -45,6 +47,9 @@ uses SDL, dialogs, {$endif} {$ENDIF} + {$ifdef FFMpegAudio} + UAudio_FFMpeg, + {$endif} UIni, UMusic; @@ -108,7 +113,9 @@ type end; - + const + SDL_AUDIO_BUFFER_SIZE = 1024; + {$ifdef DebugDisplay} //{$ifNdef win32} @@ -262,19 +269,23 @@ begin 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 + 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); + begin 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)); + {$ifdef FFMpegAudio} + end + else + if (AVPacket.stream_index = AudioStreamIndex ) then + begin + UAudio_FFMpeg.packet_queue_put(UAudio_FFMpeg.audioq, AVPacket); + {$endif} + end; try if AVPacket.data <> nil then @@ -427,6 +438,10 @@ var errnum, i, x,y: Integer; lStreamsCount : Integer; + wanted_spec , + spec : TSDL_AudioSpec; + aCodec : pAVCodec; + begin fVideoOpened := False; fVideoPaused := False; @@ -471,27 +486,47 @@ begin end; aCodecCtx := VideoFormatContext.streams[ AudioStreamIndex ].codec; + {$ifdef FFMpegAudio} + // This is the audio ffmpeg audio support Jay is working on. if aCodecCtx <> nil then begin + wanted_spec.freq := aCodecCtx.sample_rate; + wanted_spec.format := AUDIO_S16SYS; + wanted_spec.channels := aCodecCtx.channels; + wanted_spec.silence := 0; + wanted_spec.samples := SDL_AUDIO_BUFFER_SIZE; + wanted_spec.callback := UAudio_FFMpeg.audio_callback; + wanted_spec.userdata := aCodecCtx; -// 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(@wanted_spec, @spec) < 0) then + begin + writeln('SDL_OpenAudio: '+SDL_GetError()); + exit; + end; + + writeln( 'SDL opened audio device' ); + + aCodec := avcodec_find_decoder(aCodecCtx.codec_id); + if (aCodec = nil) then + begin + writeln('Unsupported codec!'); + exit; + end; + + avcodec_open(aCodecCtx, aCodec); + + writeln( 'Opened the codec' ); + + packet_queue_init( audioq ); + SDL_PauseAudio(0); + + writeln( 'SDL_PauseAudio' ); + end; -(* - if(SDL_OpenAudio(WantedAudioCodecContext, AudioCodecContext) < 0) then - begin - writeln( 'Could not do SDL_OpenAudio' ); - exit; - end; -*) - + {$endif} + if(VideoStreamIndex >= 0) then begin VideoCodecContext:=VideoFormatContext^.streams[VideoStreamIndex]^.codec; |