AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AudioProperties.cpp
Go to the documentation of this file.
1 #include "AudioProperties.hpp"
2 
4 
5 extern "C" {
6 #include <libavcodec/avcodec.h>
7 #include <libavformat/avformat.h>
8 #include <libavutil/avutil.h>
9 #include <libavutil/pixdesc.h>
10 #include <libavutil/channel_layout.h>
11 }
12 
13 #include <stdexcept>
14 
15 namespace avtranscoder
16 {
17 
18 AudioProperties::AudioProperties(const FormatContext& formatContext, const size_t index)
19  : StreamProperties(formatContext, index)
20 {
21 }
22 
24 {
25  if(!_codecContext)
26  throw std::runtime_error("unknown codec context");
27 
28  const char* fmtName = av_get_sample_fmt_name(_codecContext->sample_fmt);
29  if(!fmtName)
30  throw std::runtime_error("unknown sample format");
31 
32  return std::string(fmtName);
33 }
34 
36 {
37  if(!_codecContext)
38  throw std::runtime_error("unknown codec context");
39 
40  switch(_codecContext->sample_fmt)
41  {
42  case AV_SAMPLE_FMT_NONE:
43  return "none";
44  case AV_SAMPLE_FMT_U8:
45  return "unsigned 8 bits";
46  case AV_SAMPLE_FMT_S16:
47  return "signed 16 bits";
48  case AV_SAMPLE_FMT_S32:
49  return "signed 32 bits";
50  case AV_SAMPLE_FMT_FLT:
51  return "float";
52  case AV_SAMPLE_FMT_DBL:
53  return "double";
54  case AV_SAMPLE_FMT_U8P:
55  return "unsigned 8 bits, planar";
56  case AV_SAMPLE_FMT_S16P:
57  return "signed 16 bits, planar";
58  case AV_SAMPLE_FMT_S32P:
59  return "signed 32 bits, planar";
60  case AV_SAMPLE_FMT_FLTP:
61  return "float, planar";
62  case AV_SAMPLE_FMT_DBLP:
63  return "double, planar";
64  case AV_SAMPLE_FMT_NB:
65  return "number of sample formats";
66  }
67  return "unknown sample format";
68 }
69 
71 {
72  if(!_codecContext)
73  throw std::runtime_error("unknown codec context");
74 
75  char buf1[1024];
76  av_get_channel_layout_string(buf1, sizeof(buf1), -1, _codecContext->channel_layout);
77  return std::string(buf1);
78 }
79 
81 {
82  if(!_codecContext)
83  throw std::runtime_error("unknown codec context");
84 
85  const char* channelName = av_get_channel_name(_codecContext->channel_layout);
86  if(!channelName)
87  throw std::runtime_error("unknown channel name");
88 
89  return std::string(channelName);
90 }
91 
93 {
94  if(!_codecContext)
95  throw std::runtime_error("unknown codec context");
96 
97 #ifdef AVTRANSCODER_FFMPEG_DEPENDENCY
98  const char* channelDescription = av_get_channel_description(_codecContext->channel_layout);
99  if(!channelDescription)
100  throw std::runtime_error("unknown channel description");
101  return std::string(channelDescription);
102 #else
103  throw std::runtime_error("can't access channel description");
104 #endif
105 }
106 
108 {
109  if(!_codecContext)
110  throw std::runtime_error("unknown codec context");
111  return _codecContext->sample_rate;
112 }
113 
115 {
116  if(!_codecContext)
117  throw std::runtime_error("unknown codec context");
118  return _codecContext->channels;
119 }
120 
122 {
123  if(!_codecContext)
124  throw std::runtime_error("unknown codec context");
125 
126  // return bit rate of stream
127  if(_codecContext->bit_rate)
128  return _codecContext->bit_rate;
129 
130  // else get computed bit rate from our computation (warning: way to compute bit rate of PCM audio data)
131  int bitsPerSample = av_get_bits_per_sample(_codecContext->codec_id); // 0 if unknown for the given codec
132  return _codecContext->sample_rate * _codecContext->channels * bitsPerSample;
133 }
134 
136 {
137  if(!_formatContext)
138  throw std::runtime_error("unknown format context");
139  size_t nbSamples = _formatContext->streams[_streamIndex]->nb_frames;
140  if(nbSamples == 0)
141  nbSamples = getSampleRate() * getNbChannels() * getDuration();
142  return nbSamples;
143 }
144 
146 {
147  if(!_codecContext)
148  throw std::runtime_error("unknown codec context");
149  return _codecContext->ticks_per_frame;
150 }
151 
153 {
154  // Add properties of base class
155  PropertyVector basedProperty;
156  StreamProperties::fillVector(basedProperty);
157  data.insert(data.begin(), basedProperty.begin(), basedProperty.end());
158 
159  addProperty(data, "sampleFormatName", &AudioProperties::getSampleFormatName);
160  addProperty(data, "sampleFormatLongName", &AudioProperties::getSampleFormatLongName);
161  addProperty(data, "sampleRate", &AudioProperties::getSampleRate);
162  addProperty(data, "bitRate", &AudioProperties::getBitRate);
163  addProperty(data, "nbSamples", &AudioProperties::getNbSamples);
164  addProperty(data, "nbChannels", &AudioProperties::getNbChannels);
165  addProperty(data, "channelLayout", &AudioProperties::getChannelLayout);
166  addProperty(data, "channelName", &AudioProperties::getChannelName);
167  addProperty(data, "channelDescription", &AudioProperties::getChannelDescription);
168  addProperty(data, "ticksPerFrame", &AudioProperties::getTicksPerFrame);
169 
170  return data;
171 }
172 
173 std::ostream& operator<<(std::ostream& flux, const AudioProperties& audioProperties)
174 {
175  flux << std::left;
176  flux << detail::separator << " Audio stream " << detail::separator << std::endl;
177 
178  PropertyVector properties = audioProperties.asVector();
179  for(PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it)
180  {
181  flux << std::setw(detail::keyWidth) << it->first << ": " << it->second << std::endl;
182  }
183 
184  return flux;
185 }
186 }
std::vector< std::pair< std::string, std::string > > PropertyVector
PropertyVector is a vector of pair, because the order of properties matters to us.
Definition: util.hpp:23
const AVFormatContext * _formatContext
Has link (no ownership)
const size_t keyWidth
Definition: util.hpp:32
const std::string separator
Definition: util.hpp:33
size_t getBitRate() const
0 if unknown
void addProperty(PropertyVector &data, const std::string &key, T(AudioProperties::*getter)(void) const) const
AudioProperties(const FormatContext &formatContext, const size_t index)
std::string getChannelDescription() const
float getDuration() const
in seconds
std::string getChannelLayout() const
std::string getChannelName() const
Wrapper of an AVFormatContext.
virtual PropertyVector & fillVector(PropertyVector &data) const
To avoid copy of the vector.
AVCodecContext * _codecContext
Has link (no ownership)
std::string getSampleFormatName() const
Virtual based class of properties for all types of stream.
std::ostream & operator<<(std::ostream &flux, const InputFile &input)
Definition: InputFile.cpp:171
PropertyVector asVector() const
Same data with a specific order.
PropertyVector & fillVector(PropertyVector &data) const
To avoid copy of the vector.
std::string getSampleFormatLongName() const