Hello Since this commit, metadatas on mp3 (at least) seems to be broken ...
kent1 2010/8/20 <[email protected]> > Revision: 7451 > http://savonet.svn.sourceforge.net/savonet/?rev=7451&view=rev > Author: metamorph68 > Date: 2010-08-20 05:27:36 +0000 (Fri, 20 Aug 2010) > > Log Message: > ----------- > Hello, I'm the faad decoder and I am BACK ! > > Apparently, the mp4 decoding lib is packaged in Debian now, > under the name libmp4ff.. > > Added mime check for AAC and MP4 as the decoder gets > confused and the AAC decoder recognizes MP4 files.. > > Finally removed the formats/ directory! > > Modified Paths: > -------------- > trunk/liquidsoap/src/Makefile > trunk/liquidsoap/src/decoder/taglib_plug.ml > trunk/ocaml-faad/src/Makefile.in > trunk/ocaml-faad/src/faad.ml > trunk/ocaml-faad/src/faad.mli > trunk/ocaml-faad/src/faad_stubs.c > > Added Paths: > ----------- > trunk/liquidsoap/src/decoder/aac_decoder.ml > > Removed Paths: > ------------- > trunk/liquidsoap/src/formats/ > > Modified: trunk/liquidsoap/src/Makefile > =================================================================== > --- trunk/liquidsoap/src/Makefile 2010-08-19 20:30:21 UTC (rev 7450) > +++ trunk/liquidsoap/src/Makefile 2010-08-20 05:27:36 UTC (rev 7451) > @@ -31,15 +31,11 @@ > video_converters/native_video_converter.ml \ > $(if $(W_GAVL),video_converters/gavl_converter.ml) > > -# TODO move all formats to encoders > -formats = \ > - formats/externalformat.ml \ > - # $(if $(W_FAAD),formats/aacformat.ml) \ > - > decoders = \ > decoder/wav_decoder.ml decoder/midi_decoder.ml \ > decoder/metadata_decoder.ml \ > decoder/external_decoder.ml \ > + $(if $(W_FAAD),decoder/aac_decoder.ml) \ > $(if $(W_OGG),decoder/ogg_decoder.ml) \ > $(if $(W_MP3),decoder/mp3.ml) \ > $(if $(W_VORBIS),decoder/vorbisduration.ml) \ > > Copied: trunk/liquidsoap/src/decoder/aac_decoder.ml (from rev 7391, > trunk/liquidsoap/src/formats/aacformat.ml) > =================================================================== > --- trunk/liquidsoap/src/decoder/aac_decoder.ml > (rev 0) > +++ trunk/liquidsoap/src/decoder/aac_decoder.ml 2010-08-20 05:27:36 UTC > (rev 7451) > @@ -0,0 +1,329 @@ > > +(***************************************************************************** > + > + Liquidsoap, a programmable audio stream generator. > + Copyright 2003-2009 Savonet team > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 2 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details, fully stated in the COPYING > + file at the root of the liquidsoap distribution. > + > + You should have received a copy of the GNU General Public License > + along with this program; if not, write to the Free Software > + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 > USA > + > + > *****************************************************************************) > + > +(** Decode and read metadatas of AAC files. *) > + > +open Dtools > + > +(* A custom input function take takes > + * an offset into account *) > +let offset_input input buf offset = > + let len = String.length buf in > + (* If the buff is less than the offset, > + * consume the remaining data. *) > + let ret = > + if len < offset then > + let rec cons len = > + if len < offset then > + let (_,read) = input (offset - len) in > + cons (len+read) > + in > + cons len ; > + ref "" > + else > + (* If the buffer is more than the offset, > + * retain it and consume it first later. *) > + ref (String.sub buf offset (len-offset)) > + in > + let input len = > + let first,fst_len = > + let ret_len = String.length !ret in > + if ret_len > 0 then > + begin > + let fst_len = min len ret_len in > + let hd,tl = > + String.sub !ret 0 fst_len, > + String.sub !ret fst_len (ret_len-fst_len) > + in > + ret := tl ; > + hd, fst_len > + end > + else > + "",0 > + in > + if fst_len > 0 then > + let ret,len = > + if len > fst_len then > + input (len-fst_len) > + else > + "",0 > + in > + Printf.sprintf "%s%s" first ret,(fst_len + len) > + else > + input len > + in > + input,ret > + > +let log = Log.make ["decoder";"aac"] > + > +module Make (Generator:Generator.S_Asio) = > +struct > + > +let create_decoder input = > + let resampler = Rutils.create_audio () in > + let dec = Faad.create () in > + let aacbuflen = 1024 in > + let (aacbuf,len) = input aacbuflen in > + let offset, sample_freq, chans = > + Faad.init dec aacbuf 0 len > + in > + let input,ret = offset_input input aacbuf offset in > + Decoder.Decoder (fun gen -> > + let aacbuf,len = input aacbuflen in > + let pos, data = Faad.decode dec aacbuf 0 len in > + (* We need to keep the data > + * that has not been decoded yet.. *) > + if pos < len then > + ret := Printf.sprintf "%s%s" > + !ret (String.sub aacbuf pos (len-pos)) ; > + let content,length = > + resampler ~audio_src_rate:(float sample_freq) data > + in > + Generator.set_mode gen `Audio ; > + Generator.put_audio gen content 0 (Array.length content.(0))) > + > +end > + > +module G = Generator.From_audio_video > +module Buffered = Decoder.Buffered(G) > +module Aac = Make(G) > + > +let create_file_decoder filename kind = > + let generator = G.create `Audio in > + Buffered.file_decoder filename kind Aac.create_decoder generator > + > +(* Get the number of channels of audio in an AAC file. > + * This is done by decoding a first chunk of data, thus checking > + * that libmad can actually open the file -- which doesn't mean much. *) > +let get_type filename = > + let dec = Faad.create () in > + let fd = Unix.openfile filename [Unix.O_RDONLY] 0o644 in > + let aacbuflen = 1024 in > + let aacbuf = String.create aacbuflen in > + Tutils.finalize ~k:(fun () -> Unix.close fd) > + (fun () -> > + let _,rate,channels = > + Faad.init dec aacbuf 0 (Unix.read fd aacbuf 0 aacbuflen) > + in > + log#f 4 > + "Libfaad recognizes %S as AAC (%dHz,%d channels)." > + filename rate channels ; > + { Frame. > + audio = channels ; > + video = 0 ; > + midi = 0 }) > + > +let conf_mime_types = > + Conf.list ~p:(Decoder.conf_mime_types#plug "aac") > + "Mime-types used for guessing AAC format" > + ~d:["audio/aac"; "audio/aacp"; "audio/x-hx-aac-adts"] > + > +let () = > + match Configure.file_mime with > + | None -> > + Decoder.file_decoders#register > + "AAC/faad" > + ~sdoc:"Use libfaad to decode AAC." > + (fun ~metadata filename kind -> > + (* Don't get the file's type if no audio is allowed anyway. *) > + if kind.Frame.audio = Frame.Zero then None else > + if Frame.type_has_kind (get_type filename) kind then > + Some (fun () -> create_file_decoder filename kind) > + else begin > + None > + end) > + | Some mime_type -> > + Decoder.file_decoders#register > + "AAC/faad/mime" > + ~sdoc:"Use libmad to decode AAC if MIME type is appropriate." > + (fun ~metadata filename kind -> > + let mime = mime_type filename in > + if not (List.mem mime conf_mime_types#get) then begin > + log#f 3 "Invalid MIME type for %s: %s!" filename mime ; > + None > + end else > + if kind.Frame.audio = Frame.Variable || > + kind.Frame.audio = Frame.Succ Frame.Variable || > + (* libmad always respects the first two kinds *) > + Frame.type_has_kind (get_type filename) kind > + then > + Some (fun () -> create_file_decoder filename kind) > + else > + None) > + > +module D_stream = Make(Generator.From_audio_video_plus) > + > +let () = > + Decoder.stream_decoders#register > + "MP3/libmad" > + ~sdoc:"Use libmad to decode any stream with an appropriate MIME type." > + (fun mime kind -> > + let (<:) a b = Frame.mul_sub_mul a b in > + if List.mem mime conf_mime_types#get && > + kind.Frame.video <: Frame.Zero && > + kind.Frame.midi <: Frame.Zero && > + kind.Frame.audio <> Frame.Zero > + then > + (* In fact we can't be sure that we'll satisfy the content > + * kind, because the MP3 stream might be mono or stereo. > + * For now, we let this problem result in an error at > + * decoding-time. Failing early would only be an advantage > + * if there was possibly another plugin for decoding > + * correctly the stream (e.g. by performing conversions). *) > + Some D_stream.create_decoder > + else > + None) > + > +(* Mp4 decoding. *) > + > +let log = Log.make ["decoder";"mp4"] > + > +let mp4_decoder filename = > + let dec = Faad.create () in > + let fd = Unix.openfile filename [Unix.O_RDONLY] 0o644 in > + let closed = ref false in > + let close () = > + if not !closed then > + begin > + Unix.close fd ; > + closed := true > + end > + in > + let resampler = Rutils.create_audio () in > + let mp4,track,samples,sample,sample_freq,chans = > + try > + let mp4 = Faad.Mp4.openfile_fd fd in > + let track = Faad.Mp4.find_aac_track mp4 in > + let sample_freq, chans = Faad.Mp4.init mp4 dec track in > + let samples = Faad.Mp4.samples mp4 track in > + let sample = ref 0 in > + mp4,track,samples,sample,sample_freq,chans > + with > + | e -> close (); raise e > + in > + let gen = G.create `Audio in > + let out_ticks = ref 0 in > + (** See decoder.ml for the comments on the value here. *) > + let prebuf = > + Frame.master_of_seconds 0.5 > + in > + let fill frame = > + begin try > + while G.length gen < prebuf do > + if !sample >= samples then raise End_of_file; > + let data = Faad.Mp4.decode mp4 track !sample dec in > + incr sample ; > + let content,length = > + resampler ~audio_src_rate:(float sample_freq) data > + in > + G.put_audio gen content 0 (Array.length content.(0)) > + done > + with > + | e -> > + log#f 4 "Decoding ended: %s." (Printexc.to_string e) ; > + close () > + end ; > + let offset = Frame.position frame in > + G.fill gen frame ; > + let gen_len = G.length gen in > + out_ticks := !out_ticks + Frame.position frame - offset ; > + (* Compute an estimated number of remaining ticks. *) > + if !sample = 0 then -1 else > + let compression = > + (float (!out_ticks+gen_len)) /. (float !sample) > + in > + let remaining_ticks = > + (float gen_len) +. > + (float (samples - !sample)) *. compression > + in > + int_of_float remaining_ticks > + in > + { Decoder. > + fill = fill ; > + close = close } > + > +let conf_mime_types = > + Conf.list ~p:(Decoder.conf_mime_types#plug "mp4") > + "Mime-types used for guessing MP4 format" > + ~d:["audio/mp4"; "application/mp4"] > + > +(* Get the number of channels of audio in an AAC file. > + * This is done by decoding a first chunk of data, thus checking > + * that libmad can actually open the file -- which doesn't mean much. *) > +let get_type filename = > + let dec = Faad.create () in > + let fd = Unix.openfile filename [Unix.O_RDONLY] 0o644 in > + Tutils.finalize ~k:(fun () -> Unix.close fd) > + (fun () -> > + let mp4 = Faad.Mp4.openfile_fd fd in > + let track = Faad.Mp4.find_aac_track mp4 in > + let rate, channels = Faad.Mp4.init mp4 dec track in > + log#f 4 > + "Libfaad recognizes %S as MP4 (%dHz,%d channels)." > + filename rate channels ; > + { Frame. > + audio = channels ; > + video = 0 ; > + midi = 0 }) > + > +let () = > + match Configure.file_mime with > + | None -> > + Decoder.file_decoders#register > + "MP4/faad" > + ~sdoc:"Use libfaad to decode MP4." > + (fun ~metadata filename kind -> > + (* Don't get the file's type if no audio is allowed anyway. *) > + if kind.Frame.audio = Frame.Zero then None else > + if Frame.type_has_kind (get_type filename) kind then > + Some (fun () -> mp4_decoder filename) > + else begin > + None > + end) > + | Some mime_type -> > + Decoder.file_decoders#register > + "MP4/faad/mime" > + ~sdoc:"Use libmad to decode MP4 if MIME type is appropriate." > + (fun ~metadata filename kind -> > + let mime = mime_type filename in > + if not (List.mem mime conf_mime_types#get) then begin > + log#f 3 "Invalid MIME type for %s: %s!" filename mime ; > + None > + end else > + if kind.Frame.audio = Frame.Variable || > + kind.Frame.audio = Frame.Succ Frame.Variable || > + (* libmad always respects the first two kinds *) > + Frame.type_has_kind (get_type filename) kind > + then > + Some (fun () -> mp4_decoder filename) > + else > + None) > + > +let get_tags file = > + let fd = Unix.openfile file [Unix.O_RDONLY] 0o644 in > + Tutils.finalize ~k:(fun () -> Unix.close fd) > + (fun () -> > + let mp4 = Faad.Mp4.openfile_fd fd in > + Array.to_list (Faad.Mp4.metadata mp4)) > + > +let () = Request.mresolvers#register "MP4" get_tags > + > > Modified: trunk/liquidsoap/src/decoder/taglib_plug.ml > =================================================================== > --- trunk/liquidsoap/src/decoder/taglib_plug.ml 2010-08-19 20:30:21 UTC > (rev 7450) > +++ trunk/liquidsoap/src/decoder/taglib_plug.ml 2010-08-20 05:27:36 UTC > (rev 7451) > @@ -24,7 +24,7 @@ > > let get_tags fname = > try > - let f = open_file ~file_type:Mpeg fname in > + let f = open_file fname in > try > let gt l (n, t) = > try > > Modified: trunk/ocaml-faad/src/Makefile.in > =================================================================== > --- trunk/ocaml-faad/src/Makefile.in 2010-08-19 20:30:21 UTC (rev 7450) > +++ trunk/ocaml-faad/src/Makefile.in 2010-08-20 05:27:36 UTC (rev 7451) > @@ -28,7 +28,7 @@ > OCAMLDOCFLAGS = -stars > LIBINSTALL_FILES = $(wildcard *.mli *.cmi *.cma *.cmxa *.cmx *.a *.so) > LDFLAGS = @LDFLAGS@ > -ACLIBS = @LIBS@ > +ACLIBS = @LIBS@ -lmp4ff > CLIBS = $(ACLIBS:-l%=%) > LIBDIRS = $(LDFLAGS:-L%=%) > CC = @CC@ > > Modified: trunk/ocaml-faad/src/faad.ml > =================================================================== > --- trunk/ocaml-faad/src/faad.ml 2010-08-19 20:30:21 UTC (rev 7450) > +++ trunk/ocaml-faad/src/faad.ml 2010-08-20 05:27:36 UTC (rev 7451) > @@ -54,7 +54,6 @@ > done; > if !found then !i else raise Not_found > > -(* > module Mp4 = > struct > type decoder = t > @@ -95,4 +94,3 @@ > > external metadata : t -> (string * string) array = > "ocaml_faad_mp4_metadata" > end > -*) > > Modified: trunk/ocaml-faad/src/faad.mli > =================================================================== > --- trunk/ocaml-faad/src/faad.mli 2010-08-19 20:30:21 UTC (rev 7450) > +++ trunk/ocaml-faad/src/faad.mli 2010-08-20 05:27:36 UTC (rev 7451) > @@ -60,7 +60,6 @@ > (** Heuristic guess of the offset of the begining of a frame. *) > val find_frame : string -> int > > -(* > module Mp4 : > sig > type decoder = t > @@ -99,4 +98,3 @@ > > val metadata : t -> (string * string) array > end > -*) > > Modified: trunk/ocaml-faad/src/faad_stubs.c > =================================================================== > --- trunk/ocaml-faad/src/faad_stubs.c 2010-08-19 20:30:21 UTC (rev 7450) > +++ trunk/ocaml-faad/src/faad_stubs.c 2010-08-20 05:27:36 UTC (rev 7451) > @@ -40,6 +40,7 @@ > #include <stdio.h> > > #include <neaacdec.h> > +#include <mp4ff.h> > > static void check_err(int n) > { > @@ -144,10 +145,10 @@ > > /***** MP4 *****/ > > -/* > - > typedef struct > { > + mp4ff_t *ff; > + mp4ff_callback_t ff_cb; > int fd; > value read_cb; > value write_cb; > @@ -387,7 +388,7 @@ > mp4_t *mp = Mp4_val(m); > int t = Int_val(track); > int ret; > - unsigned int samplerate; > + long unsigned int samplerate; > unsigned char channels; > NeAACDecHandle dec = Dec_val(dh); > > @@ -548,5 +549,3 @@ > > CAMLreturn(ans); > } > - > -*/ > > > This was sent by the SourceForge.net collaborative development platform, > the world's largest Open Source development site. > > > ------------------------------------------------------------------------------ > This SF.net email is sponsored by > > Make an app they can't live without > Enter the BlackBerry Developer Challenge > http://p.sf.net/sfu/RIM-dev2dev > _______________________________________________ > Savonet-cvs mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/savonet-cvs >
------------------------------------------------------------------------------ This SF.net email is sponsored by Make an app they can't live without Enter the BlackBerry Developer Challenge http://p.sf.net/sfu/RIM-dev2dev
_______________________________________________ Savonet-devl mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/savonet-devl
