[MPlayer-dev-eng] [PATCH] edl now works when seeking, more
Reynaldo H. Verdejo Pinochet
reynaldo at opendot.cl
Wed Aug 25 07:39:14 CEST 2004
Hi all
Im trying to implement edl on mencoder, to do so
I have to remove some edl's code from mplayer.c and put it
on his own edl.c (mencoder will use the same functions)
while Im on it I have fixed some edl's flaws
* 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_
Hope to get mencoder's edl working this weekend, please review and
apply this patches ASAP
Regards
Reynaldo
-------------- next part --------------
--- mplayer.c 2004-08-25 00:18:34.000000000 -0400
+++ ../my_main/mplayer.c 2004-08-24 23:49:09.000000000 -0400
@@ -350,13 +350,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 edl_records = NULL;
edl_record_ptr next_edl_record = NULL;
-static char* edl_filename = NULL;
-static char* edl_output_filename = NULL;
+int edl_memory_slots = 0;
+int edl_operations = 0;
short edl_decision = 0;
+FILE* edl_fd = NULL;
+int edl_mute_count = 0;
#endif
static unsigned int inited_flags=0;
@@ -960,100 +960,55 @@
#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_WARN, "Cant allocate enough memory to hold EDL data!!\n");
+ mp_msg( MSGT_CPLAYER, MSGL_WARN, "Disabling EDL!!!\n" );
+ edl_filename = NULL;
+ edl_output_filename = NULL;
+ edl_records = 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 ) {
+ printf( "Error opening file [%s] for writing!\n", edl_output_filename );
+ edl_output_filename = NULL;
+ next_edl_record = edl_records;
+ }
+}
+
+
+
#endif
if(!filename){
@@ -2494,7 +2449,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;
@@ -2508,15 +2463,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++; // seek needs 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;
}
}
}
@@ -3544,24 +3470,57 @@
drop_frame_cnt=0;
too_slow_frame_cnt=0;
too_fast_frame_cnt=0;
-
+
if(vo_spudec) spudec_reset(vo_spudec);
}
}
#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;
-------------- next part --------------
--- edl.h 2004-08-25 00:18:30.000000000 -0400
+++ ../my_main/edl.h 2004-08-24 20:12:32.000000000 -0400
@@ -5,8 +5,9 @@
#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,19 @@
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;
+char *edl_output_filename;
+
+
+int edl_check_mode(void);
+int edl_count_entries(void);
+int edl_parse_file(struct edl_record *edl_records);
+
#endif
-------------- next part --------------
--- /dev/null 2004-08-08 23:33:15.000000000 -0400
+++ edl.c 2004-08-24 23:50:48.000000000 -0400
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.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 )
+ {
+ return(EDL_ERROR);
+ printf("Cant open edl file for reading!!\n");
+ }
+ else
+ {
+ while( fgets( line, 99, fd ) != NULL )
+ {
+ if( ( sscanf( line, "%f %f %d", &start, &stop, &action ) ) != 0 )
+ {
+ if(action == EDL_SKIP) entries+=1;
+ if(action == EDL_MUTE) entries+=2;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ return(EDL_ERROR);
+ }
+
+ return(entries);
+}
+
+int edl_parse_file(struct edl_record *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 ) ) == 0 )
+ {
+ printf( "Invalid EDL line: %s\n", line );
+ }
+ else
+ {
+ if( record_count > 0 )
+ {
+ if( start <= (next_edl_record - 1)->stop_sec )
+ {
+ printf( "Invalid EDL line [%d]: %s ",
+ 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", ( next_edl_record -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;
+ }
+ 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
-------------- next part --------------
--- Makefile 2004-08-23 00:31:53.000000000 -0400
+++ ../my_main/Makefile 2004-08-23 17:15:54.000000000 -0400
@@ -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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20040825/7d183db1/attachment.pgp>
More information about the MPlayer-dev-eng
mailing list