123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761(* Line *)typeinputtypeoutput(* Container *)type'acontainer(** {1 Media types} *)typeaudio=[`Audio]typevideo=[`Video]typesubtitle=[`Subtitle]typemedia_type=Media_types.t(* Format *)type('line,'media)formatexternalqp2lambda:unit->int="ocaml_avutil_qp2lambda"letqp2lambda=qp2lambda()externalexpr_parse_and_eval:string->float="ocaml_avutil_expr_parse_and_eval"(* Frame *)moduleFrame=structtype'mediatexternalpts:_t->Int64.toption="ocaml_avutil_frame_pts"externalset_pts:_t->Int64.toption->unit="ocaml_avutil_frame_set_pts"externalduration:_t->Int64.toption="ocaml_avutil_frame_duration"externalset_duration:_t->Int64.toption->unit="ocaml_avutil_frame_set_duration"externalpkt_dts:_t->Int64.toption="ocaml_avutil_frame_pkt_dts"externalset_pkt_dts:_t->Int64.toption->unit="ocaml_avutil_frame_set_pkt_dts"externalmetadata:_t->(string*string)array="ocaml_avutil_frame_metadata"letmetadataframe=Array.to_list(metadataframe)externalset_metadata:_t->(string*string)array->unit="ocaml_avutil_frame_set_metadata"letset_metadataframemetadata=set_metadataframe(Array.of_listmetadata)externalbest_effort_timestamp:_t->Int64.toption="ocaml_avutil_frame_best_effort_timestamp"externalcopy:'at->'bt->unit="ocaml_avutil_frame_copy"endtype'mediaframe='mediaFrame.ttypeerror=[`Bsf_not_found|`Decoder_not_found|`Demuxer_not_found|`Encoder_not_found|`Eof|`Exit|`Filter_not_found|`Invalid_data|`Muxer_not_found|`Option_not_found|`Patch_welcome|`Protocol_not_found|`Stream_not_found|`Bug|`Eagain|`Unknown|`Experimental|`Otherofint|`Failureofstring]externalstring_of_error:error->string="ocaml_avutil_string_of_error"exceptionErroroferrorlet()=Printexc.register_printer(function|Errorerr->Some(Printf.sprintf"Avutil.Error(%s)"(string_of_errorerr))|_->None)let()=Callback.register_exception"ffmpeg_exn_error"(Error`Unknown);Callback.register"ffmpeg_exn_failure"(funs->raise(Error(`Failures)))typedata=(int,Bigarray.int8_unsigned_elt,Bigarray.c_layout)Bigarray.Array1.tletcreate_datalen=Bigarray.Array1.createBigarray.int8_unsignedBigarray.c_layoutlentyperational={num:int;den:int}externalav_d2q:float->rational="ocaml_avutil_av_d2q"letstring_of_rational{num;den}=Printf.sprintf"%d/%d"numdenexternaltime_base:unit->rational="ocaml_avutil_time_base"moduleTime_format=structtypet=[`Second|`Millisecond|`Microsecond|`Nanosecond]endmoduleLog=structtypelevel=[`Quiet|`Panic|`Fatal|`Error|`Warning|`Info|`Verbose|`Debug|`Trace]letint_of_level=function|`Quiet->-8|`Panic->0|`Fatal->8|`Error->16|`Warning->24|`Info->32|`Verbose->40|`Debug->48|`Trace->56externalset_level:int->unit="ocaml_avutil_set_log_level"letset_levellevel=set_level(int_of_levellevel)externalsetup_log_callback:unit->unit="ocaml_avutil_setup_log_callback"(*
external process_log : (string -> unit) -> unit = "ocaml_ffmpeg_process_log"
*)letlog_fn=ref(Printf.printf"%s")letlog_fn_m=Mutex.create()letset_callbackfn=setup_log_callback();Mutex.locklog_fn_m;log_fn:=fn;Mutex.unlocklog_fn_mexternalclear_callback:unit->unit="ocaml_avutil_clear_log_callback"letclear_callback()=clear_callback();set_callback(Printf.printf"%s")(*
let () =
ignore (Thread.create (fun () -> process_log (fun msg -> !log_fn msg)) ())
*)endmodulePixel_format=structtypet=Pixel_format.ttypeflag=Pixel_format_flag.ttypecomponent_descriptor={plane:int;step:int;offset:int;shift:int;depth:int;}(* An extra hidden field is stored on the C side
with a reference to the underlying C descriptor
for use with the C functions consuming it. *)typedescriptor={name:string;nb_components:int;log2_chroma_w:int;log2_chroma_h:int;flags:flaglist;comp:component_descriptorlist;alias:stringoption;}externaldescriptor:t->descriptor="ocaml_avutil_pixelformat_descriptor"externalbits:descriptor->int="ocaml_avutil_pixelformat_bits_per_pixel"externalplanes:t->int="ocaml_avutil_pixelformat_planes"externalto_string:t->stringoption="ocaml_avutil_pixelformat_to_string"externalof_string:string->t="ocaml_avutil_pixelformat_of_string"externalget_id:t->int="ocaml_avutil_get_pixel_fmt_id"externalfind_id:int->t="ocaml_avutil_find_pixel_fmt_from_id"endmoduleChannel_layout=structtypelayout=Channel_layout.ttypetexternalcompare:t->t->bool="ocaml_avutil_compare_channel_layout"externalget_description:t->string="ocaml_avutil_get_channel_layout_description"externalfind:string->t="ocaml_avutil_get_channel_layout"externalget_nb_channels:t->int="ocaml_avutil_get_channel_layout_nb_channels"externalget_default:int->t="ocaml_avutil_get_default_channel_layout"typeopaqueexternalstart_standard_iteration:unit->opaque="ocaml_avutil_start_standard_iteration"externalget_standard:opaque->toption="ocaml_avutil_get_standard"letstandard_layouts=letstart=start_standard_iteration()inletrecfret=matchget_standardstartwithSomel->f(l::ret)|None->retinf[]letmono=find"mono"letstereo=find"stereo"letfive_point_one=find"5.1"externalget_mask:t->int64option="ocaml_avutil_get_channel_mask"letget_native_id=get_maskendmoduleSample_format=structtypet=Sample_format.texternalget_name:t->stringoption="ocaml_avutil_get_sample_fmt_name"externalget_id:t->int="ocaml_avutil_get_sample_fmt_id"externalfind:string->t="ocaml_avutil_find_sample_fmt"externalfind_id:int->t="ocaml_avutil_find_sample_fmt_from_id"endmoduleAudio=structexternalcreate_frame:Sample_format.t->Channel_layout.t->int->int->audioframe="ocaml_avutil_audio_create_frame"externalframe_get_sample_format:audioframe->Sample_format.t="ocaml_avutil_audio_frame_get_sample_format"externalframe_get_sample_rate:audioframe->int="ocaml_avutil_audio_frame_get_sample_rate"externalframe_get_channels:audioframe->int="ocaml_avutil_audio_frame_get_channels"externalframe_get_channel_layout:audioframe->Channel_layout.t="ocaml_avutil_audio_frame_get_channel_layout"externalframe_nb_samples:audioframe->int="ocaml_avutil_audio_frame_nb_samples"externalframe_copy_samples:audioframe->int->audioframe->int->int->unit="ocaml_avutil_audio_frame_copy_samples"endmoduleVideo=structtypeplanes=(data*int)arrayexternalcreate_frame:int->int->Pixel_format.t->videoframe="ocaml_avutil_video_create_frame"externalframe_get_linesize:videoframe->int->int="ocaml_avutil_video_frame_get_linesize"externalget_frame_planes:videoframe->bool->planes="ocaml_avutil_video_get_frame_bigarray_planes"letframe_visit~make_writablevisitframe=visit(get_frame_planesframemake_writable);frameexternalframe_get_width:videoframe->int="ocaml_avutil_video_frame_width"externalframe_get_height:videoframe->int="ocaml_avutil_video_frame_height"externalframe_get_pixel_format:videoframe->Pixel_format.t="ocaml_avutil_video_frame_get_pixel_format"externalframe_get_pixel_aspect:videoframe->rationaloption="ocaml_avutil_video_frame_get_pixel_aspect"endmoduleSubtitle=structlettime_base()={num=1;den=100}externalcreate_frame:int64->int64->stringarray->subtitleframe="ocaml_avutil_subtitle_create_frame"letcreate_framestart_timeend_timelines=letnum_time_base=float_of_int(time_base()).numinletden_time_base=float_of_int(time_base()).denincreate_frame(Int64.of_float(start_time*.den_time_base/.num_time_base))(Int64.of_float(end_time*.den_time_base/.num_time_base))(Array.of_listlines)externalframe_to_lines:subtitleframe->int64*int64*stringarray="ocaml_avutil_subtitle_to_lines"letframe_to_linest=letnum_time_base=float_of_int(time_base()).numinletden_time_base=float_of_int(time_base()).deninlets,e,lines=frame_to_linestinInt64.(to_floats*.num_time_base/.den_time_base,to_floate*.num_time_base/.den_time_base,Array.to_listlines)endmoduleOptions=structtypettype'aentry={default:'aoption;min:'aoption;max:'aoption;values:(string*'a)list;}typeflag=[`Encoding_param|`Decoding_param|`Audio_param|`Video_param|`Subtitle_param|`Export|`Readonly|`Bsf_param|`Runtime_param|`Filtering_param|`Deprecated|`Child_consts]externalint_of_flag:flag->int="ocaml_avutil_av_opt_int_of_flag"letflags_of_flags_flags=List.fold_left(funflagsflag->if_flagslandint_of_flagflag=0thenflagselseflag::flags)[][`Encoding_param;`Decoding_param;`Audio_param;`Video_param;`Subtitle_param;`Export;`Readonly;`Bsf_param;`Runtime_param;`Filtering_param;`Deprecated;`Child_consts;]typespec=[`Flagsofint64entry|`Intofintentry|`Int64ofint64entry|`Floatoffloatentry|`Doubleoffloatentry|`Stringofstringentry|`Rationalofrationalentry|`Binaryofstringentry|`Dictofstringentry|`UInt64ofint64entry|`Image_sizeofstringentry|`Pixel_fmtofPixel_format.tentry|`Sample_fmtofSample_format.tentry|`Video_rateofstringentry|`Durationofint64entry|`Colorofstringentry|`Channel_layoutofChannel_layout.tentry|`Boolofboolentry]typeopt={name:string;help:stringoption;flags:flaglist;spec:spec;}type'a_entry={_default:'aoption;_min:'aoption;_max:'aoption}typeconstantexternaldefault_int64:constant->int64="ocaml_avutil_avopt_default_int64"externaldefault_double:constant->float="ocaml_avutil_avopt_default_double"externaldefault_string:constant->string="ocaml_avutil_avopt_default_string"type_spec=[`Constantofconstant_entry|`Flagsofint64_entry|`Intofint_entry|`Int64ofint64_entry|`Floatoffloat_entry|`Doubleoffloat_entry|`Stringofstring_entry|`Rationalofrational_entry|`Binaryofstring_entry|`Dictofstring_entry|`UInt64ofint64_entry|`Image_sizeofstring_entry|`Pixel_fmtofPixel_format.t_entry|`Sample_fmtofSample_format.t_entry|`Video_rateofstring_entry|`Durationofint64_entry|`Colorofstring_entry|`Channel_layoutofChannel_layout.t_entry|`Boolofbool_entry]type_opt_cursortype_class_cursortype_cursor={_opt_cursor:_opt_cursor;_class_cursor:_class_cursor}type_opt={_name:string;_help:stringoption;_spec:_spec;_flags:int;_unit:stringoption;_cursor:_cursoroption;}exceptionAv_opt_iter_not_implementedof_cursoroptionlet()=Callback.register_exception"av_opt_iter_not_implemented"(Av_opt_iter_not_implementedNone)externalav_opt_iter:_cursoroption->t->_optoption="ocaml_avutil_av_opt_iter"letconstant_of_optopt(name,{_default;_})=letappendfnl=(name,fn(Option.get_default))::linletspec=(* See: https://ffmpeg.org/doxygen/trunk/opt_8c_source.html#l01281 *)matchopt.specwith(* Int *)|`Flags({values;_}asspec)->`Int64{specwithvalues=appenddefault_int64values}|`Int({values;_}asspec)->`Int{specwithvalues=append(funv->Int64.to_int(default_int64v))values;}|`Int64({values;_}asspec)->`Int64{specwithvalues=appenddefault_int64values}|`UInt64({values;_}asspec)->`UInt64{specwithvalues=appenddefault_int64values}|`Duration({values;_}asspec)->`Duration{specwithvalues=appenddefault_int64values}|`Bool({values;_}asspec)->`Bool{specwithvalues=append(funv->default_int64v=0L)values;}(* Float *)|`Float({values;_}asspec)->`Float{specwithvalues=appenddefault_doublevalues}|`Double({values;_}asspec)->`Double{specwithvalues=appenddefault_doublevalues}(* Rational *)(* This is surprising but this is the current implementation
it looks like. Might be historical. *)|`Rational({values;_}asspec)->`Rational{specwithvalues=append(funv->av_d2q(default_doublev))values;}(* String *)|`String({values;_}asspec)->`String{specwithvalues=appenddefault_stringvalues}|`Video_rate({values;_}asspec)->`Video_rate{specwithvalues=appenddefault_stringvalues}|`Color({values;_}asspec)->`Color{specwithvalues=appenddefault_stringvalues}|`Image_size({values;_}asspec)->`Image_size{specwithvalues=appenddefault_stringvalues}|`Dict({values;_}asspec)->`Dict{specwithvalues=appenddefault_stringvalues}(* Other *)|`Channel_layout({values;_}asspec)->`Channel_layout{specwithvalues=append(funv->Channel_layout.find(default_stringv))values;}|`Sample_fmt({values;_}asspec)->`Sample_fmt{specwithvalues=append(funv->Sample_format.find_id(Int64.to_int(default_int64v)))values;}|`Pixel_fmt({values;_}asspec)->`Pixel_fmt{specwithvalues=append(funv->Pixel_format.find_id(Int64.to_int(default_int64v)))values;}|_->failwith"Incompatible constant!"in{optwithspec}letoptsv=letconstants=Hashtbl.create10inletopt_of_opt{_name;_help;_spec;_flags;_unit;_}=letspec=match_specwith|`Flags{_default;_min;_max}->`Flags{default=_default;min=_min;max=_max;values=[]}|`Int{_default;_min;_max;_}->`Int{default=_default;min=_min;max=_max;values=[]}|`Int64{_default;_min;_max;_}->`Int64{default=_default;min=_min;max=_max;values=[]}|`Float{_default;_min;_max;_}->`Float{default=_default;min=_min;max=_max;values=[]}|`Double{_default;_min;_max;_}->`Double{default=_default;min=_min;max=_max;values=[]}|`String{_default;_min;_max;_}->`String{default=_default;min=_min;max=_max;values=[]}|`Rational{_default;_min;_max;_}->`Rational{default=_default;min=_min;max=_max;values=[]}|`Binary{_default;_min;_max;_}->`Binary{default=_default;min=_min;max=_max;values=[]}|`Dict{_default;_min;_max;_}->`Dict{default=_default;min=_min;max=_max;values=[]}|`UInt64{_default;_min;_max;_}->`UInt64{default=_default;min=_min;max=_max;values=[]}|`Image_size{_default;_min;_max;_}->`Image_size{default=_default;min=_min;max=_max;values=[]}|`Pixel_fmt{_default;_min;_max;_}->`Pixel_fmt{default=_default;min=_min;max=_max;values=[]}|`Sample_fmt{_default;_min;_max;_}->`Sample_fmt{default=_default;min=_min;max=_max;values=[]}|`Video_rate{_default;_min;_max;_}->`Video_rate{default=_default;min=_min;max=_max;values=[]}|`Duration{_default;_min;_max;_}->`Duration{default=_default;min=_min;max=_max;values=[]}|`Color{_default;_min;_max;_}->`Color{default=_default;min=_min;max=_max;values=[]}|`Channel_layout{_default;_min;_max;_}->`Channel_layout{default=_default;min=_min;max=_max;values=[]}|`Bool{_default;_min;_max;_}->`Bool{default=_default;min=_min;max=_max;values=[]}|`Constant_->assertfalseinletopt={name=_name;help=_help;flags=flags_of_flags_flags;spec}inmatch_unitwith|SomeuwhenHashtbl.memconstantsu->List.fold_leftconstant_of_optopt(Hashtbl.find_allconstantsu)|_->optinletrecf_cursor_opts=matchav_opt_iter_cursorvwith|None->List.mapopt_of_opt_opts|Some{_name;_spec=`Constants;_cursor;_unit;_}->Hashtbl.addconstants(Option.get_unit)(_name,s);f_cursor_opts|Some_opt->f_opt._cursor(_opt::_opts)|exceptionAv_opt_iter_not_implemented_cursor->f_cursor_optsinfNone[](* The type implementation is a tuple [(C object, OCaml value)].
OCaml value is passed to make sure that the C object is not
collected by the GC while running the function. *)typeobjtype'agetter=?search_children:bool->name:string->obj->'aexternalget:'a->?search_children:bool->name:string->'b->'c="ocaml_avutil_get_opt"letget(typea)_type?search_children~name(obj:obj):a=letc,o=Obj.magicobjinletret=get_type?search_children~namecinignoreo;retletget_string=get`Stringletget_int=get`Intletget_int64=get`Int64letget_float=get`Floatletget_rational=get`Rationalletget_image_size=get`Image_sizeletget_pixel_fmt=get`Pixel_fmtletget_sample_fmt=get`Sample_fmtletget_video_rate=get`Video_rateletget_channel_layout=get`Channel_layoutletget_dictionary?search_children~nameobj=Array.to_list(get`Dict?search_children~nameobj)end(* Options *)typevalue=[`Stringofstring|`Intofint|`Int64ofint64|`Floatoffloat]typeopts=(string,value)Hashtbl.tlet_opt_val=function|`Strings->s|`Inti->string_of_inti|`Int64i->Int64.to_stringi|`Floatf->string_of_floatfletopts_default=functionNone->Hashtbl.create0|Someopts->optsletmk_opts_arrayopts=Array.of_list(Hashtbl.fold(funopt_nameopt_valcur->(opt_name,_opt_valopt_val)::cur)opts[])letstring_of_optsopts=Hashtbl.fold(funopt_nameopt_vall->(opt_name^"="^_opt_valopt_val)::l)opts[]|>String.concat","leton_optvfn=matchvwithNone->()|Somev->fnvletadd_audio_opts?channels?channel_layout~sample_rate~sample_format~time_baseopts=Hashtbl.addopts"ar"(`Intsample_rate);on_optchannels(funchannels->Hashtbl.addopts"ac"(`Intchannels));on_optchannel_layout(funchannel_layout->letparam=matchChannel_layout.get_maskchannel_layoutwith|Someid->`Int64id|None->letchannel_layout=Channel_layout.get_default(Channel_layout.get_nb_channelschannel_layout)in`Int64(Option.get(Channel_layout.get_maskchannel_layout))inHashtbl.addopts"channel_layout"param);Hashtbl.addopts"sample_fmt"(`Int(Sample_format.get_idsample_format));Hashtbl.addopts"time_base"(`String(string_of_rationaltime_base))letmk_audio_opts?opts?channels?channel_layout~sample_rate~sample_format~time_base()=let()=match(channels,channel_layout)with|None,None->raise(Error(`Failure"At least one of channels or channel_layout must be passed!"))|_->()inletopts=opts_defaultoptsinadd_audio_opts?channels?channel_layout~sample_rate~sample_format~time_baseopts;optsletadd_video_opts?frame_rate~pixel_format~width~height~time_baseopts=Hashtbl.addopts"pixel_format"(`Int(Pixel_format.get_idpixel_format));Hashtbl.addopts"video_size"(`String(Printf.sprintf"%dx%d"widthheight));Hashtbl.addopts"time_base"(`String(string_of_rationaltime_base));matchframe_ratewith|Somer->Hashtbl.addopts"r"(`String(string_of_rationalr))|None->()letmk_video_opts?opts?frame_rate~pixel_format~width~height~time_base()=letopts=opts_defaultoptsinadd_video_opts?frame_rate~pixel_format~width~height~time_baseopts;optsletfilter_optsunusedopts=Hashtbl.filter_map_inplace(funkv->ifArray.memkunusedthenSomevelseNone)optsmoduleHwContext=structtypedevice_type=Hw_device_type.ttypedevice_contexttypeframe_contextexternalcreate_device_context:device_type->string->(string*string)array->device_context*stringarray="ocaml_avutil_create_device_context"letcreate_device_context?(device="")?optsdevice_type=letopts=opts_defaultoptsinletret,unused=create_device_contextdevice_typedevice(mk_opts_arrayopts)infilter_optsunusedopts;retexternalcreate_frame_context:width:int->height:int->src_pixel_format:Pixel_format.t->dst_pixel_format:Pixel_format.t->device_context->frame_context="ocaml_avutil_create_frame_context"end