aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfram Gloger <wmglo@dent.med.uni-muenchen.de>2004-06-11 22:03:16 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-06-11 22:03:16 +0000
commita6a92a9aa633b82ce71474a94fe976fad98a4de8 (patch)
tree027a729bf75bdd98e894ef3a7dc201000fbc9d2a
parentdbc56b3914cc70e763e902c382065ab09ee6bf1f (diff)
downloadffmpeg-a6a92a9aa633b82ce71474a94fe976fad98a4de8.tar.gz
user specified start time offset
frame dup/drop info typos patch by (Wolfram Gloger <wmglo at dent dot med dot uni-muenchen dot de>) Originally committed as revision 3217 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--ffmpeg.c29
-rw-r--r--libavformat/utils.c11
2 files changed, 34 insertions, 6 deletions
diff --git a/ffmpeg.c b/ffmpeg.c
index 041439a640..e2a016ffa2 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -58,6 +58,7 @@ static void show_license(void);
#define MAX_FILES 20
static AVFormatContext *input_files[MAX_FILES];
+static int64_t input_files_ts_offset[MAX_FILES];
static int nb_input_files = 0;
static AVFormatContext *output_files[MAX_FILES];
@@ -184,6 +185,7 @@ static int audio_codec_id = CODEC_ID_NONE;
static int64_t recording_time = 0;
static int64_t start_time = 0;
static int64_t rec_timestamp = 0;
+static int64_t input_ts_offset = 0;
static int file_overwrite = 0;
static char *str_title = NULL;
static char *str_author = NULL;
@@ -220,6 +222,8 @@ static int me_range = 0;
static int64_t video_size = 0;
static int64_t audio_size = 0;
static int64_t extra_size = 0;
+static int nb_frames_dup = 0;
+static int nb_frames_drop = 0;
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
@@ -614,6 +618,12 @@ static void do_video_out(AVFormatContext *s,
nb_frames = 2;
//printf("vdelta:%f, ost->sync_opts:%lld, ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, ost->sync_ipts, nb_frames);
}
+ if (nb_frames == 0)
+ ++nb_frames_drop;
+ else if (nb_frames == 2) {
+ ++nb_frames_dup;
+ //printf("*** dup!\n");
+ }
ost->sync_opts+= nb_frames;
if (nb_frames <= 0)
@@ -964,6 +974,10 @@ static void print_report(AVFormatContext **output_files,
sprintf(buf + strlen(buf),
"size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s",
(double)total_size / 1024, ti1, bitrate);
+
+ if (verbose > 1)
+ sprintf(buf + strlen(buf), " dup=%d drop=%d",
+ nb_frames_dup, nb_frames_drop);
if (verbose >= 0)
fprintf(stderr, "%s \r", buf);
@@ -1116,7 +1130,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
((double)ost->st->pts.val * ost->time_base.num / ost->time_base.den));
#endif
/* set the input output pts pairs */
- ost->sync_ipts = (double)ist->pts / AV_TIME_BASE;
+ ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index])/ AV_TIME_BASE;
if (ost->encoding_needed) {
switch(ost->st->codec.codec_type) {
@@ -1167,8 +1181,8 @@ static int output_packet(AVInputStream *ist, int ist_index,
opkt.stream_index= ost->index;
opkt.data= data_buf;
opkt.size= data_size;
- opkt.pts= pkt->pts; //FIXME ist->pts?
- opkt.dts= pkt->dts;
+ opkt.pts= pkt->pts + input_files_ts_offset[ist->file_index];
+ opkt.dts= pkt->dts + input_files_ts_offset[ist->file_index];
opkt.flags= pkt->flags;
av_interleaved_write_frame(os, &opkt);
@@ -2522,6 +2536,11 @@ static void opt_rec_timestamp(const char *arg)
rec_timestamp = parse_date(arg, 0) / 1000000;
}
+static void opt_input_ts_offset(const char *arg)
+{
+ input_ts_offset = parse_date(arg, 1);
+}
+
static void opt_input_file(const char *filename)
{
AVFormatContext *ic;
@@ -2632,6 +2651,9 @@ static void opt_input_file(const char *filename)
}
input_files[nb_input_files] = ic;
+ input_files_ts_offset[nb_input_files] = input_ts_offset;
+ if (ic->start_time != AV_NOPTS_VALUE && 0)
+ input_files_ts_offset[nb_input_files] -= ic->start_time;
/* dump the file content */
if (verbose >= 0)
dump_format(ic, nb_input_files, filename, 0);
@@ -3501,6 +3523,7 @@ const OptionDef options[] = {
{ "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream" },
{ "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" },
{ "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
+ { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
{ "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
{ "timestamp", HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp", "time" },
{ "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0c112b9cad..4e75bc157d 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1009,7 +1009,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
pos_min= e->pos;
ts_min= e->timestamp;
#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "unsing cached pos_min=0x%llx dts_min=%lld\n",
+ av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%llx dts_min=%lld\n",
pos_min,ts_min);
#endif
}else{
@@ -1023,7 +1023,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts
ts_max= e->timestamp;
pos_limit= pos_max - e->min_distance;
#ifdef DEBUG_SEEK
- av_log(s, AV_LOG_DEBUG, "unsing cached pos_max=0x%llx pos_limit=0x%llx dts_max=%lld\n",
+ av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%llx pos_limit=0x%llx dts_max=%lld\n",
pos_max,pos_limit, ts_max);
#endif
}
@@ -2229,6 +2229,7 @@ int64_t parse_date(const char *datestr, int duration)
const char *q;
int is_utc, len;
char lastch;
+ int negative = 0;
#undef time
time_t now = time(0);
@@ -2273,6 +2274,10 @@ int64_t parse_date(const char *datestr, int duration)
}
}
} else {
+ if (p[0] == '-') {
+ negative = 1;
+ ++p;
+ }
q = small_strptime(p, time_fmt[0], &dt);
if (!q) {
dt.tm_sec = strtol(p, (char **)&q, 10);
@@ -2312,7 +2317,7 @@ int64_t parse_date(const char *datestr, int duration)
}
t += val;
}
- return t;
+ return negative ? -t : t;
}
/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return