From 39fe33c1b05b1a3f8e4c602d865a42bedcf58586 Mon Sep 17 00:00:00 2001 From: Guenter Bartsch Date: Sun, 2 Dec 2001 21:19:21 +0000 Subject: libsputext now work without it's own thread, better sync CVS patchset: 1162 CVS date: 2001/12/02 21:19:21 --- src/demuxers/demux_avi.c | 93 ++++++++++++--------- src/libsputext/xine_decoder.c | 184 +++++++++++++++++++----------------------- 2 files changed, 138 insertions(+), 139 deletions(-) diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c index ba6d201ef..3e9cbf6e2 100644 --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.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: demux_avi.c,v 1.56 2001/12/02 15:27:19 guenter Exp $ + * $Id: demux_avi.c,v 1.57 2001/12/02 21:19:21 guenter Exp $ * * demultiplexer for avi streams * @@ -123,6 +123,7 @@ typedef struct demux_avi_s { int status; int no_audio; + int have_spu; uint32_t video_step; uint32_t AVI_errno; @@ -638,51 +639,50 @@ static long AVI_read_audio(demux_avi_t *this, avi_t *AVI, char *audbuf, } static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf, - long bytes, int *bFrameDone) -{ + long bytes, int *frame_done) { + long nr, pos, left, todo; if(!AVI->video_index) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } nr = 0; /* total number of bytes read */ - while(bytes>0) - { + while(bytes>0) { + + left = AVI->video_index[AVI->video_posf].len - AVI->video_posb; + + if(left==0) { + AVI->video_posf++; + AVI->video_posb = 0; + if (nr>0) { + *frame_done = 2; + return nr; + } left = AVI->video_index[AVI->video_posf].len - AVI->video_posb; - if(left==0) - { - AVI->video_posf++; - AVI->video_posb = 0; - if (nr>0) { - *bFrameDone = 2; - return nr; - } - left = AVI->video_index[AVI->video_posf].len - AVI->video_posb; - } - if(bytesvideo_index[AVI->video_posf].pos + AVI->video_posb; - /* printf ("demux_avi: read video from %d\n", pos); */ - if (this->input->seek (this->input, pos, SEEK_SET)<0) - return -1; - if (this->input->read(this->input, vidbuf+nr,todo) != todo) - { - this->AVI_errno = AVI_ERR_READ; - *bFrameDone = 1; - return -1; - } - bytes -= todo; - nr += todo; - AVI->video_posb += todo; } + if(bytesvideo_index[AVI->video_posf].pos + AVI->video_posb; + /* printf ("demux_avi: read video from %d\n", pos); */ + if (this->input->seek (this->input, pos, SEEK_SET)<0) + return -1; + if (this->input->read(this->input, vidbuf+nr,todo) != todo) { + this->AVI_errno = AVI_ERR_READ; + *frame_done = 1; + return -1; + } + bytes -= todo; + nr += todo; + AVI->video_posb += todo; + } left = AVI->video_index[AVI->video_posf].len - AVI->video_posb; if (left==0) - *bFrameDone = 2; + *frame_done = 2; else - *bFrameDone = 1; + *frame_done = 1; return nr; } @@ -747,6 +747,7 @@ static int demux_avi_next (demux_avi_t *this) { } } else { + /* read video */ buf->PTS = video_pts; @@ -767,10 +768,25 @@ static int demux_avi_next (demux_avi_t *this) { buf, buf->decoder_info[0]); */ - this->video_fifo->put (this->video_fifo, buf); - } + /* + * send packages to inform & drive text spu decoder + */ + + if (this->have_spu && (buf->decoder_info[0] == 2)) { + buf_element_t *buf; + buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); + + buf->type = BUF_SPU_TEXT; + buf->PTS = video_pts; + + buf->decoder_info[0] = 1; + buf->decoder_info[1] = this->avi->video_posf; + + this->video_fifo->put (this->video_fifo, buf); + } + } return (buf->size>0); } @@ -1011,9 +1027,12 @@ static void demux_avi_start (demux_plugin_t *this_gen, this->video_fifo->put (this->video_fifo, buf); + this->have_spu = 1; + printf ("demux_avi: text subtitle file available\n"); - } + } else + this->have_spu = 0; if ((err = pthread_create (&this->thread, NULL, demux_avi_loop, this)) != 0) { fprintf (stderr, "demux_avi: can't create new thread (%s)\n", diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c index 7da65b241..a7ddffdcb 100644 --- a/src/libsputext/xine_decoder.c +++ b/src/libsputext/xine_decoder.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: xine_decoder.c,v 1.2 2001/12/02 15:27:20 guenter Exp $ + * $Id: xine_decoder.c,v 1.3 2001/12/02 21:19:22 guenter Exp $ * * code based on mplayer module: * @@ -83,10 +83,12 @@ typedef struct sputext_decoder_s { int errs; subtitle_t *subtitles; int num; /* number of subtitle structs */ - int format; /* constants see below */ + int cur; /* current subtitle */ + int format; /* constants see below */ subtitle_t *previous_aqt_sub ; osd_object_t *osd; + char *font; /* thread */ int running; @@ -741,9 +743,9 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) { this->osd = osd_open (this->xine->osd_renderer, LINE_WIDTH, SUB_MAX_TEXT * LINE_HEIGHT); - osd_renderer_load_font (this->xine->osd_renderer, "vga"); + osd_renderer_load_font (this->xine->osd_renderer, this->font); - osd_set_font (this->osd,"vga"); + osd_set_font (this->osd, this->font); osd_render_text (this->osd, 0, 0, "sputext decoder"); osd_set_position (this->osd, 10, 30); @@ -752,149 +754,121 @@ static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) { } -#define PTS_FACTOR 9000 - -static void *spudec_loop (void *this_gen) { +static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { sputext_decoder_t *this = (sputext_decoder_t *) this_gen; - struct timespec tenth_second; - subtitle_t *current; - int count; - int32_t pts_factor; - - tenth_second.tv_sec = 0; - tenth_second.tv_nsec = 100000000; - - /* wait two seconds so metronom can determine the correct frame rate */ - - for (count = 0; count<20; count++) - nanosleep (&tenth_second, NULL); + if (buf->decoder_info[0] == 0) { - current = this->subtitles; - - count = 0; + int x, y; - while (current && this->running) { + x = buf->decoder_info[1] / 2 - LINE_WIDTH / 2; + if (x<0) + x = 0; - int32_t diff, sub_pts, pts; + y = buf->decoder_info[2] - (SUB_MAX_TEXT * LINE_HEIGHT) - 5; - pts = this->xine->metronom->get_current_time (this->xine->metronom); + osd_set_position (this->osd, x, y); - if (this->uses_time) - pts_factor = 9000; - else - pts_factor = this->xine->metronom->get_video_rate (this->xine->metronom); + printf ("sputext: position is %d / %d\n", x, y); -#ifdef LOG - printf ("sputext: pts_factor : %d\n", pts_factor); -#endif + this->fd = (FILE *) buf->content; + + this->subtitles = sub_read_file (this); - if (!pts_factor) { - nanosleep (&tenth_second, NULL); - continue; - } - - sub_pts = (current->start * pts_factor) + this->xine->metronom->video_wrap_offset; + printf ("sputext: subtitle format %s time.\n", this->uses_time?"uses":"doesn't use"); + printf ("sputext: read %i subtitles, %i errors.\n", this->num, this->errs); - diff = sub_pts - pts ; + this->cur = 0; - if (diff < 0) { + } else { -#ifdef LOG - printf ("sputext: current is '%s' - too old start time %d, diff %d\n", - current->text[0], sub_pts, diff ); -#endif + uint32_t pts, pts_end; + int32_t pts_factor; + int frame_num; + subtitle_t *subtitle; - current++; count++; - if (count >= this->num) - current = NULL; + subtitle = NULL; - continue; + pts = buf->PTS; + pts_end = pts; + frame_num = buf->decoder_info[1]; - } + /* + * find out which subtitle to display + */ -#ifdef LOG - printf ("sputext: current is '%s' (actually %d lines), start time %d, diff %d\n", - current->text[0], current->lines, sub_pts, diff); -#endif + if (!this->uses_time) { - if (diff < 30000) { - int line, y; + while ( (this->cur < this->num) + && (this->subtitles[this->cur].start < frame_num) ) + this->cur++; - osd_filled_rect (this->osd, 0, 0, LINE_WIDTH-1, LINE_HEIGHT * SUB_MAX_TEXT - 1, 0); + if (this->cur >= this->num) + return; - y = (SUB_MAX_TEXT - current->lines) * LINE_HEIGHT; + subtitle = &this->subtitles[this->cur]; - for (line=0; linelines; line++) { - int w,h,x; + if (subtitle->start > frame_num) + return; - osd_get_text_size( this->osd, current->text[line], - & w, &h); + pts_factor = this->xine->metronom->get_video_rate (this->xine->metronom); - x = (LINE_WIDTH - w) / 2; + pts += this->xine->metronom->video_wrap_offset; - osd_render_text (this->osd, x, y + line*20, current->text[line]); - } - - osd_show (this->osd, sub_pts); - osd_hide (this->osd, current->end * pts_factor + this->xine->metronom->video_wrap_offset); + pts_end = pts + (subtitle->end - subtitle->start) * pts_factor; - current++; count++; - if (count >= this->num) - current = NULL; + } else { - } + uint32_t start_tenth; - nanosleep (&tenth_second, NULL); - } + start_tenth = pts / 9000; - printf ("sputext: thread finished\n"); + /* FIXME: untested */ - pthread_exit (NULL); + while ( (this->cur < this->num) + && (this->subtitles[this->cur].start < start_tenth) ) + this->cur++; - return NULL; -} + if (this->cur >= this->num) + return; -static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { + subtitle = &this->subtitles[this->cur]; - sputext_decoder_t *this = (sputext_decoder_t *) this_gen; - int err; + if (subtitle->start > start_tenth) + return; - if (buf->decoder_info[0] == 0) { + pts += this->xine->metronom->video_wrap_offset; - int x, y; + pts_end = subtitle->end * 9000 + this->xine->metronom->video_wrap_offset; + } - x = buf->decoder_info[1] / 2 - LINE_WIDTH / 2; - if (x<0) - x = 0; + if (subtitle) { + int line, y; - y = buf->decoder_info[2] - (SUB_MAX_TEXT * LINE_HEIGHT) - 5; + osd_filled_rect (this->osd, 0, 0, LINE_WIDTH-1, LINE_HEIGHT * SUB_MAX_TEXT - 1, 0); - osd_set_position (this->osd, x, y); + y = (SUB_MAX_TEXT - subtitle->lines) * LINE_HEIGHT; - printf ("sputext: position is %d / %d\n", x, y); + for (line=0; linelines; line++) { + int w,h,x; - this->fd = (FILE *) buf->content; - - this->subtitles = sub_read_file (this); + osd_get_text_size( this->osd, subtitle->text[line], + & w, &h); - printf ("sputext: subtitle format %s time.\n", this->uses_time?"uses":"doesn't use"); - printf ("sputext: read %i subtitles, %i errors.\n", this->num, this->errs); + x = (LINE_WIDTH - w) / 2; - /* start thread */ + osd_render_text (this->osd, x, y + line*20, subtitle->text[line]); + } + + osd_show (this->osd, pts ); + osd_hide (this->osd, pts_end); - this->running = 1; - - if ((err = pthread_create (&this->spu_thread, - NULL, spudec_loop, this)) != 0) { - printf ("sputext: can't create new thread (%s)\n", - strerror(err)); - exit (1); } - } + this->cur++; + } } @@ -944,6 +918,12 @@ spu_decoder_t *init_spu_decoder_plugin (int iface_version, xine_t *xine) { this->xine = xine; + this->font = xine->config->register_string(xine->config, + "codec.spu_font", + "vga", + "font for avi subtitles", + NULL, NULL, NULL); + return (spu_decoder_t *) this; } -- cgit v1.2.3