[Mplayer-cvslog] CVS: main edl.c, NONE, 1.1 Makefile, 1.300, 1.301 edl.h, 1.2, 1.3 mplayer.c, 1.779, 1.780

Roberto Togni CVS syncmail at mplayerhq.hu
Sat Aug 28 02:46:08 CEST 2004


CVS change done by Roberto Togni CVS

Update of /cvsroot/mplayer/main
In directory mail:/var2/tmp/cvs-serv27489

Modified Files:
	Makefile edl.h mplayer.c 
Added Files:
	edl.c 
Log Message:
EDL enhancement/fixes:
*Some edl's code moved from mplayer.c to edl.c (mencoder will use the 
same functions)
* slighty faster
* removed MAX_EDL_ENTRIES limit (just reserve the memory we really need)
* really treat edl_records as a linked list (coz it is)
* edl now 'remembers' pending operations after a manual _seek_
* better way of handling Mute/Umute eliminates some nasty bugs
when manual seeking (scrwed up mute/unmute order, no audio after
seek, etc)
* seeking while on -edl mode now _WORKS_
Patch by Reynaldo H. Verdejo Pinochet  (reynaldo at opendot dot cl)



--- NEW FILE ---
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "mp_msg.h"
#include "edl.h"

#ifdef USE_EDL

int edl_check_mode(void)
{
    if (edl_filename && edl_output_filename)
    {
        return (EDL_ERROR);
    }

    return (1);
}

int edl_count_entries(void)
{
    FILE *fd = NULL;
    int entries = 0;
    int action = 0;
    float start = 0;
    float stop = 0;
    char line[100];

    if (edl_filename)
    {
        if ((fd = fopen(edl_filename, "r")) == NULL)
        {
            mp_msg(MSGT_CPLAYER, MSGL_WARN,
                   "Invalid EDL file, cant open '%s' for reading!\n",
                   edl_filename);
            return (EDL_ERROR);
        } else
        {
            while (fgets(line, 99, fd) != NULL)
            {
                if ((sscanf(line, "%f %f %d", &start, &stop, &action)) ==
                    3)
                {
                    if (action == EDL_SKIP)
                        entries += 1;
                    if (action == EDL_MUTE)
                        entries += 2;
                } else
                {
                    mp_msg(MSGT_CPLAYER, MSGL_WARN,
                           "Invalid EDL line: %s\n", line);
                    return (EDL_ERROR);
                }

            }
        }
    } else
    {
        return (EDL_ERROR);
    }

    return (entries);
}

int edl_parse_file(edl_record_ptr edl_records)
{
    FILE *fd;
    char line[100];
    float start, stop;
    int action;
    int record_count = 0;
    int lineCount = 0;
    struct edl_record *next_edl_record = edl_records;

    if (edl_filename)
    {
        if ((fd = fopen(edl_filename, "r")) == NULL)
        {
            return (EDL_ERROR);
        } else
        {
            while (fgets(line, 99, fd) != NULL)
            {
                lineCount++;
                if ((sscanf(line, "%f %f %d", &start, &stop, &action))
                    != 3)
                {
                    mp_msg(MSGT_CPLAYER, MSGL_WARN,
                           "Badly formated EDL line [%d]. Discarding!\n",
                           lineCount + 1, line);
                    continue;
                } else
                {
                    if (record_count > 0)
                    {
                        if (start <= (next_edl_record - 1)->stop_sec)
                        {
                            mp_msg(MSGT_CPLAYER, MSGL_WARN,
                                   "Invalid EDL line [%d]: %s",
                                   lineCount, line);
                            mp_msg(MSGT_CPLAYER, MSGL_WARN,
                                   "Last stop position was [%f]; next start is [%f]. Entries must be in chronological order and cannot overlap. Discarding!\n",
                                   (next_edl_record - 1)->stop_sec, start);
                            continue;
                        }
                    }
                    if (stop <= start)
                    {
                        mp_msg(MSGT_CPLAYER, MSGL_WARN,
                               "Invalid EDL line [%d]: %s", lineCount,
                               line);
                        mp_msg(MSGT_CPLAYER, MSGL_WARN,
                               "Stop time must follow start time. Discarding!\n");
                        continue;
                    }
                    next_edl_record->action = action;
                    if (action == EDL_MUTE)
                    {
                        next_edl_record->length_sec = 0;
                        next_edl_record->start_sec = start;
                        next_edl_record->stop_sec = start;
                        next_edl_record->mute_state = EDL_MUTE_START;
                        next_edl_record++;
                        (next_edl_record - 1)->next = next_edl_record;
                        next_edl_record->action = action;
                        next_edl_record->length_sec = 0;
                        next_edl_record->start_sec = stop;
                        next_edl_record->stop_sec = stop;
                        next_edl_record->mute_state = EDL_MUTE_END;

                    } else
                    {
                        next_edl_record->length_sec = stop - start;
                        next_edl_record->start_sec = start;
                        next_edl_record->stop_sec = stop;
                    }
                    next_edl_record++;

                    if (record_count >= 0)
                    {
                        (next_edl_record - 1)->next = next_edl_record;
                    }

                    record_count++;
                }
            }

            if (record_count > 0)
            {
                (next_edl_record - 1)->next = NULL;
            }
        }
        fclose(fd);
    } else
    {
        return (EDL_ERROR);
    }

    return (record_count);
}

#endif

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/Makefile,v
retrieving revision 1.300
retrieving revision 1.301
diff -u -r1.300 -r1.301
--- Makefile	27 Aug 2004 20:43:04 -0000	1.300
+++ Makefile	28 Aug 2004 00:46:05 -0000	1.301
@@ -19,7 +19,7 @@
 DO_MAKE = @ for i in $(SUBDIRS); do $(MAKE) -C $$i $@; done
 endif
 
-SRCS_COMMON = cpudetect.c codec-cfg.c spudec.c playtree.c playtreeparser.c asxparser.c vobsub.c subreader.c sub_cc.c find_sub.c m_config.c m_option.c parser-cfg.c m_struct.c
+SRCS_COMMON = cpudetect.c codec-cfg.c spudec.c playtree.c playtreeparser.c asxparser.c vobsub.c subreader.c sub_cc.c find_sub.c m_config.c m_option.c parser-cfg.c m_struct.c edl.c
 SRCS_MENCODER = mencoder.c mp_msg-mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/osd.c libvo/sub.c libvo/font_load.c libvo/font_load_ft.c xvid_vbr.c parser-mecmd.c
 SRCS_MPLAYER = mplayer.c mp_msg.c $(SRCS_COMMON) mixer.c parser-mpcmd.c
 

Index: edl.h
===================================================================
RCS file: /cvsroot/mplayer/main/edl.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- edl.h	3 Feb 2003 09:26:40 -0000	1.2
+++ edl.h	28 Aug 2004 00:46:05 -0000	1.3
@@ -1,12 +1,13 @@
-// EDL version 0.5
+// EDL version 0.6
 
 #ifndef EDLH
 #define EDLH
 
 #define EDL_SKIP 0
 #define EDL_MUTE 1
-
-#define MAX_EDL_ENTRIES 1000
+#define EDL_ERROR -1
+#define EDL_MUTE_START 1
+#define EDL_MUTE_END 0
 
 struct edl_record {
   float start_sec;
@@ -16,9 +17,17 @@
   float length_sec;
   long length_frame;
   short action;
+  short mute_state;
   struct edl_record* next;
 };
 
 typedef struct edl_record* edl_record_ptr;
 
+char *edl_filename; // file to extract edl entries from (-edl)
+char *edl_output_filename; // file to put edl entries in (-edlout)
+
+int edl_check_mode(void); // we cannot do -edl and -edlout at the same time
+int edl_count_entries(void); // returns total No of entries needed
+int edl_parse_file(edl_record_ptr edl_records); // fills edl stack
+
 #endif

Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.779
retrieving revision 1.780
diff -u -r1.779 -r1.780
--- mplayer.c	25 Aug 2004 09:49:43 -0000	1.779
+++ mplayer.c	28 Aug 2004 00:46:05 -0000	1.780
@@ -349,13 +349,13 @@
 #endif
 
 #ifdef USE_EDL
-struct edl_record edl_records[ MAX_EDL_ENTRIES ];
-int num_edl_records = 0;
-FILE* edl_fd = NULL;
-edl_record_ptr next_edl_record = NULL;
-static char* edl_filename = NULL;
-static char* edl_output_filename = NULL;
-short edl_decision = 0;
+edl_record_ptr edl_records = NULL; // EDL entries memory area
+edl_record_ptr next_edl_record = NULL; // only for traversing edl_records
+int edl_memory_slots = 0; // No of EDL entries (1 for skip + 2 for each mute)
+int edl_operations = 0; // No of EDL operations, skip + mute
+short edl_decision = 0; // 1 when an EDL operation has been made
+FILE* edl_fd = NULL; // fd to write to when in -edlout mode
+int edl_mute_count = 0; // even number when mute has been matched mute/unmute
 #endif
 
 static unsigned int inited_flags=0;
@@ -959,100 +959,54 @@
 #endif
 
 #ifdef USE_EDL
- {
-   FILE* fd;
-   char line[ 100 ];
-   float start, stop, duration;
-   int action;
-   int next_edl_array_index = 0;
-   int lineCount = 0;
-   next_edl_record = edl_records;
-   if( edl_filename ) {
-     if( ( fd = fopen( edl_filename, "r" ) ) == NULL ) {
-       printf( "Error opening EDL file [%s]!\n", edl_filename );
-       next_edl_record->next = NULL;
-     } else {
-       while( fgets( line, 99, fd ) != NULL ) {
-	 lineCount++;
-	 if( ( sscanf( line, "%f %f %d", &start, &stop, &action ) ) == 0 ) {
-	   printf( "Invalid EDL line: [%s]\n", line );
-	 } else {
-	   if( next_edl_array_index > 0 ) {
-	     edl_records[ next_edl_array_index-1 ].next = &edl_records[ next_edl_array_index ];
-	     if( start <= edl_records[ next_edl_array_index-1 ].stop_sec ) {
-	       printf( "Invalid EDL line [%d]: [%s]\n", lineCount, line );
-	       printf( "Last stop position was [%f]; next start is [%f]. Entries must be in chronological order and cannot overlap. Discarding EDL entry.\n", edl_records[ next_edl_array_index-1 ].stop_sec, start );
-	       continue;
-	     }
-	   }
-	   if( stop <= start ) {
-	     printf( "Invalid EDL line [%d]: [%s]\n", lineCount, line );
-	     printf( "Stop time must follow start time. Discarding EDL entry.\n" );
-	     continue;
-	   }
-	   edl_records[ next_edl_array_index ].action = action;
-	   if( action == EDL_MUTE ) {
-	     edl_records[ next_edl_array_index ].length_sec = 0;
-	     edl_records[ next_edl_array_index ].start_sec = start;
-	     edl_records[ next_edl_array_index ].stop_sec = start;
-	     next_edl_array_index++;
-	     if( next_edl_array_index >= MAX_EDL_ENTRIES-1 ) {
-	       break;
-	     }
-	     edl_records[ next_edl_array_index-1 ].next = &edl_records[ next_edl_array_index ];
-	     edl_records[ next_edl_array_index ].action = EDL_MUTE;
-	     edl_records[ next_edl_array_index ].length_sec = 0;
-	     edl_records[ next_edl_array_index ].start_sec = stop;
-	     edl_records[ next_edl_array_index ].stop_sec = stop;
-	   } else {
-	     edl_records[ next_edl_array_index ].length_sec = stop - start;
-	     edl_records[ next_edl_array_index ].start_sec = start;
-	     edl_records[ next_edl_array_index ].stop_sec = stop;
-	   }
-	   next_edl_array_index++;
-	   if( next_edl_array_index >= MAX_EDL_ENTRIES-1 ) {
-	     break;
-	   }
-	 }
-       }
-       if( next_edl_array_index > 0 ) {
-	 edl_records[ next_edl_array_index-1 ].next = &edl_records[ next_edl_array_index ];
-       }
-       edl_records[ next_edl_array_index ].start_sec = -1;
-       edl_records[ next_edl_array_index ].next = NULL;
-       num_edl_records = ( next_edl_array_index );
-     }
-     fclose( fd );
-   } else {
-     next_edl_record->next = NULL;
-   }
-   if( edl_output_filename ) {
-     if( edl_filename ) {
-       printf( "Sorry; EDL mode and EDL output mode are mutually exclusive! Disabling all EDL functions.\n" );
-       edl_output_filename = NULL;
-       edl_filename = NULL;
-       next_edl_record->next = NULL;
-     } else {
-       if( ( edl_fd = fopen( edl_output_filename, "w" ) ) == NULL ) {
-	 printf( "Error opening file [%s] for writing!\n", edl_output_filename );
-	 edl_output_filename = NULL;
-	 next_edl_record->next = NULL;
-       }
-     }
-   }
-#ifdef DEBUG_EDL
- {
-   printf( "EDL Records:\n" );
-   if( next_edl_record->next != NULL ) {
-     while( next_edl_record->next != NULL ) {
-       printf( "EDL: start [%f], stop [%f], action [%d]\n", next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->action );
-       next_edl_record = next_edl_record->next;
-     }
-     next_edl_record = edl_records;
-   }
- }
-#endif
- }
+if (edl_check_mode() == EDL_ERROR && edl_filename)
+{
+    mp_msg(MSGT_CPLAYER, MSGL_WARN,
+           "Cant use -edl and -edlout at the same time\n");
+    mp_msg(MSGT_CPLAYER, MSGL_WARN, "Not using EDL at all!!!\n");
+    edl_filename = NULL;
+    edl_output_filename = NULL;
+    edl_records = NULL;
+    next_edl_record = edl_records;
+} else if (edl_filename)
+{
+    edl_memory_slots = edl_count_entries();
+    if (edl_memory_slots > 0)
+    {
+        edl_records = calloc(edl_memory_slots, sizeof(struct edl_record));
+        if (edl_records == NULL)
+        {
+            mp_msg(MSGT_CPLAYER, MSGL_FATAL,
+                   "Cant allocate enough memory to hold EDL data, exiting!\n");
+            exit_player(NULL);	    
+        } else
+        {
+            if ((edl_operations = edl_parse_file(edl_records)) > 0)
+            {
+                mp_msg(MSGT_CPLAYER, MSGL_INFO, "Readed %d EDL actions\n",
+                       edl_operations);
+            } else
+            {
+
+                mp_msg(MSGT_CPLAYER, MSGL_INFO,
+                       "There are no EDL actions to take care of\n");
+            }
+        }
+    }
+
+    next_edl_record = edl_records;
+
+} else if (edl_output_filename)
+{
+    if ((edl_fd = fopen(edl_output_filename, "w")) == NULL)
+    {
+        mp_msg(MSGT_CPLAYER, MSGL_WARN, 
+	       "Error opening file [%s] for writing!\n",
+               edl_output_filename);
+        edl_output_filename = NULL;
+        next_edl_record = edl_records;
+    }
+}
 #endif
 
     if(!filename){
@@ -2493,7 +2447,7 @@
 //================= EDL =========================================
 
 #ifdef USE_EDL
- if( next_edl_record->next ) { // Are we (still?) doing EDL?
+ if( next_edl_record ) { // Are we (still?) doing EDL?
   if ( !sh_video ) {
     mp_msg( MSGT_CPLAYER, MSGL_ERR, "Cannot use edit list without video. EDL disabled.\n" );
     next_edl_record->next = NULL;
@@ -2507,15 +2461,15 @@
        printf( "\nEDL_SKIP: start [%f], stop [%f], length [%f]\n", next_edl_record->start_sec, next_edl_record->stop_sec, next_edl_record->length_sec );
 #endif
        edl_decision = 1;
-       next_edl_record = next_edl_record->next;
      } else if( next_edl_record->action == EDL_MUTE ) {
        mixer_mute(&mixer);
+       edl_mute_count++; // new edl seek behavior need this
 #ifdef DEBUG_EDL
        printf( "\nEDL_MUTE: [%f]\n", next_edl_record->start_sec );
 #endif
        edl_decision = 1;
-       next_edl_record = next_edl_record->next;
      }
+     next_edl_record=next_edl_record->next;
    }
   }
  }
@@ -3548,20 +3502,52 @@
       }
   }
 #ifdef USE_EDL
-      {
-	int x;
-	if( !edl_decision ) {
-	  for( x = 0; x < num_edl_records; x++ ) { // FIXME: do binary search
-	    // Find first EDL entry where start follows current time
-	    if( edl_records[ x ].start_sec >= sh_video->pts && edl_records[ x ].action != EDL_MUTE ) {
-	      next_edl_record = &edl_records[ x ];
-	      break;
-	    }
-	  }
-	} else {
-	  edl_decision = 0;
-	}
-      }
+/*
+ * We Saw a seek, have to rewind the edl operations stak
+ * and find the next edl action to take care off
+ */
+
+next_edl_record = edl_records;
+
+while (next_edl_record)
+{
+    /* trying to remember if we need to mute/unmute first
+     * prior edl implementation lacks this
+     */
+  
+    if (next_edl_record->start_sec >= sh_video->pts)
+    {
+        if (edl_mute_count > 0)
+        {
+            if ((edl_mute_count % 2) == 0 &&
+                next_edl_record->mute_state == EDL_MUTE_END)
+            {
+                mixer_mute(&mixer);
+                edl_mute_count++;
+            }
+            if ((edl_mute_count % 2) != 0 &&
+                next_edl_record->mute_state == EDL_MUTE_START)
+            {
+                mixer_mute(&mixer);
+                edl_mute_count++;
+            }
+        } else if (next_edl_record->mute_state == EDL_MUTE_END)
+        {
+            mixer_mute(&mixer);
+            edl_mute_count++;
+        }
+        break;
+    }
+
+    next_edl_record = next_edl_record->next;
+
+    if (!next_edl_record && (edl_mute_count % 2) != 0
+        && edl_mute_count > 0)
+    {
+        mixer_mute(&mixer);
+        edl_mute_count++;
+    }
+}
 #endif
   rel_seek_secs=0;
   abs_seek_pos=0;




More information about the MPlayer-cvslog mailing list