History

avresample: Introduce AVFrame-based API

Luca Barbato committed 12 years ago

Commit fb1ddcd1 parent 8c6f4306 files · +209 −2Browse files

Unified · Split

6 files
  1. doc/APIchanges +6 −0
  2. libavresample/avresample.h +69 −0
  3. libavresample/utils.c +130 −0
  4. libavresample/version.h +1 −1
  5. libavutil/error.h +2 −0
  6. libavutil/version.h +1 −1
doc/APIchanges+6−0
@@ -13,6 +13,12 @@ libavutil: 2014-08-09 · 12 unmodified lines
13 13
14API changes, most recent first:14API changes, most recent first:
15 15
162014-04-xx - xxxxxxx - lavr 2.1.0 - avresample.h
17 Add avresample_convert_frame() and avresample_config().
18
192014-04-xx - xxxxxxx - lavu 54.1.0 - error.h
20 Add AVERROR_INPUT_CHANGED and AVERROR_OUTPUT_CHANGED.
21
162014-08-xx - xxxxxxx - lavc 55.57.4 - avcodec.h222014-08-xx - xxxxxxx - lavc 55.57.4 - avcodec.h
17 Deprecate FF_IDCT_XVIDMMX define and xvidmmx idct option.23 Deprecate FF_IDCT_XVIDMMX define and xvidmmx idct option.
18 Replaced by FF_IDCT_XVID and xvid respectively.24 Replaced by FF_IDCT_XVID and xvid respectively.
libavresample/avresample.h+69−0
@@ -95,6 +95,7 @@ · 94 unmodified lines
95#include "libavutil/avutil.h"95#include "libavutil/avutil.h"
96#include "libavutil/channel_layout.h"96#include "libavutil/channel_layout.h"
97#include "libavutil/dict.h"97#include "libavutil/dict.h"
98#include "libavutil/frame.h"
98#include "libavutil/log.h"99#include "libavutil/log.h"
99#include "libavutil/mathematics.h"100#include "libavutil/mathematics.h"
100 101
@@ -165,6 +166,10 @@ AVAudioResampleContext *avresample_alloc_context(void); · 64 unmodified lines
165 166
166/**167/**
167 * Initialize AVAudioResampleContext.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 * @param avr audio resample context174 * @param avr audio resample context
170 * @return 0 on success, negative AVERROR code on failure175 * @return 0 on success, negative AVERROR code on failure
@@ -422,6 +427,70 @@ int avresample_available(AVAudioResampleContext *avr); · 251 unmodified lines
422 */427 */
423int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples);428int 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 */
474int 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 */
492int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in);
493
425/**494/**
426 * @}495 * @}
427 */496 */
libavresample/utils.c+130−0
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include "libavutil/common.h"21#include "libavutil/common.h"
22#include "libavutil/dict.h"22#include "libavutil/dict.h"
23#include "libavutil/error.h"23#include "libavutil/error.h"
24#include "libavutil/frame.h"
24#include "libavutil/log.h"25#include "libavutil/log.h"
25#include "libavutil/mem.h"26#include "libavutil/mem.h"
26#include "libavutil/opt.h"27#include "libavutil/opt.h"
@@ -500,6 +501,135 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr, · 473 unmodified lines
500 current_buffer);501 current_buffer);
501}502}
502 503
504int 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
525static 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
549static 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
586static 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
599int 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
503int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,633int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
504 int stride)634 int stride)
505{635{
libavresample/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVRESAMPLE_VERSION_MAJOR 230#define LIBAVRESAMPLE_VERSION_MAJOR 2
31#define LIBAVRESAMPLE_VERSION_MINOR 031#define LIBAVRESAMPLE_VERSION_MINOR 1
32#define LIBAVRESAMPLE_VERSION_MICRO 032#define LIBAVRESAMPLE_VERSION_MICRO 0
33 33
34#define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \34#define LIBAVRESAMPLE_VERSION_INT AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
libavutil/error.h+2−0
@@ -60,6 +60,8 @@ · 59 unmodified lines
60#define AVERROR_BUG (-0x5fb8aabe) ///< Bug detected, please report the issue60#define AVERROR_BUG (-0x5fb8aabe) ///< Bug detected, please report the issue
61#define AVERROR_UNKNOWN (-0x31b4b1ab) ///< Unknown error, typically from an external library61#define AVERROR_UNKNOWN (-0x31b4b1ab) ///< Unknown error, typically from an external library
62#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.62#define AVERROR_EXPERIMENTAL (-0x2bb2afa8) ///< Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
63#define AVERROR_INPUT_CHANGED (-0x636e6701) ///< Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
64#define AVERROR_OUTPUT_CHANGED (-0x636e6702) ///< Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED)
63 65
64/**66/**
65 * Put a description of the AVERROR code errnum in errbuf.67 * Put a description of the AVERROR code errnum in errbuf.
libavutil/version.h+1−1
@@ -54,7 +54,7 @@ · 53 unmodified lines
54 */54 */
55 55
56#define LIBAVUTIL_VERSION_MAJOR 5456#define LIBAVUTIL_VERSION_MAJOR 54
57#define LIBAVUTIL_VERSION_MINOR 057#define LIBAVUTIL_VERSION_MINOR 1
58#define LIBAVUTIL_VERSION_MICRO 058#define LIBAVUTIL_VERSION_MICRO 0
59 59
60#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \60#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t