Newer
Older
Fabrice Bellard
committed
}
static void opt_video_codec(const char *arg)
opt_codec(&video_stream_copy, &video_codec_name, AVMEDIA_TYPE_VIDEO, arg);
Fabrice Bellard
committed
}
Fabrice Bellard
committed
static void opt_subtitle_codec(const char *arg)
{
opt_codec(&subtitle_stream_copy, &subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, arg);
static int opt_codec_tag(const char *opt, const char *arg)
uint32_t *codec_tag;
codec_tag = !strcmp(opt, "atag") ? &audio_codec_tag :
!strcmp(opt, "vtag") ? &video_codec_tag :
!strcmp(opt, "stag") ? &subtitle_codec_tag : NULL;
if (!codec_tag)
return -1;
*codec_tag = strtol(arg, &tail, 0);
if (!tail || *tail)
static void opt_map(const char *arg)
stream_maps = grow_array(stream_maps, sizeof(*stream_maps), &nb_stream_maps, nb_stream_maps + 1);
m = &stream_maps[nb_stream_maps-1];
m->file_index = strtol(arg, &p, 0);
m->stream_index = strtol(p, &p, 0);
if (*p) {
p++;
m->sync_file_index = strtol(p, &p, 0);
if (*p)
p++;
m->sync_stream_index = strtol(p, &p, 0);
} else {
m->sync_file_index = m->file_index;
m->sync_stream_index = m->stream_index;
}
static void parse_meta_type(char *arg, char *type, int *index, char **endptr)
{
*endptr = arg;
if (*arg == ',') {
*type = *(++arg);
switch (*arg) {
case 'g':
break;
case 's':
case 'c':
case 'p':
*index = strtol(++arg, endptr, 0);
break;
default:
fprintf(stderr, "Invalid metadata type %c.\n", *arg);
ffmpeg_exit(1);
}
} else
*type = 'g';
}
static void opt_map_metadata(const char *arg)
Patrice Bensoussan
committed
{
AVMetaDataMap *m, *m1;
meta_data_maps = grow_array(meta_data_maps, sizeof(*meta_data_maps),
&nb_meta_data_maps, nb_meta_data_maps + 1);
Patrice Bensoussan
committed
m = &meta_data_maps[nb_meta_data_maps - 1][0];
m->file = strtol(arg, &p, 0);
parse_meta_type(p, &m->type, &m->index, &p);
Patrice Bensoussan
committed
if (*p)
p++;
m1 = &meta_data_maps[nb_meta_data_maps - 1][1];
m1->file = strtol(p, &p, 0);
parse_meta_type(p, &m1->type, &m1->index, &p);
Anton Khirnov
committed
if (m->type == 'g' || m1->type == 'g')
metadata_global_autocopy = 0;
Anton Khirnov
committed
if (m->type == 's' || m1->type == 's')
metadata_streams_autocopy = 0;
if (m->type == 'c' || m1->type == 'c')
metadata_chapters_autocopy = 0;
Patrice Bensoussan
committed
}
static void opt_map_meta_data(const char *arg)
{
fprintf(stderr, "-map_meta_data is deprecated and will be removed soon. "
"Use -map_metadata instead.\n");
opt_map_metadata(arg);
}
static void opt_map_chapters(const char *arg)
{
AVChapterMap *c;
char *p;
chapter_maps = grow_array(chapter_maps, sizeof(*chapter_maps), &nb_chapter_maps,
nb_chapter_maps + 1);
c = &chapter_maps[nb_chapter_maps - 1];
c->out_file = strtol(arg, &p, 0);
if (*p)
p++;
c->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)
input_files_ts_scale[nb_input_files] = grow_array(input_files_ts_scale[nb_input_files], sizeof(*input_files_ts_scale[nb_input_files]), &nb_input_files_ts_scale[nb_input_files], stream + 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);
return 0;
static int opt_start_time(const char *opt, const char *arg)
start_time = parse_time_or_die(opt, arg, 1);
return 0;
static int opt_recording_timestamp(const char *opt, const char *arg)
{
recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000;
return 0;
}
static int opt_input_ts_offset(const char *opt, const char *arg)
input_ts_offset = parse_time_or_die(opt, arg, 1);
return 0;
Janne Grunau
committed
static enum CodecID find_codec_or_die(const char *name, int type, int encoder, int strict)
{
const char *codec_string = encoder ? "encoder" : "decoder";
AVCodec *codec;
if(!name)
return CODEC_ID_NONE;
codec = encoder ?
avcodec_find_encoder_by_name(name) :
avcodec_find_decoder_by_name(name);
if(!codec) {
fprintf(stderr, "Unknown %s '%s'\n", codec_string, name);
}
if(codec->type != type) {
fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
}
Janne Grunau
committed
if(codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
strict > FF_COMPLIANCE_EXPERIMENTAL) {
fprintf(stderr, "%s '%s' is experimental and might produce bad "
"results.\nAdd '-strict experimental' if you want to use it.\n",
codec_string, codec->name);
codec = encoder ?
avcodec_find_encoder(codec->id) :
avcodec_find_decoder(codec->id);
if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
fprintf(stderr, "Or use the non experimental %s '%s'.\n",
codec_string, codec->name);
Janne Grunau
committed
}
return codec->id;
}
static void opt_input_file(const char *filename)
{
AVFormatContext *ic;
AVFormatParameters params, *ap = ¶ms;
AVInputFormat *file_iformat = NULL;
Michael Niedermayer
committed
int err, i, ret, rfps, rfps_base;
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));
memset(ap, 0, sizeof(*ap));
ap->prealloced_context = 1;
ap->sample_rate = audio_sample_rate;
ap->channels = audio_channels;
ap->time_base.den = frame_rate.num;
ap->time_base.num = frame_rate.den;
ap->width = frame_width;
ap->height = frame_height;
ap->pix_fmt = frame_pix_fmt;
// ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat
ap->channel = video_channel;
ap->standard = video_standard;
set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
Janne Grunau
committed
ic->video_codec_id =
find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0,
avcodec_opts[AVMEDIA_TYPE_VIDEO ]->strict_std_compliance);
ic->audio_codec_id =
find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0,
avcodec_opts[AVMEDIA_TYPE_AUDIO ]->strict_std_compliance);
ic->subtitle_codec_id=
find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,
avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
/* open the input file with generic libav function */
err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
print_error(filename, err);
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
}
ic->loop_input = loop_input;
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
ret = av_find_stream_info(ic);
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 */
for(i=0;i<ic->nb_streams;i++) {
AVCodecContext *dec = st->codec;
input_codecs = grow_array(input_codecs, sizeof(*input_codecs), &nb_input_codecs, nb_input_codecs + 1);
switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(audio_codec_name);
set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
//fprintf(stderr, "\nInput Audio channels: %d", dec->channels);
channel_layout = dec->channel_layout;
audio_channels = dec->channels;
audio_sample_rate = dec->sample_rate;
audio_sample_fmt = dec->sample_fmt;
Martin Storsjö
committed
/* Note that av_find_stream_info can add more streams, and we
* currently have no chance of setting up lowres decoding
* early enough for them. */
if (dec->lowres)
audio_sample_rate >>= dec->lowres;
case AVMEDIA_TYPE_VIDEO:
input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(video_codec_name);
set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);
frame_height = dec->height;
frame_width = dec->width;
if(ic->streams[i]->sample_aspect_ratio.num)
frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);
else
frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio);
frame_aspect_ratio *= (float) dec->width / dec->height;
frame_aspect_ratio_override = 0;
frame_pix_fmt = dec->pix_fmt;
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;
frame_height >>= dec->lowres;
frame_width >>= dec->lowres;
dec->height = frame_height;
dec->width = frame_width;
Michael Niedermayer
committed
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)
Baptiste Coudurier
committed
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);
/* update the current frame rate to match the stream frame rate */
frame_rate.num = rfps;
frame_rate.den = rfps_base;
Max Krasnyansky
committed
case AVMEDIA_TYPE_DATA:
break;
case AVMEDIA_TYPE_SUBTITLE:
input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(subtitle_codec_name);
if(subtitle_disable)
Fabrice Bellard
committed
break;
case AVMEDIA_TYPE_ATTACHMENT:
case AVMEDIA_TYPE_UNKNOWN:
break;
default:
input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);
if (verbose >= 0)
av_dump_format(ic, nb_input_files, filename, 0);
Max Krasnyansky
committed
Baptiste Coudurier
committed
av_freep(&video_codec_name);
av_freep(&audio_codec_name);
av_freep(&subtitle_codec_name);
static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr,
int *has_subtitle_ptr)
Fabrice Bellard
committed
{
int has_video, has_audio, has_subtitle, i, j;
Fabrice Bellard
committed
AVFormatContext *ic;
has_video = 0;
has_audio = 0;
has_subtitle = 0;
Fabrice Bellard
committed
for(j=0;j<nb_input_files;j++) {
ic = input_files[j];
for(i=0;i<ic->nb_streams;i++) {
Michael Niedermayer
committed
AVCodecContext *enc = ic->streams[i]->codec;
Fabrice Bellard
committed
switch(enc->codec_type) {
case AVMEDIA_TYPE_AUDIO:
Fabrice Bellard
committed
has_audio = 1;
break;
case AVMEDIA_TYPE_VIDEO:
Fabrice Bellard
committed
has_video = 1;
break;
case AVMEDIA_TYPE_SUBTITLE:
has_subtitle = 1;
break;
case AVMEDIA_TYPE_DATA:
case AVMEDIA_TYPE_ATTACHMENT:
case AVMEDIA_TYPE_UNKNOWN:
Wolfram Gloger
committed
break;
default:
Fabrice Bellard
committed
}
}
}
*has_video_ptr = has_video;
*has_audio_ptr = has_audio;
*has_subtitle_ptr = has_subtitle;
Fabrice Bellard
committed
}
static void new_video_stream(AVFormatContext *oc, int file_idx)
AVOutputStream *ost;
Fabrice Bellard
committed
AVCodecContext *video_enc;
AVCodec *codec= NULL;
st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
Fabrice Bellard
committed
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
Fabrice Bellard
committed
}
ost = new_output_stream(oc, file_idx);
output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!video_stream_copy){
if (video_codec_name) {
codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1,
avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance);
codec = avcodec_find_encoder_by_name(video_codec_name);
output_codecs[nb_output_codecs-1] = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
codec = avcodec_find_encoder(codec_id);
}
#if CONFIG_AVFILTER
if(frame_aspect_ratio_override){
i = vfilters ? strlen(vfilters) : 0;
vfilters = av_realloc(vfilters, i+100);
snprintf(vfilters+i, 100, "%csetdar=%f\n", i?',':' ', frame_aspect_ratio);
frame_aspect_ratio=0;
frame_aspect_ratio_override=0;
}
ost->avfilter= vfilters;
vfilters= NULL;
}
avcodec_get_context_defaults3(st->codec, codec);
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;
Michael Niedermayer
committed
if( (video_global_header&1)
|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){
Fabrice Bellard
committed
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
}
if(video_global_header&2){
Michael Niedermayer
committed
video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER;
avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER;
Michael Niedermayer
committed
Fabrice Bellard
committed
if (video_stream_copy) {
st->stream_copy = 1;
video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
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;
AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1};
Fabrice Bellard
committed
video_enc->codec_id = codec_id;
set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
if (codec && codec->supported_framerates && !force_fps)
fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)];
video_enc->time_base.den = fps.num;
video_enc->time_base.num = fps.den;
video_enc->width = frame_width;
video_enc->height = frame_height;
video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255);
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
Ronald S. Bultje
committed
choose_pixel_fmt(st, codec);
Fabrice Bellard
committed
if (intra_only)
Fabrice Bellard
committed
video_enc->gop_size = 0;
if (video_qscale || same_quality) {
video_enc->flags |= CODEC_FLAG_QSCALE;
Fabrice Bellard
committed
st->quality = FF_QP2LAMBDA * video_qscale;
}
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_metadata_set2(&st->metadata, "language", video_language, 0);
av_freep(&video_language);
}
Fabrice Bellard
committed
/* reset some key parameters */
video_disable = 0;
av_freep(&video_codec_name);
av_freep(&forced_key_frames);
Fabrice Bellard
committed
video_stream_copy = 0;
frame_pix_fmt = PIX_FMT_NONE;
Fabrice Bellard
committed
}
static void new_audio_stream(AVFormatContext *oc, int file_idx)
Fabrice Bellard
committed
{
AVStream *st;
AVOutputStream *ost;
AVCodec *codec= NULL;
Fabrice Bellard
committed
AVCodecContext *audio_enc;
st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
Fabrice Bellard
committed
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
Fabrice Bellard
committed
}
ost = new_output_stream(oc, file_idx);
output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!audio_stream_copy){
if (audio_codec_name) {
codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1,
avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance);
codec = avcodec_find_encoder_by_name(audio_codec_name);
output_codecs[nb_output_codecs-1] = codec;
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO);
codec = avcodec_find_encoder(codec_id);
}
}
avcodec_get_context_defaults3(st->codec, codec);
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;
avcodec_opts[AVMEDIA_TYPE_AUDIO]->flags|= CODEC_FLAG_GLOBAL_HEADER;
Fabrice Bellard
committed
if (audio_stream_copy) {
st->stream_copy = 1;
audio_enc->channels = audio_channels;
Michael Niedermayer
committed
audio_enc->sample_rate = audio_sample_rate;
Fabrice Bellard
committed
} else {
audio_enc->codec_id = codec_id;
set_context_opts(audio_enc, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
if (audio_qscale > QSCALE_NONE) {
audio_enc->flags |= CODEC_FLAG_QSCALE;
audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
}
audio_enc->channels = audio_channels;
audio_enc->sample_fmt = audio_sample_fmt;
Michael Niedermayer
committed
audio_enc->sample_rate = audio_sample_rate;
audio_enc->channel_layout = channel_layout;
if (av_get_channel_layout_nb_channels(channel_layout) != audio_channels)
audio_enc->channel_layout = 0;
Ronald S. Bultje
committed
choose_sample_fmt(st, codec);
Michael Niedermayer
committed
choose_sample_rate(st, codec);
Fabrice Bellard
committed
}
Michael Niedermayer
committed
audio_enc->time_base= (AVRational){1, audio_sample_rate};
Fabrice Bellard
committed
if (audio_language) {
av_metadata_set2(&st->metadata, "language", audio_language, 0);
av_freep(&audio_language);
Fabrice Bellard
committed
}
/* reset some key parameters */
audio_disable = 0;
av_freep(&audio_codec_name);
Fabrice Bellard
committed
audio_stream_copy = 0;
}
static void new_subtitle_stream(AVFormatContext *oc, int file_idx)
Fabrice Bellard
committed
{
AVStream *st;
AVOutputStream *ost;
AVCodec *codec=NULL;
Fabrice Bellard
committed
AVCodecContext *subtitle_enc;
st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
Fabrice Bellard
committed
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
Fabrice Bellard
committed
}
ost = new_output_stream(oc, file_idx);
subtitle_enc = st->codec;
output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if(!subtitle_stream_copy){
if (subtitle_codec_name) {
codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,
avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);
codec= output_codecs[nb_output_codecs-1] = avcodec_find_encoder_by_name(subtitle_codec_name);
} else {
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE);
codec = avcodec_find_encoder(codec_id);
}
}
avcodec_get_context_defaults3(st->codec, 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;
avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
Fabrice Bellard
committed
if (subtitle_stream_copy) {
st->stream_copy = 1;
} else {
set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);
Fabrice Bellard
committed
}
if (subtitle_language) {
av_metadata_set2(&st->metadata, "language", subtitle_language, 0);
av_freep(&subtitle_language);
Fabrice Bellard
committed
}
subtitle_disable = 0;
av_freep(&subtitle_codec_name);
Fabrice Bellard
committed
subtitle_stream_copy = 0;
}
Aurelien Jacobs
committed
static int opt_new_stream(const char *opt, const char *arg)
Fabrice Bellard
committed
{
AVFormatContext *oc;
int file_idx = nb_output_files - 1;
Fabrice Bellard
committed
if (nb_output_files <= 0) {
fprintf(stderr, "At least one output file must be specified\n");
Fabrice Bellard
committed
}
oc = output_files[file_idx];
Fabrice Bellard
committed
if (!strcmp(opt, "newvideo" )) new_video_stream (oc, file_idx);
else if (!strcmp(opt, "newaudio" )) new_audio_stream (oc, file_idx);
else if (!strcmp(opt, "newsubtitle")) new_subtitle_stream(oc, file_idx);
Aurelien Jacobs
committed
return 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];
strncpy(idx_str, arg, sizeof(idx_str));
idx_str[sizeof(idx_str)-1] = '\0';
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;
}
Fabrice Bellard
committed
static void opt_output_file(const char *filename)
{
AVFormatContext *oc;
int err, use_video, use_audio, use_subtitle;
int input_has_video, input_has_audio, input_has_subtitle;
Fabrice Bellard
committed
AVFormatParameters params, *ap = ¶ms;
AVOutputFormat *file_oformat;
oc = avformat_alloc_context();
if (!oc) {
print_error(filename, AVERROR(ENOMEM));
if (last_asked_format) {
file_oformat = av_guess_format(last_asked_format, NULL, NULL);
if (!file_oformat) {
fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format);
}
last_asked_format = NULL;
} else {
file_oformat = av_guess_format(NULL, filename, NULL);
if (!file_oformat) {
fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
filename);
oc->oformat = file_oformat;
av_strlcpy(oc->filename, filename, sizeof(oc->filename));
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);
use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name;
use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_name;
use_subtitle = file_oformat->subtitle_codec != CODEC_ID_NONE || subtitle_stream_copy || subtitle_codec_name;
Fabrice Bellard
committed
/* disable if no corresponding type found and at least one
input file */
if (nb_input_files > 0) {
check_audio_video_sub_inputs(&input_has_video, &input_has_audio,
&input_has_subtitle);
if (!input_has_video)
use_video = 0;
if (!input_has_audio)
use_audio = 0;
if (!input_has_subtitle)
use_subtitle = 0;
Fabrice Bellard
committed
/* manual disable */
if (audio_disable) use_audio = 0;
if (video_disable) use_video = 0;
if (subtitle_disable) use_subtitle = 0;
if (use_video) new_video_stream(oc, nb_output_files);
if (use_audio) new_audio_stream(oc, nb_output_files);
if (use_subtitle) new_subtitle_stream(oc, nb_output_files);
oc->timestamp = recording_timestamp;
Ronald S. Bultje
committed
av_metadata_copy(&oc->metadata, metadata, 0);
av_metadata_free(&metadata);
output_files[nb_output_files++] = oc;
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_NUMEXPECTED);
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 (!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_WRONLY)) < 0) {
print_error(filename, err);
Fabrice Bellard
committed
memset(ap, 0, sizeof(*ap));
if (av_set_parameters(oc, ap) < 0) {
fprintf(stderr, "%s: Invalid encoding parameters\n",
oc->filename);
Fabrice Bellard
committed
}
oc->preload= (int)(mux_preload*AV_TIME_BASE);
oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE);
oc->loop_output = loop_output;
set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL);
av_freep(&forced_key_frames);
/* same option as mencoder */
static void opt_pass(const char *pass_str)
{
int pass;
pass = atoi(pass_str);
if (pass != 1 && pass != 2) {
fprintf(stderr, "pass number can be only 1 or 2\n");
}
do_pass = pass;
}
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++;
}
}
static void opt_inter_matrix(const char *arg)
Vidar Madsen
committed
{
inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(inter_matrix, arg);
}
static void opt_intra_matrix(const char *arg)
Vidar Madsen
committed
{
intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
parse_matrix_coeffs(intra_matrix, arg);
}
printf("Hyper fast Audio and Video encoder\n");
printf("usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...\n");
printf("\n");
}
static void show_help(void)
{