Newer
Older
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(AVFormatContext *ic)
{
int i, rfps, rfps_base, ret;
for (i = 0; i < ic->nb_streams; i++) {
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
AVDictionaryEntry *e = NULL;
char *scale = NULL;
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);
while (e = av_dict_get(ts_scale, "", e, AV_DICT_IGNORE_SUFFIX)) {
char *p = strchr(e->key, ':');
if ((ret = check_stream_specifier(ic, st, p ? p + 1 : "")) > 0)
scale = e->value;
else if (ret < 0)
exit_program(1);
}
if (scale)
ist->ts_scale = strtod(scale, NULL);
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
ist->dec = choose_codec(ic, st, dec->codec_type, codec_names);
switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
if(!ist->dec)
ist->dec = avcodec_find_decoder(dec->codec_id);
if(audio_disable)
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(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(subtitle_disable)
st->discard = AVDISCARD_ALL;
break;
case AVMEDIA_TYPE_ATTACHMENT:
case AVMEDIA_TYPE_UNKNOWN:
break;
default:
abort();
}
}
}
static int opt_input_file(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 (last_asked_format) {
if (!(file_iformat = av_find_input_format(last_asked_format))) {
fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);
last_asked_format = NULL;
}
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 (audio_channels) {
snprintf(buf, sizeof(buf), "%d", audio_channels);
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(ic, ic->streams[i], ic->streams[i]->codec->codec_type, codec_names);
/* 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 = 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 (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);
}
/* reset seek info */
start_time = 0;
}
/* update the current parameters so that they match the one of the input stream */
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 = input_ts_offset - (copy_ts ? 0 : timestamp);
input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
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_channels = 0;
audio_sample_fmt = AV_SAMPLE_FMT_NONE;
av_dict_free(&ts_scale);
for (i = 0; i < orig_nb_streams; i++)
av_dict_free(&opts[i]);
av_freep(&opts);
av_dict_free(&codec_names);
uninit_opts();
init_opts();
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
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(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;
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(oc, st, type, codec_names);
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
ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
return ost;
}
static OutputStream *new_video_stream(AVFormatContext *oc)
Fabrice Bellard
committed
AVCodecContext *video_enc;
ost = new_output_stream(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;
ost->bitstream_filters = video_bitstream_filters;
Michael Niedermayer
committed
video_bitstream_filters= NULL;
st->codec->thread_count= thread_count;
Michael Niedermayer
committed
video_enc = st->codec;
Fabrice Bellard
committed
if(video_codec_tag)
video_enc->codec_tag= video_codec_tag;
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
}
if (video_language) {
av_dict_set(&st->metadata, "language", video_language, 0);
av_freep(&video_language);
}
Fabrice Bellard
committed
/* reset some key parameters */
video_disable = 0;
av_freep(&forced_key_frames);
frame_pix_fmt = PIX_FMT_NONE;
Fabrice Bellard
committed
}
static OutputStream *new_audio_stream(AVFormatContext *oc)
Fabrice Bellard
committed
{
AVStream *st;
Fabrice Bellard
committed
AVCodecContext *audio_enc;
ost = new_output_stream(oc, AVMEDIA_TYPE_AUDIO);
st = ost->st;
Michael Niedermayer
committed
ost->bitstream_filters = audio_bitstream_filters;
Michael Niedermayer
committed
audio_bitstream_filters= NULL;
st->codec->thread_count= thread_count;
Michael Niedermayer
committed
audio_enc = st->codec;
audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
Fabrice Bellard
committed
if(audio_codec_tag)
audio_enc->codec_tag= audio_codec_tag;
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;
if (audio_channels)
audio_enc->channels = audio_channels;
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
}
if (audio_language) {
av_dict_set(&st->metadata, "language", audio_language, 0);
av_freep(&audio_language);
Fabrice Bellard
committed
}
/* reset some key parameters */
audio_disable = 0;
Fabrice Bellard
committed
}
static OutputStream *new_data_stream(AVFormatContext *oc)
OutputStream *ost;
ost = new_output_stream(oc, AVMEDIA_TYPE_DATA);
st = ost->st;
if (!st->stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
}
if (data_codec_tag)
data_enc->codec_tag= data_codec_tag;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
data_disable = 0;
static OutputStream *new_subtitle_stream(AVFormatContext *oc)
Fabrice Bellard
committed
{
AVStream *st;
Fabrice Bellard
committed
AVCodecContext *subtitle_enc;
ost = new_output_stream(oc, AVMEDIA_TYPE_SUBTITLE);
st = ost->st;
subtitle_enc = st->codec;
Fabrice Bellard
committed
ost->bitstream_filters = subtitle_bitstream_filters;
subtitle_bitstream_filters= NULL;
subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
if(subtitle_codec_tag)
subtitle_enc->codec_tag= subtitle_codec_tag;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
Fabrice Bellard
committed
if (subtitle_language) {
av_dict_set(&st->metadata, "language", subtitle_language, 0);
av_freep(&subtitle_language);
Fabrice Bellard
committed
}
subtitle_disable = 0;
/* 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 read_ffserver_streams(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(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 int copy_chapters(int infile, int outfile)
{
AVFormatContext *is = input_files[infile].ctx;
Anton Khirnov
committed
AVFormatContext *os = output_files[outfile].ctx;
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
3616
3617
3618
3619
3620
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(start_time - input_files[infile].ts_offset,
AV_TIME_BASE_Q, in_ch->time_base);
int64_t rt = (recording_time == INT64_MAX) ? INT64_MAX :
av_rescale_q(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);
if (metadata_chapters_autocopy)
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;
}
Stefano Sabatini
committed
static int opt_output_file(const char *opt, const char *filename)
Fabrice Bellard
committed
{
AVFormatContext *oc;
AVOutputFormat *file_oformat;
OutputStream *ost;
InputStream *ist;
Stefano Sabatini
committed
err = avformat_alloc_output_context2(&oc, NULL, last_asked_format, filename);
last_asked_format = NULL;
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(oc, filename);
if (err < 0) {
print_error(filename, err);
} else if (!nb_stream_maps) {
/* pick the "best" stream of each type */
#define NEW_STREAM(type, index)\
if (index >= 0) {\
ost = new_ ## type ## _stream(oc);\
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
ost->source_index = index;\
ost->sync_ist = &input_streams[index];\
input_streams[index].discard = 0;\
}
/* video: highest resolution */
if (!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 (!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 (!subtitle_disable && oc->oformat->subtitle_codec != CODEC_ID_NONE) {
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 < nb_stream_maps; i++) {
StreamMap *map = &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(oc); break;
case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(oc); break;
case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(oc); break;
case AVMEDIA_TYPE_DATA: ost = new_data_stream(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;
}
av_dict_copy(&oc->metadata, metadata, 0);
av_dict_free(&metadata);
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 = recording_time;
output_files[nb_output_files - 1].start_time = start_time;
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)(mux_preload*AV_TIME_BASE);
oc->max_delay= (int)(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 (chapters_input_file >= nb_input_files) {
if (chapters_input_file == INT_MAX) {
/* copy chapters from the first input file that has them*/
chapters_input_file = -1;
for (i = 0; i < nb_input_files; i++)
if (input_files[i].ctx->nb_chapters) {
chapters_input_file = i;
break;
}
} else {
av_log(NULL, AV_LOG_ERROR, "Invalid input file index %d in chapter mapping.\n",
chapters_input_file);
exit_program(1);
}
}
if (chapters_input_file >= 0)
copy_chapters(chapters_input_file, nb_output_files - 1);
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
/* copy metadata */
for (i = 0; i < 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 = 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 = &meta_data_maps[i][j];
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 (metadata_global_autocopy && nb_input_files)
av_dict_copy(&oc->metadata, input_files[0].ctx->metadata,
AV_DICT_DONT_OVERWRITE);
if (metadata_streams_autocopy)
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);
}
frame_rate = (AVRational){0, 0};
frame_width = 0;
frame_height = 0;
audio_sample_rate = 0;
audio_channels = 0;
audio_sample_fmt = AV_SAMPLE_FMT_NONE;
chapters_input_file = INT_MAX;
recording_time = INT64_MAX;
av_freep(&meta_data_maps);
nb_meta_data_maps = 0;
metadata_global_autocopy = 1;
metadata_streams_autocopy = 1;
metadata_chapters_autocopy = 1;
av_freep(&stream_maps);
nb_stream_maps = 0;
av_freep(&streamid_map);
nb_streamid_map = 0;
av_dict_free(&codec_names);
av_freep(&forced_key_frames);
uninit_opts();
init_opts();
Stefano Sabatini
committed
return 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)
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);
show_help_options(options, "\nAudio options:\n",
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
OPT_AUDIO);
show_help_options(options, "\nAdvanced Audio options:\n",
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB,
OPT_AUDIO | OPT_EXPERT);
show_help_options(options, "\nSubtitle options:\n",
OPT_SUBTITLE | OPT_GRAB,
OPT_SUBTITLE);
show_help_options(options, "\nAudio/Video grab options:\n",
OPT_GRAB,
OPT_GRAB);
printf("\n");
av_opt_show2(avcodec_opts[0], NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
printf("\n");
/* individual codec options */
c = NULL;
while ((c = av_codec_next(c))) {
if (c->priv_class) {