Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.  
  36. int 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.  
  252. error:
  253.     avresample_close(avr);
  254.     return ret;
  255. }
  256.  
  257. int avresample_is_open(AVAudioResampleContext *avr)
  258. {
  259.     return !!avr->out_fifo;
  260. }
  261.  
  262. void 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.  
  278. void 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.  
  287. static 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.  
  330. int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
  331.                                            uint8_t **output, int out_plane_size,
  332.                                            int out_samples, uint8_t **input,
  333.                                            int in_plane_size, int in_samples)
  334. {
  335.     AudioData input_buffer;
  336.     AudioData output_buffer;
  337.     AudioData *current_buffer;
  338.     int ret, direct_output;
  339.  
  340.     /* reset internal buffers */
  341.     if (avr->in_buffer) {
  342.         avr->in_buffer->nb_samples = 0;
  343.         ff_audio_data_set_channels(avr->in_buffer,
  344.                                    avr->in_buffer->allocated_channels);
  345.     }
  346.     if (avr->resample_out_buffer) {
  347.         avr->resample_out_buffer->nb_samples = 0;
  348.         ff_audio_data_set_channels(avr->resample_out_buffer,
  349.                                    avr->resample_out_buffer->allocated_channels);
  350.     }
  351.     if (avr->out_buffer) {
  352.         avr->out_buffer->nb_samples = 0;
  353.         ff_audio_data_set_channels(avr->out_buffer,
  354.                                    avr->out_buffer->allocated_channels);
  355.     }
  356.  
  357.     av_log(avr, AV_LOG_TRACE, "[start conversion]\n");
  358.  
  359.     /* initialize output_buffer with output data */
  360.     direct_output = output && av_audio_fifo_size(avr->out_fifo) == 0;
  361.     if (output) {
  362.         ret = ff_audio_data_init(&output_buffer, output, out_plane_size,
  363.                                  avr->out_channels, out_samples,
  364.                                  avr->out_sample_fmt, 0, "output");
  365.         if (ret < 0)
  366.             return ret;
  367.         output_buffer.nb_samples = 0;
  368.     }
  369.  
  370.     if (input) {
  371.         /* initialize input_buffer with input data */
  372.         ret = ff_audio_data_init(&input_buffer, input, in_plane_size,
  373.                                  avr->in_channels, in_samples,
  374.                                  avr->in_sample_fmt, 1, "input");
  375.         if (ret < 0)
  376.             return ret;
  377.         current_buffer = &input_buffer;
  378.  
  379.         if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&
  380.             !avr->out_convert_needed && direct_output && out_samples >= in_samples) {
  381.             /* in some rare cases we can copy input to output and upmix
  382.                directly in the output buffer */
  383.             av_log(avr, AV_LOG_TRACE, "[copy] %s to output\n", current_buffer->name);
  384.             ret = ff_audio_data_copy(&output_buffer, current_buffer,
  385.                                      avr->remap_point == REMAP_OUT_COPY ?
  386.                                      &avr->ch_map_info : NULL);
  387.             if (ret < 0)
  388.                 return ret;
  389.             current_buffer = &output_buffer;
  390.         } else if (avr->remap_point == REMAP_OUT_COPY &&
  391.                    (!direct_output || out_samples < in_samples)) {
  392.             /* if remapping channels during output copy, we may need to
  393.              * use an intermediate buffer in order to remap before adding
  394.              * samples to the output fifo */
  395.             av_log(avr, AV_LOG_TRACE, "[copy] %s to out_buffer\n", current_buffer->name);
  396.             ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
  397.                                      &avr->ch_map_info);
  398.             if (ret < 0)
  399.                 return ret;
  400.             current_buffer = avr->out_buffer;
  401.         } else if (avr->in_copy_needed || avr->in_convert_needed) {
  402.             /* if needed, copy or convert input to in_buffer, and downmix if
  403.                applicable */
  404.             if (avr->in_convert_needed) {
  405.                 ret = ff_audio_data_realloc(avr->in_buffer,
  406.                                             current_buffer->nb_samples);
  407.                 if (ret < 0)
  408.                     return ret;
  409.                 av_log(avr, AV_LOG_TRACE, "[convert] %s to in_buffer\n", current_buffer->name);
  410.                 ret = ff_audio_convert(avr->ac_in, avr->in_buffer,
  411.                                        current_buffer);
  412.                 if (ret < 0)
  413.                     return ret;
  414.             } else {
  415.                 av_log(avr, AV_LOG_TRACE, "[copy] %s to in_buffer\n", current_buffer->name);
  416.                 ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
  417.                                          avr->remap_point == REMAP_IN_COPY ?
  418.                                          &avr->ch_map_info : NULL);
  419.                 if (ret < 0)
  420.                     return ret;
  421.             }
  422.             ff_audio_data_set_channels(avr->in_buffer, avr->in_channels);
  423.             if (avr->downmix_needed) {
  424.                 av_log(avr, AV_LOG_TRACE, "[downmix] in_buffer\n");
  425.                 ret = ff_audio_mix(avr->am, avr->in_buffer);
  426.                 if (ret < 0)
  427.                     return ret;
  428.             }
  429.             current_buffer = avr->in_buffer;
  430.         }
  431.     } else {
  432.         /* flush resampling buffer and/or output FIFO if input is NULL */
  433.         if (!avr->resample_needed)
  434.             return handle_buffered_output(avr, output ? &output_buffer : NULL,
  435.                                           NULL);
  436.         current_buffer = NULL;
  437.     }
  438.  
  439.     if (avr->resample_needed) {
  440.         AudioData *resample_out;
  441.  
  442.         if (!avr->out_convert_needed && direct_output && out_samples > 0)
  443.             resample_out = &output_buffer;
  444.         else
  445.             resample_out = avr->resample_out_buffer;
  446.         av_log(avr, AV_LOG_TRACE, "[resample] %s to %s\n",
  447.                 current_buffer ? current_buffer->name : "null",
  448.                 resample_out->name);
  449.         ret = ff_audio_resample(avr->resample, resample_out,
  450.                                 current_buffer);
  451.         if (ret < 0)
  452.             return ret;
  453.  
  454.         /* if resampling did not produce any samples, just return 0 */
  455.         if (resample_out->nb_samples == 0) {
  456.             av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
  457.             return 0;
  458.         }
  459.  
  460.         current_buffer = resample_out;
  461.     }
  462.  
  463.     if (avr->upmix_needed) {
  464.         av_log(avr, AV_LOG_TRACE, "[upmix] %s\n", current_buffer->name);
  465.         ret = ff_audio_mix(avr->am, current_buffer);
  466.         if (ret < 0)
  467.             return ret;
  468.     }
  469.  
  470.     /* if we resampled or upmixed directly to output, return here */
  471.     if (current_buffer == &output_buffer) {
  472.         av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
  473.         return current_buffer->nb_samples;
  474.     }
  475.  
  476.     if (avr->out_convert_needed) {
  477.         if (direct_output && out_samples >= current_buffer->nb_samples) {
  478.             /* convert directly to output */
  479.             av_log(avr, AV_LOG_TRACE, "[convert] %s to output\n", current_buffer->name);
  480.             ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer);
  481.             if (ret < 0)
  482.                 return ret;
  483.  
  484.             av_log(avr, AV_LOG_TRACE, "[end conversion]\n");
  485.             return output_buffer.nb_samples;
  486.         } else {
  487.             ret = ff_audio_data_realloc(avr->out_buffer,
  488.                                         current_buffer->nb_samples);
  489.             if (ret < 0)
  490.                 return ret;
  491.             av_log(avr, AV_LOG_TRACE, "[convert] %s to out_buffer\n", current_buffer->name);
  492.             ret = ff_audio_convert(avr->ac_out, avr->out_buffer,
  493.                                    current_buffer);
  494.             if (ret < 0)
  495.                 return ret;
  496.             current_buffer = avr->out_buffer;
  497.         }
  498.     }
  499.  
  500.     return handle_buffered_output(avr, output ? &output_buffer : NULL,
  501.                                   current_buffer);
  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 samples;
  589.     int bytes_per_sample = av_get_bytes_per_sample(out->format);
  590.     if (!bytes_per_sample)
  591.         return AVERROR(EINVAL);
  592.  
  593.     samples = out->linesize[0] / bytes_per_sample;
  594.     if (av_sample_fmt_is_planar(out->format)) {
  595.         return samples;
  596.     } else {
  597.         int channels = av_get_channel_layout_nb_channels(out->channel_layout);
  598.         return samples / channels;
  599.     }
  600. }
  601.  
  602. int avresample_convert_frame(AVAudioResampleContext *avr,
  603.                              AVFrame *out, AVFrame *in)
  604. {
  605.     int ret, setup = 0;
  606.  
  607.     if (!avresample_is_open(avr)) {
  608.         if ((ret = avresample_config(avr, out, in)) < 0)
  609.             return ret;
  610.         if ((ret = avresample_open(avr)) < 0)
  611.             return ret;
  612.         setup = 1;
  613.     } else {
  614.         // return as is or reconfigure for input changes?
  615.         if ((ret = config_changed(avr, out, in)))
  616.             return ret;
  617.     }
  618.  
  619.     if (out) {
  620.         if (!out->linesize[0]) {
  621.             out->nb_samples = avresample_get_out_samples(avr, in->nb_samples);
  622.             if ((ret = av_frame_get_buffer(out, 0)) < 0) {
  623.                 if (setup)
  624.                     avresample_close(avr);
  625.                 return ret;
  626.             }
  627.         } else {
  628.             if (!out->nb_samples)
  629.                 out->nb_samples = available_samples(out);
  630.         }
  631.     }
  632.  
  633.     return convert_frame(avr, out, in);
  634. }
  635.  
  636. int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
  637.                           int stride)
  638. {
  639.     int in_channels, out_channels, i, o;
  640.  
  641.     if (avr->am)
  642.         return ff_audio_mix_get_matrix(avr->am, matrix, stride);
  643.  
  644.     in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
  645.     out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
  646.  
  647.     if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
  648.         out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
  649.         av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
  650.         return AVERROR(EINVAL);
  651.     }
  652.  
  653.     if (!avr->mix_matrix) {
  654.         av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
  655.         return AVERROR(EINVAL);
  656.     }
  657.  
  658.     for (o = 0; o < out_channels; o++)
  659.         for (i = 0; i < in_channels; i++)
  660.             matrix[o * stride + i] = avr->mix_matrix[o * in_channels + i];
  661.  
  662.     return 0;
  663. }
  664.  
  665. int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
  666.                           int stride)
  667. {
  668.     int in_channels, out_channels, i, o;
  669.  
  670.     if (avr->am)
  671.         return ff_audio_mix_set_matrix(avr->am, matrix, stride);
  672.  
  673.     in_channels  = av_get_channel_layout_nb_channels(avr->in_channel_layout);
  674.     out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
  675.  
  676.     if ( in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS ||
  677.         out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
  678.         av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
  679.         return AVERROR(EINVAL);
  680.     }
  681.  
  682.     if (avr->mix_matrix)
  683.         av_freep(&avr->mix_matrix);
  684.     avr->mix_matrix = av_malloc(in_channels * out_channels *
  685.                                 sizeof(*avr->mix_matrix));
  686.     if (!avr->mix_matrix)
  687.         return AVERROR(ENOMEM);
  688.  
  689.     for (o = 0; o < out_channels; o++)
  690.         for (i = 0; i < in_channels; i++)
  691.             avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i];
  692.  
  693.     return 0;
  694. }
  695.  
  696. int avresample_set_channel_mapping(AVAudioResampleContext *avr,
  697.                                    const int *channel_map)
  698. {
  699.     ChannelMapInfo *info = &avr->ch_map_info;
  700.     int in_channels, ch, i;
  701.  
  702.     in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
  703.     if (in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS) {
  704.         av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
  705.         return AVERROR(EINVAL);
  706.     }
  707.  
  708.     memset(info, 0, sizeof(*info));
  709.     memset(info->input_map, -1, sizeof(info->input_map));
  710.  
  711.     for (ch = 0; ch < in_channels; ch++) {
  712.         if (channel_map[ch] >= in_channels) {
  713.             av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
  714.             return AVERROR(EINVAL);
  715.         }
  716.         if (channel_map[ch] < 0) {
  717.             info->channel_zero[ch] =  1;
  718.             info->channel_map[ch]  = -1;
  719.             info->do_zero          =  1;
  720.         } else if (info->input_map[channel_map[ch]] >= 0) {
  721.             info->channel_copy[ch] = info->input_map[channel_map[ch]];
  722.             info->channel_map[ch]  = -1;
  723.             info->do_copy          =  1;
  724.         } else {
  725.             info->channel_map[ch]            = channel_map[ch];
  726.             info->input_map[channel_map[ch]] = ch;
  727.             info->do_remap                   =  1;
  728.         }
  729.     }
  730.     /* Fill-in unmapped input channels with unmapped output channels.
  731.        This is used when remapping during conversion from interleaved to
  732.        planar format. */
  733.     for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
  734.         while (ch < in_channels && info->input_map[ch] >= 0)
  735.             ch++;
  736.         while (i < in_channels && info->channel_map[i] >= 0)
  737.             i++;
  738.         if (ch >= in_channels || i >= in_channels)
  739.             break;
  740.         info->input_map[ch] = i;
  741.     }
  742.  
  743.     avr->use_channel_map = 1;
  744.     return 0;
  745. }
  746.  
  747. int avresample_available(AVAudioResampleContext *avr)
  748. {
  749.     return av_audio_fifo_size(avr->out_fifo);
  750. }
  751.  
  752. int avresample_get_out_samples(AVAudioResampleContext *avr, int in_nb_samples)
  753. {
  754.     int64_t samples = avresample_get_delay(avr) + (int64_t)in_nb_samples;
  755.  
  756.     if (avr->resample_needed) {
  757.         samples = av_rescale_rnd(samples,
  758.                                  avr->out_sample_rate,
  759.                                  avr->in_sample_rate,
  760.                                  AV_ROUND_UP);
  761.     }
  762.  
  763.     samples += avresample_available(avr);
  764.  
  765.     if (samples > INT_MAX)
  766.         return AVERROR(EINVAL);
  767.  
  768.     return samples;
  769. }
  770.  
  771. int avresample_read(AVAudioResampleContext *avr, uint8_t **output, int nb_samples)
  772. {
  773.     if (!output)
  774.         return av_audio_fifo_drain(avr->out_fifo, nb_samples);
  775.     return av_audio_fifo_read(avr->out_fifo, (void**)output, nb_samples);
  776. }
  777.  
  778. unsigned avresample_version(void)
  779. {
  780.     return LIBAVRESAMPLE_VERSION_INT;
  781. }
  782.  
  783. const char *avresample_license(void)
  784. {
  785. #define LICENSE_PREFIX "libavresample license: "
  786.     return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
  787. }
  788.  
  789. const char *avresample_configuration(void)
  790. {
  791.     return FFMPEG_CONFIGURATION;
  792. }
  793.