diff options
Diffstat (limited to 'ffmpeg.c')
-rw-r--r-- | ffmpeg.c | 96 |
1 files changed, 95 insertions, 1 deletions
@@ -1282,7 +1282,7 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost, swr_set_compensation(ost->swr, comp, enc->sample_rate); } } - } else + } else if (audio_sync_method == 0) ost->sync_opts = lrintf(get_sync_ipts(ost, ist->pts) * enc->sample_rate) - av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong @@ -2328,10 +2328,57 @@ static void print_sdp(OutputFile *output_files, int n) av_freep(&avc); } +static void get_default_channel_layouts(OutputStream *ost, InputStream *ist) +{ + char layout_name[256]; + AVCodecContext *enc = ost->st->codec; + AVCodecContext *dec = ist->st->codec; + + if (!dec->channel_layout) { + if (enc->channel_layout && dec->channels == enc->channels) { + dec->channel_layout = enc->channel_layout; + } else { + dec->channel_layout = av_get_default_channel_layout(dec->channels); + + if (!dec->channel_layout) { + av_log(NULL, AV_LOG_FATAL, "Unable to find default channel " + "layout for Input Stream #%d.%d\n", ist->file_index, + ist->st->index); + exit_program(1); + } + } + av_get_channel_layout_string(layout_name, sizeof(layout_name), + dec->channels, dec->channel_layout); + av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Input Stream " + "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name); + } + if (!enc->channel_layout) { + if (dec->channels == enc->channels) { + enc->channel_layout = dec->channel_layout; + return; + } else { + enc->channel_layout = av_get_default_channel_layout(enc->channels); + } + if (!enc->channel_layout) { + av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout " + "for Output Stream #%d.%d\n", ost->file_index, + ost->st->index); + exit_program(1); + } + av_get_channel_layout_string(layout_name, sizeof(layout_name), + enc->channels, enc->channel_layout); + av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream " + "#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name); + } +} + + static int init_input_stream(int ist_index, OutputStream *output_streams, int nb_output_streams, char *error, int error_len) { InputStream *ist = &input_streams[ist_index]; + int i; + if (ist->decoding_needed) { AVCodec *codec = ist->dec; if (!codec) { @@ -2356,6 +2403,17 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb } assert_codec_experimental(ist->st->codec, 0); assert_avoptions(ist->opts); + + if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = &output_streams[i]; + if (ost->source_index == ist_index) { + if (!ist->st->codec->channel_layout || !ost->st->codec->channel_layout) + get_default_channel_layouts(ost, ist); + break; + } + } + } } ist->dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; @@ -4943,6 +5001,41 @@ static void parse_cpuflags(int argc, char **argv, const OptionDef *options) opt_cpuflags("cpuflags", argv[idx + 1]); } +static int opt_channel_layout(OptionsContext *o, const char *opt, const char *arg) +{ + char layout_str[32]; + char *stream_str; + char *ac_str; + int ret, channels, ac_str_size; + uint64_t layout; + + layout = av_get_channel_layout(arg); + if (!layout) { + av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg); + return AVERROR(EINVAL); + } + snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout); + ret = opt_default(opt, layout_str); + if (ret < 0) + return ret; + + /* set 'ac' option based on channel layout */ + channels = av_get_channel_layout_nb_channels(layout); + snprintf(layout_str, sizeof(layout_str), "%d", channels); + stream_str = strchr(opt, ':'); + ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0); + ac_str = av_mallocz(ac_str_size); + if (!ac_str) + return AVERROR(ENOMEM); + av_strlcpy(ac_str, "ac", 3); + if (stream_str) + av_strlcat(ac_str, stream_str, ac_str_size); + ret = parse_option(o, ac_str, layout_str, options); + av_free(ac_str); + + return ret; +} + #define OFFSET(x) offsetof(OptionsContext, x) static const OptionDef options[] = { /* main options */ @@ -5051,6 +5144,7 @@ static const OptionDef options[] = { { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, // { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_SPEC | OPT_STRING, {.off = OFFSET(sample_fmts)}, "set sample format", "format" }, { "rmvol", HAS_ARG | OPT_AUDIO | OPT_FLOAT | OPT_SPEC, {.off = OFFSET(rematrix_volume)}, "rematrix volume (as factor)", "volume" }, + { "channel_layout", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_FUNC2, {(void*)opt_channel_layout}, "set channel layout", "layout" }, /* subtitle options */ { "sn", OPT_BOOL | OPT_SUBTITLE | OPT_OFFSET, {.off = OFFSET(subtitle_disable)}, "disable subtitle" }, |