changeset 129:587ad94d6ac2

(none)
author ivand_qmul
date Thu, 08 Nov 2007 13:29:48 +0000
parents 247ea6460ec2
children b3df8b8185db
files data/fileio/VideoFileReader.cpp sv/audioio/AudioCallbackPlaySource.h sv/audioio/AudioPortAudioTarget.cpp sv/main/MainWindow.cpp sv/main/MainWindow.h sv/videoio/SDL_ffmpeg.cpp sv/videoio/SDL_ffmpeg.h
diffstat 7 files changed, 207 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/VideoFileReader.cpp	Thu Nov 08 10:50:48 2007 +0000
+++ b/data/fileio/VideoFileReader.cpp	Thu Nov 08 13:29:48 2007 +0000
@@ -29,7 +29,10 @@
 
 #include "VideoFileReader.h"
 
-
+#ifdef WIN32
+#include <Windows.h>
+#endif
+long long countFreq;
 VideoFileReader::VideoFileReader(QString path, bool showProgress, CacheMode mode) :
     CodedAudioFileReader(mode),
     m_path(path)
@@ -221,7 +224,13 @@
 	SDL_ffmpegGetVideoSize(film, &w, &h);
 	//SDL_ffmpegStartDecoding(film);
     SDL_Delay(1000);
-	
+	QueryPerformanceFrequency((LARGE_INTEGER *)(&countFreq));
+	countFreq/=1000;
+	film->countFreq=countFreq;
+	QueryPerformanceCounter((LARGE_INTEGER *)(&film->timer));
+	film->timer=film->timer/(film->countFreq);
+	film->timebase=1;
+	film->vs[film->videoStream]->lastTimeStamp=0;
 	while( film->videoThreadActive ) {
 
 		
@@ -263,7 +272,7 @@
         }
 
         // we wish not to kill our poor cpu, so we give it some timeoff
-        SDL_Delay(10);
+       // SDL_Delay(1);
     }
 	// after all is said and done, we should call this
     SDL_ffmpegFree(film);
--- a/sv/audioio/AudioCallbackPlaySource.h	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/audioio/AudioCallbackPlaySource.h	Thu Nov 08 13:29:48 2007 +0000
@@ -25,7 +25,7 @@
 #include <QObject>
 #include <QMutex>
 #include <QWaitCondition>
-
+#include <time.h>
 #include "base/Thread.h"
 
 #include <samplerate.h>
@@ -184,7 +184,9 @@
      * realtime thread.
      */
     size_t getSourceSamples(size_t count, float **buffer);
-
+//Ivan
+	unsigned long long hardwareBufferedTime;
+	unsigned long lastAudioTime;
     /**
      * Set the time stretcher factor (i.e. playback speed).  Also
      * specify whether the time stretcher will be variable rate
--- a/sv/audioio/AudioPortAudioTarget.cpp	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/audioio/AudioPortAudioTarget.cpp	Thu Nov 08 13:29:48 2007 +0000
@@ -22,6 +22,25 @@
 #include <cassert>
 #include <cmath>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef WIN32
+	#define __STDC_LIMIT_MACROS
+	#define __STDC_CONSTANT_MACROS
+	#include "avformat.h"
+	#include "swscale.h"
+	#include <Windows.h>
+#endif
+
+#ifdef __unix__
+        #include "ffmpeg/avformat.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
 //#define DEBUG_AUDIO_PORT_AUDIO_TARGET 1
 
 AudioPortAudioTarget::AudioPortAudioTarget(AudioCallbackPlaySource *source) :
@@ -246,7 +265,12 @@
     }
 
     m_source->setOutputLevels(peakLeft, peakRight);
-
+	/*if (received>0)
+	{
+		long long cntClick;
+		QueryPerformanceCounter((LARGE_INTEGER *)(&cntClick));
+		m_source->hardwareBufferedTime=cntClick;
+	}*/
     return 0;
 }
 
--- a/sv/main/MainWindow.cpp	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/main/MainWindow.cpp	Thu Nov 08 13:29:48 2007 +0000
@@ -115,6 +115,9 @@
 using std::map;
 using std::set;
 
+extern float hopfactor;
+extern long long countFreq;
+
 MainWindow * MainWindow::m_instance = 0;
 
 MainWindow * MainWindow::instance()
@@ -2298,8 +2301,8 @@
     }
 }
 
+// Ivan Damnjanovic 09-10/2007 added video file import
 void
-// Ivan Damnjanovic 09-10/2007 added video file import
 MainWindow::importVideo()
 {
     QString path = getOpenFileName(FileFinder::VideoFile);
@@ -3531,12 +3534,37 @@
         playbackFrameChanged(m_viewManager->getPlaybackFrame());
 	m_playSource->play(m_viewManager->getPlaybackFrame());
     }
+	m_playSource->hardwareBufferedTime=0;
+	m_playSource->lastAudioTime=0;
 }
 // Ivan Damnjanovic 16/10/2007 functions to access data needed for video player
 unsigned long 
 MainWindow::Get_CurAudioTime()
 {
-	return (m_viewManager->getPlaybackFrame()/(getMainModel()->getSampleRate()/1000));
+	unsigned long pos;
+	unsigned long newAudioTime=m_viewManager->getPlaybackFrame()/(getMainModel()->getSampleRate()/1000);
+	if(!(m_playSource->lastAudioTime==newAudioTime))
+	{
+		m_playSource->lastAudioTime=newAudioTime;
+		long long cntClick;
+		QueryPerformanceCounter((LARGE_INTEGER *)(&cntClick));
+		m_playSource->hardwareBufferedTime=cntClick;
+		pos=0;
+	}
+	else
+	{
+		long long timeTemp;
+			QueryPerformanceCounter((LARGE_INTEGER *)(&timeTemp));
+			
+			pos=(timeTemp-m_playSource->hardwareBufferedTime)/(countFreq);
+			pos*=hopfactor;
+	}
+	return (newAudioTime+pos);
+}
+unsigned long long
+MainWindow::Get_HardwareBufferTime()
+{
+	return (m_playSource->hardwareBufferedTime);
 }
 bool MainWindow::isAudioPlaying()
 {
--- a/sv/main/MainWindow.h	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/main/MainWindow.h	Thu Nov 08 13:29:48 2007 +0000
@@ -23,7 +23,7 @@
 #include <QPointer>
 #include <QTabWidget>
 #include <QStatusBar>
-
+#include <time.h>
 #include "base/Command.h"
 #include "view/ViewManager.h"
 #include "base/PropertyContainer.h"
@@ -104,6 +104,7 @@
 // Ivan Damnjanovic 09-10/2007 added video file import
 	FileOpenStatus openVideoFile(QString path, AudioFileOpenMode = AskUser);
 	unsigned long Get_CurAudioTime();
+	unsigned long long Get_HardwareBufferTime();
 	bool isAudioPlaying();
 //
     FileOpenStatus openLayerFile(QString path);
--- a/sv/videoio/SDL_ffmpeg.cpp	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/videoio/SDL_ffmpeg.cpp	Thu Nov 08 13:29:48 2007 +0000
@@ -29,6 +29,8 @@
 #include "SDL_ffmpeg.h"
 #include <SDL.h>
 #include <SDL_thread.h>
+#include <stdio.h>
+#include <Windows.h>
 #endif
 
 #ifdef __unix__
@@ -39,12 +41,16 @@
 }
 #endif
 #include "../../sv/main/MainWindow.h"
+#include <time.h>
 
 //const int SDL_FFMPEG_MAX_BUFFERED_FRAMES = 25;
 //const int SDL_FFMPEG_MAX_BUFFERED_SAMPLES = 512 * 512;
-
+extern float hopfactor;
 int FFMPEG_init_was_called = 0;
-
+FILE *pFile, *tFile;
+int64_t Time,Time1;
+int64_t realt=0;
+  
 SDL_ffmpegFile* SDL_ffmpegCreateFile() {
 
     // create SDL_ffmpegFile pointer
@@ -54,6 +60,10 @@
     // create a semaphore for every file
     file->decode = SDL_CreateSemaphore(1);
 
+	Time=0;
+	Time1=0;
+   fopen_s (&pFile,"myfile.txt","w");
+	 fopen_s (&tFile,"Timestampfile.txt","w");
     // allocate room for VStreams
     file->vs = (SDL_ffmpegStream**)malloc( sizeof(SDL_ffmpegStream*) * MAX_STREAMS );
     if(!file->vs) {
@@ -176,7 +186,8 @@
                     stream->audio = 0;
                     stream->size = 0;
                     stream->imageBuffer = (bufferImage**)calloc( SDL_FFMPEG_MAX_BUFFERED_FRAMES, sizeof(bufferImage*) );
-
+					stream->writeImage = 0;
+					stream->readImage = 0;
                     file->vs[file->VStreams] = stream;
                     file->VStreams++;
 
@@ -250,54 +261,117 @@
     SDL_SemWait(file->vs[file->videoStream]->sem);
 
     bufferImage *option = 0;
-    int i;
+    //int i;
+	float ratio;
+	int64_t pos,pos1, pos2, timestamp;
+    //for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
+		pos=MWinsA->Get_CurAudioTime();
 
-    for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
+		fprintf (pFile, "p: \t %u\t", pos);
+		//if (MWinsA->Get_HardwareBufferTime()==0)
+		//	pos1=0;
+		//else {
+		//	pos1=MWinsA->Get_HardwareBufferTime();
+		//	//fprintf (tFile, "%u\t", pos1);
+		//	int64_t timeTemp;
+		//	QueryPerformanceCounter((LARGE_INTEGER *)(&timeTemp));
+		//	
+		//	pos1=(timeTemp-pos1)/(file->countFreq*hopfactor);
+		//	fprintf (pFile, "%u\t", pos1);
+		//}
+		//pos2=pos+pos1;
+		fprintf (pFile, "%u\n", pos);
+		
+        // if this entry does not exist, continue
+        while(((file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage)>0)&&(file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp <= pos + ((AVFormatContext*)file->_ffmpeg)->start_time/1000))//&& (file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp >= pos - file->timebase+ ((AVFormatContext*)file->_ffmpeg)->start_time/1000)) 
+		{
+			//pos=MWinsA->Get_CurAudioTime();
+			//timestamp=file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp;
+			//fprintf (tFile, "try: %d	%d\n", (pos+ ((AVFormatContext*)file->_ffmpeg)->start_time/1000), timestamp);
+			// do we have an image that should have been shown?
+			//if(file->vs[file->videoStream]->imageBuffer[mod(file->vs[file->videoStream]->readImage,SDL_FFMPEG_MAX_BUFFERED_FRAMES)]->timestamp <= pos + (file->vs[file->videoStream]->timeBase)/4+((AVFormatContext*)file->_ffmpeg)->start_time/1000) {
+				
+				// if this is the first option we find, we simply save it
+				if(!option) {
 
-        // if this entry does not exist, continue
-        if(!file->vs[file->videoStream]->imageBuffer[i]) continue;
-		
+					option = file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES];
 
-		int64_t pos=MWinsA->Get_CurAudioTime();
-        // do we have an image that should have been shown?
-        if(file->vs[file->videoStream]->imageBuffer[i]->timestamp <= pos + ((AVFormatContext*)file->_ffmpeg)->start_time/1000) {
+					// set to 0 so we know this position in the buffer is available again
+					file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = 0;
+					file->vs[file->videoStream]->readImage++;
 
-            // if this is the first option we find, we simply save it
-            if(!option) {
+				} else {
 
-                option = file->vs[file->videoStream]->imageBuffer[i];
+					// we found a newer possible timestamp, we delete the older one
+					if( option->timestamp < file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]->timestamp) {
 
-                // set to 0 so we know this position in the buffer is available again
-                file->vs[file->videoStream]->imageBuffer[i] = 0;
+						// this image is too old, we discard it
+						SDL_FreeSurface( option->img );
 
-            } else {
+						// free old option
+						free( option );
 
-                // we found a newer possible timestamp, we delete the older one
-                if( option->timestamp < file->vs[file->videoStream]->imageBuffer[i]->timestamp) {
+						// new pointer to position in container
+						option = file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES];
 
-                    // this image is too old, we discard it
-                    SDL_FreeSurface( option->img );
+						// set to 0 so we know this position in the buffer is available again
+						file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = 0;
+						file->vs[file->videoStream]->readImage++;
+					}
+					else {
+						file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->readImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES]=0;
+						file->vs[file->videoStream]->readImage++;
+					}
+				}
 
-                    // free old option
-                    free( option );
-
-                    // new pointer to position in container
-                    option = file->vs[file->videoStream]->imageBuffer[i];
-
-                    // set to 0 so we know this position in the buffer is available again
-                    file->vs[file->videoStream]->imageBuffer[i] = 0;
-                }
-            }
-        }
-    }
-
+				
+				pos=MWinsA->Get_CurAudioTime();	
+				fprintf (pFile, "e:\t%u\t", pos);
+				//if (MWinsA->Get_HardwareBufferTime()==0)
+				//	pos1=0;
+				//else {
+				//	pos1=MWinsA->Get_HardwareBufferTime();
+				//	//fprintf (tFile, "%u\t", pos1);
+				//	int64_t timeTemp;
+				//	QueryPerformanceCounter((LARGE_INTEGER *)(&timeTemp));
+			
+				//	pos1=(timeTemp-pos1)/(file->countFreq*hopfactor);
+				//	fprintf (pFile, "%u\t", pos1);
+				//}
+				//fprintf (pFile, "%u\n", pos2);
+				//pos2=pos+pos1;
+				//if (pos<pos2) pos=pos2;
+		}
+		//}
+	//}
+	int x=file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage;
     // if we did not found an option, we exit
     if(!option) {
         // release the lock
+		/*timestamp=0;
+		int64_t tt=av_gettime()/1000-file->timer;
+		file->timer=av_gettime()/1000;
+		realt+=tt;
+		fprintf (tFile, "%u\t", realt);
+		fprintf (tFile, "%u\t", tt);
+		fprintf (tFile, "%u\t", pos);
+		fprintf (tFile, "%u\n", timestamp);*/
         SDL_SemPost(file->vs[file->videoStream]->sem);
         return 0;
     }
-
+	int64_t tt;
+	QueryPerformanceCounter((LARGE_INTEGER *)(&tt));
+	tt=tt/(file->countFreq)-file->timer;
+	
+	QueryPerformanceCounter((LARGE_INTEGER *)(&file->timer));
+	file->timer=file->timer/(file->countFreq);
+	realt+=tt;
+	fprintf (tFile, "%u\t", x);
+	fprintf (tFile, "%u\t", realt);
+	fprintf (tFile, "%u\t", tt);
+	timestamp=(pos-option->timestamp+((AVFormatContext*)file->_ffmpeg)->start_time/1000)/hopfactor;	
+	fprintf (tFile, "%u\t", pos);//+ (file->vs[file->videoStream]->timeBase)/4+((AVFormatContext*)file->_ffmpeg)->start_time/1000);
+	fprintf (tFile, "%d\n", timestamp);
     // we did found an option, so we return the imagedata
     return option->img;
 }
@@ -512,7 +586,7 @@
         if( SDL_ffmpegValidVideo(file) && pack.stream_index == file->vs[file->videoStream]->id && !file->skipVideo) {
 
             got_frame = 0;
-
+//Time1=av_gettime();
             // Decode the packet
             avcodec_decode_video((AVCodecContext *)(file->vs[file->videoStream]->_ffmpeg), inFrame, &got_frame, pack.data, pack.size);
 
@@ -566,13 +640,15 @@
                     // copy image data to image room
                     memcpy(buf->img->pixels, inFrameRGB->data[0],
                         file->vs[file->videoStream]->width * file->vs[file->videoStream]->height * 3);
-
+					file->timebase=buf->timestamp-file->vs[file->videoStream]->lastTimeStamp;
                     // we write the lastTimestamp we got
                     file->vs[file->videoStream]->lastTimeStamp = buf->timestamp;
 
-                    int i;
+                    //int i;
                     int again = 1;
+//Time=av_gettime()-Time1;
 
+//fprintf (pFile, "%d	\n",Time);
                     // keep trying to fit in buffer, until the data was actually placed in the buffer
                     while(again && file->threadActive) {
 
@@ -581,22 +657,28 @@
 
                             // loop through all positions in buffer until an empty
                             // space was found
-                            for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
+                            //for(i=0; i<SDL_FFMPEG_MAX_BUFFERED_FRAMES; i++) {
                                 // if this place in the buffer is empty we write our new frame
-                                if(file->vs[file->videoStream]->imageBuffer[i] == 0) {
-                                    file->vs[file->videoStream]->imageBuffer[i] = buf;
+                                if((file->vs[file->videoStream]->writeImage - file->vs[file->videoStream]->readImage) < SDL_FFMPEG_MAX_BUFFERED_FRAMES) {
+                                    file->vs[file->videoStream]->imageBuffer[file->vs[file->videoStream]->writeImage%SDL_FFMPEG_MAX_BUFFERED_FRAMES] = buf;
+									file->vs[file->videoStream]->writeImage++;
                                     // we placed our image in the buffer, moving on
                                     again = 0;
-                                    break;
+                                    
                                 }
-                            }
+                            //}
 
                         // we leave the video semaphore
                         SDL_SemPost(file->vs[file->videoStream]->sem);
-
+						
                         // frames aren't being release every ms, so we can take some
                         // time before we try and fit our new image again
-                        if(again) SDL_Delay(5);
+                        if(again) 
+						{
+							SDL_SemPost(file->decode);
+							SDL_Delay(3);
+							SDL_SemWait(file->decode);
+						}
                     }
     //            } 
 				//else {
@@ -730,7 +812,8 @@
                 // set position in buffer to 0, so we know it is empty
                 file->vs[file->videoStream]->imageBuffer[i] = 0;
             }
-
+			file->vs[file->videoStream]->writeImage=0;
+			file->vs[file->videoStream]->readImage=0;
         SDL_SemPost(file->vs[file->videoStream]->sem);
     }
 
--- a/sv/videoio/SDL_ffmpeg.h	Thu Nov 08 10:50:48 2007 +0000
+++ b/sv/videoio/SDL_ffmpeg.h	Thu Nov 08 13:29:48 2007 +0000
@@ -74,7 +74,8 @@
     // audio/video buffers
     bufferImage **imageBuffer;
     int8_t *audio;
-
+	int writeImage;
+	int readImage;
     // userinfo
     double frameRate[2];
     char language[4];
@@ -115,6 +116,9 @@
 	int skipAudio;
 	int skipVideo;
 	int delay;
+	int64_t timer;
+	int64_t countFreq;
+	int timebase;
 	int64_t audioTime;
 } SDL_ffmpegFile;