Anonymous avatar Anonymous committed 2031a59

Fixed various bugs in stop and pause. Managed to eliminate most of the
music errors that came up before, stuck only with the video errors
spouted off by ffmpeg. Must investigate further. Hrm.

Comments (0)

Files changed (6)

 # the same time.
 print "Resizing..."
 m.resize(m.width/2, m.height*2)
+print "sleeping..."
 time.sleep(10) #another ten second nap.
 print "Resizing again..."
-m.width = m.width*4 
+m.width = m.width*4
+print "sleeping again" 
 time.sleep(10)
 print "Back to normal!"
 m.width=m.width/2
 m.height = m.height/2
+print "and again, sleeping..."
 #back to our original size
 time.sleep(10)
 #Here we demonstrate the use of pause. You pause, then call pause again to play
 print "Pausing..."
 m.pause()
+print "done pausing..."
 print m.paused
 print m.playing
 time.sleep(2)
 print "Playing again..."
 m.play(-1)
 
+time.sleep(10)
 print "Surface time..."
-time.sleep(10)
 screen = pygame.display.set_mode((m.width, m.height))
 #This will move the movie player from overlay mode to blitting to the surface 
 # we've given it. This means it is our responsibility to update the display on 
         counter+=1
         print counter
         prev_time=new_time
+    #print "testing counter"
     if counter==30:
+        #print "breaking"
         break
+    #print "has_key"
     if actions.has_key(counter):
         print "Performing action at counter value: %d" % counter
         actions[counter](m)
         counter +=1
+    #print "updating"
     pygame.display.update() #we can do this because we're blitting each frame of the movie to the main screen we instantiated.
     
 m.stop()
 /* pause or resume the video */
 void stream_pause(PyMovie *movie)
 {
-	DECLAREGIL
-	GRABGIL
+	/*DECLAREGIL
+	GRABGIL*/
     Py_INCREF( movie);
-    RELEASEGIL
+    //RELEASEGIL
     int paused = movie->paused;
     //SDL_LockMutex(movie->dest_mutex);
     movie->paused = !movie->paused;
     }
     movie->last_paused=paused;
     //SDL_UnlockMutex(movie->dest_mutex);
-    GRABGIL
+    //GRABGIL
     Py_DECREF( movie);
-	RELEASEGIL
+	//RELEASEGIL
 }
 
 
 	int co = 0;
 	for(;co<10;co++)
 	{
-		if (movie->paused) {
+		if(movie->audio_paused && !movie->paused)
+		{
+			pauseBuffer(movie->channel);
+			movie->audio_paused = 0;	
+		}
+		if (movie->paused && !movie->audio_paused) {
         	pauseBuffer(movie->channel);
+        	movie->audio_paused = 1;
             goto closing;
         }
+       
         //check if the movie has ended
 		if(movie->stop)
 		{
         	/* Buffer is filled up with a new frame, we spin lock/wait for a signal, where we then call playBuffer */
         	SDL_LockMutex(movie->audio_mutex);
         	//SDL_CondWait(movie->audio_sig, movie->audio_mutex);
-        	int chan = playBuffer(movie->audio_buf1, data_size);
+        	int chan = playBuffer(movie->audio_buf1, data_size, movie->channel);
         	movie->channel = chan;
         	filled=0;
         	len1=0;
 }
 
 /* this thread gets the stream from the disk or the network */
- int decoder(void *arg)
+int decoder(void *arg)
 {
 	PyMovie *movie = arg;
 	DECLAREGIL
             (movie->videoq.size > MAX_VIDEOQ_SIZE )||
             (movie->subtitleq.size > MAX_SUBTITLEQ_SIZE)) {
             /* wait 10 ms */
-            if(movie->videoq.size > MAX_VIDEOQ_SIZE && movie->video_st)
-            	video_render(movie);
-            if(movie->audioq.size > MAX_AUDIOQ_SIZE && movie->audio_st)
-	            audio_thread(movie);
-            SDL_Delay(10);
+			if(!movie->paused)
+			{
+				//we only forcefully pull a packet of the queues when the queue is too large and the video file is not paused.
+				// The simple reason is that video_render and audio_thread do nothing, so its a waste of cycles.
+	            if(movie->videoq.size > MAX_VIDEOQ_SIZE && movie->video_st)
+	            	{video_render(movie);}
+	            if(movie->audioq.size > MAX_AUDIOQ_SIZE && movie->audio_st)
+		            {audio_thread(movie);}
+			}
             continue;
         }
         if(url_feof(ic->pb)) {
                 }
                 movie->last_showtime = av_gettime()/1000.0;
                 
-            } else {
-                SDL_Delay(10);
             }
         }
         /*
     do {
     	
         if (movie->paused && !movie->videoq.abort_request) {
-            if(movie->paused)
-	            return 0;
-        }
+	    	goto the_end;
+	    }
         if (packet_queue_get(&movie->videoq, pkt, 0) <=0)
             break;
 		
                                     frame, &got_picture,
                                     pkt->data, pkt->size);
 		
-        if(   ( pkt->dts == AV_NOPTS_VALUE)
-           && frame->reordered_opaque != AV_NOPTS_VALUE)
+        if(( pkt->dts == AV_NOPTS_VALUE) && (frame->reordered_opaque != AV_NOPTS_VALUE))
         {
             pts= frame->reordered_opaque;
         }
 	SDL_mutex *audio_mutex;
 	SDL_Thread *audio_tid;
 	int channel;
-	
+	int audio_paused;
 	/* Frame/Video Management members */
     int frame_count;
     double frame_timer;
 	PyMem_Free(mix);
 	mix=NULL;
 	//PySys_WriteStdout("Callback called.\n");
-	playBuffer(NULL, (uint32_t) 0);
+	playBuffer(NULL, (uint32_t) 0, channel);
 	//PySys_WriteStdout("Callback finished.\n");
 	//PyGILState_Release(gstate);
 }
 }
 	
 /* Play a sound buffer, with a given length */
-int playBuffer (uint8_t *buf, uint32_t len)
+int playBuffer (uint8_t *buf, uint32_t len, int channel)
 {
 	Mix_Chunk *mix;
 	int allocated=0;
 			node->len = len;
 			node->next =NULL;
 			queue_put(&queue, node);
-			return 0;
+			return channel;
 		}
 		else if(!buf && queue.size==0)
 		{
 	return 0;
 }
 		
+int getPaused (int channel)
+{
+	if(channel<=-1)
+		return 0;
+	return Mix_Paused(channel);
+}
 int seekBuffer (uint8_t *buf, uint32_t len, int channel)
 {
 	stopBuffer(channel);
-	return playBuffer(buf, len);
+	return playBuffer(buf, len, channel);
 }
 
 int setCallback(void (*callback)(int channel))
 
 int soundInit  (int freq, int size, int channels, int chunksize, SDL_cond *cond);
 int soundQuit  (void);
-int playBuffer (uint8_t *buf, uint32_t len);
+int playBuffer (uint8_t *buf, uint32_t len, int channel);
 int stopBuffer (int channel);
 int pauseBuffer(int channel);
+int getPaused  (int channel);
 int seekBuffer (uint8_t *buf, uint32_t len, int channel );
 int setCallback(void (*callback) (int channel));
 
 #include "gmovie.h"
 
 
- PyMovie*  _movie_init_internal(PyMovie *self, const char *filename, SDL_Surface *surf)
+PyMovie*  _movie_init_internal(PyMovie *self, const char *filename, SDL_Surface *surf)
 {
 	Py_INCREF(self);
 	//already malloced memory for PyMovie.
 }
 
 
- int _movie_init(PyObject *self, PyObject *args, PyObject *kwds)
+int _movie_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
 	Py_INCREF(self);
 	const char *c;
     PyObject *buffer = PyString_FromString(buf);
     return buffer;
 }
- PyObject* _movie_play(PyMovie *movie, PyObject* args)
+PyObject* _movie_play(PyMovie *movie, PyObject* args)
 {
 	PyEval_InitThreads();
 	PyInterpreterState *interp;
     movie->paused = 0;
     movie->playing = 1;
     SDL_UnlockMutex(movie->dest_mutex);
-	PyEval_ReleaseLock();	
+	Py_BEGIN_ALLOW_THREADS	
 	movie->parse_tid = SDL_CreateThread(decoder_wrapper, movie);
+	Py_END_ALLOW_THREADS
     Py_DECREF(movie);
     Py_RETURN_NONE;
 }
 
- PyObject* _movie_stop(PyMovie *movie)
+PyObject* _movie_stop(PyMovie *movie)
 {
     Py_INCREF(movie);
+    Py_BEGIN_ALLOW_THREADS
     SDL_LockMutex(movie->dest_mutex);
-	//PyThreadState_Swap(NULL);
-    PyEval_ReleaseLock();
     stream_pause(movie);
-    PyEval_AcquireLock();
     movie->seek_req = 1;
     movie->seek_pos = 0;
     movie->seek_flags =AVSEEK_FLAG_BACKWARD;
     movie->stop = 1;
+    Py_END_ALLOW_THREADS
     SDL_UnlockMutex(movie->dest_mutex);  
     Py_DECREF(movie);
     Py_RETURN_NONE;
 }  
 
- PyObject* _movie_pause(PyMovie *movie)
+PyObject* _movie_pause(PyMovie *movie)
 {
+	Py_BEGIN_ALLOW_THREADS
     stream_pause(movie); 
+    Py_END_ALLOW_THREADS
     Py_RETURN_NONE;
 }
 
- PyObject* _movie_rewind(PyMovie *movie, PyObject* args)
+PyObject* _movie_rewind(PyMovie *movie, PyObject* args)
 {
     /* For now, just alias rewind to stop */
     return _movie_stop(movie);
 	Py_RETURN_NONE;
 	
 }
- PyObject* _movie_get_paused (PyMovie *movie, void *closure)
+PyObject* _movie_get_paused (PyMovie *movie, void *closure)
 {
     return PyBool_FromLong((long)movie->paused);
 }
     	if(movie->width)
     		{pyo = PyInt_FromLong((long)movie->width);}
     	else
-    		{pyo= PyInt_FromLong((long)movie->video_st->codec->width);}
+    	{
+    		if(movie->video_st->codec)
+	    		{pyo= PyInt_FromLong((long)movie->video_st->codec->width);}
+    		else
+    			{pyo = PyInt_FromLong((long)0);}
+    	}
     }
     else
     {
 	{ NULL}
 };
 	
- static PyGetSetDef _movie_getsets[] =
+static PyGetSetDef _movie_getsets[] =
 {
     { "paused",  (getter) _movie_get_paused,  NULL,                        DOC_GMOVIEMOVIEPAUSE,   NULL },
     { "playing", (getter) _movie_get_playing, NULL,                        DOC_GMOVIEMOVIEPLAYING, NULL },
     { NULL,      NULL,                        NULL,                        NULL,                   NULL }
 };
 
- static PyTypeObject PyMovie_Type =
+static PyTypeObject PyMovie_Type =
 {
     PyObject_HEAD_INIT(NULL)
     0, 
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.