static int opt_shortest = 0;
static char *vstats_filename;
static FILE *vstats_file;
-static int copy_initial_nonkeyframes = 0;
static int audio_volume = 256;
AVFilterGraph *graph;
#endif
- int64_t sws_flags;
- AVDictionary *opts;
- int is_past_recording_time;
+ int64_t sws_flags;
+ AVDictionary *opts;
+ int is_past_recording_time;
+ int stream_copy;
+ const char *attachment_filename;
+ int copy_initial_nonkeyframes;
} OutputStream;
SpecifierOpt *ts_scale;
int nb_ts_scale;
+ SpecifierOpt *dump_attachment;
+ int nb_dump_attachment;
/* output options */
StreamMap *stream_maps;
int metadata_global_manual;
int metadata_streams_manual;
int metadata_chapters_manual;
+ const char **attachments;
+ int nb_attachments;
int chapters_input_file;
int nb_top_field_first;
SpecifierOpt *presets;
int nb_presets;
+ SpecifierOpt *copy_initial_nonkeyframes;
+ int nb_copy_initial_nonkeyframes;
#if CONFIG_AVFILTER
SpecifierOpt *filters;
int nb_filters;
memset(o, 0, sizeof(*o));
- o->mux_preload = 0.5;
o->mux_max_delay = 0.7;
o->recording_time = INT64_MAX;
o->limit_filesize = UINT64_MAX;
#if CONFIG_AVFILTER
avfilter_uninit();
#endif
+ avformat_network_deinit();
if (received_sigterm) {
av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
if ((ost->audio_resample && !ost->resample) || resample_changed) {
if (resample_changed) {
- av_log(NULL, AV_LOG_INFO, "Input stream #%d.%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",
+ av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",
ist->file_index, ist->st->index,
ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels,
dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels);
if (resample_changed) {
av_log(NULL, AV_LOG_INFO,
- "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
+ "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
ist->file_index, ist->st->index,
ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt),
dec->width , dec->height , av_get_pix_fmt_name(dec->pix_fmt));
float q = -1;
ost = &ost_table[i];
enc = ost->st->codec;
- if (!ost->st->stream_copy && enc->coded_frame)
+ if (!ost->stream_copy && enc->coded_frame)
q = enc->coded_frame->quality/(float)FF_QP2LAMBDA;
if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
av_init_packet(&opkt);
- if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
+ if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
+ !ost->copy_initial_nonkeyframes)
#if !CONFIG_AVFILTER
continue;
#else
if (ist->decoding_needed) {
AVCodec *codec = ist->dec;
if (!codec) {
- snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d.%d",
+ snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d",
ist->st->codec->codec_id, ist->file_index, ist->st->index);
return AVERROR(EINVAL);
}
}
if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
- snprintf(error, error_len, "Error while opening decoder for input stream #%d.%d",
+ snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
ist->file_index, ist->st->index);
return AVERROR(EINVAL);
}
os = output_files[ost->file_index].ctx;
ist = &input_streams[ost->source_index];
+ if (ost->attachment_filename)
+ continue;
+
codec = ost->st->codec;
icodec = ist->st->codec;
codec->bits_per_raw_sample= icodec->bits_per_raw_sample;
codec->chroma_sample_location = icodec->chroma_sample_location;
- if (ost->st->stream_copy) {
+ if (ost->stream_copy) {
uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
if (extra_size > INT_MAX) {
codec->frame_size = icodec->frame_size;
codec->audio_service_type = icodec->audio_service_type;
codec->block_align= icodec->block_align;
- if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)
- codec->block_align= 0;
- if(codec->codec_id == CODEC_ID_AC3)
- codec->block_align= 0;
break;
case AVMEDIA_TYPE_VIDEO:
codec->pix_fmt = icodec->pix_fmt;
return AVERROR(ENOMEM);
}
ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);
- if (!codec->sample_rate) {
+ if (!codec->sample_rate)
codec->sample_rate = icodec->sample_rate;
- if (icodec->lowres)
- codec->sample_rate >>= icodec->lowres;
- }
choose_sample_rate(ost->st, ost->enc);
codec->time_base = (AVRational){1, codec->sample_rate};
if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
} else {
char *logbuffer;
size_t logbuffer_size;
- if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
+ if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
logfilename);
exit_program(1);
AVCodec *codec = ost->enc;
AVCodecContext *dec = input_streams[ost->source_index].st->codec;
if (!codec) {
- snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",
+ snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d:%d",
ost->st->codec->codec_id, ost->file_index, ost->index);
ret = AVERROR(EINVAL);
goto dump_format;
ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
}
if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {
- snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",
+ snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
ost->file_index, ost->index);
ret = AVERROR(EINVAL);
goto dump_format;
av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
for (i = 0; i < nb_output_streams; i++) {
ost = &output_streams[i];
- av_log(NULL, AV_LOG_INFO, " Stream #%d.%d -> #%d.%d",
+
+ if (ost->attachment_filename) {
+ /* an attached file */
+ av_log(NULL, AV_LOG_INFO, " File %s -> Stream #%d:%d\n",
+ ost->attachment_filename, ost->file_index, ost->index);
+ continue;
+ }
+ av_log(NULL, AV_LOG_INFO, " Stream #%d:%d -> #%d:%d",
input_streams[ost->source_index].file_index,
input_streams[ost->source_index].st->index,
ost->file_index,
ost->index);
if (ost->sync_ist != &input_streams[ost->source_index])
- av_log(NULL, AV_LOG_INFO, " [sync #%d.%d]",
+ av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
ost->sync_ist->file_index,
ost->sync_ist->st->index);
- if (ost->st->stream_copy)
+ if (ost->stream_copy)
av_log(NULL, AV_LOG_INFO, " (copy)");
else
av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index].dec ?
//fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);
if (output_packet(ist, ist_index, output_streams, nb_output_streams, &pkt) < 0) {
- av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d.%d\n",
+ av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
ist->file_index, ist->st->index);
if (exit_on_error)
exit_program(1);
for (i = 0; i < nb_output_streams; i++) {
ost = &output_streams[i];
if (ost) {
- if (ost->st->stream_copy)
+ if (ost->stream_copy)
av_freep(&ost->st->codec->extradata);
if (ost->logfile) {
fclose(ost->logfile);
/* disable some already defined maps */
for (i = 0; i < o->nb_stream_maps; i++) {
m = &o->stream_maps[i];
- if (check_stream_specifier(input_files[m->file_index].ctx,
+ if (file_idx == m->file_index &&
+ check_stream_specifier(input_files[m->file_index].ctx,
input_files[m->file_index].ctx->streams[m->stream_index],
*p == ':' ? p + 1 : p) > 0)
m->disabled = 1;
return 0;
}
+static int opt_attach(OptionsContext *o, const char *opt, const char *arg)
+{
+ o->attachments = grow_array(o->attachments, sizeof(*o->attachments),
+ &o->nb_attachments, o->nb_attachments + 1);
+ o->attachments[o->nb_attachments - 1] = arg;
+ return 0;
+}
+
static void parse_meta_type(char *arg, char *type, int *index)
{
if (*arg) {
return 0;
}
-static enum CodecID find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
+static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
{
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);
av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
exit_program(1);
}
- return codec->id;
+ return codec;
}
-static AVCodec *choose_codec(OptionsContext *o, AVFormatContext *s, AVStream *st, enum AVMediaType type)
+static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
{
char *codec_name = NULL;
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;
+ if (codec_name) {
+ AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
+ st->codec->codec_id = codec->id;
+ return codec;
+ } else
+ return avcodec_find_decoder(st->codec->codec_id);
}
/**
AVStream *st = ic->streams[i];
AVCodecContext *dec = st->codec;
InputStream *ist;
- double scale = 1.0;
input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
ist = &input_streams[nb_input_streams - 1];
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->ts_scale = 1.0;
+ MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
- ist->dec = choose_codec(o, ic, st, dec->codec_type);
- if (!ist->dec)
- ist->dec = avcodec_find_decoder(dec->codec_id);
+ ist->dec = choose_decoder(o, ic, st);
switch (dec->codec_type) {
case AVMEDIA_TYPE_AUDIO:
}
}
+static void assert_file_overwrite(const char *filename)
+{
+ if (!file_overwrite &&
+ (strchr(filename, ':') == NULL || 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);
+ if (!read_yesno()) {
+ fprintf(stderr, "Not overwriting - exiting\n");
+ exit_program(1);
+ }
+ }
+ else {
+ fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
+ exit_program(1);
+ }
+ }
+ }
+}
+
+static void dump_attachment(AVStream *st, const char *filename)
+{
+ int ret;
+ AVIOContext *out = NULL;
+ AVDictionaryEntry *e;
+
+ if (!st->codec->extradata_size) {
+ av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
+ nb_input_files - 1, st->index);
+ return;
+ }
+ if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
+ filename = e->value;
+ if (!*filename) {
+ av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
+ "in stream #%d:%d.\n", nb_input_files - 1, st->index);
+ exit_program(1);
+ }
+
+ assert_file_overwrite(filename);
+
+ if ((ret = avio_open (&out, filename, AVIO_FLAG_WRITE)) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
+ filename);
+ exit_program(1);
+ }
+
+ avio_write(out, st->codec->extradata, st->codec->extradata_size);
+ avio_flush(out);
+ avio_close(out);
+}
+
static int opt_input_file(OptionsContext *o, const char *opt, const char *filename)
{
AVFormatContext *ic;
/* 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);
+ choose_decoder(o, ic, ic->streams[i]);
/* Set AVCodecContext options for avformat_find_stream_info */
opts = setup_find_stream_info_opts(ic, codec_opts);
input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
input_files[nb_input_files - 1].rate_emu = o->rate_emu;
+ for (i = 0; i < o->nb_dump_attachment; i++) {
+ int j;
+
+ for (j = 0; j < ic->nb_streams; j++) {
+ AVStream *st = ic->streams[j];
+
+ if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
+ dump_attachment(st, o->dump_attachment[i].u.str);
+ }
+ }
+
for (i = 0; i < orig_nb_streams; i++)
av_dict_free(&opts[i]);
av_freep(&opts);
return ret;
}
+static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
+{
+ char *codec_name = NULL;
+
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
+ if (!codec_name) {
+ ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
+ NULL, ost->st->codec->codec_type);
+ ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+ } else if (!strcmp(codec_name, "copy"))
+ ost->stream_copy = 1;
+ else {
+ ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
+ ost->st->codec->codec_id = ost->enc->id;
+ }
+}
+
static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
{
OutputStream *ost;
- AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0);
+ AVStream *st = avformat_new_stream(oc, NULL);
int idx = oc->nb_streams - 1, ret = 0;
- int64_t max_frames = INT64_MAX;
char *bsf = NULL, *next, *codec_tag = NULL;
AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
double qscale = -1;
exit_program(1);
}
+ if (oc->nb_streams - 1 < o->nb_streamid_map)
+ st->id = o->streamid_map[oc->nb_streams - 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->index = idx;
ost->st = st;
st->codec->codec_type = type;
- ost->enc = choose_codec(o, oc, st, type);
+ choose_encoder(o, oc, ost);
if (ost->enc) {
ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st);
}
exit_program(1);
}
- MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st);
- ost->max_frames = max_frames;
+ ost->max_frames = INT64_MAX;
+ MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
while (bsf) {
st = ost->st;
video_enc = st->codec;
- if (!st->stream_copy) {
+ if (!ost->stream_copy) {
const char *p = NULL;
char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL;
char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL;
- int i, force_fps = 0, top_field_first = -1;
+ int i;
MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
if (forced_key_frames)
parse_forced_key_frames(forced_key_frames, ost, video_enc);
- MATCH_PER_STREAM_OPT(force_fps, i, force_fps, oc, st);
- ost->force_fps = force_fps;
+ MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
+
+ ost->top_field_first = -1;
+ MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
- MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st);
- ost->top_field_first = top_field_first;
+ MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
#if CONFIG_AVFILTER
MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
audio_enc = st->codec;
audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
- if (!st->stream_copy) {
+ if (!ost->stream_copy) {
char *sample_fmt = NULL;
MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
{
- AVStream *st;
OutputStream *ost;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
- st = ost->st;
- if (!st->stream_copy) {
+ if (!ost->stream_copy) {
av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
exit_program(1);
}
static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
{
OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
- ost->st->stream_copy = 1;
+ ost->stream_copy = 1;
return ost;
}
st->info = NULL;
avcodec_copy_context(st->codec, ic->streams[i]->codec);
- if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
choose_sample_fmt(st, codec);
- else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !st->stream_copy)
+ else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
choose_pixel_fmt(st, codec);
}
case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
default:
- av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d.%d - unsupported type.\n",
+ av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
map->file_index, map->stream_index);
exit_program(1);
}
}
}
+ /* handle attached files */
+ for (i = 0; i < o->nb_attachments; i++) {
+ AVIOContext *pb;
+ uint8_t *attachment;
+ const char *p;
+ int64_t len;
+
+ if ((err = avio_open(&pb, o->attachments[i], AVIO_FLAG_READ)) < 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if ((len = avio_size(pb)) <= 0) {
+ av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ if (!(attachment = av_malloc(len))) {
+ av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
+ o->attachments[i]);
+ exit_program(1);
+ }
+ avio_read(pb, attachment, len);
+
+ ost = new_attachment_stream(o, oc);
+ ost->stream_copy = 0;
+ ost->source_index = -1;
+ ost->attachment_filename = o->attachments[i];
+ ost->st->codec->extradata = attachment;
+ ost->st->codec->extradata_size = len;
+
+ p = strrchr(o->attachments[i], '/');
+ av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
+ avio_close(pb);
+ }
+
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;
if (!(oc->oformat->flags & AVFMT_NOFILE)) {
/* test if it already exists to avoid loosing precious files */
- if (!file_overwrite &&
- (strchr(filename, ':') == NULL ||
- 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);
- if (!read_yesno()) {
- fprintf(stderr, "Not overwriting - exiting\n");
- exit_program(1);
- }
- }
- else {
- fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
- exit_program(1);
- }
- }
- }
+ assert_file_overwrite(filename);
/* open the file */
if ((err = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
}
}
- oc->preload = (int)(o->mux_preload * AV_TIME_BASE);
+ if (o->mux_preload) {
+ uint8_t buf[64];
+ snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
+ av_dict_set(&output_files[nb_output_files - 1].opts, "preload", buf, 0);
+ }
oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
oc->flags |= AVFMT_FLAG_NONBLOCK;
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];
+ InputStream *ist;
+ if (output_streams[i].source_index < 0) /* this is true e.g. for attached files */
+ continue;
+ ist = &input_streams[output_streams[i].source_index];
av_dict_copy(&output_streams[i].st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
}
{ "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, //
{ "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "threshold" },
{ "xerror", OPT_BOOL, {(void*)&exit_on_error}, "exit on error", "error" },
- { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)©_initial_nonkeyframes}, "copy initial non-keyframes" },
+ { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC, {.off = OFFSET(copy_initial_nonkeyframes)}, "copy initial non-keyframes" },
{ "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, {.off = OFFSET(max_frames)}, "set the number of frames to record", "number" },
{ "tag", OPT_STRING | HAS_ARG | OPT_SPEC, {.off = OFFSET(codec_tags)}, "force codec tag/fourcc", "fourcc/tag" },
{ "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" },
{ "filter", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(filters)}, "set stream filterchain", "filter_list" },
#endif
{ "stats", OPT_BOOL, {&print_stats}, "print progress report during encoding", },
+ { "attach", HAS_ARG | OPT_FUNC2, {(void*)opt_attach}, "add an attachment to the output file", "filename" },
+ { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(dump_attachment)}, "extract an attachment into a file", "filename" },
/* video options */
{ "vframes", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_frames}, "set the number of video frames to record", "number" },
avfilter_register_all();
#endif
av_register_all();
+ avformat_network_init();
avio_set_interrupt_cb(decode_interrupt_cb);