Newer
Older
}
if(codec->type != type) {
av_log(NULL, AV_LOG_ERROR, "Invalid %s type '%s'\n", codec_string, name);
exit_program(1);
}
return codec->id;
}
static AVCodec *choose_codec(OptionsContext *o, AVFormatContext *s, AVStream *st, enum AVMediaType type)
MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
if (!codec_name) {
if (s->oformat) {
st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename, NULL, type);
return avcodec_find_encoder(st->codec->codec_id);
}
} else if (!strcmp(codec_name, "copy"))
st->stream_copy = 1;
else {
st->codec->codec_id = find_codec_or_die(codec_name, type, s->iformat == NULL);
return s->oformat ? avcodec_find_encoder_by_name(codec_name) :
avcodec_find_decoder_by_name(codec_name);
}
return NULL;
}
/**
* Add all the streams from the given input file to the global
* list of input streams.
*/
static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
int i, rfps, rfps_base;
for (i = 0; i < ic->nb_streams; i++) {
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
InputStream *ist;
dec->thread_count = thread_count;
input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
ist = &input_streams[nb_input_streams - 1];
ist->st = st;
ist->file_index = nb_input_files;
ist->discard = 1;
ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st);
MATCH_PER_STREAM_OPT(ts_scale, dbl, scale, ic, st);
ist->ts_scale = scale;
ist->dec = choose_codec(o, ic, st, dec->codec_type);
if (!ist->dec)
ist->dec = avcodec_find_decoder(dec->codec_id);
switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if(!ist->dec)
ist->dec = avcodec_find_decoder(dec->codec_id);
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
st->discard= AVDISCARD_ALL;
break;
case AVMEDIA_TYPE_VIDEO:
if(!ist->dec)
ist->dec = avcodec_find_decoder(dec->codec_id);
rfps = ic->streams[i]->r_frame_rate.num;
rfps_base = ic->streams[i]->r_frame_rate.den;
if (dec->lowres) {
dec->flags |= CODEC_FLAG_EMU_EDGE;
}
if(me_threshold)
dec->debug |= FF_DEBUG_MV;
if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) {
if (verbose >= 0)
fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num,
(float)rfps / rfps_base, rfps, rfps_base);
}
if (o->video_disable)
st->discard= AVDISCARD_ALL;
else if(video_discard)
st->discard= video_discard;
break;
case AVMEDIA_TYPE_DATA:
break;
case AVMEDIA_TYPE_SUBTITLE:
if(!ist->dec)
ist->dec = avcodec_find_decoder(dec->codec_id);
if(o->subtitle_disable)
st->discard = AVDISCARD_ALL;
break;
case AVMEDIA_TYPE_ATTACHMENT:
case AVMEDIA_TYPE_UNKNOWN:
break;
default:
abort();
}
}
}
static int opt_input_file(OptionsContext *o, const char *opt, const char *filename)
AVInputFormat *file_iformat = NULL;
AVDictionary **opts;
int orig_nb_streams; // number of streams before avformat_find_stream_info
if (o->format) {
if (!(file_iformat = av_find_input_format(o->format))) {
fprintf(stderr, "Unknown input format: '%s'\n", o->format);
if (!strcmp(filename, "-"))
filename = "pipe:";
using_stdin |= !strncmp(filename, "pipe:", 5) ||
!strcmp(filename, "/dev/stdin");
ic = avformat_alloc_context();
if (!ic) {
print_error(filename, AVERROR(ENOMEM));
if (audio_sample_rate) {
snprintf(buf, sizeof(buf), "%d", audio_sample_rate);
av_dict_set(&format_opts, "sample_rate", buf, 0);
}
if (o->nb_audio_channels) {
snprintf(buf, sizeof(buf), "%d", o->audio_channels[o->nb_audio_channels - 1].u.i);
av_dict_set(&format_opts, "channels", buf, 0);
}
if (frame_rate.num) {
snprintf(buf, sizeof(buf), "%d/%d", frame_rate.num, frame_rate.den);
av_dict_set(&format_opts, "framerate", buf, 0);
}
if (frame_width && frame_height) {
snprintf(buf, sizeof(buf), "%dx%d", frame_width, frame_height);
av_dict_set(&format_opts, "video_size", buf, 0);
}
if (frame_pix_fmt != PIX_FMT_NONE)
av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(frame_pix_fmt), 0);
if (loop_input) {
av_log(NULL, AV_LOG_WARNING, "-loop_input is deprecated, use -loop 1\n");
ic->loop_input = loop_input;
}
/* open the input file with generic libav function */
err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
print_error(filename, err);
assert_avoptions(format_opts);
Nico Sabbi
committed
if(opt_programid) {
int i, j;
int found=0;
for(i=0; i<ic->nb_streams; i++){
ic->streams[i]->discard= AVDISCARD_ALL;
}
for(i=0; i<ic->nb_programs; i++){
AVProgram *p= ic->programs[i];
if(p->id != opt_programid){
p->discard = AVDISCARD_ALL;
}else{
found=1;
for(j=0; j<p->nb_stream_indexes; j++){
ic->streams[p->stream_index[j]]->discard= AVDISCARD_DEFAULT;
}
}
}
if(!found){
fprintf(stderr, "Specified program id not found\n");
Nico Sabbi
committed
}
/* apply forced codec ids */
for (i = 0; i < ic->nb_streams; i++)
choose_codec(o, ic, ic->streams[i], ic->streams[i]->codec->codec_type);
/* Set AVCodecContext options for avformat_find_stream_info */
opts = setup_find_stream_info_opts(ic, codec_opts);
orig_nb_streams = ic->nb_streams;
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
ret = avformat_find_stream_info(ic, opts);
if (ret < 0 && verbose >= 0) {
fprintf(stderr, "%s: could not find codec parameters\n", filename);
av_close_input_file(ic);
timestamp = o->start_time;
/* add the stream start time */
if (ic->start_time != AV_NOPTS_VALUE)
timestamp += ic->start_time;
/* if seeking requested, we execute it */
if (o->start_time != 0) {
ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
if (ret < 0) {
fprintf(stderr, "%s: could not seek to position %0.3f\n",
filename, (double)timestamp / AV_TIME_BASE);
}
}
/* update the current parameters so that they match the one of the input stream */
add_input_streams(o, ic);
if (verbose >= 0)
av_dump_format(ic, nb_input_files, filename, 0);
input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
input_files[nb_input_files - 1].ctx = ic;
input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams;
input_files[nb_input_files - 1].ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
input_files[nb_input_files - 1].rate_emu = o->rate_emu;
Max Krasnyansky
committed
top_field_first = -1;
frame_rate = (AVRational){0, 0};
frame_pix_fmt = PIX_FMT_NONE;
frame_height = 0;
frame_width = 0;
audio_sample_rate = 0;
audio_sample_fmt = AV_SAMPLE_FMT_NONE;
for (i = 0; i < orig_nb_streams; i++)
av_dict_free(&opts[i]);
av_freep(&opts);
reset_options(o, 1);
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
static void parse_forced_key_frames(char *kf, OutputStream *ost,
AVCodecContext *avctx)
{
char *p;
int n = 1, i;
int64_t t;
for (p = kf; *p; p++)
if (*p == ',')
n++;
ost->forced_kf_count = n;
ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
if (!ost->forced_kf_pts) {
av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
exit_program(1);
}
for (i = 0; i < n; i++) {
p = i ? strchr(p, ',') + 1 : kf;
t = parse_time_or_die("force_key_frames", p, 1);
ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
}
}
static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
{
OutputStream *ost;
AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
int idx = oc->nb_streams - 1;
int64_t max_frames = INT64_MAX;
char *bsf = NULL, *next, *codec_tag = NULL;
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
if (!st) {
av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
exit_program(1);
}
output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,
nb_output_streams + 1);
ost = &output_streams[nb_output_streams - 1];
ost->file_index = nb_output_files;
ost->index = idx;
ost->st = st;
st->codec->codec_type = type;
ost->enc = choose_codec(o, oc, st, type);
if (ost->enc) {
ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st);
}
avcodec_get_context_defaults3(st->codec, ost->enc);
st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st);
ost->max_frames = max_frames;
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
while (bsf) {
if (next = strchr(bsf, ','))
*next++ = 0;
if (!(bsfc = av_bitstream_filter_init(bsf))) {
av_log(NULL, AV_LOG_ERROR, "Unknown bitstream filter %s\n", bsf);
exit_program(1);
Fabrice Bellard
committed
}
if (bsfc_prev)
bsfc_prev->next = bsfc;
else
ost->bitstream_filters = bsfc;
bsfc_prev = bsfc;
bsf = next;
Fabrice Bellard
committed
}
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
if (codec_tag) {
uint32_t tag = strtol(codec_tag, &next, 0);
if (*next)
tag = AV_RL32(codec_tag);
st->codec->codec_tag = tag;
Fabrice Bellard
committed
}
ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
return ost;
}
static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
Fabrice Bellard
committed
AVCodecContext *video_enc;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
st = ost->st;
if (!st->stream_copy) {
ost->frame_aspect_ratio = frame_aspect_ratio;
frame_aspect_ratio = 0;
#if CONFIG_AVFILTER
vfilters = NULL;
st->codec->thread_count= thread_count;
Michael Niedermayer
committed
video_enc = st->codec;
if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
Fabrice Bellard
committed
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
Michael Niedermayer
committed
if (st->stream_copy) {
video_enc->sample_aspect_ratio =
st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
Fabrice Bellard
committed
} else {
Fabrice Bellard
committed
int i;
if (frame_rate.num)
ost->frame_rate = frame_rate;
video_enc->width = frame_width;
video_enc->height = frame_height;
Fabrice Bellard
committed
video_enc->pix_fmt = frame_pix_fmt;
video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
Fabrice Bellard
committed
if (intra_only)
Fabrice Bellard
committed
video_enc->gop_size = 0;
if (video_qscale || same_quant) {
Fabrice Bellard
committed
video_enc->flags |= CODEC_FLAG_QSCALE;
video_enc->global_quality = FF_QP2LAMBDA * video_qscale;
Fabrice Bellard
committed
}
if(intra_matrix)
video_enc->intra_matrix = intra_matrix;
if(inter_matrix)
video_enc->inter_matrix = inter_matrix;
p= video_rc_override_string;
for(i=0; p; i++){
int start, end, q;
int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
if(e!=3){
fprintf(stderr, "error parsing rc_override\n");
Fabrice Bellard
committed
}
video_enc->rc_override=
av_realloc(video_enc->rc_override,
Fabrice Bellard
committed
sizeof(RcOverride)*(i+1));
video_enc->rc_override[i].start_frame= start;
video_enc->rc_override[i].end_frame = end;
if(q>0){
video_enc->rc_override[i].qscale= q;
video_enc->rc_override[i].quality_factor= 1.0;
}
else{
video_enc->rc_override[i].qscale= 0;
video_enc->rc_override[i].quality_factor= -q/100.0;
}
p= strchr(p, '/');
if(p) p++;
}
video_enc->rc_override_count=i;
if (!video_enc->rc_initial_buffer_occupancy)
video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4;
Fabrice Bellard
committed
video_enc->me_threshold= me_threshold;
video_enc->intra_dc_precision= intra_dc_precision - 8;
if (do_psnr)
video_enc->flags|= CODEC_FLAG_PSNR;
Fabrice Bellard
committed
/* two pass mode */
if (do_pass) {
if (do_pass == 1) {
video_enc->flags |= CODEC_FLAG_PASS1;
} else {
video_enc->flags |= CODEC_FLAG_PASS2;
}
}
if (forced_key_frames)
parse_forced_key_frames(forced_key_frames, ost, video_enc);
Fabrice Bellard
committed
}
/* reset some key parameters */
av_freep(&forced_key_frames);
frame_pix_fmt = PIX_FMT_NONE;
Fabrice Bellard
committed
}
static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
Fabrice Bellard
committed
{
AVStream *st;
Fabrice Bellard
committed
AVCodecContext *audio_enc;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
st = ost->st;
Michael Niedermayer
committed
st->codec->thread_count= thread_count;
Michael Niedermayer
committed
audio_enc = st->codec;
audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
Fabrice Bellard
committed
audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
if (!st->stream_copy) {
if (audio_qscale > QSCALE_NONE) {
audio_enc->flags |= CODEC_FLAG_QSCALE;
audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale;
MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
if (audio_sample_fmt != AV_SAMPLE_FMT_NONE)
audio_enc->sample_fmt = audio_sample_fmt;
if (audio_sample_rate)
audio_enc->sample_rate = audio_sample_rate;
Fabrice Bellard
committed
}
Fabrice Bellard
committed
}
static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
OutputStream *ost;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
st = ost->st;
if (!st->stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
}
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
Fabrice Bellard
committed
{
AVStream *st;
Fabrice Bellard
committed
AVCodecContext *subtitle_enc;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
st = ost->st;
subtitle_enc = st->codec;
Fabrice Bellard
committed
subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
Fabrice Bellard
committed
/* arg format is "output-stream-index:streamid-value". */
Aurelien Jacobs
committed
static int opt_streamid(const char *opt, const char *arg)
{
int idx;
char *p;
char idx_str[16];
av_strlcpy(idx_str, arg, sizeof(idx_str));
p = strchr(idx_str, ':');
if (!p) {
fprintf(stderr,
"Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
arg, opt);
}
*p++ = '\0';
idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
streamid_map = grow_array(streamid_map, sizeof(*streamid_map), &nb_streamid_map, idx+1);
streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
Aurelien Jacobs
committed
return 0;
static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
AVFormatContext *is = ifile->ctx;
AVFormatContext *os = ofile->ctx;
int i;
for (i = 0; i < is->nb_chapters; i++) {
AVChapter *in_ch = is->chapters[i], *out_ch;
int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset,
AV_TIME_BASE_Q, in_ch->time_base);
int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
if (in_ch->end < ts_off)
continue;
if (rt != INT64_MAX && in_ch->start > rt + ts_off)
break;
out_ch = av_mallocz(sizeof(AVChapter));
if (!out_ch)
return AVERROR(ENOMEM);
out_ch->id = in_ch->id;
out_ch->time_base = in_ch->time_base;
out_ch->start = FFMAX(0, in_ch->start - ts_off);
out_ch->end = FFMIN(rt, in_ch->end - ts_off);
av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
os->nb_chapters++;
os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters);
if (!os->chapters)
return AVERROR(ENOMEM);
os->chapters[os->nb_chapters - 1] = out_ch;
}
return 0;
}
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
{
int i, err;
AVFormatContext *ic = NULL;
err = avformat_open_input(&ic, filename, NULL, NULL);
if (err < 0)
return err;
/* copy stream format */
for(i=0;i<ic->nb_streams;i++) {
AVStream *st;
OutputStream *ost;
AVCodec *codec;
codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
ost = new_output_stream(o, s, codec->type);
st = ost->st;
// FIXME: a more elegant solution is needed
memcpy(st, ic->streams[i], sizeof(AVStream));
st->info = av_malloc(sizeof(*st->info));
memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
avcodec_copy_context(st->codec, ic->streams[i]->codec);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
choose_sample_fmt(st, codec);
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st->stream_copy)
choose_pixel_fmt(st, codec);
}
av_close_input_file(ic);
return 0;
}
static void opt_output_file(void *optctx, const char *filename)
Fabrice Bellard
committed
{
OptionsContext *o = optctx;
Fabrice Bellard
committed
AVFormatContext *oc;
AVOutputFormat *file_oformat;
OutputStream *ost;
InputStream *ist;
err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
Stefano Sabatini
committed
print_error(filename, err);
file_oformat= oc->oformat;
if (!strcmp(file_oformat->name, "ffm") &&
av_strstart(filename, "http:", NULL)) {
/* special case for files sent to ffserver: we get the stream
parameters from ffserver */
int err = read_ffserver_streams(o, oc, filename);
if (err < 0) {
print_error(filename, err);
} else if (!o->nb_stream_maps) {
/* pick the "best" stream of each type */
#define NEW_STREAM(type, index)\
if (index >= 0) {\
ost = new_ ## type ## _stream(o, oc);\
ost->source_index = index;\
ost->sync_ist = &input_streams[index];\
input_streams[index].discard = 0;\
}
/* video: highest resolution */
if (!o->video_disable && oc->oformat->video_codec != CODEC_ID_NONE) {
int area = 0, idx = -1;
for (i = 0; i < nb_input_streams; i++) {
ist = &input_streams[i];
if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
ist->st->codec->width * ist->st->codec->height > area) {
area = ist->st->codec->width * ist->st->codec->height;
idx = i;
}
}
NEW_STREAM(video, idx);
}
/* audio: most channels */
if (!o->audio_disable && oc->oformat->audio_codec != CODEC_ID_NONE) {
int channels = 0, idx = -1;
for (i = 0; i < nb_input_streams; i++) {
ist = &input_streams[i];
if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
ist->st->codec->channels > channels) {
channels = ist->st->codec->channels;
idx = i;
}
}
NEW_STREAM(audio, idx);
}
/* subtitles: pick first */
if (!o->subtitle_disable && (oc->oformat->subtitle_codec != CODEC_ID_NONE || subtitle_codec_name)) {
for (i = 0; i < nb_input_streams; i++)
if (input_streams[i].st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
NEW_STREAM(subtitle, i);
break;
}
}
/* do something with data? */
for (i = 0; i < o->nb_stream_maps; i++) {
StreamMap *map = &o->stream_maps[i];
ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index];
switch (ist->st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
default:
av_log(NULL, AV_LOG_ERROR, "Cannot map stream #%d.%d - unsupported type.\n",
map->file_index, map->stream_index);
exit_program(1);
}
ost->source_index = input_files[map->file_index].ist_index + map->stream_index;
ost->sync_ist = &input_streams[input_files[map->sync_file_index].ist_index +
map->sync_stream_index];
ist->discard = 0;
}
Anton Khirnov
committed
output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
output_files[nb_output_files - 1].ctx = oc;
output_files[nb_output_files - 1].ost_index = nb_output_streams - oc->nb_streams;
output_files[nb_output_files - 1].recording_time = o->recording_time;
output_files[nb_output_files - 1].start_time = o->start_time;
output_files[nb_output_files - 1].limit_filesize = o->limit_filesize;
Anton Khirnov
committed
av_dict_copy(&output_files[nb_output_files - 1].opts, format_opts, 0);
Fabrice Bellard
committed
/* check filename in case of an image number is expected */
if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
Michel Bardiaux
committed
if (!av_filename_number_test(oc->filename)) {
print_error(oc->filename, AVERROR(EINVAL));
Fabrice Bellard
committed
}
if (!(oc->oformat->flags & AVFMT_NOFILE)) {
/* test if it already exists to avoid loosing precious files */
filename[1] == ':' ||
av_strstart(filename, "file:", NULL))) {
if (avio_check(filename, 0) == 0) {
if (!using_stdin) {
fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
fflush(stderr);
fprintf(stderr, "Not overwriting - exiting\n");
}
else {
fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
}
if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
print_error(filename, err);
oc->preload = (int)(o->mux_preload * AV_TIME_BASE);
oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
if (loop_output >= 0) {
av_log(NULL, AV_LOG_WARNING, "-loop_output is deprecated, use -loop\n");
oc->loop_output = loop_output;
}
/* copy chapters */
if (o->chapters_input_file >= nb_input_files) {
if (o->chapters_input_file == INT_MAX) {
/* copy chapters from the first input file that has them*/
o->chapters_input_file = -1;
for (i = 0; i < nb_input_files; i++)
if (input_files[i].ctx->nb_chapters) {
o->chapters_input_file = i;
break;
}
} else {
av_log(NULL, AV_LOG_ERROR, "Invalid input file index %d in chapter mapping.\n",
o->chapters_input_file);
exit_program(1);
}
}
if (o->chapters_input_file >= 0)
copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1],
o->metadata_chapters_manual);
/* copy metadata */
for (i = 0; i < o->nb_meta_data_maps; i++) {
AVFormatContext *files[2];
AVDictionary **meta[2];
int j;
#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
if ((index) < 0 || (index) >= (nb_elems)) {\
av_log(NULL, AV_LOG_ERROR, "Invalid %s index %d while processing metadata maps\n",\
(desc), (index));\
exit_program(1);\
}
int in_file_index = o->meta_data_maps[i][1].file;
if (in_file_index < 0)
continue;
METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")
files[0] = oc;
files[1] = input_files[in_file_index].ctx;
for (j = 0; j < 2; j++) {
MetadataMap *map = &o->meta_data_maps[i][j];
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
switch (map->type) {
case 'g':
meta[j] = &files[j]->metadata;
break;
case 's':
METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")
meta[j] = &files[j]->streams[map->index]->metadata;
break;
case 'c':
METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")
meta[j] = &files[j]->chapters[map->index]->metadata;
break;
case 'p':
METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")
meta[j] = &files[j]->programs[map->index]->metadata;
break;
}
}
av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE);
}
/* copy global metadata by default */
if (!o->metadata_global_manual && nb_input_files)
av_dict_copy(&oc->metadata, input_files[0].ctx->metadata,
AV_DICT_DONT_OVERWRITE);
if (!o->metadata_streams_manual)
for (i = output_files[nb_output_files - 1].ost_index; i < nb_output_streams; i++) {
InputStream *ist = &input_streams[output_streams[i].source_index];
av_dict_copy(&output_streams[i].st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
}
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
/* process manually set metadata */
for (i = 0; i < o->nb_metadata; i++) {
AVDictionary **m;
char type, *val;
int index = 0;
val = strchr(o->metadata[i].u.str, '=');
if (!val) {
av_log(NULL, AV_LOG_ERROR, "No '=' character in metadata string %s.\n",
o->metadata[i].u.str);
exit_program(1);
}
*val++ = 0;
parse_meta_type(o->metadata[i].specifier, &type, &index);
switch (type) {
case 'g':
m = &oc->metadata;
break;
case 's':
if (index < 0 || index >= oc->nb_streams) {
av_log(NULL, AV_LOG_ERROR, "Invalid stream index %d in metadata specifier.\n", index);
exit_program(1);
}
m = &oc->streams[i]->metadata;
break;
case 'c':
if (index < 0 || index >= oc->nb_chapters) {
av_log(NULL, AV_LOG_ERROR, "Invalid chapter index %d in metadata specifier.\n", index);
exit_program(1);
}
m = &oc->chapters[i]->metadata;
break;
default:
av_log(NULL, AV_LOG_ERROR, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
exit_program(1);
}
av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
}
frame_rate = (AVRational){0, 0};
frame_width = 0;
frame_height = 0;
audio_sample_rate = 0;
audio_sample_fmt = AV_SAMPLE_FMT_NONE;
av_freep(&streamid_map);
nb_streamid_map = 0;
av_freep(&forced_key_frames);
reset_options(o, 0);
/* same option as mencoder */
static int opt_pass(const char *opt, const char *arg)
do_pass = parse_number_or_die(opt, arg, OPT_INT, 1, 2);
return 0;
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
#elif HAVE_GETPROCESSTIMES
HANDLE proc;
FILETIME c, e, k, u;
proc = GetCurrentProcess();
GetProcessTimes(proc, &c, &e, &k, &u);
return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
#else
static int64_t getmaxrss(void)
{
#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
return (int64_t)rusage.ru_maxrss * 1024;
#elif HAVE_GETPROCESSMEMORYINFO
HANDLE proc;
PROCESS_MEMORY_COUNTERS memcounters;
proc = GetCurrentProcess();
memcounters.cb = sizeof(memcounters);
GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
return memcounters.PeakPagefileUsage;
#else
return 0;
#endif
}
static void parse_matrix_coeffs(uint16_t *dest, const char *str)
Vidar Madsen
committed
{
int i;
const char *p = str;
for(i = 0;; i++) {
dest[i] = atoi(p);
if(i == 63)
break;
p = strchr(p, ',');
if(!p) {
fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
Vidar Madsen
committed
}
p++;
}
}
Jeff Downs
committed
static int opt_inter_matrix(const char *opt, const char *arg)
Vidar Madsen
committed
{
inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(inter_matrix, arg);
Jeff Downs
committed
return 0;
Vidar Madsen
committed
}
Jeff Downs
committed
static int opt_intra_matrix(const char *opt, const char *arg)
Vidar Madsen
committed
{
intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(intra_matrix, arg);
Jeff Downs
committed
return 0;
Vidar Madsen
committed
}
printf("Hyper fast Audio and Video encoder\n");
printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
printf("\n");
Jeff Downs
committed
static int opt_help(const char *opt, const char *arg)
const AVClass *class;
av_log_set_callback(log_callback_help);
show_usage();
show_help_options(options, "Main options:\n",
Stefano Sabatini
committed
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, "\nAdvanced Video options:\n",
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
OPT_VIDEO | OPT_EXPERT);