IProperty * Property :: getFlagConstant(int32_t position) { IProperty *retval = 0; try { if (getType() != IProperty::PROPERTY_FLAGS) throw std::runtime_error("flag is not of type PROPERTY_FLAGS"); // now, iterate through all options, counting all CONSTS that belong // to the same unit as this option const char* unit = getUnit(); if (!unit || !*unit) throw std::runtime_error("flag doesn't have a unit setting, so can't tell what constants"); // Create a fake class AVClass fakeClass; fakeClass.class_name="XuggleFakeClass"; fakeClass.item_name = fakeContextToName; fakeClass.option = mOptionStart; AVClass *fakeClassPtr = &fakeClass; const AVOption* last = 0; int32_t constNo = -1; do { last = av_opt_next(&fakeClassPtr, last); if (last && last->unit && last->type == AV_OPT_TYPE_CONST && strcmp(unit, last->unit)==0) { // count in the same was as getNumFlagSettings, // and then return if the position is equal ++constNo; if (constNo == position) { retval = Property::make(av_opt_next(&fakeClassPtr, 0), last); } } } while(last); } catch (std::exception & e) { VS_LOG_DEBUG("Error: %s", e.what()); VS_REF_RELEASE(retval); } return retval; }
// If the name starts with "@", try to interpret it as a number, and set *name // to the name of the n-th parameter. static void resolve_positional_arg(void *avobj, char **name) { if (!*name || (*name)[0] != '@') return; char *end = NULL; int pos = strtol(*name + 1, &end, 10); if (!end || *end) return; const AVOption *opt = NULL; int offset = -1; while (1) { opt = av_opt_next(avobj, opt); if (!opt) return; // This is what libavfilter's parser does to skip aliases. if (opt->offset != offset && opt->type != AV_OPT_TYPE_CONST) pos--; if (pos < 0) { *name = (char *)opt->name; return; } offset = opt->offset; } }
/* process a list of value1:value2:..., each value corresponding * to subsequent AVOption, in the order they are declared */ static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options, const char *args) { const AVOption *o = NULL; const char *p = args; char *val; while (*p) { o = av_opt_next(ctx->priv, o); if (!o) { av_log(ctx, AV_LOG_ERROR, "More options provided than " "this filter supports.\n"); return AVERROR(EINVAL); } if (o->type == AV_OPT_TYPE_CONST) continue; val = av_get_token(&p, ":"); if (!val) return AVERROR(ENOMEM); av_dict_set(options, o->name, val, 0); av_freep(&val); if (*p) p++; } return 0; }
IProperty* Property :: getPropertyMetaData(void *aContext, const char *aName) { IProperty *retval = 0; const AVOption* last = 0; try { if (!aContext) throw std::runtime_error("no context passed in"); if (!aName || !*aName) throw std::runtime_error("no property name passed in"); last = av_opt_find(aContext, aName, 0, 0, 0); if (last) { if (last->type != AV_OPT_TYPE_CONST) { retval = Property::make(av_opt_next(aContext, 0), last); } } } catch (std::exception & e) { VS_LOG_DEBUG("Error: %s", e.what()); VS_REF_RELEASE(retval); } return retval; }
IProperty* Property :: getPropertyMetaData(void *aContext, int32_t aPropertyNo) { IProperty *retval = 0; const AVOption* last = 0; try { if (!aContext) throw std::runtime_error("no context passed in"); int32_t optionNo=-1; do { last = av_opt_next(aContext, last); if (last) { if (last->type != AV_OPT_TYPE_CONST) { ++optionNo; // now see if this option position matches the property asked for if (optionNo == aPropertyNo) { retval = Property::make(av_opt_next(aContext, 0), last); break; } } } } while (last); } catch (std::exception & e) { VS_LOG_DEBUG("Error: %s", e.what()); VS_REF_RELEASE(retval); } return retval; }
int32_t Property :: getNumProperties(void *aContext) { int32_t retval=0; const AVOption* last = 0; if (aContext) { do { last = av_opt_next(aContext, last); if (last) { if (last->type != AV_OPT_TYPE_CONST) ++retval; } } while (last); } return retval; }
QString options2StringHelper(void* obj, const char* unit) { qDebug("obj: %p", obj); QString s; const AVOption* opt = NULL; while ((opt = av_opt_next(obj, opt))) { if (opt->type == AV_OPT_TYPE_CONST) { if (!unit) continue; if (!qstrcmp(unit, opt->unit)) s.append(QStringLiteral(" %1=%2").arg(QLatin1String(opt->name)).arg(opt->default_val.i64)); continue; } else { if (unit) continue; } s.append(QStringLiteral("\n%1: ").arg(QLatin1String(opt->name))); switch (opt->type) { case AV_OPT_TYPE_FLAGS: case AV_OPT_TYPE_INT: case AV_OPT_TYPE_INT64: s.append(QStringLiteral("(%1)").arg(opt->default_val.i64)); break; case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_FLOAT: s.append(QStringLiteral("(%1)").arg(opt->default_val.dbl, 0, 'f')); break; case AV_OPT_TYPE_STRING: if (opt->default_val.str) s.append(QStringLiteral("(%1)").arg(QString::fromUtf8(opt->default_val.str))); break; case AV_OPT_TYPE_RATIONAL: s.append(QStringLiteral("(%1/%2)").arg(opt->default_val.q.num).arg(opt->default_val.q.den)); break; default: break; } if (opt->help) s.append(QLatin1String(" ")).append(QString::fromUtf8(opt->help)); if (opt->unit && opt->type != AV_OPT_TYPE_CONST) s.append(QLatin1String("\n ")).append(options2StringHelper(obj, opt->unit)); } return s; }
int32_t Property :: getNumFlagSettings() { int32_t retval = 0; try { if (getType() != IProperty::PROPERTY_FLAGS) throw std::runtime_error("flag is not of type PROPERTY_FLAGS"); // now, iterate through all options, counting all CONSTS that belong // to the same unit as this option const char* unit = getUnit(); if (!unit || !*unit) throw std::runtime_error("flag doesn't have a unit setting, so can't tell what constants"); // Create a fake class AVClass fakeClass; fakeClass.class_name="XuggleFakeClass"; fakeClass.item_name = fakeContextToName; fakeClass.option = mOptionStart; AVClass *fakeClassPtr = &fakeClass; const AVOption* last = 0; do { last = av_opt_next(&fakeClassPtr, last); if (last && last->unit && last->type == AV_OPT_TYPE_CONST && strcmp(unit, last->unit)==0) ++retval; } while(last); } catch (std::exception & e) { VS_LOG_DEBUG("Error: %s", e.what()); retval = -1; } return retval; }
IProperty * Property :: getFlagConstant(const char* aName) { IProperty *retval = 0; try { if (getType() != IProperty::PROPERTY_FLAGS) throw std::runtime_error("flag is not of type PROPERTY_FLAGS"); // now, iterate through all options, counting all CONSTS that belong // to the same unit as this option const char* unit = getUnit(); if (!unit || !*unit) throw std::runtime_error("flag doesn't have a unit setting, so can't tell what constants"); AVClass fakeClass; fakeClass.class_name="XuggleFakeClass"; fakeClass.item_name = fakeContextToName; fakeClass.option = mOptionStart; const AVOption* last = 0; last = av_opt_find(&fakeClass, aName, unit, 0, 0); if (last) { if (last->type == AV_OPT_TYPE_CONST) { retval = Property::make(av_opt_next(&fakeClass, 0), last); } } } catch (std::exception & e) { VS_LOG_DEBUG("Error: %s", e.what()); VS_REF_RELEASE(retval); } return retval; }
static void add_parameters( mlt_properties params, void *object, int req_flags, const char *unit, const char *subclass ) { const AVOption *opt = NULL; // For each AVOption on the AVClass object #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0) while ( ( opt = av_opt_next( object, opt ) ) ) #else while ( ( opt = av_next_option( object, opt ) ) ) #endif { // If matches flags and not a binary option (not supported by Mlt) if ( !( opt->flags & req_flags ) || ( opt->type == AV_OPT_TYPE_BINARY ) ) continue; // Ignore constants (keyword values) if ( !unit && opt->type == AV_OPT_TYPE_CONST ) continue; // When processing a groups of options (unit)... // ...ignore non-constants else if ( unit && opt->type != AV_OPT_TYPE_CONST ) continue; // ...ignore constants not in this group else if ( unit && opt->type == AV_OPT_TYPE_CONST && strcmp( unit, opt->unit ) ) continue; // ..add constants to the 'values' sequence else if ( unit && opt->type == AV_OPT_TYPE_CONST ) { char key[20]; snprintf( key, 20, "%d", mlt_properties_count( params ) ); mlt_properties_set( params, key, opt->name ); continue; } // Create a map for this option. mlt_properties p = mlt_properties_new(); char key[20]; snprintf( key, 20, "%d", mlt_properties_count( params ) ); // Add the map to the 'parameters' sequence. mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); // Add the parameter metadata for this AVOption. mlt_properties_set( p, "identifier", opt->name ); if ( opt->help ) { if ( subclass ) { char *s = malloc( strlen( opt->help ) + strlen( subclass ) + 4 ); strcpy( s, opt->help ); strcat( s, " (" ); strcat( s, subclass ); strcat( s, ")" ); mlt_properties_set( p, "description", s ); free( s ); } else mlt_properties_set( p, "description", opt->help ); } switch ( opt->type ) { case AV_OPT_TYPE_FLAGS: mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "flags" ); break; case AV_OPT_TYPE_INT: if ( !opt->unit ) { mlt_properties_set( p, "type", "integer" ); if ( opt->min != INT_MIN ) mlt_properties_set_int( p, "minimum", (int) opt->min ); if ( opt->max != INT_MAX ) mlt_properties_set_int( p, "maximum", (int) opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_int( p, "default", (int) opt->default_val.dbl ); #endif } else { mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "integer or keyword" ); } break; case AV_OPT_TYPE_INT64: mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "format", "64-bit" ); if ( opt->min != INT64_MIN ) mlt_properties_set_int64( p, "minimum", (int64_t) opt->min ); if ( opt->max != INT64_MAX ) mlt_properties_set_int64( p, "maximum", (int64_t) opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_int64( p, "default", (int64_t) opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_FLOAT: mlt_properties_set( p, "type", "float" ); if ( opt->min != FLT_MIN && opt->min != -340282346638528859811704183484516925440.0 ) mlt_properties_set_double( p, "minimum", opt->min ); if ( opt->max != FLT_MAX ) mlt_properties_set_double( p, "maximum", opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_double( p, "default", opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_DOUBLE: mlt_properties_set( p, "type", "float" ); mlt_properties_set( p, "format", "double" ); if ( opt->min != DBL_MIN ) mlt_properties_set_double( p, "minimum", opt->min ); if ( opt->max != DBL_MAX ) mlt_properties_set_double( p, "maximum", opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_double( p, "default", opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_STRING: mlt_properties_set( p, "type", "string" ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set( p, "default", opt->default_val.str ); #endif break; case AV_OPT_TYPE_RATIONAL: mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "numerator:denominator" ); break; case AV_OPT_TYPE_CONST: default: mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "format", "constant" ); break; } // If the option belongs to a group (unit) and is not a constant (keyword value) if ( opt->unit && opt->type != AV_OPT_TYPE_CONST ) { // Create a 'values' sequence. mlt_properties values = mlt_properties_new(); // Recurse to add constants in this group to the 'values' sequence. add_parameters( values, object, req_flags, opt->unit, NULL ); if ( mlt_properties_count( values ) ) mlt_properties_set_data( p, "values", values, 0, (mlt_destructor) mlt_properties_close, NULL ); else mlt_properties_close( values ); } } }
const AVOption *av_next_option(void *obj, const AVOption *last) { return av_opt_next(obj, last); }
static int process_options(AVFilterContext *ctx, AVDictionary **options, const char *args) { const AVOption *o = NULL; int ret, count = 0; char *av_uninit(parsed_key), *av_uninit(value); const char *key; int offset= -1; if (!args) return 0; while (*args) { const char *shorthand = NULL; o = av_opt_next(ctx->priv, o); if (o) { if (o->type == AV_OPT_TYPE_CONST || o->offset == offset) continue; offset = o->offset; shorthand = o->name; } ret = av_opt_get_key_value(&args, "=", ":", shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, &parsed_key, &value); if (ret < 0) { if (ret == AVERROR(EINVAL)) av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", args); else av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args, av_err2str(ret)); return ret; } if (*args) args++; if (parsed_key) { key = parsed_key; while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */ } else { key = shorthand; } av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); if (av_opt_find(ctx, key, NULL, 0, 0)) { ret = av_opt_set(ctx, key, value, 0); if (ret < 0) { av_free(value); av_free(parsed_key); return ret; } } else { av_dict_set(options, key, value, 0); if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) { if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) { if (ret == AVERROR_OPTION_NOT_FOUND) av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); av_free(value); av_free(parsed_key); return ret; } } } av_free(value); av_free(parsed_key); count++; } if (ctx->enable_str) { ret = set_enable_expr(ctx, ctx->enable_str); if (ret < 0) return ret; } return count; }
std::vector<option> dictionary::get_options(void * obj) { if (obj == NULL) { return std::vector<option>(); } std::vector<option> retval; const AVOption * avopt = NULL; while ((avopt = av_opt_next(obj, avopt)) != NULL) { option o; auto dst = (uint8_t*)obj + avopt->offset; if (avopt->name != NULL){ o.name = avopt->name; } if (avopt->help != NULL){ o.help = avopt->help; } if (avopt->unit != NULL){ o.unit = avopt->unit; } o.flags = avopt->flags; o.max = avopt->max; o.min = avopt->min; o.type = dictionary::pimpl_dictionary::convertFrom(avopt->type); //http://ffmpeg.org/doxygen/trunk/opt_8c_source.html switch (o.type){ case option_type::FLAGS: case option_type::INT: case option_type::INT64: case option_type::DURATION: case option_type::PIXEL_FMT://maybe add pixel format to variant? case option_type::SAMPLE_FMT://maybe add sample format to variant? o.default_val = avopt->default_val.i64; break; case option_type::DOUBLE: case option_type::FLOAT: case option_type::REAL_CONST: o.default_val = avopt->default_val.dbl; break; case option_type::COLOR: case option_type::IMAGE_SIZE: case option_type::VIDEO_RATE: case option_type::STRING: if (avopt->default_val.str != NULL){ o.default_val = avopt->default_val.str; } else{ o.default_val = ""; } break; case option_type::RATIONAL: o.default_val = rational(avopt->default_val.q.num, avopt->default_val.q.den); break; //TODO: implement dict //TODO: implement channel_layout default: assert(false && "Not Implemented!!"); } retval.push_back(o); } return retval; }
int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe) { BSFCompatContext *priv = bsfc->priv_data; AVPacket pkt = { 0 }; int ret; if (!priv->ctx) { ret = av_bsf_alloc(bsfc->filter, &priv->ctx); if (ret < 0) return ret; ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx); if (ret < 0) return ret; priv->ctx->time_base_in = avctx->time_base; if (bsfc->args && bsfc->filter->priv_class) { const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL); const char * shorthand[2] = {NULL}; if (opt) shorthand[0] = opt->name; ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":"); } ret = av_bsf_init(priv->ctx); if (ret < 0) return ret; } pkt.data = buf; pkt.size = buf_size; ret = av_bsf_send_packet(priv->ctx, &pkt); if (ret < 0) return ret; *poutbuf = NULL; *poutbuf_size = 0; ret = av_bsf_receive_packet(priv->ctx, &pkt); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) return 0; else if (ret < 0) return ret; *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE); if (!*poutbuf) { av_packet_unref(&pkt); return AVERROR(ENOMEM); } *poutbuf_size = pkt.size; memcpy(*poutbuf, pkt.data, pkt.size); av_packet_unref(&pkt); /* drain all the remaining packets we cannot return */ while (ret >= 0) { ret = av_bsf_receive_packet(priv->ctx, &pkt); av_packet_unref(&pkt); } if (!priv->extradata_updated) { /* update extradata in avctx from the output codec parameters */ if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) { av_freep(&avctx->extradata); avctx->extradata_size = 0; avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) return AVERROR(ENOMEM); memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size); avctx->extradata_size = priv->ctx->par_out->extradata_size; } priv->extradata_updated = 1; } return 1; }
void loadOptions( OptionMap& outOptions, void* av_class, int req_flags ) { if( ! av_class ) return; std::multimap<std::string, std::string> optionUnitToParentName; std::vector<Option> childOptions; const AVOption* avOption = NULL; // iterate on options #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 51, 12, 0 ) while( ( avOption = av_next_option( av_class, avOption ) ) ) #else while( ( avOption = av_opt_next( av_class, avOption ) ) ) #endif { if( ! avOption || ! avOption->name || ( avOption->flags & req_flags ) != req_flags ) { continue; } Option option( *const_cast<AVOption*>( avOption ), av_class ); if( option.getType() == eOptionBaseTypeChild ) { childOptions.push_back( option ); } else { outOptions.insert( std::make_pair( option.getName(), option ) ); optionUnitToParentName.insert( std::make_pair( option.getUnit(), option.getName() ) ); } } // iterate on child options for( std::vector<Option>::iterator itOption = childOptions.begin(); itOption != childOptions.end(); ++itOption ) { bool parentFound = false; for( std::multimap<std::string, std::string>::iterator itUnit = optionUnitToParentName.begin(); itUnit != optionUnitToParentName.end(); ++itUnit ) { if( itUnit->first == itOption->getUnit() ) { std::string nameParentOption = itUnit->second; Option& parentOption = outOptions.at( nameParentOption ); parentOption.appendChild( *itOption ); // child of a Choice if( parentOption.getType() == eOptionBaseTypeChoice ) { if( itOption->getDefaultInt() == parentOption.getDefaultInt() ) parentOption.setDefaultChildIndex( parentOption.getChilds().size() - 1 ); } parentFound = true; break; } } if( ! parentFound ) { LOG_WARN( "Can't find a choice option for " << itOption->getName() ) } } }