AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AudioEncoder.cpp
Go to the documentation of this file.
1 #include "AudioEncoder.hpp"
2 
3 extern "C" {
4 #include <libavcodec/avcodec.h>
5 #include <libavformat/avformat.h>
6 #include <libavutil/avutil.h>
7 }
8 
9 #include <stdexcept>
10 
11 namespace avtranscoder
12 {
13 
14 AudioEncoder::AudioEncoder(const std::string& audioCodecName)
15  : _codec(eCodecTypeEncoder, audioCodecName)
16 {
17 }
18 
20 {
21 }
22 
24 {
25  if(!profile.empty())
26  {
27  LOG_INFO("Setup audio encoder with:\n" << profile)
28  }
29 
30  // set sampleRate, number of channels, sample format
31  _codec.setAudioParameters(frameDesc);
32 
33  // setup encoder
34  setupEncoder(profile);
35 }
36 
38 {
39  // check the given profile
40  const bool isValid = ProfileLoader::checkAudioProfile(profile);
41  if(!isValid && !profile.empty())
42  {
43  const std::string msg("Invalid audio profile to setup encoder.");
44  LOG_ERROR(msg)
45  throw std::runtime_error(msg);
46  }
47 
48  // set threads before any other options
49  if(profile.count(constants::avProfileThreads))
51  else
53 
54  // set encoder options
55  for(ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it)
56  {
58  (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec ||
59  (*it).first == constants::avProfileSampleFormat || (*it).first == constants::avProfileThreads)
60  continue;
61 
62  try
63  {
64  Option& encodeOption = _codec.getOption((*it).first);
65  encodeOption.setString((*it).second);
66  }
67  catch(std::exception& e)
68  {
69  }
70  }
71 
72  // open encoder
73  _codec.openCodec();
74 
75  for(ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it)
76  {
78  (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec ||
79  (*it).first == constants::avProfileSampleFormat || (*it).first == constants::avProfileThreads)
80  continue;
81 
82  try
83  {
84  Option& encodeOption = _codec.getOption((*it).first);
85  encodeOption.setString((*it).second);
86  }
87  catch(std::exception& e)
88  {
89  LOG_WARN("AudioEncoder - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what())
90  }
91  }
92 }
93 
94 bool AudioEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
95 {
96  AVCodecContext& avCodecContext = _codec.getAVCodecContext();
97 
98  AVPacket& packet = codedFrame.getAVPacket();
99  if((avCodecContext.coded_frame) && (avCodecContext.coded_frame->pts != (int)AV_NOPTS_VALUE))
100  {
101  packet.pts = avCodecContext.coded_frame->pts;
102  }
103 
104  if(avCodecContext.coded_frame && avCodecContext.coded_frame->key_frame)
105  {
106  packet.flags |= AV_PKT_FLAG_KEY;
107  }
108 
109  return encode(&sourceFrame.getAVFrame(), packet);
110 }
111 
113 {
114  return encode(NULL, codedFrame.getAVPacket());
115 }
116 
117 bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
118 {
119  // Be sure that data of AVPacket is NULL so that the encoder will allocate it
120  encodedData.data = NULL;
121 
122  AVCodecContext& avCodecContext = _codec.getAVCodecContext();
123 #if LIBAVCODEC_VERSION_MAJOR > 53
124  int gotPacket = 0;
125  const int ret = avcodec_encode_audio2(&avCodecContext, &encodedData, decodedData, &gotPacket);
126  if(ret != 0)
127  {
128  throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
130  }
131  return gotPacket == 1;
132 #else
133  const int ret = avcodec_encode_audio(&avCodecContext, encodedData.data, encodedData.size, decodedData);
134  if(ret < 0)
135  {
136  throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
138  }
139  return true;
140 #endif
141 }
142 
143 }
void setString(const std::string &value)
Definition: Option.cpp:187
bool encodeFrame(const Frame &sourceFrame, CodedData &codedFrame)
Encode a new frame, and get coded frame.
AudioEncoder(const std::string &audioCodecName)
#define LOG_ERROR(...)
Definition: log.hpp:35
void setupAudioEncoder(const AudioFrameDesc &frameDesc, const ProfileLoader::Profile &profile=ProfileLoader::Profile())
void setInt(const int value)
Definition: Option.cpp:169
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
Definition: common.cpp:22
AVPacket & getAVPacket()
Definition: CodedData.hpp:78
std::map< std::string, std::string > Profile
const std::string avProfileIdentificator
const std::string avProfileIdentificatorHuman
#define LOG_INFO(...)
Definition: log.hpp:23
Option & getOption(const std::string &optionName)
Definition: ICodec.hpp:50
Wrapper of AVOption. Get its type to know what the option is about: Int, Double, Ratio, Choice... Parse its array of options to get the potential childs (Choice and Group).
Definition: Option.hpp:36
#define LOG_WARN(...)
Definition: log.hpp:29
Description to create an audio frame. This corresponds to the number of samples, which corresponds to...
Definition: AudioFrame.hpp:14
static bool checkAudioProfile(const Profile &profileToCheck)
This class describes decoded (raw) audio or video data.
Definition: Frame.hpp:16
void openCodec()
Initialize the codec context.
Definition: ICodec.cpp:56
AVCodecContext & getAVCodecContext()
Definition: ICodec.hpp:53
This class describes coded data.
Definition: CodedData.hpp:18
const std::string avProfileCodec
const std::string avProfileSampleFormat
const std::string avProfileThreads
void setAudioParameters(const AudioFrameDesc &audioFrameDesc)
Definition: AudioCodec.cpp:30
AVFrame & getAVFrame()
Definition: Frame.hpp:88
const std::string avProfileType
bool encode(const AVFrame *decodedData, AVPacket &encodedData)
void setupEncoder(const ProfileLoader::Profile &profile=ProfileLoader::Profile())
Setup the encoder.