Newer
Older
av_log(NULL, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
ffmpeg_exit(1);
}
} else {
int i;
char fmt_str[128];
for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
static int opt_audio_rate(const char *opt, const char *arg)
audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
return 0;
static int opt_audio_channels(const char *opt, const char *arg)
audio_channels = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
return 0;
static int opt_video_channel(const char *opt, const char *arg)
Fabrice Bellard
committed
{
video_channel = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
return 0;
Fabrice Bellard
committed
}
static void opt_video_standard(const char *arg)
{
video_standard = av_strdup(arg);
}
static void opt_codec(int *pstream_copy, char **pcodec_name,
Fabrice Bellard
committed
int codec_type, const char *arg)
av_freep(pcodec_name);
if (!strcmp(arg, "copy")) {
Fabrice Bellard
committed
*pstream_copy = 1;
*pcodec_name = av_strdup(arg);
Fabrice Bellard
committed
static void opt_audio_codec(const char *arg)
{
opt_codec(&audio_stream_copy, &audio_codec_name, AVMEDIA_TYPE_AUDIO, arg);
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 void opt_data_codec(const char *arg)
{
opt_codec(&data_stream_copy, &data_codec_name, AVMEDIA_TYPE_DATA, 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);
ic->flags |= AVFMT_FLAG_NONBLOCK | AVFMT_FLAG_PRIV_OPT;
/* open the input file with generic libav function */
err = av_open_input_file(&ic, filename, file_iformat, 0, ap);
if(err >= 0){
set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
err = av_demuxer_open(ic, ap);
if(err < 0)
avformat_free_context(ic);
}
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);
if(!input_codecs[nb_input_codecs-1])
input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id);
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]);
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);
if(!input_codecs[nb_input_codecs-1])
input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id);
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;
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(!input_codecs[nb_input_codecs-1])
input_codecs[nb_input_codecs-1] = avcodec_find_decoder(dec->codec_id);
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
top_field_first = -1;
Baptiste Coudurier
committed
av_freep(&video_codec_name);
av_freep(&audio_codec_name);
av_freep(&subtitle_codec_name);
uninit_opts();
init_opts();
static void check_inputs(int *has_video_ptr,
int *has_audio_ptr,
int *has_subtitle_ptr,
int *has_data_ptr)
Fabrice Bellard
committed
{
int has_video, has_audio, has_subtitle, has_data, 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);
}
ost->frame_aspect_ratio = frame_aspect_ratio;
frame_aspect_ratio = 0;
#if CONFIG_AVFILTER
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;
if(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;
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;
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;
}
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
static void new_data_stream(AVFormatContext *oc, int file_idx)
{
AVStream *st;
AVOutputStream *ost;
AVCodec *codec=NULL;
AVCodecContext *data_enc;
st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
ffmpeg_exit(1);
}
ost = new_output_stream(oc, file_idx);
data_enc = st->codec;
output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);
if (!data_stream_copy) {
fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n");
ffmpeg_exit(1);
}
avcodec_get_context_defaults3(st->codec, codec);
data_enc->codec_type = AVMEDIA_TYPE_DATA;
if (data_codec_tag)
data_enc->codec_tag= data_codec_tag;
if (oc->oformat->flags & AVFMT_GLOBALHEADER) {
data_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
avcodec_opts[AVMEDIA_TYPE_DATA]->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
if (data_stream_copy) {
st->stream_copy = 1;
}
data_disable = 0;
av_freep(&data_codec_name);
data_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);
else if (!strcmp(opt, "newdata" )) new_data_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];
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;
}
Fabrice Bellard
committed
static void opt_output_file(const char *filename)
{
AVFormatContext *oc;
int err, use_video, use_audio, use_subtitle, use_data;
int input_has_video, input_has_audio, input_has_subtitle, input_has_data;
Fabrice Bellard
committed
AVFormatParameters params, *ap = ¶ms;
AVOutputFormat *file_oformat;
oc = avformat_alloc_output_context(last_asked_format, NULL, filename);
last_asked_format = NULL;
if (!oc) {
print_error(filename, AVERROR(ENOMEM));
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);
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;
use_data = data_stream_copy || data_codec_name; /* XXX once generic data codec will be available add a ->data_codec reference and use it here */
Fabrice Bellard
committed
/* disable if no corresponding type found and at least one
input file */
if (nb_input_files > 0) {
check_inputs(&input_has_video,
&input_has_audio,
&input_has_subtitle,
&input_has_data);
if (!input_has_video)
use_video = 0;
if (!input_has_audio)
use_audio = 0;
if (!input_has_subtitle)
use_subtitle = 0;
if (!input_has_data)
use_data = 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);
if (use_data) new_data_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(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);
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);
uninit_opts();
init_opts();
/* same option as mencoder */
static int opt_pass(const char *opt, const char *arg)