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

Répondre à