since ogle is imo still the best DVD player ... this seems to be working well for me, but there are maybe a few issues, so I would like some testing feedback.
possible issues: * ogle tries to not buffer more than 200ms of audio data by using nanosleep() if there is more than that buffered. this scheme doesn't really make sense to me. the MPEG packets have timestamps and ogle keeps track of what has been played and what the current offset is, so I really don't see why it would use sleep semantics here. with the nanosleep active, it doesn't play smoothly and A/Vsync is off. with the nanosleep commented out, playback is smooth and A/V sync seems good to me. * didn't implement either the flush or drain functions. afaics, these aren't needed, even with ogle bufferring more than 200ms of audio data. so the main thing to check is A/V sync, especially when skipping to different titles/programs/scenes. -- jake...@sdf.lonestar.org SDF Public Access UNIX System - http://sdf.lonestar.org Index: Makefile =================================================================== RCS file: /cvs/ports/x11/ogle/Makefile,v retrieving revision 1.38 diff -u -r1.38 Makefile --- Makefile 25 Jan 2009 18:58:58 -0000 1.38 +++ Makefile 10 Feb 2009 11:53:35 -0000 @@ -6,7 +6,7 @@ COMMENT= DVD player DISTNAME= ogle-0.9.2 -PKGNAME= ${DISTNAME}p5 +PKGNAME= ${DISTNAME}p6 SHARED_LIBS= dvdcontrol 11.0 \ msgevents 8.0 HOMEPAGE= http://www.dtek.chalmers.se/groups/dvd/ @@ -25,7 +25,7 @@ PERMIT_PACKAGE_FTP=Yes WANTLIB= ICE SM X11 Xext Xinerama Xv Xxf86vm c iconv m z \ - Xau Xdmcp + Xau Xdmcp sndio LIB_DEPENDS= a52::audio/liba52 \ dvdread.>=3.0::devel/libdvdread \ @@ -54,7 +54,7 @@ --with-libmad=${DEPBASE} \ --with-xml-prefix=${DEPBASE} -CONFIGURE_ENV+=xml_config_args=--prefix=${DEPBASE} +CONFIGURE_ENV+=xml_config_args=--prefix=${DEPBASE} LIBOGLEAO_LIBS="-lsndio" post-install: cd ${PREFIX}/man/man5 && mv oglerc.5 oglerc.tbl Index: patches/patch-ac3_audio_play_c =================================================================== RCS file: patches/patch-ac3_audio_play_c diff -N patches/patch-ac3_audio_play_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-ac3_audio_play_c 10 Feb 2009 11:53:35 -0000 @@ -0,0 +1,12 @@ +$OpenBSD$ +--- ac3/audio_play.c.orig Mon Feb 9 07:07:21 2009 ++++ ac3/audio_play.c Mon Feb 9 07:07:37 2009 +@@ -273,7 +273,7 @@ int play_samples(adec_handle_t *h, int scr_nr, uint64_ + + nanosleep(&st, NULL); + #else +- nanosleep(&sleep_time, NULL); ++ //nanosleep(&sleep_time, NULL); + #endif + } + Index: patches/patch-configure =================================================================== RCS file: /cvs/ports/x11/ogle/patches/patch-configure,v retrieving revision 1.7 diff -u -r1.7 patch-configure --- patches/patch-configure 27 Apr 2005 10:29:54 -0000 1.7 +++ patches/patch-configure 10 Feb 2009 11:53:35 -0000 @@ -1,6 +1,6 @@ $OpenBSD: patch-configure,v 1.7 2005/04/27 10:29:54 espie Exp $ ---- configure.orig Tue Nov 4 12:34:13 2003 -+++ configure Wed Apr 27 12:22:32 2005 +--- configure.orig Tue Nov 4 03:34:13 2003 ++++ configure Sun Feb 8 23:20:43 2009 @@ -11184,7 +11184,7 @@ fi echo "$as_me:$LINENO: result: $ac_cv_lib_jpeg_main" >&5 echo "${ECHO_T}$ac_cv_lib_jpeg_main" >&6 @@ -19,7 +19,7 @@ DVDREAD_CPPFLAGS=-I$dvd_path/include else -@@ -12346,7 +12346,7 @@ echo "$as_me:$LINENO: result: $ac_cv_lib +@@ -12346,7 +12346,7 @@ echo "$as_me:$LINENO: result: $ac_cv_lib_a52_a52_free" echo "${ECHO_T}$ac_cv_lib_a52_a52_free" >&6 if test $ac_cv_lib_a52_a52_free = yes; then @@ -28,7 +28,7 @@ A52_CPPFLAGS=-I$a52_path/include else -@@ -12710,7 +12710,7 @@ echo "$as_me:$LINENO: result: $ac_cv_lib +@@ -12710,7 +12710,7 @@ echo "$as_me:$LINENO: result: $ac_cv_lib_mad_mad_frame echo "${ECHO_T}$ac_cv_lib_mad_mad_frame_decode" >&6 if test $ac_cv_lib_mad_mad_frame_decode = yes; then @@ -37,3 +37,12 @@ MAD_CPPFLAGS=-I$mad_path/include else +@@ -13022,7 +13022,7 @@ _ACEOF + + BUILD_AUDIO_OBSD=1 + DEFAULT_AUDIO_DRIVER="obsd" +- DEFAULT_AUDIO_DEVICE="/dev/audio" ++ DEFAULT_AUDIO_DEVICE="ao_obsd_default" + ;; + esac + fi Index: patches/patch-libogleao_obsd_audio_c =================================================================== RCS file: patches/patch-libogleao_obsd_audio_c diff -N patches/patch-libogleao_obsd_audio_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-libogleao_obsd_audio_c 10 Feb 2009 11:53:35 -0000 @@ -0,0 +1,234 @@ +$OpenBSD$ +--- libogleao/obsd_audio.c.orig Sat Feb 22 07:06:51 2003 ++++ libogleao/obsd_audio.c Mon Feb 9 07:20:20 2009 +@@ -18,44 +18,45 @@ + + #ifdef LIBOGLEAO_OBSD + ++#include <errno.h> ++#include <poll.h> ++#include <sndio.h> + #include <stdio.h> + #include <stdlib.h> +-#include <sys/ioctl.h> ++#include <string.h> + #include <unistd.h> +-#include <inttypes.h> + +-#include <fcntl.h> +-#include <sys/audioio.h> +- +-#include <sys/types.h> +-#include <sys/conf.h> +- +-#include <string.h> +- + #include "ogle_ao.h" + #include "ogle_ao_private.h" + + typedef struct obsd_instance_s { + ogle_ao_instance_t ao; +- int fd; ++ struct sio_hdl *hdl; + int sample_rate; + int samples_written; ++ int samples_played; + int sample_frame_size; + int initialized; + } obsd_instance_t; + ++static ++void obsd_onmove(void *addr, int delta) ++{ ++ obsd_instance_t *instance = (obsd_instance_t *)addr; ++ instance->samples_played += delta; ++} + + static + int obsd_init(ogle_ao_instance_t *_instance, + ogle_ao_audio_info_t *audio_info) + { + int single_sample_size; +- audio_info_t info; ++ struct sio_par par, askpar; + obsd_instance_t *instance = (obsd_instance_t *)_instance; + +- AUDIO_INITINFO(&info); +- info.play.sample_rate = audio_info->sample_rate; +- info.play.precision = audio_info->sample_resolution; ++ sio_initpar(&par); ++ par.rate = audio_info->sample_rate; ++ par.bits = audio_info->sample_resolution; + + if(audio_info->chtypes != OGLE_AO_CHTYPE_UNSPECIFIED) { + // do this only if we have requested specific channels in chtypes +@@ -69,40 +70,54 @@ int obsd_init(ogle_ao_instance_t *_instance, + } + audio_info->chlist = NULL; + +- info.play.channels = audio_info->channels; +- info.lowat = 5; +- switch(audio_info->encoding) { +- case OGLE_AO_ENCODING_LINEAR: +- default: +- info.play.encoding = AUDIO_ENCODING_LINEAR; +- break; ++ par.pchan = audio_info->channels; ++ par.sig = 1; ++ par.round = par.rate / 8; ++ par.appbufsz = par.round * 2; ++ ++ askpar = par; ++ ++ if (!sio_setpar(instance->hdl, &par)) { ++ fprintf(stderr, "sio_setpar failed\n"); ++ return -1; + } +- +- /* set the audio format */ +- if(ioctl(instance->fd, AUDIO_SETINFO, &info) == -1) { +- perror("setinfo"); ++ if (!sio_getpar(instance->hdl, &par)) { ++ fprintf(stderr, "sio_getpar failed\n"); + return -1; + } +- +- /* Check that we actually got the requested nuber of channles, +- * the frequency and precision that we asked for? */ ++ if (par.pchan != askpar.pchan || ++ par.bits != askpar.bits || ++ (par.rate * 100 > askpar.rate * 105 || par.rate * 100 < askpar.rate * 95)) { ++ fprintf(stderr, "could not configure audio device as desired\n"); ++ return -1; ++ } + + if(audio_info->chtypes != OGLE_AO_CHTYPE_UNSPECIFIED) { +- audio_info->chlist = malloc(info.play.channels * sizeof(ogle_ao_chtype_t)); ++ audio_info->chlist = malloc(par.pchan * sizeof(ogle_ao_chtype_t)); + + audio_info->chlist[0] = OGLE_AO_CHTYPE_LEFT; + audio_info->chlist[1] = OGLE_AO_CHTYPE_RIGHT; + } + + /* Stored as 8bit, 16bit, or 32bit */ +- single_sample_size = (info.play.precision + 7) / 8; ++ single_sample_size = (par.bits + 7) / 8; + if(single_sample_size > 2) { + single_sample_size = 4; + } +- instance->sample_frame_size = single_sample_size*info.play.channels; ++ instance->sample_frame_size = single_sample_size*par.pchan; ++ ++ sio_onmove(instance->hdl, obsd_onmove, instance); ++ instance->samples_played = 0; ++ instance->samples_written = 0; ++ ++ if (!sio_start(instance->hdl)) { ++ fprintf(stderr, "sio_start failed\n"); ++ return -1; ++ } ++ ++ audio_info->sample_frame_size = instance->sample_frame_size; + instance->initialized = 1; + +- audio_info->sample_frame_size = instance->sample_frame_size; + return 0; + } + +@@ -112,9 +127,9 @@ int obsd_play(ogle_ao_instance_t *_instance, void *sam + obsd_instance_t *instance = (obsd_instance_t *)_instance; + int written; + +- written = write(instance->fd, samples, nbyte); +- if(written == -1) { +- perror("audio write"); ++ written = sio_write(instance->hdl, samples, nbyte); ++ if(written != nbyte) { ++ fprintf(stderr, "sio_write failed\n"); + return -1; + } + +@@ -126,15 +141,20 @@ static + int obsd_odelay(ogle_ao_instance_t *_instance, uint32_t *samples_return) + { + obsd_instance_t *instance = (obsd_instance_t *)_instance; +- audio_info_t info; ++ struct pollfd pfd; ++ int revents, n; + int odelay; + +- if (ioctl(instance->fd, AUDIO_GETINFO, &info) == -1) { +- perror("AUDIO_GETINFO"); +- return -1; +- } ++ // update counters ++ n = sio_pollfd(instance->hdl, &pfd, POLLOUT); ++ while(poll(&pfd, n, 0) < 0 && errno == EINTR) ++ ; ++ revents = sio_revents(instance->hdl, &pfd); + +- odelay = info.play.seek / instance->sample_frame_size; ++ odelay = instance->samples_written - instance->samples_played; ++ ++ if (odelay < 0) ++ odelay = 0; + *samples_return = odelay; + + return 0; +@@ -145,7 +165,7 @@ void obsd_close(ogle_ao_instance_t *_instance) + { + obsd_instance_t *instance = (obsd_instance_t *)_instance; + +- close(instance->fd); ++ sio_close(instance->hdl); + } + + static +@@ -153,13 +173,11 @@ int obsd_flush(ogle_ao_instance_t *_instance) + { + obsd_instance_t *instance = (obsd_instance_t *)_instance; + +- fprintf(stderr, "AUDIO_FLUSH called\n"); +- ioctl(instance->fd, AUDIO_FLUSH, NULL); +- +- instance->samples_written = 0; +- +- ioctl(instance->fd, AUDIO_DRAIN, 0); +- ++fprintf(stderr, "\ncalled obsd_flush\n"); ++ ++ //instance->samples_written = 0; ++ //instance->samples_played = 0; ++ + return 0; + } + +@@ -168,8 +186,8 @@ int obsd_drain(ogle_ao_instance_t *_instance) + { + obsd_instance_t *instance = (obsd_instance_t *)_instance; + +- ioctl(instance->fd, AUDIO_DRAIN, 0); +- ++fprintf(stderr, "\ncalled obsd_drain\n"); ++ + return 0; + } + +@@ -192,10 +210,15 @@ ogle_ao_instance_t *obsd_open(char *dev) + instance->initialized = 0; + instance->sample_rate = 0; + instance->samples_written = 0; ++ instance->samples_played = 0; + instance->sample_frame_size = 0; ++ ++ if(strncmp(dev, "ao_obsd_default", 15) == 0) ++ instance->hdl = sio_open(NULL, SIO_PLAY, 0); ++ else ++ instance->hdl = sio_open(dev, SIO_PLAY, 0); + +- instance->fd = open(dev, O_WRONLY); +- if(instance->fd < 0) { ++ if(instance->hdl == NULL) { + fprintf(stderr, "Can not open %s\n", dev); + free(instance); + return NULL; Index: patches/patch-mpeg2_video_spu_mixer_c =================================================================== RCS file: /cvs/ports/x11/ogle/patches/patch-mpeg2_video_spu_mixer_c,v retrieving revision 1.4 diff -u -r1.4 patch-mpeg2_video_spu_mixer_c --- patches/patch-mpeg2_video_spu_mixer_c 13 Nov 2003 18:46:47 -0000 1.4 +++ patches/patch-mpeg2_video_spu_mixer_c 10 Feb 2009 11:53:35 -0000 @@ -1,6 +1,6 @@ $OpenBSD: patch-mpeg2_video_spu_mixer_c,v 1.4 2003/11/13 18:46:47 espie Exp $ ---- mpeg2_video/spu_mixer.c.orig 2003-10-20 22:28:27.000000000 +0200 -+++ mpeg2_video/spu_mixer.c 2003-11-06 07:34:50.000000000 +0100 +--- mpeg2_video/spu_mixer.c.orig Mon Oct 20 13:28:27 2003 ++++ mpeg2_video/spu_mixer.c Sun Feb 8 12:15:47 2009 @@ -45,6 +45,8 @@ @@ -10,7 +10,7 @@ #ifdef DEBUG #define GETBYTES(a,b) getbytes(a,b) -@@ -966,6 +968,7 @@ static void decode_display_data(spu_hand +@@ -966,6 +968,7 @@ static void decode_display_data(spu_handle_t *spu_info y = 0; DPRINTF(5, "vlc decoding\n"); @@ -18,7 +18,7 @@ while((fieldoffset[1] < spu_info->DCSQT_offset) && (y < spu_info->height)) { unsigned int vlc; unsigned int length; -@@ -1031,7 +1034,7 @@ static void decode_display_data(spu_hand +@@ -1031,7 +1034,7 @@ static void decode_display_data(spu_handle_t *spu_info #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif { Index: patches/patch-mpeg2_video_spu_mixer_h =================================================================== RCS file: /cvs/ports/x11/ogle/patches/patch-mpeg2_video_spu_mixer_h,v retrieving revision 1.2 diff -u -r1.2 patch-mpeg2_video_spu_mixer_h --- patches/patch-mpeg2_video_spu_mixer_h 13 Nov 2003 18:46:47 -0000 1.2 +++ patches/patch-mpeg2_video_spu_mixer_h 10 Feb 2009 11:53:35 -0000 @@ -1,7 +1,7 @@ $OpenBSD: patch-mpeg2_video_spu_mixer_h,v 1.2 2003/11/13 18:46:47 espie Exp $ ---- mpeg2_video/spu_mixer.h.orig 2003-10-20 18:34:33.000000000 +0200 -+++ mpeg2_video/spu_mixer.h 2003-11-06 07:34:50.000000000 +0100 -@@ -25,6 +25,9 @@ void mix_subpicture_init(int pixel_strid +--- mpeg2_video/spu_mixer.h.orig Mon Oct 20 09:34:33 2003 ++++ mpeg2_video/spu_mixer.h Sun Feb 8 12:15:47 2009 +@@ -25,6 +25,9 @@ void mix_subpicture_init(int pixel_stride,int mode); void mix_subpicture_rgb(char *data, int width, int height); int mix_subpicture_yuv(yuv_image_t *img, yuv_image_t *reserv); Index: patches/patch-mpeg2_video_video_output_x11_c =================================================================== RCS file: /cvs/ports/x11/ogle/patches/patch-mpeg2_video_video_output_x11_c,v retrieving revision 1.8 diff -u -r1.8 patch-mpeg2_video_video_output_x11_c --- patches/patch-mpeg2_video_video_output_x11_c 13 Nov 2003 18:46:47 -0000 1.8 +++ patches/patch-mpeg2_video_video_output_x11_c 10 Feb 2009 11:53:35 -0000 @@ -1,7 +1,7 @@ $OpenBSD: patch-mpeg2_video_video_output_x11_c,v 1.8 2003/11/13 18:46:47 espie Exp $ ---- mpeg2_video/video_output_x11.c.orig 2003-11-04 13:02:10.000000000 +0100 -+++ mpeg2_video/video_output_x11.c 2003-11-06 07:34:50.000000000 +0100 -@@ -1377,6 +1377,12 @@ void check_x_events(yuv_image_t *current +--- mpeg2_video/video_output_x11.c.orig Tue Nov 4 04:02:10 2003 ++++ mpeg2_video/video_output_x11.c Sun Feb 8 12:15:47 2009 +@@ -1377,6 +1377,12 @@ void check_x_events(yuv_image_t *current_image) break; } } @@ -14,7 +14,7 @@ } break; case KeyRelease: -@@ -2067,6 +2073,8 @@ static void draw_win_x11(window_info *dw +@@ -2067,6 +2073,8 @@ static void draw_win_x11(window_info *dwin) window.video_area.height); XSync(mydisplay, False); } @@ -23,7 +23,7 @@ } -@@ -2154,6 +2162,8 @@ static void draw_win_xv(window_info *dwi +@@ -2154,6 +2162,8 @@ static void draw_win_xv(window_info *dwin) It waits for an XShmCompletionEvent */ XIfEvent(mydisplay, &ev, predicate, NULL); }