AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AudioFrame.cpp
Go to the documentation of this file.
1 #include "AudioFrame.hpp"
2 
3 #include <AvTranscoder/util.hpp>
4 
5 extern "C" {
6 #include <libavutil/samplefmt.h>
7 #include <libavutil/channel_layout.h>
8 }
9 
10 #include <stdexcept>
11 
12 namespace avtranscoder
13 {
14 
15 AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const AVSampleFormat sampleFormat)
16  : _sampleRate(sampleRate)
17  , _nbChannels(nbChannels)
18  , _sampleFormat(sampleFormat)
19 {
20 }
21 
22 AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName)
23  : _sampleRate(sampleRate)
24  , _nbChannels(nbChannels)
25  , _sampleFormat(getAVSampleFormat(sampleFormatName))
26 {
27 }
28 
30 {
31  // sample rate
32  if(profile.count(constants::avProfileSampleRate))
33  _sampleRate = atoi(profile.find(constants::avProfileSampleRate)->second.c_str());
34  // channel
35  if(profile.count(constants::avProfileChannel))
36  _nbChannels = atoi(profile.find(constants::avProfileChannel)->second.c_str());
37  // sample format
38  if(profile.count(constants::avProfileSampleFormat))
39  _sampleFormat = getAVSampleFormat(profile.find(constants::avProfileSampleFormat)->second.c_str());
40 }
41 
43  : Frame()
44 {
45  allocateAVSample(ref);
46 }
47 
48 AudioFrame::AudioFrame(const Frame& otherFrame)
49  : Frame(otherFrame)
50 {
51 }
52 
53 size_t AudioFrame::getSize() const
54 {
55  if(getSampleFormat() == AV_SAMPLE_FMT_NONE)
56  {
57  LOG_WARN("Incorrect sample format when get size of audio frame: return a size of 0.")
58  return 0;
59  }
60 
61  const size_t size = getNbSamplesPerChannel() * getNbChannels() * av_get_bytes_per_sample(getSampleFormat());
62  if(size == 0)
63  {
64  std::stringstream msg;
65  msg << "Unable to determine audio buffer size:" << std::endl;
66  msg << "nb sample per channel = " << getNbSamplesPerChannel() << std::endl;
67  msg << "channels = " << getNbChannels() << std::endl;
68  msg << "bytes per sample = " << av_get_bytes_per_sample(getSampleFormat()) << std::endl;
69  throw std::runtime_error(msg.str());
70  }
71  return size;
72 }
73 
75 {
76  // Set Frame properties
77  av_frame_set_sample_rate(_frame, desc._sampleRate);
78  av_frame_set_channels(_frame, desc._nbChannels);
79  av_frame_set_channel_layout(_frame, av_get_default_channel_layout(desc._nbChannels));
80  _frame->format = desc._sampleFormat;
81  _frame->nb_samples = desc._sampleRate / 25.; // cannot be known before calling avcodec_decode_audio4
82 
83  // Allocate data
84  const int align = 0;
85  const int ret =
86  av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, desc._sampleFormat, align);
87  if(ret < 0)
88  {
89  std::stringstream os;
90  os << "Unable to allocate an audio frame of ";
91  os << "sample rate = " << _frame->sample_rate << ", ";
92  os << "nb channels = " << _frame->channels << ", ";
93  os << "channel layout = " << av_get_channel_name(_frame->channels) << ", ";
94  os << "nb samples = " << _frame->nb_samples << ", ";
95  os << "sample format = " << getSampleFormatName(desc._sampleFormat);
96  throw std::runtime_error(os.str());
97  }
98 }
99 
100 void AudioFrame::assign(const unsigned char value)
101 {
102  // Create the audio buffer
103  // The buffer will be freed in destructor of based class
104  const int audioSize = getSize();
105  unsigned char* audioBuffer = new unsigned char[audioSize];
106  memset(audioBuffer, value, audioSize);
107 
108  // Fill the picture
109  assign(audioBuffer);
110 }
111 
112 void AudioFrame::assign(const unsigned char* ptrValue)
113 {
114  const int align = 0;
115  const int ret = av_samples_fill_arrays(_frame->data, _frame->linesize, ptrValue, getNbChannels(),
117  if(ret < 0)
118  {
119  std::stringstream os;
120  os << "Unable to assign an audio buffer: " << getDescriptionFromErrorCode(ret);
121  throw std::runtime_error(os.str());
122  }
123 }
124 }
AudioFrame(const AudioFrameDesc &ref)
Definition: AudioFrame.cpp:42
AVSampleFormat getSampleFormat() const
Definition: AudioFrame.hpp:48
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
Definition: common.cpp:22
std::map< std::string, std::string > Profile
const std::string avProfileSampleRate
size_t getSize() const
in bytes
Definition: AudioFrame.cpp:53
AVSampleFormat _sampleFormat
Definition: AudioFrame.hpp:30
#define LOG_WARN(...)
Definition: log.hpp:29
AVFrame * _frame
Definition: Frame.hpp:97
Description to create an audio frame. This corresponds to the number of samples, which corresponds to...
Definition: AudioFrame.hpp:14
void setParameters(const ProfileLoader::Profile &profile)
Set the attributes from the given profile.
Definition: AudioFrame.cpp:29
size_t getNbChannels() const
Definition: AudioFrame.hpp:46
This class describes decoded (raw) audio or video data.
Definition: Frame.hpp:16
const std::string avProfileSampleFormat
std::string getSampleFormatName(const AVSampleFormat sampleFormat)
Definition: util.cpp:106
void allocateAVSample(const AudioFrameDesc &ref)
Allocate the audio buffer of the frame.
Definition: AudioFrame.cpp:74
const std::string avProfileChannel
size_t getNbSamplesPerChannel() const
Definition: AudioFrame.hpp:49
AVSampleFormat getAVSampleFormat(const std::string &sampleFormat)
Get the corresponding AVSampleFormat from the sample format name.
Definition: util.cpp:95
AudioFrameDesc(const size_t sampleRate=0, const size_t channels=0, const AVSampleFormat sampleFormat=AV_SAMPLE_FMT_NONE)
Definition: AudioFrame.cpp:15
void assign(const unsigned char value)
Assign the given value to all the data of the audio frame.
Definition: AudioFrame.cpp:100