diff options
author | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2007-06-01 21:05:12 +0200 |
---|---|---|
committer | Diego 'Flameeyes' Pettenò <flameeyes@gmail.com> | 2007-06-01 21:05:12 +0200 |
commit | f209e8b8ef44998a5ea20544bbb39aaeefa28086 (patch) | |
tree | 94f304d31e4c4bf3c1f7b0bee11cf8cceb05c15e /src/libxinevdec | |
parent | 0f8f38c36c4a2c038b11c6c00a477695e0e1908a (diff) | |
download | xine-lib-f209e8b8ef44998a5ea20544bbb39aaeefa28086.tar.gz xine-lib-f209e8b8ef44998a5ea20544bbb39aaeefa28086.tar.bz2 |
Collapse the Ogg demuxer, and the Theora, Vorbis and Speex decoders in the same 'xiph' plugin.
As the three decoders requires Ogg support, and requires an Ogg demuxer to play, enabling any one of them will then enable the ogg demuxer.
The Ogg demuxer, on its own, needs to know which of the three formats are enabled, or it will not be able to properly decode them.
With this change, only one plugin will need to load and know about Xiph formats and libraries.
--HG--
rename : src/demuxers/demux_ogg.c => src/combined/xine_ogg_demuxer.c
rename : src/libxineadec/xine_speex_decoder.c => src/combined/xine_speex_decoder.c
rename : src/libxinevdec/xine_theora_decoder.c => src/combined/xine_theora_decoder.c
rename : src/libxineadec/xine_vorbis_decoder.c => src/combined/xine_vorbis_decoder.c
Diffstat (limited to 'src/libxinevdec')
-rw-r--r-- | src/libxinevdec/Makefile.am | 8 | ||||
-rw-r--r-- | src/libxinevdec/xine_theora_decoder.c | 402 |
2 files changed, 0 insertions, 410 deletions
diff --git a/src/libxinevdec/Makefile.am b/src/libxinevdec/Makefile.am index 28a926a79..ac632dfd5 100644 --- a/src/libxinevdec/Makefile.am +++ b/src/libxinevdec/Makefile.am @@ -13,10 +13,6 @@ if ENABLE_GDK_PIXBUF gdkpixbuf_module = xineplug_decode_gdk_pixbuf.la endif -if ENABLE_THEORA -theora_module = xineplug_decode_theora.la -endif - xineplug_LTLIBRARIES = $(image_module) \ $(gdkpixbuf_module) \ $(theora_module) \ @@ -40,7 +36,3 @@ xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS) xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(GDK_PIXBUF_LIBS) xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) - -xineplug_decode_theora_la_SOURCES = xine_theora_decoder.c -xineplug_decode_theora_la_LIBADD = $(XINE_LIB) $(OGG_LIBS) $(THEORA_LIBS) -xineplug_decode_theora_la_CFLAGS = $(AM_CFLAGS) $(OGG_CFLAGS) $(THEORA_CFLAGS) diff --git a/src/libxinevdec/xine_theora_decoder.c b/src/libxinevdec/xine_theora_decoder.c deleted file mode 100644 index 032f8800f..000000000 --- a/src/libxinevdec/xine_theora_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 <stdlib.h> -#include <stdio.h> -#include <inttypes.h> -#include <string.h> -#include <pthread.h> -#include <math.h> -#include <assert.h> -#include <theora/theora.h> - -#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;i<frame->height;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;i<frame->height/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 } -}; |