Opened 4 years ago
Closed 4 years ago
#9156 closed defect (invalid)
Option flag usage
Reported by: | S.C. Douglas | Owned by: | |
---|---|---|---|
Priority: | minor | Component: | avutil |
Version: | unspecified | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
I have either badly misunderstood or I have found a fault.
I am using the public API. I have looked at the AVOption referenced by several examples of AVClass with particular interest in
{ x , x , x , AV_OPT_TYPE_CONST, x , x , x , ENC, x }
(where x = don’t care) as this is how I believe options for bit encoded flags are stored. In all the cases I have looked at the flag settings are not mutually exclusive e.g. class "mpegts_muxer_class" flags "latm" and "system_b". I tried code like
Options = NULL;
av_dict_set(&Options,"mpegts_flags","system_b",0);
av_dict_set(&Options,"mpegts_flags","latm", AV_DICT_DONT_OVERWRITE);
ReturnCode = avformat_write_header(OutputContext,&Options);
All that happened was the last flag setting in the list won. I then looked at opt.c and found flags are set in function "write_number"
...
case AV_OPT_TYPE_BOOL:
case AV_OPT_TYPE_FLAGS:
case AV_OPT_TYPE_INT:
*(int *)dst = llrint(num / den) * intnum;
break;
...
For flags to work the way I expect, i.e. you can "or" multiple values, I believe this should read
...
case AV_OPT_TYPE_BOOL:
case AV_OPT_TYPE_INT:
*(int *)dst = llrint(num / den) * intnum;
break;
case AV_OPT_TYPE_FLAGS:
*(int *)dst |= llrint(num / den) * intnum;
break;
...
As a work around I use av_opt_ptr to get the address of the *flags* variable and av_dict_get to get the values, "or" them together myself and then write them to the address using the pointer.
So the question I wish answered is have I fundamentally misunderstood the way bit flags are set in options or have I found a problem?
You misunderstood. av_dict_set() only sets an AVDictionary value of key "mpegts_flags". AV_DICT_DONT_OVERWRITE refers to the AVDictionary only.
Flag parsing happens later, when you pass the &Options dictionary to avformat_write_header. There the textual option for "mpegts_flags" is parsed according to the flags syntax, e.g "+flag" adds the specified flag to the default flags, "-flag" removes it, "flag" sets it and removes all other flags.