diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-07-13 00:42:11 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-07-13 00:42:11 +0200 |
commit | bb258fb995a42112d1fe14f53ec599b2cd19b707 (patch) | |
tree | d7152f06fcff2c66509c57a5dd906ca225069ae1 /ffmpeg.c | |
parent | 896e59758a11ff645879098b5ebca2e753731b4e (diff) | |
parent | 2cb6dec61c8e6676105de628ba20a5b3d162976e (diff) | |
download | ffmpeg-bb258fb995a42112d1fe14f53ec599b2cd19b707.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
doc: Improve references to external URLs.
h264: move decode_mb_skip() from h264.h to h.264_mvpred.h
ffplay: skip return value of avcodec_decode_video2 / avcodec_decode_subtitle2
dnxhdenc: Replace a forward declaration by the proper #include.
h264: move h264_mvpred.h include.
pix_fmt: Fix number of bits per component in yuv444p9be
lavf: deprecate AVFormatContext.timestamp
ffmpeg: merge input_files_ts_scale into InputStream.
ffmpeg: don't abuse a global for passing sample format from input to output
ffmpeg: don't abuse a global for passing channel layout from input to output
ffmpeg: factor common code from new_a/v/s/d_stream to new_output_stream()
matroskaenc: make SSA default subtitle codec.
oggdec: prevent heap corruption.
Conflicts:
doc/developer.texi
doc/faq.texi
doc/general.texi
ffmpeg.c
ffplay.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 131 |
1 files changed, 57 insertions, 74 deletions
@@ -117,8 +117,8 @@ static const OptionDef options[]; #define MAX_STREAMS 1024 /* arbitrary sanity check value */ static const char *last_asked_format = NULL; -static double *input_files_ts_scale[MAX_FILES] = {NULL}; -static int nb_input_files_ts_scale[MAX_FILES] = {0}; +static double *ts_scale; +static int nb_ts_scale; static AVFormatContext *output_files[MAX_FILES]; static int nb_output_files = 0; @@ -171,7 +171,6 @@ static char *vfilters = NULL; static int intra_only = 0; static int audio_sample_rate = 0; -static int64_t channel_layout = 0; #define QSCALE_NONE -99999 static float audio_qscale = QSCALE_NONE; static int audio_disable = 0; @@ -194,7 +193,6 @@ static float mux_max_delay= 0.7; static int64_t recording_time = INT64_MAX; static int64_t start_time = 0; -static int64_t recording_timestamp = 0; static int64_t input_ts_offset = 0; static int file_overwrite = 0; static AVDictionary *metadata; @@ -327,6 +325,7 @@ typedef struct InputStream { int64_t next_pts; /* synthetic pts for cases where pkt.pts is not defined */ int64_t pts; /* current pts */ + double ts_scale; int is_start; /* is 1 at the start and after a discontinuity */ int showed_multi_packet_warning; int is_past_recording_time; @@ -538,7 +537,6 @@ static int ffmpeg_exit(int ret) } for(i=0;i<nb_input_files;i++) { av_close_input_file(input_files[i].ctx); - av_free(input_files_ts_scale[i]); } av_free(intra_matrix); @@ -671,10 +669,16 @@ static void choose_pixel_fmt(AVStream *st, AVCodec *codec) } } -static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx) +static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCodec *codec) { - int idx = oc->nb_streams - 1; 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"); + ffmpeg_exit(1); + } output_streams_for_file[file_idx] = grow_array(output_streams_for_file[file_idx], @@ -689,6 +693,10 @@ static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx) } ost->file_index = file_idx; ost->index = idx; + ost->st = st; + ost->enc = codec; + + avcodec_get_context_defaults3(st->codec, codec); ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL); return ost; @@ -704,28 +712,21 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) if (err < 0) return err; /* copy stream format */ - s->nb_streams = 0; - s->streams = av_mallocz(sizeof(AVStream *) * ic->nb_streams); for(i=0;i<ic->nb_streams;i++) { AVStream *st; + OutputStream *ost; AVCodec *codec; - s->nb_streams++; + codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id); + ost = new_output_stream(s, nb_output_files, codec); + st = ost->st; // FIXME: a more elegant solution is needed - st = av_mallocz(sizeof(AVStream)); memcpy(st, ic->streams[i], sizeof(AVStream)); st->info = av_malloc(sizeof(*st->info)); memcpy(st->info, ic->streams[i]->info, sizeof(*st->info)); - st->codec = avcodec_alloc_context(); - if (!st->codec) { - print_error(filename, AVERROR(ENOMEM)); - ffmpeg_exit(1); - } avcodec_copy_context(st->codec, ic->streams[i]->codec); - s->streams[i] = st; - codec = avcodec_find_encoder(st->codec->codec_id); if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (audio_stream_copy) { st->stream_copy = 1; @@ -740,13 +741,8 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename) if(st->codec->flags & CODEC_FLAG_BITEXACT) nopts = 1; - - new_output_stream(s, nb_output_files); } - if (!nopts) - s->timestamp = av_gettime(); - av_close_input_file(ic); return 0; } @@ -2102,7 +2098,6 @@ static int transcode(AVFormatContext **output_files, for(i=0;i<os->nb_streams;i++,n++) { int found; ost = ost_table[n] = output_streams_for_file[k][i]; - ost->st = os->streams[i]; if (nb_stream_maps > 0) { ost->source_index = input_files[stream_maps[n].file_index].ist_index + stream_maps[n].stream_index; @@ -2278,6 +2273,9 @@ static int transcode(AVFormatContext **output_files, } choose_sample_rate(ost->st, ost->enc); codec->time_base = (AVRational){1, codec->sample_rate}; + if (codec->sample_fmt == AV_SAMPLE_FMT_NONE) + codec->sample_fmt = icodec->sample_fmt; + choose_sample_fmt(ost->st, ost->enc); if (!codec->channels) { codec->channels = icodec->channels; codec->channel_layout = icodec->channel_layout; @@ -2738,12 +2736,11 @@ static int transcode(AVFormatContext **output_files, if (pkt.pts != AV_NOPTS_VALUE) pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt.stream_index < nb_input_files_ts_scale[file_index] - && input_files_ts_scale[file_index][pkt.stream_index]){ + if (ist->ts_scale) { if(pkt.pts != AV_NOPTS_VALUE) - pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index]; + pkt.pts *= ist->ts_scale; if(pkt.dts != AV_NOPTS_VALUE) - pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index]; + pkt.dts *= ist->ts_scale; } // fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files[ist->file_index].ts_offset, ist->st->codec->codec_type); @@ -3203,8 +3200,8 @@ static int opt_input_ts_scale(const char *opt, const char *arg) if(stream >= MAX_STREAMS) ffmpeg_exit(1); - 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; + ts_scale = grow_array(ts_scale, sizeof(*ts_scale), &nb_ts_scale, stream + 1); + ts_scale[stream] = scale; return 0; } @@ -3222,7 +3219,14 @@ static int opt_start_time(const char *opt, const char *arg) static int opt_recording_timestamp(const char *opt, const char *arg) { - recording_timestamp = parse_time_or_die(opt, arg, 0) / 1000000; + char buf[128]; + int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6; + struct tm time = *gmtime((time_t*)&recording_timestamp); + strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time); + opt_metadata("metadata", buf); + + av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata " + "tag instead.\n", opt); return 0; } @@ -3401,14 +3405,15 @@ static int opt_input_file(const char *opt, const char *filename) ist->file_index = nb_input_files; ist->discard = 1; + if (i < nb_ts_scale) + ist->ts_scale = ts_scale[i]; + switch (dec->codec_type) { case AVMEDIA_TYPE_AUDIO: ist->dec = avcodec_find_decoder_by_name(audio_codec_name); if(!ist->dec) ist->dec = 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, ist->dec); - channel_layout = dec->channel_layout; - audio_sample_fmt = dec->sample_fmt; if(audio_disable) st->discard= AVDISCARD_ALL; break; @@ -3475,6 +3480,9 @@ static int opt_input_file(const char *opt, const char *filename) frame_width = 0; audio_sample_rate = 0; audio_channels = 0; + audio_sample_fmt = AV_SAMPLE_FMT_NONE; + av_freep(&ts_scale); + nb_ts_scale = 0; av_freep(&video_codec_name); av_freep(&audio_codec_name); @@ -3535,23 +3543,20 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) enum CodecID codec_id = CODEC_ID_NONE; AVCodec *codec= NULL; - 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); - 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); - ost->enc = codec; } else { codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); codec = avcodec_find_encoder(codec_id); } + } + + ost = new_output_stream(oc, file_idx, codec); + st = ost->st; + if (!video_stream_copy) { ost->frame_aspect_ratio = frame_aspect_ratio; frame_aspect_ratio = 0; #if CONFIG_AVFILTER @@ -3560,7 +3565,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) #endif } - avcodec_get_context_defaults3(st->codec, codec); ost->bitstream_filters = video_bitstream_filters; video_bitstream_filters= NULL; @@ -3674,26 +3678,18 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) AVCodecContext *audio_enc; enum CodecID codec_id = CODEC_ID_NONE; - 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); - 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); - ost->enc = 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); + ost = new_output_stream(oc, file_idx, codec); + st = ost->st; ost->bitstream_filters = audio_bitstream_filters; audio_bitstream_filters= NULL; @@ -3722,11 +3718,10 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) } if (audio_channels) audio_enc->channels = audio_channels; - audio_enc->sample_fmt = audio_sample_fmt; + 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; - audio_enc->channel_layout = channel_layout; - choose_sample_fmt(st, codec); } if (audio_language) { av_dict_set(&st->metadata, "language", audio_language, 0); @@ -3742,21 +3737,16 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) static void new_data_stream(AVFormatContext *oc, int file_idx) { AVStream *st; - AVCodec *codec=NULL; + OutputStream *ost; 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); - } - new_output_stream(oc, file_idx); + ost = new_output_stream(oc, file_idx, NULL); + st = ost->st; data_enc = st->codec; 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; @@ -3784,25 +3774,19 @@ static void new_subtitle_stream(AVFormatContext *oc, int file_idx) AVCodecContext *subtitle_enc; enum CodecID codec_id = CODEC_ID_NONE; - 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); - subtitle_enc = st->codec; 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 = avcodec_find_encoder_by_name(subtitle_codec_name); - ost->enc = codec; } 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); + ost = new_output_stream(oc, file_idx, codec); + st = ost->st; + subtitle_enc = st->codec; ost->bitstream_filters = subtitle_bitstream_filters; subtitle_bitstream_filters= NULL; @@ -3938,8 +3922,6 @@ static int opt_output_file(const char *opt, const char *filename) if (use_subtitle) new_subtitle_stream(oc, nb_output_files); if (use_data) new_data_stream(oc, nb_output_files); - oc->timestamp = recording_timestamp; - av_dict_copy(&oc->metadata, metadata, 0); av_dict_free(&metadata); } @@ -4005,6 +3987,7 @@ static int opt_output_file(const char *opt, const char *filename) frame_height = 0; audio_sample_rate = 0; audio_channels = 0; + audio_sample_fmt = AV_SAMPLE_FMT_NONE; av_freep(&forced_key_frames); uninit_opts(); |