summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-11-16 17:55:20 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-11-16 17:55:20 +0000
commiteeea841578de895ceea1e3bc478de87218d1508a (patch)
tree872e56f006d03f9ec418dcb1b1c3b997102d8436
parentd91a48cded0ab7e7f828f67928a7605c1d921640 (diff)
downloadxine-lib-eeea841578de895ceea1e3bc478de87218d1508a.tar.gz
xine-lib-eeea841578de895ceea1e3bc478de87218d1508a.tar.bz2
improving audio sync
CVS patchset: 1049 CVS date: 2001/11/16 17:55:20
-rw-r--r--src/libw32dll/Makefile.am2
-rw-r--r--src/libw32dll/w32codec.c91
2 files changed, 51 insertions, 42 deletions
diff --git a/src/libw32dll/Makefile.am b/src/libw32dll/Makefile.am
index 358dab4a2..7cf68b9a3 100644
--- a/src/libw32dll/Makefile.am
+++ b/src/libw32dll/Makefile.am
@@ -24,7 +24,7 @@ xineplug_decode_w32dll_la_LIBADD = $(top_builddir)/src/libw32dll/wine/libwine.la
$(top_builddir)/src/libw32dll/DirectShow/libds_filter.la @KSTAT_LIBS@
# $(top_builddir)/src/libw32dll/dshow_cpp/libds_filter.la @KSTAT_LIBS@
-noinst_HEADERS = w32codec.h
+noinst_HEADERS = w32codec.h libwin32.h
debug:
@list='$(SUBDIRS)'; for subdir in $$list; do \
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
index e8461b731..950f455e8 100644
--- a/src/libw32dll/w32codec.c
+++ b/src/libw32dll/w32codec.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: w32codec.c,v 1.43 2001/11/15 14:28:18 miguelfreitas Exp $
+ * $Id: w32codec.c,v 1.44 2001/11/16 17:55:20 miguelfreitas Exp $
*
* routines for using w32 codecs
* DirectShow support by Miguel Freitas (Nov/2001)
@@ -40,7 +40,6 @@
#include "DirectShow/guids.h"
#include "DirectShow/DS_AudioDecoder.h"
#include "DirectShow/DS_VideoDecoder.h"
-//#include "dshow_cpp/DS_AudioDec.h"
#include "video_out.h"
#include "audio_out.h"
@@ -86,6 +85,7 @@ typedef struct w32v_decoder_s {
int decoder_ok;
BITMAPINFOHEADER bih, o_bih;
+ char scratch1[10]; /* some codecs overflow o_bih */
HIC hic;
int yuv_supported ;
int yuv_hack_needed ;
@@ -111,13 +111,16 @@ typedef struct w32a_decoder_s {
audio_decoder_t audio_decoder;
ao_instance_t *audio_out;
- int output_open;
+ int output_open;
int decoder_ok;
unsigned char *buf;
int size;
uint32_t pts;
uint32_t scr;
+
+ /* these are used for pts estimation */
+ uint32_t lastpts, sumpts, sumsize;
unsigned char *outbuf;
int outsize;
@@ -451,7 +454,7 @@ static void w32v_init_codec (w32v_decoder_t *this, int buf_type) {
if ( this->img_buffer )
free (this->img_buffer);
this->img_buffer = malloc (this->o_bih.biSizeImage);
-
+
if ( this->buf )
free (this->buf);
this->bufsize = VIDEOBUFSIZE;
@@ -475,16 +478,8 @@ static void w32v_init_ds_codec (w32v_decoder_t *this, int buf_type) {
this->ldt_fs = Setup_LDT_Keeper();
- outfmt = IMGFMT_15RGB;
- if (this->yuv_supported) {
- vo_cap = this->video_out->get_capabilities (this->video_out);
- if (vo_cap & VO_CAP_YUY2)
- outfmt = IMGFMT_YUY2;
- }
-
ci.dll=win32_codec_name;
memcpy(&ci.guid,this->guid,sizeof(ci.guid));
-
this->ds_dec = DS_VideoDecoder_Create(&ci, &this->bih, this->flipped, 0);
if(!this->ds_dec){
@@ -493,9 +488,15 @@ static void w32v_init_ds_codec (w32v_decoder_t *this, int buf_type) {
this->decoder_ok = 0;
return;
}
-
- if(outfmt==IMGFMT_YUY2 || outfmt==IMGFMT_15RGB)
+ outfmt = IMGFMT_15RGB;
+ if (this->yuv_supported) {
+ vo_cap = this->video_out->get_capabilities (this->video_out);
+ if (vo_cap & VO_CAP_YUY2)
+ outfmt = IMGFMT_YUY2;
+ }
+
+ if(outfmt==IMGFMT_YUY2 || outfmt==IMGFMT_15RGB )
this->o_bih.biBitCount=16;
else
this->o_bih.biBitCount=outfmt&0xFF;
@@ -706,6 +707,11 @@ static void w32v_close (video_decoder_t *this_gen) {
w32v_decoder_t *this = (w32v_decoder_t *) this_gen;
+ if ( !this->ds_driver ) {
+ } else {
+ DS_VideoDecoder_Destroy(this->ds_dec);
+ }
+
if ( this->img_buffer ) {
free (this->img_buffer);
this->img_buffer = NULL;
@@ -916,24 +922,38 @@ static void w32a_decode_audio (w32a_decoder_t *this,
HRESULT hr;
int size_read, size_written;
/* DWORD srcsize=0; */
- int in_avg_pts_kbyte = 0;
-
-
- /* FIXME: the current code for estimating output pts don't work
- on wraps and seeks!!!
- also there might be serious sync problems. in short: it's
- somewhat broken and need fix.
+
+ /* FIXME: this code still far from perfect, there are a/v sync
+ issues with some streams.
*/
- if( !this->size || pts < this->pts || scr < this->scr ) {
+ /* buffer empty -> take pts/scr from package */
+ if( !this->size ) {
this->pts = pts;
this->scr = scr;
- } else {
- /* input based estimation disabled -> bad results */
- /* in_avg_pts_kbyte = (pts - this->pts) * 1024 / this->size; */
+ /*
+ printf("w32codec: resync pts (%d)\n",this->pts);
+ */
+ this->sumpts = this->sumsize = 0;
+ } else if ( !this->pts ) {
+ if( pts )
+ this->sumpts += (pts - this->lastpts);
+ this->sumsize += size;
}
-
+ /* force resync every 4 seconds */
+ if( this->sumpts >= 4 * 90000 && pts ) {
+ this->pts = pts - this->size * this->sumpts / this->sumsize;
+ this->scr = scr - this->size * this->sumpts / this->sumsize;
+ /*
+ printf("w32codec: estimated resync pts (%d)\n",this->pts);
+ */
+ this->sumpts = this->sumsize = 0;
+ }
+
+ if( pts )
+ this->lastpts = pts;
+
if( this->size + size > this->max_audio_src_size ) {
this->max_audio_src_size = this->size + size;
printf("w32codec: increasing source buffer to %d to avoid overflow.\n",
@@ -991,8 +1011,6 @@ static void w32a_decode_audio (w32a_decoder_t *this,
ash.cbSrcLengthUsed, ash.cbDstLengthUsed);
*/
DstLengthUsed = ash.cbDstLengthUsed;
- pts = this->pts;
- scr = this->scr;
p = this->outbuf;
while( DstLengthUsed )
@@ -1009,14 +1027,13 @@ static void w32a_decode_audio (w32a_decoder_t *this,
printf(" outputing %d bytes, pts = %d\n", bufsize, pts );
*/
audio_buffer->num_frames = bufsize / (this->num_channels*2);
- audio_buffer->vpts = pts;
- audio_buffer->scr = scr;
+ audio_buffer->vpts = this->pts;
+ audio_buffer->scr = this->scr;
this->audio_out->put_buffer (this->audio_out, audio_buffer);
- pts += bufsize / (this->num_channels*2) * 90000 / this->rate;
- scr += bufsize / (this->num_channels*2) * 90000 / this->rate;
- DstLengthUsed -= bufsize;
+ this->pts = this->scr = 0;
+ DstLengthUsed -= bufsize;
p += bufsize;
}
}
@@ -1025,14 +1042,6 @@ static void w32a_decode_audio (w32a_decoder_t *this,
} else {
this->size-=ash.cbSrcLengthUsed;
fast_memcpy( this->buf, &this->buf [ash.cbSrcLengthUsed], this->size);
-
- if( in_avg_pts_kbyte ) {
- this->pts += ash.cbSrcLengthUsed * in_avg_pts_kbyte / 1024;
- this->scr += ash.cbSrcLengthUsed * in_avg_pts_kbyte / 1024;
- } else {
- this->pts += ash.cbDstLengthUsed / (this->num_channels*2) * 90000 / this->rate;
- this->scr += ash.cbDstLengthUsed / (this->num_channels*2) * 90000 / this->rate;
- }
}
if( !this->ds_driver ) {