diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-01-10 22:23:54 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2003-01-10 22:23:54 +0000 |
commit | edf46e3fb8e566cb64862fdadcf8a4956557741e (patch) | |
tree | 523fcb6d09923aa4b07678663e88d1e9178f34a8 | |
parent | 77ecf6954f81c3e1b9589d2d14b79f839022e690 (diff) | |
download | xine-lib-edf46e3fb8e566cb64862fdadcf8a4956557741e.tar.gz xine-lib-edf46e3fb8e566cb64862fdadcf8a4956557741e.tar.bz2 |
just get it to compile, still not finished.
i hope to have something working this weekend
CVS patchset: 3857
CVS date: 2003/01/10 22:23:54
-rw-r--r-- | src/libsputext/Makefile.am | 11 | ||||
-rw-r--r-- | src/libsputext/demux_sputext.c | 64 | ||||
-rw-r--r-- | src/libsputext/xine_decoder.c | 880 |
3 files changed, 138 insertions, 817 deletions
diff --git a/src/libsputext/Makefile.am b/src/libsputext/Makefile.am index 642586265..2195433b1 100644 --- a/src/libsputext/Makefile.am +++ b/src/libsputext/Makefile.am @@ -3,8 +3,7 @@ LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR) if HAVE_GICONV -#sputext_decoder = xineplug_decode_sputext.la xineplug_dmx_sputext.la -sputext_decoder = xineplug_dmx_sputext.la +sputext_decoder = xineplug_decode_sputext.la xineplug_dmx_sputext.la endif lib_LTLIBRARIES = $(sputext_decoder) @@ -14,10 +13,10 @@ xineplug_dmx_sputext_la_SOURCES = demux_sputext.c xineplug_dmx_sputext_la_LIBADD = $(XINELIB) $(GICONV_BSD_LIBS) xineplug_dmx_sputext_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -#xineplug_decode_sputext_la_SOURCES = xine_decoder.c -## libgiconv is only needed with FreeBSD -#xineplug_decode_sputext_la_LIBADD = $(XINELIB) -#xineplug_decode_sputext_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ +xineplug_decode_sputext_la_SOURCES = xine_decoder.c +# libgiconv is only needed with FreeBSD +xineplug_decode_sputext_la_LIBADD = $(XINELIB) +xineplug_decode_sputext_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ ## ## Install header files (default=$includedir/xine) diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index 8d93faa48..11e956dad 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.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_sputext.c,v 1.5 2003/01/08 01:02:30 miguelfreitas Exp $ + * $Id: demux_sputext.c,v 1.6 2003/01/10 22:23:54 miguelfreitas Exp $ * * code based on old libsputext/xine_decoder.c * @@ -47,7 +47,6 @@ #include "xine_internal.h" #include "xineutils.h" #include "../demuxers/demux.h" -#include "osd.h" /* #define LOG 1 @@ -68,8 +67,8 @@ typedef struct { int lines; - unsigned long start; - unsigned long end; + unsigned long start; /* hsecs */ + unsigned long end; /* hsecs */ char *text[SUB_MAX_TEXT]; @@ -803,34 +802,30 @@ static void update_osd_dst_encoding(void *this_gen, xine_cfg_entry_t *entry) static int demux_sputext_next (demux_sputext_t *this_gen) { demux_sputext_t *this = (demux_sputext_t *) this_gen; buf_element_t *buf; - subtitle_t *sub = &this->subtitles[this->cur]; + uint32_t *val; + char *str; + subtitle_t *sub; int line; if (this->cur >= this->num) return 0; + + sub = &this->subtitles[this->cur]; buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo); buf->type = BUF_SPU_TEXT; - buf->decoder_info[1] = sub->lines; - for (line = 0; line < sub->lines; line++) - strncpy(buf->content + line * SUB_BUFSIZE, sub->text[line], SUB_BUFSIZE); - - /* calculate PTS */ - if (!this->uses_time) { - /* FIXME: framerate hardcoded - get from master stream instead */ - int64_t frame_pts = 3600; - - buf->pts = sub->start * frame_pts; - - /* duration */ - buf->decoder_info[0] = (sub->end - sub->start) * frame_pts; - - } else { - - buf->pts = sub->start * 900; - - /* duration */ - buf->decoder_info[0] = (sub->end - sub->start) * 900; + buf->pts = 0; + + val = (uint32_t * )buf->content; + *val++ = sub->lines; + *val++ = this->uses_time; + *val++ = sub->start * 10; + *val++ = sub->end * 10; + str = (char *)val; + for (line = 0; line < sub->lines; line++, str+=strlen(str)+1) { + if( strlen(sub->text[line]) > SUB_BUFSIZE ) + sub->text[line][SUB_BUFSIZE] = '\0'; + strcpy(str, sub->text[line]); } this->stream->video_fifo->put(this->stream->video_fifo, buf); @@ -857,18 +852,19 @@ static int demux_sputext_get_status (demux_plugin_t *this_gen) { } static int demux_sputext_get_stream_length (demux_plugin_t *this_gen) { - /* FIXME: what to return? Get length from master stream perhaps? */ - return 0; + demux_sputext_t *this = (demux_sputext_t *) this_gen; + + if( this->uses_time && this->num ) { + return this->subtitles[this->num-1].end * 10; + } else { + return 0; + } } static int demux_sputext_send_chunk (demux_plugin_t *this_gen) { demux_sputext_t *this = (demux_sputext_t *) this_gen; - /* send at most 10 buffers to fifo in advance */ - if (this->stream->video_fifo->size(this->stream->video_fifo) >= 10) - xine_usec_sleep(200000); - if (this->stream->video_fifo->size(this->stream->video_fifo) < 10 && - !demux_sputext_next (this)) { + if (!demux_sputext_next (this)) { this->status = DEMUX_FINISHED; } @@ -879,6 +875,10 @@ static int demux_sputext_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time) { demux_sputext_t *this = (demux_sputext_t*)this_gen; /* FIXME: change this->cur according to seek target and set a discontinuity */ + + if( this->uses_time && start_time ) { + } + return this->status; } diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c index 593c6c7f4..e4db27b16 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.41 2002/09/05 22:18:58 mroi Exp $ + * $Id: xine_decoder.c,v 1.42 2003/01/10 22:23:54 miguelfreitas Exp $ * * code based on mplayer module: * @@ -46,23 +46,9 @@ /* #define LOG 1 */ - -#define ERR (void *)-1 - #define SUB_MAX_TEXT 5 -typedef struct { - - int lines; - - unsigned long start; - unsigned long end; - - char *text[SUB_MAX_TEXT]; - - osd_object_t *osd; - -} subtitle_t; +#define SUB_BUFSIZE 1024 typedef enum { @@ -73,15 +59,25 @@ typedef enum { SUBTITLE_SIZE_NUM /* number of values in enum */ } subtitle_size; + +typedef struct sputext_class_s { + spu_decoder_class_t class; + + xine_t *xine; + + +} sputext_class_t; + + typedef struct sputext_decoder_s { spu_decoder_t spu_decoder; - xine_t *xine; + sputext_class_t *class; + xine_stream_t *stream; - vo_instance_t *vo_out; int output_open; - FILE *fd; + char text[SUB_MAX_TEXT][SUB_BUFSIZE]; float mpsub_position; @@ -90,691 +86,18 @@ typedef struct sputext_decoder_s { int font_size; int line_height; int uses_time; - int errs; - subtitle_t *subtitles; - int num; /* number of subtitle structs */ - int cur; /* current subtitle */ - int format; /* constants see below */ - subtitle_t *previous_aqt_sub ; - osd_renderer_t *renderer; - osd_object_t *osd; - char *font; - char *src_encoding; - char *dst_encoding; + char *font; subtitle_size subtitle_size; - int64_t last_subtitle_end; /* no new subtitle before this vpts */ int time_offset; /* offset in 1/100sec to add to vpts */ -} sputext_decoder_t; - -#define FORMAT_MICRODVD 0 -#define FORMAT_SUBRIP 1 -#define FORMAT_SUBVIEWER 2 -#define FORMAT_SAMI 3 -#define FORMAT_VPLAYER 4 -#define FORMAT_RT 5 -#define FORMAT_SSA 6 /* Sub Station Alpha */ -#define FORMAT_DUNNO 7 /*... erm ... dunnowhat. tell me if you know */ -#define FORMAT_MPSUB 8 -#define FORMAT_AQTITLE 9 - -static int eol(char p) { - return (p=='\r' || p=='\n' || p=='\0'); -} - -static inline void trail_space(char *s) { - int i; - while (isspace(*s)) - strcpy(s, s + 1); - i = strlen(s) - 1; - while (i > 0 && isspace(s[i])) - s[i--] = '\0'; -} - - -static subtitle_t *sub_read_line_sami(sputext_decoder_t *this, subtitle_t *current) { - - static char line[1001]; - static char *s = NULL; - char text[1000], *p, *q; - int state; - - p = NULL; - current->lines = current->start = current->end = 0; - state = 0; - - /* read the first line */ - if (!s) - if (!(s = fgets(line, 1000, this->fd))) return 0; - - do { - switch (state) { - - case 0: /* find "START=" */ - s = strstr (s, "Start="); - if (s) { - current->start = strtol (s + 6, &s, 0) / 10; - state = 1; continue; - } - break; - - case 1: /* find "<P" */ - if ((s = strstr (s, "<P"))) { s += 2; state = 2; continue; } - break; - - case 2: /* find ">" */ - if ((s = strchr (s, '>'))) { s++; state = 3; p = text; continue; } - break; - - case 3: /* get all text until '<' appears */ - if (*s == '\0') { break; } - else if (*s == '<') { state = 4; } - else if (!strncasecmp (s, " ", 6)) { *p++ = ' '; s += 6; } - else if (*s == '\r') { s++; } - else if (!strncasecmp (s, "<br>", 4) || *s == '\n') { - *p = '\0'; p = text; trail_space (text); - if (text[0] != '\0') - current->text[current->lines++] = strdup (text); - if (*s == '\n') s++; else s += 4; - } - else *p++ = *s++; - continue; - - case 4: /* get current->end or skip <TAG> */ - q = strstr (s, "Start="); - if (q) { - current->end = strtol (q + 6, &q, 0) / 10 - 1; - *p = '\0'; trail_space (text); - if (text[0] != '\0') - current->text[current->lines++] = strdup (text); - if (current->lines > 0) { state = 99; break; } - state = 0; continue; - } - s = strchr (s, '>'); - if (s) { s++; state = 3; continue; } - break; - } - - /* read next line */ - if (state != 99 && !(s = fgets (line, 1000, this->fd))) - return 0; - - } while (state != 99); - - return current; -} - - -static char *sub_readtext(char *source, char **dest) { - int len=0; - char *p=source; - - while ( !eol(*p) && *p!= '|' ) { - p++,len++; - } - - *dest= (char *)xine_xmalloc (len+1); - if (!dest) - return ERR; - - strncpy(*dest, source, len); - (*dest)[len]=0; - - while (*p=='\r' || *p=='\n' || *p=='|') - p++; - - if (*p) return p; /* not-last text field */ - else return NULL; /* last text field */ -} - -static subtitle_t *sub_read_line_microdvd(sputext_decoder_t *this, subtitle_t *current) { - - char line[1001]; - char line2[1001]; - char *p, *next; - int i; - - bzero (current, sizeof(subtitle_t)); - - current->end=-1; - do { - if (!fgets (line, 1000, this->fd)) return NULL; - } while ((sscanf (line, "{%ld}{}%[^\r\n]", &(current->start), line2) !=2) && - (sscanf (line, "{%ld}{%ld}%[^\r\n]", &(current->start), &(current->end),line2) !=3) - ); - - p=line2; - - next=p, i=0; - while ((next =sub_readtext (next, &(current->text[i])))) { - if (current->text[i]==ERR) return ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf ("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } - } - current->lines= ++i; - - return current; -} - -static subtitle_t *sub_read_line_subrip(sputext_decoder_t *this, subtitle_t *current) { - - char line[1001]; - int a1,a2,a3,a4,b1,b2,b3,b4; - char *p=NULL, *q=NULL; - int len; - - bzero (current, sizeof(subtitle_t)); - - while (1) { - if (!fgets (line, 1000, this->fd)) return NULL; - if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4) < 8) continue; - current->start = a1*360000+a2*6000+a3*100+a4; - current->end = b1*360000+b2*6000+b3*100+b4; - - if (!fgets (line, 1000, this->fd)) return NULL; - - p=q=line; - for (current->lines=1; current->lines < SUB_MAX_TEXT; current->lines++) { - for (q=p,len=0; *p && *p!='\r' && *p!='\n' && strncmp(p,"[br]",4); p++,len++); - current->text[current->lines-1]=(char *)xine_xmalloc (len+1); - if (!current->text[current->lines-1]) return ERR; - strncpy (current->text[current->lines-1], q, len); - current->text[current->lines-1][len]='\0'; - if (!*p || *p=='\r' || *p=='\n') break; - while (*p++!=']'); - } - break; - } - return current; -} - -static subtitle_t *sub_read_line_third(sputext_decoder_t *this,subtitle_t *current) { - char line[1001]; - int a1,a2,a3,a4,b1,b2,b3,b4; - char *p=NULL; - int i,len; - - bzero (current, sizeof(subtitle_t)); - - while (!current->text[0]) { - if (!fgets (line, 1000, this->fd)) return NULL; - if ((len=sscanf (line, "%d:%d:%d,%d --> %d:%d:%d,%d",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8) - continue; - current->start = a1*360000+a2*6000+a3*100+a4/10; - current->end = b1*360000+b2*6000+b3*100+b4/10; - for (i=0; i<SUB_MAX_TEXT;) { - if (!fgets (line, 1000, this->fd)) break; - len=0; - for (p=line; *p!='\n' && *p!='\r' && *p; p++,len++); - if (len) { - current->text[i]=(char *)xine_xmalloc (len+1); - if (!current->text[i]) return ERR; - strncpy (current->text[i], line, len); current->text[i][len]='\0'; - i++; - } else { - break; - } - } - current->lines=i; - } - return current; -} - -static subtitle_t *sub_read_line_vplayer(sputext_decoder_t *this,subtitle_t *current) { - char line[1001]; - char line2[1001]; - int a1,a2,a3,b1,b2,b3; - char *p=NULL, *next; - int i,len,len2,plen; - - bzero (current, sizeof(subtitle_t)); - - while (!current->text[0]) { - if (!fgets (line, 1000, this->fd)) return NULL; - if ((len=sscanf (line, "%d:%d:%d:%n",&a1,&a2,&a3,&plen)) < 3) - continue; - if (!fgets (line2, 1000, this->fd)) return NULL; - if ((len2=sscanf (line2, "%d:%d:%d:",&b1,&b2,&b3)) < 3) - continue; - /* przewiń o linijkę do tyłu: */ - fseek(this->fd,-strlen(line2),SEEK_CUR); - - current->start = a1*360000+a2*6000+a3*100; - current->end = b1*360000+b2*6000+b3*100; - if ((current->end - current->start) > 1000) - current->end = current->start + 1000; /* not too long though. */ - /* teraz czas na wkopiowanie stringu */ - p=line; - /* finds the body of the subtitle_t */ - for (i=0; i<3; i++){ - p=strchr(p,':')+1; - } - i=0; - - if (*p!='|') { - next = p,i=0; - while ((next =sub_readtext (next, &(current->text[i])))) { - if (current->text[i]==ERR) - return ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf ("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } - } - current->lines=i+1; - } - } - return current; -} - -static subtitle_t *sub_read_line_rt(sputext_decoder_t *this,subtitle_t *current) { - /* - * TODO: This format uses quite rich (sub/super)set of xhtml - * I couldn't check it since DTD is not included. - * WARNING: full XML parses can be required for proper parsing - */ - char line[1001]; - int a1,a2,a3,a4,b1,b2,b3,b4; - char *p=NULL,*next=NULL; - int i,len,plen; - - bzero (current, sizeof(subtitle_t)); - - while (!current->text[0]) { - if (!fgets (line, 1000, this->fd)) return NULL; - /* - * TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0 - * to describe the same moment in time. Maybe there are even more formats in use. - */ - if ((len=sscanf (line, "<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8) - - plen=a1=a2=a3=a4=b1=b2=b3=b4=0; - if ( - ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&plen)) < 4) && - ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&b2,&b3,&b4,&plen)) < 5) && - /* ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&plen)) < 5) && */ - ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&b4,&plen)) < 6) && - ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\" %*[Ee]nd=\"%d:%d:%d.%d\"%*[^<]<clear/>%n",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4,&plen)) < 8) - ) - continue; - current->start = a1*360000+a2*6000+a3*100+a4/10; - current->end = b1*360000+b2*6000+b3*100+b4/10; - p=line; p+=plen;i=0; - /* TODO: I don't know what kind of convention is here for marking multiline subs, maybe <br/> like in xml? */ - next = strstr(line,"<clear/>")+8;i=0; - while ((next =sub_readtext (next, &(current->text[i])))) { - if (current->text[i]==ERR) - return ERR; - i++; - if (i>=SUB_MAX_TEXT) { - printf ("Too many lines in a subtitle\n"); - current->lines=i; - return current; - } - } - current->lines=i+1; - } - return current; -} - -static subtitle_t *sub_read_line_ssa(sputext_decoder_t *this,subtitle_t *current) { - - int hour1, min1, sec1, hunsec1, - hour2, min2, sec2, hunsec2, nothing; - int num; - - char line[1000], - line3[1000], - *line2; - char *tmp; - - do { - if (!fgets (line, 1000, this->fd)) - return NULL; - } while (sscanf (line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d," - "%[^\n\r]", ¬hing, - &hour1, &min1, &sec1, &hunsec1, - &hour2, &min2, &sec2, &hunsec2, - line3) < 9); - line2=strstr(line3,",,"); - if (!line2) return NULL; - line2 ++; - line2 ++; - - current->lines=1;num=0; - current->start = 360000*hour1 + 6000*min1 + 100*sec1 + hunsec1; - current->end = 360000*hour2 + 6000*min2 + 100*sec2 + hunsec2; - - while ( (tmp=strstr(line2, "\\n")) ) { - current->text[num]=(char *)xine_xmalloc(tmp-line2+1); - strncpy (current->text[num], line2, tmp-line2); - current->text[num][tmp-line2]='\0'; - line2=tmp+2; - num++; - current->lines++; - if (current->lines >= SUB_MAX_TEXT) return current; - } - - - current->text[num]=(char *) xine_xmalloc(strlen(line2)+1); - strcpy(current->text[num],line2); - - return current; -} - -static subtitle_t *sub_read_line_dunnowhat (sputext_decoder_t *this, subtitle_t *current) { - char line[1001]; - char text[1001]; - - bzero (current, sizeof(subtitle_t)); - - if (!fgets (line, 1000, this->fd)) - return NULL; - if (sscanf (line, "%ld,%ld,\"%[^\"]", &(current->start), - &(current->end), text) <3) - return ERR; - current->text[0] = strdup(text); - current->lines = 1; - - return current; -} - -static subtitle_t *sub_read_line_mpsub (sputext_decoder_t *this, subtitle_t *current) { - char line[1000]; - float a,b; - int num=0; - char *p, *q; - - do { - if (!fgets(line, 1000, this->fd)) - return NULL; - } while (sscanf (line, "%f %f", &a, &b) !=2); - - this->mpsub_position += (a*100.0); - current->start = (int) this->mpsub_position; - this->mpsub_position += (b*100.0); - current->end = (int) this->mpsub_position; - - while (num < SUB_MAX_TEXT) { - if (!fgets (line, 1000, this->fd)) - return NULL; - - p=line; - while (isspace(*p)) - p++; - - if (eol(*p) && num > 0) - return current; - - if (eol(*p)) - return NULL; - - for (q=p; !eol(*q); q++); - *q='\0'; - if (strlen(p)) { - current->text[num]=strdup(p); - printf (">%s<\n",p); - current->lines = ++num; - } else { - if (num) - return current; - else - return NULL; - } - } - - return NULL; -} - -static subtitle_t *sub_read_line_aqt (sputext_decoder_t *this, subtitle_t *current) { - char line[1001]; - - bzero (current, sizeof(subtitle_t)); - while (1) { - /* try to locate next subtitle_t */ - if (!fgets (line, 1000, this->fd)) - return NULL; - if (!(sscanf (line, "-->> %ld", &(current->start)) <1)) - break; - } - - if (this->previous_aqt_sub != NULL) - this->previous_aqt_sub->end = current->start-1; - - this->previous_aqt_sub = current; - - if (!fgets (line, 1000, this->fd)) - return NULL; - - sub_readtext((char *) &line,¤t->text[0]); - current->lines = 1; - current->end = current->start; /* will be corrected by next subtitle_t */ - - if (!fgets (line, 1000, this->fd)) - return current;; - - sub_readtext((char *) &line,¤t->text[1]); - current->lines = 2; - - if ((current->text[0]=="") && (current->text[1]=="")) { - /* void subtitle -> end of previous marked and exit */ - this->previous_aqt_sub = NULL; - return NULL; - } - - return current; -} - -static int sub_autodetect (sputext_decoder_t *this) { - - char line[1001]; - int i,j=0; - char p; - - while (j < 100) { - j++; - if (!fgets (line, 1000, this->fd)) - return -1; - - if ((sscanf (line, "{%d}{}", &i)==1) || - (sscanf (line, "{%d}{%d}", &i, &i)==2)) { - this->uses_time=0; - printf ("sputext: microdvd subtitle format detected\n"); - return FORMAT_MICRODVD; - } - - if (sscanf (line, "%d:%d:%d.%d,%d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i)==8){ - this->uses_time=1; - printf ("sputext: subrip subtitle format detected\n"); - return FORMAT_SUBRIP; - } - - if (sscanf (line, "%d:%d:%d,%d --> %d:%d:%d,%d", &i, &i, &i, &i, &i, &i, &i, &i)==8) { - this->uses_time=1; - printf ("sputext: subviewer subtitle format detected\n"); - return FORMAT_SUBVIEWER; - } - if (strstr (line, "<SAMI>")) { - this->uses_time=1; - printf ("sputext: sami subtitle format detected\n"); - return FORMAT_SAMI; - } - if (sscanf (line, "%d:%d:%d:", &i, &i, &i )==3) { - this->uses_time=1; - printf ("sputext: vplayer subtitle format detected\n"); - return FORMAT_VPLAYER; - } - /* - * TODO: just checking if first line of sub starts with "<" is WAY - * too weak test for RT - * Please someone who knows the format of RT... FIX IT!!! - * It may conflict with other sub formats in the future (actually it doesn't) - */ - if ( *line == '<' ) { - this->uses_time=1; - printf ("sputext: rt subtitle format detected\n"); - return FORMAT_RT; - } - if (!memcmp(line, "Dialogue: Marked", 16)){ - this->uses_time=1; - printf ("sputext: ssa subtitle format detected\n"); - return FORMAT_SSA; - } - if (sscanf (line, "%d,%d,\"%c", &i, &i, (char *) &i) == 3) { - this->uses_time=0; - printf ("sputext: (dunno) subtitle format detected\n"); - return FORMAT_DUNNO; - } - if (sscanf (line, "FORMAT=%d", &i) == 1) { - this->uses_time=0; - printf ("sputext: mpsub subtitle format detected\n"); - return FORMAT_MPSUB; - } - if (sscanf (line, "FORMAT=TIM%c", &p)==1 && p=='E') { - this->uses_time=1; - printf ("sputext: mpsub subtitle format detected\n"); - return FORMAT_MPSUB; - } - if (strstr (line, "-->>")) { - this->uses_time=0; - printf ("sputext: aqtitle subtitle format detected\n"); - return FORMAT_AQTITLE; - } - } - - return -1; /* too many bad lines */ -} - -static subtitle_t *sub_read_file (sputext_decoder_t *this) { - - int n_max; - subtitle_t *first; - subtitle_t * (*func[])(sputext_decoder_t *this,subtitle_t *dest)= - { - sub_read_line_microdvd, - sub_read_line_subrip, - sub_read_line_third, - sub_read_line_sami, - sub_read_line_vplayer, - sub_read_line_rt, - sub_read_line_ssa, - sub_read_line_dunnowhat, - sub_read_line_mpsub, - sub_read_line_aqt - - }; - iconv_t iconv_descr; - - this->format=sub_autodetect (this); - if (this->format==-1) { - printf ("sputext: Could not determine file format\n"); - return NULL; - } - - printf ("sputext: Detected subtitle file format: %d\n",this->format); - - rewind (this->fd); - - this->num=0;n_max=32; - first = (subtitle_t *) xine_xmalloc(n_max*sizeof(subtitle_t)); - if(!first) return NULL; - - iconv_descr=iconv_open(this->dst_encoding,this->src_encoding); - while(1){ - subtitle_t *sub; - if(this->num>=n_max){ - n_max+=16; - first=realloc(first,n_max*sizeof(subtitle_t)); - } - sub = func[this->format] (this, &first[this->num]); - if (!sub) - break; /* EOF */ - - if (sub==ERR) - ++this->errs; - else { - int i; - if (this->num > 0 && first[this->num-1].end == -1) { - first[this->num-1].end = sub->start; - } - for(i=0; i<first[this->num].lines; i++) - { char *tmp; - char *in_buff, *out_buff; - int in_len, out_len; - - in_len=strlen(first[this->num].text[i])+1; - tmp=malloc(in_len); - in_buff=first[this->num].text[i]; - out_buff=tmp; - out_len=in_len; - if ((size_t)(-1)!=iconv(iconv_descr,&in_buff,&in_len,&out_buff,&out_len)) - { free(first[this->num].text[i]); - first[this->num].text[i]=tmp; - } - else - { printf("sputext: Can't convert subtitle text\n"); } - } - ++this->num; /* Error vs. Valid */ - } - } - iconv_close(iconv_descr); - - printf ("sputext: Read %i subtitles", this->num); - if (this->errs) - printf (", %i bad line(s).\n", this->errs); - else - printf (".\n"); - - return first; -} - - -static void list_sub_file (sputext_decoder_t *this, subtitle_t* subs) { - - int i,j; - - for(j=0;j<this->num;j++){ - subtitle_t* egysub=&subs[j]; - printf ("%i line%c (%li-%li) ", - egysub->lines, - (1==egysub->lines)?' ':'s', - egysub->start, - egysub->end); - for (i=0; i<egysub->lines; i++) { - printf ("%s%s",egysub->text[i], i==egysub->lines-1?"":" <BREAK> "); - } - printf ("\n"); - } - - printf ("Subtitle format %s time.\n", this->uses_time?"uses":"doesn't use"); - printf ("Read %i subtitles, %i errors.\n", this->num, this->errs); - -} - - -static void spudec_init (spu_decoder_t *this_gen, vo_instance_t *vo_out) { - - sputext_decoder_t *this = (sputext_decoder_t *) this_gen; - - this->vo_out = vo_out; - this->output_open = 0; + osd_renderer_t *renderer; + osd_object_t *osd; - this->mpsub_position = 0; - this->uses_time = 0; - this->errs = 0; - this->num = 0; - this->format = 0; - this->previous_aqt_sub = NULL; + int64_t last_subtitle_end; /* no new subtitle before this vpts */ +} sputext_decoder_t; -} static void update_font_size (sputext_decoder_t *this) { static int sizes[SUBTITLE_SIZE_NUM][4] = { @@ -816,44 +139,38 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { sputext_decoder_t *this = (sputext_decoder_t *) this_gen; int64_t current_time; + uint32_t start, end; + if( !this->width || !this->height || !this->renderer ) { + + } + +#if 0 if (buf->decoder_flags & BUF_FLAG_HEADER) { this->width = buf->decoder_info[1]; this->height = buf->decoder_info[2]; - this->renderer = this->xine->osd_renderer; + this->renderer = this->stream->osd_renderer; this->osd = NULL; update_font_size (this); - current_time = this->xine->metronom->get_current_time (this->xine->metronom); + current_time = this->stream->xine->clock->get_current_time (this->stream->xine->clock); this->renderer->show (this->osd, current_time); this->renderer->hide (this->osd, current_time+300000); - this->fd = (FILE *) buf->content; - - this->subtitles = sub_read_file (this); - - 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); - - this->cur = 0; - } else { int64_t sub_start, sub_end; - subtitle_t *subtitle; /* don't want to see subtitle */ - if(this->xine->spu_channel_user == -2) + if(this->stream->spu_channel_user == -2) return; - subtitle = NULL; - + /* * find out which subtitle to display */ - if (!this->uses_time) { int frame_num; int64_t pts_factor; @@ -862,14 +179,14 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { frame_num = buf->decoder_info[1]; /* FIXME FIXME FIXME - pts_factor = this->xine->metronom->get_video_rate (this->xine->metronom); + pts_factor = this->stream->metronom->get_video_rate (this->stream->metronom); */ pts_factor = 3000; frame_offset = this->time_offset * 900 / pts_factor; while ( (this->cur < this->num) - && (this->subtitles[this->cur].start + frame_offset < frame_num) ) + && (this->text[this->cur].start + frame_offset < frame_num) ) this->cur++; if (this->cur >= this->num) @@ -880,7 +197,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { if (subtitle->start + frame_offset > frame_num) return; - sub_start = this->xine->metronom->got_spu_packet(this->xine->metronom, buf->pts); + sub_start = this->stream->metronom->got_spu_packet(this->stream->metronom, buf->pts); sub_end = sub_start + (subtitle->end - subtitle->start) * pts_factor; } else { @@ -909,7 +226,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { if (subtitle->start + this->time_offset > (start_tenth+20)) return; - sub_start = this->xine->metronom->got_spu_packet(this->xine->metronom, (subtitle->start+this->time_offset)*900); + sub_start = this->stream->metronom->got_spu_packet(this->stream->metronom, (subtitle->start+this->time_offset)*900); sub_end = sub_start + (subtitle->end - subtitle->start)*900; } @@ -959,23 +276,27 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { #ifdef LOG printf ("sputext: scheduling subtitle >%s< at %lld until %lld, current time is %lld\n", subtitle->text[0], sub_start, sub_end, - this->xine->metronom->get_current_time (this->xine->metronom)); + this->stream->metronom->get_current_time (this->stream->metronom)); #endif } - this->cur++; } +#endif } static void spudec_reset (spu_decoder_t *this_gen) { sputext_decoder_t *this = (sputext_decoder_t *) this_gen; - this->cur = 0; } -static void spudec_close (spu_decoder_t *this_gen) { +static void spudec_discontinuity (spu_decoder_t *this_gen) { + sputext_decoder_t *this = (sputext_decoder_t *) this_gen; + +} + +static void spudec_dispose (spu_decoder_t *this_gen) { sputext_decoder_t *this = (sputext_decoder_t *) this_gen; if (this->osd) { @@ -985,10 +306,6 @@ static void spudec_close (spu_decoder_t *this_gen) { } -static char *spudec_get_id(void) { - return "sputext"; -} - static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry) { sputext_decoder_t *this = (sputext_decoder_t *)this_gen; @@ -1001,24 +318,6 @@ static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry) printf("libsputext: spu_font = %s\n", this->font ); } -static void update_osd_src_encoding(void *this_gen, xine_cfg_entry_t *entry) -{ - sputext_decoder_t *this = (sputext_decoder_t *)this_gen; - - this->src_encoding = entry->str_value; - - printf("libsputext: spu_src_encoding = %s\n", this->src_encoding ); -} - -static void update_osd_dst_encoding(void *this_gen, xine_cfg_entry_t *entry) -{ - sputext_decoder_t *this = (sputext_decoder_t *)this_gen; - - this->dst_encoding = entry->str_value; - - printf("libsputext: spu_dst_encoding = %s\n", this->dst_encoding ); -} - static void update_subtitle_size(void *this_gen, xine_cfg_entry_t *entry) { sputext_decoder_t *this = (sputext_decoder_t *)this_gen; @@ -1037,55 +336,78 @@ static void update_time_offset(void *this_gen, xine_cfg_entry_t *entry) printf("libsputext: time_offset = %d\n", this->time_offset ); } -static void spudec_dispose (spu_decoder_t *this_gen) { - free (this_gen); -} - -static void *init_spu_decoder_plugin (xine_t *xine, void *data) { +static spu_decoder_t *sputext_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { + sputext_class_t *class = (sputext_class_t *)class_gen; sputext_decoder_t *this ; static char *subtitle_size_strings[] = { "small", "normal", "large", NULL }; this = (sputext_decoder_t *) xine_xmalloc (sizeof (sputext_decoder_t)); - this->spu_decoder.init = spudec_init; this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; - this->spu_decoder.close = spudec_close; - this->spu_decoder.get_identifier = spudec_get_id; + this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; + this->spu_decoder.get_nav_pci = NULL; + this->spu_decoder.set_button = NULL; + this->spu_decoder.dispose = spudec_dispose; + + this->class = class; + this->stream = stream; + + this->font = class->xine->config->register_string(class->xine->config, + "codec.spu_font", + "sans", + _("font for avi subtitles"), + NULL, 0, update_osd_font, this); + this->subtitle_size = class->xine->config->register_enum(class->xine->config, + "codec.spu_subtitle_size", + 1, + subtitle_size_strings, + _("subtitle size (relative window size)"), + NULL, 0, update_subtitle_size, this); + this->time_offset = class->xine->config->register_num (class->xine->config, + "codec.spu_time_offset", + 0, + _("subtitle time offset in 1/100 sec"), + NULL, 10, update_time_offset, this); - this->xine = xine; - this->font = xine->config->register_string(xine->config, - "codec.spu_font", - "sans", - _("font for avi subtitles"), - NULL, 0, update_osd_font, this); - this->subtitle_size = xine->config->register_enum(xine->config, - "codec.spu_subtitle_size", - 1, - subtitle_size_strings, - _("subtitle size (relative window size)"), - NULL, 0, update_subtitle_size, this); - this->src_encoding = xine->config->register_string(xine->config, - "codec.spu_src_encoding", - "windows-1250", - _("source encoding of subtitles"), - NULL, 10, update_osd_src_encoding, this); - this->dst_encoding = xine->config->register_string(xine->config, - "codec.spu_dst_encoding", - "iso-8859-2", - _("target encoding for subtitles (have to match font encoding)"), - NULL, 10, update_osd_dst_encoding, this); - this->time_offset = xine->config->register_num (xine->config, - "codec.spu_time_offset", - 0, - _("subtitle time offset in 1/100 sec"), - NULL, 10, update_time_offset, this); + + this->mpsub_position = 0; return (spu_decoder_t *) this; } +static void sputext_class_dispose (spu_decoder_class_t *this) { + free (this); +} + +static char *sputext_class_get_identifier (spu_decoder_class_t *this) { + return "sputext"; +} + +static char *sputext_class_get_description (spu_decoder_class_t *this) { + return "external subtitle decoder plugin"; +} + + +static void *init_spu_decoder_plugin (xine_t *xine, void *data) { + + sputext_class_t *this ; + + this = (sputext_class_t *) xine_xmalloc (sizeof (sputext_class_t)); + + this->class.open_plugin = sputext_class_open_plugin; + this->class.get_identifier = sputext_class_get_identifier; + this->class.get_description = sputext_class_get_description; + this->class.dispose = sputext_class_dispose; + + this->xine = xine; + + return &this->class; +} + + /* plugin catalog information */ static uint32_t supported_types[] = { BUF_SPU_TEXT, 0 }; @@ -1096,6 +418,6 @@ static decoder_info_t spudec_info = { plugin_info_t xine_plugin_info[] = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_SPU_DECODER, 9, "sputext", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, + { PLUGIN_SPU_DECODER, 13, "sputext", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |