[xiph-commits] r3868 - in liboggplay/trunk: . include/oggplay python src/examples src/liboggplay win32

wiking at svn.annodex.net wiking at svn.annodex.net
Mon Mar 2 03:44:47 PST 2009


Author: wiking
Date: 2009-03-02 03:44:46 -0800 (Mon, 02 Mar 2009)
New Revision: 3868

Modified:
   liboggplay/trunk/README
   liboggplay/trunk/configure.ac
   liboggplay/trunk/include/oggplay/oggplay.h
   liboggplay/trunk/include/oggplay/oggplay_callback_info.h
   liboggplay/trunk/include/oggplay/oggplay_enums.h
   liboggplay/trunk/oggplay-uninstalled.pc.in
   liboggplay/trunk/oggplay.pc.in
   liboggplay/trunk/python/liboggplay.i
   liboggplay/trunk/src/examples/Makefile.am
   liboggplay/trunk/src/examples/glut-player.c
   liboggplay/trunk/src/liboggplay/Makefile.am
   liboggplay/trunk/src/liboggplay/Version_script.in
   liboggplay/trunk/src/liboggplay/oggplay.c
   liboggplay/trunk/src/liboggplay/oggplay_callback.c
   liboggplay/trunk/src/liboggplay/oggplay_callback_info.c
   liboggplay/trunk/src/liboggplay/oggplay_data.c
   liboggplay/trunk/src/liboggplay/oggplay_data.h
   liboggplay/trunk/src/liboggplay/oggplay_file_reader.c
   liboggplay/trunk/src/liboggplay/oggplay_private.h
   liboggplay/trunk/src/liboggplay/oggplay_seek.c
   liboggplay/trunk/src/liboggplay/oggplay_yuv2rgb.c
   liboggplay/trunk/win32/liboggplay.def
Log:
Added libtiger (http://code.google.com/p/libtiger) support with the example how to use in glut-player.

Fixed endianness problem in yuv2rgb code, so that the conversion functions do what they suppose to do
regadless of the host machine's byte order.


Modified: liboggplay/trunk/README
===================================================================
--- liboggplay/trunk/README	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/README	2009-03-02 11:44:46 UTC (rev 3868)
@@ -29,6 +29,15 @@
 
   * libkate -- from http://libkate.googlecode.com/
 
+To render Kate streams as video overlays, you need
+
+  * libtiger -- from http://libtiger.googlecode.com/
+
+Note that libtiger needs Pango and Cairo:
+
+  * Pango -- http://www.pango.org/
+  * Cairo -- http://cairographics.com/
+
 See the README files associated with these libraries for installation
 instructions.
 

Modified: liboggplay/trunk/configure.ac
===================================================================
--- liboggplay/trunk/configure.ac	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/configure.ac	2009-03-02 11:44:46 UTC (rev 3868)
@@ -176,6 +176,33 @@
 fi
 
 dnl
+dnl  Detect libtiger
+dnl
+AC_ARG_WITH(
+  tiger,
+  AS_HELP_STRING(
+    [--with-tiger],
+    [Enable rendering of Kate streams with the Tiger rendering library, using Pango and Cairo (default autodetect)]
+  ),
+  [use_tiger="$withval"]
+)
+if test "x$use_tiger" != "xno"; then
+  PKG_CHECK_MODULES(TIGER, tiger >= 0.3.1, HAVE_TIGER="yes", HAVE_TIGER="no")
+  if test "x$HAVE_TIGER" = "xyes" ; then
+    AC_DEFINE(HAVE_TIGER, [], [Define if have libtiger])
+    AC_SUBST(TIGER_CFLAGS)
+    AC_SUBST(TIGER_LIBS)
+  else
+    AC_MSG_RESULT($HAVE_TIGER)
+    if test "x$use_tiger" = "xyes"; then
+      AC_MSG_ERROR([libtiger could not be found and was explicitely requested])
+    fi
+  fi
+else
+  HAVE_TIGER=no
+fi
+
+dnl
 dnl Detect Imlib2 (used by dump-all-streams example)
 dnl
 PKG_CHECK_MODULES(IMLIB2, imlib2, HAVE_IMLIB2="yes", HAVE_IMLIB2="no")
@@ -378,6 +405,7 @@
   Example programs will be built but not installed.
 
   Kate support: .................. ${HAVE_KATE}
+  Tiger support: ................. ${HAVE_TIGER}
 ------------------------------------------------------------------------
 ])
 

Modified: liboggplay/trunk/include/oggplay/oggplay.h
===================================================================
--- liboggplay/trunk/include/oggplay/oggplay.h	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/include/oggplay/oggplay.h	2009-03-02 11:44:46 UTC (rev 3868)
@@ -94,6 +94,9 @@
 oggplay_set_callback_num_frames(OggPlay *me, int stream, int frames);
 
 OggPlayErrorCode
+oggplay_set_callback_period(OggPlay *me, int stream, int milliseconds);
+
+OggPlayErrorCode
 oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset);
 
 OggPlayErrorCode
@@ -112,12 +115,21 @@
 oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num);
 
 OggPlayErrorCode
+oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert);
+
+OggPlayErrorCode
 oggplay_get_kate_category(OggPlay *me, int track, const char** category);
 
 OggPlayErrorCode
 oggplay_get_kate_language(OggPlay *me, int track, const char** language);
 
 OggPlayErrorCode
+oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger);
+
+OggPlayErrorCode
+oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track);
+
+OggPlayErrorCode
 oggplay_start_decoding(OggPlay *me);
 
 OggPlayErrorCode

Modified: liboggplay/trunk/include/oggplay/oggplay_callback_info.h
===================================================================
--- liboggplay/trunk/include/oggplay/oggplay_callback_info.h	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/include/oggplay/oggplay_callback_info.h	2009-03-02 11:44:46 UTC (rev 3868)
@@ -45,6 +45,14 @@
   unsigned char   * v;
 } OggPlayVideoData;
 
+typedef struct {
+  unsigned char   * rgba; /* may be NULL if no alpha */
+  unsigned char   * rgb; /* may be NULL if alpha */
+  size_t          width; /* in pixels */
+  size_t          height; /* in pixels */
+  size_t          stride; /* in bytes */
+} OggPlayOverlayData;
+
 typedef void * OggPlayAudioData;
 
 typedef char OggPlayTextData;
@@ -67,6 +75,9 @@
 OggPlayVideoData *
 oggplay_callback_info_get_video_data(OggPlayDataHeader *header);
 
+OggPlayOverlayData *
+oggplay_callback_info_get_overlay_data(OggPlayDataHeader *header);
+
 OggPlayAudioData *
 oggplay_callback_info_get_audio_data(OggPlayDataHeader *header);
 

Modified: liboggplay/trunk/include/oggplay/oggplay_enums.h
===================================================================
--- liboggplay/trunk/include/oggplay/oggplay_enums.h	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/include/oggplay/oggplay_enums.h	2009-03-02 11:44:46 UTC (rev 3868)
@@ -62,13 +62,15 @@
   E_OGGPLAY_TIMEOUT           = -17,
   E_OGGPLAY_CANT_SEEK         = -18,
   E_OGGPLAY_NO_KATE_SUPPORT   = -19,
-  E_OGGPLAY_OUT_OF_MEMORY     = -20,
+  E_OGGPLAY_NO_TIGER_SUPPORT  = -20,
+  E_OGGPLAY_OUT_OF_MEMORY     = -21,
   E_OGGPLAY_NOTCHICKENPAYBACK = -777
 } OggPlayErrorCode;
 
 typedef enum OggPlayDataType {
   OGGPLAY_INACTIVE      = -1,
   OGGPLAY_YUV_VIDEO     = 0,
+  OGGPLAY_RGBA_VIDEO    = 1,
   OGGPLAY_SHORTS_AUDIO  = 1000,
   OGGPLAY_FLOATS_AUDIO  = 1001,
   OGGPLAY_CMML          = 2000,

Modified: liboggplay/trunk/oggplay-uninstalled.pc.in
===================================================================
--- liboggplay/trunk/oggplay-uninstalled.pc.in	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/oggplay-uninstalled.pc.in	2009-03-02 11:44:46 UTC (rev 3868)
@@ -8,5 +8,5 @@
 Requires: oggz fishsound theora
 Version: @VERSION@
 Libs: -L${libdir} -loggplay 
-Libs.private: @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @KATE_LIBS@
-Cflags: -I${includedir} @KATE_CFLAGS@
+Libs.private: @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @TIGER_LIBS@ @KATE_LIBS@
+Cflags: -I${includedir} @TIGER_CFLAGS@ @KATE_CFLAGS@

Modified: liboggplay/trunk/oggplay.pc.in
===================================================================
--- liboggplay/trunk/oggplay.pc.in	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/oggplay.pc.in	2009-03-02 11:44:46 UTC (rev 3868)
@@ -8,5 +8,5 @@
 Requires: oggz fishsound theora
 Version: @VERSION@
 Libs: -L${libdir} -loggplay 
-Libs.private: @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @KATE_LIBS@
-Cflags: -I${includedir} @KATE_CFLAGS@
+Libs.private: @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @TIGER_LIBS@ @KATE_LIBS@
+Cflags: -I${includedir} @TIGER_CFLAGS@ @KATE_CFLAGS@

Modified: liboggplay/trunk/python/liboggplay.i
===================================================================
--- liboggplay/trunk/python/liboggplay.i	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/python/liboggplay.i	2009-03-02 11:44:46 UTC (rev 3868)
@@ -25,6 +25,7 @@
   E_OGGPLAY_TIMEOUT           = -17,
   E_OGGPLAY_CANT_SEEK         = -18,
   E_OGGPLAY_NO_KATE_SUPPORT   = -19,
+  E_OGGPLAY_NO_TIGER_SUPPORT  = -20,
   E_OGGPLAY_NOTCHICKENPAYBACK = -777
 } OggPlayErrorCode;
 
@@ -225,6 +226,9 @@
 oggplay_set_callback_num_frames(OggPlay *me, int stream, int frames);
 
 OggPlayErrorCode
+oggplay_set_callback_period(OggPlay *me, int stream, int milliseconds);
+
+OggPlayErrorCode
 oggplay_set_offset(OggPlay *me, int track, ogg_int64_t offset);
 
 OggPlayErrorCode
@@ -243,12 +247,21 @@
 oggplay_get_video_fps(OggPlay *me, int track, int* fps_denom, int* fps_num);
 
 OggPlayErrorCode
+oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert);
+
+OggPlayErrorCode
 oggplay_get_kate_language(OggPlay *me, int track, const char** language);
 
 OggPlayErrorCode
 oggplay_get_kate_category(OggPlay *me, int track, const char** category);
 
 OggPlayErrorCode
+oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger);
+
+OggPlayErrorCode
+oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track);
+
+OggPlayErrorCode
 oggplay_start_decoding(OggPlay *me);
 
 OggPlayErrorCode

Modified: liboggplay/trunk/src/examples/Makefile.am
===================================================================
--- liboggplay/trunk/src/examples/Makefile.am	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/examples/Makefile.am	2009-03-02 11:44:46 UTC (rev 3868)
@@ -8,13 +8,13 @@
 	mac/gplayer.xcodeproj/project.pbxproj
 
 AM_CFLAGS = -Wall \
-            @OGGZ_CFLAGS@ @THEORA_CFLAGS@ @FISHSOUND_CFLAGS@ @KATE_CFLAGS@
+            @OGGZ_CFLAGS@ @THEORA_CFLAGS@ @FISHSOUND_CFLAGS@ @TIGER_CFLAGS@ @KATE_CFLAGS@
 
 INCLUDES = -I$(top_srcdir)/include
 
 OGGPLAYDIR = ../liboggplay
 OGGPLAY_LIBS = $(OGGPLAYDIR)/liboggplay.la @OGGZ_LIBS@ @THEORA_LIBS@ \
-	       @FISHSOUND_LIBS@ @KATE_LIBS@ @SEMAPHORE_LIBS@
+	       @FISHSOUND_LIBS@ @TIGER_LIBS@ @KATE_LIBS@ @SEMAPHORE_LIBS@
 
 if HAVE_GLUT
 glut_tools = glut-player

Modified: liboggplay/trunk/src/examples/glut-player.c
===================================================================
--- liboggplay/trunk/src/examples/glut-player.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/examples/glut-player.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -58,58 +58,54 @@
 static GLuint texture;
 
 static unsigned char *texture_bits = NULL;
-static int texture_width;
-static int texture_height;
+static int texture_width = 0;
+static int texture_height = 0;
 static float texture_wscale;
 static float texture_hscale;
-static int window_width;
-static int window_height;
+static int window_width = 0;
+static int window_height = 0;
 
 static OggPlay    * player = NULL;
 
 static sem_t        stop_sem;
 
 
-static int video_track;
-static int audio_track;
+static int video_track = -1;
+static int audio_track = -1;
+static int kate_track = -1;
 
 #define DISPLAY_FRAMES 1
+#define DISPLAY_FPS 0
 
 #define PERIOD_SIZE   512
 
-void
-handle_video_data (OggPlay * player, int track_num, 
-                    OggPlayVideoData * video_data, int frame) {
+#ifdef DISPLAY_FPS
+static struct timeval tv0,tv1;
+#endif
 
-  int               y_width;
-  int               y_height;
-  int               uv_width;
-  int               uv_height;
+static void
+update_video_size(int width, int height) {
+
   int               po2_width;
   int               po2_height;  
-  OggPlayYUVChannels      yuv;
-  OggPlayRGBChannels      rgb;
 
-  oggplay_get_video_y_size(player, track_num, &y_width, &y_height);
-  if (y_width != window_width)
+  if (width != window_width)
   {
 #if DISPLAY_FRAMES
-    glutReshapeWindow(y_width, y_height);
+    glutReshapeWindow(width, height);
 #endif
-    window_width = y_width;
-    window_height = y_height;
+    window_width = width;
+    window_height = height;
+#ifdef DEBUG
     printf("New window size is (%d, %d)\n", window_width, window_height);
+#endif
   }
-    
-  oggplay_get_video_uv_size(player, track_num, &uv_width, &uv_height);
-  //assert(uv_width == y_width / 2);
-  //assert(uv_height == y_height / 2);
-  
-  for (po2_width = 1; po2_width < y_width; po2_width <<= 1);
-  for (po2_height = 1; po2_height < y_height; po2_height <<= 1);
-  texture_wscale = (float) y_width / po2_width;
-  texture_hscale = (float) y_height / po2_height;
 
+  for (po2_width = 1; po2_width < width; po2_width <<= 1);
+  for (po2_height = 1; po2_height < height; po2_height <<= 1);
+  texture_wscale = (float) width / po2_width;
+  texture_hscale = (float) height / po2_height;
+
   if (texture_bits == NULL) {
 
     texture_bits = calloc(1, po2_width * po2_height * 4);
@@ -124,7 +120,27 @@
     texture_width = po2_width;
     texture_height = po2_height;
   }
+}
 
+void
+handle_video_data (OggPlay * player, int track_num, 
+                    OggPlayVideoData * video_data, int frame) {
+
+  int               y_width;
+  int               y_height;
+  int               uv_width;
+  int               uv_height;
+  OggPlayYUVChannels      yuv;
+  OggPlayRGBChannels      rgb;
+
+  oggplay_get_video_y_size(player, track_num, &y_width, &y_height);
+  update_video_size(y_width, y_height);
+
+  oggplay_get_video_uv_size(player, track_num, &uv_width, &uv_height);
+  //assert(uv_width == y_width / 2);
+  //assert(uv_height == y_height / 2);
+  
+
   /*
    * Convert the YUV data to RGB, using platform-specific optimisations
    * where possible.
@@ -145,6 +161,64 @@
 
 }
 
+void
+handle_overlay_data (OggPlay * player, int track_num, 
+                     OggPlayOverlayData * overlay_data, int frame) {
+
+  int               w;
+  int               h;
+  int               x;
+  int               y;
+
+  /* if we're getting RGBA (eg, the track was not set to be overlayed on top of video),
+     but we do not actually have any video, then ignore alpha and blit the overlay as
+     fully opaque since there's nothing behind it anyway */
+  if (overlay_data->rgb || video_track<0) {
+    /* RGB video, no alpha */
+    const unsigned char *video = overlay_data->rgb ? overlay_data->rgb : overlay_data->rgba;
+    update_video_size(overlay_data->width, overlay_data->height);
+
+    for (y=0; y < overlay_data->height; ++y) {
+      const unsigned char *src = video+y*overlay_data->stride;
+      unsigned char *dest = texture_bits+y*texture_width*4;
+      memcpy(dest, src, overlay_data->width*4);
+    }
+  }
+  else {
+
+    if (!texture_bits) {
+      /* no video to overlay on, we draw the overlay only */
+      update_video_size(overlay_data->width, overlay_data->height);
+      return;
+    }
+
+    /* overlay data onto rgb */
+    w = window_width;
+    if (overlay_data->width < w)
+      w = overlay_data->width;
+    h = window_height;
+    if (overlay_data->height < h)
+      h = overlay_data->height;
+
+    /* damn slow - full frame alpha blending in C - use liboil ? */
+    for (y=0; y<h; ++y) {
+      const unsigned char *src = overlay_data->rgba+y*overlay_data->stride;
+      unsigned char *dest = texture_bits+y*texture_width*4;
+      for (x=0; x<w; ++x) {
+        unsigned char a=src[3];
+        if (a) {
+          /* note: we're getting premultiplied alpha, so src[n] isn't mutliplied by a here */
+          dest[0] = src[0] + (255-a) * dest[0]/256;
+          dest[1] = src[1] + (255-a) * dest[1]/256;
+          dest[2] = src[2] + (255-a) * dest[2]/256;
+        }
+        dest += 4;
+        src += 4;
+      }
+    }
+  }
+}
+
 static int              rate = 16000;
 static int              channels = 2;
 static int              fps_denom = 1000;
@@ -176,9 +250,11 @@
   target_audio_rate = (int)(rate * channels * sizeof(short) / 25);
 #endif
   tmp = AFMT_S16_LE;
-  ioctl(snd_fd, SNDCTL_DSP_SETFMT, &tmp);
-  ioctl(snd_fd, SNDCTL_DSP_CHANNELS, &channels);
-  ioctl(snd_fd, SNDCTL_DSP_SPEED, &rate);
+  if (snd_fd >= 0) {
+    ioctl(snd_fd, SNDCTL_DSP_SETFMT, &tmp);
+    ioctl(snd_fd, SNDCTL_DSP_CHANNELS, &channels);
+    ioctl(snd_fd, SNDCTL_DSP_SPEED, &rate);
+  }
 }
 
 static short *buffer = NULL;
@@ -193,13 +269,20 @@
   }
  
   if (buffer_length < size) {
-    buffer = realloc(buffer, size * sizeof (short) * 2);
+    /* could overflow if number of channels goes up midway (eg, chained stream)
+       but at least it doesn't access bad memory for mono streams now */
+    short *new_buffer = realloc(buffer, size * sizeof (short) * channels);
+    if (!new_buffer)
+      return;
+    buffer = new_buffer;
     buffer_length = size;
   }
   
-  float_to_short_array((float *)data, buffer, size * 2);
+  float_to_short_array((float *)data, buffer, size * channels);
  
-  write(snd_fd, buffer, size * 2 * sizeof(short));
+  if (snd_fd >= 0) {
+    write(snd_fd, buffer, size * channels * sizeof(short));
+  }
 }
 
 #endif
@@ -211,6 +294,7 @@
   int                     i;
   OggPlayDataHeader    ** headers;
   OggPlayVideoData      * video_data;
+  OggPlayOverlayData    * overlay_data;
 #if USE_AUDIO
   OggPlayAudioData      * audio_data;
   count_info              tsc;
@@ -241,9 +325,15 @@
     }
 #if USE_AUDIO
     if (rate > 0) {
-      ioctl(snd_fd, SNDCTL_DSP_GETOPTR, &tsc);
-      long long bytes = tsc.bytes;
-      long long offset = (target - (bytes * 10000 / rate / 4)) * 100;
+      long long offset;
+      if (snd_fd >= 0) {
+        ioctl(snd_fd, SNDCTL_DSP_GETOPTR, &tsc);
+        long long bytes = tsc.bytes;
+        offset = (target - (bytes * 10000 / rate / 4)) * 100;
+      }
+      else {
+        offset = fps_denom*10000/fps_num * 100;
+      }
 #else
     {
       long long offset = fps_denom*10000/fps_num * 100;
@@ -279,6 +369,17 @@
             oggplay_callback_info_get_presentation_time(headers[required - 1]));
           */
           break;
+        case OGGPLAY_RGBA_VIDEO:
+          /*
+           * there should only be one record
+           */
+          required = oggplay_callback_info_get_required(track_info[i]);
+          if (required>0) {
+            overlay_data = oggplay_callback_info_get_overlay_data(headers[0]);
+            ld_time = oggplay_callback_info_get_presentation_time(headers[0]);
+            handle_overlay_data(player, i, overlay_data, n_frames);
+          }
+          break;
         case OGGPLAY_FLOATS_AUDIO:
 #if USE_AUDIO
         required = oggplay_callback_info_get_required(track_info[i]);
@@ -326,9 +427,18 @@
     printf("Processing frame: %d | audio B/s: %d | average audio B/s %f | targetaudio rate %d B/s\n", n_frames, bytes_per_frame, (float)(total_audio_bytes/n_frames), target_audio_rate); 
     bytes_per_frame = 0;
 #endif    
+#ifdef DISPLAY_FPS
+    gettimeofday(&tv1,NULL);
+    printf("%.2f fps        \r",1000000.0/(tv1.tv_usec-tv0.tv_usec+1000000*(tv1.tv_sec-tv0.tv_sec)));
+    fflush(stdout);
+    tv0=tv1;
+#endif
+
 #if DISPLAY_FRAMES
 #if USE_AUDIO
-    ioctl(snd_fd, SNDCTL_DSP_GETOPTR, &tsc);
+    if (snd_fd >= 0) {
+      ioctl(snd_fd, SNDCTL_DSP_GETOPTR, &tsc);
+    }
 #endif
     glutPostRedisplay();
     //show_window();
@@ -345,17 +455,23 @@
 MessageEnum         msg;
 static sem_t        msg_sem;
 
+static void cleanup()
+{
+#if DISPLAY_FRAMES
+  glutDestroyWindow(window);
+#endif
+  if (texture_bits != NULL) {
+    free(texture_bits);
+    texture_bits = NULL;
+  }
+  glDeleteTextures(1,&texture);
+  oggplay_close(player);
+}
 
 void key_pressed(unsigned char k, int a, int b) {
 
   if (k == 'q') {
-#if DISPLAY_FRAMES
-    glutDestroyWindow(window);
-#endif
-    if (texture_bits != NULL) {
-      free(texture_bits);
-    }
-    oggplay_close(player);
+    cleanup();
     exit(0);
   } else if (k == 'l') {
     msg = SEEK_FORWARD;
@@ -468,7 +584,10 @@
   printf ("there are %d tracks\n", oggplay_get_num_tracks (player));
  
   video_track = -1; 
+  audio_track = -1;
+  kate_track = -1;
   for (i = 0; i < oggplay_get_num_tracks (player); i++) {
+    int activate_track = 1;
     printf("Track %d is of type %s\n", i, 
                     oggplay_get_track_typename (player, i));
     if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_THEORA) {
@@ -496,15 +615,41 @@
       int ret = oggplay_get_kate_category(player, i, &category);
       ret = oggplay_get_kate_language(player, i, &language);
       printf("category %s, language %s\n", category, language);
+      if (kate_track < 0) {
+        kate_track = i;
+        if (video_track != -1) {
+          /* if we have video, request overlaying onto the video */
+          oggplay_convert_video_to_rgb(player, video_track, 1);
+          oggplay_overlay_kate_track_on_video(player, i, video_track);
+        }
+      }
+      else {
+        /* do not activate more than one Kate track, they're probably going
+           to be subtitles in various languages, so will end up overlapping
+           each other - comment this line out if they're supposed to be
+           displayed on top of each other (eg subtitles+logo, etc) */
+        activate_track = 0;
+      }
     }
 
-    if (oggplay_set_track_active(player, i) < 0) {
-      printf("\tNote: Could not set this track active!\n");
+    if (activate_track) {
+      if (oggplay_set_track_active(player, i) < 0) {
+        printf("\tNote: Could not set this track active!\n");
+      }
     }
   }
 
   if (video_track == -1) {
-    oggplay_set_callback_num_frames(player, audio_track, 2048);
+    if (audio_track >= 0) {
+      oggplay_set_callback_num_frames(player, audio_track, 2048);
+    }
+    else if (kate_track >= 0) {
+      /* there was no video nor audio, so play the Kate track alone */
+      oggplay_set_callback_period (player, kate_track, 40); /* in milliseconds, 25 fps */
+    }
+    else {
+      /* no video... no audio... and no kate... what we gonna do ??? */
+    }
   }
 
 #if DISPLAY_FRAMES

Modified: liboggplay/trunk/src/liboggplay/Makefile.am
===================================================================
--- liboggplay/trunk/src/liboggplay/Makefile.am	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/Makefile.am	2009-03-02 11:44:46 UTC (rev 3868)
@@ -35,6 +35,6 @@
 	oggplay_seek.c		\
 	oggplay_tools.c
 
-liboggplay_la_CFLAGS = $(AM_CFLAGS) $(OGGZ_CFLAGS) $(FISHSOUND_CFLAGS) $(ALTIVEC_CFLAGS)
+liboggplay_la_CFLAGS = $(AM_CFLAGS) $(OGGZ_CFLAGS) $(FISHSOUND_CFLAGS) $(ALTIVEC_CFLAGS) @TIGER_CFLAGS@ @KATE_CFLAGS@
 liboggplay_la_LDFLAGS = -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@ 
-liboggplay_la_LIBADD = @SEMAPHORE_LIBS@ @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @KATE_LIBS@
+liboggplay_la_LIBADD = @SEMAPHORE_LIBS@ @OGGZ_LIBS@ @FISHSOUND_LIBS@ @THEORA_LIBS@ @TIGER_LIBS@ @KATE_LIBS@

Modified: liboggplay/trunk/src/liboggplay/Version_script.in
===================================================================
--- liboggplay/trunk/src/liboggplay/Version_script.in	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/Version_script.in	2009-03-02 11:44:46 UTC (rev 3868)
@@ -22,6 +22,7 @@
 
                 oggplay_set_data_callback;
                 oggplay_set_callback_num_frames;
+                oggplay_set_callback_period;
                 oggplay_start_decoding;
                 oggplay_step_decoding;
 
@@ -32,10 +33,13 @@
                 oggplay_get_video_y_size;
                 oggplay_get_video_uv_size;
                 oggplay_get_video_fps;
+                oggplay_convert_video_to_rgb;
                 oggplay_get_audio_channels;
                 oggplay_get_audio_samplerate;				
                 oggplay_get_kate_category;
                 oggplay_get_kate_language;
+                oggplay_overlay_kate_track_on_video;
+                oggplay_set_kate_tiger_rendering;
 
                 oggplay_callback_info_get_type;
                 oggplay_callback_info_get_available;
@@ -43,6 +47,7 @@
                 oggplay_callback_info_get_headers;
 		            oggplay_callback_info_get_record_size;
                 oggplay_callback_info_get_video_data;
+                oggplay_callback_info_get_overlay_data;
                 oggplay_callback_info_get_audio_data;
                 oggplay_callback_info_get_text_data;
                 oggplay_callback_info_get_presentation_time;

Modified: liboggplay/trunk/src/liboggplay/oggplay.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -218,8 +218,23 @@
   me->callback_period = me->decode_data[track]->granuleperiod * frames;
   me->target = me->presentation_time + me->callback_period - 1;
 
-//  printf("targ: %lld, callback_per: %lld, prestime: %lld\n", me->target, me->callback_period,me->presentation_time );  
+  return E_OGGPLAY_OK;
+}
 
+OggPlayErrorCode
+oggplay_set_callback_period(OggPlay *me, int track, int milliseconds) {
+
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_OGGPLAY;
+  }
+
+  if (track < 0 || track >= me->num_tracks) {
+    return E_OGGPLAY_BAD_TRACK;
+  }
+
+  me->callback_period = (((ogg_int64_t)milliseconds)<<32);
+  me->target = me->presentation_time + me->callback_period - 1;
+
   return E_OGGPLAY_OK;
 
 }
@@ -231,7 +246,7 @@
     return E_OGGPLAY_BAD_OGGPLAY;
   }
 
-  if (track <= 0 || track > me->num_tracks) {
+  if (track < 0 || track >= me->num_tracks) {
     return E_OGGPLAY_BAD_TRACK;
   }
 
@@ -271,6 +286,36 @@
 }
 
 OggPlayErrorCode
+oggplay_convert_video_to_rgb(OggPlay *me, int track, int convert) {
+  OggPlayTheoraDecode *decode;
+
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_OGGPLAY;
+  }
+
+  if (track < 0 || track >= me->num_tracks) {
+    return E_OGGPLAY_BAD_TRACK;
+  }
+
+  if (me->decode_data[track]->content_type != OGGZ_CONTENT_THEORA) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  decode = (OggPlayTheoraDecode *)(me->decode_data[track]);
+
+  if (decode->convert_to_rgb != convert) {
+    decode->convert_to_rgb = convert;
+    me->decode_data[track]->decoded_type = convert ? OGGPLAY_RGBA_VIDEO : OGGPLAY_YUV_VIDEO;
+
+    /* flush any records created with previous type */
+    oggplay_data_free_list(me->decode_data[track]->data_list);
+    me->decode_data[track]->data_list = NULL;
+  }
+
+  return E_OGGPLAY_OK;
+}
+
+OggPlayErrorCode
 oggplay_get_video_y_size(OggPlay *me, int track, int *y_width, int *y_height) {
 
   OggPlayTheoraDecode *decode;
@@ -331,7 +376,7 @@
 
 }
 
-int
+OggPlayErrorCode
 oggplay_get_audio_channels(OggPlay *me, int track, int* channels) {
 
   OggPlayAudioDecode *decode;
@@ -358,7 +403,7 @@
 
 }
 
-int
+OggPlayErrorCode
 oggplay_get_audio_samplerate(OggPlay *me, int track, int* rate) {
 
   OggPlayAudioDecode * decode;
@@ -385,7 +430,7 @@
 
 }
 
-int
+OggPlayErrorCode
 oggplay_get_kate_category(OggPlay *me, int track, const char** category) {
 
   OggPlayKateDecode * decode;
@@ -398,21 +443,24 @@
     return E_OGGPLAY_BAD_TRACK;
   }
 
-  if (me->decode_data[track]->decoded_type != OGGPLAY_KATE) {
+  if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayKateDecode *)(me->decode_data[track]);
 
 #ifdef HAVE_KATE
-  (*category) = decode->k.ki->category;
-  return E_OGGPLAY_OK;
+  if (decode->init) {
+    (*category) = decode->k.ki->category;
+    return E_OGGPLAY_OK;
+  }
+  else return E_OGGPLAY_UNINITIALISED;
 #else
   return E_OGGPLAY_NO_KATE_SUPPORT;
 #endif
 }
 
-int
+OggPlayErrorCode
 oggplay_get_kate_language(OggPlay *me, int track, const char** language) {
 
   OggPlayKateDecode * decode;
@@ -425,16 +473,100 @@
     return E_OGGPLAY_BAD_TRACK;
   }
 
-  if (me->decode_data[track]->decoded_type != OGGPLAY_KATE) {
+  if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
     return E_OGGPLAY_WRONG_TRACK_TYPE;
   }
 
   decode = (OggPlayKateDecode *)(me->decode_data[track]);
 
 #ifdef HAVE_KATE
-  (*language) = decode->k.ki->language;
+  if (decode->init) {
+    (*language) = decode->k.ki->language;
+    return E_OGGPLAY_OK;
+  }
+  else return E_OGGPLAY_UNINITIALISED;
+#else
+  return E_OGGPLAY_NO_KATE_SUPPORT;
+#endif
+}
+
+OggPlayErrorCode
+oggplay_set_kate_tiger_rendering(OggPlay *me, int track, int use_tiger) {
+
+  OggPlayKateDecode * decode;
+
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_OGGPLAY;
+  }
+
+  if (track < 0 || track >= me->num_tracks) {
+    return E_OGGPLAY_BAD_TRACK;
+  }
+
+  if (me->decode_data[track]->content_type != OGGZ_CONTENT_KATE) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  decode = (OggPlayKateDecode *)(me->decode_data[track]);
+
+#ifdef HAVE_KATE
+#ifdef HAVE_TIGER
+  if (decode->init && decode->tr) {
+    decode->use_tiger = use_tiger;
+    decode->decoder.decoded_type = use_tiger ? OGGPLAY_RGBA_VIDEO : OGGPLAY_KATE;
+    return E_OGGPLAY_OK;
+  }
+  else return E_OGGPLAY_UNINITIALISED;
+#else
+  return E_OGGPLAY_NO_TIGER_SUPPORT;
+#endif
+#else
+  return E_OGGPLAY_NO_KATE_SUPPORT;
+#endif
+}
+
+OggPlayErrorCode
+oggplay_overlay_kate_track_on_video(OggPlay *me, int kate_track, int video_track) {
+
+  OggPlayKateDecode * decode;
+
+  if (me == NULL) {
+    return E_OGGPLAY_BAD_OGGPLAY;
+  }
+
+  if (kate_track < 0 || kate_track >= me->num_tracks) {
+    return E_OGGPLAY_BAD_TRACK;
+  }
+  if (video_track < 0 || video_track >= me->num_tracks) {
+    return E_OGGPLAY_BAD_TRACK;
+  }
+
+  if (me->decode_data[kate_track]->content_type != OGGZ_CONTENT_KATE) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  if (me->decode_data[kate_track]->decoded_type != OGGPLAY_RGBA_VIDEO) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  if (me->decode_data[video_track]->content_type != OGGZ_CONTENT_THEORA) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  if (me->decode_data[video_track]->decoded_type != OGGPLAY_RGBA_VIDEO) {
+    return E_OGGPLAY_WRONG_TRACK_TYPE;
+  }
+
+  decode = (OggPlayKateDecode *)(me->decode_data[kate_track]);
+
+#ifdef HAVE_KATE
+#ifdef HAVE_TIGER
+  decode->overlay_dest = video_track;
   return E_OGGPLAY_OK;
 #else
+  return E_OGGPLAY_NO_TIGER_SUPPORT;
+#endif
+#else
   return E_OGGPLAY_NO_KATE_SUPPORT;
 #endif
 }
@@ -634,6 +766,8 @@
     oggplay_buffer_shutdown(me, me->buffer);
   }
 
+  oggplay_free(me->callback_info);
+  oggplay_free(me->decode_data);
   oggplay_free(me);
 
   return E_OGGPLAY_OK;

Modified: liboggplay/trunk/src/liboggplay/oggplay_callback.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_callback.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_callback.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -57,6 +57,7 @@
   decoder->granulepos_seen = 0;
   decoder->frame_delta = 0;
   decoder->y_width = 0;
+  decoder->convert_to_rgb = 0;
   decoder->decoder.decoded_type = OGGPLAY_YUV_VIDEO;
 }
 
@@ -383,11 +384,34 @@
 oggplay_init_kate(void *user_data) {
 
 #ifdef HAVE_KATE
+  int ret;
   OggPlayKateDecode   * decoder     = (OggPlayKateDecode *)user_data;
 
-  kate_high_decode_init(&(decoder->k));
+  decoder->init = 0;
+  ret = kate_high_decode_init(&(decoder->k));
+  if (ret < 0) {
+    /* what to do ? */
+  }
+  else {
+    decoder->init = 1;
+  }
   decoder->decoder.decoded_type = OGGPLAY_KATE;
+
+#ifdef HAVE_TIGER
+  decoder->use_tiger = 1;
+  decoder->overlay_dest = -1;
+
+  ret = tiger_renderer_create(&(decoder->tr));
+  if (ret < 0) {
+    /* what to do ? */
+    decoder->tr = NULL;
+  }
+  if (decoder->use_tiger) {
+    decoder->decoder.decoded_type = OGGPLAY_RGBA_VIDEO;
+  }
 #endif
+
+#endif
 }
 
 void
@@ -396,8 +420,16 @@
 #ifdef HAVE_KATE
   OggPlayKateDecode   * decoder = (OggPlayKateDecode *)user_data;
 
-  kate_high_decode_clear(&(decoder->k));
+#ifdef HAVE_TIGER
+  if (decoder->tr) {
+    tiger_renderer_destroy(decoder->tr);
+  }
 #endif
+
+  if (decoder->init) {
+    kate_high_decode_clear(&(decoder->k));
+  }
+#endif
 }
 
 int
@@ -414,8 +446,15 @@
   const kate_event *ev = NULL;
   int ret;
 
+  if (!decoder->init) {
+    return E_OGGPLAY_UNINITIALISED;
+  }
+
   kate_packet_wrap(&kp, op->bytes, op->packet);
   ret = kate_high_decode_packetin(&(decoder->k), &kp, &ev);
+  if (ret < 0) {
+    return E_OGGPLAY_BAD_INPUT;
+  }
 
   if (granulepos != -1) {
     granuleshift = oggz_get_granuleshift(oggz, serialno);

Modified: liboggplay/trunk/src/liboggplay/oggplay_callback_info.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_callback_info.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_callback_info.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -72,6 +72,24 @@
     
     (*info)[i] = track_info;
 
+#ifdef HAVE_TIGER
+    /* not so nice to have this here, but the tiger_renderer needs updating regularly
+     * as some items may be animated, so would yield data without the stream actually
+     * receiving any packets.
+     * In addition, Kate streams can now be overlayed on top of a video, so this needs
+     * calling to render the overlay.
+     * FIXME: is this the best place to put this ? Might do too much work if the info
+     * is going to be destroyed ?
+     */
+    if (track->content_type == OGGZ_CONTENT_KATE) {
+      OggPlayKateDecode *decode = (OggPlayKateDecode *)track;
+      OggPlayCallbackInfo * video_info = NULL;
+      if (decode->overlay_dest >= 0)
+        video_info = me->callback_info + decode->overlay_dest;
+      oggplay_data_update_tiger(decode, track->active, me->target, video_info);
+    }
+#endif
+
     /*
      * this track is inactive and has no data - create an empty record
      * for it
@@ -432,6 +450,17 @@
 
 }
 
+OggPlayOverlayData *
+oggplay_callback_info_get_overlay_data(OggPlayDataHeader *header) {
+
+  if (header == NULL) {
+    return NULL;
+  }
+
+  return &((OggPlayOverlayRecord *)header)->data;
+
+}
+
 OggPlayAudioData *
 oggplay_callback_info_get_audio_data(OggPlayDataHeader *header) {
 

Modified: liboggplay/trunk/src/liboggplay/oggplay_data.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_data.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_data.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -37,6 +37,7 @@
  */
 
 #include "oggplay_private.h"
+#include "oggplay/oggplay_callback_info.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -350,7 +351,6 @@
 
   record->header.samples_in_record = 1;
   data = &(record->data);
-  oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
 
   data->y = (unsigned char *)(record + 1);
   data->u = data->y + (decode->y_stride * decode->y_height);
@@ -381,31 +381,161 @@
     q2 += buffer->uv_stride;
   }
 
-  oggplay_data_add_to_list((OggPlayDecode *)decode, &(record->header));
+  /* if we're to send RGB video, convert here */
+  if (decode->convert_to_rgb) {
+    OggPlayYUVChannels      yuv;
+    OggPlayRGBChannels      rgb;
+    OggPlayOverlayRecord  * orecord;
+    OggPlayOverlayData    * odata;
+
+    yuv.ptry = data->y;
+    yuv.ptru = data->u;
+    yuv.ptrv = data->v;
+    yuv.y_width = decode->y_width;
+    yuv.y_height = decode->y_height;
+    yuv.uv_width = decode->uv_width;
+    yuv.uv_height = decode->uv_height;
+
+    size = sizeof(OggPlayOverlayRecord) + decode->y_width * decode->y_height * 4;
+    orecord = (OggPlayOverlayRecord*) oggplay_malloc (size);
+    if (orecord) {
+      oggplay_data_initialise_header((OggPlayDecode *)decode, &(orecord->header));
+      orecord->header.samples_in_record = 1;
+      odata = &(orecord->data);
+
+      rgb.ptro = (unsigned char*)(orecord+1);
+      rgb.rgb_width = yuv.y_width;
+      rgb.rgb_height = yuv.y_height;
+
+      oggplay_yuv2rgba(&yuv, &rgb);
+
+//      odata->rgb = NULL;
+//      odata->rgba = rgb.ptro;
+      odata->rgb = rgb.ptro;
+      odata->rgba = NULL;
+      odata->width = rgb.rgb_width;
+      odata->height = rgb.rgb_height;
+      odata->stride = rgb.rgb_width*4;
+
+      oggplay_free(record);
+    
+      oggplay_data_add_to_list((OggPlayDecode *)decode, &(orecord->header));
+    }
+  }
+  else {
+    oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
+    oggplay_data_add_to_list((OggPlayDecode *)decode, &(record->header));
+  }
 }
 
 #ifdef HAVE_KATE
 void
 oggplay_data_handle_kate_data(OggPlayKateDecode *decode, const kate_event *ev) {
 
-  // TODO: should be able to send the data rendered as YUV data, but just text for now
-
   OggPlayTextRecord * record = NULL;
 
-  record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
-  
-  if (record = NULL)
-    return;
+#ifdef HAVE_TIGER
+  tiger_renderer_add_event(decode->tr, ev->ki, ev);
 
-  oggplay_data_initialise_header(&decode->decoder, &(record->header));
+  if (decode->use_tiger) {
+    /* if rendering with Tiger, we don't add an event, a synthetic one will be
+       generated each "tick" with an updated tracker state */
+  }
+  else
+#endif
+  {
+    record = (OggPlayTextRecord*)oggplay_calloc (sizeof(OggPlayTextRecord) + ev->len0, 1);
+    if (!record)
+      return;
 
-  //record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
-  record->header.samples_in_record = (ev->end_time-ev->start_time)*1000;
-  record->data = (char *)(record + 1);
+    oggplay_data_initialise_header(&decode->decoder, &(record->header));
 
-  memcpy(record->data, ev->text, ev->len0);
+    //record->header.presentation_time = (ogg_int64_t)(ev->start_time*1000);
+    record->header.samples_in_record = (ev->end_time-ev->start_time)*1000;
+    record->data = (char *)(record + 1);
 
-  oggplay_data_add_to_list(&decode->decoder, &(record->header));
+    memcpy(record->data, ev->text, ev->len0);
+
+    oggplay_data_add_to_list(&decode->decoder, &(record->header));
+  }
 }
 #endif
 
+#ifdef HAVE_TIGER
+void
+oggplay_data_update_tiger(OggPlayKateDecode *decode, int active, ogg_int64_t presentation_time, OggPlayCallbackInfo *info) {
+
+  OggPlayOverlayRecord  * record = NULL;
+  OggPlayOverlayData    * data = NULL;
+  size_t                size = sizeof (OggPlayOverlayRecord);
+  int                   track = active && decode->use_tiger;
+  kate_float            t = ((((presentation_time >> 16) * 1000) >> 16) & 0xFFFFFFFF) / 1000.0f;
+
+  if (!decode->init) return;
+
+  if (track) {
+    if (info) {
+      if (info->required_records>0) {
+        OggPlayDataHeader *header = info->records[0];
+        data = (OggPlayOverlayData*)(header+1);
+        if (decode->tr && data->rgb) {
+          tiger_renderer_set_buffer(decode->tr, data->rgb, data->width, data->height, data->stride, 1);
+        }
+        else {
+          /* we're supposed to overlay on a frame, but the available frame has no RGB buffer */
+          /* fprintf(stderr,"no RGB buffer found for video frame\n"); */
+          return;
+        }
+      }
+      else {
+        /* we're supposed to overlay on a frame, but there is no frame available */
+        /* fprintf(stderr,"no video frame to overlay on\n"); */
+        return;
+      }
+    }
+    else {
+      // TODO: some way of knowing the size of the video we'll be drawing onto, if any
+      int width = decode->k.ki->original_canvas_width;
+      int height = decode->k.ki->original_canvas_height;
+      if (width <= 0 || height <= 0) {
+        /* some default resolution if we're not overlaying onto a video and the canvas size is unknown */
+        width = 640;
+        height = 480;
+      }
+      size = sizeof (OggPlayOverlayRecord) + width*height*4;
+      record = (OggPlayOverlayRecord*)oggplay_calloc (1, size);
+      if (!record)
+        return;
+
+      record->header.samples_in_record = 1;
+      data= &(record->data);
+      oggplay_data_initialise_header((OggPlayDecode *)decode, &(record->header));
+
+      data->rgba = (unsigned char*)(record+1);
+      data->rgb = NULL;
+      data->width = width;
+      data->height = height;
+      data->stride = width*4;
+
+      if (decode->tr && data->rgba) {
+        tiger_renderer_set_buffer(decode->tr, data->rgba, data->width, data->height, data->stride, 1);
+      }
+
+      oggplay_data_add_to_list(&decode->decoder, &(record->header));
+      record->header.presentation_time=presentation_time;
+    }
+  }
+
+  if (decode->tr) {
+    tiger_renderer_update(decode->tr, t, track);
+  }
+
+  if (track) {
+    /* buffer was either calloced, so already cleared, or already filled with video, so no clearing */
+    if (decode->tr) {
+      tiger_renderer_render(decode->tr);
+    }
+  }
+}
+#endif
+

Modified: liboggplay/trunk/src/liboggplay/oggplay_data.h
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_data.h	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_data.h	2009-03-02 11:44:46 UTC (rev 3868)
@@ -59,7 +59,14 @@
                               const kate_event *ev);
 #endif
 
+#ifdef HAVE_TIGER
 void
+oggplay_data_update_tiger(OggPlayKateDecode *decode,
+                          int active, ogg_int64_t presentation_time,
+                          OggPlayCallbackInfo *info);
+#endif
+
+void
 oggplay_data_clean_list (OggPlayDecode *decode);
 
 void

Modified: liboggplay/trunk/src/liboggplay/oggplay_file_reader.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_file_reader.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_file_reader.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -153,6 +153,7 @@
   me->functions.io_read = &oggplay_file_reader_io_read;
   me->functions.io_seek = &oggplay_file_reader_io_seek;
   me->functions.io_tell = &oggplay_file_reader_io_tell;
+  me->functions.duration = NULL;
 
   return (OggPlayReader *)me;
 

Modified: liboggplay/trunk/src/liboggplay/oggplay_private.h
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_private.h	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_private.h	2009-03-02 11:44:46 UTC (rev 3868)
@@ -52,6 +52,9 @@
 #ifdef HAVE_KATE
 #include <kate/kate.h>
 #endif
+#ifdef HAVE_TIGER
+#include <tiger/tiger.h>
+#endif
 
 #ifdef WIN32
 #include "config_win32.h"
@@ -85,6 +88,11 @@
 
 typedef struct {
   OggPlayDataHeader   header;
+  OggPlayOverlayData  data;
+} OggPlayOverlayRecord;
+
+typedef struct {
+  OggPlayDataHeader   header;
   void              * data;
 } OggPlayAudioRecord;
 
@@ -167,6 +175,7 @@
   int             uv_height;
   int             uv_stride;
   int             cached_keyframe;
+  int             convert_to_rgb;
 } OggPlayTheoraDecode;
 
 typedef struct {
@@ -191,7 +200,13 @@
 #ifdef HAVE_KATE
   int             granuleshift;
   kate_state      k;
+  int             init;
+#ifdef HAVE_TIGER
+  int use_tiger;
+  int overlay_dest;
+  tiger_renderer *tr;
 #endif
+#endif
 } OggPlayKateDecode;
 
 struct OggPlaySeekTrash;

Modified: liboggplay/trunk/src/liboggplay/oggplay_seek.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_seek.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_seek.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -137,6 +137,20 @@
   }
 
   /*
+  * we need to notify the tiger renderer that we seeked, so that
+  * now obsolete events are discarded
+  */
+#ifdef HAVE_TIGER
+  for (i = 0; i < me->num_tracks; i++) {
+    OggPlayDecode *track = me->decode_data[i];
+    if (track && track->content_type == OGGZ_CONTENT_KATE) {
+      OggPlayKateDecode *decode = (OggPlayKateDecode *)(me->decode_data[i]);
+      if (decode->use_tiger) tiger_renderer_seek(decode->tr, milliseconds/1000.0);
+    }
+  }
+#endif
+
+  /*
    * set the presentation time
    */
   me->presentation_time = milliseconds;

Modified: liboggplay/trunk/src/liboggplay/oggplay_yuv2rgb.c
===================================================================
--- liboggplay/trunk/src/liboggplay/oggplay_yuv2rgb.c	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/src/liboggplay/oggplay_yuv2rgb.c	2009-03-02 11:44:46 UTC (rev 3868)
@@ -141,6 +141,12 @@
 out[2] = CLAMP(g); \
 out[3] = CLAMP(b);
 
+#define VANILLA_ABGR_OUT(out, r, g, b) \
+out[0] = 255;	   \
+out[1] = CLAMP(b); \
+out[2] = CLAMP(g); \
+out[3] = CLAMP(r);
+
 /* yuv420p -> */
 #define LOOKUP_COEFFS int ruv = CoefsRV[*pv]; 			\
 		      int guv = CoefsGU[*pu] + CoefsGV[*pv]; 	\
@@ -157,6 +163,7 @@
 
 YUV_CONVERT(yuv420_to_rgba_vanilla, CONVERT(VANILLA_RGBA_OUT), 2, 8, 2, 1)
 YUV_CONVERT(yuv420_to_bgra_vanilla, CONVERT(VANILLA_BGRA_OUT), 2, 8, 2, 1)
+YUV_CONVERT(yuv420_to_abgr_vanilla, CONVERT(VANILLA_ABGR_OUT), 2, 8, 2, 1)
 YUV_CONVERT(yuv420_to_argb_vanilla, CONVERT(VANILLA_ARGB_OUT), 2, 8, 2, 1)
 
 #undef CONVERT
@@ -201,18 +208,27 @@
 #elif defined(__ppc__) || defined(__ppc64__)
 		if (features & OC_CPU_PPC_ALTIVEC)
 		{
-			init_altivec();
+      init_tables();
 			yuv_conv.yuv2rgba = yuv420_to_rgba_vanilla;
 			yuv_conv.yuv2bgra = yuv420_to_bgra_vanilla;
 			yuv_conv.yuv2argb = yuv420_to_argb_vanilla;
 			return;
 		}
 #endif		
-		/* no CPU extension was found... using vanilla converter */
+		/*
+     * no CPU extension was found... using vanilla converter, with respect
+     * to the endianness of the host
+     */
 		init_tables();
+#if WORDS_BIGENDIAN || IS_BIG_ENDIAN 
+		yuv_conv.yuv2rgba = yuv420_to_abgr_vanilla;
+		yuv_conv.yuv2bgra = yuv420_to_argb_vanilla;
+		yuv_conv.yuv2argb = yuv420_to_bgra_vanilla;
+#else
 		yuv_conv.yuv2rgba = yuv420_to_rgba_vanilla;
 		yuv_conv.yuv2bgra = yuv420_to_bgra_vanilla;
 		yuv_conv.yuv2argb = yuv420_to_argb_vanilla;
+#endif
 	}
 }
 

Modified: liboggplay/trunk/win32/liboggplay.def
===================================================================
--- liboggplay/trunk/win32/liboggplay.def	2009-02-26 05:22:37 UTC (rev 3867)
+++ liboggplay/trunk/win32/liboggplay.def	2009-03-02 11:44:46 UTC (rev 3868)
@@ -63,5 +63,6 @@
 ; Oggplay SSE YUV <-> RGB converter functions
 ;
 
-oggplay_yuv2rgb				@33
-oggplay_yuv2bgr				@34
+oggplay_yuv2rgba				@33
+oggplay_yuv2bgra				@34
+oggplay_yuv2argb				@33



More information about the commits mailing list