From 961c91517ea9f2b8342b1f84e9afeb1afbf89ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 4 Apr 2007 22:14:43 +0200 Subject: Move the Theora decoder from libtheora to libxinevdec, as it's a single file. --HG-- rename : src/libtheora/xine_decoder.c => src/libxinevdec/xine_theora_decoder.c --- configure.ac | 1 - src/Makefile.am | 1 - src/libtheora/Makefile.am | 15 -- src/libtheora/xine_decoder.c | 402 ---------------------------------- src/libxinevdec/Makefile.am | 8 + src/libxinevdec/xine_theora_decoder.c | 402 ++++++++++++++++++++++++++++++++++ 6 files changed, 410 insertions(+), 419 deletions(-) delete mode 100644 src/libtheora/Makefile.am delete mode 100644 src/libtheora/xine_decoder.c create mode 100644 src/libxinevdec/xine_theora_decoder.c diff --git a/configure.ac b/configure.ac index 1e910bbca..e81757fa7 100644 --- a/configure.ac +++ b/configure.ac @@ -2647,7 +2647,6 @@ src/libspucc/Makefile src/libspucmml/Makefile src/libspudvb/Makefile src/libsputext/Makefile -src/libtheora/Makefile src/libspeex/Makefile src/libw32dll/Makefile src/libw32dll/wine/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 86832bf18..e6c684819 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,7 +22,6 @@ SUBDIRS = \ libw32dll \ libxinevdec \ libxineadec \ - libtheora \ libspeex \ libreal \ libfaad \ diff --git a/src/libtheora/Makefile.am b/src/libtheora/Makefile.am deleted file mode 100644 index d3813765d..000000000 --- a/src/libtheora/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -include $(top_srcdir)/misc/Makefile.common - -AM_CFLAGS = $(THEORA_CFLAGS) - -libdir = $(XINE_PLUGINDIR) - -if HAVE_THEORA -theora_module = xineplug_decode_theora.la -endif - -lib_LTLIBRARIES = $(theora_module) - -xineplug_decode_theora_la_SOURCES = xine_decoder.c -xineplug_decode_theora_la_LIBADD = $(OGG_LIBS) $(THEORA_LIBS) $(XINE_LIB) -xineplug_decode_theora_la_LDFLAGS = -avoid-version -module diff --git a/src/libtheora/xine_decoder.c b/src/libtheora/xine_decoder.c deleted file mode 100644 index 032f8800f..000000000 --- a/src/libtheora/xine_decoder.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (C) 2001-2003 the xine project - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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.26 2006/07/10 22:08:30 dgp85 Exp $ - * - * xine decoder plugin using libtheora - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_MODULE "theora_decoder" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" -#include "metronom.h" -#include "xineutils.h" - -typedef struct theora_class_s { - video_decoder_class_t decoder_class; -} theora_class_t; - -typedef struct theora_decoder_s { - video_decoder_t theora_decoder; - theora_class_t *class; - theora_info t_info; - theora_comment t_comment; - theora_state t_state; - ogg_packet op; - yuv_buffer yuv; - xine_stream_t* stream; - int reject; - int op_max_size; - char* packet; - int done; - int width, height; - double ratio; - int offset_x, offset_y; - int frame_duration; - int skipframes; - int hp_read; - int initialized; -} theora_decoder_t; - -static void readin_op (theora_decoder_t *this, char* src, int size) { - if ( this->done+size > this->op_max_size) { - while (this->op_max_size < this->done+size) - this->op_max_size=this->op_max_size*2; - this->packet=realloc(this->packet, this->op_max_size); - this->op.packet=this->packet; - } - xine_fast_memcpy ( this->packet+this->done, src, size); - this->done=this->done+size; -} - -static void yuv2frame(yuv_buffer *yuv, vo_frame_t *frame, int offset_x, int offset_y) { - int i; - int crop_offset; - - /* fixme - direct rendering (exchaning pointers) may be possible. - * frame->base[0] = yuv->y could work if one could change the - * pitches[0,1,2] values, and rely on the drawing routine using - * the new pitches. With cropping and offsets, it's a bit trickier, - * but it would still be possible. - * Attempts at doing this have yielded nothing but SIGSEVs so far. - */ - - /* Copy yuv data onto the frame. Cropping and offset as specified - * by the frame_width, frame_height, offset_x and offset_y fields - * in the theora header is carried out. - */ - - crop_offset=offset_x+yuv->y_stride*offset_y; - for(i=0;iheight;i++) - xine_fast_memcpy(frame->base[0]+frame->pitches[0]*i, - yuv->y+crop_offset+yuv->y_stride*i, - frame->width); - - crop_offset=(offset_x/2)+(yuv->uv_stride)*(offset_y/2); - for(i=0;iheight/2;i++){ - xine_fast_memcpy(frame->base[1]+frame->pitches[1]*i, - yuv->u+crop_offset+yuv->uv_stride*i, - frame->width/2); - xine_fast_memcpy(frame->base[2]+frame->pitches[2]*i, - yuv->v+crop_offset+yuv->uv_stride*i, - frame->width/2); - - } -} - -static int collect_data (theora_decoder_t *this, buf_element_t *buf ) { - /* Assembles an ogg_packet which was sent with send_ogg_packet over xinebuffers */ - /* this->done, this->rejected, this->op and this->decoder->flags are needed*/ - int op_size = sizeof (ogg_packet); - - if (buf->decoder_flags & BUF_FLAG_FRAME_START) { - this->done=0; /*start from the beginnig*/ - this->reject=0;/*new packet - new try*/ - - /*copy the ogg_packet struct and the sum, correct the adress of the packet*/ - xine_fast_memcpy (&this->op, buf->content, op_size); - this->op.packet=this->packet; - - readin_op (this, buf->content + op_size, buf->size - op_size ); - /*read the rest of the data*/ - - } else { - if (this->done==0 || this->reject) { - /*we are starting to collect an packet without the beginnig - reject the rest*/ - printf ("libtheora: rejecting packet\n"); - this->reject=1; - return 0; - } - readin_op (this, buf->content, buf->size ); - } - - if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && !this->reject) { - if ( this->done != this->op.bytes ) { - printf ("libtheora: A packet changed its size during transfer - rejected\n"); - printf (" size %d should be %ld\n", this->done , this->op.bytes); - this->op.bytes=this->done; - } - return 1; - } - return 0; -} - -static void theora_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { - /* - * decode data from buf and feed decoded frames to - * video output - */ - theora_decoder_t *this = (theora_decoder_t *) this_gen; - vo_frame_t *frame; - yuv_buffer yuv; - int ret; - - if (!collect_data(this, buf)) return; - /*return, until a entire packets is collected*/ - - if ( (buf->decoder_flags & BUF_FLAG_HEADER) && - !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { - /*get the first 3 packets and decode the header during preview*/ - - if (this->hp_read==0) { - /*decode first hp*/ - if (theora_decode_header(&this->t_info, &this->t_comment, &this->op)>=0) { - this->hp_read++; - return; - } - } - - if (this->hp_read==1) { - /*decode three header packets*/ - if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { - printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); - } else { - this->hp_read++; - return; - } - } - - if (this->hp_read==2) { - if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { - printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); - } - /*headers are now decoded. initialize the decoder*/ - theora_decode_init (&this->t_state, &this->t_info); - - lprintf("theora stream is Theora %dx%d %.02f fps video.\n" - " frame content is %dx%d with offset (%d,%d).\n" - " pixel aspect is %d:%d.\n", - this->t_info.width,this->t_info.height, - (double)this->t_info.fps_numerator/this->t_info.fps_denominator, - this->t_info.frame_width, this->t_info.frame_height, - this->t_info.offset_x, this->t_info.offset_y, - this->t_info.aspect_numerator, this->t_info.aspect_denominator); - - this->frame_duration=((int64_t)90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; - this->width=this->t_info.frame_width; - this->height=this->t_info.frame_height; - if (this->t_info.aspect_numerator==0 || this->t_info.aspect_denominator==0) - /* 0-values are undefined, so don't do any scaling. */ - this->ratio=(double)this->width/(double)this->height; - else - /* Yes, this video needs to be scaled. */ - this->ratio=(double)(this->width*this->t_info.aspect_numerator) / - (double)(this->height*this->t_info.aspect_denominator); - this->offset_x=this->t_info.offset_x; - this->offset_y=this->t_info.offset_y; - this->initialized=1; - this->hp_read++; - } - - } else if (buf->decoder_flags & BUF_FLAG_HEADER) { - /*ignore headerpackets*/ - - return; - - } else { - /*decode videodata*/ - - if (!this->initialized) { - printf ("libtheora: cannot decode stream without header\n"); - return; - } - - ret=theora_decode_packetin( &this->t_state, &this->op); - - if ( ret!=0) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libtheora:Received an bad packet\n"); - } else if (!this->skipframes) { - - theora_decode_YUVout(&this->t_state,&yuv); - - /*fixme - aspectratio from theora is not considered*/ - frame = this->stream->video_out->get_frame( this->stream->video_out, - this->width, this->height, - this->ratio, - XINE_IMGFMT_YV12, - VO_BOTH_FIELDS); - yuv2frame(&yuv, frame, this->offset_x, this->offset_y); - - frame->pts = buf->pts; - frame->duration=this->frame_duration; - this->skipframes=frame->draw(frame, this->stream); - frame->free(frame); - } else { - this->skipframes=this->skipframes-1; - } - } -} - - -static void theora_flush (video_decoder_t *this_gen) { - /* - * flush out any frames that are still stored in the decoder - */ - theora_decoder_t *this = (theora_decoder_t *) this_gen; - this->skipframes=0; -} - -static void theora_reset (video_decoder_t *this_gen) { - /* - * reset decoder after engine flush (prepare for new - * video data not related to recently decoded data) - */ - theora_decoder_t *this = (theora_decoder_t *) this_gen; - this->skipframes=0; -} - -static void theora_discontinuity (video_decoder_t *this_gen) { - /* - * inform decoder that a time reference discontinuity has happened. - * that is, it must forget any currently held pts value - */ - theora_decoder_t *this = (theora_decoder_t *) this_gen; - this->skipframes=0; -} - -static void theora_dispose (video_decoder_t *this_gen) { - /* - * close down, free all resources - */ - - theora_decoder_t *this = (theora_decoder_t *) this_gen; - - lprintf ("dispose \n"); - - theora_clear (&this->t_state); - theora_comment_clear (&this->t_comment); - theora_info_clear (&this->t_info); - this->stream->video_out->close(this->stream->video_out, this->stream); - free (this->packet); - free (this); -} - -static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - - /* - * open a new instance of this plugin class - */ - - theora_decoder_t *this ; - - this = (theora_decoder_t *) xine_xmalloc (sizeof (theora_decoder_t)); - - this->theora_decoder.decode_data = theora_decode_data; - this->theora_decoder.flush = theora_flush; - this->theora_decoder.reset = theora_reset; - this->theora_decoder.discontinuity = theora_discontinuity; - this->theora_decoder.dispose = theora_dispose; - - this->stream = stream; - this->class = (theora_class_t *) class_gen; - - this->op_max_size = 4096; - this->packet = malloc(this->op_max_size); - - this->done = 0; - - this->stream = stream; - - this->initialized = 0; - - theora_comment_init (&this->t_comment); - theora_info_init (&this->t_info); - stream->video_out->open (stream->video_out, stream); - - return &this->theora_decoder; - -} - -/* - * theora plugin class - */ - -static char *theora_get_identifier (video_decoder_class_t *this) { - /* - * return short, human readable identifier for this plugin class - */ - return "theora video"; -} - -static char *theora_get_description (video_decoder_class_t *this) { - /* - * return human readable (verbose = 1 line) description for - * this plugin class - */ - return "theora video decoder plugin"; -} - -static void theora_dispose_class (video_decoder_class_t *this) { - /* - * free all class-related resources - */ - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - /*initialize our plugin*/ - theora_class_t *this; - - this = (theora_class_t *) xine_xmalloc (sizeof (theora_class_t)); - - this->decoder_class.open_plugin = theora_open_plugin; - this->decoder_class.get_identifier = theora_get_identifier; - this->decoder_class.get_description = theora_get_description; - this->decoder_class.dispose = theora_dispose_class; - - return this; -} - -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_THEORA, 0 }; - -static const decoder_info_t dec_info_video = { - supported_types, /* supported types */ - 5 /* priority */ -}; - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 18, "theora", XINE_VERSION_CODE, &dec_info_video, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am index 903399cbb..87ee050e6 100644 --- a/src/libxinevdec/Makefile.am +++ b/src/libxinevdec/Makefile.am @@ -13,8 +13,13 @@ if HAVE_GDK_PIXBUF gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la endif +if HAVE_THEORA +theora_module = xineplug_decode_theora.la +endif + xineplug_LTLIBRARIES = $(image_module) \ $(gdkpixbuf_module) \ + $(theora_module) \ xineplug_decode_bitplane.la \ xineplug_decode_rgb.la \ xineplug_decode_yuv.la @@ -36,3 +41,6 @@ xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXBUF_LIBS) +xineplug_decode_theora_la_SOURCES = xine_theora_decoder.c +xineplug_decode_theora_la_CFLAGS = $(AM_CFLAGS) $(OGG_CFLAGS) $(THEORA_CFLAGS) +xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS) diff --git a/src/libxinevdec/xine_theora_decoder.c b/src/libxinevdec/xine_theora_decoder.c new file mode 100644 index 000000000..032f8800f --- /dev/null +++ b/src/libxinevdec/xine_theora_decoder.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2001-2003 the xine project + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * 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.26 2006/07/10 22:08:30 dgp85 Exp $ + * + * xine decoder plugin using libtheora + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_MODULE "theora_decoder" +#define LOG_VERBOSE +/* +#define LOG +*/ + +#include "xine_internal.h" +#include "video_out.h" +#include "buffer.h" +#include "metronom.h" +#include "xineutils.h" + +typedef struct theora_class_s { + video_decoder_class_t decoder_class; +} theora_class_t; + +typedef struct theora_decoder_s { + video_decoder_t theora_decoder; + theora_class_t *class; + theora_info t_info; + theora_comment t_comment; + theora_state t_state; + ogg_packet op; + yuv_buffer yuv; + xine_stream_t* stream; + int reject; + int op_max_size; + char* packet; + int done; + int width, height; + double ratio; + int offset_x, offset_y; + int frame_duration; + int skipframes; + int hp_read; + int initialized; +} theora_decoder_t; + +static void readin_op (theora_decoder_t *this, char* src, int size) { + if ( this->done+size > this->op_max_size) { + while (this->op_max_size < this->done+size) + this->op_max_size=this->op_max_size*2; + this->packet=realloc(this->packet, this->op_max_size); + this->op.packet=this->packet; + } + xine_fast_memcpy ( this->packet+this->done, src, size); + this->done=this->done+size; +} + +static void yuv2frame(yuv_buffer *yuv, vo_frame_t *frame, int offset_x, int offset_y) { + int i; + int crop_offset; + + /* fixme - direct rendering (exchaning pointers) may be possible. + * frame->base[0] = yuv->y could work if one could change the + * pitches[0,1,2] values, and rely on the drawing routine using + * the new pitches. With cropping and offsets, it's a bit trickier, + * but it would still be possible. + * Attempts at doing this have yielded nothing but SIGSEVs so far. + */ + + /* Copy yuv data onto the frame. Cropping and offset as specified + * by the frame_width, frame_height, offset_x and offset_y fields + * in the theora header is carried out. + */ + + crop_offset=offset_x+yuv->y_stride*offset_y; + for(i=0;iheight;i++) + xine_fast_memcpy(frame->base[0]+frame->pitches[0]*i, + yuv->y+crop_offset+yuv->y_stride*i, + frame->width); + + crop_offset=(offset_x/2)+(yuv->uv_stride)*(offset_y/2); + for(i=0;iheight/2;i++){ + xine_fast_memcpy(frame->base[1]+frame->pitches[1]*i, + yuv->u+crop_offset+yuv->uv_stride*i, + frame->width/2); + xine_fast_memcpy(frame->base[2]+frame->pitches[2]*i, + yuv->v+crop_offset+yuv->uv_stride*i, + frame->width/2); + + } +} + +static int collect_data (theora_decoder_t *this, buf_element_t *buf ) { + /* Assembles an ogg_packet which was sent with send_ogg_packet over xinebuffers */ + /* this->done, this->rejected, this->op and this->decoder->flags are needed*/ + int op_size = sizeof (ogg_packet); + + if (buf->decoder_flags & BUF_FLAG_FRAME_START) { + this->done=0; /*start from the beginnig*/ + this->reject=0;/*new packet - new try*/ + + /*copy the ogg_packet struct and the sum, correct the adress of the packet*/ + xine_fast_memcpy (&this->op, buf->content, op_size); + this->op.packet=this->packet; + + readin_op (this, buf->content + op_size, buf->size - op_size ); + /*read the rest of the data*/ + + } else { + if (this->done==0 || this->reject) { + /*we are starting to collect an packet without the beginnig + reject the rest*/ + printf ("libtheora: rejecting packet\n"); + this->reject=1; + return 0; + } + readin_op (this, buf->content, buf->size ); + } + + if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && !this->reject) { + if ( this->done != this->op.bytes ) { + printf ("libtheora: A packet changed its size during transfer - rejected\n"); + printf (" size %d should be %ld\n", this->done , this->op.bytes); + this->op.bytes=this->done; + } + return 1; + } + return 0; +} + +static void theora_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { + /* + * decode data from buf and feed decoded frames to + * video output + */ + theora_decoder_t *this = (theora_decoder_t *) this_gen; + vo_frame_t *frame; + yuv_buffer yuv; + int ret; + + if (!collect_data(this, buf)) return; + /*return, until a entire packets is collected*/ + + if ( (buf->decoder_flags & BUF_FLAG_HEADER) && + !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { + /*get the first 3 packets and decode the header during preview*/ + + if (this->hp_read==0) { + /*decode first hp*/ + if (theora_decode_header(&this->t_info, &this->t_comment, &this->op)>=0) { + this->hp_read++; + return; + } + } + + if (this->hp_read==1) { + /*decode three header packets*/ + if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { + printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); + } else { + this->hp_read++; + return; + } + } + + if (this->hp_read==2) { + if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { + printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); + } + /*headers are now decoded. initialize the decoder*/ + theora_decode_init (&this->t_state, &this->t_info); + + lprintf("theora stream is Theora %dx%d %.02f fps video.\n" + " frame content is %dx%d with offset (%d,%d).\n" + " pixel aspect is %d:%d.\n", + this->t_info.width,this->t_info.height, + (double)this->t_info.fps_numerator/this->t_info.fps_denominator, + this->t_info.frame_width, this->t_info.frame_height, + this->t_info.offset_x, this->t_info.offset_y, + this->t_info.aspect_numerator, this->t_info.aspect_denominator); + + this->frame_duration=((int64_t)90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; + this->width=this->t_info.frame_width; + this->height=this->t_info.frame_height; + if (this->t_info.aspect_numerator==0 || this->t_info.aspect_denominator==0) + /* 0-values are undefined, so don't do any scaling. */ + this->ratio=(double)this->width/(double)this->height; + else + /* Yes, this video needs to be scaled. */ + this->ratio=(double)(this->width*this->t_info.aspect_numerator) / + (double)(this->height*this->t_info.aspect_denominator); + this->offset_x=this->t_info.offset_x; + this->offset_y=this->t_info.offset_y; + this->initialized=1; + this->hp_read++; + } + + } else if (buf->decoder_flags & BUF_FLAG_HEADER) { + /*ignore headerpackets*/ + + return; + + } else { + /*decode videodata*/ + + if (!this->initialized) { + printf ("libtheora: cannot decode stream without header\n"); + return; + } + + ret=theora_decode_packetin( &this->t_state, &this->op); + + if ( ret!=0) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libtheora:Received an bad packet\n"); + } else if (!this->skipframes) { + + theora_decode_YUVout(&this->t_state,&yuv); + + /*fixme - aspectratio from theora is not considered*/ + frame = this->stream->video_out->get_frame( this->stream->video_out, + this->width, this->height, + this->ratio, + XINE_IMGFMT_YV12, + VO_BOTH_FIELDS); + yuv2frame(&yuv, frame, this->offset_x, this->offset_y); + + frame->pts = buf->pts; + frame->duration=this->frame_duration; + this->skipframes=frame->draw(frame, this->stream); + frame->free(frame); + } else { + this->skipframes=this->skipframes-1; + } + } +} + + +static void theora_flush (video_decoder_t *this_gen) { + /* + * flush out any frames that are still stored in the decoder + */ + theora_decoder_t *this = (theora_decoder_t *) this_gen; + this->skipframes=0; +} + +static void theora_reset (video_decoder_t *this_gen) { + /* + * reset decoder after engine flush (prepare for new + * video data not related to recently decoded data) + */ + theora_decoder_t *this = (theora_decoder_t *) this_gen; + this->skipframes=0; +} + +static void theora_discontinuity (video_decoder_t *this_gen) { + /* + * inform decoder that a time reference discontinuity has happened. + * that is, it must forget any currently held pts value + */ + theora_decoder_t *this = (theora_decoder_t *) this_gen; + this->skipframes=0; +} + +static void theora_dispose (video_decoder_t *this_gen) { + /* + * close down, free all resources + */ + + theora_decoder_t *this = (theora_decoder_t *) this_gen; + + lprintf ("dispose \n"); + + theora_clear (&this->t_state); + theora_comment_clear (&this->t_comment); + theora_info_clear (&this->t_info); + this->stream->video_out->close(this->stream->video_out, this->stream); + free (this->packet); + free (this); +} + +static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + + /* + * open a new instance of this plugin class + */ + + theora_decoder_t *this ; + + this = (theora_decoder_t *) xine_xmalloc (sizeof (theora_decoder_t)); + + this->theora_decoder.decode_data = theora_decode_data; + this->theora_decoder.flush = theora_flush; + this->theora_decoder.reset = theora_reset; + this->theora_decoder.discontinuity = theora_discontinuity; + this->theora_decoder.dispose = theora_dispose; + + this->stream = stream; + this->class = (theora_class_t *) class_gen; + + this->op_max_size = 4096; + this->packet = malloc(this->op_max_size); + + this->done = 0; + + this->stream = stream; + + this->initialized = 0; + + theora_comment_init (&this->t_comment); + theora_info_init (&this->t_info); + stream->video_out->open (stream->video_out, stream); + + return &this->theora_decoder; + +} + +/* + * theora plugin class + */ + +static char *theora_get_identifier (video_decoder_class_t *this) { + /* + * return short, human readable identifier for this plugin class + */ + return "theora video"; +} + +static char *theora_get_description (video_decoder_class_t *this) { + /* + * return human readable (verbose = 1 line) description for + * this plugin class + */ + return "theora video decoder plugin"; +} + +static void theora_dispose_class (video_decoder_class_t *this) { + /* + * free all class-related resources + */ + free (this); +} + +static void *init_plugin (xine_t *xine, void *data) { + /*initialize our plugin*/ + theora_class_t *this; + + this = (theora_class_t *) xine_xmalloc (sizeof (theora_class_t)); + + this->decoder_class.open_plugin = theora_open_plugin; + this->decoder_class.get_identifier = theora_get_identifier; + this->decoder_class.get_description = theora_get_description; + this->decoder_class.dispose = theora_dispose_class; + + return this; +} + +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_THEORA, 0 }; + +static const decoder_info_t dec_info_video = { + supported_types, /* supported types */ + 5 /* priority */ +}; + +const plugin_info_t xine_plugin_info[] EXPORTED = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 18, "theora", XINE_VERSION_CODE, &dec_info_video, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; -- cgit v1.2.3