Commits

Anonymous committed 77cf3e2

Fixed seek issues, memory load issue, fixed bug in the movie_test. Added
proper sound seeking so that audio and video don't desync after
seeking.

Issue still not resolved, where the audio and video desync with a spot
of stuttering sound, until seek is used after the bad portion, on the
Doctor Horrible Ep. 1 video. No other video I've used has this problem.

Comments (0)

Files changed (5)

 
 print "Please give an (absolute)filename of a movie file you'd like to play: ",
 #filename = raw_input()
-filename="/home/tyler/tos.avi"
+filename="/home/tyler/War3.avi"
 #initialization. It could also have a surface as a second argument, and every 
 # frame will be blitted to that surface. It is the programmer's responsibility
 # to be on time for rendering that surface.
 
 m.play(-1)       #We're going to use infinite play, so we can demonstrate all 
                 # the features.
-time.sleep(200)  #sleep for ten seconds to let one see the video play, and hear 
+time.sleep(2)  #sleep for ten seconds to let one see the video play, and hear 
                 # the audio
 ##print "Paused:",m.paused
 ##print "Playing:",m.playing
 ##print "Movie:",m
 ##print "Y Top:",m.ytop
 ##print "X Left:",m.xleft
-time.sleep(30)
+time.sleep(10)
 print "Testing seek..."
-m.easy_seek(10, 5, 0, 0)
+m.easy_seek(10, 0, 0, 0)
 time.sleep(5)
-m.easy_seek(10, 5, 0, 0)
+m.easy_seek(10, 0, 0, 0)
 time.sleep(1)
 m.pause()
 time.sleep(5)
 #while not m.finished:
 #    time.sleep(0.1)
 #    pygame.display.update()
-
+m.stop()
+time.sleep(5)
+del m
 
 
 m=movie.Movie(filename, screen)
 	return comm;
 }
 
-int hasCommand(CommandQueue *q)
+inline int hasCommand(CommandQueue *q)
 {
 	if(q->size>0)
 		return 1;
         }
        
         GRABGIL
-	        PySys_WriteStdout("Actual Delay: %f\tdelay: %f\tdiff: %f\tpts: %f\tFrame-timer: %f\tCurrent_time: %f\tsync_thres: %f\n", (actual_delay*1000.0)+10, delay, diff, movie->video_current_pts, movie->frame_timer, (cur_time / 1000000.0), sync_threshold);
+	        //PySys_WriteStdout("Actual Delay: %f\tdelay: %f\tdiff: %f\tpts: %f\tFrame-timer: %f\tCurrent_time: %f\tsync_thres: %f\n", (actual_delay*1000.0)+10, delay, diff, movie->video_current_pts, movie->frame_timer, (cur_time / 1000000.0), sync_threshold);
         //double audio = getAudioClock();
         //PySys_WriteStdout("Audio_Clock: %f\tVideo_Clock: %f\tDiff: %f\n", ref_clock, movie->video_current_pts, ref_clock-movie->video_current_pts);
         /*if((actual_delay*1000.0)>250.0)
         channels = enc->channels;
         if(!movie->replay)
         {
-	        if (soundInit  (freq, -16, channels, 1024) < 0)
+	        if (soundInit  (freq, -16, channels, 1024, av_q2d(ic->streams[stream_index]->time_base)) < 0)
 	        {
 	            RAISE(PyExc_SDLError, SDL_GetError ());
 	        }
     video_open(movie, 0);
     movie->last_showtime = av_gettime()/1000.0;
     double start_time=av_gettime();
+    int seeking =0;
     for(;;)
     {
     	if(hasCommand(movie->commands) && !movie->working)
             if(aud_stream_index>=0)
 				aud_seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[vid_stream_index]->time_base);
 			
+			//int64_t end = av_rescale_q(movie->video_st->duration, AV_TIME_BASE_Q, movie->video_st->time_base);
 			if(vid_stream_index>=0)
 			{
+            	if(vid_seek_target > movie->video_st->duration)
+            	{	
+            		vid_seek_target = vid_seek_target%movie->video_st->duration;
+            	}
             	ret = av_seek_frame(movie->ic, vid_stream_index, vid_seek_target, movie->seek_flags);
+            	
 	            if (ret < 0)
 	            {
 	                PyErr_Format(PyExc_IOError, "%s: error while seeking", movie->ic->filename);
             {
                 packet_queue_flush(&movie->audioq);
                 packet_queue_put(&movie->audioq, &flush_pkt);
+            	seeking=1;	
+            
             }
      
             movie->seek_req = 0;
          			bytesDecoded = avcodec_decode_video(movie->video_st->codec, frame, &frameFinished, pkt->data, pkt->size);
          			if(frameFinished)
          			{
-         				if(pkt->pts >= vid_seek_target)
+         				if((pkt->pts >= vid_seek_target) || (pkt->dts >= vid_seek_target))
+         				{
+         					av_free(frame);
          					break;
+         				}
          			}
+         			av_free(frame);
          		}
          		av_free_packet(pkt);
          	}
-         	
+         	av_free_packet(pkt);
+         	        	
         }
         /* if the queue are full, no need to read more */
         if ( //yay for short circuit logic testing
             }
             if (pkt->stream_index == movie->audio_stream)
             {
+            	if(seeking)
+            	{
+            		seekBuffer(pkt->pts);
+            		seeking=0;
+            	}
                 packet_queue_put(&movie->audioq, pkt);
+                
             }
             else if (pkt->stream_index == movie->video_stream)
             {
 }
 
 //initialize the mixer audio subsystem, code cribbed from mixer.c
-int soundInit  (int freq, int size, int channels, int chunksize)
+int soundInit  (int freq, int size, int channels, int chunksize, double time_base)
 {
     Uint16 fmt = 0;
     int i;
     ainfo->mutex = SDL_CreateMutex();
     ainfo->queue.mutex = SDL_CreateMutex();
     ainfo->ended=1;
+    ainfo->time_base=time_base;
     Mix_VolumeMusic (127);
     
     //ainfo->_tstate = _tstate;
 	{
     	int bytes_per_sec = ainfo->channels*ainfo->sample_rate*2;
     	ainfo->audio_clock+= (double) len/(double) bytes_per_sec;
-    	int n_pkts = bytes_per_sec/len;
-    	//double change = (double)pts/(double)n_pkts;
-    	//double clock = ainfo->audio_clock;
-    	/*if(((change-clock)> 0.2 ) && (change-clock)<5.0)
-    	{
-    		ainfo->audio_clock = change;
-    	}*/
+    	
 	}
     ainfo->current_frame_size =len;
     int chan = ainfo->channel;
         return 0;
     return Mix_Paused(channel);
 }
-int seekBuffer (uint8_t *buf, uint32_t len, int channel)
+int seekBuffer (double pts)
 {
 	/*we need to flush our buffer */
 	queue_flush(&ainfo->queue);
-	ainfo->ended=1;
+	if (pts != AV_NOPTS_VALUE) 
+	{
+            ainfo->audio_clock = ainfo->time_base*pts;
+    }
+	//ainfo->ended=1;
 	return 1;
 }
 
     SDL_mutex   *mutex;
 	//PyThreadState *_tstate;
 	int restart;
+	double time_base;
 }
 AudioInfo;
 
 AudioInfo *ainfo;
 
-int soundInit     (int freq, int size, int channels, int chunksize);
+int soundInit     (int freq, int size, int channels, int chunksize, double time_base);
 int soundQuit     (void);
 int soundStart    (void);
 int soundEnd      (void);
 int getPaused     (int channel);
 double getAudioClock (void);
 int getBufferQueueSize(void);
-int seekBuffer    (uint8_t *buf, uint32_t len, int channel );
+int seekBuffer    (double pts);
 int setCallback   (void (*callback) (int channel));
 int resetAudioInfo(void);
 #endif /*_GSOUND_H_*/
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.