[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