AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Option.cpp
Go to the documentation of this file.
1 #include "Option.hpp"
2 
3 extern "C" {
4 #include <libavutil/error.h>
5 #include <libavutil/mem.h>
6 }
7 
8 #include <sstream>
9 #include <stdexcept>
10 
11 namespace avtranscoder
12 {
13 
14 Option::Option(AVOption& avOption, void* avContext)
15  : _avOption(&avOption)
16  , _avContext(avContext)
17  , _childOptions()
18  , _defaultChildIndex(0)
19 {
21 }
22 
23 EOptionBaseType Option::getTypeFromAVOption(const std::string& unit, const AVOptionType avType)
24 {
25  if(!unit.empty() && avType == AV_OPT_TYPE_FLAGS)
26  return eOptionBaseTypeGroup;
27  else if(!unit.empty() && (avType == AV_OPT_TYPE_INT || avType == AV_OPT_TYPE_INT64))
28  return eOptionBaseTypeChoice;
29  else if(!unit.empty() && avType == AV_OPT_TYPE_CONST)
30  return eOptionBaseTypeChild;
31 
32  switch(avType)
33  {
34  case AV_OPT_TYPE_FLAGS:
35  {
36  return eOptionBaseTypeBool;
37  }
38  case AV_OPT_TYPE_INT:
39  case AV_OPT_TYPE_INT64:
40  {
41  return eOptionBaseTypeInt;
42  }
43  case AV_OPT_TYPE_DOUBLE:
44  case AV_OPT_TYPE_FLOAT:
45  {
46  return eOptionBaseTypeDouble;
47  }
48  case AV_OPT_TYPE_STRING:
49  case AV_OPT_TYPE_BINARY:
50  {
51  return eOptionBaseTypeString;
52  }
53  case AV_OPT_TYPE_RATIONAL:
54  {
55  return eOptionBaseTypeRatio;
56  }
57  default:
58  {
60  }
61  }
63 }
64 
66 {
67  return _type;
68 }
69 
71 {
72  return _avOption->default_val.i64;
73 }
74 
76 {
77  return _avOption->default_val.i64;
78 }
79 
81 {
82  return _avOption->default_val.dbl;
83 }
84 
85 std::string Option::getDefaultString() const
86 {
87  return std::string(_avOption->default_val.str ? _avOption->default_val.str : "");
88 }
89 
90 std::pair<int, int> Option::getDefaultRatio() const
91 {
92  return std::make_pair(_avOption->default_val.q.num, _avOption->default_val.q.den);
93 }
94 
95 bool Option::getBool() const
96 {
97  int64_t out_val;
98  int error = av_opt_get_int(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, &out_val);
99  checkFFmpegGetOption(error);
100 
101  return out_val ? true : false;
102 }
103 
104 int Option::getInt() const
105 {
106  int64_t out_val;
107  int error = av_opt_get_int(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, &out_val);
108  checkFFmpegGetOption(error);
109 
110  return out_val;
111 }
112 
113 double Option::getDouble() const
114 {
115  double out_val;
116  int error = av_opt_get_double(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, &out_val);
117  checkFFmpegGetOption(error);
118 
119  return out_val;
120 }
121 
122 std::string Option::getString() const
123 {
124  void* out_val = av_malloc(128);
125  int error = av_opt_get(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, (uint8_t**)&out_val);
126 
127  std::string strValue(out_val ? reinterpret_cast<const char*>(out_val) : "");
128 
129  av_free(out_val);
130 
131  checkFFmpegGetOption(error);
132 
133  return strValue;
134 }
135 
136 std::pair<int, int> Option::getRatio() const
137 {
138  Rational out_val;
139  int error = av_opt_get_q(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, &out_val);
140  checkFFmpegGetOption(error);
141 
142  return std::make_pair(out_val.num, out_val.den);
143 }
144 
145 void Option::setFlag(const std::string& flag, const bool enable)
146 {
147  int64_t optVal;
148  int error = av_opt_get_int(_avContext, getName().c_str(), AV_OPT_SEARCH_CHILDREN, &optVal);
149  checkFFmpegGetOption(error);
150 
151  if(enable)
152  optVal = optVal | _avOption->default_val.i64;
153  else
154  optVal = optVal & ~_avOption->default_val.i64;
155 
156  error = av_opt_set_int(_avContext, getName().c_str(), optVal, AV_OPT_SEARCH_CHILDREN);
157  checkFFmpegSetOption(error, flag);
158 }
159 
160 void Option::setBool(const bool value)
161 {
162  int error = av_opt_set_int(_avContext, getName().c_str(), value, AV_OPT_SEARCH_CHILDREN);
163 
164  std::ostringstream os;
165  os << (value ? "true" : "false");
166  checkFFmpegSetOption(error, os.str());
167 }
168 
169 void Option::setInt(const int value)
170 {
171  int error = av_opt_set_int(_avContext, getName().c_str(), value, AV_OPT_SEARCH_CHILDREN);
172 
173  std::ostringstream os;
174  os << value;
175  checkFFmpegSetOption(error, os.str());
176 }
177 
178 void Option::setDouble(const double value)
179 {
180  int error = av_opt_set_double(_avContext, getName().c_str(), value, AV_OPT_SEARCH_CHILDREN);
181 
182  std::ostringstream os;
183  os << value;
184  checkFFmpegSetOption(error, os.str());
185 }
186 
187 void Option::setString(const std::string& value)
188 {
189  int error = av_opt_set(_avContext, getName().c_str(), value.c_str(), AV_OPT_SEARCH_CHILDREN);
190  checkFFmpegSetOption(error, value);
191 }
192 
193 void Option::setRatio(const int num, const int den)
194 {
195  Rational ratio;
196  ratio.num = num;
197  ratio.den = den;
198  int error = av_opt_set_q(_avContext, getName().c_str(), ratio, AV_OPT_SEARCH_CHILDREN);
199 
200  std::ostringstream os;
201  os << num << "/" << den;
202  checkFFmpegSetOption(error, os.str());
203 }
204 
205 void Option::appendChild(const Option& child)
206 {
207  _childOptions.push_back(child);
208 }
209 
210 void Option::checkFFmpegGetOption(const int ffmpegReturnCode) const
211 {
212  if(ffmpegReturnCode)
213  {
214  throw std::runtime_error("unknown key " + getName() + ": " + getDescriptionFromErrorCode(ffmpegReturnCode));
215  }
216 }
217 
218 void Option::checkFFmpegSetOption(const int ffmpegReturnCode, const std::string& optionValue)
219 {
220  if(ffmpegReturnCode)
221  {
222  throw std::runtime_error("setting " + getName() + " parameter to " + optionValue + ": " +
223  getDescriptionFromErrorCode(ffmpegReturnCode));
224  }
225 }
226 
227 void loadOptions(OptionMap& outOptions, void* av_class, int req_flags)
228 {
229  if(!av_class)
230  return;
231 
232  std::multimap<std::string, std::string> optionUnitToParentName;
233  std::vector<Option> childOptions;
234 
235  const AVOption* avOption = NULL;
236 
237 // iterate on options
238 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(51, 12, 0)
239  while((avOption = av_next_option(av_class, avOption)))
240 #else
241  while((avOption = av_opt_next(av_class, avOption)))
242 #endif
243  {
244  if(!avOption || !avOption->name || (avOption->flags & req_flags) != req_flags)
245  {
246  continue;
247  }
248 
249  Option option(*const_cast<AVOption*>(avOption), av_class);
250 
251  if(option.getType() == eOptionBaseTypeChild)
252  {
253  childOptions.push_back(option);
254  }
255  else
256  {
257  outOptions.insert(std::make_pair(option.getName(), option));
258  optionUnitToParentName.insert(std::make_pair(option.getUnit(), option.getName()));
259  }
260  }
261 
262  // iterate on child options
263  for(std::vector<Option>::iterator itOption = childOptions.begin(); itOption != childOptions.end(); ++itOption)
264  {
265  bool parentFound = false;
266  for(std::multimap<std::string, std::string>::iterator itUnit = optionUnitToParentName.begin();
267  itUnit != optionUnitToParentName.end(); ++itUnit)
268  {
269  if(itUnit->first == itOption->getUnit())
270  {
271  std::string nameParentOption = itUnit->second;
272  Option& parentOption = outOptions.at(nameParentOption);
273 
274  parentOption.appendChild(*itOption);
275 
276  // child of a Choice
277  if(parentOption.getType() == eOptionBaseTypeChoice)
278  {
279  if(itOption->getDefaultInt() == parentOption.getDefaultInt())
280  parentOption.setDefaultChildIndex(parentOption.getChilds().size() - 1);
281  }
282 
283  parentFound = true;
284  break;
285  }
286  }
287 
288  if(!parentFound)
289  {
290  LOG_WARN("Can't find a choice option for " << itOption->getName())
291  }
292  }
293 }
294 
295 void loadOptions(OptionArray& outOptions, void* av_class, int req_flags)
296 {
297  OptionMap optionMap;
298  loadOptions(optionMap, av_class, req_flags);
299 
300  for(OptionMap::iterator it = optionMap.begin(); it != optionMap.end(); ++it)
301  outOptions.push_back(it->second);
302 }
303 }
Option(AVOption &avOption, void *avContext)
Definition: Option.cpp:14
void setString(const std::string &value)
Definition: Option.cpp:187
bool getDefaultBool() const
Definition: Option.cpp:70
void loadOptions(OptionMap &outOptions, void *av_class, int req_flags)
Definition: Option.cpp:227
std::string getDefaultString() const
Definition: Option.cpp:85
std::map< std::string, Option > OptionMap
Key: option name / value: option.
Definition: Option.hpp:119
std::vector< Option > OptionArray
Definition: Option.hpp:118
std::pair< int, int > getRatio() const
Definition: Option.cpp:136
void setInt(const int value)
Definition: Option.cpp:169
void checkFFmpegGetOption(const int ffmpegReturnCode) const
Check the return value from FFmpeg functions.
Definition: Option.cpp:210
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
Definition: common.cpp:22
void setRatio(const int num, const int den)
Definition: Option.cpp:193
AVOption * _avOption
Has link (no ownership)
Definition: Option.hpp:101
bool getBool() const
Definition: Option.cpp:95
std::string getName() const
Definition: Option.hpp:44
EOptionBaseType getTypeFromAVOption(const std::string &unit, const AVOptionType avType)
Definition: Option.cpp:23
void checkFFmpegSetOption(const int ffmpegReturnCode, const std::string &optionValue)
Definition: Option.cpp:218
void setDefaultChildIndex(size_t index)
Definition: Option.hpp:87
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
double getDouble() const
Definition: Option.cpp:113
std::vector< Option > _childOptions
Definition: Option.hpp:114
void setDouble(const double value)
Definition: Option.cpp:178
EOptionBaseType getType() const
Definition: Option.cpp:65
double getDefaultDouble() const
Definition: Option.cpp:80
#define LOG_WARN(...)
Definition: log.hpp:29
void * _avContext
Pointer to the corresponding context. Need it to set and get the option values.
Definition: Option.hpp:108
std::pair< int, int > getDefaultRatio() const
Definition: Option.cpp:90
std::string getUnit() const
Definition: Option.hpp:46
EOptionBaseType _type
Definition: Option.hpp:102
int getInt() const
Definition: Option.cpp:104
AVRational Rational
Definition: common.hpp:55
void setFlag(const std::string &flag, const bool enable)
Definition: Option.cpp:145
void setBool(const bool value)
Definition: Option.cpp:160
int getDefaultInt() const
Definition: Option.cpp:75
const std::vector< Option > & getChilds() const
Definition: Option.hpp:83
std::string getString() const
Definition: Option.cpp:122
void appendChild(const Option &child)
Definition: Option.cpp:205