This patch contains the following commits: avplay: Support the new channel layout API
avconv: Support the new channel layout API tools: Update to the new channel layout API examples: Update to the new channel layout API --- avtools/avconv.c | 30 +++++++------------------- avtools/avconv.h | 8 +++---- avtools/avconv_filter.c | 44 ++++++++++++++++++++++++++++++-------- avtools/avconv_opt.c | 48 ++++++++++++++++++++++++------------------ avtools/avplay.c | 50 +++++++++++++++++++++++--------------------- avtools/cmdutils.c | 15 +++++++++++-- avtools/cmdutils.h | 8 ------- doc/examples/decode_audio.c | 2 +- doc/examples/encode_audio.c | 36 ++++++++++++++++++------------- doc/examples/filter_audio.c | 11 +++++----- doc/examples/output.c | 30 ++++++++++++++++++-------- doc/examples/transcode_aac.c | 29 +++++++++++++++---------- tools/graph2dot.c | 7 +++---- tools/ismindex.c | 2 +- tools/sidxindex.c | 2 +- 15 files changed, 185 insertions(+), 137 deletions(-) diff --git a/avtools/avconv.c b/avtools/avconv.c index a1427e0cb4..904ea82de8 100644 --- a/avtools/avconv.c +++ b/avtools/avconv.c @@ -163,7 +163,7 @@ static void avconv_cleanup(int ret) for (j = 0; j < fg->nb_outputs; j++) { av_freep(&fg->outputs[j]->name); av_freep(&fg->outputs[j]->formats); - av_freep(&fg->outputs[j]->channel_layouts); + av_freep(&fg->outputs[j]->ch_layouts); av_freep(&fg->outputs[j]->sample_rates); av_freep(&fg->outputs[j]); } @@ -1209,7 +1209,8 @@ static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame) switch (ifilter->ist->st->codecpar->codec_type) { case AVMEDIA_TYPE_AUDIO: need_reinit |= ifilter->sample_rate != frame->sample_rate || - ifilter->channel_layout != frame->ch_layout.u.mask; + av_channel_layout_compare(&ifilter->ch_layout, + &frame->ch_layout); break; case AVMEDIA_TYPE_VIDEO: need_reinit |= ifilter->width != frame->width || @@ -1322,24 +1323,6 @@ static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacke return 0; } -int guess_input_channel_layout(InputStream *ist) -{ - AVCodecContext *dec = ist->dec_ctx; - - if (!dec->channel_layout) { - char layout_name[256]; - - dec->channel_layout = av_get_default_channel_layout(dec->channels); - if (!dec->channel_layout) - return 0; - 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); - } - return 1; -} - static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output, int *decode_failed) { @@ -1982,6 +1965,7 @@ static int init_output_stream_encode(OutputStream *ost) InputStream *ist = get_input_stream(ost); AVCodecContext *enc_ctx = ost->enc_ctx; AVCodecContext *dec_ctx = NULL; + int ret; set_encoder_id(output_files[ost->file_index], ost); @@ -1998,8 +1982,10 @@ static int init_output_stream_encode(OutputStream *ost) case AVMEDIA_TYPE_AUDIO: enc_ctx->sample_fmt = ost->filter->filter->inputs[0]->format; enc_ctx->sample_rate = ost->filter->filter->inputs[0]->sample_rate; - enc_ctx->channel_layout = ost->filter->filter->inputs[0]->ch_layout.u.mask; - enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout); + ret = av_channel_layout_copy(&enc_ctx->ch_layout, + &ost->filter->filter->inputs[0]->ch_layout); + if (ret < 0) + return ret; enc_ctx->time_base = (AVRational){ 1, enc_ctx->sample_rate }; break; case AVMEDIA_TYPE_VIDEO: diff --git a/avtools/avconv.h b/avtools/avconv.h index 4c699333a5..2d3a77ba65 100644 --- a/avtools/avconv.h +++ b/avtools/avconv.h @@ -220,7 +220,7 @@ typedef struct InputFilter { AVRational sample_aspect_ratio; int sample_rate; - uint64_t channel_layout; + AVChannelLayout ch_layout; AVBufferRef *hw_frames_ctx; @@ -242,11 +242,11 @@ typedef struct OutputFilter { AVRational frame_rate; int format; int sample_rate; - uint64_t channel_layout; + AVChannelLayout ch_layout; // those are only set if no format is specified and the encoder gives us multiple options int *formats; - uint64_t *channel_layouts; + AVChannelLayout *ch_layouts; int *sample_rates; } OutputFilter; @@ -499,8 +499,6 @@ void opt_output_file(void *optctx, const char *filename); void assert_avoptions(AVDictionary *m); -int guess_input_channel_layout(InputStream *ist); - int configure_filtergraph(FilterGraph *fg); int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out); int ist_in_filtergraph(FilterGraph *fg, InputStream *ist); diff --git a/avtools/avconv_filter.c b/avtools/avconv_filter.c index 7df64c647a..30e95a23a5 100644 --- a/avtools/avconv_filter.c +++ b/avtools/avconv_filter.c @@ -73,8 +73,30 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats, DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0, GET_SAMPLE_RATE_NAME) -DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0, - GET_CH_LAYOUT_NAME) +static char *choose_channel_layouts(OutputFilter *ofilter) +{ + if (av_channel_layout_check(&ofilter->ch_layout)) { + return av_channel_layout_describe(&ofilter->ch_layout); + } else if (ofilter->ch_layouts) { + const AVChannelLayout *p; + AVIOContext *s = NULL; + uint8_t *ret; + int len; + + if (avio_open_dyn_buf(&s) < 0) + exit(1); + + for (p = ofilter->ch_layouts; av_channel_layout_check(p); p++) { + char *chlstr = av_channel_layout_describe(p); + avio_printf(s, "%s|", chlstr); + av_free(chlstr); + } + len = avio_close_dyn_buf(s, &ret); + ret[len - 1] = 0; + return ret; + } else + return NULL; +} int init_simple_filtergraph(InputStream *ist, OutputStream *ost) { @@ -391,7 +413,6 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, { OutputStream *ost = ofilter->ost; OutputFile *of = output_files[ost->file_index]; - AVCodecContext *codec = ost->enc_ctx; AVFilterContext *last_filter = out->filter_ctx; int pad_idx = out->pad_idx; char *sample_fmts, *sample_rates, *channel_layouts; @@ -406,9 +427,6 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, if (ret < 0) return ret; - if (codec->channels && !codec->channel_layout) - codec->channel_layout = av_get_default_channel_layout(codec->channels); - sample_fmts = choose_sample_fmts(ofilter); sample_rates = choose_sample_rates(ofilter); channel_layouts = choose_channel_layouts(ofilter); @@ -591,7 +609,9 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, par->time_base = (AVRational){ 1, ifilter->sample_rate }; par->sample_rate = ifilter->sample_rate; par->format = ifilter->format; - av_channel_layout_from_mask(&par->ch_layout, ifilter->channel_layout); + ret = av_channel_layout_copy(&par->ch_layout, &ifilter->ch_layout); + if (ret < 0) + return ret; ret = av_buffersrc_parameters_set(ifilter->filter, par); av_freep(&par); @@ -758,7 +778,9 @@ int configure_filtergraph(FilterGraph *fg) ofilter->height = link->h; ofilter->sample_rate = link->sample_rate; - ofilter->channel_layout = link->ch_layout.u.mask; + ret = av_channel_layout_copy(&ofilter->ch_layout, &link->ch_layout); + if (ret < 0) + return ret; } for (i = 0; i < fg->nb_inputs; i++) { @@ -789,6 +811,8 @@ fail: int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) { + int ret; + av_buffer_unref(&ifilter->hw_frames_ctx); ifilter->format = frame->format; @@ -798,7 +822,9 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame) ifilter->sample_aspect_ratio = frame->sample_aspect_ratio; ifilter->sample_rate = frame->sample_rate; - ifilter->channel_layout = frame->ch_layout.u.mask; + ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout); + if (ret < 0) + return ret; if (frame->hw_frames_ctx) { ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx); diff --git a/avtools/avconv_opt.c b/avtools/avconv_opt.c index 9076b74e38..27373fe1f8 100644 --- a/avtools/avconv_opt.c +++ b/avtools/avconv_opt.c @@ -662,8 +662,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) break; case AVMEDIA_TYPE_AUDIO: - guess_input_channel_layout(ist); - break; case AVMEDIA_TYPE_DATA: case AVMEDIA_TYPE_SUBTITLE: case AVMEDIA_TYPE_ATTACHMENT: @@ -1414,7 +1412,17 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc) if (!ost->stream_copy) { char *sample_fmt = NULL; - MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st); + { + int i, ret; + for (i = 0; i < o->nb_audio_channels; i++) { + char *spec = o->audio_channels[i].specifier; + if ((ret = check_stream_specifier(oc, st, spec)) > 0) + av_channel_layout_default(&audio_enc->ch_layout, + o->audio_channels[i].u.i); + else if (ret < 0) + exit_program(1); + } + } MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st); if (sample_fmt && @@ -1930,17 +1938,18 @@ loop_end: memcpy(f->sample_rates, ost->enc->supported_samplerates, (count + 1) * sizeof(*f->sample_rates)); } - if (ost->enc_ctx->channels) { - f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels); - } else if (ost->enc->channel_layouts) { + if (av_channel_layout_check(&ost->enc_ctx->ch_layout)) { + av_channel_layout_copy(&f->ch_layout, &ost->enc_ctx->ch_layout); + } else if (ost->enc->ch_layouts) { count = 0; - while (ost->enc->channel_layouts[count]) + while (av_channel_layout_check(&ost->enc->ch_layouts[count])) count++; - f->channel_layouts = av_mallocz_array(count + 1, sizeof(*f->channel_layouts)); - if (!f->channel_layouts) + f->ch_layouts = av_mallocz_array(count + 1, sizeof(*f->ch_layouts)); + if (!f->ch_layouts) exit_program(1); - memcpy(f->channel_layouts, ost->enc->channel_layouts, - (count + 1) * sizeof(*f->channel_layouts)); + // TODO use av_channel_layout_copy? + memcpy(f->ch_layouts, ost->enc->ch_layouts, + (count + 1) * sizeof(*f->ch_layouts)); } break; } @@ -2300,22 +2309,21 @@ static int opt_channel_layout(void *optctx, 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; + int ret, ac_str_size; + AVChannelLayout ch_layout = {0}; - layout = av_get_channel_layout(arg); - if (!layout) { + ret = av_channel_layout_from_string(&ch_layout, arg); + if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg); - return AVERROR(EINVAL); + return ret; } - snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout); - ret = opt_default(NULL, opt, layout_str); + snprintf(layout_str, sizeof(layout_str), "%s", arg); + ret = opt_default(NULL, "ch_layout", 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); + snprintf(layout_str, sizeof(layout_str), "%d", ch_layout.nb_channels); stream_str = strchr(opt, ':'); ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0); ac_str = av_mallocz(ac_str_size); diff --git a/avtools/avplay.c b/avtools/avplay.c index 544c5dd4a1..183890d798 100644 --- a/avtools/avplay.c +++ b/avtools/avplay.c @@ -160,11 +160,10 @@ typedef struct PlayerState { AVPacket audio_pkt_temp; AVPacket audio_pkt; enum AVSampleFormat sdl_sample_fmt; - uint64_t sdl_channel_layout; - int sdl_channels; + AVChannelLayout sdl_ch_layout; int sdl_sample_rate; enum AVSampleFormat resample_sample_fmt; - uint64_t resample_channel_layout; + AVChannelLayout resample_ch_layout; int resample_sample_rate; AVAudioResampleContext *avr; AVFrame *frame; @@ -721,7 +720,7 @@ static void video_audio_display(PlayerState *s) nb_freq = 1 << (rdft_bits - 1); /* compute display index : center on currently output samples */ - channels = s->sdl_channels; + channels = s->sdl_ch_layout.nb_channels; nb_display_channels = channels; if (!s->paused) { int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq); @@ -930,7 +929,7 @@ static double get_audio_clock(PlayerState *is) hw_buf_size = audio_write_get_buf_size(is); bytes_per_sec = 0; if (is->audio_st) { - bytes_per_sec = is->sdl_sample_rate * is->sdl_channels * + bytes_per_sec = is->sdl_sample_rate * is->sdl_ch_layout.nb_channels * av_get_bytes_per_sample(is->sdl_sample_fmt); } if (bytes_per_sec) @@ -1725,7 +1724,7 @@ static int synchronize_audio(PlayerState *is, short *samples, int n, samples_size; double ref_clock; - n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt); + n = is->sdl_ch_layout.nb_channels * av_get_bytes_per_sample(is->sdl_sample_fmt); samples_size = samples_size1; /* if not master, then we try to remove or add samples to correct the clock */ @@ -1832,16 +1831,18 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) flush_complete = 1; continue; } - data_size = av_samples_get_buffer_size(NULL, dec->channels, + data_size = av_samples_get_buffer_size(NULL, dec->ch_layout.nb_channels, is->frame->nb_samples, is->frame->format, 1); audio_resample = is->frame->format != is->sdl_sample_fmt || - is->frame->ch_layout.u.mask != is->sdl_channel_layout || + av_channel_layout_compare(&is->frame->ch_layout, + &is->sdl_ch_layout) || is->frame->sample_rate != is->sdl_sample_rate; resample_changed = is->frame->format != is->resample_sample_fmt || - is->frame->ch_layout.u.mask != is->resample_channel_layout || + av_channel_layout_compare(&is->frame->ch_layout, + &is->resample_ch_layout) || is->frame->sample_rate != is->resample_sample_rate; if ((!is->avr && audio_resample) || resample_changed) { @@ -1856,10 +1857,10 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) } } if (audio_resample) { - av_opt_set_int(is->avr, "in_channel_layout", is->frame->channel_layout, 0); + av_opt_set_channel_layout(is->avr, "in_ch_layout", &is->frame->ch_layout, 0); av_opt_set_int(is->avr, "in_sample_fmt", is->frame->format, 0); av_opt_set_int(is->avr, "in_sample_rate", is->frame->sample_rate, 0); - av_opt_set_int(is->avr, "out_channel_layout", is->sdl_channel_layout, 0); + av_opt_set_channel_layout(is->avr, "out_ch_layout", &is->sdl_ch_layout, 0); av_opt_set_int(is->avr, "out_sample_fmt", is->sdl_sample_fmt, 0); av_opt_set_int(is->avr, "out_sample_rate", is->sdl_sample_rate, 0); @@ -1869,7 +1870,9 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) } } is->resample_sample_fmt = is->frame->format; - is->resample_channel_layout = is->frame->channel_layout; + ret = av_channel_layout_copy(&is->resample_ch_layout, &is->frame->ch_layout); + if (ret < 0) + break; is->resample_sample_rate = is->frame->sample_rate; } @@ -1880,7 +1883,7 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) int nb_samples = is->frame->nb_samples; out_size = av_samples_get_buffer_size(&out_linesize, - is->sdl_channels, + is->sdl_ch_layout.nb_channels, nb_samples, is->sdl_sample_fmt, 0); tmp_out = av_realloc(is->audio_buf1, out_size); @@ -1899,7 +1902,7 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) break; } is->audio_buf = is->audio_buf1; - data_size = out_samples * osize * is->sdl_channels; + data_size = out_samples * osize * is->sdl_ch_layout.nb_channels; } else { is->audio_buf = is->frame->data[0]; } @@ -1907,7 +1910,7 @@ static int audio_decode_frame(PlayerState *is, double *pts_ptr) /* if no pts, then compute it */ pts = is->audio_clock; *pts_ptr = pts; - n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt); + n = is->sdl_ch_layout.nb_channels * av_get_bytes_per_sample(is->sdl_sample_fmt); is->audio_clock += (double)data_size / (double)(n * is->sdl_sample_rate); #ifdef DEBUG @@ -2085,22 +2088,19 @@ static int stream_component_open(PlayerState *is, int stream_index) if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { is->sdl_sample_rate = avctx->sample_rate; - if (!avctx->channel_layout) - avctx->channel_layout = av_get_default_channel_layout(avctx->channels); - if (!avctx->channel_layout) { + if (!av_channel_layout_check(&avctx->ch_layout)) { fprintf(stderr, "unable to guess channel layout\n"); ret = AVERROR_INVALIDDATA; goto fail; } - if (avctx->channels == 1) - is->sdl_channel_layout = AV_CH_LAYOUT_MONO; + if (avctx->ch_layout.nb_channels == 1) + is->sdl_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; else - is->sdl_channel_layout = AV_CH_LAYOUT_STEREO; - is->sdl_channels = av_get_channel_layout_nb_channels(is->sdl_channel_layout); + is->sdl_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; wanted_spec.format = AUDIO_S16SYS; wanted_spec.freq = is->sdl_sample_rate; - wanted_spec.channels = is->sdl_channels; + wanted_spec.channels = is->sdl_ch_layout.nb_channels; wanted_spec.silence = 0; wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; wanted_spec.callback = sdl_audio_callback; @@ -2113,7 +2113,9 @@ static int stream_component_open(PlayerState *is, int stream_index) is->audio_hw_buf_size = spec.size; is->sdl_sample_fmt = AV_SAMPLE_FMT_S16; is->resample_sample_fmt = is->sdl_sample_fmt; - is->resample_channel_layout = avctx->channel_layout; + ret = av_channel_layout_copy(&is->resample_ch_layout, &avctx->ch_layout); + if (ret < 0) + goto fail; is->resample_sample_rate = avctx->sample_rate; } diff --git a/avtools/cmdutils.c b/avtools/cmdutils.c index 9d6a2b9f2b..238045f6b7 100644 --- a/avtools/cmdutils.c +++ b/avtools/cmdutils.c @@ -1038,8 +1038,19 @@ static void print_codec(const AVCodec *c) GET_SAMPLE_RATE_NAME); PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats", AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME); - PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts", - 0, GET_CH_LAYOUT_DESC); + + if (c->ch_layouts) { + const AVChannelLayout *p = c->ch_layouts; + + printf(" Supported channel layouts:"); + while (!av_channel_layout_check(p)) { + char *chlstr = av_channel_layout_describe(p); + printf(" %s", chlstr); + av_free(chlstr); + p++; + } + printf("\n"); + } if (c->priv_class) { show_help_children(c->priv_class, diff --git a/avtools/cmdutils.h b/avtools/cmdutils.h index cc78ac5911..2389435a79 100644 --- a/avtools/cmdutils.h +++ b/avtools/cmdutils.h @@ -555,12 +555,4 @@ const char *media_type_string(enum AVMediaType media_type); char name[16];\ snprintf(name, sizeof(name), "%d", rate); -#define GET_CH_LAYOUT_NAME(ch_layout)\ - char name[16];\ - snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout); - -#define GET_CH_LAYOUT_DESC(ch_layout)\ - char name[128];\ - av_get_channel_layout_string(name, sizeof(name), 0, ch_layout); - #endif /* LIBAV_CMDUTILS_H */ diff --git a/doc/examples/decode_audio.c b/doc/examples/decode_audio.c index d952b4923b..ec933ea11c 100644 --- a/doc/examples/decode_audio.c +++ b/doc/examples/decode_audio.c @@ -63,7 +63,7 @@ static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, /* the stream parameters may change at any time, check that they are * what we expect */ - if (av_get_channel_layout_nb_channels(frame->channel_layout) != 2 || + if (frame->ch_layout.nb_channels != 2 || frame->format != AV_SAMPLE_FMT_S16P) { fprintf(stderr, "Unsupported frame parameters\n"); exit(1); diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c index a32fcc9004..b941fb5352 100644 --- a/doc/examples/encode_audio.c +++ b/doc/examples/encode_audio.c @@ -67,26 +67,27 @@ static int select_sample_rate(const AVCodec *codec) } /* select layout with the highest channel count */ -static int select_channel_layout(const AVCodec *codec) +static int select_channel_layout(AVCodecContext *ctx, const AVCodec *codec) { - const uint64_t *p; - uint64_t best_ch_layout = 0; - int best_nb_channels = 0; + const AVChannelLayout *p; + int ret, best_nb_channels = 0; - if (!codec->channel_layouts) + if (!codec->ch_layouts) return AV_CH_LAYOUT_STEREO; - p = codec->channel_layouts; - while (*p) { - int nb_channels = av_get_channel_layout_nb_channels(*p); + p = codec->ch_layouts; + while (av_channel_layout_check(p)) { + int nb_channels = (*p).nb_channels; if (nb_channels > best_nb_channels) { - best_ch_layout = *p; best_nb_channels = nb_channels; + ret = av_channel_layout_copy(&ctx->ch_layout, p); + if (ret < 0) + return ret; } p++; } - return best_ch_layout; + return 0; } static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, @@ -160,8 +161,11 @@ int main(int argc, char **argv) /* select other audio parameters supported by the encoder */ c->sample_rate = select_sample_rate(codec); - c->channel_layout = select_channel_layout(codec); - c->channels = av_get_channel_layout_nb_channels(c->channel_layout); + ret = select_channel_layout(c, codec); + if (ret < 0) { + fprintf(stderr, "failed to select best channel layout\n"); + exit(1); + } /* open it */ if (avcodec_open2(c, codec, NULL) < 0) { @@ -191,7 +195,11 @@ int main(int argc, char **argv) frame->nb_samples = c->frame_size; frame->format = c->sample_fmt; - frame->channel_layout = c->channel_layout; + ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout); + if (ret < 0) { + fprintf(stderr, "could not copy channel layout in audio frame\n"); + exit(1); + } /* allocate the data buffers */ ret = av_frame_get_buffer(frame, 0); @@ -214,7 +222,7 @@ int main(int argc, char **argv) for (j = 0; j < c->frame_size; j++) { samples[2*j] = (int)(sin(t) * 10000); - for (k = 1; k < c->channels; k++) + for (k = 1; k < c->ch_layout.nb_channels; k++) samples[2*j + k] = samples[2*j]; t += tincr; } diff --git a/doc/examples/filter_audio.c b/doc/examples/filter_audio.c index 458004355f..cfd6470984 100644 --- a/doc/examples/filter_audio.c +++ b/doc/examples/filter_audio.c @@ -55,7 +55,7 @@ #define INPUT_SAMPLERATE 48000 #define INPUT_FORMAT AV_SAMPLE_FMT_FLTP -#define INPUT_CHANNEL_LAYOUT AV_CH_LAYOUT_5POINT0 +#define INPUT_CHANNEL_LAYOUT (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0 #define VOLUME_VAL 0.90 @@ -74,7 +74,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src, AVDictionary *options_dict = NULL; uint8_t options_str[1024]; - uint8_t ch_layout[64]; + AVChannelLayout ch_layout = INPUT_CHANNEL_LAYOUT; int err; @@ -100,8 +100,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src, } /* Set the filter options through the AVOptions API. */ - av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, INPUT_CHANNEL_LAYOUT); - av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN); + av_opt_set_channel_layout(abuffer_ctx, "ch_layout", &ch_layout, AV_OPT_SEARCH_CHILDREN); av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN); av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN); av_opt_set_int(abuffer_ctx, "sample_rate", INPUT_SAMPLERATE, AV_OPT_SEARCH_CHILDREN); @@ -215,7 +214,7 @@ static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src, static int process_output(struct AVMD5 *md5, AVFrame *frame) { int planar = av_sample_fmt_is_planar(frame->format); - int channels = av_get_channel_layout_nb_channels(frame->channel_layout); + int channels = frame->ch_layout.nb_channels; int planes = planar ? channels : 1; int bps = av_get_bytes_per_sample(frame->format); int plane_size = bps * frame->nb_samples * (planar ? 1 : channels); @@ -248,7 +247,7 @@ static int get_input(AVFrame *frame, int frame_num) /* Set up the frame properties and allocate the buffer for the data. */ frame->sample_rate = INPUT_SAMPLERATE; frame->format = INPUT_FORMAT; - frame->channel_layout = INPUT_CHANNEL_LAYOUT; + frame->ch_layout = INPUT_CHANNEL_LAYOUT; frame->nb_samples = FRAME_SIZE; frame->pts = frame_num * FRAME_SIZE; diff --git a/doc/examples/output.c b/doc/examples/output.c index 59e7b95d17..85ac37170b 100644 --- a/doc/examples/output.c +++ b/doc/examples/output.c @@ -77,6 +77,8 @@ static void add_audio_stream(OutputStream *ost, AVFormatContext *oc, { AVCodecContext *c; AVCodec *codec; + AVChannelLayout ch_layout; + static AVChannelLayout stereo = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; int ret; /* find the audio encoder */ @@ -99,12 +101,17 @@ static void add_audio_stream(OutputStream *ost, AVFormatContext *oc, } ost->enc = c; + ch_layout = codec->ch_layouts ? codec->ch_layouts[0] : stereo; + /* put sample parameters */ c->sample_fmt = codec->sample_fmts ? codec->sample_fmts[0] : AV_SAMPLE_FMT_S16; c->sample_rate = codec->supported_samplerates ? codec->supported_samplerates[0] : 44100; - c->channel_layout = codec->channel_layouts ? codec->channel_layouts[0] : AV_CH_LAYOUT_STEREO; - c->channels = av_get_channel_layout_nb_channels(c->channel_layout); c->bit_rate = 64000; + ret = av_channel_layout_copy(&c->ch_layout, &ch_layout); + if (ret < 0) { + fprintf(stderr, "Could not copy channel layout\n"); + exit(1); + } ost->st->time_base = (AVRational){ 1, c->sample_rate }; @@ -125,10 +132,10 @@ static void add_audio_stream(OutputStream *ost, AVFormatContext *oc, av_opt_set_int(ost->avr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(ost->avr, "in_sample_rate", 44100, 0); - av_opt_set_int(ost->avr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0); + av_opt_set_channel_layout(ost->avr, "in_ch_layout", &stereo, 0); av_opt_set_int(ost->avr, "out_sample_fmt", c->sample_fmt, 0); av_opt_set_int(ost->avr, "out_sample_rate", c->sample_rate, 0); - av_opt_set_int(ost->avr, "out_channel_layout", c->channel_layout, 0); + av_opt_set_channel_layout(ost->avr, "out_ch_layout", &c->ch_layout, 0); ret = avresample_open(ost->avr); if (ret < 0) { @@ -138,7 +145,7 @@ static void add_audio_stream(OutputStream *ost, AVFormatContext *oc, } static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, - uint64_t channel_layout, + AVChannelLayout *ch_layout, int sample_rate, int nb_samples) { AVFrame *frame = av_frame_alloc(); @@ -150,9 +157,13 @@ static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, } frame->format = sample_fmt; - frame->channel_layout = channel_layout; frame->sample_rate = sample_rate; frame->nb_samples = nb_samples; + ret = av_channel_layout_copy(&frame->ch_layout, ch_layout); + if (ret < 0) { + fprintf(stderr, "Error copying a channel layout in an audio frame\n"); + exit(1); + } if (nb_samples) { ret = av_frame_get_buffer(frame, 0); @@ -169,6 +180,7 @@ static void open_audio(AVFormatContext *oc, OutputStream *ost) { AVCodecContext *c; int nb_samples, ret; + static AVChannelLayout stereo = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; c = ost->enc; @@ -189,9 +201,9 @@ static void open_audio(AVFormatContext *oc, OutputStream *ost) else nb_samples = c->frame_size; - ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout, + ost->frame = alloc_audio_frame(c->sample_fmt, &c->ch_layout, c->sample_rate, nb_samples); - ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, AV_CH_LAYOUT_STEREO, + ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &stereo, 44100, nb_samples); /* copy the stream parameters to the muxer */ @@ -218,7 +230,7 @@ static AVFrame *get_audio_frame(OutputStream *ost) for (j = 0; j < frame->nb_samples; j++) { v = (int)(sin(ost->t) * 10000); - for (i = 0; i < ost->enc->channels; i++) + for (i = 0; i < ost->enc->ch_layout.nb_channels; i++) *q++ = v; ost->t += ost->tincr; ost->tincr += ost->tincr2; diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c index 44d5af6b04..5ee4056c8e 100644 --- a/doc/examples/transcode_aac.c +++ b/doc/examples/transcode_aac.c @@ -207,8 +207,7 @@ static int open_output_file(const char *filename, /* Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ - avctx->channels = OUTPUT_CHANNELS; - avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS); + av_channel_layout_default(&avctx->ch_layout, OUTPUT_CHANNELS); avctx->sample_rate = input_codec_context->sample_rate; avctx->sample_fmt = output_codec->sample_fmts[0]; avctx->bit_rate = OUTPUT_BIT_RATE; @@ -293,7 +292,8 @@ static int init_resampler(AVCodecContext *input_codec_context, /* Only initialize the resampler if it is necessary, i.e., * if and only if the sample formats differ. */ if (input_codec_context->sample_fmt != output_codec_context->sample_fmt || - input_codec_context->channels != output_codec_context->channels) { + av_channel_layout_compare(&input_codec_context->ch_layout, + &output_codec_context->ch_layout)) { int error; /* Create a resampler context for the conversion. */ @@ -307,10 +307,10 @@ static int init_resampler(AVCodecContext *input_codec_context, * are assumed for simplicity (they are sometimes not detected * properly by the demuxer and/or decoder). */ - av_opt_set_int(*resample_context, "in_channel_layout", - av_get_default_channel_layout(input_codec_context->channels), 0); - av_opt_set_int(*resample_context, "out_channel_layout", - av_get_default_channel_layout(output_codec_context->channels), 0); + av_opt_set_channel_layout(*resample_context, "in_ch_layout", + &input_codec_context->ch_layout, 0); + av_opt_set_channel_layout(*resample_context, "out_ch_layout", + &output_codec_context->ch_layout, 0); av_opt_set_int(*resample_context, "in_sample_rate", input_codec_context->sample_rate, 0); av_opt_set_int(*resample_context, "out_sample_rate", @@ -340,7 +340,7 @@ static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context) { /* Create the FIFO buffer based on the specified output sample format. */ if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt, - output_codec_context->channels, 1))) { + output_codec_context->ch_layout.nb_channels, 1))) { fprintf(stderr, "Could not allocate FIFO\n"); return AVERROR(ENOMEM); } @@ -440,7 +440,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples, * Each pointer will later point to the audio samples of the corresponding * channels (although it may be NULL for interleaved formats). */ - if (!(*converted_input_samples = calloc(output_codec_context->channels, + if (!(*converted_input_samples = calloc(output_codec_context->ch_layout.nb_channels, sizeof(**converted_input_samples)))) { fprintf(stderr, "Could not allocate converted input sample pointers\n"); return AVERROR(ENOMEM); @@ -449,7 +449,7 @@ static int init_converted_samples(uint8_t ***converted_input_samples, /* Allocate memory for the samples of all channels in one consecutive * block for convenience. */ if ((error = av_samples_alloc(*converted_input_samples, NULL, - output_codec_context->channels, + output_codec_context->ch_layout.nb_channels, frame_size, output_codec_context->sample_fmt, 0)) < 0) { fprintf(stderr, @@ -630,9 +630,16 @@ static int init_output_frame(AVFrame **frame, * Default channel layouts based on the number of channels * are assumed for simplicity. */ (*frame)->nb_samples = frame_size; - (*frame)->channel_layout = output_codec_context->channel_layout; (*frame)->format = output_codec_context->sample_fmt; (*frame)->sample_rate = output_codec_context->sample_rate; + error = av_channel_layout_copy(&(*frame)->ch_layout, + &output_codec_context->ch_layout); + if (error < 0) { + fprintf(stderr, "Could not copy channel layout (error '%s')\n", + get_error_text(error)); + av_frame_free(frame); + return error; + } /* Allocate the samples of the created frame. This call will make * sure that the audio frame can hold as many samples as specified. */ diff --git a/tools/graph2dot.c b/tools/graph2dot.c index fbf8902146..9a48208a6c 100644 --- a/tools/graph2dot.c +++ b/tools/graph2dot.c @@ -86,13 +86,12 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph) desc->name, link->w, link->h, link->time_base.num, link->time_base.den); } else if (link->type == AVMEDIA_TYPE_AUDIO) { - char buf[255]; - av_get_channel_layout_string(buf, sizeof(buf), -1, - link->channel_layout); + char *chlstr = av_channel_layout_describe(&link->ch_layout); fprintf(outfile, " [ label= \"fmt:%s sr:%d cl:%s\" ]", av_get_sample_fmt_name(link->format), - link->sample_rate, buf); + link->sample_rate, chlstr); + av_free(chlstr); } fprintf(outfile, ";\n"); } diff --git a/tools/ismindex.c b/tools/ismindex.c index 3d7e082b6d..5127e3a3cd 100644 --- a/tools/ismindex.c +++ b/tools/ismindex.c @@ -571,7 +571,7 @@ static int handle_file(struct Tracks *tracks, const char *file, int split, if (tracks->audio_track < 0) tracks->audio_track = tracks->nb_tracks; tracks->nb_audio_tracks++; - track->channels = st->codecpar->channels; + track->channels = st->codecpar->ch_layout.nb_channels; track->sample_rate = st->codecpar->sample_rate; if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { track->fourcc = "AACL"; diff --git a/tools/sidxindex.c b/tools/sidxindex.c index e740a94b98..4724321e30 100644 --- a/tools/sidxindex.c +++ b/tools/sidxindex.c @@ -191,7 +191,7 @@ static int handle_file(struct Tracks *tracks, const char *file) track->timescale, AV_ROUND_UP)); if (track->is_audio) { - track->channels = st->codecpar->channels; + track->channels = st->codecpar->ch_layout.nb_channels; track->sample_rate = st->codecpar->sample_rate; } if (track->is_video) { -- 2.13.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel