Unified · Split
| @@ -69,6 +69,28 @@ typedef struct { · 68 unmodified lines | |||
| 69 | return AVERROR(EINVAL);\ | 69 | return AVERROR(EINVAL);\ |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static int insert_filter(BufferSourceContext *abuffer, | ||
| 73 | AVFilterLink *link, AVFilterContext **filt_ctx, | ||
| 74 | const char *filt_name); | ||
| 75 | static void remove_filter(AVFilterContext **filt_ctx); | ||
| 76 | static int reconfigure_filter(BufferSourceContext *abuffer, AVFilterContext *filt_ctx); | ||
| 77 | |||
| 78 | static inline void log_input_change(void *ctx, AVFilterLink *link, AVFilterBufferRef *ref) | ||
| 79 | { | ||
| 80 | char old_layout_str[16], new_layout_str[16]; | ||
| 81 | av_get_channel_layout_string(old_layout_str, sizeof(old_layout_str), | ||
| 82 | -1, link->channel_layout); | ||
| 83 | av_get_channel_layout_string(new_layout_str, sizeof(new_layout_str), | ||
| 84 | -1, ref->audio->channel_layout); | ||
| 85 | av_log(ctx, AV_LOG_INFO, | ||
| 86 | "Audio input format changed: " | ||
| 87 | "%s:%s:%d -> %s:%s:%d, normalizing\n", | ||
| 88 | av_get_sample_fmt_name(link->format), | ||
| 89 | old_layout_str, (int)link->sample_rate, | ||
| 90 | av_get_sample_fmt_name(ref->format), | ||
| 91 | new_layout_str, ref->audio->sample_rate); | ||
| 92 | } | ||
| 93 | |||
| 72 | static int check_format_change_video(AVFilterContext *buffer_filter, | 94 | static int check_format_change_video(AVFilterContext *buffer_filter, |
| 73 | AVFilterBufferRef *picref) | 95 | AVFilterBufferRef *picref) |
| 74 | { | 96 | { |
| @@ -122,12 +144,72 @@ static int check_format_change_video(AVFilterContext *buffer_filter, · 47 unmodified lines | |||
| 122 | return 0; | 144 | return 0; |
| 123 | } | 145 | } |
| 124 | 146 | ||
| 147 | static int check_format_change_audio(AVFilterContext *ctx, | ||
| 148 | AVFilterBufferRef *samplesref) | ||
| 149 | { | ||
| 150 | BufferSourceContext *abuffer = ctx->priv; | ||
| 151 | AVFilterLink *link; | ||
| 152 | int ret, logged = 0; | ||
| 153 | |||
| 154 | link = ctx->outputs[0]; | ||
| 155 | if (samplesref->audio->sample_rate != link->sample_rate) { | ||
| 156 | |||
| 157 | log_input_change(ctx, link, samplesref); | ||
| 158 | logged = 1; | ||
| 159 | |||
| 160 | abuffer->sample_rate = samplesref->audio->sample_rate; | ||
| 161 | |||
| 162 | if (!abuffer->aresample) { | ||
| 163 | ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample"); | ||
| 164 | if (ret < 0) return ret; | ||
| 165 | } else { | ||
| 166 | link = abuffer->aresample->outputs[0]; | ||
| 167 | if (samplesref->audio->sample_rate == link->sample_rate) | ||
| 168 | remove_filter(&abuffer->aresample); | ||
| 169 | else | ||
| 170 | if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0) | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | link = ctx->outputs[0]; | ||
| 176 | if (samplesref->format != link->format || | ||
| 177 | samplesref->audio->channel_layout != link->channel_layout || | ||
| 178 | samplesref->audio->planar != link->planar) { | ||
| 179 | |||
| 180 | if (!logged) log_input_change(ctx, link, samplesref); | ||
| 181 | |||
| 182 | abuffer->sample_format = samplesref->format; | ||
| 183 | abuffer->channel_layout = samplesref->audio->channel_layout; | ||
| 184 | abuffer->packing_format = samplesref->audio->planar; | ||
| 185 | |||
| 186 | if (!abuffer->aconvert) { | ||
| 187 | ret = insert_filter(abuffer, link, &abuffer->aconvert, "aconvert"); | ||
| 188 | if (ret < 0) return ret; | ||
| 189 | } else { | ||
| 190 | link = abuffer->aconvert->outputs[0]; | ||
| 191 | if (samplesref->format == link->format && | ||
| 192 | samplesref->audio->channel_layout == link->channel_layout && | ||
| 193 | samplesref->audio->planar == link->planar | ||
| 194 | ) | ||
| 195 | remove_filter(&abuffer->aconvert); | ||
| 196 | else | ||
| 197 | if ((ret = reconfigure_filter(abuffer, abuffer->aconvert)) < 0) | ||
| 198 | return ret; | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 125 | static int check_format_change(AVFilterContext *buffer_filter, | 205 | static int check_format_change(AVFilterContext *buffer_filter, |
| 126 | AVFilterBufferRef *picref) | 206 | AVFilterBufferRef *picref) |
| 127 | { | 207 | { |
| 128 | switch (buffer_filter->outputs[0]->type) { | 208 | switch (buffer_filter->outputs[0]->type) { |
| 129 | case AVMEDIA_TYPE_VIDEO: | 209 | case AVMEDIA_TYPE_VIDEO: |
| 130 | return check_format_change_video(buffer_filter, picref); | 210 | return check_format_change_video(buffer_filter, picref); |
| 211 | case AVMEDIA_TYPE_AUDIO: | ||
| 212 | return check_format_change_audio(buffer_filter, picref); | ||
| 131 | default: | 213 | default: |
| 132 | return AVERROR(ENOSYS); | 214 | return AVERROR(ENOSYS); |
| 133 | } | 215 | } |
| @@ -484,29 +566,12 @@ static void remove_filter(AVFilterContext **filt_ctx) · 350 unmodified lines | |||
| 484 | set_link_source(src, outlink); | 566 | set_link_source(src, outlink); |
| 485 | } | 567 | } |
| 486 | 568 | ||
| 487 | static inline void log_input_change(void *ctx, AVFilterLink *link, AVFilterBufferRef *ref) | ||
| 488 | { | ||
| 489 | char old_layout_str[16], new_layout_str[16]; | ||
| 490 | av_get_channel_layout_string(old_layout_str, sizeof(old_layout_str), | ||
| 491 | -1, link->channel_layout); | ||
| 492 | av_get_channel_layout_string(new_layout_str, sizeof(new_layout_str), | ||
| 493 | -1, ref->audio->channel_layout); | ||
| 494 | av_log(ctx, AV_LOG_INFO, | ||
| 495 | "Audio input format changed: " | ||
| 496 | "%s:%s:%d -> %s:%s:%d, normalizing\n", | ||
| 497 | av_get_sample_fmt_name(link->format), | ||
| 498 | old_layout_str, (int)link->sample_rate, | ||
| 499 | av_get_sample_fmt_name(ref->format), | ||
| 500 | new_layout_str, ref->audio->sample_rate); | ||
| 501 | } | ||
| 502 | |||
| 503 | int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx, | 569 | int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx, |
| 504 | AVFilterBufferRef *samplesref, | 570 | AVFilterBufferRef *samplesref, |
| 505 | int av_unused flags) | 571 | int av_unused flags) |
| 506 | { | 572 | { |
| 507 | BufferSourceContext *abuffer = ctx->priv; | 573 | BufferSourceContext *abuffer = ctx->priv; |
| 508 | AVFilterLink *link; | 574 | int ret; |
| 509 | int ret, logged = 0; | ||
| 510 | 575 | ||
| 511 | if (av_fifo_space(abuffer->fifo) < sizeof(samplesref)) { | 576 | if (av_fifo_space(abuffer->fifo) < sizeof(samplesref)) { |
| 512 | av_log(ctx, AV_LOG_ERROR, | 577 | av_log(ctx, AV_LOG_ERROR, |
| @@ -515,55 +580,9 @@ int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx, · 2 unmodified lines | |||
| 515 | return AVERROR(EINVAL); | 580 | return AVERROR(EINVAL); |
| 516 | } | 581 | } |
| 517 | 582 | ||
| 518 | // Normalize input | 583 | ret = check_format_change(ctx, samplesref); |
| 519 | 584 | if (ret < 0) | |
| 520 | link = ctx->outputs[0]; | 585 | return ret; |
| 521 | if (samplesref->audio->sample_rate != link->sample_rate) { | ||
| 522 | |||
| 523 | log_input_change(ctx, link, samplesref); | ||
| 524 | logged = 1; | ||
| 525 | |||
| 526 | abuffer->sample_rate = samplesref->audio->sample_rate; | ||
| 527 | |||
| 528 | if (!abuffer->aresample) { | ||
| 529 | ret = insert_filter(abuffer, link, &abuffer->aresample, "aresample"); | ||
| 530 | if (ret < 0) return ret; | ||
| 531 | } else { | ||
| 532 | link = abuffer->aresample->outputs[0]; | ||
| 533 | if (samplesref->audio->sample_rate == link->sample_rate) | ||
| 534 | remove_filter(&abuffer->aresample); | ||
| 535 | else | ||
| 536 | if ((ret = reconfigure_filter(abuffer, abuffer->aresample)) < 0) | ||
| 537 | return ret; | ||
| 538 | } | ||
| 539 | } | ||
| 540 | |||
| 541 | link = ctx->outputs[0]; | ||
| 542 | if (samplesref->format != link->format || | ||
| 543 | samplesref->audio->channel_layout != link->channel_layout || | ||
| 544 | samplesref->audio->planar != link->planar) { | ||
| 545 | |||
| 546 | if (!logged) log_input_change(ctx, link, samplesref); | ||
| 547 | |||
| 548 | abuffer->sample_format = samplesref->format; | ||
| 549 | abuffer->channel_layout = samplesref->audio->channel_layout; | ||
| 550 | abuffer->packing_format = samplesref->audio->planar; | ||
| 551 | |||
| 552 | if (!abuffer->aconvert) { | ||
| 553 | ret = insert_filter(abuffer, link, &abuffer->aconvert, "aconvert"); | ||
| 554 | if (ret < 0) return ret; | ||
| 555 | } else { | ||
| 556 | link = abuffer->aconvert->outputs[0]; | ||
| 557 | if (samplesref->format == link->format && | ||
| 558 | samplesref->audio->channel_layout == link->channel_layout && | ||
| 559 | samplesref->audio->planar == link->planar | ||
| 560 | ) | ||
| 561 | remove_filter(&abuffer->aconvert); | ||
| 562 | else | ||
| 563 | if ((ret = reconfigure_filter(abuffer, abuffer->aconvert)) < 0) | ||
| 564 | return ret; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | 586 | ||
| 568 | if (sizeof(samplesref) != av_fifo_generic_write(abuffer->fifo, &samplesref, | 587 | if (sizeof(samplesref) != av_fifo_generic_write(abuffer->fifo, &samplesref, |
| 569 | sizeof(samplesref), NULL)) { | 588 | sizeof(samplesref), NULL)) { |