summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-23 00:33:22 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-23 00:33:22 +0000
commit7f1c5834473c4041337e30f5e606aca629498aa7 (patch)
treee4d54c5ec378c502d6f8ffe19c068c8295ee5735
parentda027164877a7a8c2288256145ee16c7878c36b2 (diff)
downloadmpv-7f1c5834473c4041337e30f5e606aca629498aa7.tar.bz2
mpv-7f1c5834473c4041337e30f5e606aca629498aa7.tar.xz
Merged EDL 0.5 patch - it's something like Quicktime's edit lists.
(skip sections listed in a text file. it also supports creating them) patch by Michael Halcrow <mah69@email.byu.edu> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8532 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--DOCS/mplayer.113
-rw-r--r--cfg-common.h5
-rw-r--r--cfg-mplayer.h7
-rwxr-xr-xconfigure17
-rw-r--r--edl.h25
-rw-r--r--input/input.c6
-rw-r--r--input/input.h4
-rw-r--r--mplayer.c178
8 files changed, 249 insertions, 6 deletions
diff --git a/DOCS/mplayer.1 b/DOCS/mplayer.1
index f54aa8080d..1fad4ade32 100644
--- a/DOCS/mplayer.1
+++ b/DOCS/mplayer.1
@@ -206,6 +206,19 @@ Prints some statistics on CPU usage and dropped frames at the end.
Use in combination with \-nosound and \-vo null for benchmarking only the
video codec.
.TP
+.B \-edl <filename>
+Enables edit decision list actions during playback. Video will be
+skipped over and audio will be muted and unmuted according to the
+entries in the given file. See DOCS/edl.html for details on how to use
+this.
+.TP
+.B \-edlout <filename>
+Creates a new file and writes edit decision list records to that
+file. During playback, when the user hits 'i', an entry to skip over
+the last two seconds of playback will be written to the file. This
+provides a starting point from which the user can fine-tune EDL
+entries later. See DOCS/edl.html for details.
+.TP
.B \-framedrop (also see \-hardframedrop)
Skips displaying some frames to maintain A/\:V sync on slow systems.
Decoding of B frames is also skipped and video filters are not used.
diff --git a/cfg-common.h b/cfg-common.h
index 731434784e..d4f5e910f0 100644
--- a/cfg-common.h
+++ b/cfg-common.h
@@ -227,6 +227,11 @@ extern int demuxer_type, audio_demuxer_type, sub_demuxer_type;
#include "libmpdemux/tv.h"
+#ifdef USE_EDL
+extern char* edl_filename;
+extern char* edl_output_filename;
+#endif
+
#ifdef USE_TV
struct config tvopts_conf[]={
{"on", &tv_param_on, CONF_TYPE_FLAG, 0, 0, 1, NULL},
diff --git a/cfg-mplayer.h b/cfg-mplayer.h
index 7fd9c672d4..859dc48955 100644
--- a/cfg-mplayer.h
+++ b/cfg-mplayer.h
@@ -203,6 +203,13 @@ static config_t mplayer_opts[]={
CONF_TYPE_PRINT, 0, 0, 0, NULL},
{"noalsa", "Option -noalsa has been removed, new audio code doesn't need it! Remove it from your config file!\n",
CONF_TYPE_PRINT, 0, 0, 0, NULL},
+#ifdef USE_EDL
+ {"edl", &edl_filename, CONF_TYPE_STRING, 0, 0, 0, NULL},
+ {"edlout", &edl_output_filename, CONF_TYPE_STRING, 0, 0, 0, NULL},
+#else
+ {"edl", "MPlayer was compiled without EDL support\n", CONF_TYPE_PRINT, 0, 0, 0, NULL},
+ {"edlout", "MPlayer was compiled without EDL support\n", CONF_TYPE_PRINT, 0, 0, 0, NULL},
+#endif
#ifdef HAVE_X11
{"display", &mDisplayName, CONF_TYPE_STRING, 0, 0, 0, NULL},
diff --git a/configure b/configure
index 925fc1d819..e3820480a5 100755
--- a/configure
+++ b/configure
@@ -140,6 +140,7 @@ Optional features:
--disable-tv disable TV Interface (tv/dvb grabbers) [enable]
--disable-tv-v4l disable Video4Linux TV Interface support [autodetect]
--disable-tv-bsdbt848 disable BSD BT848 Interface support [autodetect]
+ --disable-edl disable EDL (edit decision list) support [enable]
--disable-rtc disable RTC (/dev/rtc) on Linux [autodetect]
--disable-streaming disable network streaming support
(support for: http/mms/rtp) [enable]
@@ -1003,6 +1004,7 @@ _select=yes
_tv=yes
_tv_v4l=auto
_tv_bsdbt848=auto
+_edl=yes
_streaming=yes
_vidix=auto
_joystick=no
@@ -1153,6 +1155,8 @@ for ac_option do
--disable-alsa) _alsa=no ;;
--enable-tv) _tv=yes ;;
--disable-tv) _tv=no ;;
+ --enable-edl) _edl=yes ;;
+ --disable-edl) _edl=no ;;
--enable-tv-bsdbt848) _tv_bsdbt848=yes ;;
--disable-tv-bsdbt848) _tv_bsdbt848=no ;;
--enable-tv-v4l) _tv_v4l=yes ;;
@@ -4210,6 +4214,16 @@ else
fi
echores "$_tv"
+echocheck "EDL support"
+if test "$_edl" = yes ; then
+ _def_edl='#define USE_EDL'
+ _inputmodules="edl $_inputmodules"
+else
+ _noinputmodules="edl $_noinputmodules"
+ _def_edl='#undef USE_EDL'
+fi
+echores "$_edl"
+
echocheck "*BSD BrookTree 848 TV interface"
if test "$_tv_bsdbt848" = auto ; then
_tv_bsdbt848=no
@@ -5027,6 +5041,9 @@ $_def_nas
/* Enable TV Interface support */
$_def_tv
+/* Enable EDL support */
+$_def_edl
+
/* Enable Video 4 Linux TV interface support */
$_def_tv_v4l
diff --git a/edl.h b/edl.h
new file mode 100644
index 0000000000..f6817ffa15
--- /dev/null
+++ b/edl.h
@@ -0,0 +1,25 @@
+// EDL version 0.5
+// Author: Michael Halcrow <mhalcrow@byu.edu>
+
+#ifndef EDLH
+#define EDLH
+
+#define EDL_SKIP 0
+#define EDL_MUTE 1
+
+#define MAX_EDL_ENTRIES 1000
+
+struct edl_record {
+ float start_sec;
+ long start_frame;
+ float stop_sec;
+ long stop_frame;
+ float length_sec;
+ long length_frame;
+ short action;
+ struct edl_record* next;
+};
+
+typedef struct edl_record* edl_record_ptr;
+
+#endif
diff --git a/input/input.c b/input/input.c
index 3cce4ebf33..3b580bd06b 100644
--- a/input/input.c
+++ b/input/input.c
@@ -46,6 +46,9 @@
static mp_cmd_t mp_cmds[] = {
{ MP_CMD_SEEK, "seek", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
+#ifdef USE_EDL
+ { MP_CMD_EDL_MARK, "edl_mark", 0, { {-1,{0}} } },
+#endif
{ MP_CMD_AUDIO_DELAY, "audio_delay", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } },
{ MP_CMD_QUIT, "quit", 0, { {-1,{0}} } },
{ MP_CMD_PAUSE, "pause", 0, { {-1,{0}} } },
@@ -246,6 +249,9 @@ static mp_cmd_bind_t def_cmd_binds[] = {
{ { 't', 0 }, "sub_pos +1" },
{ { 'v', 0 }, "sub_visibility" },
{ { 'j', 0 }, "vobsub_lang" },
+#ifdef USE_EDL
+ { { 'i', 0 }, "edl_mark" },
+#endif
#ifdef USE_TV
{ { 'h', 0 }, "tv_step_channel 1" },
{ { 'k', 0 }, "tv_step_channel -1" },
diff --git a/input/input.h b/input/input.h
index 95b606bc6e..b55aaa40cd 100644
--- a/input/input.h
+++ b/input/input.h
@@ -37,6 +37,10 @@
#define MP_CMD_GET_TIME_LENGTH 34
#define MP_CMD_GET_PERCENT_POS 35
#define MP_CMD_SUB_STEP 36
+//#define MP_CMD_TV_SET_CHANNEL 37
+#ifdef USE_EDL
+#define MP_CMD_EDL_MARK 38
+#endif
#define MP_CMD_GUI_EVENTS 5000
#define MP_CMD_GUI_LOADFILE 5001
diff --git a/mplayer.c b/mplayer.c
index 2e8a02d5a8..5a2364a0c0 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -56,6 +56,10 @@
#include <dvdnav.h>
#endif
+#ifdef USE_EDL
+#include "edl.h"
+#endif
+
#include "spudec.h"
#include "vobsub.h"
@@ -298,6 +302,16 @@ static char* menu_root = "main";
static int nortc;
#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;
+#endif
+
static unsigned int inited_flags=0;
#define INITED_VO 1
#define INITED_AO 2
@@ -725,6 +739,102 @@ if(!parse_codec_cfg(get_path("codecs.conf"))){
exit(0);
}
+#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 = 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
+ }
+#endif
if(!filename && !vcd_track && !dvd_title && !dvd_nav && !tv_param_on){
if(!use_gui){
@@ -1955,6 +2065,32 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
dvdnav_stream_sleeping((dvdnav_priv_t*)stream->priv);
#endif
+//================= EDL =========================================
+
+#ifdef USE_EDL
+ if( next_edl_record->next ) { // Are we (still?) doing EDL?
+ if( d_video->pts >= next_edl_record->start_sec ) {
+ if( next_edl_record->action == EDL_SKIP ) {
+ osd_function = OSD_FFW;
+ abs_seek_pos = 0;
+ rel_seek_secs = next_edl_record->length_sec;
+#ifdef DEBUG_EDL
+ 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();
+#ifdef DEBUG_EDL
+ printf( "\nEDL_MUTE: [%f]\n", next_edl_record->start_sec );
+#endif
+ edl_decision = 1;
+ next_edl_record = next_edl_record->next;
+ }
+ }
+ }
+#endif
+
//================= Keyboard events, SEEKing ====================
current_module="key_events";
@@ -1985,6 +2121,14 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
osd_function= (v > 0) ? OSD_FFW : OSD_REW;
}
} break;
+#ifdef USE_EDL
+ case MP_CMD_EDL_MARK:
+ if( edl_fd ) {
+ float v = d_video->pts;
+ fprintf( edl_fd, "%f %f %d\n", v-2, v, 0 );
+ }
+ break;
+#endif
case MP_CMD_AUDIO_DELAY : {
float v = cmd->args[0].v.f;
audio_delay += v;
@@ -2665,12 +2809,18 @@ if(rel_seek_secs || abs_seek_pos){
#ifdef USE_OSD
// Set OSD:
if(osd_level){
- int len=((demuxer->movi_end-demuxer->movi_start)>>8);
- if (len>0 && sh_video){
- osd_visible=sh_video->fps; // 1 sec
- vo_osd_progbar_type=0;
- vo_osd_progbar_value=(demuxer->filepos-demuxer->movi_start)/len;
- vo_osd_changed(OSDTYPE_PROGBAR);
+#ifdef USE_EDL
+ if( !edl_decision ) {
+#else
+ if( 1 ) { // Let the compiler optimize this out
+#endif
+ int len=((demuxer->movi_end-demuxer->movi_start)>>8);
+ if (len>0 && sh_video){
+ osd_visible=sh_video->fps; // 1 sec
+ vo_osd_progbar_type=0;
+ vo_osd_progbar_value=(demuxer->filepos-demuxer->movi_start)/len;
+ vo_osd_changed(OSDTYPE_PROGBAR);
+ }
}
}
#endif
@@ -2686,6 +2836,22 @@ if(rel_seek_secs || abs_seek_pos){
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 >= d_video->pts && edl_records[ x ].action != EDL_MUTE ) {
+ next_edl_record = &edl_records[ x ];
+ break;
+ }
+ }
+ } else {
+ edl_decision = 0;
+ }
+ }
+#endif
rel_seek_secs=0;
abs_seek_pos=0;
frame_time_remaining=0;