[Libav-user] movflags/faststart flag for avcodec_open2

Jodon Karlik jodonk at gmail.com
Fri May 4 06:02:55 EEST 2018

> Hello,
>>>> I am trying to ensure that I have the moov metadata for H.264 encoded
>>>> video at the beginning of the file. I have seen examples online that
>>>> indicate I need to give ffmpeg the "-movflags +faststart"  option, but I am
>>>> coding against libav*. How do these options translate to the options given
>>>> to the AVDictionary parameter of avcodec_open2? Or rather, am I barking up
>>>> the wrong tree entirely?
>>>> I assumed that it was trivially a dictionary entry with key "movflags"
>>>> and value "faststart" after I inspected movenc.c in libavformat, but this
>>>> is not currently working for me and I need to determine what I have wrong
>>>> (the "how" or the "what"). I appreciate any help.
>>>> --michael
>>>> _______________________________________________
>>>> Libav-user mailing list
>>>> Libav-user at ffmpeg.org
>>>> http://ffmpeg.org/mailman/listinfo/libav-user
>>> You can search in dict.h and use: int av_dict_set(AVDictionary **pm,
>>> const char *key, const char *value, int flags).
>>> Example:
>>> AVDictionary* myOptions;
>>> av_dict_set( &myOptions, "movflags", "+faststart", 0 );
>>> av_dict_set will allocate the dictionary for you.
>>> To understand how this all works:  there is a bunch of code in ffmpeg
>>> that deals with AVOptions (and these dictionaries) and converts human
>>> readable data into the right flags.  In the ffmpeg source code, in
>>> libavformat/movenc.c you can find:
>>> static const AVOption options[] = {
>>>     { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags),
>>> AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX,
>>> AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
>>> ...
>>>     { "faststart", "Run a second pass to put the index (moov atom) at
>>> the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 =
>>> "movflags" },
>>> The first one defines the human-readable "movflags" to access the
>>> "flags" member variable, and the one further down that ends with "movflags"
>>> is a way of saying the "faststart" string refers to a flag that applies to
>>> the variable movflags.  In opt.c you'll find special code for
>>> AV_OPT_TYPE_FLAGS that deals with prefixing with "+" or "-" which will add
>>> or remove flags from the variable specified.  Once you know all of this,
>>> the code (and settings) become quite readable which is nice.
>>> Everything that is an AVClass can be accessed using these types of
>>> options through the AVOptions interfaces (libavutil/opt.h), or passing in
>>> an AVDictionary with the options when creating it, as you've found.  I've
>>> found it helpful when starting out to use the AVOptions interface rather
>>> than AVDictionary.  The reason being, there's more immediately feedback
>>> through the return code of av_opt_set, and you can grab the configuration
>>> of an object through av_opt_serialize.  This will help you catch errors
>>> like setting movflags on the stream rather than the muxer.
>>> Cheers.
>>> _______________________________________________
>>> Libav-user mailing list
>>> Libav-user at ffmpeg.org
>>> http://ffmpeg.org/mailman/listinfo/libav-user
> On Thu, May 3, 2018 at 3:31 PM, Michael Armes <michael.armes at gmail.com>
> wrote:
>> Jordan,
>> Thanks for the reply. It's great to know that I'm on track with the
>> option name/value and my use of av_dict_set. Also good to know that the -/+
>> logic applies here.
>> Can you confirm that:
>> AVDictionary* myOptions;
>> av_dict_set( &myOptions, "movflags", "+faststart", 0 );
>> avcodec_open2(context, codec, &myOptions);
>> should set the option on the muxer?
>> Interestingly, if I use av_opt_serialize on the AvCodecContext after
>> opening
>> av_opt_serialize(context, 0, 0, &buffer, ':', ';');
>> after opening the codec, I don't see the flag set.
>> b:1216000;ab:1216000;bt:4000000;flags:0x80400000;me_method:-
>> 1;time_base:1/20;g:12;ar:0;ac:0;cutoff:0;frame_size:0;frame_
>> number:0;delay:0;qcomp:-1.00000
>> I'm looking for the 7th bit (128) to be set on flags, yes?
>> On Wed, May 2, 2018 at 5:45 PM, Jodon Karlik <jodonk at gmail.com> wrote:
>>> My apologizes. Here is the full list of options from the serialize. I do
> appreciate any help. Heads up that I will be away starting tomorrow until
> Monday. If I don't respond timely, it doesn't mean I don't care. :-)
> b:1216000;ab:1216000;bt:4000000;flags:0x80400000;me_
> method:-1;time_base:1/20;g:12;ar:0;ac:0;cutoff:0;frame_size:
> 0;frame_number:0;delay:0;qcomp:-1.000000;qblur:-1.
> 000000;qmin:-1;qmax:-1;qdiff:-1;bf:0;b_qfactor:-1.000000;rc_
> strategy:0;b_strategy:-1;ps:0;mv_bits:0;header_bits:0;i_tex_
> bits:0;p_tex_bits:0;i_count:0;p_count:0;skip_count:0;misc_
> bits:0;frame_bits:0;codec_tag:0;bug:0x00000001;strict:0;b_
> qoffset:1.250000;err_detect:0x00000000;has_b_frames:2;
> block_align:0;mpeg_quant:0;qsquish:0.000000;rc_qmod_amp:
> 0.000000;rc_qmod_freq:0;rc_override_count:0;rc_eq:;
> maxrate:0;minrate:0;bufsize:0;rc_buf_aggressivity:1.000000;
> i_qfactor:-1.000000;i_qoffset:0.000000;rc_init_cplx:0.
> 000000;dct:0;lumi_mask:0.000000;tcplx_mask:0.000000;
> scplx_mask:0.000000;p_mask:0.000000;dark_mask:0.000000;
> idct:0;slice_count:0;ec:0x00000003;bits_per_coded_
> sample:0;pred:0;aspect:0/1;sar:0/1;debug:0x00000000;
> vismv:0x00000000;cmp:-1;subcmp:0;mbcmp:0;ildctcmp:8;
> dia_size:0;last_pred:0;preme:0;precmp:0;pre_dia_size:0;
> subq:-1;dtg_active_format:0;me_range:-1;ibias:999999;
> pbias:999999;global_quality:0;coder:-1;context:0;slice_
> flags:0;xvmc_acceleration:0;mbd:0;stream_codec_tag:0;sc_
> threshold:-1;lmin:0;lmax:0;nr:-1;rc_init_occupancy:-1;
> flags2:0x00000000;error:0;threads:0;me_threshold:0;mb_
> threshold:0;dc:0;nssew:8;skip_top:0;skip_bottom:0;profile:-
> 99;level:-99;lowres:0;skip_threshold:0;skip_factor:0;
> skip_exp:0;skipcmp:13;border_mask:0.000000;mblmin:236;
> mblmax:3658;mepc:256;skip_loop_filter:0;skip_idct:0;
> skip_frame:0;bidir_refine:1;brd_scale:0;keyint_min:-1;
> refs:-1;chromaoffset:0;trellis:-1;sc_factor:6;mv0_
> threshold:256;b_sensitivity:40;compression_level:-1;min_
> prediction_order:0;max_prediction_order:0;timecode_
> frame_start:-1;bits_per_raw_sample:0;channel_layout:0;
> request_channel_layout:0;rc_max_vbv_use:0.000000;rc_min_
> vbv_use:3.000000;ticks_per_frame:2;color_primaries:2;
> color_trc:2;colorspace:2;color_range:0;chroma_sample_
> location:0;log_level_offset:0;slices:0;thread_type:
> 0x00000000;audio_service_type:0;request_sample_fmt:u8;pkt_
> timebase:0/1;sub_charenc:;sub_charenc_mode:0x00000000;sub_
> text_format:0;refcounted_frames:false;side_data_only_
> packets:true;skip_alpha:false;field_order:0;dump_separator:;
> codec_whitelist:;pixel_format:yuv420p;video_size:1204x338
Heads-up the rule here is to not "top post" (i.e. put replies below the
original message) and the mods are quite strict on it.  I was hoping
someone with more experience would chime in, but I'll give this a shot:

I think you're applying the dictionary to the wrong object.  If you look at
the previous code you're targeting ("faststart" in movenc.c) you'll notice
it has a bunch of variables that are nowhere to be found (e.g.
min_frag_duration).  This indicates to me that you're inspecting an object
that doesn't have the ability for faststart which you're requesting.  It
could be that you're writing an AVI as opposed to an MP4 or a MOV, or
what's being applied is to the AVCodecContext as opposed to the
AVFormatContext (I didn't read into the avcodec_open2, but that would make
sense).  For my stuff, I wrote my own C++ wrapper which applies these
things in descending order:  Muxer (AVFormatContext), the Stream
(AVCodecContext->stream pointers of AVStream), and the Codec itself
(AVCodecContext which I think is what you're doing here).  Again, I use
av_opt which would catch these things.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20180503/65c10d91/attachment.html>

More information about the Libav-user mailing list