Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
>>>>>
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 =
>>>>
FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM,
>>>>
"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;qma
>>
x:-1;qdiff:-1;bf:0;b_qfactor:-1.000000;rc_strategy:0;b_strat
>>
egy:-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;m
>>
peg_quant:0;qsquish:0.000000;rc_qmod_amp:0.000000;rc_qmod_fr
>>
eq: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.0000
>>
00;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.
>
Cheers.
Thank you for the help. I think I finally have a handle on what is going
on. Firstly, I need to pass the dictionary to avformat_write_header. There
are some children on the AVFormatContext that need the option set and this
will handle that through avformat_init_output. However, this is only part
of the way there. Now I am getting invalid mp4s without the moov atom
entirely.
Secondly, I have a custom IO callbacks that I hooked up
through avio_alloc_context. This is necessary because I am in the cloud and
do not have a filesystem. The faststart second pass attempts to reopen the
file for reading to avoid some read/seek loops. This open is failing. My
guess is that I also need to supply custom io_open and io_close callbacks
to my AVFormatContext.
I will take it from here.
Cheers,
Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <
http://ffmpeg.org/pipermail/libav-user/attachments/20180508/c495d8f4/attachment.html
>