From e05ef252cdfedebc10470253b2605be3c6c6b2db Mon Sep 17 00:00:00 2001 From: Guenter Bartsch Date: Sat, 16 Mar 2002 20:53:49 +0000 Subject: framerate and other fixes for demux_asf CVS patchset: 1574 CVS date: 2002/03/16 20:53:49 --- src/demuxers/demux_asf.c | 105 ++++++++++++++++++++++++++++------------ src/input/input_file.c | 12 +++-- src/input/input_plugin.h | 7 +-- src/libw32dll/w32codec.c | 64 ++++++++++++++++++------ src/xine-engine/buffer.h | 3 +- src/xine-engine/video_decoder.c | 6 +-- 6 files changed, 142 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index 770aa36c7..3fbe3715c 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000, 2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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: demux_asf.c,v 1.24 2002/03/11 12:31:24 guenter Exp $ + * $Id: demux_asf.c,v 1.25 2002/03/16 20:53:49 guenter Exp $ * * demultiplexer for asf streams * @@ -112,6 +112,7 @@ typedef struct demux_asf_s { /* packet filling */ int packet_size_left; + int64_t duration; /* only for reading */ int packet_padsize; @@ -124,6 +125,8 @@ typedef struct demux_asf_s { int status; int send_end_buffers; + + int send_discontinuity; /* byte reordering from audio streams */ int reorder_h; @@ -579,7 +582,6 @@ static void asf_reorder(demux_asf_t *this, uint8_t *src, int len){ static int asf_get_packet(demux_asf_t *this) { int timestamp, hdr_size; - uint32_t sig = 0; hdr_size = 11; @@ -610,13 +612,14 @@ static int asf_get_packet(demux_asf_t *this) { hdr_size++; } timestamp = get_le32(this); - get_le16(this); /* duration */ + this->duration += get_le16(this) * 90; /* duration */ if (this->packet_flags & 0x01) { this->nb_frames = get_byte(this); /* nb_frames */ hdr_size++; } else this->nb_frames = 1; + this->frame = 0; this->packet_size_left = this->packet_size - hdr_size; @@ -638,9 +641,28 @@ static void hexdump (unsigned char *data, int len, xine_t *xine) { } +static void asf_send_discontinuity (demux_asf_t *this, int64_t pts) { + + buf_element_t *buf; + + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + buf->type = BUF_CONTROL_DISCONTINUITY; + buf->disc_off = pts; + this->video_fifo->put (this->video_fifo, buf); + + if(this->audio_fifo) { + buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); + buf->type = BUF_CONTROL_DISCONTINUITY; + buf->disc_off = pts; + this->audio_fifo->put (this->audio_fifo, buf); + } + +} + + static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, - int frag_offset, int seq, int timestamp, - int frag_len, int payload_size) { + int frag_offset, int seq, int timestamp, + int frag_len, int payload_size) { buf_element_t *buf; int bufsize; @@ -688,6 +710,12 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, buf->input_time = 0 ; } buf->pts = timestamp * 90; + + if (buf->pts && this->send_discontinuity) { + this->send_discontinuity = 0; + asf_send_discontinuity (this, buf->pts); + } + buf->type = stream->buf_type; buf->size = bufsize; timestamp = 0; @@ -697,8 +725,13 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, /* test if whole packet read */ if (stream->frag_offset == payload_size) { - buf->decoder_flags = BUF_FLAG_FRAME_END; + if (this->duration) { + buf->decoder_flags = BUF_FLAG_FRAME_END | BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = this->duration; + } else + buf->decoder_flags = BUF_FLAG_FRAME_END; stream->frag_offset = 0; + this->duration = 0; } else buf->decoder_flags = 0; @@ -706,11 +739,10 @@ static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_stream_t *stream, } } - static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, - int frag_offset, int seq, int timestamp, - int frag_len, int payload_size) { - + int frag_offset, int seq, int timestamp, + int frag_len, int payload_size) { + buf_element_t *buf; /* @@ -761,6 +793,12 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, buf->pts = stream->timestamp * 90 + stream->ts_per_kbyte * (p-stream->buffer) / 1024; + + if (buf->pts && this->send_discontinuity) { + this->send_discontinuity = 0; + asf_send_discontinuity (this, buf->pts); + } + buf->type = stream->buf_type; buf->size = bufsize; @@ -768,9 +806,14 @@ static void asf_send_buffer_defrag (demux_asf_t *this, asf_stream_t *stream, p+=bufsize; /* test if whole packet read */ - if ( !stream->frag_offset ) - buf->decoder_flags = BUF_FLAG_FRAME_END ; - else + if ( !stream->frag_offset ) { + if (this->duration) { + buf->decoder_flags = BUF_FLAG_FRAME_END | BUF_FLAG_FRAMERATE; + buf->decoder_info[0] = this->duration; + } else + buf->decoder_flags = BUF_FLAG_FRAME_END; + this->duration = 0; + } else buf->decoder_flags = 0; stream->fifo->put (stream->fifo, buf); @@ -825,7 +868,7 @@ static void asf_read_packet(demux_asf_t *this) { /* fail safe */ /* printf ("demux_asf: reading new packet, packet size left %d\n", this->packet_size_left); - */ + */ if (this->packet_size_left) this->input->seek (this->input, this->packet_size_left, SEEK_CUR); @@ -872,8 +915,8 @@ static void asf_read_packet(demux_asf_t *this) { flags = get_byte(this); /* - printf ("\ndemux_asf: segment header, stream id %02x, frag_offset %d, flags : %02x\n", - stream_id, frag_offset, flags); + printf ("\ndemux_asf: segment header, stream id %02x, frag_offset %d, flags : %02x\n", + stream_id, frag_offset, flags); */ if (flags == 1) { @@ -894,8 +937,8 @@ static void asf_read_packet(demux_asf_t *this) { this->packet_size_left -= data_length + 4; /* - printf ("demux_asf: reading grouping part segment, size = %d\n", - data_length); + printf ("demux_asf: reading grouping part segment, size = %d\n", + data_length); */ } else { @@ -904,7 +947,7 @@ static void asf_read_packet(demux_asf_t *this) { this->packet_size_left = this->packet_padsize; /* - printf ("demux_asf: reading grouping single segment, size = %d\n", data_length); + printf ("demux_asf: reading grouping single segment, size = %d\n", data_length); */ } @@ -912,20 +955,20 @@ static void asf_read_packet(demux_asf_t *this) { int object_length = get_byte(this); /* - printf ("demux_asf: sending grouped object, len = %d\n", object_length); + printf ("demux_asf: sending grouped object, len = %d\n", object_length); */ if (stream) { if (stream->defrag) asf_send_buffer_defrag (this, stream, 0, seq, timestamp, - object_length, object_length); + object_length, object_length); else asf_send_buffer_nodefrag (this, stream, 0, seq, timestamp, - object_length, object_length); + object_length, object_length); } else { /* - printf ("demux_asf: unhandled stream type, id %d\n", stream_id); + printf ("demux_asf: unhandled stream type, id %d\n", stream_id); */ this->input->seek (this->input, object_length, SEEK_CUR); } @@ -950,9 +993,9 @@ static void asf_read_packet(demux_asf_t *this) { } this->packet_size_left -= FRAME_HEADER_SIZE + frag_len - 6; -/* - printf ("demux_asf: reading part segment, size = %d\n", - frag_len); + /* + printf ("demux_asf: reading part segment, size = %d\n", + frag_len); */ } else { @@ -960,7 +1003,7 @@ static void asf_read_packet(demux_asf_t *this) { this->packet_size_left = this->packet_padsize; /* - printf ("demux_asf: reading single segment, size = %d\n", frag_len); + printf ("demux_asf: reading single segment, size = %d\n", frag_len); */ } @@ -975,7 +1018,7 @@ static void asf_read_packet(demux_asf_t *this) { frag_len, payload_size); } else { /* - printf ("demux_asf: unhandled stream type, id %d\n", stream_id); + printf ("demux_asf: unhandled stream type, id %d\n", stream_id); */ this->input->seek (this->input, frag_len, SEEK_CUR); } @@ -1118,6 +1161,8 @@ static void demux_asf_start (demux_plugin_t *this_gen, this->num_video_streams = 0; this->packet_size = 0; this->seqno = 0; + this->send_discontinuity = 1; + this->duration = 0; if (this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) this->input->seek (this->input, 0, SEEK_SET); diff --git a/src/input/input_file.c b/src/input/input_file.c index 08d1e8839..71de6bdb8 100644 --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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: input_file.c,v 1.39 2002/02/17 17:32:50 guenter Exp $ + * $Id: input_file.c,v 1.40 2002/03/16 20:53:50 guenter Exp $ */ #ifdef HAVE_CONFIG_H @@ -379,6 +379,9 @@ static off_t file_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi static off_t file_plugin_get_current_pos (input_plugin_t *this_gen){ file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + if (this->fh <0) + return 0; + return lseek (this->fh, 0, SEEK_CUR); } @@ -390,6 +393,9 @@ static off_t file_plugin_get_length (input_plugin_t *this_gen) { struct stat buf ; file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + if (this->fh <0) + return 0; + if (fstat (this->fh, &buf) == 0) { return buf.st_size; } else diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h index b35490ca5..7406b87e3 100644 --- a/src/input/input_plugin.h +++ b/src/input/input_plugin.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000, 2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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: input_plugin.h,v 1.20 2001/12/09 23:09:32 guenter Exp $ + * $Id: input_plugin.h,v 1.21 2002/03/16 20:53:50 guenter Exp $ */ #ifndef HAVE_INPUT_PLUGIN_H @@ -299,6 +299,7 @@ struct input_plugin_s #define INPUT_OPTIONAL_DATA_TEXTSPU0 4 #define INPUT_OPTIONAL_DATA_TEXTSPU1 5 #define INPUT_OPTIONAL_DATA_TEXTSPU2 6 +#define INPUT_OPTIONAL_DATA_PREVIEW 7 /* * each input plugin _must_ implement this function: diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c index 352f43ac1..d197a387e 100644 --- a/src/libw32dll/w32codec.c +++ b/src/libw32dll/w32codec.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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.64 2002/03/11 12:31:26 guenter Exp $ + * $Id: w32codec.c,v 1.65 2002/03/16 20:53:50 guenter Exp $ * * routines for using w32 codecs * DirectShow support by Miguel Freitas (Nov/2001) @@ -46,7 +46,11 @@ #include "buffer.h" #include "xineutils.h" #include "xine_internal.h" - + +/* +#define LOG +*/ + static GUID CLSID_Voxware = { 0x73f7a062, 0x8829, 0x11d1, @@ -89,7 +93,7 @@ typedef struct w32v_decoder_s { video_decoder_t video_decoder; vo_instance_t *video_out; - int video_step; + int64_t video_step; int decoder_ok; BITMAPINFOHEADER bih, o_bih; @@ -396,7 +400,9 @@ static void w32v_init_codec (w32v_decoder_t *this, int buf_type) { w32v_init_rgb_ycc(); +#ifdef LOG printf ("w32codec: init codec...\n"); +#endif memset(&this->o_bih, 0, sizeof(BITMAPINFOHEADER)); this->o_bih.biSize = sizeof(BITMAPINFOHEADER); @@ -569,18 +575,26 @@ static void w32v_init_ds_codec (w32v_decoder_t *this, int buf_type) { static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { w32v_decoder_t *this = (w32v_decoder_t *) this_gen; - /* - printf ("w32codec: processing packet type = %08x, buf : %d, - buf->decoder_info[0]=%d\n", - buf->type, buf, buf->decoder_info[0]); - */ + +#ifdef LOG + printf ("w32codec: processing packet type = %08x, buf->decoder_flags=%08x\n", + buf->type, buf->decoder_flags); +#endif + if (buf->decoder_flags & BUF_FLAG_HEADER) { if ( buf->type & 0xff ) return; +#ifdef LOG + printf ("w32codec: processing header ...\n"); +#endif + /* init package containing bih */ memcpy ( &this->bih, buf->content, sizeof (BITMAPINFOHEADER)); this->video_step = buf->decoder_info[1]; +#ifdef LOG + printf ("w32codec: video_step is %lld\n", this->video_step); +#endif pthread_mutex_lock(&win32_codec_name_mutex); win32_codec_name = get_vids_codec_name (this, buf->type); @@ -596,7 +610,9 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { } else if (this->decoder_ok) { - /* printf ("w32codec: processing packet ...\n"); */ +#ifdef LOG + printf ("w32codec: processing packet ...\n"); +#endif if( (int) buf->size <= 0 ) return; @@ -617,6 +633,9 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { this->size += buf->size; + if (buf->decoder_flags & BUF_FLAG_FRAMERATE) + this->video_step = buf->decoder_info[0]; + if (buf->decoder_flags & BUF_FLAG_FRAME_END) { HRESULT ret; @@ -636,6 +655,10 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { img->duration = this->video_step; +#ifdef LOG + printf ("w32codec: frame duration is %lld\n", this->video_step); +#endif + if (this->outfmt==IMGFMT_YUY2) img_buffer = img->base[0]; @@ -654,7 +677,7 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { (this->skipframes)?NULL:img_buffer); } - if(!this->skipframes) { + if (!this->skipframes) { if (this->outfmt==IMGFMT_YUY2) { /* already decoded into YUY2 format by DLL */ /* @@ -718,12 +741,18 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { } img->pts = buf->pts; - if(ret || this->skipframes) { - if( !this->skipframes ) + if (ret || this->skipframes) { + if (!this->skipframes) printf("w32codec: Error decompressing frame, err=%ld\n", (long)ret); img->bad_frame = 1; +#ifdef LOG + printf ("w32codec: BAD FRAME, duration is %lld\n", img->duration); +#endif } else { img->bad_frame = 0; +#ifdef LOG + printf ("w32codec: GOOD FRAME, duration is %lld\n\n", img->duration); +#endif } if (img->copy && !this->skipframes) { @@ -740,7 +769,12 @@ static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { } this->skipframes = img->draw(img); - if( this->skipframes < 0 ) + +#ifdef LOG + printf ("w32codec: skipframes is %d\n", this->skipframes); +#endif + + if (this->skipframes < 0) this->skipframes = 0; img->free(img); diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h index 5444d78d5..e818d9cbf 100644 --- a/src/xine-engine/buffer.h +++ b/src/xine-engine/buffer.h @@ -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: buffer.h,v 1.35 2002/03/11 12:31:26 guenter Exp $ + * $Id: buffer.h,v 1.36 2002/03/16 20:53:50 guenter Exp $ * * * contents: @@ -168,6 +168,7 @@ struct buf_element_s { #define BUF_FLAG_PREVIEW 0x0010 #define BUF_FLAG_END_USER 0x0020 #define BUF_FLAG_END_STREAM 0x0040 +#define BUF_FLAG_FRAMERATE 0x0080 typedef struct fifo_buffer_s fifo_buffer_t; struct fifo_buffer_s diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c index 66421fecb..6604d2c33 100644 --- a/src/xine-engine/video_decoder.c +++ b/src/xine-engine/video_decoder.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2000-2001 the xine project + * Copyright (C) 2000-2002 the xine project * - * This file is part of xine, a unix video player. + * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -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: video_decoder.c,v 1.77 2002/03/11 19:49:07 jkeil Exp $ + * $Id: video_decoder.c,v 1.78 2002/03/16 20:53:50 guenter Exp $ * */ -- cgit v1.2.3