static AVFormatContext *input_files[MAX_FILES];
static int64_t input_files_ts_offset[MAX_FILES];
+static double input_files_ts_scale[MAX_FILES][MAX_STREAMS];
static int nb_input_files = 0;
static AVFormatContext *output_files[MAX_FILES];
static int frame_leftBand = 0;
static int frame_rightBand = 0;
static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX};
-static AVRational frame_rate = (AVRational) {0,0};
+static AVRational frame_rate;
static float video_qscale = 0;
-static int video_qdiff = 3;
static uint16_t *intra_matrix = NULL;
static uint16_t *inter_matrix = NULL;
#if 0 //experimental, (can be removed)
static int audio_stream_copy = 0;
static int video_stream_copy = 0;
static int subtitle_stream_copy = 0;
-static int video_sync_method= 1;
+static int video_sync_method= -1;
static int audio_sync_method= 0;
static float audio_drift_threshold= 0.1;
static int copy_ts= 0;
else if (st->codec->codec_type == CODEC_TYPE_VIDEO && video_stream_copy)
st->stream_copy = 1;
+ if(!st->codec->thread_count)
+ st->codec->thread_count = 1;
+ if(st->codec->thread_count>1)
+ avcodec_thread_init(st->codec, st->codec->thread_count);
+
if(st->codec->flags & CODEC_FLAG_BITEXACT)
nopts = 1;
}
*frame_size = 0;
- if(video_sync_method){
+ if(video_sync_method>0 || (video_sync_method && av_q2d(enc->time_base) > 0.001)){
double vdelta;
vdelta = get_sync_ipts(ost) / av_q2d(enc->time_base) - ost->sync_opts;
//FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
len = pkt->size;
ptr = pkt->data;
- while (len > 0) {
+
+ //while we have more to decode or while the decoder did output something on EOF
+ while (len > 0 || (!pkt && ist->next_pts != ist->pts)) {
handle_eof:
ist->pts= ist->next_pts;
else
opkt.pts= AV_NOPTS_VALUE;
- if (pkt->dts == AV_NOPTS_VALUE)
- opkt.dts = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ost->st->time_base);
- else
- opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
+ if (pkt->dts == AV_NOPTS_VALUE)
+ opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base);
+ else
+ opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
opkt.flags= pkt->flags;
}
}
if (!found) {
+ int i= ost->file_index;
+ dump_format(output_files[i], i, output_files[i]->filename, 1);
fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
ost->file_index, ost->index);
av_exit(1);
codec->time_base = ist->st->time_base;
switch(codec->codec_type) {
case CODEC_TYPE_AUDIO:
+ if(audio_volume != 256) {
+ fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");
+ av_exit(1);
+ }
codec->sample_rate = icodec->sample_rate;
codec->channels = icodec->channels;
codec->frame_size = icodec->frame_size;
if (pkt.pts != AV_NOPTS_VALUE)
pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);
+ if(input_files_ts_scale[file_index][pkt.stream_index]){
+ if(pkt.pts != AV_NOPTS_VALUE)
+ pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index];
+ if(pkt.dts != AV_NOPTS_VALUE)
+ pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index];
+ }
+
// fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);
if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) {
int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
for(type=0; type<CODEC_TYPE_NB; type++){
const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
if(o2)
- o = av_set_string(avctx_opts[type], opt, arg);
+ o = av_set_string2(avctx_opts[type], opt, arg, 1);
}
if(!o)
- o = av_set_string(avformat_opts, opt, arg);
+ o = av_set_string2(avformat_opts, opt, arg, 1);
if(!o)
- o = av_set_string(sws_opts, opt, arg);
+ o = av_set_string2(sws_opts, opt, arg, 1);
if(!o){
if(opt[0] == 'a')
- o = av_set_string(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg);
+ o = av_set_string2(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1);
else if(opt[0] == 'v')
- o = av_set_string(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg);
+ o = av_set_string2(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1);
else if(opt[0] == 's')
- o = av_set_string(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg);
+ o = av_set_string2(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1);
}
if(!o)
return -1;
}
}
-static void opt_qdiff(const char *arg)
-{
- video_qdiff = atoi(arg);
- if (video_qdiff < 0 ||
- video_qdiff > 31) {
- fprintf(stderr, "qdiff must be >= 1 and <= 31\n");
- av_exit(1);
- }
-}
-
static void opt_strict(const char *arg)
{
strict= atoi(arg);
m->in_file = strtol(p, &p, 0);
}
+static void opt_input_ts_scale(const char *arg)
+{
+ unsigned int stream;
+ double scale;
+ char *p;
+
+ stream = strtol(arg, &p, 0);
+ if (*p)
+ p++;
+ scale= strtod(p, &p);
+
+ if(stream >= MAX_STREAMS)
+ av_exit(1);
+
+ input_files_ts_scale[nb_input_files][stream]= scale;
+}
+
static int opt_recording_time(const char *opt, const char *arg)
{
recording_time = parse_time_or_die(opt, arg, 1);
const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
/* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
if(str && ((opt->flags & flags) == flags))
- av_set_string(ctx, opt_names[i], str);
+ av_set_string2(ctx, opt_names[i], str, 1);
}
}
if(inter_matrix)
video_enc->inter_matrix = inter_matrix;
- video_enc->max_qdiff = video_qdiff;
video_enc->thread_count = thread_count;
p= video_rc_override_string;
for(i=0; p; i++){
av_strstart(filename, "http:", NULL)) {
/* special case for files sent to ffserver: we get the stream
parameters from ffserver */
- if (read_ffserver_streams(oc, filename) < 0) {
- fprintf(stderr, "Could not read stream parameters from '%s'\n", filename);
+ int err = read_ffserver_streams(oc, filename);
+ if (err < 0) {
+ print_error(filename, err);
av_exit(1);
}
} else {
"Hyper fast Audio and Video encoder\n");
printf("\n");
show_help_options(options, "Main options:\n",
- OPT_EXPERT | OPT_AUDIO | OPT_VIDEO, 0);
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB, 0);
+ show_help_options(options, "\nAdvanced options:\n",
+ OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE | OPT_GRAB,
+ OPT_EXPERT);
show_help_options(options, "\nVideo options:\n",
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
OPT_VIDEO);
show_help_options(options, "\nAudio/Video grab options:\n",
OPT_GRAB,
OPT_GRAB);
- show_help_options(options, "\nAdvanced options:\n",
- OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
- OPT_EXPERT);
printf("\n");
av_opt_show(avctx_opts[0], NULL);
printf("\n");
fprintf(stderr, "Preset file invalid\n");
av_exit(1);
}
- opt_default(tmp, tmp2);
+ if(!strcmp(tmp, "acodec")){
+ opt_audio_codec(tmp2);
+ }else if(!strcmp(tmp, "vcodec")){
+ opt_video_codec(tmp2);
+ }else if(!strcmp(tmp, "scodec")){
+ opt_subtitle_codec(tmp2);
+ }else
+ opt_default(tmp, tmp2);
}
fclose(f);
{ "fs", HAS_ARG | OPT_INT64, {(void*)&limit_filesize}, "set the limit file size in bytes", "limit_size" }, //
{ "ss", OPT_FUNC2 | HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" },
{ "itsoffset", OPT_FUNC2 | HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" },
+ { "itsscale", HAS_ARG, {(void*)opt_input_ts_scale}, "set the input ts scale", "stream:scale" },
{ "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" },
{ "timestamp", OPT_FUNC2 | HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp", "time" },
{ "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" },
{ "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" },
{ "genre", HAS_ARG | OPT_STRING, {(void*)&str_genre}, "set the genre", "string" },
{ "album", HAS_ARG | OPT_STRING, {(void*)&str_album}, "set the album", "string" },
+ { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
{ "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},
"add timings for benchmarking" },
{ "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump},
{ "b", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
{ "vb", OPT_FUNC2 | HAS_ARG | OPT_VIDEO, {(void*)opt_bitrate}, "set bitrate (in bits/s)", "bitrate" },
{ "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[CODEC_TYPE_VIDEO]}, "set the number of video frames to record", "number" },
- { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" },
{ "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
{ "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
{ "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
{ "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" },
{ "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
{ "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" },
- { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantizer scale (VBR)", "q" },
{ "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" },
{ "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
{ "me_threshold", HAS_ARG | OPT_FUNC2 | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" },
avdevice_register_all();
av_register_all();
+ if(isatty(STDIN_FILENO))
+ url_set_interrupt_cb(decode_interrupt_cb);
+
for(i=0; i<CODEC_TYPE_NB; i++){
avctx_opts[i]= avcodec_alloc_context2(i);
}