mirror of
https://github.com/mpv-player/mpv
synced 2024-10-06 14:54:02 +02:00
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
This commit is contained in:
parent
da02716487
commit
7f1c583447
@ -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.
|
||||
|
@ -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},
|
||||
|
@ -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},
|
||||
|
17
configure
vendored
17
configure
vendored
@ -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
|
||||
|
||||
|
25
edl.h
Normal file
25
edl.h
Normal file
@ -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
|
@ -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" },
|
||||
|
@ -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
|
||||
|
166
mplayer.c
166
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,6 +2809,11 @@ if(rel_seek_secs || abs_seek_pos){
|
||||
#ifdef USE_OSD
|
||||
// Set OSD:
|
||||
if(osd_level){
|
||||
#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
|
||||
@ -2673,6 +2822,7 @@ if(rel_seek_secs || abs_seek_pos){
|
||||
vo_osd_changed(OSDTYPE_PROGBAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(sh_video) {
|
||||
c_total=0;
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user