X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffmpeg.c;h=4700144f356a0bcc06fa7451bbac9acba1e01443;hb=cb25a186eb4da5a4e1c943e89b9cf8a7852723c7;hp=72189f119389e5bea62903402ed82a6e411b6b1f;hpb=d40ff29cacf9b8ffa1061392a0e9b3056c4882ea;p=ffmpeg diff --git a/ffmpeg.c b/ffmpeg.c index 72189f11938..4700144f356 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -117,15 +117,6 @@ typedef struct { int ofile_idx, ostream_idx; // output } AudioChannelMap; -/** - * select an input file for an output file - */ -typedef struct MetadataMap { - int file; ///< file index - char type; ///< type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram - int index; ///< stream/chapter/program number -} MetadataMap; - static const OptionDef options[]; #define MAX_STREAMS 1024 /* arbitrary sanity check value */ @@ -360,9 +351,6 @@ typedef struct OptionsContext { int nb_stream_maps; AudioChannelMap *audio_channel_maps; ///< one info entry per -map_channel int nb_audio_channel_maps; ///< number of (valid) -map_channel settings - /* first item specifies output metadata, second is input */ - MetadataMap (*meta_data_maps)[2]; - int nb_meta_data_maps; int metadata_global_manual; int metadata_streams_manual; int metadata_chapters_manual; @@ -461,7 +449,6 @@ static void reset_options(OptionsContext *o, int is_input) av_freep(&o->stream_maps); av_freep(&o->audio_channel_maps); - av_freep(&o->meta_data_maps); av_freep(&o->streamid_map); memset(o, 0, sizeof(*o)); @@ -565,7 +552,6 @@ static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) { av_freep(&buf->base[0]); av_free(buf); - ist->dr1 = 0; if ((ret = alloc_buffer(ist, s, &buf)) < 0) return ret; } @@ -634,9 +620,9 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost) } else sample_aspect_ratio = ist->st->codec->sample_aspect_ratio; - snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width, + snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d:flags=%d", ist->st->codec->width, ist->st->codec->height, ist->st->codec->pix_fmt, 1, AV_TIME_BASE, - sample_aspect_ratio.num, sample_aspect_ratio.den); + sample_aspect_ratio.num, sample_aspect_ratio.den, SWS_BILINEAR + ((icodec->flags&CODEC_FLAG_BITEXACT) ? SWS_BITEXACT:0)); ret = avfilter_graph_create_filter(&ost->input_video_filter, avfilter_get_by_name("buffer"), "src", args, NULL, ost->graph); @@ -1571,7 +1557,9 @@ static void do_video_out(AVFormatContext *s, OutputStream *ost, if (ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE) { duration = FFMAX(av_q2d(ist->st->time_base), av_q2d(ist->st->codec->time_base)); - if(ist->st->avg_frame_rate.num) + if(ist->st->r_frame_rate.num) + duration= FFMAX(duration, 1/av_q2d(ist->st->r_frame_rate)); + if(ist->st->avg_frame_rate.num && 0) duration= FFMAX(duration, 1/av_q2d(ist->st->avg_frame_rate)); duration /= av_q2d(enc->time_base); @@ -2174,10 +2162,13 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int for(i=0;iencoding_needed){ + int changed = ist->st->codec->width != ost->input_video_filter->outputs[0]->w + || ist->st->codec->height != ost->input_video_filter->outputs[0]->h + || ist->st->codec->pix_fmt != ost->input_video_filter->outputs[0]->format; if (!frame_sample_aspect->num) *frame_sample_aspect = ist->st->sample_aspect_ratio; decoded_frame->pts = ist->pts; - if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER) { + if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER && !changed) { FrameBuffer *buf = decoded_frame->opaque; AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( decoded_frame->data, decoded_frame->linesize, @@ -2680,8 +2671,8 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num}; if ( av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH && (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){ - av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n" - "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n"); + av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n" + "Please consider specifying a lower framerate, a different muxer or -vsync 2\n"); } for (j = 0; j < ost->forced_kf_count; j++) ost->forced_kf_pts[j] = av_rescale_q(ost->forced_kf_pts[j], @@ -3118,15 +3109,16 @@ static int transcode(OutputFile *output_files, int nb_output_files, if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) || pkt_dts+1pts){ - av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid droping\n", pkt.dts, ist->next_dts, pkt.stream_index); + av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt.dts, ist->next_dts, pkt.stream_index); pkt.dts = AV_NOPTS_VALUE; } if (pkt.pts != AV_NOPTS_VALUE){ int64_t pkt_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q); delta = pkt_pts - ist->next_dts; if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE || - (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)) { - av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid droping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index); + (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) || + pkt_pts+1pts) { + av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index); pkt.pts = AV_NOPTS_VALUE; } } @@ -3905,7 +3897,7 @@ static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream * } } -static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) +static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index) { OutputStream *ost; AVStream *st = avformat_new_stream(oc, NULL); @@ -4002,6 +3994,14 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags); + + ost->source_index = source_index; + if (source_index >= 0) { + ost->sync_ist = &input_streams[source_index]; + input_streams[source_index].discard = 0; + input_streams[source_index].st->discard = AVDISCARD_NONE; + } + return ost; } @@ -4022,13 +4022,13 @@ static void parse_matrix_coeffs(uint16_t *dest, const char *str) } } -static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) +static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { AVStream *st; OutputStream *ost; AVCodecContext *video_enc; - ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO); + ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index); st = ost->st; video_enc = st->codec; @@ -4153,14 +4153,14 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) return ost; } -static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc) +static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { int n; AVStream *st; OutputStream *ost; AVCodecContext *audio_enc; - ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO); + ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index); st = ost->st; audio_enc = st->codec; @@ -4202,11 +4202,11 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc) return ost; } -static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc) +static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { OutputStream *ost; - ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA); + ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index); if (!ost->stream_copy) { av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n"); exit_program(1); @@ -4215,20 +4215,20 @@ static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc) return ost; } -static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc) +static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { - OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT); + OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index); ost->stream_copy = 1; return ost; } -static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc) +static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index) { AVStream *st; OutputStream *ost; AVCodecContext *subtitle_enc; - ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE); + ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index); st = ost->st; subtitle_enc = st->codec; @@ -4316,7 +4316,7 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch AVCodecContext *avctx; codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id); - ost = new_output_stream(o, s, codec->type); + ost = new_output_stream(o, s, codec->type, -1); st = ost->st; avctx = st->codec; ost->enc = codec; @@ -4388,14 +4388,6 @@ static void opt_output_file(void *optctx, const char *filename) } } else if (!o->nb_stream_maps) { /* pick the "best" stream of each type */ -#define NEW_STREAM(type, index)\ - if (index >= 0) {\ - ost = new_ ## type ## _stream(o, oc);\ - ost->source_index = index;\ - ost->sync_ist = &input_streams[index];\ - input_streams[index].discard = 0;\ - input_streams[index].st->discard = AVDISCARD_NONE;\ - } /* video: highest resolution */ if (!o->video_disable && oc->oformat->video_codec != CODEC_ID_NONE) { @@ -4408,7 +4400,8 @@ static void opt_output_file(void *optctx, const char *filename) idx = i; } } - NEW_STREAM(video, idx); + if (idx >= 0) + new_video_stream(o, oc, idx); } /* audio: most channels */ @@ -4422,14 +4415,15 @@ static void opt_output_file(void *optctx, const char *filename) idx = i; } } - NEW_STREAM(audio, idx); + if (idx >= 0) + new_audio_stream(o, oc, idx); } /* subtitles: pick first */ if (!o->subtitle_disable && (oc->oformat->subtitle_codec != CODEC_ID_NONE || subtitle_codec_name)) { for (i = 0; i < nb_input_streams; i++) if (input_streams[i].st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - NEW_STREAM(subtitle, i); + new_subtitle_stream(o, oc, i); break; } } @@ -4437,6 +4431,7 @@ static void opt_output_file(void *optctx, const char *filename) } else { for (i = 0; i < o->nb_stream_maps; i++) { StreamMap *map = &o->stream_maps[i]; + int src_idx = input_files[map->file_index].ist_index + map->stream_index; if (map->disabled) continue; @@ -4452,22 +4447,16 @@ static void opt_output_file(void *optctx, const char *filename) continue; switch (ist->st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break; - case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break; - case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break; - case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break; - case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break; + case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, src_idx); break; + case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, src_idx); break; + case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc, src_idx); break; + case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc, src_idx); break; + case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break; default: av_log(NULL, AV_LOG_FATAL, "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; - ist->st->discard = AVDISCARD_NONE; } } @@ -4507,9 +4496,8 @@ static void opt_output_file(void *optctx, const char *filename) } avio_read(pb, attachment, len); - ost = new_attachment_stream(o, oc); + ost = new_attachment_stream(o, oc, -1); 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; @@ -5004,6 +4992,15 @@ static int opt_qscale(OptionsContext *o, const char *opt, const char *arg) return ret; } +static int opt_profile(OptionsContext *o, const char *opt, const char *arg) +{ + if(!strcmp(opt, "profile")){ + av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n"); + return parse_option(o, "profile:v", arg, options); + } + return opt_default(opt, arg); +} + static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg) { return parse_option(o, "filter:v", arg, options); @@ -5082,6 +5079,7 @@ static const OptionDef options[] = { { "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" }, { "qscale", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_qscale}, "use fixed quality scale (VBR)", "q" }, + { "profile", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_profile}, "set profile", "profile" }, #if CONFIG_AVFILTER { "filter", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(filters)}, "set stream filterchain", "filter_list" }, #endif