1/* 2 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "libavutil/common.h" 22#include "libavutil/dict.h" 23// #include "libavutil/error.h" 24#include "libavutil/frame.h" 25#include "libavutil/log.h" 26#include "libavutil/mem.h" 27#include "libavutil/opt.h" 28 29#include "avresample.h" 30#include "internal.h" 31#include "audio_data.h" 32#include "audio_convert.h" 33#include "audio_mix.h" 34#include "resample.h" 35 36int avresample_open(AVAudioResampleContext *avr) 37{ 38 int ret; 39 40 if (avresample_is_open(avr)) { 41 av_log(avr, AV_LOG_ERROR, "The resampling context is already open.\n"); 42 return AVERROR(EINVAL); 43 } 44 45 /* set channel mixing parameters */ 46 avr->in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); 47 if (avr->in_channels <= 0 || avr->in_channels > AVRESAMPLE_MAX_CHANNELS) { 48 av_log(avr, AV_LOG_ERROR, "Invalid input channel layout: %"PRIu64"\n", 49 avr->in_channel_layout); 50 return AVERROR(EINVAL); 51 } 52 avr->out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); 53 if (avr->out_channels <= 0 || avr->out_channels > AVRESAMPLE_MAX_CHANNELS) { 54 av_log(avr, AV_LOG_ERROR, "Invalid output channel layout: %"PRIu64"\n", 55 avr->out_channel_layout); 56 return AVERROR(EINVAL); 57 } 58 avr->resample_channels = FFMIN(avr->in_channels, avr->out_channels); 59 avr->downmix_needed = avr->in_channels > avr->out_channels; 60 avr->upmix_needed = avr->out_channels > avr->in_channels || 61 (!avr->downmix_needed && (avr->mix_matrix || 62 avr->in_channel_layout != avr->out_channel_layout)); 63 avr->mixing_needed = avr->downmix_needed || avr->upmix_needed; 64 65 /* set resampling parameters */ 66 avr->resample_needed = avr->in_sample_rate != avr->out_sample_rate || 67 avr->force_resampling; 68 69 /* select internal sample format if not specified by the user */ 70 if (avr->internal_sample_fmt == AV_SAMPLE_FMT_NONE && 71 (avr->mixing_needed || avr->resample_needed)) { 72 enum AVSampleFormat in_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt); 73 enum AVSampleFormat out_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt); 74 int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt), 75 av_get_bytes_per_sample(out_fmt)); 76 if (max_bps <= 2) { 77 avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P; 78 } else if (avr->mixing_needed) { 79 avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP; 80 } else { 81 if (max_bps <= 4) { 82 if (in_fmt == AV_SAMPLE_FMT_S32P || 83 out_fmt == AV_SAMPLE_FMT_S32P) { 84 if (in_fmt == AV_SAMPLE_FMT_FLTP || 85 out_fmt == AV_SAMPLE_FMT_FLTP) { 86 /* if one is s32 and the other is flt, use dbl */ 87 avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP; 88 } else { 89 /* if one is s32 and the other is s32, s16, or u8, use s32 */ 90 avr->internal_sample_fmt = AV_SAMPLE_FMT_S32P; 91 } 92 } else { 93 /* if one is flt and the other is flt, s16 or u8, use flt */ 94 avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP; 95 } 96 } else { 97 /* if either is dbl, use dbl */ 98 avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP; 99 } 100 } 101 av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n", 102 av_get_sample_fmt_name(avr->internal_sample_fmt)); 103 } 104 105 /* we may need to add an extra conversion in order to remap channels if 106 the output format is not planar */ 107 if (avr->use_channel_map && !avr->mixing_needed && !avr->resample_needed && 108 !ff_sample_fmt_is_planar(avr->out_sample_fmt, avr->out_channels)) { 109 avr->internal_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt); 110 } 111 112 /* set sample format conversion parameters */ 113 if (avr->resample_needed || avr->mixing_needed) 114 avr->in_convert_needed = avr->in_sample_fmt != avr->internal_sample_fmt; 115 else 116 avr->in_convert_needed = avr->use_channel_map && 117 !ff_sample_fmt_is_planar(avr->out_sample_fmt, avr->out_channels); 118 119 if (avr->resample_needed || avr->mixing_needed || avr->in_convert_needed) 120 avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt; 121 else 122 avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt; 123 124 avr->in_copy_needed = !avr->in_convert_needed && (avr->mixing_needed || 125 (avr->use_channel_map && avr->resample_needed)); 126 127 if (avr->use_channel_map) { 128 if (avr->in_copy_needed) { 129 avr->remap_point = REMAP_IN_COPY; 130 av_log(avr, AV_LOG_TRACE, "remap channels during in_copy\n"); 131 } else if (avr->in_convert_needed) { 132 avr->remap_point = REMAP_IN_CONVERT; 133 av_log(avr, AV_LOG_TRACE, "remap channels during in_convert\n"); 134 } else if (avr->out_convert_needed) { 135 avr->remap_point = REMAP_OUT_CONVERT; 136 av_log(avr, AV_LOG_TRACE, "remap channels during out_convert\n"); 137 } else { 138 avr->remap_point = REMAP_OUT_COPY; 139 av_log(avr, AV_LOG_TRACE, "remap channels during out_copy\n"); 140 } 141 142#ifdef DEBUG 143 { 144 int ch; 145 av_log(avr, AV_LOG_TRACE, "output map: "); 146 if (avr->ch_map_info.do_remap) 147 for (ch = 0; ch < avr->in_channels; ch++) 148 av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_map[ch]); 149 else 150 av_log(avr, AV_LOG_TRACE, "n/a"); 151 av_log(avr, AV_LOG_TRACE, "\n"); 152 av_log(avr, AV_LOG_TRACE, "copy map: "); 153 if (avr->ch_map_info.do_copy) 154 for (ch = 0; ch < avr->in_channels; ch++) 155 av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_copy[ch]); 156 else 157 av_log(avr, AV_LOG_TRACE, "n/a"); 158 av_log(avr, AV_LOG_TRACE, "\n"); 159 av_log(avr, AV_LOG_TRACE, "zero map: "); 160 if (avr->ch_map_info.do_zero) 161 for (ch = 0; ch < avr->in_channels; ch++) 162 av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.channel_zero[ch]); 163 else 164 av_log(avr, AV_LOG_TRACE, "n/a"); 165 av_log(avr, AV_LOG_TRACE, "\n"); 166 av_log(avr, AV_LOG_TRACE, "input map: "); 167 for (ch = 0; ch < avr->in_channels; ch++) 168 av_log(avr, AV_LOG_TRACE, " % 2d", avr->ch_map_info.input_map[ch]); 169 av_log(avr, AV_LOG_TRACE, "\n"); 170 } 171#endif 172 } else 173 avr->remap_point = REMAP_NONE; 174 175 /* allocate buffers */ 176 if (avr->in_copy_needed || avr->in_convert_needed) { 177 avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels), 178 0, avr->internal_sample_fmt, 179 "in_buffer"); 180 if (!avr->in_buffer) { 181 ret = AVERROR(EINVAL); 182 goto error; 183 } 184 } 185 if (avr->resample_needed) { 186 avr->resample_out_buffer = ff_audio_data_alloc(avr->out_channels, 187 1024, avr->internal_sample_fmt, 188 "resample_out_buffer"); 189 if (!avr->resample_out_buffer) { 190 ret = AVERROR(EINVAL); 191 goto error; 192 } 193 } 194 if (avr->out_convert_needed) { 195 avr->out_buffer = ff_audio_data_alloc(avr->out_channels, 0, 196 avr->out_sample_fmt, "out_buffer"); 197 if (!avr->out_buffer) { 198 ret = AVERROR(EINVAL); 199 goto error; 200 } 201 } 202 avr->out_fifo = av_audio_fifo_alloc(avr->out_sample_fmt, avr->out_channels, 203 1024); 204 if (!avr->out_fifo) { 205 ret = AVERROR(ENOMEM); 206 goto error; 207 } 208 209 /* setup contexts */ 210 if (avr->in_convert_needed) { 211 avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt, 212 avr->in_sample_fmt, avr->in_channels, 213 avr->in_sample_rate, 214 avr->remap_point == REMAP_IN_CONVERT); 215 if (!avr->ac_in) { 216 ret = AVERROR(ENOMEM); 217 goto error; 218 } 219 } 220 if (avr->out_convert_needed) { 221 enum AVSampleFormat src_fmt; 222 if (avr->in_convert_needed) 223 src_fmt = avr->internal_sample_fmt; 224 else 225 src_fmt = avr->in_sample_fmt; 226 avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt, 227 avr->out_channels, 228 avr->out_sample_rate, 229 avr->remap_point == REMAP_OUT_CONVERT); 230 if (!avr->ac_out) { 231 ret = AVERROR(ENOMEM); 232 goto error; 233 } 234 } 235 if (avr->resample_needed) { 236 avr->resample = ff_audio_resample_init(avr); 237 if (!avr->resample) { 238 ret = AVERROR(ENOMEM); 239 goto error; 240 } 241 } 242 if (avr->mixing_needed) { 243 avr->am = ff_audio_mix_alloc(avr); 244 if (!avr->am) { 245 ret = AVERROR(ENOMEM); 246 goto error; 247 } 248 } 249 250 return 0; 251 252error: 253 avresample_close(avr); 254 return ret; 255} 256 257int avresample_is_open(AVAudioResampleContext *avr) 258{ 259 return !!avr->out_fifo; 260} 261 262void avresample_close(AVAudioResampleContext *avr) 263{ 264 ff_audio_data_free(&avr->in_buffer); 265 ff_audio_data_free(&avr->resample_out_buffer); 266 ff_audio_data_free(&avr->out_buffer); 267 av_audio_fifo_free(avr->out_fifo); 268 avr->out_fifo = NULL; 269 ff_audio_convert_free(&avr->ac_in); 270 ff_audio_convert_free(&avr->ac_out); 271 ff_audio_resample_free(&avr->resample); 272 ff_audio_mix_free(&avr->am); 273 av_freep(&avr->mix_matrix); 274 275 avr->use_channel_map = 0; 276} 277 278void avresample_free(AVAudioResampleContext **avr) 279{ 280 if (!*avr) 281 return; 282 avresample_close(*avr); 283 av_opt_free(*avr); 284 av_freep(avr); 285} 286 287static int handle_buffered_output(AVAudioResampleContext *avr, 288 AudioData *output, AudioData *converted) 289{ 290 int ret; 291 292 if (!output || av_audio_fifo_size(avr->out_fifo) > 0 || 293 (converted && output->allocated_samples < converted->nb_samples)) { 294 if (converted) { 295 /* if there are any samples in the output FIFO or if the 296 user-supplied output buffer is not large enough for all samples, 297 we add to the output FIFO */ 298 av_log(avr, AV_LOG_TRACE, "[FIFO] add %s to out_fifo\n", converted->name); 299 ret = ff_audio_data_add_to_fifo(avr->out_fifo, converted, 0, 300 converted->nb_samples); 301 if (ret < 0) 302 return ret; 303 } 304 305 /* if the user specified an output buffer, read samples from the output 306 FIFO to the user output */ 307 if (output && output->allocated_samples > 0) { 308 av_log(avr, AV_LOG_TRACE, "[FIFO] read from out_fifo to output\n"); 309 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 310 return ff_audio_data_read_from_fifo(avr->out_fifo, output, 311 output->allocated_samples); 312 } 313 } else if (converted) { 314 /* copy directly to output if it is large enough or there is not any 315 data in the output FIFO */ 316 av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", converted->name); 317 output->nb_samples = 0; 318 ret = ff_audio_data_copy(output, converted, 319 avr->remap_point == REMAP_OUT_COPY ? 320 &avr->ch_map_info : NULL); 321 if (ret < 0) 322 return ret; 323 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 324 return output->nb_samples; 325 } 326 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 327 return 0; 328} 329 330int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, 331 uint8_t **output, int out_plane_size, 332 int out_samples, 333 uint8_t * const *input, 334 int in_plane_size, int in_samples) 335{ 336 AudioData input_buffer; 337 AudioData output_buffer; 338 AudioData *current_buffer; 339 int ret, direct_output; 340 341 /* reset internal buffers */ 342 if (avr->in_buffer) { 343 avr->in_buffer->nb_samples = 0; 344 ff_audio_data_set_channels(avr->in_buffer, 345 avr->in_buffer->allocated_channels); 346 } 347 if (avr->resample_out_buffer) { 348 avr->resample_out_buffer->nb_samples = 0; 349 ff_audio_data_set_channels(avr->resample_out_buffer, 350 avr->resample_out_buffer->allocated_channels); 351 } 352 if (avr->out_buffer) { 353 avr->out_buffer->nb_samples = 0; 354 ff_audio_data_set_channels(avr->out_buffer, 355 avr->out_buffer->allocated_channels); 356 } 357 358 av_log(avr, AV_LOG_TRACE, "[start conversion]\n"); 359 360 /* initialize output_buffer with output data */ 361 direct_output = output && av_audio_fifo_size(avr->out_fifo) == 0; 362 if (output) { 363 ret = ff_audio_data_init(&output_buffer, output, out_plane_size, 364 avr->out_channels, out_samples, 365 avr->out_sample_fmt, 0, "output"); 366 if (ret < 0) 367 return ret; 368 output_buffer.nb_samples = 0; 369 } 370 371 if (input) { 372 /* initialize input_buffer with input data */ 373 ret = ff_audio_data_init(&input_buffer, input, in_plane_size, 374 avr->in_channels, in_samples, 375 avr->in_sample_fmt, 1, "input"); 376 if (ret < 0) 377 return ret; 378 current_buffer = &input_buffer; 379 380 if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed && 381 !avr->out_convert_needed && direct_output && out_samples >= in_samples) { 382 /* in some rare cases we can copy input to output and upmix 383 directly in the output buffer */ 384 av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", current_buffer->name); 385 ret = ff_audio_data_copy(&output_buffer, current_buffer, 386 avr->remap_point == REMAP_OUT_COPY ? 387 &avr->ch_map_info : NULL); 388 if (ret < 0) 389 return ret; 390 current_buffer = &output_buffer; 391 } else if (avr->remap_point == REMAP_OUT_COPY && 392 (!direct_output || out_samples < in_samples)) { 393 /* if remapping channels during output copy, we may need to 394 * use an intermediate buffer in order to remap before adding 395 * samples to the output fifo */ 396 av_log(avr, AV_LOG_TRACE, "[copy] %s to out_buffer\n", current_buffer->name); 397 ret = ff_audio_data_copy(avr->out_buffer, current_buffer, 398 &avr->ch_map_info); 399 if (ret < 0) 400 return ret; 401 current_buffer = avr->out_buffer; 402 } else if (avr->in_copy_needed || avr->in_convert_needed) { 403 /* if needed, copy or convert input to in_buffer, and downmix if 404 applicable */ 405 if (avr->in_convert_needed) { 406 ret = ff_audio_data_realloc(avr->in_buffer, 407 current_buffer->nb_samples); 408 if (ret < 0) 409 return ret; 410 av_log(avr, AV_LOG_TRACE, "[convert] %s to in_buffer\n", current_buffer->name); 411 ret = ff_audio_convert(avr->ac_in, avr->in_buffer, 412 current_buffer); 413 if (ret < 0) 414 return ret; 415 } else { 416 av_log(avr, AV_LOG_TRACE, "[copy] %s to in_buffer\n", current_buffer->name); 417 ret = ff_audio_data_copy(avr->in_buffer, current_buffer, 418 avr->remap_point == REMAP_IN_COPY ? 419 &avr->ch_map_info : NULL); 420 if (ret < 0) 421 return ret; 422 } 423 ff_audio_data_set_channels(avr->in_buffer, avr->in_channels); 424 if (avr->downmix_needed) { 425 av_log(avr, AV_LOG_TRACE, "[downmix] in_buffer\n"); 426 ret = ff_audio_mix(avr->am, avr->in_buffer); 427 if (ret < 0) 428 return ret; 429 } 430 current_buffer = avr->in_buffer; 431 } 432 } else { 433 /* flush resampling buffer and/or output FIFO if input is NULL */ 434 if (!avr->resample_needed) 435 return handle_buffered_output(avr, output ? &output_buffer : NULL, 436 NULL); 437 current_buffer = NULL; 438 } 439 440 if (avr->resample_needed) { 441 AudioData *resample_out; 442 443 if (!avr->out_convert_needed && direct_output && out_samples > 0) 444 resample_out = &output_buffer; 445 else 446 resample_out = avr->resample_out_buffer; 447 av_log(avr, AV_LOG_TRACE, "[resample] %s to %s\n", 448 current_buffer ? current_buffer->name : "null", 449 resample_out->name); 450 ret = ff_audio_resample(avr->resample, resample_out, 451 current_buffer); 452 if (ret < 0) 453 return ret; 454 455 /* if resampling did not produce any samples, just return 0 */ 456 if (resample_out->nb_samples == 0) { 457 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 458 return 0; 459 } 460 461 current_buffer = resample_out; 462 } 463 464 if (avr->upmix_needed) { 465 av_log(avr, AV_LOG_TRACE, "[upmix] %s\n", current_buffer->name); 466 ret = ff_audio_mix(avr->am, current_buffer); 467 if (ret < 0) 468 return ret; 469 } 470 471 /* if we resampled or upmixed directly to output, return here */ 472 if (current_buffer == &output_buffer) { 473 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 474 return current_buffer->nb_samples; 475 } 476 477 if (avr->out_convert_needed) { 478 if (direct_output && out_samples >= current_buffer->nb_samples) { 479 /* convert directly to output */ 480 av_log(avr, AV_LOG_TRACE, "[convert] %s to output\n", current_buffer->name); 481 ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer); 482 if (ret < 0) 483 return ret; 484 485 av_log(avr, AV_LOG_TRACE, "[end conversion]\n"); 486 return output_buffer.nb_samples; 487 } else { 488 ret = ff_audio_data_realloc(avr->out_buffer, 489 current_buffer->nb_samples); 490 if (ret < 0) 491 return ret; 492 av_log(avr, AV_LOG_TRACE, "[convert] %s to out_buffer\n", current_buffer->name); 493 ret = ff_audio_convert(avr->ac_out, avr->out_buffer, 494 current_buffer); 495 if (ret < 0) 496 return ret; 497 current_buffer = avr->out_buffer; 498 } 499 } 500 501 return handle_buffered_output(avr, output ? &output_buffer : NULL, 502 current_buffer); 503} 504 505int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in) 506{ 507 if (avresample_is_open(avr)) { 508 avresample_close(avr); 509 } 510 511 if (in) { 512 avr->in_channel_layout = in->channel_layout; 513 avr->in_sample_rate = in->sample_rate; 514 avr->in_sample_fmt = in->format; 515 } 516 517 if (out) { 518 avr->out_channel_layout = out->channel_layout; 519 avr->out_sample_rate = out->sample_rate; 520 avr->out_sample_fmt = out->format; 521 } 522 523 return 0; 524} 525 526static int config_changed(AVAudioResampleContext *avr, 527 AVFrame *out, AVFrame *in) 528{ 529 int ret = 0; 530 531 if (in) { 532 if (avr->in_channel_layout != in->channel_layout || 533 avr->in_sample_rate != in->sample_rate || 534 avr->in_sample_fmt != in->format) { 535 ret |= AVERROR_INPUT_CHANGED; 536 } 537 } 538 539 if (out) { 540 if (avr->out_channel_layout != out->channel_layout || 541 avr->out_sample_rate != out->sample_rate || 542 avr->out_sample_fmt != out->format) { 543 ret |= AVERROR_OUTPUT_CHANGED; 544 } 545 } 546 547 return ret; 548} 549 550static inline int convert_frame(AVAudioResampleContext *avr, 551 AVFrame *out, AVFrame *in) 552{ 553 int ret; 554 uint8_t **out_data = NULL, **in_data = NULL; 555 int out_linesize = 0, in_linesize = 0; 556 int out_nb_samples = 0, in_nb_samples = 0; 557 558 if (out) { 559 out_data = out->extended_data; 560 out_linesize = out->linesize[0]; 561 out_nb_samples = out->nb_samples; 562 } 563 564 if (in) { 565 in_data = in->extended_data; 566 in_linesize = in->linesize[0]; 567 in_nb_samples = in->nb_samples; 568 } 569 570 ret = avresample_convert(avr, out_data, out_linesize, 571 out_nb_samples, 572 in_data, in_linesize, 573 in_nb_samples); 574 575 if (ret < 0) { 576 if (out) 577 out->nb_samples = 0; 578 return ret; 579 } 580 581 if (out) 582 out->nb_samples = ret; 583 584 return 0; 585} 586 587static inline int available_samples(AVFrame *out) 588{ 589 int samples; 590 int bytes_per_sample = av_get_bytes_per_sample(out->format); 591 if (!bytes_per_sample) 592 return AVERROR(EINVAL); 593 594 samples = out->linesize[0] / bytes_per_sample; 595 if (av_sample_fmt_is_planar(out->format)) { 596 return samples; 597 } else { 598 int channels = av_get_channel_layout_nb_channels(out->channel_layout); 599 return samples / channels; 600 } 601} 602 603int avresample_convert_frame(AVAudioResampleContext *avr, 604 AVFrame *out, AVFrame *in) 605{ 606 int ret, setup = 0; 607 608 if (!avresample_is_open(avr)) { 609 if ((ret = avresample_config(avr, out, in)) < 0) 610 return ret; 611 if ((ret = avresample_open(avr)) < 0) 612 return ret; 613 setup = 1; 614 } else { 615 // return as is or reconfigure for input changes? 616 if ((ret = config_changed(avr, out, in))) 617 return ret; 618 } 619 620 if (out) { 621 if (!out->linesize[0]) { 622 out->nb_samples = avresample_get_out_samples(avr, in->nb_samples); 623 if ((ret = av_frame_get_buffer(out, 0)) < 0) { 624 if (setup) 625 avresample_close(avr); 626 return ret; 627 } 628 } else { 629 if (!out->nb_samples) 630 out->nb_samples = available_samples(out); 631 } 632 } 633 634 return convert_frame(avr, out, in); 635} 636 637int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, 638 int stride) 639{ 640 int in_channels, out_channels, i, o; 641 642 if (avr->am) 643 return ff_audio_mix_get_matrix(avr->am, matrix, stride); 644 645 in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); 646 out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); 647 648 if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || 649 out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { 650 av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); 651 return AVERROR(EINVAL); 652 } 653 654 if (!avr->mix_matrix) { 655 av_log(avr, AV_LOG_ERROR, "matrix is not set\n"); 656 return AVERROR(EINVAL); 657 } 658 659 for (o = 0; o < out_channels; o++) 660 for (i = 0; i < in_channels; i++) 661 matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i]; 662 663 return 0; 664} 665 666int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, 667 int stride) 668{ 669 int in_channels, out_channels, i, o; 670 671 if (avr->am) 672 return ff_audio_mix_set_matrix(avr->am, matrix, stride); 673 674 in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); 675 out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); 676 677 if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || 678 out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { 679 av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); 680 return AVERROR(EINVAL); 681 } 682 683 if (avr->mix_matrix) 684 av_freep(&avr->mix_matrix); 685 avr->mix_matrix = av_malloc(in_channels * out_channels * 686 sizeof(*avr->mix_matrix)); 687 if (!avr->mix_matrix) 688 return AVERROR(ENOMEM); 689 690 for (o = 0; o < out_channels; o++) 691 for (i = 0; i < in_channels; i++) 692 avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i]; 693 694 return 0; 695} 696 697int avresample_set_channel_mapping(AVAudioResampleContext *avr, 698 const int *channel_map) 699{ 700 ChannelMapInfo *info = &avr->ch_map_info; 701 int in_channels, ch, i; 702 703 in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); 704 if (in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS) { 705 av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n"); 706 return AVERROR(EINVAL); 707 } 708 709 memset(info, 0, sizeof(*info)); 710 memset(info->input_map, -1, sizeof(info->input_map)); 711 712 for (ch = 0; ch < in_channels; ch++) { 713 if (channel_map[ch] >= in_channels) { 714 av_log(avr, AV_LOG_ERROR, "Invalid channel map\n"); 715 return AVERROR(EINVAL); 716 } 717 if (channel_map[ch] < 0) { 718 info->channel_zero[ch] = 1; 719 info->channel_map[ch] = -1; 720 info->do_zero = 1; 721 } else if (info->input_map[channel_map[ch]] >= 0) { 722 info->channel_copy[ch] = info->input_map[channel_map[ch]]; 723 info->channel_map[ch] = -1; 724 info->do_copy = 1; 725 } else { 726 info->channel_map[ch] = channel_map[ch]; 727 info->input_map[channel_map[ch]] = ch; 728 info->do_remap = 1; 729 } 730 } 731 /* Fill-in unmapped input channels with unmapped output channels. 732 This is used when remapping during conversion from interleaved to 733 planar format. */ 734 for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) { 735 while (ch < in_channels && info->input_map[ch] >= 0) 736 ch++; 737 while (i < in_channels && info->channel_map[i] >= 0) 738 i++; 739 if (ch >= in_channels || i >= in_channels) 740 break; 741 info->input_map[ch] = i; 742 } 743 744 avr->use_channel_map = 1; 745 return 0; 746} 747 748int avresample_available(AVAudioResampleContext *avr) 749{ 750 return av_audio_fifo_size(avr->out_fifo); 751} 752 753int avresample_get_out_samples(AVAudioResampleContext *avr, int in_nb_samples) 754{ 755 int64_t samples = avresample_get_delay(avr) + (int64_t)in_nb_samples; 756 757 if (avr->resample_needed) { 758 samples = av_rescale_rnd(samples, 759 avr->out_sample_rate, 760 avr->in_sample_rate, 761 AV_ROUND_UP); 762 } 763 764 samples += avresample_available(avr); 765 766 if (samples > INT_MAX) 767 return AVERROR(EINVAL); 768 769 return samples; 770} 771 772int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples) 773{ 774 if (!output) 775 return av_audio_fifo_drain(avr->out_fifo, nb_samples); 776 return av_audio_fifo_read(avr->out_fifo, (void**)output, nb_samples); 777} 778 779unsigned avresample_version(void) 780{ 781 return LIBAVRESAMPLE_VERSION_INT; 782} 783 784const char *avresample_license(void) 785{ 786#define LICENSE_PREFIX "libavresample license: " 787 return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; 788} 789 790const char *avresample_configuration(void) 791{ 792 return FFMPEG_CONFIGURATION; 793} 794