Opened 3 years ago

Closed 3 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?

Change History (1)

comment:1 by Marton Balint, 3 years ago

Resolution: invalid
Status: newclosed

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.

Note: See TracTickets for help on using tickets.