From 80d90eb2a7e653e10716d479520fbc28a1405a5a Mon Sep 17 00:00:00 2001 From: Andreas Heinchen Date: Thu, 19 Jun 2003 15:31:04 +0000 Subject: make xine work with theora-alpha2 CVS patchset: 5072 CVS date: 2003/06/19 15:31:04 --- src/demuxers/demux_ogg.c | 35 ++++++++++++++++++++++----- src/libtheora/xine_decoder.c | 57 ++++++++++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/demuxers/demux_ogg.c b/src/demuxers/demux_ogg.c index 78c5fa532..293b46426 100644 --- a/src/demuxers/demux_ogg.c +++ b/src/demuxers/demux_ogg.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_ogg.c,v 1.101 2003/05/25 13:39:14 guenter Exp $ + * $Id: demux_ogg.c,v 1.102 2003/06/19 15:31:04 heinchen Exp $ * * demultiplexer for ogg streams * @@ -87,6 +87,7 @@ typedef struct demux_ogg_s { #ifdef HAVE_THEORA theora_info t_info; + theora_comment t_comment; #endif int status; @@ -414,10 +415,14 @@ static void send_ogg_buf (demux_ogg_t *this, } else if ((this->buf_types[stream_num] & 0xFFFF0000) == BUF_VIDEO_THEORA) { int64_t pts; - theora_info test; + theora_info t_info; + theora_comment t_comment; + + theora_info_init (&t_info); + theora_comment_init (&t_comment); /*Lets see if this is an Header*/ - if ((theora_decode_header(&test,op))>=0) { + if ((theora_decode_header(&t_info, &t_comment, op))>=0) { decoder_flags=decoder_flags|BUF_FLAG_HEADER; #ifdef LOG printf ("demux_ogg: found an header\n"); @@ -439,6 +444,9 @@ static void send_ogg_buf (demux_ogg_t *this, #endif send_ogg_packet (this, this->video_fifo, op, pts, decoder_flags, stream_num); + + theora_comment_clear (&t_comment); + theora_info_clear (&t_info); #endif } else if ((this->buf_types[stream_num] & 0xFF000000) == BUF_VIDEO_BASE) { @@ -1029,7 +1037,7 @@ static void demux_ogg_send_header (demux_ogg_t *this) { #ifdef HAVE_THEORA printf ("demux_ogg: Theorastreamsupport is highly alpha at the moment\n"); - if (theora_decode_header(&this->t_info, &op)>=0) { + if (theora_decode_header(&this->t_info, &this->t_comment, &op)>=0) { this->num_video_streams++; @@ -1038,7 +1046,7 @@ static void demux_ogg_send_header (demux_ogg_t *this) { this->frame_duration = ((int64_t) 90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; - this->preview_buffers[stream_num]=1; + this->preview_buffers[stream_num]=3; this->buf_types[stream_num] = BUF_VIDEO_THEORA; this->stream->meta_info[XINE_META_INFO_VIDEOCODEC] @@ -1050,6 +1058,11 @@ static void demux_ogg_send_header (demux_ogg_t *this) { this->stream->stream_info[XINE_STREAM_INFO_FRAME_DURATION] = ((int64_t) 90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; +#ifdef LOG + printf ("demux_ogg: decoded theora header \n"); + printf (" frameduration %d\n",this->frame_duration); + printf (" w:%d h:%d \n",this->t_info.width,this->t_info.height); +#endif } else { /*Rejected stream*/ printf ("demux_ogg: A theora header was rejected by libtheora\n"); @@ -1298,6 +1311,11 @@ static void demux_ogg_dispose (demux_plugin_t *this_gen) { ogg_sync_clear(&this->oy); +#ifdef HAVE_THEORA + theora_comment_clear (&this->t_comment); + theora_info_clear (&this->t_info); +#endif + free (this); } @@ -1582,7 +1600,12 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen, this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; - + +#ifdef HAVE_THEORA + theora_info_init (&this->t_info); + theora_comment_init (&this->t_comment); +#endif + return &this->demux_plugin; } diff --git a/src/libtheora/xine_decoder.c b/src/libtheora/xine_decoder.c index d33b99c0a..10ad3a776 100644 --- a/src/libtheora/xine_decoder.c +++ b/src/libtheora/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.6 2003/05/04 13:13:58 heinchen Exp $ + * $Id: xine_decoder.c,v 1.7 2003/06/19 15:31:04 heinchen Exp $ * * xine decoder plugin using libtheora * @@ -53,6 +53,7 @@ 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; @@ -62,9 +63,10 @@ typedef struct theora_decoder_s { char* packet; int done; int width, height; - int initialized; 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) { @@ -84,8 +86,10 @@ static void show_op_stats (theora_decoder_t *this) { static void yuv2frame(yuv_buffer *yuv, vo_frame_t *frame) { int i; - /*fixme - clarify if the frame must be copied or if there is a simpler solution + /*fixme - clarify if the frame must be copied or if there is a faster solution like exchanging the pointers*/ + + /*copy all 3 parts of the picture*/ for(i=0;iy_height;i++) xine_fast_memcpy(frame->base[0]+yuv->y_width*i, yuv->y+yuv->y_stride*i, @@ -101,7 +105,7 @@ static void yuv2frame(yuv_buffer *yuv, vo_frame_t *frame) { } static int collect_data (theora_decoder_t *this, buf_element_t *buf ) { - /* Assembles an ogg_packet which was send with send_ogg_packet over xinebuffers */ + /* 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); @@ -150,11 +154,24 @@ static void theora_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { int ret; if (!collect_data(this, buf)) return; + /*return, until a entire packets is collected*/ - if ((buf->decoder_flags & BUF_FLAG_HEADER) && !this->initialized) { - if (theora_decode_header(&this->t_info,&this->op)>=0) { - theora_decode_init (&this->t_state,&this->t_info); - this->initialized=1; + if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) ) { + /*get the first 3 packets and decode the header during preview*/ + + + if (this->hp_read<=2) { + /*decode three header packets*/ + if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)<0) { + printf ("libtheora: Was unable to decode header #%d, corrput stream?\n",this->hp_read); + } else { + this->hp_read++; + } + } + + if (this->hp_read==3) { + /*headers are now decoded. initialize the decoder*/ + theora_decode_init (&this->t_state, &this->t_info); this->frame_duration=((int64_t)90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; #ifdef LOG printf("libtheora: theora stream is Theora %dx%d %.02f fps video.\n", @@ -163,13 +180,17 @@ static void theora_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { #endif this->width=this->t_info.width; this->height=this->t_info.height; - } else - printf ("libtheora: Header could not be decoded.\n"); + this->initialized=1; + this->hp_read++; + } + } else if (buf->decoder_flags & BUF_FLAG_HEADER) { + /*ignore headerpackets*/ + return; - } else if (buf->decoder_flags & BUF_FLAG_PREVIEW) { - return; + } else { + /*decode videodata*/ if (!this->initialized) { printf ("libtheora: cannot decode stream without header\n"); @@ -240,6 +261,8 @@ static void theora_dispose (video_decoder_t *this_gen) { printf ("libtheora: 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); @@ -253,9 +276,11 @@ static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xi theora_decoder_t *this ; - printf ("You are trying to decode an theorastream. Theora is in the moment\n"); - printf ("in development, expect nasty surprises. If the stream could not be played back\n"); - printf ("go to http://xine.sourceforge.net and grab the latest release of xine.\n"); + printf ("You are trying to decode an theorastream. At the moment, theora is in\n"); + printf ("development. If the stream could not be played back go to\n"); + printf ("http://xine.sourceforge.net and get the latest release of xine.\n"); + printf ("This release will play back streams which have been encoded with\n"); + printf ("libtheora-alpha2."\n"); this = (theora_decoder_t *) malloc (sizeof (theora_decoder_t)); memset(this, 0, sizeof (theora_decoder_t)); @@ -278,6 +303,8 @@ static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xi 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; -- cgit v1.2.3