From c95d450dadb640aa3ee4cb9536626fe183549ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20=27Flameeyes=27=20Petten=C3=B2?= Date: Wed, 4 Apr 2007 22:36:40 +0200 Subject: Rename xine_decoder.c to xine_mpeg2new_decoder.c. Use xineplug_LTLIBRARIES. --HG-- rename : src/libmpeg2new/xine_decoder.c => src/libmpeg2new/xine_mpeg2new_decoder.c --- src/libmpeg2new/Makefile.am | 11 +- src/libmpeg2new/xine_decoder.c | 519 -------------------------------- src/libmpeg2new/xine_mpeg2new_decoder.c | 519 ++++++++++++++++++++++++++++++++ 3 files changed, 523 insertions(+), 526 deletions(-) delete mode 100644 src/libmpeg2new/xine_decoder.c create mode 100644 src/libmpeg2new/xine_mpeg2new_decoder.c (limited to 'src') diff --git a/src/libmpeg2new/Makefile.am b/src/libmpeg2new/Makefile.am index 03dae6cba..49959da86 100644 --- a/src/libmpeg2new/Makefile.am +++ b/src/libmpeg2new/Makefile.am @@ -1,16 +1,13 @@ include $(top_srcdir)/misc/Makefile.common -AM_CFLAGS = $(LIBMPEG2_CFLAGS) - SUBDIRS = libmpeg2 -libdir = $(XINE_PLUGINDIR) - -lib_LTLIBRARIES = xineplug_decode_mpeg2.la +xineplug_LTLIBRARIES = xineplug_decode_mpeg2.la xineplug_decode_mpeg2_la_SOURCES = \ - xine_decoder.c + xine_mpeg2_decoder.c +xineplug_decode_mpeg2_la_CFLAGS = $(VISIBILITY_FLAG) $(LIBMPEG2_CFLAGS) xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) ./libmpeg2/libmpeg2.la -xineplug_decode_mpeg2_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ +xineplug_decode_mpeg2_la_LDFLAGS = $(xineplug_ldflags) diff --git a/src/libmpeg2new/xine_decoder.c b/src/libmpeg2new/xine_decoder.c deleted file mode 100644 index 9e36772b7..000000000 --- a/src/libmpeg2new/xine_decoder.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (C) 2000-2004 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.22 2004/12/16 13:59:06 mroi Exp $ - * - * stuff needed to turn libmpeg2 into a xine decoder plugin - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "./include/mpeg2.h" -#include "xine_internal.h" -#include "video_out.h" -#include "buffer.h" - - - -#define LOG -#define LOG_FRAME_ALLOC_FREE -#define LOG_ENTRY -#define LOG_FRAME_COUNTER - - -typedef struct { - video_decoder_class_t decoder_class; -} mpeg2_class_t; - -typedef struct { - uint32_t id; - vo_frame_t * img; -} img_state_t; - -typedef struct mpeg2_video_decoder_s { - video_decoder_t video_decoder; - mpeg2dec_t *mpeg2dec; - mpeg2_class_t *class; - xine_stream_t *stream; - int32_t force_aspect; - int force_pan_scan; - double ratio; - img_state_t img_state[30]; - uint32_t frame_number; - uint32_t rff_pattern; - -} mpeg2_video_decoder_t; - - -static void mpeg2_video_print_bad_state(img_state_t * img_state) { - int32_t n,m; - m=0; - for(n=0;n<30;n++) { - if (img_state[n].id>0) { - printf("%d = %u\n",n, img_state[n].id); - m++; - } - } - if (m > 3) _x_abort(); - if (m == 0) printf("NO FRAMES\n"); -} - -static void mpeg2_video_free_all(img_state_t * img_state) { - int32_t n,m; - vo_frame_t * img; - printf("libmpeg2new:free_all\n"); - for(n=0;n<30;n++) { - if (img_state[n].id>0) { - img = img_state[n].img; - img->free(img); - img_state[n].id = 0; - } - } -} - - -static void mpeg2_video_print_fbuf(const mpeg2_fbuf_t * fbuf) { - printf("%p",fbuf); - vo_frame_t * img; - if (fbuf) { - img = (vo_frame_t *) fbuf->id; - if (img) { - printf (", img=%p, (id=%d)\n", - img, img->id); - } else { - printf (", img=NULL\n"); - } - } else { - printf ("\n"); - } -} - -static void mpeg2_video_decode_data (video_decoder_t *this_gen, buf_element_t *buf_element) { - mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; - uint8_t * current = buf_element->content; - uint8_t * end = buf_element->content + buf_element->size; - const mpeg2_info_t * info; - mpeg2_state_t state; - vo_frame_t * img; - uint32_t picture_structure; - int32_t frame_skipping; - - /* handle aspect hints from xine-dvdnav */ - if (buf_element->decoder_flags & BUF_FLAG_SPECIAL) { - if (buf_element->decoder_info[1] == BUF_SPECIAL_ASPECT) { - this->force_aspect = buf_element->decoder_info[2]; - if (buf_element->decoder_info[3] == 0x1 && buf_element->decoder_info[2] == 3) - /* letterboxing is denied, we have to do pan&scan */ - this->force_pan_scan = 1; - else - this->force_pan_scan = 0; - } - - return; - } - - if (buf_element->decoder_flags != 0) return; - -#ifdef LOG_ENTRY - printf ("libmpeg2: decode_data: enter\n"); -#endif - - mpeg2_buffer (this->mpeg2dec, current, end); - - info = mpeg2_info (this->mpeg2dec); - - while ((state = mpeg2_parse (this->mpeg2dec)) != STATE_BUFFER) { - switch (state) { - case STATE_SEQUENCE: - /* might set nb fbuf, convert format, stride */ - /* might set fbufs */ - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, info->sequence->byte_rate * 8); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, info->sequence->picture_width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, info->sequence->picture_height); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, info->sequence->frame_period / 300); - if (this->force_aspect) info->sequence->pixel_width = this->force_aspect; - switch (info->sequence->pixel_width) { - case 3: - this->ratio = 16.0 / 9.0; - break; - case 4: - this->ratio = 2.11; - break; - case 2: - this->ratio = 4.0 / 3.0; - break; - case 1: - default: - this->ratio = (double)info->sequence->picture_width/(double)info->sequence->picture_height; - break; - } - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, (int)(10000*this->ratio)); - - if (info->sequence->flags & SEQ_FLAG_MPEG2) { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 2 (libmpeg2new)"); - } else { - _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 1 (libmpeg2new)"); - } - - break; - case STATE_PICTURE: - /* might skip */ - /* might set fbuf */ - if (info->current_picture->nb_fields == 1) { - picture_structure = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? VO_TOP_FIELD : VO_BOTTOM_FIELD; - } else { - picture_structure = VO_BOTH_FIELDS; - } - - img = this->stream->video_out->get_frame (this->stream->video_out, - info->sequence->picture_width, - info->sequence->picture_height, - this->ratio, - XINE_IMGFMT_YV12, - picture_structure); - this->frame_number++; -#ifdef LOG_FRAME_COUNTER - printf("libmpeg2:frame_number=%d\n",this->frame_number); -#endif - img->top_field_first = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? 1 : 0; - img->repeat_first_field = (info->current_picture->nb_fields > 2) ? 1 : 0; - img->duration=info->sequence->frame_period / 300; - if( ((this->rff_pattern & 0xff) == 0xaa || - (this->rff_pattern & 0xff) == 0x55) ) { - /* special case for ntsc 3:2 pulldown */ - img->duration += img->duration/4; - } else { - if( img->repeat_first_field ) { - img->duration = (img->duration * info->current_picture->nb_fields) / 2; - } - } - - if ((info->current_picture->flags & 7) == 1) { - img->pts=buf_element->pts; /* If an I frame, use PTS */ - } else { - img->pts=0; - } - - -#ifdef LOG_FRAME_ALLOC_FREE - printf ("libmpeg2:decode_data:get_frame xine=%p (id=%d)\n", img,img->id); -#endif - if (this->img_state[img->id].id != 0) { - printf ("libmpeg2:decode_data:get_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); - _x_abort(); - } - - this->img_state[img->id].id = 1; - this->img_state[img->id].img = img; - - mpeg2_set_buf (this->mpeg2dec, img->base, img); - break; - case STATE_SLICE: - case STATE_END: -#if 0 - printf("libmpeg2:decode_data:current_fbuf="); - mpeg2_video_print_fbuf(info->current_fbuf); - printf("libmpeg2:decode_data:display_fbuf="); - mpeg2_video_print_fbuf(info->display_fbuf); - printf("libmpeg2:decode_data:discard_fbuf="); - mpeg2_video_print_fbuf(info->discard_fbuf); -#endif - /* draw current picture */ - /* might free frame buffer */ - if (info->display_fbuf && info->display_fbuf->id) { - img = (vo_frame_t *) info->display_fbuf->id; - /* this should be used to detect any special rff pattern */ - this->rff_pattern = this->rff_pattern << 1; - this->rff_pattern |= img->repeat_first_field; - -#ifdef LOG_FRAME_ALLOC_FREE - printf ("libmpeg2:decode_data:draw_frame xine=%p, fbuf=%p, id=%d \n", img, info->display_fbuf, img->id); -#endif - if (this->img_state[img->id].id != 1) { - printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); - _x_abort(); - } - if (this->img_state[img->id].id == 1) { - frame_skipping = img->draw (img, this->stream); - /* FIXME: Handle skipping */ - this->img_state[img->id].id = 2; - } - - } - if (info->discard_fbuf && !info->discard_fbuf->id) { - printf ("libmpeg2:decode_data:BAD free_frame discard: xine=%p, fbuf=%p\n", info->discard_fbuf->id, info->discard_fbuf); - //_x_abort(); - } - if (info->discard_fbuf && info->discard_fbuf->id) { - img = (vo_frame_t *) info->discard_fbuf->id; -#ifdef LOG_FRAME_ALLOC_FREE - printf ("libmpeg2:decode_data:free_frame xine=%p, fbuf=%p,id=%d\n", img, info->discard_fbuf, img->id); -#endif - if (this->img_state[img->id].id != 2) { - printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); - _x_abort(); - } - if (this->img_state[img->id].id == 2) { - img->free(img); - this->img_state[img->id].id = 0; - } - } -#ifdef LOG_FRAME_ALLOC_FREE - mpeg2_video_print_bad_state(this->img_state); -#endif - break; - case STATE_GOP: - break; - default: - printf("libmpeg2new: STATE unknown %d\n",state); - break; - } - - } -#ifdef LOG_ENTRY - printf ("libmpeg2: decode_data: exit\n"); -#endif - -} - -static void mpeg2_video_flush (video_decoder_t *this_gen) { - mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; - -#ifdef LOG_ENTRY - printf ("libmpeg2: flush\n"); -#endif - -/* mpeg2_flush (&this->mpeg2); */ -} - -static void mpeg2_video_reset (video_decoder_t *this_gen) { - mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; - int32_t state; - const mpeg2_info_t * info; - vo_frame_t * img; - int32_t frame_skipping; - -#ifdef LOG_ENTRY - printf ("libmpeg2: reset\n"); -#endif - mpeg2_reset (this->mpeg2dec, 1); /* 1 for full reset */ - mpeg2_video_free_all(this->img_state); - - -#if 0 /* This bit of code does not work yet. */ - info = mpeg2_info (this->mpeg2dec); - state = mpeg2_reset (this->mpeg2dec); - printf("reset state1:%d\n",state); - if (info->display_fbuf && info->display_fbuf->id) { - img = (vo_frame_t *) info->display_fbuf->id; - - if (this->img_state[img->id] != 1) { - printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 1) { - frame_skipping = img->draw (img, this->stream); - /* FIXME: Handle skipping */ - this->img_state[img->id] = 2; - } - } - - if (info->discard_fbuf && !info->discard_fbuf->id) { - printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); - _x_abort(); - } - if (info->discard_fbuf && info->discard_fbuf->id) { - img = (vo_frame_t *) info->discard_fbuf->id; - if (this->img_state[img->id] != 2) { - printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 2) { - img->free(img); - this->img_state[img->id] = 0; - } - } - state = mpeg2_parse (this->mpeg2dec); - printf("reset state2:%d\n",state); - if (info->display_fbuf && info->display_fbuf->id) { - img = (vo_frame_t *) info->display_fbuf->id; - - if (this->img_state[img->id] != 1) { - printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 1) { - frame_skipping = img->draw (img, this->stream); - /* FIXME: Handle skipping */ - this->img_state[img->id] = 2; - } - } - - if (info->discard_fbuf && !info->discard_fbuf->id) { - printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); - _x_abort(); - } - if (info->discard_fbuf && info->discard_fbuf->id) { - img = (vo_frame_t *) info->discard_fbuf->id; - if (this->img_state[img->id] != 2) { - printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 2) { - img->free(img); - this->img_state[img->id] = 0; - } - } - state = mpeg2_parse (this->mpeg2dec); - printf("reset state3:%d\n",state); - if (info->display_fbuf && info->display_fbuf->id) { - img = (vo_frame_t *) info->display_fbuf->id; - - if (this->img_state[img->id] != 1) { - printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 1) { - frame_skipping = img->draw (img, this->stream); - /* FIXME: Handle skipping */ - this->img_state[img->id] = 2; - } - } - - if (info->discard_fbuf && !info->discard_fbuf->id) { - printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); - _x_abort(); - } - if (info->discard_fbuf && info->discard_fbuf->id) { - img = (vo_frame_t *) info->discard_fbuf->id; - if (this->img_state[img->id] != 2) { - printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); - _x_abort(); - } - if (this->img_state[img->id] == 2) { - img->free(img); - this->img_state[img->id] = 0; - } - } -#endif - -} - -static void mpeg2_video_discontinuity (video_decoder_t *this_gen) { - mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; - -#ifdef LOG_ENTRY - printf ("libmpeg2: dicontinuity\n"); -#endif -/* mpeg2_discontinuity (&this->mpeg2dec); */ -} - -static void mpeg2_video_dispose (video_decoder_t *this_gen) { - - mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; - -#ifdef LOG_ENTRY - printf ("libmpeg2: close\n"); -#endif - - mpeg2_close (this->mpeg2dec); - - this->stream->video_out->close(this->stream->video_out, this->stream); - - free (this); -} - -static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { - mpeg2_video_decoder_t *this ; - int32_t n; - - this = (mpeg2_video_decoder_t *) xine_xmalloc (sizeof (mpeg2_video_decoder_t)); - - this->video_decoder.decode_data = mpeg2_video_decode_data; - this->video_decoder.flush = mpeg2_video_flush; - this->video_decoder.reset = mpeg2_video_reset; - this->video_decoder.discontinuity = mpeg2_video_discontinuity; - this->video_decoder.dispose = mpeg2_video_dispose; - this->stream = stream; - this->class = (mpeg2_class_t *) class_gen; - this->frame_number=0; - this->rff_pattern=0; - - this->mpeg2dec = mpeg2_init (); - mpeg2_custom_fbuf (this->mpeg2dec, 1); /* <- Force libmpeg2 to use xine frame buffers. */ - stream->video_out->open(stream->video_out, stream); - this->force_aspect = this->force_pan_scan = 0; - for(n=0;n<30;n++) this->img_state[n].id=0; - - return &this->video_decoder; -} - -/* - * mpeg2 plugin class - */ - -static char *get_identifier (video_decoder_class_t *this) { - return "mpeg2new"; -} - -static char *get_description (video_decoder_class_t *this) { - return "mpeg2 based video decoder plugin"; -} - -static void dispose_class (video_decoder_class_t *this) { - free (this); -} - -static void *init_plugin (xine_t *xine, void *data) { - - mpeg2_class_t *this; - - this = (mpeg2_class_t *) xine_xmalloc (sizeof (mpeg2_class_t)); - - this->decoder_class.open_plugin = open_plugin; - this->decoder_class.get_identifier = get_identifier; - this->decoder_class.get_description = get_description; - this->decoder_class.dispose = dispose_class; - - return this; -} -/* - * exported plugin catalog entry - */ - -static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; - -static decoder_info_t dec_info_mpeg2 = { - supported_types, /* supported types */ - 6 /* priority */ -}; - -plugin_info_t xine_plugin_info[] = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_DECODER, 18, "mpeg2new", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/src/libmpeg2new/xine_mpeg2new_decoder.c b/src/libmpeg2new/xine_mpeg2new_decoder.c new file mode 100644 index 000000000..9e36772b7 --- /dev/null +++ b/src/libmpeg2new/xine_mpeg2new_decoder.c @@ -0,0 +1,519 @@ +/* + * Copyright (C) 2000-2004 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.22 2004/12/16 13:59:06 mroi Exp $ + * + * stuff needed to turn libmpeg2 into a xine decoder plugin + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "./include/mpeg2.h" +#include "xine_internal.h" +#include "video_out.h" +#include "buffer.h" + + + +#define LOG +#define LOG_FRAME_ALLOC_FREE +#define LOG_ENTRY +#define LOG_FRAME_COUNTER + + +typedef struct { + video_decoder_class_t decoder_class; +} mpeg2_class_t; + +typedef struct { + uint32_t id; + vo_frame_t * img; +} img_state_t; + +typedef struct mpeg2_video_decoder_s { + video_decoder_t video_decoder; + mpeg2dec_t *mpeg2dec; + mpeg2_class_t *class; + xine_stream_t *stream; + int32_t force_aspect; + int force_pan_scan; + double ratio; + img_state_t img_state[30]; + uint32_t frame_number; + uint32_t rff_pattern; + +} mpeg2_video_decoder_t; + + +static void mpeg2_video_print_bad_state(img_state_t * img_state) { + int32_t n,m; + m=0; + for(n=0;n<30;n++) { + if (img_state[n].id>0) { + printf("%d = %u\n",n, img_state[n].id); + m++; + } + } + if (m > 3) _x_abort(); + if (m == 0) printf("NO FRAMES\n"); +} + +static void mpeg2_video_free_all(img_state_t * img_state) { + int32_t n,m; + vo_frame_t * img; + printf("libmpeg2new:free_all\n"); + for(n=0;n<30;n++) { + if (img_state[n].id>0) { + img = img_state[n].img; + img->free(img); + img_state[n].id = 0; + } + } +} + + +static void mpeg2_video_print_fbuf(const mpeg2_fbuf_t * fbuf) { + printf("%p",fbuf); + vo_frame_t * img; + if (fbuf) { + img = (vo_frame_t *) fbuf->id; + if (img) { + printf (", img=%p, (id=%d)\n", + img, img->id); + } else { + printf (", img=NULL\n"); + } + } else { + printf ("\n"); + } +} + +static void mpeg2_video_decode_data (video_decoder_t *this_gen, buf_element_t *buf_element) { + mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; + uint8_t * current = buf_element->content; + uint8_t * end = buf_element->content + buf_element->size; + const mpeg2_info_t * info; + mpeg2_state_t state; + vo_frame_t * img; + uint32_t picture_structure; + int32_t frame_skipping; + + /* handle aspect hints from xine-dvdnav */ + if (buf_element->decoder_flags & BUF_FLAG_SPECIAL) { + if (buf_element->decoder_info[1] == BUF_SPECIAL_ASPECT) { + this->force_aspect = buf_element->decoder_info[2]; + if (buf_element->decoder_info[3] == 0x1 && buf_element->decoder_info[2] == 3) + /* letterboxing is denied, we have to do pan&scan */ + this->force_pan_scan = 1; + else + this->force_pan_scan = 0; + } + + return; + } + + if (buf_element->decoder_flags != 0) return; + +#ifdef LOG_ENTRY + printf ("libmpeg2: decode_data: enter\n"); +#endif + + mpeg2_buffer (this->mpeg2dec, current, end); + + info = mpeg2_info (this->mpeg2dec); + + while ((state = mpeg2_parse (this->mpeg2dec)) != STATE_BUFFER) { + switch (state) { + case STATE_SEQUENCE: + /* might set nb fbuf, convert format, stride */ + /* might set fbufs */ + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, info->sequence->byte_rate * 8); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, info->sequence->picture_width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, info->sequence->picture_height); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, info->sequence->frame_period / 300); + if (this->force_aspect) info->sequence->pixel_width = this->force_aspect; + switch (info->sequence->pixel_width) { + case 3: + this->ratio = 16.0 / 9.0; + break; + case 4: + this->ratio = 2.11; + break; + case 2: + this->ratio = 4.0 / 3.0; + break; + case 1: + default: + this->ratio = (double)info->sequence->picture_width/(double)info->sequence->picture_height; + break; + } + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, (int)(10000*this->ratio)); + + if (info->sequence->flags & SEQ_FLAG_MPEG2) { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 2 (libmpeg2new)"); + } else { + _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 1 (libmpeg2new)"); + } + + break; + case STATE_PICTURE: + /* might skip */ + /* might set fbuf */ + if (info->current_picture->nb_fields == 1) { + picture_structure = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? VO_TOP_FIELD : VO_BOTTOM_FIELD; + } else { + picture_structure = VO_BOTH_FIELDS; + } + + img = this->stream->video_out->get_frame (this->stream->video_out, + info->sequence->picture_width, + info->sequence->picture_height, + this->ratio, + XINE_IMGFMT_YV12, + picture_structure); + this->frame_number++; +#ifdef LOG_FRAME_COUNTER + printf("libmpeg2:frame_number=%d\n",this->frame_number); +#endif + img->top_field_first = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? 1 : 0; + img->repeat_first_field = (info->current_picture->nb_fields > 2) ? 1 : 0; + img->duration=info->sequence->frame_period / 300; + if( ((this->rff_pattern & 0xff) == 0xaa || + (this->rff_pattern & 0xff) == 0x55) ) { + /* special case for ntsc 3:2 pulldown */ + img->duration += img->duration/4; + } else { + if( img->repeat_first_field ) { + img->duration = (img->duration * info->current_picture->nb_fields) / 2; + } + } + + if ((info->current_picture->flags & 7) == 1) { + img->pts=buf_element->pts; /* If an I frame, use PTS */ + } else { + img->pts=0; + } + + +#ifdef LOG_FRAME_ALLOC_FREE + printf ("libmpeg2:decode_data:get_frame xine=%p (id=%d)\n", img,img->id); +#endif + if (this->img_state[img->id].id != 0) { + printf ("libmpeg2:decode_data:get_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); + _x_abort(); + } + + this->img_state[img->id].id = 1; + this->img_state[img->id].img = img; + + mpeg2_set_buf (this->mpeg2dec, img->base, img); + break; + case STATE_SLICE: + case STATE_END: +#if 0 + printf("libmpeg2:decode_data:current_fbuf="); + mpeg2_video_print_fbuf(info->current_fbuf); + printf("libmpeg2:decode_data:display_fbuf="); + mpeg2_video_print_fbuf(info->display_fbuf); + printf("libmpeg2:decode_data:discard_fbuf="); + mpeg2_video_print_fbuf(info->discard_fbuf); +#endif + /* draw current picture */ + /* might free frame buffer */ + if (info->display_fbuf && info->display_fbuf->id) { + img = (vo_frame_t *) info->display_fbuf->id; + /* this should be used to detect any special rff pattern */ + this->rff_pattern = this->rff_pattern << 1; + this->rff_pattern |= img->repeat_first_field; + +#ifdef LOG_FRAME_ALLOC_FREE + printf ("libmpeg2:decode_data:draw_frame xine=%p, fbuf=%p, id=%d \n", img, info->display_fbuf, img->id); +#endif + if (this->img_state[img->id].id != 1) { + printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); + _x_abort(); + } + if (this->img_state[img->id].id == 1) { + frame_skipping = img->draw (img, this->stream); + /* FIXME: Handle skipping */ + this->img_state[img->id].id = 2; + } + + } + if (info->discard_fbuf && !info->discard_fbuf->id) { + printf ("libmpeg2:decode_data:BAD free_frame discard: xine=%p, fbuf=%p\n", info->discard_fbuf->id, info->discard_fbuf); + //_x_abort(); + } + if (info->discard_fbuf && info->discard_fbuf->id) { + img = (vo_frame_t *) info->discard_fbuf->id; +#ifdef LOG_FRAME_ALLOC_FREE + printf ("libmpeg2:decode_data:free_frame xine=%p, fbuf=%p,id=%d\n", img, info->discard_fbuf, img->id); +#endif + if (this->img_state[img->id].id != 2) { + printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); + _x_abort(); + } + if (this->img_state[img->id].id == 2) { + img->free(img); + this->img_state[img->id].id = 0; + } + } +#ifdef LOG_FRAME_ALLOC_FREE + mpeg2_video_print_bad_state(this->img_state); +#endif + break; + case STATE_GOP: + break; + default: + printf("libmpeg2new: STATE unknown %d\n",state); + break; + } + + } +#ifdef LOG_ENTRY + printf ("libmpeg2: decode_data: exit\n"); +#endif + +} + +static void mpeg2_video_flush (video_decoder_t *this_gen) { + mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; + +#ifdef LOG_ENTRY + printf ("libmpeg2: flush\n"); +#endif + +/* mpeg2_flush (&this->mpeg2); */ +} + +static void mpeg2_video_reset (video_decoder_t *this_gen) { + mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; + int32_t state; + const mpeg2_info_t * info; + vo_frame_t * img; + int32_t frame_skipping; + +#ifdef LOG_ENTRY + printf ("libmpeg2: reset\n"); +#endif + mpeg2_reset (this->mpeg2dec, 1); /* 1 for full reset */ + mpeg2_video_free_all(this->img_state); + + +#if 0 /* This bit of code does not work yet. */ + info = mpeg2_info (this->mpeg2dec); + state = mpeg2_reset (this->mpeg2dec); + printf("reset state1:%d\n",state); + if (info->display_fbuf && info->display_fbuf->id) { + img = (vo_frame_t *) info->display_fbuf->id; + + if (this->img_state[img->id] != 1) { + printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 1) { + frame_skipping = img->draw (img, this->stream); + /* FIXME: Handle skipping */ + this->img_state[img->id] = 2; + } + } + + if (info->discard_fbuf && !info->discard_fbuf->id) { + printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); + _x_abort(); + } + if (info->discard_fbuf && info->discard_fbuf->id) { + img = (vo_frame_t *) info->discard_fbuf->id; + if (this->img_state[img->id] != 2) { + printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 2) { + img->free(img); + this->img_state[img->id] = 0; + } + } + state = mpeg2_parse (this->mpeg2dec); + printf("reset state2:%d\n",state); + if (info->display_fbuf && info->display_fbuf->id) { + img = (vo_frame_t *) info->display_fbuf->id; + + if (this->img_state[img->id] != 1) { + printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 1) { + frame_skipping = img->draw (img, this->stream); + /* FIXME: Handle skipping */ + this->img_state[img->id] = 2; + } + } + + if (info->discard_fbuf && !info->discard_fbuf->id) { + printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); + _x_abort(); + } + if (info->discard_fbuf && info->discard_fbuf->id) { + img = (vo_frame_t *) info->discard_fbuf->id; + if (this->img_state[img->id] != 2) { + printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 2) { + img->free(img); + this->img_state[img->id] = 0; + } + } + state = mpeg2_parse (this->mpeg2dec); + printf("reset state3:%d\n",state); + if (info->display_fbuf && info->display_fbuf->id) { + img = (vo_frame_t *) info->display_fbuf->id; + + if (this->img_state[img->id] != 1) { + printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 1) { + frame_skipping = img->draw (img, this->stream); + /* FIXME: Handle skipping */ + this->img_state[img->id] = 2; + } + } + + if (info->discard_fbuf && !info->discard_fbuf->id) { + printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); + _x_abort(); + } + if (info->discard_fbuf && info->discard_fbuf->id) { + img = (vo_frame_t *) info->discard_fbuf->id; + if (this->img_state[img->id] != 2) { + printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); + _x_abort(); + } + if (this->img_state[img->id] == 2) { + img->free(img); + this->img_state[img->id] = 0; + } + } +#endif + +} + +static void mpeg2_video_discontinuity (video_decoder_t *this_gen) { + mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; + +#ifdef LOG_ENTRY + printf ("libmpeg2: dicontinuity\n"); +#endif +/* mpeg2_discontinuity (&this->mpeg2dec); */ +} + +static void mpeg2_video_dispose (video_decoder_t *this_gen) { + + mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; + +#ifdef LOG_ENTRY + printf ("libmpeg2: close\n"); +#endif + + mpeg2_close (this->mpeg2dec); + + this->stream->video_out->close(this->stream->video_out, this->stream); + + free (this); +} + +static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { + mpeg2_video_decoder_t *this ; + int32_t n; + + this = (mpeg2_video_decoder_t *) xine_xmalloc (sizeof (mpeg2_video_decoder_t)); + + this->video_decoder.decode_data = mpeg2_video_decode_data; + this->video_decoder.flush = mpeg2_video_flush; + this->video_decoder.reset = mpeg2_video_reset; + this->video_decoder.discontinuity = mpeg2_video_discontinuity; + this->video_decoder.dispose = mpeg2_video_dispose; + this->stream = stream; + this->class = (mpeg2_class_t *) class_gen; + this->frame_number=0; + this->rff_pattern=0; + + this->mpeg2dec = mpeg2_init (); + mpeg2_custom_fbuf (this->mpeg2dec, 1); /* <- Force libmpeg2 to use xine frame buffers. */ + stream->video_out->open(stream->video_out, stream); + this->force_aspect = this->force_pan_scan = 0; + for(n=0;n<30;n++) this->img_state[n].id=0; + + return &this->video_decoder; +} + +/* + * mpeg2 plugin class + */ + +static char *get_identifier (video_decoder_class_t *this) { + return "mpeg2new"; +} + +static char *get_description (video_decoder_class_t *this) { + return "mpeg2 based video decoder plugin"; +} + +static void dispose_class (video_decoder_class_t *this) { + free (this); +} + +static void *init_plugin (xine_t *xine, void *data) { + + mpeg2_class_t *this; + + this = (mpeg2_class_t *) xine_xmalloc (sizeof (mpeg2_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.get_identifier = get_identifier; + this->decoder_class.get_description = get_description; + this->decoder_class.dispose = dispose_class; + + return this; +} +/* + * exported plugin catalog entry + */ + +static uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; + +static decoder_info_t dec_info_mpeg2 = { + supported_types, /* supported types */ + 6 /* priority */ +}; + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_VIDEO_DECODER, 18, "mpeg2new", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; -- cgit v1.2.3