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