mirror of
https://github.com/mpv-player/mpv
synced 2025-03-29 15:00:27 +00:00
after a long time, finally i could add -endpos option to mplayer executable.
as oded told me on 1006 02 24, i applied it, blame me if some problem occurs, i hope not, since i tried it for a while.... git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@19979 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
c8c0aa686f
commit
928da7a448
@ -1273,6 +1273,30 @@ the entries in the given file.
|
||||
See DOCS/\:HTML/\:en/\:edl.html for details on how to use this.
|
||||
.
|
||||
.TP
|
||||
.B \-endpos <[[hh:]mm:]ss[.ms]|size[b|kb|mb]> (also see \-ss and \-sb)
|
||||
Stop at given time or byte position.
|
||||
.br
|
||||
.I NOTE:
|
||||
Byte position is enabled only for MEncoder and will not be accurate, as it can
|
||||
only stop at a frame boundary.
|
||||
When used in conjunction with \-ss option, \-endpos time will shift forward by
|
||||
seconds specified with \-ss.
|
||||
.sp 1
|
||||
.I EXAMPLE:
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs "\-endpos 56"
|
||||
Stop at 56 seconds.
|
||||
.IPs "\-endpos 01:10:00"
|
||||
Stop at 1 hour 10 minutes.
|
||||
.IPs "\-ss 10 \-endpos 56"
|
||||
Stop at 1 minute 6 seconds.
|
||||
.IPs "\-endpos 100mb"
|
||||
Encode only 100 MB.
|
||||
.RE
|
||||
.PD 1
|
||||
.
|
||||
.TP
|
||||
.B \-forceidx
|
||||
Force index rebuilding.
|
||||
Useful for files with broken index (A/V desync, etc).
|
||||
@ -6550,26 +6574,6 @@ CBR only, VBR ignores this as it puts each packet in a new chunk.
|
||||
Sets up the audio buffering time interval (default: 0.5s).
|
||||
.
|
||||
.TP
|
||||
.B \-endpos <[[hh:]mm:]ss[.ms]|size[b|kb|mb]> (also see \-ss and \-sb)
|
||||
Stop encoding at the given time or byte position.
|
||||
.br
|
||||
.I NOTE:
|
||||
Byte position will not be accurate, as it can only stop at
|
||||
a frame boundary.
|
||||
.sp 1
|
||||
.I EXAMPLE:
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs "\-endpos 56"
|
||||
Encode only 56 seconds.
|
||||
.IPs "\-endpos 01:10:00"
|
||||
Encode only 1 hour 10 minutes.
|
||||
.IPs "\-endpos 100mb"
|
||||
Encode only 100 MB.
|
||||
.RE
|
||||
.PD 1
|
||||
.
|
||||
.TP
|
||||
.B \-fafmttag <format>
|
||||
Can be used to override the audio format tag of the output file.
|
||||
.sp 1
|
||||
|
@ -93,6 +93,9 @@
|
||||
{"sb", &seek_to_byte, CONF_TYPE_POSITION, CONF_MIN, 0, 0, NULL},
|
||||
{"ss", &seek_to_sec, CONF_TYPE_STRING, CONF_MIN, 0, 0, NULL},
|
||||
|
||||
// stop at given position
|
||||
{"endpos", &end_at, CONF_TYPE_TIME_SIZE, 0, 0, 0, NULL},
|
||||
|
||||
{"edl", &edl_filename, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
|
||||
// AVI specific: force non-interleaved mode
|
||||
|
@ -185,8 +185,6 @@ extern int write_odml; /* defined in libmpdemux/muxer_avi.c */
|
||||
m_option_t mencoder_opts[]={
|
||||
/* name, pointer, type, flags, min, max */
|
||||
|
||||
{"endpos", &end_at_string, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
|
||||
{"frameno-file", &frameno_filename, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
|
||||
|
||||
{"hr-edl-seek", &edl_seek_type, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
|
@ -201,6 +201,7 @@ static char help_text[]=
|
||||
#define MSGTR_EdloutBadStop "EDL skip canceled, last start > stop\n"
|
||||
#define MSGTR_EdloutStartSkip "EDL skip start, press 'i' again to end block.\n"
|
||||
#define MSGTR_EdloutEndSkip "EDL skip end, line written.\n"
|
||||
#define MSGTR_MPEndposNoSizeBased "Option -endpos in MPlayer does not yet support size units.\n"
|
||||
|
||||
// mplayer.c OSD
|
||||
|
||||
|
72
m_option.c
72
m_option.c
@ -1175,6 +1175,78 @@ m_option_type_t m_option_type_afmt = {
|
||||
};
|
||||
|
||||
|
||||
// Time or size (-endpos)
|
||||
|
||||
static int parse_time_size(m_option_t* opt,char *name, char *param, void* dst, int src) {
|
||||
|
||||
if (dst == NULL)
|
||||
return 0;
|
||||
|
||||
m_time_size_t* ts = dst;
|
||||
ts->pos=0;
|
||||
|
||||
char unit[4];
|
||||
int a,b;
|
||||
float d;
|
||||
double end_at;
|
||||
|
||||
if (param == NULL || strlen(param) == 0)
|
||||
return M_OPT_MISSING_PARAM;
|
||||
|
||||
/* End at size parsing */
|
||||
if(sscanf(param, "%lf%3s", &end_at, unit) == 2) {
|
||||
ts->type = END_AT_SIZE;
|
||||
if(!strcasecmp(unit, "b"))
|
||||
;
|
||||
else if(!strcasecmp(unit, "kb"))
|
||||
end_at *= 1024;
|
||||
else if(!strcasecmp(unit, "mb"))
|
||||
end_at *= 1024*1024;
|
||||
else if(!strcasecmp(unit, "gb"))
|
||||
end_at *= 1024*1024*1024;
|
||||
else
|
||||
ts->type = END_AT_NONE;
|
||||
|
||||
if (ts->type == END_AT_SIZE) {
|
||||
ts->pos = end_at;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* End at time parsing. This has to be last because of
|
||||
* sscanf("%f", ...) below */
|
||||
if (sscanf(param, "%d:%d:%f", &a, &b, &d) == 3)
|
||||
end_at = 3600*a + 60*b + d;
|
||||
else if (sscanf(param, "%d:%f", &a, &d) == 2)
|
||||
end_at = 60*a + d;
|
||||
else if (sscanf(param, "%f", &d) == 1)
|
||||
end_at = d;
|
||||
else {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid time or size: '%s'\n",
|
||||
name,param);
|
||||
return M_OPT_INVALID;
|
||||
}
|
||||
|
||||
ts->type = END_AT_TIME;
|
||||
ts->pos = end_at;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
m_option_type_t m_option_type_time_size = {
|
||||
"Time or size",
|
||||
"",
|
||||
sizeof(m_time_size_t),
|
||||
0,
|
||||
parse_time_size,
|
||||
NULL,
|
||||
copy_opt,
|
||||
copy_opt,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
//// Objects (i.e. filters, etc) settings
|
||||
|
||||
#include "m_struct.h"
|
||||
|
10
m_option.h
10
m_option.h
@ -28,6 +28,7 @@ extern m_option_type_t m_option_type_double;
|
||||
extern m_option_type_t m_option_type_string;
|
||||
extern m_option_type_t m_option_type_string_list;
|
||||
extern m_option_type_t m_option_type_position;
|
||||
extern m_option_type_t m_option_type_time_size;
|
||||
|
||||
extern m_option_type_t m_option_type_print;
|
||||
extern m_option_type_t m_option_type_print_indirect;
|
||||
@ -59,6 +60,14 @@ typedef m_opt_func_full_t cfg_func_arg_param_t;
|
||||
typedef m_opt_func_param_t cfg_func_param_t;
|
||||
typedef m_opt_func_t cfg_func_t;
|
||||
|
||||
#define END_AT_NONE 0
|
||||
#define END_AT_TIME 1
|
||||
#define END_AT_SIZE 2
|
||||
typedef struct {
|
||||
double pos;
|
||||
int type;
|
||||
} m_time_size_t;
|
||||
|
||||
/// Extra definition needed for \ref m_option_type_obj_settings_list options.
|
||||
typedef struct {
|
||||
/// Pointer to an array of pointer to some object type description struct.
|
||||
@ -159,6 +168,7 @@ extern m_obj_params_t m_span_params_def;
|
||||
#define CONF_TYPE_OBJ_PRESETS (&m_option_type_obj_presets)
|
||||
#define CONF_TYPE_CUSTOM_URL (&m_option_type_custom_url)
|
||||
#define CONF_TYPE_OBJ_PARAMS (&m_option_type_obj_params)
|
||||
#define CONF_TYPE_TIME_SIZE (&m_option_type_time_size)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
62
mencoder.c
62
mencoder.c
@ -252,10 +252,10 @@ static int cfg_include(m_option_t *conf, char *filename){
|
||||
static char *seek_to_sec=NULL;
|
||||
static off_t seek_to_byte=0;
|
||||
|
||||
static m_time_size_t end_at = { .type = END_AT_NONE, .pos = 0 };
|
||||
|
||||
static char * frameno_filename=NULL;
|
||||
|
||||
static void parse_end_at(void);
|
||||
static char * end_at_string=0;
|
||||
//static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width, int height);
|
||||
|
||||
typedef struct {
|
||||
@ -355,10 +355,6 @@ static float stop_time(demuxer_t* demuxer, muxer_stream_t* mux_v);
|
||||
static int at_eof=0;
|
||||
static int interrupted=0;
|
||||
|
||||
enum end_at_type_t {END_AT_NONE, END_AT_TIME, END_AT_SIZE};
|
||||
static enum end_at_type_t end_at_type = END_AT_NONE;
|
||||
static double end_at;
|
||||
|
||||
static void exit_sighandler(int x){
|
||||
at_eof=1;
|
||||
interrupted=2; /* 1 means error */
|
||||
@ -1040,8 +1036,6 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
parse_end_at();
|
||||
|
||||
if (seek_to_sec) {
|
||||
int a,b; float d;
|
||||
|
||||
@ -1080,7 +1074,7 @@ if(file_format == DEMUXER_TYPE_TV)
|
||||
}
|
||||
|
||||
play_n_frames=play_n_frames_mf;
|
||||
if (curfile && end_at_type == END_AT_TIME) end_at += mux_v->timer;
|
||||
if (curfile && end_at.type == END_AT_TIME) end_at.pos += mux_v->timer;
|
||||
|
||||
if (edl_records) free_edl(edl_records);
|
||||
next_edl_record = edl_records = NULL;
|
||||
@ -1099,8 +1093,8 @@ while(!at_eof){
|
||||
float v_pts=0;
|
||||
int skip_flag=0; // 1=skip -1=duplicate
|
||||
|
||||
if((end_at_type == END_AT_SIZE && end_at <= ftello(muxer_f)) ||
|
||||
(end_at_type == END_AT_TIME && end_at < mux_v->timer))
|
||||
if((end_at.type == END_AT_SIZE && end_at.pos <= ftello(muxer_f)) ||
|
||||
(end_at.type == END_AT_TIME && end_at.pos < mux_v->timer))
|
||||
break;
|
||||
|
||||
if(play_n_frames>=0){
|
||||
@ -1590,50 +1584,6 @@ if(stream) free_stream(stream); // kill cache thread
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
static void parse_end_at(void)
|
||||
{
|
||||
|
||||
end_at_type = END_AT_NONE;
|
||||
if (!end_at_string) return;
|
||||
|
||||
/* End at size parsing */
|
||||
{
|
||||
char unit[4];
|
||||
|
||||
end_at_type = END_AT_SIZE;
|
||||
|
||||
if(sscanf(end_at_string, "%lf%3s", &end_at, unit) == 2) {
|
||||
if(!strcasecmp(unit, "b"))
|
||||
;
|
||||
else if(!strcasecmp(unit, "kb"))
|
||||
end_at *= 1024;
|
||||
else if(!strcasecmp(unit, "mb"))
|
||||
end_at *= 1024*1024;
|
||||
else
|
||||
end_at_type = END_AT_NONE;
|
||||
}
|
||||
else
|
||||
end_at_type = END_AT_NONE;
|
||||
}
|
||||
|
||||
/* End at time parsing. This has to be last because of
|
||||
* sscanf("%f", ...) below */
|
||||
if(end_at_type == END_AT_NONE)
|
||||
{
|
||||
int a,b; float d;
|
||||
|
||||
end_at_type = END_AT_TIME;
|
||||
|
||||
if (sscanf(end_at_string, "%d:%d:%f", &a, &b, &d) == 3)
|
||||
end_at = 3600*a + 60*b + d;
|
||||
else if (sscanf(end_at_string, "%d:%f", &a, &d) == 2)
|
||||
end_at = 60*a + d;
|
||||
else if (sscanf(end_at_string, "%f", &d) == 1)
|
||||
end_at = d;
|
||||
else
|
||||
end_at_type = END_AT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Flip the image in src and store the result in dst. src and dst may overlap.
|
||||
@ -1659,7 +1609,7 @@ static uint8_t* flip_upside_down(uint8_t* dst, const uint8_t* src, int width,
|
||||
static float stop_time(demuxer_t* demuxer, muxer_stream_t* mux_v) {
|
||||
float timeleft = -1;
|
||||
if (play_n_frames >= 0) timeleft = mux_v->timer + play_n_frames * (double)(mux_v->h.dwScale) / mux_v->h.dwRate;
|
||||
if (end_at_type == END_AT_TIME && (timeleft > end_at || timeleft == -1)) timeleft = end_at;
|
||||
if (end_at.type == END_AT_TIME && (timeleft > end_at.pos || timeleft == -1)) timeleft = end_at.pos;
|
||||
if (next_edl_record && demuxer && demuxer->video) { // everything is OK to be checked
|
||||
float tmp = mux_v->timer + next_edl_record->start_sec - demuxer->video->pts;
|
||||
if (timeleft == -1 || timeleft > tmp) {
|
||||
|
27
mplayer.c
27
mplayer.c
@ -250,6 +250,8 @@ static off_t step_sec=0;
|
||||
static int loop_times=-1;
|
||||
static int loop_seek=0;
|
||||
|
||||
static m_time_size_t end_at = { .type = END_AT_NONE, .pos = 0 };
|
||||
|
||||
// A/V sync:
|
||||
int autosync=0; // 30 might be a good default value.
|
||||
|
||||
@ -4050,10 +4052,16 @@ while(sh_audio){
|
||||
|
||||
if(!sh_video) {
|
||||
// handle audio-only case:
|
||||
if(!quiet) {
|
||||
double a_pos = playing_audio_pts(sh_audio, d_audio, audio_out);
|
||||
double a_pos=0;
|
||||
if(!quiet || end_at.type == END_AT_TIME )
|
||||
a_pos = playing_audio_pts(sh_audio, d_audio, audio_out);
|
||||
|
||||
if(!quiet)
|
||||
print_status(a_pos, 0, 0);
|
||||
}
|
||||
|
||||
if(end_at.type == END_AT_TIME && end_at.pos < a_pos)
|
||||
eof = PT_NEXT_ENTRY;
|
||||
|
||||
} else {
|
||||
|
||||
/*========================== PLAY VIDEO ============================*/
|
||||
@ -4296,6 +4304,10 @@ if(time_frame>0.001 && !(vo_flags&256)){
|
||||
too_slow_frame_cnt++;
|
||||
/* printf ("PANIC: too slow frame (%.3f)!\n", j); */
|
||||
|
||||
// FIXME: add size based support for -endpos
|
||||
if ( end_at.type == END_AT_TIME && end_at.pos < sh_video->pts )
|
||||
eof = PT_NEXT_ENTRY;
|
||||
|
||||
if(vo_config_count) video_out->flip_page();
|
||||
if (play_n_frames >= 0) {
|
||||
--play_n_frames;
|
||||
@ -5214,6 +5226,15 @@ if(step_sec>0) {
|
||||
seek_to_sec = NULL;
|
||||
}
|
||||
|
||||
if (end_at.type != END_AT_NONE) {
|
||||
if(end_at.type == END_AT_SIZE) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_MPEndposNoSizeBased);
|
||||
end_at.type = END_AT_NONE;
|
||||
} else {
|
||||
end_at.pos += rel_seek_secs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Looping. */
|
||||
if(eof==1 && loop_times>=0) {
|
||||
int l = loop_times;
|
||||
|
Loading…
Reference in New Issue
Block a user