Commits

Anonymous committed cdd6aaf

Finished addition of CommandQueue, will add ytop, xleft, surface stuff
to command queue now. Also fixed an issue when stopping and playing a
video.

Will be trying to have ffmpeg write directly to the surface array.

  • Participants
  • Parent commits 9ac8fde
  • Branches tylerthemovie

Comments (0)

Files changed (7)

 ##print "Movie:",m
 ##print "Y Top:",m.ytop
 ##print "X Left:",m.xleft
-time.sleep(30)
-print "Testing seek..."
-m.easy_seek(second=10, minute=5, reverse=0)
-time.sleep(5)
-m.easy_seek(second=10, minute=5, reverse=0)
-time.sleep(1)
-m.pause()
-time.sleep(5)
-m.pause()
-time.sleep(10000)
-
-print "Altering xleft and ytop..."
-m.xleft += 10
-m.ytop  +=10
-time.sleep(10)
-m.xleft -= 10
-m.ytop -=10
+##time.sleep(30)
+##print "Testing seek..."
+##m.easy_seek(second=10, minute=5, reverse=0)
+##time.sleep(5)
+##m.easy_seek(second=10, minute=5, reverse=0)
+##time.sleep(1)
+##m.pause()
+##time.sleep(5)
+##m.pause()
+##time.sleep(10)
+##
+##print "Altering xleft and ytop..."
+##m.xleft += 10
+##m.ytop  +=10
+##time.sleep(10)
+##m.xleft -= 10
+##m.ytop -=10
 #Now we're going to play with the size of the window, affecting the video on 
 #the fly. resize(width, height) is the main function, changes them both at
 # 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
-print "sleeping again" 
-time.sleep(10)
-print "Back to normal!"
-m.width=m.width/2
-m.height = m.height/2
-print "and again, sleeping..."
+##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
+##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)
+##time.sleep(10)
 
 
 #Here we demonstrate the use of pause. You pause, then call pause again to play
 ##print m.paused
 ##print m.playing
 ##time.sleep(10)
-###Here is the stop function. Right now, rewind is the exact same as stop.
-##print "Stopping..., sleeping for 3 seconds"
-##m.stop()
-##time.sleep(3)
-###And now we restart playing.
-##print "Playing again..." 
-##m.play(-1)
-##print "done restart play..."
-##time.sleep(10)
+#Here is the stop function. Right now, rewind is the exact same as stop.
+print "Stopping..., sleeping for 3 seconds"
+m.stop()
+time.sleep(5)
+#And now we restart playing.
+del m
+print "Playing again..." 
+m=movie.Movie(filename)
+m.play(-1)
+print "done restart play..."
+time.sleep(10)
 print "Surface time..."
 screen = pygame.display.set_mode((640, 348))
 #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 
 # time.
+while not m.finished:
+    time.sleep(0.1)
+    pygame.display.update()
+
+
 
 m=movie.Movie(filename, screen)
 counter = 0
 #include "_gcommand.h"
 
-
 void addCommand(CommandQueue *q, Command *comm)
 {
 	SDL_LockMutex(q->q_mutex);
-	if(!q->first)
+	q->registry[comm->type]++;
+	if(!q->size)
 	{
 		q->first=comm;
 		q->size++;
 		SDL_UnlockMutex(q->q_mutex);
 		return;
 	}
-	if(!q->last)
+	if(q->size==1)
 	{
 		q->last=comm;
 		q->first->next=comm;
 	}
 	SDL_UnlockMutex(q->q_mutex);
 }
+
+int registerCommand(CommandQueue *q)
+{
+	//int cur = q->reg_ix;
+	if(q->reg_ix>=1024)
+		q->reg_ix=0;
+	q->registry[q->reg_ix]=0;
+	q->reg_ix++;
+	return q->reg_ix-1;
+}
 #include <SDL_thread.h>
 #include <Python.h>
 
+#define COMMON_COMMAND \
+	int type;\
+	size_t size; 
+
+
 typedef struct Command
 {
-	int type;
+	COMMON_COMMAND
 	struct Command *next;
-	size_t size;
 } Command;
 
+#define FULL COMMAND \
+	int type;\
+	size_t size;\
+	struct Command *next;
+
 typedef struct CommandQueue
 {
 	int size;
 	SDL_mutex *q_mutex;
 	Command *first;
 	Command *last;
+	int registry[1024];
+	int reg_ix;
 } CommandQueue;
 
 
 int hasCommand(CommandQueue *q);
 void flushCommands(CommandQueue *q);
 
+int registerCommand(CommandQueue *q);
+
 #endif /*_GCOMMAND_H_*/
     return val;
 }
 
+void registerCommands(PyMovie *self)
+{
+	self->seekCommandType=registerCommand(self->commands);
+    self->pauseCommandType=registerCommand(self->commands);
+    self->stopCommandType=registerCommand(self->commands);
+    self->resizeCommandType=registerCommand(self->commands);
+}
+
 /* seek in the stream */
 void stream_seek(PyMovie *movie, int64_t pos, int rel)
 {
-    //DECLAREGIL
-    //GRABGIL
-    //Py_INCREF( movie);
-    //RELEASEGIL
-    if (!movie->seek_req)
-    {
-        movie->seek_pos = pos;
-        movie->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;
-
-        movie->seek_req = 1;
-    }
-    //GRABGIL
-    //Py_DECREF( movie);
-    //RELEASEGIL
+    seekCommand *seek = (seekCommand *) PyMem_Malloc(sizeof(seekCommand));
+    seek->type = movie->seekCommandType;
+    seek->size = sizeof(seekCommand);
+    seek->pos = pos;
+    seek->rel = rel;
+    addCommand(movie->commands, (Command *)seek);
 }
 
 /* pause or resume the video */
 void stream_pause(PyMovie *movie)
 {
-    if(movie->ob_refcnt !=0)Py_INCREF( movie);
+    /*if(movie->ob_refcnt !=0)Py_INCREF( movie);
     int paused=movie->paused;
     movie->paused = !movie->paused;
     if (!movie->paused)
     }
     movie->last_paused=paused;
     if(movie->ob_refcnt !=0) {Py_DECREF( movie);}
+	*/
+	pauseCommand *pause = (pauseCommand *) PyMem_Malloc(sizeof(pauseCommand));
+	pause->type = movie->pauseCommandType;
+	pause->size = sizeof(pauseCommand);
+	addCommand(movie->commands, (Command *)pause);
 }
 
 int audio_thread(void *arg)
     		pauseBuffer(movie->channel);
     		movie->audio_paused=movie->paused;
     		if(movie->audio_paused)
+    		{
+    			movie->working=0;
     			continue;
+    		}
     	}
+    	
         if(movie->paused)
         {
         	SDL_Delay(10);
     	if(movie->sub_st)
     		stream_component_end(movie, movie->sub_st->index, 1);
     	#endif
+    	if(movie->stop)
+    	{
+    		VidPicture *vp;
+
+	        int i;
+	        for( i =0; i<VIDEO_PICTURE_QUEUE_SIZE; i++)
+	        {
+	            vp = &movie->pictq[i];
+	            if (vp->dest_overlay)
+	            {
+	                SDL_FreeYUVOverlay(vp->dest_overlay);
+	                vp->dest_overlay = NULL;
+	            }
+	            if(vp->dest_surface)
+	            {
+	                SDL_FreeSurface(vp->dest_surface);
+	                vp->dest_surface=NULL;
+	            }
+	            
+	        }	
+    	}
     }
     GRABGIL
     Py_DECREF(movie);
     AVPacket pkt1, *pkt = &pkt1;
     movie->stop=0;
     movie->finished =0;
+    movie->playing=1;
     ic=movie->ic;
     int co=0;
     SDL_Delay(150);
     movie->last_showtime = av_gettime()/1000.0;
     for(;;)
     {
+    	if(hasCommand(movie->commands) && !movie->working)
+    	{
+    		Command *comm = getCommand(movie->commands);
+    		if(comm->type==movie->seekCommandType)
+    		{
+    			seekCommand *seek = (seekCommand *)comm;
+    			movie->seek_req=1;
+    			movie->seek_pos = seek->pos;
+    			movie->seek_flags |= seek->rel;
+    			/* clear stuff away now */
+    			comm = NULL;
+    			//GRABGIL
+    			PyMem_Free(seek);
+				//RELEASEGIL
+    			movie->working=1;
+    		}
+    		else if(comm->type==movie->pauseCommandType)
+    		{
+    			pauseCommand *pause = (pauseCommand *)comm;
+    			movie->paused = !movie->paused;
+    			movie->working = movie->paused;
+			    if (!movie->paused)
+			    {
+			        movie->video_current_pts = get_video_clock(movie);
+			        movie->frame_timer += (av_gettime() - movie->video_current_pts_time) / 1000000.0;
+			    }
+			    comm=NULL;
+			    PyMem_Free(pause);			    
+    		}
+    		else if (comm->type ==movie->stopCommandType)
+    		{
+    			stopCommand *stop = (stopCommand *)comm;
+    			movie->stop=1;
+    			comm=NULL;
+    			PyMem_Free(stop);
+    			movie->working=1;
+    		}
+    		else if (comm->type == movie->resizeCommandType)
+    		{
+    			resizeCommand *resize=(resizeCommand *)comm;
+    			if (resize->h)
+    			{
+    				movie->resize_h=1;
+    				movie->height=resize->h;
+    			}
+    			if(resize->w)
+    			{
+    				movie->resize_w=1;
+    				movie->width= resize->w;
+    			}	
+    			comm=NULL;
+    			PyMem_Free(resize);
+    		}	
+    		
+    	}
+    	
         co++;
         if (movie->abort_request)
         {
         if (movie->paused != movie->last_paused)
         {
             movie->last_paused = movie->paused;
-            if(!movie->audio_paused)
-            {
-            	//we do this in case we haven't reached the audio thread yet... which will cause this function to just loop without ever touching the audio_thread function.
-	            pauseBuffer(movie->channel);
-            }
             if (movie->paused)
-            {
-            	
+            {            	
                 av_read_pause(ic);
             }
             else
          		}
          		av_free_packet(pkt);
          	}
+         	movie->working=0;
         }
         /* if the queue are full, no need to read more */
         if ( //yay for short circuit logic testing
     #endif
     Py_DECREF( movie);
     RELEASEGIL
+    movie->playing=0;
     if(movie->abort_request)
     {
         return -1;
     int              abort_request;  /* Tells whether or not to stop playing and return */
     int              paused; 		 /* Boolean for communicating to the threads to pause playback */
     int              last_paused;    /* For comparing the state of paused to what it was last time around. */
+    int 			 working;
     char             filename[1024];
     char            *_backend;       //"FFMPEG_WRAPPER";
     int              overlay;        //>0 if we are to use the overlay, otherwise <=0
     SDL_Surface     *canon_surf;     //pointer to the surface given by the programmer. We do NOT free this... it is not ours. We just write to it.
     PyThreadState   *_tstate;        //really do not touch this unless you have to. This is used for threading control and primitives.
 	int finished;
+	
+	/* command queue stuff */
+    CommandQueue *commands;
+	int seekCommandType;   
+	int pauseCommandType; 
+    int stopCommandType;
+    int resizeCommandType;
     int diff_co; //counter
 
     /* Seek-info */
 
 }
 PyMovie;
+
+/*command definitions */
+typedef struct seekCommand
+{
+	COMMON_COMMAND
+	struct Command *next;
+	int64_t pos;
+	int rel;
+} seekCommand;
+
+
+typedef struct pauseCommand
+{
+	COMMON_COMMAND
+	struct Command *next;
+} pauseCommand;
+
+typedef struct stopCommand
+{
+	COMMON_COMMAND
+	struct Command *next;
+} stopCommand;
+
+typedef struct resizeCommand
+{
+	COMMON_COMMAND
+	struct Command *next;
+	int h;
+	int w;
+} resizeCommand;
+
 /* end of struct definitions */
 /* function definitions */
 
 double get_external_clock (PyMovie *is);
 double get_master_clock   (PyMovie *is);
 
+/* 		Command management */
+void registerCommands(PyMovie *movie);
+
 #if 0
 /*		Subtitle Management*/
 int subtitle_render(void *arg);
     int chan = ainfo->channel;
     
     //SDL_mutexV(ainfo->mutex);
+    int paused = Mix_Paused(channel);
+    if(paused)
+    {
+    	ainfo->ended=0;
+        Mix_Resume(-1);
+    }
     
     int playing = Mix_Playing(chan);
     if(playing && allocated &&false)
     Py_INCREF(self);
     //already malloced memory for PyMovie.
     self->_backend="FFMPEG_WRAPPER";
+    self->commands = (CommandQueue *)PyMem_Malloc(sizeof(CommandQueue));
+    self->commands->q_mutex = SDL_CreateMutex();
+	self->commands->size=0;
+	self->commands->reg_ix=0;
+	registerCommands(self);
+    self->commands->size=0;
     if(!surf)
     {
         //set overlay to true
         PyErr_SetString(PyExc_TypeError, "No valid arguments");
         return -1;
     }
-
+	
     if(surf && PySurface_Check(surf))
     {
         SDL_Surface *target = PySurface_AsSurface(surf);
     {
     	//first we release the GIL, then we release all the resources associated with the streams, if they exist.
     	PyEval_ReleaseLock();
-        if(movie->video_st)
-            stream_component_end(movie, movie->video_st->index, 0);
-        if(movie->audio_st)
-            stream_component_end(movie, movie->audio_st->index, 0);
-        PyEval_AcquireLock();
-        movie->stop = 0;
+		_movie_stop(movie);
     }
 
     SDL_LockMutex(movie->dest_mutex);
 
 PyObject* _movie_stop(PyMovie *movie)
 {
-    Py_INCREF(movie);
+    /*Py_INCREF(movie);
     Py_BEGIN_ALLOW_THREADS
     SDL_LockMutex(movie->dest_mutex);
     stream_pause(movie);
     Py_END_ALLOW_THREADS
     SDL_UnlockMutex(movie->dest_mutex);
     Py_DECREF(movie);
+    Py_RETURN_NONE;*/
+    stream_pause(movie);
+    stopCommand *stop = (stopCommand *)PyMem_Malloc(sizeof(stopCommand));
+    stop->type = movie->stopCommandType;
+    addCommand(movie->commands, (Command *)stop);
     Py_RETURN_NONE;
 }
 
 PyObject* _movie_pause(PyMovie *movie)
 {
 
-    Py_BEGIN_ALLOW_THREADS
+    //Py_BEGIN_ALLOW_THREADS
     stream_pause(movie);
-    Py_END_ALLOW_THREADS
+    //Py_END_ALLOW_THREADS
     Py_RETURN_NONE;
 }
 
     {
         return RAISE (PyExc_SDLError, "Cannot set negative sized display mode");
     }
-    movie->height = h;
-    movie->width  = w;
+    resizeCommand *resize = (resizeCommand *)PyMem_Malloc(sizeof(resizeCommand));
+    resize->type = movie->resizeCommandType;
+    
+    resize->h = h;
+    resize->w  = w;
+    addCommand(movie->commands, (Command *)resize);
     //status indicators for rendering and that. Very important!
-    movie->resize_w =  movie->resize_h= 1;
+    //movie->resize_w =  movie->resize_h= 1;
     Py_RETURN_NONE;
 
 }
     if(PyInt_Check(width))
     {
         w = (int)PyInt_AsLong(width);
-        movie->resize_w=1;
-        movie->width=w;
+        resizeCommand *resize = (resizeCommand *)PyMem_Malloc(sizeof(resizeCommand));
+    	resize->type = movie->resizeCommandType;
+    
+    	resize->h = 0;
+    	resize->w  = w;
+		addCommand(movie->commands, (Command *)resize);
         return 0;
     }
     else
     if(PyInt_Check(height))
     {
         h = (int)PyInt_AsLong(height);
-        movie->resize_h=1;
-        movie->height=h;
+    	resizeCommand *resize = (resizeCommand *)PyMem_Malloc(sizeof(resizeCommand));
+    	resize->type = movie->resizeCommandType;
+    
+    	resize->h = h;
+    	resize->w  = 0;
+		addCommand(movie->commands, (Command *)resize);
         return 0;
     }
     else