* commit 'fb1ddcdc8f51b9d261ae8e9c26b91e81f7b6bf45': avresample: Introduce AVFrame-based API Conflicts: libavresample/utils.c libavutil/version.h
Unified · Split
| @@ -15,6 +15,12 @@ libavutil: 2014-08-09 · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | API changes, most recent first: |
| 17 | 17 | |
| 18 | +2014-04-xx - xxxxxxx - lavr 2.1.0 - avresample.h | |
| 19 | + Add avresample_convert_frame() and avresample_config(). | |
| 20 | + | |
| 21 | +2014-04-xx - xxxxxxx - lavu 54.1.0 - error.h | |
| 22 | + Add AVERROR_INPUT_CHANGED and AVERROR_OUTPUT_CHANGED. | |
| 23 | + | |
| 18 | 24 | 2014-08-xx - xxxxxxx - lavc 55.57.4 - avcodec.h |
| 19 | 25 | Deprecate FF_IDCT_XVIDMMX define and xvidmmx idct option. |
| 20 | 26 | Replaced by FF_IDCT_XVID and xvid respectively. |
| @@ -95,6 +95,7 @@ · 94 unmodified lines | ||
| 95 | 95 | #include "libavutil/avutil.h" |
| 96 | 96 | #include "libavutil/channel_layout.h" |
| 97 | 97 | #include "libavutil/dict.h" |
| 98 | +#include "libavutil/frame.h" | |
| 98 | 99 | #include "libavutil/log.h" |
| 99 | 100 | #include "libavutil/mathematics.h" |
| 100 | 101 | |
| @@ -165,6 +166,10 @@ AVAudioResampleContext *avresample_alloc_context(void); · 64 unmodified lines | ||
| 165 | 166 | |
| 166 | 167 | /** |
| 167 | 168 | * Initialize AVAudioResampleContext. |
| 169 | + * @note The context must be configured using the AVOption API. | |
| 170 | + * | |
| 171 | + * @see av_opt_set_int() | |
| 172 | + * @see av_opt_set_dict() | |
| 168 | 173 | * |
| 169 | 174 | * @param avr audio resample context |
| 170 | 175 | * @return 0 on success, negative AVERROR code on failure |
| @@ -422,6 +427,70 @@ int avresample_available(AVAudioResampleContext *avr); · 251 unmodified lines | ||
| 422 | 427 | */ |
| 423 | 428 | int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples); |
| 424 | 429 | |
| 430 | +/** | |
| 431 | + * Convert the samples in the input AVFrame and write them to the output AVFrame. | |
| 432 | + * | |
| 433 | + * Input and output AVFrames must have channel_layout, sample_rate and format set. | |
| 434 | + * | |
| 435 | + * The upper bound on the number of output samples is obtained through | |
| 436 | + * avresample_get_out_samples(). | |
| 437 | + * | |
| 438 | + * If the output AVFrame does not have the data pointers allocated the nb_samples | |
| 439 | + * field will be set using avresample_get_out_samples() and av_frame_get_buffer() | |
| 440 | + * is called to allocate the frame. | |
| 441 | + * | |
| 442 | + * The output AVFrame can be NULL or have fewer allocated samples than required. | |
| 443 | + * In this case, any remaining samples not written to the output will be added | |
| 444 | + * to an internal FIFO buffer, to be returned at the next call to this function | |
| 445 | + * or to avresample_convert() or to avresample_read(). | |
| 446 | + * | |
| 447 | + * If converting sample rate, there may be data remaining in the internal | |
| 448 | + * resampling delay buffer. avresample_get_delay() tells the number of | |
| 449 | + * remaining samples. To get this data as output, call this function or | |
| 450 | + * avresample_convert() with NULL input. | |
| 451 | + * | |
| 452 | + * At the end of the conversion process, there may be data remaining in the | |
| 453 | + * internal FIFO buffer. avresample_available() tells the number of remaining | |
| 454 | + * samples. To get this data as output, either call this function or | |
| 455 | + * avresample_convert() with NULL input or call avresample_read(). | |
| 456 | + * | |
| 457 | + * If the AVAudioResampleContext configuration does not match the output and | |
| 458 | + * input AVFrame settings the conversion does not take place and depending on | |
| 459 | + * which AVFrame is not matching AVERROR_OUTPUT_CHANGED, AVERROR_INPUT_CHANGED | |
| 460 | + * or AVERROR_OUTPUT_CHANGED|AVERROR_INPUT_CHANGED is returned. | |
| 461 | + * | |
| 462 | + * @see avresample_get_out_samples() | |
| 463 | + * @see avresample_available() | |
| 464 | + * @see avresample_convert() | |
| 465 | + * @see avresample_read() | |
| 466 | + * @see avresample_get_delay() | |
| 467 | + * | |
| 468 | + * @param avr audio resample context | |
| 469 | + * @param output output AVFrame | |
| 470 | + * @param input input AVFrame | |
| 471 | + * @return 0 on success, AVERROR on failure or nonmatching | |
| 472 | + * configuration. | |
| 473 | + */ | |
| 474 | +int avresample_convert_frame(AVAudioResampleContext *avr, | |
| 475 | + AVFrame *output, AVFrame *input); | |
| 476 | + | |
| 477 | +/** | |
| 478 | + * Configure or reconfigure the AVAudioResampleContext using the information | |
| 479 | + * provided by the AVFrames. | |
| 480 | + * | |
| 481 | + * The original resampling context is reset even on failure. | |
| 482 | + * The function calls avresample_close() internally if the context is open. | |
| 483 | + * | |
| 484 | + * @see avresample_open(); | |
| 485 | + * @see avresample_close(); | |
| 486 | + * | |
| 487 | + * @param avr audio resample context | |
| 488 | + * @param output output AVFrame | |
| 489 | + * @param input input AVFrame | |
| 490 | + * @return 0 on success, AVERROR on failure. | |
| 491 | + */ | |
| 492 | +int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in); | |
| 493 | + | |
| 425 | 494 | /** |
| 426 | 495 | * @} |
| 427 | 496 | */ |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include "libavutil/common.h" |
| 22 | 22 | #include "libavutil/dict.h" |
| 23 | 23 | // #include "libavutil/error.h" |
| 24 | +#include "libavutil/frame.h" | |
| 24 | 25 | #include "libavutil/log.h" |
| 25 | 26 | #include "libavutil/mem.h" |
| 26 | 27 | #include "libavutil/opt.h" |
| @@ -500,6 +501,135 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, · 473 unmodified lines | ||
| 500 | 501 | current_buffer); |
| 501 | 502 | } |
| 502 | 503 | |
| 504 | +int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in) | |
| 505 | +{ | |
| 506 | + if (avresample_is_open(avr)) { | |
| 507 | + avresample_close(avr); | |
| 508 | + } | |
| 509 | + | |
| 510 | + if (in) { | |
| 511 | + avr->in_channel_layout = in->channel_layout; | |
| 512 | + avr->in_sample_rate = in->sample_rate; | |
| 513 | + avr->in_sample_fmt = in->format; | |
| 514 | + } | |
| 515 | + | |
| 516 | + if (out) { | |
| 517 | + avr->out_channel_layout = out->channel_layout; | |
| 518 | + avr->out_sample_rate = out->sample_rate; | |
| 519 | + avr->out_sample_fmt = out->format; | |
| 520 | + } | |
| 521 | + | |
| 522 | + return 0; | |
| 523 | +} | |
| 524 | + | |
| 525 | +static int config_changed(AVAudioResampleContext *avr, | |
| 526 | + AVFrame *out, AVFrame *in) | |
| 527 | +{ | |
| 528 | + int ret = 0; | |
| 529 | + | |
| 530 | + if (in) { | |
| 531 | + if (avr->in_channel_layout != in->channel_layout || | |
| 532 | + avr->in_sample_rate != in->sample_rate || | |
| 533 | + avr->in_sample_fmt != in->format) { | |
| 534 | + ret |= AVERROR_INPUT_CHANGED; | |
| 535 | + } | |
| 536 | + } | |
| 537 | + | |
| 538 | + if (out) { | |
| 539 | + if (avr->out_channel_layout != out->channel_layout || | |
| 540 | + avr->out_sample_rate != out->sample_rate || | |
| 541 | + avr->out_sample_fmt != out->format) { | |
| 542 | + ret |= AVERROR_OUTPUT_CHANGED; | |
| 543 | + } | |
| 544 | + } | |
| 545 | + | |
| 546 | + return ret; | |
| 547 | +} | |
| 548 | + | |
| 549 | +static inline int convert_frame(AVAudioResampleContext *avr, | |
| 550 | + AVFrame *out, AVFrame *in) | |
| 551 | +{ | |
| 552 | + int ret; | |
| 553 | + uint8_t **out_data = NULL, **in_data = NULL; | |
| 554 | + int out_linesize = 0, in_linesize = 0; | |
| 555 | + int out_nb_samples = 0, in_nb_samples = 0; | |
| 556 | + | |
| 557 | + if (out) { | |
| 558 | + out_data = out->extended_data; | |
| 559 | + out_linesize = out->linesize[0]; | |
| 560 | + out_nb_samples = out->nb_samples; | |
| 561 | + } | |
| 562 | + | |
| 563 | + if (in) { | |
| 564 | + in_data = in->extended_data; | |
| 565 | + in_linesize = in->linesize[0]; | |
| 566 | + in_nb_samples = in->nb_samples; | |
| 567 | + } | |
| 568 | + | |
| 569 | + ret = avresample_convert(avr, out_data, out_linesize, | |
| 570 | + out_nb_samples, | |
| 571 | + in_data, in_linesize, | |
| 572 | + in_nb_samples); | |
| 573 | + | |
| 574 | + if (ret < 0) { | |
| 575 | + if (out) | |
| 576 | + out->nb_samples = 0; | |
| 577 | + return ret; | |
| 578 | + } | |
| 579 | + | |
| 580 | + if (out) | |
| 581 | + out->nb_samples = ret; | |
| 582 | + | |
| 583 | + return 0; | |
| 584 | +} | |
| 585 | + | |
| 586 | +static inline int available_samples(AVFrame *out) | |
| 587 | +{ | |
| 588 | + int bytes_per_sample = av_get_bytes_per_sample(out->format); | |
| 589 | + int samples = out->linesize[0] / bytes_per_sample; | |
| 590 | + | |
| 591 | + if (av_sample_fmt_is_planar(out->format)) { | |
| 592 | + return samples; | |
| 593 | + } else { | |
| 594 | + int channels = av_get_channel_layout_nb_channels(out->channel_layout); | |
| 595 | + return samples / channels; | |
| 596 | + } | |
| 597 | +} | |
| 598 | + | |
| 599 | +int avresample_convert_frame(AVAudioResampleContext *avr, | |
| 600 | + AVFrame *out, AVFrame *in) | |
| 601 | +{ | |
| 602 | + int ret, setup = 0; | |
| 603 | + | |
| 604 | + if (!avresample_is_open(avr)) { | |
| 605 | + if ((ret = avresample_config(avr, out, in)) < 0) | |
| 606 | + return ret; | |
| 607 | + if ((ret = avresample_open(avr)) < 0) | |
| 608 | + return ret; | |
| 609 | + setup = 1; | |
| 610 | + } else { | |
| 611 | + // return as is or reconfigure for input changes? | |
| 612 | + if ((ret = config_changed(avr, out, in))) | |
| 613 | + return ret; | |
| 614 | + } | |
| 615 | + | |
| 616 | + if (out) { | |
| 617 | + if (!out->linesize[0]) { | |
| 618 | + out->nb_samples = avresample_get_out_samples(avr, in->nb_samples); | |
| 619 | + if ((ret = av_frame_get_buffer(out, 0)) < 0) { | |
| 620 | + if (setup) | |
| 621 | + avresample_close(avr); | |
| 622 | + return ret; | |
| 623 | + } | |
| 624 | + } else { | |
| 625 | + if (!out->nb_samples) | |
| 626 | + out->nb_samples = available_samples(out); | |
| 627 | + } | |
| 628 | + } | |
| 629 | + | |
| 630 | + return convert_frame(avr, out, in); | |
| 631 | +} | |
| 632 | + | |
| 503 | 633 | int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix, |
| 504 | 634 | int stride) |
| 505 | 635 | { |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include "libavutil/version.h" |
| 29 | 29 | |
| 30 | 30 | #define LIBAVRESAMPLE_VERSION_MAJOR 2 |
| 31 | −#define LIBAVRESAMPLE_VERSION_MINOR 0 | |
| 31 | +#define LIBAVRESAMPLE_VERSION_MINOR 1 | |
| 32 | 32 | #define LIBAVRESAMPLE_VERSION_MICRO 0 |
| 33 | 33 | |
| 34 | 34 | #define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \ |
| @@ -70,6 +70,8 @@ · 69 unmodified lines | ||
| 70 | 70 | #define AVERROR_BUG2 FFERRTAG( 'B','U','G',' ') |
| 71 | 71 | #define AVERROR_UNKNOWN FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library |
| 72 | 72 | #define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it. |
| 73 | +#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED) | |
| 74 | +#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED) | |
| 73 | 75 | |
| 74 | 76 | #define AV_ERROR_MAX_STRING_SIZE 64 |
| 75 | 77 | |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | */ |
| 57 | 57 | |
| 58 | 58 | #define LIBAVUTIL_VERSION_MAJOR 54 |
| 59 | −#define LIBAVUTIL_VERSION_MINOR 0 | |
| 59 | +#define LIBAVUTIL_VERSION_MINOR 1 | |
| 60 | 60 | #define LIBAVUTIL_VERSION_MICRO 100 |
| 61 | 61 | |
| 62 | 62 | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |