AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AudioTransform.cpp
Go to the documentation of this file.
1 #include "AudioTransform.hpp"
2 
3 #include <AvTranscoder/util.hpp>
5 
6 extern "C" {
7 #include <libavcodec/avcodec.h>
8 #include <libavutil/opt.h>
9 
10 #ifdef AVTRANSCODER_LIBAV_DEPENDENCY
11 #include <libavresample/avresample.h>
12 #define AllocResampleContext avresample_alloc_context
13 #define FreeResampleContext avresample_free
14 #define InitResampleContext avresample_open
15 #define SetSampleFormat av_opt_set_int
16 #else
17 #include <libswresample/swresample.h>
18 #define AllocResampleContext swr_alloc
19 #define FreeResampleContext swr_free
20 #define InitResampleContext swr_init
21 #define SetSampleFormat av_opt_set_sample_fmt
22 #endif
23 
24 #if LIBAVCODEC_VERSION_MAJOR > 54
25 #include <libavutil/frame.h>
26 #endif
27 }
28 
29 #include <stdexcept>
30 #include <sstream>
31 
32 namespace avtranscoder
33 {
34 
36  : _audioConvertContext(NULL)
37  , _isInit(false)
38 {
39 }
40 
42 {
44 }
45 
46 bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame)
47 {
48  // Set convert context
51  {
52  throw std::runtime_error("unable to create audio convert context");
53  }
54 
55  const AudioFrame& src = static_cast<const AudioFrame&>(srcFrame);
56  const AudioFrame& dst = static_cast<const AudioFrame&>(dstFrame);
57 
58  av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.getNbChannels()), 0);
59  av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.getNbChannels()), 0);
60  av_opt_set_int(_audioConvertContext, "in_sample_rate", src.getSampleRate(), 0);
61  av_opt_set_int(_audioConvertContext, "out_sample_rate", dst.getSampleRate(), 0);
62  SetSampleFormat(_audioConvertContext, "in_sample_fmt", src.getSampleFormat(), 0);
63  SetSampleFormat(_audioConvertContext, "out_sample_fmt", dst.getSampleFormat(), 0);
64 
66  {
68  std::stringstream msg;
69  msg << "Unable to open audio convert context:" << std::endl;
70  msg << "in_channel_layout " << av_get_default_channel_layout(src.getNbChannels()) << std::endl;
71  msg << "out_channel_layout " << av_get_default_channel_layout(dst.getNbChannels()) << std::endl;
72  msg << "in_sample_rate " << src.getSampleRate() << std::endl;
73  msg << "out_sample_rate " << dst.getSampleRate() << std::endl;
74  msg << "in_sample_fmt " << src.getSampleFormat() << std::endl;
75  msg << "out_sample_fmt " << dst.getSampleFormat() << std::endl;
76  throw std::runtime_error(msg.str());
77  }
78 
79  std::stringstream msg;
80  msg << "Audio conversion from " << getSampleFormatName(src.getSampleFormat()) << " to "
81  << getSampleFormatName(dst.getSampleFormat()) << std::endl;
82  msg << "Source, number of channels = " << src.getNbChannels() << std::endl;
83  msg << "Source, sample rate = " << src.getSampleRate() << std::endl;
84  msg << "Destination, number of channels = " << dst.getNbChannels() << std::endl;
85  msg << "Destination, sample rate = " << dst.getSampleRate() << std::endl;
86  LOG_INFO(msg.str())
87 
88  return true;
89 }
90 
91 void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame)
92 {
93  if(!_isInit)
94  _isInit = init(srcFrame, dstFrame);
95 
96  // if number of samples change from previous frame
97  const size_t nbInputSamplesPerChannel = srcFrame.getAVFrame().nb_samples;
98 
99  const unsigned char** srcData = srcFrame.getData();
100  unsigned char** dstData = dstFrame.getData();
101 
102  int nbOutputSamplesPerChannel;
103 #ifdef AVTRANSCODER_LIBAV_DEPENDENCY
104  nbOutputSamplesPerChannel =
105  avresample_convert(_audioConvertContext, dstData, 0, nbInputSamplesPerChannel, srcData, 0, nbInputSamplesPerChannel);
106 #else
107  nbOutputSamplesPerChannel =
108  swr_convert(_audioConvertContext, dstData, nbInputSamplesPerChannel, srcData, nbInputSamplesPerChannel);
109 #endif
110 
111  if(nbOutputSamplesPerChannel < 0)
112  {
113  throw std::runtime_error("unable to convert audio samples");
114  }
115  else
116  {
117  dstFrame.getAVFrame().nb_samples = nbOutputSamplesPerChannel;
118  }
119 }
120 }
bool init(const Frame &srcFrame, const Frame &dstFrame)
void convert(const Frame &srcFrame, Frame &dstFrame)
AVSampleFormat getSampleFormat() const
Definition: AudioFrame.hpp:48
#define InitResampleContext
#define LOG_INFO(...)
Definition: log.hpp:23
#define AllocResampleContext
unsigned char ** getData()
Get all the data of the frame.
Definition: Frame.hpp:35
size_t getSampleRate() const
Definition: AudioFrame.hpp:45
size_t getNbChannels() const
Definition: AudioFrame.hpp:46
This class describes decoded audio data.
Definition: AudioFrame.hpp:36
This class describes decoded (raw) audio or video data.
Definition: Frame.hpp:16
#define SetSampleFormat
std::string getSampleFormatName(const AVSampleFormat sampleFormat)
Definition: util.cpp:106
AVFrame & getAVFrame()
Definition: Frame.hpp:88
#define FreeResampleContext
ResampleContext * _audioConvertContext