Le lundi 29 mars 2010 02:41:06, David Baelde a écrit :
> This is an informal bug report and fix: I have noticed that
> input.http() is broken on SVN -- more precisely, ogg stream decoding
> is broken. It seems that a not-so recent modification was incorrect,
> or interacted badly with something else since then. In any case the
> following quick fix exists, but we need to understand better what
> happened.

I have looked at this briefly.. These is some work to do on the ogg decoder for 
streams..:

 * The metadata need to be grabbed and passed to the generator.
 * When the stream ends, we need to try to reset the ogg decoder to read the 
next track. The problem is that there is no add_break available for the buffer.
 * The kind has to be tested during the first decoding. This is a bit ugly 
because everything is callback-based..

See attached a quick and dirty patch..


Romain
Index: decoder/ogg_decoder.ml
===================================================================
--- decoder/ogg_decoder.ml	(révision 7226)
+++ decoder/ogg_decoder.ml	(copie de travail)
@@ -113,7 +113,7 @@
 
 (* TODO this mimicks the old code, but in the near future decoding should
  * take into account the target content kind, e.g. for dropping channels *)
-let create_decoder mode input =
+let create_decoder source input =
   let decoder =
     let sync = Ogg.Sync.create input in
       Ogg_demuxer.init sync
@@ -121,15 +121,36 @@
   let video_convert = video_convert () in
   let audio_resample = Rutils.create_audio () in
   let video_resample = video_resample () in
+  let initial_decoding = ref true in
+  let initial_audio = ref ([||],0,None,false) in
+  let initial_video = ref ([||],0,None,false) in
     Decoder.Decoder (fun buffer ->
       if Ogg_demuxer.eos decoder then
-        raise Ogg_demuxer.End_of_stream;
-      let feed ((buf,sample_freq),_) =
+       if source = `Stream then
+        begin
+         try
+           Ogg_demuxer.reset decoder ;
+           initial_decoding := true
+           (** No add_break for Generator.S_Asio.. *)
+           (*Generator.add_break buffer *)
+         with
+           | _ -> raise Ogg_demuxer.End_of_stream
+        end
+       else raise Ogg_demuxer.End_of_stream ;
+      let feed ((buf,sample_freq),meta) =
         let audio_src_rate = float sample_freq in
         let content,length =
           audio_resample ~audio_src_rate buf
         in
-          Generator.put_audio buffer content 0 length
+        if not !initial_decoding then
+         begin
+          Generator.put_audio buffer content 0 length ;
+          match meta, source with
+            | Some m, `Stream -> Generator.add_metadata buffer m
+            | _,_     -> ()
+         end
+        else
+          initial_audio := (content,length,meta,true)
       in
       let got_audio =
         try
@@ -139,12 +160,20 @@
           | Not_found
           | Ogg.Not_enough_data -> false
       in
-      let feed (buf,_) =
+      let feed (buf,meta) =
         let in_freq = int_of_float buf.Ogg_demuxer.fps in
         let out_freq = Lazy.force Frame.video_rate in
         let rgb = video_convert buf in
         let stream = video_resample ~in_freq ~out_freq [|rgb|] 0 1 in
-          Generator.put_video buffer [|stream|] 0 (Array.length stream)
+        if not !initial_decoding then
+         begin
+          Generator.put_video buffer [|stream|] 0 (Array.length stream) ;
+          match meta, source with
+            | Some m, `Stream -> Generator.add_metadata buffer m
+            | _,_ -> ()
+         end
+        else
+          initial_video := ([|stream|],(Array.length stream),meta,true) 
       in
       (* Try to decode video. *)
       let got_video =
@@ -156,7 +185,38 @@
           | Ogg.Not_enough_data -> false
       in
         if not got_audio && not got_video then
-          Ogg_demuxer.feed decoder)
+          Ogg_demuxer.feed decoder
+        else
+          if !initial_decoding then
+           begin
+            let mode = 
+              match !initial_audio,!initial_video with
+                | (_,_,_,true),(_,_,_,true) -> `Both
+                | (_,_,_,true),(_,_,_,false) -> `Audio
+                | (_,_,_,false),(_,_,_,true) -> `Video
+                | _ -> assert false
+            in
+            Generator.set_mode buffer mode ;
+            let (data,len,meta,is_present) = !initial_audio in
+            initial_audio := ([||],0,None,false) ;
+            if is_present then
+             begin
+              Generator.put_audio buffer data 0 len ;
+              match meta,source with
+                | Some m, `Stream -> Generator.add_metadata buffer m
+                | _ -> ()
+             end ;
+            let (data,len,meta,is_present) = !initial_video in
+            initial_video := ([||],0,None,false) ;
+            if is_present then
+             begin
+              Generator.put_video buffer data 0 len ;
+              match meta,source with
+                | Some m,`Stream -> Generator.add_metadata buffer m
+                | _,_ -> ()
+             end ;
+            initial_decoding := false
+           end)
 
 end
 
@@ -174,7 +234,7 @@
       | _, _ -> `Both
   in
   let generator = G.create mode in
-    Buffered.file_decoder filename kind (D.create_decoder mode) generator
+    Buffered.file_decoder filename kind (D.create_decoder `File) generator
 
 let get_type filename =
   let sync,fd = Ogg.Sync.create_from_file filename in
@@ -238,7 +298,7 @@
      (fun mime kind ->
         if List.mem mime mime_types#get then
           (* TODO We must find a way here... *)
-          Some (D_stream.create_decoder `Audio)
+          Some (D_stream.create_decoder `Stream)
         else
           None)
 
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Savonet-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-devl

Répondre à