[xiph-commits] r3193 - oogg/trunk

shans at svn.annodex.net shans at svn.annodex.net
Wed Aug 15 21:31:15 PDT 2007


Author: shans
Date: 2007-08-15 21:31:14 -0700 (Wed, 15 Aug 2007)
New Revision: 3193

Modified:
   oogg/trunk/granules.ml
Log:
Theora forward and backward reconstruction of granulepos values



Modified: oogg/trunk/granules.ml
===================================================================
--- oogg/trunk/granules.ml	2007-08-16 00:23:37 UTC (rev 3192)
+++ oogg/trunk/granules.ml	2007-08-16 04:31:14 UTC (rev 3193)
@@ -35,20 +35,27 @@
     Some (granulerate_time 1L granule_rate (oogg64_to_float gp))
     );;
 
+let theora_shift bos = 
+  let bos_packet = List.hd bos.raw_data in
+  ((extract_int8 bos_packet 40 land 0x03) lsl 3)
+  lor
+  ((extract_int8 bos_packet 41 land 0xe0) lsr 5);;
+
+let theora_gp_to_frames shift gpv =
+  let igp = oogg64_to_int64 gpv in
+  let keyframe = Int64.shift_right igp shift in
+  let offset = Int64.logand igp 
+      (Int64.sub (Int64.shift_left Int64.one shift) Int64.one) in
+  (keyframe, offset)
+
 let theora_time bos gp = match gp with
   | None -> None
   | Some gp -> (
     let bos_packet = List.hd bos.raw_data in
     let num = extract_be_int32 bos_packet 22 in
     let denom = extract_be_int32 bos_packet 26 in
-    let shift = 
-      ((extract_int8 bos_packet 40 land 0x03) lsl 3)
-      lor
-      ((extract_int8 bos_packet 41 land 0xe0) lsr 5) in
-    let igp = oogg64_to_int64 gp in
-    let keyframe = Int64.shift_right igp shift in
-    let offset = Int64.logand igp 
-        (Int64.sub (Int64.shift_left Int64.one shift) Int64.one) in
+    let shift = theora_shift bos in
+    let (keyframe, offset) = theora_gp_to_frames shift gp in
     let gpv = Int64.to_float (Int64.add keyframe offset) in
     Some (granulerate_time denom num gpv)
   );;
@@ -84,8 +91,23 @@
                     (Int64.of_int ((thislen + lastlen) / 4))))
   );;
 
-let theora_last_gp _ _ _ _ = None;;
+let theora_frames_to_gp shift keyframe frame = 
+  int64_to_oogg64 (Int64.add (Int64.shift_left keyframe shift) frame);;
 
+(* assume that we only do negative generation at the beginning, and
+   that we never go over more than 1 keyframe.  At worst we just miss
+   out on a keyframe at the beginning
+ *)
+let theora_last_gp bos prevpack thispack thisgp = 
+  match thisgp with
+    | None -> None
+    | Some gp -> (
+      let shift = theora_shift bos in
+      let (keyframe, offset) = theora_gp_to_frames shift gp in
+      if offset = 0L
+      then Some (theora_frames_to_gp shift 0L (Int64.sub keyframe 1L))
+      else Some (theora_frames_to_gp shift keyframe (Int64.sub offset 1L)));;
+
 let last_gp_function id bos = match id with
   | Vorbis -> vorbis_last_gp bos
   | Theora -> theora_last_gp bos
@@ -101,7 +123,21 @@
               Some (int64_to_oogg64 (Int64.add (oogg64_to_int64 gp)
                   (Int64.of_int ((thislen + prevlen) / 4))));;
  
-let theora_next_gp _ _ _ _ = None;;
+let theora_next_gp bos prevpack thispack lastgp =
+  match lastgp with
+    | None -> None
+    | Some gp -> (
+      let shift = theora_shift bos in
+      let (keyframe, offset) = theora_gp_to_frames shift gp in
+      let fb = extract_int8 thispack 0 in
+      if (fb land 0x80) = 0x80 (* header packet *)
+      then Some (0,0,0,0)
+      else (
+        if (fb land 0x40) = 0x40 (* inter packet *)
+        then Some (theora_frames_to_gp shift keyframe (Int64.add offset 1L))
+        else Some (theora_frames_to_gp shift 
+            (Int64.add (Int64.add keyframe offset) 1L) 0L)
+      ));;
 
 let next_gp_function id bos = match id with
   | Vorbis -> vorbis_next_gp bos



More information about the commits mailing list