From 24c8e13594e6bfd8fdf835b915c834de8894334d Mon Sep 17 00:00:00 2001 From: s_alexander Date: Tue, 8 Dec 2009 02:38:39 +0000 Subject: added starting pts handling some video files have a starting point for the pts calculation that starting point has to be subtracted from the pts of each frame to avoid hanging of the video git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2003 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/media/UVideo.pas | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/media/UVideo.pas b/src/media/UVideo.pas index 3f25cdf7..6db9cd20 100644 --- a/src/media/UVideo.pas +++ b/src/media/UVideo.pas @@ -22,7 +22,7 @@ * $URL$ * $Id$ *} - + unit UVideo; {* @@ -136,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 @@ -146,7 +146,7 @@ type procedure SynchronizeTime(Frame: PAVFrame; var pts: double); procedure GetVideoRect(var ScreenRect, TexRect: TRectCoords); - + procedure ShowDebugInfo(); public @@ -172,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; @@ -249,7 +249,7 @@ begin // TODO: do we really want this by default? fLoop := true; fLoopTime := 0; - + fAspectCorrection := acoCrop; end; @@ -481,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; @@ -575,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 @@ -622,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} @@ -646,7 +650,7 @@ begin {$IFDEF VideoBenchmark} Log.BenchmarkStart(15); {$ENDIF} - + // fetch new frame (updates fTime) Success := DecodeFrame(); TimeDifference := NewTime - fTime; @@ -673,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 @@ -699,7 +703,7 @@ begin 0, fCodecContext^.Height, @(fAVFrameRGB.data), @(fAVFrameRGB.linesize)); {$ELSE} - // img_convert from lib/ffmpeg/avcodec.pas is actually deprecated. + // 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 @@ -709,7 +713,7 @@ begin PAVPicture(fAVFrame), fCodecContext^.pix_fmt, fCodecContext^.width, fCodecContext^.height); {$ENDIF} - + if (errnum < 0) then begin Log.LogError('Image conversion failed', 'TVideoPlayback_ffmpeg.GetFrame'); @@ -940,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 -- cgit v1.2.3